/** * Generate the widget and return it as string * * @return string */ public function generate() { $this->import('BackendUser', 'User'); $this->convertValuesToPaths(); /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); $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'); } $tree = ''; // Root nodes (breadcrumb menu) if (!empty($GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'])) { $nodes = $this->eliminateNestedPaths($GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root']); foreach ($nodes as $node) { $tree .= $this->renderFiletree(TL_ROOT . '/' . $node, 0, true); } } elseif ($this->path != '') { $protected = true; $path = $this->path; // Check if the folder is protected (see #287) do { if (file_exists(TL_ROOT . '/' . $path . '/.public')) { $protected = false; } $path = dirname($path); } while ($path != '.' && $protected !== false); $tree .= $this->renderFiletree(TL_ROOT . '/' . $this->path, 0, false, $protected); } elseif ($this->User->isAdmin) { $tree .= $this->renderFiletree(TL_ROOT . '/' . \Config::get('uploadPath'), 0); } else { $nodes = $this->eliminateNestedPaths($this->User->filemounts); foreach ($nodes as $node) { $tree .= $this->renderFiletree(TL_ROOT . '/' . $node, 0, true); } } // 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.gif') . ' ' . (\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>'; }
/** * 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>'; }