From 719cf2f77284f46b16ab790e9a124d0359e15ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Katja=20S=C3=BCss?= Date: Mon, 14 Aug 2023 07:10:23 +0200 Subject: [PATCH] Fix broken relations info (#1673) * Update add.py * Fix broken relations info - Additional info for broken: paths. - Catch and ignore invalid/broken relations. - Fix @id for relations, broken, and relation stats - fix items_total for broken * Create 1673.bugfix * black --- news/1673.bugfix | 1 + src/plone/restapi/services/relations/add.py | 2 +- src/plone/restapi/services/relations/get.py | 32 ++++++++------------- 3 files changed, 14 insertions(+), 21 deletions(-) create mode 100644 news/1673.bugfix diff --git a/news/1673.bugfix b/news/1673.bugfix new file mode 100644 index 0000000000..fec8d4d327 --- /dev/null +++ b/news/1673.bugfix @@ -0,0 +1 @@ +Fix broken relations info. @ksuess \ No newline at end of file diff --git a/src/plone/restapi/services/relations/add.py b/src/plone/restapi/services/relations/add.py index a86eac0732..de9b186561 100644 --- a/src/plone/restapi/services/relations/add.py +++ b/src/plone/restapi/services/relations/add.py @@ -25,7 +25,7 @@ @implementer(IPublishTraverse) class PostRelations(Service): - """Create new relations.""" + """Create new relations or rebuild relations.""" def __init__(self, context, request): super().__init__(context, request) diff --git a/src/plone/restapi/services/relations/get.py b/src/plone/restapi/services/relations/get.py index ea79c96b5d..8ff4f424b7 100644 --- a/src/plone/restapi/services/relations/get.py +++ b/src/plone/restapi/services/relations/get.py @@ -31,14 +31,6 @@ except ImportError: get_relations_stats = None -try: - from Products.CMFPlone.relationhelper import rebuild_relations -except ImportError: - try: - from collective.relationhelpers.api import rebuild_relations - except ImportError: - rebuild_relations = None - def make_summary(obj, request): """Add UID to metadata_fields.""" @@ -100,7 +92,8 @@ def get_relations( except TypeError as e: raise ValueError(str(e)) count = 0 - relations = relation_catalog.findRelations(query) + relations = list(relation_catalog.findRelations(query)) + for relation in relations: if relation.isBroken(): if not onlyBroken: @@ -125,11 +118,15 @@ def get_relations( if onlyBroken: results[relation.from_attribute].append( [ - source_obj and source_obj.absolute_url() or "", - target_obj and target_obj.absolute_url() or "", + source_obj and source_obj.absolute_url() or relation.from_path, + target_obj and target_obj.absolute_url() or relation.to_path, ] ) else: + # Exclude relations without source or target. + # Dispensable with https://github.com/zopefoundation/z3c.relationfield/pull/24 + if not source_obj or not target_obj: + continue results[relation.from_attribute].append( { "source": make_summary(source_obj, request), @@ -174,8 +171,6 @@ class GetRelations(Service): onlyBroken: boolean: dictionary with broken relations per relation type query_source: Restrict relations by path or SearchableText query_target: Restrict relations by path or SearchableText - rebuild: Rebuild relations - flush: If rebuild, then this also flushes the intIds Returns: stats if no parameter, else relations @@ -188,7 +183,6 @@ def reply(self): # Disable CSRF protection if "IDisableCSRFProtection" in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) - source = self.request.get("source", None) target = self.request.get("target", None) relationship = self.request.get("relation", None) @@ -209,14 +203,14 @@ def reply(self): if len(relationNames) == 0: return self.reply_no_content(status=204) result = { - "@id": f'{self.request["SERVER_URL"]}{self.request.environ["REQUEST_URI"]}', + "@id": f"{self.context.absolute_url()}/@relations?onlyBroken=true", "relations": {}, } for relationName in relationNames: rels = get_relations(relationship=relationName, onlyBroken=True) result["relations"][relationName] = { "items": rels[relationName], - "items_total": len(rels), + "items_total": len(rels[relationName]), } return result @@ -224,9 +218,7 @@ def reply(self): if not source and not target and not relationship: try: stats = relation_stats() - stats[ - "@id" - ] = f'{self.request["SERVER_URL"]}{self.request.environ["REQUEST_URI"]}' + stats["@id"] = f"{self.context.absolute_url()}/@relations" return stats except ImportError: self.request.response.setStatus(501) @@ -287,7 +279,7 @@ def reply(self): ) result = { - "@id": f'{self.request["SERVER_URL"]}{self.request.environ["REQUEST_URI"]}', + "@id": f"{self.context.absolute_url()}/@relations?{self.request['QUERY_STRING']}", "relations": {}, } if relationship and not data: