/** * Recursively render the filetree * * @param string $path * @param integer $intMargin * @param boolean $mount * @param boolean $blnProtected * @param array $arrFound * * @return string */ protected function renderFiletree($path, $intMargin, $mount = false, $blnProtected = true, $arrFound = array()) { // Invalid path if (!is_dir($path)) { return ''; } // Make sure that $this->varValue is an array (see #3369) if (!is_array($this->varValue)) { $this->varValue = array($this->varValue); } static $session; /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); $session = $objSessionBag->all(); $flag = substr($this->strField, 0, 2); $node = 'tree_' . $this->strTable . '_' . $this->strField; $xtnode = 'tree_' . $this->strTable . '_' . $this->strName; // Get session data and toggle nodes if (\Input::get($flag . 'tg')) { $session[$node][\Input::get($flag . 'tg')] = isset($session[$node][\Input::get($flag . 'tg')]) && $session[$node][\Input::get($flag . 'tg')] == 1 ? 0 : 1; $objSessionBag->replace($session); $this->redirect(preg_replace('/(&(amp;)?|\\?)' . $flag . 'tg=[^& ]*/i', '', \Environment::get('request'))); } $return = ''; $intSpacing = 20; $files = array(); $folders = array(); $level = $intMargin / $intSpacing + 1; // Mount folder if ($mount) { $folders = array($path); } else { foreach (scan($path) as $v) { if (strncmp($v, '.', 1) === 0) { continue; } if (is_dir($path . '/' . $v)) { $folders[] = $path . '/' . $v; } else { $files[] = $path . '/' . $v; } } } natcasesort($folders); $folders = array_values($folders); natcasesort($files); $files = array_values($files); // Sort descending (see #4072) if ($this->sort == 'desc') { $folders = array_reverse($folders); $files = array_reverse($files); } $folderClass = $this->files || $this->filesOnly ? 'tl_folder' : 'tl_file'; // Process folders for ($f = 0, $c = count($folders); $f < $c; $f++) { $content = scan($folders[$f]); $currentFolder = str_replace(TL_ROOT . '/', '', $folders[$f]); $countFiles = count($content); // Check whether there are subfolders or files foreach ($content as $file) { if (strncmp($file, '.', 1) === 0) { --$countFiles; } elseif (!$this->files && !$this->filesOnly && is_file($folders[$f] . '/' . $file)) { --$countFiles; } elseif (!empty($arrFound) && !in_array($currentFolder . '/' . $file, $arrFound) && !preg_grep('/^' . preg_quote($currentFolder . '/' . $file, '/') . '\\//', $arrFound)) { --$countFiles; } } if (!empty($arrFound) && $countFiles < 1 && !in_array($currentFolder, $arrFound)) { continue; } $tid = md5($folders[$f]); $folderAttribute = 'style="margin-left:20px"'; $session[$node][$tid] = is_numeric($session[$node][$tid]) ? $session[$node][$tid] : 0; $currentFolder = str_replace(TL_ROOT . '/', '', $folders[$f]); $blnIsOpen = !empty($arrFound) || $session[$node][$tid] == 1 || count(preg_grep('/^' . preg_quote($currentFolder, '/') . '\\//', $this->varValue)) > 0; $return .= "\n " . '<li class="' . $folderClass . ' toggle_select hover-div"><div class="tl_left" style="padding-left:' . $intMargin . 'px">'; // Add a toggle button if there are childs if ($countFiles > 0) { $folderAttribute = ''; $img = $blnIsOpen ? 'folMinus.svg' : 'folPlus.svg'; $alt = $blnIsOpen ? $GLOBALS['TL_LANG']['MSC']['collapseNode'] : $GLOBALS['TL_LANG']['MSC']['expandNode']; $return .= '<a href="' . \Backend::addToUrl($flag . 'tg=' . $tid) . '" title="' . \StringUtil::specialchars($alt) . '" onclick="return AjaxRequest.toggleFiletree(this,\'' . $xtnode . '_' . $tid . '\',\'' . $currentFolder . '\',\'' . $this->strField . '\',\'' . $this->strName . '\',' . $level . ')">' . \Image::getHtml($img, '', 'style="margin-right:2px"') . '</a>'; } $protected = $blnProtected; // Check whether the folder is public if ($protected === true && array_search('.public', $content) !== false) { $protected = false; } $folderImg = $protected ? 'folderCP.svg' : 'folderC.svg'; $folderLabel = $this->files || $this->filesOnly ? '<strong>' . \StringUtil::specialchars(basename($currentFolder)) . '</strong>' : \StringUtil::specialchars(basename($currentFolder)); // Add the current folder $return .= \Image::getHtml($folderImg, '', $folderAttribute) . ' <a href="' . \Backend::addToUrl('fn=' . $this->urlEncode($currentFolder)) . '" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['selectNode']) . '">' . $folderLabel . '</a></div> <div class="tl_right">'; // Add a checkbox or radio button if (!$this->filesOnly) { switch ($this->fieldType) { case 'checkbox': $return .= '<input type="checkbox" name="' . $this->strName . '[]" id="' . $this->strName . '_' . md5($currentFolder) . '" class="tl_tree_checkbox" value="' . \StringUtil::specialchars($currentFolder) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFolder, $this->varValue) . '>'; break; case 'radio': $return .= '<input type="radio" name="' . $this->strName . '" id="' . $this->strName . '_' . md5($currentFolder) . '" class="tl_tree_radio" value="' . \StringUtil::specialchars($currentFolder) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFolder, $this->varValue) . '>'; break; } } $return .= '</div><div style="clear:both"></div></li>'; // Call the next node if ($blnIsOpen) { $return .= '<li class="parent" id="' . $xtnode . '_' . $tid . '"><ul class="level_' . $level . '">'; $return .= $this->renderFiletree($folders[$f], $intMargin + $intSpacing, false, $protected, $arrFound); $return .= '</ul></li>'; } } // Process files if ($this->files || $this->filesOnly) { for ($h = 0, $c = count($files); $h < $c; $h++) { $thumbnail = ''; $currentFile = str_replace(TL_ROOT . '/', '', $files[$h]); $currentEncoded = $this->urlEncode($currentFile); $objFile = new \File($currentFile); if (!empty($this->arrValidFileTypes) && !in_array($objFile->extension, $this->arrValidFileTypes)) { continue; } // Ignore files not matching the search criteria if (!empty($arrFound) && !in_array($currentFile, $arrFound)) { continue; } $return .= "\n " . '<li class="tl_file toggle_select hover-div"><div class="tl_left" style="padding-left:' . ($intMargin + $intSpacing) . 'px">'; $thumbnail .= ' <span class="tl_gray">(' . $this->getReadableSize($objFile->filesize); if ($objFile->width && $objFile->height) { $thumbnail .= ', ' . $objFile->width . 'x' . $objFile->height . ' px'; } $thumbnail .= ')</span>'; // Generate thumbnail if ($objFile->isImage && $objFile->viewHeight > 0 && \Config::get('thumbnails') && ($objFile->isSvgImage || $objFile->height <= \Config::get('gdMaxImgHeight') && $objFile->width <= \Config::get('gdMaxImgWidth'))) { $imageObj = \Image::create($currentEncoded, array(400, $objFile->height && $objFile->height < 50 ? $objFile->height : 50, 'box')); $importantPart = $imageObj->getImportantPart(); $thumbnail .= '<br>' . \Image::getHtml($imageObj->executeResize()->getResizedPath(), '', 'style="margin:0 0 2px -19px"'); if ($importantPart['x'] > 0 || $importantPart['y'] > 0 || $importantPart['width'] < $objFile->width || $importantPart['height'] < $objFile->height) { $thumbnail .= ' ' . \Image::getHtml($imageObj->setZoomLevel(100)->setTargetWidth(320)->setTargetHeight($objFile->height && $objFile->height < 40 ? $objFile->height : 40)->executeResize()->getResizedPath(), '', 'style="margin:0 0 2px 0;vertical-align:bottom"'); } } $return .= \Image::getHtml($objFile->icon, $objFile->mime) . ' ' . \StringUtil::convertEncoding(\StringUtil::specialchars(basename($currentFile)), \Config::get('characterSet')) . $thumbnail . '</div> <div class="tl_right">'; // Add checkbox or radio button switch ($this->fieldType) { case 'checkbox': $return .= '<input type="checkbox" name="' . $this->strName . '[]" id="' . $this->strName . '_' . md5($currentFile) . '" class="tl_tree_checkbox" value="' . \StringUtil::specialchars($currentFile) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFile, $this->varValue) . '>'; break; case 'radio': $return .= '<input type="radio" name="' . $this->strName . '" id="' . $this->strName . '_' . md5($currentFile) . '" class="tl_tree_radio" value="' . \StringUtil::specialchars($currentFile) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFile, $this->varValue) . '>'; break; } $return .= '</div><div style="clear:both"></div></li>'; } } return $return; }
/** * Add a breadcrumb menu to the file tree * * @param string $strKey * * @throws AccessDeniedException * @throws \RuntimeException */ public static function addFilesBreadcrumb($strKey = 'tl_files_node') { /** @var AttributeBagInterface $objSession */ $objSession = \System::getContainer()->get('session')->getBag('contao_backend'); // Set a new node if (isset($_GET['fn'])) { // Check the path (thanks to Arnaud Buchoux) if (\Validator::isInsecurePath(\Input::get('fn', true))) { throw new \RuntimeException('Insecure path ' . \Input::get('fn', true)); } $objSession->set($strKey, \Input::get('fn', true)); \Controller::redirect(preg_replace('/(&|\\?)fn=[^&]*/', '', \Environment::get('request'))); } $strNode = $objSession->get($strKey); if ($strNode == '') { return; } // Check the path (thanks to Arnaud Buchoux) if (\Validator::isInsecurePath($strNode)) { throw new \RuntimeException('Insecure path ' . $strNode); } // Currently selected folder does not exist if (!is_dir(TL_ROOT . '/' . $strNode)) { $objSession->set($strKey, ''); return; } $objUser = \BackendUser::getInstance(); $strPath = \Config::get('uploadPath'); $arrNodes = explode('/', preg_replace('/^' . preg_quote(\Config::get('uploadPath'), '/') . '\\//', '', $strNode)); $arrLinks = array(); // Add root link $arrLinks[] = \Image::getHtml('filemounts.svg') . ' <a href="' . \Backend::addToUrl('fn=') . '" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['selectAllNodes']) . '">' . $GLOBALS['TL_LANG']['MSC']['filterAll'] . '</a>'; // Generate breadcrumb trail foreach ($arrNodes as $strFolder) { $strPath .= '/' . $strFolder; // Do not show pages which are not mounted if (!$objUser->hasAccess($strPath, 'filemounts')) { continue; } // No link for the active folder if ($strPath == $strNode) { $arrLinks[] = \Image::getHtml('folderC.svg') . ' ' . $strFolder; } else { $arrLinks[] = \Image::getHtml('folderC.svg') . ' <a href="' . \Backend::addToUrl('fn=' . $strPath) . '" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['selectNode']) . '">' . $strFolder . '</a>'; } } // Check whether the node is mounted if (!$objUser->hasAccess($strNode, 'filemounts')) { $objSession->set($strKey, ''); throw new AccessDeniedException('Folder ID "' . $strNode . '" is not mounted'); } // Limit tree $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'] = array($strNode); // Insert breadcrumb menu $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['breadcrumb'] .= ' <ul id="tl_breadcrumb"> <li>' . implode(' > </li><li>', $arrLinks) . '</li> </ul>'; }
/** * Render the versions dropdown menu * * @return string */ public function renderDropdown() { $objVersion = $this->Database->prepare("SELECT tstamp, version, username, active FROM tl_version WHERE fromTable=? AND pid=? ORDER BY version DESC")->execute($this->strTable, $this->intPid); if ($objVersion->numRows < 2) { return ''; } $versions = ''; while ($objVersion->next()) { $versions .= ' <option value="' . $objVersion->version . '"' . ($objVersion->active ? ' selected="selected"' : '') . '>' . $GLOBALS['TL_LANG']['MSC']['version'] . ' ' . $objVersion->version . ' (' . \Date::parse(\Config::get('datimFormat'), $objVersion->tstamp) . ') ' . $objVersion->username . '</option>'; } return ' <div class="tl_version_panel"> <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_version" class="tl_form" method="post"> <div class="tl_formbody"> <input type="hidden" name="FORM_SUBMIT" value="tl_version"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <select name="version" class="tl_select">' . $versions . ' </select> <button type="submit" name="showVersion" id="showVersion" class="tl_submit">' . $GLOBALS['TL_LANG']['MSC']['restore'] . '</button> <a href="' . \Backend::addToUrl('versions=1&popup=1') . '" title="' . \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['showDifferences']) . '" onclick="Backend.openModalIframe({\'width\':768,\'title\':\'' . \StringUtil::specialchars(str_replace("'", "\\'", sprintf($GLOBALS['TL_LANG']['MSC']['recordOfTable'], $this->intPid, $this->strTable))) . '\',\'url\':this.href});return false">' . \Image::getHtml('diff.svg') . '</a> </div> </form> </div> '; }
/** * Recursively render the pagetree * * @param integer $id * @param integer $intMargin * @param boolean $protectedPage * @param boolean $blnNoRecursion * @param array $arrFound * * @return string */ protected function renderPagetree($id, $intMargin, $protectedPage = false, $blnNoRecursion = false, $arrFound = array()) { static $session; /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); $session = $objSessionBag->all(); $flag = substr($this->strField, 0, 2); $node = 'tree_' . $this->strTable . '_' . $this->strField; $xtnode = 'tree_' . $this->strTable . '_' . $this->strName; // Get the session data and toggle the nodes if (\Input::get($flag . 'tg')) { $session[$node][\Input::get($flag . 'tg')] = isset($session[$node][\Input::get($flag . 'tg')]) && $session[$node][\Input::get($flag . 'tg')] == 1 ? 0 : 1; $objSessionBag->replace($session); $this->redirect(preg_replace('/(&(amp;)?|\\?)' . $flag . 'tg=[^& ]*/i', '', \Environment::get('request'))); } $objPage = $this->Database->prepare("SELECT id, alias, type, protected, published, start, stop, hide, title FROM tl_page WHERE id=?")->limit(1)->execute($id); // Return if there is no result if ($objPage->numRows < 1) { return ''; } $return = ''; $intSpacing = 20; $childs = array(); // Check whether there are child records if (!$blnNoRecursion) { $objNodes = $this->Database->prepare("SELECT id FROM tl_page WHERE pid=?" . (!empty($arrFound) ? " AND id IN(" . implode(',', array_map('intval', $arrFound)) . ")" : '') . " ORDER BY sorting")->execute($id); if ($objNodes->numRows) { $childs = $objNodes->fetchEach('id'); } } $return .= "\n " . '<li class="' . ($objPage->type == 'root' ? 'tl_folder' : 'tl_file') . ' toggle_select hover-div"><div class="tl_left" style="padding-left:' . ($intMargin + $intSpacing) . 'px">'; $folderAttribute = 'style="margin-left:20px"'; $session[$node][$id] = is_numeric($session[$node][$id]) ? $session[$node][$id] : 0; $level = $intMargin / $intSpacing + 1; $blnIsOpen = !empty($arrFound) || $session[$node][$id] == 1 || in_array($id, $this->arrNodes); if (!empty($childs)) { $folderAttribute = ''; $img = $blnIsOpen ? 'folMinus.svg' : 'folPlus.svg'; $alt = $blnIsOpen ? $GLOBALS['TL_LANG']['MSC']['collapseNode'] : $GLOBALS['TL_LANG']['MSC']['expandNode']; $return .= '<a href="' . \Backend::addToUrl($flag . 'tg=' . $id) . '" title="' . \StringUtil::specialchars($alt) . '" onclick="return AjaxRequest.togglePagetree(this,\'' . $xtnode . '_' . $id . '\',\'' . $this->strField . '\',\'' . $this->strName . '\',' . $level . ')">' . \Image::getHtml($img, '', 'style="margin-right:2px"') . '</a>'; } // Set the protection status $objPage->protected = $objPage->protected || $protectedPage; // Add the current page if (!empty($childs)) { $return .= \Image::getHtml($this->getPageStatusIcon($objPage), '', $folderAttribute) . ' <a href="' . \Backend::addToUrl('pn=' . $objPage->id) . '" title="' . \StringUtil::specialchars($objPage->title . ' (' . $objPage->alias . \Config::get('urlSuffix') . ')') . '">' . ($objPage->type == 'root' ? '<strong>' : '') . $objPage->title . ($objPage->type == 'root' ? '</strong>' : '') . '</a></div> <div class="tl_right">'; } else { $return .= \Image::getHtml($this->getPageStatusIcon($objPage), '', $folderAttribute) . ' ' . ($objPage->type == 'root' ? '<strong>' : '') . $objPage->title . ($objPage->type == 'root' ? '</strong>' : '') . '</div> <div class="tl_right">'; } // Add checkbox or radio button switch ($this->fieldType) { case 'checkbox': $return .= '<input type="checkbox" name="' . $this->strName . '[]" id="' . $this->strName . '_' . $id . '" class="tl_tree_checkbox" value="' . \StringUtil::specialchars($id) . '" onfocus="Backend.getScrollOffset()"' . static::optionChecked($id, $this->varValue) . '>'; break; default: case 'radio': $return .= '<input type="radio" name="' . $this->strName . '" id="' . $this->strName . '_' . $id . '" class="tl_tree_radio" value="' . \StringUtil::specialchars($id) . '" onfocus="Backend.getScrollOffset()"' . static::optionChecked($id, $this->varValue) . '>'; break; } $return .= '</div><div style="clear:both"></div></li>'; // Begin a new submenu if ($blnIsOpen || !empty($childs) && $objSessionBag->get('page_selector_search') != '') { $return .= '<li class="parent" id="' . $node . '_' . $id . '"><ul class="level_' . $level . '">'; for ($k = 0, $c = count($childs); $k < $c; $k++) { $return .= $this->renderPagetree($childs[$k], $intMargin + $intSpacing, $objPage->protected, $blnNoRecursion, $arrFound); } $return .= '</ul></li>'; } return $return; }
/** * Run the tests for given table * * @param string $module * @param string $table * * @return array */ protected function runTestsForTable($module, $table) { $db = Database::getInstance(); $user = BackendUser::getInstance(); $return = []; switch ($table) { case 'tl_calendar_events': $calendars = $db->execute("SELECT id, title FROM tl_calendar WHERE seo_serp_ignore='' ORDER BY title"); while ($calendars->next()) { $test = $this->runTests($table, $db->prepare("SELECT * FROM tl_calendar_events WHERE pid=?")->execute($calendars->id)); $return[] = ['url' => Backend::addToUrl($this->redirectParamName . '=' . $module . '|' . base64_encode('table=' . $table . '&id=' . $calendars->id)), 'reference' => $calendars->title, 'message' => $this->generateTestMessage($test), 'result' => $test, 'hasAccess' => $user->isAdmin || is_array($user->calendars) && in_array($calendars->id, $user->calendars)]; } break; case 'tl_news': $archives = $db->execute("SELECT id, title FROM tl_news_archive WHERE seo_serp_ignore='' ORDER BY title"); while ($archives->next()) { $test = $this->runTests($table, $db->prepare("SELECT * FROM tl_news WHERE pid=?")->execute($archives->id)); $return[] = ['url' => Backend::addToUrl($this->redirectParamName . '=' . $module . '|' . base64_encode('table=' . $table . '&id=' . $archives->id)), 'reference' => $archives->title, 'message' => $this->generateTestMessage($test), 'result' => $test, 'hasAccess' => $user->isAdmin || is_array($user->news) && in_array($archives->id, $user->news)]; } break; case 'tl_page': $rootIds = $db->execute("SELECT id FROM tl_page WHERE type='root' AND seo_serp_ignore=''"); $pageIds = $db->getChildRecords($rootIds->fetchEach('id'), 'tl_page'); if (count($pageIds) > 0) { $pages = $db->execute("SELECT * FROM tl_page WHERE id IN (" . implode(',', $pageIds) . ")"); if ($pages->numRows) { $notes = []; $test = $this->runTests($table, $pages->reset()); // Add the note if the user is not admin and there are some errors or warnings if (!$user->isAdmin && ($test['errors'] > 0 || $test['warnings'] > 0)) { $rootCount = 0; $userCount = 0; // Count the total root pages and those the user has access to while ($pages->next()) { if ($pages->type === 'root') { $rootCount++; if (in_array($pages->id, (array) $user->pagemounts)) { $userCount++; } } } if ($userCount < $rootCount) { $notes[] = $GLOBALS['TL_LANG']['MSC']['seo_serp_module.pagesNote']; } } $return[] = ['url' => Backend::addToUrl($this->redirectParamName . '=' . $module), 'message' => $this->generateTestMessage($test), 'result' => $test, 'hasAccess' => true, 'notes' => $notes]; } } break; } return $return; }
/** * Generate the widget and return it as string * * @return string */ public function generate() { $arrOptions = array(); if (!$this->multiple && count($this->arrOptions) > 1) { $this->arrOptions = array($this->arrOptions[0]); } // The "required" attribute only makes sense for single checkboxes if ($this->mandatory && !$this->multiple) { $this->arrAttributes['required'] = 'required'; } /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); $state = $objSessionBag->get('checkbox_groups'); // Toggle the checkbox group if (\Input::get('cbc')) { $state[\Input::get('cbc')] = isset($state[\Input::get('cbc')]) && $state[\Input::get('cbc')] == 1 ? 0 : 1; $objSessionBag->set('checkbox_groups', $state); $this->redirect(preg_replace('/(&(amp;)?|\\?)cbc=[^& ]*/i', '', \Environment::get('request'))); } $blnFirst = true; $blnCheckAll = true; foreach ($this->arrOptions as $i => $arrOption) { // Single dimension array if (is_numeric($i)) { $arrOptions[] = $this->generateCheckbox($arrOption, $i); continue; } $id = 'cbc_' . $this->strId . '_' . \StringUtil::standardize($i); $img = 'folPlus.svg'; $display = 'none'; if (!isset($state[$id]) || !empty($state[$id])) { $img = 'folMinus.svg'; $display = 'block'; } $arrOptions[] = '<div class="checkbox_toggler' . ($blnFirst ? '_first' : '') . '"><a href="' . \Backend::addToUrl('cbc=' . $id) . '" onclick="AjaxRequest.toggleCheckboxGroup(this,\'' . $id . '\');Backend.getScrollOffset();return false">' . \Image::getHtml($img) . '</a>' . $i . '</div><fieldset id="' . $id . '" class="tl_checkbox_container checkbox_options" style="display:' . $display . '"><input type="checkbox" id="check_all_' . $id . '" class="tl_checkbox" onclick="Backend.toggleCheckboxGroup(this, \'' . $id . '\')"> <label for="check_all_' . $id . '" style="color:#a6a6a6"><em>' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</em></label>'; // Multidimensional array foreach ($arrOption as $k => $v) { $arrOptions[] = $this->generateCheckbox($v, standardize($i) . '_' . $k); } $arrOptions[] = '</fieldset>'; $blnFirst = false; $blnCheckAll = false; } // Add a "no entries found" message if there are no options if (empty($arrOptions)) { $arrOptions[] = '<p class="tl_noopt">' . $GLOBALS['TL_LANG']['MSC']['noResult'] . '</p>'; $blnCheckAll = false; } if ($this->multiple) { return sprintf('<fieldset id="ctrl_%s" class="tl_checkbox_container%s"><legend>%s%s%s%s</legend><input type="hidden" name="%s" value="">%s%s</fieldset>%s', $this->strId, $this->strClass != '' ? ' ' . $this->strClass : '', $this->mandatory ? '<span class="invisible">' . $GLOBALS['TL_LANG']['MSC']['mandatory'] . ' </span>' : '', $this->strLabel, $this->mandatory ? '<span class="mandatory">*</span>' : '', $this->xlabel, $this->strName, $blnCheckAll ? '<input type="checkbox" id="check_all_' . $this->strId . '" class="tl_checkbox" onclick="Backend.toggleCheckboxGroup(this,\'ctrl_' . $this->strId . '\')' . ($this->onclick ? ';' . $this->onclick : '') . '"> <label for="check_all_' . $this->strId . '" style="color:#a6a6a6"><em>' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</em></label><br>' : '', str_replace('<br></fieldset><br>', '</fieldset>', implode('<br>', $arrOptions)), $this->wizard); } else { return sprintf('<div id="ctrl_%s" class="tl_checkbox_single_container%s"><input type="hidden" name="%s" value="">%s</div>%s', $this->strId, $this->strClass != '' ? ' ' . $this->strClass : '', $this->strName, str_replace('<br></div><br>', '</div>', implode('<br>', $arrOptions)), $this->wizard); } }
/** * Add some suffix to the current URL. * * @param AddToUrlEvent $event The event. * * @return void */ public static function handleAddToUrl(AddToUrlEvent $event) { $event->setUrl(Backend::addToUrl($event->getSuffix())); }
/** * Returns HTML markup for the global operation. * * @param PageModel $page * @param array $languages * * @return string */ private function onSwitchButtonCallback(PageModel $page, array $languages) { $page->loadDetails(); $list = ''; $markup = <<<'HTML' <div class="header_switchLanguage"> <svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M782 1078q-1 3-12.5-.5t-31.5-11.5l-20-9q-44-20-87-49-7-5-41-31.5t-38-28.5q-67 103-134 181-81 95-105 110-4 2-19.5 4t-18.5 0q6-4 82-92 21-24 85.5-115t78.5-118q17-30 51-98.5t36-77.5q-8-1-110 33-8 2-27.5 7.5t-34.5 9.5-17 5q-2 2-2 10.5t-1 9.5q-5 10-31 15-23 7-47 0-18-4-28-21-4-6-5-23 6-2 24.5-5t29.5-6q58-16 105-32 100-35 102-35 10-2 43-19.5t44-21.5q9-3 21.5-8t14.5-5.5 6 .5q2 12-1 33 0 2-12.5 27t-26.5 53.5-17 33.5q-25 50-77 131l64 28q12 6 74.5 32t67.5 28q4 1 10.5 25.5t4.5 30.5zm-205-486q3 15-4 28-12 23-50 38-30 12-60 12-26-3-49-26-14-15-18-41l1-3q3 3 19.5 5t26.5 0 58-16q36-12 55-14 17 0 21 17zm698 129l63 227-139-42zm-1108 800l694-232v-1032l-694 233v1031zm1241-317l102 31-181-657-100-31-216 536 102 31 45-110 211 65zm-503-962l573 184v-380zm311 1323l158 13-54 160-40-66q-130 83-276 108-58 12-91 12h-84q-79 0-199.5-39t-183.5-85q-8-7-8-16 0-8 5-13.5t13-5.5q4 0 18 7.5t30.5 16.5 20.5 11q73 37 159.5 61.5t157.5 24.5q95 0 167-14.5t157-50.5q15-7 30.5-15.5t34-19 28.5-16.5zm448-1079v1079l-774-246q-14 6-375 127.5t-368 121.5q-13 0-18-13 0-1-1-3v-1078q3-9 4-10 5-6 20-11 106-35 149-50v-384l558 198q2 0 160.5-55t316-108.5 161.5-53.5q20 0 20 21v418z"/></svg> <strong>%s:</strong> <span>%s <ul> <li><strong>%s:</strong></li> %s </ul> </span> </div> HTML; foreach ($languages as $id => $language) { $list .= sprintf('<li><a href="%s" title="%s">%s</a></li>', Backend::addToUrl('&switchLanguage=' . $id), sprintf($GLOBALS['TL_LANG']['MSC']['switchLanguageTo'][1], $language), $language); } return sprintf($markup, $GLOBALS['TL_LANG']['MSC']['switchLanguage'], $this->getLanguageLabel($page->language), $GLOBALS['TL_LANG']['MSC']['switchLanguageTo'][0], $list); }