trimsplit() публичный статический Метод

Split a string into fragments, remove whitespace and return fragments as array
public static trimsplit ( string $strPattern, string $strString ) : array
$strPattern string The split pattern
$strString string The input string
Результат array The fragments array
Пример #1
0
 /**
  * Display a wildcard in the back end
  *
  * @return string
  */
 public function generate()
 {
     if (TL_MODE == 'BE') {
         /** @var BackendTemplate|object $objTemplate */
         $objTemplate = new \BackendTemplate('be_wildcard');
         $objTemplate->wildcard = '### ' . Utf8::strtoupper($GLOBALS['TL_LANG']['FMD']['rssReader'][0]) . ' ###';
         $objTemplate->title = $this->headline;
         $objTemplate->id = $this->id;
         $objTemplate->link = $this->name;
         $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id;
         return $objTemplate->parse();
     }
     $this->objFeed = new \SimplePie();
     $arrUrls = \StringUtil::trimsplit('[\\n\\t ]', trim($this->rss_feed));
     if (count($arrUrls) > 1) {
         $this->objFeed->set_feed_url($arrUrls);
     } else {
         $this->objFeed->set_feed_url($arrUrls[0]);
     }
     $this->objFeed->set_output_encoding(\Config::get('characterSet'));
     $this->objFeed->set_cache_location(TL_ROOT . '/system/tmp');
     $this->objFeed->enable_cache(false);
     if ($this->rss_cache > 0) {
         $this->objFeed->enable_cache(true);
         $this->objFeed->set_cache_duration($this->rss_cache);
     }
     if (!$this->objFeed->init()) {
         $this->log('Error importing RSS feed "' . $this->rss_feed . '"', __METHOD__, TL_ERROR);
         return '';
     }
     $this->objFeed->handle_content_type();
     return parent::generate();
 }
Пример #2
0
 /**
  * Initialize the object
  *
  * @param string  $strTable
  * @param integer $intPid
  */
 public function __construct($strTable, $intPid)
 {
     $this->import('Database');
     parent::__construct();
     $this->strTable = $strTable;
     $this->intPid = $intPid;
     // Store the path if it is an editable file
     if ($strTable == 'tl_files') {
         $objFile = \FilesModel::findByPk($intPid);
         if ($objFile !== null && in_array($objFile->extension, \StringUtil::trimsplit(',', strtolower(\Config::get('editableFiles'))))) {
             $this->strPath = $objFile->path;
         }
     }
 }
Пример #3
0
 /**
  * Ajax actions that do require a data container object
  *
  * @param DataContainer $dc
  *
  * @throws NoContentResponseException
  * @throws ResponseException
  * @throws BadRequestHttpException
  */
 public function executePostActions(DataContainer $dc)
 {
     header('Content-Type: text/html; charset=' . \Config::get('characterSet'));
     // Bypass any core logic for non-core drivers (see #5957)
     if (!$dc instanceof DC_File && !$dc instanceof DC_Folder && !$dc instanceof DC_Table) {
         $this->executePostActionsHook($dc);
         throw new NoContentResponseException();
     }
     switch ($this->strAction) {
         // Load nodes of the page structure tree
         case 'loadStructure':
             throw new ResponseException($this->convertToResponse($dc->ajaxTreeView($this->strAjaxId, intval(\Input::post('level')))));
             // Load nodes of the file manager tree
         // Load nodes of the file manager tree
         case 'loadFileManager':
             throw new ResponseException($this->convertToResponse($dc->ajaxTreeView(\Input::post('folder', true), intval(\Input::post('level')))));
             // Load nodes of the page tree
         // Load nodes of the page tree
         case 'loadPagetree':
             $varValue = null;
             $strField = $dc->field = \Input::post('name');
             // Call the load_callback
             if (is_array($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'])) {
                 foreach ($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'] as $callback) {
                     if (is_array($callback)) {
                         $this->import($callback[0]);
                         $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $dc);
                     } elseif (is_callable($callback)) {
                         $varValue = $callback($varValue, $dc);
                     }
                 }
             }
             /** @var PageSelector $strClass */
             $strClass = $GLOBALS['BE_FFL']['pageSelector'];
             /** @var PageSelector $objWidget */
             $objWidget = new $strClass($strClass::getAttributesFromDca($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField], $dc->field, $varValue, $strField, $dc->table, $dc));
             throw new ResponseException($this->convertToResponse($objWidget->generateAjax($this->strAjaxId, \Input::post('field'), intval(\Input::post('level')))));
             // Load nodes of the file tree
         // Load nodes of the file tree
         case 'loadFiletree':
             $varValue = null;
             $strField = $dc->field = \Input::post('name');
             // Call the load_callback
             if (is_array($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'])) {
                 foreach ($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'] as $callback) {
                     if (is_array($callback)) {
                         $this->import($callback[0]);
                         $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $dc);
                     } elseif (is_callable($callback)) {
                         $varValue = $callback($varValue, $dc);
                     }
                 }
             }
             /** @var FileSelector $strClass */
             $strClass = $GLOBALS['BE_FFL']['fileSelector'];
             /** @var FileSelector $objWidget */
             $objWidget = new $strClass($strClass::getAttributesFromDca($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField], $dc->field, $varValue, $strField, $dc->table, $dc));
             // Load a particular node
             if (\Input::post('folder', true) != '') {
                 throw new ResponseException($this->convertToResponse($objWidget->generateAjax(\Input::post('folder', true), \Input::post('field'), intval(\Input::post('level')))));
             }
             throw new ResponseException($this->convertToResponse($objWidget->generate()));
             // Reload the page/file picker
         // Reload the page/file picker
         case 'reloadPagetree':
         case 'reloadFiletree':
             $intId = \Input::get('id');
             $strField = $dc->inputName = \Input::post('name');
             // Handle the keys in "edit multiple" mode
             if (\Input::get('act') == 'editAll') {
                 $intId = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', $strField);
                 $strField = preg_replace('/(.*)_[0-9a-zA-Z]+$/', '$1', $strField);
             }
             $dc->field = $strField;
             // The field does not exist
             if (!isset($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField])) {
                 $this->log('Field "' . $strField . '" does not exist in DCA "' . $dc->table . '"', __METHOD__, TL_ERROR);
                 throw new BadRequestHttpException('Bad request');
             }
             $objRow = null;
             $varValue = null;
             // Load the value
             if (\Input::get('act') != 'overrideAll') {
                 if ($GLOBALS['TL_DCA'][$dc->table]['config']['dataContainer'] == 'File') {
                     $varValue = \Config::get($strField);
                 } elseif ($intId > 0 && $this->Database->tableExists($dc->table)) {
                     $objRow = $this->Database->prepare("SELECT * FROM " . $dc->table . " WHERE id=?")->execute($intId);
                     // The record does not exist
                     if ($objRow->numRows < 1) {
                         $this->log('A record with the ID "' . $intId . '" does not exist in table "' . $dc->table . '"', __METHOD__, TL_ERROR);
                         throw new BadRequestHttpException('Bad request');
                     }
                     $varValue = $objRow->{$strField};
                     $dc->activeRecord = $objRow;
                 }
             }
             // Call the load_callback
             if (is_array($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'])) {
                 foreach ($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField]['load_callback'] as $callback) {
                     if (is_array($callback)) {
                         $this->import($callback[0]);
                         $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $dc);
                     } elseif (is_callable($callback)) {
                         $varValue = $callback($varValue, $dc);
                     }
                 }
             }
             // Set the new value
             $varValue = \Input::post('value', true);
             $strKey = $this->strAction == 'reloadPagetree' ? 'pageTree' : 'fileTree';
             // Convert the selected values
             if ($varValue != '') {
                 $varValue = \StringUtil::trimsplit("\t", $varValue);
                 // Automatically add resources to the DBAFS
                 if ($strKey == 'fileTree') {
                     foreach ($varValue as $k => $v) {
                         if (\Dbafs::shouldBeSynchronized($v)) {
                             $objFile = \FilesModel::findByPath($v);
                             if ($objFile === null) {
                                 $objFile = \Dbafs::addResource($v);
                             }
                             $varValue[$k] = $objFile->uuid;
                         }
                     }
                 }
                 $varValue = serialize($varValue);
             }
             /** @var FileTree|PageTree $strClass */
             $strClass = $GLOBALS['BE_FFL'][$strKey];
             /** @var FileTree|PageTree $objWidget */
             $objWidget = new $strClass($strClass::getAttributesFromDca($GLOBALS['TL_DCA'][$dc->table]['fields'][$strField], $dc->inputName, $varValue, $strField, $dc->table, $dc));
             throw new ResponseException($this->convertToResponse($objWidget->generate()));
             // Feature/unfeature an element
         // Feature/unfeature an element
         case 'toggleFeatured':
             if (class_exists($dc->table, false)) {
                 $dca = new $dc->table();
                 if (method_exists($dca, 'toggleFeatured')) {
                     $dca->toggleFeatured(\Input::post('id'), \Input::post('state') == 1 ? true : false);
                 }
             }
             throw new NoContentResponseException();
             // Toggle subpalettes
         // Toggle subpalettes
         case 'toggleSubpalette':
             $this->import('BackendUser', 'User');
             // Check whether the field is a selector field and allowed for regular users (thanks to Fabian Mihailowitsch) (see #4427)
             if (!is_array($GLOBALS['TL_DCA'][$dc->table]['palettes']['__selector__']) || !in_array(\Input::post('field'), $GLOBALS['TL_DCA'][$dc->table]['palettes']['__selector__']) || $GLOBALS['TL_DCA'][$dc->table]['fields'][\Input::post('field')]['exclude'] && !$this->User->hasAccess($dc->table . '::' . \Input::post('field'), 'alexf')) {
                 $this->log('Field "' . \Input::post('field') . '" is not an allowed selector field (possible SQL injection attempt)', __METHOD__, TL_ERROR);
                 throw new BadRequestHttpException('Bad request');
             }
             if ($dc instanceof DC_Table) {
                 if (\Input::get('act') == 'editAll') {
                     $this->strAjaxId = preg_replace('/.*_([0-9a-zA-Z]+)$/', '$1', \Input::post('id'));
                     $this->Database->prepare("UPDATE " . $dc->table . " SET " . \Input::post('field') . "='" . (intval(\Input::post('state') == 1) ? 1 : '') . "' WHERE id=?")->execute($this->strAjaxId);
                     if (\Input::post('load')) {
                         echo $dc->editAll($this->strAjaxId, \Input::post('id'));
                     }
                 } else {
                     $this->Database->prepare("UPDATE " . $dc->table . " SET " . \Input::post('field') . "='" . (intval(\Input::post('state') == 1) ? 1 : '') . "' WHERE id=?")->execute($dc->id);
                     if (\Input::post('load')) {
                         throw new ResponseException($this->convertToResponse($dc->edit(false, \Input::post('id'))));
                     }
                 }
             } elseif ($dc instanceof DC_File) {
                 $val = intval(\Input::post('state') == 1) ? true : false;
                 \Config::persist(\Input::post('field'), $val);
                 if (\Input::post('load')) {
                     \Config::set(\Input::post('field'), $val);
                     throw new ResponseException($this->convertToResponse($dc->edit(false, \Input::post('id'))));
                 }
             }
             throw new NoContentResponseException();
             // DropZone file upload
         // DropZone file upload
         case 'fileupload':
             $dc->move();
             throw new NoContentResponseException();
             // HOOK: pass unknown actions to callback functions
         // HOOK: pass unknown actions to callback functions
         default:
             $this->executePostActionsHook($dc);
             throw new NoContentResponseException();
     }
 }
Пример #4
0
 /**
  * Converts a palette string to a configuration array.
  *
  * @param string $palette The palette string
  *
  * @return array The configuration array
  */
 private function explode($palette)
 {
     if ('' === (string) $palette) {
         return [];
     }
     $legendCount = 0;
     $legendMap = [];
     $groups = StringUtil::trimsplit(';', $palette);
     foreach ($groups as $group) {
         $hide = false;
         $fields = StringUtil::trimsplit(',', $group);
         if (preg_match('#\\{(.+?)(:hide)?\\}#', $fields[0], $matches)) {
             $legend = $matches[1];
             $hide = count($matches) > 2 && ':hide' === $matches[2];
             array_shift($fields);
         } else {
             $legend = $legendCount++;
         }
         $legendMap[$legend] = ['fields' => $fields, 'hide' => $hide];
     }
     return $legendMap;
 }
