loadLanguageFile() public static méthode

Load a set of language files
public static loadLanguageFile ( string $strName, boolean $strLanguage = null, boolean $blnNoCache = false )
$strName string The table name
$strLanguage boolean An optional language code
$blnNoCache boolean If true, the cache will be bypassed
 /**
  * @return array
  */
 public function getCurrencies()
 {
     $return = array();
     $arrAux = array();
     \Contao\System::loadLanguageFile('currencies');
     $this->loadCurrencies();
     if (is_array($this->arrCurrencies)) {
         foreach ($this->arrCurrencies as $strKey => $strName) {
             $arrAux[$strKey] = isset($GLOBALS['TL_LANG']['CUR'][$strKey]) ? Utf8::toAscii($GLOBALS['TL_LANG']['CUR'][$strKey]) : $strName;
         }
     }
     asort($arrAux);
     if (is_array($arrAux)) {
         foreach (array_keys($arrAux) as $strKey) {
             $return[$strKey] = isset($GLOBALS['TL_LANG']['CUR'][$strKey]) ? $GLOBALS['TL_LANG']['CUR'][$strKey] : $this->arrCurrencies[$strKey];
         }
     }
     // HOOK: add custom logic
     if (isset($GLOBALS['TL_HOOKS']['getCurrencies']) && is_array($GLOBALS['TL_HOOKS']['getCurrencies'])) {
         foreach ($GLOBALS['TL_HOOKS']['getCurrencies'] as $callback) {
             $return = static::importStatic($callback[0])->{$callback}[1]($return, $this->arrCurrencies);
         }
     }
     return $return;
 }
Exemple #2
0
 /**
  * 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 buttons.
  *
  * @param $articleId
  *
  * @return string
  */
 protected function getButtons($articleId)
 {
     global $container;
     System::loadLanguageFile('tl_article');
     $translator = $container['translator'];
     $buttons = self::getModalEditButton($articleId, $translator);
     $buttons .= self::getModalShowButton($articleId, $translator);
     return $buttons;
 }
 /**
  * Initialize the controller
  */
 public function __construct()
 {
     $this->import('Config');
     $this->import('Session');
     \Config::set('showHelp', false);
     $this->setStaticUrls();
     \System::loadLanguageFile('default');
     \System::loadLanguageFile('tl_install');
 }
Exemple #5
0
 /**
  * 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');
     $strFile = \Input::get('src', true);
     $strFile = base64_decode($strFile);
     $strFile = preg_replace('@^/+@', '', rawurldecode($strFile));
     $this->strFile = $strFile;
 }
 /**
  * Generate the purge cache field
  *
  * @return string
  */
 public function generatePurgeField()
 {
     System::loadLanguageFile('tl_maintenance');
     $template = new BackendTemplate('be_vimeo_rebuilder_user');
     $template->elementsCount = count(Rebuilder::getContentElements());
     if (($stats = Rebuilder::generateStats()) !== null) {
         foreach ($stats as $k => $v) {
             $template->{$k} = $v;
         }
     }
     return $template->parse();
 }
 /**
  * @param $strField
  */
 protected function addTranslationContentToField($strField)
 {
     if ($this->Config->get($strField) === null) {
         $arrValues = array();
         System::loadLanguageFile('tl_email', 'de', true);
         $arrValues['de'] = $GLOBALS['TL_LANG']['tl_email']['defaultContents'][$strField];
         System::loadLanguageFile('tl_email', 'en', true);
         $arrValues['en'] = $GLOBALS['TL_LANG']['tl_email']['defaultContents'][$strField];
         // Load translation file by current language
         System::loadLanguageFile('tl_email', null, true);
         $this->Config->persist($strField, TranslationFieldsModel::saveValuesAndReturnFid($arrValues));
     }
 }
