Skip to content

Instantly share code, notes, and snippets.

Created June 4, 2015 09:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/170da6f16b7c40601939 to your computer and use it in GitHub Desktop.
Save anonymous/170da6f16b7c40601939 to your computer and use it in GitHub Desktop.
<?php
/**
* @author Henning Kvinnesland <henning@keyteq.no>
* @since 02.06.15
*/
namespace Kavli\GenericBundle\Override;
class ContentPackageHandler extends \eZContentObjectPackageHandler
{
const XML_ROOT_TAG = 'content-object-blocks';
// Keep track of ids assigned to the new objects. (old => new)
protected $objectMap = array();
public function createObjectListNode($options)
{
/** @var \DomElement $node */
$node = parent::createObjectListNode($options);
$blocks = $this->getObjectBlocks();
if (!count($blocks)) {
return $node;
}
$dom = $node->ownerDocument;
$packageRoot = $dom->createElement(self::XML_ROOT_TAG);
$dom->appendChild($packageRoot);
$blockRoot = $dom->createElement('blocks');
$packageRoot->appendChild($blockRoot);
foreach ($blocks as $objectId => $blockArray) {
/** @var \eZPageBlock $block */
foreach ($blockArray as $block) {
$blockXml = $block->toXML($dom);
$blockXml->setAttribute('object-id', $objectId);
$blockRoot->appendChild($blockXml);
}
}
$node->appendChild($packageRoot);
return $node;
}
public function install($package, $installType, $parameters, $name, $os, $filename, $subdirectory, $content, &$installParameters, &$installData)
{
$res = parent::install($package, $installType, $parameters, $name, $os, $filename, $subdirectory, $content, $installParameters, $installData);
if ($res) {
$this->installBlocks($content);
}
return $res;
}
protected function installBlocks(\DomElement $node)
{
$rootNode = $node->getElementsByTagName(self::XML_ROOT_TAG)->item(0);
if (!$rootNode) {
return false;
}
/** @var \DomElement $rootNode */
$blockRootNode = $rootNode->getElementsByTagName('blocks')->item(0);
if (!$blockRootNode) {
return false;
}
$blocks = array();
/** @var \DomElement $blockRootNode */
foreach ($blockRootNode->getElementsByTagName('block') as $blockXml) {
/** @var \DomElement $blockXml */
$objectId = $blockXml->getAttribute('object-id');
$blockXml->removeAttribute('object-id');
$block = \eZPageBlock::createFromXML($blockXml);
$blocks[$objectId][$block->id()] = $block;
}
foreach ($blocks as $objectId => $blockArray) {
$newId = $this->objectMap[$objectId];
$newlyCreatedObject = \eZContentObject::fetch($newId);
foreach ($this->getEzPageAttributes($newlyCreatedObject) as $attribute) {
foreach ($this->getZones($attribute) as $zone) {
$this->replaceBlocks($zone, $blocks[$objectId]);
}
// Purge updated data to the database.
$attribute->store();
$ezPageType = new \eZPageType();
$ezPageType->onPublish($attribute, $newlyCreatedObject, $newlyCreatedObject->assignedNodes());
}
}
}
protected function replaceBlocks(\eZPageZone $zone, $source)
{
$newBlocks = array();
for ($i = 0; $i < $zone->getBlockCount(); $i++) {
$block = $zone->getBlock($i);
/** @var \eZPageBlock $importedBlock */
$importedBlock = $source[$block->id()];
$newBlocks[] = $this->cloneBlock($importedBlock);
$zone->removeBlock($i);
}
foreach ($newBlocks as $block) {
$zone->addBlock($block);
}
}
protected function cloneBlock(\eZPageBlock $existingBlock)
{
$block = clone $existingBlock;
for ($i = 0; $i < $block->getItemCount(); $i++) {
$item = $block->getItem($i);
$newId = $this->objectMap[$item->attribute('object_id')];
$itemObject = \eZContentObject::fetch($newId);
$item->setAttribute('object_id', $itemObject->ID);
$item->setAttribute('node_id', $itemObject->MainNodeID());
}
return $block;
}
protected function getObjectBlocks()
{
$blocks = array();
/** @var \eZContentObject $object */
foreach ($this->ObjectArray as $object) {
foreach ($this->getEzPageAttributes($object) as $attribute) {
foreach ($this->getZones($attribute) as $zone) {
for ($i = 0; $i < $zone->getBlockCount(); $i++) {
$blocks[$object->ID][] = $zone->getBlock($i);
}
}
}
}
return $blocks;
}
/**
* @param \eZContentObject $object
* @return \eZContentObjectAttribute[]
*/
protected function getEzPageAttributes(\eZContentObject $object)
{
return array_filter($object->currentVersion()->dataMap(), function(\eZContentObjectAttribute $attribute)
{
return $attribute->DataTypeString == 'ezpage';
});
}
/**
* @param \eZContentObjectAttribute $attribute
* @return \eZPageZone[]
*/
protected function getZones(\eZContentObjectAttribute $attribute)
{
/** @var \eZPage $attributeContents */
$attributeContents = $attribute->content();
$zones = array();
for ($i = 0; $i < $attributeContents->getZoneCount(); $i++) {
$zones[] = $attributeContents->getZone($i);
}
return $zones;
}
/**
* @param \Domelement[] $objectNodes
* @param \Domelement[] $topNodeListNode
* @param array $installParameters
*
* @return bool
*/
public function installContentObjects($objectNodes, $topNodeListNode, &$installParameters)
{
if (isset($installParameters['user_id']))
$userID = $installParameters['user_id'];
else
$userID = \eZUser::currentUserID();
$handlerType = $this->handlerType();
$firstInstalledID = null;
foreach ($objectNodes as $objectNode) {
/** @var \DomElement $realObjectNode */
$realObjectNode = $this->getRealObjectNode($objectNode);
// Cycle until we reach an element where error has occured.
// If action has been choosen, try install this item again, else skip it.
if (isset($installParameters['error']['error_code']) &&
!$this->isErrorElement($realObjectNode->getAttribute('remote_id'), $installParameters)
) {
continue;
}
//we are here, it means we'll try to install some object.
if (!$firstInstalledID) {
$firstInstalledID = $realObjectNode->getAttribute('remote_id');
}
$newObject = \eZContentObject::unserialize($this->Package, $realObjectNode, $installParameters, $userID, $handlerType);
$this->objectMap[$realObjectNode->getAttribute('ezremote:id')] = $newObject->ID;
if (!$newObject) {
return false;
}
if (is_object($newObject)) {
\eZContentObject::clearCache($newObject->attribute('id'));
unset($newObject);
}
unset($realObjectNode);
if (isset($installParameters['error']) && count($installParameters['error'])) {
$installParameters['error'] = array();
}
}
$this->installSuspendedNodeAssignment($installParameters);
$this->installSuspendedObjectRelations($installParameters);
// Call postUnserialize on all installed objects
foreach ($objectNodes as $objectNode) {
if ($objectNode->localName == 'object') {
$remoteID = $objectNode->getAttribute('remote_id');
} else {
$remoteID = substr($objectNode->getAttribute('filename'), 7, 32);
}
// Begin from the object that we started from in the previous cycle
if ($firstInstalledID && $remoteID != $firstInstalledID) {
continue;
} else {
$firstInstalledID = null;
}
$object = \eZContentObject::fetchByRemoteID($remoteID);
if (is_object($object)) {
$object->postUnserialize($this->Package);
\eZContentObject::clearCache($object->attribute('id'));
}
unset($object);
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment