28 from cubicweb.selectors import is_instance |
29 from cubicweb.selectors import is_instance |
29 from cubicweb.server.hook import Hook |
30 from cubicweb.server.hook import Hook |
30 |
31 |
31 class PersonAgeRange(Hook): |
32 class PersonAgeRange(Hook): |
32 __regid__ = 'person_age_range' |
33 __regid__ = 'person_age_range' |
|
34 __select__ = Hook.__select__ & is_instance('Person') |
33 events = ('before_add_entity', 'before_update_entity') |
35 events = ('before_add_entity', 'before_update_entity') |
34 __select__ = Hook.__select__ & is_instance('Person') |
|
35 |
36 |
36 def __call__(self): |
37 def __call__(self): |
37 if 'age' in self.entity.cw_edited: |
38 if 'age' in self.entity.cw_edited: |
38 if 0 <= self.entity.age <= 120: |
39 if 0 <= self.entity.age <= 120: |
39 return |
40 return |
93 Suppose we want to check that there is no cycle by the `subsidiary_of` |
94 Suppose we want to check that there is no cycle by the `subsidiary_of` |
94 relation. This is best achieved in an operation since all relations are likely to |
95 relation. This is best achieved in an operation since all relations are likely to |
95 be set at commit time. |
96 be set at commit time. |
96 |
97 |
97 .. sourcecode:: python |
98 .. sourcecode:: python |
|
99 |
|
100 from cubicweb.server.hook import Hook, Operation, match_rtype |
98 |
101 |
99 def check_cycle(self, session, eid, rtype, role='subject'): |
102 def check_cycle(self, session, eid, rtype, role='subject'): |
100 parents = set([eid]) |
103 parents = set([eid]) |
101 parent = session.entity_from_eid(eid) |
104 parent = session.entity_from_eid(eid) |
102 while parent.related(rtype, role): |
105 while parent.related(rtype, role): |
144 CheckSubsidiaryCycleOp) |
147 CheckSubsidiaryCycleOp) |
145 |
148 |
146 class CheckSubsidiaryCycleOp(Operation): |
149 class CheckSubsidiaryCycleOp(Operation): |
147 |
150 |
148 def precommit_event(self): |
151 def precommit_event(self): |
149 for eid in self._cw.transaction_data.pop('subsidiary_cycle_detection'): |
152 for eid in self.session.transaction_data['subsidiary_cycle_detection']: |
150 check_cycle(self.session, eid, 'subsidiary_of') |
153 check_cycle(self.session, eid, self.rtype) |
151 |
154 |
152 |
155 |
153 Here, we call :func:`set_operation` so that we will simply accumulate eids of |
156 Here, we call :func:`set_operation` so that we will simply accumulate eids of |
154 entities to check at the end in a single CheckSubsidiaryCycleOp operation. Value |
157 entities to check at the end in a single `CheckSubsidiaryCycleOp` |
155 are stored in a set associated to the 'subsidiary_cycle_detection' transaction |
158 operation. Value are stored in a set associated to the |
156 data key. The set initialization and operation creation are handled nicely by |
159 'subsidiary_cycle_detection' transaction data key. The set initialization and |
157 :func:set_operation. |
160 operation creation are handled nicely by :func:`set_operation`. |
158 |
161 |
159 A more realistic example can be found in the advanced tutorial chapter |
162 A more realistic example can be found in the advanced tutorial chapter |
160 :ref:`adv_tuto_security_propagation`. |
163 :ref:`adv_tuto_security_propagation`. |
161 |
164 |
162 |
165 |