Exemple #8
0
 /**
  * Initialize the controller
  *
  * 1. Import the user
  * 2. Call the parent constructor
  * 3. Login the user
  * 4. Load the language files
  * DO NOT CHANGE THIS ORDER!
  */
 public function __construct()
 {
     $this->import('BackendUser', 'User');
     parent::__construct();
     // Login
     if ($this->User->login()) {
         $strUrl = 'contao/main.php';
         // Redirect to the last page visited
         if (\Input::get('referer', true) != '') {
             $strUrl = base64_decode(\Input::get('referer', true));
         }
         $this->redirect($strUrl);
     } elseif (!empty($_POST['username']) && !empty($_POST['password'])) {
         $this->reload();
     } elseif ($this->User->logout()) {
         $this->reload();
     }
     \System::loadLanguageFile('default');
     \System::loadLanguageFile('tl_user');
 }
 /**
  * Generate the module
  */
 protected function compile()
 {
     /** @var PageModel $objPage */
     global $objPage;
     $this->import('FrontendUser', 'User');
     $GLOBALS['TL_LANGUAGE'] = $objPage->language;
     \System::loadLanguageFile('tl_member');
     $this->loadDataContainer('tl_member');
     // Old password widget
     $arrFields['oldPassword'] = array('name' => 'oldpassword', 'label' => &$GLOBALS['TL_LANG']['MSC']['oldPassword'], 'inputType' => 'text', 'eval' => array('mandatory' => true, 'preserveTags' => true, 'hideInput' => true));
     // New password widget
     $arrFields['newPassword'] = $GLOBALS['TL_DCA']['tl_member']['fields']['password'];
     $arrFields['newPassword']['name'] = 'password';
     $arrFields['newPassword']['label'] =& $GLOBALS['TL_LANG']['MSC']['newPassword'];
     $row = 0;
     $strFields = '';
     $doNotSubmit = false;
     $objMember = \MemberModel::findByPk($this->User->id);
     $strFormId = 'tl_change_password_' . $this->id;
     $flashBag = \System::getContainer()->get('session')->getFlashBag();
     $strTable = $objMember->getTable();
     // Initialize the versioning (see #8301)
     $objVersions = new \Versions($strTable, $objMember->id);
     $objVersions->setUsername($objMember->username);
     $objVersions->setUserId(0);
     $objVersions->setEditUrl('contao/main.php?do=member&act=edit&id=%s&rt=1');
     $objVersions->initialize();
     /** @var FormTextField $objOldPassword */
     $objOldPassword = null;
     /** @var FormPassword $objNewPassword */
     $objNewPassword = null;
     // Initialize the widgets
     foreach ($arrFields as $strKey => $arrField) {
         /** @var Widget $strClass */
         $strClass = $GLOBALS['TL_FFL'][$arrField['inputType']];
         // Continue if the class is not defined
         if (!class_exists($strClass)) {
             continue;
         }
         $arrField['eval']['required'] = $arrField['eval']['mandatory'];
         /** @var Widget $objWidget */
         $objWidget = new $strClass($strClass::getAttributesFromDca($arrField, $arrField['name']));
         $objWidget->storeValues = true;
         $objWidget->rowClass = 'row_' . $row . ($row == 0 ? ' row_first' : '') . ($row % 2 == 0 ? ' even' : ' odd');
         // Increase the row count if it is a password field
         if ($objWidget instanceof FormPassword) {
             $objWidget->rowClassConfirm = 'row_' . ++$row . ($row % 2 == 0 ? ' even' : ' odd');
         }
         ++$row;
         // Store the widget objects
         $strVar = 'obj' . ucfirst($strKey);
         ${$strVar} = $objWidget;
         // Validate the widget
         if (\Input::post('FORM_SUBMIT') == $strFormId) {
             $objWidget->validate();
             // Validate the old password
             if ($strKey == 'oldPassword') {
                 if (\Encryption::test($objMember->password)) {
                     $blnAuthenticated = \Encryption::verify($objWidget->value, $objMember->password);
                 } else {
                     list($strPassword, $strSalt) = explode(':', $objMember->password);
                     $blnAuthenticated = $strSalt == '' ? $strPassword === sha1($objWidget->value) : $strPassword === sha1($strSalt . $objWidget->value);
                 }
                 if (!$blnAuthenticated) {
                     $objWidget->value = '';
                     $objWidget->addError($GLOBALS['TL_LANG']['MSC']['oldPasswordWrong']);
                     sleep(2);
                     // Wait 2 seconds while brute forcing :)
                 }
             }
             if ($objWidget->hasErrors()) {
                 $doNotSubmit = true;
             }
         }
         $strFields .= $objWidget->parse();
     }
     $this->Template->fields = $strFields;
     $this->Template->hasError = $doNotSubmit;
     // Store the new password
     if (\Input::post('FORM_SUBMIT') == $strFormId && !$doNotSubmit) {
         $objMember->tstamp = time();
         $objMember->password = $objNewPassword->value;
         $objMember->save();
         // Create a new version
         if ($GLOBALS['TL_DCA'][$strTable]['config']['enableVersioning']) {
             $objVersions->create();
         }
         // HOOK: set new password callback
         if (isset($GLOBALS['TL_HOOKS']['setNewPassword']) && is_array($GLOBALS['TL_HOOKS']['setNewPassword'])) {
             foreach ($GLOBALS['TL_HOOKS']['setNewPassword'] as $callback) {
                 $this->import($callback[0]);
                 $this->{$callback[0]}->{$callback[1]}($objMember, $objNewPassword->value, $this);
             }
         }
         // Check whether there is a jumpTo page
         if (($objJumpTo = $this->objModel->getRelated('jumpTo')) instanceof PageModel) {
             $this->jumpToOrReload($objJumpTo->row());
         }
         $flashBag->set('mod_change_password_confirm', $GLOBALS['TL_LANG']['MSC']['newPasswordSet']);
         $this->reload();
     }
     // Confirmation message
     if ($flashBag->has('mod_change_password_confirm')) {
         $arrMessages = $flashBag->get('mod_change_password_confirm');
         $this->Template->message = $arrMessages[0];
     }
     $this->Template->formId = $strFormId;
     $this->Template->action = \Environment::get('indexFreeRequest');
     $this->Template->slabel = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['changePassword']);
     $this->Template->rowLast = 'row_' . $row . ' row_last' . ($row % 2 == 0 ? ' even' : ' odd');
 }
 /**
  * Generate the module
  */
 protected function compile()
 {
     /** @var PageModel $objPage */
     global $objPage;
     $GLOBALS['TL_LANGUAGE'] = $objPage->language;
     \System::loadLanguageFile('tl_member');
     $this->loadDataContainer('tl_member');
     // Call onload_callback (e.g. to check permissions)
     if (is_array($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback'])) {
         foreach ($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback'] as $callback) {
             if (is_array($callback)) {
                 $this->import($callback[0]);
                 $this->{$callback[0]}->{$callback[1]}();
             } elseif (is_callable($callback)) {
                 $callback();
             }
         }
     }
     // Activate account
     if (\Input::get('token') != '') {
         $this->activateAcount();
         return;
     }
     if ($this->memberTpl != '') {
         /** @var FrontendTemplate|object $objTemplate */
         $objTemplate = new \FrontendTemplate($this->memberTpl);
         $this->Template = $objTemplate;
         $this->Template->setData($this->arrData);
     }
     $this->Template->fields = '';
     $objCaptcha = null;
     $doNotSubmit = false;
     $strFormId = 'tl_registration_' . $this->id;
     // Predefine the group order (other groups will be appended automatically)
     $arrGroups = array('personal' => array(), 'address' => array(), 'contact' => array(), 'login' => array(), 'profile' => array());
     // Captcha
     if (!$this->disableCaptcha) {
         $arrCaptcha = array('id' => 'registration', 'label' => $GLOBALS['TL_LANG']['MSC']['securityQuestion'], 'type' => 'captcha', 'mandatory' => true, 'required' => true);
         /** @var FormCaptcha $strClass */
         $strClass = $GLOBALS['TL_FFL']['captcha'];
         // Fallback to default if the class is not defined
         if (!class_exists($strClass)) {
             $strClass = 'FormCaptcha';
         }
         /** @var FormCaptcha $objCaptcha */
         $objCaptcha = new $strClass($arrCaptcha);
         if (\Input::post('FORM_SUBMIT') == $strFormId) {
             $objCaptcha->validate();
             if ($objCaptcha->hasErrors()) {
                 $doNotSubmit = true;
             }
         }
     }
     $objMember = null;
     // Check for a follow-up registration (see #7992)
     if (\Input::post('email', true) != '' && ($objMember = \MemberModel::findUnactivatedByEmail(\Input::post('email', true))) !== null) {
         $this->resendActivationMail($objMember);
         return;
     }
     $arrUser = array();
     $arrFields = array();
     $hasUpload = false;
     $i = 0;
     // Build form
     foreach ($this->editable as $field) {
         $arrData = $GLOBALS['TL_DCA']['tl_member']['fields'][$field];
         // Map checkboxWizards to regular checkbox widgets
         if ($arrData['inputType'] == 'checkboxWizard') {
             $arrData['inputType'] = 'checkbox';
         }
         // Map fileTrees to upload widgets (see #8091)
         if ($arrData['inputType'] == 'fileTree') {
             $arrData['inputType'] = 'upload';
         }
         /** @var Widget $strClass */
         $strClass = $GLOBALS['TL_FFL'][$arrData['inputType']];
         // Continue if the class is not defined
         if (!class_exists($strClass)) {
             continue;
         }
         $arrData['eval']['required'] = $arrData['eval']['mandatory'];
         // Unset the unique field check upon follow-up registrations
         if ($objMember !== null && $arrData['eval']['unique'] && \Input::post($field) == $objMember->{$field}) {
             $arrData['eval']['unique'] = false;
         }
         $objWidget = new $strClass($strClass::getAttributesFromDca($arrData, $field, $arrData['default'], '', '', $this));
         $objWidget->storeValues = true;
         $objWidget->rowClass = 'row_' . $i . ($i == 0 ? ' row_first' : '') . ($i % 2 == 0 ? ' even' : ' odd');
         // Increase the row count if its a password field
         if ($objWidget instanceof FormPassword) {
             $objWidget->rowClassConfirm = 'row_' . ++$i . ($i % 2 == 0 ? ' even' : ' odd');
         }
         // Validate input
         if (\Input::post('FORM_SUBMIT') == $strFormId) {
             $objWidget->validate();
             $varValue = $objWidget->value;
             // Check whether the password matches the username
             if ($objWidget instanceof FormPassword && \Encryption::verify(\Input::post('username'), $varValue)) {
                 $objWidget->addError($GLOBALS['TL_LANG']['ERR']['passwordName']);
             }
             $rgxp = $arrData['eval']['rgxp'];
             // Convert date formats into timestamps (check the eval setting first -> #3063)
             if ($varValue != '' && in_array($rgxp, array('date', 'time', 'datim'))) {
                 try {
                     $objDate = new \Date($varValue, \Date::getFormatFromRgxp($rgxp));
                     $varValue = $objDate->tstamp;
                 } catch (\OutOfBoundsException $e) {
                     $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varValue));
                 }
             }
             // Make sure that unique fields are unique (check the eval setting first -> #3063)
             if ($arrData['eval']['unique'] && $varValue != '' && !$this->Database->isUniqueValue('tl_member', $field, $varValue)) {
                 $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $field));
             }
             // Save callback
             if ($objWidget->submitInput() && !$objWidget->hasErrors() && is_array($arrData['save_callback'])) {
                 foreach ($arrData['save_callback'] as $callback) {
                     try {
                         if (is_array($callback)) {
                             $this->import($callback[0]);
                             $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, null);
                         } elseif (is_callable($callback)) {
                             $varValue = $callback($varValue, null);
                         }
                     } catch (\Exception $e) {
                         $objWidget->class = 'error';
                         $objWidget->addError($e->getMessage());
                     }
                 }
             }
             // Store the current value
             if ($objWidget->hasErrors()) {
                 $doNotSubmit = true;
             } elseif ($objWidget->submitInput()) {
                 // Set the correct empty value (see #6284, #6373)
                 if ($varValue === '') {
                     $varValue = $objWidget->getEmptyValue();
                 }
                 // Encrypt the value (see #7815)
                 if ($arrData['eval']['encrypt']) {
                     $varValue = \Encryption::encrypt($varValue);
                 }
                 // Set the new value
                 $arrUser[$field] = $varValue;
             }
         }
         if ($objWidget instanceof \uploadable) {
             $hasUpload = true;
         }
         $temp = $objWidget->parse();
         $this->Template->fields .= $temp;
         $arrFields[$arrData['eval']['feGroup']][$field] .= $temp;
         ++$i;
     }
     // Captcha
     if (!$this->disableCaptcha) {
         $objCaptcha->rowClass = 'row_' . $i . ($i == 0 ? ' row_first' : '') . ($i % 2 == 0 ? ' even' : ' odd');
         $strCaptcha = $objCaptcha->parse();
         $this->Template->fields .= $strCaptcha;
         $arrFields['captcha']['captcha'] .= $strCaptcha;
     }
     $this->Template->rowLast = 'row_' . ++$i . ($i % 2 == 0 ? ' even' : ' odd');
     $this->Template->enctype = $hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
     $this->Template->hasError = $doNotSubmit;
     // Create new user if there are no errors
     if (\Input::post('FORM_SUBMIT') == $strFormId && !$doNotSubmit) {
         $this->createNewUser($arrUser);
     }
     $this->Template->loginDetails = $GLOBALS['TL_LANG']['tl_member']['loginDetails'];
     $this->Template->addressDetails = $GLOBALS['TL_LANG']['tl_member']['addressDetails'];
     $this->Template->contactDetails = $GLOBALS['TL_LANG']['tl_member']['contactDetails'];
     $this->Template->personalData = $GLOBALS['TL_LANG']['tl_member']['personalData'];
     $this->Template->captchaDetails = $GLOBALS['TL_LANG']['MSC']['securityQuestion'];
     // Add the groups
     foreach ($arrFields as $k => $v) {
         // Deprecated since Contao 4.0, to be removed in Contao 5.0
         $this->Template->{$k} = $v;
         $key = $k . ($k == 'personal' ? 'Data' : 'Details');
         $arrGroups[$GLOBALS['TL_LANG']['tl_member'][$key]] = $v;
     }
     $this->Template->categories = $arrGroups;
     $this->Template->formId = $strFormId;
     $this->Template->slabel = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['register']);
     $this->Template->action = \Environment::get('indexFreeRequest');
     // Deprecated since Contao 4.0, to be removed in Contao 5.0
     $this->Template->captcha = $arrFields['captcha']['captcha'];
 }
 /**
  * Create the extract from the DCA or the database.sql files
  */
 protected function createExtract()
 {
     // Load the default language file (see #7202)
     if (empty($GLOBALS['TL_LANG']['MSC'])) {
         System::loadLanguageFile('default');
     }
     // Load the data container
     if (!isset($GLOBALS['loadDataContainer'][$this->strTable])) {
         $this->loadDataContainer($this->strTable);
     }
     // Return if the DC type is "File"
     if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dataContainer'] == 'File') {
         return;
     }
     $blnFromFile = false;
     $arrRelations = array();
     // Check whether there are fields (see #4826)
     if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'])) {
         foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'] as $field => $config) {
             // Check whether all fields have an SQL definition
             if (!isset($config['sql']) && isset($config['inputType'])) {
                 $blnFromFile = true;
             }
             // Check whether there is a relation (see #6524)
             if (isset($config['relation'])) {
                 $table = substr($config['foreignKey'], 0, strrpos($config['foreignKey'], '.'));
                 $arrRelations[$field] = array_merge(array('table' => $table, 'field' => 'id'), $config['relation']);
                 // Table name and field name are mandatory
                 if (empty($arrRelations[$field]['table']) || empty($arrRelations[$field]['field'])) {
                     throw new \Exception('Incomplete relation defined for ' . $this->strTable . '.' . $field);
                 }
             }
         }
     }
     $sql = $GLOBALS['TL_DCA'][$this->strTable]['config']['sql'] ?: array();
     $fields = $GLOBALS['TL_DCA'][$this->strTable]['fields'] ?: array();
     // Deprecated since Contao 4.0, to be removed in Contao 5.0
     if ($blnFromFile) {
         trigger_error('Using database.sql files has been deprecated and will no longer work in Contao 5.0. Use a DCA file instead.', E_USER_DEPRECATED);
         if (!isset(static::$arrSql[$this->strTable])) {
             try {
                 /** @var SplFileInfo[] $files */
                 $files = \System::getContainer()->get('contao.resource_locator')->locate('config/database.sql', null, false);
             } catch (\InvalidArgumentException $e) {
                 return array();
             }
             $arrSql = array();
             foreach ($files as $file) {
                 $arrSql = array_merge_recursive($arrSql, \SqlFileParser::parse($file));
             }
             static::$arrSql = $arrSql;
         }
         $arrTable = static::$arrSql[$this->strTable];
         list($engine, , $charset) = explode(' ', trim($arrTable['TABLE_OPTIONS']));
         if ($engine != '') {
             $sql['engine'] = str_replace('ENGINE=', '', $engine);
         }
         if ($charset != '') {
             $sql['charset'] = str_replace('CHARSET=', '', $charset);
         }
         // Fields
         if (isset($arrTable['TABLE_FIELDS'])) {
             foreach ($arrTable['TABLE_FIELDS'] as $k => $v) {
                 $fields[$k]['sql'] = str_replace('`' . $k . '` ', '', $v);
             }
         }
         // Keys
         if (isset($arrTable['TABLE_CREATE_DEFINITIONS'])) {
             foreach ($arrTable['TABLE_CREATE_DEFINITIONS'] as $strKey) {
                 if (preg_match('/^([A-Z]+ )?KEY .+\\(([^)]+)\\)$/', $strKey, $arrMatches) && preg_match_all('/`([^`]+)`/', $arrMatches[2], $arrFields)) {
                     $type = trim($arrMatches[1]);
                     $field = implode(',', $arrFields[1]);
                     $sql['keys'][$field] = $type != '' ? strtolower($type) : 'index';
                 }
             }
         }
     }
     // Not a database table or no field information
     if (empty($sql) || empty($fields)) {
         return;
     }
     // Add the default engine and charset if none is given
     if (empty($sql['engine'])) {
         $sql['engine'] = 'MyISAM';
     }
     if (empty($sql['charset'])) {
         $sql['charset'] = \Config::get('dbCharset');
     }
     // Meta
     $this->arrMeta = array('engine' => $sql['engine'], 'charset' => $sql['charset']);
     // Fields
     if (!empty($fields)) {
         $this->arrFields = array();
         $this->arrOrderFields = array();
         foreach ($fields as $field => $config) {
             if (isset($config['sql'])) {
                 $this->arrFields[$field] = $config['sql'];
             }
             // Only add order fields of binary fields (see #7785)
             if (isset($config['inputType']) && $config['inputType'] == 'fileTree' && isset($config['eval']['orderField'])) {
                 $this->arrOrderFields[] = $config['eval']['orderField'];
             }
             if (isset($config['eval']['unique']) && $config['eval']['unique']) {
                 $this->arrUniqueFields[] = $field;
             }
         }
     }
     // Keys
     if (!empty($sql['keys']) && is_array($sql['keys'])) {
         $this->arrKeys = array();
         foreach ($sql['keys'] as $field => $type) {
             $this->arrKeys[$field] = $type;
             if ($type == 'unique') {
                 $this->arrUniqueFields[] = $field;
             }
         }
     }
     // Relations
     if (!empty($arrRelations)) {
         $this->arrRelations = array();
         foreach ($arrRelations as $field => $config) {
             $this->arrRelations[$field] = array();
             foreach ($config as $k => $v) {
                 $this->arrRelations[$field][$k] = $v;
             }
         }
     }
     $this->arrUniqueFields = array_unique($this->arrUniqueFields);
     $this->blnIsDbTable = true;
 }
 /**
  * Prepare buttons.
  *
  * @param $newsId
  *
  * @return string
  */
 protected function prepareButtons($newsId)
 {
     global $container;
     System::loadLanguageFile('tl_calendar_events');
     $translator = $container['translator'];
     $buttons = self::getModalEditButton($newsId, $translator);
     $buttons .= self::getModalShowButton($newsId, $translator);
     return $buttons;
 }
 /**
  * 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];
     // Back end modules
     if ($table == 'tl_user_group' && $field == 'modules') {
         $rows = array();
         foreach (array_keys($GLOBALS['BE_MOD']) as $group) {
             $rows[] = array('headspan', $arrData['reference'][$group]);
             foreach ($GLOBALS['BE_MOD'][$group] as $module => $class) {
                 $rows[] = $arrData['reference'][$module];
             }
         }
         $objTemplate->rows = $rows;
     } elseif ($table == 'tl_module' && $field == 'type') {
         $rows = array();
         foreach (array_keys($GLOBALS['FE_MOD']) as $group) {
             $rows[] = array('headspan', $arrData['reference'][$group]);
             foreach ($GLOBALS['FE_MOD'][$group] as $module => $class) {
                 $rows[] = $arrData['reference'][$module];
             }
         }
         $objTemplate->rows = $rows;
     } elseif ($table == 'tl_content' && $field == 'type') {
         $rows = array();
         foreach (array_keys($GLOBALS['TL_CTE']) as $group) {
             $rows[] = array('headspan', $arrData['reference'][$group]);
             foreach ($GLOBALS['TL_CTE'][$group] as $element => $class) {
                 $rows[] = $arrData['reference'][$element];
             }
         }
         $objTemplate->rows = $rows;
     } elseif (!empty($arrData['reference'])) {
         $rows = array();
         $options = is_array($arrData['options']) ? $arrData['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 (!is_array($arrData['reference'][$option])) {
                     $rows[] = array('headspan', $arrData['reference'][$option]);
                 } else {
                     $rows[] = $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 = 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();
 }
 /**
  * Generate the module
  */
 protected function compile()
 {
     \System::loadLanguageFile($this->list_table);
     $this->loadDataContainer($this->list_table);
     // List a single record
     if (\Input::get('show')) {
         $this->listSingleRecord(\Input::get('show'));
         return;
     }
     /**
      * Add the search menu
      */
     $strWhere = '';
     $varKeyword = '';
     $strOptions = '';
     $this->Template->searchable = false;
     $arrSearchFields = \StringUtil::trimsplit(',', $this->list_search);
     if (!empty($arrSearchFields) && is_array($arrSearchFields)) {
         $this->Template->searchable = true;
         if (\Input::get('search') && \Input::get('for')) {
             $varKeyword = '%' . \Input::get('for') . '%';
             $strWhere = (!$this->list_where ? " WHERE " : " AND ") . \Input::get('search') . " LIKE ?";
         }
         foreach ($arrSearchFields as $field) {
             $strOptions .= '  <option value="' . $field . '"' . ($field == \Input::get('search') ? ' selected="selected"' : '') . '>' . (strlen($label = $GLOBALS['TL_DCA'][$this->list_table]['fields'][$field]['label'][0]) ? $label : $field) . '</option>' . "\n";
         }
     }
     $this->Template->search_fields = $strOptions;
     /**
      * Get the total number of records
      */
     $strQuery = "SELECT COUNT(*) AS count FROM " . $this->list_table;
     if ($this->list_where) {
         $strQuery .= " WHERE (" . $this->list_where . ")";
     }
     $strQuery .= $strWhere;
     $objTotal = $this->Database->prepare($strQuery)->execute($varKeyword);
     /**
      * Validate the page count
      */
     $id = 'page_l' . $this->id;
     $page = \Input::get($id) !== null ? \Input::get($id) : 1;
     $per_page = \Input::get('per_page') ?: $this->perPage;
     // Thanks to Hagen Klemp (see #4485)
     if ($per_page > 0 && ($page < 1 || $page > max(ceil($objTotal->count / $per_page), 1))) {
         throw new PageNotFoundException('Page not found: ' . \Environment::get('uri'));
     }
     /**
      * Get the selected records
      */
     $strQuery = "SELECT " . $this->strPk . "," . $this->list_fields;
     if ($this->list_info_where) {
         $strQuery .= ", (SELECT COUNT(*) FROM " . $this->list_table . " t2 WHERE t2." . $this->strPk . "=t1." . $this->strPk . " AND " . $this->list_info_where . ") AS _details";
     }
     $strQuery .= " FROM " . $this->list_table . " t1";
     if ($this->list_where) {
         $strQuery .= " WHERE (" . $this->list_where . ")";
     }
     $strQuery .= $strWhere;
     // Cast date fields to int (see #5609)
     $isInt = function ($field) {
         return $GLOBALS['TL_DCA'][$this->list_table]['fields'][$field]['eval']['rgxp'] == 'date' || $GLOBALS['TL_DCA'][$this->list_table]['fields'][$field]['eval']['rgxp'] == 'time' || $GLOBALS['TL_DCA'][$this->list_table]['fields'][$field]['eval']['rgxp'] == 'datim';
     };
     // Order by
     if (\Input::get('order_by')) {
         if ($isInt(\Input::get('order_by'))) {
             $strQuery .= " ORDER BY CAST(" . \Input::get('order_by') . " AS SIGNED) " . \Input::get('sort');
         } else {
             $strQuery .= " ORDER BY " . \Input::get('order_by') . ' ' . \Input::get('sort');
         }
     } elseif ($this->list_sort) {
         if ($isInt($this->list_sort)) {
             $strQuery .= " ORDER BY CAST(" . $this->list_sort . " AS SIGNED)";
         } else {
             $strQuery .= " ORDER BY " . $this->list_sort;
         }
     }
     $objDataStmt = $this->Database->prepare($strQuery);
     // Limit
     if (\Input::get('per_page')) {
         $objDataStmt->limit(\Input::get('per_page'), ($page - 1) * $per_page);
     } elseif ($this->perPage) {
         $objDataStmt->limit($this->perPage, ($page - 1) * $per_page);
     }
     $objData = $objDataStmt->execute($varKeyword);
     /**
      * Prepare the URL
      */
     $strUrl = preg_replace('/\\?.*$/', '', \Environment::get('request'));
     $blnQuery = false;
     foreach (preg_split('/&(amp;)?/', \Environment::get('queryString')) as $fragment) {
         if ($fragment != '' && strncasecmp($fragment, 'order_by', 8) !== 0 && strncasecmp($fragment, 'sort', 4) !== 0 && strncasecmp($fragment, $id, strlen($id)) !== 0) {
             $strUrl .= (!$blnQuery ? '?' : '&amp;') . $fragment;
             $blnQuery = true;
         }
     }
     $this->Template->url = $strUrl;
     $strVarConnector = $blnQuery ? '&amp;' : '?';
     /**
      * Prepare the data arrays
      */
     $arrTh = array();
     $arrTd = array();
     $arrFields = \StringUtil::trimsplit(',', $this->list_fields);
     // THEAD
     for ($i = 0, $c = count($arrFields); $i < $c; $i++) {
         // Never show passwords
         if ($GLOBALS['TL_DCA'][$this->list_table]['fields'][$arrFields[$i]]['inputType'] == 'password') {
             continue;
         }
         $class = '';
         $sort = 'asc';
         $strField = strlen($label = $GLOBALS['TL_DCA'][$this->list_table]['fields'][$arrFields[$i]]['label'][0]) ? $label : $arrFields[$i];
         // Add a CSS class to the order_by column
         if (\Input::get('order_by') == $arrFields[$i]) {
             $sort = \Input::get('sort') == 'asc' ? 'desc' : 'asc';
             $class = ' sorted ' . \Input::get('sort');
         }
         $arrTh[] = array('link' => $strField, 'href' => ampersand($strUrl) . $strVarConnector . 'order_by=' . $arrFields[$i] . '&amp;sort=' . $sort, 'title' => \StringUtil::specialchars(sprintf($GLOBALS['TL_LANG']['MSC']['list_orderBy'], $strField)), 'class' => $class . ($i == 0 ? ' col_first' : ''));
     }
     $j = 0;
     $arrRows = $objData->fetchAllAssoc();
     // TBODY
     for ($i = 0, $c = count($arrRows); $i < $c; $i++) {
         $j = 0;
         $class = 'row_' . $i . ($i == 0 ? ' row_first' : '') . ($i + 1 == count($arrRows) ? ' row_last' : '') . ($i % 2 == 0 ? ' even' : ' odd');
         foreach ($arrRows[$i] as $k => $v) {
             // Skip the primary key
             if ($k == $this->strPk && !in_array($this->strPk, $arrFields)) {
                 continue;
             }
             if ($k == '_details') {
                 continue;
             }
             // Never show passwords
             if ($GLOBALS['TL_DCA'][$this->list_table]['fields'][$k]['inputType'] == 'password') {
                 continue;
             }
             $value = $this->formatValue($k, $v);
             $arrTd[$class][$k] = array('raw' => $v, 'content' => $value ? $value : '&nbsp;', 'class' => 'col_' . $j . ($j++ == 0 ? ' col_first' : '') . ($this->list_info ? '' : ($j >= count($arrRows[$i]) - 1 ? ' col_last' : '')), 'id' => $arrRows[$i][$this->strPk], 'field' => $k, 'url' => $strUrl . $strVarConnector . 'show=' . $arrRows[$i][$this->strPk], 'details' => isset($arrRows[$i]['_details']) ? $arrRows[$i]['_details'] : 1);
         }
     }
     $this->Template->thead = $arrTh;
     $this->Template->tbody = $arrTd;
     /**
      * Pagination
      */
     $objPagination = new \Pagination($objTotal->count, $per_page, \Config::get('maxPaginationLinks'), $id);
     $this->Template->pagination = $objPagination->generate("\n  ");
     $this->Template->per_page = $per_page;
     $this->Template->total = $objTotal->count;
     /**
      * Template variables
      */
     $this->Template->action = \Environment::get('indexFreeRequest');
     $this->Template->details = $this->list_info != '' ? true : false;
     $this->Template->search_label = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['search']);
     $this->Template->per_page_label = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['list_perPage']);
     $this->Template->fields_label = $GLOBALS['TL_LANG']['MSC']['all_fields'][0];
     $this->Template->keywords_label = $GLOBALS['TL_LANG']['MSC']['keywords'];
     $this->Template->search = \Input::get('search');
     $this->Template->for = \Input::get('for');
     $this->Template->order_by = \Input::get('order_by');
     $this->Template->sort = \Input::get('sort');
     $this->Template->col_last = 'col_' . $j;
 }
 /**
  * Generate the module
  */
 protected function compile()
 {
     /** @var PageModel $objPage */
     global $objPage;
     $this->import('FrontendUser', 'User');
     $GLOBALS['TL_LANGUAGE'] = $objPage->language;
     \System::loadLanguageFile('tl_member');
     $this->loadDataContainer('tl_member');
     // Call onload_callback (e.g. to check permissions)
     if (is_array($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback'])) {
         foreach ($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback'] as $callback) {
             if (is_array($callback)) {
                 $this->import($callback[0]);
                 $this->{$callback[0]}->{$callback[1]}();
             } elseif (is_callable($callback)) {
                 $callback();
             }
         }
     }
     $this->Template->fields = '';
     $arrFields = array();
     $doNotSubmit = false;
     $hasUpload = false;
     $row = 0;
     // Predefine the group order (other groups will be appended automatically)
     $arrGroups = array('personal' => array(), 'address' => array(), 'contact' => array(), 'login' => array(), 'profile' => array());
     $blnModified = false;
     $objMember = \MemberModel::findByPk($this->User->id);
     $strTable = $objMember->getTable();
     $strFormId = 'tl_member_' . $this->id;
     $flashBag = \System::getContainer()->get('session')->getFlashBag();
     // Initialize the versioning (see #7415)
     $objVersions = new \Versions($strTable, $objMember->id);
     $objVersions->setUsername($objMember->username);
     $objVersions->setUserId(0);
     $objVersions->setEditUrl('contao/main.php?do=member&act=edit&id=%s&rt=1');
     $objVersions->initialize();
     // Build the form
     foreach ($this->editable as $field) {
         $arrData =& $GLOBALS['TL_DCA']['tl_member']['fields'][$field];
         // Map checkboxWizards to regular checkbox widgets
         if ($arrData['inputType'] == 'checkboxWizard') {
             $arrData['inputType'] = 'checkbox';
         }
         // Map fileTrees to upload widgets (see #8091)
         if ($arrData['inputType'] == 'fileTree') {
             $arrData['inputType'] = 'upload';
         }
         /** @var Widget $strClass */
         $strClass = $GLOBALS['TL_FFL'][$arrData['inputType']];
         // Continue if the class does not exist
         if (!$arrData['eval']['feEditable'] || !class_exists($strClass)) {
             continue;
         }
         $strGroup = $arrData['eval']['feGroup'];
         $arrData['eval']['required'] = false;
         // Use strlen() here (see #3277)
         if ($arrData['eval']['mandatory']) {
             if (is_array($this->User->{$field})) {
                 if (empty($this->User->{$field})) {
                     $arrData['eval']['required'] = true;
                 }
             } else {
                 if (!strlen($this->User->{$field})) {
                     $arrData['eval']['required'] = true;
                 }
             }
         }
         $varValue = $this->User->{$field};
         // Call the load_callback
         if (isset($arrData['load_callback']) && is_array($arrData['load_callback'])) {
             foreach ($arrData['load_callback'] as $callback) {
                 if (is_array($callback)) {
                     $this->import($callback[0]);
                     $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $this->User, $this);
                 } elseif (is_callable($callback)) {
                     $varValue = $callback($varValue, $this->User, $this);
                 }
             }
         }
         /** @var Widget $objWidget */
         $objWidget = new $strClass($strClass::getAttributesFromDca($arrData, $field, $varValue, '', '', $this));
         $objWidget->storeValues = true;
         $objWidget->rowClass = 'row_' . $row . ($row == 0 ? ' row_first' : '') . ($row % 2 == 0 ? ' even' : ' odd');
         // Increase the row count if it is a password field
         if ($objWidget instanceof FormPassword) {
             if ($objMember->password != '') {
                 $objWidget->mandatory = false;
             }
             $objWidget->rowClassConfirm = 'row_' . ++$row . ($row % 2 == 0 ? ' even' : ' odd');
         }
         // Validate the form data
         if (\Input::post('FORM_SUBMIT') == $strFormId) {
             $objWidget->validate();
             $varValue = $objWidget->value;
             $rgxp = $arrData['eval']['rgxp'];
             // Convert date formats into timestamps (check the eval setting first -> #3063)
             if ($varValue != '' && in_array($rgxp, array('date', 'time', 'datim'))) {
                 try {
                     $objDate = new \Date($varValue, \Date::getFormatFromRgxp($rgxp));
                     $varValue = $objDate->tstamp;
                 } catch (\OutOfBoundsException $e) {
                     $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varValue));
                 }
             }
             // Make sure that unique fields are unique (check the eval setting first -> #3063)
             if ($arrData['eval']['unique'] && $varValue != '' && !$this->Database->isUniqueValue('tl_member', $field, $varValue, $this->User->id)) {
                 $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $field));
             }
             // Trigger the save_callback (see #5247)
             if ($objWidget->submitInput() && !$objWidget->hasErrors() && is_array($arrData['save_callback'])) {
                 foreach ($arrData['save_callback'] as $callback) {
                     try {
                         if (is_array($callback)) {
                             $this->import($callback[0]);
                             $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $this->User, $this);
                         } elseif (is_callable($callback)) {
                             $varValue = $callback($varValue, $this->User, $this);
                         }
                     } catch (\Exception $e) {
                         $objWidget->class = 'error';
                         $objWidget->addError($e->getMessage());
                     }
                 }
             }
             // Do not submit the field if there are errors
             if ($objWidget->hasErrors()) {
                 $doNotSubmit = true;
             } elseif ($objWidget->submitInput()) {
                 // Store the form data
                 $_SESSION['FORM_DATA'][$field] = $varValue;
                 // Set the correct empty value (see #6284, #6373)
                 if ($varValue === '') {
                     $varValue = $objWidget->getEmptyValue();
                 }
                 // Encrypt the value (see #7815)
                 if ($arrData['eval']['encrypt']) {
                     $varValue = \Encryption::encrypt($varValue);
                 }
                 // Set the new value
                 if ($varValue !== $this->User->{$field}) {
                     $this->User->{$field} = $varValue;
                     // Set the new field in the member model
                     $blnModified = true;
                     $objMember->{$field} = $varValue;
                 }
             }
         }
         if ($objWidget instanceof \uploadable) {
             $hasUpload = true;
         }
         $temp = $objWidget->parse();
         $this->Template->fields .= $temp;
         $arrFields[$strGroup][$field] .= $temp;
         ++$row;
     }
     // Save the model
     if ($blnModified) {
         $objMember->tstamp = time();
         $objMember->save();
         // Create a new version
         if ($GLOBALS['TL_DCA'][$strTable]['config']['enableVersioning']) {
             $objVersions->create();
             $this->log('A new version of record "' . $strTable . '.id=' . $objMember->id . '" has been created' . $this->getParentEntries($strTable, $objMember->id), __METHOD__, TL_GENERAL);
         }
     }
     $this->Template->hasError = $doNotSubmit;
     // Redirect or reload if there was no error
     if (\Input::post('FORM_SUBMIT') == $strFormId && !$doNotSubmit) {
         // HOOK: updated personal data
         if (isset($GLOBALS['TL_HOOKS']['updatePersonalData']) && is_array($GLOBALS['TL_HOOKS']['updatePersonalData'])) {
             foreach ($GLOBALS['TL_HOOKS']['updatePersonalData'] as $callback) {
                 $this->import($callback[0]);
                 $this->{$callback[0]}->{$callback[1]}($this->User, $_SESSION['FORM_DATA'], $this);
             }
         }
         // Call the onsubmit_callback
         if (is_array($GLOBALS['TL_DCA']['tl_member']['config']['onsubmit_callback'])) {
             foreach ($GLOBALS['TL_DCA']['tl_member']['config']['onsubmit_callback'] as $callback) {
                 if (is_array($callback)) {
                     $this->import($callback[0]);
                     $this->{$callback[0]}->{$callback[1]}($this->User, $this);
                 } elseif (is_callable($callback)) {
                     $callback($this->User, $this);
                 }
             }
         }
         // Check whether there is a jumpTo page
         if (($objJumpTo = $this->objModel->getRelated('jumpTo')) !== null) {
             $this->jumpToOrReload($objJumpTo->row());
         }
         $flashBag->set('mod_personal_data_confirm', $GLOBALS['TL_LANG']['MSC']['savedData']);
         $this->reload();
     }
     $this->Template->loginDetails = $GLOBALS['TL_LANG']['tl_member']['loginDetails'];
     $this->Template->addressDetails = $GLOBALS['TL_LANG']['tl_member']['addressDetails'];
     $this->Template->contactDetails = $GLOBALS['TL_LANG']['tl_member']['contactDetails'];
     $this->Template->personalData = $GLOBALS['TL_LANG']['tl_member']['personalData'];
     // Add the groups
     foreach ($arrFields as $k => $v) {
         // Deprecated since Contao 4.0, to be removed in Contao 5.0
         $this->Template->{$k} = $v;
         $key = $k . ($k == 'personal' ? 'Data' : 'Details');
         $arrGroups[$GLOBALS['TL_LANG']['tl_member'][$key]] = $v;
     }
     // Confirmation message
     if ($flashBag->has('mod_personal_data_confirm')) {
         $arrMessages = $flashBag->get('mod_personal_data_confirm');
         $this->Template->message = $arrMessages[0];
     }
     $this->Template->categories = $arrGroups;
     $this->Template->formId = $strFormId;
     $this->Template->slabel = specialchars($GLOBALS['TL_LANG']['MSC']['saveData']);
     $this->Template->action = \Environment::get('indexFreeRequest');
     $this->Template->enctype = $hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
     $this->Template->rowLast = 'row_' . $row . ($row % 2 == 0 ? ' even' : ' odd');
 }
 /**
  * Loads the language strings.
  *
  * @return array|null The language strings or null
  */
 private function loadLanguageStrings()
 {
     $this->framework->initialize();
     System::loadLanguageFile('exception');
     if (!isset($GLOBALS['TL_LANG']['XPT'])) {
         return null;
     }
     return $GLOBALS['TL_LANG']['XPT'];
 }
