vendor/contao/core-bundle/src/Resources/contao/classes/Hybrid.php line 220

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of Contao.
  4.  *
  5.  * (c) Leo Feyer
  6.  *
  7.  * @license LGPL-3.0-or-later
  8.  */
  9. namespace Contao;
  10. use Contao\Model\Collection;
  11. /**
  12.  * Parent class for objects that can be modules or content elements.
  13.  *
  14.  * @property string $headline
  15.  * @property string $cssID
  16.  * @property string $space
  17.  * @property string $typePrefix
  18.  * @property string $hl
  19.  * @property string $attributes
  20.  */
  21. abstract class Hybrid extends Frontend
  22. {
  23.     /**
  24.      * Key
  25.      * @var string
  26.      */
  27.     protected $strKey;
  28.     /**
  29.      * Table
  30.      * @var string
  31.      */
  32.     protected $strTable;
  33.     /**
  34.      * Template
  35.      * @var string
  36.      */
  37.     protected $strTemplate;
  38.     /**
  39.      * Column
  40.      * @var string
  41.      */
  42.     protected $strColumn;
  43.     /**
  44.      * Model
  45.      * @var Model
  46.      */
  47.     protected $objModel;
  48.     /**
  49.      * Parent element
  50.      * @var Model
  51.      */
  52.     protected $objParent;
  53.     /**
  54.      * Current record
  55.      * @var array
  56.      */
  57.     protected $arrData = array();
  58.     /**
  59.      * Style array
  60.      * @var array
  61.      */
  62.     protected $arrStyle = array();
  63.     /**
  64.      * Initialize the object
  65.      *
  66.      * @param ContentModel|ModuleModel $objElement
  67.      * @param string                   $strColumn
  68.      */
  69.     public function __construct($objElement$strColumn='main')
  70.     {
  71.         parent::__construct();
  72.         // Store the parent element (see #4556)
  73.         if ($objElement instanceof Model || $objElement instanceof Collection)
  74.         {
  75.             /** @var ContentModel|ModuleModel $objModel */
  76.             $objModel $objElement;
  77.             if ($objModel instanceof Collection)
  78.             {
  79.                 $objModel $objModel->current();
  80.             }
  81.             $this->objParent $objModel;
  82.         }
  83.         if (!$this->strKey || !$this->strTable)
  84.         {
  85.             return;
  86.         }
  87.         $strModelClass Model::getClassFromTable($this->strTable);
  88.         // Load the model
  89.         if (class_exists($strModelClass))
  90.         {
  91.             /** @var Model|null $objHybrid */
  92.             $objHybrid $strModelClass::findByPk($objElement->{$this->strKey});
  93.             if ($objHybrid === null)
  94.             {
  95.                 return;
  96.             }
  97.             $this->objModel $objHybrid;
  98.         }
  99.         // Directly query the database if there is no model class
  100.         else
  101.         {
  102.             $objHybrid $this->Database->prepare("SELECT * FROM " $this->strTable " WHERE id=?")
  103.                                         ->limit(1)
  104.                                         ->execute($objElement->{$this->strKey});
  105.             if ($objHybrid->numRows 1)
  106.             {
  107.                 return;
  108.             }
  109.         }
  110.         $cssID = array();
  111.         $this->arrData $objHybrid->row();
  112.         // Get the CSS ID from the parent element (!)
  113.         $this->cssID StringUtil::deserialize($objElement->cssIDtrue);
  114.         // Override the CSS ID (see #305)
  115.         if (!empty($this->cssID[0]))
  116.         {
  117.             $cssID[0] = $this->cssID[0];
  118.         }
  119.         // Merge the CSS classes (see #6011)
  120.         if (!empty($this->cssID[1]))
  121.         {
  122.             $cssID[1] = trim(($cssID[1] ?? '') . ' ' $this->cssID[1]);
  123.         }
  124.         $this->cssID $cssID;
  125.         $this->typePrefix $objElement->typePrefix;
  126.         $arrHeadline StringUtil::deserialize($objElement->headline);
  127.         $this->headline = \is_array($arrHeadline) ? $arrHeadline['value'] ?? '' $arrHeadline;
  128.         $this->hl $arrHeadline['unit'] ?? 'h1';
  129.         $this->strColumn $strColumn;
  130.     }
  131.     /**
  132.      * Set an object property
  133.      *
  134.      * @param string $strKey
  135.      * @param mixed  $varValue
  136.      */
  137.     public function __set($strKey$varValue)
  138.     {
  139.         $this->arrData[$strKey] = $varValue;
  140.     }
  141.     /**
  142.      * Return an object property
  143.      *
  144.      * @param string $strKey
  145.      *
  146.      * @return mixed
  147.      */
  148.     public function __get($strKey)
  149.     {
  150.         return $this->arrData[$strKey] ?? parent::__get($strKey);
  151.     }
  152.     /**
  153.      * Check whether a property is set
  154.      *
  155.      * @param string $strKey
  156.      *
  157.      * @return boolean
  158.      */
  159.     public function __isset($strKey)
  160.     {
  161.         return isset($this->arrData[$strKey]);
  162.     }
  163.     /**
  164.      * Return the model
  165.      *
  166.      * @return Model
  167.      */
  168.     public function getModel()
  169.     {
  170.         return $this->objModel;
  171.     }
  172.     /**
  173.      * Return the parent object
  174.      *
  175.      * @return object
  176.      */
  177.     public function getParent()
  178.     {
  179.         return $this->objParent;
  180.     }
  181.     /**
  182.      * Parse the template
  183.      *
  184.      * @return string
  185.      */
  186.     public function generate()
  187.     {
  188.         if ($this->isHidden())
  189.         {
  190.             return '';
  191.         }
  192.         $this->Template = new FrontendTemplate($this->strTemplate);
  193.         $this->Template->setData($this->arrData);
  194.         $this->compile();
  195.         $this->Template->style = !empty($this->arrStyle) ? implode(' '$this->arrStyle) : '';
  196.         $this->Template->class trim($this->typePrefix $this->strKey ' ' . ($this->cssID[1] ?? ''));
  197.         $this->Template->cssID = !empty($this->cssID[0]) ? ' id="' $this->cssID[0] . '"' '';
  198.         $this->Template->inColumn $this->strColumn;
  199.         if (!$this->Template->headline)
  200.         {
  201.             $this->Template->headline $this->headline;
  202.         }
  203.         if (!$this->Template->hl)
  204.         {
  205.             $this->Template->hl $this->hl;
  206.         }
  207.         if (!empty($this->objParent->classes) && \is_array($this->objParent->classes))
  208.         {
  209.             $this->Template->class .= ' ' implode(' '$this->objParent->classes);
  210.         }
  211.         return $this->Template->parse();
  212.     }
  213.     protected function isHidden()
  214.     {
  215.         // Only content models can be invisible
  216.         if (!$this->objParent instanceof ContentModel)
  217.         {
  218.             return false;
  219.         }
  220.         // Skip unsaved elements (see #2708)
  221.         if (isset($this->objParent->tstamp) && !$this->objParent->tstamp)
  222.         {
  223.             return true;
  224.         }
  225.         $isInvisible $this->objParent->invisible || ($this->objParent->start && $this->objParent->start time()) || ($this->objParent->stop && $this->objParent->stop <= time());
  226.         // The element is visible, so show it
  227.         if (!$isInvisible)
  228.         {
  229.             return false;
  230.         }
  231.         $tokenChecker System::getContainer()->get('contao.security.token_checker');
  232.         // Preview mode is enabled, so show the element
  233.         if ($tokenChecker->isPreviewMode())
  234.         {
  235.             return false;
  236.         }
  237.         $request System::getContainer()->get('request_stack')->getCurrentRequest();
  238.         // We are in the back end, so show the element
  239.         if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
  240.         {
  241.             return false;
  242.         }
  243.         return true;
  244.     }
  245.     /**
  246.      * Compile the current element
  247.      */
  248.     abstract protected function compile();
  249. }
  250. class_alias(Hybrid::class, 'Hybrid');