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

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