Exemple #17
0
 /**
  * Add the welcome screen
  *
  * @return string
  */
 protected function welcomeScreen()
 {
     \System::loadLanguageFile('explain');
     /** @var BackendTemplate|object $objTemplate */
     $objTemplate = new \BackendTemplate('be_welcome');
     $objTemplate->messages = \Message::generateUnwrapped() . \Backend::getSystemMessages();
     $objTemplate->loginMsg = $GLOBALS['TL_LANG']['MSC']['firstLogin'];
     // Add the login message
     if ($this->User->lastLogin > 0) {
         $formatter = new DateTimeFormatter(\System::getContainer()->get('translator'));
         $diff = $formatter->formatDiff(new \DateTime(date('Y-m-d H:i:s', $this->User->lastLogin)), new \DateTime());
         $objTemplate->loginMsg = sprintf($GLOBALS['TL_LANG']['MSC']['lastLogin'][1], '<time title="' . \Date::parse(\Config::get('datimFormat'), $this->User->lastLogin) . '">' . $diff . '</time>');
     }
     // Add the versions overview
     \Versions::addToTemplate($objTemplate);
     $objTemplate->welcome = sprintf($GLOBALS['TL_LANG']['MSC']['welcomeTo'], \Config::get('websiteTitle'));
     $objTemplate->showDifferences = \StringUtil::specialchars(str_replace("'", "\\'", $GLOBALS['TL_LANG']['MSC']['showDifferences']));
     $objTemplate->recordOfTable = \StringUtil::specialchars(str_replace("'", "\\'", $GLOBALS['TL_LANG']['MSC']['recordOfTable']));
     $objTemplate->systemMessages = $GLOBALS['TL_LANG']['MSC']['systemMessages'];
     $objTemplate->shortcuts = $GLOBALS['TL_LANG']['MSC']['shortcuts'][0];
     $objTemplate->shortcutsLink = $GLOBALS['TL_LANG']['MSC']['shortcuts'][1];
     $objTemplate->editElement = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['editElement']);
     return $objTemplate->parse();
 }
