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

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