hooks/integrity.py
changeset 8556 bbe0d6985e59
parent 8508 7801f2acd1dc
child 9361 0542a85fe667
equal deleted inserted replaced
8555:c747242d22a6 8556:bbe0d6985e59
     1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     1 # copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     3 #
     3 #
     4 # This file is part of CubicWeb.
     4 # This file is part of CubicWeb.
     5 #
     5 #
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
    18 """Core hooks: check for data integrity according to the instance'schema
    18 """Core hooks: check for data integrity according to the instance'schema
    19 validity
    19 validity
    20 """
    20 """
    21 
    21 
    22 __docformat__ = "restructuredtext en"
    22 __docformat__ = "restructuredtext en"
       
    23 _ = unicode
    23 
    24 
    24 from threading import Lock
    25 from threading import Lock
    25 
    26 
    26 from yams.schema import role_name
    27 from cubicweb import validation_error
    27 
       
    28 from cubicweb import ValidationError
       
    29 from cubicweb.schema import (META_RTYPES, WORKFLOW_RTYPES,
    28 from cubicweb.schema import (META_RTYPES, WORKFLOW_RTYPES,
    30                              RQLConstraint, RQLUniqueConstraint)
    29                              RQLConstraint, RQLUniqueConstraint)
    31 from cubicweb.predicates import is_instance
    30 from cubicweb.predicates import is_instance
    32 from cubicweb.uilib import soup2xhtml
    31 from cubicweb.uilib import soup2xhtml
    33 from cubicweb.server import hook
    32 from cubicweb.server import hook
    85                 continue
    84                 continue
    86             if rtype in pendingrtypes:
    85             if rtype in pendingrtypes:
    87                 continue
    86                 continue
    88             if not session.execute(self.base_rql % rtype, {'x': eid}):
    87             if not session.execute(self.base_rql % rtype, {'x': eid}):
    89                 etype = session.describe(eid)[0]
    88                 etype = session.describe(eid)[0]
    90                 _ = session._
       
    91                 msg = _('at least one relation %(rtype)s is required on '
    89                 msg = _('at least one relation %(rtype)s is required on '
    92                         '%(etype)s (%(eid)s)')
    90                         '%(etype)s (%(eid)s)')
    93                 msg %= {'rtype': _(rtype), 'etype': _(etype), 'eid': eid}
    91                 raise validation_error(eid, {(rtype, self.role): msg},
    94                 raise ValidationError(eid, {role_name(rtype, self.role): msg})
    92                                        {'rtype': rtype, 'etype': etype, 'eid': eid},
       
    93                                        ['rtype', 'etype'])
    95 
    94 
    96 
    95 
    97 class _CheckSRelationOp(_CheckRequiredRelationOperation):
    96 class _CheckSRelationOp(_CheckRequiredRelationOperation):
    98     """check required subject relation"""
    97     """check required subject relation"""
    99     role = 'subject'
    98     role = 'subject'
   229                 if val is None:
   228                 if val is None:
   230                     continue
   229                     continue
   231                 rql = '%s X WHERE X %s %%(val)s' % (entity.e_schema, attr)
   230                 rql = '%s X WHERE X %s %%(val)s' % (entity.e_schema, attr)
   232                 rset = self._cw.execute(rql, {'val': val})
   231                 rset = self._cw.execute(rql, {'val': val})
   233                 if rset and rset[0][0] != entity.eid:
   232                 if rset and rset[0][0] != entity.eid:
   234                     msg = self._cw._('the value "%s" is already used, use another one')
   233                     msg = _('the value "%s" is already used, use another one')
   235                     qname = role_name(attr, 'subject')
   234                     raise validation_error(entity, {(attr, 'subject'): msg},
   236                     raise ValidationError(entity.eid, {qname: msg % val})
   235                                            (val,))
   237 
   236 
   238 
   237 
   239 class DontRemoveOwnersGroupHook(IntegrityHook):
   238 class DontRemoveOwnersGroupHook(IntegrityHook):
   240     """delete the composed of a composite relation when this relation is deleted
   239     """delete the composed of a composite relation when this relation is deleted
   241     """
   240     """
   244     events = ('before_delete_entity', 'before_update_entity')
   243     events = ('before_delete_entity', 'before_update_entity')
   245 
   244 
   246     def __call__(self):
   245     def __call__(self):
   247         entity = self.entity
   246         entity = self.entity
   248         if self.event == 'before_delete_entity' and entity.name == 'owners':
   247         if self.event == 'before_delete_entity' and entity.name == 'owners':
   249             msg = self._cw._('can\'t be deleted')
   248             raise validation_error(entity, {None: _("can't be deleted")})
   250             raise ValidationError(entity.eid, {None: msg})
       
   251         elif self.event == 'before_update_entity' \
   249         elif self.event == 'before_update_entity' \
   252                  and 'name' in entity.cw_edited:
   250                  and 'name' in entity.cw_edited:
   253             oldname, newname = entity.cw_edited.oldnewvalue('name')
   251             oldname, newname = entity.cw_edited.oldnewvalue('name')
   254             if oldname == 'owners' and newname != oldname:
   252             if oldname == 'owners' and newname != oldname:
   255                 qname = role_name('name', 'subject')
   253                 raise validation_error(entity, {('name', 'subject'): _("can't be changed")})
   256                 msg = self._cw._('can\'t be changed')
       
   257                 raise ValidationError(entity.eid, {qname: msg})
       
   258 
   254 
   259 
   255 
   260 class TidyHtmlFields(IntegrityHook):
   256 class TidyHtmlFields(IntegrityHook):
   261     """tidy HTML in rich text strings"""
   257     """tidy HTML in rich text strings"""
   262     __regid__ = 'htmltidy'
   258     __regid__ = 'htmltidy'