def copyRelationsOnSourceCopy(obj, event): """Copies all source relaitonships marked with IRetainOnCopy when the source object is copied""" orig_obj = obj.__orig_object__.aq_inner source = IRelationshipSource(orig_obj) cur_ifaces = directlyProvidedBy(obj) directlyProvides(obj, *[i for i in cur_ifaces if i is not ICopyPendingAdd]) delattr(obj, '__orig_object__') copy_filter = IRetainOnCopy.providedBy # this is not efficient to source objects with a huge number of # relations rels = source.getRelationships(rel_filter=copy_filter) container = getUtility(IComplexRelationshipContainer, name='relations') unwrapped_obj = aq_base(obj) for rel in rels: # copy the relationship rel_copy = locationCopy(aq_base(rel)) # The references on the copy becames copies themselves we need # to make sure all such references point to the originals: rel_copy.__dict__ = rel.__dict__ # We should also remove existing ILocation pointers rel_copy.__parent__ = rel_copy.__name__ = None # Now we add the relationship (with wrong sources for now) to # give it a context. container.add(rel_copy) # replace the old sources with just the copy rel_copy.sources = (obj,)
def handleSourceTargetDelete(ob, event): """Fires relevant events for all references related to the object""" try: source = IRelationshipSource(ob) target = IRelationshipTarget(ob) except (ComponentLookupError, TypeError): return # we tuplify the generator to prevent errors if we need to delete elements rels = tuple(source.getRelationships()) for rel in rels: notify(RelationSourceDeleted(rel, ob)) rels = tuple(target.getRelationships()) for rel in rels: notify(RelationTargetDeleted(rel, ob))
def PloneRelationsAdapter(context, field): relationship = field.relationship from plone.app.relations.interfaces import IRelationshipSource return IRelationshipSource(context).getTargets(relation=relationship)