Пример #5
0
 /**
  * Generate the module
  */
 protected function compile()
 {
     // Mark the x and y parameter as used (see #4277)
     if (isset($_GET['x'])) {
         \Input::get('x');
         \Input::get('y');
     }
     // Trigger the search module from a custom form
     if (!isset($_GET['keywords']) && \Input::post('FORM_SUBMIT') == 'tl_search') {
         $_GET['keywords'] = \Input::post('keywords');
         $_GET['query_type'] = \Input::post('query_type');
         $_GET['per_page'] = \Input::post('per_page');
     }
     $blnFuzzy = $this->fuzzy;
     $strQueryType = \Input::get('query_type') ?: $this->queryType;
     $strKeywords = trim(\Input::get('keywords'));
     $this->Template->uniqueId = $this->id;
     $this->Template->queryType = $strQueryType;
     $this->Template->keyword = \StringUtil::specialchars($strKeywords);
     $this->Template->keywordLabel = $GLOBALS['TL_LANG']['MSC']['keywords'];
     $this->Template->optionsLabel = $GLOBALS['TL_LANG']['MSC']['options'];
     $this->Template->search = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['searchLabel']);
     $this->Template->matchAll = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['matchAll']);
     $this->Template->matchAny = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['matchAny']);
     $this->Template->action = ampersand(\Environment::get('indexFreeRequest'));
     $this->Template->advanced = $this->searchType == 'advanced';
     // Redirect page
     if ($this->jumpTo && ($objTarget = $this->objModel->getRelated('jumpTo')) instanceof PageModel) {
         /** @var PageModel $objTarget */
         $this->Template->action = $objTarget->getFrontendUrl();
     }
     $this->Template->pagination = '';
     $this->Template->results = '';
     // Execute the search if there are keywords
     if ($strKeywords != '' && $strKeywords != '*' && !$this->jumpTo) {
         // Reference page
         if ($this->rootPage > 0) {
             $intRootId = $this->rootPage;
             $arrPages = $this->Database->getChildRecords($this->rootPage, 'tl_page');
             array_unshift($arrPages, $this->rootPage);
         } else {
             /** @var PageModel $objPage */
             global $objPage;
             $intRootId = $objPage->rootId;
             $arrPages = $this->Database->getChildRecords($objPage->rootId, 'tl_page');
         }
         // HOOK: add custom logic (see #5223)
         if (isset($GLOBALS['TL_HOOKS']['customizeSearch']) && is_array($GLOBALS['TL_HOOKS']['customizeSearch'])) {
             foreach ($GLOBALS['TL_HOOKS']['customizeSearch'] as $callback) {
                 $this->import($callback[0]);
                 $this->{$callback[0]}->{$callback[1]}($arrPages, $strKeywords, $strQueryType, $blnFuzzy);
             }
         }
         // Return if there are no pages
         if (!is_array($arrPages) || empty($arrPages)) {
             return;
         }
         $strCachePath = str_replace(TL_ROOT . DIRECTORY_SEPARATOR, '', \System::getContainer()->getParameter('kernel.cache_dir'));
         $arrResult = null;
         $strChecksum = md5($strKeywords . $strQueryType . $intRootId . $blnFuzzy);
         $query_starttime = microtime(true);
         $strCacheFile = $strCachePath . '/contao/search/' . $strChecksum . '.json';
         // Load the cached result
         if (file_exists(TL_ROOT . '/' . $strCacheFile)) {
             $objFile = new \File($strCacheFile);
             if ($objFile->mtime > time() - 1800) {
                 $arrResult = json_decode($objFile->getContent(), true);
             } else {
                 $objFile->delete();
             }
         }
         // Cache the result
         if ($arrResult === null) {
             try {
                 $objSearch = \Search::searchFor($strKeywords, $strQueryType == 'or', $arrPages, 0, 0, $blnFuzzy);
                 $arrResult = $objSearch->fetchAllAssoc();
             } catch (\Exception $e) {
                 $this->log('Website search failed: ' . $e->getMessage(), __METHOD__, TL_ERROR);
                 $arrResult = array();
             }
             \File::putContent($strCacheFile, json_encode($arrResult));
         }
         $query_endtime = microtime(true);
         // Sort out protected pages
         if (\Config::get('indexProtected') && !BE_USER_LOGGED_IN) {
             $this->import('FrontendUser', 'User');
             foreach ($arrResult as $k => $v) {
                 if ($v['protected']) {
                     if (!FE_USER_LOGGED_IN) {
                         unset($arrResult[$k]);
                     } else {
                         $groups = \StringUtil::deserialize($v['groups']);
                         if (!is_array($groups) || empty($groups) || !count(array_intersect($groups, $this->User->groups))) {
                             unset($arrResult[$k]);
                         }
                     }
                 }
             }
             $arrResult = array_values($arrResult);
         }
         $count = count($arrResult);
         $this->Template->count = $count;
         $this->Template->page = null;
         $this->Template->keywords = $strKeywords;
         // No results
         if ($count < 1) {
             $this->Template->header = sprintf($GLOBALS['TL_LANG']['MSC']['sEmpty'], $strKeywords);
             $this->Template->duration = substr($query_endtime - $query_starttime, 0, 6) . ' ' . $GLOBALS['TL_LANG']['MSC']['seconds'];
             return;
         }
         $from = 1;
         $to = $count;
         // Pagination
         if ($this->perPage > 0) {
             $id = 'page_s' . $this->id;
             $page = \Input::get($id) !== null ? \Input::get($id) : 1;
             $per_page = \Input::get('per_page') ?: $this->perPage;
             // Do not index or cache the page if the page number is outside the range
             if ($page < 1 || $page > max(ceil($count / $per_page), 1)) {
                 throw new PageNotFoundException('Page not found: ' . \Environment::get('uri'));
             }
             $from = ($page - 1) * $per_page + 1;
             $to = $from + $per_page > $count ? $count : $from + $per_page - 1;
             // Pagination menu
             if ($to < $count || $from > 1) {
                 $objPagination = new \Pagination($count, $per_page, \Config::get('maxPaginationLinks'), $id);
                 $this->Template->pagination = $objPagination->generate("\n  ");
             }
             $this->Template->page = $page;
         }
         // Get the results
         for ($i = $from - 1; $i < $to && $i < $count; $i++) {
             /** @var FrontendTemplate|object $objTemplate */
             $objTemplate = new \FrontendTemplate($this->searchTpl);
             $objTemplate->url = $arrResult[$i]['url'];
             $objTemplate->link = $arrResult[$i]['title'];
             $objTemplate->href = $arrResult[$i]['url'];
             $objTemplate->title = \StringUtil::specialchars($arrResult[$i]['title']);
             $objTemplate->class = ($i == $from - 1 ? 'first ' : '') . ($i == $to - 1 || $i == $count - 1 ? 'last ' : '') . ($i % 2 == 0 ? 'even' : 'odd');
             $objTemplate->relevance = sprintf($GLOBALS['TL_LANG']['MSC']['relevance'], number_format($arrResult[$i]['relevance'] / $arrResult[0]['relevance'] * 100, 2) . '%');
             $objTemplate->filesize = $arrResult[$i]['filesize'];
             $objTemplate->matches = $arrResult[$i]['matches'];
             $arrContext = array();
             $arrMatches = \StringUtil::trimsplit(',', $arrResult[$i]['matches']);
             // Get the context
             foreach ($arrMatches as $strWord) {
                 $arrChunks = array();
                 preg_match_all('/(^|\\b.{0,' . $this->contextLength . '}\\PL)' . str_replace('+', '\\+', $strWord) . '(\\PL.{0,' . $this->contextLength . '}\\b|$)/ui', $arrResult[$i]['text'], $arrChunks);
                 foreach ($arrChunks[0] as $strContext) {
                     $arrContext[] = ' ' . $strContext . ' ';
                 }
             }
             // Shorten the context and highlight all keywords
             if (!empty($arrContext)) {
                 $objTemplate->context = trim(\StringUtil::substrHtml(implode('…', $arrContext), $this->totalLength));
                 $objTemplate->context = preg_replace('/(\\PL)(' . implode('|', $arrMatches) . ')(\\PL)/ui', '$1<mark class="highlight">$2</mark>$3', $objTemplate->context);
                 $objTemplate->hasContext = true;
             }
             $this->Template->results .= $objTemplate->parse();
         }
         $this->Template->header = vsprintf($GLOBALS['TL_LANG']['MSC']['sResults'], array($from, $to, $count, $strKeywords));
         $this->Template->duration = substr($query_endtime - $query_starttime, 0, 6) . ' ' . $GLOBALS['TL_LANG']['MSC']['seconds'];
     }
 }
Пример #6
0
    /**
     * Generate the filter panel and return it as HTML string
     *
     * @param integer $intFilterPanel
     *
     * @return string
     */
    protected function filterMenu($intFilterPanel)
    {
        /** @var AttributeBagInterface $objSessionBag */
        $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend');
        $fields = '';
        $this->bid = 'tl_buttons_a';
        $sortingFields = array();
        $session = $objSessionBag->all();
        $filter = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4 ? $this->strTable . '_' . CURRENT_ID : $this->strTable;
        // Get the sorting fields
        foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'] as $k => $v) {
            if (intval($v['filter']) == $intFilterPanel) {
                $sortingFields[] = $k;
            }
        }
        // Return if there are no sorting fields
        if (empty($sortingFields)) {
            return '';
        }
        // Set filter from user input
        if (\Input::post('FORM_SUBMIT') == 'tl_filters') {
            foreach ($sortingFields as $field) {
                if (\Input::post($field, true) != 'tl_' . $field) {
                    $session['filter'][$filter][$field] = \Input::post($field, true);
                } else {
                    unset($session['filter'][$filter][$field]);
                }
            }
            $objSessionBag->replace($session);
        } else {
            foreach ($sortingFields as $field) {
                if (isset($session['filter'][$filter][$field])) {
                    // Sort by day
                    if (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(5, 6))) {
                        if ($session['filter'][$filter][$field] == '') {
                            $this->procedure[] = $field . "=''";
                        } else {
                            $objDate = new \Date($session['filter'][$filter][$field]);
                            $this->procedure[] = $field . ' BETWEEN ? AND ?';
                            $this->values[] = $objDate->dayBegin;
                            $this->values[] = $objDate->dayEnd;
                        }
                    } elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(7, 8))) {
                        if ($session['filter'][$filter][$field] == '') {
                            $this->procedure[] = $field . "=''";
                        } else {
                            $objDate = new \Date($session['filter'][$filter][$field]);
                            $this->procedure[] = $field . ' BETWEEN ? AND ?';
                            $this->values[] = $objDate->monthBegin;
                            $this->values[] = $objDate->monthEnd;
                        }
                    } elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(9, 10))) {
                        if ($session['filter'][$filter][$field] == '') {
                            $this->procedure[] = $field . "=''";
                        } else {
                            $objDate = new \Date($session['filter'][$filter][$field]);
                            $this->procedure[] = $field . ' BETWEEN ? AND ?';
                            $this->values[] = $objDate->yearBegin;
                            $this->values[] = $objDate->yearEnd;
                        }
                    } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['multiple']) {
                        // CSV lists (see #2890)
                        if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['csv'])) {
                            $this->procedure[] = $this->Database->findInSet('?', $field, true);
                            $this->values[] = $session['filter'][$filter][$field];
                        } else {
                            $this->procedure[] = $field . ' LIKE ?';
                            $this->values[] = '%"' . $session['filter'][$filter][$field] . '"%';
                        }
                    } else {
                        $this->procedure[] = $field . '=?';
                        $this->values[] = $session['filter'][$filter][$field];
                    }
                }
            }
        }
        // Add sorting options
        foreach ($sortingFields as $cnt => $field) {
            $arrValues = array();
            $arrProcedure = array();
            if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4) {
                $arrProcedure[] = 'pid=?';
                $arrValues[] = CURRENT_ID;
            }
            if (!$this->treeView && !empty($this->root) && is_array($this->root)) {
                $arrProcedure[] = "id IN(" . implode(',', array_map('intval', $this->root)) . ")";
            }
            // Check for a static filter (see #4719)
            if (!empty($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['filter']) && is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['filter'])) {
                foreach ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['filter'] as $fltr) {
                    $arrProcedure[] = $fltr[0];
                    $arrValues[] = $fltr[1];
                }
            }
            // Support empty ptable fields
            if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable']) {
                $arrProcedure[] = $this->ptable == 'tl_article' ? "(ptable=? OR ptable='')" : "ptable=?";
                $arrValues[] = $this->ptable;
            }
            $what = $field;
            // Optimize the SQL query (see #8485)
            if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'])) {
                // Sort by day
                if (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(5, 6))) {
                    $what = "UNIX_TIMESTAMP(FROM_UNIXTIME({$field} , '%%Y-%%m-%%d')) AS {$field}";
                } elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(7, 8))) {
                    $what = "UNIX_TIMESTAMP(FROM_UNIXTIME({$field} , '%%Y-%%m-01')) AS {$field}";
                } elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(9, 10))) {
                    $what = "UNIX_TIMESTAMP(FROM_UNIXTIME({$field} , '%%Y-01-01')) AS {$field}";
                }
            }
            $objFields = $this->Database->prepare("SELECT DISTINCT " . $what . " FROM " . $this->strTable . (is_array($arrProcedure) && strlen($arrProcedure[0]) ? ' WHERE ' . implode(' AND ', $arrProcedure) : ''))->execute($arrValues);
            // Begin select menu
            $fields .= '
<select name="' . $field . '" id="' . $field . '" class="tl_select' . (isset($session['filter'][$filter][$field]) ? ' active' : '') . '">
  <option value="tl_' . $field . '">' . (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['label']) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['label'][0] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['label']) . '</option>
  <option value="tl_' . $field . '">---</option>';
            if ($objFields->numRows) {
                $options = $objFields->fetchEach($field);
                // Sort by day
                if (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(5, 6))) {
                    $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'] == 6 ? rsort($options) : sort($options);
                    foreach ($options as $k => $v) {
                        if ($v == '') {
                            $options[$v] = '-';
                        } else {
                            $options[$v] = \Date::parse(\Config::get('dateFormat'), $v);
                        }
                        unset($options[$k]);
                    }
                } elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(7, 8))) {
                    $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'] == 8 ? rsort($options) : sort($options);
                    foreach ($options as $k => $v) {
                        if ($v == '') {
                            $options[$v] = '-';
                        } else {
                            $options[$v] = date('Y-m', $v);
                            $intMonth = date('m', $v) - 1;
                            if (isset($GLOBALS['TL_LANG']['MONTHS'][$intMonth])) {
                                $options[$v] = $GLOBALS['TL_LANG']['MONTHS'][$intMonth] . ' ' . date('Y', $v);
                            }
                        }
                        unset($options[$k]);
                    }
                } elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(9, 10))) {
                    $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'] == 10 ? rsort($options) : sort($options);
                    foreach ($options as $k => $v) {
                        if ($v == '') {
                            $options[$v] = '-';
                        } else {
                            $options[$v] = date('Y', $v);
                        }
                        unset($options[$k]);
                    }
                }
                // Manual filter
                if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['multiple']) {
                    $moptions = array();
                    // TODO: find a more effective solution
                    foreach ($options as $option) {
                        // CSV lists (see #2890)
                        if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['csv'])) {
                            $doptions = \StringUtil::trimsplit($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['csv'], $option);
                        } else {
                            $doptions = \StringUtil::deserialize($option);
                        }
                        if (is_array($doptions)) {
                            $moptions = array_merge($moptions, $doptions);
                        }
                    }
                    $options = $moptions;
                }
                $options = array_unique($options);
                $options_callback = array();
                // Call the options_callback
                if ((is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback']) || is_callable($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback'])) && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['reference']) {
                    if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback'])) {
                        $strClass = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback'][0];
                        $strMethod = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback'][1];
                        $this->import($strClass);
                        $options_callback = $this->{$strClass}->{$strMethod}($this);
                    } elseif (is_callable($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback'])) {
                        $options_callback = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options_callback']($this);
                    }
                    // Sort options according to the keys of the callback array
                    $options = array_intersect(array_keys($options_callback), $options);
                }
                $options_sorter = array();
                $blnDate = in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(5, 6, 7, 8, 9, 10));
                // Options
                foreach ($options as $kk => $vv) {
                    $value = $blnDate ? $kk : $vv;
                    // Options callback
                    if (!empty($options_callback) && is_array($options_callback)) {
                        $vv = $options_callback[$vv];
                    } elseif (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['foreignKey'])) {
                        $key = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['foreignKey'], 2);
                        $objParent = $this->Database->prepare("SELECT " . $key[1] . " AS value FROM " . $key[0] . " WHERE id=?")->limit(1)->execute($vv);
                        if ($objParent->numRows) {
                            $vv = $objParent->value;
                        }
                    } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['isBoolean'] || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['inputType'] == 'checkbox' && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['multiple']) {
                        $vv = $vv != '' ? $GLOBALS['TL_LANG']['MSC']['yes'] : $GLOBALS['TL_LANG']['MSC']['no'];
                    } elseif ($field == 'pid') {
                        $this->loadDataContainer($this->ptable);
                        $showFields = $GLOBALS['TL_DCA'][$this->ptable]['list']['label']['fields'];
                        if (!$showFields[0]) {
                            $showFields[0] = 'id';
                        }
                        $objShowFields = $this->Database->prepare("SELECT " . $showFields[0] . " FROM " . $this->ptable . " WHERE id=?")->limit(1)->execute($vv);
                        if ($objShowFields->numRows) {
                            $vv = $objShowFields->{$showFields[0]};
                        }
                    }
                    $option_label = '';
                    // Use reference array
                    if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['reference'])) {
                        $option_label = is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['reference'][$vv]) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['reference'][$vv][0] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['reference'][$vv];
                    } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['isAssociative'] || array_is_assoc($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options'])) {
                        $option_label = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['options'][$vv];
                    }
                    // No empty options allowed
                    if (!strlen($option_label)) {
                        $option_label = $vv ?: '-';
                    }
                    $options_sorter['  <option value="' . \StringUtil::specialchars($value) . '"' . (isset($session['filter'][$filter][$field]) && $value == $session['filter'][$filter][$field] ? ' selected="selected"' : '') . '>' . $option_label . '</option>'] = Utf8::toAscii($option_label);
                }
                // Sort by option values
                if (!$blnDate) {
                    natcasesort($options_sorter);
                    if (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['flag'], array(2, 4, 12))) {
                        $options_sorter = array_reverse($options_sorter, true);
                    }
                }
                $fields .= "\n" . implode("\n", array_keys($options_sorter));
            }
            // End select menu
            $fields .= '
</select> ';
            // Force a line-break after six elements (see #3777)
            if (($cnt + 1) % 6 == 0) {
                $fields .= '<br>';
            }
        }
        return '

<div class="tl_filter tl_subpanel">
<strong>' . $GLOBALS['TL_LANG']['MSC']['filter'] . ':</strong> ' . $fields . '
</div>';
    }
