/** * Run the controller and parse the login template * * @return Response */ public function run() { /** @var BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_login'); $strHeadline = sprintf($GLOBALS['TL_LANG']['MSC']['loginTo'], \Config::get('websiteTitle')); $objTemplate->theme = \Backend::getTheme(); $objTemplate->messages = \Message::generate(); $objTemplate->base = \Environment::get('base'); $objTemplate->language = $GLOBALS['TL_LANGUAGE']; $objTemplate->languages = \System::getLanguages(true); $objTemplate->title = \StringUtil::specialchars($strHeadline); $objTemplate->charset = \Config::get('characterSet'); $objTemplate->action = ampersand(\Environment::get('request')); $objTemplate->userLanguage = $GLOBALS['TL_LANG']['tl_user']['language'][0]; $objTemplate->headline = $strHeadline; $objTemplate->curLanguage = \Input::post('language') ?: str_replace('-', '_', $GLOBALS['TL_LANGUAGE']); $objTemplate->curUsername = \Input::post('username') ?: ''; $objTemplate->uClass = $_POST && empty($_POST['username']) ? ' class="login_error"' : ''; $objTemplate->pClass = $_POST && empty($_POST['password']) ? ' class="login_error"' : ''; $objTemplate->loginButton = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['loginBT']); $objTemplate->username = $GLOBALS['TL_LANG']['tl_user']['username'][0]; $objTemplate->password = $GLOBALS['TL_LANG']['MSC']['password'][0]; $objTemplate->feLink = $GLOBALS['TL_LANG']['MSC']['feLink']; $objTemplate->default = $GLOBALS['TL_LANG']['MSC']['default']; $objTemplate->jsDisabled = $GLOBALS['TL_LANG']['MSC']['jsDisabled']; return $objTemplate->getResponse(); }
/** * Initialize the controller * * 1. Import the user * 2. Call the parent constructor * 3. Authenticate the user * 4. Load the language files * DO NOT CHANGE THIS ORDER! */ public function __construct() { $this->import('BackendUser', 'User'); parent::__construct(); $this->User->authenticate(); \System::loadLanguageFile('default'); }
/** * Get the current action * * @param string $strAction * * @throws \Exception */ public function __construct($strAction) { if ($strAction == '') { throw new \Exception('Missing Ajax action'); } $this->strAction = $strAction; parent::__construct(); }
/** * Constructor */ public function __construct() { try { $this->apiKey = Config::get('clr_api_key'); $this->soap = new SoapClient(Config::get('clr_wsdl_url')); } catch (Exception $e) { $this->log('Kein API-Key oder WSDL-File für cleverreach.de in den Einstellungen hinterlegt', 'CleverReach::construct', TL_ERROR); } parent::__construct(); }
/** * Generate the widget and return it as string * * @return string */ public function generate() { $this->import('BackendUser', 'User'); $this->convertValuesToPaths(); /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); $strNode = $objSessionBag->get('tl_files_picker'); // Unset the node if it is not within the path (see #5899) if ($strNode != '' && $this->path != '') { if (strncmp($strNode . '/', $this->path . '/', strlen($this->path) + 1) !== 0) { $objSessionBag->remove('tl_files_picker'); } } // Add the breadcrumb menu if (\Input::get('do') != 'files') { \Backend::addFilesBreadcrumb('tl_files_picker'); } $tree = ''; // Root nodes (breadcrumb menu) if (!empty($GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'])) { $nodes = $this->eliminateNestedPaths($GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root']); foreach ($nodes as $node) { $tree .= $this->renderFiletree(TL_ROOT . '/' . $node, 0, true); } } elseif ($this->path != '') { $protected = true; $path = $this->path; // Check if the folder is protected (see #287) do { if (file_exists(TL_ROOT . '/' . $path . '/.public')) { $protected = false; } $path = dirname($path); } while ($path != '.' && $protected !== false); $tree .= $this->renderFiletree(TL_ROOT . '/' . $this->path, 0, false, $protected); } elseif ($this->User->isAdmin) { $tree .= $this->renderFiletree(TL_ROOT . '/' . \Config::get('uploadPath'), 0); } else { $nodes = $this->eliminateNestedPaths($this->User->filemounts); foreach ($nodes as $node) { $tree .= $this->renderFiletree(TL_ROOT . '/' . $node, 0, true); } } // Select all checkboxes if ($this->fieldType == 'checkbox') { $strReset = "\n" . ' <li class="tl_folder"><div class="tl_left"> </div> <div class="tl_right"><label for="check_all_' . $this->strId . '" class="tl_change_selected">' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</label> <input type="checkbox" id="check_all_' . $this->strId . '" class="tl_tree_checkbox" value="" onclick="Backend.toggleCheckboxGroup(this,\'' . $this->strName . '\')"></div><div style="clear:both"></div></li>'; } else { $strReset = "\n" . ' <li class="tl_folder"><div class="tl_left"> </div> <div class="tl_right"><label for="reset_' . $this->strId . '" class="tl_change_selected">' . $GLOBALS['TL_LANG']['MSC']['resetSelected'] . '</label> <input type="radio" name="' . $this->strName . '" id="reset_' . $this->strName . '" class="tl_tree_radio" value="" onfocus="Backend.getScrollOffset()"></div><div style="clear:both"></div></li>'; } // Return the tree return '<ul class="tl_listing tree_view picker_selector' . ($this->strClass != '' ? ' ' . $this->strClass : '') . '" id="' . $this->strId . '"> <li class="tl_folder_top"><div class="tl_left">' . \Image::getHtml($GLOBALS['TL_DCA']['tl_files']['list']['sorting']['icon'] ?: 'filemounts.gif') . ' ' . (\Config::get('websiteTitle') ?: 'Contao Open Source CMS') . '</div> <div class="tl_right"> </div><div style="clear:both"></div></li><li class="parent" id="' . $this->strId . '_parent"><ul>' . $tree . $strReset . ' </ul></li></ul>'; }
/** * Run the controller and parse the password template * * @return Response */ public function run() { /** @var BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_password'); if (\Input::post('FORM_SUBMIT') == 'tl_password') { $pw = \Input::postUnsafeRaw('password'); $cnf = \Input::postUnsafeRaw('confirm'); // The passwords do not match if ($pw != $cnf) { \Message::addError($GLOBALS['TL_LANG']['ERR']['passwordMatch']); } elseif (Utf8::strlen($pw) < \Config::get('minPasswordLength')) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['passwordLength'], \Config::get('minPasswordLength'))); } elseif ($pw == $this->User->username) { \Message::addError($GLOBALS['TL_LANG']['ERR']['passwordName']); } else { // Make sure the password has been changed if (\Encryption::verify($pw, $this->User->password)) { \Message::addError($GLOBALS['TL_LANG']['MSC']['pw_change']); } else { $this->loadDataContainer('tl_user'); // Trigger the save_callback if (is_array($GLOBALS['TL_DCA']['tl_user']['fields']['password']['save_callback'])) { foreach ($GLOBALS['TL_DCA']['tl_user']['fields']['password']['save_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $pw = $this->{$callback[0]}->{$callback[1]}($pw); } elseif (is_callable($callback)) { $pw = $callback($pw); } } } $objUser = \UserModel::findByPk($this->User->id); $objUser->pwChange = ''; $objUser->password = \Encryption::hash($pw); $objUser->save(); \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['pw_changed']); $this->redirect('contao/main.php'); } } $this->reload(); } $objTemplate->theme = \Backend::getTheme(); $objTemplate->messages = \Message::generate(); $objTemplate->base = \Environment::get('base'); $objTemplate->language = $GLOBALS['TL_LANGUAGE']; $objTemplate->title = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['pw_new']); $objTemplate->charset = \Config::get('characterSet'); $objTemplate->action = ampersand(\Environment::get('request')); $objTemplate->headline = $GLOBALS['TL_LANG']['MSC']['pw_change']; $objTemplate->submitButton = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['continue']); $objTemplate->password = $GLOBALS['TL_LANG']['MSC']['password'][0]; $objTemplate->confirm = $GLOBALS['TL_LANG']['MSC']['confirm'][0]; return $objTemplate->getResponse(); }
/** * Run the controller and parse the template * * @return Response */ public function run() { /** @var BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_alerts'); $objTemplate->theme = \Backend::getTheme(); $objTemplate->base = \Environment::get('base'); $objTemplate->language = $GLOBALS['TL_LANGUAGE']; $objTemplate->title = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['systemMessages']); $objTemplate->charset = \Config::get('characterSet'); $objTemplate->messages = \Message::generateUnwrapped() . \Backend::getSystemMessages(); return $objTemplate->getResponse(); }
/** * Auto expand the tree * * @throws \Exception */ public function autoExpandTree() { $session = Session::getInstance()->getData(); if ($session['seo_serp_expand_tree'] !== 'tl_page' && !Input::get('serp_tests_expand')) { return; } $nodes = Database::getInstance()->execute("SELECT DISTINCT pid FROM tl_page WHERE pid>0"); // Reset the array first $session['tl_page_tree'] = []; // Expand the tree while ($nodes->next()) { $session['tl_page_tree'][$nodes->pid] = 1; } // Avoid redirect loop $session['seo_serp_expand_tree'] = null; Session::getInstance()->setData($session); Backend::redirect(str_replace('serp_tests_expand=1', '', Environment::get('request'))); }
/** * 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(); }
/** * 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(); }
/** * Render the versions dropdown menu * * @return string */ public function renderDropdown() { $objVersion = $this->Database->prepare("SELECT tstamp, version, username, active FROM tl_version WHERE fromTable=? AND pid=? ORDER BY version DESC")->execute($this->strTable, $this->intPid); if ($objVersion->numRows < 2) { return ''; } $versions = ''; while ($objVersion->next()) { $versions .= ' <option value="' . $objVersion->version . '"' . ($objVersion->active ? ' selected="selected"' : '') . '>' . $GLOBALS['TL_LANG']['MSC']['version'] . ' ' . $objVersion->version . ' (' . \Date::parse(\Config::get('datimFormat'), $objVersion->tstamp) . ') ' . $objVersion->username . '</option>'; } return ' <div class="tl_version_panel"> <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_version" class="tl_form" method="post"> <div class="tl_formbody"> <input type="hidden" name="FORM_SUBMIT" value="tl_version"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <select name="version" class="tl_select">' . $versions . ' </select> <button type="submit" name="showVersion" id="showVersion" class="tl_submit">' . $GLOBALS['TL_LANG']['MSC']['restore'] . '</button> <a href="' . \Backend::addToUrl('versions=1&popup=1') . '" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['showDifferences']) . '" onclick="Backend.openModalIframe({\'width\':768,\'title\':\'' . \StringUtil::specialchars(str_replace("'", "\\'", sprintf($GLOBALS['TL_LANG']['MSC']['recordOfTable'], $this->intPid, $this->strTable))) . '\',\'url\':this.href});return false">' . \Image::getHtml('diff.svg') . '</a> </div> </form> </div> '; }
/** * Run the controller and parse the template * * @return Response */ public function run() { $this->disableProfiler(); if (\Environment::get('isAjaxRequest')) { $this->getDatalistOptions(); } $strUser = ''; $strHash = $this->getSessionHash('FE_USER_AUTH'); // Get the front end user if (FE_USER_LOGGED_IN) { $objUser = $this->Database->prepare("SELECT username FROM tl_member WHERE id=(SELECT pid FROM tl_session WHERE hash=?)")->limit(1)->execute($strHash); if ($objUser->numRows) { $strUser = $objUser->username; } } /** @var BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_switch'); $objTemplate->user = $strUser; $objTemplate->show = \Input::cookie('FE_PREVIEW'); $objTemplate->update = false; // Switch if (\Input::post('FORM_SUBMIT') == 'tl_switch') { $time = time(); // Hide unpublished elements if (\Input::post('unpublished') == 'hide') { $this->setCookie('FE_PREVIEW', 0, $time - 86400); $objTemplate->show = 0; } else { $this->setCookie('FE_PREVIEW', 1, $time + \Config::get('sessionTimeout')); $objTemplate->show = 1; } // Allow admins to switch user accounts if ($this->User->isAdmin) { // Remove old sessions $this->Database->prepare("DELETE FROM tl_session WHERE tstamp<? OR hash=?")->execute($time - \Config::get('sessionTimeout'), $strHash); // Log in the front end user if (\Input::post('user')) { $objUser = \MemberModel::findByUsername(\Input::post('user')); if ($objUser !== null) { // Insert the new session $this->Database->prepare("INSERT INTO tl_session (pid, tstamp, name, sessionID, ip, hash) VALUES (?, ?, ?, ?, ?, ?)")->execute($objUser->id, $time, 'FE_USER_AUTH', \System::getContainer()->get('session')->getId(), \Environment::get('ip'), $strHash); // Set the cookie $this->setCookie('FE_USER_AUTH', $strHash, $time + \Config::get('sessionTimeout'), null, null, false, true); $objTemplate->user = \Input::post('user'); } } else { // Remove cookie $this->setCookie('FE_USER_AUTH', $strHash, $time - 86400, null, null, false, true); $objTemplate->user = ''; } } $objTemplate->update = true; } // Default variables $objTemplate->theme = \Backend::getTheme(); $objTemplate->base = \Environment::get('base'); $objTemplate->language = $GLOBALS['TL_LANGUAGE']; $objTemplate->apply = $GLOBALS['TL_LANG']['MSC']['apply']; $objTemplate->reload = $GLOBALS['TL_LANG']['MSC']['reload']; $objTemplate->feUser = $GLOBALS['TL_LANG']['MSC']['feUser']; $objTemplate->username = $GLOBALS['TL_LANG']['MSC']['username']; $objTemplate->charset = \Config::get('characterSet'); $objTemplate->lblHide = $GLOBALS['TL_LANG']['MSC']['hiddenHide']; $objTemplate->lblShow = $GLOBALS['TL_LANG']['MSC']['hiddenShow']; $objTemplate->fePreview = $GLOBALS['TL_LANG']['MSC']['fePreview']; $objTemplate->hiddenElements = $GLOBALS['TL_LANG']['MSC']['hiddenElements']; $objTemplate->closeSrc = TL_FILES_URL . 'system/themes/' . \Backend::getTheme() . '/images/close.gif'; $objTemplate->action = ampersand(\Environment::get('request')); $objTemplate->isAdmin = $this->User->isAdmin; return $objTemplate->getResponse(); }
/** * Add a breadcrumb menu to the file tree * * @param string $strKey * * @throws AccessDeniedException * @throws \RuntimeException */ public static function addFilesBreadcrumb($strKey = 'tl_files_node') { /** @var AttributeBagInterface $objSession */ $objSession = \System::getContainer()->get('session')->getBag('contao_backend'); // Set a new node if (isset($_GET['fn'])) { // Check the path (thanks to Arnaud Buchoux) if (\Validator::isInsecurePath(\Input::get('fn', true))) { throw new \RuntimeException('Insecure path ' . \Input::get('fn', true)); } $objSession->set($strKey, \Input::get('fn', true)); \Controller::redirect(preg_replace('/(&|\\?)fn=[^&]*/', '', \Environment::get('request'))); } $strNode = $objSession->get($strKey); if ($strNode == '') { return; } // Check the path (thanks to Arnaud Buchoux) if (\Validator::isInsecurePath($strNode)) { throw new \RuntimeException('Insecure path ' . $strNode); } // Currently selected folder does not exist if (!is_dir(TL_ROOT . '/' . $strNode)) { $objSession->set($strKey, ''); return; } $objUser = \BackendUser::getInstance(); $strPath = \Config::get('uploadPath'); $arrNodes = explode('/', preg_replace('/^' . preg_quote(\Config::get('uploadPath'), '/') . '\\//', '', $strNode)); $arrLinks = array(); // Add root link $arrLinks[] = \Image::getHtml('filemounts.svg') . ' <a href="' . \Backend::addToUrl('fn=') . '" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['selectAllNodes']) . '">' . $GLOBALS['TL_LANG']['MSC']['filterAll'] . '</a>'; // Generate breadcrumb trail foreach ($arrNodes as $strFolder) { $strPath .= '/' . $strFolder; // Do not show pages which are not mounted if (!$objUser->hasAccess($strPath, 'filemounts')) { continue; } // No link for the active folder if ($strPath == $strNode) { $arrLinks[] = \Image::getHtml('folderC.svg') . ' ' . $strFolder; } else { $arrLinks[] = \Image::getHtml('folderC.svg') . ' <a href="' . \Backend::addToUrl('fn=' . $strPath) . '" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['selectNode']) . '">' . $strFolder . '</a>'; } } // Check whether the node is mounted if (!$objUser->hasAccess($strNode, 'filemounts')) { $objSession->set($strKey, ''); throw new AccessDeniedException('Folder ID "' . $strNode . '" is not mounted'); } // Limit tree $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'] = array($strNode); // Insert breadcrumb menu $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['breadcrumb'] .= ' <ul id="tl_breadcrumb"> <li>' . implode(' > </li><li>', $arrLinks) . '</li> </ul>'; }
/** * Import the back end user object */ public function __construct() { parent::__construct(); $this->import('BackendUser', 'User'); }
/** * Run the controller and parse the template * * @return Response */ public function run() { $table = \Input::get('table'); $field = \Input::get('field'); \System::loadLanguageFile($table); $this->loadDataContainer($table); /** @var BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_help'); $objTemplate->rows = array(); $objTemplate->explanation = ''; $arrData = $GLOBALS['TL_DCA'][$table]['fields'][$field]; // Add the reference if (!empty($arrData['reference'])) { $rows = array(); if (is_array($arrData['options'])) { $options = $arrData['options']; } elseif (is_array($arrData['options_callback'])) { $this->import($arrData['options_callback'][0]); $options = $this->{$arrData['options_callback'][0]}->{$arrData['options_callback'][1]}(new \DC_Table($table)); } elseif (is_callable($arrData['options_callback'])) { $options = $arrData['options_callback'](); } else { $options = array_keys($arrData['reference']); } // Unset the predefined image sizes unset($options['image_sizes']); foreach ($options as $key => $option) { if (is_array($option)) { if (is_array($arrData['reference'][$key])) { $rows[] = array('headspan', $arrData['reference'][$key][0]); } else { $rows[] = array('headspan', $arrData['reference'][$key]); } foreach ($option as $opt) { $rows[] = $arrData['reference'][$opt]; } } else { if (isset($arrData['reference'][$key])) { $rows[] = $arrData['reference'][$key]; } elseif (is_array($arrData['reference'][$option])) { $rows[] = $arrData['reference'][$option]; } else { $rows[] = array('headspan', $arrData['reference'][$option]); } } } $objTemplate->rows = $rows; } // Add an explanation if (isset($arrData['explanation'])) { \System::loadLanguageFile('explain'); $key = $arrData['explanation']; if (!is_array($GLOBALS['TL_LANG']['XPL'][$key])) { $objTemplate->explanation = trim($GLOBALS['TL_LANG']['XPL'][$key]); } else { $objTemplate->rows = $GLOBALS['TL_LANG']['XPL'][$key]; } } $objTemplate->theme = \Backend::getTheme(); $objTemplate->base = \Environment::get('base'); $objTemplate->language = $GLOBALS['TL_LANGUAGE']; $objTemplate->title = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['helpWizardTitle']); $objTemplate->charset = \Config::get('characterSet'); $objTemplate->headline = $arrData['label'][0] ?: $field; $objTemplate->helpWizard = $GLOBALS['TL_LANG']['MSC']['helpWizard']; return $objTemplate->getResponse(); }
/** * Run the tests for given table * * @param string $module * @param string $table * * @return array */ protected function runTestsForTable($module, $table) { $db = Database::getInstance(); $user = BackendUser::getInstance(); $return = []; switch ($table) { case 'tl_calendar_events': $calendars = $db->execute("SELECT id, title FROM tl_calendar WHERE seo_serp_ignore='' ORDER BY title"); while ($calendars->next()) { $test = $this->runTests($table, $db->prepare("SELECT * FROM tl_calendar_events WHERE pid=?")->execute($calendars->id)); $return[] = ['url' => Backend::addToUrl($this->redirectParamName . '=' . $module . '|' . base64_encode('table=' . $table . '&id=' . $calendars->id)), 'reference' => $calendars->title, 'message' => $this->generateTestMessage($test), 'result' => $test, 'hasAccess' => $user->isAdmin || is_array($user->calendars) && in_array($calendars->id, $user->calendars)]; } break; case 'tl_news': $archives = $db->execute("SELECT id, title FROM tl_news_archive WHERE seo_serp_ignore='' ORDER BY title"); while ($archives->next()) { $test = $this->runTests($table, $db->prepare("SELECT * FROM tl_news WHERE pid=?")->execute($archives->id)); $return[] = ['url' => Backend::addToUrl($this->redirectParamName . '=' . $module . '|' . base64_encode('table=' . $table . '&id=' . $archives->id)), 'reference' => $archives->title, 'message' => $this->generateTestMessage($test), 'result' => $test, 'hasAccess' => $user->isAdmin || is_array($user->news) && in_array($archives->id, $user->news)]; } break; case 'tl_page': $rootIds = $db->execute("SELECT id FROM tl_page WHERE type='root' AND seo_serp_ignore=''"); $pageIds = $db->getChildRecords($rootIds->fetchEach('id'), 'tl_page'); if (count($pageIds) > 0) { $pages = $db->execute("SELECT * FROM tl_page WHERE id IN (" . implode(',', $pageIds) . ")"); if ($pages->numRows) { $notes = []; $test = $this->runTests($table, $pages->reset()); // Add the note if the user is not admin and there are some errors or warnings if (!$user->isAdmin && ($test['errors'] > 0 || $test['warnings'] > 0)) { $rootCount = 0; $userCount = 0; // Count the total root pages and those the user has access to while ($pages->next()) { if ($pages->type === 'root') { $rootCount++; if (in_array($pages->id, (array) $user->pagemounts)) { $userCount++; } } } if ($userCount < $rootCount) { $notes[] = $GLOBALS['TL_LANG']['MSC']['seo_serp_module.pagesNote']; } } $return[] = ['url' => Backend::addToUrl($this->redirectParamName . '=' . $module), 'message' => $this->generateTestMessage($test), 'result' => $test, 'hasAccess' => true, 'notes' => $notes]; } } break; } return $return; }
/** * Recursively render the filetree * * @param string $path * @param integer $intMargin * @param boolean $mount * @param boolean $blnProtected * @param array $arrFound * * @return string */ protected function renderFiletree($path, $intMargin, $mount = false, $blnProtected = true, $arrFound = array()) { // Invalid path if (!is_dir($path)) { return ''; } // Make sure that $this->varValue is an array (see #3369) if (!is_array($this->varValue)) { $this->varValue = array($this->varValue); } static $session; /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); $session = $objSessionBag->all(); $flag = substr($this->strField, 0, 2); $node = 'tree_' . $this->strTable . '_' . $this->strField; $xtnode = 'tree_' . $this->strTable . '_' . $this->strName; // Get session data and toggle nodes if (\Input::get($flag . 'tg')) { $session[$node][\Input::get($flag . 'tg')] = isset($session[$node][\Input::get($flag . 'tg')]) && $session[$node][\Input::get($flag . 'tg')] == 1 ? 0 : 1; $objSessionBag->replace($session); $this->redirect(preg_replace('/(&(amp;)?|\\?)' . $flag . 'tg=[^& ]*/i', '', \Environment::get('request'))); } $return = ''; $intSpacing = 20; $files = array(); $folders = array(); $level = $intMargin / $intSpacing + 1; // Mount folder if ($mount) { $folders = array($path); } else { foreach (scan($path) as $v) { if (strncmp($v, '.', 1) === 0) { continue; } if (is_dir($path . '/' . $v)) { $folders[] = $path . '/' . $v; } else { $files[] = $path . '/' . $v; } } } natcasesort($folders); $folders = array_values($folders); natcasesort($files); $files = array_values($files); // Sort descending (see #4072) if ($this->sort == 'desc') { $folders = array_reverse($folders); $files = array_reverse($files); } $folderClass = $this->files || $this->filesOnly ? 'tl_folder' : 'tl_file'; // Process folders for ($f = 0, $c = count($folders); $f < $c; $f++) { $content = scan($folders[$f]); $currentFolder = str_replace(TL_ROOT . '/', '', $folders[$f]); $countFiles = count($content); // Check whether there are subfolders or files foreach ($content as $file) { if (strncmp($file, '.', 1) === 0) { --$countFiles; } elseif (!$this->files && !$this->filesOnly && is_file($folders[$f] . '/' . $file)) { --$countFiles; } elseif (!empty($arrFound) && !in_array($currentFolder . '/' . $file, $arrFound) && !preg_grep('/^' . preg_quote($currentFolder . '/' . $file, '/') . '\\//', $arrFound)) { --$countFiles; } } if (!empty($arrFound) && $countFiles < 1 && !in_array($currentFolder, $arrFound)) { continue; } $tid = md5($folders[$f]); $folderAttribute = 'style="margin-left:20px"'; $session[$node][$tid] = is_numeric($session[$node][$tid]) ? $session[$node][$tid] : 0; $currentFolder = str_replace(TL_ROOT . '/', '', $folders[$f]); $blnIsOpen = !empty($arrFound) || $session[$node][$tid] == 1 || count(preg_grep('/^' . preg_quote($currentFolder, '/') . '\\//', $this->varValue)) > 0; $return .= "\n " . '<li class="' . $folderClass . ' toggle_select hover-div"><div class="tl_left" style="padding-left:' . $intMargin . 'px">'; // Add a toggle button if there are childs if ($countFiles > 0) { $folderAttribute = ''; $img = $blnIsOpen ? 'folMinus.svg' : 'folPlus.svg'; $alt = $blnIsOpen ? $GLOBALS['TL_LANG']['MSC']['collapseNode'] : $GLOBALS['TL_LANG']['MSC']['expandNode']; $return .= '<a href="' . \Backend::addToUrl($flag . 'tg=' . $tid) . '" title="' . \StringUtil::specialchars($alt) . '" onclick="return AjaxRequest.toggleFiletree(this,\'' . $xtnode . '_' . $tid . '\',\'' . $currentFolder . '\',\'' . $this->strField . '\',\'' . $this->strName . '\',' . $level . ')">' . \Image::getHtml($img, '', 'style="margin-right:2px"') . '</a>'; } $protected = $blnProtected; // Check whether the folder is public if ($protected === true && array_search('.public', $content) !== false) { $protected = false; } $folderImg = $protected ? 'folderCP.svg' : 'folderC.svg'; $folderLabel = $this->files || $this->filesOnly ? '<strong>' . \StringUtil::specialchars(basename($currentFolder)) . '</strong>' : \StringUtil::specialchars(basename($currentFolder)); // Add the current folder $return .= \Image::getHtml($folderImg, '', $folderAttribute) . ' <a href="' . \Backend::addToUrl('fn=' . $this->urlEncode($currentFolder)) . '" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['selectNode']) . '">' . $folderLabel . '</a></div> <div class="tl_right">'; // Add a checkbox or radio button if (!$this->filesOnly) { switch ($this->fieldType) { case 'checkbox': $return .= '<input type="checkbox" name="' . $this->strName . '[]" id="' . $this->strName . '_' . md5($currentFolder) . '" class="tl_tree_checkbox" value="' . \StringUtil::specialchars($currentFolder) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFolder, $this->varValue) . '>'; break; case 'radio': $return .= '<input type="radio" name="' . $this->strName . '" id="' . $this->strName . '_' . md5($currentFolder) . '" class="tl_tree_radio" value="' . \StringUtil::specialchars($currentFolder) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFolder, $this->varValue) . '>'; break; } } $return .= '</div><div style="clear:both"></div></li>'; // Call the next node if ($blnIsOpen) { $return .= '<li class="parent" id="' . $xtnode . '_' . $tid . '"><ul class="level_' . $level . '">'; $return .= $this->renderFiletree($folders[$f], $intMargin + $intSpacing, false, $protected, $arrFound); $return .= '</ul></li>'; } } // Process files if ($this->files || $this->filesOnly) { for ($h = 0, $c = count($files); $h < $c; $h++) { $thumbnail = ''; $currentFile = str_replace(TL_ROOT . '/', '', $files[$h]); $currentEncoded = $this->urlEncode($currentFile); $objFile = new \File($currentFile); if (!empty($this->arrValidFileTypes) && !in_array($objFile->extension, $this->arrValidFileTypes)) { continue; } // Ignore files not matching the search criteria if (!empty($arrFound) && !in_array($currentFile, $arrFound)) { continue; } $return .= "\n " . '<li class="tl_file toggle_select hover-div"><div class="tl_left" style="padding-left:' . ($intMargin + $intSpacing) . 'px">'; $thumbnail .= ' <span class="tl_gray">(' . $this->getReadableSize($objFile->filesize); if ($objFile->width && $objFile->height) { $thumbnail .= ', ' . $objFile->width . 'x' . $objFile->height . ' px'; } $thumbnail .= ')</span>'; // Generate thumbnail if ($objFile->isImage && $objFile->viewHeight > 0 && \Config::get('thumbnails') && ($objFile->isSvgImage || $objFile->height <= \Config::get('gdMaxImgHeight') && $objFile->width <= \Config::get('gdMaxImgWidth'))) { $imageObj = \Image::create($currentEncoded, array(400, $objFile->height && $objFile->height < 50 ? $objFile->height : 50, 'box')); $importantPart = $imageObj->getImportantPart(); $thumbnail .= '<br>' . \Image::getHtml($imageObj->executeResize()->getResizedPath(), '', 'style="margin:0 0 2px -19px"'); if ($importantPart['x'] > 0 || $importantPart['y'] > 0 || $importantPart['width'] < $objFile->width || $importantPart['height'] < $objFile->height) { $thumbnail .= ' ' . \Image::getHtml($imageObj->setZoomLevel(100)->setTargetWidth(320)->setTargetHeight($objFile->height && $objFile->height < 40 ? $objFile->height : 40)->executeResize()->getResizedPath(), '', 'style="margin:0 0 2px 0;vertical-align:bottom"'); } } $return .= \Image::getHtml($objFile->icon, $objFile->mime) . ' ' . \StringUtil::convertEncoding(\StringUtil::specialchars(basename($currentFile)), \Config::get('characterSet')) . $thumbnail . '</div> <div class="tl_right">'; // Add checkbox or radio button switch ($this->fieldType) { case 'checkbox': $return .= '<input type="checkbox" name="' . $this->strName . '[]" id="' . $this->strName . '_' . md5($currentFile) . '" class="tl_tree_checkbox" value="' . \StringUtil::specialchars($currentFile) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFile, $this->varValue) . '>'; break; case 'radio': $return .= '<input type="radio" name="' . $this->strName . '" id="' . $this->strName . '_' . md5($currentFile) . '" class="tl_tree_radio" value="' . \StringUtil::specialchars($currentFile) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFile, $this->varValue) . '>'; break; } $return .= '</div><div style="clear:both"></div></li>'; } } return $return; }
/** * Import the back end user object */ public function __construct() { parent::__construct(); \System::loadLanguageFile('foundation'); $this->import('BackendUser', 'User'); }
* Table tl_email */ $GLOBALS['TL_DCA']['tl_email'] = array('config' => array('dataContainer' => 'File'), 'palettes' => array('default' => '{emailSender_legend},emailFrom,emailFromName'), 'fields' => array('emailFrom' => array('label' => &$GLOBALS['TL_LANG']['tl_email']['emailFrom'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('mandatory' => true, 'rgxp' => 'email', 'tl_class' => 'w50')), 'emailFromName' => array('label' => &$GLOBALS['TL_LANG']['tl_email']['emailFromName'], 'exclude' => true, 'inputType' => 'TranslationTextField', 'eval' => array('mandatory' => true, 'rgxp' => 'alpha', 'tl_class' => 'w50')))); /** * Add email fields dynamically */ if (is_array($GLOBALS['TL_EMAIL'])) { foreach ($GLOBALS['TL_EMAIL'] as $strName) { $arrReferences = array(); $arrReferences[] = $GLOBALS['TL_LANG']['tl_email']['helpwizard']; switch ($strName) { case 'emailNewMember': case 'emailChangedMemberPassword': $arrReferences = array_merge($arrReferences, \System::getContainer()->get('craffft.accountmail.util.helpwizard')->getHelpwizardReferencesByMember()); break; case 'emailNewUser': case 'emailChangedUserPassword': $arrReferences = array_merge($arrReferences, \System::getContainer()->get('craffft.accountmail.util.helpwizard')->getHelpwizardReferencesByUser()); break; } $GLOBALS['TL_DCA']['tl_email']['palettes']['default'] .= sprintf(';{%s_legend:hide}', $strName); $GLOBALS['TL_DCA']['tl_email']['palettes']['default'] .= sprintf(',%s%s', $strName, 'Subject'); $GLOBALS['TL_DCA']['tl_email']['palettes']['default'] .= sprintf(',%s%s', $strName, 'Template'); $GLOBALS['TL_DCA']['tl_email']['palettes']['default'] .= sprintf(',%s%s', $strName, 'Content'); $GLOBALS['TL_DCA']['tl_email']['fields'][$strName . 'Subject'] = array('label' => &$GLOBALS['TL_LANG']['tl_email']['emailSubject'], 'exclude' => true, 'inputType' => 'TranslationTextField', 'reference' => $arrReferences, 'eval' => array('mandatory' => true, 'helpwizard' => true, 'tl_class' => 'w50')); $GLOBALS['TL_DCA']['tl_email']['fields'][$strName . 'Template'] = array('label' => &$GLOBALS['TL_LANG']['tl_email']['emailTemplate'], 'default' => 'mail_default', 'exclude' => true, 'inputType' => 'select', 'options_callback' => function () { return \Contao\Backend::getTemplateGroup('mail_'); }, 'eval' => array('mandatory' => true, 'tl_class' => 'w50')); $GLOBALS['TL_DCA']['tl_email']['fields'][$strName . 'Content'] = array('label' => &$GLOBALS['TL_LANG']['tl_email']['emailContent'], 'exclude' => true, 'inputType' => 'TranslationTextArea', 'reference' => $arrReferences, 'eval' => array('mandatory' => true, 'helpwizard' => true, 'rte' => 'tinyFlash', 'tl_class' => 'clr')); } }
/** * Return the back end themes as array * * @return array An array of available back end themes * * @deprecated Deprecated since Contao 4.0, to be removed in Contao 5.0. * Use Backend::getThemes() instead. */ public static function getBackendThemes() { trigger_error('Using Controller::getBackendThemes() has been deprecated and will no longer work in Contao 5.0. Use Backend::getThemes() instead.', E_USER_DEPRECATED); return \Backend::getThemes(); }
/** * Build the sort panel and return it as string * * @return string */ protected function panel() { $search = $this->searchMenu(); if (\Input::post('FORM_SUBMIT') == 'tl_filters') { $this->reload(); } return ' <form action="' . ampersand(\Environment::get('request'), true) . '" class="tl_form" method="post"> <div class="tl_formbody"> <input type="hidden" name="FORM_SUBMIT" value="tl_filters"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <div class="tl_panel"> <div class="tl_submit_panel tl_subpanel"> <input type="image" name="filter" id="filter" src="' . TL_FILES_URL . 'system/themes/' . \Backend::getTheme() . '/images/reload.gif" class="tl_img_submit" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['applyTitle']) . '" alt="' . specialchars($GLOBALS['TL_LANG']['MSC']['apply']) . '"> </div>' . $search . ' <div class="clear"></div> </div> </div> </form> '; }
/** * Output the template file * * @return Response */ protected function output() { // Default headline if ($this->Template->headline == '') { $this->Template->headline = \Config::get('websiteTitle'); } // Default title if ($this->Template->title == '') { $this->Template->title = $this->Template->headline; } /** @var SessionInterface $objSession */ $objSession = \System::getContainer()->get('session'); // File picker reference if (\Input::get('popup') && \Input::get('act') != 'show' && (\Input::get('do') == 'page' || \Input::get('do') == 'files') && $objSession->get('filePickerRef')) { $this->Template->managerHref = ampersand($objSession->get('filePickerRef')); $this->Template->manager = strpos($objSession->get('filePickerRef'), 'contao/page?') !== false ? $GLOBALS['TL_LANG']['MSC']['pagePickerHome'] : $GLOBALS['TL_LANG']['MSC']['filePickerHome']; } // Website title if (\Config::get('websiteTitle') != 'Contao Open Source CMS') { $this->Template->websiteTitle = \Config::get('websiteTitle'); } $this->Template->theme = \Backend::getTheme(); $this->Template->base = \Environment::get('base'); $this->Template->language = $GLOBALS['TL_LANGUAGE']; $this->Template->title = \StringUtil::specialchars($this->Template->title); $this->Template->charset = \Config::get('characterSet'); $this->Template->account = $GLOBALS['TL_LANG']['MOD']['login'][1]; $this->Template->preview = $GLOBALS['TL_LANG']['MSC']['fePreview']; $this->Template->previewTitle = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['fePreviewTitle']); $this->Template->pageOffset = \Input::cookie('BE_PAGE_OFFSET'); $this->Template->logout = $GLOBALS['TL_LANG']['MSC']['logoutBT']; $this->Template->logoutTitle = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['logoutBTTitle']); $this->Template->backendModules = $GLOBALS['TL_LANG']['MSC']['backendModules']; $this->Template->username = $GLOBALS['TL_LANG']['MSC']['user'] . ' ' . $GLOBALS['TL_USERNAME']; $this->Template->skipNavigation = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['skipNavigation']); $this->Template->request = ampersand(\Environment::get('request')); $this->Template->top = $GLOBALS['TL_LANG']['MSC']['backToTop']; $this->Template->modules = $this->User->navigation(); $this->Template->home = $GLOBALS['TL_LANG']['MSC']['home']; $this->Template->homeTitle = $GLOBALS['TL_LANG']['MSC']['homeTitle']; $this->Template->backToTop = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['backToTopTitle']); $this->Template->expandNode = $GLOBALS['TL_LANG']['MSC']['expandNode']; $this->Template->collapseNode = $GLOBALS['TL_LANG']['MSC']['collapseNode']; $this->Template->loadingData = $GLOBALS['TL_LANG']['MSC']['loadingData']; $this->Template->isPopup = \Input::get('popup'); $this->Template->systemMessages = $GLOBALS['TL_LANG']['MSC']['systemMessages']; $strSystemMessages = \Backend::getSystemMessages(); $this->Template->systemMessagesCount = substr_count($strSystemMessages, 'class="tl_'); $this->Template->systemErrorMessagesCount = substr_count($strSystemMessages, 'class="tl_error"'); // Front end preview links if (defined('CURRENT_ID') && CURRENT_ID != '') { if (\Input::get('do') == 'page') { $this->Template->frontendFile = '?page=' . CURRENT_ID; } elseif (\Input::get('do') == 'article' && ($objArticle = \ArticleModel::findByPk(CURRENT_ID)) !== null) { $this->Template->frontendFile = '?page=' . $objArticle->pid; } elseif (\Input::get('do') != '') { $event = new PreviewUrlCreateEvent(\Input::get('do'), CURRENT_ID); \System::getContainer()->get('event_dispatcher')->dispatch(ContaoCoreEvents::PREVIEW_URL_CREATE, $event); if (($strQuery = $event->getQuery()) !== null) { $this->Template->frontendFile = '?' . $strQuery; } } } return $this->Template->getResponse(); }
/** * Generate the Google XML sitemaps * * @param integer $intId The root page ID */ public function generateSitemap($intId = 0) { $time = \Date::floorToMinute(); $objDatabase = \Database::getInstance(); $this->purgeXmlFiles(); // Only root pages should have sitemap names $objDatabase->execute("UPDATE tl_page SET createSitemap='', sitemapName='' WHERE type!='root'"); // Get a particular root page if ($intId > 0) { do { $objRoot = $objDatabase->prepare("SELECT * FROM tl_page WHERE id=?")->limit(1)->execute($intId); if ($objRoot->numRows < 1) { break; } $intId = $objRoot->pid; } while ($objRoot->type != 'root' && $intId > 0); // Make sure the page is published if (!$objRoot->published || $objRoot->start != '' && $objRoot->start > $time || $objRoot->stop != '' && $objRoot->stop <= $time + 60) { return; } // Check the sitemap name if (!$objRoot->createSitemap || !$objRoot->sitemapName) { return; } $objRoot->reset(); } else { $objRoot = $objDatabase->execute("SELECT id, language, sitemapName FROM tl_page WHERE type='root' AND createSitemap='1' AND sitemapName!='' AND (start='' OR start<='{$time}') AND (stop='' OR stop>'" . ($time + 60) . "') AND published='1'"); } // Return if there are no pages if ($objRoot->numRows < 1) { return; } // Create the XML file while ($objRoot->next()) { $objFile = new \File('web/share/' . $objRoot->sitemapName . '.xml'); $objFile->truncate(); $objFile->append('<?xml version="1.0" encoding="UTF-8"?>'); $objFile->append('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">'); // Find the searchable pages $arrPages = \Backend::findSearchablePages($objRoot->id, '', true); // HOOK: take additional pages if (isset($GLOBALS['TL_HOOKS']['getSearchablePages']) && is_array($GLOBALS['TL_HOOKS']['getSearchablePages'])) { foreach ($GLOBALS['TL_HOOKS']['getSearchablePages'] as $callback) { $this->import($callback[0]); $arrPages = $this->{$callback[0]}->{$callback[1]}($arrPages, $objRoot->id, true, $objRoot->language); } } // Add pages foreach ($arrPages as $strUrl) { $strUrl = rawurlencode($strUrl); $strUrl = str_replace(array('%2F', '%3F', '%3D', '%26', '%3A//'), array('/', '?', '=', '&', '://'), $strUrl); $strUrl = ampersand($strUrl, true); $objFile->append(' <url><loc>' . $strUrl . '</loc></url>'); } $objFile->append('</urlset>'); $objFile->close(); // Add a log entry $this->log('Generated sitemap "' . $objRoot->sitemapName . '.xml"', __METHOD__, TL_CRON); } }
/** * Compare versions */ public function compare() { $strBuffer = ''; $arrVersions = array(); $intTo = 0; $intFrom = 0; $objVersions = $this->Database->prepare("SELECT * FROM tl_version WHERE pid=? AND fromTable=? ORDER BY version DESC")->execute($this->intPid, $this->strTable); if ($objVersions->numRows < 2) { $strBuffer = '<p>There are no versions of ' . $this->strTable . '.id=' . $this->intPid . '</p>'; } else { $intIndex = 0; $from = array(); // Store the versions and mark the active one while ($objVersions->next()) { if ($objVersions->active) { $intIndex = $objVersions->version; } $arrVersions[$objVersions->version] = $objVersions->row(); $arrVersions[$objVersions->version]['info'] = $GLOBALS['TL_LANG']['MSC']['version'] . ' ' . $objVersions->version . ' (' . \Date::parse(\Config::get('datimFormat'), $objVersions->tstamp) . ') ' . $objVersions->username; } // To if (\Input::post('to') && isset($arrVersions[\Input::post('to')])) { $intTo = \Input::post('to'); $to = deserialize($arrVersions[\Input::post('to')]['data']); } elseif (\Input::get('to') && isset($arrVersions[\Input::get('to')])) { $intTo = \Input::get('to'); $to = deserialize($arrVersions[\Input::get('to')]['data']); } else { $intTo = $intIndex; $to = deserialize($arrVersions[$intTo]['data']); } // From if (\Input::post('from') && isset($arrVersions[\Input::post('from')])) { $intFrom = \Input::post('from'); $from = deserialize($arrVersions[\Input::post('from')]['data']); } elseif (\Input::get('from') && isset($arrVersions[\Input::get('from')])) { $intFrom = \Input::get('from'); $from = deserialize($arrVersions[\Input::get('from')]['data']); } elseif ($intIndex > 1) { $intFrom = $intIndex - 1; $from = deserialize($arrVersions[$intFrom]['data']); } // Only continue if both version numbers are set if ($intTo > 0 && $intFrom > 0) { \System::loadLanguageFile($this->strTable); $this->loadDataContainer($this->strTable); // Get the order fields $objDcaExtractor = \DcaExtractor::getInstance($this->strTable); $arrOrder = $objDcaExtractor->getOrderFields(); // Find the changed fields and highlight the changes foreach ($to as $k => $v) { if ($from[$k] != $to[$k]) { if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['inputType'] == 'password' || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['doNotShow'] || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['hideInput']) { continue; } $blnIsBinary = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['inputType'] == 'fileTree' || in_array($k, $arrOrder); // Decrypt the values if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['encrypt']) { $to[$k] = \Encryption::decrypt($to[$k]); $from[$k] = \Encryption::decrypt($from[$k]); } // Convert serialized arrays into strings if (is_array($tmp = deserialize($to[$k])) && !is_array($to[$k])) { $to[$k] = $this->implodeRecursive($tmp, $blnIsBinary); } if (is_array($tmp = deserialize($from[$k])) && !is_array($from[$k])) { $from[$k] = $this->implodeRecursive($tmp, $blnIsBinary); } unset($tmp); // Convert binary UUIDs to their hex equivalents (see #6365) if ($blnIsBinary && \Validator::isBinaryUuid($to[$k])) { $to[$k] = \StringUtil::binToUuid($to[$k]); } if ($blnIsBinary && \Validator::isBinaryUuid($from[$k])) { $to[$k] = \StringUtil::binToUuid($from[$k]); } // Convert date fields if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['rgxp'] == 'date') { $to[$k] = \Date::parse(\Config::get('dateFormat'), $to[$k] ?: ''); $from[$k] = \Date::parse(\Config::get('dateFormat'), $from[$k] ?: ''); } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['rgxp'] == 'time') { $to[$k] = \Date::parse(\Config::get('timeFormat'), $to[$k] ?: ''); $from[$k] = \Date::parse(\Config::get('timeFormat'), $from[$k] ?: ''); } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['rgxp'] == 'datim' || $k == 'tstamp') { $to[$k] = \Date::parse(\Config::get('datimFormat'), $to[$k] ?: ''); $from[$k] = \Date::parse(\Config::get('datimFormat'), $from[$k] ?: ''); } // Convert strings into arrays if (!is_array($to[$k])) { $to[$k] = explode("\n", $to[$k]); } if (!is_array($from[$k])) { $from[$k] = explode("\n", $from[$k]); } $objDiff = new \Diff($from[$k], $to[$k]); $strBuffer .= $objDiff->Render(new DiffRenderer(array('field' => $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['label'][0] ?: (isset($GLOBALS['TL_LANG']['MSC'][$k]) ? is_array($GLOBALS['TL_LANG']['MSC'][$k]) ? $GLOBALS['TL_LANG']['MSC'][$k][0] : $GLOBALS['TL_LANG']['MSC'][$k] : $k)))); } } } } // Identical versions if ($strBuffer == '') { $strBuffer = '<p>' . $GLOBALS['TL_LANG']['MSC']['identicalVersions'] . '</p>'; } /** @var BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_diff'); // Template variables $objTemplate->content = $strBuffer; $objTemplate->versions = $arrVersions; $objTemplate->to = $intTo; $objTemplate->from = $intFrom; $objTemplate->showLabel = specialchars($GLOBALS['TL_LANG']['MSC']['showDifferences']); $objTemplate->theme = \Backend::getTheme(); $objTemplate->base = \Environment::get('base'); $objTemplate->language = $GLOBALS['TL_LANGUAGE']; $objTemplate->title = specialchars($GLOBALS['TL_LANG']['MSC']['showDifferences']); $objTemplate->charset = \Config::get('characterSet'); $objTemplate->action = ampersand(\Environment::get('request')); throw new ResponseException($objTemplate->getResponse()); }
/** * Run the controller and parse the template * * @return Response */ public function run() { /** @var SessionInterface $objSession */ $objSession = \System::getContainer()->get('session'); /** @var BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_picker'); $objTemplate->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') ? $objSession->get('CURRENT_ID') : \Input::get('id')); $this->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 = \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); } $objSession->set('filePickerRef', \Environment::get('request')); $arrValues = array_filter(explode(',', \Input::get('value'))); // Convert UUIDs to binary foreach ($arrValues as $k => $v) { // Can be a UUID or a path if (\Validator::isStringUuid($v)) { $arrValues[$k] = \StringUtil::uuidToBin($v); } } // Call the load_callback if (is_array($GLOBALS['TL_DCA'][$strTable]['fields'][$strField]['load_callback'])) { foreach ($GLOBALS['TL_DCA'][$strTable]['fields'][$strField]['load_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $arrValues = $this->{$callback[0]}->{$callback[1]}($arrValues, $objDca); } elseif (is_callable($callback)) { $arrValues = $callback($arrValues, $objDca); } } } /** @var FileSelector $strClass */ $strClass = $GLOBALS['BE_FFL']['fileSelector']; /** @var FileSelector $objFileTree */ $objFileTree = new $strClass($strClass::getAttributesFromDca($GLOBALS['TL_DCA'][$strTable]['fields'][$strField], $strField, $arrValues, $strField, $strTable, $objDca)); /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = $objSession->getBag('contao_backend'); $objTemplate->main = $objFileTree->generate(); $objTemplate->theme = \Backend::getTheme(); $objTemplate->base = \Environment::get('base'); $objTemplate->language = $GLOBALS['TL_LANGUAGE']; $objTemplate->title = specialchars($GLOBALS['TL_LANG']['MSC']['filepicker']); $objTemplate->charset = \Config::get('characterSet'); $objTemplate->addSearch = true; $objTemplate->search = $GLOBALS['TL_LANG']['MSC']['search']; $objTemplate->searchExclude = $GLOBALS['TL_LANG']['MSC']['searchExclude']; $objTemplate->action = ampersand(\Environment::get('request')); $objTemplate->value = $objSessionBag->get('file_selector_search'); $objTemplate->manager = $GLOBALS['TL_LANG']['MSC']['fileManager']; $objTemplate->managerHref = 'contao/main.php?do=files&popup=1'; $objTemplate->breadcrumb = $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['breadcrumb']; if (\Input::get('switch')) { $objTemplate->switch = $GLOBALS['TL_LANG']['MSC']['pagePicker']; $objTemplate->switchHref = str_replace('contao/file?', 'contao/page?', ampersand(\Environment::get('request'))); } return $objTemplate->getResponse(); }
/** * Recursively render the pagetree * * @param integer $id * @param integer $intMargin * @param boolean $protectedPage * @param boolean $blnNoRecursion * @param array $arrFound * * @return string */ protected function renderPagetree($id, $intMargin, $protectedPage = false, $blnNoRecursion = false, $arrFound = array()) { static $session; /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); $session = $objSessionBag->all(); $flag = substr($this->strField, 0, 2); $node = 'tree_' . $this->strTable . '_' . $this->strField; $xtnode = 'tree_' . $this->strTable . '_' . $this->strName; // Get the session data and toggle the nodes if (\Input::get($flag . 'tg')) { $session[$node][\Input::get($flag . 'tg')] = isset($session[$node][\Input::get($flag . 'tg')]) && $session[$node][\Input::get($flag . 'tg')] == 1 ? 0 : 1; $objSessionBag->replace($session); $this->redirect(preg_replace('/(&(amp;)?|\\?)' . $flag . 'tg=[^& ]*/i', '', \Environment::get('request'))); } $objPage = $this->Database->prepare("SELECT id, alias, type, protected, published, start, stop, hide, title FROM tl_page WHERE id=?")->limit(1)->execute($id); // Return if there is no result if ($objPage->numRows < 1) { return ''; } $return = ''; $intSpacing = 20; $childs = array(); // Check whether there are child records if (!$blnNoRecursion) { $objNodes = $this->Database->prepare("SELECT id FROM tl_page WHERE pid=?" . (!empty($arrFound) ? " AND id IN(" . implode(',', array_map('intval', $arrFound)) . ")" : '') . " ORDER BY sorting")->execute($id); if ($objNodes->numRows) { $childs = $objNodes->fetchEach('id'); } } $return .= "\n " . '<li class="' . ($objPage->type == 'root' ? 'tl_folder' : 'tl_file') . ' toggle_select hover-div"><div class="tl_left" style="padding-left:' . ($intMargin + $intSpacing) . 'px">'; $folderAttribute = 'style="margin-left:20px"'; $session[$node][$id] = is_numeric($session[$node][$id]) ? $session[$node][$id] : 0; $level = $intMargin / $intSpacing + 1; $blnIsOpen = !empty($arrFound) || $session[$node][$id] == 1 || in_array($id, $this->arrNodes); if (!empty($childs)) { $folderAttribute = ''; $img = $blnIsOpen ? 'folMinus.svg' : 'folPlus.svg'; $alt = $blnIsOpen ? $GLOBALS['TL_LANG']['MSC']['collapseNode'] : $GLOBALS['TL_LANG']['MSC']['expandNode']; $return .= '<a href="' . \Backend::addToUrl($flag . 'tg=' . $id) . '" title="' . \StringUtil::specialchars($alt) . '" onclick="return AjaxRequest.togglePagetree(this,\'' . $xtnode . '_' . $id . '\',\'' . $this->strField . '\',\'' . $this->strName . '\',' . $level . ')">' . \Image::getHtml($img, '', 'style="margin-right:2px"') . '</a>'; } // Set the protection status $objPage->protected = $objPage->protected || $protectedPage; // Add the current page if (!empty($childs)) { $return .= \Image::getHtml($this->getPageStatusIcon($objPage), '', $folderAttribute) . ' <a href="' . \Backend::addToUrl('pn=' . $objPage->id) . '" title="' . \StringUtil::specialchars($objPage->title . ' (' . $objPage->alias . \Config::get('urlSuffix') . ')') . '">' . ($objPage->type == 'root' ? '<strong>' : '') . $objPage->title . ($objPage->type == 'root' ? '</strong>' : '') . '</a></div> <div class="tl_right">'; } else { $return .= \Image::getHtml($this->getPageStatusIcon($objPage), '', $folderAttribute) . ' ' . ($objPage->type == 'root' ? '<strong>' : '') . $objPage->title . ($objPage->type == 'root' ? '</strong>' : '') . '</div> <div class="tl_right">'; } // Add checkbox or radio button switch ($this->fieldType) { case 'checkbox': $return .= '<input type="checkbox" name="' . $this->strName . '[]" id="' . $this->strName . '_' . $id . '" class="tl_tree_checkbox" value="' . \StringUtil::specialchars($id) . '" onfocus="Backend.getScrollOffset()"' . static::optionChecked($id, $this->varValue) . '>'; break; default: case 'radio': $return .= '<input type="radio" name="' . $this->strName . '" id="' . $this->strName . '_' . $id . '" class="tl_tree_radio" value="' . \StringUtil::specialchars($id) . '" onfocus="Backend.getScrollOffset()"' . static::optionChecked($id, $this->varValue) . '>'; break; } $return .= '</div><div style="clear:both"></div></li>'; // Begin a new submenu if ($blnIsOpen || !empty($childs) && $objSessionBag->get('page_selector_search') != '') { $return .= '<li class="parent" id="' . $node . '_' . $id . '"><ul class="level_' . $level . '">'; for ($k = 0, $c = count($childs); $k < $c; $k++) { $return .= $this->renderPagetree($childs[$k], $intMargin + $intSpacing, $objPage->protected, $blnNoRecursion, $arrFound); } $return .= '</ul></li>'; } return $return; }
/** * Build the sort panel and return it as string * * @return string */ protected function panel() { if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['panelLayout'] == '') { return ''; } $intFilterPanel = 0; $arrPanels = array(); foreach (trimsplit(';', $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['panelLayout']) as $strPanel) { $panels = ''; $arrSubPanels = trimsplit(',', $strPanel); foreach ($arrSubPanels as $strSubPanel) { $panel = ''; // Regular panels if ($strSubPanel == 'search' || $strSubPanel == 'limit' || $strSubPanel == 'sort') { $panel = $this->{$strSubPanel . 'Menu'}(); } elseif ($strSubPanel == 'filter') { $panel = $this->{$strSubPanel . 'Menu'}(++$intFilterPanel); } else { $arrCallback = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['panel_callback'][$strSubPanel]; if (is_array($arrCallback)) { $this->import($arrCallback[0]); $panel = $this->{$arrCallback[0]}->{$arrCallback[1]}($this); } elseif (is_callable($arrCallback)) { $panel = $arrCallback($this); } } // Add the panel if it is not empty if ($panel != '') { $panels = $panel . $panels; } } // Add the group if it is not empty if ($panels != '') { $arrPanels[] = $panels; } } if (empty($arrPanels)) { return ''; } if (\Input::post('FORM_SUBMIT') == 'tl_filters') { $this->reload(); } $return = ''; $intTotal = count($arrPanels); $intLast = $intTotal - 1; for ($i = 0; $i < $intTotal; $i++) { $submit = ''; if ($i == $intLast) { $submit = ' <div class="tl_submit_panel tl_subpanel"> <input type="image" name="filter" id="filter" src="' . TL_FILES_URL . 'system/themes/' . \Backend::getTheme() . '/images/reload.gif" class="tl_img_submit" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['applyTitle']) . '" alt="' . specialchars($GLOBALS['TL_LANG']['MSC']['apply']) . '"> </div>'; } $return .= ' <div class="tl_panel">' . $submit . $arrPanels[$i] . ' <div class="clear"></div> </div>'; } $return = ' <form action="' . ampersand(\Environment::get('request'), true) . '" class="tl_form" method="post"> <div class="tl_formbody"> <input type="hidden" name="FORM_SUBMIT" value="tl_filters"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> ' . $return . ' </div> </form> '; return $return; }
/** * Generate the module * * @return string */ public function run() { if (!\Config::get('enableSearch')) { return ''; } $time = time(); /** @var BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_rebuild_index'); $objTemplate->action = ampersand(\Environment::get('request')); $objTemplate->indexHeadline = $GLOBALS['TL_LANG']['tl_maintenance']['searchIndex']; $objTemplate->isActive = $this->isActive(); // Add the error message if ($_SESSION['REBUILD_INDEX_ERROR'] != '') { $objTemplate->indexMessage = $_SESSION['REBUILD_INDEX_ERROR']; $_SESSION['REBUILD_INDEX_ERROR'] = ''; } // Rebuild the index if (\Input::get('act') == 'index') { // Check the request token (see #4007) if (!isset($_GET['rt']) || !\RequestToken::validate(\Input::get('rt'))) { /** @var SessionInterface $objSession */ $objSession = \System::getContainer()->get('session'); $objSession->set('INVALID_TOKEN_URL', \Environment::get('request')); $this->redirect('contao/confirm.php'); } $arrPages = $this->findSearchablePages(); // HOOK: take additional pages if (isset($GLOBALS['TL_HOOKS']['getSearchablePages']) && is_array($GLOBALS['TL_HOOKS']['getSearchablePages'])) { foreach ($GLOBALS['TL_HOOKS']['getSearchablePages'] as $callback) { $this->import($callback[0]); $arrPages = $this->{$callback[0]}->{$callback[1]}($arrPages); } } // Return if there are no pages if (empty($arrPages)) { $_SESSION['REBUILD_INDEX_ERROR'] = $GLOBALS['TL_LANG']['tl_maintenance']['noSearchable']; $this->redirect($this->getReferer()); } // Truncate the search tables $this->import('Automator'); $this->Automator->purgeSearchTables(); // Hide unpublished elements $this->setCookie('FE_PREVIEW', 0, $time - 86400); // Calculate the hash $strHash = $this->getSessionHash('FE_USER_AUTH'); // Remove old sessions $this->Database->prepare("DELETE FROM tl_session WHERE tstamp<? OR hash=?")->execute($time - \Config::get('sessionTimeout'), $strHash); // Log in the front end user if (is_numeric(\Input::get('user')) && \Input::get('user') > 0) { // Insert a new session $this->Database->prepare("INSERT INTO tl_session (pid, tstamp, name, sessionID, ip, hash) VALUES (?, ?, ?, ?, ?, ?)")->execute(\Input::get('user'), $time, 'FE_USER_AUTH', \System::getContainer()->get('session')->getId(), \Environment::get('ip'), $strHash); // Set the cookie $this->setCookie('FE_USER_AUTH', $strHash, $time + \Config::get('sessionTimeout'), null, null, false, true); } else { // Unset the cookies $this->setCookie('FE_USER_AUTH', $strHash, $time - 86400, null, null, false, true); $this->setCookie('FE_AUTO_LOGIN', \Input::cookie('FE_AUTO_LOGIN'), $time - 86400, null, null, false, true); } $strBuffer = ''; $rand = rand(); // Display the pages for ($i = 0, $c = count($arrPages); $i < $c; $i++) { $strBuffer .= '<span class="page_url" data-url="' . $arrPages[$i] . '#' . $rand . $i . '">' . \StringUtil::substr($arrPages[$i], 100) . '</span><br>'; unset($arrPages[$i]); // see #5681 } $objTemplate->content = $strBuffer; $objTemplate->note = $GLOBALS['TL_LANG']['tl_maintenance']['indexNote']; $objTemplate->loading = $GLOBALS['TL_LANG']['tl_maintenance']['indexLoading']; $objTemplate->complete = $GLOBALS['TL_LANG']['tl_maintenance']['indexComplete']; $objTemplate->indexContinue = $GLOBALS['TL_LANG']['MSC']['continue']; $objTemplate->theme = \Backend::getTheme(); $objTemplate->isRunning = true; return $objTemplate->parse(); } $arrUser = array('' => '-'); // Get active front end users $objUser = $this->Database->execute("SELECT id, username FROM tl_member WHERE disable!='1' AND (start='' OR start<='{$time}') AND (stop='' OR stop>'" . ($time + 60) . "') ORDER BY username"); while ($objUser->next()) { $arrUser[$objUser->id] = $objUser->username . ' (' . $objUser->id . ')'; } // Default variables $objTemplate->user = $arrUser; $objTemplate->indexLabel = $GLOBALS['TL_LANG']['tl_maintenance']['frontendUser'][0]; $objTemplate->indexHelp = \Config::get('showHelp') && strlen($GLOBALS['TL_LANG']['tl_maintenance']['frontendUser'][1]) ? $GLOBALS['TL_LANG']['tl_maintenance']['frontendUser'][1] : ''; $objTemplate->indexSubmit = $GLOBALS['TL_LANG']['tl_maintenance']['indexSubmit']; return $objTemplate->parse(); }
public function getFrontendUrl($arrRow) { return parent::generateFrontendUrl($arrRow); }
/** * 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 . '&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>'; }