vendor/pimcore/pimcore/models/Document/Editable.php line 815

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 Enterprise License (PEL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  * @category   Pimcore
  12.  * @package    Document
  13.  *
  14.  * @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  15.  * @license    http://www.pimcore.org/license     GPLv3 and PEL
  16.  */
  17. namespace Pimcore\Model\Document;
  18. use Pimcore\Document\Editable\Block\BlockName;
  19. use Pimcore\Document\Editable\Block\BlockState;
  20. use Pimcore\Document\Editable\Block\BlockStateStack;
  21. use Pimcore\Document\Tag\NamingStrategy\NamingStrategyInterface;
  22. use Pimcore\Event\DocumentEvents;
  23. use Pimcore\Event\Model\Document\EditableNameEvent;
  24. use Pimcore\Logger;
  25. use Pimcore\Model;
  26. use Pimcore\Model\Document;
  27. use Pimcore\Model\Document\Targeting\TargetingDocumentInterface;
  28. use Pimcore\Model\Webservice;
  29. use Pimcore\Templating\Model\ViewModel;
  30. use Pimcore\Templating\Model\ViewModelInterface;
  31. use Pimcore\Tool\HtmlUtils;
  32. /**
  33.  * @method \Pimcore\Model\Document\Editable\Dao getDao()
  34.  * @method void save()
  35.  * @method void delete()
  36.  */
  37. abstract class Editable extends Model\AbstractModel implements Model\Document\Editable\EditableInterface
  38. {
  39.     /**
  40.      * Options of the current tag, can contain some configurations for the editmode, or the thumbnail name, ...
  41.      *
  42.      * @var array
  43.      *
  44.      * @deprecated will be removed in Pimcore 7. use $config instead
  45.      */
  46.     protected $options;
  47.     /**
  48.      * Contains some configurations for the editmode, or the thumbnail name, ...
  49.      *
  50.      * @var array
  51.      */
  52.     protected $config;
  53.     /**
  54.      * @var string
  55.      */
  56.     protected $name;
  57.     /**
  58.      * Contains the real name of the editable without the prefixes and suffixes
  59.      * which are generated automatically by blocks and areablocks
  60.      *
  61.      * @var string
  62.      */
  63.     protected $realName;
  64.     /**
  65.      * Contains parent hierarchy names (used when building elements inside a block/areablock hierarchy)
  66.      *
  67.      * @var array
  68.      */
  69.     private $parentBlockNames = [];
  70.     /**
  71.      * Element belongs to the ID of the document
  72.      *
  73.      * @var int
  74.      */
  75.     protected $documentId;
  76.     /**
  77.      * Element belongs to the document
  78.      *
  79.      * @var Document\PageSnippet|null
  80.      */
  81.     protected $document;
  82.     /**
  83.      * @deprecated Unused - will be removed in 7.0
  84.      *
  85.      * @var string|null
  86.      */
  87.     protected $controller;
  88.     /**
  89.      * @var ViewModelInterface|null
  90.      *
  91.      * @deprecated
  92.      */
  93.     protected $view;
  94.     /**
  95.      * In Editmode or not
  96.      *
  97.      * @var bool
  98.      */
  99.     protected $editmode;
  100.     /**
  101.      * @var bool
  102.      */
  103.     protected $inherited false;
  104.     public function __construct()
  105.     {
  106.         $this->options = & $this->config;
  107.     }
  108.     /**
  109.      * @var string
  110.      */
  111.     protected $inDialogBox null;
  112.     /**
  113.      * @param string $type
  114.      * @param string $name
  115.      * @param int $documentId
  116.      * @param array|null $config
  117.      * @param string|null $controller
  118.      * @param ViewModel|null $view
  119.      * @param bool|null $editmode
  120.      *
  121.      * @return Editable
  122.      */
  123.     public static function factory($type$name$documentId$config null$controller null$view null$editmode null)
  124.     {
  125.         $loader = \Pimcore::getContainer()->get(Document\Editable\Loader\EditableLoader::class);
  126.         /** @var Editable $editable */
  127.         $editable $loader->build($type);
  128.         $editable->setName($name);
  129.         $editable->setDocumentId($documentId);
  130.         $editable->setController($controller);
  131.         if (!$view) {
  132.             // needed for the RESTImporter. For areabricks define a default implementation. Otherwise cannot find a tag handler.
  133.             $view = new ViewModel();
  134.         }
  135.         $editable->setView($view);
  136.         $editable->setEditmode($editmode);
  137.         $editable->setConfig($config);
  138.         return $editable;
  139.     }
  140.     /**
  141.      * @return string|void
  142.      *
  143.      * @throws \Exception
  144.      */
  145.     public function admin()
  146.     {
  147.         $options $this->getEditmodeOptions();
  148.         $code $this->outputEditmodeOptions($optionstrue);
  149.         $attributes $this->getEditmodeElementAttributes($options);
  150.         $attributeString HtmlUtils::assembleAttributeString($attributes);
  151.         $htmlContainerCode = ('<div ' $attributeString '></div>');
  152.         if ($this->isInDialogBox()) {
  153.             $htmlContainerCode $this->wrapEditmodeContainerCodeForDialogBox($attributes['id'], $htmlContainerCode);
  154.         }
  155.         $code .= $htmlContainerCode;
  156.         return $code;
  157.     }
  158.     /**
  159.      * @param string $id
  160.      * @param string $code
  161.      *
  162.      * @return string
  163.      */
  164.     protected function wrapEditmodeContainerCodeForDialogBox(string $idstring $code): string
  165.     {
  166.         $code '<template id="template__' $id '">' $code '</template>';
  167.         return $code;
  168.     }
  169.     /**
  170.      * Builds options passed to editmode frontend as JSON config
  171.      *
  172.      * @return array
  173.      */
  174.     protected function getEditmodeOptions(): array
  175.     {
  176.         $options = [
  177.             // we don't use : and . in IDs (although it's allowed in HTML spec)
  178.             // because they are used in CSS syntax and therefore can't be used in querySelector()
  179.             'id' => 'pimcore_editable_' str_replace([':''.'], '_'$this->getName()),
  180.             'name' => $this->getName(),
  181.             'realName' => $this->getRealName(),
  182.             'config' => $this->getConfig(),
  183.             'data' => $this->getEditmodeData(),
  184.             'type' => $this->getType(),
  185.             'inherited' => $this->getInherited(),
  186.             'inDialogBox' => $this->getInDialogBox(),
  187.         ];
  188.         return $options;
  189.     }
  190.     /**
  191.      * Builds data used for editmode
  192.      *
  193.      * @return mixed
  194.      */
  195.     protected function getEditmodeData()
  196.     {
  197.         // get configuration data for admin
  198.         if (method_exists($this'getDataEditmode')) {
  199.             $data $this->getDataEditmode();
  200.         } else {
  201.             $data $this->getData();
  202.         }
  203.         return $data;
  204.     }
  205.     /**
  206.      * Builds attributes used on the editmode HTML element
  207.      *
  208.      * @param array $options
  209.      *
  210.      * @return array
  211.      */
  212.     protected function getEditmodeElementAttributes(array $options): array
  213.     {
  214.         if (!isset($options['id'])) {
  215.             throw new \RuntimeException(sprintf('Expected an "id" option to be set on the "%s" editable options array'$this->getName()));
  216.         }
  217.         $attributes array_merge($this->getEditmodeBlockStateAttributes(), [
  218.             'id' => $options['id'],
  219.             'class' => implode(' '$this->getEditmodeElementClasses()),
  220.         ]);
  221.         return $attributes;
  222.     }
  223.     protected function getEditmodeBlockStateAttributes(): array
  224.     {
  225.         $blockState $this->getBlockState();
  226.         $blockNames array_map(function (BlockName $blockName) {
  227.             return $blockName->getRealName();
  228.         }, $blockState->getBlocks());
  229.         $attributes = [
  230.             'data-name' => $this->getName(),
  231.             'data-real-name' => $this->getRealName(),
  232.             'data-type' => $this->getType(),
  233.             'data-block-names' => implode(', '$blockNames),
  234.             'data-block-indexes' => implode(', '$blockState->getIndexes()),
  235.         ];
  236.         return $attributes;
  237.     }
  238.     /**
  239.      * Builds classes used on the editmode HTML element
  240.      *
  241.      * @return array
  242.      */
  243.     protected function getEditmodeElementClasses(): array
  244.     {
  245.         $classes = [
  246.             'pimcore_editable',
  247.             'pimcore_tag_' $this->getType(),
  248.             'pimcore_editable_' $this->getType(),
  249.         ];
  250.         $editableConfig $this->getConfig();
  251.         if (isset($editableConfig['class'])) {
  252.             if (is_array($editableConfig['class'])) {
  253.                 $classes array_merge($classes$editableConfig['class']);
  254.             } else {
  255.                 $classes[] = (string)$editableConfig['class'];
  256.             }
  257.         }
  258.         return $classes;
  259.     }
  260.     /**
  261.      * Sends data to the output stream
  262.      *
  263.      * @param string $value
  264.      */
  265.     protected function outputEditmode($value)
  266.     {
  267.         if ($this->getEditmode()) {
  268.             echo $value "\n";
  269.         }
  270.     }
  271.     /**
  272.      * Push editmode options into the JS config array
  273.      *
  274.      * @param array $options
  275.      * @param bool $return
  276.      *
  277.      * @return string|void
  278.      */
  279.     protected function outputEditmodeOptions(array $options$return false)
  280.     {
  281.         // filter all non-scalar values before we pass them to the config object (JSON)
  282.         $clean = function ($value) use (&$clean) {
  283.             if (is_array($value)) {
  284.                 foreach ($value as &$item) {
  285.                     $item $clean($item);
  286.                 }
  287.             } elseif (!is_scalar($value)) {
  288.                 $value null;
  289.             }
  290.             return $value;
  291.         };
  292.         $options $clean($options);
  293.         $code '
  294.             <script>
  295.                 editableDefinitions.push(' json_encode($optionsJSON_PRETTY_PRINT) . ');
  296.             </script>
  297.         ';
  298.         if (json_last_error()) {
  299.             throw new \Exception('json encode failed: ' json_last_error_msg());
  300.         }
  301.         if ($return) {
  302.             return $code;
  303.         }
  304.         $this->outputEditmode($code);
  305.         return;
  306.     }
  307.     /**
  308.      * @return mixed
  309.      */
  310.     public function getValue()
  311.     {
  312.         return $this->getData();
  313.     }
  314.     /**
  315.      * @return string
  316.      */
  317.     public function getName()
  318.     {
  319.         return $this->name;
  320.     }
  321.     /**
  322.      * @param string $name
  323.      *
  324.      * @return $this
  325.      */
  326.     public function setName($name)
  327.     {
  328.         $this->name $name;
  329.         return $this;
  330.     }
  331.     /**
  332.      * @param int $id
  333.      *
  334.      * @return $this
  335.      */
  336.     public function setDocumentId($id)
  337.     {
  338.         $this->documentId = (int) $id;
  339.         if ($this->document instanceof PageSnippet && $this->document->getId() !== $this->documentId) {
  340.             $this->document null;
  341.         }
  342.         return $this;
  343.     }
  344.     /**
  345.      * @return int
  346.      */
  347.     public function getDocumentId()
  348.     {
  349.         return $this->documentId;
  350.     }
  351.     /**
  352.      * @param Document\PageSnippet $document
  353.      *
  354.      * @return $this
  355.      */
  356.     public function setDocument(Document\PageSnippet $document)
  357.     {
  358.         $this->document $document;
  359.         $this->documentId = (int) $document->getId();
  360.         return $this;
  361.     }
  362.     /**
  363.      * @return Document\PageSnippet
  364.      */
  365.     public function getDocument()
  366.     {
  367.         if (!$this->document) {
  368.             $this->document Document\PageSnippet::getById($this->documentId);
  369.         }
  370.         return $this->document;
  371.     }
  372.     /**
  373.      * @return array
  374.      *
  375.      * @deprecated will be removed in Pimcore 7. Use getConfig() instead.
  376.      */
  377.     public function getOptions()
  378.     {
  379.         return $this->getConfig();
  380.     }
  381.     /**
  382.      * @param array $options
  383.      *
  384.      * @return $this
  385.      *
  386.      * @deprecated will be removed in Pimcore 7. Use setConfig() instead.
  387.      */
  388.     public function setOptions($options)
  389.     {
  390.         return $this->setConfig($options);
  391.     }
  392.     /**
  393.      * @return array
  394.      */
  395.     public function getConfig()
  396.     {
  397.         return is_array($this->config) ? $this->config : [];
  398.     }
  399.     /**
  400.      * @param array $config
  401.      *
  402.      * @return $this
  403.      */
  404.     public function setConfig($config)
  405.     {
  406.         $this->config $config;
  407.         return $this;
  408.     }
  409.     /**
  410.      * @param string $name
  411.      * @param mixed $value
  412.      *
  413.      * @return self
  414.      */
  415.     public function setOption(string $name$value): self
  416.     {
  417.         if (!is_array($this->options)) {
  418.             $this->options = [];
  419.         }
  420.         $this->options[$name] = $value;
  421.         return $this;
  422.     }
  423.     /**
  424.      * @deprecated
  425.      *
  426.      * @param string|null $controller
  427.      *
  428.      * @return $this
  429.      */
  430.     public function setController($controller)
  431.     {
  432.         $this->controller $controller;
  433.         return $this;
  434.     }
  435.     /**
  436.      * @deprecated
  437.      *
  438.      * @return string|null
  439.      */
  440.     public function getController()
  441.     {
  442.         return $this->controller;
  443.     }
  444.     /**
  445.      * @param ViewModelInterface $view
  446.      *
  447.      * @return $this
  448.      *
  449.      * @deprecated
  450.      */
  451.     public function setView($view)
  452.     {
  453.         $this->view $view;
  454.         return $this;
  455.     }
  456.     /**
  457.      * @return ViewModelInterface
  458.      *
  459.      * @deprecated
  460.      */
  461.     public function getView()
  462.     {
  463.         return $this->view;
  464.     }
  465.     /**
  466.      * @return string
  467.      */
  468.     public function getRealName()
  469.     {
  470.         return $this->realName;
  471.     }
  472.     /**
  473.      * @param string $realName
  474.      */
  475.     public function setRealName($realName)
  476.     {
  477.         $this->realName $realName;
  478.     }
  479.     final public function setParentBlockNames($parentNames)
  480.     {
  481.         if (is_array($parentNames)) {
  482.             // unfortunately we cannot make a type hint here, because of compatibility reasons
  483.             // old versions where 'parentBlockNames' was not excluded in __sleep() have still this property
  484.             // in the serialized data, and mostly with the value NULL, on restore this would lead to an error
  485.             $this->parentBlockNames $parentNames;
  486.         }
  487.     }
  488.     final public function getParentBlockNames(): array
  489.     {
  490.         return $this->parentBlockNames;
  491.     }
  492.     /**
  493.      * Returns only the properties which should be serialized
  494.      *
  495.      * @return array
  496.      */
  497.     public function __sleep()
  498.     {
  499.         $finalVars = [];
  500.         $parentVars parent::__sleep();
  501.         $blockedVars = ['controller''view''editmode''options''config''parentBlockNames''document'];
  502.         foreach ($parentVars as $key) {
  503.             if (!in_array($key$blockedVars)) {
  504.                 $finalVars[] = $key;
  505.             }
  506.         }
  507.         return $finalVars;
  508.     }
  509.     public function __clone()
  510.     {
  511.         parent::__clone();
  512.         $this->view null;
  513.         $this->document null;
  514.     }
  515.     /**
  516.      * direct output to the frontend
  517.      *
  518.      * @return string
  519.      */
  520.     public function render()
  521.     {
  522.         if ($this->editmode) {
  523.             return $this->admin();
  524.         }
  525.         return $this->frontend();
  526.     }
  527.     /**
  528.      * direct output to the frontend
  529.      *
  530.      * @return string
  531.      */
  532.     public function __toString()
  533.     {
  534.         $result '';
  535.         try {
  536.             $result $this->render();
  537.         } catch (\Throwable $e) {
  538.             if (\Pimcore::inDebugMode()) {
  539.                 // the __toString method isn't allowed to throw exceptions
  540.                 $result '<b style="color:#f00">' $e->getMessage().'</b><br/>'.$e->getTraceAsString();
  541.                 return $result;
  542.             }
  543.             Logger::error('toString() returned an exception: {exception}', [
  544.                 'exception' => $e,
  545.             ]);
  546.             return '';
  547.         }
  548.         if (is_string($result) || is_numeric($result)) {
  549.             // we have to cast to string, because int/float is not auto-converted and throws an exception
  550.             return (string) $result;
  551.         }
  552.         return '';
  553.     }
  554.     /**
  555.      * @return bool
  556.      */
  557.     public function getEditmode()
  558.     {
  559.         return $this->editmode;
  560.     }
  561.     /**
  562.      * @param bool $editmode
  563.      *
  564.      * @return $this
  565.      */
  566.     public function setEditmode($editmode)
  567.     {
  568.         $this->editmode = (bool) $editmode;
  569.         return $this;
  570.     }
  571.     /**
  572.      * @return mixed
  573.      */
  574.     public function getDataForResource()
  575.     {
  576.         $this->checkValidity();
  577.         return $this->getData();
  578.     }
  579.     /**
  580.      * @param Model\Document\PageSnippet $ownerDocument
  581.      * @param array $tags
  582.      *
  583.      * @return array
  584.      */
  585.     public function getCacheTags($ownerDocument$tags = [])
  586.     {
  587.         return $tags;
  588.     }
  589.     /**
  590.      * This is a dummy and is mostly implemented by relation types
  591.      */
  592.     public function resolveDependencies()
  593.     {
  594.         return [];
  595.     }
  596.     /**
  597.      * Receives a standard class object from webservice import and fills the current editable's data
  598.      *
  599.      * @abstract
  600.      *
  601.      * @deprecated
  602.      *
  603.      * @param Webservice\Data\Document\Element $wsElement
  604.      * @param Model\Document\PageSnippet $document
  605.      * @param array $params
  606.      * @param Model\Webservice\IdMapperInterface|null $idMapper
  607.      */
  608.     public function getFromWebserviceImport($wsElement$document null$params = [], $idMapper null)
  609.     {
  610.     }
  611.     /**
  612.      * Returns the current editable's data for web service export
  613.      *
  614.      * @deprecated
  615.      *
  616.      * @param Model\Document\PageSnippet|null $document
  617.      * @param array $params
  618.      * @abstract
  619.      *
  620.      * @return mixed
  621.      */
  622.     public function getForWebserviceExport($document null$params = [])
  623.     {
  624.         $keys get_object_vars($this);
  625.         $el = [];
  626.         foreach ($keys as $key => $value) {
  627.             if ($value instanceof Model\Element\ElementInterface) {
  628.                 $value $value->getId();
  629.             }
  630.             $className Webservice\Data\Mapper::findWebserviceClass($value'out');
  631.             $el[$key] = Webservice\Data\Mapper::map($value$className'out');
  632.         }
  633.         unset($el['dao']);
  634.         unset($el['documentId']);
  635.         unset($el['document']);
  636.         unset($el['controller']);
  637.         unset($el['view']);
  638.         unset($el['editmode']);
  639.         $el Webservice\Data\Mapper::toObject($el);
  640.         return $el;
  641.     }
  642.     /**
  643.      * @return bool
  644.      */
  645.     public function checkValidity()
  646.     {
  647.         return true;
  648.     }
  649.     /**
  650.      * @param bool $inherited
  651.      *
  652.      * @return $this
  653.      */
  654.     public function setInherited($inherited)
  655.     {
  656.         $this->inherited $inherited;
  657.         return $this;
  658.     }
  659.     /**
  660.      * @return bool
  661.      */
  662.     public function getInherited()
  663.     {
  664.         return $this->inherited;
  665.     }
  666.     /**
  667.      * TODO inject block state via DI
  668.      *
  669.      * @return BlockState
  670.      */
  671.     protected function getBlockState(): BlockState
  672.     {
  673.         return \Pimcore::getContainer()->get(BlockStateStack::class)->getCurrentState();
  674.     }
  675.     /**
  676.      * Builds a tag name for an editable, taking current
  677.      * block state (block, index) and targeting into account.
  678.      *
  679.      * @param string $type
  680.      * @param string $name
  681.      * @param Document|null $document
  682.      *
  683.      * @return string
  684.      *
  685.      * @throws \Exception
  686.      *
  687.      * @deprecated since v6.8 and will be removed in 7. use buildEditableName() instead
  688.      */
  689.     public static function buildTagName(string $typestring $nameDocument $document null)
  690.     {
  691.         return self::buildEditableName($type$name$document);
  692.     }
  693.     /**
  694.      * Builds an editable name for an editable, taking current
  695.      * block state (block, index) and targeting into account.
  696.      *
  697.      * @param string $type
  698.      * @param string $name
  699.      * @param Document|null $document
  700.      *
  701.      * @return string
  702.      *
  703.      * @throws \Exception
  704.      */
  705.     public static function buildEditableName(string $typestring $nameDocument $document null)
  706.     {
  707.         // do NOT allow dots (.) and colons (:) here as they act as delimiters
  708.         // for block hierarchy in the new naming scheme (see #1467)!
  709.         if (!preg_match("@^[a-zA-Z0-9\-_]+$@"$name)) {
  710.             throw new \InvalidArgumentException(
  711.                 'Only valid CSS class selectors are allowed as the name for an editable (which is basically [a-zA-Z0-9\-_]+). Your name was: ' $name
  712.             );
  713.         }
  714.         // @todo add document-id to registry key | for example for embeded snippets
  715.         // set suffixes if the editable is inside a block
  716.         $container = \Pimcore::getContainer();
  717.         $blockState $container->get(BlockStateStack::class)->getCurrentState();
  718.         /**
  719.          * @var NamingStrategyInterface
  720.          */
  721.         $namingStrategy $container->get('pimcore.document.tag.naming.strategy');
  722.         // if element not nested inside a hierarchical element (e.g. block), add the
  723.         // targeting prefix if configured on the document. hasBlocks() determines if
  724.         // there are any parent blocks for the current element
  725.         $targetGroupEditableName null;
  726.         if ($document && $document instanceof TargetingDocumentInterface) {
  727.             $targetGroupEditableName $document->getTargetGroupEditableName($name);
  728.             if (!$blockState->hasBlocks()) {
  729.                 $name $targetGroupEditableName;
  730.             }
  731.         }
  732.         $editableName $namingStrategy->buildTagName($name$type$blockState$targetGroupEditableName);
  733.         $event = new EditableNameEvent($type$name$blockState$editableName$document);
  734.         \Pimcore::getEventDispatcher()->dispatch(DocumentEvents::EDITABLE_NAME$event);
  735.         $editableName $event->getEditableName();
  736.         if (strlen($editableName) > 750) {
  737.             throw new \Exception(sprintf(
  738.                 'Composite name for editable "%s" is longer than 750 characters. Use shorter names for your editables or reduce amount of nesting levels. Name is: %s',
  739.                 $name,
  740.                 $editableName
  741.             ));
  742.         }
  743.         return $editableName;
  744.     }
  745.     /**
  746.      * @param string $name
  747.      * @param Document $document
  748.      *
  749.      * @return string
  750.      *
  751.      * @deprecated since v6.8 and will be removed in 7. Use buildEditableRealName() instead
  752.      */
  753.     public static function buildTagRealName(string $nameDocument $document): string
  754.     {
  755.         return self::buildEditableRealName($name$document);
  756.     }
  757.     /**
  758.      * @param string $name
  759.      * @param Document $document
  760.      *
  761.      * @return string
  762.      */
  763.     public static function buildEditableRealName(string $nameDocument $document): string
  764.     {
  765.         $blockState = \Pimcore::getContainer()->get(BlockStateStack::class)->getCurrentState();
  766.         // if element not nested inside a hierarchical element (e.g. block), add the
  767.         // targeting prefix if configured on the document. hasBlocks() determines if
  768.         // there are any parent blocks for the current element
  769.         if ($document instanceof TargetingDocumentInterface && !$blockState->hasBlocks()) {
  770.             $name $document->getTargetGroupEditableName($name);
  771.         }
  772.         return $name;
  773.     }
  774.     /**
  775.      * @deprecated
  776.      *
  777.      * @param array|object $data
  778.      *
  779.      * @return object
  780.      */
  781.     public function sanitizeWebserviceData($data)
  782.     {
  783.         if (is_array($data)) {
  784.             $data = (object) $data;
  785.         }
  786.         return $data;
  787.     }
  788.     /**
  789.      * @return bool
  790.      */
  791.     public function isInDialogBox(): bool
  792.     {
  793.         return (bool) $this->inDialogBox;
  794.     }
  795.     /**
  796.      * @return string|null
  797.      */
  798.     public function getInDialogBox(): ?string
  799.     {
  800.         return $this->inDialogBox;
  801.     }
  802.     /**
  803.      * @param string|null $inDialogBox
  804.      *
  805.      * @return $this
  806.      */
  807.     public function setInDialogBox(?string $inDialogBox): self
  808.     {
  809.         $this->inDialogBox $inDialogBox;
  810.         return $this;
  811.     }
  812. }
  813. class_alias(Editable::class, 'Pimcore\Model\Document\Tag');