def test(self, context, tested_base_category_list=None, strict_membership=0, isMemberOf=None, **kw): """ A Predicate can be tested on a given context. Parameters can passed in order to ignore some conditions. - tested_base_category_list: this is the list of category that we do want to test. For example, we might want to test only the destination or the source of a predicate. - if strict_membership is specified, we should make sure that we are strictly a member of tested categories - isMemberOf can be a function caching results for CategoryTool.isMemberOf: it is always called with given 'context' and 'strict_membership' values, and different categories. """ self = self.asPredicate() if self is None: # asPredicate returned None, so this predicate never applies. # But if we reach this it is because catalog is not up to date. return False result = 1 if getattr(aq_base(self), '_identity_criterion', None) is None: self._identity_criterion = PersistentMapping() self._range_criterion = PersistentMapping() # LOG('PREDICATE TEST', 0, # 'testing %s on context of %s' % \ # (self.getRelativeUrl(), context.getRelativeUrl())) for property, value in self._identity_criterion.iteritems(): if isinstance(value, (list, tuple)): result = context.getProperty(property) in value else: result = context.getProperty(property) == value # LOG('predicate test', 0, # '%s after prop %s : %s == %s' % \ # (result, property, context.getProperty(property), value)) if not result: return result for property, (min, max) in self._range_criterion.iteritems(): value = context.getProperty(property) if min is not None: result = value >= min # LOG('predicate test', 0, # '%s after prop %s : %s >= %s' % \ # (result, property, value, min)) if not result: return result if max is not None: result = value < max # LOG('predicate test', 0, # '%s after prop %s : %s < %s' % \ # (result, property, value, max)) if not result: return result multimembership_criterion_base_category_list = \ self.getMultimembershipCriterionBaseCategoryList() membership_criterion_base_category_list = \ self.getMembershipCriterionBaseCategoryList() tested_base_category = {} # LOG('predicate test', 0, # 'categories will be tested in multi %s single %s as %s' % \ # (multimembership_criterion_base_category_list, # membership_criterion_base_category_list, # self.getMembershipCriterionCategoryList())) # Test category memberships. Enable the read-only transaction cache # because this part is strictly read-only, and context.isMemberOf # is very expensive when the category list has many items. if isMemberOf is None: isMemberOf = context._getCategoryTool().isMemberOf with readOnlyTransactionCache(): for c in self.getMembershipCriterionCategoryList(): bc = c.split('/', 1)[0] if tested_base_category_list is None or bc in tested_base_category_list: if bc in multimembership_criterion_base_category_list: if not isMemberOf(context, c, strict_membership=strict_membership): return 0 elif bc in membership_criterion_base_category_list and \ not tested_base_category.get(bc): tested_base_category[bc] = \ isMemberOf(context, c, strict_membership=strict_membership) if 0 in tested_base_category.itervalues(): return 0 # Test method calls test_method_id_list = self.getTestMethodIdList() if test_method_id_list is not None : for test_method_id in test_method_id_list : if test_method_id is not None: method = getattr(context,test_method_id) try: result = method(self) except TypeError: if method.func_code.co_argcount != isinstance(method, MethodType): raise # backward compatibilty with script that takes no argument warn('Predicate %s uses an old-style method (%s) that does not' ' take the predicate as argument' % ( self.getRelativeUrl(), method.__name__), DeprecationWarning) result = method() # LOG('predicate test', 0, # '%s after method %s ' % (result, test_method_id)) if not result: return result test_tales_expression = self.getTestTalesExpression() if test_tales_expression != 'python: True': expression = Expression(test_tales_expression) from Products.ERP5Type.Utils import createExpressionContext # evaluate a tales expression with the tested value as context result = expression(createExpressionContext(context)) return result
def test(self, context, tested_base_category_list=None, **kw): """ A Predicate can be tested on a given context. Parameters can passed in order to ignore some conditions. - tested_base_category_list: this is the list of category that we do want to test. For example, we might want to test only the destination or the source of a predicate. This method returns portal type name if test success, else returns False. """ self = self.asPredicate() result = 1 if getattr(aq_base(self), '_identity_criterion', None) is None: self._identity_criterion = {} self._range_criterion = {} for property, value in self._identity_criterion.iteritems(): result = result and (context.getProperty(property) in value) for property, (min, max) in self._range_criterion.iteritems(): value = context.getProperty(property) if min is not None: result = result and (value >= min) if max is not None: result = result and (value < max) multimembership_criterion_base_category_list = \ self.getMultimembershipCriterionBaseCategoryList() membership_criterion_base_category_list = \ self.getMembershipCriterionBaseCategoryList() tested_base_category = {} membership_criterion_category_list = \ self.getMembershipCriterionCategoryList() if tested_base_category_list is not None: membership_criterion_category_list = [x for x in \ membership_criterion_category_list if x.split('/', 1)[0] in \ tested_base_category_list] # Test category memberships. Enable the read-only transaction cache # because this part is strictly read-only, and context.isMemberOf # is very expensive when the category list has many items. with readOnlyTransactionCache(): for c in membership_criterion_category_list: bc = c.split('/', 1)[0] if (bc not in tested_base_category) and \ (bc in multimembership_criterion_base_category_list): tested_base_category[bc] = 1 elif (bc not in tested_base_category) and \ (bc in membership_criterion_base_category_list): tested_base_category[bc] = 0 if (bc in multimembership_criterion_base_category_list): tested_base_category[bc] = tested_base_category[bc] and \ context.isMemberOf(c) elif (bc in membership_criterion_base_category_list): tested_base_category[bc] = tested_base_category[bc] or \ context.isMemberOf(c) result = result and (0 not in tested_base_category.values()) # Test method calls test_method_id_list = self.getTestMethodIdList() if test_method_id_list: for test_method_id in test_method_id_list: if (test_method_id is not None) and result: method = getattr(context, test_method_id) result = result and method(self) else: result = result and self.getDestinationPortalType() return result