/** * 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']; }
/** * Generate sprite from given data */ public function generateSprite(\DataContainer $row) { // Get the theme meta data $objTheme = $this->Database->prepare("SELECT * FROM tl_theme WHERE id=?")->execute($row->id); if ($objTheme->numRows < 1) { return; } if ($objTheme->spritegen_enable != false) { // Replace the numeric folder IDs $objInputFolder = FilesModel::findByPk($objTheme->spritegen_source); $objOutputFolder = FilesModel::findByPk($objTheme->spritegen_output_folder); if ($objInputFolder !== null) { // Provide settings for SpriteGen() $cssSprites = new \SpriteGen(); $cssSprites->addImageFolder(TL_ROOT . '/' . $objInputFolder->path); $cssSprites->setOutputFolder(TL_ROOT . '/' . $objOutputFolder->path); $cssSprites->setCacheTime(0); $cssSprites->useDatabase($objTheme->spritegen_modify_selectors, unserialize($objTheme->spritegen_selectors)); // Generate Sprite $cssSprites->generateSprite($objTheme->spritegen_output_file, $objTheme->id, true, $objTheme->spritegen_direction, $objTheme->spritegen_output_width); // Display success confirmation \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['spritegen_successful']); $this->log('Generated image and style sheet for sprite ' . $objTheme->spritegen_output_file, __METHOD__, CRON); } } }
public static function sendConfirmationNotificationBe(\DataContainer $objDc) { if (($objSubmission = static::findByPk($objDc->id)) !== null) { static::sendConfirmationNotification($objSubmission->id); \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['confirmationNotificationSent']); \Controller::redirect(Url::addQueryString('id=' . $objSubmission->pid, Url::removeQueryString(array('key')))); } }
/** * Update the robots.txt when the page was stored. */ public function updateRobotsTxt(DataContainer $dc) { if (Hofff\Contao\RobotsTxtEditor\RobotsTxtEditor::generateRobotsTxts()) { \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['robotstxt_updated']); } else { \Message::addError($GLOBALS['TL_LANG']['ERR']['robotstxt_not_updated']); } }
/** * 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(); }
/** * Check the FTP connection * @param \DataContainer */ public function checkFileServerConnection(\DataContainer $dc) { if ($dc->activeRecord->type != 'ftp' || $dc->activeRecord->file_connection != 'ftp') { return; } $strClass = $GLOBALS['NOTIFICATION_CENTER']['FTP'][$dc->activeRecord->ftp_type]; if (!class_exists($strClass)) { \Message::addError($GLOBALS['TL_LANG']['tl_nc_gateway']['ftp_error_class']); return; } $objHandler = new $strClass(); try { $objHandler->connect($dc->activeRecord); } catch (\Exception $e) { \Message::addError(sprintf($GLOBALS['TL_LANG']['tl_nc_gateway']['ftp_error_connect'], $e->getMessage())); return; } \Message::addConfirmation($GLOBALS['TL_LANG']['tl_nc_gateway']['ftp_confirm']); }
/** * 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(); }
/** * 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']; }
/** * Return the "newsletter" button * @param array * @param string * @param string * @param string * @param string * @param string * @return string */ public function newsletterIcon($row, $href, $label, $title, $icon, $attributes) { $objArchive = \NewsArchiveModel::findByPk($row['pid']); if (!$objArchive->newsletter || !$objArchive->newsletter_channel || !$objArchive->nc_notification) { return ''; } // Toggle the record if (Input::get('newsletter')) { if ($this->sendNewsMessage(Input::get('newsletter'))) { Message::addConfirmation($GLOBALS['TL_LANG']['tl_news']['message_news_newsletter_confirm']); } else { Message::addError($GLOBALS['TL_LANG']['tl_news']['message_news_newsletter_error']); } $this->redirect($this->getReferer()); } // Return just an image if newsletter was sent if ($row['newsletter']) { return Image::getHtml(str_replace('.png', '_.png', $icon), $label); } // Add the confirmation popup $intRecipients = \NewsletterRecipientsModel::countBy(array("pid=? AND active=1"), $objArchive->newsletter_channel); $attributes = 'onclick="if(!confirm(\'' . sprintf($GLOBALS['TL_LANG']['tl_news']['sendNewsletterConfirm'], $intRecipients) . '\'))return false;Backend.getScrollOffset()"'; return '<a href="' . $this->addToUrl($href . '&newsletter=' . $row['id']) . '" title="' . specialchars($title) . '"' . $attributes . '>' . Image::getHtml($icon, $label) . '</a> '; }
/** * 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>'; }
/** * Add a confirmation message * * @param string $strMessage The confirmation * * @deprecated Use Message::addConfirmation() instead */ protected function addConfirmationMessage($strMessage) { \Message::addConfirmation($strMessage); }
/** * Import files from selected folder * * @param string $strPath */ protected function importFromPath($strPath) { $arrFiles = scan(TL_ROOT . '/' . $strPath); if (empty($arrFiles)) { \Message::addError($GLOBALS['TL_LANG']['MSC']['noFilesInFolder']); \Controller::reload(); } $blnEmpty = true; $arrDelete = array(); $objProducts = \Database::getInstance()->prepare("SELECT * FROM tl_iso_product WHERE pid=0")->execute(); while ($objProducts->next()) { $arrImageNames = array(); $arrImages = deserialize($objProducts->images); if (!is_array($arrImages)) { $arrImages = array(); } else { foreach ($arrImages as $row) { if ($row['src']) { $arrImageNames[] = $row['src']; } } } $arrPattern = array(); $arrPattern[] = $objProducts->alias ? standardize($objProducts->alias) : null; $arrPattern[] = $objProducts->sku ? $objProducts->sku : null; $arrPattern[] = $objProducts->sku ? standardize($objProducts->sku) : null; $arrPattern[] = !empty($arrImageNames) ? implode('|', $arrImageNames) : null; // !HOOK: add custom import regex patterns if (isset($GLOBALS['ISO_HOOKS']['addAssetImportRegexp']) && is_array($GLOBALS['ISO_HOOKS']['addAssetImportRegexp'])) { foreach ($GLOBALS['ISO_HOOKS']['addAssetImportRegexp'] as $callback) { $objCallback = \System::importStatic($callback[0]); $arrPattern = $objCallback->{$callback}[1]($arrPattern, $objProducts); } } $strPattern = '@^(' . implode('|', array_filter($arrPattern)) . ')@i'; $arrMatches = preg_grep($strPattern, $arrFiles); if (!empty($arrMatches)) { $arrNewImages = array(); foreach ($arrMatches as $file) { if (is_dir(TL_ROOT . '/' . $strPath . '/' . $file)) { $arrSubfiles = scan(TL_ROOT . '/' . $strPath . '/' . $file); if (!empty($arrSubfiles)) { foreach ($arrSubfiles as $subfile) { if (is_file($strPath . '/' . $file . '/' . $subfile)) { $objFile = new \File($strPath . '/' . $file . '/' . $subfile); if ($objFile->isGdImage) { $arrNewImages[] = $strPath . '/' . $file . '/' . $subfile; } } } } } elseif (is_file(TL_ROOT . '/' . $strPath . '/' . $file)) { $objFile = new \File($strPath . '/' . $file); if ($objFile->isGdImage) { $arrNewImages[] = $strPath . '/' . $file; } } } if (!empty($arrNewImages)) { foreach ($arrNewImages as $strFile) { $pathinfo = pathinfo(TL_ROOT . '/' . $strFile); // Will recursively create the folder $objFolder = new \Folder('isotope/' . strtolower(substr($pathinfo['filename'], 0, 1))); $strCacheName = $pathinfo['filename'] . '-' . substr(md5_file(TL_ROOT . '/' . $strFile), 0, 8) . '.' . $pathinfo['extension']; \Files::getInstance()->copy($strFile, $objFolder->path . '/' . $strCacheName); $arrImages[] = array('src' => $strCacheName); $arrDelete[] = $strFile; \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['MSC']['assetImportConfirmation'], $pathinfo['filename'] . '.' . $pathinfo['extension'], $objProducts->name)); $blnEmpty = false; } \Database::getInstance()->prepare("UPDATE tl_iso_product SET images=? WHERE id=?")->execute(serialize($arrImages), $objProducts->id); } } } if (!empty($arrDelete)) { $arrDelete = array_unique($arrDelete); foreach ($arrDelete as $file) { \Files::getInstance()->delete($file); } } if ($blnEmpty) { \Message::addInfo($GLOBALS['TL_LANG']['MSC']['assetImportNoFilesFound']); } \Controller::reload(); }
/** * 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; }
/** * Check the uploaded files and move them to the target directory * * @param string $strTarget * * @return array * * @throws \Exception */ public function uploadTo($strTarget) { if ($strTarget == '' || \Validator::isInsecurePath($strTarget)) { throw new \InvalidArgumentException('Invalid target path ' . $strTarget); } $maxlength_kb = $this->getMaximumUploadSize(); $maxlength_kb_readable = $this->getReadableSize($maxlength_kb); $arrUploaded = array(); $arrFiles = $this->getFilesFromGlobal(); foreach ($arrFiles as $file) { // Sanitize the filename try { $file['name'] = \StringUtil::sanitizeFileName($file['name']); } catch (\InvalidArgumentException $e) { \Message::addError($GLOBALS['TL_LANG']['ERR']['filename']); $this->blnHasError = true; continue; } // Invalid file name if (!\Validator::isValidFileName($file['name'])) { \Message::addError($GLOBALS['TL_LANG']['ERR']['filename']); $this->blnHasError = true; } elseif (!is_uploaded_file($file['tmp_name'])) { if ($file['error'] == 1 || $file['error'] == 2) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filesize'], $maxlength_kb_readable)); $this->log('File "' . $file['name'] . '" exceeds the maximum file size of ' . $maxlength_kb_readable, __METHOD__, TL_ERROR); $this->blnHasError = true; } elseif ($file['error'] == 3) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filepartial'], $file['name'])); $this->log('File "' . $file['name'] . '" was only partially uploaded', __METHOD__, TL_ERROR); $this->blnHasError = true; } elseif ($file['error'] > 0) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['fileerror'], $file['error'], $file['name'])); $this->log('File "' . $file['name'] . '" could not be uploaded (error ' . $file['error'] . ')', __METHOD__, TL_ERROR); $this->blnHasError = true; } } elseif ($file['size'] > $maxlength_kb) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filesize'], $maxlength_kb_readable)); $this->log('File "' . $file['name'] . '" exceeds the maximum file size of ' . $maxlength_kb_readable, __METHOD__, TL_ERROR); $this->blnHasError = true; } else { $strExtension = pathinfo($file['name'], PATHINFO_EXTENSION); $arrAllowedTypes = trimsplit(',', strtolower(\Config::get('uploadTypes'))); // File type not allowed if (!in_array(strtolower($strExtension), $arrAllowedTypes)) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $strExtension)); $this->log('File type "' . $strExtension . '" is not allowed to be uploaded (' . $file['name'] . ')', __METHOD__, TL_ERROR); $this->blnHasError = true; } else { $this->import('Files'); $strNewFile = $strTarget . '/' . $file['name']; // Set CHMOD and resize if neccessary if ($this->Files->move_uploaded_file($file['tmp_name'], $strNewFile)) { $this->Files->chmod($strNewFile, \Config::get('defaultFileChmod')); $blnResized = $this->resizeUploadedImage($strNewFile); // Notify the user if (!$blnResized) { \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['MSC']['fileUploaded'], $file['name'])); $this->log('File "' . $file['name'] . '" uploaded successfully', __METHOD__, TL_FILES); } $arrUploaded[] = $strNewFile; } } } } return $arrUploaded; }
/** * Generate the autoload.php files */ protected function createAutoloadFiles() { $arrModules = \Input::post('modules'); if (empty($arrModules)) { \Message::addError($GLOBALS['TL_LANG']['tl_autoload']['emptySelection']); return; } $intYear = date('Y'); foreach ($arrModules as $strModule) { // The autoload.php file exists if (!\Input::post('override') && file_exists(TL_ROOT . '/system/modules/' . $strModule . '/config/autoload.php')) { \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_autoload']['autoloadExists'], $strModule)); continue; } $intClassWidth = 0; $arrFiles = array(); $arrClassLoader = array(); $arrNamespaces = array(); // Default configuration $arrDefaultConfig = array('register_namespaces' => true, 'register_classes' => true, 'register_templates' => true); // Create the autoload.ini file if it does not yet exist if (!file_exists(TL_ROOT . '/system/modules/' . $strModule . '/config/autoload.ini')) { $objIni = new \File('system/modules/devtools/templates/dev_ini.html5', true); $objIni->copyTo('system/modules/' . $strModule . '/config/autoload.ini'); } $arrDefaultConfig = array_merge($arrDefaultConfig, parse_ini_file(TL_ROOT . '/system/modules/' . $strModule . '/config/autoload.ini', true)); /** @var \SplFileInfo[] $objFiles */ $objFiles = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(TL_ROOT . '/system/modules/' . $strModule, \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::FOLLOW_SYMLINKS | \FilesystemIterator::SKIP_DOTS)); // Get all PHP files foreach ($objFiles as $objFile) { if ($objFile->getExtension() == 'php') { $strRelpath = str_replace(TL_ROOT . '/system/modules/' . $strModule . '/', '', $objFile->getPathname()); if (strncmp($strRelpath, 'assets/', 7) !== 0 && strncmp($strRelpath, 'config/', 7) !== 0 && strncmp($strRelpath, 'dca/', 4) !== 0 && strncmp($strRelpath, 'languages/', 10) !== 0 && strncmp($strRelpath, 'templates/', 10) !== 0) { $arrFiles[] = $strRelpath; } } } // Scan for classes foreach ($arrFiles as $strFile) { $arrConfig = $arrDefaultConfig; // Search for a path configuration (see #4776) foreach ($arrDefaultConfig as $strPattern => $arrPathConfig) { // Merge the path configuration with the global configuration if (is_array($arrPathConfig) && fnmatch($strPattern, $strFile)) { $arrConfig = array_merge($arrDefaultConfig, $arrPathConfig); break; } } // Continue if neither namespaces nor classes shall be registered if (!$arrConfig['register_namespaces'] && !$arrConfig['register_classes']) { continue; } $strBuffer = ''; $arrMatches = array(); // Store the file size for fread() $size = filesize(TL_ROOT . '/system/modules/' . $strModule . '/' . $strFile); $fh = fopen(TL_ROOT . '/system/modules/' . $strModule . '/' . $strFile, 'rb'); // Read until a class or interface definition has been found while (!preg_match('/(class|interface|trait) ' . preg_quote(basename($strFile, '.php'), '/') . '/', $strBuffer, $arrMatches) && $size > 0 && !feof($fh)) { $length = min(512, $size); $strBuffer .= fread($fh, $length); $size -= $length; // see #4876 } fclose($fh); // The file does not contain a class or interface if (empty($arrMatches)) { continue; } $strNamespace = preg_replace('/^.*namespace ([^; ]+);.*$/s', '$1', $strBuffer); // No namespace declaration found if ($strNamespace == $strBuffer) { $strNamespace = ''; } unset($strBuffer); // Register the namespace if ($strNamespace != '') { if ($arrConfig['register_namespaces'] && $strNamespace != 'Contao') { // Register only the first chunk as namespace if (strpos($strNamespace, '\\') !== false) { $arrNamespaces[] = substr($strNamespace, 0, strpos($strNamespace, '\\')); } else { $arrNamespaces[] = $strNamespace; } } $strNamespace .= '\\'; } // Register the class if ($arrConfig['register_classes']) { $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')) { /** @var \SplFileInfo[] $objFiles */ $objFiles = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(TL_ROOT . '/system/modules/' . $strModule . '/templates', \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::FOLLOW_SYMLINKS | \FilesystemIterator::SKIP_DOTS)); foreach ($objFiles as $objFile) { $arrConfig = $arrDefaultConfig; $strRelpath = str_replace(TL_ROOT . '/system/modules/' . $strModule . '/', '', $objFile->getPathname()); // Search for a path configuration (see #4776) foreach ($arrDefaultConfig as $strPattern => $arrPathConfig) { // Merge the path configuration with the global configuration if (is_array($arrPathConfig) && fnmatch($strPattern, $strRelpath)) { $arrConfig = array_merge($arrDefaultConfig, $arrPathConfig); break; } } // Continue if templates shall not be registered if (!$arrConfig['register_templates']) { continue; } $arrTplExts = trimsplit(',', strtolower(\Config::get('templateFiles'))); // Add all known template types (see #5857) if (in_array(strtolower($objFile->getExtension()), $arrTplExts)) { $strRelpath = str_replace(TL_ROOT . '/', '', $objFile->getPathname()); $strKey = basename($strRelpath, strrchr($strRelpath, '.')); $arrTplLoader[$strKey] = dirname($strRelpath); $intTplWidth = max(strlen($strKey), $intTplWidth); } } } // Neither classes nor templates found if (empty($arrNamespaces) && empty($arrClassLoader) && empty($arrTplLoader)) { continue; } $objFile = new \File('system/modules/' . $strModule . '/config/autoload.php', true); $objFile->write(<<<EOT <?php /** * Contao Open Source CMS * * Copyright (c) 2005-{$intYear} Leo Feyer * * @license LGPL-3.0+ */ EOT ); // Namespaces if (!empty($arrNamespaces)) { $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) { $strRelpath = str_replace('system/modules/' . $strModule . '/', '', $strPath); $strBasedir = substr($strRelpath, 0, strpos($strRelpath, '/')); if ($strBasedir != '') { if ($strGroup === null) { $strGroup = $strBasedir; $objFile->append("\t// " . ucfirst($strBasedir)); } elseif ($strBasedir != $strGroup) { $strGroup = $strBasedir; $objFile->append("\n\t// " . ucfirst($strBasedir)); } } $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(sprintf($GLOBALS['TL_LANG']['tl_autoload']['autoloadConfirm'], $strModule)); } }
/** * Generate the ide_compat.php file */ protected function createIdeCompatFile() { $arrCompat = array(); // Scan all modules $arrModules = array_filter(scan(TL_ROOT . '/system/modules'), function ($e) { return is_dir(TL_ROOT . '/system/modules/' . $e) ? $e : null; }); foreach ($arrModules as $strModule) { $arrFiles = array(); // Recursively scan all subfolders $objFiles = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(TL_ROOT . '/system/modules/' . $strModule, \FilesystemIterator::UNIX_PATHS)); // Get all PHP files foreach ($objFiles as $objFile) { if ($objFile->isFile() && pathinfo($objFile->getFilename(), PATHINFO_EXTENSION) == 'php') { $strRelpath = str_replace(TL_ROOT . '/system/modules/' . $strModule . '/', '', $objFile->getPathname()); if (strncmp($strRelpath, 'assets/', 7) !== 0 && strncmp($strRelpath, 'config/', 7) !== 0 && strncmp($strRelpath, 'dca/', 4) !== 0 && strncmp($strRelpath, 'languages/', 10) !== 0 && strncmp($strRelpath, 'templates/', 10) !== 0) { $arrFiles[] = $strRelpath; } } } // Scan for classes foreach ($arrFiles as $strFile) { $strBuffer = ''; $arrMatches = array(); $fh = fopen(TL_ROOT . '/system/modules/' . $strModule . '/' . $strFile, 'rb'); // Read until a class or interface definition has been found while (!feof($fh) && !preg_match('/(class|interface) ' . preg_quote(basename($strFile, '.php'), '/') . '/', $strBuffer, $arrMatches)) { $strBuffer .= fread($fh, 512); } fclose($fh); // The file does not contain a class or interface if (empty($arrMatches)) { continue; } $strType = $arrMatches[1]; $strNamespace = preg_replace('/^.*namespace ([^; ]+);.*$/s', '$1', $strBuffer); // No namespace declaration found if ($strNamespace == $strBuffer) { continue; } list($strFirst, $strRest) = explode('\\', $strNamespace, 2); // Add the ide_compat information $arrCompat[$strModule][$strRest][] = array('namespace' => $strFirst, 'class' => basename($strFile, '.php'), 'abstract' => preg_match('/^.*abstract ' . preg_quote($strType, '/') . ' [^;]+.*$/s', $strBuffer), 'type' => $strType); unset($strBuffer); } } $intYear = date('Y'); // Write the file $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://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 ); // Add the classes foreach ($arrCompat as $strModule => $arrNamespaces) { $objFile->append("\n// " . $strModule); foreach ($arrNamespaces as $strNamespace => $arrClasses) { $objFile->append('namespace ' . $strNamespace . ' {'); foreach ($arrClasses as $arrClass) { $objFile->append("\t" . ($arrClass['abstract'] ? 'abstract ' : '') . $arrClass['type'] . ' ' . $arrClass['class'] . ' extends ' . $arrClass['namespace'] . '\\' . ($strNamespace ? $strNamespace . '\\' : '') . $arrClass['class'] . ' {}'); } $objFile->append('}'); } } $objFile->close(); \Message::addConfirmation($GLOBALS['TL_LANG']['tl_autoload']['ideCompatConfirm']); }
/** * Extract the theme files and write the data to the database * * @param array $arrFiles * @param array $arrDbFields */ protected function extractThemeFiles($arrFiles, $arrDbFields) { foreach ($arrFiles as $strZipFile) { $xml = null; // Open the archive $objArchive = new \ZipReader($strZipFile); // Extract all files while ($objArchive->next()) { // Load the XML file if ($objArchive->file_name == 'theme.xml') { $xml = new \DOMDocument(); $xml->preserveWhiteSpace = false; $xml->loadXML($objArchive->unzip()); continue; } // Limit file operations to files and the templates directory if (strncmp($objArchive->file_name, 'files/', 6) !== 0 && strncmp($objArchive->file_name, 'tl_files/', 9) !== 0 && strncmp($objArchive->file_name, 'templates/', 10) !== 0) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidFile'], $objArchive->file_name)); continue; } // Extract the files try { \File::putContent($this->customizeUploadPath($objArchive->file_name), $objArchive->unzip()); } catch (\Exception $e) { \Message::addError($e->getMessage()); } } // Continue if there is no XML file if (!$xml instanceof \DOMDocument) { \Message::addError(sprintf($GLOBALS['TL_LANG']['tl_theme']['missing_xml'], basename($strZipFile))); continue; } $arrMapper = array(); $tables = $xml->getElementsByTagName('table'); $arrNewFolders = array(); // Extract the folder names from the XML file for ($i = 0; $i < $tables->length; $i++) { if ($tables->item($i)->getAttribute('name') == 'tl_theme') { $fields = $tables->item($i)->childNodes->item(0)->childNodes; for ($k = 0; $k < $fields->length; $k++) { if ($fields->item($k)->getAttribute('name') == 'folders') { $arrNewFolders = deserialize($fields->item($k)->nodeValue); break; } } break; } } // Sync the new folder(s) if (!empty($arrNewFolders) && is_array($arrNewFolders)) { foreach ($arrNewFolders as $strFolder) { \Dbafs::addResource($this->customizeUploadPath($strFolder)); } } // Lock the tables $arrLocks = array('tl_files' => 'WRITE', 'tl_theme' => 'WRITE', 'tl_style_sheet' => 'WRITE', 'tl_style' => 'WRITE', 'tl_module' => 'WRITE', 'tl_layout' => 'WRITE', 'tl_image_size' => 'WRITE', 'tl_image_size_item' => 'WRITE'); // Load the DCAs of the locked tables (see #7345) foreach (array_keys($arrLocks) as $table) { $this->loadDataContainer($table); } $this->Database->lockTables($arrLocks); // Get the current auto_increment values $tl_files = $this->Database->getNextId('tl_files'); $tl_theme = $this->Database->getNextId('tl_theme'); $tl_style_sheet = $this->Database->getNextId('tl_style_sheet'); $tl_style = $this->Database->getNextId('tl_style'); $tl_module = $this->Database->getNextId('tl_module'); $tl_layout = $this->Database->getNextId('tl_layout'); $tl_image_size = $this->Database->getNextId('tl_image_size'); $tl_image_size_item = $this->Database->getNextId('tl_image_size_item'); // 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 (!in_array($table, array_keys($arrLocks))) { continue; } // Get the order fields $objDcaExtractor = \DcaExtractor::getInstance($table); $arrOrder = $objDcaExtractor->getOrderFields(); // Loop through the rows for ($j = 0; $j < $rows->length; $j++) { $set = array(); $fields = $rows->item($j)->childNodes; // Loop through the fields for ($k = 0; $k < $fields->length; $k++) { $value = $fields->item($k)->nodeValue; $name = $fields->item($k)->getAttribute('name'); // Skip NULL values if ($value == 'NULL') { continue; } elseif ($name == 'id') { $id = ${$table}++; $arrMapper[$table][$value] = $id; $value = $id; } elseif ($name == 'pid') { if ($table == 'tl_style') { $value = $arrMapper['tl_style_sheet'][$value]; } elseif ($table == 'tl_image_size_item') { $value = $arrMapper['tl_image_size'][$value]; } else { $value = $arrMapper['tl_theme'][$value]; } } elseif ($name == 'fallback') { $value = ''; } elseif ($table == 'tl_layout' && $name == 'stylesheet') { $stylesheets = deserialize($value); if (is_array($stylesheets)) { foreach (array_keys($stylesheets) as $key) { $stylesheets[$key] = $arrMapper['tl_style_sheet'][$stylesheets[$key]]; } $value = serialize($stylesheets); } } elseif ($table == 'tl_layout' && $name == 'modules') { $modules = deserialize($value); if (is_array($modules)) { foreach ($modules as $key => $mod) { if ($mod['mod'] > 0) { $modules[$key]['mod'] = $arrMapper['tl_module'][$mod['mod']]; } } $value = serialize($modules); } } elseif (($table == 'tl_theme' || $table == 'tl_style_sheet') && $name == 'name') { $objCount = $this->Database->prepare("SELECT COUNT(*) AS count FROM " . $table . " WHERE name=?")->execute($value); if ($objCount->count > 0) { $value = preg_replace('/( |\\-)[0-9]+$/', '', $value); $value .= ($table == 'tl_style_sheet' ? '-' : ' ') . ${$table}; } } elseif (($table == 'tl_style_sheet' || $table == 'tl_style' || $table == 'tl_files' && $name == 'path') && strpos($value, 'files') !== false) { $tmp = deserialize($value); if (is_array($tmp)) { foreach ($tmp as $kk => $vv) { $tmp[$kk] = $this->customizeUploadPath($vv); } $value = serialize($tmp); } else { $value = $this->customizeUploadPath($value); } } elseif ($GLOBALS['TL_DCA'][$table]['fields'][$name]['inputType'] == 'fileTree' && !$GLOBALS['TL_DCA'][$table]['fields'][$name]['eval']['multiple']) { if (!$value) { $value = null; // Contao >= 3.2 } else { // Do not use the FilesModel here – tables are locked! $objFile = $this->Database->prepare("SELECT uuid FROM tl_files WHERE path=?")->limit(1)->execute($this->customizeUploadPath($value)); $value = $objFile->uuid; } } elseif ($GLOBALS['TL_DCA'][$table]['fields'][$name]['inputType'] == 'fileTree' || in_array($name, $arrOrder)) { $tmp = deserialize($value); if (is_array($tmp)) { foreach ($tmp as $kk => $vv) { // Do not use the FilesModel here – tables are locked! $objFile = $this->Database->prepare("SELECT uuid FROM tl_files WHERE path=?")->limit(1)->execute($this->customizeUploadPath($vv)); $tmp[$kk] = $objFile->uuid; } $value = serialize($tmp); } } elseif ($GLOBALS['TL_DCA'][$table]['fields'][$name]['inputType'] == 'imageSize') { $imageSizes = deserialize($value, true); if (!empty($imageSizes)) { if (is_numeric($imageSizes[2])) { $imageSizes[2] = $arrMapper['tl_image_size'][$imageSizes[2]]; } } $value = serialize($imageSizes); } $set[$name] = $value; } // Skip fields that are not in the database (e.g. because of missing extensions) foreach ($set as $k => $v) { if (!in_array($k, $arrDbFields[$table])) { unset($set[$k]); } } // Create the templates folder even if it is empty (see #4793) if ($table == 'tl_theme' && isset($set['templates']) && strncmp($set['templates'], 'templates/', 10) === 0 && !is_dir(TL_ROOT . '/' . $set['templates'])) { new \Folder($set['templates']); } // Update tl_files (entries have been created by the Dbafs class) if ($table == 'tl_files') { $this->Database->prepare("UPDATE {$table} %s WHERE path=?")->set($set)->execute($set['path']); } else { $this->Database->prepare("INSERT INTO {$table} %s")->set($set)->execute(); } } } // Unlock the tables $this->Database->unlockTables(); // Update the style sheets $this->import('StyleSheets'); $this->StyleSheets->updateStyleSheets(); // Notify the user \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_theme']['theme_imported'], basename($strZipFile))); // HOOK: add custom logic if (isset($GLOBALS['TL_HOOKS']['extractThemeFiles']) && is_array($GLOBALS['TL_HOOKS']['extractThemeFiles'])) { $intThemeId = empty($arrMapper['tl_theme']) ? null : reset($arrMapper['tl_theme']); foreach ($GLOBALS['TL_HOOKS']['extractThemeFiles'] as $callback) { \System::importStatic($callback[0])->{$callback}[1]($xml, $objArchive, $intThemeId, $arrMapper); } } unset($tl_files, $tl_theme, $tl_style_sheet, $tl_style, $tl_module, $tl_layout, $tl_image_size, $tl_image_size_item); } \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->Session->remove('uploaded_themes'); // Redirect $this->redirect(str_replace('&key=importTheme', '', \Environment::get('request'))); }
/** * Delete tl_user_to_group and create new * * @return void */ public function syncUserToGroup() { $this->syncAssociationTable('user'); \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['userGroupsSynchronized']); $this->redirect($this->Environment->script . '?do=user'); }
/** * 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>'; }
/** * 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']; }
/** * 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 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>'; }
/** * Validate input and set value * * @param mixed $varInput * * @return string */ protected function validator($varInput) { $this->blnSubmitInput = false; if (($varInput == '' || $varInput == '*****') && $this->varValue != '') { return '*****'; } if (utf8_strlen($varInput) < \Config::get('minPasswordLength')) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['passwordLength'], \Config::get('minPasswordLength'))); } if ($varInput != $this->getPost($this->strName . '_confirm')) { $this->addError($GLOBALS['TL_LANG']['ERR']['passwordMatch']); } if ($varInput == $GLOBALS['TL_USERNAME']) { $this->addError($GLOBALS['TL_LANG']['ERR']['passwordName']); } $varInput = parent::validator($varInput); if (!$this->hasErrors()) { $this->blnSubmitInput = true; \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['pw_changed']); return \Encryption::hash($varInput); } return ''; }
public function importPostal(\DataContainer $dc) { if (\Input::get('key') != 'importPostal') { return ''; } $strTemplate = 'be_geonames_import_postal'; $strFormID = 'tl_geonames_import_postal'; $this->import('BackendUser', 'User'); $class = $this->User->uploader; // See #4086 and #7046 if (!class_exists($class) || $class == 'DropZone') { $class = 'FileUpload'; } $objUploader = new $class(); // Import CSS if (\Input::post('FORM_SUBMIT') == $strFormID) { $arrUploaded = $objUploader->uploadTo('system/tmp'); if (empty($arrUploaded)) { \Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); $this->reload(); } $intTotal = 0; $intInvalid = 0; $intInserted = 0; $arrInvalid = array(); $arrInserted = array(); foreach ($arrUploaded as $strCsvFile) { $objFile = new \File($strCsvFile, true); if (!in_array($objFile->extension, array('csv', 'txt'))) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension)); continue; } $arrItems = $this->getItemsFromCsvFile($objFile, \Input::post('separator')); $objImporter = new GeonamesPostalImporter($arrItems); $objImporter->run(); $intTotal += $objImporter->getValidCount(); $intInvalid += $objImporter->getInvalidCount(); $intInserted += $objImporter->getInsertedCount(); $arrInserted = array_merge($arrInserted, $objImporter->getInsertedItems()); $arrInvalid = array_merge($arrInvalid, $objImporter->getInvalidItems()); } \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_geonames_postal']['confirmPromoters'], $intTotal)); if ($intInvalid > 0) { \Message::addError(sprintf($GLOBALS['TL_LANG']['tl_geonames_postal']['invalidPromoters'], $intInvalid)); foreach ($arrInvalid as $arrEntry) { \Message::addError('Row: ' . $arrEntry['row'] . ' – ' . $arrEntry['msg']); } } if ($intInserted > 0) { \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_geonames_postal']['insertedPromoters'], $intInserted)); foreach ($arrInserted as $arrEntry) { \Message::addConfirmation('Row: ' . $arrEntry['row'] . ' – ' . $arrEntry['msg']); } } \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->reload(); } $objT = new \BackendTemplate($strTemplate); $objT->action = ampersand(\Environment::get('request'), true); $objT->formID = $strFormID; $objT->objUploader = $objUploader; $objT->back = ampersand(str_replace('&key=importPostal', '', \Environment::get('request'))); $objT->submitText = specialchars($GLOBALS['TL_LANG']['tl_geonames_postal']['import'][0]); // Return form return $objT->parse(); }
/** * 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); }
/** * 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; }
/** * Return a checkbox to delete session data * * @param DataContainer $dc * * @return string */ public function sessionField(DataContainer $dc) { if (Input::post('FORM_SUBMIT') == 'tl_user') { $arrPurge = Input::post('purge'); if (is_array($arrPurge)) { $this->import('Automator'); if (in_array('purge_session', $arrPurge)) { $this->Session->setData(array()); Message::addConfirmation($GLOBALS['TL_LANG']['tl_user']['sessionPurged']); } if (in_array('purge_images', $arrPurge)) { $this->Automator->purgeImageCache(); Message::addConfirmation($GLOBALS['TL_LANG']['tl_user']['htmlPurged']); } if (in_array('purge_pages', $arrPurge)) { $this->Automator->purgePageCache(); Message::addConfirmation($GLOBALS['TL_LANG']['tl_user']['tempPurged']); } } } return ' <div> <fieldset class="tl_checkbox_container"> <legend>' . $GLOBALS['TL_LANG']['tl_user']['session'][0] . '</legend> <input type="checkbox" id="check_all_purge" class="tl_checkbox" onclick="Backend.toggleCheckboxGroup(this, \'ctrl_purge\')"> <label for="check_all_purge" style="color:#a6a6a6"><em>' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</em></label><br> <input type="checkbox" name="purge[]" id="opt_purge_0" class="tl_checkbox" value="purge_session" onfocus="Backend.getScrollOffset()"> <label for="opt_purge_0">' . $GLOBALS['TL_LANG']['tl_user']['sessionLabel'] . '</label><br> <input type="checkbox" name="purge[]" id="opt_purge_1" class="tl_checkbox" value="purge_images" onfocus="Backend.getScrollOffset()"> <label for="opt_purge_1">' . $GLOBALS['TL_LANG']['tl_user']['htmlLabel'] . '</label><br> <input type="checkbox" name="purge[]" id="opt_purge_2" class="tl_checkbox" value="purge_pages" onfocus="Backend.getScrollOffset()"> <label for="opt_purge_2">' . $GLOBALS['TL_LANG']['tl_user']['tempLabel'] . '</label> </fieldset>' . $dc->help() . ' </div>'; }
/** * 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']; }