vendor/madeyourday/contao-rocksolid-custom-elements/src/Element/CustomElement.php line 41

Open in your IDE?
  1. <?php
  2. /*
  3.  * Copyright MADE/YOUR/DAY OG <mail@madeyourday.net>
  4.  *
  5.  * For the full copyright and license information, please view the LICENSE
  6.  * file that was distributed with this source code.
  7.  */
  8. namespace MadeYourDay\RockSolidCustomElements\Element;
  9. use Contao\ContentElement;
  10. use Contao\ContentModel;
  11. use Contao\Image\PictureConfiguration;
  12. use Contao\Input;
  13. use Contao\ModuleModel;
  14. use Contao\StringUtil;
  15. use Contao\System;
  16. use Contao\Validator;
  17. use MadeYourDay\RockSolidColumns\Element\ColumnsStart;
  18. use MadeYourDay\RockSolidCustomElements\Template\CustomTemplate;
  19. use MadeYourDay\RockSolidCustomElements\CustomElements;
  20. use Symfony\Component\HttpFoundation\Request;
  21. /**
  22.  * Custom content element and frontend module
  23.  *
  24.  * @author Martin Auswöger <martin@madeyourday.net>
  25.  */
  26. class CustomElement extends ContentElement
  27. {
  28.     /**
  29.      * @var string Template
  30.      */
  31.     protected $strTemplate 'rsce_default';
  32.     /**
  33.      * Find the correct template and parse it
  34.      *
  35.      * @return string Parsed template
  36.      */
  37.     public function generate()
  38.     {
  39.         $this->strTemplate $this->customTpl ?: $this->type;
  40.         // Return output for the backend if in BE mode
  41.         if (($output $this->rsceGetBackendOutput()) !== null) {
  42.             return $output;
  43.         }
  44.         try {
  45.             return parent::generate();
  46.         }
  47.         catch (\Exception $exception) {
  48.             if (System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest(System::getContainer()->get('request_stack')->getCurrentRequest() ?? Request::create(''))) {
  49.                 $template = new CustomTemplate($this->strTemplate);
  50.                 $template->setData($this->Template->getData());
  51.                 $this->Template $template;
  52.                 return $this->Template->parse();
  53.             }
  54.             throw $exception;
  55.         }
  56.     }
  57.     /**
  58.      * Generate backend output if TL_MODE is set to BE
  59.      *
  60.      * @return string|null Backend output or null
  61.      */
  62.     public function rsceGetBackendOutput()
  63.     {
  64.         if (!System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest(System::getContainer()->get('request_stack')->getCurrentRequest() ?? Request::create(''))) {
  65.             return null;
  66.         }
  67.         $config CustomElements::getConfigByType($this->type) ?: array();
  68.         // Handle newsletter output the same way as the frontend
  69.         if (!empty($config['isNewsletter'])) {
  70.             if (Input::get('do') === 'newsletter') {
  71.                 return null;
  72.             }
  73.             foreach(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $entry) {
  74.                 $method $entry['class'] . '::' $entry['function'];
  75.                 if (
  76.                     $entry['file'] === System::getContainer()->getParameter('kernel.project_dir') . '/system/modules/newsletter/classes/Newsletter.php'
  77.                     || $entry['file'] === System::getContainer()->getParameter('kernel.project_dir') . '/vendor/contao/newsletter-bundle/src/Resources/contao/classes/Newsletter.php'
  78.                     || $entry['file'] === System::getContainer()->getParameter('kernel.project_dir') . '/vendor/contao/newsletter-bundle/contao/classes/Newsletter.php'
  79.                     || $method === 'Contao\\Newsletter::send'
  80.                     || $method === 'tl_newsletter::listNewsletters'
  81.                 ) {
  82.                     return null;
  83.                 }
  84.             }
  85.         }
  86.         if (!empty($config['beTemplate'])) {
  87.             if (!isset($this->arrData['wildcard'])) {
  88.                 $label CustomElements::getLabelTranslated($config['label']);
  89.                 $this->arrData['wildcard'] = '### ' mb_strtoupper(is_array($label) ? $label[0] : $label) . ' ###';
  90.             }
  91.             if (!isset($this->arrData['title'])) {
  92.                 $this->arrData['title'] = $this->headline;
  93.             }
  94.             if (
  95.                 !isset($this->arrData['link'])
  96.                 && !isset($this->arrData['href'])
  97.                 && $this->objModel instanceof ModuleModel
  98.             ) {
  99.                 $this->arrData['link'] = $this->name;
  100.                 $this->arrData['href'] = 'contao?do=themes&amp;table=tl_module&amp;act=edit&amp;id=' $this->id;
  101.             }
  102.             $this->strTemplate $config['beTemplate'];
  103.             return null;
  104.         }
  105.         if (
  106.             in_array($this->type$GLOBALS['TL_WRAPPERS']['start'])
  107.             || in_array($this->type$GLOBALS['TL_WRAPPERS']['stop'])
  108.             || in_array($this->type$GLOBALS['TL_WRAPPERS']['separator'])
  109.         ) {
  110.             return '';
  111.         }
  112.         return null;
  113.     }
  114.     /**
  115.      * Parse the json data and pass it to the template
  116.      *
  117.      * @return void
  118.      */
  119.     public function compile()
  120.     {
  121.         // Add an image
  122.         if ($this->addImage && trim($this->singleSRC)) {
  123.             $figure System::getContainer()
  124.                 ->get('contao.image.studio')
  125.                 ->createFigureBuilder()
  126.                 ->from($this->singleSRC)
  127.                 ->setSize(StringUtil::deserialize($this->arrData['size'] ?? null) ?: null)
  128.                 ->enableLightbox((bool) ($this->arrData['fullsize'] ?? false))
  129.                 ->setLightboxSize(StringUtil::deserialize($this->arrData['lightboxSize'] ?? null) ?: null)
  130.                 ->setMetadata((new ContentModel())->setRow($this->arrData)->getOverwriteMetadata())
  131.                 ->buildIfResourceExists();
  132.             if ($figure) {
  133.                 $figure->applyLegacyTemplateData($this->Templatenull$this->arrData['floating'] ?? null);
  134.             }
  135.         }
  136.         $data = array();
  137.         if ($this->rsce_data && substr($this->rsce_data01) === '{') {
  138.             $data json_decode($this->rsce_data);
  139.         }
  140.         $data $this->deserializeDataRecursive($data);
  141.         foreach ($data as $key => $value) {
  142.             $this->Template->$key $value;
  143.         }
  144.         $self $this;
  145.         $this->Template->getImageObject = function() use($self) {
  146.             return call_user_func_array(array($self'getImageObject'), func_get_args());
  147.         };
  148.         $this->Template->getColumnClassName = function() use($self) {
  149.             return call_user_func_array(array($self'getColumnClassName'), func_get_args());
  150.         };
  151.     }
  152.     /**
  153.      * Deserialize all data recursively
  154.      *
  155.      * @param  array|object $data data array or object
  156.      * @return array|object       data passed in with deserialized values
  157.      */
  158.     protected function deserializeDataRecursive($data)
  159.     {
  160.         foreach ($data as $key => $value) {
  161.             if (is_string($value) && trim($value)) {
  162.                 if (is_object($data)) {
  163.                     $data->$key StringUtil::deserialize($value);
  164.                 }
  165.                 else {
  166.                     $data[$key] = StringUtil::deserialize($value);
  167.                 }
  168.             }
  169.             else if (is_array($value) || is_object($value)) {
  170.                 if (is_object($data)) {
  171.                     $data->$key $this->deserializeDataRecursive($value);
  172.                 }
  173.                 else {
  174.                     $data[$key] = $this->deserializeDataRecursive($value);
  175.                 }
  176.             }
  177.         }
  178.         if ($data instanceof \stdClass) {
  179.             $return = new class extends \stdClass{
  180.                 public function __get($name) {
  181.                     return null;
  182.                 }
  183.             };
  184.             foreach ($data as $key => $value) {
  185.                 $return->$key $value;
  186.             }
  187.             $data $return;
  188.         }
  189.         return $data;
  190.     }
  191.     /**
  192.      * Get an image object from id/uuid and an optional size configuration
  193.      *
  194.      * @param  int|string                        $id         ID, UUID string or binary
  195.      * @param  string|array|PictureConfiguration $size       [width, height, mode] optionally serialized or a config object
  196.      * @param  int                               $maxSize    Gets passed to addImageToTemplate as $intMaxWidth
  197.      * @param  string                            $lightboxId Gets passed to addImageToTemplate as $strLightboxId
  198.      * @param  array                             $item       Gets merged and passed to addImageToTemplate as $arrItem
  199.      * @return object                                        Image object (similar as addImageToTemplate)
  200.      */
  201.     public function getImageObject($id$size null$deprecated null$lightboxId null$item = array())
  202.     {
  203.         if (!$id) {
  204.             return null;
  205.         }
  206.         $figure System::getContainer()
  207.             ->get('contao.image.studio')
  208.             ->createFigureBuilder()
  209.             ->from($id)
  210.             ->setSize($size)
  211.             ->enableLightbox((bool) ($item['fullsize'] ?? false))
  212.             ->setLightboxGroupIdentifier($lightboxId)
  213.             ->setLightboxSize(StringUtil::deserialize($item['lightboxSize'] ?? null) ?: null)
  214.             ->setMetadata((new ContentModel())->setRow($item)->getOverwriteMetadata())
  215.             ->buildIfResourceExists();
  216.         if (null === $figure) {
  217.             return null;
  218.         }
  219.         return (object) array_merge($figure->getLegacyTemplateData(), ['figure' => $figure]);
  220.     }
  221.     /**
  222.      * Get the column class name for the specified index
  223.      *
  224.      * @param  int    $index Index of the column
  225.      * @return string        Class name(s)
  226.      */
  227.     public function getColumnClassName($index)
  228.     {
  229.         if (!class_exists(ColumnsStart::class)) {
  230.             return '';
  231.         }
  232.         $config ColumnsStart::getColumnsConfiguration($this->arrData);
  233.         $classes = array('rs-column');
  234.         foreach ($config as $name => $media) {
  235.             $classes array_merge($classes$media[$index count($media)]);
  236.             if ($index count($media)) {
  237.                 $classes[] = '-' $name '-first-row';
  238.             }
  239.         }
  240.         return implode(' '$classes);
  241.     }
  242. }