/** * Generate the module */ protected function compile() { \System::loadLanguageFile('tl_autoload'); // Process the request if (\Input::post('FORM_SUBMIT') == 'tl_autoload') { $this->createAutoloadFiles(); $this->reload(); } $arrModules = array(); // List all modules foreach (scan(TL_ROOT . '/system/modules') as $strFile) { if (strncmp($strFile, '.', 1) === 0 || !is_dir(TL_ROOT . '/system/modules/' . $strFile)) { continue; } $arrModules[] = $strFile; } $this->Template->modules = $arrModules; $this->Template->messages = \Message::generate(); $this->Template->href = $this->getReferer(true); $this->Template->title = specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']); $this->Template->button = $GLOBALS['TL_LANG']['MSC']['backBT']; $this->Template->headline = $GLOBALS['TL_LANG']['tl_autoload']['headline']; $this->Template->action = ampersand(\Environment::get('request')); $this->Template->available = $GLOBALS['TL_LANG']['tl_autoload']['available']; $this->Template->xplAvailable = $GLOBALS['TL_LANG']['tl_autoload']['xplAvailable']; $this->Template->selectAll = $GLOBALS['TL_LANG']['MSC']['selectAll']; $this->Template->override = $GLOBALS['TL_LANG']['tl_autoload']['override']; $this->Template->xplOverride = $GLOBALS['TL_LANG']['tl_autoload']['xplOverride']; $this->Template->submitButton = specialchars($GLOBALS['TL_LANG']['MSC']['continue']); $this->Template->autoload = $GLOBALS['TL_LANG']['tl_autoload']['autoload']; $this->Template->ideCompat = $GLOBALS['TL_LANG']['tl_autoload']['ideCompat']; }
/** * Generate module */ protected function compile() { // Create files if (\Input::post('FORM_SUBMIT') == 'tl_newsport') { $objModel = NewsportConfigModel::findByPk($this->objDc->id); if ($objModel === null) { return; } $importer = new NewsImporter($objModel); if ($importer->run()) { // Confirm and reload \Message::addConfirmation($GLOBALS['TL_LANG']['tl_newsport_config']['confirm']); $this->reload(); } } $this->Template->base = \Environment::get('base'); $this->Template->href = $this->getReferer(true); $this->Template->title = specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']); $this->Template->action = ampersand(\Environment::get('request')); $this->Template->selectAll = $GLOBALS['TL_LANG']['MSC']['selectAll']; $this->Template->button = $GLOBALS['TL_LANG']['MSC']['backBT']; $this->Template->message = \Message::generate(); $this->Template->submit = specialchars($GLOBALS['TL_LANG']['tl_newsport_config']['import'][0]); $this->Template->headline = sprintf($GLOBALS['TL_LANG']['tl_newsport_config']['headline'], \Input::get('id')); $this->Template->explain = $GLOBALS['TL_LANG']['tl_newsport_config']['make'][1]; $this->Template->label = $GLOBALS['TL_LANG']['tl_newsport_config']['label']; }
/** * Run the controller and parse the login template */ public function run() { $this->Template = new BackendTemplate('be_login'); // Show a cookie warning if (Input::get('referer', true) != '' && empty($_COOKIE)) { $this->Template->noCookies = $GLOBALS['TL_LANG']['MSC']['noCookies']; } $strHeadline = sprintf($GLOBALS['TL_LANG']['MSC']['loginTo'], Config::get('websiteTitle')); $this->Template->theme = Backend::getTheme(); $this->Template->messages = Message::generate(); $this->Template->base = Environment::get('base'); $this->Template->language = $GLOBALS['TL_LANGUAGE']; $this->Template->languages = System::getLanguages(true); $this->Template->title = specialchars($strHeadline); $this->Template->charset = Config::get('characterSet'); $this->Template->action = ampersand(Environment::get('request')); $this->Template->userLanguage = $GLOBALS['TL_LANG']['tl_user']['language'][0]; $this->Template->headline = $strHeadline; $this->Template->curLanguage = Input::post('language') ?: str_replace('-', '_', $GLOBALS['TL_LANGUAGE']); $this->Template->curUsername = Input::post('username') ?: ''; $this->Template->uClass = $_POST && empty($_POST['username']) ? ' class="login_error"' : ''; $this->Template->pClass = $_POST && empty($_POST['password']) ? ' class="login_error"' : ''; $this->Template->loginButton = specialchars($GLOBALS['TL_LANG']['MSC']['loginBT']); $this->Template->username = $GLOBALS['TL_LANG']['tl_user']['username'][0]; $this->Template->password = $GLOBALS['TL_LANG']['MSC']['password'][0]; $this->Template->feLink = $GLOBALS['TL_LANG']['MSC']['feLink']; $this->Template->frontendFile = Environment::get('base'); $this->Template->disableCron = Config::get('disableCron'); $this->Template->ie6warning = sprintf($GLOBALS['TL_LANG']['ERR']['ie6warning'], '<a href="http://ie6countdown.com">', '</a>'); $this->Template->default = $GLOBALS['TL_LANG']['MSC']['default']; $this->Template->output(); }
/** * Display a wildcard in the back end * @return string */ public function generate() { if (TL_MODE == 'BE') { $objTemplate = new \BackendTemplate('be_wildcard'); $objTemplate->wildcard = '### ' . utf8_strtoupper($GLOBALS['TL_LANG']['FMD']['facebook_login'][0]) . ' ###'; $objTemplate->title = $this->headline; $objTemplate->id = $this->id; $objTemplate->link = $this->name; $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id; return $objTemplate->parse(); } // Return if a front end user is logged in if (FE_USER_LOGGED_IN) { return ''; } // Execute the login if (\Input::get('fblogin')) { if ($this->loginWithFacebook()) { $this->jumpToOrReload($this->jumpTo); } else { $_SESSION['FACEBOOK_LOGIN'] = \Message::generate(); $this->redirect(preg_replace('/(\\?|&)fblogin=1/', '', \Environment::get('request'))); } } return parent::generate(); }
/** * Run the controller and parse the password template */ public function run() { /** @var \BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_password'); if (\Input::post('FORM_SUBMIT') == 'tl_password') { $pw = \Input::postUnsafeRaw('password'); $cnf = \Input::postUnsafeRaw('confirm'); // The passwords do not match if ($pw != $cnf) { \Message::addError($GLOBALS['TL_LANG']['ERR']['passwordMatch']); } elseif (utf8_strlen($pw) < \Config::get('minPasswordLength')) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['passwordLength'], \Config::get('minPasswordLength'))); } elseif ($pw == $this->User->username) { \Message::addError($GLOBALS['TL_LANG']['ERR']['passwordName']); } else { // Make sure the password has been changed if (\Encryption::verify($pw, $this->User->password)) { \Message::addError($GLOBALS['TL_LANG']['MSC']['pw_change']); } else { $this->loadDataContainer('tl_user'); // Trigger the save_callback if (is_array($GLOBALS['TL_DCA']['tl_user']['fields']['password']['save_callback'])) { foreach ($GLOBALS['TL_DCA']['tl_user']['fields']['password']['save_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $pw = $this->{$callback[0]}->{$callback[1]}($pw); } elseif (is_callable($callback)) { $pw = $callback($pw); } } } $objUser = \UserModel::findByPk($this->User->id); $objUser->pwChange = ''; $objUser->password = \Encryption::hash($pw); $objUser->save(); \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['pw_changed']); $this->redirect('' . $GLOBALS['TL_CONFIG']['backendPath'] . '/main.php'); } } $this->reload(); } $objTemplate->theme = \Backend::getTheme(); $objTemplate->messages = \Message::generate(); $objTemplate->base = \Environment::get('base'); $objTemplate->language = $GLOBALS['TL_LANGUAGE']; $objTemplate->title = specialchars($GLOBALS['TL_LANG']['MSC']['pw_new']); $objTemplate->charset = \Config::get('characterSet'); $objTemplate->action = ampersand(\Environment::get('request')); $objTemplate->headline = $GLOBALS['TL_LANG']['MSC']['pw_change']; $objTemplate->submitButton = specialchars($GLOBALS['TL_LANG']['MSC']['continue']); $objTemplate->password = $GLOBALS['TL_LANG']['MSC']['password'][0]; $objTemplate->confirm = $GLOBALS['TL_LANG']['MSC']['confirm'][0]; $objTemplate->output(); }
/** * Run the controller and parse the password template */ public function run() { $this->Template = new BackendTemplate('be_password'); if (Input::post('FORM_SUBMIT') == 'tl_password') { $pw = Input::post('password'); $cnf = Input::post('confirm'); // Do not allow special characters if (preg_match('/[#\\(\\)\\/<=>]/', html_entity_decode(Input::post('password')))) { Message::addError($GLOBALS['TL_LANG']['ERR']['extnd']); } elseif ($pw != $cnf) { Message::addError($GLOBALS['TL_LANG']['ERR']['passwordMatch']); } elseif (utf8_strlen($pw) < $GLOBALS['TL_CONFIG']['minPasswordLength']) { Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['passwordLength'], $GLOBALS['TL_CONFIG']['minPasswordLength'])); } elseif ($pw == $this->User->username) { Message::addError($GLOBALS['TL_LANG']['ERR']['passwordName']); } else { list(, $strSalt) = explode(':', $this->User->password); $strPassword = sha1($strSalt . $pw); // Make sure the password has been changed if ($strPassword . ':' . $strSalt == $this->User->password) { Message::addError($GLOBALS['TL_LANG']['MSC']['pw_change']); } else { $strSalt = substr(md5(uniqid(mt_rand(), true)), 0, 23); $strPassword = sha1($strSalt . $pw); $objUser = UserModel::findByPk($this->User->id); $objUser->pwChange = ''; $objUser->password = $strPassword . ':' . $strSalt; $objUser->save(); Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['pw_changed']); $this->redirect('contao/main.php'); } } $this->reload(); } $this->Template->theme = $this->getTheme(); $this->Template->messages = Message::generate(); $this->Template->base = Environment::get('base'); $this->Template->language = $GLOBALS['TL_LANGUAGE']; $this->Template->title = specialchars($GLOBALS['TL_LANG']['MSC']['pw_new']); $this->Template->charset = $GLOBALS['TL_CONFIG']['characterSet']; $this->Template->action = ampersand(Environment::get('request')); $this->Template->headline = $GLOBALS['TL_LANG']['MSC']['pw_change']; $this->Template->submitButton = specialchars($GLOBALS['TL_LANG']['MSC']['continue']); $this->Template->password = $GLOBALS['TL_LANG']['MSC']['password'][0]; $this->Template->confirm = $GLOBALS['TL_LANG']['MSC']['confirm'][0]; $this->Template->output(); }
/** * Generate the module * * @return string */ public function run() { $template = new \BackendTemplate('be_css_class_replacer_update'); $template->isActive = $this->isActive(); $template->action = ampersand(\Environment::get('request')); $template->message = \Message::generate(); $template->headline = specialchars($GLOBALS['TL_LANG']['tl_maintenance']['css-class-replacer-headline']); $template->description = specialchars($GLOBALS['TL_LANG']['tl_maintenance']['css-class-replacer-description']); $template->submit = specialchars($GLOBALS['TL_LANG']['tl_maintenance']['css-class-replacer-submit']); if ($this->isActive()) { $rules = RuleModel::findAll(); $helper = new BackendHelper(); $helper->updateCacheableValues($rules); \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_maintenance']['css-class-replacer-message'], $rules->count())); \Controller::reload(); } return $template->parse(); }
/** * Imports rules from XML * * @param \DataContainer $dc * @return string */ public function import(\DataContainer $dc) { $class = \BackendUser::getInstance()->uploader; if (!class_exists($class) || $class == 'DropZone') { $class = 'FileUpload'; } $uploader = new $class(); if (\Input::post('FORM_SUBMIT') == 'css_class_replacer_import') { $uploaded = $uploader->uploadTo('system/tmp'); foreach ($uploaded as $file) { $this->importRuleSet($file, $dc->id); } // Let's be nice and update the cache automatically $rules = RuleModel::findAll(); $helper = new BackendHelper(); $helper->updateCacheableValues($rules); } // Return the form return ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=importCssClassReplacerRules', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="css_class_replacer_import" class="tl_form" method="post" enctype="multipart/form-data"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="css_class_replacer_import"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <div class="tl_tbox"> <h3>' . $GLOBALS['TL_LANG']['tl_css_class_replacer']['source'][0] . '</h3>' . $uploader->generateMarkup() . (isset($GLOBALS['TL_LANG']['tl_css_class_replacer']['source'][1]) ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_css_class_replacer']['source'][1] . '</p>' : '') . ' </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_css_class_replacer']['import'][0]) . '"> </div> </div> </form>'; }
/** * Import images and other media file for products * * @return string */ public function generate() { $objTree = new \FileTree(\FileTree::getAttributesFromDca($GLOBALS['TL_DCA']['tl_iso_product']['fields']['source'], 'source', null, 'source', 'tl_iso_product')); // Import assets if (\Input::post('FORM_SUBMIT') == 'tl_iso_product_import' && \Input::post('source') != '') { $objFolder = \FilesModel::findByUuid(\StringUtil::uuidToBin(\Input::post('source'))); if (null !== $objFolder) { $this->importFromPath($objFolder->path); } } // Return form return ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=import', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBT']) . '">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> <h2 class="sub_headline">' . $GLOBALS['TL_LANG']['tl_iso_product']['import'][1] . '</h2> <div class="tl_message"><div class="tl_info">' . $GLOBALS['TL_LANG']['tl_iso_product']['importAssetsDescr'] . '</div></div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_iso_product_import" class="tl_form" method="post"> <div class="tl_formbody_edit iso_importassets"> <input type="hidden" name="FORM_SUBMIT" value="tl_iso_product_import"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <div class="tl_tbox block"> <h3><label for="source">' . $GLOBALS['TL_LANG']['tl_iso_product']['source'][0] . '</label></h3> ' . $objTree->generate() . (strlen($GLOBALS['TL_LANG']['tl_iso_product']['source'][1]) ? ' <p class="tl_help">' . $GLOBALS['TL_LANG']['tl_iso_product']['source'][1] . '</p>' : '') . ' </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" alt="import product assets" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_iso_product']['import'][0]) . '"> </div> </div> </form>'; }
/** * Run the controller and parse the password template */ public function run() { $this->Template = new BackendTemplate('be_password'); if (Input::post('FORM_SUBMIT') == 'tl_password') { $pw = Input::post('password', true); $cnf = Input::post('confirm', true); // The passwords do not match if ($pw != $cnf) { Message::addError($GLOBALS['TL_LANG']['ERR']['passwordMatch']); } elseif (utf8_strlen($pw) < $GLOBALS['TL_CONFIG']['minPasswordLength']) { Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['passwordLength'], $GLOBALS['TL_CONFIG']['minPasswordLength'])); } elseif ($pw == $this->User->username) { Message::addError($GLOBALS['TL_LANG']['ERR']['passwordName']); } else { // Make sure the password has been changed if (crypt($pw, $this->User->password) == $this->User->password) { Message::addError($GLOBALS['TL_LANG']['MSC']['pw_change']); } else { $objUser = UserModel::findByPk($this->User->id); $objUser->pwChange = ''; $objUser->password = Encryption::hash($pw); $objUser->save(); Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['pw_changed']); $this->redirect('contao/main.php'); } } $this->reload(); } $this->Template->theme = $this->getTheme(); $this->Template->messages = Message::generate(); $this->Template->base = Environment::get('base'); $this->Template->language = $GLOBALS['TL_LANGUAGE']; $this->Template->title = specialchars($GLOBALS['TL_LANG']['MSC']['pw_new']); $this->Template->charset = $GLOBALS['TL_CONFIG']['characterSet']; $this->Template->action = ampersand(Environment::get('request')); $this->Template->headline = $GLOBALS['TL_LANG']['MSC']['pw_change']; $this->Template->submitButton = specialchars($GLOBALS['TL_LANG']['MSC']['continue']); $this->Template->password = $GLOBALS['TL_LANG']['MSC']['password'][0]; $this->Template->confirm = $GLOBALS['TL_LANG']['MSC']['confirm'][0]; $this->Template->output(); }
/** * @param \NotificationCenter\Model\Notification[] $notifications * @param int[] $ids * * @return string */ public static function generateForm(array $notifications, array $ids) { $return = ' <div id="tl_buttons"> <a href="' . \System::getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> <h2 class="sub_headline">' . $GLOBALS['TL_LANG']['tl_lead']['notification'][0] . '</h2> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_leads_notification" class="tl_form" method="post"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_leads_notification"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="IDS[]" value="' . implode('"> <input type="hidden" name="IDS[]" value="', $ids) . '"> <div class="tl_tbox"> <h3><label for="notification">' . $GLOBALS['TL_LANG']['tl_lead']['notification_list'][0] . '</label></h3> <select name="notification" id="notification" class="tl_select">'; // Generate options foreach ($notifications as $id => $name) { $return .= '<option value="' . $id . '">' . $name . '</option>'; } $return .= ' </select> <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_lead']['notification_list'][1] . '</p> </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_lead']['notification'][0]) . '"> </div> </div> </form>'; return $return; }
/** * Generate module */ protected function compile() { // Create files if (\Input::post('FORM_SUBMIT') == 'tl_entity_import') { $objModel = EntityImportConfigModel::findByPk($this->objDc->id); if ($objModel === null) { return; } if (class_exists($objModel->importerClass)) { // use a particular importer (e.g. NewsImporter) \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_entity_import_config']['importerInfo'], $objModel->importerClass)); $importer = new $objModel->importerClass($objModel); } else { \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_entity_import_config']['importerInfo'], 'Importer')); $importer = new Importer($objModel); } if ($importer->run(\Input::post('dry-run'))) { // Confirm and reload $strMessage = $GLOBALS['TL_LANG']['tl_entity_import_config']['confirm']; if (\Input::post('dry-run')) { $strMessage = $GLOBALS['TL_LANG']['tl_entity_import_config']['confirmDry']; } \Message::addConfirmation($strMessage); \Controller::reload(); } } $this->Template->base = \Environment::get('base'); $this->Template->href = \Controller::getReferer(true); $this->Template->title = specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']); $this->Template->action = ampersand(\Environment::get('request')); $this->Template->selectAll = $GLOBALS['TL_LANG']['MSC']['selectAll']; $this->Template->button = $GLOBALS['TL_LANG']['MSC']['backBT']; $this->Template->message = \Message::generate(); $this->Template->submit = specialchars($GLOBALS['TL_LANG']['tl_entity_import_config']['import'][0]); $this->Template->dryRun = specialchars($GLOBALS['TL_LANG']['tl_entity_import_config']['dryRun'][0]); $this->Template->headline = sprintf($GLOBALS['TL_LANG']['tl_entity_import_config']['headline'], \Input::get('id')); $this->Template->explain = $GLOBALS['TL_LANG']['tl_entity_import_config']['make'][1]; $this->Template->label = $GLOBALS['TL_LANG']['tl_entity_import_config']['label']; }
public function importExt() { $this->loadLanguageFile("tl_calendar_events"); $this->Template = new BackendTemplate('be_importExt_calendar'); $this->Template->headline = 'Test'; $this->Template->message = \Message::generate(); $this->Template->event_type = $this->getEventTypeWidget(); $this->Template->hrefBack = ampersand(str_replace('&key=import', '', \Environment::get('request'))); $this->Template->goBack = $GLOBALS['TL_LANG']['MSC']['goBack']; $this->Template->headline = $GLOBALS['TL_LANG']['MSC']['import_calendar'][0]; $this->Template->request = ampersand(\Environment::get('request'), ENCODE_AMPERSANDS); $this->Template->submit = specialchars($GLOBALS['TL_LANG']['tl_calendar_events']['importExt'][0]); if (\Input::post('FORM_SUBMIT') == 'tl_importExt_calendar') { if (empty(\Input::post('event_type'))) { \Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); $this->reload(); } else { $this->Session->set('event_type', \Input::post('event_type')); $this->redirect(str_replace('&key=importExt', '&key=import', \Environment::get('request'))); } } return $this->Template->parse(); }
/** * Renturn a form to choose an existing style sheet and import it * @param \DataContainer * @return string */ public function send(\DataContainer $objDc) { if (TL_MODE == 'BE') { $GLOBALS['TL_CSS'][] = 'system/modules/newsletter_content/assets/css/style.css'; if ($this->isFlexible) { $GLOBALS['TL_CSS'][] = 'system/modules/newsletter_content/assets/css/style-flexible.css'; } } $objNewsletter = $this->Database->prepare("SELECT n.*, c.useSMTP, c.smtpHost, c.smtpPort, c.smtpUser, c.smtpPass FROM tl_newsletter n LEFT JOIN tl_newsletter_channel c ON n.pid=c.id WHERE n.id=?")->limit(1)->execute($objDc->id); // Return if there is no newsletter if ($objNewsletter->numRows < 1) { return ''; } // Overwrite the SMTP configuration if ($objNewsletter->useSMTP) { $GLOBALS['TL_CONFIG']['useSMTP'] = true; $GLOBALS['TL_CONFIG']['smtpHost'] = $objNewsletter->smtpHost; $GLOBALS['TL_CONFIG']['smtpUser'] = $objNewsletter->smtpUser; $GLOBALS['TL_CONFIG']['smtpPass'] = $objNewsletter->smtpPass; $GLOBALS['TL_CONFIG']['smtpEnc'] = $objNewsletter->smtpEnc; $GLOBALS['TL_CONFIG']['smtpPort'] = $objNewsletter->smtpPort; } // Add default sender address if ($objNewsletter->sender == '') { list($objNewsletter->senderName, $objNewsletter->sender) = \String::splitFriendlyEmail($GLOBALS['TL_CONFIG']['adminEmail']); } $arrAttachments = array(); $blnAttachmentsFormatError = false; // Add attachments if ($objNewsletter->addFile) { $files = deserialize($objNewsletter->files); if (!empty($files) && is_array($files)) { $objFiles = \FilesModel::findMultipleByUuids($files); if ($objFiles === null) { if (!\Validator::isUuid($files[0])) { $blnAttachmentsFormatError = true; \Message::addError($GLOBALS['TL_LANG']['ERR']['version2format']); } } else { while ($objFiles->next()) { if (is_file(TL_ROOT . '/' . $objFiles->path)) { $arrAttachments[] = $objFiles->path; } } } } } // Get content $html = ''; $objContentElements = \ContentModel::findPublishedByPidAndTable($objNewsletter->id, 'tl_newsletter'); if ($objContentElements !== null) { if (!defined('NEWSLETTER_CONTENT_PREVIEW')) { define('NEWSLETTER_CONTENT_PREVIEW', true); } while ($objContentElements->next()) { $html .= $this->getContentElement($objContentElements->id); } } // Replace insert tags $text = $this->replaceInsertTags($objNewsletter->text); $html = $this->replaceInsertTags($html); // Convert relative URLs $html = $this->convertRelativeUrls($html); // Set back to object $objNewsletter->content = $html; // Send newsletter if (!$blnAttachmentsFormatError && \Input::get('token') != '' && \Input::get('token') == $this->Session->get('tl_newsletter_send')) { $referer = preg_replace('/&(amp;)?(start|mpc|token|recipient|preview)=[^&]*/', '', \Environment::get('request')); // Preview if (isset($_GET['preview'])) { // Check the e-mail address if (!\Validator::isEmail(\Input::get('recipient', true))) { $_SESSION['TL_PREVIEW_MAIL_ERROR'] = true; $this->redirect($referer); } // get preview recipient $arrRecipient = array(); $strEmail = urldecode(\Input::get('recipient', true)); $objRecipient = $this->Database->prepare("SELECT * FROM tl_member m WHERE email=? ORDER BY email")->limit(1)->execute($strEmail); if ($objRecipient->num_rows < 1) { $arrRecipient['email'] = $strEmail; } else { $arrRecipient = $objRecipient->row(); } $arrRecipient = array_merge($arrRecipient, array('extra' => '&preview=1', 'tracker_png' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $strEmail . '&preview=1&t=png', 'tracker_gif' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $strEmail . '&preview=1&t=gif', 'tracker_css' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $strEmail . '&preview=1&t=css', 'tracker_js' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $strEmail . '&preview=1&t=js')); // Send $objEmail = $this->generateEmailObject($objNewsletter, $arrAttachments); $objNewsletter->email = $strEmail; $this->sendNewsletter($objEmail, $objNewsletter, $arrRecipient, $text, $html); // Redirect \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_newsletter']['confirm'], 1)); $this->redirect($referer); } // Get the total number of recipients $objTotal = $this->Database->prepare("SELECT COUNT(DISTINCT email) AS count FROM tl_newsletter_recipients WHERE pid=? AND active=1")->execute($objNewsletter->pid); // Return if there are no recipients if ($objTotal->count < 1) { $this->Session->set('tl_newsletter_send', null); \Message::addError($GLOBALS['TL_LANG']['tl_newsletter']['error']); $this->redirect($referer); } $intTotal = $objTotal->count; // Get page and timeout $intTimeout = \Input::get('timeout') > 0 ? \Input::get('timeout') : 1; $intStart = \Input::get('start') ? \Input::get('start') : 0; $intPages = \Input::get('mpc') ? \Input::get('mpc') : 10; // Get recipients $objRecipients = $this->Database->prepare("SELECT *, r.email FROM tl_newsletter_recipients r LEFT JOIN tl_member m ON(r.email=m.email) WHERE r.pid=? AND r.active=1 GROUP BY r.email ORDER BY r.email")->limit($intPages, $intStart)->execute($objNewsletter->pid); echo '<div style="font-family:Verdana,sans-serif;font-size:11px;line-height:16px;margin-bottom:12px">'; // Send newsletter if ($objRecipients->numRows > 0) { // Update status if ($intStart == 0) { $this->Database->prepare("UPDATE tl_newsletter SET sent=1, date=? WHERE id=?")->execute(time(), $objNewsletter->id); $_SESSION['REJECTED_RECIPIENTS'] = array(); } while ($objRecipients->next()) { $objEmail = $this->generateEmailObject($objNewsletter, $arrAttachments); $objNewsletter->email = $objRecipients->email; $arrRecipient = array_merge($objRecipients->row(), array('tracker_png' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $objRecipients->email . '&t=png', 'tracker_gif' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $objRecipients->email . '&t=gif', 'tracker_css' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $objRecipients->email . '&t=css', 'tracker_js' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $objRecipients->email . '&t=js')); $this->sendNewsletter($objEmail, $objNewsletter, $arrRecipient, $text, $html); echo 'Sending newsletter to <strong>' . $objRecipients->email . '</strong><br>'; } } echo '<div style="margin-top:12px">'; // Redirect back home if ($objRecipients->numRows < 1 || $intStart + $intPages >= $intTotal) { $this->Session->set('tl_newsletter_send', null); // Deactivate rejected addresses if (!empty($_SESSION['REJECTED_RECIPIENTS'])) { $intRejected = count($_SESSION['REJECTED_RECIPIENTS']); \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_newsletter']['rejected'], $intRejected)); $intTotal -= $intRejected; foreach ($_SESSION['REJECTED_RECIPIENTS'] as $strRecipient) { $this->Database->prepare("UPDATE tl_newsletter_recipients SET active='' WHERE email=?")->execute($strRecipient); $this->log('Recipient address "' . $strRecipient . '" was rejected and has been deactivated', __METHOD__, TL_ERROR); } } $this->Database->prepare("UPDATE tl_newsletter SET recipients=?, rejected=? WHERE id=?")->execute($intTotal, $intRejected, $objNewsletter->id); \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_newsletter']['confirm'], $intTotal)); echo '<script>setTimeout(\'window.location="' . \Environment::get('base') . $referer . '"\',1000)</script>'; echo '<a href="' . \Environment::get('base') . $referer . '">Please click here to proceed if you are not using JavaScript</a>'; } else { $url = preg_replace('/&(amp;)?(start|mpc|recipient)=[^&]*/', '', \Environment::get('request')) . '&start=' . ($intStart + $intPages) . '&mpc=' . $intPages; echo '<script>setTimeout(\'window.location="' . \Environment::get('base') . $url . '"\',' . $intTimeout * 1000 . ')</script>'; echo '<a href="' . \Environment::get('base') . $url . '">Please click here to proceed if you are not using JavaScript</a>'; } echo '</div></div>'; exit; } $strToken = md5(uniqid(mt_rand(), true)); $this->Session->set('tl_newsletter_send', $strToken); $sprintf = $objNewsletter->senderName != '' ? $objNewsletter->senderName . ' <%s>' : '%s'; $this->import('BackendUser', 'User'); // prepare preview $preview = $text; if (!$objNewsletter->sendText) { // Default template if ($objNewsletter->template == '') { $objNewsletter->template = 'mail_default'; } // Load the mail template $objTemplate = new \BackendTemplate($objNewsletter->template); $objTemplate->setData($objNewsletter->row()); $objTemplate->title = $objNewsletter->subject; $objTemplate->body = $html; $objTemplate->charset = $GLOBALS['TL_CONFIG']['characterSet']; $objTemplate->css = $css; // Backwards compatibility // Parse template $preview = $objTemplate->parse(); } // Replace inserttags $arrName = explode(' ', $this->User->name); $preview = $this->replaceInsertTags($preview); $preview = $this->prepareLinkTracking($preview, $objNewsletter->id, $this->User->email, '&preview=1'); $preview = $this->parseSimpleTokens($preview, array('firstname' => $arrName[0], 'lastname' => $arrName[sizeof($arrName) - 1], 'street' => 'Königsbrücker Str. 9', 'postal' => '01099', 'city' => 'Dresden', 'phone' => '0351 30966184', 'email' => $this->User->email, 'tracker_png' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $this->User->email . '&preview=1&t=png', 'tracker_gif' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $this->User->email . '&preview=1&t=gif', 'tracker_css' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $this->User->email . '&preview=1&t=css', 'tracker_js' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $this->User->email . '&preview=1&t=js')); // Create cache folder if (!file_exists(TL_ROOT . '/system/cache/newsletter')) { mkdir(TL_ROOT . '/system/cache/newsletter'); file_put_contents(TL_ROOT . '/system/cache/newsletter/.htaccess', '<IfModule !mod_authz_core.c> Order allow,deny Allow from all </IfModule> <IfModule mod_authz_core.c> Require all granted </IfModule>'); } // Cache preview file_put_contents(TL_ROOT . '/system/cache/newsletter/' . $objNewsletter->alias . '.html', preg_replace('/^\\s+|\\n|\\r|\\s+$/m', '', $preview)); // Preview newsletter $return = ' <div id="tl_buttons"> <a href="' . $this->getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> <h2 class="sub_headline">' . sprintf($GLOBALS['TL_LANG']['tl_newsletter']['send'][1], $objNewsletter->id) . '</h2> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('script'), true) . '" id="tl_newsletter_send" class="tl_form" method="get"> <div class="tl_formbody_edit tl_newsletter_send"> <input type="hidden" name="do" value="' . \Input::get('do') . '"> <input type="hidden" name="table" value="' . \Input::get('table') . '"> <input type="hidden" name="key" value="' . \Input::get('key') . '"> <input type="hidden" name="id" value="' . \Input::get('id') . '"> <input type="hidden" name="token" value="' . $strToken . '"> <table class="prev_header"> <tr class="row_0"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['from'] . '</td> <td class="col_1">' . sprintf($sprintf, $objNewsletter->sender) . '</td> </tr> <tr class="row_1"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['subject'][0] . '</td> <td class="col_1">' . $objNewsletter->subject . '</td> </tr> <tr class="row_2"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['template'][0] . '</td> <td class="col_1">' . $objNewsletter->template . '</td> </tr>' . (!empty($arrAttachments) && is_array($arrAttachments) ? ' <tr class="row_3"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['attachments'] . '</td> <td class="col_1">' . implode(', ', $arrAttachments) . '</td> </tr>' : '') . ' </table>' . (!$objNewsletter->sendText ? ' <iframe class="preview_html" id="preview_html" seamless border="0" width="703px" height="503px" style="padding:0" src="system/cache/newsletter/' . $objNewsletter->alias . '.html"></iframe> ' : '') . ' <div class="preview_text"> ' . nl2br_html5($text) . ' </div> <div class="tl_tbox"> <div class="w50"> <h3><label for="ctrl_mpc">' . $GLOBALS['TL_LANG']['tl_newsletter']['mailsPerCycle'][0] . '</label></h3> <input type="text" name="mpc" id="ctrl_mpc" value="10" class="tl_text" onfocus="Backend.getScrollOffset()">' . ($GLOBALS['TL_LANG']['tl_newsletter']['mailsPerCycle'][1] && $GLOBALS['TL_CONFIG']['showHelp'] ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['mailsPerCycle'][1] . '</p>' : '') . ' </div> <div class="w50"> <h3><label for="ctrl_timeout">' . $GLOBALS['TL_LANG']['tl_newsletter']['timeout'][0] . '</label></h3> <input type="text" name="timeout" id="ctrl_timeout" value="1" class="tl_text" onfocus="Backend.getScrollOffset()">' . ($GLOBALS['TL_LANG']['tl_newsletter']['timeout'][1] && $GLOBALS['TL_CONFIG']['showHelp'] ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['timeout'][1] . '</p>' : '') . ' </div> <div class="w50"> <h3><label for="ctrl_start">' . $GLOBALS['TL_LANG']['tl_newsletter']['start'][0] . '</label></h3> <input type="text" name="start" id="ctrl_start" value="0" class="tl_text" onfocus="Backend.getScrollOffset()">' . ($GLOBALS['TL_LANG']['tl_newsletter']['start'][1] && $GLOBALS['TL_CONFIG']['showHelp'] ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['start'][1] . '</p>' : '') . ' </div> <div class="w50"> <h3><label for="ctrl_recipient">' . $GLOBALS['TL_LANG']['tl_newsletter']['sendPreviewTo'][0] . '</label></h3> <input type="text" name="recipient" id="ctrl_recipient" value="' . $this->User->email . '" class="tl_text" onfocus="Backend.getScrollOffset()">' . (isset($_SESSION['TL_PREVIEW_MAIL_ERROR']) ? ' <div class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['email'] . '</div>' : ($GLOBALS['TL_LANG']['tl_newsletter']['sendPreviewTo'][1] && $GLOBALS['TL_CONFIG']['showHelp'] ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['sendPreviewTo'][1] . '</p>' : '')) . ' </div> <div class="clear"></div> </div> </div>'; // Do not send the newsletter if there is an attachment format error if (!$blnAttachmentsFormatError) { $return .= ' <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="preview" class="tl_submit" accesskey="p" value="' . specialchars($GLOBALS['TL_LANG']['tl_newsletter']['preview']) . '"> <input type="submit" id="send" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_newsletter']['send'][0]) . '" onclick="return confirm(\'' . str_replace("'", "\\'", $GLOBALS['TL_LANG']['tl_newsletter']['sendConfirm']) . '\')"> </div> </div>'; } $return .= ' </form>'; unset($_SESSION['TL_PREVIEW_MAIL_ERROR']); return $return; }
/** * List all records of the current table and return them as HTML string * * @return string */ protected function listView() { $return = ''; $table = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 6 ? $this->ptable : $this->strTable; $orderBy = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['fields']; $firstOrderBy = preg_replace('/\\s+.*$/', '', $orderBy[0]); if (is_array($this->orderBy) && $this->orderBy[0] != '') { $orderBy = $this->orderBy; $firstOrderBy = $this->firstOrderBy; } $query = "SELECT * FROM " . $this->strTable; if (!empty($this->procedure)) { $query .= " WHERE " . implode(' AND ', $this->procedure); } if (!empty($this->root) && is_array($this->root)) { $query .= (!empty($this->procedure) ? " AND " : " WHERE ") . "id IN(" . implode(',', array_map('intval', $this->root)) . ")"; } if (is_array($orderBy) && $orderBy[0] != '') { foreach ($orderBy as $k => $v) { list($key, $direction) = explode(' ', $v, 2); if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['eval']['findInSet']) { if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback'])) { $strClass = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback'][0]; $strMethod = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback'][1]; $this->import($strClass); $keys = $this->{$strClass}->{$strMethod}($this); } elseif (is_callable($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback'])) { $keys = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options_callback']($this); } else { $keys = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['options']; } if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['eval']['isAssociative'] || array_is_assoc($keys)) { $keys = array_keys($keys); } $orderBy[$k] = $this->Database->findInSet($v, $keys); } elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$key]['flag'], array(5, 6, 7, 8, 9, 10))) { $orderBy[$k] = "CAST({$key} AS SIGNED)" . ($direction ? " {$direction}" : ""); // see #5503 } } if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 3) { $firstOrderBy = 'pid'; $showFields = $GLOBALS['TL_DCA'][$table]['list']['label']['fields']; $query .= " ORDER BY (SELECT " . $showFields[0] . " FROM " . $this->ptable . " WHERE " . $this->ptable . ".id=" . $this->strTable . ".pid), " . implode(', ', $orderBy); // Set the foreignKey so that the label is translated (also for backwards compatibility) if ($GLOBALS['TL_DCA'][$table]['fields']['pid']['foreignKey'] == '') { $GLOBALS['TL_DCA'][$table]['fields']['pid']['foreignKey'] = $this->ptable . '.' . $showFields[0]; } // Remove the parent field from label fields array_shift($showFields); $GLOBALS['TL_DCA'][$table]['list']['label']['fields'] = $showFields; } else { $query .= " ORDER BY " . implode(', ', $orderBy); } } if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 1 && $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['flag'] % 2 == 0) { $query .= " DESC"; } $objRowStmt = $this->Database->prepare($query); if ($this->limit != '') { $arrLimit = explode(',', $this->limit); $objRowStmt->limit($arrLimit[1], $arrLimit[0]); } $objRow = $objRowStmt->execute($this->values); $this->bid = $return != '' ? $this->bid : 'tl_buttons'; // Display buttos if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] || !empty($GLOBALS['TL_DCA'][$this->strTable]['list']['global_operations'])) { $return .= ' <div id="' . $this->bid . '">' . (\Input::get('act') == 'select' || $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' && !$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable'] ? ' <a href="' . ($this->ptable != '' ? $this->addToUrl('act=create' . ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] < 4 ? '&mode=2' : '') . '&pid=' . $this->intId) : $this->addToUrl('act=create')) . '" 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> ' : '') . $this->generateGlobalButtons() . ' </div>' . \Message::generate(true); } // Return "no records found" message if ($objRow->numRows < 1) { $return .= ' <p class="tl_empty">' . $GLOBALS['TL_LANG']['MSC']['noResult'] . '</p>'; } else { $result = $objRow->fetchAllAssoc(); $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 . '">' : '') . ' <div class="tl_listing_container list_view">' . (\Input::get('act') == 'select' ? ' <div class="tl_select_trigger"> <label for="tl_select_trigger" class="tl_select_label">' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</label> <input type="checkbox" id="tl_select_trigger" onclick="Backend.toggleCheckboxes(this)" class="tl_tree_checkbox"> </div>' : '') . ' <table class="tl_listing' . ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'] ? ' showColumns' : '') . '">'; // Automatically add the "order by" field as last column if we do not have group headers if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns']) { $blnFound = false; // Extract the real key and compare it to $firstOrderBy foreach ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'] as $f) { if (strpos($f, ':') !== false) { list($f) = explode(':', $f, 2); } if ($firstOrderBy == $f) { $blnFound = true; break; } } if (!$blnFound) { $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][] = $firstOrderBy; } } // Generate the table header if the "show columns" option is active if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns']) { $return .= ' <tr>'; foreach ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'] as $f) { if (strpos($f, ':') !== false) { list($f) = explode(':', $f, 2); } $return .= ' <th class="tl_folder_tlist col_' . $f . ($f == $firstOrderBy ? ' ordered_by' : '') . '">' . (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label']) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label'][0] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label']) . '</th>'; } $return .= ' <th class="tl_folder_tlist tl_right_nowrap"> </th> </tr>'; } // Process result and add label and buttons $remoteCur = false; $groupclass = 'tl_folder_tlist'; $eoCount = -1; foreach ($result as $row) { $args = array(); $this->current[] = $row['id']; $showFields = $GLOBALS['TL_DCA'][$table]['list']['label']['fields']; // Label foreach ($showFields as $k => $v) { // Decrypt the value if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['encrypt']) { $row[$v] = \Encryption::decrypt(deserialize($row[$v])); } if (strpos($v, ':') !== false) { list($strKey, $strTable) = explode(':', $v); list($strTable, $strField) = explode('.', $strTable); $objRef = $this->Database->prepare("SELECT " . $strField . " FROM " . $strTable . " WHERE id=?")->limit(1)->execute($row[$strKey]); $args[$k] = $objRef->numRows ? $objRef->{$strField} : ''; } elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['flag'], array(5, 6, 7, 8, 9, 10))) { if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['rgxp'] == 'date') { $args[$k] = $row[$v] ? \Date::parse(\Config::get('dateFormat'), $row[$v]) : '-'; } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['rgxp'] == 'time') { $args[$k] = $row[$v] ? \Date::parse(\Config::get('timeFormat'), $row[$v]) : '-'; } else { $args[$k] = $row[$v] ? \Date::parse(\Config::get('datimFormat'), $row[$v]) : '-'; } } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['inputType'] == 'checkbox' && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['multiple']) { $args[$k] = $row[$v] != '' ? $GLOBALS['TL_LANG']['MSC']['yes'] : $GLOBALS['TL_LANG']['MSC']['no']; } else { $row_v = deserialize($row[$v]); if (is_array($row_v)) { $args_k = array(); foreach ($row_v as $option) { $args_k[] = $GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$option] ?: $option; } $args[$k] = implode(', ', $args_k); } elseif (isset($GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]])) { $args[$k] = is_array($GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]]) ? $GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]][0] : $GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$row[$v]]; } elseif (($GLOBALS['TL_DCA'][$table]['fields'][$v]['eval']['isAssociative'] || array_is_assoc($GLOBALS['TL_DCA'][$table]['fields'][$v]['options'])) && isset($GLOBALS['TL_DCA'][$table]['fields'][$v]['options'][$row[$v]])) { $args[$k] = $GLOBALS['TL_DCA'][$table]['fields'][$v]['options'][$row[$v]]; } else { $args[$k] = $row[$v]; } } } // Shorten the label it if it is too long $label = vsprintf($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['format'] ?: '%s', $args); if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'] > 0 && $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'] < strlen(strip_tags($label))) { $label = trim(\StringUtil::substrHtml($label, $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'])) . ' …'; } // Remove empty brackets (), [], {}, <> and empty tags from the label $label = preg_replace('/\\( *\\) ?|\\[ *\\] ?|\\{ *\\} ?|< *> ?/', '', $label); $label = preg_replace('/<[^>]+>\\s*<\\/[^>]+>/', '', $label); // Build the sorting groups if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] > 0) { $current = $row[$firstOrderBy]; $orderBy = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['fields']; $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, $current, $sortingMode); // Add the group header if (!$GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'] && !$GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['disableGrouping'] && ($remoteNew != $remoteCur || $remoteCur === false)) { $eoCount = -1; $group = $this->formatGroupHeader($firstOrderBy, $remoteNew, $sortingMode, $row); $remoteCur = $remoteNew; $return .= ' <tr> <td colspan="2" class="' . $groupclass . '">' . $group . '</td> </tr>'; $groupclass = 'tl_folder_list'; } } $return .= ' <tr class="' . (++$eoCount % 2 == 0 ? 'even' : 'odd') . ' click2edit toggle_select" onmouseover="Theme.hoverRow(this,1)" onmouseout="Theme.hoverRow(this,0)"> '; $colspan = 1; // Call the label_callback ($row, $label, $this) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']) || is_callable($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'])) { if (is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'])) { $strClass = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'][0]; $strMethod = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'][1]; $this->import($strClass); $args = $this->{$strClass}->{$strMethod}($row, $label, $this, $args); } elseif (is_callable($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'])) { $args = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']($row, $label, $this, $args); } // Handle strings and arrays (backwards compatibility) if (!$GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns']) { $label = is_array($args) ? implode(' ', $args) : $args; } elseif (!is_array($args)) { $args = array($args); $colspan = count($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields']); } } // Show columns if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns']) { foreach ($args as $j => $arg) { $return .= '<td colspan="' . $colspan . '" class="tl_file_list col_' . $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][$j] . ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][$j] == $firstOrderBy ? ' ordered_by' : '') . '">' . ($arg ?: '-') . '</td>'; } } else { $return .= '<td class="tl_file_list">' . $label . '</td>'; } // Buttons ($row, $table, $root, $blnCircularReference, $childs, $previous, $next) $return .= (\Input::get('act') == 'select' ? ' <td class="tl_file_list tl_right_nowrap"><input type="checkbox" name="IDS[]" id="ids_' . $row['id'] . '" class="tl_tree_checkbox" value="' . $row['id'] . '"></td>' : ' <td class="tl_file_list tl_right_nowrap">' . $this->generateButtons($row, $this->strTable, $this->root) . '</td>') . ' </tr>'; } // Close the table $return .= ' </table> </div>'; // Close the form if (\Input::get('act') == 'select') { // Submit buttons $arrButtons = array(); if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notDeletable']) { $arrButtons['delete'] = '<input type="submit" name="delete" id="delete" class="tl_submit" accesskey="d" onclick="return confirm(\'' . $GLOBALS['TL_LANG']['MSC']['delAllConfirm'] . '\')" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['deleteSelected']) . '">'; } if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notCopyable']) { $arrButtons['copy'] = '<input type="submit" name="copy" id="copy" class="tl_submit" accesskey="c" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['copySelected']) . '">'; } if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable']) { $arrButtons['override'] = '<input type="submit" name="override" id="override" class="tl_submit" accesskey="v" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['overrideSelected']) . '">'; $arrButtons['edit'] = '<input type="submit" name="edit" id="edit" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['editSelected']) . '">'; } // 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; }
/** * Return all messages as HTML * * @param boolean $blnDcLayout If true, the line breaks are different * @param boolean $blnNoWrapper If true, there will be no wrapping DIV * * @return string The messages HTML markup * * @deprecated Use Message::generate() instead */ protected function getMessages($blnDcLayout = false, $blnNoWrapper = false) { return \Message::generate($blnDcLayout, $blnNoWrapper); }
/** * Synchronize the file system with the database * @return string */ public function sync() { if (!$this->blnIsDbAssisted) { return ''; } $this->arrMessages = array(); // Reset the "found" flag $this->Database->query("UPDATE tl_files SET found=''"); // Traverse the file system $this->execSync($GLOBALS['TL_CONFIG']['uploadPath']); // Check for left-over entries in the DB $objFiles = \FilesModel::findByFound(''); if ($objFiles !== null) { $arrFiles = array(); $arrFolders = array(); while ($objFiles->next()) { if ($objFiles->type == 'file') { $arrFiles[] = $objFiles->current(); } else { $arrFolders[] = $objFiles->current(); } } // Check whether a folder has moved foreach ($arrFolders as $objFolder) { $objFound = \FilesModel::findBy(array('hash=?', 'found=1'), $objFolder->hash); if ($objFound !== null) { $this->arrMessages[] = '<p class="tl_info">' . sprintf($GLOBALS['TL_LANG']['tl_files']['syncFound'], $objFolder->path, $objFound->path) . '</p>'; // Update the original entry $objFolder->pid = $objFound->pid; $objFolder->tstamp = $objFound->tstamp; $objFolder->name = $objFound->name; $objFolder->type = $objFound->type; $objFolder->path = $objFound->path; $objFolder->save(); // Update the PID of the child records $objChildren = \FilesModel::findByPid($objFound->id); if ($objChildren !== null) { while ($objChildren->next()) { $objChildren->pid = $objFolder->id; $objChildren->save(); } } // Delete the newer (duplicate) entry $objFound->delete(); } else { // Delete the entry if the folder has gone $objFolder->delete(); $this->arrMessages[] = '<p class="tl_error">' . sprintf($GLOBALS['TL_LANG']['tl_files']['syncRemoved'], $objFolder->path) . '</p>'; } } // Check whether a file has moved foreach ($arrFiles as $objFile) { $objFound = \FilesModel::findBy(array('hash=?', 'found=1'), $objFile->hash); if ($objFound !== null) { $this->arrMessages[] = '<p class="tl_info">' . sprintf($GLOBALS['TL_LANG']['tl_files']['syncFound'], $objFile->path, $objFound->path) . '</p>'; // Update the original entry $objFile->pid = $objFound->pid; $objFile->tstamp = $objFound->tstamp; $objFile->name = $objFound->name; $objFile->type = $objFound->type; $objFile->path = $objFound->path; $objFile->save(); // Delete the newer (duplicate) entry $objFound->delete(); } else { // Delete the entry if the file has gone $objFile->delete(); $this->arrMessages[] = '<p class="tl_error">' . sprintf($GLOBALS['TL_LANG']['tl_files']['syncRemoved'], $objFile->path) . '</p>'; } } } $return = ' <div id="tl_buttons"> <a href="' . $this->getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> <h2 class="sub_headline">' . $GLOBALS['TL_LANG']['tl_files']['sync'][1] . '</h2> ' . \Message::generate() . ' <div class="tl_message nobg" style="margin-bottom:2em">'; // Add the messages foreach ($this->arrMessages as $strMessage) { $return .= "\n " . $strMessage; } $return .= ' </div> <div class="tl_submit_container"> <a href="' . $this->getReferer(true) . '" class="tl_submit" style="display:inline-block">' . $GLOBALS['TL_LANG']['MSC']['continue'] . '</a> </div> '; return $return; }
/** * Synchronize the file system with the database * * @return string */ public function sync() { if (!$this->blnIsDbAssisted) { return ''; } $this->import('BackendUser', 'User'); $this->loadLanguageFile('tl_files'); // Check the permission to synchronize if (!$this->User->hasAccess('f6', 'fop')) { $this->log('Not enough permissions to synchronize the file system', __METHOD__, TL_ERROR); $this->redirect('contao/main.php?act=error'); } // Synchronize $strLog = \Dbafs::syncFiles(); // Show the results $arrMessages = array(); $arrCounts = array('Added' => 0, 'Changed' => 0, 'Unchanged' => 0, 'Moved' => 0, 'Deleted' => 0); // Read the log file $fh = fopen(TL_ROOT . '/' . $strLog, 'rb'); while (($buffer = fgets($fh)) !== false) { list($type, $file) = explode('] ', trim(substr($buffer, 1)), 2); // Add a message depending on the type switch ($type) { case 'Added': $arrMessages[] = '<p class="tl_new">' . sprintf($GLOBALS['TL_LANG']['tl_files']['syncAdded'], specialchars($file)) . '</p>'; break; case 'Changed': $arrMessages[] = '<p class="tl_info">' . sprintf($GLOBALS['TL_LANG']['tl_files']['syncChanged'], specialchars($file)) . '</p>'; break; case 'Unchanged': $arrMessages[] = '<p class="tl_confirm hidden">' . sprintf($GLOBALS['TL_LANG']['tl_files']['syncUnchanged'], specialchars($file)) . '</p>'; break; case 'Moved': list($source, $target) = explode(' to ', $file, 2); $arrMessages[] = '<p class="tl_info">' . sprintf($GLOBALS['TL_LANG']['tl_files']['syncMoved'], specialchars($source), specialchars($target)) . '</p>'; break; case 'Deleted': $arrMessages[] = '<p class="tl_error">' . sprintf($GLOBALS['TL_LANG']['tl_files']['syncDeleted'], specialchars($file)) . '</p>'; break; } ++$arrCounts[$type]; } // Close the log file unset($buffer); fclose($fh); // Confirm \Message::addConfirmation($GLOBALS['TL_LANG']['tl_files']['syncComplete']); $return = ' <div id="tl_buttons"> <a href="' . $this->getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <div id="sync-results"> <p class="left">' . sprintf($GLOBALS['TL_LANG']['tl_files']['syncResult'], \System::getFormattedNumber($arrCounts['Added'], 0), \System::getFormattedNumber($arrCounts['Changed'], 0), \System::getFormattedNumber($arrCounts['Unchanged'], 0), \System::getFormattedNumber($arrCounts['Moved'], 0), \System::getFormattedNumber($arrCounts['Deleted'], 0)) . '</p> <p class="right"><input type="checkbox" id="show-hidden" class="tl_checkbox" onclick="Backend.toggleUnchanged()"> <label for="show-hidden">' . $GLOBALS['TL_LANG']['tl_files']['syncShowUnchanged'] . '</label></p> <div class="clear"></div> </div> <div class="tl_message nobg" id="result-list" style="margin-bottom:2em">'; // Add the messages foreach ($arrMessages as $strMessage) { $return .= "\n " . $strMessage; } $return .= ' </div> <div class="tl_submit_container"> <a href="' . $this->getReferer(true) . '" class="tl_submit" style="display:inline-block">' . $GLOBALS['TL_LANG']['MSC']['continue'] . '</a> </div> '; return $return; }
/** * Return a form to choose an existing style sheet and import it * @return string * @throws \Exception */ public function importStyleSheet() { if (\Input::get('key') != 'import') { return ''; } $this->import('BackendUser', 'User'); $class = $this->User->uploader; // See #4086 if (!class_exists($class)) { $class = 'FileUpload'; } $objUploader = new $class(); // Import CSS if (\Input::post('FORM_SUBMIT') == 'tl_style_sheet_import') { $arrUploaded = $objUploader->uploadTo('system/tmp'); if (empty($arrUploaded)) { \Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); $this->reload(); } foreach ($arrUploaded as $strCssFile) { // Folders cannot be imported if (is_dir(TL_ROOT . '/' . $strCssFile)) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['importFolder'], basename($strCssFile))); continue; } $objFile = new \File($strCssFile); // Check the file extension if ($objFile->extension != 'css') { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension)); continue; } $strFile = $objFile->getContent(); $strFile = str_replace("\r", '', $strFile); $strName = preg_replace('/\\.css$/i', '', basename($strCssFile)); $strName = $this->checkStyleSheetName($strName); // Create the new style sheet $objStyleSheet = $this->Database->prepare("INSERT INTO tl_style_sheet (pid, tstamp, name, media) VALUES (?, ?, ?, ?)")->execute(\Input::get('id'), time(), $strName, array('all')); $insertId = $objStyleSheet->insertId; $intSorting = 0; $strComment = ''; $strCategory = ''; if (!is_numeric($insertId) || $insertId < 0) { throw new \Exception('Invalid insert ID'); } $strFile = str_replace('/**/', '[__]', $strFile); $strFile = preg_replace(array('/\\/\\*\\*\\n( *\\*.*\\n){2,} *\\*\\//', '/\\/\\*[^\\*]+\\{[^\\}]+\\}[^\\*]+\\*\\//'), '', $strFile); $arrChunks = preg_split('/\\{([^\\}]*)\\}|\\*\\//U', $strFile, -1, PREG_SPLIT_DELIM_CAPTURE); for ($i = 0; $i < count($arrChunks); $i++) { $strChunk = trim($arrChunks[$i]); if ($strChunk == '') { continue; } $strChunk = preg_replace('/[\\n\\r\\t]+/', ' ', $strChunk); // Category if (strncmp($strChunk, '/**', 3) === 0) { $strCategory = str_replace(array('/*', '*/', '*', '[__]'), '', $strChunk); $strCategory = trim(preg_replace('/\\s+/', ' ', $strCategory)); } elseif (strncmp($strChunk, '/*', 2) === 0) { $strComment = str_replace(array('/*', '*/', '*', '[__]'), '', $strChunk); $strComment = trim(preg_replace('/\\s+/', ' ', $strComment)); } else { $strNext = trim($arrChunks[$i + 1]); $strNext = preg_replace('/[\\n\\r\\t]+/', ' ', $strNext); $arrDefinition = array('pid' => $insertId, 'category' => $strCategory, 'comment' => $strComment, 'sorting' => $intSorting += 128, 'selector' => $strChunk, 'attributes' => $strNext); $this->createDefinition($arrDefinition); ++$i; $strComment = ''; } } // Write the style sheet $this->updateStyleSheet($insertId); // Notify the user if ($strName . '.css' != basename($strCssFile)) { \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_style_sheet']['css_renamed'], basename($strCssFile), $strName . '.css')); } else { \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_style_sheet']['css_imported'], $strName . '.css')); } } // Redirect setcookie('BE_PAGE_OFFSET', 0, 0, '/'); $this->redirect(str_replace('&key=import', '', \Environment::get('request'))); } // Return form return ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=import', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> <h2 class="sub_headline">' . $GLOBALS['TL_LANG']['tl_style_sheet']['import'][1] . '</h2> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_style_sheet_import" class="tl_form" method="post" enctype="multipart/form-data"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_style_sheet_import"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="MAX_FILE_SIZE" value="' . $GLOBALS['TL_CONFIG']['maxFileSize'] . '"> <div class="tl_tbox"> <h3>' . $GLOBALS['TL_LANG']['tl_style_sheet']['source'][0] . '</h3>' . $objUploader->generateMarkup() . (isset($GLOBALS['TL_LANG']['tl_style_sheet']['source'][1]) ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_style_sheet']['source'][1] . '</p>' : '') . ' </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_style_sheet']['import'][0]) . '"> </div> </div> </form>'; }
/** * Auto-generate a form to edit the local configuration file * * @return string */ public function edit() { $return = ''; $ajaxId = null; if (\Environment::get('isAjaxRequest')) { $ajaxId = func_get_arg(1); } // Build an array from boxes and rows $this->strPalette = $this->getPalette(); $boxes = trimsplit(';', $this->strPalette); $legends = array(); if (!empty($boxes)) { foreach ($boxes as $k => $v) { $boxes[$k] = trimsplit(',', $v); foreach ($boxes[$k] as $kk => $vv) { if (preg_match('/^\\[.*\\]$/', $vv)) { continue; } if (preg_match('/^\\{.*\\}$/', $vv)) { $legends[$k] = substr($vv, 1, -1); unset($boxes[$k][$kk]); } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$vv]['exclude'] || !is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$vv])) { unset($boxes[$k][$kk]); } } // Unset a box if it does not contain any fields if (empty($boxes[$k])) { unset($boxes[$k]); } } // Render boxes $class = 'tl_tbox'; $fs = $this->Session->get('fieldset_states'); $blnIsFirst = true; foreach ($boxes as $k => $v) { $strAjax = ''; $blnAjax = false; $key = ''; $cls = ''; $legend = ''; if (isset($legends[$k])) { list($key, $cls) = explode(':', $legends[$k]); $legend = "\n" . '<legend onclick="AjaxRequest.toggleFieldset(this, \'' . $key . '\', \'' . $this->strTable . '\')">' . (isset($GLOBALS['TL_LANG'][$this->strTable][$key]) ? $GLOBALS['TL_LANG'][$this->strTable][$key] : $key) . '</legend>'; } if (isset($fs[$this->strTable][$key])) { $class .= $fs[$this->strTable][$key] ? '' : ' collapsed'; } else { $class .= $cls && $legend ? ' ' . $cls : ''; } $return .= "\n\n" . '<fieldset' . ($key ? ' id="pal_' . $key . '"' : '') . ' class="' . $class . ($legend ? '' : ' nolegend') . '">' . $legend; // Build rows of the current box foreach ($v as $vv) { if ($vv == '[EOF]') { if ($blnAjax && \Environment::get('isAjaxRequest')) { return $strAjax . '<input type="hidden" name="FORM_FIELDS[]" value="' . specialchars($this->strPalette) . '">'; } $blnAjax = false; $return .= "\n " . '</div>'; continue; } if (preg_match('/^\\[.*\\]$/', $vv)) { $thisId = 'sub_' . substr($vv, 1, -1); $blnAjax = $ajaxId == $thisId && \Environment::get('isAjaxRequest') ? true : false; $return .= "\n " . '<div id="' . $thisId . '">'; continue; } $this->strField = $vv; $this->strInputName = $vv; $this->varValue = \Config::get($this->strField); // Handle entities if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'text' || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'textarea') { if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['multiple']) { $this->varValue = deserialize($this->varValue); } if (!is_array($this->varValue)) { $this->varValue = htmlspecialchars($this->varValue); } else { foreach ($this->varValue as $k => $v) { $this->varValue[$k] = htmlspecialchars($v); } } } // Autofocus the first field if ($blnIsFirst && $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'text') { $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['autofocus'] = 'autofocus'; $blnIsFirst = false; } // Call load_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->varValue = $this->{$callback[0]}->{$callback[1]}($this->varValue, $this); } elseif (is_callable($callback)) { $this->varValue = $callback($this->varValue, $this); } } } // Build row $blnAjax ? $strAjax .= $this->row() : ($return .= $this->row()); } $class = 'tl_box'; $return .= "\n" . '</fieldset>'; } } $this->import('Files'); // Check whether the target file is writeable if (!$this->Files->is_writeable('system/config/localconfig.php')) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['notWriteable'], 'system/config/localconfig.php')); } // Submit buttons $arrButtons = array(); $arrButtons['save'] = '<input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['save']) . '">'; $arrButtons['saveNclose'] = '<input type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['saveNclose']) . '">'; // Call the buttons_callback (see #4691) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $arrButtons = $this->{$callback[0]}->{$callback[1]}($arrButtons, $this); } elseif (is_callable($callback)) { $arrButtons = $callback($arrButtons, $this); } } } // Add the buttons and end the form $return .= ' </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> ' . implode(' ', $arrButtons) . ' </div> </div> </form> <script> window.addEvent(\'domready\', function() { Theme.focusInput("' . $this->strTable . '"); }); </script>'; // Begin the form (-> DO NOT CHANGE THIS ORDER -> this way the onsubmit attribute of the form can be changed by a field) $return = ' <div id="tl_buttons"> <a href="' . $this->getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="' . $this->strTable . '" class="tl_form" method="post"' . (!empty($this->onsubmit) ? ' onsubmit="' . implode(' ', $this->onsubmit) . '"' : '') . '> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="' . specialchars($this->strTable) . '"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="FORM_FIELDS[]" value="' . specialchars($this->strPalette) . '">' . ($this->noReload ? ' <p class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['general'] . '</p>' : '') . $return; // Reload the page to prevent _POST variables from being sent twice if (\Input::post('FORM_SUBMIT') == $this->strTable && !$this->noReload) { // Call onsubmit_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->{$callback[0]}->{$callback[1]}($this); } elseif (is_callable($callback)) { $callback($this); } } } // Reload if (\Input::post('saveNclose')) { \Message::reset(); \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->redirect($this->getReferer()); } $this->reload(); } // Set the focus if there is an error if ($this->noReload) { $return .= ' <script> window.addEvent(\'domready\', function() { Backend.vScrollTo(($(\'' . $this->strTable . '\').getElement(\'label.error\').getPosition().y - 20)); }); </script>'; } return $return; }
/** * Add the welcome screen * * @return string */ protected function welcomeScreen() { \System::loadLanguageFile('explain'); /** @var \BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_welcome'); $objTemplate->messages = \Message::generate(false, true); // 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(); }
/** * Compare the theme tables with the local database and check whether there are custom layout sections * * @param array $arrFiles * @param array $arrDbFields * * @return string */ protected function compareThemeFiles($arrFiles, $arrDbFields) { $return = ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=importTheme', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_theme_import" class="tl_form" method="post"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_theme_import"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="confirm" value="1">'; $count = 0; // Check the theme data foreach ($arrFiles as $strFile) { $return .= ' <div class="tl_' . ($count++ < 1 ? 't' : '') . 'box theme_import"> <h3>' . basename($strFile) . '</h3> <h4>' . $GLOBALS['TL_LANG']['tl_theme']['tables_fields'] . '</h4>'; // Find the XML file $objArchive = new \ZipReader($strFile); // Continue if there is no XML file if ($objArchive->getFile('theme.xml') === false) { $return .= "\n " . '<p class="tl_red" style="margin:0">' . sprintf($GLOBALS['TL_LANG']['tl_theme']['missing_xml'], basename($strFile)) . "</p>\n</div>"; continue; } // Open the XML file $xml = new \DOMDocument(); $xml->preserveWhiteSpace = false; $xml->loadXML($objArchive->unzip()); $tables = $xml->getElementsByTagName('table'); $blnHasError = false; // Loop through the tables for ($i = 0; $i < $tables->length; $i++) { $rows = $tables->item($i)->childNodes; $table = $tables->item($i)->getAttribute('name'); // Skip invalid tables if ($table != 'tl_theme' && $table != 'tl_style_sheet' && $table != 'tl_style' && $table != 'tl_module' && $table != 'tl_layout' && $table != 'tl_image_size' && $table != 'tl_image_size_item') { continue; } $arrFieldNames = array(); // Loop through the rows for ($j = 0; $j < $rows->length; $j++) { $fields = $rows->item($j)->childNodes; // Loop through the fields for ($k = 0; $k < $fields->length; $k++) { $arrFieldNames[$fields->item($k)->getAttribute('name')] = true; } } $arrFieldNames = array_keys($arrFieldNames); // Loop through the fields foreach ($arrFieldNames as $name) { // Print a warning if a field is missing if (!in_array($name, $arrDbFields[$table])) { $blnHasError = true; $return .= "\n " . '<p class="tl_red" style="margin:0">' . sprintf($GLOBALS['TL_LANG']['tl_theme']['missing_field'], $table . '.' . $name) . '</p>'; } } } // Confirmation if (!$blnHasError) { $return .= "\n " . '<p class="tl_green" style="margin:0">' . $GLOBALS['TL_LANG']['tl_theme']['tables_ok'] . '</p>'; } // Check the custom templates $return .= ' <h4>' . $GLOBALS['TL_LANG']['tl_theme']['custom_templates'] . '</h4>'; $objArchive->reset(); $blnTplExists = false; // Loop through the archive while ($objArchive->next()) { if (strncmp($objArchive->file_name, 'templates/', 10) !== 0) { continue; } if (file_exists(TL_ROOT . '/' . $objArchive->file_name)) { $blnTplExists = true; $return .= "\n " . '<p class="tl_red" style="margin:0">' . sprintf($GLOBALS['TL_LANG']['tl_theme']['template_exists'], $objArchive->file_name) . '</p>'; } } // Confirmation if (!$blnTplExists) { $return .= "\n " . '<p class="tl_green" style="margin:0">' . $GLOBALS['TL_LANG']['tl_theme']['templates_ok'] . '</p>'; } // HOOK: add custom logic if (isset($GLOBALS['TL_HOOKS']['compareThemeFiles']) && is_array($GLOBALS['TL_HOOKS']['compareThemeFiles'])) { foreach ($GLOBALS['TL_HOOKS']['compareThemeFiles'] as $callback) { $return .= \System::importStatic($callback[0])->{$callback}[1]($xml, $objArchive); } } $return .= ' </div>'; } // Return the form return $return . ' </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['continue']) . '"> </div> </div> </form>'; }
/** * Show header of the parent table and list all records of the current table * @return string */ protected function parentView() { $blnClipboard = false; $arrClipboard = $this->Session->get('CLIPBOARD'); $blnHasSorting = false; $blnMultiboard = false; // Check clipboard if (!empty($arrClipboard[$this->strTable])) { $blnClipboard = true; $arrClipboard = $arrClipboard[$this->strTable]; if (is_array($arrClipboard['id'])) { $blnMultiboard = true; } } // Load the fonts to display the paste hint $GLOBALS['TL_CONFIG']['loadGoogleFonts'] = $blnClipboard; $strBackUrl = \Input::get('id') ? 'contao/main.php?do=iso_products' : \System::getReferer(true, $this->ptable); $return = ' <div id="tl_buttons">' . (\Input::get('nb') ? ' ' : ' <a href="' . $strBackUrl . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a>') . ' ' . (!$blnClipboard ? \Input::get('act') != 'select' ? (!$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable'] ? ' <a href="' . $this->addToUrl($blnHasSorting ? 'act=paste&mode=create' : 'act=create&mode=2&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> ' : '') . $this->generateGlobalButtons() : '' : '<a href="' . $this->addToUrl('clipboard=1') . '" class="header_clipboard" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['clearClipboard']) . '" accesskey="x">' . $GLOBALS['TL_LANG']['MSC']['clearClipboard'] . '</a> ') . ' </div>' . \Message::generate(true); // Get all details of the parent record $objParent = $this->Database->prepare("SELECT * FROM " . $this->strTable . " 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" method="post"> <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 iso_listing_container parent_view"> <div class="tl_header click2edit" onmouseover="Theme.hoverDiv(this,1)" onmouseout="Theme.hoverDiv(this,0)">'; // List all records of the child table if (!\Input::get('act') || \Input::get('act') == 'paste' || \Input::get('act') == 'select') { $imagePasteAfter = \Image::getHtml('pasteafter.gif', $GLOBALS['TL_LANG'][$this->strTable]['pasteafter'][0]); $imageEditHeader = \Image::getHtml('edit.gif', $GLOBALS['TL_LANG'][$this->strTable]['edit'][0]); $strEditHeader = $GLOBALS['TL_LANG'][$this->strTable]['edit'][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">' : (!$GLOBALS['TL_DCA'][$this->ptable]['config']['notEditable'] ? ' <a href="' . preg_replace('/&(amp;)?table=[^& ]*/i', $this->ptable != '' ? '&table=' . $this->ptable : '', $this->addToUrl('act=edit')) . '" class="edit" title="' . specialchars($strEditHeader) . '">' . $imageEditHeader . '</a>' : '') . ($blnHasSorting && !$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable'] ? ' <a href="' . $this->addToUrl('act=create&mode=2&pid=' . $objParent->id . '&id=' . $this->intId) . '" title="' . specialchars($GLOBALS['TL_LANG'][$this->strTable]['pastenew'][0]) . '">' . $imagePasteNew . '</a>' : '') . ($blnClipboard ? ' <a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&mode=2&pid=' . $objParent->id . (!$blnMultiboard ? '&id=' . $arrClipboard['id'] : '')) . '" title="' . specialchars($GLOBALS['TL_LANG'][$this->strTable]['pasteafter'][0]) . '" onclick="Backend.getScrollOffset()">' . $imagePasteAfter . '</a>' : '')) . ' </div>'; // Format header fields $add = array(); $headerFields = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['headerFields']; foreach ($headerFields as $v) { $_v = deserialize($objParent->{$v}); if (is_array($_v)) { $_v = implode(', ', $_v); } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['inputType'] == 'checkbox' && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['multiple']) { $_v = $_v != '' ? $GLOBALS['TL_LANG']['MSC']['yes'] : $GLOBALS['TL_LANG']['MSC']['no']; } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['rgxp'] == 'date') { $_v = $_v ? \Date::parse($GLOBALS['TL_CONFIG']['dateFormat'], $_v) : '-'; } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['rgxp'] == 'time') { $_v = $_v ? \Date::parse($GLOBALS['TL_CONFIG']['timeFormat'], $_v) : '-'; } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['rgxp'] == 'datim') { $_v = $_v ? \Date::parse($GLOBALS['TL_CONFIG']['datimFormat'], $_v) : '-'; } elseif ($v == 'tstamp') { $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($GLOBALS['TL_CONFIG']['datimFormat'], max($objParent->tstamp, $objMaxTstamp->tstamp)); } elseif (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['foreignKey'])) { $arrForeignKey = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['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->strTable]['fields'][$v]['reference'][$_v])) { $_v = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['reference'][$_v][0]; } elseif (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['reference'][$_v])) { $_v = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['reference'][$_v]; } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['isAssociative'] || array_is_assoc($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options'])) { $_v = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options'][$_v]; } // Add the sorting field if ($_v != '') { $key = isset($GLOBALS['TL_LANG'][$this->strTable][$v][0]) ? $GLOBALS['TL_LANG'][$this->strTable][$v][0] : $v; $add[$key] = $_v; } } // Trigger the header_callback (see #3417) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['header_callback'])) { $strClass = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['header_callback'][0]; $strMethod = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['header_callback'][1]; $this->import($strClass); $add = $this->{$strClass}->{$strMethod}($add, $this); } elseif (is_callable($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['header_callback'])) { $add = call_user_func($GLOBALS['TL_DCA'][$this->strTable]['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]); } $this->procedure[] = "pid=?"; $this->values[] = CURRENT_ID; // Support empty ptable fields (backwards compatibility) if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable']) { $this->procedure[] = "ptable=?"; $this->values[] = $this->strTable; } // WHERE if (!empty($this->procedure)) { $query .= " WHERE " . implode(' AND ', $this->procedure); } if (!empty($this->root) && is_array($this->root)) { $query .= (!empty($this->procedure) ? " 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($this->values); if ($objOrderBy->numRows < 1) { return $return . ' <p class="tl_empty_parent_view">' . $GLOBALS['TL_LANG']['MSC']['noResult'] . '</p> </div>'; } $result = $objOrderBy->fetchAllAssoc(); $return .= ' <table class="tl_listing' . ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'] ? ' showColumns' : '') . '">'; // Automatically add the "order by" field as last column if we do not have group headers if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns']) { $blnFound = false; // Extract the real key and compare it to $firstOrderBy foreach ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'] as $f) { if (strpos($f, ':') !== false) { list($f, ) = explode(':', $f, 2); } if ($firstOrderBy == $f) { $blnFound = true; break; } } if (!$blnFound) { $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][] = $firstOrderBy; } } // Generate the table header if the "show columns" option is active if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns']) { $return .= ' <tr>'; foreach ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'] as $f) { if (strpos($f, ':') !== false) { list($f, ) = explode(':', $f, 2); } $return .= ' <th class="tl_folder_tlist col_' . $f . ($f == $firstOrderBy ? ' ordered_by' : '') . '">' . (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label']) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label'][0] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$f]['label']) . '</th>'; } $return .= ' <th class="tl_folder_tlist tl_right_nowrap iso_operations"> </th> </tr>'; } // Process result and add label and buttons $remoteCur = false; $groupclass = 'tl_folder_tlist'; $eoCount = -1; foreach ($result as $row) { $args = array(); $this->current[] = $row['id']; $showFields = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields']; // Label foreach ($showFields as $k => $v) { // Decrypt the value if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['encrypt']) { $row[$v] = \Encryption::decrypt(deserialize($row[$v])); } if (strpos($v, ':') !== false) { list($strKey, $strTable) = explode(':', $v); list($strTable, $strField) = explode('.', $strTable); $objRef = $this->Database->prepare("SELECT " . $strField . " FROM " . $strTable . " WHERE id=?")->limit(1)->execute($row[$strKey]); $args[$k] = $objRef->numRows ? $objRef->{$strField} : ''; } elseif (in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['flag'], array(5, 6, 7, 8, 9, 10))) { if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['rgxp'] == 'date') { $args[$k] = $row[$v] ? \Date::parse($GLOBALS['TL_CONFIG']['dateFormat'], $row[$v]) : '-'; } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['rgxp'] == 'time') { $args[$k] = $row[$v] ? \Date::parse($GLOBALS['TL_CONFIG']['timeFormat'], $row[$v]) : '-'; } else { $args[$k] = $row[$v] ? \Date::parse($GLOBALS['TL_CONFIG']['datimFormat'], $row[$v]) : '-'; } } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['inputType'] == 'checkbox' && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['multiple']) { $args[$k] = $row[$v] != '' ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['label'][0] : ''; } else { $row_v = deserialize($row[$v]); if (is_array($row_v)) { $args_k = array(); foreach ($row_v as $option) { $args_k[] = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['reference'][$option] ?: $option; } $args[$k] = implode(', ', $args_k); } elseif (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['reference'][$row[$v]])) { $args[$k] = is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['reference'][$row[$v]]) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['reference'][$row[$v]][0] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['reference'][$row[$v]]; } elseif (($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['isAssociative'] || array_is_assoc($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options'])) && isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options'][$row[$v]])) { $args[$k] = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options'][$row[$v]]; } else { $args[$k] = $row[$v]; } } } // Shorten the label it if it is too long $label = vsprintf($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['format'] ?: '%s', $args); if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'] > 0 && $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'] < strlen(strip_tags($label))) { $label = trim(\String::substrHtml($label, $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['maxCharacters'])) . ' …'; } // Remove empty brackets (), [], {}, <> and empty tags from the label $label = preg_replace('/\\( *\\) ?|\\[ *\\] ?|\\{ *\\} ?|< *> ?/', '', $label); $label = preg_replace('/<[^>]+>\\s*<\\/[^>]+>/', '', $label); // Build the sorting groups if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] > 0) { $current = $row[$firstOrderBy]; $orderBy = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['fields']; $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, $current, $sortingMode); // Add the group header if (!$GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns'] && !$GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['disableGrouping'] && ($remoteNew != $remoteCur || $remoteCur === false)) { $eoCount = -1; $group = $this->formatGroupHeader($firstOrderBy, $remoteNew, $sortingMode, $row); $remoteCur = $remoteNew; $return .= ' <tr> <td colspan="2" class="' . $groupclass . '">' . $group . '</td> </tr>'; $groupclass = 'tl_folder_list'; } } $return .= ' <tr class="' . (++$eoCount % 2 == 0 ? 'even' : 'odd') . ' click2edit" onmouseover="Theme.hoverRow(this,1)" onmouseout="Theme.hoverRow(this,0)" onclick="Theme.toggleSelect(this)"> '; $colspan = 1; // Call the label callback ($row, $label, $this) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback']) || is_callable($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'])) { if (is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'])) { $strClass = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'][0]; $strMethod = $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'][1]; $this->import($strClass); $args = $this->{$strClass}->{$strMethod}($row, $label, $this, $args); } else { $args = call_user_func($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['label_callback'], $row, $label, $this, $args); } // Handle strings and arrays (backwards compatibility) if (!$GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns']) { $label = is_array($args) ? implode(' ', $args) : $args; } elseif (!is_array($args)) { $args = array($args); $colspan = count($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields']); } } // Show columns if ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['showColumns']) { foreach ($args as $j => $arg) { $return .= '<td colspan="' . $colspan . '" class="tl_file_list col_' . $GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][$j] . ($GLOBALS['TL_DCA'][$this->strTable]['list']['label']['fields'][$j] == $firstOrderBy ? ' ordered_by' : '') . '">' . ($arg ?: '-') . '</td>'; } } else { $return .= '<td class="tl_file_list">' . $label . '</td>'; } // Buttons ($row, $table, $root, $blnCircularReference, $childs, $previous, $next) $return .= (\Input::get('act') == 'select' ? ' <td class="tl_file_list tl_right_nowrap iso_operations"><input type="checkbox" name="IDS[]" id="ids_' . $row['id'] . '" class="tl_tree_checkbox" value="' . $row['id'] . '"></td>' : ' <td class="tl_file_list tl_right_nowrap iso_operations">' . $this->generateButtons($row, $this->strTable, $this->root) . '</td>') . ' </tr>'; } // Close the table $return .= ' </table> </div>'; } // Close form if (\Input::get('act') == 'select') { // Submit buttons $arrButtons = array(); if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notDeletable']) { $arrButtons['delete'] = '<input type="submit" name="delete" id="delete" class="tl_submit" accesskey="d" onclick="return confirm(\'' . $GLOBALS['TL_LANG']['MSC']['delAllConfirm'] . '\')" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['deleteSelected']) . '">'; } if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notSortable']) { $arrButtons['cut'] = '<input type="submit" name="cut" id="cut" class="tl_submit" accesskey="x" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['moveSelected']) . '">'; } if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notCopyable']) { $arrButtons['copy'] = '<input type="submit" name="copy" id="copy" class="tl_submit" accesskey="c" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['copySelected']) . '">'; } if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable']) { $arrButtons['override'] = '<input type="submit" name="override" id="override" class="tl_submit" accesskey="v" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['overrideSelected']) . '">'; $arrButtons['edit'] = '<input type="submit" name="edit" id="edit" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['editSelected']) . '">'; } // 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; }
/** * 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(); } } } // Set the template if ($this->memberTpl != '') { /** @var \FrontendTemplate|object $objTemplate */ $objTemplate = new \FrontendTemplate($this->memberTpl); $this->Template = $objTemplate; $this->Template->setData($this->arrData); } $this->Template->fields = ''; $this->Template->tableless = $this->tableless; $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(); // 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; $arrData['eval']['tableless'] = $this->tableless; // 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, $field, $strTable, $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') == 'tl_member_' . $this->id) { $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') == 'tl_member_' . $this->id && !$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()); } \Message::addConfirmation($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) { $this->Template->{$k} = $v; // backwards compatibility $key = $k . ($k == 'personal' ? 'Data' : 'Details'); $arrGroups[$GLOBALS['TL_LANG']['tl_member'][$key]] = $v; } $this->Template->categories = $arrGroups; $this->Template->formId = 'tl_member_' . $this->id; $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'); $this->Template->message = \Message::generate(false, true); }
/** * Return a form to choose a CSV file and import it * * @param DataContainer $dc * * @return string */ public function importList(DataContainer $dc) { if (\Input::get('key') != 'list') { return ''; } $this->import('BackendUser', 'User'); $class = $this->User->uploader; // See #4086 and #7046 if (!class_exists($class) || $class == 'DropZone') { $class = 'FileUpload'; } /** @var FileUpload $objUploader */ $objUploader = new $class(); // Import CSS if (\Input::post('FORM_SUBMIT') == 'tl_list_import') { $arrUploaded = $objUploader->uploadTo('system/tmp'); if (empty($arrUploaded)) { \Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); $this->reload(); } $this->import('Database'); $arrList = array(); foreach ($arrUploaded as $strCsvFile) { $objFile = new \File($strCsvFile); if ($objFile->extension != 'csv') { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension)); continue; } // Get separator switch (\Input::post('separator')) { case 'semicolon': $strSeparator = ';'; break; case 'tabulator': $strSeparator = "\t"; break; case 'linebreak': $strSeparator = "\n"; break; default: $strSeparator = ','; break; } $resFile = $objFile->handle; while (($arrRow = @fgetcsv($resFile, null, $strSeparator)) !== false) { $arrList = array_merge($arrList, $arrRow); } } $objVersions = new \Versions($dc->table, \Input::get('id')); $objVersions->create(); $this->Database->prepare("UPDATE " . $dc->table . " SET listitems=? WHERE id=?")->execute(serialize($arrList), \Input::get('id')); \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->redirect(str_replace('&key=list', '', \Environment::get('request'))); } // Return form return ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=list', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_list_import" class="tl_form" method="post" enctype="multipart/form-data"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_list_import"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="MAX_FILE_SIZE" value="' . \Config::get('maxFileSize') . '"> <div class="tl_tbox"> <h3><label for="separator">' . $GLOBALS['TL_LANG']['MSC']['separator'][0] . '</label></h3> <select name="separator" id="separator" class="tl_select" onfocus="Backend.getScrollOffset()"> <option value="comma">' . $GLOBALS['TL_LANG']['MSC']['comma'] . '</option> <option value="semicolon">' . $GLOBALS['TL_LANG']['MSC']['semicolon'] . '</option> <option value="tabulator">' . $GLOBALS['TL_LANG']['MSC']['tabulator'] . '</option> <option value="linebreak">' . $GLOBALS['TL_LANG']['MSC']['linebreak'] . '</option> </select>' . ($GLOBALS['TL_LANG']['MSC']['separator'][1] != '' ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['MSC']['separator'][1] . '</p>' : '') . ' <h3>' . $GLOBALS['TL_LANG']['MSC']['source'][0] . '</h3>' . $objUploader->generateMarkup() . (isset($GLOBALS['TL_LANG']['MSC']['source'][1]) ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['MSC']['source'][1] . '</p>' : '') . ' </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <button type="submit" name="save" id="save" class="tl_submit" accesskey="s">' . $GLOBALS['TL_LANG']['MSC']['lw_import'][0] . '</button> </div> </div> </form>'; }
/** * Return a form to choose an existing style sheet and import it * * @return string * * @throws \Exception */ public function importStyleSheet() { if (\Input::get('key') != 'import') { return ''; } $this->import('BackendUser', 'User'); $class = $this->User->uploader; // See #4086 and #7046 if (!class_exists($class) || $class == 'DropZone') { $class = 'FileUpload'; } /** @var \FileUpload $objUploader */ $objUploader = new $class(); // Import CSS if (\Input::post('FORM_SUBMIT') == 'tl_style_sheet_import') { $arrUploaded = $objUploader->uploadTo('system/tmp'); if (empty($arrUploaded)) { \Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); $this->reload(); } foreach ($arrUploaded as $strCssFile) { // Folders cannot be imported if (is_dir(TL_ROOT . '/' . $strCssFile)) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['importFolder'], basename($strCssFile))); continue; } $objFile = new \File($strCssFile, true); // Check the file extension if ($objFile->extension != 'css') { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension)); continue; } // Check the file name $strName = preg_replace('/\\.css$/i', '', basename($strCssFile)); $strName = $this->checkStyleSheetName($strName); // Create the new style sheet $objStyleSheet = $this->Database->prepare("INSERT INTO tl_style_sheet (pid, tstamp, name, media) VALUES (?, ?, ?, ?)")->execute(\Input::get('id'), time(), $strName, array('all')); $insertId = $objStyleSheet->insertId; if (!is_numeric($insertId) || $insertId < 0) { throw new \Exception('Invalid insert ID'); } // Read the file and remove carriage returns $strFile = $objFile->getContent(); $strFile = str_replace("\r", '', $strFile); $arrTokens = array(); $strBuffer = ''; $intSorting = 0; $strComment = ''; $strCategory = ''; $intLength = strlen($strFile); // Tokenize for ($i = 0; $i < $intLength; $i++) { $char = $strFile[$i]; // Whitespace if ($char == '' || $char == "\n" || $char == "\t") { // Ignore } elseif ($char == '/') { if ($strFile[$i + 1] == '*') { while ($i < $intLength) { $strBuffer .= $strFile[$i++]; if ($strFile[$i] == '/' && $strFile[$i - 1] == '*') { $arrTokens[] = array('type' => 'comment', 'content' => $strBuffer . $strFile[$i]); $strBuffer = ''; break; } } } } elseif ($char == '@') { $intLevel = 0; $strSelector = ''; while ($i < $intLength) { $strBuffer .= $strFile[$i++]; if ($strFile[$i] == '{') { if (++$intLevel == 1) { ++$i; $strSelector = $strBuffer; $strBuffer = ''; } } elseif ($strFile[$i] == '}') { if (--$intLevel == 0) { $arrTokens[] = array('type' => 'atblock', 'selector' => $strSelector, 'content' => $strBuffer); $strBuffer = ''; break; } } } } else { $strSelector = ''; while ($i < $intLength) { $strBuffer .= $strFile[$i++]; if ($strFile[$i] == '{') { ++$i; $strSelector = $strBuffer; $strBuffer = ''; } elseif ($strFile[$i] == '}') { $arrTokens[] = array('type' => 'block', 'selector' => $strSelector, 'content' => $strBuffer); $strBuffer = ''; break; } } } } foreach ($arrTokens as $arrToken) { // Comments if ($arrToken['type'] == 'comment') { // Category (comments start with /** and contain only one line) if (strncmp($arrToken['content'], '/**', 3) === 0 && substr_count($arrToken['content'], "\n") == 2) { $strCategory = trim(str_replace(array('/*', '*/', '*'), '', $arrToken['content'])); } elseif (strpos($arrToken['content'], "\n") === false) { $strComment = trim(str_replace(array('/*', '*/', '*'), '', $arrToken['content'])); } } elseif ($arrToken['type'] == 'atblock') { $arrSet = array('pid' => $insertId, 'category' => $strCategory, 'comment' => $strComment, 'sorting' => $intSorting += 128, 'selector' => trim($arrToken['selector']), 'own' => $arrToken['content']); $this->Database->prepare("INSERT INTO tl_style %s")->set($arrSet)->execute(); $strComment = ''; } else { $arrDefinition = array('pid' => $insertId, 'category' => $strCategory, 'comment' => $strComment, 'sorting' => $intSorting += 128, 'selector' => trim($arrToken['selector']), 'attributes' => $arrToken['content']); $this->createDefinition($arrDefinition); $strComment = ''; } } // Write the style sheet $this->updateStyleSheet($insertId); // Notify the user if ($strName . '.css' != basename($strCssFile)) { \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_style_sheet']['css_renamed'], basename($strCssFile), $strName . '.css')); } else { \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_style_sheet']['css_imported'], $strName . '.css')); } } // Redirect \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->redirect(str_replace('&key=import', '', \Environment::get('request'))); } // Return form return ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=import', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_style_sheet_import" class="tl_form" method="post" enctype="multipart/form-data"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_style_sheet_import"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="MAX_FILE_SIZE" value="' . \Config::get('maxFileSize') . '"> <div class="tl_tbox"> <h3>' . $GLOBALS['TL_LANG']['tl_style_sheet']['source'][0] . '</h3>' . $objUploader->generateMarkup() . (isset($GLOBALS['TL_LANG']['tl_style_sheet']['source'][1]) ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_style_sheet']['source'][1] . '</p>' : '') . ' </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_style_sheet']['import'][0]) . '"> </div> </div> </form>'; }
/** * 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); $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']['tableless'] = $this->tableless; $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') == 'tl_change_password') { $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') == 'tl_change_password' && !$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')) !== null) { $this->jumpToOrReload($objJumpTo->row()); } \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['newPasswordSet']); $this->reload(); } $this->Template->action = \Environment::get('indexFreeRequest'); $this->Template->slabel = specialchars($GLOBALS['TL_LANG']['MSC']['changePassword']); $this->Template->rowLast = 'row_' . $row . ' row_last' . ($row % 2 == 0 ? ' even' : ' odd'); $this->Template->tableless = $this->tableless; $this->Template->message = \Message::generate(false, true); }
/** * Generate module */ protected function compile() { $this->loadLanguageFile('tl_autoload'); // Create the config/autoload.php file if (\Input::post('FORM_SUBMIT') == 'tl_autoload') { // Always scan all modules in ide_compat mode if (\Input::post('ide_compat')) { $arrModules = array_filter(scan(TL_ROOT . '/system/modules'), function ($e) { return is_dir(TL_ROOT . '/system/modules/' . $e) ? $e : null; }); } else { $arrModules = \Input::post('modules'); } $intYear = date('Y'); if (empty($arrModules)) { \Message::adError($GLOBALS['TL_LANG']['tl_merge']['emptySelection']); } else { $arrCompat = array(); foreach ($arrModules as $strModule) { // config/autoload.php exists if (!\Input::post('ide_compat') && !\Input::post('override') && file_exists(TL_ROOT . '/system/modules/' . $strModule . '/config/autoload.php')) { \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_merge']['autoloadExists'], $strModule)); continue; } $intClassWidth = 0; $arrClassLoader = array(); $arrNamespaces = array(); $arrFiles = scan(TL_ROOT . '/system/modules/' . $strModule); // Support subfolders foreach ($arrFiles as $strFolder) { if ($strFolder != 'config' && $strFolder != 'dca' && $strFolder != 'html' && $strFolder != 'languages' && $strFolder != 'templates') { if (is_dir(TL_ROOT . '/system/modules/' . $strModule . '/' . $strFolder)) { $files = scan(TL_ROOT . '/system/modules/' . $strModule . '/' . $strFolder); $files = array_map(function ($val) use($strFolder) { return $strFolder . '/' . $val; }, $files); $arrFiles = array_merge($arrFiles, $files); } } } // Scan for classes foreach ($arrFiles as $strFile) { if (strrchr($strFile, '.') != '.php') { continue; } // Read the first 1200 characters of the file (should include the namespace tag) $fh = fopen(TL_ROOT . '/system/modules/' . $strModule . '/' . $strFile, 'rb'); $strBuffer = fread($fh, 1200); fclose($fh); if (strpos($strBuffer, 'namespace') === false) { $strNamespace = ''; } else { $strNamespace = preg_replace('/^.*namespace ([^;]+).*$/s', '$1', $strBuffer); $strNamespace = str_replace('\\', '\\\\', $strNamespace); if ($strNamespace != 'Contao') { $arrNamespaces[] = $strNamespace; } else { $arrCompat[$strModule][] = basename($strFile, '.php'); } $strNamespace .= '\\\\'; } $strKey = $strNamespace . basename($strFile, '.php'); $arrClassLoader[$strKey] = 'system/modules/' . $strModule . '/' . $strFile; $intClassWidth = max(strlen($strKey), $intClassWidth); } $intTplWidth = 0; $arrTplLoader = array(); // Scan for templates if (is_dir(TL_ROOT . '/system/modules/' . $strModule . '/templates')) { foreach (scan(TL_ROOT . '/system/modules/' . $strModule . '/templates') as $strFile) { if (strrchr($strFile, '.') != '.html5' && strrchr($strFile, '.') != '.xhtml') { continue; } $strKey = basename($strFile, strrchr($strFile, '.')); $arrTplLoader[$strKey] = 'system/modules/' . $strModule . '/templates'; $intTplWidth = max(strlen($strKey), $intTplWidth); } } // Neither classes nor templates found if (empty($arrClassLoader) && empty($arrTplLoader)) { continue; } $strPackage = ucfirst($strModule); $objFile = new \File('system/modules/' . $strModule . '/config/autoload.php'); $objFile->write(<<<EOT <?php /** * Contao Open Source CMS * * Copyright (C) 2005-{$intYear} Leo Feyer * * @package {$strPackage} * @link http://www.contao.org * @license http://www.gnu.org/licenses/lgpl-3.0.html LGPL */ EOT ); // Namespaces $arrNamespaces = array_unique($arrNamespaces); if (!empty($arrNamespaces)) { $objFile->append(<<<EOT /** * Register the namespaces */ ClassLoader::addNamespaces(array ( EOT ); foreach ($arrNamespaces as $strNamespace) { $objFile->append("\t'" . $strNamespace . "',"); } $objFile->append('));'); } // Classes if (!empty($arrClassLoader)) { $objFile->append(<<<EOT /** * Register the classes */ ClassLoader::addClasses(array ( EOT ); $strGroup = null; foreach ($arrClassLoader as $strClass => $strPath) { if ($strGroup === null) { $strGroup = dirname($strPath); $objFile->append("\t// " . ucfirst(basename($strGroup))); } elseif (dirname($strPath) != $strGroup) { $strGroup = dirname($strPath); $objFile->append("\n\t// " . ucfirst(basename($strGroup))); } $strClass = "'" . $strClass . "'"; $objFile->append("\t" . str_pad($strClass, $intClassWidth + 2) . " => '{$strPath}',"); } $objFile->append('));'); } // Templates if (!empty($arrTplLoader)) { $objFile->append(<<<EOT /** * Register the templates */ TemplateLoader::addFiles(array ( EOT ); foreach ($arrTplLoader as $strName => $strPath) { $strName = "'" . $strName . "'"; $objFile->append("\t" . str_pad($strName, $intTplWidth + 2) . " => '{$strPath}',"); } $objFile->append('));'); } $objFile->close(); \Message::addConfirmation('Module "' . $strModule . '" has been merged'); } } // IDE compatibility if (\Input::post('ide_compat')) { $objFile = new \File('system/helper/ide_compat.php'); $objFile->write(<<<EOT <?php /** * Contao Open Source CMS * * Copyright (C) 2005-{$intYear} Leo Feyer * * @package Core * @link http://www.contao.org * @license http://www.gnu.org/licenses/lgpl-3.0.html LGPL */ /** * This file is not used in Contao. Its only purpose is to make * PHP IDEs like Eclipse, Zend Studio or PHPStorm realize the * class origins, since the dynamic class aliasing we are using * is a bit too complex for them to understand. */ EOT ); $arrLibrary = array(); // library/Contao foreach (scan(TL_ROOT . '/system/library/Contao') as $strFile) { if (strncmp($strFile, '.', 1) === 0) { continue; } if (is_file(TL_ROOT . '/system/library/Contao/' . $strFile)) { $arrLibrary[] = basename($strFile, '.php'); } elseif ($strFile != 'Database') { foreach (scan(TL_ROOT . '/system/library/Contao/' . $strFile) as $strSubfile) { if (is_file(TL_ROOT . '/system/library/Contao/' . $strFile . '/' . $strSubfile)) { $arrLibrary[] = basename($strFile, '.php') . '_' . basename($strSubfile, '.php'); } } } } // library/Contao/Database foreach (scan(TL_ROOT . '/system/library/Contao/Database') as $strFile) { if (strncmp($strFile, '.', 1) === 0) { continue; } if (is_file(TL_ROOT . '/system/library/Contao/Database/' . $strFile)) { $arrLibrary[] = 'Database_' . basename($strFile, '.php'); } else { foreach (scan(TL_ROOT . '/system/library/Contao/Database/' . $strFile) as $strSubfile) { if (is_file(TL_ROOT . '/system/library/Contao/Database/' . $strFile . '/' . $strSubfile)) { $arrLibrary[] = 'Database_' . basename($strFile, '.php') . '_' . basename($strSubfile, '.php'); } } } } array_unshift($arrCompat, $arrLibrary); $arrIsAbstract = array('Database', 'Database_Statement', 'Database_Result', 'Files', 'User', 'Widget', 'BackendModule', 'Events', 'ContentElement', 'Hybrid', 'Module', 'ModuleNews'); // Add the classes foreach ($arrCompat as $strModule => $arrClasses) { $objFile->append("\n// " . ($strModule ?: 'library')); foreach ($arrClasses as $strClass) { $objFile->append((in_array($strClass, $arrIsAbstract) ? 'abstract ' : '') . "class {$strClass} extends Contao\\{$strClass} {}"); } } $objFile->close(); } $this->reload(); } $arrModules = array(); // List all modules foreach (scan(TL_ROOT . '/system/modules') as $strFile) { if (strncmp($strFile, '.', 1) === 0 || !is_dir(TL_ROOT . '/system/modules/' . $strFile)) { continue; } $arrModules[] = $strFile; } $this->Template->modules = $arrModules; $this->Template->messages = \Message::generate(); $this->Template->href = $this->getReferer(true); $this->Template->title = specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']); $this->Template->button = $GLOBALS['TL_LANG']['MSC']['backBT']; $this->Template->headline = $GLOBALS['TL_LANG']['tl_merge']['headline']; $this->Template->action = ampersand(\Environment::get('request')); $this->Template->available = $GLOBALS['TL_LANG']['tl_merge']['available']; $this->Template->selectAll = $GLOBALS['TL_LANG']['MSC']['selectAll']; $this->Template->override = $GLOBALS['TL_LANG']['tl_merge']['override']; $this->Template->explain = $GLOBALS['TL_LANG']['tl_merge']['explain']; $this->Template->submitButton = specialchars($GLOBALS['TL_LANG']['MSC']['continue']); $this->Template->options = $GLOBALS['TL_LANG']['tl_merge']['options']; $this->Template->ide_compat = $GLOBALS['TL_LANG']['tl_merge']['ide_compat']; }
/** * Generate module */ protected function compile() { // Create files if (\Input::post('FORM_SUBMIT') == 'tl_extension') { $objModule = $this->Database->prepare("SELECT * FROM tl_extension WHERE id=?")->limit(1)->execute($this->objDc->id); if ($objModule->numRows < 1) { return; } // Disable the debug mode (see #7068) \Config::set('debugMode', false); // config/config.php $tplConfig = $this->newTemplate('dev_config', $objModule); \File::putContent('system/modules/' . $objModule->folder . '/config/config.php', $tplConfig->parse()); // config/autoload.ini $tplConfig = $this->newTemplate('dev_ini', $objModule); \File::putContent('system/modules/' . $objModule->folder . '/config/autoload.ini', $tplConfig->parse()); // Back end if ($objModule->addBeMod) { $arrClasses = array_filter(trimsplit(',', $objModule->beClasses)); // Classes foreach ($arrClasses as $strClass) { $tplClass = $this->newTemplate('dev_beClass', $objModule); $tplClass->class = $strClass; \File::putContent('system/modules/' . $objModule->folder . '/' . $this->guessSubfolder($strClass) . '/' . $strClass . '.php', $tplClass->parse()); } $arrTables = array_filter(trimsplit(',', $objModule->beTables)); // Back end data container files foreach ($arrTables as $strTable) { $tplTable = $this->newTemplate('dev_dca', $objModule); $tplTable->table = $strTable; \File::putContent('system/modules/' . $objModule->folder . '/dca/' . $strTable . '.php', $tplTable->parse()); } $arrTemplates = array_filter(trimsplit(',', $objModule->beTemplates)); // Templates foreach ($arrTemplates as $strTemplate) { $tplTemplate = $this->newTemplate('dev_beTemplate', $objModule); \File::putContent('system/modules/' . $objModule->folder . '/templates/' . $strTemplate . '.html5', $tplTemplate->parse()); } } $arrTables = array(); // Front end if ($objModule->addFeMod) { $arrClasses = array_filter(trimsplit(',', $objModule->feClasses)); // Classes foreach ($arrClasses as $strClass) { $tplClass = $this->newTemplate('dev_feClass', $objModule); $tplClass->class = $strClass; $tplClass->extends = $this->guessParentClass($strClass); \File::putContent('system/modules/' . $objModule->folder . '/' . $this->guessSubfolder($strClass) . '/' . $strClass . '.php', $tplClass->parse()); } $arrTables = array_filter(trimsplit(',', $objModule->feTables)); // Front end data container files foreach ($arrTables as $strTable) { $tplTable = $this->newTemplate('dev_feDca', $objModule); $tplTable->table = $strTable; \File::putContent('system/modules/' . $objModule->folder . '/dca/' . $strTable . '.php', $tplTable->parse()); } // Models foreach ($arrTables as $strTable) { $strModel = \Model::getClassFromTable($strTable); $tplTable = $this->newTemplate('dev_model', $objModule); $tplTable->table = $strTable; $tplTable->class = $strModel; \File::putContent('system/modules/' . $objModule->folder . '/models/' . $strModel . '.php', $tplTable->parse()); } $arrTemplates = array_filter(trimsplit(',', $objModule->feTemplates)); // Templates foreach ($arrTemplates as $strTemplate) { $tplTemplate = $this->newTemplate('dev_feTemplate', $objModule); $objTemplate = new \File('system/modules/' . $objModule->folder . '/templates/' . $strTemplate . '.html5', true); $objTemplate->write($tplTemplate->parse()); $objTemplate->close(); $objTemplate->copyTo('system/modules/' . $objModule->folder . '/templates/' . $strTemplate . '.xhtml'); } } // Language packs if ($objModule->addLanguage) { $arrLanguages = array_filter(trimsplit(',', $objModule->languages)); foreach ($arrLanguages as $strLanguage) { // languages/xx/default.php $tplLanguage = $this->newTemplate('dev_default', $objModule); $tplLanguage->language = $strLanguage; \File::putContent('system/modules/' . $objModule->folder . '/languages/' . $strLanguage . '/default.php', $tplLanguage->parse()); // languages/xx/modules.php $tplLanguage = $this->newTemplate('dev_modules', $objModule); $tplLanguage->language = $strLanguage; \File::putContent('system/modules/' . $objModule->folder . '/languages/' . $strLanguage . '/modules.php', $tplLanguage->parse()); // languages/xx/<table>.php foreach ($arrTables as $strTable) { $tplLanguage = $this->newTemplate('dev_table', $objModule); $tplLanguage->language = $strLanguage; $tplLanguage->table = $strTable; \File::putContent('system/modules/' . $objModule->folder . '/languages/' . $strLanguage . '/' . $strTable . '.php', $tplLanguage->parse()); } } } // Public folder $tplConfig = $this->newTemplate('dev_htaccess', $objModule); \File::putContent('system/modules/' . $objModule->folder . '/assets/.htaccess', $tplConfig->parse()); // Confirm and reload \Message::addConfirmation($GLOBALS['TL_LANG']['tl_extension']['confirm']); $this->reload(); } $this->Template->base = \Environment::get('base'); $this->Template->href = $this->getReferer(true); $this->Template->title = specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']); $this->Template->action = ampersand(\Environment::get('request')); $this->Template->selectAll = $GLOBALS['TL_LANG']['MSC']['selectAll']; $this->Template->button = $GLOBALS['TL_LANG']['MSC']['backBT']; $this->Template->message = \Message::generate(); $this->Template->submit = specialchars($GLOBALS['TL_LANG']['tl_extension']['make'][0]); $this->Template->headline = sprintf($GLOBALS['TL_LANG']['tl_extension']['headline'], \Input::get('id')); $this->Template->explain = $GLOBALS['TL_LANG']['tl_extension']['make'][1]; $this->Template->label = $GLOBALS['TL_LANG']['tl_extension']['label']; }
/** * Return a form to choose a CSV file and import it * * @return string */ public function importRecipients() { if (\Input::get('key') != 'import') { return ''; } $this->import('BackendUser', 'User'); $class = $this->User->uploader; // See #4086 and #7046 if (!class_exists($class) || $class == 'DropZone') { $class = 'FileUpload'; } /** @var \FileUpload $objUploader */ $objUploader = new $class(); // Import CSS if (\Input::post('FORM_SUBMIT') == 'tl_recipients_import') { $arrUploaded = $objUploader->uploadTo('system/tmp'); if (empty($arrUploaded)) { \Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); $this->reload(); } $time = time(); $intTotal = 0; $intInvalid = 0; foreach ($arrUploaded as $strCsvFile) { $objFile = new \File($strCsvFile, true); if ($objFile->extension != 'csv') { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension)); continue; } // Get separator switch (\Input::post('separator')) { case 'semicolon': $strSeparator = ';'; break; case 'tabulator': $strSeparator = "\t"; break; case 'linebreak': $strSeparator = "\n"; break; default: $strSeparator = ','; break; } $arrRecipients = array(); $resFile = $objFile->handle; while (($arrRow = @fgetcsv($resFile, null, $strSeparator)) !== false) { $arrRecipients = array_merge($arrRecipients, $arrRow); } $arrRecipients = array_filter(array_unique($arrRecipients)); foreach ($arrRecipients as $strRecipient) { // Skip invalid entries if (!\Validator::isEmail($strRecipient)) { $this->log('Recipient address "' . $strRecipient . '" seems to be invalid and has been skipped', __METHOD__, TL_ERROR); ++$intInvalid; continue; } // Check whether the e-mail address exists $objRecipient = $this->Database->prepare("SELECT COUNT(*) AS count FROM tl_newsletter_recipients WHERE pid=? AND email=?")->execute(\Input::get('id'), $strRecipient); if ($objRecipient->count < 1) { $this->Database->prepare("INSERT INTO tl_newsletter_recipients SET pid=?, tstamp={$time}, email=?, active=1")->execute(\Input::get('id'), $strRecipient); ++$intTotal; } } } \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_newsletter_recipients']['confirm'], $intTotal)); if ($intInvalid > 0) { \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_newsletter_recipients']['invalid'], $intInvalid)); } \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->reload(); } // Return form return ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=import', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_recipients_import" class="tl_form" method="post" enctype="multipart/form-data"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_recipients_import"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="MAX_FILE_SIZE" value="' . \Config::get('maxFileSize') . '"> <div class="tl_tbox"> <h3><label for="separator">' . $GLOBALS['TL_LANG']['MSC']['separator'][0] . '</label></h3> <select name="separator" id="separator" class="tl_select" onfocus="Backend.getScrollOffset()"> <option value="comma">' . $GLOBALS['TL_LANG']['MSC']['comma'] . '</option> <option value="semicolon">' . $GLOBALS['TL_LANG']['MSC']['semicolon'] . '</option> <option value="tabulator">' . $GLOBALS['TL_LANG']['MSC']['tabulator'] . '</option> <option value="linebreak">' . $GLOBALS['TL_LANG']['MSC']['linebreak'] . '</option> </select>' . ($GLOBALS['TL_LANG']['MSC']['separator'][1] != '' ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['MSC']['separator'][1] . '</p>' : '') . ' <h3>' . $GLOBALS['TL_LANG']['MSC']['source'][0] . '</h3>' . $objUploader->generateMarkup() . (isset($GLOBALS['TL_LANG']['MSC']['source'][1]) ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['MSC']['source'][1] . '</p>' : '') . ' </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_newsletter_recipients']['import'][0]) . '"> </div> </div> </form>'; }