plone / plone.restapi

RESTful API for Plone.
http://plonerestapi.readthedocs.org/
85 stars 75 forks source link

Copy and paste doesn't work when content has children #1536

Closed wesleybl closed 1 year ago

wesleybl commented 1 year ago

Describe the bug If a Document has children, it is not possible to copy and paste this Document. We get the error:

2022-11-07 14:34:45 ERROR [Zope.SiteErrorLog:35][waitress-1] AttributeError: http://localhost:3000/@copy
Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 167, in transaction_pubevents
  Module ZPublisher.WSGIPublisher, line 376, in publish_module
  Module ZPublisher.WSGIPublisher, line 271, in publish
  Module ZPublisher.mapply, line 85, in mapply
  Module ZPublisher.WSGIPublisher, line 68, in call_object
  Module plone.rest.service, line 22, in __call__
  Module plone.restapi.services, line 19, in render
  Module plone.restapi.services.copymove.copymove, line 83, in reply
  Module OFS.CopySupport, line 317, in manage_pasteObjects
  Module OFS.CopySupport, line 226, in _pasteObjects
  Module zope.event, line 32, in notify
  Module zope.component.event, line 27, in dispatch
  Module zope.component._api, line 134, in subscribers
  Module zope.interface.registry, line 448, in subscribers
  Module zope.interface.adapter, line 899, in subscribers
  Module zope.component.event, line 36, in objectEventNotify
  Module zope.component._api, line 134, in subscribers
  Module zope.interface.registry, line 448, in subscribers
  Module zope.interface.adapter, line 899, in subscribers
  Module OFS.subscribers, line 136, in dispatchObjectCopiedEvent
  Module zope.container.contained, line 157, in dispatchToSublocations
  Module zope.component._api, line 138, in handle
  Module zope.interface.registry, line 448, in subscribers
  Module zope.interface.adapter, line 899, in subscribers
  Module plone.app.linkintegrity.handlers, line 116, in modifiedContent
  Module plone.restapi.blocks_linkintegrity, line 25, in retrieveLinks
AttributeError: REQUEST

To Reproduce Steps to reproduce the behavior:

  1. Create a document.
  2. Inside that document, create another document.
  3. Go to Contents, and try to copy and paste the parent document.
  4. See error

Expected behavior Copy and paste works.

Software (please complete the following information):

tiberiuichim commented 1 year ago

This is a plone.restapi issue.

wesleybl commented 1 year ago

@cekk can you please take a look here? It seems that it was after the PR https://github.com/plone/plone.restapi/pull/953 that this error started to occur.

davisagli commented 1 year ago

Using getRequest from zope.globalrequest instead of context.REQUEST should avoid this error (which happens if the object does not have a full acquisition chain to the Zope root)

wesleybl commented 1 year ago

@davisagli in fact, the classes that implement the interface don't even use request. For example:

https://github.com/plone/plone.restapi/blob/60293d86de9a89220052f434e92f01649b0b7029/src/plone/restapi/blocks_linkintegrity.py#L37-L39

So I wonder if the request could not be removed.

tiberiuichim commented 1 year ago

@wesleybl the request is useful as discriminators in the adaptors, as they allow overriding, per Plone site, the behavior, in case that's needed.

wesleybl commented 1 year ago

@tiberiuichim you mean through a layer? Adapter does not have the layer attribute. It is not possible to customize an adapter per site, through layer.

tiberiuichim commented 1 year ago

@wesleybl they don't have the layer, but the request will provide a marker layer interface. https://github.com/plone/bobtemplates.plone/blob/9bf1efef7c735ecec99d6e195aa5b10fa0e3dbfa/bobtemplates/plone/addon/src/+package.namespace+/+package.name+/profiles/default/browserlayer.xml.bob

wesleybl commented 1 year ago

@tiberiuichim are you proposing to customize the adapter and make an if in the custom adapter itself?

tiberiuichim commented 1 year ago

@wesleybl no... but I'm not sure I understand your last message correctly.

In any case, let me try explain:

wesleybl commented 1 year ago

so you can register an override not by doing it via a configure-overrides.zcml, but you can do it in normal code, by using a more specific layer interface instead of IBrowserRequest

@tiberiuichim in that case, you would not overwrite the original. You would have one more subscriber on the site with the more specific interface. More specific interfaces only overwrite components that have the layer abribute.

I don't know if that's what you were looking for, I don't even know if it's worth keeping the request because of that.

tiberiuichim commented 1 year ago

@wesleybl I see now the issue, the adapters are actually subscribers.

mauritsvanrees commented 1 year ago

Is anyone trying to fix this? Fastest fix would seem, as indicated above, to use getRequest from zope.globalrequest if self.context.REQUEST is missing. Whether the request is really needed/useful here seems a separate issue that we could talk about later.