diff --git a/CHANGES.rst b/CHANGES.rst index 1c54fc9b9c..777b14f212 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,6 +14,7 @@ Changelog **Changed** +- #1490 Support Dexterity Behavior Fields in API - #1488 Support Dexterity Contents in Catalog Indexers - #1486 Clean-up of indexes and metadata from `setup_catalog` diff --git a/bika/lims/api/__init__.py b/bika/lims/api/__init__.py index 5e248920c1..1f06c045d7 100644 --- a/bika/lims/api/__init__.py +++ b/bika/lims/api/__init__.py @@ -19,6 +19,7 @@ # Some rights reserved, see README and LICENSE. import re +from collections import OrderedDict from datetime import datetime from datetime import timedelta @@ -34,6 +35,7 @@ from plone import api as ploneapi from plone.api.exc import InvalidParameterError from plone.app.layout.viewlets.content import ContentHistoryView +from plone.behavior.interfaces import IBehaviorAssignable from plone.dexterity.interfaces import IDexterityContent from plone.i18n.normalizer.interfaces import IFileNameNormalizer from plone.i18n.normalizer.interfaces import IIDNormalizer @@ -57,6 +59,7 @@ from zope.event import notify from zope.lifecycleevent import ObjectCreatedEvent from zope.lifecycleevent import modified +from zope.schema import getFieldsInOrder from zope.security.interfaces import Unauthorized """SENAITE LIMS Framework API @@ -333,20 +336,26 @@ def get_schema(brain_or_object): def get_fields(brain_or_object): - """Get the list of fields from the object + """Get a name to field mapping of the object :param brain_or_object: A single catalog brain or content object :type brain_or_object: ATContentType/DexterityContentType/CatalogBrain - :returns: List of fields - :rtype: list + :returns: Mapping of name -> field + :rtype: OrderedDict """ obj = get_object(brain_or_object) schema = get_schema(obj) if is_dexterity_content(obj): - names = schema.names() - fields = map(lambda name: schema.get(name), names) - return dict(zip(names, fields)) - return dict(zip(schema.keys(), schema.fields())) + # get the fields directly provided by the interface + fields = getFieldsInOrder(schema) + # append the fields coming from behaviors + behavior_assignable = IBehaviorAssignable(obj) + if behavior_assignable: + behaviors = behavior_assignable.enumerateBehaviors() + for behavior in behaviors: + fields.extend(getFieldsInOrder(behavior.interface)) + return OrderedDict(fields) + return OrderedDict(schema) def get_id(brain_or_object):