/** * Return a search form that allows to search results using regular expressions * * @return string */ protected function searchMenu() { $searchFields = array(); /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); $session = $objSessionBag->all(); // Get search fields foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'] as $k => $v) { if ($v['search']) { $searchFields[] = $k; } } // Return if there are no search fields if (empty($searchFields)) { return ''; } // Store search value in the current session if (\Input::post('FORM_SUBMIT') == 'tl_filters') { $strField = \Input::post('tl_field', true); $strKeyword = ltrim(\Input::postRaw('tl_value'), '*'); // Make sure the regular expression is valid if ($strKeyword != '') { try { $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE " . $strField . " REGEXP ?")->limit(1)->execute($strKeyword); } catch (\Exception $e) { $strKeyword = ''; } } $session['search'][$this->strTable]['field'] = $strField; $session['search'][$this->strTable]['value'] = $strKeyword; $objSessionBag->replace($session); } elseif ($session['search'][$this->strTable]['value'] != '') { $strPattern = "CAST(%s AS CHAR) REGEXP ?"; if (substr(\Config::get('dbCollation'), -3) == '_ci') { $strPattern = "LOWER(CAST(%s AS CHAR)) REGEXP LOWER(?)"; } $fld = $session['search'][$this->strTable]['field']; if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$fld]['foreignKey'])) { list($t, $f) = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$fld]['foreignKey']); $this->procedure[] = "(" . sprintf($strPattern, $fld) . " OR " . sprintf($strPattern, "(SELECT {$f} FROM {$t} WHERE {$t}.id={$this->strTable}.{$fld})") . ")"; $this->values[] = $session['search'][$this->strTable]['value']; } else { $this->procedure[] = sprintf($strPattern, $fld); } $this->values[] = $session['search'][$this->strTable]['value']; } $options_sorter = array(); foreach ($searchFields as $field) { $option_label = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['label'][0] ?: (is_array($GLOBALS['TL_LANG']['MSC'][$field]) ? $GLOBALS['TL_LANG']['MSC'][$field][0] : $GLOBALS['TL_LANG']['MSC'][$field]); $options_sorter[Utf8::toAscii($option_label) . '_' . $field] = ' <option value="' . specialchars($field) . '"' . ($field == $session['search'][$this->strTable]['field'] ? ' selected="selected"' : '') . '>' . $option_label . '</option>'; } // Sort by option values $options_sorter = natcaseksort($options_sorter); $active = $session['search'][$this->strTable]['value'] != '' ? true : false; return ' <div class="tl_search tl_subpanel"> <strong>' . $GLOBALS['TL_LANG']['MSC']['search'] . ':</strong> <select name="tl_field" class="tl_select' . ($active ? ' active' : '') . '"> ' . implode("\n", $options_sorter) . ' </select> <span> = </span> <input type="search" name="tl_value" class="tl_text' . ($active ? ' active' : '') . '" value="' . specialchars($session['search'][$this->strTable]['value']) . '"> </div>'; }
/** * Generate the widget and return it as string * * @return string */ public function generate() { $this->import('BackendUser', 'User'); $this->convertValuesToPaths(); if ($this->extensions != '') { $this->arrValidFileTypes = \StringUtil::trimsplit(',', strtolower($this->extensions)); } /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); // Store the keyword if (\Input::post('FORM_SUBMIT') == 'item_selector') { $strKeyword = ltrim(\Input::postRaw('keyword'), '*'); // Make sure the regular expression is valid if ($strKeyword != '') { try { $this->Database->prepare("SELECT * FROM tl_files WHERE name REGEXP ?")->limit(1)->execute($strKeyword); } catch (\Exception $e) { $strKeyword = ''; } } $objSessionBag->set('file_selector_search', $strKeyword); $this->reload(); } $tree = ''; $for = $objSessionBag->get('file_selector_search'); $arrFound = array(); // Search for a specific file if ($for != '') { // Wrap in a try catch block in case the regular expression is invalid (see #7743) try { $strPattern = "CAST(name AS CHAR) REGEXP ?"; if (substr(\Config::get('dbCollation'), -3) == '_ci') { $strPattern = "LOWER(CAST(name AS CHAR)) REGEXP LOWER(?)"; } $strType = ''; if (strpos($for, 'type:file') !== false) { $strType = " AND type='file'"; $for = trim(str_replace('type:file', '', $for)); } if (strpos($for, 'type:folder') !== false) { $strType = " AND type='folder'"; $for = trim(str_replace('type:folder', '', $for)); } $objRoot = $this->Database->prepare("SELECT path, type, extension FROM tl_files WHERE {$strPattern} {$strType} GROUP BY path")->execute($for); if ($objRoot->numRows < 1) { $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'] = array(''); } else { $arrPaths = array(); // Respect existing limitations if ($this->path != '') { while ($objRoot->next()) { if (strncmp($this->path . '/', $objRoot->path . '/', strlen($this->path) + 1) === 0) { if ($objRoot->type == 'folder' || empty($this->arrValidFileTypes) || in_array($objRoot->extension, $this->arrValidFileTypes)) { $arrFound[] = $objRoot->path; } $arrPaths[] = $objRoot->type == 'folder' ? $objRoot->path : dirname($objRoot->path); } } } elseif ($this->User->isAdmin) { // Show all files to admins while ($objRoot->next()) { if ($objRoot->type == 'folder' || empty($this->arrValidFileTypes) || in_array($objRoot->extension, $this->arrValidFileTypes)) { $arrFound[] = $objRoot->path; } $arrPaths[] = $objRoot->type == 'folder' ? $objRoot->path : dirname($objRoot->path); } } else { if (is_array($this->User->filemounts)) { while ($objRoot->next()) { // Show only mounted folders to regular users foreach ($this->User->filemounts as $path) { if (strncmp($path . '/', $objRoot->path . '/', strlen($path) + 1) === 0) { if ($objRoot->type == 'folder' || empty($this->arrValidFileTypes) || in_array($objRoot->extension, $this->arrValidFileTypes)) { $arrFound[] = $objRoot->path; } $arrPaths[] = $objRoot->type == 'folder' ? $objRoot->path : dirname($objRoot->path); } } } } } $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'] = array_unique($arrPaths); } } catch (\Exception $e) { } } $strNode = $objSessionBag->get('tl_files_picker'); // Unset the node if it is not within the path (see #5899) if ($strNode != '' && $this->path != '') { if (strncmp($strNode . '/', $this->path . '/', strlen($this->path) + 1) !== 0) { $objSessionBag->remove('tl_files_picker'); } } // Add the breadcrumb menu if (\Input::get('do') != 'files') { \Backend::addFilesBreadcrumb('tl_files_picker'); } // Root nodes (breadcrumb menu) if (!empty($GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'])) { $root = $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root']; // Allow only those roots that are within the custom path if ($this->path != '') { $root = array_intersect(preg_grep('/^' . preg_quote($this->path, '/') . '(?:$|\\/)/', $root), $root); if (empty($root)) { // Set all folders inside the custom path as root nodes $root = array_map(function ($el) { return $this->path . '/' . $el; }, scan(TL_ROOT . '/' . $this->path)); // Hide the breadcrumb $GLOBALS['TL_DCA']['tl_file']['list']['sorting']['breadcrumb'] = ''; } } $nodes = $this->eliminateNestedPaths($root); foreach ($nodes as $node) { $tree .= $this->renderFiletree(TL_ROOT . '/' . $node, 0, true, true, $arrFound); } } elseif ($this->path != '') { $tree .= $this->renderFiletree(TL_ROOT . '/' . $this->path, 0, false, $this->isProtectedPath($this->path), $arrFound); } elseif ($this->User->isAdmin) { $tree .= $this->renderFiletree(TL_ROOT . '/' . \Config::get('uploadPath'), 0, false, true, $arrFound); } else { $nodes = $this->eliminateNestedPaths($this->User->filemounts); foreach ($nodes as $node) { $tree .= $this->renderFiletree(TL_ROOT . '/' . $node, 0, true, true, $arrFound); } } // Select all checkboxes if ($this->fieldType == 'checkbox') { $strReset = "\n" . ' <li class="tl_folder"><div class="tl_left"> </div> <div class="tl_right"><label for="check_all_' . $this->strId . '" class="tl_change_selected">' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</label> <input type="checkbox" id="check_all_' . $this->strId . '" class="tl_tree_checkbox" value="" onclick="Backend.toggleCheckboxGroup(this,\'' . $this->strName . '\')"></div><div style="clear:both"></div></li>'; } else { $strReset = "\n" . ' <li class="tl_folder"><div class="tl_left"> </div> <div class="tl_right"><label for="reset_' . $this->strId . '" class="tl_change_selected">' . $GLOBALS['TL_LANG']['MSC']['resetSelected'] . '</label> <input type="radio" name="' . $this->strName . '" id="reset_' . $this->strName . '" class="tl_tree_radio" value="" onfocus="Backend.getScrollOffset()"></div><div style="clear:both"></div></li>'; } // Return the tree return '<ul class="tl_listing tree_view picker_selector' . ($this->strClass != '' ? ' ' . $this->strClass : '') . '" id="' . $this->strId . '"> <li class="tl_folder_top"><div class="tl_left">' . \Image::getHtml($GLOBALS['TL_DCA']['tl_files']['list']['sorting']['icon'] ?: 'filemounts.svg') . ' ' . (\Config::get('websiteTitle') ?: 'Contao Open Source CMS') . '</div> <div class="tl_right"> </div><div style="clear:both"></div></li><li class="parent" id="' . $this->strId . '_parent"><ul>' . $tree . $strReset . ' </ul></li></ul>'; }
/** * 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); // Check whether file type is editable if (!in_array($objFile->extension, trimsplit(',', \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'); } // Add the versioning routines if ($this->blnIsDbAssisted) { $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) { /** @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 ($this->blnIsDbAssisted && $GLOBALS['TL_DCA'][$this->strTable]['config']['enableVersioning'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['hideVersionMenu']) { $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; }
/** * Generate the widget and return it as string * * @return string */ public function generate() { $this->import('BackendUser', 'User'); /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); // Store the keyword if (\Input::post('FORM_SUBMIT') == 'item_selector') { $strKeyword = ltrim(\Input::postRaw('keyword'), '*'); // Make sure the regular expression is valid if ($strKeyword != '') { try { $this->Database->prepare("SELECT * FROM tl_page WHERE title REGEXP ?")->limit(1)->execute($strKeyword); } catch (\Exception $e) { $strKeyword = ''; } } $objSessionBag->set('page_selector_search', $strKeyword); $this->reload(); } $tree = ''; $this->getPathNodes(); $for = $objSessionBag->get('page_selector_search'); $arrFound = array(); // Search for a specific page if ($for != '') { // Wrap in a try catch block in case the regular expression is invalid (see #7743) try { $strPattern = "CAST(title AS CHAR) REGEXP ?"; if (substr(\Config::get('dbCollation'), -3) == '_ci') { $strPattern = "LOWER(CAST(title AS CHAR)) REGEXP LOWER(?)"; } $objRoot = $this->Database->prepare("SELECT id FROM tl_page WHERE {$strPattern} GROUP BY id")->execute($for); if ($objRoot->numRows < 1) { $GLOBALS['TL_DCA']['tl_page']['list']['sorting']['root'] = array(0); } else { $arrIds = array(); // Respect existing limitations if (is_array($this->rootNodes)) { while ($objRoot->next()) { // Predefined node set (see #3563) if (count(array_intersect($this->rootNodes, $this->Database->getParentRecords($objRoot->id, 'tl_page'))) > 0) { $arrFound[] = $objRoot->id; $arrIds[] = $objRoot->id; } } } elseif ($this->User->isAdmin) { // Show all pages to admins while ($objRoot->next()) { $arrFound[] = $objRoot->id; $arrIds[] = $objRoot->id; } } else { while ($objRoot->next()) { // Show only mounted pages to regular users if (count(array_intersect($this->User->pagemounts, $this->Database->getParentRecords($objRoot->id, 'tl_page'))) > 0) { $arrFound[] = $objRoot->id; $arrIds[] = $objRoot->id; } } } $GLOBALS['TL_DCA']['tl_page']['list']['sorting']['root'] = array_unique($arrIds); } } catch (\Exception $e) { } } $strNode = $objSessionBag->get('tl_page_picker'); // Unset the node if it is not within the predefined node set (see #5899) if ($strNode > 0 && is_array($this->rootNodes)) { if (!in_array($strNode, $this->Database->getChildRecords($this->rootNodes, 'tl_page'))) { $objSessionBag->remove('tl_page_picker'); } } // Add the breadcrumb menu if (\Input::get('do') != 'page') { \Backend::addPagesBreadcrumb('tl_page_picker'); } // Root nodes (breadcrumb menu) if (!empty($GLOBALS['TL_DCA']['tl_page']['list']['sorting']['root'])) { $root = $GLOBALS['TL_DCA']['tl_page']['list']['sorting']['root']; // Allow only those roots that are allowed in root nodes if (is_array($this->rootNodes)) { $root = array_intersect(array_merge($this->rootNodes, $this->Database->getChildRecords($this->rootNodes, 'tl_page')), $root); if (empty($root)) { $root = $this->rootNodes; // Hide the breadcrumb $GLOBALS['TL_DCA']['tl_page']['list']['sorting']['breadcrumb'] = ''; } } $nodes = $this->eliminateNestedPages($root); foreach ($nodes as $node) { $tree .= $this->renderPagetree($node, -20, false, false, $arrFound); } } elseif (is_array($this->rootNodes)) { $nodes = $this->eliminateNestedPages($this->rootNodes); foreach ($nodes as $node) { $tree .= $this->renderPagetree($node, -20, false, false, $arrFound); } } elseif ($this->User->isAdmin) { $objPage = $this->Database->prepare("SELECT id FROM tl_page WHERE pid=? ORDER BY sorting")->execute(0); while ($objPage->next()) { $tree .= $this->renderPagetree($objPage->id, -20, false, false, $arrFound); } } else { $nodes = $this->eliminateNestedPages($this->User->pagemounts); foreach ($nodes as $node) { $tree .= $this->renderPagetree($node, -20, false, false, $arrFound); } } // Select all checkboxes if ($this->fieldType == 'checkbox') { $strReset = "\n" . ' <li class="tl_folder"><div class="tl_left"> </div> <div class="tl_right"><label for="check_all_' . $this->strId . '" class="tl_change_selected">' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</label> <input type="checkbox" id="check_all_' . $this->strId . '" class="tl_tree_checkbox" value="" onclick="Backend.toggleCheckboxGroup(this,\'' . $this->strName . '\')"></div><div style="clear:both"></div></li>'; } else { $strReset = "\n" . ' <li class="tl_folder"><div class="tl_left"> </div> <div class="tl_right"><label for="reset_' . $this->strId . '" class="tl_change_selected">' . $GLOBALS['TL_LANG']['MSC']['resetSelected'] . '</label> <input type="radio" name="' . $this->strName . '" id="reset_' . $this->strName . '" class="tl_tree_radio" value="" onfocus="Backend.getScrollOffset()"></div><div style="clear:both"></div></li>'; } // Return the tree return '<ul class="tl_listing tree_view picker_selector' . ($this->strClass != '' ? ' ' . $this->strClass : '') . '" id="' . $this->strId . '"> <li class="tl_folder_top"><div class="tl_left">' . \Image::getHtml($GLOBALS['TL_DCA']['tl_page']['list']['sorting']['icon'] ?: 'pagemounts.svg') . ' ' . (\Config::get('websiteTitle') ?: 'Contao Open Source CMS') . '</div> <div class="tl_right"> </div><div style="clear:both"></div></li><li class="parent" id="' . $this->strId . '_parent"><ul>' . $tree . $strReset . ' </ul></li></ul>'; }
/** * Return a search form that allows to search results using regular expressions * * @return string */ protected function searchMenu() { /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); $session = $objSessionBag->all(); // Store search value in the current session if (\Input::post('FORM_SUBMIT') == 'tl_filters') { $strField = \Input::post('tl_field', true); $strKeyword = ltrim(\Input::postRaw('tl_value'), '*'); // Make sure the regular expression is valid if ($strKeyword != '') { try { $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE " . $strField . " REGEXP ?")->limit(1)->execute($strKeyword); } catch (\Exception $e) { $strKeyword = ''; } } $session['search'][$this->strTable]['field'] = $strField; $session['search'][$this->strTable]['value'] = $strKeyword; $objSessionBag->replace($session); } elseif ($session['search'][$this->strTable]['value'] != '') { $strPattern = "CAST(name AS CHAR) REGEXP ?"; if (substr(\Config::get('dbCollation'), -3) == '_ci') { $strPattern = "LOWER(CAST(name AS CHAR)) REGEXP LOWER(?)"; } if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields']['name']['foreignKey'])) { list($t, $f) = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields']['name']['foreignKey']); $this->procedure[] = "(" . $strPattern . " OR " . sprintf($strPattern, "(SELECT {$f} FROM {$t} WHERE {$t}.id={$this->strTable}.name)") . ")"; $this->values[] = $session['search'][$this->strTable]['value']; } else { $this->procedure[] = $strPattern; } $this->values[] = $session['search'][$this->strTable]['value']; } $active = $session['search'][$this->strTable]['value'] != '' ? true : false; return ' <div class="tl_search tl_subpanel"> <strong>' . $GLOBALS['TL_LANG']['MSC']['search'] . ':</strong> <select name="tl_field" class="tl_select' . ($active ? ' active' : '') . '"> <option value="name">' . ($GLOBALS['TL_DCA'][$this->strTable]['fields']['name']['label'][0] ?: (is_array($GLOBALS['TL_LANG']['MSC']['name']) ? $GLOBALS['TL_LANG']['MSC']['name'][0] : $GLOBALS['TL_LANG']['MSC']['name'])) . '</option> </select> <span> = </span> <input type="search" name="tl_value" class="tl_text' . ($active ? ' active' : '') . '" value="' . \StringUtil::specialchars($session['search'][$this->strTable]['value']) . '"> </div>'; }