/** * Generate the content element */ protected function compile() { $rows = deserialize($this->tableitems); $this->Template->id = 'table_' . $this->id; $this->Template->summary = specialchars($this->summary); $this->Template->useHeader = $this->thead ? true : false; $this->Template->useFooter = $this->tfoot ? true : false; $this->Template->useLeftTh = $this->tleft ? true : false; $this->Template->sortable = $this->sortable ? true : false; $arrHeader = array(); $arrBody = array(); $arrFooter = array(); // Table header if ($this->thead) { foreach ($rows[0] as $i => $v) { // Set table sort cookie if ($this->sortable && $i == $this->sortIndex) { $co = 'TS_TABLE_' . $this->id; $so = $this->sortOrder == 'descending' ? 'desc' : 'asc'; if (\Input::cookie($co) == '') { \System::setCookie($co, $i . '|' . $so, 0); } } // Add cell $arrHeader[] = array('class' => 'head_' . $i . ($i == 0 ? ' col_first' : '') . ($i == count($rows[0]) - 1 ? ' col_last' : '') . ($i == 0 && $this->tleft ? ' unsortable' : ''), 'content' => $v != '' ? nl2br_html5($v) : ' '); } array_shift($rows); } $this->Template->header = $arrHeader; $limit = $this->tfoot ? count($rows) - 1 : count($rows); // Table body for ($j = 0; $j < $limit; $j++) { $class_tr = ''; if ($j == 0) { $class_tr .= ' row_first'; } if ($j == $limit - 1) { $class_tr .= ' row_last'; } $class_eo = $j % 2 == 0 ? ' odd' : ' even'; foreach ($rows[$j] as $i => $v) { $class_td = ''; if ($i == 0) { $class_td .= ' col_first'; } if ($i == count($rows[$j]) - 1) { $class_td .= ' col_last'; } $arrBody['row_' . $j . $class_tr . $class_eo][] = array('class' => 'col_' . $i . $class_td, 'content' => $v != '' ? nl2br_html5($v) : ' '); } } $this->Template->body = $arrBody; // Table footer if ($this->tfoot) { foreach ($rows[count($rows) - 1] as $i => $v) { $arrFooter[] = array('class' => 'foot_' . $i . ($i == 0 ? ' col_first' : '') . ($i == count($rows[count($rows) - 1]) - 1 ? ' col_last' : ''), 'content' => $v != '' ? nl2br_html5($v) : ' '); } } $this->Template->footer = $arrFooter; }
/** * @param Database_Result $objPage * @param Database_Result $objLayout * @param PageRegular $objPageRegular */ public function login($objPage, $objLayout, $objPageRegular) { $time = time(); $objMember = \Database::getInstance()->prepare("SELECT * FROM tl_member WHERE loginLink = ? AND (loginLinkExpire > ? OR loginLinkExpire = '')")->execute($this->authKey, $time); $objMemberModel = \MemberModel::findById($objMember->id); if ($objMember->numRows != 1 || $objMember->loginLink != $this->authKey) { return; } if (!FE_USER_LOGGED_IN) { // Generate the cookie hash $this->strHash = sha1(session_id() . (!\Config::get('disableIpCheck') ? \Environment::get('ip') : '') . 'FE_USER_AUTH'); // Clean up old sessions \Database::getInstance()->prepare("DELETE FROM tl_session WHERE tstamp<? OR hash=?")->execute($time - \Config::get('sessionTimeout'), $this->strHash); // Save the session in the database \Database::getInstance()->prepare("INSERT INTO tl_session (pid, tstamp, name, sessionID, ip, hash) VALUES (?, ?, ?, ?, ?, ?)")->execute($objMember->id, $time, 'FE_USER_AUTH', session_id(), \Environment::get('ip'), $this->strHash); // Set the authentication cookie \System::setCookie('FE_USER_AUTH', $this->strHash, $time + \Config::get('sessionTimeout'), null, null, false, true); // Set the login status (backwards compatibility) $_SESSION['TL_USER_LOGGED_IN'] = true; // Save the login status $_SESSION['TL_USER_LOGGED_IN'] = true; \System::log('User "' . $objMember->username . '" logged in by authKey', 'LoginLink()', TL_ACCESS); \Controller::reload(); } if ($objMember->jumpTo) { $objPage = \PageModel::findByPk($objMember->jumpTo); } $strUrl = \Controller::generateFrontendUrl($objPage->row()); $strParam = ''; foreach ($_GET as $index => $value) { if ($index == 'key') { continue; } if (!$strParam) { $strParam .= '?' . $index . '=' . \Input::get($index); } else { $strParam .= '&' . $index . '=' . \Input::get($index); } } \Controller::redirect($strUrl . $strParam); }
/** * Auto-generate a form to override all records that are currently shown * * @return string */ public function overrideAll() { if ($GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable']) { $this->log('Table "' . $this->strTable . '" is not editable', __METHOD__, TL_ERROR); $this->redirect('contao/main.php?act=error'); } $return = ''; $this->import('BackendUser', 'User'); // Get current IDs from session $session = $this->Session->getData(); $ids = $session['CURRENT']['IDS']; // Save field selection in session if (\Input::post('FORM_SUBMIT') == $this->strTable . '_all' && \Input::get('fields')) { $session['CURRENT'][$this->strTable] = \Input::post('all_fields'); $this->Session->setData($session); } // Add fields $fields = $session['CURRENT'][$this->strTable]; if (!empty($fields) && is_array($fields) && \Input::get('fields')) { $class = 'tl_tbox'; $formFields = array(); // Save record if (\Input::post('FORM_SUBMIT') == $this->strTable) { foreach ($ids as $id) { $this->intId = $id; $this->procedure = array('id=?'); $this->values = array($this->intId); $this->blnCreateNewVersion = false; // Get the field values $objRow = $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE id=?")->limit(1)->execute($this->intId); // Store the active record $this->objActiveRecord = $objRow; $objVersions = new \Versions($this->strTable, $this->intId); $objVersions->initialize(); // Store all fields foreach ($fields as $v) { // Check whether field is excluded if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['exclude']) { continue; } $this->strField = $v; $this->strInputName = $v; $this->varValue = ''; // Make sure the new value is applied $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['alwaysSave'] = true; // Store value $this->row(); } // Post processing if (!$this->noReload) { // Call the onsubmit_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->{$callback[0]}->{$callback[1]}($this); } elseif (is_callable($callback)) { $callback($this); } } } // Create a new version if ($this->blnCreateNewVersion) { $objVersions->create(); // Call the onversion_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['onversion_callback'])) { @trigger_error('Using the onversion_callback has been deprecated and will no longer work in Contao 5.0. Use the oncreate_version_callback instead.', E_USER_DEPRECATED); foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['onversion_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->{$callback[0]}->{$callback[1]}($this->strTable, $this->intId, $this); } elseif (is_callable($callback)) { $callback($this->strTable, $this->intId, $this); } } } } // Set the current timestamp (-> DO NOT CHANGE ORDER version - timestamp) if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable']) { $this->Database->prepare("UPDATE " . $this->strTable . " SET ptable=?, tstamp=? WHERE id=?")->execute($this->ptable, time(), $this->intId); } else { $this->Database->prepare("UPDATE " . $this->strTable . " SET tstamp=? WHERE id=?")->execute(time(), $this->intId); } } } } $blnIsFirst = true; // Begin current row $return .= ' <div class="' . $class . '">'; foreach ($fields as $v) { // Check whether field is excluded if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['exclude']) { continue; } $formFields[] = $v; $this->intId = 0; $this->procedure = array('id=?'); $this->values = array($this->intId); $this->strField = $v; $this->strInputName = $v; $this->varValue = ''; // Autofocus the first field if ($blnIsFirst && $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'text') { $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['autofocus'] = 'autofocus'; $blnIsFirst = false; } // Disable auto-submit $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['submitOnChange'] = false; $return .= $this->row(); } // Close box $return .= ' <input type="hidden" name="FORM_FIELDS[]" value="' . specialchars(implode(',', $formFields)) . '"> </div>'; // Submit buttons $arrButtons = array(); $arrButtons['save'] = '<input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['save']) . '">'; $arrButtons['saveNclose'] = '<input type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['saveNclose']) . '">'; // Call the buttons_callback (see #4691) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $arrButtons = $this->{$callback[0]}->{$callback[1]}($arrButtons, $this); } elseif (is_callable($callback)) { $arrButtons = $callback($arrButtons, $this); } } } // Add the form $return = ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="' . $this->strTable . '" class="tl_form" method="post" enctype="' . ($this->blnUploadable ? 'multipart/form-data' : 'application/x-www-form-urlencoded') . '"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="' . $this->strTable . '"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '">' . ($this->noReload ? ' <p class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['general'] . '</p>' : '') . $return . ' </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> ' . implode(' ', $arrButtons) . ' </div> </div> </form>'; // Set the focus if there is an error if ($this->noReload) { $return .= ' <script> window.addEvent(\'domready\', function() { Backend.vScrollTo(($(\'' . $this->strTable . '\').getElement(\'label.error\').getPosition().y - 20)); }); </script>'; } // Reload the page to prevent _POST variables from being sent twice if (\Input::post('FORM_SUBMIT') == $this->strTable && !$this->noReload) { if (\Input::post('saveNclose')) { \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->redirect($this->getReferer()); } $this->reload(); } } else { $options = ''; $fields = array(); // Add fields of the current table $fields = array_merge($fields, array_keys($GLOBALS['TL_DCA'][$this->strTable]['fields'])); // Add meta fields if the current user is an administrator if ($this->User->isAdmin) { if ($this->Database->fieldExists('sorting', $this->strTable) && !in_array('sorting', $fields)) { array_unshift($fields, 'sorting'); } if ($this->Database->fieldExists('pid', $this->strTable) && !in_array('pid', $fields)) { array_unshift($fields, 'pid'); } } // Show all non-excluded fields foreach ($fields as $field) { if ($field == 'pid' || $field == 'sorting' || !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['exclude'] && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['doNotShow'] && (strlen($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['inputType']) || is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['input_field_callback']))) { $options .= ' <input type="checkbox" name="all_fields[]" id="all_' . $field . '" class="tl_checkbox" value="' . specialchars($field) . '"> <label for="all_' . $field . '" class="tl_checkbox_label">' . ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['label'][0] ?: $GLOBALS['TL_LANG']['MSC'][$field][0]) . '</label><br>'; } } $blnIsError = $_POST && empty($_POST['all_fields']); // Return the select menu $return .= ' <form action="' . ampersand(\Environment::get('request'), true) . '&fields=1" id="' . $this->strTable . '_all" class="tl_form" method="post"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="' . $this->strTable . '_all"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '">' . ($blnIsError ? ' <p class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['general'] . '</p>' : '') . ' <div class="tl_tbox"> <fieldset class="tl_checkbox_container"> <legend' . ($blnIsError ? ' class="error"' : '') . '>' . $GLOBALS['TL_LANG']['MSC']['all_fields'][0] . '</legend> <input type="checkbox" id="check_all" class="tl_checkbox" onclick="Backend.toggleCheckboxes(this)"> <label for="check_all" style="color:#a6a6a6"><em>' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</em></label><br>' . $options . ' </fieldset>' . ($blnIsError ? ' <p class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['all_fields'] . '</p>' : (\Config::get('showHelp') && strlen($GLOBALS['TL_LANG']['MSC']['all_fields'][1]) ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['MSC']['all_fields'][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']['MSC']['continue']) . '"> </div> </div> </form>'; } // Return 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>' . $return; }
/** * Load the source editor * * @return string */ public function source() { $this->isValid($this->intId); if (is_dir(TL_ROOT . '/' . $this->intId)) { $this->log('Folder "' . $this->intId . '" cannot be edited', __METHOD__, TL_ERROR); $this->redirect('contao/main.php?act=error'); } elseif (!file_exists(TL_ROOT . '/' . $this->intId)) { $this->log('File "' . $this->intId . '" does not exist', __METHOD__, TL_ERROR); $this->redirect('contao/main.php?act=error'); } $this->import('BackendUser', 'User'); // Check user permission if (!$this->User->hasAccess('f5', 'fop')) { $this->log('Not enough permissions to edit the file source of file "' . $this->intId . '"', __METHOD__, TL_ERROR); $this->redirect('contao/main.php?act=error'); } $objFile = new \File($this->intId, true); // Check whether file type is editable if (!in_array($objFile->extension, trimsplit(',', strtolower(\Config::get('editableFiles'))))) { $this->log('File type "' . $objFile->extension . '" (' . $this->intId . ') is not allowed to be edited', __METHOD__, TL_ERROR); $this->redirect('contao/main.php?act=error'); } $objMeta = null; $objVersions = null; // Add the versioning routines if ($this->blnIsDbAssisted && \Dbafs::shouldBeSynchronized($this->intId)) { $objMeta = \FilesModel::findByPath($objFile->value); if ($objMeta === null) { $objMeta = \Dbafs::addResource($objFile->value); } $objVersions = new \Versions($this->strTable, $objMeta->id); if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['hideVersionMenu']) { // Compare versions if (\Input::get('versions')) { $objVersions->compare(); } // Restore a version if (\Input::post('FORM_SUBMIT') == 'tl_version' && \Input::post('version') != '') { $objVersions->restore(\Input::post('version')); // Purge the script cache (see #7005) if ($objFile->extension == 'css' || $objFile->extension == 'scss' || $objFile->extension == 'less') { $this->import('Automator'); $this->Automator->purgeScriptCache(); } $this->reload(); } } $objVersions->initialize(); } $strContent = $objFile->getContent(); if ($objFile->extension == 'svgz') { $strContent = gzdecode($strContent); } // Process the request if (\Input::post('FORM_SUBMIT') == 'tl_files') { // Restore the basic entities (see #7170) $strSource = \StringUtil::restoreBasicEntities(\Input::postRaw('source')); // Save the file if (md5($strContent) != md5($strSource)) { if ($objFile->extension == 'svgz') { $strSource = gzencode($strSource); } // Write the file $objFile->write($strSource); $objFile->close(); // Update the database if ($this->blnIsDbAssisted && $objMeta !== null) { /** @var \FilesModel $objMeta */ $objMeta->hash = $objFile->hash; $objMeta->save(); $objVersions->create(); } // Purge the script cache (see #7005) if ($objFile->extension == 'css' || $objFile->extension == 'scss' || $objFile->extension == 'less') { $this->import('Automator'); $this->Automator->purgeScriptCache(); } } if (\Input::post('saveNclose')) { \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->redirect($this->getReferer()); } $this->reload(); } $codeEditor = ''; // Prepare the code editor if (\Config::get('useCE')) { $selector = 'ctrl_source'; $type = $objFile->extension; // Load the code editor configuration ob_start(); include TL_ROOT . '/system/config/ace.php'; $codeEditor = ob_get_contents(); ob_end_clean(); unset($selector, $type); } // Versions overview if ($GLOBALS['TL_DCA'][$this->strTable]['config']['enableVersioning'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['hideVersionMenu'] && $this->blnIsDbAssisted && $objVersions !== null) { $version = $objVersions->renderDropdown(); } else { $version = ''; } // Submit buttons $arrButtons = array(); $arrButtons['save'] = '<input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['save']) . '">'; $arrButtons['saveNclose'] = '<input type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['saveNclose']) . '">'; // Call the buttons_callback (see #4691) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $arrButtons = $this->{$callback[0]}->{$callback[1]}($arrButtons, $this); } elseif (is_callable($callback)) { $arrButtons = $callback($arrButtons, $this); } } } // Add the form return $version . ' <div id="tl_buttons"> <a href="' . $this->getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_files" class="tl_form" method="post"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_files"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <div class="tl_tbox"> <h3><label for="ctrl_source">' . $GLOBALS['TL_LANG']['tl_files']['editor'][0] . '</label></h3> <textarea name="source" id="ctrl_source" class="tl_textarea monospace" rows="12" cols="80" style="height:400px" onfocus="Backend.getScrollOffset()">' . "\n" . htmlspecialchars($strContent) . '</textarea>' . (\Config::get('showHelp') && strlen($GLOBALS['TL_LANG']['tl_files']['editor'][1]) ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_files']['editor'][1] . '</p>' : '') . ' </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> ' . implode(' ', $arrButtons) . ' </div> </div> </form>' . "\n\n" . $codeEditor; }
/** * Auto-generate a form to edit the local configuration file * * @return string */ public function edit() { $return = ''; $ajaxId = null; if (\Environment::get('isAjaxRequest')) { $ajaxId = func_get_arg(1); } // Build an array from boxes and rows $this->strPalette = $this->getPalette(); $boxes = trimsplit(';', $this->strPalette); $legends = array(); if (!empty($boxes)) { foreach ($boxes as $k => $v) { $boxes[$k] = trimsplit(',', $v); foreach ($boxes[$k] as $kk => $vv) { if (preg_match('/^\\[.*\\]$/', $vv)) { continue; } if (preg_match('/^\\{.*\\}$/', $vv)) { $legends[$k] = substr($vv, 1, -1); unset($boxes[$k][$kk]); } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$vv]['exclude'] || !is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$vv])) { unset($boxes[$k][$kk]); } } // Unset a box if it does not contain any fields if (empty($boxes[$k])) { unset($boxes[$k]); } } // Render boxes $class = 'tl_tbox'; $fs = $this->Session->get('fieldset_states'); $blnIsFirst = true; foreach ($boxes as $k => $v) { $strAjax = ''; $blnAjax = false; $key = ''; $cls = ''; $legend = ''; if (isset($legends[$k])) { list($key, $cls) = explode(':', $legends[$k]); $legend = "\n" . '<legend onclick="AjaxRequest.toggleFieldset(this, \'' . $key . '\', \'' . $this->strTable . '\')">' . (isset($GLOBALS['TL_LANG'][$this->strTable][$key]) ? $GLOBALS['TL_LANG'][$this->strTable][$key] : $key) . '</legend>'; } if (isset($fs[$this->strTable][$key])) { $class .= $fs[$this->strTable][$key] ? '' : ' collapsed'; } else { $class .= $cls && $legend ? ' ' . $cls : ''; } $return .= "\n\n" . '<fieldset' . ($key ? ' id="pal_' . $key . '"' : '') . ' class="' . $class . ($legend ? '' : ' nolegend') . '">' . $legend; // Build rows of the current box foreach ($v as $vv) { if ($vv == '[EOF]') { if ($blnAjax && \Environment::get('isAjaxRequest')) { return $strAjax . '<input type="hidden" name="FORM_FIELDS[]" value="' . specialchars($this->strPalette) . '">'; } $blnAjax = false; $return .= "\n " . '</div>'; continue; } if (preg_match('/^\\[.*\\]$/', $vv)) { $thisId = 'sub_' . substr($vv, 1, -1); $blnAjax = $ajaxId == $thisId && \Environment::get('isAjaxRequest') ? true : false; $return .= "\n " . '<div id="' . $thisId . '">'; continue; } $this->strField = $vv; $this->strInputName = $vv; $this->varValue = \Config::get($this->strField); // Handle entities if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'text' || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'textarea') { if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['multiple']) { $this->varValue = deserialize($this->varValue); } if (!is_array($this->varValue)) { $this->varValue = htmlspecialchars($this->varValue); } else { foreach ($this->varValue as $k => $v) { $this->varValue[$k] = htmlspecialchars($v); } } } // Autofocus the first field if ($blnIsFirst && $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'text') { $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['autofocus'] = 'autofocus'; $blnIsFirst = false; } // Call load_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->varValue = $this->{$callback[0]}->{$callback[1]}($this->varValue, $this); } elseif (is_callable($callback)) { $this->varValue = $callback($this->varValue, $this); } } } // Build row $blnAjax ? $strAjax .= $this->row() : ($return .= $this->row()); } $class = 'tl_box'; $return .= "\n" . '</fieldset>'; } } $this->import('Files'); // Check whether the target file is writeable if (!$this->Files->is_writeable('system/config/localconfig.php')) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['notWriteable'], 'system/config/localconfig.php')); } // Submit buttons $arrButtons = array(); $arrButtons['save'] = '<input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['save']) . '">'; $arrButtons['saveNclose'] = '<input type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['saveNclose']) . '">'; // Call the buttons_callback (see #4691) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $arrButtons = $this->{$callback[0]}->{$callback[1]}($arrButtons, $this); } elseif (is_callable($callback)) { $arrButtons = $callback($arrButtons, $this); } } } // Add the buttons and end the form $return .= ' </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> ' . implode(' ', $arrButtons) . ' </div> </div> </form> <script> window.addEvent(\'domready\', function() { Theme.focusInput("' . $this->strTable . '"); }); </script>'; // Begin the form (-> DO NOT CHANGE THIS ORDER -> this way the onsubmit attribute of the form can be changed by a field) $return = ' <div id="tl_buttons"> <a href="' . $this->getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="' . $this->strTable . '" class="tl_form" method="post"' . (!empty($this->onsubmit) ? ' onsubmit="' . implode(' ', $this->onsubmit) . '"' : '') . '> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="' . specialchars($this->strTable) . '"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="FORM_FIELDS[]" value="' . specialchars($this->strPalette) . '">' . ($this->noReload ? ' <p class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['general'] . '</p>' : '') . $return; // Reload the page to prevent _POST variables from being sent twice if (\Input::post('FORM_SUBMIT') == $this->strTable && !$this->noReload) { // Call onsubmit_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->{$callback[0]}->{$callback[1]}($this); } elseif (is_callable($callback)) { $callback($this); } } } // Reload if (\Input::post('saveNclose')) { \Message::reset(); \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->redirect($this->getReferer()); } $this->reload(); } // Set the focus if there is an error if ($this->noReload) { $return .= ' <script> window.addEvent(\'domready\', function() { Backend.vScrollTo(($(\'' . $this->strTable . '\').getElement(\'label.error\').getPosition().y - 20)); }); </script>'; } return $return; }
/** * 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'))); }
/** * 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>'; }
/** * Return a form to choose a CSV file and import it * * @param DataContainer $dc * * @return string */ public function importList(DataContainer $dc) { if (\Input::get('key') != 'list') { return ''; } $this->import('BackendUser', 'User'); $class = $this->User->uploader; // See #4086 and #7046 if (!class_exists($class) || $class == 'DropZone') { $class = 'FileUpload'; } /** @var FileUpload $objUploader */ $objUploader = new $class(); // Import CSS if (\Input::post('FORM_SUBMIT') == 'tl_list_import') { $arrUploaded = $objUploader->uploadTo('system/tmp'); if (empty($arrUploaded)) { \Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); $this->reload(); } $this->import('Database'); $arrList = array(); foreach ($arrUploaded as $strCsvFile) { $objFile = new \File($strCsvFile); if ($objFile->extension != 'csv') { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension)); continue; } // Get separator switch (\Input::post('separator')) { case 'semicolon': $strSeparator = ';'; break; case 'tabulator': $strSeparator = "\t"; break; case 'linebreak': $strSeparator = "\n"; break; default: $strSeparator = ','; break; } $resFile = $objFile->handle; while (($arrRow = @fgetcsv($resFile, null, $strSeparator)) !== false) { $arrList = array_merge($arrList, $arrRow); } } $objVersions = new \Versions($dc->table, \Input::get('id')); $objVersions->create(); $this->Database->prepare("UPDATE " . $dc->table . " SET listitems=? WHERE id=?")->execute(serialize($arrList), \Input::get('id')); \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->redirect(str_replace('&key=list', '', \Environment::get('request'))); } // Return form return ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=list', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_list_import" class="tl_form" method="post" enctype="multipart/form-data"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_list_import"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="MAX_FILE_SIZE" value="' . \Config::get('maxFileSize') . '"> <div class="tl_tbox"> <h3><label for="separator">' . $GLOBALS['TL_LANG']['MSC']['separator'][0] . '</label></h3> <select name="separator" id="separator" class="tl_select" onfocus="Backend.getScrollOffset()"> <option value="comma">' . $GLOBALS['TL_LANG']['MSC']['comma'] . '</option> <option value="semicolon">' . $GLOBALS['TL_LANG']['MSC']['semicolon'] . '</option> <option value="tabulator">' . $GLOBALS['TL_LANG']['MSC']['tabulator'] . '</option> <option value="linebreak">' . $GLOBALS['TL_LANG']['MSC']['linebreak'] . '</option> </select>' . ($GLOBALS['TL_LANG']['MSC']['separator'][1] != '' ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['MSC']['separator'][1] . '</p>' : '') . ' <h3>' . $GLOBALS['TL_LANG']['MSC']['source'][0] . '</h3>' . $objUploader->generateMarkup() . (isset($GLOBALS['TL_LANG']['MSC']['source'][1]) ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['MSC']['source'][1] . '</p>' : '') . ' </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <button type="submit" name="save" id="save" class="tl_submit" accesskey="s">' . $GLOBALS['TL_LANG']['MSC']['lw_import'][0] . '</button> </div> </div> </form>'; }
/** * Return a form to choose an existing style sheet and import it * * @return string * * @throws \Exception */ public function importStyleSheet() { if (\Input::get('key') != 'import') { return ''; } $this->import('BackendUser', 'User'); $class = $this->User->uploader; // See #4086 and #7046 if (!class_exists($class) || $class == 'DropZone') { $class = 'FileUpload'; } /** @var \FileUpload $objUploader */ $objUploader = new $class(); // Import CSS if (\Input::post('FORM_SUBMIT') == 'tl_style_sheet_import') { $arrUploaded = $objUploader->uploadTo('system/tmp'); if (empty($arrUploaded)) { \Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); $this->reload(); } foreach ($arrUploaded as $strCssFile) { // Folders cannot be imported if (is_dir(TL_ROOT . '/' . $strCssFile)) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['importFolder'], basename($strCssFile))); continue; } $objFile = new \File($strCssFile, true); // Check the file extension if ($objFile->extension != 'css') { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension)); continue; } // Check the file name $strName = preg_replace('/\\.css$/i', '', basename($strCssFile)); $strName = $this->checkStyleSheetName($strName); // Create the new style sheet $objStyleSheet = $this->Database->prepare("INSERT INTO tl_style_sheet (pid, tstamp, name, media) VALUES (?, ?, ?, ?)")->execute(\Input::get('id'), time(), $strName, array('all')); $insertId = $objStyleSheet->insertId; if (!is_numeric($insertId) || $insertId < 0) { throw new \Exception('Invalid insert ID'); } // Read the file and remove carriage returns $strFile = $objFile->getContent(); $strFile = str_replace("\r", '', $strFile); $arrTokens = array(); $strBuffer = ''; $intSorting = 0; $strComment = ''; $strCategory = ''; $intLength = strlen($strFile); // Tokenize for ($i = 0; $i < $intLength; $i++) { $char = $strFile[$i]; // Whitespace if ($char == '' || $char == "\n" || $char == "\t") { // Ignore } elseif ($char == '/') { if ($strFile[$i + 1] == '*') { while ($i < $intLength) { $strBuffer .= $strFile[$i++]; if ($strFile[$i] == '/' && $strFile[$i - 1] == '*') { $arrTokens[] = array('type' => 'comment', 'content' => $strBuffer . $strFile[$i]); $strBuffer = ''; break; } } } } elseif ($char == '@') { $intLevel = 0; $strSelector = ''; while ($i < $intLength) { $strBuffer .= $strFile[$i++]; if ($strFile[$i] == '{') { if (++$intLevel == 1) { ++$i; $strSelector = $strBuffer; $strBuffer = ''; } } elseif ($strFile[$i] == '}') { if (--$intLevel == 0) { $arrTokens[] = array('type' => 'atblock', 'selector' => $strSelector, 'content' => $strBuffer); $strBuffer = ''; break; } } } } else { $strSelector = ''; while ($i < $intLength) { $strBuffer .= $strFile[$i++]; if ($strFile[$i] == '{') { ++$i; $strSelector = $strBuffer; $strBuffer = ''; } elseif ($strFile[$i] == '}') { $arrTokens[] = array('type' => 'block', 'selector' => $strSelector, 'content' => $strBuffer); $strBuffer = ''; break; } } } } foreach ($arrTokens as $arrToken) { // Comments if ($arrToken['type'] == 'comment') { // Category (comments start with /** and contain only one line) if (strncmp($arrToken['content'], '/**', 3) === 0 && substr_count($arrToken['content'], "\n") == 2) { $strCategory = trim(str_replace(array('/*', '*/', '*'), '', $arrToken['content'])); } elseif (strpos($arrToken['content'], "\n") === false) { $strComment = trim(str_replace(array('/*', '*/', '*'), '', $arrToken['content'])); } } elseif ($arrToken['type'] == 'atblock') { $arrSet = array('pid' => $insertId, 'category' => $strCategory, 'comment' => $strComment, 'sorting' => $intSorting += 128, 'selector' => trim($arrToken['selector']), 'own' => $arrToken['content']); $this->Database->prepare("INSERT INTO tl_style %s")->set($arrSet)->execute(); $strComment = ''; } else { $arrDefinition = array('pid' => $insertId, 'category' => $strCategory, 'comment' => $strComment, 'sorting' => $intSorting += 128, 'selector' => trim($arrToken['selector']), 'attributes' => $arrToken['content']); $this->createDefinition($arrDefinition); $strComment = ''; } } // Write the style sheet $this->updateStyleSheet($insertId); // Notify the user if ($strName . '.css' != basename($strCssFile)) { \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_style_sheet']['css_renamed'], basename($strCssFile), $strName . '.css')); } else { \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_style_sheet']['css_imported'], $strName . '.css')); } } // Redirect \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->redirect(str_replace('&key=import', '', \Environment::get('request'))); } // Return form return ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=import', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_style_sheet_import" class="tl_form" method="post" enctype="multipart/form-data"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_style_sheet_import"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="MAX_FILE_SIZE" value="' . \Config::get('maxFileSize') . '"> <div class="tl_tbox"> <h3>' . $GLOBALS['TL_LANG']['tl_style_sheet']['source'][0] . '</h3>' . $objUploader->generateMarkup() . (isset($GLOBALS['TL_LANG']['tl_style_sheet']['source'][1]) ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_style_sheet']['source'][1] . '</p>' : '') . ' </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_style_sheet']['import'][0]) . '"> </div> </div> </form>'; }
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(); }
/** * Auto-generate a form to edit the current database record * @param integer * @param integer * @return string */ public function edit($intID = false, $ajaxId = false) { if ($GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable']) { \System::log('Table ' . $this->strTable . ' is not editable', __METHOD__, TL_ERROR); \Controller::redirect('contao/main.php?act=error'); } if ($intID) { $this->intId = $intID; } // Get the current record $objRow = \Database::getInstance()->prepare("SELECT * FROM {$this->strTable} WHERE id=?")->limit(1)->execute($this->intId); // Redirect if there is no record with the given ID if ($objRow->numRows < 1) { \System::log('Could not load record "' . $this->strTable . '.id=' . $this->intId . '"', __METHOD__, TL_ERROR); \Controller::redirect('contao/main.php?act=error'); } elseif ($objRow->language != '') { \System::log('Cannot edit language record "' . $this->strTable . '.id=' . $this->intId . '"', __METHOD__, TL_ERROR); \Controller::redirect('contao/main.php?act=error'); } $this->objActiveRecord = $objRow; $return = ''; $this->values[] = $this->intId; $this->procedure[] = 'id=?'; $this->blnCreateNewVersion = false; $objVersions = new \Versions($this->strTable, $this->intId); // Compare versions if (\Input::get('versions')) { $objVersions->compare(); } // Restore a version if (\Input::post('FORM_SUBMIT') == 'tl_version' && \Input::post('version') != '') { $objVersions->restore(\Input::post('version')); $this->reload(); } $objVersions->initialize(); // Load and/or change language $this->blnEditLanguage = false; if (!empty($this->arrTranslations)) { $blnLanguageUpdated = false; $session = $this->Session->getData(); if (\Input::post('FORM_SUBMIT') == 'tl_language') { if (in_array(\Input::post('language'), $this->arrTranslations)) { $session['language'][$this->strTable][$this->intId] = \Input::post('language'); } else { unset($session['language'][$this->strTable][$this->intId]); } $blnLanguageUpdated = true; } elseif (\Input::post('FORM_SUBMIT') == $this->strTable && isset($_POST['deleteLanguage'])) { $this->Database->prepare("DELETE FROM {$this->strTable} WHERE pid=? AND language=?")->execute($this->intId, $session['language'][$this->strTable][$this->intId]); unset($session['language'][$this->strTable][$this->intId]); $blnLanguageUpdated = true; } if ($blnLanguageUpdated) { $this->Session->setData($session); $_SESSION['TL_INFO'] = ''; \Controller::reload(); } if ($_SESSION['BE_DATA']['language'][$this->strTable][$this->intId] != '' && in_array($_SESSION['BE_DATA']['language'][$this->strTable][$this->intId], $this->arrTranslations)) { $objRow = $this->Database->prepare("SELECT * FROM {$this->strTable} WHERE pid=? AND language=?")->execute($this->intId, $_SESSION['BE_DATA']['language'][$this->strTable][$this->intId]); if (!$objRow->numRows) { $intId = $this->Database->prepare("INSERT INTO {$this->strTable} (pid,tstamp,language) VALUES (?,?,?)")->execute($this->intId, time(), $_SESSION['BE_DATA']['language'][$this->strTable][$this->intId])->insertId; $objRow = $this->Database->prepare("SELECT * FROM {$this->strTable} WHERE id=?")->execute($intId); } $this->objActiveRecord = $objRow; $this->values = array($this->intId, $_SESSION['BE_DATA']['language'][$this->strTable][$this->intId]); $this->procedure = array('pid=?', 'language=?'); $this->blnEditLanguage = true; } } // Build an array from boxes and rows $this->strPalette = $this->getPalette(); $boxes = trimsplit(';', $this->strPalette); $legends = array(); if (!empty($boxes)) { foreach ($boxes as $k => $v) { $eCount = 1; $boxes[$k] = trimsplit(',', $v); foreach ($boxes[$k] as $kk => $vv) { if (preg_match('/^\\[.*\\]$/i', $vv)) { ++$eCount; continue; } if (preg_match('/^\\{.*\\}$/', $vv)) { $legends[$k] = substr($vv, 1, -1); unset($boxes[$k][$kk]); } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$vv]['exclude'] || !is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$vv])) { unset($boxes[$k][$kk]); } elseif ($this->blnEditLanguage && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$vv]['attributes']['multilingual']) { unset($boxes[$k][$kk]); } } // Unset a box if it does not contain any fields if (count($boxes[$k]) < $eCount) { unset($boxes[$k]); } } $class = 'tl_tbox'; $fs = $this->Session->get('fieldset_states'); $blnIsFirst = true; // Render boxes foreach ($boxes as $k => $v) { $strAjax = ''; $blnAjax = false; $key = ''; $cls = ''; $legend = ''; if (isset($legends[$k])) { list($key, $cls) = explode(':', $legends[$k]); $legend = "\n" . '<legend onclick="AjaxRequest.toggleFieldset(this,\'' . $key . '\',\'' . $this->strTable . '\')">' . (isset($GLOBALS['TL_LANG'][$this->strTable][$key]) ? $GLOBALS['TL_LANG'][$this->strTable][$key] : $key) . '</legend>'; } if (isset($fs[$this->strTable][$key])) { $class .= $fs[$this->strTable][$key] ? '' : ' collapsed'; } else { $class .= $cls && $legend ? ' ' . $cls : ''; } $return .= "\n\n" . '<fieldset' . ($key ? ' id="pal_' . $key . '"' : '') . ' class="' . $class . ($legend ? '' : ' nolegend') . '">' . $legend; // Build rows of the current box foreach ($v as $vv) { if ($vv == '[EOF]') { if ($blnAjax && \Environment::get('isAjaxRequest')) { return $strAjax . '<input type="hidden" name="FORM_FIELDS[]" value="' . specialchars($this->strPalette) . '">'; } $blnAjax = false; $return .= "\n" . '</div>'; continue; } if (preg_match('/^\\[.*\\]$/', $vv)) { $thisId = 'sub_' . substr($vv, 1, -1); $blnAjax = $ajaxId == $thisId && \Environment::get('isAjaxRequest') ? true : false; $return .= "\n" . '<div id="' . $thisId . '">'; continue; } $this->strField = $vv; $this->strInputName = $vv; $this->varValue = $this->objActiveRecord->{$vv}; // Autofocus the first field if ($blnIsFirst && $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'text') { $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['autofocus'] = 'autofocus'; $blnIsFirst = false; } // Convert CSV fields (see #2890) if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['multiple'] && isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv'])) { $this->varValue = trimsplit($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv'], $this->varValue); } // Call load_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->varValue = $this->{$callback}[0]->{$callback}[1]($this->varValue, $this); } elseif (is_callable($callback)) { $this->varValue = call_user_func($callback, $this->varValue, $this); } } } // Re-set the current value $this->objActiveRecord->{$this->strField} = $this->varValue; // Build the row and pass the current palette string (thanks to Tristan Lins) $blnAjax ? $strAjax .= $this->row($this->strPalette) : ($return .= $this->row($this->strPalette)); } $class = 'tl_box'; $return .= "\n" . '</fieldset>'; } } $version = ''; // Versions overview if ($GLOBALS['TL_DCA'][$this->strTable]['config']['enableVersioning']) { $version = $objVersions->renderDropdown(); } if ('' === $version) { $version = '<div class="tl_version_panel"></div>'; } // Check languages if (!empty($this->arrTranslations)) { $arrAvailableLanguages = $this->Database->prepare("SELECT language FROM {$this->strTable} WHERE pid=?")->execute($this->intId)->fetchEach('language'); $available = ''; $undefined = ''; foreach ($this->arrTranslations as $language) { if (in_array($language, $arrAvailableLanguages)) { if ($_SESSION['BE_DATA']['language'][$this->strTable][$this->intId] == $language) { $available .= '<option value="' . $language . '" selected="selected">' . $this->arrTranslationLabels[$language] . '</option>'; $_SESSION['TL_INFO'] = array($GLOBALS['TL_LANG']['MSC']['editingLanguage']); } else { $available .= '<option value="' . $language . '">' . $this->arrTranslationLabels[$language] . '</option>'; } } else { $undefined .= '<option value="' . $language . '">' . $this->arrTranslationLabels[$language] . ' (' . $GLOBALS['TL_LANG']['MSC']['undefinedLanguage'] . ')' . '</option>'; } } $version = str_replace('<div class="tl_version_panel">', '<div class="tl_version_panel tl_iso_products_panel"> <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_language" class="tl_form" method="post"> <div class="tl_formbody"> <input type="hidden" name="FORM_SUBMIT" value="tl_language"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <select name="language" class="tl_select' . (strlen($_SESSION['BE_DATA']['language'][$this->strTable][$this->intId]) ? ' active' : '') . '" onchange="document.id(this).getParent(\'form\').submit()"> <option value="">' . $GLOBALS['TL_LANG']['MSC']['defaultLanguage'] . '</option>' . $available . $undefined . ' </select> <noscript> <input type="submit" name="editLanguage" class="tl_submit" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['editLanguage']) . '"> </noscript> </div> </form>', $version); } // Submit buttons $arrButtons = array(); $arrButtons['save'] = '<input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['save']) . '">'; if (!\Input::get('nb')) { $arrButtons['saveNclose'] = '<input type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['saveNclose']) . '">'; } if (!\Input::get('popup') && !$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable']) { $arrButtons['saveNcreate'] = '<input type="submit" name="saveNcreate" id="saveNcreate" class="tl_submit" accesskey="n" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['saveNcreate']) . '">'; } if (\Input::get('s2e')) { $arrButtons['saveNedit'] = '<input type="submit" name="saveNedit" id="saveNedit" class="tl_submit" accesskey="e" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['saveNedit']) . '">'; } elseif (!\Input::get('popup') && ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4 || strlen($this->ptable) || $GLOBALS['TL_DCA'][$this->strTable]['config']['switchToEdit'])) { $arrButtons['saveNback'] = '<input type="submit" name="saveNback" id="saveNback" class="tl_submit" accesskey="g" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['saveNback']) . '">'; } if ($this->blnEditLanguage) { $arrButtons['deleteLanguage'] = '<input type="submit" name="deleteLanguage" class="tl_submit" style="float:right" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['deleteLanguage']) . '" onclick="return confirm(\'' . $GLOBALS['TL_LANG']['MSC']['deleteLanguageConfirm'] . '\')">'; } // Call the buttons_callback (see #4691) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $arrButtons = $this->{$callback}[0]->{$callback}[1]($arrButtons, $this); } elseif (is_callable($callback)) { $arrButtons = $callback($arrButtons, $this); } } } // Add the buttons and end the form $return .= ' </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> ' . implode(' ', $arrButtons) . ' </div> </div> </form> <script> window.addEvent(\'domready\', function() { Theme.focusInput("' . $this->strTable . '"); }); </script>'; $copyFallback = $this->blnEditLanguage ? ' :: <a href="' . \Backend::addToUrl('act=copyFallback') . '" class="header_iso_copy" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['copyFallback']) . '" accesskey="d" onclick="Backend.getScrollOffset();">' . ($GLOBALS['TL_LANG']['MSC']['copyFallback'] ? $GLOBALS['TL_LANG']['MSC']['copyFallback'] : 'copyFallback') . '</a>' : ''; // Begin the form (-> DO NOT CHANGE THIS ORDER -> this way the onsubmit attribute of the form can be changed by a field) $return = $version . ' <div id="tl_buttons">' . (\Input::get('nb') ? ' ' : ' <a href="' . \System::getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a>') . $copyFallback . ' </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="' . $this->strTable . '" class="tl_form" method="post" enctype="' . ($this->blnUploadable ? 'multipart/form-data' : 'application/x-www-form-urlencoded') . '"' . (!empty($this->onsubmit) ? ' onsubmit="' . implode(' ', $this->onsubmit) . '"' : '') . '> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="' . specialchars($this->strTable) . '"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="FORM_FIELDS[]" value="' . specialchars($this->strPalette) . '">' . ($this->noReload ? ' <p class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['general'] . '</p>' : '') . $return; // Reload the page to prevent _POST variables from being sent twice if (\Input::post('FORM_SUBMIT') == $this->strTable && !$this->noReload) { $arrValues = $this->values; array_unshift($arrValues, time()); // Trigger the onsubmit_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->{$callback}[0]->{$callback}[1]($this); } elseif (is_callable($callback)) { call_user_func($callback, $this); } } } // Save the current version if ($this->blnCreateNewVersion) { $objVersions->create(); // Call the onversion_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['onversion_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['onversion_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->{$callback}[0]->{$callback}[1]($this->strTable, $this->objActiveRecord->id, $this); } elseif (is_callable($callback)) { call_user_func($callback, $this->strTable, $this->objActiveRecord->id, $this); } } } \System::log('A new version of record "' . $this->strTable . '.id=' . $this->intId . '" has been created' . $this->getParentEntries($this->strTable, $this->intId), __METHOD__, TL_GENERAL); } // Set the current timestamp (-> DO NOT CHANGE THE ORDER version - timestamp) if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable']) { $this->Database->prepare("UPDATE " . $this->strTable . " SET ptable=?, tstamp=? WHERE id=?")->execute($this->ptable, time(), $this->intId); } else { $this->Database->prepare("UPDATE " . $this->strTable . " SET tstamp=? WHERE id=?")->execute(time(), $this->intId); } // Redirect if (isset($_POST['saveNclose'])) { \Message::reset(); \System::setCookie('BE_PAGE_OFFSET', 0, 0); \Controller::redirect(\System::getReferer()); } elseif (isset($_POST['saveNedit'])) { \Message::reset(); \System::setCookie('BE_PAGE_OFFSET', 0, 0); $strUrl = \Backend::addToUrl($GLOBALS['TL_DCA'][$this->strTable]['list']['operations']['edit']['href'], false); $strUrl = preg_replace('/(&)?(s2e|act)=[^&]*/i', '', $strUrl); \Controller::redirect($strUrl); } elseif (isset($_POST['saveNback'])) { \Message::reset(); \System::setCookie('BE_PAGE_OFFSET', 0, 0); if ($this->ptable == '') { \Controller::redirect(TL_SCRIPT . '?do=' . \Input::get('do')); } elseif ($this->ptable == 'tl_theme' && $this->strTable == 'tl_style_sheet' || $this->ptable == 'tl_page' && $this->strTable == 'tl_article') { \Controller::redirect(\System::getReferer(false, $this->strTable)); } else { \Controller::redirect(\System::getReferer(false, $this->ptable)); } } elseif (isset($_POST['saveNcreate'])) { \Message::reset(); \System::setCookie('BE_PAGE_OFFSET', 0, 0); $strUrl = TL_SCRIPT . '?do=' . \Input::get('do'); if (isset($_GET['table'])) { $strUrl .= '&table=' . \Input::get('table'); } // Tree view if ($this->treeView) { $strUrl .= '&act=create&mode=1&pid=' . $this->intId; } elseif ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4 || $this->activeRecord->pid > 0) { $strUrl .= $this->Database->fieldExists('sorting', $this->strTable) ? '&act=create&mode=1&pid=' . $this->intId . '&id=' . $this->activeRecord->pid : '&act=create&mode=2&pid=' . $this->activeRecord->pid; } else { $strUrl .= $this->ptable != '' ? '&act=create&mode=2&pid=' . CURRENT_ID : '&act=create'; } \Controller::redirect($strUrl . '&rt=' . REQUEST_TOKEN); } \Controller::reload(); } // Set the focus if there is an error if ($this->noReload) { $return .= ' <script> window.addEvent(\'domready\', function() { Backend.vScrollTo(($(\'' . $this->strTable . '\').getElement(\'label.error\').getPosition().y - 20)); }); </script>'; } return $return; }
/** * Return a form to choose an existing sermon and import it * @return string * @throws \Exception */ public function importSermon() { 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 Sermon if (\Input::post('FORM_SUBMIT') == 'tl_sermoner_items_import') { $uploadPath = \FilesModel::findByUuid(SermonArchiveModel::findByPk(\Input::get('id'))->directUploadDestination)->path; $arrUploaded = $objUploader->uploadTo($uploadPath); if (empty($arrUploaded)) { \Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); $this->reload(); } foreach ($arrUploaded as $strAudioFile) { // Folders cannot be imported if (is_dir(TL_ROOT . '/' . $strAudioFile)) { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['importFolder'], basename($strAudioFile))); continue; } $objFile = \Dbafs::addResource($strAudioFile); // Check the file extension if ($objFile->extension != 'mp3') { \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension)); continue; } $this->import('getid3'); $getID3 = new \getID3(); $ThisFileInfo = $getID3->analyze(TL_ROOT . '/' . $objFile->path); $metadata = $ThisFileInfo['tags']['id3v2']; //prepare date out of comment field $comment = array_pop($metadata['comment']); preg_match("/[0-9]{2}\\.{1}[0-9]{2}\\.[0-9]{4}/", $comment, $date); $date = new \Date($date[0]); $objSermon = $this->Database->prepare("INSERT INTO tl_sermoner_items (pid, tstamp, title, speaker, date, audioSingleSRC) VALUES (?,?,?,?,?,?)")->execute(\Input::get('id'), time(), $metadata['title'][0], $metadata['artist'][0], $date->timestamp, $objFile->uuid); $insertId = $objSermon->insertId; if (!is_numeric($insertId) || $insertId < 0) { throw new \Exception('Invalid insert ID'); } } // Redirect \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->redirect(str_replace('&key=import', '&act=edit&id=' . $insertId, \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_sermoner_items']['import'][1] . '</h2> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_sermoner_items_import" class="tl_form" method="post" enctype="multipart/form-data"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_sermoner_items_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_sermoner_items']['source'][0] . '</h3>' . $objUploader->generateMarkup() . (isset($GLOBALS['TL_LANG']['tl_sermoner_items']['source'][1]) ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_sermoner_items']['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_sermoner_items']['import'][0]) . '"> </div> </div> </form>'; }
/** * Load the current cart * @param Config * @return Cart */ public static function findForCurrentStore() { global $objPage; if (TL_MODE != 'FE' || null === $objPage || $objPage->rootId == 0) { return null; } $time = time(); $strHash = \Input::cookie(static::$strCookie); $intStore = (int) \PageModel::findByPk($objPage->rootId)->iso_store_id; // Check to see if the user is logged in. if (FE_USER_LOGGED_IN !== true) { if ($strHash == '') { $strHash = sha1(session_id() . (!$GLOBALS['TL_CONFIG']['disableIpCheck'] ? \Environment::get('ip') : '') . $intStore . static::$strCookie); \System::setCookie(static::$strCookie, $strHash, $time + $GLOBALS['TL_CONFIG']['iso_cartTimeout'], $GLOBALS['TL_CONFIG']['websitePath']); } $objCart = static::findOneBy(array('uniqid=?', 'store_id=?'), array($strHash, $intStore)); } else { $objCart = static::findOneBy(array('member=?', 'store_id=?'), array(\FrontendUser::getInstance()->id, $intStore)); } // Create new cart if ($objCart === null) { $objConfig = Config::findByRootPageOrFallback($objPage->rootId); $objCart = new static(); // Can't call the individual rows here, it would trigger markModified and a save() $objCart->setRow(array_merge($objCart->row(), array('tstamp' => $time, 'member' => FE_USER_LOGGED_IN === true ? \FrontendUser::getInstance()->id : 0, 'uniqid' => FE_USER_LOGGED_IN === true ? '' : $strHash, 'config_id' => $objConfig->id, 'store_id' => $intStore))); } else { $objCart->tstamp = $time; } return $objCart; }
/** * Import ZAD Send News managers from XML files. * @param Array */ protected function importFiles($files) { foreach ($files as $zipfile) { $xml = null; // open zip file $zip = new \ZipReader($zipfile); // extract XML file if ($zip->next() && $zip->file_name == 'sendnews.xml') { // load the XML file $xml = new \DOMDocument(); $xml->preserveWhiteSpace = false; $xml->loadXML($zip->unzip()); } // if there is no XML file, skip to next zip file if (!$xml instanceof \DOMDocument) { \Message::addError(sprintf($GLOBALS['TL_LANG']['tl_zad_sendnews']['err_import_xml'], basename($zipfile))); continue; } // read XML $tab = array(); $version = $xml->getElementsByTagName('tables')->item($i)->getAttribute('version'); if (!$version || $version != '2.0') { // warning: version is different! \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_zad_sendnews']['wrn_import_version'], basename($zipfile))); } $tables = $xml->getElementsByTagName('table'); for ($i = 0; $i < $tables->length; $i++) { // loop through tables $rows = $tables->item($i)->childNodes; $table = $tables->item($i)->getAttribute('name'); for ($j = 0; $j < $rows->length; $j++) { // loop through rows $fields = $rows->item($j)->childNodes; for ($k = 0; $k < $fields->length; $k++) { // loop through fields $value = $fields->item($k)->nodeValue; $name = $fields->item($k)->getAttribute('name'); $tab[$table][$j][$name] = $value; } } } // get current news archive id $news = $this->Database->prepare("SELECT id FROM tl_news_archive WHERE title=?")->limit(1)->execute($tab['tl_news_archive'][0]['title']); if ($news->numRows < 1) { // set first news archive $news = $this->Database->prepare("SELECT id FROM tl_news_archive ORDER BY id")->limit(1)->execute(); if ($news->numRows < 1) { // no news archive $news->id = 0; } } // set news archive id $tab['tl_zad_sendnews'][0]['news_archive'] = $news->id; // get current news author id $user = $this->Database->prepare("SELECT id FROM tl_user WHERE username=? OR name=? OR email=?")->limit(1)->execute($tab['tl_user'][0]['username'], $tab['tl_user'][0]['name'], $tab['tl_user'][0]['email']); if ($user->numRows < 1) { // set first user $user = $this->Database->prepare("SELECT id FROM tl_user ORDER BY id")->limit(1)->execute(); if ($user->numRows < 1) { // no news author $user->id = 0; } } // set news author id $tab['tl_zad_sendnews'][0]['news_author'] = $user->id; // set send news manager name $name = $this->Database->prepare("SELECT count(*) AS cnt FROM tl_zad_sendnews WHERE name LIKE ?")->execute($tab['tl_zad_sendnews'][0]['name'] . '%'); $tab['tl_zad_sendnews'][0]['name'] .= $name->cnt > 0 ? ' - ' . $name->cnt : ''; // lock tables $locks = array('tl_zad_sendnews' => 'WRITE', 'tl_zad_sendnews_rule' => 'WRITE'); $this->Database->lockTables($locks); // get current values $tab['tl_zad_sendnews'][0]['id'] = $this->Database->getNextId('tl_zad_sendnews'); $tab['tl_zad_sendnews'][0]['tstamp'] = time(); $tab['tl_zad_sendnews'][0]['active'] = ''; // insert imported manager $this->Database->prepare("INSERT INTO tl_zad_sendnews %s")->set($tab['tl_zad_sendnews'][0])->execute(); // insert imported rules foreach ($tab['tl_zad_sendnews_rule'] as $rule) { // get current values $rule['id'] = $this->Database->getNextId('tl_zad_sendnews_rule'); $rule['pid'] = $tab['tl_zad_sendnews'][0]['id']; $rule['tstamp'] = time(); $this->Database->prepare("INSERT INTO tl_zad_sendnews_rule %s")->set($rule)->execute(); } // unlock tables $this->Database->unlockTables(); // notify the user \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_zad_sendnews']['ok_imported'], basename($zipfile))); } // redirect \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->redirect(str_replace('&key=import', '', \Environment::get('request'))); }
/** * Auto-generate a form to edit all records that are currently shown * @param integer * @param integer * @return string */ public function editAll($intId = null, $ajaxId = null) { if ($GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable']) { $this->log('Table "' . $this->strTable . '" is not editable', __METHOD__, TL_ERROR); \Controller::redirect('contao/main.php?act=error'); } $return = ''; $this->import('BackendUser', 'User'); // Get current IDs from session $session = $this->Session->getData(); $ids = $session['CURRENT']['IDS']; if ($intId != '' && \Environment::get('isAjaxRequest')) { $ids = array($intId); } // Save field selection in session if (\Input::post('FORM_SUBMIT') == $this->strTable . '_all' && \Input::get('fields')) { $session['CURRENT'][$this->strTable] = \Input::post('all_fields'); $this->Session->setData($session); } // Add fields $fields = $session['CURRENT'][$this->strTable]; if (!empty($fields) && is_array($fields) && \Input::get('fields')) { $class = 'tl_tbox'; $this->checkForTinyMce(); // Walk through each record foreach ($ids as $id) { $this->intId = $id; $this->procedure = array('id=?'); $this->values = array($this->intId); $this->blnCreateNewVersion = false; $this->strPalette = trimsplit('[;,]', $this->getPalette()); // Add meta fields if the current user is an administrator if ($this->User->isAdmin) { if (\Database::getInstance()->fieldExists('sorting', $this->strTable)) { array_unshift($this->strPalette, 'sorting'); } if (\Database::getInstance()->fieldExists('pid', $this->strTable)) { array_unshift($this->strPalette, 'pid'); } $GLOBALS['TL_DCA'][$this->strTable]['fields']['pid'] = array('label' => &$GLOBALS['TL_LANG']['MSC']['pid'], 'inputType' => 'text', 'eval' => array('rgxp' => 'digit')); $GLOBALS['TL_DCA'][$this->strTable]['fields']['sorting'] = array('label' => &$GLOBALS['TL_LANG']['MSC']['sorting'], 'inputType' => 'text', 'eval' => array('rgxp' => 'digit')); } // Begin current row $strAjax = ''; $blnAjax = false; $return .= ' <div class="' . $class . '">'; $class = 'tl_box'; $formFields = array(); $arrBaseFields = array(); $arrDetailFields = array(); $arrSqlDetails = array(); foreach ($fields as $strField) { if (in_array($strField, $this->arrBaseFields)) { $arrBaseFields[] = $strField; } elseif (in_array($strField, $this->arrDetailFields)) { $arrDetailFields[] = $strField; $arrSqlDetails[] = '(SELECT value FROM tl_formdata_details WHERE ff_name=\'' . $strField . '\' AND pid=f.id) AS `' . $strField . '`'; } } $strSqlFields = !empty($arrBaseFields) ? implode(', ', $arrBaseFields) : ''; $strSqlFields .= !empty($arrSqlDetails) ? (strlen($strSqlFields) ? ', ' : '') . implode(', ', $arrSqlDetails) : ''; // Get the field values $objRow = \Database::getInstance()->prepare("SELECT " . $strSqlFields . " FROM " . $this->strTable . " f WHERE id=?")->limit(1)->execute($this->intId); // Store the active record $this->objActiveRecord = $objRow; $blnIsFirst = true; foreach ($this->strPalette as $v) { // Check whether field is excluded if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['exclude']) { continue; } if ($v == '[EOF]') { if ($blnAjax && \Environment::get('isAjaxRequest')) { return $strAjax . '<input type="hidden" name="FORM_FIELDS_' . $id . '[]" value="' . specialchars(implode(',', $formFields)) . '">'; } $blnAjax = false; $return .= "\n " . '</div>'; continue; } if (preg_match('/^\\[.*\\]$/', $v)) { $thisId = 'sub_' . substr($v, 1, -1) . '_' . $id; $blnAjax = $ajaxId == $thisId && \Environment::get('isAjaxRequest') ? true : false; $return .= "\n " . '<div id="' . $thisId . '">'; continue; } if (!in_array($v, $fields)) { continue; } $this->strField = $v; $this->strInputName = $v . '_' . $this->intId; $formFields[] = $v . '_' . $this->intId; // Set the default value and try to load the current value from DB $this->varValue = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['default'] ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['default'] : ''; if ($objRow->{$v} !== false) { $this->varValue = $objRow->{$v}; } // Autofocus the first field if ($blnIsFirst && $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'text') { $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['autofocus'] = 'autofocus'; $blnIsFirst = false; } // Call options_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options_callback'])) { $strClass = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options_callback'][0]; $strMethod = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options_callback'][1]; $this->import($strClass); $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options'] = $this->{$strClass}->{$strMethod}($this); } // Convert CSV fields if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['multiple'] && isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv'])) { $this->varValue = trimsplit($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv'], $this->varValue); } // prepare values of special fields like radio, select and checkbox $strInputType = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType']; // field types radio, select, multi checkbox if (in_array($strInputType, array('radio', 'select', 'conditionalselect', 'countryselect')) || $strInputType == 'checkbox' && $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['multiple']) { if (in_array($this->strField, $this->arrBaseFields) && in_array($this->strField, $this->arrOwnerFields)) { if ($this->strField == 'fd_user') { if ($this->User && $this->User->id) { $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['default'] = $this->User->id; } } } else { // foreignKey fields if ($strInputType == 'select' && strlen($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['foreignKey'])) { // include blank Option $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['includeBlankOption'] = true; $arrKey = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['foreignKey']); $strForeignTable = $arrKey[0]; $strForeignField = $arrKey[1]; // WHERE condition for foreignKey $strForeignKeyCond = ''; if (strlen($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['foreignKeyWhere'])) { $strForeignKeyCond = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['foreignKeyWhere']; } // check if foreignKey table is a formdata table if (substr($strForeignTable, 0, 3) == 'fd_') { $strFormKey = substr($strForeignTable, 3); $strForeignDcaKey = $strForeignTable; $strForeignTable = 'tl_formdata'; // backup current dca and load dca for foreign formdata $BAK_DCA = $GLOBALS['TL_DCA'][$this->strTable]; $this->loadDataContainer($strForeignDcaKey); $strForeignField = $arrKey[1]; $strForeignSqlField = '(SELECT value FROM tl_formdata_details WHERE ff_name="' . $strForeignField . '" AND pid=f.id ) AS `' . $strForeignField . '`'; $sqlForeignFd = "SELECT f.id," . $strForeignSqlField . " FROM tl_formdata f, tl_formdata_details fd "; $sqlForeignFd .= "WHERE (f.id=fd.pid) AND f." . $GLOBALS['TL_DCA'][$strForeignTable]['tl_formdata']['formFilterKey'] . "='" . $GLOBALS['TL_DCA'][$strForeignTable]['tl_formdata']['formFilterValue'] . "' AND fd.ff_name='" . $strForeignField . "'"; if (!empty($strForeignKeyCond)) { $arrForeignKeyCond = preg_split('/([\\s!=><]+)/', $strForeignKeyCond, -1, PREG_SPLIT_DELIM_CAPTURE); $strForeignCondField = $arrForeignKeyCond[0]; unset($arrForeignKeyCond[0]); if (in_array($strForeignCondField, $GLOBALS['TL_DCA'][$strForeignTable]['tl_formdata']['baseFields'])) { $sqlForeignFd .= ' AND f.' . $strForeignCondField . implode('', $arrForeignKeyCond); } if (in_array($strForeignCondField, $GLOBALS['TL_DCA'][$strForeignTable]['tl_formdata']['detailFields'])) { $sqlForeignFd .= ' AND (SELECT value FROM tl_formdata_details WHERE ff_name="' . $strForeignCondField . '" AND pid=f.id ) ' . implode('', $arrForeignKeyCond); } } $objForeignFd = \Database::getInstance()->prepare($sqlForeignFd)->execute(); // reset current dca $GLOBALS['TL_DCA'][$this->strTable] = $BAK_DCA; unset($BAK_DCA); if ($objForeignFd->numRows) { $arrForeignRecords = $objForeignFd->fetchAllAssoc(); if (!empty($arrForeignRecords)) { foreach ($arrForeignRecords as $arrForeignRecord) { $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options'][$arrForeignRecord['id']] = $arrForeignRecord[$strForeignField] . ' [~' . $arrForeignRecord['id'] . '~]'; } } unset($arrForeignRecords); } // unset dca 'foreignKey': prevents \Widget::getAttributesFromDca to read options from table instead handle as normal select unset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['foreignKey']); unset($objForeignFd); } elseif (\Database::getInstance()->fieldExists($strForeignField, $strForeignTable)) { $blnAlias = \Database::getInstance()->fieldExists('alias', $strForeignTable); $sqlForeign = "SELECT id," . ($blnAlias ? "alias," : "") . $strForeignField . " FROM " . $strForeignTable . (strlen($strForeignKeyCond) ? " WHERE " . $strForeignKeyCond : '') . " ORDER BY " . $strForeignField; $objForeign = \Database::getInstance()->prepare($sqlForeign)->execute(); if ($objForeign->numRows) { $arrForeignRecords = $objForeign->fetchAllAssoc(); if (!empty($arrForeignRecords)) { foreach ($arrForeignRecords as $arrForeignRecord) { $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options'][$arrForeignRecord['id']] = $arrForeignRecord[$strForeignField] . ' [~' . ($blnAlias && strlen($arrForeignRecord['alias']) ? $arrForeignRecord['alias'] : $arrForeignRecord['id']) . '~]'; } } unset($arrForeignRecords); } // unset dca 'foreignKey': prevents \Widget::getAttributesFromDca to read options from table instead handle as normal select unset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['foreignKey']); unset($objForeign); } // sort options on label asort($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options']); } if (!is_array($this->varValue)) { $strSep = isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv']) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv'] : '|'; $arrValues = explode($strSep, $this->varValue); } else { $arrValues = $this->varValue; } if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['efgStoreValues']) { $this->varValue = $arrValues; } else { // prepare values $arrNewValues = array(); foreach ($arrValues as $kVal => $vVal) { $vVal = trim($vVal); $strK = false; if (strlen($vVal) && $strK == false) { // handle grouped options foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options'] as $strOptsKey => $varOpts) { if (is_array($varOpts)) { $strK = array_search($vVal, $varOpts); } else { $strK = array_search($vVal, $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options']); } if ($strK !== false) { $arrNewValues[] = $strK; break; } } // add saved option to available options if it does not exist if ($strK === false) { $strK = preg_replace('/(.*?\\[)(.*?)(\\])/si', '$2', $vVal); $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options'][$strK] = $vVal; $arrNewValues[] = $strK; } } } $this->varValue = $arrNewValues; } } } elseif ($strInputType == 'checkbox' && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['multiple']) { // Modify options to handle Contao 3 new validation in Widget::isValidOption() if (in_array($this->strField, $this->arrDetailFields)) { $strFirstOpt = array_pop($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options']); $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options'][1] = $strFirstOpt; if (!empty($this->varValue)) { $this->varValue = '1'; } } } elseif ($strInputType == 'efgLookupSelect') { $arrFieldOptions = $this->Formdata->prepareWidgetOptions($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]); // prepare options array and value if (is_array($arrFieldOptions)) { // prepare options array $arrNewOptions = array(); foreach ($arrFieldOptions as $k => $v) { $arrNewOptions[$v['value']] = $v['label']; } } $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options'] = $arrNewOptions; // prepare varValue if (!empty($this->varValue)) { if (!is_array($this->varValue)) { $strSep = isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv']) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv'] : '|'; $this->varValue = explode($strSep, $this->varValue); } foreach ($this->varValue as $k => $v) { $sNewVal = array_search($v, $arrNewOptions); if ($sNewVal) { $this->varValue[$v] = $sNewVal; } } } // render type efgLookupSelect as SelectMenu $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] = 'select'; } elseif ($strInputType == 'efgLookupCheckbox') { $arrFieldOptions = $this->Formdata->prepareWidgetOptions($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]); // prepare options array and value if (is_array($arrFieldOptions)) { // prepare options array $arrNewOptions = array(); foreach ($arrFieldOptions as $k => $v) { $arrNewOptions[$v['value']] = $v['label']; } } $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options'] = $arrNewOptions; // prepare varValue if (!empty($this->varValue)) { if (!is_array($this->varValue)) { $strSep = isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv']) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv'] : '|'; $this->varValue = explode($strSep, $this->varValue); } foreach ($this->varValue as $k => $v) { $sNewVal = array_search($v, $arrNewOptions); if ($sNewVal) { $this->varValue[$v] = $sNewVal; } } } // render type efgLookupCheckbox as CheckboxMenu $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] = 'checkbox'; } elseif ($strInputType == 'efgLookupRadio') { $arrFieldOptions = $this->Formdata->prepareWidgetOptions($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]); // prepare options array and value if (is_array($arrFieldOptions)) { // prepare options array $arrNewOptions = array(); foreach ($arrFieldOptions as $k => $v) { $arrNewOptions[$v['value']] = $v['label']; } } $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['options'] = $arrNewOptions; // prepare varValue if (!empty($this->varValue)) { if (!is_array($this->varValue)) { $strSep = isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv']) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv'] : '|'; $this->varValue = explode($strSep, $this->varValue); } foreach ($this->varValue as $k => $v) { $sNewVal = array_search($v, $arrNewOptions); if ($sNewVal) { $this->varValue[$v] = $sNewVal; } } } // render type efgLookupRadio as RadioMenu $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] = 'radio'; } else { $this->varValue = $this->Formdata->prepareDatabaseValueForWidget($this->varValue, $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]); } $this->objActiveRecord->{$this->strField} = $this->varValue; // Call load_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->varValue = $this->{$callback}[0]->{$callback}[1]($this->varValue, $this); } elseif (is_callable($callback)) { $this->varValue = $callback($this->varValue, $this); } } $this->objActiveRecord->{$this->strField} = $this->varValue; } // Build the current row $blnAjax ? $strAjax .= $this->row() : ($return .= $this->row()); } // Close box $return .= ' <input type="hidden" name="FORM_FIELDS_' . $this->intId . '[]" value="' . specialchars(implode(',', $formFields)) . '"> </div>'; // Save record if (\Input::post('FORM_SUBMIT') == $this->strTable && !$this->noReload) { // Call onsubmit_callback if (is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->{$callback}[0]->{$callback}[1]($this); } elseif (is_callable($callback)) { $callback($this); } } } // Set current timestamp (-> DO NOT CHANGE ORDER version - timestamp) \Database::getInstance()->prepare("UPDATE " . $this->strTable . " SET tstamp=? WHERE id=?")->execute(time(), $this->intId); } } // Submit buttons $arrButtons = array(); $arrButtons['save'] = '<input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['save']) . '">'; $arrButtons['saveNclose'] = '<input type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['saveNclose']) . '">'; // Call the buttons_callback (see #4691) if (is_array($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'])) { foreach ($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $arrButtons = $this->{$callback}[0]->{$callback}[1]($arrButtons, $this); } elseif (is_callable($callback)) { $arrButtons = $callback($arrButtons, $this); } } } // Add the form $return = ' <h2 class="sub_headline_all">' . sprintf($GLOBALS['TL_LANG']['MSC']['all_info'], $this->strTable) . '</h2> <form action="' . ampersand(\Environment::get('request'), true) . '" id="' . $this->strTable . '" class="tl_form" method="post" enctype="' . ($this->blnUploadable ? 'multipart/form-data' : 'application/x-www-form-urlencoded') . '"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="' . $this->strTable . '"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '">' . ($this->noReload ? ' <p class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['general'] . '</p>' : '') . $return . ' </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> ' . implode(' ', $arrButtons) . ' </div> </div> </form>'; // TODO: find a better solution to handle toggleSubpalette ... $return .= $this->getSubpaletteJavascript(); $return .= $this->getFilepickerJavascript('reloadEfgFiletree'); // Set the focus if there is an error if ($this->noReload) { $return .= ' <script> window.addEvent(\'domready\', function() { Backend.vScrollTo(($(\'' . $this->strTable . '\').getElement(\'label.error\').getPosition().y - 20)); }); </script>'; } // Reload the page to prevent _POST variables from being sent twice if (\Input::post('FORM_SUBMIT') == $this->strTable && !$this->noReload) { if (\Input::post('saveNclose')) { \System::setCookie('BE_PAGE_OFFSET', 0, 0); \Controller::redirect($this->getReferer()); } \Controller::reload(); } } else { $options = ''; $fields = array(); // Add fields of the current table $fields = array_merge($fields, array_keys($GLOBALS['TL_DCA'][$this->strTable]['fields'])); // Add meta fields if the current user is an administrator if ($this->User->isAdmin) { if (\Database::getInstance()->fieldExists('sorting', $this->strTable) && !in_array('sorting', $fields)) { array_unshift($fields, 'sorting'); } if (\Database::getInstance()->fieldExists('pid', $this->strTable) && !in_array('pid', $fields)) { array_unshift($fields, 'pid'); } } // Show all non-excluded fields foreach ($fields as $field) { if ($field == 'pid' || $field == 'sorting' || !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['exclude'] && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['eval']['doNotShow'] && (strlen($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['inputType']) || is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['input_field_callback']))) { $options .= ' <input type="checkbox" name="all_fields[]" id="all_' . $field . '" class="tl_checkbox" value="' . specialchars($field) . '"> <label for="all_' . $field . '" class="tl_checkbox_label">' . ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['label'][0] ?: $GLOBALS['TL_LANG']['MSC'][$field][0]) . '</label><br>'; } } $blnIsError = $_POST && empty($_POST['all_fields']); // Return the select menu $return .= ' <h2 class="sub_headline_all">' . sprintf($GLOBALS['TL_LANG']['MSC']['all_info'], $this->strTable) . '</h2> <form action="' . ampersand(\Environment::get('request'), true) . '&fields=1" id="' . $this->strTable . '_all" class="tl_form" method="post"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="' . $this->strTable . '_all"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '">' . ($blnIsError ? ' <p class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['general'] . '</p>' : '') . ' <div class="tl_tbox"> <fieldset class="tl_checkbox_container"> <legend' . ($blnIsError ? ' class="error"' : '') . '>' . $GLOBALS['TL_LANG']['MSC']['all_fields'][0] . '</legend> <input type="checkbox" id="check_all" class="tl_checkbox" onclick="Backend.toggleCheckboxes(this)"> <label for="check_all" style="color:#a6a6a6"><em>' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</em></label><br>' . $options . ' </fieldset>' . ($blnIsError ? ' <p class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['all_fields'] . '</p>' : ($GLOBALS['TL_CONFIG']['showHelp'] && strlen($GLOBALS['TL_LANG']['MSC']['all_fields'][1]) ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['MSC']['all_fields'][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']['MSC']['continue']) . '"> </div> </div> </form>'; } // Return 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>' . $return; }