Exemple #18
0
 /**
  * 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();
 }
 /**
  * Return the languages for the TinyMCE spellchecker
  *
  * @return string The TinyMCE spellchecker language string
  */
 protected function getSpellcheckerString()
 {
     \System::loadLanguageFile('languages');
     $return = array();
     $langs = scan(__DIR__ . '/../../languages');
     array_unshift($langs, $GLOBALS['TL_LANGUAGE']);
     foreach ($langs as $lang) {
         $lang = substr($lang, 0, 2);
         if (isset($GLOBALS['TL_LANG']['LNG'][$lang])) {
             $return[$lang] = $GLOBALS['TL_LANG']['LNG'][$lang] . '=' . $lang;
         }
     }
     return '+' . implode(',', array_unique($return));
 }
Exemple #20
0
 /**
  * Run the controller
  *
  * @return Response
  */
 public function run()
 {
     /** @var SessionInterface $objSession */
     $objSession = \System::getContainer()->get('session');
     // Redirect to the back end home page
     if (\Input::post('FORM_SUBMIT') == 'invalid_token_url') {
         list($strUrl) = explode('?', $objSession->get('INVALID_TOKEN_URL'));
         $this->redirect($strUrl);
     }
     /** @var BackendTemplate|object $objTemplate */
     $objTemplate = new \BackendTemplate('be_confirm');
     // Prepare the URL
     $url = preg_replace('/(\\?|&)rt=[^&]*/', '', $objSession->get('INVALID_TOKEN_URL'));
     $objTemplate->href = ampersand($url . (strpos($url, '?') !== false ? '&rt=' : '?rt=') . REQUEST_TOKEN);
     $vars = array();
     list(, $request) = explode('?', $url, 2);
     // Extract the arguments
     foreach (explode('&', $request) as $arg) {
         list($key, $value) = explode('=', $arg, 2);
         $vars[$key] = $value;
     }
     $arrInfo = array();
     // Provide more information about the link (see #4007)
     foreach ($vars as $k => $v) {
         switch ($k) {
             default:
                 $arrInfo[$k] = $v;
                 break;
             case 'do':
                 $arrInfo['do'] = $GLOBALS['TL_LANG']['MOD'][$v][0];
                 break;
             case 'id':
                 $arrInfo['id'] = 'ID ' . $v;
                 break;
         }
     }
     // Use the first table if none is given
     if (!isset($arrInfo['table'])) {
         foreach ($GLOBALS['BE_MOD'] as $category => $modules) {
             if (isset($GLOBALS['BE_MOD'][$category][$vars['do']])) {
                 $arrInfo['table'] = $GLOBALS['BE_MOD'][$category][$vars['do']]['tables'][0];
                 break;
             }
         }
     }
     \System::loadLanguageFile($arrInfo['table']);
     // Override the action label
     if (isset($arrInfo['clipboard'])) {
         $arrInfo['act'] = $GLOBALS['TL_LANG']['MSC']['clearClipboard'];
     } elseif (isset($arrInfo['mode']) && !isset($arrInfo['act'])) {
         if ($arrInfo['mode'] == 'create') {
             $arrInfo['act'] = $GLOBALS['TL_LANG'][$arrInfo['table']]['new'][0];
         } elseif ($arrInfo['mode'] == 'cut' || $arrInfo['mode'] == 'copy') {
             $arrInfo['act'] = $GLOBALS['TL_LANG'][$arrInfo['table']][$arrInfo['mode']][0];
         }
     } else {
         $arrInfo['act'] = $GLOBALS['TL_LANG'][$arrInfo['table']][$arrInfo['act']][0];
     }
     unset($arrInfo['pid']);
     unset($arrInfo['clipboard']);
     unset($arrInfo['ref']);
     unset($arrInfo['mode']);
     // Template variables
     $objTemplate->confirm = true;
     $objTemplate->link = \StringUtil::specialchars($url);
     $objTemplate->info = $arrInfo;
     $objTemplate->labels = $GLOBALS['TL_LANG']['CONFIRM'];
     $objTemplate->explain = $GLOBALS['TL_LANG']['ERR']['invalidTokenUrl'];
     $objTemplate->cancel = $GLOBALS['TL_LANG']['MSC']['cancelBT'];
     $objTemplate->continue = $GLOBALS['TL_LANG']['MSC']['continue'];
     $objTemplate->theme = \Backend::getTheme();
     $objTemplate->base = \Environment::get('base');
     $objTemplate->language = $GLOBALS['TL_LANGUAGE'];
     $objTemplate->title = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['invalidTokenUrl']);
     $objTemplate->charset = \Config::get('characterSet');
     return $objTemplate->getResponse();
 }
 /**
  * Loads the language strings.
  *
  * @return array|null The language strings or null
  */
 private function loadLanguageStrings()
 {
     if (!class_exists('Contao\\System')) {
         return null;
     }
     System::loadLanguageFile('exception');
     if (!isset($GLOBALS['TL_LANG']['XPT'])) {
         return null;
     }
     return $GLOBALS['TL_LANG']['XPT'];
 }
 /**
  * Add the welcome screen
  *
  * @return string
  */
 protected function welcomeScreen()
 {
     \System::loadLanguageFile('explain');
     /** @var \BackendTemplate|object $objTemplate */
     $objTemplate = new \BackendTemplate('be_welcome');
     $objTemplate->messages = \Message::generateUnwrapped();
     // HOOK: add custom messages
     if (isset($GLOBALS['TL_HOOKS']['getSystemMessages']) && is_array($GLOBALS['TL_HOOKS']['getSystemMessages'])) {
         $arrMessages = array();
         foreach ($GLOBALS['TL_HOOKS']['getSystemMessages'] as $callback) {
             $this->import($callback[0]);
             $strBuffer = $this->{$callback}[0]->{$callback}[1]();
             if ($strBuffer != '') {
                 $arrMessages[] = $strBuffer;
             }
         }
         if (!empty($arrMessages)) {
             $objTemplate->messages .= "\n" . implode("\n", $arrMessages);
         }
     }
     // Add the versions overview
     \Versions::addToTemplate($objTemplate);
     $objTemplate->welcome = sprintf($GLOBALS['TL_LANG']['MSC']['welcomeTo'], \Config::get('websiteTitle'));
     $objTemplate->showDifferences = specialchars(str_replace("'", "\\'", $GLOBALS['TL_LANG']['MSC']['showDifferences']));
     $objTemplate->systemMessages = $GLOBALS['TL_LANG']['MSC']['systemMessages'];
     $objTemplate->shortcuts = $GLOBALS['TL_LANG']['MSC']['shortcuts'][0];
     $objTemplate->shortcutsLink = $GLOBALS['TL_LANG']['MSC']['shortcuts'][1];
     $objTemplate->editElement = specialchars($GLOBALS['TL_LANG']['MSC']['editElement']);
     return $objTemplate->parse();
 }
