vendor/pimcore/pimcore/models/DataObject/Fieldcollection.php line 306

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Model\DataObject;
  15. use Pimcore\Model;
  16. use Pimcore\Model\DataObject;
  17. use Pimcore\Model\Element\DirtyIndicatorInterface;
  18. /**
  19.  * @template TItem of Model\DataObject\Fieldcollection\Data\AbstractData
  20.  *
  21.  * @method array delete(Concrete $object, $saveMode = false)
  22.  * @method Fieldcollection\Dao getDao()
  23.  * @method array load(Concrete $object)
  24.  */
  25. class Fieldcollection extends Model\AbstractModel implements \IteratorDirtyIndicatorInterfaceObjectAwareFieldInterface
  26. {
  27.     use Model\Element\Traits\DirtyIndicatorTrait;
  28.     /**
  29.      * @internal
  30.      *
  31.      * @var TItem[]
  32.      */
  33.     protected $items = [];
  34.     /**
  35.      * @internal
  36.      *
  37.      * @var string
  38.      */
  39.     protected $fieldname;
  40.     /**
  41.      * @param TItem[] $items
  42.      * @param string|null $fieldname
  43.      */
  44.     public function __construct($items = [], $fieldname null)
  45.     {
  46.         if (!empty($items)) {
  47.             $this->setItems($items);
  48.         }
  49.         if ($fieldname) {
  50.             $this->setFieldname($fieldname);
  51.         }
  52.         $this->markFieldDirty('_self'true);
  53.     }
  54.     /**
  55.      * @return TItem[]
  56.      */
  57.     public function getItems()
  58.     {
  59.         return $this->items;
  60.     }
  61.     /**
  62.      * @param TItem[] $items
  63.      *
  64.      * @return $this
  65.      */
  66.     public function setItems($items)
  67.     {
  68.         $this->items $items;
  69.         $this->markFieldDirty('_self'true);
  70.         return $this;
  71.     }
  72.     /**
  73.      * @return string
  74.      */
  75.     public function getFieldname()
  76.     {
  77.         return $this->fieldname;
  78.     }
  79.     /**
  80.      * @param string $fieldname
  81.      *
  82.      * @return $this
  83.      */
  84.     public function setFieldname($fieldname)
  85.     {
  86.         $this->fieldname $fieldname;
  87.         return $this;
  88.     }
  89.     /**
  90.      * @internal
  91.      *
  92.      * @return Fieldcollection\Definition[]
  93.      */
  94.     public function getItemDefinitions()
  95.     {
  96.         $definitions = [];
  97.         foreach ($this->getItems() as $item) {
  98.             $definitions[$item->getType()] = $item->getDefinition();
  99.         }
  100.         return $definitions;
  101.     }
  102.     /**
  103.      * @param Concrete $object
  104.      * @param array $params
  105.      *
  106.      * @throws \Exception
  107.      */
  108.     public function save($object$params = [])
  109.     {
  110.         $saveRelationalData $this->getDao()->save($object$params);
  111.         /** @var Model\DataObject\ClassDefinition\Data\Fieldcollections $fieldDef */
  112.         $fieldDef $object->getClass()->getFieldDefinition($this->getFieldname());
  113.         $allowedTypes $fieldDef->getAllowedTypes();
  114.         $collectionItems $this->getItems();
  115.         if (is_array($collectionItems)) {
  116.             $index 0;
  117.             foreach ($collectionItems as $collection) {
  118.                 if ($collection instanceof Fieldcollection\Data\AbstractData) {
  119.                     if (in_array($collection->getType(), $allowedTypes)) {
  120.                         $collection->setFieldname($this->getFieldname());
  121.                         $collection->setIndex($index++);
  122.                         $params['owner'] = $collection;
  123.                         // set the current object again, this is necessary because the related object in $this->object can change (eg. clone & copy & paste, etc.)
  124.                         $collection->setObject($object);
  125.                         $collection->getDao()->save($object$params$saveRelationalData);
  126.                     } else {
  127.                         throw new \Exception('Fieldcollection of type ' $collection->getType() . ' is not allowed in field: ' $this->getFieldname());
  128.                     }
  129.                 }
  130.             }
  131.         }
  132.     }
  133.     /**
  134.      * @return bool
  135.      */
  136.     public function isEmpty()
  137.     {
  138.         return count($this->getItems()) < 1;
  139.     }
  140.     /**
  141.      * @param TItem $item
  142.      */
  143.     public function add($item)
  144.     {
  145.         $this->items[] = $item;
  146.         $this->markFieldDirty('_self'true);
  147.     }
  148.     /**
  149.      * @param int $index
  150.      */
  151.     public function remove($index)
  152.     {
  153.         if (isset($this->items[$index])) {
  154.             array_splice($this->items$index1);
  155.             $this->markFieldDirty('_self'true);
  156.         }
  157.     }
  158.     /**
  159.      * @param int $index
  160.      *
  161.      * @return Fieldcollection\Data\AbstractData|null
  162.      */
  163.     public function get($index)
  164.     {
  165.         return $this->items[$index] ?? null;
  166.     }
  167.     /**
  168.      * @param int|null $index
  169.      *
  170.      * @return Fieldcollection\Data\AbstractData|null
  171.      */
  172.     private function getByOriginalIndex($index)
  173.     {
  174.         if ($index === null) {
  175.             return null;
  176.         }
  177.         if (is_array($this->items)) {
  178.             foreach ($this->items as $item) {
  179.                 if ($item->getIndex() === $index) {
  180.                     return $item;
  181.                 }
  182.             }
  183.         }
  184.         return null;
  185.     }
  186.     /**
  187.      * @return int
  188.      */
  189.     public function getCount()
  190.     {
  191.         return count($this->getItems());
  192.     }
  193.     /**
  194.      * Methods for Iterator
  195.      */
  196.     /**
  197.      * @return void
  198.      */
  199.     #[\ReturnTypeWillChange]
  200.     public function rewind()// : void
  201.     {
  202.         reset($this->items);
  203.     }
  204.     /**
  205.      * @return TItem|false
  206.      */
  207.     #[\ReturnTypeWillChange]
  208.     public function current()// : Model\DataObject\Fieldcollection\Data\AbstractData|false
  209.     {
  210.         return current($this->items);
  211.     }
  212.     /**
  213.      * @return int|null
  214.      */
  215.     #[\ReturnTypeWillChange]
  216.     public function key()// : int|null
  217.     {
  218.         return key($this->items);
  219.     }
  220.     /**
  221.      * @return void
  222.      */
  223.     #[\ReturnTypeWillChange]
  224.     public function next()// : void
  225.     {
  226.         next($this->items);
  227.     }
  228.     /**
  229.      * @return bool
  230.      */
  231.     #[\ReturnTypeWillChange]
  232.     public function valid()// : bool
  233.     {
  234.         return $this->current() !== false;
  235.     }
  236.     /**
  237.      * @param Concrete $object
  238.      * @param string $type
  239.      * @param string $fcField
  240.      * @param int $index
  241.      * @param string $field
  242.      *
  243.      * @throws \Exception
  244.      *
  245.      * @internal
  246.      */
  247.     public function loadLazyField(Concrete $object$type$fcField$index$field)
  248.     {
  249.         // lazy loading existing can be data if the item already had an index
  250.         $item $this->getByOriginalIndex($index);
  251.         if ($item && !$item->isLazyKeyLoaded($field)) {
  252.             if ($type == $item->getType()) {
  253.                 $fcDef Model\DataObject\Fieldcollection\Definition::getByKey($type);
  254.                 /** @var Model\DataObject\ClassDefinition\Data\CustomResourcePersistingInterface $fieldDef */
  255.                 $fieldDef $fcDef->getFieldDefinition($field);
  256.                 $params = [
  257.                     'context' => [
  258.                         'object' => $object,
  259.                         'containerType' => 'fieldcollection',
  260.                         'containerKey' => $type,
  261.                         'fieldname' => $fcField,
  262.                         'index' => $index,
  263.                     ], ];
  264.                 $isDirtyDetectionDisabled DataObject::isDirtyDetectionDisabled();
  265.                 DataObject::disableDirtyDetection();
  266.                 $data $fieldDef->load($item$params);
  267.                 DataObject::setDisableDirtyDetection($isDirtyDetectionDisabled);
  268.                 $item->setObjectVar($field$data);
  269.             }
  270.             $item->markLazyKeyAsLoaded($field);
  271.         }
  272.     }
  273.     /**
  274.      * @return Concrete|null
  275.      */
  276.     protected function getObject(): ?Concrete
  277.     {
  278.         $this->rewind();
  279.         $item $this->current();
  280.         if ($item instanceof Model\DataObject\Fieldcollection\Data\AbstractData) {
  281.             return $item->getObject();
  282.         }
  283.         return null;
  284.     }
  285.     /**
  286.      * @param Concrete|null $object
  287.      *
  288.      * @return $this
  289.      */
  290.     public function setObject(?Concrete $object)
  291.     {
  292.         // update all items with the new $object
  293.         if (is_array($this->getItems())) {
  294.             foreach ($this->getItems() as $item) {
  295.                 if ($item instanceof Model\DataObject\Fieldcollection\Data\AbstractData) {
  296.                     $item->setObject($object);
  297.                 }
  298.             }
  299.         }
  300.         return $this;
  301.     }
  302.     /**
  303.      * @internal
  304.      */
  305.     public function loadLazyData()
  306.     {
  307.         $items $this->getItems();
  308.         if (is_array($items)) {
  309.             /** @var Model\DataObject\Fieldcollection\Data\AbstractData $item */
  310.             foreach ($items as $item) {
  311.                 $fcType $item->getType();
  312.                 $fieldcolDef Model\DataObject\Fieldcollection\Definition::getByKey($fcType);
  313.                 $fds $fieldcolDef->getFieldDefinitions();
  314.                 foreach ($fds as $fd) {
  315.                     $fieldGetter 'get' ucfirst($fd->getName());
  316.                     $fieldValue $item->$fieldGetter();
  317.                     if ($fieldValue instanceof Localizedfield) {
  318.                         $fieldValue->loadLazyData();
  319.                     }
  320.                 }
  321.             }
  322.         }
  323.     }
  324. }