Пример #7
0
 /**
  * Return an array that can be used by the database installer
  *
  * @return array The data array
  */
 public function getDbInstallerArray()
 {
     $return = array();
     // Fields
     foreach ($this->arrFields as $k => $v) {
         $return['TABLE_FIELDS'][$k] = '`' . $k . '` ' . $v;
     }
     $quote = function ($item) {
         return '`' . $item . '`';
     };
     // Keys
     foreach ($this->arrKeys as $k => $v) {
         // Handle multi-column indexes (see #5556)
         if (strpos($k, ',') !== false) {
             $f = array_map($quote, \StringUtil::trimsplit(',', $k));
             $k = str_replace(',', '_', $k);
         } else {
             $f = array($quote($k));
         }
         // Handle key lengths (see #221)
         if (preg_match('/\\([0-9]+\\)/', $v)) {
             list($v, $length) = explode('(', rtrim($v, ')'));
             $f = array($quote($k) . '(' . $length . ')');
         }
         if ($v == 'primary') {
             $k = 'PRIMARY';
             $v = 'PRIMARY KEY  (' . implode(', ', $f) . ')';
         } elseif ($v == 'index') {
             $v = 'KEY `' . $k . '` (' . implode(', ', $f) . ')';
         } else {
             $v = strtoupper($v) . ' KEY `' . $k . '` (' . implode(', ', $f) . ')';
         }
         $return['TABLE_CREATE_DEFINITIONS'][$k] = $v;
     }
     $return['TABLE_OPTIONS'] = '';
     // Options
     foreach ($this->arrMeta as $k => $v) {
         if ($k == 'engine') {
             $return['TABLE_OPTIONS'] .= ' ENGINE=' . $v;
         } elseif ($k == 'charset') {
             $return['TABLE_OPTIONS'] .= ' DEFAULT CHARSET=' . $v;
         }
     }
     return $return;
 }
Пример #8
0
    /**
     * Auto-generate a form to edit the local configuration file
     *
     * @return string
     */
    public function edit()
    {
        $return = '';
        $ajaxId = null;
        if (\Environment::get('isAjaxRequest')) {
            $ajaxId = func_get_arg(1);
        }
        // Build an array from boxes and rows
        $this->strPalette = $this->getPalette();
        $boxes = \StringUtil::trimsplit(';', $this->strPalette);
        $legends = array();
        if (!empty($boxes)) {
            foreach ($boxes as $k => $v) {
                $boxes[$k] = \StringUtil::trimsplit(',', $v);
                foreach ($boxes[$k] as $kk => $vv) {
                    if (preg_match('/^\\[.*\\]$/', $vv)) {
                        continue;
                    }
                    if (preg_match('/^\\{.*\\}$/', $vv)) {
                        $legends[$k] = substr($vv, 1, -1);
                        unset($boxes[$k][$kk]);
                    } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$vv]['exclude'] || !is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$vv])) {
                        unset($boxes[$k][$kk]);
                    }
                }
                // Unset a box if it does not contain any fields
                if (empty($boxes[$k])) {
                    unset($boxes[$k]);
                }
            }
            /** @var AttributeBagInterface $objSessionBag */
            $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend');
            // Render boxes
            $class = 'tl_tbox';
            $fs = $objSessionBag->get('fieldset_states');
            $blnIsFirst = true;
            foreach ($boxes as $k => $v) {
                $strAjax = '';
                $blnAjax = false;
                $key = '';
                $cls = '';
                $legend = '';
                if (isset($legends[$k])) {
                    list($key, $cls) = explode(':', $legends[$k]);
                    $legend = "\n" . '<legend onclick="AjaxRequest.toggleFieldset(this, \'' . $key . '\', \'' . $this->strTable . '\')">' . (isset($GLOBALS['TL_LANG'][$this->strTable][$key]) ? $GLOBALS['TL_LANG'][$this->strTable][$key] : $key) . '</legend>';
                }
                if (isset($fs[$this->strTable][$key])) {
                    $class .= $fs[$this->strTable][$key] ? '' : ' collapsed';
                } else {
                    $class .= $cls && $legend ? ' ' . $cls : '';
                }
                $return .= "\n\n" . '<fieldset' . ($key ? ' id="pal_' . $key . '"' : '') . ' class="' . $class . ($legend ? '' : ' nolegend') . '">' . $legend;
                // Build rows of the current box
                foreach ($v as $vv) {
                    if ($vv == '[EOF]') {
                        if ($blnAjax && \Environment::get('isAjaxRequest')) {
                            return $strAjax . '<input type="hidden" name="FORM_FIELDS[]" value="' . \StringUtil::specialchars($this->strPalette) . '">';
                        }
                        $blnAjax = false;
                        $return .= "\n  " . '</div>';
                        continue;
                    }
                    if (preg_match('/^\\[.*\\]$/', $vv)) {
                        $thisId = 'sub_' . substr($vv, 1, -1);
                        $blnAjax = $ajaxId == $thisId && \Environment::get('isAjaxRequest') ? true : false;
                        $return .= "\n  " . '<div id="' . $thisId . '">';
                        continue;
                    }
                    $this->strField = $vv;
                    $this->strInputName = $vv;
                    $this->varValue = \Config::get($this->strField);
                    // Handle entities
                    if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'text' || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'textarea') {
                        if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['multiple']) {
                            $this->varValue = \StringUtil::deserialize($this->varValue);
                        }
                        if (!is_array($this->varValue)) {
                            $this->varValue = htmlspecialchars($this->varValue);
                        } else {
                            foreach ($this->varValue as $k => $v) {
                                $this->varValue[$k] = htmlspecialchars($v);
                            }
                        }
                    }
                    // Autofocus the first field
                    if ($blnIsFirst && $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'text') {
                        $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['autofocus'] = 'autofocus';
                        $blnIsFirst = false;
                    }
                    // Call load_callback
                    if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'])) {
                        foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'] as $callback) {
                            if (is_array($callback)) {
                                $this->import($callback[0]);
                                $this->varValue = $this->{$callback[0]}->{$callback[1]}($this->varValue, $this);
                            } elseif (is_callable($callback)) {
                                $this->varValue = $callback($this->varValue, $this);
                            }
                        }
                    }
                    // Build row
                    $blnAjax ? $strAjax .= $this->row() : ($return .= $this->row());
                }
                $class = 'tl_box';
                $return .= "\n" . '</fieldset>';
            }
        }
        $this->import('Files');
        // Check whether the target file is writeable
        if (!$this->Files->is_writeable('system/config/localconfig.php')) {
            \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['notWriteable'], 'system/config/localconfig.php'));
        }
        // Submit buttons
        $arrButtons = array();
        $arrButtons['save'] = '<button type="submit" name="save" id="save" class="tl_submit" accesskey="s">' . $GLOBALS['TL_LANG']['MSC']['save'] . '</button>';
        $arrButtons['saveNclose'] = '<button type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c">' . $GLOBALS['TL_LANG']['MSC']['saveNclose'] . '</button>';
        // Call the buttons_callback (see #4691)
        if (is_array($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'])) {
            foreach ($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'] as $callback) {
                if (is_array($callback)) {
                    $this->import($callback[0]);
                    $arrButtons = $this->{$callback[0]}->{$callback[1]}($arrButtons, $this);
                } elseif (is_callable($callback)) {
                    $arrButtons = $callback($arrButtons, $this);
                }
            }
        }
        // Add the buttons and end the form
        $return .= '
</div>

<div class="tl_formbody_submit">

<div class="tl_submit_container">
  ' . implode(' ', $arrButtons) . '
</div>

</div>
</form>

<script>
  window.addEvent(\'domready\', function() {
    Theme.focusInput("' . $this->strTable . '");
  });
</script>';
        // Begin the form (-> DO NOT CHANGE THIS ORDER -> this way the onsubmit attribute of the form can be changed by a field)
        $return = '
<div id="tl_buttons">
<a href="' . $this->getReferer(true) . '" class="header_back" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a>
</div>
' . \Message::generate() . '
<form action="' . ampersand(\Environment::get('request'), true) . '" id="' . $this->strTable . '" class="tl_form" method="post"' . (!empty($this->onsubmit) ? ' onsubmit="' . implode(' ', $this->onsubmit) . '"' : '') . '>

<div class="tl_formbody_edit">
<input type="hidden" name="FORM_SUBMIT" value="' . $this->strTable . '">
<input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '">
<input type="hidden" name="FORM_FIELDS[]" value="' . \StringUtil::specialchars($this->strPalette) . '">' . ($this->noReload ? '