Exemple #23
0
 /**
  * Open a back end module and return it as HTML
  *
  * @param string $module
  *
  * @return string
  *
  * @throws AccessDeniedException
  */
 protected function getBackendModule($module)
 {
     $arrModule = array();
     foreach ($GLOBALS['BE_MOD'] as &$arrGroup) {
         if (isset($arrGroup[$module])) {
             $arrModule =& $arrGroup[$module];
             break;
         }
     }
     $this->import('BackendUser', 'User');
     // Dynamically add the "personal data" module (see #4193)
     if (\Input::get('do') == 'login') {
         $arrModule = array('tables' => array('tl_user'), 'callback' => 'ModuleUser');
     } elseif ($module != 'undo' && !$this->User->hasAccess($module, 'modules')) {
         throw new AccessDeniedException('Back end module "' . $module . '" is not allowed for user "' . $this->User->username . '".');
     }
     /** @var SessionInterface $objSession */
     $objSession = \System::getContainer()->get('session');
     $arrTables = (array) $arrModule['tables'];
     $strTable = \Input::get('table') ?: $arrTables[0];
     $id = !\Input::get('act') && \Input::get('id') ? \Input::get('id') : $objSession->get('CURRENT_ID');
     // Store the current ID in the current session
     if ($id != $objSession->get('CURRENT_ID')) {
         $objSession->set('CURRENT_ID', $id);
     }
     define('CURRENT_ID', \Input::get('table') ? $id : \Input::get('id'));
     $this->Template->headline = $GLOBALS['TL_LANG']['MOD'][$module][0];
     // Add the module style sheet
     if (isset($arrModule['stylesheet'])) {
         foreach ((array) $arrModule['stylesheet'] as $stylesheet) {
             $GLOBALS['TL_CSS'][] = $stylesheet;
         }
     }
     // Add module javascript
     if (isset($arrModule['javascript'])) {
         foreach ((array) $arrModule['javascript'] as $javascript) {
             $GLOBALS['TL_JAVASCRIPT'][] = $javascript;
         }
     }
     $dc = null;
     // Create the data container object
     if ($strTable != '') {
         if (!in_array($strTable, $arrTables)) {
             throw new AccessDeniedException('Table "' . $strTable . '" is not allowed in module "' . $module . '".');
         }
         // Load the language and DCA file
         \System::loadLanguageFile($strTable);
         $this->loadDataContainer($strTable);
         // Include all excluded fields which are allowed for the current user
         if ($GLOBALS['TL_DCA'][$strTable]['fields']) {
             foreach ($GLOBALS['TL_DCA'][$strTable]['fields'] as $k => $v) {
                 if ($v['exclude']) {
                     if ($this->User->hasAccess($strTable . '::' . $k, 'alexf')) {
                         if ($strTable == 'tl_user_group') {
                             $GLOBALS['TL_DCA'][$strTable]['fields'][$k]['orig_exclude'] = $GLOBALS['TL_DCA'][$strTable]['fields'][$k]['exclude'];
                         }
                         $GLOBALS['TL_DCA'][$strTable]['fields'][$k]['exclude'] = false;
                     }
                 }
             }
         }
         // Fabricate a new data container object
         if ($GLOBALS['TL_DCA'][$strTable]['config']['dataContainer'] == '') {
             $this->log('Missing data container for table "' . $strTable . '"', __METHOD__, TL_ERROR);
             trigger_error('Could not create a data container object', E_USER_ERROR);
         }
         $dataContainer = 'DC_' . $GLOBALS['TL_DCA'][$strTable]['config']['dataContainer'];
         /** @var DataContainer $dc */
         $dc = new $dataContainer($strTable, $arrModule);
     }
     // AJAX request
     if ($_POST && \Environment::get('isAjaxRequest')) {
         $this->objAjax->executePostActions($dc);
     } elseif (class_exists($arrModule['callback'])) {
         /** @var Module $objCallback */
         $objCallback = new $arrModule['callback']($dc);
         $this->Template->main .= $objCallback->generate();
     } elseif (\Input::get('key') && isset($arrModule[\Input::get('key')])) {
         $objCallback = \System::importStatic($arrModule[\Input::get('key')][0]);
         $this->Template->main .= $objCallback->{$arrModule[\Input::get('key')][1]}($dc);
         // Add the name of the parent element
         if (isset($_GET['table']) && in_array(\Input::get('table'), $arrTables) && \Input::get('table') != $arrTables[0]) {
             if ($GLOBALS['TL_DCA'][$strTable]['config']['ptable'] != '') {
                 $objRow = $this->Database->prepare("SELECT * FROM " . $GLOBALS['TL_DCA'][$strTable]['config']['ptable'] . " WHERE id=?")->limit(1)->execute(CURRENT_ID);
                 if ($objRow->title != '') {
                     $this->Template->headline .= ' » ' . $objRow->title;
                 } elseif ($objRow->name != '') {
                     $this->Template->headline .= ' » ' . $objRow->name;
                 }
             }
         }
         // Add the name of the submodule
         $this->Template->headline .= ' » ' . sprintf($GLOBALS['TL_LANG'][$strTable][\Input::get('key')][1], \Input::get('id'));
     } elseif (is_object($dc)) {
         $act = \Input::get('act');
         if ($act == '' || $act == 'paste' || $act == 'select') {
             $act = $dc instanceof \listable ? 'showAll' : 'edit';
         }
         switch ($act) {
             case 'delete':
             case 'show':
             case 'showAll':
             case 'undo':
                 if (!$dc instanceof \listable) {
                     $this->log('Data container ' . $strTable . ' is not listable', __METHOD__, TL_ERROR);
                     trigger_error('The current data container is not listable', E_USER_ERROR);
                 }
                 break;
             case 'create':
             case 'cut':
             case 'cutAll':
             case 'copy':
             case 'copyAll':
             case 'move':
             case 'edit':
                 if (!$dc instanceof \editable) {
                     $this->log('Data container ' . $strTable . ' is not editable', __METHOD__, TL_ERROR);
                     trigger_error('The current data container is not editable', E_USER_ERROR);
                 }
                 break;
         }
         $strFirst = null;
         $strSecond = null;
         // Handle child child tables (e.g. tl_style)
         if (isset($GLOBALS['TL_DCA'][$strTable]['config']['ptable'])) {
             $ptable = $GLOBALS['TL_DCA'][$strTable]['config']['ptable'];
             if (in_array($ptable, $arrTables)) {
                 $this->loadDataContainer($ptable);
                 if (isset($GLOBALS['TL_DCA'][$ptable]['config']['ptable'])) {
                     $ftable = $GLOBALS['TL_DCA'][$ptable]['config']['ptable'];
                     if (in_array($ftable, $arrTables)) {
                         $strFirst = $ftable;
                         $strSecond = $ptable;
                     }
                 }
             }
         }
         // Build the breadcrumb trail
         if ($strFirst !== null && $strSecond !== null) {
             if (!isset($_GET['act']) || \Input::get('act') == 'paste' && \Input::get('mode') == 'create' || \Input::get('act') == 'select' || \Input::get('act') == 'editAll' || \Input::get('act') == 'overrideAll') {
                 if ($strTable == $strSecond) {
                     $strQuery = "SELECT * FROM {$strFirst} WHERE id=?";
                 } else {
                     $strQuery = "SELECT * FROM {$strFirst} WHERE id=(SELECT pid FROM {$strSecond} WHERE id=?)";
                 }
             } else {
                 if ($strTable == $strSecond) {
                     $strQuery = "SELECT * FROM {$strFirst} WHERE id=(SELECT pid FROM {$strSecond} WHERE id=?)";
                 } else {
                     $strQuery = "SELECT * FROM {$strFirst} WHERE id=(SELECT pid FROM {$strSecond} WHERE id=(SELECT pid FROM {$strTable} WHERE id=?))";
                 }
             }
             // Add the first level name
             $objRow = $this->Database->prepare($strQuery)->limit(1)->execute($dc->id);
             if ($objRow->title != '') {
                 $this->Template->headline .= ' » ' . $objRow->title;
             } elseif ($objRow->name != '') {
                 $this->Template->headline .= ' » ' . $objRow->name;
             }
             if (isset($GLOBALS['TL_LANG']['MOD'][$strSecond])) {
                 $this->Template->headline .= ' » ' . $GLOBALS['TL_LANG']['MOD'][$strSecond];
             }
             // Add the second level name
             $objRow = $this->Database->prepare("SELECT * FROM {$strSecond} WHERE id=?")->limit(1)->execute(CURRENT_ID);
             if ($objRow->title != '') {
                 $this->Template->headline .= ' » ' . $objRow->title;
             } elseif ($objRow->name != '') {
                 $this->Template->headline .= ' » ' . $objRow->name;
             }
         } else {
             // Add the name of the parent element
             if ($strTable && in_array($strTable, $arrTables) && $strTable != $arrTables[0]) {
                 if ($GLOBALS['TL_DCA'][$strTable]['config']['ptable'] != '') {
                     $objRow = $this->Database->prepare("SELECT * FROM " . $GLOBALS['TL_DCA'][$strTable]['config']['ptable'] . " WHERE id=?")->limit(1)->execute(CURRENT_ID);
                     if ($objRow->title != '') {
                         $this->Template->headline .= ' » ' . $objRow->title;
                     } elseif ($objRow->name != '') {
                         $this->Template->headline .= ' » ' . $objRow->name;
                     }
                 }
             }
             // Add the name of the submodule
             if ($strTable && isset($GLOBALS['TL_LANG']['MOD'][$strTable])) {
                 $this->Template->headline .= ' » ' . $GLOBALS['TL_LANG']['MOD'][$strTable];
             }
         }
         // Add the current action
         if (\Input::get('act') == 'editAll') {
             $this->Template->headline .= ' » ' . $GLOBALS['TL_LANG']['MSC']['all'][0];
         } elseif (\Input::get('act') == 'overrideAll') {
             $this->Template->headline .= ' » ' . $GLOBALS['TL_LANG']['MSC']['all_override'][0];
         } else {
             if (\Input::get('id')) {
                 if (\Input::get('do') == 'files' || \Input::get('do') == 'tpl_editor') {
                     // Handle new folders (see #7980)
                     if (strpos(\Input::get('id'), '__new__') !== false) {
                         $this->Template->headline .= ' » ' . dirname(\Input::get('id')) . ' » ' . $GLOBALS['TL_LANG'][$strTable]['new'][1];
                     } else {
                         $this->Template->headline .= ' » ' . \Input::get('id');
                     }
                 } elseif (is_array($GLOBALS['TL_LANG'][$strTable][$act])) {
                     $this->Template->headline .= ' » ' . sprintf($GLOBALS['TL_LANG'][$strTable][$act][1], \Input::get('id'));
                 }
             } elseif (\Input::get('pid')) {
                 if (\Input::get('do') == 'files' || \Input::get('do') == 'tpl_editor') {
                     $this->Template->headline .= ' » ' . \Input::get('pid');
                 } elseif (is_array($GLOBALS['TL_LANG'][$strTable][$act])) {
                     $this->Template->headline .= ' » ' . sprintf($GLOBALS['TL_LANG'][$strTable][$act][1], \Input::get('pid'));
                 }
             }
         }
         return $dc->{$act}();
     }
     return null;
 }
