/** * @param $intId * @param $blnVisible * @param DataContainer|null $dc */ public function toggleVisibility($intId, $blnVisible, DataContainer $dc = null) { // Set the ID and action Input::setGet('id', $intId); Input::setGet('act', 'toggle'); if ($dc) { $dc->id = $intId; // see #8043 } // Check the field access if (!$this->User->hasAccess('tl_api_client::disable', 'alexf')) { throw new AccessDeniedException('Not enough permissions to activate/deactivate member ID ' . $intId . '.'); } $objVersions = new Versions('tl_api_client', $intId); $objVersions->initialize(); // Trigger the save_callback if (is_array($GLOBALS['TL_DCA']['tl_api_client']['fields']['disable']['save_callback'])) { foreach ($GLOBALS['TL_DCA']['tl_api_client']['fields']['disable']['save_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $blnVisible = $this->{$callback[0]}->{$callback[1]}($blnVisible, $dc ?: $this); } elseif (is_callable($callback)) { $blnVisible = $callback($blnVisible, $dc ?: $this); } } } $time = time(); // Update the database $this->Database->prepare("UPDATE tl_api_client SET tstamp={$time}, disable='" . ($blnVisible ? '' : 1) . "' WHERE id=?")->execute($intId); $objVersions->create(); $this->log('A new version of record "tl_api_client.id=' . $intId . '" has been created' . $this->getParentEntries('tl_api_client', $intId), __METHOD__, TL_GENERAL); }
/** * Auto-generate a form to override all records that are currently shown * * @return string * * @throws InternalServerErrorException */ public function overrideAll() { if ($GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable']) { throw new InternalServerErrorException('Table "' . $this->strTable . '" is not editable.'); } $return = ''; $this->import('BackendUser', 'User'); /** @var SessionInterface $objSession */ $objSession = \System::getContainer()->get('session'); // Get current IDs from session $session = $objSession->all(); $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'); $objSession->replace($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'])) { 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); } } } $this->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 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'] = '<button type="submit" name="save" id="save" class="tl_submit" accesskey="s">' . $GLOBALS['TL_LANG']['MSC']['save'] . '</button>'; $arrButtons['saveNclose'] = '<button type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c">' . $GLOBALS['TL_LANG']['MSC']['saveNclose'] . '</button>'; // 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 (isset($_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]) . ' <span style="color:#b3b3b3;padding-left:3px">[' . $field . ']</span>') . '</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"> <button type="submit" name="save" id="save" class="tl_submit" accesskey="s">' . $GLOBALS['TL_LANG']['MSC']['continue'] . '</button> </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; }
/** * Set the new password */ protected function setNewPassword() { $objMember = \MemberModel::findOneByActivation(\Input::get('token')); if ($objMember === null || $objMember->login == '') { $this->strTemplate = 'mod_message'; /** @var FrontendTemplate|object $objTemplate */ $objTemplate = new \FrontendTemplate($this->strTemplate); $this->Template = $objTemplate; $this->Template->type = 'error'; $this->Template->message = $GLOBALS['TL_LANG']['MSC']['accountError']; return; } $strTable = $objMember->getTable(); // Initialize the versioning (see #8301) $objVersions = new \Versions($strTable, $objMember->id); $objVersions->setUsername($objMember->username); $objVersions->setUserId(0); $objVersions->setEditUrl('contao/main.php?do=member&act=edit&id=%s&rt=1'); $objVersions->initialize(); // Define the form field $arrField = $GLOBALS['TL_DCA']['tl_member']['fields']['password']; /** @var Widget $strClass */ $strClass = $GLOBALS['TL_FFL']['password']; // Fallback to default if the class is not defined if (!class_exists($strClass)) { $strClass = 'FormPassword'; } /** @var Widget $objWidget */ $objWidget = new $strClass($strClass::getAttributesFromDca($arrField, 'password')); // Set row classes $objWidget->rowClass = 'row_0 row_first even'; $objWidget->rowClassConfirm = 'row_1 odd'; $this->Template->rowLast = 'row_2 row_last even'; /** @var SessionInterface $objSession */ $objSession = \System::getContainer()->get('session'); // Validate the field if (strlen(\Input::post('FORM_SUBMIT')) && \Input::post('FORM_SUBMIT') == $objSession->get('setPasswordToken')) { $objWidget->validate(); // Set the new password and redirect if (!$objWidget->hasErrors()) { $objSession->set('setPasswordToken', ''); $objMember->tstamp = time(); $objMember->activation = ''; $objMember->password = $objWidget->value; $objMember->save(); // Create a new version if ($GLOBALS['TL_DCA'][$strTable]['config']['enableVersioning']) { $objVersions->create(); } // HOOK: set new password callback if (isset($GLOBALS['TL_HOOKS']['setNewPassword']) && is_array($GLOBALS['TL_HOOKS']['setNewPassword'])) { foreach ($GLOBALS['TL_HOOKS']['setNewPassword'] as $callback) { $this->import($callback[0]); $this->{$callback[0]}->{$callback[1]}($objMember, $objWidget->value, $this); } } // Redirect to the jumpTo page if (($objTarget = $this->objModel->getRelated('reg_jumpTo')) instanceof PageModel) { /** @var PageModel $objTarget */ $this->redirect($objTarget->getFrontendUrl()); } // Confirm $this->strTemplate = 'mod_message'; /** @var FrontendTemplate|object $objTemplate */ $objTemplate = new \FrontendTemplate($this->strTemplate); $this->Template = $objTemplate; $this->Template->type = 'confirm'; $this->Template->message = $GLOBALS['TL_LANG']['MSC']['newPasswordSet']; return; } } $strToken = md5(uniqid(mt_rand(), true)); $objSession->set('setPasswordToken', $strToken); $this->Template->formId = $strToken; $this->Template->fields = $objWidget->parse(); $this->Template->action = \Environment::get('indexFreeRequest'); $this->Template->slabel = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['setNewPassword']); }
/** * Generate the module */ protected function compile() { /** @var PageModel $objPage */ global $objPage; $this->import('FrontendUser', 'User'); $GLOBALS['TL_LANGUAGE'] = $objPage->language; \System::loadLanguageFile('tl_member'); $this->loadDataContainer('tl_member'); // Old password widget $arrFields['oldPassword'] = array('name' => 'oldpassword', 'label' => &$GLOBALS['TL_LANG']['MSC']['oldPassword'], 'inputType' => 'text', 'eval' => array('mandatory' => true, 'preserveTags' => true, 'hideInput' => true)); // New password widget $arrFields['newPassword'] = $GLOBALS['TL_DCA']['tl_member']['fields']['password']; $arrFields['newPassword']['name'] = 'password'; $arrFields['newPassword']['label'] =& $GLOBALS['TL_LANG']['MSC']['newPassword']; $row = 0; $strFields = ''; $doNotSubmit = false; $objMember = \MemberModel::findByPk($this->User->id); $strFormId = 'tl_change_password_' . $this->id; $flashBag = \System::getContainer()->get('session')->getFlashBag(); $strTable = $objMember->getTable(); // Initialize the versioning (see #8301) $objVersions = new \Versions($strTable, $objMember->id); $objVersions->setUsername($objMember->username); $objVersions->setUserId(0); $objVersions->setEditUrl('contao/main.php?do=member&act=edit&id=%s&rt=1'); $objVersions->initialize(); /** @var FormTextField $objOldPassword */ $objOldPassword = null; /** @var FormPassword $objNewPassword */ $objNewPassword = null; // Initialize the widgets foreach ($arrFields as $strKey => $arrField) { /** @var Widget $strClass */ $strClass = $GLOBALS['TL_FFL'][$arrField['inputType']]; // Continue if the class is not defined if (!class_exists($strClass)) { continue; } $arrField['eval']['required'] = $arrField['eval']['mandatory']; /** @var Widget $objWidget */ $objWidget = new $strClass($strClass::getAttributesFromDca($arrField, $arrField['name'])); $objWidget->storeValues = true; $objWidget->rowClass = 'row_' . $row . ($row == 0 ? ' row_first' : '') . ($row % 2 == 0 ? ' even' : ' odd'); // Increase the row count if it is a password field if ($objWidget instanceof FormPassword) { $objWidget->rowClassConfirm = 'row_' . ++$row . ($row % 2 == 0 ? ' even' : ' odd'); } ++$row; // Store the widget objects $strVar = 'obj' . ucfirst($strKey); ${$strVar} = $objWidget; // Validate the widget if (\Input::post('FORM_SUBMIT') == $strFormId) { $objWidget->validate(); // Validate the old password if ($strKey == 'oldPassword') { if (\Encryption::test($objMember->password)) { $blnAuthenticated = \Encryption::verify($objWidget->value, $objMember->password); } else { list($strPassword, $strSalt) = explode(':', $objMember->password); $blnAuthenticated = $strSalt == '' ? $strPassword === sha1($objWidget->value) : $strPassword === sha1($strSalt . $objWidget->value); } if (!$blnAuthenticated) { $objWidget->value = ''; $objWidget->addError($GLOBALS['TL_LANG']['MSC']['oldPasswordWrong']); sleep(2); // Wait 2 seconds while brute forcing :) } } if ($objWidget->hasErrors()) { $doNotSubmit = true; } } $strFields .= $objWidget->parse(); } $this->Template->fields = $strFields; $this->Template->hasError = $doNotSubmit; // Store the new password if (\Input::post('FORM_SUBMIT') == $strFormId && !$doNotSubmit) { $objMember->tstamp = time(); $objMember->password = $objNewPassword->value; $objMember->save(); // Create a new version if ($GLOBALS['TL_DCA'][$strTable]['config']['enableVersioning']) { $objVersions->create(); } // HOOK: set new password callback if (isset($GLOBALS['TL_HOOKS']['setNewPassword']) && is_array($GLOBALS['TL_HOOKS']['setNewPassword'])) { foreach ($GLOBALS['TL_HOOKS']['setNewPassword'] as $callback) { $this->import($callback[0]); $this->{$callback[0]}->{$callback[1]}($objMember, $objNewPassword->value, $this); } } // Check whether there is a jumpTo page if (($objJumpTo = $this->objModel->getRelated('jumpTo')) instanceof PageModel) { $this->jumpToOrReload($objJumpTo->row()); } $flashBag->set('mod_change_password_confirm', $GLOBALS['TL_LANG']['MSC']['newPasswordSet']); $this->reload(); } // Confirmation message if ($flashBag->has('mod_change_password_confirm')) { $arrMessages = $flashBag->get('mod_change_password_confirm'); $this->Template->message = $arrMessages[0]; } $this->Template->formId = $strFormId; $this->Template->action = \Environment::get('indexFreeRequest'); $this->Template->slabel = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['changePassword']); $this->Template->rowLast = 'row_' . $row . ' row_last' . ($row % 2 == 0 ? ' even' : ' odd'); }
/** * Create a new user and redirect * * @param array $arrData */ protected function createNewUser($arrData) { $arrData['tstamp'] = time(); $arrData['login'] = $this->reg_allowLogin; $arrData['activation'] = md5(uniqid(mt_rand(), true)); $arrData['dateAdded'] = $arrData['tstamp']; // Set default groups if (!array_key_exists('groups', $arrData)) { $arrData['groups'] = $this->reg_groups; } // Disable account $arrData['disable'] = 1; // Send activation e-mail if ($this->reg_activate) { $this->sendActivationMail($arrData); } // Make sure newsletter is an array if (isset($arrData['newsletter']) && !is_array($arrData['newsletter'])) { $arrData['newsletter'] = array($arrData['newsletter']); } // Create the user $objNewUser = new \MemberModel(); $objNewUser->setRow($arrData); $objNewUser->save(); // Assign home directory if ($this->reg_assignDir) { $objHomeDir = \FilesModel::findByUuid($this->reg_homeDir); if ($objHomeDir !== null) { $this->import('Files'); $strUserDir = \StringUtil::standardize($arrData['username']) ?: 'user_' . $objNewUser->id; // Add the user ID if the directory exists while (is_dir(TL_ROOT . '/' . $objHomeDir->path . '/' . $strUserDir)) { $strUserDir .= '_' . $objNewUser->id; } // Create the user folder new \Folder($objHomeDir->path . '/' . $strUserDir); $objUserDir = \FilesModel::findByPath($objHomeDir->path . '/' . $strUserDir); // Save the folder ID $objNewUser->assignDir = 1; $objNewUser->homeDir = $objUserDir->uuid; $objNewUser->save(); } } // HOOK: send insert ID and user data if (isset($GLOBALS['TL_HOOKS']['createNewUser']) && is_array($GLOBALS['TL_HOOKS']['createNewUser'])) { foreach ($GLOBALS['TL_HOOKS']['createNewUser'] as $callback) { $this->import($callback[0]); $this->{$callback[0]}->{$callback[1]}($objNewUser->id, $arrData, $this); } } // Create the initial version (see #7816) $objVersions = new \Versions('tl_member', $objNewUser->id); $objVersions->setUsername($objNewUser->username); $objVersions->setUserId(0); $objVersions->setEditUrl('contao/main.php?do=member&act=edit&id=%s&rt=1'); $objVersions->initialize(); // Inform admin if no activation link is sent if (!$this->reg_activate) { $this->sendAdminNotification($objNewUser->id, $arrData); } // Check whether there is a jumpTo page if (($objJumpTo = $this->objModel->getRelated('jumpTo')) instanceof PageModel) { $this->jumpToOrReload($objJumpTo->row()); } $this->reload(); }
/** * Load the source editor * * @return string * * @throws InternalServerErrorException */ public function source() { $this->isValid($this->intId); if (is_dir(TL_ROOT . '/' . $this->intId)) { throw new InternalServerErrorException('Folder "' . $this->intId . '" cannot be edited.'); } elseif (!file_exists(TL_ROOT . '/' . $this->intId)) { throw new InternalServerErrorException('File "' . $this->intId . '" does not exist.'); } $this->import('BackendUser', 'User'); // Check user permission if (!$this->User->hasAccess('f5', 'fop')) { throw new AccessDeniedException('Not enough permissions to edit the file source of file "' . $this->intId . '".'); } $objFile = new \File($this->intId); // Check whether file type is editable if (!in_array($objFile->extension, trimsplit(',', \Config::get('editableFiles')))) { throw new AccessDeniedException('File type "' . $objFile->extension . '" (' . $this->intId . ') is not allowed to be edited.'); } $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 (isset($_POST['saveNclose'])) { \System::setCookie('BE_PAGE_OFFSET', 0, 0); $this->redirect($this->getReferer()); } $this->reload(); } $codeEditor = ''; // Prepare the code editor if (\Config::get('useCE')) { /** @var BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_ace'); $objTemplate->selector = 'ctrl_source'; $objTemplate->type = $objFile->extension; $codeEditor = $objTemplate->parse(); } // 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'] = '<button type="submit" name="save" id="save" class="tl_submit" accesskey="s">' . $GLOBALS['TL_LANG']['MSC']['save'] . '</button>'; $arrButtons['saveNclose'] = '<button type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c">' . $GLOBALS['TL_LANG']['MSC']['saveNclose'] . '</button>'; // 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; }
/** * Add the welcome screen * * @return string */ protected function welcomeScreen() { \System::loadLanguageFile('explain'); /** @var BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_welcome'); $objTemplate->messages = \Message::generateUnwrapped() . \Backend::getSystemMessages(); $objTemplate->loginMsg = $GLOBALS['TL_LANG']['MSC']['firstLogin']; // Add the login message if ($this->User->lastLogin > 0) { $formatter = new DateTimeFormatter(\System::getContainer()->get('translator')); $diff = $formatter->formatDiff(new \DateTime(date('Y-m-d H:i:s', $this->User->lastLogin)), new \DateTime()); $objTemplate->loginMsg = sprintf($GLOBALS['TL_LANG']['MSC']['lastLogin'][1], '<time title="' . \Date::parse(\Config::get('datimFormat'), $this->User->lastLogin) . '">' . $diff . '</time>'); } // Add the versions overview \Versions::addToTemplate($objTemplate); $objTemplate->welcome = sprintf($GLOBALS['TL_LANG']['MSC']['welcomeTo'], \Config::get('websiteTitle')); $objTemplate->showDifferences = \StringUtil::specialchars(str_replace("'", "\\'", $GLOBALS['TL_LANG']['MSC']['showDifferences'])); $objTemplate->recordOfTable = \StringUtil::specialchars(str_replace("'", "\\'", $GLOBALS['TL_LANG']['MSC']['recordOfTable'])); $objTemplate->systemMessages = $GLOBALS['TL_LANG']['MSC']['systemMessages']; $objTemplate->shortcuts = $GLOBALS['TL_LANG']['MSC']['shortcuts'][0]; $objTemplate->shortcutsLink = $GLOBALS['TL_LANG']['MSC']['shortcuts'][1]; $objTemplate->editElement = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['editElement']); return $objTemplate->parse(); }
/** * Create a new version of a record * * @param string $strTable The table name * @param integer $intId The ID of the element to be versioned * * @deprecated Deprecated since Contao 4.0, to be removed in Contao 5.0. * Use Versions->create() instead. */ protected function createNewVersion($strTable, $intId) { trigger_error('Using Controller::createNewVersion() has been deprecated and will no longer work in Contao 5.0. Use Versions->create() instead.', E_USER_DEPRECATED); $objVersions = new \Versions($strTable, $intId); $objVersions->create(); }
/** * Generate the module */ protected function compile() { /** @var PageModel $objPage */ global $objPage; $this->import('FrontendUser', 'User'); $GLOBALS['TL_LANGUAGE'] = $objPage->language; \System::loadLanguageFile('tl_member'); $this->loadDataContainer('tl_member'); // Call onload_callback (e.g. to check permissions) if (is_array($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback'])) { foreach ($GLOBALS['TL_DCA']['tl_member']['config']['onload_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->{$callback[0]}->{$callback[1]}(); } elseif (is_callable($callback)) { $callback(); } } } $this->Template->fields = ''; $arrFields = array(); $doNotSubmit = false; $hasUpload = false; $row = 0; // Predefine the group order (other groups will be appended automatically) $arrGroups = array('personal' => array(), 'address' => array(), 'contact' => array(), 'login' => array(), 'profile' => array()); $blnModified = false; $objMember = \MemberModel::findByPk($this->User->id); $strTable = $objMember->getTable(); $strFormId = 'tl_member_' . $this->id; $flashBag = \System::getContainer()->get('session')->getFlashBag(); // Initialize the versioning (see #7415) $objVersions = new \Versions($strTable, $objMember->id); $objVersions->setUsername($objMember->username); $objVersions->setUserId(0); $objVersions->setEditUrl('contao/main.php?do=member&act=edit&id=%s&rt=1'); $objVersions->initialize(); // Build the form foreach ($this->editable as $field) { $arrData =& $GLOBALS['TL_DCA']['tl_member']['fields'][$field]; // Map checkboxWizards to regular checkbox widgets if ($arrData['inputType'] == 'checkboxWizard') { $arrData['inputType'] = 'checkbox'; } // Map fileTrees to upload widgets (see #8091) if ($arrData['inputType'] == 'fileTree') { $arrData['inputType'] = 'upload'; } /** @var Widget $strClass */ $strClass = $GLOBALS['TL_FFL'][$arrData['inputType']]; // Continue if the class does not exist if (!$arrData['eval']['feEditable'] || !class_exists($strClass)) { continue; } $strGroup = $arrData['eval']['feGroup']; $arrData['eval']['required'] = false; // Use strlen() here (see #3277) if ($arrData['eval']['mandatory']) { if (is_array($this->User->{$field})) { if (empty($this->User->{$field})) { $arrData['eval']['required'] = true; } } else { if (!strlen($this->User->{$field})) { $arrData['eval']['required'] = true; } } } $varValue = $this->User->{$field}; // Call the load_callback if (isset($arrData['load_callback']) && is_array($arrData['load_callback'])) { foreach ($arrData['load_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $this->User, $this); } elseif (is_callable($callback)) { $varValue = $callback($varValue, $this->User, $this); } } } /** @var Widget $objWidget */ $objWidget = new $strClass($strClass::getAttributesFromDca($arrData, $field, $varValue, '', '', $this)); $objWidget->storeValues = true; $objWidget->rowClass = 'row_' . $row . ($row == 0 ? ' row_first' : '') . ($row % 2 == 0 ? ' even' : ' odd'); // Increase the row count if it is a password field if ($objWidget instanceof FormPassword) { if ($objMember->password != '') { $objWidget->mandatory = false; } $objWidget->rowClassConfirm = 'row_' . ++$row . ($row % 2 == 0 ? ' even' : ' odd'); } // Validate the form data if (\Input::post('FORM_SUBMIT') == $strFormId) { $objWidget->validate(); $varValue = $objWidget->value; $rgxp = $arrData['eval']['rgxp']; // Convert date formats into timestamps (check the eval setting first -> #3063) if ($varValue != '' && in_array($rgxp, array('date', 'time', 'datim'))) { try { $objDate = new \Date($varValue, \Date::getFormatFromRgxp($rgxp)); $varValue = $objDate->tstamp; } catch (\OutOfBoundsException $e) { $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varValue)); } } // Make sure that unique fields are unique (check the eval setting first -> #3063) if ($arrData['eval']['unique'] && $varValue != '' && !$this->Database->isUniqueValue('tl_member', $field, $varValue, $this->User->id)) { $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $field)); } // Trigger the save_callback (see #5247) if ($objWidget->submitInput() && !$objWidget->hasErrors() && is_array($arrData['save_callback'])) { foreach ($arrData['save_callback'] as $callback) { try { if (is_array($callback)) { $this->import($callback[0]); $varValue = $this->{$callback[0]}->{$callback[1]}($varValue, $this->User, $this); } elseif (is_callable($callback)) { $varValue = $callback($varValue, $this->User, $this); } } catch (\Exception $e) { $objWidget->class = 'error'; $objWidget->addError($e->getMessage()); } } } // Do not submit the field if there are errors if ($objWidget->hasErrors()) { $doNotSubmit = true; } elseif ($objWidget->submitInput()) { // Store the form data $_SESSION['FORM_DATA'][$field] = $varValue; // Set the correct empty value (see #6284, #6373) if ($varValue === '') { $varValue = $objWidget->getEmptyValue(); } // Encrypt the value (see #7815) if ($arrData['eval']['encrypt']) { $varValue = \Encryption::encrypt($varValue); } // Set the new value if ($varValue !== $this->User->{$field}) { $this->User->{$field} = $varValue; // Set the new field in the member model $blnModified = true; $objMember->{$field} = $varValue; } } } if ($objWidget instanceof \uploadable) { $hasUpload = true; } $temp = $objWidget->parse(); $this->Template->fields .= $temp; $arrFields[$strGroup][$field] .= $temp; ++$row; } // Save the model if ($blnModified) { $objMember->tstamp = time(); $objMember->save(); // Create a new version if ($GLOBALS['TL_DCA'][$strTable]['config']['enableVersioning']) { $objVersions->create(); $this->log('A new version of record "' . $strTable . '.id=' . $objMember->id . '" has been created' . $this->getParentEntries($strTable, $objMember->id), __METHOD__, TL_GENERAL); } } $this->Template->hasError = $doNotSubmit; // Redirect or reload if there was no error if (\Input::post('FORM_SUBMIT') == $strFormId && !$doNotSubmit) { // HOOK: updated personal data if (isset($GLOBALS['TL_HOOKS']['updatePersonalData']) && is_array($GLOBALS['TL_HOOKS']['updatePersonalData'])) { foreach ($GLOBALS['TL_HOOKS']['updatePersonalData'] as $callback) { $this->import($callback[0]); $this->{$callback[0]}->{$callback[1]}($this->User, $_SESSION['FORM_DATA'], $this); } } // Call the onsubmit_callback if (is_array($GLOBALS['TL_DCA']['tl_member']['config']['onsubmit_callback'])) { foreach ($GLOBALS['TL_DCA']['tl_member']['config']['onsubmit_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $this->{$callback[0]}->{$callback[1]}($this->User, $this); } elseif (is_callable($callback)) { $callback($this->User, $this); } } } // Check whether there is a jumpTo page if (($objJumpTo = $this->objModel->getRelated('jumpTo')) !== null) { $this->jumpToOrReload($objJumpTo->row()); } $flashBag->set('mod_personal_data_confirm', $GLOBALS['TL_LANG']['MSC']['savedData']); $this->reload(); } $this->Template->loginDetails = $GLOBALS['TL_LANG']['tl_member']['loginDetails']; $this->Template->addressDetails = $GLOBALS['TL_LANG']['tl_member']['addressDetails']; $this->Template->contactDetails = $GLOBALS['TL_LANG']['tl_member']['contactDetails']; $this->Template->personalData = $GLOBALS['TL_LANG']['tl_member']['personalData']; // Add the groups foreach ($arrFields as $k => $v) { // Deprecated since Contao 4.0, to be removed in Contao 5.0 $this->Template->{$k} = $v; $key = $k . ($k == 'personal' ? 'Data' : 'Details'); $arrGroups[$GLOBALS['TL_LANG']['tl_member'][$key]] = $v; } // Confirmation message if ($flashBag->has('mod_personal_data_confirm')) { $arrMessages = $flashBag->get('mod_personal_data_confirm'); $this->Template->message = $arrMessages[0]; } $this->Template->categories = $arrGroups; $this->Template->formId = $strFormId; $this->Template->slabel = specialchars($GLOBALS['TL_LANG']['MSC']['saveData']); $this->Template->action = \Environment::get('indexFreeRequest'); $this->Template->enctype = $hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded'; $this->Template->rowLast = 'row_' . $row . ($row % 2 == 0 ? ' even' : ' odd'); }
/** * Add the welcome screen * * @return string */ protected function welcomeScreen() { \System::loadLanguageFile('explain'); /** @var \BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_welcome'); $objTemplate->messages = \Message::generateUnwrapped(); // HOOK: add custom messages if (isset($GLOBALS['TL_HOOKS']['getSystemMessages']) && is_array($GLOBALS['TL_HOOKS']['getSystemMessages'])) { $arrMessages = array(); foreach ($GLOBALS['TL_HOOKS']['getSystemMessages'] as $callback) { $this->import($callback[0]); $strBuffer = $this->{$callback}[0]->{$callback}[1](); if ($strBuffer != '') { $arrMessages[] = $strBuffer; } } if (!empty($arrMessages)) { $objTemplate->messages .= "\n" . implode("\n", $arrMessages); } } // Add the versions overview \Versions::addToTemplate($objTemplate); $objTemplate->welcome = sprintf($GLOBALS['TL_LANG']['MSC']['welcomeTo'], \Config::get('websiteTitle')); $objTemplate->showDifferences = specialchars(str_replace("'", "\\'", $GLOBALS['TL_LANG']['MSC']['showDifferences'])); $objTemplate->systemMessages = $GLOBALS['TL_LANG']['MSC']['systemMessages']; $objTemplate->shortcuts = $GLOBALS['TL_LANG']['MSC']['shortcuts'][0]; $objTemplate->shortcutsLink = $GLOBALS['TL_LANG']['MSC']['shortcuts'][1]; $objTemplate->editElement = specialchars($GLOBALS['TL_LANG']['MSC']['editElement']); return $objTemplate->parse(); }