def _acquire_value(self, context):
        if isinstance(context, MetadataBase) or context is None:
            # we do not test the factory, it is not acquisition wrapped and
            # we cant get the request...
            return None

        request = context.REQUEST
        if IDuringContentCreation.providedBy(request):
            # object does not yet exist, context is container (add)
            container = context
        else:
            # object already exists, container is parent of context (edit)
            container = context.aq_inner.aq_parent

        acquired_value = acquire_field_value(self.field, container)

        # Use acquired value if one was found
        if acquired_value is not NO_VALUE_FOUND:
            return acquired_value

        # Otherwise fall back to static field default
        #
        # NOTE: We deliberately avoid accessing field.default, because doing
        # so would invoke a defaultFactory if present
        return self.field.__dict__.get('default', None)
    def _acquire_value(self, context):
        if isinstance(context, MetadataBase) or context is None:
            # we do not test the factory, it is not acquisition wrapped and
            # we cant get the request...
            return None

        request = context.REQUEST
        if IDuringContentCreation.providedBy(request):
            # object does not yet exist, context is container (add)
            container = context
        else:
            # object already exists, container is parent of context (edit)
            container = context.aq_inner.aq_parent

        acquired_value = acquire_field_value(self.field, container)

        # Use acquired value if one was found
        if acquired_value is not NO_VALUE_FOUND:
            return acquired_value

        # Otherwise fall back to static field default
        #
        # NOTE: We deliberately avoid accessing field.default, because doing
        # so would invoke a defaultFactory if present
        return self.field.__dict__.get('default', None)
    def _acquire_value(self, context):
        if isinstance(context, MetadataBase) or context is None:
            # we do not test the factory, it is not acquisition wrapped and
            # we cant get the request...
            return None

        request = context.REQUEST
        if IDuringContentCreation.providedBy(request):
            # object does not yet exist, context is container (add)
            container = context
        elif ISiteRoot.providedBy(context):
            # The context is the siteroot when using the /@types endpoint
            # from the plone rest-api.
            # See https://github.com/4teamwork/opengever.core/issues/5283
            container = context
        else:
            # object already exists, container is parent of context (edit)
            container = context.aq_inner.aq_parent

        acquired_value = acquire_field_value(self.field, container)

        # Use acquired value if one was found
        if acquired_value is not NO_VALUE_FOUND:
            return acquired_value

        # Otherwise fall back to static field default
        #
        # NOTE: We deliberately avoid accessing field.default, because doing
        # so would invoke a defaultFactory if present
        return self.field.__dict__.get('default', None)
def propagate_vocab_restrictions(container, event, restricted_fields, marker):
    """Propagate changes to fields with restricted vocabularies down to
    children of the folderish object (for the children whose field value would
    now violate the business rule imposed by the restricted vocabulary).
    """
    def dottedname(field):
        return '.'.join((field.interface.__name__, field.__name__))

    changed_fields = []
    for desc in event.descriptions:
        for name in desc.attributes:
            changed_fields.append(name)

    fields_to_check = []
    for field in restricted_fields:
        if dottedname(field) in changed_fields:
            fields_to_check.append(field)

    if not fields_to_check:
        return

    children = container.portal_catalog(
        # XXX: Depth should not be limited (Issue #2027)
        path={
            'depth': 2,
            'query': '/'.join(container.getPhysicalPath())
        },
        object_provides=(marker.__identifier__, ))

    for child in children:
        obj = child.getObject()
        for field in fields_to_check:
            voc = field.bind(obj).source
            value = field.get(field.interface(obj))
            if value not in voc:
                # Change the child object's field value to a valid one
                # acquired from above
                new_value = acquire_field_value(field, obj.aq_parent)
                field.set(field.interface(obj), new_value)
def propagate_vocab_restrictions(container, event, restricted_fields, marker):
    """Propagate changes to fields with restricted vocabularies down to
    children of the folderish object (for the children whose field value would
    now violate the business rule imposed by the restricted vocabulary).
    """
    def dottedname(field):
        return '.'.join((field.interface.__name__, field.__name__))

    changed_fields = []
    for desc in event.descriptions:
        for name in desc.attributes:
            changed_fields.append(name)

    fields_to_check = []
    for field in restricted_fields:
        if dottedname(field) in changed_fields:
            fields_to_check.append(field)

    if not fields_to_check:
        return

    children = container.portal_catalog(
        # XXX: Depth should not be limited (Issue #2027)
        path={'depth': 2,
              'query': '/'.join(container.getPhysicalPath())},
        object_provides=(marker.__identifier__,)
    )

    for child in children:
        obj = child.getObject()
        for field in fields_to_check:
            voc = field.bind(obj).source
            value = field.get(field.interface(obj))
            if value not in voc:
                # Change the child object's field value to a valid one
                # acquired from above
                new_value = acquire_field_value(field, obj.aq_parent)
                field.set(field.interface(obj), new_value)