Exemple #24
0
 /**
  * Check whether there is a cached version of the page and return a response object
  *
  * @return Response|null
  */
 public static function getResponseFromCache()
 {
     // Build the page if a user is (potentially) logged in or there is POST data
     if (!empty($_POST) || \Input::cookie('BE_USER_AUTH') || \Input::cookie('FE_USER_AUTH') || \Input::cookie('FE_AUTO_LOGIN') || $_SESSION['DISABLE_CACHE'] || isset($_SESSION['LOGIN_ERROR']) || \Message::hasMessages() || \Config::get('debugMode')) {
         return null;
     }
     $strCacheDir = \System::getContainer()->getParameter('kernel.cache_dir');
     // Try to map the empty request
     if (\Environment::get('relativeRequest') == '') {
         // Return if the language is added to the URL and the empty domain will be redirected
         if (\Config::get('addLanguageToUrl') && !\Config::get('doNotRedirectEmpty')) {
             return null;
         }
         $strCacheKey = null;
         $arrLanguage = \Environment::get('httpAcceptLanguage');
         $strMappingFile = $strCacheDir . '/contao/config/mapping.php';
         // Try to get the cache key from the mapper array
         if (file_exists($strMappingFile)) {
             $arrMapper = (include $strMappingFile);
             $arrPaths = array(\Environment::get('host'), '*');
             // Try the language specific keys
             foreach ($arrLanguage as $strLanguage) {
                 foreach ($arrPaths as $strPath) {
                     $strKey = $strPath . '/empty.' . $strLanguage;
                     if (isset($arrMapper[$strKey])) {
                         $strCacheKey = $arrMapper[$strKey];
                         break;
                     }
                 }
             }
             // Try the fallback key
             if ($strCacheKey === null) {
                 foreach ($arrPaths as $strPath) {
                     $strKey = $strPath . '/empty.fallback';
                     if (isset($arrMapper[$strKey])) {
                         $strCacheKey = $arrMapper[$strKey];
                         break;
                     }
                 }
             }
         }
         // Fall back to the first accepted language
         if ($strCacheKey === null) {
             $strCacheKey = \Environment::get('host') . '/empty.' . $arrLanguage[0];
         }
     } else {
         $strCacheKey = \Environment::get('host') . '/' . \Environment::get('relativeRequest');
     }
     // HOOK: add custom logic
     if (isset($GLOBALS['TL_HOOKS']['getCacheKey']) && is_array($GLOBALS['TL_HOOKS']['getCacheKey'])) {
         foreach ($GLOBALS['TL_HOOKS']['getCacheKey'] as $callback) {
             $strCacheKey = \System::importStatic($callback[0])->{$callback[1]}($strCacheKey);
         }
     }
     $blnFound = false;
     $strCacheFile = null;
     // Check for a mobile layout
     if (\Input::cookie('TL_VIEW') == 'mobile' || \Environment::get('agent')->mobile && \Input::cookie('TL_VIEW') != 'desktop') {
         $strMd5CacheKey = md5($strCacheKey . '.mobile');
         $strCacheFile = $strCacheDir . '/contao/html/' . substr($strMd5CacheKey, 0, 1) . '/' . $strMd5CacheKey . '.html';
         if (file_exists($strCacheFile)) {
             $blnFound = true;
         }
     } else {
         $strMd5CacheKey = md5($strCacheKey . '.desktop');
         $strCacheFile = $strCacheDir . '/contao/html/' . substr($strMd5CacheKey, 0, 1) . '/' . $strMd5CacheKey . '.html';
         if (file_exists($strCacheFile)) {
             $blnFound = true;
         }
     }
     // Check for a regular layout
     if (!$blnFound) {
         $strMd5CacheKey = md5($strCacheKey);
         $strCacheFile = $strCacheDir . '/contao/html/' . substr($strMd5CacheKey, 0, 1) . '/' . $strMd5CacheKey . '.html';
         if (file_exists($strCacheFile)) {
             $blnFound = true;
         }
     }
     // Return if the file does not exist
     if (!$blnFound) {
         return null;
     }
     $expire = null;
     $content = null;
     $type = null;
     $files = null;
     $assets = null;
     // Include the file
     ob_start();
     require_once $strCacheFile;
     // The file has expired
     if ($expire < time()) {
         ob_end_clean();
         return null;
     }
     // Define the static URL constants (see #7914)
     define('TL_FILES_URL', $files);
     define('TL_ASSETS_URL', $assets);
     // Read the buffer
     $strBuffer = ob_get_clean();
     /** @var AttributeBagInterface $session */
     $session = \System::getContainer()->get('session')->getBag('contao_frontend');
     // Session required to determine the referer
     $data = $session->all();
     // Set the new referer
     if (!isset($_GET['pdf']) && !isset($_GET['file']) && !isset($_GET['id']) && $data['referer']['current'] != \Environment::get('requestUri')) {
         $data['referer']['last'] = $data['referer']['current'];
         $data['referer']['current'] = substr(\Environment::get('requestUri'), strlen(\Environment::get('path')) + 1);
     }
     // Store the session data
     $session->replace($data);
     // Load the default language file (see #2644)
     \System::loadLanguageFile('default');
     // Replace the insert tags and then re-replace the request_token tag in case a form element has been loaded via insert tag
     $strBuffer = \Controller::replaceInsertTags($strBuffer, false);
     $strBuffer = str_replace(array('{{request_token}}', '[{]', '[}]'), array(REQUEST_TOKEN, '{{', '}}'), $strBuffer);
     // HOOK: allow to modify the compiled markup (see #4291 and #7457)
     if (isset($GLOBALS['TL_HOOKS']['modifyFrontendPage']) && is_array($GLOBALS['TL_HOOKS']['modifyFrontendPage'])) {
         foreach ($GLOBALS['TL_HOOKS']['modifyFrontendPage'] as $callback) {
             $strBuffer = \System::importStatic($callback[0])->{$callback[1]}($strBuffer, null);
         }
     }
     // Content type
     if (!$content) {
         $content = 'text/html';
     }
     $response = new Response($strBuffer);
     // Send the status header (see #6585)
     if ($type == 'error_403') {
         $response->setStatusCode(Response::HTTP_FORBIDDEN);
     } elseif ($type == 'error_404') {
         $response->setStatusCode(Response::HTTP_NOT_FOUND);
     }
     $response->headers->set('Vary', 'User-Agent', false);
     $response->headers->set('Content-Type', $content . '; charset=' . \Config::get('characterSet'));
     // Send the cache headers
     if ($expire !== null && (\Config::get('cacheMode') == 'both' || \Config::get('cacheMode') == 'browser')) {
         $response->headers->set('Cache-Control', 'public, max-age=' . ($expire - time()));
         $response->headers->set('Pragma', 'public');
         $response->headers->set('Last-Modified', gmdate('D, d M Y H:i:s', time()) . ' GMT');
         $response->headers->set('Expires', gmdate('D, d M Y H:i:s', $expire) . ' GMT');
     } else {
         $response->headers->set('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
         $response->headers->set('Pragma', 'no-cache');
         $response->headers->set('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
         $response->headers->set('Expires', 'Fri, 06 Jun 1975 15:10:00 GMT');
     }
     return $response;
 }
Exemple #25
0
 /**
  * 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 = \StringUtil::deserialize($arrVersions[\Input::post('to')]['data']);
         } elseif (\Input::get('to') && isset($arrVersions[\Input::get('to')])) {
             $intTo = \Input::get('to');
             $to = \StringUtil::deserialize($arrVersions[\Input::get('to')]['data']);
         } else {
             $intTo = $intIndex;
             $to = \StringUtil::deserialize($arrVersions[$intTo]['data']);
         }
         // From
         if (\Input::post('from') && isset($arrVersions[\Input::post('from')])) {
             $intFrom = \Input::post('from');
             $from = \StringUtil::deserialize($arrVersions[\Input::post('from')]['data']);
         } elseif (\Input::get('from') && isset($arrVersions[\Input::get('from')])) {
             $intFrom = \Input::get('from');
             $from = \StringUtil::deserialize($arrVersions[\Input::get('from')]['data']);
         } elseif ($intIndex > 1) {
             $intFrom = $intIndex - 1;
             $from = \StringUtil::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]['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 = \StringUtil::deserialize($to[$k])) && !is_array($to[$k])) {
                         $to[$k] = $this->implodeRecursive($tmp, $blnIsBinary);
                     }
                     if (is_array($tmp = \StringUtil::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 = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['showDifferences']);
     $objTemplate->theme = \Backend::getTheme();
     $objTemplate->base = \Environment::get('base');
     $objTemplate->language = $GLOBALS['TL_LANGUAGE'];
     $objTemplate->title = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['showDifferences']);
     $objTemplate->charset = \Config::get('characterSet');
     $objTemplate->action = ampersand(\Environment::get('request'));
     throw new ResponseException($objTemplate->getResponse());
 }
Exemple #26
0
 /**
  * Try to login the current user
  *
  * @return boolean True if the user could be logged in
  */
 public function login()
 {
     \System::loadLanguageFile('default');
     // Do not continue if username or password are missing
     if (empty($_POST['username']) || empty($_POST['password'])) {
         return false;
     }
     // Load the user object
     if ($this->findBy('username', \Input::post('username', true)) == false) {
         $blnLoaded = false;
         // HOOK: pass credentials to callback functions
         if (isset($GLOBALS['TL_HOOKS']['importUser']) && is_array($GLOBALS['TL_HOOKS']['importUser'])) {
             foreach ($GLOBALS['TL_HOOKS']['importUser'] as $callback) {
                 $this->import($callback[0], 'objImport', true);
                 $blnLoaded = $this->objImport->{$callback[1]}(\Input::post('username', true), \Input::postUnsafeRaw('password'), $this->strTable);
                 // Load successfull
                 if ($blnLoaded === true) {
                     break;
                 }
             }
         }
         // Return if the user still cannot be loaded
         if (!$blnLoaded || $this->findBy('username', \Input::post('username', true)) == false) {
             \Message::addError($GLOBALS['TL_LANG']['ERR']['invalidLogin']);
             $this->log('Could not find user "' . \Input::post('username', true) . '"', __METHOD__, TL_ACCESS);
             return false;
         }
     }
     $time = time();
     // Set the user language
     if (\Input::post('language')) {
         $this->language = \Input::post('language');
     }
     // Lock the account if there are too many login attempts
     if ($this->loginCount < 1) {
         $this->locked = $time;
         $this->loginCount = \Config::get('loginCount');
         $this->save();
         // Add a log entry and the error message, because checkAccountStatus() will not be called (see #4444)
         $this->log('User "' . $this->username . '" has been locked for ' . ceil(\Config::get('lockPeriod') / 60) . ' minutes', __METHOD__, TL_ACCESS);
         \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['accountLocked'], ceil(($this->locked + \Config::get('lockPeriod') - $time) / 60)));
         // Send admin notification
         if (\Config::get('adminEmail') != '') {
             $objEmail = new \Email();
             $objEmail->subject = $GLOBALS['TL_LANG']['MSC']['lockedAccount'][0];
             $objEmail->text = sprintf($GLOBALS['TL_LANG']['MSC']['lockedAccount'][1], $this->username, TL_MODE == 'FE' ? $this->firstname . " " . $this->lastname : $this->name, \Idna::decode(\Environment::get('base')), ceil(\Config::get('lockPeriod') / 60));
             $objEmail->sendTo(\Config::get('adminEmail'));
         }
         return false;
     }
     // Check the account status
     if ($this->checkAccountStatus() == false) {
         return false;
     }
     // The password has been generated with crypt()
     if (\Encryption::test($this->password)) {
         $blnAuthenticated = \Encryption::verify(\Input::postUnsafeRaw('password'), $this->password);
     } else {
         list($strPassword, $strSalt) = explode(':', $this->password);
         $blnAuthenticated = $strSalt == '' ? $strPassword === sha1(\Input::postUnsafeRaw('password')) : $strPassword === sha1($strSalt . \Input::postUnsafeRaw('password'));
         // Store a SHA-512 encrpyted version of the password
         if ($blnAuthenticated) {
             $this->password = \Encryption::hash(\Input::postUnsafeRaw('password'));
         }
     }
     // HOOK: pass credentials to callback functions
     if (!$blnAuthenticated && isset($GLOBALS['TL_HOOKS']['checkCredentials']) && is_array($GLOBALS['TL_HOOKS']['checkCredentials'])) {
         foreach ($GLOBALS['TL_HOOKS']['checkCredentials'] as $callback) {
             $this->import($callback[0], 'objAuth', true);
             $blnAuthenticated = $this->objAuth->{$callback[1]}(\Input::post('username', true), \Input::postUnsafeRaw('password'), $this);
             // Authentication successfull
             if ($blnAuthenticated === true) {
                 break;
             }
         }
     }
     // Redirect if the user could not be authenticated
     if (!$blnAuthenticated) {
         --$this->loginCount;
         $this->save();
         \Message::addError($GLOBALS['TL_LANG']['ERR']['invalidLogin']);
         $this->log('Invalid password submitted for username "' . $this->username . '"', __METHOD__, TL_ACCESS);
         return false;
     }
     $this->setUserFromDb();
     // Update the record
     $this->lastLogin = $this->currentLogin;
     $this->currentLogin = $time;
     $this->loginCount = \Config::get('loginCount');
     $this->save();
     // Generate the session
     $this->regenerateSessionId();
     $this->generateSession();
     $this->log('User "' . $this->username . '" has logged in', __METHOD__, TL_ACCESS);
     // HOOK: post login callback
     if (isset($GLOBALS['TL_HOOKS']['postLogin']) && is_array($GLOBALS['TL_HOOKS']['postLogin'])) {
         foreach ($GLOBALS['TL_HOOKS']['postLogin'] as $callback) {
             $this->import($callback[0], 'objLogin', true);
             $this->objLogin->{$callback[1]}($this);
         }
     }
     return true;
 }
 /**
  * Generate the module
  */
 protected function compile()
 {
     /** @var PageModel $objPage */
     global $objPage;
     $GLOBALS['TL_LANGUAGE'] = $objPage->language;
     \System::loadLanguageFile('tl_member');
     $this->loadDataContainer('tl_member');
     // Set new password
     if (strlen(\Input::get('token'))) {
         $this->setNewPassword();
         return;
     }
     // Username widget
     if (!$this->reg_skipName) {
         $arrFields['username'] = $GLOBALS['TL_DCA']['tl_member']['fields']['username'];
         $arrFields['username']['name'] = 'username';
     }
     // E-mail widget
     $arrFields['email'] = $GLOBALS['TL_DCA']['tl_member']['fields']['email'];
     $arrFields['email']['name'] = 'email';
     // Captcha widget
     if (!$this->disableCaptcha) {
         $arrFields['captcha'] = array('name' => 'lost_password', 'label' => $GLOBALS['TL_LANG']['MSC']['securityQuestion'], 'inputType' => 'captcha', 'eval' => array('mandatory' => true));
     }
     $row = 0;
     $strFields = '';
     $doNotSubmit = false;
     $strFormId = 'tl_lost_password_' . $this->id;
     // Initialize the widgets
     foreach ($arrFields as $arrField) {
         /** @var Widget $strClass */
         $strClass = $GLOBALS['TL_FFL'][$arrField['inputType']];
         // Continue if the class is not defined
         if (!class_exists($strClass)) {
             continue;
         }
         $arrField['eval']['required'] = $arrField['eval']['mandatory'];
         /** @var Widget $objWidget */
         $objWidget = new $strClass($strClass::getAttributesFromDca($arrField, $arrField['name']));
         $objWidget->storeValues = true;
         $objWidget->rowClass = 'row_' . $row . ($row == 0 ? ' row_first' : '') . ($row % 2 == 0 ? ' even' : ' odd');
         ++$row;
         // Validate the widget
         if (\Input::post('FORM_SUBMIT') == $strFormId) {
             $objWidget->validate();
             if ($objWidget->hasErrors()) {
                 $doNotSubmit = true;
             }
         }
         $strFields .= $objWidget->parse();
     }
     $this->Template->fields = $strFields;
     $this->Template->hasError = $doNotSubmit;
     // Look for an account and send the password link
     if (\Input::post('FORM_SUBMIT') == $strFormId && !$doNotSubmit) {
         if ($this->reg_skipName) {
             $objMember = \MemberModel::findActiveByEmailAndUsername(\Input::post('email', true), null);
         } else {
             $objMember = \MemberModel::findActiveByEmailAndUsername(\Input::post('email', true), \Input::post('username'));
         }
         if ($objMember === null) {
             sleep(2);
             // Wait 2 seconds while brute forcing :)
             $this->Template->error = $GLOBALS['TL_LANG']['MSC']['accountNotFound'];
         } else {
             $this->sendPasswordLink($objMember);
         }
     }
     $this->Template->formId = $strFormId;
     $this->Template->username = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['username']);
     $this->Template->email = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['emailAddress']);
     $this->Template->action = \Environment::get('indexFreeRequest');
     $this->Template->slabel = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['requestPassword']);
     $this->Template->rowLast = 'row_' . $row . ' row_last' . ($row % 2 == 0 ? ' even' : ' odd');
 }
 /**
  * Generate a regular page
  *
  * @param \PageModel $objPage
  *
  * @internal
  */
 protected function prepare($objPage)
 {
     $GLOBALS['TL_KEYWORDS'] = '';
     $GLOBALS['TL_LANGUAGE'] = $objPage->language;
     $locale = str_replace('-', '_', $objPage->language);
     \System::getContainer()->get('request_stack')->getCurrentRequest()->setLocale($locale);
     \System::getContainer()->get('translator')->setLocale($locale);
     \System::loadLanguageFile('default');
     // Static URLs
     $this->setStaticUrls();
     // Get the page layout
     $objLayout = $this->getPageLayout($objPage);
     // HOOK: modify the page or layout object (see #4736)
     if (isset($GLOBALS['TL_HOOKS']['getPageLayout']) && is_array($GLOBALS['TL_HOOKS']['getPageLayout'])) {
         foreach ($GLOBALS['TL_HOOKS']['getPageLayout'] as $callback) {
             $this->import($callback[0]);
             $this->{$callback}[0]->{$callback}[1]($objPage, $objLayout, $this);
         }
     }
     /** @var \ThemeModel $objTheme */
     $objTheme = $objLayout->getRelated('pid');
     // Set the layout template and template group
     $objPage->template = $objLayout->template ?: 'fe_page';
     $objPage->templateGroup = $objTheme->templates;
     // Store the output format
     list($strFormat, $strVariant) = explode('_', $objLayout->doctype);
     $objPage->outputFormat = $strFormat;
     $objPage->outputVariant = $strVariant;
     // Initialize the template
     $this->createTemplate($objPage, $objLayout);
     // Initialize modules and sections
     $arrCustomSections = array();
     $arrSections = array('header', 'left', 'right', 'main', 'footer');
     $arrModules = deserialize($objLayout->modules);
     $arrModuleIds = array();
     // Filter the disabled modules
     foreach ($arrModules as $module) {
         if ($module['enable']) {
             $arrModuleIds[] = $module['mod'];
         }
     }
     // Get all modules in a single DB query
     $objModules = \ModuleModel::findMultipleByIds($arrModuleIds);
     if ($objModules !== null || $arrModules[0]['mod'] == 0) {
         $arrMapper = array();
         // Create a mapper array in case a module is included more than once (see #4849)
         if ($objModules !== null) {
             while ($objModules->next()) {
                 $arrMapper[$objModules->id] = $objModules->current();
             }
         }
         foreach ($arrModules as $arrModule) {
             // Disabled module
             if (!$arrModule['enable']) {
                 continue;
             }
             // Replace the module ID with the module model
             if ($arrModule['mod'] > 0 && isset($arrMapper[$arrModule['mod']])) {
                 $arrModule['mod'] = $arrMapper[$arrModule['mod']];
             }
             // Generate the modules
             if (in_array($arrModule['col'], $arrSections)) {
                 // Filter active sections (see #3273)
                 if ($arrModule['col'] == 'header' && $objLayout->rows != '2rwh' && $objLayout->rows != '3rw') {
                     continue;
                 }
                 if ($arrModule['col'] == 'left' && $objLayout->cols != '2cll' && $objLayout->cols != '3cl') {
                     continue;
                 }
                 if ($arrModule['col'] == 'right' && $objLayout->cols != '2clr' && $objLayout->cols != '3cl') {
                     continue;
                 }
                 if ($arrModule['col'] == 'footer' && $objLayout->rows != '2rwf' && $objLayout->rows != '3rw') {
                     continue;
                 }
                 $this->Template->{$arrModule}['col'] .= $this->getFrontendModule($arrModule['mod'], $arrModule['col']);
             } else {
                 $arrCustomSections[$arrModule['col']] .= $this->getFrontendModule($arrModule['mod'], $arrModule['col']);
             }
         }
     }
     $this->Template->sections = $arrCustomSections;
     // Mark RTL languages (see #7171)
     if ($GLOBALS['TL_LANG']['MSC']['textDirection'] == 'rtl') {
         $this->Template->isRTL = true;
     }
     // HOOK: modify the page or layout object
     if (isset($GLOBALS['TL_HOOKS']['generatePage']) && is_array($GLOBALS['TL_HOOKS']['generatePage'])) {
         foreach ($GLOBALS['TL_HOOKS']['generatePage'] as $callback) {
             $this->import($callback[0]);
             $this->{$callback}[0]->{$callback}[1]($objPage, $objLayout, $this);
         }
     }
     // Set the page title and description AFTER the modules have been generated
     $this->Template->mainTitle = $objPage->rootPageTitle;
     $this->Template->pageTitle = $objPage->pageTitle ?: $objPage->title;
     // Meta robots tag
     $this->Template->robots = $objPage->robots ?: 'index,follow';
     // Remove shy-entities (see #2709)
     $this->Template->mainTitle = str_replace('[-]', '', $this->Template->mainTitle);
     $this->Template->pageTitle = str_replace('[-]', '', $this->Template->pageTitle);
     // Fall back to the default title tag
     if ($objLayout->titleTag == '') {
         $objLayout->titleTag = '{{page::pageTitle}} - {{page::rootPageTitle}}';
     }
     // Assign the title and description
     $this->Template->title = strip_insert_tags($this->replaceInsertTags($objLayout->titleTag));
     // see #7097
     $this->Template->description = str_replace(array("\n", "\r", '"'), array(' ', '', ''), $objPage->description);
     // Body onload and body classes
     $this->Template->onload = trim($objLayout->onload);
     $this->Template->class = trim($objLayout->cssClass . ' ' . $objPage->cssClass);
     // Execute AFTER the modules have been generated and create footer scripts first
     $this->createFooterScripts($objLayout);
     $this->createHeaderScripts($objPage, $objLayout);
 }
