/** * Set the property * * @param string $key * @param int $value * * @throws \InvalidArgumentException */ public static function set($key, $value) { if (!in_array($key, static::getAllowedKeys(), true)) { throw new \InvalidArgumentException(sprintf('The key "%s" is not allowed', $key)); } $data = static::getData(); $data[$key] = (int) $value; Config::set(static::$configKey, serialize($data)); Config::persist(static::$configKey, serialize($data)); }
/** * Check for new \Contao versions */ public function checkForUpdates() { if (!is_numeric(BUILD)) { return; } // HOOK: proxy module if (Config::get('useProxy')) { $objRequest = new \ProxyRequest(); } else { $objRequest = new \Request(); } $objRequest->send(\Config::get('liveUpdateBase') . (LONG_TERM_SUPPORT ? 'lts-version.txt' : 'version.txt')); if (!$objRequest->hasError()) { \Config::set('latestVersion', $objRequest->response); \Config::persist('latestVersion', $objRequest->response); } // Add a log entry $this->log('Checked for Contao updates', __METHOD__, TL_CRON); }
/** * Run the controller and parse the template */ public function run() { $template = new BackendTemplate('be_picker'); $template->main = ''; // Ajax request if ($_POST && Environment::get('isAjaxRequest')) { $this->ajax = new Ajax(Input::post('action')); $this->ajax->executePreActions(); } $rebuilder = new Rebuilder(); $rebuilder->setPopupMode(true); $template->main = $rebuilder->run(); $template->theme = Backend::getTheme(); $template->base = Environment::get('base'); $template->language = $GLOBALS['TL_LANGUAGE']; $template->title = specialchars($GLOBALS['TL_LANG']['MSC']['pagepicker']); $template->charset = Config::get('characterSet'); Config::set('debugMode', false); $template->output(); }
/** * Return a select menu to limit results * * @param boolean $blnOptional * * @return string */ protected function limitMenu($blnOptional = false) { /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); $session = $objSessionBag->all(); $filter = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4 ? $this->strTable . '_' . CURRENT_ID : $this->strTable; $fields = ''; // Set limit from user input if (\Input::post('FORM_SUBMIT') == 'tl_filters' || \Input::post('FORM_SUBMIT') == 'tl_filters_limit') { $strLimit = \Input::post('tl_limit'); if ($strLimit == 'tl_limit') { unset($session['filter'][$filter]['limit']); } else { // Validate the user input (thanks to aulmn) (see #4971) if ($strLimit == 'all' || preg_match('/^[0-9]+,[0-9]+$/', $strLimit)) { $session['filter'][$filter]['limit'] = $strLimit; } } $objSessionBag->replace($session); if (\Input::post('FORM_SUBMIT') == 'tl_filters_limit') { $this->reload(); } } else { $this->limit = $session['filter'][$filter]['limit'] != '' ? $session['filter'][$filter]['limit'] == 'all' ? null : $session['filter'][$filter]['limit'] : '0,' . \Config::get('resultsPerPage'); $arrProcedure = $this->procedure; $arrValues = $this->values; $query = "SELECT COUNT(*) AS count FROM " . $this->strTable; if (!empty($this->root) && is_array($this->root)) { $arrProcedure[] = 'id IN(' . implode(',', $this->root) . ')'; } // Support empty ptable fields if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable']) { $arrProcedure[] = $this->ptable == 'tl_article' ? "(ptable=? OR ptable='')" : "ptable=?"; $arrValues[] = $this->ptable; } if (!empty($arrProcedure)) { $query .= " WHERE " . implode(' AND ', $arrProcedure); } $objTotal = $this->Database->prepare($query)->execute($arrValues); $this->total = $objTotal->count; $options_total = 0; $blnIsMaxResultsPerPage = false; // Overall limit if ($this->total > \Config::get('maxResultsPerPage') && ($this->limit === null || preg_replace('/^.*,/', '', $this->limit) == \Config::get('maxResultsPerPage'))) { if ($this->limit === null) { $this->limit = '0,' . \Config::get('maxResultsPerPage'); } $blnIsMaxResultsPerPage = true; \Config::set('resultsPerPage', \Config::get('maxResultsPerPage')); $session['filter'][$filter]['limit'] = \Config::get('maxResultsPerPage'); } $options = ''; // Build options if ($this->total > 0) { $options = ''; $options_total = ceil($this->total / \Config::get('resultsPerPage')); // Reset limit if other parameters have decreased the number of results if ($this->limit !== null && ($this->limit == '' || preg_replace('/,.*$/', '', $this->limit) > $this->total)) { $this->limit = '0,' . \Config::get('resultsPerPage'); } // Build options for ($i = 0; $i < $options_total; $i++) { $this_limit = $i * \Config::get('resultsPerPage') . ',' . \Config::get('resultsPerPage'); $upper_limit = $i * \Config::get('resultsPerPage') + \Config::get('resultsPerPage'); if ($upper_limit > $this->total) { $upper_limit = $this->total; } $options .= ' <option value="' . $this_limit . '"' . \Widget::optionSelected($this->limit, $this_limit) . '>' . ($i * \Config::get('resultsPerPage') + 1) . ' - ' . $upper_limit . '</option>'; } if (!$blnIsMaxResultsPerPage) { $options .= ' <option value="all"' . \Widget::optionSelected($this->limit, null) . '>' . $GLOBALS['TL_LANG']['MSC']['filterAll'] . '</option>'; } } // Return if there is only one page if ($blnOptional && ($this->total < 1 || $options_total < 2)) { return ''; } $fields = ' <select name="tl_limit" class="tl_select' . ($session['filter'][$filter]['limit'] != 'all' && $this->total > \Config::get('resultsPerPage') ? ' active' : '') . '" onchange="this.form.submit()"> <option value="tl_limit">' . $GLOBALS['TL_LANG']['MSC']['filterRecords'] . '</option>' . $options . ' </select> '; } return ' <div class="tl_limit tl_subpanel"> <strong>' . $GLOBALS['TL_LANG']['MSC']['showOnly'] . ':</strong> ' . $fields . ' </div>'; }
/** * Set all user properties from a database record */ protected function setUserFromDb() { $this->intId = $this->id; // Unserialize values foreach ($this->arrData as $k => $v) { if (!is_numeric($v)) { $this->{$k} = deserialize($v); } } $GLOBALS['TL_USERNAME'] = $this->username; \System::getContainer()->get('request_stack')->getCurrentRequest()->setLocale($this->language); \System::getContainer()->get('translator')->setLocale($this->language); // Deprecated since Contao 4.0, to be removed in Contao 5.0 $GLOBALS['TL_LANGUAGE'] = str_replace('_', '-', $this->language); \Config::set('showHelp', $this->showHelp); \Config::set('useRTE', $this->useRTE); \Config::set('useCE', $this->useCE); \Config::set('thumbnails', $this->thumbnails); \Config::set('backendTheme', $this->backendTheme); // Inherit permissions $always = array('alexf'); $depends = array('modules', 'themes', 'pagemounts', 'alpty', 'filemounts', 'fop', 'forms', 'formp', 'imageSizes'); // HOOK: Take custom permissions if (!empty($GLOBALS['TL_PERMISSIONS']) && is_array($GLOBALS['TL_PERMISSIONS'])) { $depends = array_merge($depends, $GLOBALS['TL_PERMISSIONS']); } // Overwrite user permissions if only group permissions shall be inherited if ($this->inherit == 'group') { foreach ($depends as $field) { $this->{$field} = array(); } } // Merge permissions $inherit = in_array($this->inherit, array('group', 'extend')) ? array_merge($always, $depends) : $always; $time = \Date::floorToMinute(); foreach ((array) $this->groups as $id) { $objGroup = $this->Database->prepare("SELECT * FROM tl_user_group WHERE id=? AND disable!='1' AND (start='' OR start<='{$time}') AND (stop='' OR stop>'" . ($time + 60) . "')")->limit(1)->execute($id); if ($objGroup->numRows > 0) { foreach ($inherit as $field) { $value = deserialize($objGroup->{$field}, true); // The new page/file picker can return integers instead of arrays, so use empty() instead of is_array() and deserialize(true) here if (!empty($value)) { $this->{$field} = array_merge(is_array($this->{$field}) ? $this->{$field} : ($this->{$field} != '' ? array($this->{$field}) : array()), $value); $this->{$field} = array_unique($this->{$field}); } } } } // Make sure pagemounts and filemounts are set! if (!is_array($this->pagemounts)) { $this->pagemounts = array(); } else { $this->pagemounts = array_filter($this->pagemounts); } if (!is_array($this->filemounts)) { $this->filemounts = array(); } else { $this->filemounts = array_filter($this->filemounts); } // Store the numeric file mounts $this->arrFilemountIds = $this->filemounts; // Convert the file mounts into paths if (!$this->isAdmin && !empty($this->filemounts)) { $objFiles = \FilesModel::findMultipleByUuids($this->filemounts); if ($objFiles !== null) { $this->filemounts = $objFiles->fetchEach('path'); } } }
/** * 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(); } }
/** * List all files and folders of the file system * * @return string */ public function showAll() { $return = ''; /** @var SessionInterface $objSession */ $objSession = \System::getContainer()->get('session'); /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = $objSession->getBag('contao_backend'); $session = $objSessionBag->all(); // Add to clipboard if (\Input::get('act') == 'paste') { if (\Input::get('mode') != 'create' && \Input::get('mode') != 'move') { $this->isValid($this->intId); } $arrClipboard = $objSession->get('CLIPBOARD'); $arrClipboard[$this->strTable] = array('id' => $this->urlEncode($this->intId), 'childs' => \Input::get('childs'), 'mode' => \Input::get('mode')); $objSession->set('CLIPBOARD', $arrClipboard); } // Get the session data and toggle the nodes if (\Input::get('tg') == 'all') { // Expand tree if (!is_array($session['filetree']) || empty($session['filetree']) || current($session['filetree']) != 1) { $session['filetree'] = $this->getMD5Folders(\Config::get('uploadPath')); } else { $session['filetree'] = array(); } $objSessionBag->replace($session); $this->redirect(preg_replace('/(&(amp;)?|\\?)tg=[^& ]*/i', '', \Environment::get('request'))); } $blnClipboard = false; $arrClipboard = $objSession->get('CLIPBOARD'); // Check clipboard if (!empty($arrClipboard[$this->strTable])) { $blnClipboard = true; $arrClipboard = $arrClipboard[$this->strTable]; } // Load the fonts to display the paste hint \Config::set('loadGoogleFonts', $blnClipboard); $this->import('Files'); $this->import('BackendUser', 'User'); $arrFound = array(); $for = $session['search'][$this->strTable]['value']; // Limit the results by modifying $this->arrFilemounts if ($for != '') { // Wrap in a try catch block in case the regular expression is invalid (see #7743) try { $strPattern = "CAST(name AS CHAR) REGEXP ?"; if (substr(\Config::get('dbCollation'), -3) == '_ci') { $strPattern = "LOWER(CAST(name AS CHAR)) REGEXP LOWER(?)"; } if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields']['name']['foreignKey'])) { list($t, $f) = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields']['name']['foreignKey']); $objRoot = $this->Database->prepare("SELECT path, type, extension FROM {$this->strTable} WHERE (" . $strPattern . " OR " . sprintf($strPattern, "(SELECT {$f} FROM {$t} WHERE {$t}.id={$this->strTable}.name)") . ") GROUP BY path")->execute($for, $for); } else { $objRoot = $this->Database->prepare("SELECT path, type, extension FROM {$this->strTable} WHERE " . $strPattern . " GROUP BY path")->execute($for); } if ($objRoot->numRows < 1) { $this->arrFilemounts = array(); } else { $arrRoot = array(); // Respect existing limitations (root IDs) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['root'])) { while ($objRoot->next()) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['root'] as $root) { if (strncmp($root . '/', $objRoot->path . '/', strlen($root) + 1) === 0) { if ($objRoot->type == 'folder' || empty($this->arrValidFileTypes) || in_array($objRoot->extension, $this->arrValidFileTypes)) { $arrFound[] = $objRoot->path; } $arrRoot[] = $objRoot->type == 'folder' ? $objRoot->path : dirname($objRoot->path); continue 2; } } } } else { while ($objRoot->next()) { if ($objRoot->type == 'folder' || empty($this->arrValidFileTypes) || in_array($objRoot->extension, $this->arrValidFileTypes)) { $arrFound[] = $objRoot->path; } $arrRoot[] = $objRoot->type == 'folder' ? $objRoot->path : dirname($objRoot->path); } } $this->arrFilemounts = $this->eliminateNestedPaths(array_unique($arrRoot)); } } catch (\Exception $e) { } } // Call recursive function tree() if (empty($this->arrFilemounts) && !is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['root']) && $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['root'] !== false) { $return .= $this->generateTree(TL_ROOT . '/' . \Config::get('uploadPath'), 0, false, true, $blnClipboard ? $arrClipboard : false, $arrFound); } else { for ($i = 0, $c = count($this->arrFilemounts); $i < $c; $i++) { if ($this->arrFilemounts[$i] != '' && is_dir(TL_ROOT . '/' . $this->arrFilemounts[$i])) { $return .= $this->generateTree(TL_ROOT . '/' . $this->arrFilemounts[$i], 0, true, true, $blnClipboard ? $arrClipboard : false, $arrFound); } } } // Check for the "create new" button $clsNew = 'header_new_folder'; $lblNew = $GLOBALS['TL_LANG'][$this->strTable]['new'][0]; $ttlNew = $GLOBALS['TL_LANG'][$this->strTable]['new'][1]; $hrfNew = '&act=paste&mode=create'; if (isset($GLOBALS['TL_DCA'][$this->strTable]['list']['new'])) { $clsNew = $GLOBALS['TL_DCA'][$this->strTable]['list']['new']['class']; $lblNew = $GLOBALS['TL_DCA'][$this->strTable]['list']['new']['label'][0]; $ttlNew = $GLOBALS['TL_DCA'][$this->strTable]['list']['new']['label'][1]; $hrfNew = $GLOBALS['TL_DCA'][$this->strTable]['list']['new']['href']; } $imagePasteInto = \Image::getHtml('pasteinto.gif', $GLOBALS['TL_LANG'][$this->strTable]['pasteinto'][0]); // Build the tree $return = $this->panel() . ' <div id="tl_buttons">' . (\Input::get('act') == 'select' ? ' <a href="' . $this->getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> ' : '') . (\Input::get('act') != 'select' && !$blnClipboard && !$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable'] ? ' <a href="' . $this->addToUrl($hrfNew) . '" class="' . $clsNew . '" title="' . specialchars($ttlNew) . '" accesskey="n" onclick="Backend.getScrollOffset()">' . $lblNew . '</a> <a href="' . $this->addToUrl('&act=paste&mode=move') . '" class="header_new" title="' . specialchars($GLOBALS['TL_LANG'][$this->strTable]['move'][1]) . '" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG'][$this->strTable]['move'][0] . '</a> ' : '') . ($blnClipboard ? ' <a href="' . $this->addToUrl('clipboard=1') . '" class="header_clipboard" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['clearClipboard']) . '" accesskey="x">' . $GLOBALS['TL_LANG']['MSC']['clearClipboard'] . '</a> ' : $this->generateGlobalButtons()) . ' </div>' . \Message::generate(true) . (\Input::get('act') == 'select' ? ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_select" class="tl_form' . (\Input::get('act') == 'select' ? ' unselectable' : '') . '" method="post" novalidate> <div class="tl_formbody"> <input type="hidden" name="FORM_SUBMIT" value="tl_select"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '">' : '') . ($session['search'][$this->strTable]['value'] != '' ? ' <div class="tl_message tl_message_picker"> <p class="tl_info">' . $GLOBALS['TL_LANG']['MSC']['searchExclude'] . '</p> </div>' : '') . ($blnClipboard ? ' <div id="paste_hint"> <p>' . $GLOBALS['TL_LANG']['MSC']['selectNewPosition'] . '</p> </div>' : '') . ' <div class="tl_listing_container tree_view" id="tl_listing">' . (isset($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['breadcrumb']) ? $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['breadcrumb'] : '') . (\Input::get('act') == 'select' ? ' <div class="tl_select_trigger"> <label for="tl_select_trigger" class="tl_select_label">' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</label> <input type="checkbox" id="tl_select_trigger" onclick="Backend.toggleCheckboxes(this)" class="tl_tree_checkbox"> </div>' : '') . ' <ul class="tl_listing"> <li class="tl_folder_top"><div class="tl_left">' . \Image::getHtml('filemounts.gif') . ' ' . $GLOBALS['TL_LANG']['MSC']['filetree'] . '</div> <div class="tl_right">' . ($blnClipboard && empty($this->arrFilemounts) && !is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['root']) && $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['root'] !== false ? '<a href="' . $this->addToUrl('&act=' . $arrClipboard['mode'] . '&mode=2&pid=' . \Config::get('uploadPath') . (!is_array($arrClipboard['id']) ? '&id=' . $arrClipboard['id'] : '')) . '" title="' . specialchars($GLOBALS['TL_LANG'][$this->strTable]['pasteinto'][1]) . '" onclick="Backend.getScrollOffset()">' . $imagePasteInto . '</a>' : ' ') . '</div><div style="clear:both"></div></li>' . $return . ' </ul> </div>'; // Close the form if (\Input::get('act') == 'select') { // Submit buttons $arrButtons = array(); if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notDeletable']) { $arrButtons['delete'] = '<button type="submit" name="delete" id="delete" class="tl_submit" accesskey="d" onclick="return confirm(\'' . $GLOBALS['TL_LANG']['MSC']['delAllConfirmFile'] . '\')">' . $GLOBALS['TL_LANG']['MSC']['deleteSelected'] . '</button>'; } if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notSortable']) { $arrButtons['cut'] = '<button type="submit" name="cut" id="cut" class="tl_submit" accesskey="x">' . $GLOBALS['TL_LANG']['MSC']['moveSelected'] . '</button>'; } if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notCopyable']) { $arrButtons['copy'] = '<button type="submit" name="copy" id="copy" class="tl_submit" accesskey="c">' . $GLOBALS['TL_LANG']['MSC']['copySelected'] . '</button>'; } if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable']) { $arrButtons['edit'] = '<button type="submit" name="edit" id="edit" class="tl_submit" accesskey="s">' . $GLOBALS['TL_LANG']['MSC']['editSelected'] . '</button>'; } // Call the buttons_callback (see #4691) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['select']['buttons_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['select']['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); } } } $return .= ' <div class="tl_formbody_submit" style="text-align:right"> <div class="tl_submit_container"> ' . implode(' ', $arrButtons) . ' </div> </div> </div> </form>'; } return $return; }
/** * Save the current value * * @param mixed $varValue */ protected function save($varValue) { if (\Input::post('FORM_SUBMIT') != $this->strTable) { return; } $arrData = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]; // Make sure that checkbox values are boolean if ($arrData['inputType'] == 'checkbox' && !$arrData['eval']['multiple']) { $varValue = $varValue ? true : false; } if ($varValue != '') { // Convert binary UUIDs (see #6893) if ($arrData['inputType'] == 'fileTree') { $varValue = deserialize($varValue); if (!is_array($varValue)) { $varValue = \StringUtil::binToUuid($varValue); } else { $varValue = serialize(array_map('StringUtil::binToUuid', $varValue)); } } // 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; } // Handle entities if ($arrData['inputType'] == 'text' || $arrData['inputType'] == 'textarea') { $varValue = deserialize($varValue); if (!is_array($varValue)) { $varValue = \StringUtil::restoreBasicEntities($varValue); } else { $varValue = serialize(array_map('StringUtil::restoreBasicEntities', $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); } } } $strCurrent = $this->varValue; // Handle arrays and strings if (is_array($strCurrent)) { $strCurrent = serialize($strCurrent); } elseif (is_string($strCurrent)) { $strCurrent = html_entity_decode($this->varValue, ENT_QUOTES, \Config::get('characterSet')); } // Save the value if there was no error if ((strlen($varValue) || !$arrData['eval']['doNotSaveEmpty']) && $strCurrent != $varValue) { \Config::persist($this->strField, $varValue); $deserialize = deserialize($varValue); $prior = is_bool(\Config::get($this->strField)) ? \Config::get($this->strField) ? 'true' : 'false' : \Config::get($this->strField); // Add a log entry if (!is_array(deserialize($prior)) && !is_array($deserialize)) { if ($arrData['inputType'] == 'password' || $arrData['inputType'] == 'textStore') { $this->log('The global configuration variable "' . $this->strField . '" has been changed', __METHOD__, TL_CONFIGURATION); } else { $this->log('The global configuration variable "' . $this->strField . '" has been changed from "' . $prior . '" to "' . $varValue . '"', __METHOD__, TL_CONFIGURATION); } } // Set the new value so the input field can show it $this->varValue = $deserialize; \Config::set($this->strField, $deserialize); } }
/** * List all files and folders of the file system * * @return string */ public function showAll() { $return = ''; /** @var SessionInterface $objSession */ $objSession = \System::getContainer()->get('session'); // Add to clipboard if (\Input::get('act') == 'paste') { if (\Input::get('mode') != 'create' && \Input::get('mode') != 'move') { $this->isValid($this->intId); } $arrClipboard = $objSession->get('CLIPBOARD'); $arrClipboard[$this->strTable] = array('id' => $this->urlEncode($this->intId), 'childs' => \Input::get('childs'), 'mode' => \Input::get('mode')); $objSession->set('CLIPBOARD', $arrClipboard); } // Get the session data and toggle the nodes if (\Input::get('tg') == 'all') { /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = $objSession->getBag('contao_backend'); $session = $objSessionBag->all(); // Expand tree if (!is_array($session['filetree']) || empty($session['filetree']) || current($session['filetree']) != 1) { $session['filetree'] = $this->getMD5Folders(\Config::get('uploadPath')); } else { $session['filetree'] = array(); } $objSessionBag->replace($session); $this->redirect(preg_replace('/(&(amp;)?|\\?)tg=[^& ]*/i', '', \Environment::get('request'))); } $blnClipboard = false; $arrClipboard = $objSession->get('CLIPBOARD'); // Check clipboard if (!empty($arrClipboard[$this->strTable])) { $blnClipboard = true; $arrClipboard = $arrClipboard[$this->strTable]; } // Load the fonts to display the paste hint \Config::set('loadGoogleFonts', $blnClipboard); $this->import('Files'); $this->import('BackendUser', 'User'); // Call recursive function tree() if (empty($this->arrFilemounts) && !is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['root']) && $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['root'] !== false) { $return .= $this->generateTree(TL_ROOT . '/' . \Config::get('uploadPath'), 0, false, true, $blnClipboard ? $arrClipboard : false); } else { for ($i = 0, $c = count($this->arrFilemounts); $i < $c; $i++) { if ($this->arrFilemounts[$i] != '' && is_dir(TL_ROOT . '/' . $this->arrFilemounts[$i])) { $return .= $this->generateTree(TL_ROOT . '/' . $this->arrFilemounts[$i], 0, true, true, $blnClipboard ? $arrClipboard : false); } } } // Check for the "create new" button $clsNew = 'header_new_folder'; $lblNew = $GLOBALS['TL_LANG'][$this->strTable]['new'][0]; $ttlNew = $GLOBALS['TL_LANG'][$this->strTable]['new'][1]; $hrfNew = '&act=paste&mode=create'; if (isset($GLOBALS['TL_DCA'][$this->strTable]['list']['new'])) { $clsNew = $GLOBALS['TL_DCA'][$this->strTable]['list']['new']['class']; $lblNew = $GLOBALS['TL_DCA'][$this->strTable]['list']['new']['label'][0]; $ttlNew = $GLOBALS['TL_DCA'][$this->strTable]['list']['new']['label'][1]; $hrfNew = $GLOBALS['TL_DCA'][$this->strTable]['list']['new']['href']; } $imagePasteInto = \Image::getHtml('pasteinto.gif', $GLOBALS['TL_LANG'][$this->strTable]['pasteinto'][0]); // Build the tree $return = ' <div id="tl_buttons">' . (\Input::get('act') == 'select' ? ' <a href="' . $this->getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> ' : '') . (\Input::get('act') != 'select' && !$blnClipboard ? ' <a href="' . $this->addToUrl($hrfNew) . '" class="' . $clsNew . '" title="' . specialchars($ttlNew) . '" accesskey="n" onclick="Backend.getScrollOffset()">' . $lblNew . '</a> ' . (!$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable'] ? '<a href="' . $this->addToUrl('&act=paste&mode=move') . '" class="header_new" title="' . specialchars($GLOBALS['TL_LANG'][$this->strTable]['move'][1]) . '" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG'][$this->strTable]['move'][0] . '</a> ' : '') . $this->generateGlobalButtons() : '') . ($blnClipboard ? '<a href="' . $this->addToUrl('clipboard=1') . '" class="header_clipboard" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['clearClipboard']) . '" accesskey="x">' . $GLOBALS['TL_LANG']['MSC']['clearClipboard'] . '</a> ' : '') . ' </div>' . \Message::generate(true) . (\Input::get('act') == 'select' ? ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_select" class="tl_form' . (\Input::get('act') == 'select' ? ' unselectable' : '') . '" method="post" novalidate> <div class="tl_formbody"> <input type="hidden" name="FORM_SUBMIT" value="tl_select"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '">' : '') . ($blnClipboard ? ' <div id="paste_hint"> <p>' . $GLOBALS['TL_LANG']['MSC']['selectNewPosition'] . '</p> </div>' : '') . ' <div class="tl_listing_container tree_view" id="tl_listing">' . (isset($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['breadcrumb']) ? $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['breadcrumb'] : '') . (\Input::get('act') == 'select' ? ' <div class="tl_select_trigger"> <label for="tl_select_trigger" class="tl_select_label">' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</label> <input type="checkbox" id="tl_select_trigger" onclick="Backend.toggleCheckboxes(this)" class="tl_tree_checkbox"> </div>' : '') . ' <ul class="tl_listing"> <li class="tl_folder_top" onmouseover="Theme.hoverDiv(this,1)" onmouseout="Theme.hoverDiv(this,0)"><div class="tl_left">' . \Image::getHtml('filemounts.gif') . ' ' . $GLOBALS['TL_LANG']['MSC']['filetree'] . '</div> <div class="tl_right">' . ($blnClipboard && empty($this->arrFilemounts) && !is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['root']) && $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['root'] !== false ? '<a href="' . $this->addToUrl('&act=' . $arrClipboard['mode'] . '&mode=2&pid=' . \Config::get('uploadPath') . (!is_array($arrClipboard['id']) ? '&id=' . $arrClipboard['id'] : '')) . '" title="' . specialchars($GLOBALS['TL_LANG'][$this->strTable]['pasteinto'][1]) . '" onclick="Backend.getScrollOffset()">' . $imagePasteInto . '</a>' : ' ') . '</div><div style="clear:both"></div></li>' . $return . ' </ul> </div>'; // Close the form if (\Input::get('act') == 'select') { // Submit buttons $arrButtons = array(); if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notDeletable']) { $arrButtons['delete'] = '<button type="submit" name="delete" id="delete" class="tl_submit" accesskey="d" onclick="return confirm(\'' . $GLOBALS['TL_LANG']['MSC']['delAllConfirmFile'] . '\')">' . $GLOBALS['TL_LANG']['MSC']['deleteSelected'] . '</button>'; } if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notSortable']) { $arrButtons['cut'] = '<button type="submit" name="cut" id="cut" class="tl_submit" accesskey="x">' . $GLOBALS['TL_LANG']['MSC']['moveSelected'] . '</button>'; } if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notCopyable']) { $arrButtons['copy'] = '<button type="submit" name="copy" id="copy" class="tl_submit" accesskey="c">' . $GLOBALS['TL_LANG']['MSC']['copySelected'] . '</button>'; } if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable']) { $arrButtons['edit'] = '<button type="submit" name="edit" id="edit" class="tl_submit" accesskey="s">' . $GLOBALS['TL_LANG']['MSC']['editSelected'] . '</button>'; } // Call the buttons_callback (see #4691) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['select']['buttons_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['select']['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); } } } $return .= ' <div class="tl_formbody_submit" style="text-align:right"> <div class="tl_submit_container"> ' . implode(' ', $arrButtons) . ' </div> </div> </div> </form>'; } return $return; }
/** * Sets a Contao parameter. * * @param string $key The key * @param mixed $value The value */ public function setConfig($key, $value) { Config::set($key, $value); }
/** * Run the controller and parse the template */ public function run() { $template = new BackendTemplate('be_main'); $template->main = ''; // Ajax request if ($_POST && Environment::get('isAjaxRequest')) { $this->objAjax = new Ajax(Input::post('action')); $this->objAjax->executePreActions(); } $strTable = Input::get('table'); $strField = Input::get('field'); // Define the current ID define('CURRENT_ID', Input::get('table') ? $this->Session->get('CURRENT_ID') : Input::get('id')); Controller::loadDataContainer($strTable); $strDriver = 'DC_' . $GLOBALS['TL_DCA'][$strTable]['config']['dataContainer']; $objDca = new $strDriver($strTable); $objDca->field = $strField; // Set the active record if ($this->Database->tableExists($strTable)) { /** @var Model $strModel $strModel */ $strModel = Model::getClassFromTable($strTable); if (class_exists($strModel)) { $objModel = $strModel::findByPk(Input::get('id')); if ($objModel !== null) { $objDca->activeRecord = $objModel; } } } // AJAX request if ($_POST && Environment::get('isAjaxRequest')) { $this->objAjax->executePostActions($objDca); } $partial = new BackendTemplate('be_rte_table_editor'); $template->isPopup = true; $template->main = $partial->parse(); $template->theme = Backend::getTheme(); $template->base = Environment::get('base'); $template->language = $GLOBALS['TL_LANGUAGE']; $template->title = specialchars($GLOBALS['TL_LANG']['MSC']['pagepicker']); $template->charset = Config::get('characterSet'); Config::set('debugMode', false); $template->output(); }
/** * Version 3.0.0 update */ protected function update300() { // Step 1: database structure if (!$this->Database->tableExists('tl_files')) { $this->enableMaintenanceMode(); if (\Input::post('FORM_SUBMIT') == 'tl_30update') { $this->import('Database\\Updater', 'Updater'); $this->Updater->run300Update(); $this->reload(); } // Disable the tasks extension (see #4907) if (is_dir(TL_ROOT . '/system/modules/tasks')) { \System::disableModule('tasks'); } // Reset the upload path if it has been changed already (see #5560 and #5870) if (\Config::get('uploadPath') == 'files' && is_dir(TL_ROOT . '/tl_files')) { \Config::set('uploadPath', 'tl_files'); \Config::persist('uploadPath', 'tl_files'); } // Show a warning if the upload folder does not exist (see #4626) if (!is_dir(TL_ROOT . '/' . \Config::get('uploadPath'))) { $this->Template->filesWarning = sprintf($GLOBALS['TL_LANG']['tl_install']['filesWarning'], '<a href="https://gist.github.com/3304014" target="_blank">https://gist.github.com/3304014</a>'); } $this->Template->step = 1; $this->Template->is30Update = true; $this->outputAndExit(); } $objRow = $this->Database->query("SELECT COUNT(*) AS count FROM tl_files"); // Step 2: scan the upload folder if it is not empty (see #6061) if ($objRow->count < 1 && count(scan(TL_ROOT . '/' . \Config::get('uploadPath'))) > 0) { $this->enableMaintenanceMode(); if (\Input::post('FORM_SUBMIT') == 'tl_30update') { $this->import('Database\\Updater', 'Updater'); $this->Updater->scanUploadFolder(); \Config::persist('checkFileTree', true); $this->reload(); } $this->Template->step = 2; $this->Template->is30Update = true; $this->outputAndExit(); } elseif (\Config::get('checkFileTree')) { $this->enableMaintenanceMode(); if (\Input::post('FORM_SUBMIT') == 'tl_30update') { $this->import('Database\\Updater', 'Updater'); $this->Updater->updateFileTreeFields(); \Config::persist('checkFileTree', false); $this->reload(); } $this->Template->step = 3; $this->Template->is30Update = true; $this->outputAndExit(); } }