From 065e6da7399b102f84584ace88da4698ac7f0605 Mon Sep 17 00:00:00 2001 From: Divesh Pahuja Date: Wed, 20 Oct 2021 11:44:41 +0200 Subject: [PATCH] [Documents] Introduce interfaces for editables to replace method_exists usages (#10607) * [Documents] Editables - introduce IdRewriterinterface for rewriteIds() - resolves #8908 * [Documents] Editables - introduce EditmodeDataInterface for getDataEditmode() - resolves #8908 * [Documents] Editables - introduce LazyLoadInterface for load() - resolves #8908 * [Documents] Editables - introduce additional interfaces - upgrade notes #8908 * Apply suggestions from code review Co-authored-by: Jacob Dreesen * Renamed LazyLoadInterface to LazyLoadingInterface to be consistent in naming * Removed type-hint on \Pimcore\Model\Document\Editable\IdRewriterInterface::rewriteIds() as core-editables implement this interface already and would break custom editables extending core editables implementing this interface Co-authored-by: Jacob Dreesen Co-authored-by: Bernhard Rusch --- .../09_Upgrade_Notes/README.md | 2 + lib/Templating/Renderer/EditableRenderer.php | 9 ++++- models/Document/Editable.php | 8 +++- models/Document/Editable/Date.php | 8 ++-- .../Editable/EditmodeDataInterface.php | 28 ++++++++++++++ .../Document/Editable/IdRewriterInterface.php | 38 +++++++++++++++++++ models/Document/Editable/Image.php | 22 +++-------- models/Document/Editable/Input.php | 7 +++- .../Editable/LazyLoadingInterface.php | 28 ++++++++++++++ models/Document/Editable/Link.php | 22 +++-------- models/Document/Editable/Multiselect.php | 6 +-- models/Document/Editable/Pdf.php | 6 +-- models/Document/Editable/Relation.php | 26 ++++--------- models/Document/Editable/Relations.php | 27 +++++-------- models/Document/Editable/Renderlet.php | 26 ++++--------- models/Document/Editable/Snippet.php | 26 ++++--------- models/Document/Editable/Textarea.php | 7 +++- models/Document/Editable/Video.php | 16 ++------ models/Document/Editable/Wysiwyg.php | 25 +++--------- models/Document/Service.php | 26 +++++++++++-- 20 files changed, 201 insertions(+), 162 deletions(-) create mode 100644 models/Document/Editable/EditmodeDataInterface.php create mode 100644 models/Document/Editable/IdRewriterInterface.php create mode 100644 models/Document/Editable/LazyLoadingInterface.php diff --git a/doc/Development_Documentation/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md b/doc/Development_Documentation/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md index 081286dd546..b1316f1040a 100644 --- a/doc/Development_Documentation/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md +++ b/doc/Development_Documentation/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md @@ -1,4 +1,6 @@ # Upgrade Notes +## 10.3.0 +- [Documents] Introduced additional interfaces for editable methods `getDataEditmode()`, `rewriteIds()` & `load()`. Existing `method_exists` calls are deprecated and will be removed in Pimcore 11. ## 10.2.0 - [Maintenance] Maintenance tasks are now handled with Symfony Messenger. The `pimcore:maintenance` command will add the maintenance messages to the bus and runs them afterwards immediately from the queue. However it's recommended to setup independent workers that process the queues, by running `bin/console messenger:consume pimcore_core pimcore_maintenance` (using e.g. Supervisor) and adding `--async` option to the `pimcore:maintenance` command that stops the maintenance command to process the queue directly. Details about setting it up for production environments, please check [Symfony Messenger Component docs](https://symfony.com/doc/current/messenger.html#deploying-to-production). diff --git a/lib/Templating/Renderer/EditableRenderer.php b/lib/Templating/Renderer/EditableRenderer.php index b3340eff138..5e9822ae788 100644 --- a/lib/Templating/Renderer/EditableRenderer.php +++ b/lib/Templating/Renderer/EditableRenderer.php @@ -18,6 +18,7 @@ use Pimcore\Document\Editable\EditmodeEditableDefinitionCollector; use Pimcore\Http\Request\Resolver\EditmodeResolver; use Pimcore\Model\Document\Editable; +use Pimcore\Model\Document\Editable\LazyLoadingInterface; use Pimcore\Model\Document\Editable\Loader\EditableLoaderInterface; use Pimcore\Model\Document\PageSnippet; use Psr\Log\LoggerAwareInterface; @@ -90,7 +91,13 @@ public function getEditable(PageSnippet $document, string $type, string $name, a $editable = $document->getEditable($name); if ($editable instanceof Editable\EditableInterface && $editable->getType() === $type) { // call the load() method if it exists to reinitialize the data (eg. from serializing, ...) - if (method_exists($editable, 'load')) { + //TODO Pimcore 11: remove method_exists BC layer + if ($editable instanceof LazyLoadingInterface || method_exists($editable, 'load')) { + if (!$editable instanceof LazyLoadingInterface) { + trigger_deprecation('pimcore/pimcore', '10.3', + sprintf('Usage of method_exists is deprecated since version 10.3 and will be removed in Pimcore 11.' . + 'Implement the %s interface instead.', LazyLoadingInterface::class)); + } $editable->load(); } } else { diff --git a/models/Document/Editable.php b/models/Document/Editable.php index 822918b4801..9e6b8ea0647 100644 --- a/models/Document/Editable.php +++ b/models/Document/Editable.php @@ -189,7 +189,13 @@ public function getEditmodeDefinition(): array protected function getEditmodeData() { // get configuration data for admin - if (method_exists($this, 'getDataEditmode')) { + //TODO Pimcore 11: remove method_exists BC layer + if ($this instanceof Document\Editable\EditmodeDataInterface || method_exists($this, 'getDataEditmode')) { + if (!$this instanceof Document\Editable\EditmodeDataInterface) { + trigger_deprecation('pimcore/pimcore', '10.3', + sprintf('Usage of method_exists is deprecated since version 10.3 and will be removed in Pimcore 11.' . + 'Implement the %s interface instead.', Document\Editable\EditmodeDataInterface::class)); + } $data = $this->getDataEditmode(); } else { $data = $this->getData(); diff --git a/models/Document/Editable/Date.php b/models/Document/Editable/Date.php index 484032ac9ec..f930f9cc10b 100644 --- a/models/Document/Editable/Date.php +++ b/models/Document/Editable/Date.php @@ -20,7 +20,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Date extends Model\Document\Editable +class Date extends Model\Document\Editable implements EditmodeDataInterface { /** * Contains the date @@ -56,11 +56,9 @@ public function getDate() } /** - * Converts the data so it's suitable for the editmode - * - * @return int|null + * {@inheritdoc} */ - public function getDataEditmode() + public function getDataEditmode() /** : mixed */ { if ($this->date) { return $this->date->getTimestamp(); diff --git a/models/Document/Editable/EditmodeDataInterface.php b/models/Document/Editable/EditmodeDataInterface.php new file mode 100644 index 00000000000..ad7cf4ccf0e --- /dev/null +++ b/models/Document/Editable/EditmodeDataInterface.php @@ -0,0 +1,28 @@ + array( + * SOURCE_ID => TARGET_ID, + * SOURCE_ID => TARGET_ID + * ), + * "object" => array(...), + * "asset" => array(...) + * ) + * + * @param array $idMapping + * + * @return void + */ + public function rewriteIds(/*array*/ $idMapping) /** : void */; +} diff --git a/models/Document/Editable/Image.php b/models/Document/Editable/Image.php index 1f8258ab2e8..205001c5b23 100644 --- a/models/Document/Editable/Image.php +++ b/models/Document/Editable/Image.php @@ -23,7 +23,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Image extends Model\Document\Editable +class Image extends Model\Document\Editable implements IdRewriterInterface, EditmodeDataInterface { /** * ID of the referenced image @@ -146,11 +146,9 @@ public function getDataForResource() } /** - * Converts the data so it's suitable for the editmode - * - * @return array|null + * {@inheritdoc} */ - public function getDataEditmode() + public function getDataEditmode() /** : mixed */ { $image = $this->getImage(); @@ -741,19 +739,9 @@ public function getMarker() } /** - * Rewrites id from source to target, $idMapping contains - * array( - * "document" => array( - * SOURCE_ID => TARGET_ID, - * SOURCE_ID => TARGET_ID - * ), - * "object" => array(...), - * "asset" => array(...) - * ) - * - * @param array $idMapping + * { @inheritdoc } */ - public function rewriteIds($idMapping) + public function rewriteIds($idMapping) /** : void */ { if (array_key_exists('asset', $idMapping) && array_key_exists($this->getId(), $idMapping['asset'])) { $this->setId($idMapping['asset'][$this->getId()]); diff --git a/models/Document/Editable/Input.php b/models/Document/Editable/Input.php index 925d5894a22..0aaff0370cf 100644 --- a/models/Document/Editable/Input.php +++ b/models/Document/Editable/Input.php @@ -20,7 +20,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Input extends Model\Document\Editable +class Input extends Model\Document\Editable implements EditmodeDataInterface { /** * Contains the text for this element @@ -70,7 +70,10 @@ public function frontend() return $text; } - public function getDataEditmode() + /** + * {@inheritdoc} + */ + public function getDataEditmode() /** : mixed */ { return htmlentities($this->text); } diff --git a/models/Document/Editable/LazyLoadingInterface.php b/models/Document/Editable/LazyLoadingInterface.php new file mode 100644 index 00000000000..655c24ace85 --- /dev/null +++ b/models/Document/Editable/LazyLoadingInterface.php @@ -0,0 +1,28 @@ +updatePathFromInternal(true, true); @@ -506,19 +504,9 @@ public function resolveDependencies() } /** - * Rewrites id from source to target, $idMapping contains - * array( - * "document" => array( - * SOURCE_ID => TARGET_ID, - * SOURCE_ID => TARGET_ID - * ), - * "object" => array(...), - * "asset" => array(...) - * ) - * - * @param array $idMapping + * { @inheritdoc } */ - public function rewriteIds($idMapping) + public function rewriteIds($idMapping) /** : void */ { if (isset($this->data['internal']) && $this->data['internal']) { $type = $this->data['internalType']; diff --git a/models/Document/Editable/Multiselect.php b/models/Document/Editable/Multiselect.php index ba44201ae26..75ccb50646d 100644 --- a/models/Document/Editable/Multiselect.php +++ b/models/Document/Editable/Multiselect.php @@ -20,7 +20,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Multiselect extends Model\Document\Editable +class Multiselect extends Model\Document\Editable implements EditmodeDataInterface { /** * Contains the current selected values @@ -64,9 +64,9 @@ public function frontend() } /** - * @return array + * {@inheritdoc} */ - public function getDataEditmode() + public function getDataEditmode() /** : mixed */ { return $this->values; } diff --git a/models/Document/Editable/Pdf.php b/models/Document/Editable/Pdf.php index ff21c32821a..f3201ed1ad1 100644 --- a/models/Document/Editable/Pdf.php +++ b/models/Document/Editable/Pdf.php @@ -22,7 +22,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Pdf extends Model\Document\Editable +class Pdf extends Model\Document\Editable implements EditmodeDataInterface { /** * @internal @@ -60,9 +60,9 @@ public function getDataForResource() } /** - * @return array + * {@inheritdoc} */ - public function getDataEditmode() + public function getDataEditmode() /** : mixed */ { $pages = 0; diff --git a/models/Document/Editable/Relation.php b/models/Document/Editable/Relation.php index fea46de7564..ef1624c98ff 100644 --- a/models/Document/Editable/Relation.php +++ b/models/Document/Editable/Relation.php @@ -24,7 +24,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Relation extends Model\Document\Editable +class Relation extends Model\Document\Editable implements IdRewriterInterface, EditmodeDataInterface, LazyLoadingInterface { /** * ID of the source object @@ -84,11 +84,9 @@ public function getData() } /** - * Converts the data so it's suitable for the editmode - * - * @return array|null + * {@inheritdoc} */ - public function getDataEditmode() + public function getDataEditmode() /** : mixed */ { $this->setElement(); @@ -279,9 +277,9 @@ public function __sleep() } /** - * this method is called by Document\Service::loadAllDocumentFields() to load all lazy loading fields + * {@inheritdoc} */ - public function load() + public function load() /** : void */ { if (!$this->element) { $this->setElement(); @@ -329,19 +327,9 @@ public function getSubtype() } /** - * Rewrites id from source to target, $idMapping contains - * array( - * "document" => array( - * SOURCE_ID => TARGET_ID, - * SOURCE_ID => TARGET_ID - * ), - * "object" => array(...), - * "asset" => array(...) - * ) - * - * @param array $idMapping + * { @inheritdoc } */ - public function rewriteIds($idMapping) + public function rewriteIds($idMapping) /** : void */ { if (array_key_exists($this->type, $idMapping) && array_key_exists($this->getId(), $idMapping[$this->type])) { $this->id = $idMapping[$this->type][$this->getId()]; diff --git a/models/Document/Editable/Relations.php b/models/Document/Editable/Relations.php index 413e549a83d..fa6c3e57be0 100644 --- a/models/Document/Editable/Relations.php +++ b/models/Document/Editable/Relations.php @@ -24,7 +24,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Relations extends Model\Document\Editable implements \Iterator +class Relations extends Model\Document\Editable implements \Iterator, IdRewriterInterface, EditmodeDataInterface, LazyLoadingInterface { /** * @internal @@ -93,11 +93,9 @@ public function getDataForResource() } /** - * Converts the data so it's suitable for the editmode - * - * @return array + * {@inheritdoc} */ - public function getDataEditmode() + public function getDataEditmode() /** : mixed */ { $this->setElements(); $return = []; @@ -219,19 +217,9 @@ public function resolveDependencies() } /** - * Rewrites id from source to target, $idMapping contains - * array( - * "document" => array( - * SOURCE_ID => TARGET_ID, - * SOURCE_ID => TARGET_ID - * ), - * "object" => array(...), - * "asset" => array(...) - * ) - * - * @param array $idMapping + * { @inheritdoc } */ - public function rewriteIds($idMapping) + public function rewriteIds($idMapping) /** : void */ { // reset existing elements store $this->elements = []; @@ -265,7 +253,10 @@ public function __sleep() return $finalVars; } - public function load() + /** + * {@inheritdoc} + */ + public function load() /** : void */ { $this->setElements(); } diff --git a/models/Document/Editable/Renderlet.php b/models/Document/Editable/Renderlet.php index 75d963d1ece..ae8212529ec 100644 --- a/models/Document/Editable/Renderlet.php +++ b/models/Document/Editable/Renderlet.php @@ -27,7 +27,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Renderlet extends Model\Document\Editable +class Renderlet extends Model\Document\Editable implements IdRewriterInterface, EditmodeDataInterface, LazyLoadingInterface { /** * Contains the ID of the linked object @@ -86,11 +86,9 @@ public function getData() } /** - * Converts the data so it's suitable for the editmode - * - * @return mixed + * {@inheritdoc} */ - public function getDataEditmode() + public function getDataEditmode() /** : mixed */ { if ($this->o instanceof Element\ElementInterface) { return [ @@ -308,9 +306,9 @@ public function __sleep() } /** - * this method is called by Document\Service::loadAllDocumentFields() to load all lazy loading fields + * {@inheritdoc} */ - public function load() + public function load() /** : void */ { if (!$this->o) { $this->setElement(); @@ -378,19 +376,9 @@ public function getSubtype() } /** - * Rewrites id from source to target, $idMapping contains - * array( - * "document" => array( - * SOURCE_ID => TARGET_ID, - * SOURCE_ID => TARGET_ID - * ), - * "object" => array(...), - * "asset" => array(...) - * ) - * - * @param array $idMapping + * { @inheritdoc } */ - public function rewriteIds($idMapping) + public function rewriteIds($idMapping) /** : void */ { $type = (string) $this->type; if ($type && array_key_exists($this->type, $idMapping) && array_key_exists($this->getId(), $idMapping[$this->type])) { diff --git a/models/Document/Editable/Snippet.php b/models/Document/Editable/Snippet.php index c1a1483065b..d3122950b8d 100644 --- a/models/Document/Editable/Snippet.php +++ b/models/Document/Editable/Snippet.php @@ -26,7 +26,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Snippet extends Model\Document\Editable +class Snippet extends Model\Document\Editable implements IdRewriterInterface, EditmodeDataInterface, LazyLoadingInterface { /** * Contains the ID of the linked snippet @@ -79,11 +79,9 @@ public function getId() } /** - * Converts the data so it's suitable for the editmode - * - * @return mixed + * {@inheritdoc} */ - public function getDataEditmode() + public function getDataEditmode() /** : mixed */ { if ($this->snippet instanceof Document\Snippet) { return [ @@ -239,9 +237,9 @@ public function __sleep() } /** - * this method is called by Document\Service::loadAllDocumentFields() to load all lazy loading fields + * {@inheritdoc} */ - public function load() + public function load() /** : void */ { if (!$this->snippet && $this->id) { $this->snippet = Document\Snippet::getById($this->id); @@ -249,19 +247,9 @@ public function load() } /** - * Rewrites id from source to target, $idMapping contains - * array( - * "document" => array( - * SOURCE_ID => TARGET_ID, - * SOURCE_ID => TARGET_ID - * ), - * "object" => array(...), - * "asset" => array(...) - * ) - * - * @param array $idMapping + * { @inheritdoc } */ - public function rewriteIds($idMapping) + public function rewriteIds($idMapping) /** : void */ { $id = $this->getId(); if (array_key_exists('document', $idMapping) && array_key_exists($id, $idMapping['document'])) { diff --git a/models/Document/Editable/Textarea.php b/models/Document/Editable/Textarea.php index 8b28c7a8323..8130dfe2b35 100644 --- a/models/Document/Editable/Textarea.php +++ b/models/Document/Editable/Textarea.php @@ -20,7 +20,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Textarea extends Model\Document\Editable +class Textarea extends Model\Document\Editable implements EditmodeDataInterface { /** * Contains the text @@ -74,7 +74,10 @@ public function frontend() return $text; } - public function getDataEditmode() + /** + * {@inheritdoc} + */ + public function getDataEditmode() /** : mixed */ { return htmlentities($this->text); } diff --git a/models/Document/Editable/Video.php b/models/Document/Editable/Video.php index fa05e8884a0..f78da2b4559 100644 --- a/models/Document/Editable/Video.php +++ b/models/Document/Editable/Video.php @@ -24,7 +24,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Video extends Model\Document\Editable +class Video extends Model\Document\Editable implements IdRewriterInterface { /** * contains depending on the type of the video the unique identifier eg. "http://www.youtube.com", "789", ... @@ -1009,19 +1009,9 @@ public function getId() } /** - * Rewrites id from source to target, $idMapping contains - * array( - * "document" => array( - * SOURCE_ID => TARGET_ID, - * SOURCE_ID => TARGET_ID - * ), - * "object" => array(...), - * "asset" => array(...) - * ) - * - * @param array $idMapping + * { @inheritdoc } */ - public function rewriteIds($idMapping) + public function rewriteIds($idMapping) /** : void */ { if ($this->type == 'asset' && array_key_exists('asset', $idMapping) && array_key_exists($this->getId(), $idMapping['asset'])) { $this->setId($idMapping['asset'][$this->getId()]); diff --git a/models/Document/Editable/Wysiwyg.php b/models/Document/Editable/Wysiwyg.php index 1d318ac2d38..a0173a8ded1 100644 --- a/models/Document/Editable/Wysiwyg.php +++ b/models/Document/Editable/Wysiwyg.php @@ -22,7 +22,7 @@ /** * @method \Pimcore\Model\Document\Editable\Dao getDao() */ -class Wysiwyg extends Model\Document\Editable +class Wysiwyg extends Model\Document\Editable implements IdRewriterInterface, EditmodeDataInterface { /** * Contains the text @@ -58,11 +58,9 @@ public function getText() } /** - * Converts the data so it's suitable for the editmode - * - * @return mixed + * {@inheritdoc} */ - public function getDataEditmode() + public function getDataEditmode() /** : mixed */ { $document = $this->getDocument(); @@ -130,22 +128,9 @@ public function getCacheTags(Model\Document\PageSnippet $ownerDocument, array $t } /** - * Rewrites id from source to target, $idMapping contains - * array( - * "document" => array( - * SOURCE_ID => TARGET_ID, - * SOURCE_ID => TARGET_ID - * ), - * "object" => array(...), - * "asset" => array(...) - * ) - * - * @param array $idMapping - * - * @return void - * + * { @inheritdoc } */ - public function rewriteIds($idMapping) + public function rewriteIds($idMapping) /** : void */ { $html = new DomCrawler($this->text); diff --git a/models/Document/Service.php b/models/Document/Service.php index 1cbd56a98c8..2fba7ed9f81 100644 --- a/models/Document/Service.php +++ b/models/Document/Service.php @@ -22,6 +22,8 @@ use Pimcore\File; use Pimcore\Model; use Pimcore\Model\Document; +use Pimcore\Model\Document\Editable\IdRewriterInterface; +use Pimcore\Model\Document\Editable\LazyLoadingInterface; use Pimcore\Model\Element; use Pimcore\Tool; use Pimcore\Tool\Serialize; @@ -329,7 +331,13 @@ public static function loadAllDocumentFields($doc) if ($doc instanceof Document\PageSnippet) { foreach ($doc->getEditables() as $name => $data) { - if (method_exists($data, 'load')) { + //TODO Pimcore 11: remove method_exists BC layer + if ($data instanceof LazyLoadingInterface || method_exists($data, 'load')) { + if (!$data instanceof LazyLoadingInterface) { + trigger_deprecation('pimcore/pimcore', '10.3', + sprintf('Usage of method_exists is deprecated since version 10.3 and will be removed in Pimcore 11.' . + 'Implement the %s interface instead.', LazyLoadingInterface::class)); + } $data->load(); } } @@ -405,7 +413,13 @@ public static function rewriteIds($document, $rewriteConfig, $params = []) if ($contentMaster instanceof Document\PageSnippet) { $contentMasterEditables = $contentMaster->getEditables(); foreach ($contentMasterEditables as $contentMasterEditable) { - if (method_exists($contentMasterEditable, 'rewriteIds')) { + //TODO Pimcore 11: remove method_exists BC layer + if ($contentMasterEditable instanceof IdRewriterInterface || method_exists($contentMasterEditable, 'rewriteIds')) { + if (!$contentMasterEditable instanceof IdRewriterInterface) { + trigger_deprecation('pimcore/pimcore', '10.3', + sprintf('Usage of method_exists is deprecated since version 10.3 and will be removed in Pimcore 11.' . + 'Implement the %s interface instead.', IdRewriterInterface::class)); + } $editable = clone $contentMasterEditable; $editable->rewriteIds($rewriteConfig); @@ -422,7 +436,13 @@ public static function rewriteIds($document, $rewriteConfig, $params = []) } else { $editables = $document->getEditables(); foreach ($editables as &$editable) { - if (method_exists($editable, 'rewriteIds')) { + //TODO Pimcore 11: remove method_exists BC layer + if ($editable instanceof IdRewriterInterface || method_exists($editable, 'rewriteIds')) { + if (!$editable instanceof IdRewriterInterface) { + trigger_deprecation('pimcore/pimcore', '10.3', + sprintf('Usage of method_exists is deprecated since version 10.3 and will be removed in Pimcore 11.' . + 'Implement the %s interface instead.', IdRewriterInterface::class)); + } $editable->rewriteIds($rewriteConfig); } }