vendor/numero2/contao-marketing-suite/src/Resources/contao/library/MarketingSuite/Hooks/Hooks.php line 149

Open in your IDE?
  1. <?php
  2. /**
  3.  * Contao Open Source CMS
  4.  *
  5.  * Copyright (c) 2005-2021 Leo Feyer
  6.  *
  7.  * @package   Contao Marketing Suite
  8.  * @author    Benny Born <benny.born@numero2.de>
  9.  * @author    Michael Bösherz <michael.boesherz@numero2.de>
  10.  * @license   Commercial
  11.  * @copyright 2021 numero2 - Agentur für digitales Marketing
  12.  */
  13. namespace numero2\MarketingSuite\Hooks;
  14. use Contao\Backend;
  15. use Contao\CMSConfig;
  16. use Contao\Controller;
  17. use Contao\CoreBundle\Exception\InternalServerErrorHttpException;
  18. use Contao\CoreBundle\Exception\NoContentResponseException;
  19. use Contao\CoreBundle\Exception\ResponseException;
  20. use Contao\Dbafs;
  21. use Contao\DC_CMSFile;
  22. use Contao\FilesModel;
  23. use Contao\Input;
  24. use Contao\StringUtil;
  25. use Contao\Widget;
  26. use numero2\MarketingSuite\Widget\ElementStyle;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  29. class Hooks extends Backend {
  30.     /**
  31.      * Validate a custom regular expression
  32.      *
  33.      * @param string $strRgxp
  34.      * @param mixed $varValue
  35.      * @param \Widget $objWidget
  36.      *
  37.      * @return bool
  38.      */
  39.     public static function validateRgxp$strRgxp$varValueWidget $objWidget ) {
  40.         switch( $strRgxp ) {
  41.             case 'natural_min_4_weeks':
  42.                 self::validateRgxp('natural'$varValue$objWidget);
  43.                 $aMin = [
  44.                     'day' => 28
  45.                 ,   'week' => 4
  46.                 ,   'month' => 1
  47.                 ];
  48.                 $unit array_keys($aMin)[0];
  49.                 if( !empty($objWidget->value['unit']) ){
  50.                     $unit $objWidget->value['unit'];
  51.                 }
  52.                 $postUnit Input::post($objWidget->name);
  53.                 if( !empty($postUnit['unit']) ){
  54.                     $unit $postUnit['unit'];
  55.                 }
  56.                 if( $varValue $aMin[$unit] ) {
  57.                     $objWidget->addError($GLOBALS['TL_LANG']['ERR']['natural_min_4_weeks']);
  58.                 }
  59.                 if( $varValue <= ) {
  60.                     $objWidget->addError($GLOBALS['TL_LANG']['ERR']['natural_greater_0']);
  61.                 }
  62.                 return true;
  63.                 break;
  64.             case 'cms_url':
  65.                 if( preg_match('/^{{[^{}]+}}$/'$varValue) ) {
  66.                     return true;
  67.                 }
  68.                 $varValue Controller::replaceInsertTags($varValue);
  69.                 $parsed parse_url($varValue);
  70.                 if( !is_array($parsed) ) {
  71.                     $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['cms_url_parse_failed'], $varValue));
  72.                 }
  73.                 if( !isset($parsed['scheme']) ) {
  74.                     $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['cms_url_scheme_missing'], $varValue));
  75.                 }
  76.                 if( !isset($parsed['host']) ) {
  77.                     $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['cms_url_host_missing'], $varValue));
  78.                 }
  79.                 return true;
  80.         }
  81.         return false;
  82.     }
  83.     /**
  84.      * Perform pre action hook
  85.      *
  86.      * @param string $strAction
  87.      */
  88.     public function executePreActions$strAction ) {
  89.         if( $strAction === 'updateElementPreview' ) {
  90.             $oElement null;
  91.             $oElement = new ElementStyle();
  92.             $dc = (object) [
  93.                 'table' => Input::get('table')
  94.             ,   'activeRecord' => (object) [
  95.                     'id' => Input::post('id')
  96.                 ,   'type' => Input::post('type')
  97.                 ]
  98.             ];
  99.             $sMarkup '';
  100.             $sMarkup $oElement->generatePreview$dc$_POST );
  101.             $oResponse null;
  102.             $oResponse = new ResponseController::replaceOldBePaths($sMarkup) );
  103.             throw new ResponseException($oResponse);
  104.         }
  105.     }
  106.     /**
  107.      * This will be called when the system will be initialized.
  108.      */
  109.     public static function initializeSystem() {
  110.         //initialize CMSConfig
  111.         CMSConfig::getInstance();
  112.     }
  113.     /**
  114.      * Will provide the useful postActionHook features from the core for our
  115.      * own DC_CMSFile data container
  116.      *
  117.      * @param string $strAction
  118.      * @param \DC_CMSFile $dc
  119.      *
  120.      * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
  121.      * @throws \Contao\CoreBundle\Exception\ResponseException
  122.      * @throws \Contao\CoreBundle\Exception\NoContentResponseException
  123.      * @throws \Contao\CoreBundle\Exception\InternalServerErrorHttpException
  124.      */
  125.     public function postActionHookForDC_CMSFile$strAction$dc ) {
  126.         // only use when DC_CMSFile
  127.         if( !$dc instanceof DC_CMSFile ) {
  128.             return ;
  129.         }
  130.         switch( $strAction ) {
  131.             // Load nodes of the file tree
  132.             case 'loadFiletree':
  133.                 $varValue null;
  134.                 $strField $dc->field Input::post('name');
  135.                 // Call the load_callback
  136.                 if( \is_array($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'] ?? null) ) {
  137.                     foreach( $GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'] as $callback ) {
  138.                         if( \is_array($callback) ) {
  139.                             $this->import($callback[0]);
  140.                             $varValue $this->{$callback[0]}->{$callback[1]}($varValue$dc);
  141.                         } else if( \is_callable($callback) ) {
  142.                             $varValue $callback($varValue$dc);
  143.                         }
  144.                     }
  145.                 }
  146.                 /** @var FileSelector $strClass */
  147.                 $strClass $GLOBALS['BE_FFL']['fileSelector'];
  148.                 /** @var FileSelector $objWidget */
  149.                 $objWidget = new $strClass($strClass::getAttributesFromDca($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField], $dc->field$varValue$strField$dc->table$dc));
  150.                 // Load a particular node
  151.                 if( Input::post('folder'true) != '' )  {
  152.                     throw new ResponseException($this->convertToResponse($objWidget->generateAjax(Input::post('folder'true), Input::post('field'), (int) Input::post('level'))));
  153.                 }
  154.                 throw new ResponseException($this->convertToResponse($objWidget->generate()));
  155.             // Reload the page/file picker
  156.             case 'reloadPagetree':
  157.             case 'reloadFiletree':
  158.                 $intId Input::get('id');
  159.                 $strField $dc->inputName Input::post('name');
  160.                 // Handle the keys in "edit multiple" mode
  161.                 if( Input::get('act') == 'editAll' ) {
  162.                     $intId preg_replace('/.*_([0-9a-zA-Z]+)$/''$1'$strField);
  163.                     $strField preg_replace('/(.*)_[0-9a-zA-Z]+$/''$1'$strField);
  164.                 }
  165.                 $dc->field $strField;
  166.                 // The field does not exist
  167.                 if( !isset($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]) ) {
  168.                     $this->log('Field "' $strField '" does not exist in DCA "' $dc->table '"'__METHOD__TL_ERROR);
  169.                     throw new BadRequestHttpException('Bad request');
  170.                 }
  171.                 $objRow null;
  172.                 $varValue null;
  173.                 // Load the value
  174.                 if( Input::get('act') != 'overrideAll' ) {
  175.                     $varValue CMSConfig::get($strField);
  176.                 }
  177.                 // Call the load_callback
  178.                 if( \is_array($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'] ?? null) ) {
  179.                     foreach( $GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'] as $callback ) {
  180.                         if( \is_array($callback) ) {
  181.                             $this->import($callback[0]);
  182.                             $varValue $this->{$callback[0]}->{$callback[1]}($varValue$dc);
  183.                         } else if( \is_callable($callback) ) {
  184.                             $varValue $callback($varValue$dc);
  185.                         }
  186.                     }
  187.                 }
  188.                 // Set the new value
  189.                 $varValue Input::post('value'true);
  190.                 $strKey = ($strAction == 'reloadPagetree') ? 'pageTree' 'fileTree';
  191.                 // Convert the selected values
  192.                 if( $varValue != '' ) {
  193.                     $varValue StringUtil::trimsplit("\t"$varValue);
  194.                     // Automatically add resources to the DBAFS
  195.                     if( $strKey == 'fileTree' ) {
  196.                         foreach( $varValue as $k=>$v ) {
  197.                             $v rawurldecode($v);
  198.                             if( Dbafs::shouldBeSynchronized($v) ) {
  199.                                 $objFile FilesModel::findByPath($v);
  200.                                 if( $objFile === null ) {
  201.                                     $objFile Dbafs::addResource($v);
  202.                                 }
  203.                                 $varValue[$k] = $objFile->uuid;
  204.                             }
  205.                         }
  206.                     }
  207.                     $varValue serialize($varValue);
  208.                 }
  209.                 /** @var FileTree|PageTree $strClass */
  210.                 $strClass $GLOBALS['BE_FFL'][$strKey];
  211.                 /** @var FileTree|PageTree $objWidget */
  212.                 $objWidget = new $strClass($strClass::getAttributesFromDca($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField], $dc->inputName$varValue$strField$dc->table$dc));
  213.                 throw new ResponseException($this->convertToResponse($objWidget->generate()));
  214.             // Toggle subpalettes
  215.             case 'toggleSubpalette':
  216.                 $this->import('BackendUser''User');
  217.                 // Check whether the field is a selector field and allowed for regular users (thanks to Fabian Mihailowitsch) (see #4427)
  218.                 if( !\is_array($GLOBALS['TL_DCA'][$dc->table]['palettes']['__selector__'] ?? null) || !\in_array(Input::post('field'), $GLOBALS['TL_DCA'][$dc->table]['palettes']['__selector__'] ?? []) || (($GLOBALS['TL_DCA'][$dc->table]['fields'][Input::post('field')]['exclude']??null) && !$this->User->hasAccess($dc->table '::' Input::post('field'), 'alexf')) ) {
  219.                     $this->log('Field "' Input::post('field') . '" is not an allowed selector field (possible SQL injection attempt)'__METHOD__TL_ERROR);
  220.                     throw new BadRequestHttpException('Bad request');
  221.                 }
  222.                 $val = ((Input::post('state') == 1) ? true false);
  223.                 CMSConfig::persist(Input::post('field'), $val);
  224.                 if( Input::post('load') ) {
  225.                     CMSConfig::set(Input::post('field'), $val);
  226.                     throw new ResponseException($this->convertToResponse($dc->edit(falseInput::post('id'))));
  227.                 }
  228.                 throw new NoContentResponseException();
  229.             // DropZone file upload
  230.             case 'fileupload':
  231.                 $dc->move(true);
  232.                 throw new InternalServerErrorHttpException();
  233.         }
  234.     }
  235.     /**
  236.      * Convert a string to a response object
  237.      *
  238.      * @param string $str
  239.      *
  240.      * @return \Symfony\Component\HttpFoundation\Response
  241.      */
  242.     protected function convertToResponse$str ) {
  243.         return new ResponseController::replaceOldBePaths($str) );
  244.     }
  245. }