vendor/pimcore/pimcore/models/Element/AbstractElement.php line 98

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\Element;
  15. use Pimcore\Cache\Runtime;
  16. use Pimcore\Event\AdminEvents;
  17. use Pimcore\Event\Model\ElementEvent;
  18. use Pimcore\Event\Traits\RecursionBlockingEventDispatchHelperTrait;
  19. use Pimcore\Model;
  20. use Pimcore\Model\DataObject\AbstractObject;
  21. use Pimcore\Model\Element\Traits\DirtyIndicatorTrait;
  22. /**
  23.  * @method Model\Document\Dao|Model\Asset\Dao|Model\DataObject\AbstractObject\Dao getDao()
  24.  */
  25. abstract class AbstractElement extends Model\AbstractModel implements ElementInterfaceElementDumpStateInterfaceDirtyIndicatorInterface
  26. {
  27.     use ElementDumpStateTrait;
  28.     use DirtyIndicatorTrait;
  29.     use RecursionBlockingEventDispatchHelperTrait;
  30.     /**
  31.      * @internal
  32.      *
  33.      * @var Model\Dependency|null
  34.      */
  35.     protected $dependencies;
  36.     /**
  37.      * @internal
  38.      *
  39.      * @var int
  40.      */
  41.     protected $__dataVersionTimestamp null;
  42.     /**
  43.      * @internal
  44.      */
  45.     protected function updateModificationInfos()
  46.     {
  47.         if (Model\Version::isEnabled() === true) {
  48.             $this->setVersionCount($this->getDao()->getVersionCountForUpdate() + 1);
  49.         }
  50.         if ($this->getVersionCount() > 4200000000) {
  51.             $this->setVersionCount(1);
  52.         }
  53.         $modificationDateKey $this instanceof AbstractObject 'o_modificationDate' 'modificationDate';
  54.         if (!$this->isFieldDirty($modificationDateKey)) {
  55.             $updateTime time();
  56.             $this->setModificationDate($updateTime);
  57.         }
  58.         if (!$this->getCreationDate()) {
  59.             $this->setCreationDate($this->getModificationDate());
  60.         }
  61.         // auto assign user if possible, if not changed explicitly, if no user present, use ID=0 which represents the "system" user
  62.         $userModificationKey $this instanceof AbstractObject 'o_userModification' 'userModification';
  63.         if (!$this->isFieldDirty($userModificationKey)) {
  64.             $userId 0;
  65.             $user \Pimcore\Tool\Admin::getCurrentUser();
  66.             if ($user instanceof Model\User) {
  67.                 $userId $user->getId();
  68.             }
  69.             $this->setUserModification($userId);
  70.         }
  71.         if ($this->getUserOwner() === null) {
  72.             $this->setUserOwner($this->getUserModification());
  73.         }
  74.     }
  75.     /**
  76.      * {@inheritdoc}
  77.      */
  78.     public function getProperty($name$asContainer false)
  79.     {
  80.         $properties $this->getProperties();
  81.         if ($this->hasProperty($name)) {
  82.             if ($asContainer) {
  83.                 return $properties[$name];
  84.             } else {
  85.                 return $properties[$name]->getData();
  86.             }
  87.         }
  88.         return null;
  89.     }
  90.     /**
  91.      * {@inheritdoc}
  92.      */
  93.     public function hasProperty($name)
  94.     {
  95.         $properties $this->getProperties();
  96.         return array_key_exists($name$properties);
  97.     }
  98.     /**
  99.      * @param string $name
  100.      */
  101.     public function removeProperty($name)
  102.     {
  103.         $properties $this->getProperties();
  104.         unset($properties[$name]);
  105.         $this->setProperties($properties);
  106.     }
  107.     /**
  108.      * {@inheritdoc}
  109.      */
  110.     public function getCacheTag()
  111.     {
  112.         $elementType Service::getElementType($this);
  113.         return Service::getElementCacheTag($elementType$this->getId());
  114.     }
  115.     /**
  116.      * @internal
  117.      *
  118.      * @param string|int $id
  119.      *
  120.      * @return string
  121.      */
  122.     protected static function getCacheKey($id): string
  123.     {
  124.         $elementType Service::getElementTypeByClassName(static::class);
  125.         return Service::getElementCacheTag($elementType$id);
  126.     }
  127.     /**
  128.      * {@inheritdoc}
  129.      */
  130.     public function getCacheTags(array $tags = []): array
  131.     {
  132.         $tags[$this->getCacheTag()] = $this->getCacheTag();
  133.         return $tags;
  134.     }
  135.     /**
  136.      * Resolves the dependencies of the element and returns an array of them - Used by update()
  137.      *
  138.      * @internal
  139.      *
  140.      * @return array
  141.      */
  142.     protected function resolveDependencies(): array
  143.     {
  144.         $dependencies = [[]];
  145.         // check for properties
  146.         if (method_exists($this'getProperties')) {
  147.             foreach ($this->getProperties() as $property) {
  148.                 $dependencies[] = $property->resolveDependencies();
  149.             }
  150.         }
  151.         return array_merge(...$dependencies);
  152.     }
  153.     /**
  154.      * {@inheritdoc}
  155.      */
  156.     public function isLocked()
  157.     {
  158.         if ($this->getLocked()) {
  159.             return true;
  160.         }
  161.         // check for inherited
  162.         return $this->getDao()->isLocked();
  163.     }
  164.     /**
  165.      * @internal
  166.      *
  167.      * @return array
  168.      */
  169.     public function getUserPermissions()
  170.     {
  171.         $baseClass Service::getBaseClassNameForElement($this);
  172.         $workspaceClass '\\Pimcore\\Model\\User\\Workspace\\' $baseClass;
  173.         /** @var Model\AbstractModel $dummy */
  174.         $dummy = new $workspaceClass();
  175.         $vars $dummy->getObjectVars();
  176.         $ignored = ['userId''cid''cpath''dao'];
  177.         $permissions = [];
  178.         foreach ($vars as $name => $defaultValue) {
  179.             if (!in_array($name$ignored)) {
  180.                 $permissions[$name] = $this->isAllowed($name);
  181.             }
  182.         }
  183.         return $permissions;
  184.     }
  185.     /**
  186.      * {@inheritdoc}
  187.      */
  188.     public function isAllowed($type, ?Model\User $user null)
  189.     {
  190.         if (null === $user) {
  191.             $user \Pimcore\Tool\Admin::getCurrentUser();
  192.         }
  193.         if (!$user) {
  194.             if (php_sapi_name() === 'cli') {
  195.                 return true;
  196.             }
  197.             return false;
  198.         }
  199.         //everything is allowed for admin
  200.         if ($user->isAdmin()) {
  201.             return true;
  202.         }
  203.         $isAllowed $this->getDao()->isAllowed($type$user);
  204.         $event = new ElementEvent($this, ['isAllowed' => $isAllowed'permissionType' => $type'user' => $user]);
  205.         \Pimcore::getEventDispatcher()->dispatch($eventAdminEvents::ELEMENT_PERMISSION_IS_ALLOWED);
  206.         return (bool) $event->getArgument('isAllowed');
  207.     }
  208.     /**
  209.      * @internal
  210.      */
  211.     public function unlockPropagate()
  212.     {
  213.         $type Service::getElementType($this);
  214.         $ids $this->getDao()->unlockPropagate();
  215.         // invalidate cache items
  216.         foreach ($ids as $id) {
  217.             $element Service::getElementById($type$id);
  218.             if ($element) {
  219.                 $element->clearDependentCache();
  220.             }
  221.         }
  222.     }
  223.     /**
  224.      * @internal
  225.      *
  226.      * @throws \Exception
  227.      */
  228.     protected function validatePathLength()
  229.     {
  230.         if (mb_strlen($this->getRealFullPath()) > 765) {
  231.             throw new \Exception("Full path is limited to 765 characters, reduce the length of your parent's path");
  232.         }
  233.     }
  234.     /**
  235.      * {@inheritdoc}
  236.      */
  237.     public function __toString()
  238.     {
  239.         return $this->getFullPath();
  240.     }
  241.     /**
  242.      * @return int
  243.      */
  244.     public function __getDataVersionTimestamp()
  245.     {
  246.         return $this->__dataVersionTimestamp;
  247.     }
  248.     /**
  249.      * @param int $_dataVersionTimestamp
  250.      */
  251.     public function __setDataVersionTimestamp($_dataVersionTimestamp)
  252.     {
  253.         $this->__dataVersionTimestamp $_dataVersionTimestamp;
  254.     }
  255.     /**
  256.      * {@inheritdoc}
  257.      */
  258.     public function __isBasedOnLatestData()
  259.     {
  260.         return $this->getDao()->__isBasedOnLatestData();
  261.     }
  262.     /**
  263.      * @internal
  264.      *
  265.      * @param string|null $versionNote
  266.      * @param bool $saveOnlyVersion
  267.      * @param bool $saveStackTrace
  268.      * @param bool $isAutoSave
  269.      *
  270.      * @return Model\Version
  271.      *
  272.      * @throws \Exception
  273.      */
  274.     protected function doSaveVersion($versionNote null$saveOnlyVersion true$saveStackTrace true$isAutoSave false)
  275.     {
  276.         $version null;
  277.         if ($isAutoSave) {
  278.             $list = new Model\Version\Listing();
  279.             $list->setLoadAutoSave(true);
  280.             $list->setCondition('autoSave = 1 AND cid = ? AND cType = ? AND userId = ? ', [$this->getId(), Service::getElementType($this), $this->getUserModification()]);
  281.             $version $list->current();
  282.         }
  283.         if (!$version) {
  284.             /** @var Model\Version $version */
  285.             $version self::getModelFactory()->build(Model\Version::class);
  286.         }
  287.         $version->setCid($this->getId());
  288.         $version->setCtype(Service::getElementType($this));
  289.         $version->setDate($this->getModificationDate());
  290.         $version->setUserId($this->getUserModification());
  291.         $version->setData($this);
  292.         $version->setNote($versionNote);
  293.         $version->setGenerateStackTrace($saveStackTrace);
  294.         $version->setAutoSave($isAutoSave);
  295.         if ($saveOnlyVersion) {
  296.             $versionCount $this->getDao()->getVersionCountForUpdate();
  297.             $versionCount++;
  298.         } else {
  299.             $versionCount $this->getVersionCount();
  300.         }
  301.         $version->setVersionCount($versionCount);
  302.         $version->save();
  303.         return $version;
  304.     }
  305.     /**
  306.      * {@inheritdoc}
  307.      */
  308.     public function getDependencies()
  309.     {
  310.         if (!$this->dependencies) {
  311.             $this->dependencies Model\Dependency::getBySourceId($this->getId(), Service::getElementType($this));
  312.         }
  313.         return $this->dependencies;
  314.     }
  315.     /**
  316.      * {@inheritdoc}
  317.      */
  318.     public function getScheduledTasks()
  319.     {
  320.         return [];
  321.     }
  322.     /**
  323.      * {@inheritdoc}
  324.      */
  325.     public function getVersions()
  326.     {
  327.         return [];
  328.     }
  329.     /**
  330.      * {@inheritdoc}
  331.      */
  332.     public function __sleep()
  333.     {
  334.         $parentVars parent::__sleep();
  335.         $blockedVars = ['dependencies'];
  336.         return array_diff($parentVars$blockedVars);
  337.     }
  338.     /**
  339.      * {@inheritdoc}
  340.      */
  341.     public function __clone()
  342.     {
  343.         parent::__clone();
  344.         $this->dependencies null;
  345.     }
  346.     /**
  347.      * @internal
  348.      *
  349.      * @param int $userId
  350.      */
  351.     public function deleteAutoSaveVersions($userId null)
  352.     {
  353.         $list = new Model\Version\Listing();
  354.         $list->setLoadAutoSave(true);
  355.         if ($userId) {
  356.             $list->setCondition('`ctype` = ? AND cid = ? AND `autoSave` = 1 AND userId = ?', [Service::getElementType($this), $this->getId(), $userId]);
  357.         } else {
  358.             $list->setCondition('`ctype` = ? AND cid = ? AND `autoSave` = 1', [Service::getElementType($this), $this->getId()]);
  359.         }
  360.         foreach ($list->load() as $version) {
  361.             $version->delete();
  362.         }
  363.     }
  364.     /**
  365.      * @internal
  366.      */
  367.     protected function removeInheritedProperties()
  368.     {
  369.         $myProperties $this->getProperties();
  370.         if ($myProperties) {
  371.             foreach ($this->getProperties() as $name => $property) {
  372.                 if ($property->getInherited()) {
  373.                     unset($myProperties[$name]);
  374.                 }
  375.             }
  376.         }
  377.         $this->setProperties($myProperties);
  378.     }
  379.     /**
  380.      * @internal
  381.      */
  382.     protected function renewInheritedProperties()
  383.     {
  384.         $this->removeInheritedProperties();
  385.         // add to registry to avoid infinite regresses in the following $this->getDao()->getProperties()
  386.         $cacheKey self::getCacheKey($this->getId());
  387.         if (!Runtime::isRegistered($cacheKey)) {
  388.             Runtime::set($cacheKey$this);
  389.         }
  390.         $myProperties $this->getProperties();
  391.         $inheritedProperties $this->getDao()->getProperties(true);
  392.         $this->setProperties(array_merge($inheritedProperties$myProperties));
  393.     }
  394. }