vendor/pimcore/pimcore/models/DataObject/Fieldcollection/Definition.php line 90

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\Fieldcollection;
  15. use Pimcore\DataObject\ClassBuilder\PHPFieldCollectionClassDumperInterface;
  16. use Pimcore\Model;
  17. use Pimcore\Model\DataObject;
  18. use Pimcore\Model\DataObject\ClassDefinition\Data\FieldDefinitionEnrichmentInterface;
  19. /**
  20.  * @method \Pimcore\Model\DataObject\Fieldcollection\Definition\Dao getDao()
  21.  * @method string getTableName(DataObject\ClassDefinition $class)
  22.  * @method void createUpdateTable(DataObject\ClassDefinition $class)
  23.  * @method string getLocalizedTableName(DataObject\ClassDefinition $class)
  24.  */
  25. class Definition extends Model\AbstractModel
  26. {
  27.     use DataObject\Traits\FieldcollectionObjectbrickDefinitionTrait;
  28.     use DataObject\Traits\LocateFileTrait;
  29.     use Model\DataObject\ClassDefinition\Helper\VarExport;
  30.     /**
  31.      * {@inheritdoc}
  32.      */
  33.     protected function doEnrichFieldDefinition($fieldDefinition$context = [])
  34.     {
  35.         //TODO Pimcore 11: remove method_exists BC layer
  36.         if ($fieldDefinition instanceof FieldDefinitionEnrichmentInterface || method_exists($fieldDefinition'enrichFieldDefinition')) {
  37.             if (!$fieldDefinition instanceof FieldDefinitionEnrichmentInterface) {
  38.                 trigger_deprecation('pimcore/pimcore''10.1',
  39.                     sprintf('Usage of method_exists is deprecated since version 10.1 and will be removed in Pimcore 11.' .
  40.                     'Implement the %s interface instead.'FieldDefinitionEnrichmentInterface::class));
  41.             }
  42.             $context['containerType'] = 'fieldcollection';
  43.             $context['containerKey'] = $this->getKey();
  44.             $fieldDefinition $fieldDefinition->enrichFieldDefinition($context);
  45.         }
  46.         return $fieldDefinition;
  47.     }
  48.     /**
  49.      * @internal
  50.      *
  51.      * @param DataObject\ClassDefinition\Layout|DataObject\ClassDefinition\Data $def
  52.      */
  53.     protected function extractDataDefinitions($def)
  54.     {
  55.         if ($def instanceof DataObject\ClassDefinition\Layout) {
  56.             if ($def->hasChildren()) {
  57.                 foreach ($def->getChildren() as $child) {
  58.                     $this->extractDataDefinitions($child);
  59.                 }
  60.             }
  61.         }
  62.         if ($def instanceof DataObject\ClassDefinition\Data) {
  63.             $existing $this->getFieldDefinition($def->getName());
  64.             if ($existing && method_exists($existing'addReferencedField')) {
  65.                 // this is especially for localized fields which get aggregated here into one field definition
  66.                 // in the case that there are more than one localized fields in the class definition
  67.                 // see also pimcore.object.edit.addToDataFields();
  68.                 $existing->addReferencedField($def);
  69.             } else {
  70.                 $this->addFieldDefinition($def->getName(), $def);
  71.             }
  72.         }
  73.     }
  74.     /**
  75.      * @param string $key
  76.      *
  77.      * @throws \Exception
  78.      *
  79.      * @return self|null
  80.      */
  81.     public static function getByKey($key)
  82.     {
  83.         /** @var Definition $fc */
  84.         $fc null;
  85.         $cacheKey 'fieldcollection_' $key;
  86.         try {
  87.             $fc \Pimcore\Cache\Runtime::get($cacheKey);
  88.             if (!$fc) {
  89.                 throw new \Exception('FieldCollection in registry is not valid');
  90.             }
  91.         } catch (\Exception $e) {
  92.             $def = new Definition();
  93.             $def->setKey($key);
  94.             $fieldFile $def->getDefinitionFile();
  95.             if (is_file($fieldFile)) {
  96.                 $fc = include $fieldFile;
  97.                 \Pimcore\Cache\Runtime::set($cacheKey$fc);
  98.             }
  99.         }
  100.         if ($fc) {
  101.             return $fc;
  102.         }
  103.         return null;
  104.     }
  105.     /**
  106.      * @param bool $saveDefinitionFile
  107.      *
  108.      * @throws \Exception
  109.      */
  110.     public function save($saveDefinitionFile true)
  111.     {
  112.         if (!$this->getKey()) {
  113.             throw new \Exception('A field-collection needs a key to be saved!');
  114.         }
  115.         if (!preg_match('/[a-zA-Z]+/'$this->getKey())) {
  116.             throw new \Exception(sprintf('Invalid key for field-collection: %s'$this->getKey()));
  117.         }
  118.         if ($this->getParentClass() && !preg_match('/^[a-zA-Z_\x7f-\xff\\\][a-zA-Z0-9_\x7f-\xff\\\]*$/'$this->getParentClass())) {
  119.             throw new \Exception(sprintf('Invalid parentClass value for class definition: %s',
  120.                 $this->getParentClass()));
  121.         }
  122.         $fieldDefinitions $this->getFieldDefinitions();
  123.         foreach ($fieldDefinitions as $fd) {
  124.             if ($fd->isForbiddenName()) {
  125.                 throw new \Exception(sprintf('Forbidden name used for field definition: %s'$fd->getName()));
  126.             }
  127.             if ($fd instanceof DataObject\ClassDefinition\Data\DataContainerAwareInterface) {
  128.                 $fd->preSave($this);
  129.             }
  130.         }
  131.         $this->generateClassFiles($saveDefinitionFile);
  132.         // update classes
  133.         $classList = new DataObject\ClassDefinition\Listing();
  134.         $classes $classList->load();
  135.         if (is_array($classes)) {
  136.             foreach ($classes as $class) {
  137.                 foreach ($class->getFieldDefinitions() as $fieldDef) {
  138.                     if ($fieldDef instanceof DataObject\ClassDefinition\Data\Fieldcollections) {
  139.                         if (in_array($this->getKey(), $fieldDef->getAllowedTypes())) {
  140.                             $this->getDao()->createUpdateTable($class);
  141.                             break;
  142.                         }
  143.                     }
  144.                 }
  145.             }
  146.         }
  147.     }
  148.     /**
  149.      * @internal
  150.      *
  151.      * @param bool $generateDefinitionFile
  152.      *
  153.      * @throws \Exception
  154.      * @throws DataObject\Exception\DefinitionWriteException
  155.      */
  156.     protected function generateClassFiles($generateDefinitionFile true)
  157.     {
  158.         if ($generateDefinitionFile && !$this->isWritable()) {
  159.             throw new DataObject\Exception\DefinitionWriteException();
  160.         }
  161.         $definitionFile $this->getDefinitionFile();
  162.         if ($generateDefinitionFile) {
  163.             /** @var self $clone */
  164.             $clone DataObject\Service::cloneDefinition($this);
  165.             $clone->setDao(null);
  166.             unset($clone->fieldDefinitions);
  167.             DataObject\ClassDefinition::cleanupForExport($clone->layoutDefinitions);
  168.             $exportedClass var_export($clonetrue);
  169.             $data '<?php';
  170.             $data .= "\n\n";
  171.             $data .= "\nreturn " $exportedClass ";\n";
  172.             \Pimcore\File::put($definitionFile$data);
  173.         }
  174.         \Pimcore::getContainer()->get(PHPFieldCollectionClassDumperInterface::class)->dumpPHPClass($this);
  175.         $fieldDefinitions $this->getFieldDefinitions();
  176.         foreach ($fieldDefinitions as $fd) {
  177.             if ($fd instanceof DataObject\ClassDefinition\Data\DataContainerAwareInterface) {
  178.                 $fd->postSave($this);
  179.             }
  180.         }
  181.     }
  182.     public function delete()
  183.     {
  184.         @unlink($this->getDefinitionFile());
  185.         @unlink($this->getPhpClassFile());
  186.         // update classes
  187.         $classList = new DataObject\ClassDefinition\Listing();
  188.         $classes $classList->load();
  189.         if (is_array($classes)) {
  190.             foreach ($classes as $class) {
  191.                 foreach ($class->getFieldDefinitions() as $fieldDef) {
  192.                     if ($fieldDef instanceof DataObject\ClassDefinition\Data\Fieldcollections) {
  193.                         if (in_array($this->getKey(), $fieldDef->getAllowedTypes())) {
  194.                             $this->getDao()->delete($class);
  195.                             break;
  196.                         }
  197.                     }
  198.                 }
  199.             }
  200.         }
  201.     }
  202.     /**
  203.      * @internal
  204.      *
  205.      * @return bool
  206.      */
  207.     public function isWritable(): bool
  208.     {
  209.         if ($_SERVER['PIMCORE_CLASS_DEFINITION_WRITABLE'] ?? false) {
  210.             return true;
  211.         }
  212.         return !str_starts_with($this->getDefinitionFile(), PIMCORE_CUSTOM_CONFIGURATION_DIRECTORY);
  213.     }
  214.     /**
  215.      * @internal
  216.      *
  217.      * @param string|null $key
  218.      *
  219.      * @return string
  220.      */
  221.     public function getDefinitionFile($key null)
  222.     {
  223.         return $this->locateDefinitionFile($key ?? $this->getKey(), 'fieldcollections/%s.php');
  224.     }
  225.     /**
  226.      * @internal
  227.      * @internal
  228.      *
  229.      * @return string
  230.      */
  231.     public function getPhpClassFile()
  232.     {
  233.         return $this->locateFile(ucfirst($this->getKey()), 'DataObject/Fieldcollection/Data/%s.php');
  234.     }
  235. }