def afterRetrieveModifier(self, obj, repo_clone, preserve=()): # check if the modifier is called with a valid working copy if obj is None: return [], [], {} if ( ( HAVE_Z3_IFACE and IReferenceable.providedBy(obj) or not HAVE_Z3_IFACE and IReferenceable.isImplementedBy(obj) ) and hasattr(aq_base(obj), REFERENCE_ANNOTATION) and hasattr(aq_base(repo_clone), REFERENCE_ANNOTATION) ): # Remove AT references that no longer exists in the retrived version orig_refs_container = getattr(aq_base(obj), REFERENCE_ANNOTATION) repo_clone_refs_container = getattr(aq_base(repo_clone), REFERENCE_ANNOTATION) ref_objs = orig_refs_container.objectValues() repo_clone_ref_ids = repo_clone_refs_container.objectIds() reference_catalog = getToolByName(obj, "reference_catalog") if reference_catalog: for ref in ref_objs: if ref.getId() not in repo_clone_ref_ids: reference_catalog.deleteReference(ref.sourceUID, ref.targetUID, ref.relationship) return [], [], {}
def afterRetrieveModifier(self, obj, repo_clone, preserve=()): # check if the modifier is called with a valid working copy if obj is None: return [], [], {} if (HAVE_Z3_IFACE and IReferenceable.providedBy(obj) or not HAVE_Z3_IFACE and IReferenceable.isImplementedBy(obj)) \ and hasattr(aq_base(obj), REFERENCE_ANNOTATION): #Preserve AT references orig_refs_container = getattr(aq_base(obj), REFERENCE_ANNOTATION) setattr(repo_clone, REFERENCE_ANNOTATION, orig_refs_container) return [], [], {}
def _get_references_for(self, context): try: referenceable = IReferenceable(context) except TypeError: # could not adapt # this means we have a dexterity object without # plone.app.referenceablebehavior activated. objs = [] else: objs = referenceable.getReferences() if HAS_ZC_RELATION: relation_catalog = getUtility(ICatalog) obj_intid = getUtility(IIntIds).getId(context) relations = tuple(relation_catalog.findRelations({'from_id': obj_intid})) objs += map(attrgetter('to_object'), relations) return list(set(objs))
def _get_references_for(self, context): try: referenceable = IReferenceable(context) except TypeError: # could not adapt # this means we have a dexterity object without # plone.app.referenceablebehavior activated. objs = [] else: objs = referenceable.getReferences() if HAS_ZC_RELATION: relation_catalog = getUtility(ICatalog) obj_intid = getUtility(IIntIds).getId(context) relations = tuple(relation_catalog.findRelations({'from_id': obj_intid})) objs += map(attrgetter('to_object'), relations) return list(set(objs))
def test_implements(self): if self.dummy is not None: self.failIf(IReferenceable.providedBy(self.dummy)) self.failIf(IExtensibleMetadata.providedBy(self.dummy)) self.failIf(self.dummy.isReferenceable) self.failUnless(IBaseContent.providedBy(self.dummy)) self.failUnless(IATTopicCriterion.providedBy(self.dummy)) self.failUnless(verifyObject(IBaseContent, self.dummy)) self.failUnless(verifyObject(IATTopicCriterion, self.dummy))
def test_implements(self): if self.dummy is not None: self.assertFalse(IReferenceable.providedBy(self.dummy)) self.assertFalse(IExtensibleMetadata.providedBy(self.dummy)) self.assertFalse(self.dummy.isReferenceable) self.assertTrue(IBaseContent.providedBy(self.dummy)) self.assertTrue(IATTopicCriterion.providedBy(self.dummy)) self.assertTrue(verifyObject(IBaseContent, self.dummy)) self.assertTrue(verifyObject(IATTopicCriterion, self.dummy))
def test_implements(self): if self.dummy is not None: self.assertFalse(IReferenceable.providedBy(self.dummy)) self.assertFalse(IExtensibleMetadata.providedBy(self.dummy)) self.assertFalse(self.dummy.isReferenceable) self.assertTrue(IBaseContent.providedBy(self.dummy)) self.assertTrue(IATTopicCriterion.providedBy(self.dummy)) self.assertTrue(verifyObject(IBaseContent, self.dummy)) self.assertTrue(verifyObject(IATTopicCriterion, self.dummy))
def _fixupATReferences(self, obj): """Reindex AT reference data, and delete reference implementations when the target doesn't exist anymore. Deletion of references is done at the end of the recursiveRetrieve operation to avoid deleting refs to targets that will be retrieved later in the recursiveRetrive. It doesn't call refcatalog.deleteReference as that method uses brains to retrieve reference implementations. If the target doesn't exist, brains for references pointing to it do not exist either. This manually calls reference.delHook to let it finalize correctly but traps ReferenceException eventually emitted in the process and forces the deletion, because leaving the reference impl. there will leave refcatalog in an incosistent state. """ if ( HAVE_Z3_IFACE and IReferenceable.providedBy(obj) or not HAVE_Z3_IFACE and IReferenceable.isImplementedBy(obj) ) and hasattr(obj, REFERENCES_CONTAINER_NAME): # Delete refs if their target doesn't exists anymore ref_folder = getattr(obj, REFERENCES_CONTAINER_NAME) uid_catalog = getToolByName(self, "uid_catalog") ref_catalog = getToolByName(self, "reference_catalog") ref_objs = ref_folder.objectValues() for ref in ref_objs: if not uid_catalog(UID=ref.targetUID): try: # at's _deleteReference passes the catalog # itself, the source and target obj... i'm # going to emulate it as much as i can ref.delHook(ref_catalog, obj, None) except ReferenceException: pass ref_folder.manage_delObjects(ref.getId()) # then reindex references container = aq_parent(aq_inner(obj)) obj._updateCatalog(container)
def _fixupATReferences(self, obj): """Reindex AT reference data, and delete reference implementations when the target doesn't exist anymore. Deletion of references is done at the end of the recursiveRetrieve operation to avoid deleting refs to targets that will be retrieved later in the recursiveRetrive. It doesn't call refcatalog.deleteReference as that method uses brains to retrieve reference implementations. If the target doesn't exist, brains for references pointing to it do not exist either. This manually calls reference.delHook to let it finalize correctly but traps ReferenceException eventually emitted in the process and forces the deletion, because leaving the reference impl. there will leave refcatalog in an incosistent state. """ if (HAVE_Z3_IFACE and IReferenceable.providedBy(obj) or not HAVE_Z3_IFACE and IReferenceable.isImplementedBy(obj)) and hasattr( obj, REFERENCES_CONTAINER_NAME): # Delete refs if their target doesn't exists anymore ref_folder = getattr(obj, REFERENCES_CONTAINER_NAME) uid_catalog = getToolByName(self, "uid_catalog") ref_catalog = getToolByName(self, "reference_catalog") ref_objs = ref_folder.objectValues() for ref in ref_objs: if not uid_catalog(UID=ref.targetUID): try: # at's _deleteReference passes the catalog # itself, the source and target obj... i'm # going to emulate it as much as i can ref.delHook(ref_catalog, obj, None) except ReferenceException: pass ref_folder.manage_delObjects(ref.getId()) # then reindex references container = aq_parent(aq_inner(obj)) obj._updateCatalog(container)
def is_referenceable(obj): """Find out if this object (AT or DX) is referenceable. Return True if a obj can be referenced using the reference_catalog used by Archetypes-Relations and Linkintegrity. Relations using the relation_catalog (zc.relation.interfaces.ICatalog) are not covered by this test! """ is_referenceable = False if IReferenceable.providedBy(obj) or \ safe_hasattr(aq_base(obj), 'isReferenceable'): is_referenceable = True else: try: # This most likely the case when plone.app.referenceablebehavior # is enabled. obj = IReferenceable(obj) is_referenceable = True except TypeError: is_referenceable = False return is_referenceable
def _listTypeInfo(self): """ List the portal types which are available. """ pt = getToolByName(self, "portal_types", None) at = getToolByName(self, "archetype_tool", None) if (pt is None) or (at is None): return () else: meta_types = [ ty["meta_type"] for ty in at.listRegisteredTypes() if IReferenceable.isImplementedByInstancesOf(ty["klass"]) ] tis = [t for t in pt.objectValues() if t.content_meta_type in meta_types] tis.sort(lambda a, b: cmp(a.Title(), b.Title())) return tis
def _listTypeInfo(self): """ List the portal types which are available. """ pt = getToolByName(self, 'portal_types', None) at = getToolByName(self, 'archetype_tool', None) if (pt is None) or (at is None): return () else: meta_types = [ ty['meta_type'] for ty in at.listRegisteredTypes() if IReferenceable.isImplementedByInstancesOf(ty['klass']) ] tis = [ t for t in pt.objectValues() if t.content_meta_type in meta_types ] tis.sort(lambda a, b: cmp(a.Title(), b.Title())) return tis
def is_referenceable(obj): """Find out if this object (AT or DX) is referenceable. Return True if a obj can be referenced using the reference_catalog used by Archetypes-Relations and Linkintegrity. Relations using the relation_catalog (zc.relation.interfaces.ICatalog) are not covered by this test! """ is_referenceable = False if IReferenceable.providedBy(obj) or \ safe_hasattr(aq_base(obj), 'isReferenceable'): is_referenceable = True else: try: # This most likely the case when plone.app.referenceablebehavior # is enabled. obj = IReferenceable(obj) is_referenceable = True except TypeError: is_referenceable = False return is_referenceable
def _catalogReferencesFor(self, obj, path): if IReferenceable.providedBy(obj): obj._catalogRefs(self)
def isReferenceable(self, object): return (IReferenceable.providedBy(object) or shasattr(object, 'isReferenceable'))
def _catalogReferencesFor(self,obj,path): if IReferenceable.isImplementedBy(obj): obj._catalogRefs(self)
def isReferenceable(self, object): return (IReferenceable.isImplementedBy(object) or shasattr(object, 'isReferenceable'))
def getData(self): """ Returns backreferences: { 'uid-obj-a': { 'the-field': [ 'uid-of-another-unpublished-object', 'my-uid', 'uid-obj-b', ], }, 'uid-obj-b': { 'ref-field': 'my-uid', }, } """ data = {} if hasattr(aq_base(self.context), 'getBackReferenceImpl'): referenceable = self.context else: try: referenceable = IReferenceable(self.context) except TypeError: # could not adapt # this means we have a dexterity object without # plone.app.referenceablebehavior activated. return data old_security_manager = getSecurityManager() newSecurityManager(self.context.REQUEST, SpecialUsers.system) try: references = referenceable.getBackReferenceImpl() finally: setSecurityManager(old_security_manager) for ref in references: # get source object src = ref.getSourceObject() if src is None: continue suid = src.UID() if suid not in data.keys(): data[suid] = {} if getattr(ref, 'field', None) is None: continue if ref.field in data[suid]: # we already added this field continue else: # add the field value field = src.getField(ref.field) if field: data[suid][ref.field] = field.getRaw(src) return data
def test_doesImplementAT(self): self.assertTrue(IBaseContent.providedBy(self._ATCT)) self.assertTrue(IReferenceable.providedBy(self._ATCT)) self.assertTrue(verifyObject(IBaseContent, self._ATCT)) self.assertTrue(verifyObject(IReferenceable, self._ATCT))
def test_doesImplementAT(self): self.assertTrue(IBaseContent.providedBy(self._ATCT)) self.assertTrue(IReferenceable.providedBy(self._ATCT)) self.assertTrue(verifyObject(IBaseContent, self._ATCT)) self.assertTrue(verifyObject(IReferenceable, self._ATCT))
def test_doesImplementAT(self): self.failUnless(IBaseContent.providedBy(self._ATCT)) self.failUnless(IReferenceable.providedBy(self._ATCT)) self.failUnless(verifyObject(IBaseContent, self._ATCT)) self.failUnless(verifyObject(IReferenceable, self._ATCT))
def modify_fti(fti, klass, pkg_name): fti[0]['id'] = klass.__name__ fti[0]['meta_type'] = klass.meta_type fti[0]['description'] = klass.__doc__ fti[0]['factory'] = 'add%s' % klass.__name__ fti[0]['product'] = pkg_name if hasattr(klass, 'content_icon'): fti[0]['content_icon'] = klass.content_icon if hasattr(klass, 'global_allow'): fti[0]['global_allow'] = klass.global_allow if hasattr(klass, 'allow_discussion'): fti[0]['allow_discussion'] = klass.allow_discussion if hasattr(klass, 'allowed_content_types'): allowed = klass.allowed_content_types fti[0]['allowed_content_types'] = allowed fti[0]['filter_content_types'] = allowed and True or False if hasattr(klass, 'filter_content_types'): fti[0]['filter_content_types'] = klass.filter_content_types if hasattr(klass, 'immediate_view'): fti[0]['immediate_view'] = klass.immediate_view if not IReferenceable.isImplementedByInstancesOf(klass): refs = findDict(fti[0]['actions'], 'id', 'references') refs['visible'] = False if not IExtensibleMetadata.isImplementedByInstancesOf(klass): refs = findDict(fti[0]['actions'], 'id', 'metadata') refs['visible'] = False # Set folder_listing to 'view' if the class implements ITemplateMixin if not ITemplateMixin.isImplementedByInstancesOf(klass): actions = [] for action in fti[0]['actions']: if action['id'] != 'folderlisting': actions.append(action) else: action['action'] = 'string:${folder_url}/view' actions.append(action) fti[0]['actions'] = tuple(actions) # Remove folderlisting action from non folderish content types if not getattr(klass,'isPrincipiaFolderish', None): actions = [] for action in fti[0]['actions']: if action['id'] != 'folderlisting': actions.append(action) fti[0]['actions'] = tuple(actions) # CMF 1.5 method aliases if getattr(klass, 'aliases', None): aliases = klass.aliases if not isinstance(aliases, dict): raise TypeError, "Invalid type for method aliases in class %s" % klass for required in ('(Default)', 'view',): if required not in aliases: raise ValueError, "Alias %s is required but not provied by %s" % ( required, klass) fti[0]['aliases'] = aliases # Dynamic View FTI support if getattr(klass, 'default_view', False): default_view = klass.default_view if not isinstance(default_view, basestring): raise TypeError, "Invalid type for default view in class %s" % klass fti[0]['default_view'] = default_view fti[0]['view_methods'] = (default_view, ) if getattr(klass, 'suppl_views', False): suppl_views = klass.suppl_views if not isinstance(suppl_views, (list, tuple)): raise TypeError, "Invalid type for suppl views in class %s" % klass if not default_view in suppl_views: suppl_views = suppl_views + (default_view, ) fti[0]['view_methods'] = suppl_views if getattr(klass, '_at_fti_meta_type', False): fti[0]['fti_meta_type'] = klass._at_fti_meta_type else: if fti[0].get('fti_meta_type', False): klass._at_fti_meta_type = fti[0]['fti_meta_type'] else: fti[0]['fti_meta_type'] = FactoryTypeInformation.meta_type
def getData(self): """ Returns backreferences: { 'uid-obj-a': { 'the-field': [ 'uid-of-another-unpublished-object', 'my-uid', 'uid-obj-b', ], }, 'uid-obj-b': { 'ref-field': 'my-uid', }, } """ data = {} if hasattr(aq_base(self.context), 'getBackReferenceImpl'): referenceable = self.context else: try: referenceable = IReferenceable(self.context) except TypeError: # could not adapt # this means we have a dexterity object without # plone.app.referenceablebehavior activated. return data old_security_manager = getSecurityManager() newSecurityManager(self.context.REQUEST, SpecialUsers.system) try: references = referenceable.getBackReferenceImpl() finally: setSecurityManager(old_security_manager) for ref in references: # get source object src = ref.getSourceObject() if src is None: continue suid = src.UID() if suid not in data.keys(): data[suid] = {} if getattr(ref, 'field', None) is None: continue if ref.field in data[suid]: # we already added this field continue else: # add the field value field = src.getField(ref.field) if field: data[suid][ref.field] = field.getRaw(src) return data
def test_doesImplementAT(self): self.failUnless(IBaseContent.providedBy(self._ATCT)) self.failUnless(IReferenceable.providedBy(self._ATCT)) self.failUnless(verifyObject(IBaseContent, self._ATCT)) self.failUnless(verifyObject(IReferenceable, self._ATCT))