Skip to content

Commit

Permalink
Merge pull request #31 from YouweGit/bugfix/bridgeDataObjectsNotCopied
Browse files Browse the repository at this point in the history
[BUGFIX] Bridge data objects not copied
  • Loading branch information
jorisros committed Jun 27, 2019
2 parents 4f301c5 + e7a0fba commit fef74c9
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 0 deletions.
142 changes: 142 additions & 0 deletions EventListener/CopyEventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?php

namespace ObjectBridgeBundle\EventListener;

use ObjectBridgeBundle\Model\DataObject\ClassDefinition\Data\ObjectBridge;
use Pimcore\Event\Model\DataObjectEvent;
use Pimcore\Model\DataObject;
use Pimcore\Model\Element;
use Pimcore\Model\Version;

/**
* Copy event listener
*/
class CopyEventListener
{
/**
* @var \Pimcore\Model\User
*/
protected $user;

/**
* @var DataObject\Service
*/
protected $dataObjectService;

public function __construct()
{
$this->user = \Pimcore\Tool\Admin::getCurrentUser();
$this->dataObjectService = new DataObject\Service($this->user);
}

/**
* @param DataObjectEvent $dataObjectEvent
* @return void
*/
public function postCopy(DataObjectEvent $dataObjectEvent): void
{
$newDataObject = $dataObjectEvent->getObject();
if (!$newDataObject instanceof DataObject\Concrete) {
return;
}

foreach ($newDataObject->getClass()->getFieldDefinitions(['suppressEnrichment' => true]) as $fieldDefinition) {
if (!$fieldDefinition instanceof ObjectBridge) {
continue;
}

$this->copyObjectBridgeDataObjects($newDataObject, $fieldDefinition);
}
}

/**
* @param DataObject\Concrete $dataObject
* @param ObjectBridge $objectBridge
* @return void
* @throws \Exception
*/
protected function copyObjectBridgeDataObjects(DataObject\Concrete $dataObject, ObjectBridge $objectBridge): void
{
$sourceDataObjectGetter = 'get' . ucfirst($objectBridge->getBridgeField());
$bridgeDataObjectsGetter = 'get' . ucfirst($objectBridge->getName());
$bridgeDataObjectsSetter = 'set' . ucfirst($objectBridge->getName());
unset($objectBridge);

if (!method_exists($dataObject, $bridgeDataObjectsGetter) || !method_exists($dataObject, $bridgeDataObjectsGetter)) {
return;
}

// Retrieve current bridge data objects
$referencedBridgeDataObjects = $dataObject->$bridgeDataObjectsGetter();

// Update bridge data objects
$dataObject->$bridgeDataObjectsSetter(
$this->copyBridgeDataObjects(
$dataObject,
$sourceDataObjectGetter,
...$referencedBridgeDataObjects
)
);
$dataObject->save();
}

/**
* @param string $sourceDataObjectGetter
* @param DataObject\Concrete ...$bridgeDataObjects
* @return DataObject\Concrete[]
*/
protected function copyBridgeDataObjects(
DataObject\Concrete $dataObject,
string $sourceDataObjectGetter,
DataObject\Concrete ...$bridgeDataObjects
): array {
$copiedBridgeDataObjects = [];
$i = 0;
foreach ($bridgeDataObjects as $bridgeDataObject) {
if (!$bridgeDataObject instanceof DataObject\Concrete) {
continue;
}

$sourceDataObject = $bridgeDataObject->$sourceDataObjectGetter();
if (!$sourceDataObject instanceof DataObject\Concrete) {
continue;
}

// Set key on original object to assure the copied object does not cause errors because of duplicate key
$bridgeDataObject->setKey($dataObject->getId() . '_' . $sourceDataObject->getId());

// Copy bridge data object and add it to the array
$copiedBridgeDataObjects[] = $this->copyAsChild($bridgeDataObject->getParent(), $bridgeDataObject);
}

return $copiedBridgeDataObjects;
}

/**
* Customized copy method without updateChilds, which causes an out of
* memory fatal error when copying a large number of bridge data objects
* @see DataObject\Service::copyAsChild()
*
* @param DataObject\AbstractObject $target Folder to copy data object to
* @param DataObject\Concrete $source Data object to copy
* @return DataObject\Concrete
*
*/
protected function copyAsChild(DataObject\AbstractObject $target, DataObject\Concrete $source): DataObject\Concrete
{
$new = Element\Service::cloneMe($source);
$new->setId(null);

$new->setChildren(null);
$new->setKey(Element\Service::getSaveCopyName('object', $new->getKey(), $target));
$new->setParentId($target->getId());
$new->setUserOwner($this->user->getId());
$new->setUserModification($this->user->getId());
$new->setDao(null);
$new->setLocked(false);
$new->setCreationDate(time());
$new->save();

return $new;
}
}
3 changes: 3 additions & 0 deletions Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ services:
tags:
- { name: kernel.event_listener, event: pimcore.dataobject.preDelete, method: objectPreDelete }

ObjectBridgeBundle\EventListener\CopyEventListener:
tags:
- { name: kernel.event_listener, event: pimcore.dataobject.postCopy, method: postCopy }

0 comments on commit fef74c9

Please sign in to comment.