vendor/pimcore/pimcore/models/Document/Editable/Block.php line 25

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\Editable;
  15. use Pimcore\Document\Editable\Block\BlockName;
  16. use Pimcore\Model;
  17. use Pimcore\Tool\HtmlUtils;
  18. /**
  19.  * @method \Pimcore\Model\Document\Editable\Dao getDao()
  20.  */
  21. class Block extends Model\Document\Editable implements BlockInterface
  22. {
  23.     /**
  24.      * @internal
  25.      */
  26.     const ATTRIBUTE_IGNORE_EDITMODE_INDICES '_block_ignore_extra_editmode_indices';
  27.     /**
  28.      * Contains an array of indices, which represent the order of the elements in the block
  29.      *
  30.      * @internal
  31.      *
  32.      * @var array
  33.      */
  34.     protected $indices = [];
  35.     /**
  36.      * Current step of the block while iteration
  37.      *
  38.      * @internal
  39.      *
  40.      * @var int
  41.      */
  42.     protected $current 0;
  43.     /**
  44.      * {@inheritdoc}
  45.      */
  46.     public function getType()
  47.     {
  48.         return 'block';
  49.     }
  50.     /**
  51.      * {@inheritdoc}
  52.      */
  53.     public function getData()
  54.     {
  55.         return $this->indices;
  56.     }
  57.     /**
  58.      * {@inheritdoc}
  59.      */
  60.     public function admin()
  61.     {
  62.         // nothing to do
  63.         return '';
  64.     }
  65.     /**
  66.      * {@inheritdoc}
  67.      */
  68.     public function frontend()
  69.     {
  70.         // nothing to do
  71.         return '';
  72.     }
  73.     /**
  74.      * {@inheritdoc}
  75.      */
  76.     public function setDataFromResource($data)
  77.     {
  78.         $this->indices \Pimcore\Tool\Serialize::unserialize($data);
  79.         return $this;
  80.     }
  81.     /**
  82.      * {@inheritdoc}
  83.      */
  84.     public function setDataFromEditmode($data)
  85.     {
  86.         $this->indices $data;
  87.         return $this;
  88.     }
  89.     /**
  90.      * @internal
  91.      *
  92.      * @return $this
  93.      */
  94.     protected function setDefault()
  95.     {
  96.         if (empty($this->indices) && isset($this->config['default']) && $this->config['default']) {
  97.             for ($i 0$i < (int)$this->config['default']; $i++) {
  98.                 $this->indices[$i] = $i 1;
  99.             }
  100.         }
  101.         return $this;
  102.     }
  103.     /**
  104.      * {@inheritdoc}
  105.      */
  106.     public function getIterator()
  107.     {
  108.         while ($this->loop()) {
  109.             yield $this->getCurrentIndex();
  110.         }
  111.         if ($this->getEditmode() && !$this->isIgnoreEditmodeIndices()) {
  112.             // yeah, I know the following is f******* crazy :D
  113.             $this->current 0;
  114.             $indicesBackup $this->indices;
  115.             $this->indices[0] = 1000000;
  116.             $this->getBlockState()->pushBlock(BlockName::createFromEditable($this));
  117.             $this->blockConstruct();
  118.             $blockStartHtml $this->blockStart(truetrue);
  119.             ob_start();
  120.             $editableDefCollector $this->getEditableDefinitionCollector();
  121.             $editableDefCollector->stashPush();
  122.             yield $this->getCurrentIndex() + 1;
  123.             $blockEndHtml $this->blockEnd(true);
  124.             $this->blockDestruct();
  125.             $blockState $this->getBlockState();
  126.             if ($blockState->hasBlocks()) {
  127.                 $blockState->popBlock();
  128.             }
  129.             $templateEditableDefinitions $editableDefCollector->getDefinitions();
  130.             $editableDefCollector->stashPull();
  131.             $this->config['template'] = [
  132.                 'html' => $blockStartHtml ob_get_clean() . $blockEndHtml,
  133.                 'editables' => $templateEditableDefinitions,
  134.             ];
  135.             $editableDefCollector->add($this);
  136.             $this->indices $indicesBackup;
  137.         }
  138.     }
  139.     /**
  140.      * @internal
  141.      *
  142.      * @return bool
  143.      */
  144.     public function loop()
  145.     {
  146.         $manual false;
  147.         if (($this->config['manual'] ?? false) == true) {
  148.             $manual true;
  149.         }
  150.         $this->setDefault();
  151.         if ($this->current 0) {
  152.             if (!$manual) {
  153.                 $this->blockDestruct();
  154.                 $this->blockEnd();
  155.             }
  156.         } else {
  157.             if (!$manual) {
  158.                 $this->start();
  159.             }
  160.         }
  161.         if ($this->current count($this->indices) && $this->current $this->config['limit']) {
  162.             if (!$manual) {
  163.                 $this->blockConstruct();
  164.                 $this->blockStart();
  165.             }
  166.             return true;
  167.         } else {
  168.             if (!$manual) {
  169.                 $this->end();
  170.             }
  171.             return false;
  172.         }
  173.     }
  174.     /**
  175.      * {@inheritdoc}
  176.      */
  177.     protected function getEditmodeElementAttributes(): array
  178.     {
  179.         $attributes parent::getEditmodeElementAttributes();
  180.         $attributes array_merge($attributes, [
  181.             'name' => $this->getName(),
  182.             'type' => $this->getType(),
  183.         ]);
  184.         return $attributes;
  185.     }
  186.     /**
  187.      * {@inheritdoc}
  188.      */
  189.     public function start()
  190.     {
  191.         // set name suffix for the whole block element, this will be added to all child elements of the block
  192.         $this->getBlockState()->pushBlock(BlockName::createFromEditable($this));
  193.         $attributes $this->getEditmodeElementAttributes();
  194.         $attributeString HtmlUtils::assembleAttributeString($attributes);
  195.         $this->outputEditmode('<div ' $attributeString '>');
  196.         return $this;
  197.     }
  198.     /**
  199.      * {@inheritdoc}
  200.      */
  201.     public function end()
  202.     {
  203.         $this->current 0;
  204.         // remove the current block which was set by $this->start()
  205.         $blockState $this->getBlockState();
  206.         if ($blockState->hasBlocks()) {
  207.             $blockState->popBlock();
  208.         }
  209.         $this->outputEditmode('</div>');
  210.     }
  211.     /**
  212.      * {@inheritdoc}
  213.      */
  214.     public function blockConstruct()
  215.     {
  216.         // set the current block suffix for the child elements (0, 1, 3, ...)
  217.         // this will be removed in blockDestruct
  218.         $this->getBlockState()->pushIndex($this->indices[$this->current] ?? 0);
  219.     }
  220.     /**
  221.      * {@inheritdoc}
  222.      */
  223.     public function blockDestruct()
  224.     {
  225.         $blockState $this->getBlockState();
  226.         if ($blockState->hasIndexes()) {
  227.             $blockState->popIndex();
  228.         }
  229.     }
  230.     /**
  231.      * {@inheritdoc}
  232.      */
  233.     public function blockStart($showControls true$return false)
  234.     {
  235.         $attr $this->getBlockAttributes();
  236.         $outerAttributes = [
  237.             'key' => $this->indices[$this->current] ?? null,
  238.         ];
  239.         $oAttr HtmlUtils::assembleAttributeString($outerAttributes);
  240.         $html '<div class="pimcore_block_entry" ' $oAttr ' ' $attr '>';
  241.         if ($showControls) {
  242.             $html .= $this->blockControls(true);
  243.         }
  244.         if ($return) {
  245.             return $html;
  246.         }
  247.         $this->outputEditmode($html);
  248.     }
  249.     /**
  250.      * Custom position of button controls between blockStart -> blockEnd
  251.      *
  252.      * @param bool $return
  253.      */
  254.     public function blockControls($return false)
  255.     {
  256.         $attr $this->getBlockAttributes();
  257.         $html = <<<EOT
  258. <div class="pimcore_block_buttons" $attr>
  259.     <div class="pimcore_block_amount" $attr></div>
  260.     <div class="pimcore_block_plus" $attr></div>
  261.     <div class="pimcore_block_minus" $attr></div>
  262.     <div class="pimcore_block_up" $attr></div>
  263.     <div class="pimcore_block_down" $attr></div>
  264.     <div class="pimcore_block_clear" $attr></div>
  265. </div>
  266. EOT;
  267.         $this->current++;
  268.         if ($return) {
  269.             return $html;
  270.         }
  271.         $this->outputEditmode($html);
  272.     }
  273.     /**
  274.      * {@inheritdoc}
  275.      */
  276.     public function blockEnd($return false)
  277.     {
  278.         // close outer element
  279.         $html '</div>';
  280.         if ($return) {
  281.             return $html;
  282.         }
  283.         $this->outputEditmode($html);
  284.     }
  285.     /**
  286.      * {@inheritdoc}
  287.      */
  288.     public function setConfig($config)
  289.     {
  290.         if (empty($config['limit'])) {
  291.             $config['limit'] = 1000000;
  292.         }
  293.         $this->config $config;
  294.         if (($this->config['manual'] ?? false) === true) {
  295.             $this->config['reload'] = true;
  296.         }
  297.         return $this;
  298.     }
  299.     /**
  300.      * {@inheritdoc}
  301.      */
  302.     public function getCount()
  303.     {
  304.         return count($this->indices);
  305.     }
  306.     /**
  307.      * {@inheritdoc}
  308.      */
  309.     public function getCurrent()
  310.     {
  311.         return $this->current 1;
  312.     }
  313.     /**
  314.      * {@inheritdoc}
  315.      */
  316.     public function getCurrentIndex()
  317.     {
  318.         return $this->indices[$this->getCurrent()] ?? 0;
  319.     }
  320.     /**
  321.      * @return array
  322.      */
  323.     public function getIndices()
  324.     {
  325.         return $this->indices;
  326.     }
  327.     /**
  328.      * If object was serialized, set the counter back to 0
  329.      */
  330.     public function __wakeup()
  331.     {
  332.         $this->current 0;
  333.     }
  334.     /**
  335.      * {@inheritdoc}
  336.      */
  337.     public function isEmpty()
  338.     {
  339.         return !(bool) count($this->indices);
  340.     }
  341.     /**
  342.      * @return Block\Item[]
  343.      */
  344.     public function getElements()
  345.     {
  346.         $document $this->getDocument();
  347.         // https://github.com/pimcore/pimcore/issues/6629
  348.         if (!$document instanceof Model\Document\PageSnippet) {
  349.             return [];
  350.         }
  351.         $parentBlockNames $this->getParentBlockNames();
  352.         $parentBlockNames[] = $this->getName();
  353.         $list = [];
  354.         foreach ($this->getData() as $index) {
  355.             $list[] = new Block\Item($document$parentBlockNames, (int)$index);
  356.         }
  357.         return $list;
  358.     }
  359.     /**
  360.      * @return string
  361.      */
  362.     private function getBlockAttributes(): string
  363.     {
  364.         $attributes = [
  365.             'data-name' => $this->getName(),
  366.             'data-real-name' => $this->getRealName(),
  367.         ];
  368.         return HtmlUtils::assembleAttributeString($attributes);
  369.     }
  370.     /**
  371.      * @return bool
  372.      */
  373.     private function isIgnoreEditmodeIndices(): bool
  374.     {
  375.         $requestStack \Pimcore::getContainer()->get('request_stack');
  376.         $request $requestStack->getCurrentRequest();
  377.         if ($request === null) {
  378.             return false;
  379.         }
  380.         return $request->get(self::ATTRIBUTE_IGNORE_EDITMODE_INDICESfalse);
  381.     }
  382. }