vendor/pimcore/pimcore/models/Document/PageSnippet.php line 411

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\Document;
  15. use Pimcore\Document\Editable\EditableUsageResolver;
  16. use Pimcore\Event\DocumentEvents;
  17. use Pimcore\Event\Model\DocumentEvent;
  18. use Pimcore\Http\RequestHelper;
  19. use Pimcore\Logger;
  20. use Pimcore\Messenger\VersionDeleteMessage;
  21. use Pimcore\Model;
  22. use Pimcore\Model\Document;
  23. use Pimcore\Model\Document\Editable\Loader\EditableLoaderInterface;
  24. /**
  25.  * @method \Pimcore\Model\Document\PageSnippet\Dao getDao()
  26.  * @method \Pimcore\Model\Version|null getLatestVersion(?int $userId = null)
  27.  */
  28. abstract class PageSnippet extends Model\Document
  29. {
  30.     use Model\Element\Traits\ScheduledTasksTrait;
  31.     /**
  32.      * @internal
  33.      *
  34.      * @var string|null
  35.      */
  36.     protected $controller;
  37.     /**
  38.      * @internal
  39.      *
  40.      * @var string|null
  41.      */
  42.     protected $template;
  43.     /**
  44.      * Contains all content-editables of the document
  45.      *
  46.      * @internal
  47.      *
  48.      * @var array|null
  49.      *
  50.      */
  51.     protected $editables null;
  52.     /**
  53.      * Contains all versions of the document
  54.      *
  55.      * @internal
  56.      *
  57.      * @var array
  58.      */
  59.     protected $versions null;
  60.     /**
  61.      * @internal
  62.      *
  63.      * @var null|int
  64.      */
  65.     protected $contentMainDocumentId;
  66.     /**
  67.      * @internal
  68.      *
  69.      * @var null|int
  70.      */
  71.     protected $contentMasterDocumentId;
  72.     /**
  73.      * @internal
  74.      *
  75.      * @var bool
  76.      */
  77.     protected bool $supportsContentMain true;
  78.     /**
  79.      * @internal
  80.      *
  81.      * @var null|bool
  82.      */
  83.     protected $missingRequiredEditable null;
  84.     /**
  85.      * @internal
  86.      *
  87.      * @var null|bool
  88.      */
  89.     protected $staticGeneratorEnabled null;
  90.     /**
  91.      * @internal
  92.      *
  93.      * @var null|int
  94.      */
  95.     protected $staticGeneratorLifetime null;
  96.     /**
  97.      * @internal
  98.      *
  99.      * @var array
  100.      */
  101.     protected $inheritedEditables = [];
  102.     private static bool $getInheritedValues false;
  103.     public function __construct()
  104.     {
  105.         $this->contentMasterDocumentId = & $this->contentMainDocumentId;
  106.     }
  107.     public static function setGetInheritedValues(bool $getInheritedValues): void
  108.     {
  109.         self::$getInheritedValues $getInheritedValues;
  110.     }
  111.     public static function getGetInheritedValues(): bool
  112.     {
  113.         return self::$getInheritedValues;
  114.     }
  115.     /**
  116.      * {@inheritdoc}
  117.      */
  118.     public function save()
  119.     {
  120.         // checking the required editables renders the document, so this needs to be
  121.         // before the database transaction, see also https://github.com/pimcore/pimcore/issues/8992
  122.         $this->checkMissingRequiredEditable();
  123.         if ($this->getMissingRequiredEditable() && $this->getPublished()) {
  124.             throw new Model\Element\ValidationException('Prevented publishing document - missing values for required editables');
  125.         }
  126.         return parent::save(...func_get_args());
  127.     }
  128.     /**
  129.      * {@inheritdoc}
  130.      */
  131.     protected function update($params = [])
  132.     {
  133.         // update elements
  134.         $editables $this->getEditables();
  135.         $this->getDao()->deleteAllEditables();
  136.         parent::update($params);
  137.         if (is_array($editables) && count($editables)) {
  138.             foreach ($editables as $editable) {
  139.                 if (!$editable->getInherited()) {
  140.                     $editable->setDao(null);
  141.                     $editable->setDocumentId($this->getId());
  142.                     $editable->save();
  143.                 }
  144.             }
  145.         }
  146.         // scheduled tasks are saved in $this->saveVersion();
  147.         // save version if needed
  148.         $this->saveVersion(falsefalse$params['versionNote'] ?? null);
  149.     }
  150.     /**
  151.      * @param bool $setModificationDate
  152.      * @param bool $saveOnlyVersion
  153.      * @param string $versionNote
  154.      * @param bool $isAutoSave
  155.      *
  156.      * @return null|Model\Version
  157.      *
  158.      * @throws \Exception
  159.      */
  160.     public function saveVersion($setModificationDate true$saveOnlyVersion true$versionNote null$isAutoSave false)
  161.     {
  162.         try {
  163.             // hook should be also called if "save only new version" is selected
  164.             if ($saveOnlyVersion) {
  165.                 $preUpdateEvent = new DocumentEvent($this, [
  166.                     'saveVersionOnly' => true,
  167.                     'isAutoSave' => $isAutoSave,
  168.                 ]);
  169.                 \Pimcore::getEventDispatcher()->dispatch($preUpdateEventDocumentEvents::PRE_UPDATE);
  170.             }
  171.             // set date
  172.             if ($setModificationDate) {
  173.                 $this->setModificationDate(time());
  174.             }
  175.             // scheduled tasks are saved always, they are not versioned!
  176.             $this->saveScheduledTasks();
  177.             // create version
  178.             $version null;
  179.             // only create a new version if there is at least 1 allowed
  180.             // or if saveVersion() was called directly (it's a newer version of the object)
  181.             $documentsConfig \Pimcore\Config::getSystemConfiguration('documents');
  182.             if ((is_null($documentsConfig['versions']['days'] ?? null) && is_null($documentsConfig['versions']['steps'] ?? null))
  183.                 || (!empty($documentsConfig['versions']['steps']))
  184.                 || !empty($documentsConfig['versions']['days'])
  185.                 || $setModificationDate) {
  186.                 $saveStackTrace = !($documentsConfig['versions']['disable_stack_trace'] ?? false);
  187.                 $version $this->doSaveVersion($versionNote$saveOnlyVersion$saveStackTrace$isAutoSave);
  188.             }
  189.             // hook should be also called if "save only new version" is selected
  190.             if ($saveOnlyVersion) {
  191.                 $postUpdateEvent = new DocumentEvent($this, [
  192.                     'saveVersionOnly' => true,
  193.                     'isAutoSave' => $isAutoSave,
  194.                 ]);
  195.                 \Pimcore::getEventDispatcher()->dispatch($postUpdateEventDocumentEvents::POST_UPDATE);
  196.             }
  197.             return $version;
  198.         } catch (\Exception $e) {
  199.             $postUpdateFailureEvent = new DocumentEvent($this, [
  200.                 'saveVersionOnly' => true,
  201.                 'exception' => $e,
  202.                 'isAutoSave' => $isAutoSave,
  203.             ]);
  204.             \Pimcore::getEventDispatcher()->dispatch($postUpdateFailureEventDocumentEvents::POST_UPDATE_FAILURE);
  205.             throw $e;
  206.         }
  207.     }
  208.     /**
  209.      * {@inheritdoc}
  210.      */
  211.     protected function doDelete()
  212.     {
  213.         // Dispatch Symfony Message Bus to delete versions
  214.         \Pimcore::getContainer()->get('messenger.bus.pimcore-core')->dispatch(
  215.             new VersionDeleteMessage(Service::getElementType($this), $this->getId())
  216.         );
  217.         // remove all tasks
  218.         $this->getDao()->deleteAllTasks();
  219.         parent::doDelete();
  220.     }
  221.     /**
  222.      * {@inheritdoc}
  223.      */
  224.     public function getCacheTags(array $tags = []): array
  225.     {
  226.         $tags parent::getCacheTags($tags);
  227.         foreach ($this->getEditables() as $editable) {
  228.             $tags $editable->getCacheTags($this$tags);
  229.         }
  230.         return $tags;
  231.     }
  232.     /**
  233.      * {@inheritdoc}
  234.      */
  235.     protected function resolveDependencies(): array
  236.     {
  237.         $dependencies = [parent::resolveDependencies()];
  238.         foreach ($this->getEditables() as $editable) {
  239.             $dependencies[] = $editable->resolveDependencies();
  240.         }
  241.         if ($this->getContentMainDocument() instanceof Document) {
  242.             $mainDocumentId $this->getContentMainDocument()->getId();
  243.             $dependencies[] = [
  244.                 'document_' $mainDocumentId => [
  245.                     'id' => $mainDocumentId,
  246.                     'type' => 'document',
  247.                 ],
  248.             ];
  249.         }
  250.         return array_merge(...$dependencies);
  251.     }
  252.     /**
  253.      * @return string
  254.      */
  255.     public function getController()
  256.     {
  257.         if (empty($this->controller)) {
  258.             $this->controller \Pimcore::getContainer()->getParameter('pimcore.documents.default_controller');
  259.         }
  260.         return $this->controller;
  261.     }
  262.     /**
  263.      * @return string|null
  264.      */
  265.     public function getTemplate()
  266.     {
  267.         return $this->template;
  268.     }
  269.     /**
  270.      * @param string|null $controller
  271.      *
  272.      * @return $this
  273.      */
  274.     public function setController($controller)
  275.     {
  276.         $this->controller $controller;
  277.         return $this;
  278.     }
  279.     /**
  280.      * @param string|null $template
  281.      *
  282.      * @return $this
  283.      */
  284.     public function setTemplate($template)
  285.     {
  286.         $this->template $template;
  287.         return $this;
  288.     }
  289.     /**
  290.      * Set raw data of an editable (eg. for editmode)
  291.      *
  292.      * @internal
  293.      *
  294.      * @param string $name
  295.      * @param string $type
  296.      * @param mixed $data
  297.      *
  298.      * @return $this
  299.      */
  300.     public function setRawEditable(string $namestring $type$data)
  301.     {
  302.         try {
  303.             if ($type) {
  304.                 /** @var EditableLoaderInterface $loader */
  305.                 $loader \Pimcore::getContainer()->get(Document\Editable\Loader\EditableLoader::class);
  306.                 $editable $loader->build($type);
  307.                 $this->editables $this->editables ?? [];
  308.                 $this->editables[$name] = $editable;
  309.                 $this->editables[$name]->setDataFromEditmode($data);
  310.                 $this->editables[$name]->setName($name);
  311.                 $this->editables[$name]->setDocument($this);
  312.             }
  313.         } catch (\Exception $e) {
  314.             Logger::warning("can't set element " $name ' with the type ' $type ' to the document: ' $this->getRealFullPath());
  315.         }
  316.         return $this;
  317.     }
  318.     /**
  319.      * Set an element with the given key/name
  320.      *
  321.      * @param Editable $editable
  322.      *
  323.      * @return $this
  324.      */
  325.     public function setEditable(Editable $editable)
  326.     {
  327.         $this->getEditables();
  328.         $this->editables[$editable->getName()] = $editable;
  329.         return $this;
  330.     }
  331.     /**
  332.      * @param string $name
  333.      *
  334.      * @return $this
  335.      */
  336.     public function removeEditable(string $name)
  337.     {
  338.         $this->getEditables();
  339.         if (isset($this->editables[$name])) {
  340.             unset($this->editables[$name]);
  341.         }
  342.         return $this;
  343.     }
  344.     /**
  345.      * Get an editable with the given key/name
  346.      *
  347.      * @param string $name
  348.      *
  349.      * @return Editable|null
  350.      */
  351.     public function getEditable(string $name)
  352.     {
  353.         $editables $this->getEditables();
  354.         if (isset($this->editables[$name])) {
  355.             return $editables[$name];
  356.         }
  357.         $inheritedEditable null;
  358.         if (array_key_exists($name$this->inheritedEditables)) {
  359.             $inheritedEditable $this->inheritedEditables[$name];
  360.         }
  361.         if (!$inheritedEditable) {
  362.             // check for content main document (inherit data)
  363.             $contentMainDocument $this->getContentMainDocument();
  364.             if ($contentMainDocument instanceof self && $contentMainDocument->getId() != $this->getId()) {
  365.                 $inheritedEditable $contentMainDocument->getEditable($name);
  366.                 if ($inheritedEditable) {
  367.                     $inheritedEditable = clone $inheritedEditable;
  368.                     $inheritedEditable->setInherited(true);
  369.                     $this->inheritedEditables[$name] = $inheritedEditable;
  370.                 }
  371.             }
  372.         }
  373.         return $inheritedEditable;
  374.     }
  375.     /**
  376.      * @param int|string|null $contentMainDocumentId
  377.      *
  378.      * @return $this
  379.      *
  380.      * @throws \Exception
  381.      */
  382.     public function setContentMainDocumentId($contentMainDocumentId/*, bool $validate*/)
  383.     {
  384.         // this is that the path is automatically converted to ID => when setting directly from admin UI
  385.         if (!is_numeric($contentMainDocumentId) && !empty($contentMainDocumentId)) {
  386.             if ($contentMainDocument Document\PageSnippet::getByPath($contentMainDocumentId)) {
  387.                 $contentMainDocumentId $contentMainDocument->getId();
  388.             } else {
  389.                 // Content main document was deleted or don't exist
  390.                 $contentMainDocumentId null;
  391.             }
  392.         }
  393.         // Don't set the content main document if the document is already part of the main document chain
  394.         if ($contentMainDocumentId) {
  395.             if ($currentContentMainDocument Document\PageSnippet::getById($contentMainDocumentId)) {
  396.                 $validate \func_get_args()[1] ?? false;
  397.                 $maxDepth 20;
  398.                 do {
  399.                     if ($currentContentMainDocument->getId() === $this->getId()) {
  400.                         throw new \Exception('This document is already part of the main document chain, please choose a different one.');
  401.                     }
  402.                     $currentContentMainDocument $currentContentMainDocument->getContentMainDocument();
  403.                 } while ($currentContentMainDocument && $maxDepth-- > && $validate);
  404.             } else {
  405.                 // Content main document was deleted or don't exist
  406.                 $contentMainDocumentId null;
  407.             }
  408.         }
  409.         $this->contentMainDocumentId $contentMainDocumentId;
  410.         return $this;
  411.     }
  412.     /**
  413.      * @deprecated will be removed in Pimcore 11
  414.      *
  415.      * @param int|string|null $contentMasterDocumentId
  416.      *
  417.      * @return $this
  418.      *
  419.      * @throws \Exception
  420.      */
  421.     public function setContentMasterDocumentId($contentMasterDocumentId/*, bool $validate*/)
  422.     {
  423.         trigger_deprecation(
  424.             'pimcore/pimcore',
  425.             '10.6.0',
  426.             sprintf('%s is deprecated and will be removed in Pimcore 11. Use %s instead.'__METHOD__str_replace('Master''Main'__METHOD__))
  427.         );
  428.         $this->setContentMainDocumentId($contentMasterDocumentId);
  429.         return $this;
  430.     }
  431.     /**
  432.      * @return int|null
  433.      */
  434.     public function getContentMainDocumentId()
  435.     {
  436.         return $this->contentMainDocumentId;
  437.     }
  438.     /**
  439.      * @deprecated will be removed in Pimcore 11
  440.      *
  441.      * @return int|null
  442.      */
  443.     public function getContentMasterDocumentId()
  444.     {
  445.         trigger_deprecation(
  446.             'pimcore/pimcore',
  447.             '10.6.0',
  448.             sprintf('%s is deprecated and will be removed in Pimcore 11. Use %s instead.'__METHOD__str_replace('Master''Main'__METHOD__))
  449.         );
  450.         return $this->getContentMainDocumentId();
  451.     }
  452.     /**
  453.      * @return Document\PageSnippet|null
  454.      */
  455.     public function getContentMainDocument()
  456.     {
  457.         if ($mainDocumentId $this->getContentMainDocumentId()) {
  458.             return Document\PageSnippet::getById($mainDocumentId);
  459.         }
  460.         return null;
  461.     }
  462.     /**
  463.      * @deprecated will be removed in Pimcore 11
  464.      *
  465.      * @return Document\PageSnippet|null
  466.      */
  467.     public function getContentMasterDocument()
  468.     {
  469.         trigger_deprecation(
  470.             'pimcore/pimcore',
  471.             '10.6.0',
  472.             sprintf('%s is deprecated and will be removed in Pimcore 11. Use %s instead.'__METHOD__str_replace('Master''Main'__METHOD__))
  473.         );
  474.         return $this->getContentMainDocument();
  475.     }
  476.     /**
  477.      * @param Document\PageSnippet|null $document
  478.      *
  479.      * @return $this
  480.      */
  481.     public function setContentMainDocument($document)
  482.     {
  483.         if ($document instanceof self) {
  484.             $this->setContentMainDocumentId($document->getId(), true);
  485.         } else {
  486.             $this->setContentMainDocumentId(null);
  487.         }
  488.         return $this;
  489.     }
  490.     /**
  491.      * @deprecated will be removed in Pimcore 11
  492.      *
  493.      * @param Document\PageSnippet|null $document
  494.      *
  495.      * @return $this
  496.      */
  497.     public function setContentMasterDocument($document)
  498.     {
  499.         trigger_deprecation(
  500.             'pimcore/pimcore',
  501.             '10.6.0',
  502.             sprintf('%s is deprecated and will be removed in Pimcore 11. Use %s instead.'__METHOD__str_replace('Master''Main'__METHOD__))
  503.         );
  504.         return $this->setContentMainDocument($document);
  505.     }
  506.     /**
  507.      * @param string $name
  508.      *
  509.      * @return bool
  510.      */
  511.     public function hasEditable(string $name)
  512.     {
  513.         return $this->getEditable($name) !== null;
  514.     }
  515.     /**
  516.      * @return Editable[]
  517.      */
  518.     public function getEditables(): array
  519.     {
  520.         if ($this->editables === null) {
  521.             $documentEditables $this->getDao()->getEditables();
  522.             if (self::getGetInheritedValues() && $this->supportsContentMain() && $this->getContentMainDocument()) {
  523.                 $contentMainEditables $this->getContentMainDocument()->getEditables();
  524.                 $documentEditables array_merge($contentMainEditables$documentEditables);
  525.                 $this->inheritedEditables $documentEditables;
  526.             }
  527.             $this->setEditables($documentEditables);
  528.         }
  529.         return $this->editables;
  530.     }
  531.     /**
  532.      * @param array|null $editables
  533.      *
  534.      * @return $this
  535.      *
  536.      */
  537.     public function setEditables(?array $editables)
  538.     {
  539.         $this->editables $editables;
  540.         return $this;
  541.     }
  542.     /**
  543.      * @return Model\Version[]
  544.      */
  545.     public function getVersions()
  546.     {
  547.         if ($this->versions === null) {
  548.             $this->setVersions($this->getDao()->getVersions());
  549.         }
  550.         return $this->versions;
  551.     }
  552.     /**
  553.      * @param array $versions
  554.      *
  555.      * @return $this
  556.      */
  557.     public function setVersions($versions)
  558.     {
  559.         $this->versions $versions;
  560.         return $this;
  561.     }
  562.     /**
  563.      * @see Document::getFullPath
  564.      *
  565.      * @return string
  566.      */
  567.     public function getHref()
  568.     {
  569.         return $this->getFullPath();
  570.     }
  571.     /**
  572.      * {@inheritdoc}
  573.      */
  574.     public function __sleep()
  575.     {
  576.         $finalVars = [];
  577.         $parentVars parent::__sleep();
  578.         $blockedVars = ['inheritedEditables'];
  579.         foreach ($parentVars as $key) {
  580.             if (!in_array($key$blockedVars)) {
  581.                 $finalVars[] = $key;
  582.             }
  583.         }
  584.         return $finalVars;
  585.     }
  586.     /**
  587.      * @param string|null $hostname
  588.      * @param string|null $scheme
  589.      *
  590.      * @return string
  591.      *
  592.      * @throws \Exception
  593.      */
  594.     public function getUrl($hostname null$scheme null)
  595.     {
  596.         if (!$scheme) {
  597.             $scheme 'http://';
  598.             /** @var RequestHelper $requestHelper */
  599.             $requestHelper \Pimcore::getContainer()->get(RequestHelper::class);
  600.             if ($requestHelper->hasMainRequest()) {
  601.                 $scheme $requestHelper->getMainRequest()->getScheme() . '://';
  602.             }
  603.         }
  604.         if (!$hostname) {
  605.             $hostname \Pimcore\Config::getSystemConfiguration('general')['domain'];
  606.             if (empty($hostname)) {
  607.                 if (!$hostname \Pimcore\Tool::getHostname()) {
  608.                     throw new \Exception('No hostname available');
  609.                 }
  610.             }
  611.         }
  612.         $url $scheme $hostname;
  613.         if ($this instanceof Page && $this->getPrettyUrl()) {
  614.             $url .= $this->getPrettyUrl();
  615.         } else {
  616.             $url .= $this->getFullPath();
  617.         }
  618.         $site \Pimcore\Tool\Frontend::getSiteForDocument($this);
  619.         if ($site instanceof Model\Site && $site->getMainDomain()) {
  620.             $url $scheme $site->getMainDomain() . preg_replace('@^' $site->getRootPath() . '/?@''/'$this->getRealFullPath());
  621.         }
  622.         return $url;
  623.     }
  624.     /**
  625.      * checks if the document is missing values for required editables
  626.      *
  627.      * @return bool|null
  628.      */
  629.     public function getMissingRequiredEditable()
  630.     {
  631.         return $this->missingRequiredEditable;
  632.     }
  633.     /**
  634.      * @param bool|null $missingRequiredEditable
  635.      *
  636.      * @return $this
  637.      */
  638.     public function setMissingRequiredEditable($missingRequiredEditable)
  639.     {
  640.         if ($missingRequiredEditable !== null) {
  641.             $missingRequiredEditable = (bool) $missingRequiredEditable;
  642.         }
  643.         $this->missingRequiredEditable $missingRequiredEditable;
  644.         return $this;
  645.     }
  646.     /**
  647.      * @internal
  648.      *
  649.      * @return bool
  650.      */
  651.     public function supportsContentMain(): bool
  652.     {
  653.         return $this->supportsContentMain;
  654.     }
  655.     /**
  656.      * Validates if there is a missing value for required editable
  657.      *
  658.      * @internal
  659.      */
  660.     protected function checkMissingRequiredEditable()
  661.     {
  662.         // load data which must be requested
  663.         $this->getProperties();
  664.         $this->getEditables();
  665.         //Allowed tags for required check
  666.         $allowedTypes = ['input''wysiwyg''textarea''numeric'];
  667.         if ($this->getMissingRequiredEditable() === null) {
  668.             /** @var EditableUsageResolver $editableUsageResolver */
  669.             $editableUsageResolver \Pimcore::getContainer()->get(EditableUsageResolver::class);
  670.             try {
  671.                 $documentCopy Service::cloneMe($this);
  672.                 if ($documentCopy instanceof self) {
  673.                     // rendering could fail if the controller/action doesn't exist, in this case we can skip the required check
  674.                     $editableNames $editableUsageResolver->getUsedEditableNames($documentCopy);
  675.                     foreach ($editableNames as $editableName) {
  676.                         $editable $documentCopy->getEditable($editableName);
  677.                         if ($editable instanceof Editable && in_array($editable->getType(), $allowedTypes)) {
  678.                             $editableConfig $editable->getConfig();
  679.                             if ($editable->isEmpty() && isset($editableConfig['required']) && $editableConfig['required'] == true) {
  680.                                 $this->setMissingRequiredEditable(true);
  681.                                 break;
  682.                             }
  683.                         }
  684.                     }
  685.                 }
  686.             } catch (\Exception $e) {
  687.                 // noting to do, as rendering the document failed for whatever reason
  688.             }
  689.         }
  690.     }
  691.     /**
  692.      * @return bool|null
  693.      */
  694.     public function getStaticGeneratorEnabled(): ?bool
  695.     {
  696.         return $this->staticGeneratorEnabled;
  697.     }
  698.     /**
  699.      * @param bool|null $staticGeneratorEnabled
  700.      */
  701.     public function setStaticGeneratorEnabled(?bool $staticGeneratorEnabled): void
  702.     {
  703.         $this->staticGeneratorEnabled $staticGeneratorEnabled;
  704.     }
  705.     /**
  706.      * @return int|null
  707.      */
  708.     public function getStaticGeneratorLifetime(): ?int
  709.     {
  710.         return $this->staticGeneratorLifetime;
  711.     }
  712.     /**
  713.      * @param int|null $staticGeneratorLifetime
  714.      */
  715.     public function setStaticGeneratorLifetime(?int $staticGeneratorLifetime): void
  716.     {
  717.         $this->staticGeneratorLifetime $staticGeneratorLifetime;
  718.     }
  719.     public function __wakeup()
  720.     {
  721.         $propertyMappings = [
  722.             'contentMasterDocumentId' => 'contentMainDocumentId',
  723.         ];
  724.         foreach ($propertyMappings as $oldProperty => $newProperty) {
  725.             if ($this->$newProperty === null) {
  726.                 $this->$newProperty $this->$oldProperty;
  727.                 $this->$oldProperty = & $this->$newProperty;
  728.             }
  729.         }
  730.         parent::__wakeup();
  731.     }
  732. }