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

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