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

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