Exemple #29
0
    /**
     * Show header of the parent table and list all records of the current table
     *
     * @return string
     */
    protected function parentView()
    {
        /** @var SessionInterface $objSession */
        $objSession = \System::getContainer()->get('session');
        $blnClipboard = false;
        $arrClipboard = $objSession->get('CLIPBOARD');
        $table = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 6 ? $this->ptable : $this->strTable;
        $blnHasSorting = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['fields'][0] == 'sorting';
        $blnMultiboard = false;
        // Check clipboard
        if (!empty($arrClipboard[$table])) {
            $blnClipboard = true;
            $arrClipboard = $arrClipboard[$table];
            if (is_array($arrClipboard['id'])) {
                $blnMultiboard = true;
            }
        }
        // Load the fonts to display the paste hint
        \Config::set('loadGoogleFonts', $blnClipboard);
        // Load the language file and data container array of the parent table
        \System::loadLanguageFile($this->ptable);
        $this->loadDataContainer($this->ptable);
        $return = '
<div id="tl_buttons">' . (\Input::get('nb') ? '&nbsp;' : ($this->ptable ? '
<a href="' . $this->getReferer(true, $this->ptable) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a>' : (isset($GLOBALS['TL_DCA'][$this->strTable]['config']['backlink']) ? '
<a href="contao/main.php?' . $GLOBALS['TL_DCA'][$this->strTable]['config']['backlink'] . '" 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($blnHasSorting ? 'act=paste&amp;mode=create' : 'act=create&amp;mode=2&amp;pid=' . $this->intId) . '" class="header_new" title="' . specialchars($GLOBALS['TL_LANG'][$this->strTable]['new'][1]) . '" accesskey="n" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG'][$this->strTable]['new'][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);
        // Get all details of the parent record
        $objParent = $this->Database->prepare("SELECT * FROM " . $this->ptable . " WHERE id=?")->limit(1)->execute(CURRENT_ID);
        if ($objParent->numRows < 1) {
            return $return;
        }
        $return .= (\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 parent_view">

<div class="tl_header click2edit toggle_select hover-div">';
        // List all records of the child table
        if (!\Input::get('act') || \Input::get('act') == 'paste' || \Input::get('act') == 'select') {
            $this->import('BackendUser', 'User');
            // Header
            $imagePasteNew = \Image::getHtml('new.gif', $GLOBALS['TL_LANG'][$this->strTable]['pastenew'][0]);
            $imagePasteAfter = \Image::getHtml('pasteafter.gif', $GLOBALS['TL_LANG'][$this->strTable]['pasteafter'][0]);
            $imageEditHeader = \Image::getHtml('header.gif', $GLOBALS['TL_LANG'][$this->strTable]['editheader'][0]);
            $return .= '
<div class="tl_content_right">' . (\Input::get('act') == 'select' ? '
<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">' : ($blnClipboard ? ' <a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&amp;mode=2&amp;pid=' . $objParent->id . (!$blnMultiboard ? '&amp;id=' . $arrClipboard['id'] : '')) . '" title="' . specialchars($GLOBALS['TL_LANG'][$this->strTable]['pasteafter'][0]) . '" onclick="Backend.getScrollOffset()">' . $imagePasteAfter . '</a>' : (!$GLOBALS['TL_DCA'][$this->ptable]['config']['notEditable'] && $this->User->canEditFieldsOf($this->ptable) ? '
<a href="' . preg_replace('/&(amp;)?table=[^& ]*/i', $this->ptable != '' ? '&amp;table=' . $this->ptable : '', $this->addToUrl('act=edit')) . '" class="edit" title="' . specialchars(isset($GLOBALS['TL_LANG'][$this->ptable]['editmeta'][1]) ? $GLOBALS['TL_LANG'][$this->ptable]['editmeta'][1] : $GLOBALS['TL_LANG'][$this->strTable]['editheader'][1]) . '">' . $imageEditHeader . '</a>' : '') . ($blnHasSorting && !$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable'] ? ' <a href="' . $this->addToUrl('act=create&amp;mode=2&amp;pid=' . $objParent->id . '&amp;id=' . $this->intId) . '" title="' . specialchars($GLOBALS['TL_LANG'][$this->strTable]['pastenew'][0]) . '">' . $imagePasteNew . '</a>' : ''))) . '
</div>';
            // Format header fields
            $add = array();
            $headerFields = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['headerFields'];
            foreach ($headerFields as $v) {
                $_v = deserialize($objParent->{$v});
                // Translate UUIDs to paths
                if ($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['inputType'] == 'fileTree') {
                    $objFiles = \FilesModel::findMultipleByUuids((array) $_v);
                    if ($objFiles !== null) {
                        $_v = $objFiles->fetchEach('path');
                    }
                }
                if (is_array($_v)) {
                    $_v = implode(', ', $_v);
                } elseif ($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['inputType'] == 'checkbox' && !$GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['eval']['multiple']) {
                    $_v = $_v != '' ? $GLOBALS['TL_LANG']['MSC']['yes'] : $GLOBALS['TL_LANG']['MSC']['no'];
                } elseif ($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['eval']['rgxp'] == 'date') {
                    $_v = $_v ? \Date::parse(\Config::get('dateFormat'), $_v) : '-';
                } elseif ($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['eval']['rgxp'] == 'time') {
                    $_v = $_v ? \Date::parse(\Config::get('timeFormat'), $_v) : '-';
                } elseif ($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['eval']['rgxp'] == 'datim') {
                    $_v = $_v ? \Date::parse(\Config::get('datimFormat'), $_v) : '-';
                } elseif ($v == 'tstamp') {
                    if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable']) {
                        $ptable = $GLOBALS['TL_DCA'][$this->strTable]['config']['ptable'];
                        $cond = $ptable == 'tl_article' ? "(ptable=? OR ptable='')" : "ptable=?";
                        $objMaxTstamp = $this->Database->prepare("SELECT MAX(tstamp) AS tstamp FROM " . $this->strTable . " WHERE pid=? AND {$cond}")->execute($objParent->id, $ptable);
                    } else {
                        $objMaxTstamp = $this->Database->prepare("SELECT MAX(tstamp) AS tstamp FROM " . $this->strTable . " WHERE pid=?")->execute($objParent->id);
                    }
                    if (!$objMaxTstamp->tstamp) {
                        $objMaxTstamp->tstamp = $objParent->tstamp;
                    }
                    $_v = \Date::parse(\Config::get('datimFormat'), max($objParent->tstamp, $objMaxTstamp->tstamp));
                } elseif (isset($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['foreignKey'])) {
                    $arrForeignKey = explode('.', $GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['foreignKey'], 2);
                    $objLabel = $this->Database->prepare("SELECT " . $arrForeignKey[1] . " AS value FROM " . $arrForeignKey[0] . " WHERE id=?")->limit(1)->execute($_v);
                    if ($objLabel->numRows) {
                        $_v = $objLabel->value;
                    }
                } elseif (is_array($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['reference'][$_v])) {
                    $_v = $GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['reference'][$_v][0];
                } elseif (isset($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['reference'][$_v])) {
                    $_v = $GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['reference'][$_v];
                } elseif ($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['eval']['isAssociative'] || array_is_assoc($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['options'])) {
                    $_v = $GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['options'][$_v];
                } elseif (is_array($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['options_callback'])) {
                    $strClass = $GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['options_callback'][0];
                    $strMethod = $GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['options_callback'][1];
                    $this->import($strClass);
                    $options_callback = $this->{$strClass}->{$strMethod}($this);
                    $_v = $options_callback[$_v];
                } elseif (is_callable($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['options_callback'])) {
                    $options_callback = $GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['options_callback']($this);
                    $_v = $options_callback[$_v];
                }
                // Add the sorting field
                if ($_v != '') {
                    if (isset($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['label'])) {
                        $key = is_array($GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['label']) ? $GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['label'][0] : $GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['label'];
                    } else {
                        $key = isset($GLOBALS['TL_LANG'][$this->ptable][$v][0]) ? $GLOBALS['TL_LANG'][$this->ptable][$v][0] : $v;
                    }
                    $add[$key] = $_v;
                }
            }
            // Trigger the header_callback (see #3417)
            if (is_array($GLOBALS['TL_DCA'][$table]['list']['sorting']['header_callback'])) {
                $strClass = $GLOBALS['TL_DCA'][$table]['list']['sorting']['header_callback'][0];
                $strMethod = $GLOBALS['TL_DCA'][$table]['list']['sorting']['header_callback'][1];
                $this->import($strClass);
                $add = $this->{$strClass}->{$strMethod}($add, $this);
            } elseif (is_callable($GLOBALS['TL_DCA'][$table]['list']['sorting']['header_callback'])) {
                $add = $GLOBALS['TL_DCA'][$table]['list']['sorting']['header_callback']($add, $this);
            }
            // Output the header data
            $return .= '