<p class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['general'] . '</p>' : '') . $return;
        // Reload the page to prevent _POST variables from being sent twice
        if (\Input::post('FORM_SUBMIT') == $this->strTable && !$this->noReload) {
            // Call onsubmit_callback
            if (is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'])) {
                foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'] as $callback) {
                    if (is_array($callback)) {
                        $this->import($callback[0]);
                        $this->{$callback[0]}->{$callback[1]}($this);
                    } elseif (is_callable($callback)) {
                        $callback($this);
                    }
                }
            }
            // Reload
            if (isset($_POST['saveNclose'])) {
                \Message::reset();
                \System::setCookie('BE_PAGE_OFFSET', 0, 0);
                $this->redirect($this->getReferer());
            }
            $this->reload();
        }
        // Set the focus if there is an error
        if ($this->noReload) {
            $return .= '

<script>
  window.addEvent(\'domready\', function() {
    Backend.vScrollTo(($(\'' . $this->strTable . '\').getElement(\'label.error\').getPosition().y - 20));
  });
</script>';
        }
        return $return;
    }
Пример #9
0
 /**
  * Recursively validate an input variable
  *
  * @param mixed $varInput The user input
  *
  * @return mixed The original or modified user input
  */
 protected function validator($varInput)
 {
     if (is_array($varInput)) {
         foreach ($varInput as $k => $v) {
             $varInput[$k] = $this->validator($v);
         }
         return $varInput;
     }
     if (!$this->doNotTrim) {
         $varInput = trim($varInput);
     }
     if ($varInput == '') {
         if (!$this->mandatory) {
             return '';
         } else {
             if ($this->strLabel == '') {
                 $this->addError($GLOBALS['TL_LANG']['ERR']['mdtryNoLabel']);
             } else {
                 $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['mandatory'], $this->strLabel));
             }
         }
     }
     if ($this->minlength && $varInput != '' && Utf8::strlen($varInput) < $this->minlength) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['minlength'], $this->strLabel, $this->minlength));
     }
     if ($this->maxlength && $varInput != '' && Utf8::strlen($varInput) > $this->maxlength) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['maxlength'], $this->strLabel, $this->maxlength));
     }
     if ($this->minval && is_numeric($varInput) && $varInput < $this->minval) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['minval'], $this->strLabel, $this->minval));
     }
     if ($this->maxval && is_numeric($varInput) && $varInput > $this->maxval) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['maxval'], $this->strLabel, $this->maxval));
     }
     if ($this->rgxp != '') {
         switch ($this->rgxp) {
             // Special validation rule for style sheets
             case strncmp($this->rgxp, 'digit_', 6) === 0:
                 $textual = explode('_', $this->rgxp);
                 array_shift($textual);
                 if (in_array($varInput, $textual) || strncmp($varInput, '$', 1) === 0) {
                     break;
                 }
                 // DO NOT ADD A break; STATEMENT HERE
                 // Numeric characters (including full stop [.] and minus [-])
             // DO NOT ADD A break; STATEMENT HERE
             // Numeric characters (including full stop [.] and minus [-])
             case 'digit':
                 // Support decimal commas and convert them automatically (see #3488)
                 if (substr_count($varInput, ',') == 1 && strpos($varInput, '.') === false) {
                     $varInput = str_replace(',', '.', $varInput);
                 }
                 if (!\Validator::isNumeric($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['digit'], $this->strLabel));
                 }
                 break;
                 // Natural numbers (positive integers)
             // Natural numbers (positive integers)
             case 'natural':
                 if (!\Validator::isNatural($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['natural'], $this->strLabel));
                 }
                 break;
                 // Alphabetic characters (including full stop [.] minus [-] and space [ ])
             // Alphabetic characters (including full stop [.] minus [-] and space [ ])
             case 'alpha':
                 if (!\Validator::isAlphabetic($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['alpha'], $this->strLabel));
                 }
                 break;
                 // Alphanumeric characters (including full stop [.] minus [-], underscore [_] and space [ ])
             // Alphanumeric characters (including full stop [.] minus [-], underscore [_] and space [ ])
             case 'alnum':
                 if (!\Validator::isAlphanumeric($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['alnum'], $this->strLabel));
                 }
                 break;
                 // Do not allow any characters that are usually encoded by class Input ([#<>()\=])
             // Do not allow any characters that are usually encoded by class Input ([#<>()\=])
             case 'extnd':
                 if (!\Validator::isExtendedAlphanumeric(html_entity_decode($varInput))) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['extnd'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a valid date format
             // Check whether the current value is a valid date format
             case 'date':
                 if (!\Validator::isDate($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['date'], \Date::getInputFormat(\Date::getNumericDateFormat())));
                 } else {
                     // Validate the date (see #5086)
                     try {
                         new \Date($varInput, \Date::getNumericDateFormat());
                     } catch (\OutOfBoundsException $e) {
                         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varInput));
                     }
                 }
                 break;
                 // Check whether the current value is a valid time format
             // Check whether the current value is a valid time format
             case 'time':
                 if (!\Validator::isTime($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['time'], \Date::getInputFormat(\Date::getNumericTimeFormat())));
                 }
                 break;
                 // Check whether the current value is a valid date and time format
             // Check whether the current value is a valid date and time format
             case 'datim':
                 if (!\Validator::isDatim($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['dateTime'], \Date::getInputFormat(\Date::getNumericDatimFormat())));
                 } else {
                     // Validate the date (see #5086)
                     try {
                         new \Date($varInput, \Date::getNumericDatimFormat());
                     } catch (\OutOfBoundsException $e) {
                         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varInput));
                     }
                 }
                 break;
                 // Check whether the current value is a valid friendly name e-mail address
             // Check whether the current value is a valid friendly name e-mail address
             case 'friendly':
                 list($strName, $varInput) = \StringUtil::splitFriendlyEmail($varInput);
                 // no break;
                 // Check whether the current value is a valid e-mail address
             // no break;
             // Check whether the current value is a valid e-mail address
             case 'email':
                 if (!\Validator::isEmail($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['email'], $this->strLabel));
                 }
                 if ($this->rgxp == 'friendly' && !empty($strName)) {
                     $varInput = $strName . ' [' . $varInput . ']';
                 }
                 break;
                 // Check whether the current value is list of valid e-mail addresses
             // Check whether the current value is list of valid e-mail addresses
             case 'emails':
                 $arrEmails = \StringUtil::trimsplit(',', $varInput);
                 foreach ($arrEmails as $strEmail) {
                     $strEmail = \Idna::encodeEmail($strEmail);
                     if (!\Validator::isEmail($strEmail)) {
                         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['emails'], $this->strLabel));
                         break;
                     }
                 }
                 break;
                 // Check whether the current value is a valid URL
             // Check whether the current value is a valid URL
             case 'url':
                 if (!\Validator::isUrl($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['url'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a valid alias
             // Check whether the current value is a valid alias
             case 'alias':
                 if (!\Validator::isAlias($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['alias'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a valid folder URL alias
             // Check whether the current value is a valid folder URL alias
             case 'folderalias':
                 if (!\Validator::isFolderAlias($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['folderalias'], $this->strLabel));
                 }
                 break;
                 // Phone numbers (numeric characters, space [ ], plus [+], minus [-], parentheses [()] and slash [/])
             // Phone numbers (numeric characters, space [ ], plus [+], minus [-], parentheses [()] and slash [/])
             case 'phone':
                 if (!\Validator::isPhone(html_entity_decode($varInput))) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['phone'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a percent value
             // Check whether the current value is a percent value
             case 'prcnt':
                 if (!\Validator::isPercent($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['prcnt'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a locale
             // Check whether the current value is a locale
             case 'locale':
                 if (!\Validator::isLocale($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['locale'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a language code
             // Check whether the current value is a language code
             case 'language':
                 if (!\Validator::isLanguage($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['language'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a Google+ ID or vanity name
             // Check whether the current value is a Google+ ID or vanity name
             case 'google+':
                 if (!\Validator::isGooglePlusId($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidGoogleId'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a field name
             // Check whether the current value is a field name
             case 'fieldname':
                 if (!\Validator::isFieldName($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidFieldName'], $this->strLabel));
                 }
                 break;
                 // HOOK: pass unknown tags to callback functions
             // HOOK: pass unknown tags to callback functions
             default:
                 if (isset($GLOBALS['TL_HOOKS']['addCustomRegexp']) && is_array($GLOBALS['TL_HOOKS']['addCustomRegexp'])) {
                     foreach ($GLOBALS['TL_HOOKS']['addCustomRegexp'] as $callback) {
                         $this->import($callback[0]);
                         $break = $this->{$callback[0]}->{$callback[1]}($this->rgxp, $varInput, $this);
                         // Stop the loop if a callback returned true
                         if ($break === true) {
                             break;
                         }
                     }
                 }
                 break;
         }
     }
     if ($this->isHexColor && $varInput != '' && strncmp($varInput, '$', 1) !== 0) {
         $varInput = preg_replace('/[^a-f0-9]+/i', '', $varInput);
     }
     if ($this->nospace && preg_match('/[\\t ]+/', $varInput)) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['noSpace'], $this->strLabel));
     }
     if ($this->spaceToUnderscore) {
         $varInput = preg_replace('/\\s+/', '_', trim($varInput));
     }
     if (is_bool($this->trailingSlash) && $varInput != '') {
         $varInput = preg_replace('/\\/+$/', '', $varInput) . ($this->trailingSlash ? '/' : '');
     }
     return $varInput;
 }
Пример #10
0
 /**
  * Add enclosures to a template
  *
  * @param object $objTemplate The template object to add the enclosures to
  * @param array  $arrItem     The element or module as array
  * @param string $strKey      The name of the enclosures field in $arrItem
  */
 public static function addEnclosuresToTemplate($objTemplate, $arrItem, $strKey = 'enclosure')
 {
     $arrEnclosures = \StringUtil::deserialize($arrItem[$strKey]);
     if (!is_array($arrEnclosures) || empty($arrEnclosures)) {
         return;
     }
     $objFiles = \FilesModel::findMultipleByUuids($arrEnclosures);
     if ($objFiles === null) {
         return;
     }
     $file = \Input::get('file', true);
     // Send the file to the browser and do not send a 404 header (see #5178)
     if ($file != '') {
         while ($objFiles->next()) {
             if ($file == $objFiles->path) {
                 static::sendFileToBrowser($file);
             }
         }
         $objFiles->reset();
     }
     /** @var PageModel $objPage */
     global $objPage;
     $arrEnclosures = array();
     $allowedDownload = \StringUtil::trimsplit(',', strtolower(\Config::get('allowedDownload')));
     // Add download links
     while ($objFiles->next()) {
         if ($objFiles->type == 'file') {
             if (!in_array($objFiles->extension, $allowedDownload) || !is_file(TL_ROOT . '/' . $objFiles->path)) {
                 continue;
             }
             $objFile = new \File($objFiles->path);
             $strHref = \Environment::get('request');
             // Remove an existing file parameter (see #5683)
             if (preg_match('/(&(amp;)?|\\?)file=/', $strHref)) {
                 $strHref = preg_replace('/(&(amp;)?|\\?)file=[^&]+/', '', $strHref);
             }
             $strHref .= (strpos($strHref, '?') !== false ? '&amp;' : '?') . 'file=' . \System::urlEncode($objFiles->path);
             $arrMeta = \Frontend::getMetaData($objFiles->meta, $objPage->language);
             if (empty($arrMeta) && $objPage->rootFallbackLanguage !== null) {
                 $arrMeta = \Frontend::getMetaData($objFiles->meta, $objPage->rootFallbackLanguage);
             }
             // Use the file name as title if none is given
             if ($arrMeta['title'] == '') {
                 $arrMeta['title'] = \StringUtil::specialchars($objFile->basename);
             }
             $arrEnclosures[] = array('id' => $objFiles->id, 'uuid' => $objFiles->uuid, 'name' => $objFile->basename, 'title' => \StringUtil::specialchars(sprintf($GLOBALS['TL_LANG']['MSC']['download'], $objFile->basename)), 'link' => $arrMeta['title'], 'caption' => $arrMeta['caption'], 'href' => $strHref, 'filesize' => static::getReadableSize($objFile->filesize), 'icon' => \Image::getPath($objFile->icon), 'mime' => $objFile->mime, 'meta' => $arrMeta, 'extension' => $objFile->extension, 'path' => $objFile->dirname, 'enclosure' => $objFiles->path);
         }
     }
     $objTemplate->enclosure = $arrEnclosures;
 }
Пример #11
0
 /**
  * Generate the form
  *
  * @return string
  */
 protected function compile()
 {
     $hasUpload = false;
     $doNotSubmit = false;
     $arrSubmitted = array();
     $this->loadDataContainer('tl_form_field');
     $formId = $this->formID != '' ? 'auto_' . $this->formID : 'auto_form_' . $this->id;
     $this->Template->fields = '';
     $this->Template->hidden = '';
     $this->Template->formSubmit = $formId;
     $this->Template->method = $this->method == 'GET' ? 'get' : 'post';
     $this->initializeSession($formId);
     $arrLabels = array();
     // Get all form fields
     $arrFields = array();
     $objFields = \FormFieldModel::findPublishedByPid($this->id);
     if ($objFields !== null) {
         while ($objFields->next()) {
             if ($objFields->name != '') {
                 $arrFields[$objFields->name] = $objFields->current();
             } else {
                 $arrFields[] = $objFields->current();
             }
         }
     }
     // HOOK: compile form fields
     if (isset($GLOBALS['TL_HOOKS']['compileFormFields']) && is_array($GLOBALS['TL_HOOKS']['compileFormFields'])) {
         foreach ($GLOBALS['TL_HOOKS']['compileFormFields'] as $callback) {
             $this->import($callback[0]);
             $arrFields = $this->{$callback[0]}->{$callback[1]}($arrFields, $formId, $this);
         }
     }
     // Process the fields
     if (!empty($arrFields) && is_array($arrFields)) {
         $row = 0;
         $max_row = count($arrFields);
         foreach ($arrFields as $objField) {
             /** @var FormFieldModel $objField */
             $strClass = $GLOBALS['TL_FFL'][$objField->type];
             // Continue if the class is not defined
             if (!class_exists($strClass)) {
                 continue;
             }
             $arrData = $objField->row();
             $arrData['decodeEntities'] = true;
             $arrData['allowHtml'] = $this->allowTags;
             $arrData['rowClass'] = 'row_' . $row . ($row == 0 ? ' row_first' : ($row == $max_row - 1 ? ' row_last' : '')) . ($row % 2 == 0 ? ' even' : ' odd');
             // Increase the row count if its a password field
             if ($objField->type == 'password') {
                 ++$row;
                 ++$max_row;
                 $arrData['rowClassConfirm'] = 'row_' . $row . ($row == $max_row - 1 ? ' row_last' : '') . ($row % 2 == 0 ? ' even' : ' odd');
             }
             // Submit buttons do not use the name attribute
             if ($objField->type == 'submit') {
                 $arrData['name'] = '';
             }
             // Unset the default value depending on the field type (see #4722)
             if (!empty($arrData['value'])) {
                 if (!in_array('value', \StringUtil::trimsplit('[,;]', $GLOBALS['TL_DCA']['tl_form_field']['palettes'][$objField->type]))) {
                     $arrData['value'] = '';
                 }
             }
             /** @var Widget $objWidget */
             $objWidget = new $strClass($arrData);
             $objWidget->required = $objField->mandatory ? true : false;
             // HOOK: load form field callback
             if (isset($GLOBALS['TL_HOOKS']['loadFormField']) && is_array($GLOBALS['TL_HOOKS']['loadFormField'])) {
                 foreach ($GLOBALS['TL_HOOKS']['loadFormField'] as $callback) {
                     $this->import($callback[0]);
                     $objWidget = $this->{$callback[0]}->{$callback[1]}($objWidget, $formId, $this->arrData, $this);
                 }
             }
             // Validate the input
             if (\Input::post('FORM_SUBMIT') == $formId) {
                 $objWidget->validate();
                 // HOOK: validate form field callback
                 if (isset($GLOBALS['TL_HOOKS']['validateFormField']) && is_array($GLOBALS['TL_HOOKS']['validateFormField'])) {
                     foreach ($GLOBALS['TL_HOOKS']['validateFormField'] as $callback) {
                         $this->import($callback[0]);
                         $objWidget = $this->{$callback[0]}->{$callback[1]}($objWidget, $formId, $this->arrData, $this);
                     }
                 }
                 if ($objWidget->hasErrors()) {
                     $doNotSubmit = true;
                 } elseif ($objWidget->submitInput()) {
                     $arrSubmitted[$objField->name] = $objWidget->value;
                     $_SESSION['FORM_DATA'][$objField->name] = $objWidget->value;
                     unset($_POST[$objField->name]);
                     // see #5474
                 }
             }
             if ($objWidget instanceof \uploadable) {
                 $hasUpload = true;
             }
             if ($objWidget instanceof FormHidden) {
                 $this->Template->hidden .= $objWidget->parse();
                 --$max_row;
                 continue;
             }
             if ($objWidget->name != '' && $objWidget->label != '') {
                 $arrLabels[$objWidget->name] = $this->replaceInsertTags($objWidget->label);
                 // see #4268
             }
             $this->Template->fields .= $objWidget->parse();
             ++$row;
         }
     }
     // Process the form data
     if (\Input::post('FORM_SUBMIT') == $formId && !$doNotSubmit) {
         $this->processFormData($arrSubmitted, $arrLabels, $arrFields);
     }
     // Add a warning to the page title
     if ($doNotSubmit && !\Environment::get('isAjaxRequest')) {
         /** @var PageModel $objPage */
         global $objPage;
         $title = $objPage->pageTitle ?: $objPage->title;
         $objPage->pageTitle = $GLOBALS['TL_LANG']['ERR']['form'] . ' - ' . $title;
         $_SESSION['FILES'] = array();
         // see #3007
     }
     $strAttributes = '';
     $arrAttributes = \StringUtil::deserialize($this->attributes, true);
     if ($arrAttributes[1] != '') {
         $strAttributes .= ' class="' . $arrAttributes[1] . '"';
     }
     $formId = $arrAttributes[0] ?: 'f' . $this->id;
     // Count up form usages
     if (isset(static::$arrFormUsages[$formId])) {
         static::$arrFormUsages[$formId]++;
     } else {
         static::$arrFormUsages[$formId] = 1;
     }
     // Adjust form id
     if (static::$arrFormUsages[$formId] > 1) {
         $formId .= '_' . static::$arrFormUsages[$formId];
     }
     $this->Template->hasError = $doNotSubmit;
     $this->Template->attributes = $strAttributes;
     $this->Template->enctype = $hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
     $this->Template->formId = $formId;
     $this->Template->action = \Environment::get('indexFreeRequest');
     $this->Template->maxFileSize = $hasUpload ? $this->objModel->getMaxUploadFileSize() : false;
     $this->Template->novalidate = $this->novalidate ? ' novalidate' : '';
     // Get the target URL
     if ($this->method == 'GET' && $this->jumpTo && ($objTarget = $this->objModel->getRelated('jumpTo')) instanceof PageModel) {
         /** @var PageModel $objTarget */
         $this->Template->action = $objTarget->getFrontendUrl();
     }
     return $this->Template->parse();
 }
Пример #12
0
 /**
  * Save the current value
  *
  * @param mixed $varValue
  *
  * @throws \Exception
  */
 protected function save($varValue)
 {
     if (\Input::post('FORM_SUBMIT') != $this->strTable) {
         return;
     }
     $arrData = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField];
     // File names
     if ($this->strField == 'name') {
         if (!file_exists(TL_ROOT . '/' . $this->strPath . '/' . $this->varValue . $this->strExtension) || !$this->isMounted($this->strPath . '/' . $this->varValue . $this->strExtension) || $this->varValue === $varValue) {
             return;
         }
         $this->import('Files');
         $varValue = Utf8::toAscii($varValue);
         // Trigger the save_callback
         if (is_array($arrData['save_callback'])) {
             foreach ($arrData['save_callback'] as $callback) {
                 if (is_array($callback)) {
                     $this->import($callback[0]);
                     $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $this);
                 } elseif (is_callable($callback)) {
                     $varValue = $callback($varValue, $this);
                 }
             }
         }
         // The target exists
         if (strcasecmp($this->strPath . '/' . $this->varValue . $this->strExtension, $this->strPath . '/' . $varValue . $this->strExtension) !== 0 && file_exists(TL_ROOT . '/' . $this->strPath . '/' . $varValue . $this->strExtension)) {
             throw new \Exception(sprintf($GLOBALS['TL_LANG']['ERR']['fileExists'], $varValue));
         }
         $arrImageTypes = \StringUtil::trimsplit(',', strtolower(\Config::get('validImageTypes')));
         // Remove potentially existing thumbnails (see #6641)
         if (in_array(substr($this->strExtension, 1), $arrImageTypes)) {
             foreach (glob(TL_ROOT . '/' . \System::getContainer()->getParameter('contao.image.target_path') . '/*/' . $this->varValue . '-*' . $this->strExtension) as $strThumbnail) {
                 $this->Files->delete(str_replace(TL_ROOT . '/', '', $strThumbnail));
             }
         }
         // Rename the file
         $this->Files->rename($this->strPath . '/' . $this->varValue . $this->strExtension, $this->strPath . '/' . $varValue . $this->strExtension);
         // New folders
         if (stristr($this->intId, '__new__') !== false) {
             // Update the database
             if ($this->blnIsDbAssisted && \Dbafs::shouldBeSynchronized($this->strPath . '/' . $varValue . $this->strExtension)) {
                 $this->objActiveRecord = \Dbafs::addResource($this->strPath . '/' . $varValue . $this->strExtension);
             }
             $this->log('Folder "' . $this->strPath . '/' . $varValue . $this->strExtension . '" has been created', __METHOD__, TL_FILES);
         } else {
             // Update the database
             if ($this->blnIsDbAssisted) {
                 $syncSource = \Dbafs::shouldBeSynchronized($this->strPath . '/' . $this->varValue . $this->strExtension);
                 $syncTarget = \Dbafs::shouldBeSynchronized($this->strPath . '/' . $varValue . $this->strExtension);
                 if ($syncSource && $syncTarget) {
                     \Dbafs::moveResource($this->strPath . '/' . $this->varValue . $this->strExtension, $this->strPath . '/' . $varValue . $this->strExtension);
                 } elseif ($syncSource) {
                     \Dbafs::deleteResource($this->strPath . '/' . $this->varValue . $this->strExtension);
                 } elseif ($syncTarget) {
                     \Dbafs::addResource($this->strPath . '/' . $varValue . $this->strExtension);
                 }
             }
             $this->log('File or folder "' . $this->strPath . '/' . $this->varValue . $this->strExtension . '" has been renamed to "' . $this->strPath . '/' . $varValue . $this->strExtension . '"', __METHOD__, TL_FILES);
         }
         // Update the symlinks
         if (is_link(TL_ROOT . '/web/' . $this->strPath . '/' . $this->varValue . $this->strExtension)) {
             $this->Files->delete('web/' . $this->strPath . '/' . $this->varValue . $this->strExtension);
             SymlinkUtil::symlink($this->strPath . '/' . $varValue . $this->strExtension, 'web/' . $this->strPath . '/' . $varValue . $this->strExtension, TL_ROOT);
         }
         // Set the new value so the input field can show it
         if (\Input::get('act') == 'editAll') {
             /** @var SessionInterface $objSession */
             $objSession = \System::getContainer()->get('session');
             $session = $objSession->all();
             if (($index = array_search($this->strPath . '/' . $this->varValue . $this->strExtension, $session['CURRENT']['IDS'])) !== false) {
                 $session['CURRENT']['IDS'][$index] = $this->strPath . '/' . $varValue . $this->strExtension;
                 $objSession->replace($session);
             }
         }
         $this->varValue = $varValue;
     } elseif ($this->blnIsDbAssisted && $this->objActiveRecord !== null) {
         // Convert date formats into timestamps
         if ($varValue != '' && in_array($arrData['eval']['rgxp'], array('date', 'time', 'datim'))) {
             $objDate = new \Date($varValue, \Date::getFormatFromRgxp($arrData['eval']['rgxp']));
             $varValue = $objDate->tstamp;
         }
         // Make sure unique fields are unique
         if ($arrData['eval']['unique'] && $varValue != '' && !$this->Database->isUniqueValue($this->strTable, $this->strField, $varValue, $this->objActiveRecord->id)) {
             throw new \Exception(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $this->strField));
         }
         // Handle multi-select fields in "override all" mode
         if (\Input::get('act') == 'overrideAll' && ($arrData['inputType'] == 'checkbox' || $arrData['inputType'] == 'checkboxWizard') && $arrData['eval']['multiple']) {
             if ($this->objActiveRecord !== null) {
                 $new = \StringUtil::deserialize($varValue, true);
                 $old = \StringUtil::deserialize($this->objActiveRecord->{$this->strField}, true);
                 switch (\Input::post($this->strInputName . '_update')) {
                     case 'add':
                         $varValue = array_values(array_unique(array_merge($old, $new)));
                         break;
                     case 'remove':
                         $varValue = array_values(array_diff($old, $new));
                         break;
                     case 'replace':
                         $varValue = $new;
                         break;
                 }
                 if (!is_array($varValue) || empty($varValue)) {
                     $varValue = '';
                 } elseif (isset($arrData['eval']['csv'])) {
                     $varValue = implode($arrData['eval']['csv'], $varValue);
                     // see #2890
                 } else {
                     $varValue = serialize($varValue);
                 }
             }
         }
         // Convert arrays (see #2890)
         if ($arrData['eval']['multiple'] && isset($arrData['eval']['csv'])) {
             $varValue = implode($arrData['eval']['csv'], \StringUtil::deserialize($varValue, true));
         }
         // Trigger the save_callback
         if (is_array($arrData['save_callback'])) {
             foreach ($arrData['save_callback'] as $callback) {
                 if (is_array($callback)) {
                     $this->import($callback[0]);
                     $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $this);
                 } elseif (is_callable($callback)) {
                     $varValue = $callback($varValue, $this);
                 }
             }
         }
         // Save the value if there was no error
         if (($varValue != '' || !$arrData['eval']['doNotSaveEmpty']) && ($this->varValue != $varValue || $arrData['eval']['alwaysSave'])) {
             // If the field is a fallback field, empty all other columns
             if ($arrData['eval']['fallback'] && $varValue != '') {
                 $this->Database->execute("UPDATE " . $this->strTable . " SET " . $this->strField . "=''");
             }
             // Set the correct empty value (see #6284, #6373)
             if ($varValue === '') {
                 $varValue = \Widget::getEmptyValueByFieldType($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['sql']);
             }
             $this->objActiveRecord->{$this->strField} = $varValue;
             $this->objActiveRecord->save();
             $this->blnCreateNewVersion = true;
             $this->varValue = \StringUtil::deserialize($varValue);
         }
     }
 }
Пример #13
0
 /**
  * Replace insert tags with their values
  *
  * @param string  $strBuffer The text with the tags to be replaced
  * @param boolean $blnCache  If false, non-cacheable tags will be replaced
  *
  * @return string The text with the replaced tags
  */
 protected function doReplace($strBuffer, $blnCache)
 {
     /** @var PageModel $objPage */
     global $objPage;
     // Preserve insert tags
     if (\Config::get('disableInsertTags')) {
         return \StringUtil::restoreBasicEntities($strBuffer);
     }
     $tags = preg_split('/{{([^{}]+)}}/', $strBuffer, -1, PREG_SPLIT_DELIM_CAPTURE);
     if (count($tags) < 2) {
         return \StringUtil::restoreBasicEntities($strBuffer);
     }
     $strBuffer = '';
     // Create one cache per cache setting (see #7700)
     static $arrItCache;
     $arrCache =& $arrItCache[$blnCache];
     for ($_rit = 0, $_cnt = count($tags); $_rit < $_cnt; $_rit += 2) {
         $strBuffer .= $tags[$_rit];
         $strTag = $tags[$_rit + 1];
         // Skip empty tags
         if ($strTag == '') {
             continue;
         }
         $flags = explode('|', $strTag);
         $tag = array_shift($flags);
         $elements = explode('::', $tag);
         // Load the value from cache
         if (isset($arrCache[$strTag]) && !in_array('refresh', $flags)) {
             $strBuffer .= $arrCache[$strTag];
             continue;
         }
         // Skip certain elements if the output will be cached
         if ($blnCache) {
             if ($elements[0] == 'date' || $elements[0] == 'ua' || $elements[0] == 'post' || $elements[0] == 'file' && !\Validator::isStringUuid($elements[1]) || $elements[1] == 'back' || $elements[1] == 'referer' || $elements[0] == 'request_token' || $elements[0] == 'toggle_view' || strncmp($elements[0], 'cache_', 6) === 0 || in_array('uncached', $flags)) {
                 /** @var FragmentHandler $fragmentHandler */
                 $fragmentHandler = \System::getContainer()->get('fragment.handler');
                 $strBuffer .= $fragmentHandler->render(new ControllerReference('contao.controller.insert_tags:renderAction', ['insertTag' => '{{' . $strTag . '}}']), 'esi');
                 continue;
             }
         }
         $arrCache[$strTag] = '';
         // Replace the tag
         switch (strtolower($elements[0])) {
             // Date
             case 'date':
                 $arrCache[$strTag] = \Date::parse($elements[1] ?: \Config::get('dateFormat'));
                 break;
                 // Accessibility tags
             // Accessibility tags
             case 'lang':
                 if ($elements[1] == '') {
                     $arrCache[$strTag] = '</span>';
                 } else {
                     $arrCache[$strTag] = $arrCache[$strTag] = '<span lang="' . \StringUtil::specialchars($elements[1]) . '">';
                 }
                 break;
                 // Line break
             // Line break
             case 'br':
                 $arrCache[$strTag] = '<br>';
                 break;
                 // E-mail addresses
             // E-mail addresses
             case 'email':
             case 'email_open':
             case 'email_url':
                 if ($elements[1] == '') {
                     $arrCache[$strTag] = '';
                     break;
                 }
                 $strEmail = \StringUtil::encodeEmail($elements[1]);
                 // Replace the tag
                 switch (strtolower($elements[0])) {
                     case 'email':
                         $arrCache[$strTag] = '<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;' . $strEmail . '" class="email">' . preg_replace('/\\?.*$/', '', $strEmail) . '</a>';
                         break;
                     case 'email_open':
                         $arrCache[$strTag] = '<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;' . $strEmail . '" title="' . $strEmail . '" class="email">';
                         break;
                     case 'email_url':
                         $arrCache[$strTag] = $strEmail;
                         break;
                 }
                 break;
                 // Label tags
             // Label tags
             case 'label':
                 $keys = explode(':', $elements[1]);
                 if (count($keys) < 2) {
                     $arrCache[$strTag] = '';
                     break;
                 }
                 $file = $keys[0];
                 // Map the key (see #7217)
                 switch ($file) {
                     case 'CNT':
                         $file = 'countries';
                         break;
                     case 'LNG':
                         $file = 'languages';
                         break;
                     case 'MOD':
                     case 'FMD':
                         $file = 'modules';
                         break;
                     case 'FFL':
                         $file = 'tl_form_field';
                         break;
                     case 'CACHE':
                         $file = 'tl_page';
                         break;
                     case 'XPL':
                         $file = 'explain';
                         break;
                     case 'XPT':
                         $file = 'exception';
                         break;
                     case 'MSC':
                     case 'ERR':
                     case 'CTE':
                     case 'PTY':
                     case 'FOP':
                     case 'CHMOD':
                     case 'DAYS':
                     case 'MONTHS':
                     case 'UNITS':
                     case 'CONFIRM':
                     case 'DP':
                     case 'COLS':
                         $file = 'default';
                         break;
                 }
                 \System::loadLanguageFile($file);
                 if (count($keys) == 2) {
                     $arrCache[$strTag] = $GLOBALS['TL_LANG'][$keys[0]][$keys[1]];
                 } else {
                     $arrCache[$strTag] = $GLOBALS['TL_LANG'][$keys[0]][$keys[1]][$keys[2]];
                 }
                 break;
                 // Front end user
             // Front end user
             case 'user':
                 if (FE_USER_LOGGED_IN) {
                     $this->import('FrontendUser', 'User');
                     $value = $this->User->{$elements[1]};
                     if ($value == '') {
                         $arrCache[$strTag] = $value;
                         break;
                     }
                     $this->loadDataContainer('tl_member');
                     if ($GLOBALS['TL_DCA']['tl_member']['fields'][$elements[1]]['inputType'] == 'password') {
                         $arrCache[$strTag] = '';
                         break;
                     }
                     $value = \StringUtil::deserialize($value);
                     // Decrypt the value
                     if ($GLOBALS['TL_DCA']['tl_member']['fields'][$elements[1]]['eval']['encrypt']) {
                         $value = \Encryption::decrypt($value);
                     }
                     $rgxp = $GLOBALS['TL_DCA']['tl_member']['fields'][$elements[1]]['eval']['rgxp'];
                     $opts = $GLOBALS['TL_DCA']['tl_member']['fields'][$elements[1]]['options'];
                     $rfrc = $GLOBALS['TL_DCA']['tl_member']['fields'][$elements[1]]['reference'];
                     if ($rgxp == 'date') {
                         $arrCache[$strTag] = \Date::parse(\Config::get('dateFormat'), $value);
                     } elseif ($rgxp == 'time') {
                         $arrCache[$strTag] = \Date::parse(\Config::get('timeFormat'), $value);
                     } elseif ($rgxp == 'datim') {
                         $arrCache[$strTag] = \Date::parse(\Config::get('datimFormat'), $value);
                     } elseif (is_array($value)) {
                         $arrCache[$strTag] = implode(', ', $value);
                     } elseif (is_array($opts) && array_is_assoc($opts)) {
                         $arrCache[$strTag] = isset($opts[$value]) ? $opts[$value] : $value;
                     } elseif (is_array($rfrc)) {
                         $arrCache[$strTag] = isset($rfrc[$value]) ? is_array($rfrc[$value]) ? $rfrc[$value][0] : $rfrc[$value] : $value;
                     } else {
                         $arrCache[$strTag] = $value;
                     }
                     // Convert special characters (see #1890)
                     $arrCache[$strTag] = \StringUtil::specialchars($arrCache[$strTag]);
                 }
                 break;
                 // Link
             // Link
             case 'link':
             case 'link_open':
             case 'link_url':
             case 'link_title':
             case 'link_target':
             case 'link_name':
                 $strTarget = null;
                 // Back link
                 if ($elements[1] == 'back') {
                     $strUrl = 'javascript:history.go(-1)';
                     $strTitle = $GLOBALS['TL_LANG']['MSC']['goBack'];
                     // No language files if the page is cached
                     if (!strlen($strTitle)) {
                         $strTitle = 'Go back';
                     }
                     $strName = $strTitle;
                 } elseif (strncmp($elements[1], 'http://', 7) === 0 || strncmp($elements[1], 'https://', 8) === 0) {
                     $strUrl = $elements[1];
                     $strTitle = $elements[1];
                     $strName = str_replace(array('http://', 'https://'), '', $elements[1]);
                 } else {
                     // User login page
                     if ($elements[1] == 'login') {
                         if (!FE_USER_LOGGED_IN) {
                             break;
                         }
                         $this->import('FrontendUser', 'User');
                         $elements[1] = $this->User->loginPage;
                     }
                     $objNextPage = \PageModel::findByIdOrAlias($elements[1]);
                     if ($objNextPage === null) {
                         break;
                     }
                     // Page type specific settings (thanks to Andreas Schempp)
                     switch ($objNextPage->type) {
                         case 'redirect':
                             $strUrl = $objNextPage->url;
                             if (strncasecmp($strUrl, 'mailto:', 7) === 0) {
                                 $strUrl = \StringUtil::encodeEmail($strUrl);
                             }
                             break;
                         case 'forward':
                             if ($objNextPage->jumpTo) {
                                 /** @var PageModel $objNext */
                                 $objNext = $objNextPage->getRelated('jumpTo');
                             } else {
                                 $objNext = \PageModel::findFirstPublishedRegularByPid($objNextPage->id);
                             }
                             if ($objNext instanceof PageModel) {
                                 $strUrl = $objNext->getFrontendUrl();
                                 break;
                             }
                             // DO NOT ADD A break; STATEMENT
                         // DO NOT ADD A break; STATEMENT
                         default:
                             $strUrl = $objNextPage->getFrontendUrl();
                             break;
                     }
                     $strName = $objNextPage->title;
                     $strTarget = $objNextPage->target ? ' target="_blank"' : '';
                     $strTitle = $objNextPage->pageTitle ?: $objNextPage->title;
                 }
                 // Replace the tag
                 switch (strtolower($elements[0])) {
                     case 'link':
                         $arrCache[$strTag] = sprintf('<a href="%s" title="%s"%s>%s</a>', $strUrl, \StringUtil::specialchars($strTitle), $strTarget, $strName);
                         break;
                     case 'link_open':
                         $arrCache[$strTag] = sprintf('<a href="%s" title="%s"%s>', $strUrl, \StringUtil::specialchars($strTitle), $strTarget);
                         break;
                     case 'link_url':
                         $arrCache[$strTag] = $strUrl;
                         break;
                     case 'link_title':
                         $arrCache[$strTag] = \StringUtil::specialchars($strTitle);
                         break;
                     case 'link_target':
                         $arrCache[$strTag] = $strTarget;
                         break;
                     case 'link_name':
                         $arrCache[$strTag] = $strName;
                         break;
                 }
                 break;
                 // Closing link tag
             // Closing link tag
             case 'link_close':
             case 'email_close':
                 $arrCache[$strTag] = '</a>';
                 break;
                 // Insert article
             // Insert article
             case 'insert_article':
                 if (($strOutput = $this->getArticle($elements[1], false, true)) !== false) {
                     $arrCache[$strTag] = ltrim($strOutput);
                 } else {
                     $arrCache[$strTag] = '<p class="error">' . sprintf($GLOBALS['TL_LANG']['MSC']['invalidPage'], $elements[1]) . '</p>';
                 }
                 break;
                 // Insert content element
             // Insert content element
             case 'insert_content':
                 $arrCache[$strTag] = $this->getContentElement($elements[1]);
                 break;
                 // Insert module
             // Insert module
             case 'insert_module':
                 $arrCache[$strTag] = $this->getFrontendModule($elements[1]);
                 break;
                 // Insert form
             // Insert form
             case 'insert_form':
                 $arrCache[$strTag] = $this->getForm($elements[1]);
                 break;
                 // Article
             // Article
             case 'article':
             case 'article_open':
             case 'article_url':
             case 'article_title':
                 if (($objArticle = \ArticleModel::findByIdOrAlias($elements[1])) === null || !($objPid = $objArticle->getRelated('pid')) instanceof PageModel) {
                     break;
                 }
                 /** @var PageModel $objPid */
                 $strUrl = $objPid->getFrontendUrl('/articles/' . ($objArticle->alias ?: $objArticle->id));
                 // Replace the tag
                 switch (strtolower($elements[0])) {
                     case 'article':
                         $arrCache[$strTag] = sprintf('<a href="%s" title="%s">%s</a>', $strUrl, \StringUtil::specialchars($objArticle->title), $objArticle->title);
                         break;
                     case 'article_open':
                         $arrCache[$strTag] = sprintf('<a href="%s" title="%s">', $strUrl, \StringUtil::specialchars($objArticle->title));
                         break;
                     case 'article_url':
                         $arrCache[$strTag] = $strUrl;
                         break;
                     case 'article_title':
                         $arrCache[$strTag] = \StringUtil::specialchars($objArticle->title);
                         break;
                 }
                 break;
                 // Article teaser
             // Article teaser
             case 'article_teaser':
                 $objTeaser = \ArticleModel::findByIdOrAlias($elements[1]);
                 if ($objTeaser !== null) {
                     $arrCache[$strTag] = \StringUtil::toHtml5($objTeaser->teaser);
                 }
                 break;
                 // Last update
             // Last update
             case 'last_update':
                 $strQuery = "SELECT MAX(tstamp) AS tc";
                 $bundles = \System::getContainer()->getParameter('kernel.bundles');
                 if (isset($bundles['ContaoNewsBundle'])) {
                     $strQuery .= ", (SELECT MAX(tstamp) FROM tl_news) AS tn";
                 }
                 if (isset($bundles['ContaoCalendarBundle'])) {
                     $strQuery .= ", (SELECT MAX(tstamp) FROM tl_calendar_events) AS te";
                 }
                 $strQuery .= " FROM tl_content";
                 $objUpdate = \Database::getInstance()->query($strQuery);
                 if ($objUpdate->numRows) {
                     $arrCache[$strTag] = \Date::parse($elements[1] ?: \Config::get('datimFormat'), max($objUpdate->tc, $objUpdate->tn, $objUpdate->te));
                 }
                 break;
                 // Version
             // Version
             case 'version':
                 $arrCache[$strTag] = VERSION . '.' . BUILD;
                 break;
                 // Request token
             // Request token
             case 'request_token':
                 $arrCache[$strTag] = REQUEST_TOKEN;
                 break;
                 // POST data
             // POST data
             case 'post':
                 $arrCache[$strTag] = \Input::post($elements[1]);
                 break;
                 // Mobile/desktop toggle (see #6469)
             // Mobile/desktop toggle (see #6469)
             case 'toggle_view':
                 $strUrl = ampersand(\Environment::get('request'));
                 $strGlue = strpos($strUrl, '?') === false ? '?' : '&amp;';
                 if (\Input::cookie('TL_VIEW') == 'mobile' || \Environment::get('agent')->mobile && \Input::cookie('TL_VIEW') != 'desktop') {
                     $arrCache[$strTag] = '<a href="' . $strUrl . $strGlue . 'toggle_view=desktop" class="toggle_desktop" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['toggleDesktop'][1]) . '">' . $GLOBALS['TL_LANG']['MSC']['toggleDesktop'][0] . '</a>';
                 } else {
                     $arrCache[$strTag] = '<a href="' . $strUrl . $strGlue . 'toggle_view=mobile" class="toggle_mobile" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['toggleMobile'][1]) . '">' . $GLOBALS['TL_LANG']['MSC']['toggleMobile'][0] . '</a>';
                 }
                 break;
                 // Conditional tags (if)
             // Conditional tags (if)
             case 'iflng':
                 if ($elements[1] != '' && $elements[1] != $objPage->language) {
                     for (; $_rit < $_cnt; $_rit += 2) {
                         if ($tags[$_rit + 1] == 'iflng' || $tags[$_rit + 1] == 'iflng::' . $objPage->language) {
                             break;
                         }
                     }
                 }
                 unset($arrCache[$strTag]);
                 break;
                 // Conditional tags (if not)
             // Conditional tags (if not)
             case 'ifnlng':
                 if ($elements[1] != '') {
                     $langs = \StringUtil::trimsplit(',', $elements[1]);
                     if (in_array($objPage->language, $langs)) {
                         for (; $_rit < $_cnt; $_rit += 2) {
                             if ($tags[$_rit + 1] == 'ifnlng') {
                                 break;
                             }
                         }
                     }
                 }
                 unset($arrCache[$strTag]);
                 break;
                 // Environment
             // Environment
             case 'env':
                 switch ($elements[1]) {
                     case 'host':
                         $arrCache[$strTag] = \Idna::decode(\Environment::get('host'));
                         break;
                     case 'http_host':
                         $arrCache[$strTag] = \Idna::decode(\Environment::get('httpHost'));
                         break;
                     case 'url':
                         $arrCache[$strTag] = \Idna::decode(\Environment::get('url'));
                         break;
                     case 'path':
                         $arrCache[$strTag] = \Idna::decode(\Environment::get('base'));
                         break;
                     case 'request':
                         $arrCache[$strTag] = \Environment::get('indexFreeRequest');
                         break;
                     case 'ip':
                         $arrCache[$strTag] = \Environment::get('ip');
                         break;
                     case 'referer':
                         $arrCache[$strTag] = $this->getReferer(true);
                         break;
                     case 'files_url':
                         $arrCache[$strTag] = TL_FILES_URL;
                         break;
                     case 'assets_url':
                     case 'plugins_url':
                     case 'script_url':
                         $arrCache[$strTag] = TL_ASSETS_URL;
                         break;
                     case 'base_url':
                         $arrCache[$strTag] = \System::getContainer()->get('request_stack')->getCurrentRequest()->getBaseUrl();
                         break;
                 }
                 break;
                 // Page
             // Page
             case 'page':
                 if ($elements[1] == 'pageTitle' && $objPage->pageTitle == '') {
                     $elements[1] = 'title';
                 } elseif ($elements[1] == 'parentPageTitle' && $objPage->parentPageTitle == '') {
                     $elements[1] = 'parentTitle';
                 } elseif ($elements[1] == 'mainPageTitle' && $objPage->mainPageTitle == '') {
                     $elements[1] = 'mainTitle';
                 }
                 // Do not use \StringUtil::specialchars() here (see #4687)
                 $arrCache[$strTag] = $objPage->{$elements[1]};
                 break;
                 // User agent
             // User agent
             case 'ua':
                 $ua = \Environment::get('agent');
                 if ($elements[1] != '') {
                     $arrCache[$strTag] = $ua->{$elements[1]};
                 } else {
                     $arrCache[$strTag] = '';
                 }
                 break;
                 // Abbreviations
             // Abbreviations
             case 'abbr':
             case 'acronym':
                 if ($elements[1] != '') {
                     $arrCache[$strTag] = '<abbr title="' . \StringUtil::specialchars($elements[1]) . '">';
                 } else {
                     $arrCache[$strTag] = '</abbr>';
                 }
                 break;
                 // Images
             // Images
             case 'image':
             case 'picture':
                 $width = null;
                 $height = null;
                 $alt = '';
                 $class = '';
                 $rel = '';
                 $strFile = $elements[1];
                 $mode = '';
                 $size = null;
                 $strTemplate = 'picture_default';
                 // Take arguments
                 if (strpos($elements[1], '?') !== false) {
                     $arrChunks = explode('?', urldecode($elements[1]), 2);
                     $strSource = \StringUtil::decodeEntities($arrChunks[1]);
                     $strSource = str_replace('[&]', '&', $strSource);
                     $arrParams = explode('&', $strSource);
                     foreach ($arrParams as $strParam) {
                         list($key, $value) = explode('=', $strParam);
                         switch ($key) {
                             case 'width':
                                 $width = $value;
                                 break;
                             case 'height':
                                 $height = $value;
                                 break;
                             case 'alt':
                                 $alt = $value;
                                 break;
                             case 'class':
                                 $class = $value;
                                 break;
                             case 'rel':
                                 $rel = $value;
                                 break;
                             case 'mode':
                                 $mode = $value;
                                 break;
                             case 'size':
                                 $size = (int) $value;
                                 break;
                             case 'template':
                                 $strTemplate = preg_replace('/[^a-z0-9_]/i', '', $value);
                                 break;
                         }
                     }
                     $strFile = $arrChunks[0];
                 }
                 if (\Validator::isUuid($strFile)) {
                     // Handle UUIDs
                     $objFile = \FilesModel::findByUuid($strFile);
                     if ($objFile === null) {
                         $arrCache[$strTag] = '';
                         break;
                     }
                     $strFile = $objFile->path;
                 } elseif (is_numeric($strFile)) {
                     // Handle numeric IDs (see #4805)
                     $objFile = \FilesModel::findByPk($strFile);
                     if ($objFile === null) {
                         $arrCache[$strTag] = '';
                         break;
                     }
                     $strFile = $objFile->path;
                 } else {
                     // Check the path
                     if (\Validator::isInsecurePath($strFile)) {
                         throw new \RuntimeException('Invalid path ' . $strFile);
                     }
                 }
                 // Check the maximum image width
                 if (\Config::get('maxImageWidth') > 0 && $width > \Config::get('maxImageWidth')) {
                     $width = \Config::get('maxImageWidth');
                     $height = null;
                 }
                 // Generate the thumbnail image
                 try {
                     // Image
                     if (strtolower($elements[0]) == 'image') {
                         $dimensions = '';
                         $src = \System::getContainer()->get('contao.image.image_factory')->create(TL_ROOT . '/' . rawurldecode($strFile), array($width, $height, $mode))->getUrl(TL_ROOT);
                         $objFile = new \File(rawurldecode($src));
                         // Add the image dimensions
                         if (($imgSize = $objFile->imageSize) !== false) {
                             $dimensions = ' width="' . \StringUtil::specialchars($imgSize[0]) . '" height="' . \StringUtil::specialchars($imgSize[1]) . '"';
                         }
                         $arrCache[$strTag] = '<img src="' . TL_FILES_URL . $src . '" ' . $dimensions . ' alt="' . \StringUtil::specialchars($alt) . '"' . ($class != '' ? ' class="' . \StringUtil::specialchars($class) . '"' : '') . '>';
                     } else {
                         $picture = \System::getContainer()->get('contao.image.picture_factory')->create(TL_ROOT . '/' . $strFile, $size);
                         $picture = array('img' => $picture->getImg(TL_ROOT), 'sources' => $picture->getSources(TL_ROOT));
                         $picture['alt'] = $alt;
                         $picture['class'] = $class;
                         $pictureTemplate = new \FrontendTemplate($strTemplate);
                         $pictureTemplate->setData($picture);
                         $arrCache[$strTag] = $pictureTemplate->parse();
                     }
                     // Add a lightbox link
                     if ($rel != '') {
                         if (strncmp($rel, 'lightbox', 8) !== 0) {
                             $attribute = ' rel="' . \StringUtil::specialchars($rel) . '"';
                         } else {
                             $attribute = ' data-lightbox="' . \StringUtil::specialchars(substr($rel, 8)) . '"';
                         }
                         $arrCache[$strTag] = '<a href="' . TL_FILES_URL . $strFile . '"' . ($alt != '' ? ' title="' . \StringUtil::specialchars($alt) . '"' : '') . $attribute . '>' . $arrCache[$strTag] . '</a>';
                     }
                 } catch (\Exception $e) {
                     $arrCache[$strTag] = '';
                 }
                 break;
                 // Files (UUID or template path)
             // Files (UUID or template path)
             case 'file':
                 if (\Validator::isUuid($elements[1])) {
                     $objFile = \FilesModel::findByUuid($elements[1]);
                     if ($objFile !== null) {
                         $arrCache[$strTag] = $objFile->path;
                         break;
                     }
                 }
                 $arrGet = $_GET;
                 \Input::resetCache();
                 $strFile = $elements[1];
                 // Take arguments and add them to the $_GET array
                 if (strpos($elements[1], '?') !== false) {
                     $arrChunks = explode('?', urldecode($elements[1]));
                     $strSource = \StringUtil::decodeEntities($arrChunks[1]);
                     $strSource = str_replace('[&]', '&', $strSource);
                     $arrParams = explode('&', $strSource);
                     foreach ($arrParams as $strParam) {
                         $arrParam = explode('=', $strParam);
                         $_GET[$arrParam[0]] = $arrParam[1];
                     }
                     $strFile = $arrChunks[0];
                 }
                 // Check the path
                 if (\Validator::isInsecurePath($strFile)) {
                     throw new \RuntimeException('Invalid path ' . $strFile);
                 }
                 // Include .php, .tpl, .xhtml and .html5 files
                 if (preg_match('/\\.(php|tpl|xhtml|html5)$/', $strFile) && file_exists(TL_ROOT . '/templates/' . $strFile)) {
                     ob_start();
                     include TL_ROOT . '/templates/' . $strFile;
                     $arrCache[$strTag] = ob_get_clean();
                 }
                 $_GET = $arrGet;
                 \Input::resetCache();
                 break;
                 // HOOK: pass unknown tags to callback functions
             // HOOK: pass unknown tags to callback functions
             default:
                 if (isset($GLOBALS['TL_HOOKS']['replaceInsertTags']) && is_array($GLOBALS['TL_HOOKS']['replaceInsertTags'])) {
                     foreach ($GLOBALS['TL_HOOKS']['replaceInsertTags'] as $callback) {
                         $this->import($callback[0]);
                         $varValue = $this->{$callback[0]}->{$callback[1]}($tag, $blnCache, $arrCache[$strTag], $flags, $tags, $arrCache, $_rit, $_cnt);
                         // see #6672
                         // Replace the tag and stop the loop
                         if ($varValue !== false) {
                             $arrCache[$strTag] = $varValue;
                             break;
                         }
                     }
                 }
                 \System::getContainer()->get('monolog.logger.contao')->log(LogLevel::INFO, 'Unknown insert tag: ' . $strTag);
                 break;
         }
         // Handle the flags
         if (!empty($flags)) {
             foreach ($flags as $flag) {
                 switch ($flag) {
                     case 'addslashes':
                     case 'standardize':
                     case 'ampersand':
                     case 'specialchars':
                     case 'nl2br':
                     case 'nl2br_pre':
                     case 'strtolower':
                     case 'utf8_strtolower':
                     case 'strtoupper':
                     case 'utf8_strtoupper':
                     case 'ucfirst':
                     case 'lcfirst':
                     case 'ucwords':
                     case 'trim':
                     case 'rtrim':
                     case 'ltrim':
                     case 'utf8_romanize':
                     case 'urlencode':
                     case 'rawurlencode':
                         $arrCache[$strTag] = $flag($arrCache[$strTag]);
                         break;
                     case 'encodeEmail':
                         $arrCache[$strTag] = \StringUtil::$flag($arrCache[$strTag]);
                         break;
                     case 'number_format':
                         $arrCache[$strTag] = \System::getFormattedNumber($arrCache[$strTag], 0);
                         break;
                     case 'currency_format':
                         $arrCache[$strTag] = \System::getFormattedNumber($arrCache[$strTag], 2);
                         break;
                     case 'readable_size':
                         $arrCache[$strTag] = \System::getReadableSize($arrCache[$strTag]);
                         break;
                     case 'flatten':
                         if (!is_array($arrCache[$strTag])) {
                             break;
                         }
                         $it = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($arrCache[$strTag]));
                         $result = array();
                         foreach ($it as $leafValue) {
                             $keys = array();
                             foreach (range(0, $it->getDepth()) as $depth) {
                                 $keys[] = $it->getSubIterator($depth)->key();
                             }
                             $result[] = implode('.', $keys) . ': ' . $leafValue;
                         }
                         $arrCache[$strTag] = implode(', ', $result);
                         break;
                         // HOOK: pass unknown flags to callback functions
                     // HOOK: pass unknown flags to callback functions
                     default:
                         if (isset($GLOBALS['TL_HOOKS']['insertTagFlags']) && is_array($GLOBALS['TL_HOOKS']['insertTagFlags'])) {
                             foreach ($GLOBALS['TL_HOOKS']['insertTagFlags'] as $callback) {
                                 $this->import($callback[0]);
                                 $varValue = $this->{$callback[0]}->{$callback[1]}($flag, $tag, $arrCache[$strTag], $flags, $blnCache, $tags, $arrCache, $_rit, $_cnt);
                                 // see #5806
                                 // Replace the tag and stop the loop
                                 if ($varValue !== false) {
                                     $arrCache[$strTag] = $varValue;
                                     break;
                                 }
                             }
                         }
                         \System::getContainer()->get('monolog.logger.contao')->log(LogLevel::INFO, 'Unknown insert tag flag: ' . $flag);
                         break;
                 }
             }
         }
         $strBuffer .= $arrCache[$strTag];
     }
     return \StringUtil::restoreBasicEntities($strBuffer);
 }
Пример #14
0
 /**
  * Create a new object to handle an image
  *
  * @param File $file A file instance of the original image
  *
  * @throws \InvalidArgumentException If the file does not exists or cannot be processed
  *
  * @deprecated Deprecated since Contao 4.3, to be removed in Contao 5.0.
  *             Use the contao.image.image_factory service instead.
  */
 public function __construct(File $file)
 {
     @trigger_error('Using new Contao\\Image() has been deprecated and will no longer work in Contao 5.0. Use the contao.image.image_factory service instead.', E_USER_DEPRECATED);
     // Check whether the file exists
     if (!$file->exists()) {
         // Handle public bundle resources
         if (file_exists(TL_ROOT . '/web/' . $file->path)) {
             $file = new \File('web/' . $file->path);
         } else {
             throw new \InvalidArgumentException('Image "' . $file->path . '" could not be found');
         }
     }
     $this->fileObj = $file;
     $arrAllowedTypes = \StringUtil::trimsplit(',', strtolower(\Config::get('validImageTypes')));
     // Check the file type
     if (!in_array($this->fileObj->extension, $arrAllowedTypes)) {
         throw new \InvalidArgumentException('Image type "' . $this->fileObj->extension . '" was not allowed to be processed');
     }
 }
 /**
  * Compile the template
  *
  * @param bool $blnCheckRequest If true, check for unsued $_GET parameters
  *
  * @throws \UnusedArgumentsException If there are unused $_GET parameters
  *
  * @internal Do not call this method in your code. It will be made private in Contao 5.0.
  */
 protected function compile($blnCheckRequest = false)
 {
     $this->keywords = '';
     $arrKeywords = \StringUtil::trimsplit(',', $GLOBALS['TL_KEYWORDS']);
     // Add the meta keywords
     if (strlen($arrKeywords[0])) {
         $this->keywords = str_replace(array("\n", "\r", '"'), array(' ', '', ''), implode(', ', array_unique($arrKeywords)));
     }
     // Parse the template
     $this->strBuffer = $this->parse();
     // HOOK: add custom output filters
     if (isset($GLOBALS['TL_HOOKS']['outputFrontendTemplate']) && is_array($GLOBALS['TL_HOOKS']['outputFrontendTemplate'])) {
         foreach ($GLOBALS['TL_HOOKS']['outputFrontendTemplate'] as $callback) {
             $this->import($callback[0]);
             $this->strBuffer = $this->{$callback[0]}->{$callback[1]}($this->strBuffer, $this->strTemplate);
         }
     }
     // Add the output to the cache
     $this->addToCache();
     // Unset only after the output has been cached (see #7824)
     unset($_SESSION['LOGIN_ERROR']);
     // Replace insert tags and then re-replace the request_token tag in case a form element has been loaded via insert tag
     $this->strBuffer = $this->replaceInsertTags($this->strBuffer, false);
     $this->strBuffer = str_replace(array('{{request_token}}', '[{]', '[}]'), array(REQUEST_TOKEN, '{{', '}}'), $this->strBuffer);
     $this->strBuffer = $this->replaceDynamicScriptTags($this->strBuffer);
     // see #4203
     // HOOK: allow to modify the compiled markup (see #4291)
     if (isset($GLOBALS['TL_HOOKS']['modifyFrontendPage']) && is_array($GLOBALS['TL_HOOKS']['modifyFrontendPage'])) {
         foreach ($GLOBALS['TL_HOOKS']['modifyFrontendPage'] as $callback) {
             $this->import($callback[0]);
             $this->strBuffer = $this->{$callback[0]}->{$callback[1]}($this->strBuffer, $this->strTemplate);
         }
     }
     // Check whether all $_GET parameters have been used (see #4277)
     if ($blnCheckRequest && \Input::hasUnusedGet()) {
         throw new \UnusedArgumentsException();
     }
     parent::compile();
 }
Пример #16
0
 /**
  * Generate the module
  */
 protected function compile()
 {
     \System::loadLanguageFile($this->list_table);
     $this->loadDataContainer($this->list_table);
     // List a single record
     if (\Input::get('show')) {
         $this->listSingleRecord(\Input::get('show'));
         return;
     }
     /**
      * Add the search menu
      */
     $strWhere = '';
     $varKeyword = '';
     $strOptions = '';
     $this->Template->searchable = false;
     $arrSearchFields = \StringUtil::trimsplit(',', $this->list_search);
     if (!empty($arrSearchFields) && is_array($arrSearchFields)) {
         $this->Template->searchable = true;
         if (\Input::get('search') && \Input::get('for')) {
             $varKeyword = '%' . \Input::get('for') . '%';
             $strWhere = (!$this->list_where ? " WHERE " : " AND ") . \Input::get('search') . " LIKE ?";
         }
         foreach ($arrSearchFields as $field) {
             $strOptions .= '  <option value="' . $field . '"' . ($field == \Input::get('search') ? ' selected="selected"' : '') . '>' . (strlen($label = $GLOBALS['TL_DCA'][$this->list_table]['fields'][$field]['label'][0]) ? $label : $field) . '</option>' . "\n";
         }
     }
     $this->Template->search_fields = $strOptions;
     /**
      * Get the total number of records
      */
     $strQuery = "SELECT COUNT(*) AS count FROM " . $this->list_table;
     if ($this->list_where) {
         $strQuery .= " WHERE (" . $this->list_where . ")";
     }
     $strQuery .= $strWhere;
     $objTotal = $this->Database->prepare($strQuery)->execute($varKeyword);
     /**
      * Validate the page count
      */
     $id = 'page_l' . $this->id;
     $page = \Input::get($id) !== null ? \Input::get($id) : 1;
     $per_page = \Input::get('per_page') ?: $this->perPage;
     // Thanks to Hagen Klemp (see #4485)
     if ($per_page > 0 && ($page < 1 || $page > max(ceil($objTotal->count / $per_page), 1))) {
         throw new PageNotFoundException('Page not found: ' . \Environment::get('uri'));
     }
     /**
      * Get the selected records
      */
     $strQuery = "SELECT " . $this->strPk . "," . $this->list_fields;
     if ($this->list_info_where) {
         $strQuery .= ", (SELECT COUNT(*) FROM " . $this->list_table . " t2 WHERE t2." . $this->strPk . "=t1." . $this->strPk . " AND " . $this->list_info_where . ") AS _details";
     }
     $strQuery .= " FROM " . $this->list_table . " t1";
     if ($this->list_where) {
         $strQuery .= " WHERE (" . $this->list_where . ")";
     }
     $strQuery .= $strWhere;
     // Cast date fields to int (see #5609)
     $isInt = function ($field) {
         return $GLOBALS['TL_DCA'][$this->list_table]['fields'][$field]['eval']['rgxp'] == 'date' || $GLOBALS['TL_DCA'][$this->list_table]['fields'][$field]['eval']['rgxp'] == 'time' || $GLOBALS['TL_DCA'][$this->list_table]['fields'][$field]['eval']['rgxp'] == 'datim';
     };
     // Order by
     if (\Input::get('order_by')) {
         if ($isInt(\Input::get('order_by'))) {
             $strQuery .= " ORDER BY CAST(" . \Input::get('order_by') . " AS SIGNED) " . \Input::get('sort');
         } else {
             $strQuery .= " ORDER BY " . \Input::get('order_by') . ' ' . \Input::get('sort');
         }
     } elseif ($this->list_sort) {
         if ($isInt($this->list_sort)) {
             $strQuery .= " ORDER BY CAST(" . $this->list_sort . " AS SIGNED)";
         } else {
             $strQuery .= " ORDER BY " . $this->list_sort;
         }
     }
     $objDataStmt = $this->Database->prepare($strQuery);
     // Limit
     if (\Input::get('per_page')) {
         $objDataStmt->limit(\Input::get('per_page'), ($page - 1) * $per_page);
     } elseif ($this->perPage) {
         $objDataStmt->limit($this->perPage, ($page - 1) * $per_page);
     }
     $objData = $objDataStmt->execute($varKeyword);
     /**
      * Prepare the URL
      */
     $strUrl = preg_replace('/\\?.*$/', '', \Environment::get('request'));
     $blnQuery = false;
     foreach (preg_split('/&(amp;)?/', \Environment::get('queryString')) as $fragment) {
         if ($fragment != '' && strncasecmp($fragment, 'order_by', 8) !== 0 && strncasecmp($fragment, 'sort', 4) !== 0 && strncasecmp($fragment, $id, strlen($id)) !== 0) {
             $strUrl .= (!$blnQuery ? '?' : '&amp;') . $fragment;
             $blnQuery = true;
         }
     }
     $this->Template->url = $strUrl;
     $strVarConnector = $blnQuery ? '&amp;' : '?';
     /**
      * Prepare the data arrays
      */
     $arrTh = array();
     $arrTd = array();
     $arrFields = \StringUtil::trimsplit(',', $this->list_fields);
     // THEAD
     for ($i = 0, $c = count($arrFields); $i < $c; $i++) {
         // Never show passwords
         if ($GLOBALS['TL_DCA'][$this->list_table]['fields'][$arrFields[$i]]['inputType'] == 'password') {
             continue;
         }
         $class = '';
         $sort = 'asc';
         $strField = strlen($label = $GLOBALS['TL_DCA'][$this->list_table]['fields'][$arrFields[$i]]['label'][0]) ? $label : $arrFields[$i];
         // Add a CSS class to the order_by column
         if (\Input::get('order_by') == $arrFields[$i]) {
             $sort = \Input::get('sort') == 'asc' ? 'desc' : 'asc';
             $class = ' sorted ' . \Input::get('sort');
         }
         $arrTh[] = array('link' => $strField, 'href' => ampersand($strUrl) . $strVarConnector . 'order_by=' . $arrFields[$i] . '&amp;sort=' . $sort, 'title' => \StringUtil::specialchars(sprintf($GLOBALS['TL_LANG']['MSC']['list_orderBy'], $strField)), 'class' => $class . ($i == 0 ? ' col_first' : ''));
     }
     $j = 0;
     $arrRows = $objData->fetchAllAssoc();
     // TBODY
     for ($i = 0, $c = count($arrRows); $i < $c; $i++) {
         $j = 0;
         $class = 'row_' . $i . ($i == 0 ? ' row_first' : '') . ($i + 1 == count($arrRows) ? ' row_last' : '') . ($i % 2 == 0 ? ' even' : ' odd');
         foreach ($arrRows[$i] as $k => $v) {
             // Skip the primary key
             if ($k == $this->strPk && !in_array($this->strPk, $arrFields)) {
                 continue;
             }
             if ($k == '_details') {
                 continue;
             }
             // Never show passwords
             if ($GLOBALS['TL_DCA'][$this->list_table]['fields'][$k]['inputType'] == 'password') {
                 continue;
             }
             $value = $this->formatValue($k, $v);
             $arrTd[$class][$k] = array('raw' => $v, 'content' => $value ? $value : '&nbsp;', 'class' => 'col_' . $j . ($j++ == 0 ? ' col_first' : '') . ($this->list_info ? '' : ($j >= count($arrRows[$i]) - 1 ? ' col_last' : '')), 'id' => $arrRows[$i][$this->strPk], 'field' => $k, 'url' => $strUrl . $strVarConnector . 'show=' . $arrRows[$i][$this->strPk], 'details' => isset($arrRows[$i]['_details']) ? $arrRows[$i]['_details'] : 1);
         }
     }
     $this->Template->thead = $arrTh;
     $this->Template->tbody = $arrTd;
     /**
      * Pagination
      */
     $objPagination = new \Pagination($objTotal->count, $per_page, \Config::get('maxPaginationLinks'), $id);
     $this->Template->pagination = $objPagination->generate("\n  ");
     $this->Template->per_page = $per_page;
     $this->Template->total = $objTotal->count;
     /**
      * Template variables
      */
     $this->Template->action = \Environment::get('indexFreeRequest');
     $this->Template->details = $this->list_info != '' ? true : false;
     $this->Template->search_label = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['search']);
     $this->Template->per_page_label = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['list_perPage']);
     $this->Template->fields_label = $GLOBALS['TL_LANG']['MSC']['all_fields'][0];
     $this->Template->keywords_label = $GLOBALS['TL_LANG']['MSC']['keywords'];
     $this->Template->search = \Input::get('search');
     $this->Template->for = \Input::get('for');
     $this->Template->order_by = \Input::get('order_by');
     $this->Template->sort = \Input::get('sort');
     $this->Template->col_last = 'col_' . $j;
 }
Пример #17
0
    /**
     * Render a row of a box and return it as HTML string
     *
     * @param string $strPalette
     *
     * @return string
     *
     * @throws AccessDeniedException
     * @throws \Exception
     */
    protected function row($strPalette = null)
    {
        $arrData = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField];
        // Check if the field is excluded
        if ($arrData['exclude']) {
            throw new AccessDeniedException('Field "' . $this->strTable . '.' . $this->strField . '" is excluded from being edited.');
        }
        $xlabel = '';
        // Toggle line wrap (textarea)
        if ($arrData['inputType'] == 'textarea' && !isset($arrData['eval']['rte'])) {
            $xlabel .= ' ' . \Image::getHtml('wrap.svg', $GLOBALS['TL_LANG']['MSC']['wordWrap'], 'title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['wordWrap']) . '" class="toggleWrap" onclick="Backend.toggleWrap(\'ctrl_' . $this->strInputName . '\')"');
        }
        // Add the help wizard
        if ($arrData['eval']['helpwizard']) {
            $xlabel .= ' <a href="contao/help.php?table=' . $this->strTable . '&amp;field=' . $this->strField . '" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['helpWizard']) . '" onclick="Backend.openModalIframe({\'width\':735,\'title\':\'' . \StringUtil::specialchars(str_replace("'", "\\'", $arrData['label'][0])) . '\',\'url\':this.href});return false">' . \Image::getHtml('about.svg', $GLOBALS['TL_LANG']['MSC']['helpWizard'], 'style="vertical-align:text-bottom"') . '</a>';
        }
        // Add a custom xlabel
        if (is_array($arrData['xlabel'])) {
            foreach ($arrData['xlabel'] as $callback) {
                if (is_array($callback)) {
                    $this->import($callback[0]);
                    $xlabel .= $this->{$callback[0]}->{$callback[1]}($this);
                } elseif (is_callable($callback)) {
                    $xlabel .= $callback($this);
                }
            }
        }
        // Input field callback
        if (is_array($arrData['input_field_callback'])) {
            $this->import($arrData['input_field_callback'][0]);
            return $this->{$arrData['input_field_callback'][0]}->{$arrData['input_field_callback'][1]}($this, $xlabel);
        } elseif (is_callable($arrData['input_field_callback'])) {
            return $arrData['input_field_callback']($this, $xlabel);
        }
        /** @var Widget $strClass */
        $strClass = $GLOBALS['BE_FFL'][$arrData['inputType']];
        // Return if the widget class does not exists
        if (!class_exists($strClass)) {
            return '';
        }
        $arrData['eval']['required'] = false;
        // Use strlen() here (see #3277)
        if ($arrData['eval']['mandatory']) {
            if (is_array($this->varValue)) {
                if (empty($this->varValue)) {
                    $arrData['eval']['required'] = true;
                }
            } else {
                if (!strlen($this->varValue)) {
                    $arrData['eval']['required'] = true;
                }
            }
        }
        // Convert insert tags in src attributes (see #5965)
        if (isset($arrData['eval']['rte']) && strncmp($arrData['eval']['rte'], 'tiny', 4) === 0) {
            $this->varValue = \StringUtil::insertTagToSrc($this->varValue);
        }
        /** @var Widget $objWidget */
        $objWidget = new $strClass($strClass::getAttributesFromDca($arrData, $this->strInputName, $this->varValue, $this->strField, $this->strTable, $this));
        $objWidget->xlabel = $xlabel;
        $objWidget->currentRecord = $this->intId;
        // Validate the field
        if (\Input::post('FORM_SUBMIT') == $this->strTable) {
            $key = \Input::get('act') == 'editAll' ? 'FORM_FIELDS_' . $this->intId : 'FORM_FIELDS';
            // Calculate the current palette
            $postPaletteFields = implode(',', \Input::post($key));
            $postPaletteFields = array_unique(\StringUtil::trimsplit('[,;]', $postPaletteFields));
            // Compile the palette if there is none
            if ($strPalette === null) {
                $newPaletteFields = \StringUtil::trimsplit('[,;]', $this->getPalette());
            } else {
                // Use the given palette ($strPalette is an array in editAll mode)
                $newPaletteFields = is_array($strPalette) ? $strPalette : \StringUtil::trimsplit('[,;]', $strPalette);
                // Re-check the palette if the current field is a selector field
                if (isset($GLOBALS['TL_DCA'][$this->strTable]['palettes']['__selector__']) && in_array($this->strField, $GLOBALS['TL_DCA'][$this->strTable]['palettes']['__selector__'])) {
                    // If the field value has changed, recompile the palette
                    if ($this->varValue != \Input::post($this->strInputName)) {
                        $newPaletteFields = \StringUtil::trimsplit('[,;]', $this->getPalette());
                    }
                }
            }
            // Adjust the names in editAll mode
            if (\Input::get('act') == 'editAll') {
                foreach ($newPaletteFields as $k => $v) {
                    $newPaletteFields[$k] = $v . '_' . $this->intId;
                }
                if ($this->User->isAdmin) {
                    $newPaletteFields['pid'] = 'pid_' . $this->intId;
                    $newPaletteFields['sorting'] = 'sorting_' . $this->intId;
                }
            }
            $paletteFields = array_intersect($postPaletteFields, $newPaletteFields);
            // Validate and save the field
            if (in_array($this->strInputName, $paletteFields) || \Input::get('act') == 'overrideAll') {
                $objWidget->validate();
                if ($objWidget->hasErrors()) {
                    // Skip mandatory fields on auto-submit (see #4077)
                    if (\Input::post('SUBMIT_TYPE') != 'auto' || !$objWidget->mandatory || $objWidget->value != '') {
                        $this->noReload = true;
                    }
                } elseif ($objWidget->submitInput()) {
                    $varValue = $objWidget->value;
                    // Sort array by key (fix for JavaScript wizards)
                    if (is_array($varValue)) {
                        ksort($varValue);
                        $varValue = serialize($varValue);
                    }
                    // Convert file paths in src attributes (see #5965)
                    if ($varValue && isset($arrData['eval']['rte']) && strncmp($arrData['eval']['rte'], 'tiny', 4) === 0) {
                        $varValue = \StringUtil::srcToInsertTag($varValue);
                    }
                    // Save the current value
                    try {
                        $this->save($varValue);
                    } catch (\Exception $e) {
                        $this->noReload = true;
                        $objWidget->addError($e->getMessage());
                    }
                }
            }
        }
        $wizard = '';
        $strHelpClass = '';
        // Date picker
        if ($arrData['eval']['datepicker']) {
            $rgxp = $arrData['eval']['rgxp'];
            $format = \Date::formatToJs(\Config::get($rgxp . 'Format'));
            switch ($rgxp) {
                case 'datim':
                    $time = ",\n      timePicker:true";
                    break;
                case 'time':
                    $time = ",\n      pickOnly:\"time\"";
                    break;
                default:
                    $time = '';
                    break;
            }
            $wizard .= ' ' . \Image::getHtml('assets/datepicker/images/icon.svg', '', 'title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['datepicker']) . '" id="toggle_' . $objWidget->id . '" style="cursor:pointer"') . '
  <script>
    window.addEvent("domready", function() {
      new Picker.Date($("ctrl_' . $objWidget->id . '"), {
        draggable: false,
        toggle: $("toggle_' . $objWidget->id . '"),
        format: "' . $format . '",
        positionOffset: {x:-211,y:-209}' . $time . ',
        pickerClass: "datepicker_bootstrap",
        useFadeInOut: !Browser.ie,
        startDay: ' . $GLOBALS['TL_LANG']['MSC']['weekOffset'] . ',
        titleFormat: "' . $GLOBALS['TL_LANG']['MSC']['titleFormat'] . '"
      });
    });
  </script>';
        }
        // Color picker
        if ($arrData['eval']['colorpicker']) {
            // Support single fields as well (see #5240)
            $strKey = $arrData['eval']['multiple'] ? $this->strField . '_0' : $this->strField;
            $wizard .= ' ' . \Image::getHtml('pickcolor.svg', $GLOBALS['TL_LANG']['MSC']['colorpicker'], 'title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['colorpicker']) . '" id="moo_' . $this->strField . '"') . '
  <script>
    window.addEvent("domready", function() {
      new MooRainbow("moo_' . $this->strField . '", {
        id: "ctrl_' . $strKey . '",
        startColor: ((cl = $("ctrl_' . $strKey . '").value.hexToRgb(true)) ? cl : [255, 0, 0]),
        imgPath: "assets/colorpicker/images/",
        onComplete: function(color) {
          $("ctrl_' . $strKey . '").value = color.hex.replace("#", "");
        }
      });
    });
  </script>';
        }
        // Add a custom wizard
        if (is_array($arrData['wizard'])) {
            foreach ($arrData['wizard'] as $callback) {
                if (is_array($callback)) {
                    $this->import($callback[0]);
                    $wizard .= $this->{$callback[0]}->{$callback[1]}($this);
                } elseif (is_callable($callback)) {
                    $wizard .= $callback($this);
                }
            }
        }
        $objWidget->wizard = $wizard;
        // Set correct form enctype
        if ($objWidget instanceof \uploadable) {
            $this->blnUploadable = true;
        }
        // Mark floated single checkboxes
        if ($arrData['inputType'] == 'checkbox' && !$arrData['eval']['multiple'] && strpos($arrData['eval']['tl_class'], 'w50') !== false) {
            $arrData['eval']['tl_class'] .= ' cbx';
        } elseif ($arrData['inputType'] == 'text' && $arrData['eval']['multiple'] && strpos($arrData['eval']['tl_class'], 'wizard') !== false) {
            $arrData['eval']['tl_class'] .= ' inline';
        }
        // No 2-column layout in "edit all" mode
        if (\Input::get('act') == 'editAll' || \Input::get('act') == 'overrideAll') {
            $arrData['eval']['tl_class'] = str_replace(array('w50', 'clr', 'wizard', 'long', 'm12', 'cbx'), '', $arrData['eval']['tl_class']);
        }
        $updateMode = '';
        // Replace the textarea with an RTE instance
        if (!empty($arrData['eval']['rte'])) {
            list($file, $type) = explode('|', $arrData['eval']['rte'], 2);
            /** @var BackendTemplate|object $objTemplate */
            $objTemplate = new \BackendTemplate("be_{$file}");
            $objTemplate->selector = 'ctrl_' . $this->strInputName;
            // Deprecated since Contao 4.0, to be removed in Contao 5.0
            $objTemplate->language = \Backend::getTinyMceLanguage();
            $updateMode = $objTemplate->parse();
            unset($file, $type);
        } elseif (\Input::get('act') == 'overrideAll' && ($arrData['inputType'] == 'checkbox' || $arrData['inputType'] == 'checkboxWizard') && $arrData['eval']['multiple']) {
            $updateMode = '
</div>
<div>
  <fieldset class="tl_radio_container">
  <legend>' . $GLOBALS['TL_LANG']['MSC']['updateMode'] . '</legend>
    <input type="radio" name="' . $this->strInputName . '_update" id="opt_' . $this->strInputName . '_update_1" class="tl_radio" value="add" onfocus="Backend.getScrollOffset()"> <label for="opt_' . $this->strInputName . '_update_1">' . $GLOBALS['TL_LANG']['MSC']['updateAdd'] . '</label><br>
    <input type="radio" name="' . $this->strInputName . '_update" id="opt_' . $this->strInputName . '_update_2" class="tl_radio" value="remove" onfocus="Backend.getScrollOffset()"> <label for="opt_' . $this->strInputName . '_update_2">' . $GLOBALS['TL_LANG']['MSC']['updateRemove'] . '</label><br>
    <input type="radio" name="' . $this->strInputName . '_update" id="opt_' . $this->strInputName . '_update_0" class="tl_radio" value="replace" checked="checked" onfocus="Backend.getScrollOffset()"> <label for="opt_' . $this->strInputName . '_update_0">' . $GLOBALS['TL_LANG']['MSC']['updateReplace'] . '</label>
  </fieldset>';
        }
        $strPreview = '';
        // Show a preview image (see #4948)
        if ($this->strTable == 'tl_files' && $this->strField == 'name' && $this->objActiveRecord !== null && $this->objActiveRecord->type == 'file') {
            $objFile = new \File($this->objActiveRecord->path);
            if ($objFile->isImage) {
                $image = \Image::getPath('placeholder.svg');
                if ($objFile->isSvgImage || $objFile->height <= \Config::get('gdMaxImgHeight') && $objFile->width <= \Config::get('gdMaxImgWidth')) {
                    if ($objFile->width > 699 || $objFile->height > 524 || !$objFile->width || !$objFile->height) {
                        $image = rawurldecode(\Image::get($objFile->path, 699, 524, 'box'));
                    } else {
                        $image = $objFile->path;
                    }
                }
                $objImage = new \File($image);
                $ctrl = 'ctrl_preview_' . substr(md5($image), 0, 8);
                $strPreview = '

<div id="' . $ctrl . '" class="tl_edit_preview" data-original-width="' . $objFile->viewWidth . '" data-original-height="' . $objFile->viewHeight . '">
  <img src="' . $objImage->dataUri . '" width="' . $objImage->width . '" height="' . $objImage->height . '" alt="">
</div>';
                // Add the script to mark the important part
                if (basename($image) !== 'placeholder.svg') {
                    $strPreview .= '<script>Backend.editPreviewWizard($(\'' . $ctrl . '\'));</script>';
                    if (\Config::get('showHelp')) {
                        $strPreview .= '<p class="tl_help tl_tip">' . $GLOBALS['TL_LANG'][$this->strTable]['edit_preview_help'] . '</p>';
                    }
                }
            }
        }
        return $strPreview . '
<div' . ($arrData['eval']['tl_class'] ? ' class="' . $arrData['eval']['tl_class'] . '"' : '') . '>' . $objWidget->parse() . $updateMode . (!$objWidget->hasErrors() ? $this->help($strHelpClass) : '') . '
</div>';
    }
Пример #18
0
 /**
  * Add templates to the archive
  *
  * @param ZipWriter $objArchive
  * @param string    $strFolder
  */
 protected function addTemplatesToArchive(ZipWriter $objArchive, $strFolder)
 {
     // Strip the templates folder name
     $strFolder = preg_replace('@^templates/@', '', $strFolder);
     // Re-add the templates folder name
     if ($strFolder == '') {
         $strFolder = 'templates';
     } else {
         $strFolder = 'templates/' . $strFolder;
     }
     if (\Validator::isInsecurePath($strFolder)) {
         throw new \RuntimeException('Insecure path ' . $strFolder);
     }
     // Return if the folder does not exist
     if (!is_dir(TL_ROOT . '/' . $strFolder)) {
         return;
     }
     $arrAllowed = \StringUtil::trimsplit(',', strtolower(\Config::get('templateFiles')));
     array_push($arrAllowed, 'sql');
     // see #7048
     // Add all template files to the archive
     foreach (scan(TL_ROOT . '/' . $strFolder) as $strFile) {
         if (preg_match('/\\.(' . implode('|', $arrAllowed) . ')$/', $strFile) && strncmp($strFile, 'be_', 3) !== 0 && strncmp($strFile, 'nl_', 3) !== 0) {
             $objArchive->addFile($strFolder . '/' . $strFile);
         }
     }
 }
Пример #19
0
 /**
  * Generate a particular subpart of the file tree and return it as HTML string
  *
  * @param integer $strFolder
  * @param string  $strField
  * @param integer $level
  * @param boolean $mount
  *
  * @return string
  */
 public function generateAjax($strFolder, $strField, $level, $mount = false)
 {
     if (!\Environment::get('isAjaxRequest')) {
         return '';
     }
     $this->strField = $strField;
     $this->loadDataContainer($this->strTable);
     // Load the current values
     switch ($GLOBALS['TL_DCA'][$this->strTable]['config']['dataContainer']) {
         case 'File':
             if (\Config::get($this->strField) != '') {
                 $this->varValue = \Config::get($this->strField);
             }
             break;
         case 'Table':
             $this->import('Database');
             if (!$this->Database->fieldExists($this->strField, $this->strTable)) {
                 break;
             }
             $objField = $this->Database->prepare("SELECT " . $this->strField . " FROM " . $this->strTable . " WHERE id=?")->limit(1)->execute($this->strId);
             if ($objField->numRows) {
                 $this->varValue = \StringUtil::deserialize($objField->{$this->strField});
             }
             break;
     }
     $this->convertValuesToPaths();
     if ($this->extensions != '') {
         $this->arrValidFileTypes = \StringUtil::trimsplit(',', $this->extensions);
     }
     return $this->renderFiletree(TL_ROOT . '/' . $strFolder, $level * 20, $mount, $this->isProtectedPath($strFolder));
 }
Пример #20
0
 /**
  * Compile the template
  *
  * @throws \UnusedArgumentsException If there are unused $_GET parameters
  *
  * @internal Do not call this method in your code. It will be made private in Contao 5.0.
  */
 protected function compile()
 {
     $this->keywords = '';
     $arrKeywords = \StringUtil::trimsplit(',', $GLOBALS['TL_KEYWORDS']);
     // Add the meta keywords
     if (strlen($arrKeywords[0])) {
         $this->keywords = str_replace(array("\n", "\r", '"'), array(' ', '', ''), implode(', ', array_unique($arrKeywords)));
     }
     // Parse the template
     $this->strBuffer = $this->parse();
     // HOOK: add custom output filters
     if (isset($GLOBALS['TL_HOOKS']['outputFrontendTemplate']) && is_array($GLOBALS['TL_HOOKS']['outputFrontendTemplate'])) {
         foreach ($GLOBALS['TL_HOOKS']['outputFrontendTemplate'] as $callback) {
             $this->import($callback[0]);
             $this->strBuffer = $this->{$callback[0]}->{$callback[1]}($this->strBuffer, $this->strTemplate);
         }
     }
     // Replace insert tags
     $this->strBuffer = $this->replaceInsertTags($this->strBuffer);
     $this->strBuffer = $this->replaceDynamicScriptTags($this->strBuffer);
     // see #4203
     // HOOK: allow to modify the compiled markup (see #4291)
     if (isset($GLOBALS['TL_HOOKS']['modifyFrontendPage']) && is_array($GLOBALS['TL_HOOKS']['modifyFrontendPage'])) {
         foreach ($GLOBALS['TL_HOOKS']['modifyFrontendPage'] as $callback) {
             $this->import($callback[0]);
             $this->strBuffer = $this->{$callback[0]}->{$callback[1]}($this->strBuffer, $this->strTemplate);
         }
     }
     // Check whether all $_GET parameters have been used (see #4277)
     if ($this->blnCheckRequest && \Input::hasUnusedGet()) {
         throw new \UnusedArgumentsException();
     }
     parent::compile();
 }