diff --git a/README.md b/README.md index f07b750..cbe294a 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,27 @@ to stdout, a file or an pimcore asset. If enabled, exports can be made available via a REST API, too. +Table of contents +================= + + + * [Basilicom Xml Tool bundle for Pimcore](#basilicom-xml-tool-bundle-for-pimcore) + * [License](#license) + * [Requirements](#requirements) + * [Installation](#installation) + * [Configuration](#configuration) + * [Console Usage](#console-usage) + * [Usage: REST API](#usage-rest-api) + * [Limitations](#limitations) + + ## License GPLv3 - see: LICENSE ## Requirements +* PHP >= 7.1 * Pimcore >= 5.0.0 * XSL PHP extension for --xslt option support @@ -38,11 +53,11 @@ the Object tree, example for path ```/foo```: Example output: -Note: The Object tree ```/``` contains in the example a single Object of +Note: The Object tree ```/foo``` contains in the example a single Object of the Object Class ```Bar``` with a single Input property of ```name```. ``` -Exporting tree of Objects starting at / +Exporting tree of Objects starting at /foo <:children> @@ -101,8 +116,8 @@ basilicom_xml_tool: endpoints: test1: token: secrettoken0815 - root: Products - path: /export/products + root: Products # Root name of the exported XML file + path: /export/products # Path to the exporting objects xslt: ../sample.xsl include_variants: true omit_relation_object_fields: true @@ -126,8 +141,11 @@ Only a few field types are supported for now: * date * datetime * ManyToManyObjectRelation +* color +* rgbaColor +* localizedFields To extend the supported types, implement a -```getForType*``` method in ```ExportCommand.php```. +```getForType*``` method in ```Service/Xml.php```. diff --git a/Service/Xml.php b/Service/Xml.php index 4fd68cc..9a10b3a 100644 --- a/Service/Xml.php +++ b/Service/Xml.php @@ -2,8 +2,11 @@ namespace Basilicom\XmlToolBundle\Service; +use DOMDocument; +use DOMException; use Pimcore\Model\DataObject; use Spatie\ArrayToXml\ArrayToXml; +use XSLTProcessor; class Xml { @@ -35,6 +38,8 @@ public function isIncludeVariants(): bool /** * @param bool $includeVariants + * + * @return void */ public function setIncludeVariants(bool $includeVariants): void { @@ -51,16 +56,24 @@ public function isOmitRelationObjectFields(): bool /** * @param bool $omitRelationObjectFields + * + * @return void */ public function setOmitRelationObjectFields(bool $omitRelationObjectFields): void { $this->omitRelationObjectFields = $omitRelationObjectFields; } - + /** + * @param $object + * @param $root + * + * @return DOMDocument|false + * + * @throws DOMException + */ public function exportTree($object, $root) { - $treeData = $this->exportObject($object); $treeData['_attributes']['xmlns:pc'] = 'https://basilicom.de/pimcore'; @@ -69,10 +82,10 @@ public function exportTree($object, $root) $xmlDom = $arrayToXml->toDom(); if ($this->xslt) { - $xslDom = new \DOMDocument; + $xslDom = new DOMDocument; $xslDom->load($this->xslt); - $proc = new \XSLTProcessor; + $proc = new XSLTProcessor; $proc->importStyleSheet($xslDom); $xmlDom = $proc->transformToDoc($xmlDom); @@ -84,11 +97,13 @@ public function exportTree($object, $root) /** * @param DataObject $object * @param bool $useRecursion + * @param bool $addFields + * * @return array * * @todo Check for a specific "export" on a class in order to allow overriding the "default" way */ - private function exportObject(DataObject $object, $useRecursion=true, $addFields=true) + private function exportObject(DataObject $object, $useRecursion=true, $addFields=true): array { $objectData = []; @@ -98,18 +113,14 @@ private function exportObject(DataObject $object, $useRecursion=true, $addFields /** @var DataObject\ClassDefinition $cl */ $cl = $object->getClass(); - $className = $cl->getName(); - - if ($addFields) { $fds = $cl->getFieldDefinitions(); $this->processFieldDefinitions($fds, $object, $objectData); } - } $childDataList = []; @@ -152,17 +163,22 @@ private function exportObject(DataObject $object, $useRecursion=true, $addFields 'type' => $object->getType(), 'key' => $object->getKey(), 'class' => $className, - 'is-variant-leaf' => (($object->getType()=='variant')&&(count($variantDataList)==0)?'true':'false'), - 'is-object-leaf' => (($object->getType()=='object')&&(count($childDataList)==0)?'true':'false'), + 'is-variant-leaf' => (($object->getType()==='variant')&&(count($variantDataList)===0)?'true':'false'), + 'is-object-leaf' => (($object->getType()==='object')&&(count($childDataList)===0)?'true':'false'), ]; return $objectData; } - - private function processFieldDefinitions($fds, $object, &$objectData) + /** + * @param $fds + * @param $object + * @param $objectData + * + * @return void + */ + private function processFieldDefinitions($fds, $object, &$objectData): void { - foreach ($fds as $fd) { $fieldName = $fd->getName(); $fieldType = $fd->getFieldtype(); @@ -173,7 +189,7 @@ private function processFieldDefinitions($fds, $object, &$objectData) $objectData[$fieldName] = $this->$getterFunction($object, $fieldName); - } elseif ($fieldType == 'localizedfields') { + } elseif ($fieldType === 'localizedfields') { $localizedFields = $fd->getFieldDefinitions(); foreach (\Pimcore\Tool::getValidLanguages() as $language) { @@ -188,52 +204,66 @@ private function processFieldDefinitions($fds, $object, &$objectData) //echo "Unsupported field type: " . $fieldType . ' for '.$fieldName."\n"; } } - } // add a getForType* method for every Pimcore Datatype: - private function getForTypeManyToManyObjectRelation($object, $fieldname) + /** + * @param $object + * @param $fieldname + * + * @return array + */ + private function getForTypeManyToManyObjectRelation($object, $fieldname): array { $relations = []; + $getterFunction = 'get'.ucfirst($fieldname); - foreach($object->$getterFunction() as $relationObject) { - $exportObject = $this->exportObject($relationObject, false, !$this->omitRelationObjectFields); + /** @var array|null $relationObjects */ + $relationObjects = $object->$getterFunction(); + + if (is_iterable($relationObjects)) { + foreach($relationObjects as $relationObject) { + $exportObject = $this->exportObject($relationObject, false, !$this->omitRelationObjectFields); - if (!array_key_exists($exportObject['_attributes']['class'], $relations)) { - $relations[$exportObject['_attributes']['class']] = []; + if (!array_key_exists($exportObject['_attributes']['class'], $relations)) { + $relations[$exportObject['_attributes']['class']] = []; + } + $relations[$exportObject['_attributes']['class']][] = $exportObject; } - $relations[$exportObject['_attributes']['class']][] = $exportObject; } return $relations; } - private function getForTypeAdvancedManyToManyObjectRelation($object, $fieldname) + /** + * @param $object + * @param $fieldname + * + * @return array + */ + private function getForTypeAdvancedManyToManyObjectRelation($object, $fieldname): array { - $relations = []; $meta = []; $getterFunction = 'get'.ucfirst($fieldname); - - /** @var Data\ObjectMetadata $relationMetaObject */ - foreach($object->$getterFunction() as $relationMetaObject) { - - $relationObject = $relationMetaObject->getObject(); - - $exportObject = $this->exportObject($relationObject, false, !$this->omitRelationObjectFields); - - $data = $relationMetaObject->getData(); - - - $meta['pc:relation'][] = [ - $exportObject['_attributes']['class'] => $exportObject, - 'pc:meta'=>$data - ]; + /** @var Data\ObjectMetadata[]|null $relationMetaObjects */ + $relationMetaObjects = $object->$getterFunction(); + + if (is_iterable($relationMetaObjects)) { + foreach ($object->$getterFunction() as $relationMetaObject) { + $relationObject = $relationMetaObject->getObject(); + $exportObject = $this->exportObject($relationObject, false, !$this->omitRelationObjectFields); + $data = $relationMetaObject->getData(); + + $meta['pc:relation'][] = [ + $exportObject['_attributes']['class'] => $exportObject, + 'pc:meta' => $data + ]; + } } - return $meta; } @@ -241,9 +271,10 @@ private function getForTypeAdvancedManyToManyObjectRelation($object, $fieldname) * Alias - old field type! * @param $object * @param $fieldname + * * @return array */ - private function getForTypeObjectsMetadata($object, $fieldname) + private function getForTypeObjectsMetadata($object, $fieldname): array { return $this->getForTypeAdvancedManyToManyObjectRelation($object, $fieldname); } @@ -252,21 +283,28 @@ private function getForTypeObjectsMetadata($object, $fieldname) * Alias - old field type! * @param $object * @param $fieldname + * * @return array */ - private function getForTypeObjects($object, $fieldname) + private function getForTypeObjects($object, $fieldname): array { return $this->getForTypeManyToManyObjectRelation($object, $fieldname); } - private function getForTypeInput($object, $fieldname) + /** + * @param $object + * @param $fieldname + * + * @return array|null + */ + private function getForTypeInput($object, $fieldname): ?array { $getterFunction = 'get'.ucfirst($fieldname); - if ($this->language == null) { + if ($this->language === null) { $data = $object->$getterFunction(); - if ($data == null) { + if ($data === null) { return $data; } else { return ['_cdata' => $data]; @@ -277,34 +315,69 @@ private function getForTypeInput($object, $fieldname) } } - private function getForTypeImage($object, $fieldname) + /** + * @param $object + * @param $fieldname + * + * @return array|null + */ + private function getForTypeImage($object, $fieldname): ?array { return $this->getForTypeInput($object, $fieldname); } - private function getForTypeSelect($object, $fieldname) + /** + * @param $object + * @param $fieldname + * + * @return array|null + */ + private function getForTypeSelect($object, $fieldname): ?array { return $this->getForTypeInput($object, $fieldname); } + /** + * @param $object + * @param $fieldname + * + * @return mixed + */ private function getForTypeNumeric($object, $fieldname) { $getterFunction = 'get'.ucfirst($fieldname); - $data = $object->$getterFunction(); - return $data; + return $object->$getterFunction(); } - private function getForTypeTextarea($object, $fieldname) + /** + * @param $object + * @param $fieldname + * + * @return array|null + */ + private function getForTypeTextarea($object, $fieldname): ?array { return $this->getForTypeInput($object, $fieldname); } - private function getForTypeWysiwyg($object, $fieldname) + /** + * @param $object + * @param $fieldname + * + * @return array|null + */ + private function getForTypeWysiwyg($object, $fieldname): ?array { return $this->getForTypeInput($object, $fieldname); } - private function getForTypeRgbaColor($object, $fieldname) + /** + * @param $object + * @param $fieldname + * + * @return array|null + */ + private function getForTypeRgbaColor($object, $fieldname): ?array { return $this->getForTypeInput($object, $fieldname); } @@ -313,23 +386,34 @@ private function getForTypeRgbaColor($object, $fieldname) * Alias, old field type! * @param $object * @param $fieldname + * * @return array|null */ - private function getForTypeColor($object, $fieldname) + private function getForTypeColor($object, $fieldname): ?array { return $this->getForTypeRgbaColor($object, $fieldname); } - private function getForTypeDate($object, $fieldname) + /** + * @param $object + * @param $fieldname + * + * @return string + */ + private function getForTypeDate($object, $fieldname): string { $getterFunction = 'get'.ucfirst($fieldname); - $data = (string)$object->$getterFunction(); - return $data; + return (string)$object->$getterFunction(); } - private function getForTypeDatetime($object, $fieldname) + /** + * @param $object + * @param $fieldname + * + * @return string + */ + private function getForTypeDatetime($object, $fieldname): string { return $this->getForTypeDate($object, $fieldname); } - }