<table class="tl_header_table">';
            foreach ($add as $k => $v) {
                if (is_array($v)) {
                    $v = $v[0];
                }
                $return .= '
  <tr>
    <td><span class="tl_label">' . $k . ':</span> </td>
    <td>' . $v . '</td>
  </tr>';
            }
            $return .= '
</table>
</div>';
            $orderBy = array();
            $firstOrderBy = array();
            // Add all records of the current table
            $query = "SELECT * FROM " . $this->strTable;
            if (is_array($this->orderBy) && strlen($this->orderBy[0])) {
                $orderBy = $this->orderBy;
                $firstOrderBy = preg_replace('/\\s+.*$/', '', $orderBy[0]);
                // Order by the foreign key
                if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$firstOrderBy]['foreignKey'])) {
                    $key = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$firstOrderBy]['foreignKey'], 2);
                    $query = "SELECT *, (SELECT " . $key[1] . " FROM " . $key[0] . " WHERE " . $this->strTable . "." . $firstOrderBy . "=" . $key[0] . ".id) AS foreignKey FROM " . $this->strTable;
                    $orderBy[0] = 'foreignKey';
                }
            } elseif (is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['fields'])) {
                $orderBy = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['fields'];
                $firstOrderBy = preg_replace('/\\s+.*$/', '', $orderBy[0]);
            }
            $arrProcedure = $this->procedure;
            $arrValues = $this->values;
            // Support empty ptable fields
            if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable']) {
                $arrProcedure[] = $this->ptable == 'tl_article' ? "(ptable=? OR ptable='')" : "ptable=?";
                $arrValues[] = $this->ptable;
            }
            // WHERE
            if (!empty($arrProcedure)) {
                $query .= " WHERE " . implode(' AND ', $arrProcedure);
            }
            if (!empty($this->root) && is_array($this->root)) {
                $query .= (!empty($arrProcedure) ? " AND " : " WHERE ") . "id IN(" . implode(',', array_map('intval', $this->root)) . ")";
            }
            // ORDER BY
            if (!empty($orderBy) && is_array($orderBy)) {
                $query .= " ORDER BY " . implode(', ', $orderBy);
            }
            $objOrderByStmt = $this->Database->prepare($query);
            // LIMIT
            if (strlen($this->limit)) {
                $arrLimit = explode(',', $this->limit);
                $objOrderByStmt->limit($arrLimit[1], $arrLimit[0]);
            }
            $objOrderBy = $objOrderByStmt->execute($arrValues);
            if ($objOrderBy->numRows < 1) {
                return $return . '
<p class="tl_empty_parent_view">' . $GLOBALS['TL_LANG']['MSC']['noResult'] . '</p>

</div>';
            }
            // Call the child_record_callback
            if (is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['child_record_callback']) || is_callable($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['child_record_callback'])) {
                $strGroup = '';
                $blnIndent = false;
                $intWrapLevel = 0;
                $row = $objOrderBy->fetchAllAssoc();
                // Make items sortable
                if ($blnHasSorting) {
                    $return .= '

<ul id="ul_' . CURRENT_ID . '">';
                }
                for ($i = 0, $c = count($row); $i < $c; $i++) {
                    $this->current[] = $row[$i]['id'];
                    $imagePasteAfter = \Image::getHtml('pasteafter.gif', sprintf($GLOBALS['TL_LANG'][$this->strTable]['pasteafter'][1], $row[$i]['id']));
                    $imagePasteNew = \Image::getHtml('new.gif', sprintf($GLOBALS['TL_LANG'][$this->strTable]['pastenew'][1], $row[$i]['id']));
                    // Decrypt encrypted value
                    foreach ($row[$i] as $k => $v) {
                        if ($GLOBALS['TL_DCA'][$table]['fields'][$k]['eval']['encrypt']) {
                            $row[$i][$k] = \Encryption::decrypt(deserialize($v));
                        }
                    }
                    // Make items sortable
                    if ($blnHasSorting) {
                        $return .= '
<li id="li_' . $row[$i]['id'] . '">';
                    }
                    // Add the group header
                    if (!$GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['disableGrouping'] && $firstOrderBy != 'sorting') {
                        $sortingMode = count($orderBy) == 1 && $firstOrderBy == $orderBy[0] && $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['flag'] != '' && $GLOBALS['TL_DCA'][$this->strTable]['fields'][$firstOrderBy]['flag'] == '' ? $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['flag'] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$firstOrderBy]['flag'];
                        $remoteNew = $this->formatCurrentValue($firstOrderBy, $row[$i][$firstOrderBy], $sortingMode);
                        $group = $this->formatGroupHeader($firstOrderBy, $remoteNew, $sortingMode, $row);
                        if ($group != $strGroup) {
                            $return .= "\n\n" . '<div class="tl_content_header">' . $group . '</div>';
                            $strGroup = $group;
                        }
                    }
                    $blnWrapperStart = in_array($row[$i]['type'], $GLOBALS['TL_WRAPPERS']['start']);
                    $blnWrapperSeparator = in_array($row[$i]['type'], $GLOBALS['TL_WRAPPERS']['separator']);
                    $blnWrapperStop = in_array($row[$i]['type'], $GLOBALS['TL_WRAPPERS']['stop']);
                    // Closing wrappers
                    if ($blnWrapperStop) {
                        if (--$intWrapLevel < 1) {
                            $blnIndent = false;
                        }
                    }
                    $return .= '

<div class="tl_content' . ($blnWrapperStart ? ' wrapper_start' : '') . ($blnWrapperSeparator ? ' wrapper_separator' : '') . ($blnWrapperStop ? ' wrapper_stop' : '') . ($blnIndent ? ' indent indent_' . $intWrapLevel : '') . ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['child_record_class'] != '' ? ' ' . $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['child_record_class'] : '') . ($i % 2 == 0 ? ' even' : ' odd') . ' click2edit toggle_select hover-div">
<div class="tl_content_right">';
                    // Opening wrappers
                    if ($blnWrapperStart) {
                        if (++$intWrapLevel > 0) {
                            $blnIndent = true;
                        }
                    }
                    // Edit multiple
                    if (\Input::get('act') == 'select') {
                        $return .= '<input type="checkbox" name="IDS[]" id="ids_' . $row[$i]['id'] . '" class="tl_tree_checkbox" value="' . $row[$i]['id'] . '">';
                    } else {
                        $return .= $this->generateButtons($row[$i], $this->strTable, $this->root, false, null, $row[$i - 1]['id'], $row[$i + 1]['id']);
                        // Sortable table
                        if ($blnHasSorting) {
                            // Create new button
                            if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable']) {
                                $return .= ' <a href="' . $this->addToUrl('act=create&amp;mode=1&amp;pid=' . $row[$i]['id'] . '&amp;id=' . $objParent->id) . '" title="' . specialchars(sprintf($GLOBALS['TL_LANG'][$this->strTable]['pastenew'][1], $row[$i]['id'])) . '">' . $imagePasteNew . '</a>';
                            }
                            // Prevent circular references
                            if ($blnClipboard && $arrClipboard['mode'] == 'cut' && $row[$i]['id'] == $arrClipboard['id'] || $blnMultiboard && $arrClipboard['mode'] == 'cutAll' && in_array($row[$i]['id'], $arrClipboard['id'])) {
                                $return .= ' ' . \Image::getHtml('pasteafter_.gif');
                            } elseif ($blnMultiboard) {
                                $return .= ' <a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&amp;mode=1&amp;pid=' . $row[$i]['id']) . '" title="' . specialchars(sprintf($GLOBALS['TL_LANG'][$this->strTable]['pasteafter'][1], $row[$i]['id'])) . '" onclick="Backend.getScrollOffset()">' . $imagePasteAfter . '</a>';
                            } elseif ($blnClipboard) {
                                $return .= ' <a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&amp;mode=1&amp;pid=' . $row[$i]['id'] . '&amp;id=' . $arrClipboard['id']) . '" title="' . specialchars(sprintf($GLOBALS['TL_LANG'][$this->strTable]['pasteafter'][1], $row[$i]['id'])) . '" onclick="Backend.getScrollOffset()">' . $imagePasteAfter . '</a>';
                            }
                            // Drag handle
                            if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notSortable']) {
                                $return .= ' ' . \Image::getHtml('drag.gif', '', 'class="drag-handle" title="' . sprintf($GLOBALS['TL_LANG'][$this->strTable]['cut'][1], $row[$i]['id']) . '"');
                            }
                        }
                    }
                    if (is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['child_record_callback'])) {
                        $strClass = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['child_record_callback'][0];
                        $strMethod = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['child_record_callback'][1];
                        $this->import($strClass);
                        $return .= '</div>' . $this->{$strClass}->{$strMethod}($row[$i]) . '</div>';
                    } elseif (is_callable($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['child_record_callback'])) {
                        $return .= '</div>' . $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['child_record_callback']($row[$i]) . '</div>';
                    }
                    // Make items sortable
                    if ($blnHasSorting) {
                        $return .= '

</li>';
                    }
                }
            }
        }
        // Make items sortable
        if ($blnHasSorting && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notSortable'] && \Input::get('act') != 'select') {
            $return .= '
</ul>

<script>
  Backend.makeParentViewSortable("ul_' . CURRENT_ID . '");
</script>';
        }
        $return .= '

</div>';
        // Close 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']['delAllConfirm'] . '\')">' . $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['override'] = '<button type="submit" name="override" id="override" class="tl_submit" accesskey="v">' . $GLOBALS['TL_LANG']['MSC']['overrideSelected'] . '</button>';
                $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;
    }
 /**
  * Run the tests on a table
  *
  * @param string $table
  * @param Result $records
  *
  * @return array
  */
 protected function runTests($table, Result $records)
 {
     System::loadLanguageFile('seo_serp_tests');
     $result = ['errors' => 0, 'warnings' => 0];
     /** @var TestInterface $test */
     foreach (TestsManager::getAll() as $test) {
         // Skip the unsupported tests
         if (!$test->supports($table)) {
             continue;
         }
         while ($records->next()) {
             try {
                 $test->run($records->row(), $table);
             } catch (ErrorException $e) {
                 $result['errors']++;
             } catch (WarningException $e) {
                 $result['warnings']++;
             }
         }
         $records->reset();
     }
     return $result;
 }