/** * mb_convert_encoding */ function mb_convert_encoding($str, $to_encoding, $from_encoding = null) { if (null === $from_encoding) { return utf8_convert_encoding($str, $to_encoding); } else { return utf8_convert_encoding($str, $to_encoding, $from_encoding); } }
/** * Parse the meta.txt file of a folder * @param string * @param boolean * @deprecated Meta data is now stored in the database */ protected function parseMetaFile($strPath, $blnIsFile = false) { if (in_array($strPath, $this->arrProcessed)) { return; } $strFile = $strPath . '/meta_' . $GLOBALS['TL_LANGUAGE'] . '.txt'; if (!file_exists(TL_ROOT . '/' . $strFile)) { $strFile = $strPath . '/meta.txt'; if (!file_exists(TL_ROOT . '/' . $strFile)) { return; } } $strBuffer = file_get_contents(TL_ROOT . '/' . $strFile); $strBuffer = utf8_convert_encoding($strBuffer, $GLOBALS['TL_CONFIG']['characterSet']); $arrBuffer = array_filter(trimsplit('[\\n\\r]+', $strBuffer)); foreach ($arrBuffer as $v) { list($strLabel, $strValue) = array_map('trim', explode('=', $v, 2)); $this->arrMeta[$strLabel] = array_map('trim', explode('|', $strValue)); if (!$blnIsFile || in_array($strPath . '/' . $strLabel, $this->multiSRC)) { $this->arrAux[] = $strPath . '/' . $strLabel; } } $this->arrProcessed[] = $strPath; }
/** * Output the template file */ protected function output() { $this->Template->theme = $this->getTheme(); $this->Template->base = $this->Environment->base; $this->Template->language = $GLOBALS['TL_LANGUAGE']; $this->Template->title = $GLOBALS['TL_CONFIG']['websiteTitle']; $this->Template->charset = $GLOBALS['TL_CONFIG']['characterSet']; $this->Template->href = ampersand($this->Environment->request, true) . '&download=1'; $this->Template->headline = basename(utf8_convert_encoding($this->strFile, $GLOBALS['TL_CONFIG']['characterSet'])); $this->Template->label_imagesize = $GLOBALS['TL_LANG']['MSC']['fileImageSize']; $this->Template->label_filesize = $GLOBALS['TL_LANG']['MSC']['fileSize']; $this->Template->label_ctime = $GLOBALS['TL_LANG']['MSC']['fileCreated']; $this->Template->label_mtime = $GLOBALS['TL_LANG']['MSC']['fileModified']; $this->Template->label_atime = $GLOBALS['TL_LANG']['MSC']['fileAccessed']; $this->Template->label_atime = $GLOBALS['TL_LANG']['MSC']['fileAccessed']; $this->Template->label_path = $GLOBALS['TL_LANG']['MSC']['filePath']; $this->Template->download = $GLOBALS['TL_LANG']['MSC']['fileDownload']; $this->Template->output(); }
/** * Recursively render the filetree * * @param string $path * @param integer $intMargin * @param boolean $mount * @param boolean $blnProtected * * @return string */ protected function renderFiletree($path, $intMargin, $mount = false, $blnProtected = false) { // 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; $session = $this->Session->getData(); $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; $this->Session->setData($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++) { $countFiles = 0; $content = scan($folders[$f]); $return .= "\n " . '<li class="' . $folderClass . ' toggle_select" onmouseover="Theme.hoverDiv(this, 1)" onmouseout="Theme.hoverDiv(this, 0)"><div class="tl_left" style="padding-left:' . $intMargin . 'px">'; // Check whether there are subfolders or files foreach ($content as $v) { if (is_dir($folders[$f] . '/' . $v) || $this->files || $this->filesOnly) { $countFiles++; } } $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 = $session[$node][$tid] == 1 || count(preg_grep('/^' . preg_quote($currentFolder, '/') . '\\//', $this->varValue)) > 0; // Add a toggle button if there are childs if ($countFiles > 0) { $folderAttribute = ''; $img = $blnIsOpen ? 'folMinus.gif' : 'folPlus.gif'; $alt = $blnIsOpen ? $GLOBALS['TL_LANG']['MSC']['collapseNode'] : $GLOBALS['TL_LANG']['MSC']['expandNode']; $return .= '<a href="' . $this->addToUrl($flag . 'tg=' . $tid) . '" title="' . 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 === true || array_search('.htaccess', $content) !== false ? true : false; $folderImg = $protected ? 'folderCP.gif' : 'folderC.gif'; $folderLabel = $this->files || $this->filesOnly ? '<strong>' . specialchars(basename($currentFolder)) . '</strong>' : specialchars(basename($currentFolder)); // Add the current folder $return .= \Image::getHtml($folderImg, '', $folderAttribute) . ' <a href="' . $this->addToUrl('node=' . $this->urlEncode($currentFolder)) . '" title="' . 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="' . 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="' . specialchars($currentFolder) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFolder, $this->varValue) . '>'; break; } } $return .= '</div><div style="clear:both"></div></li>'; // Call the next node if ($countFiles > 0 && $blnIsOpen) { $return .= '<li class="parent" id="' . $xtnode . '_' . $tid . '"><ul class="level_' . $level . '">'; $return .= $this->renderFiletree($folders[$f], $intMargin + $intSpacing, false, $protected); $return .= '</ul></li>'; } } // Process files if ($this->files || $this->filesOnly) { $allowedExtensions = null; if ($this->extensions != '') { $allowedExtensions = trimsplit(',', $this->extensions); } 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, true); // Check file extension if (is_array($allowedExtensions) && !in_array($objFile->extension, $allowedExtensions)) { continue; } $return .= "\n " . '<li class="tl_file toggle_select" onmouseover="Theme.hoverDiv(this, 1)" onmouseout="Theme.hoverDiv(this, 0)"><div class="tl_left" style="padding-left:' . ($intMargin + $intSpacing) . 'px">'; // Generate thumbnail if ($objFile->isImage && $objFile->viewHeight > 0) { if ($objFile->width && $objFile->height) { $thumbnail .= ' <span class="tl_gray">(' . $objFile->width . 'x' . $objFile->height . ')</span>'; } if (\Config::get('thumbnails') && ($objFile->isSvgImage || $objFile->height <= \Config::get('gdMaxImgHeight') && $objFile->width <= \Config::get('gdMaxImgWidth'))) { $thumbnail .= '<br><img src="' . TL_FILES_URL . \Image::get($currentEncoded, 400, $objFile->height && $objFile->height < 50 ? $objFile->height : 50, 'box') . '" alt="" style="margin:0 0 2px -19px">'; } } $return .= \Image::getHtml($objFile->icon, $objFile->mime) . ' ' . utf8_convert_encoding(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="' . 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="' . specialchars($currentFile) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFile, $this->varValue) . '>'; break; } $return .= '</div><div style="clear:both"></div></li>'; } } return $return; }
/** * Run the controller and parse the template */ public function run() { if ($this->strFile == '') { die('No file given'); } // Make sure there are no attempts to hack the file system if (preg_match('@^\\.+@i', $this->strFile) || preg_match('@\\.+/@i', $this->strFile) || preg_match('@(://)+@i', $this->strFile)) { die('Invalid file name'); } // Limit preview to the files directory if (!preg_match('@^' . preg_quote(\Config::get('uploadPath'), '@') . '@i', $this->strFile)) { die('Invalid path'); } // Check whether the file exists if (!file_exists(TL_ROOT . '/' . $this->strFile)) { die('File not found'); } // Check whether the file is mounted (thanks to Marko Cupic) if (!$this->User->hasAccess($this->strFile, 'filemounts')) { die('Permission denied'); } // Open the download dialogue if (\Input::get('download')) { $objFile = new \File($this->strFile, true); $objFile->sendToBrowser(); } /** @var \BackendTemplate|object $objTemplate */ $objTemplate = new \BackendTemplate('be_popup'); // Add the resource (see #6880) if (($objModel = \FilesModel::findByPath($this->strFile)) === null) { if (\Dbafs::shouldBeSynchronized($this->strFile)) { $objModel = \Dbafs::addResource($this->strFile); } } if ($objModel !== null) { $objTemplate->uuid = \StringUtil::binToUuid($objModel->uuid); // see #5211 } // Add the file info if (is_dir(TL_ROOT . '/' . $this->strFile)) { $objFile = new \Folder($this->strFile, true); $objTemplate->filesize = $this->getReadableSize($objFile->size) . ' (' . number_format($objFile->size, 0, $GLOBALS['TL_LANG']['MSC']['decimalSeparator'], $GLOBALS['TL_LANG']['MSC']['thousandsSeparator']) . ' Byte)'; } else { $objFile = new \File($this->strFile, true); // Image if ($objFile->isImage) { $objTemplate->isImage = true; $objTemplate->width = $objFile->width; $objTemplate->height = $objFile->height; $objTemplate->src = $this->urlEncode($this->strFile); } $objTemplate->href = ampersand(\Environment::get('request'), true) . '&download=1'; $objTemplate->filesize = $this->getReadableSize($objFile->filesize) . ' (' . number_format($objFile->filesize, 0, $GLOBALS['TL_LANG']['MSC']['decimalSeparator'], $GLOBALS['TL_LANG']['MSC']['thousandsSeparator']) . ' Byte)'; } $objTemplate->icon = $objFile->icon; $objTemplate->mime = $objFile->mime; $objTemplate->ctime = \Date::parse(\Config::get('datimFormat'), $objFile->ctime); $objTemplate->mtime = \Date::parse(\Config::get('datimFormat'), $objFile->mtime); $objTemplate->atime = \Date::parse(\Config::get('datimFormat'), $objFile->atime); $objTemplate->path = specialchars($this->strFile); $objTemplate->theme = \Backend::getTheme(); $objTemplate->base = \Environment::get('base'); $objTemplate->language = $GLOBALS['TL_LANGUAGE']; $objTemplate->title = specialchars($this->strFile); $objTemplate->charset = \Config::get('characterSet'); $objTemplate->headline = basename(utf8_convert_encoding($this->strFile, \Config::get('characterSet'))); $objTemplate->label_uuid = $GLOBALS['TL_LANG']['MSC']['fileUuid']; $objTemplate->label_imagesize = $GLOBALS['TL_LANG']['MSC']['fileImageSize']; $objTemplate->label_filesize = $GLOBALS['TL_LANG']['MSC']['fileSize']; $objTemplate->label_ctime = $GLOBALS['TL_LANG']['MSC']['fileCreated']; $objTemplate->label_mtime = $GLOBALS['TL_LANG']['MSC']['fileModified']; $objTemplate->label_atime = $GLOBALS['TL_LANG']['MSC']['fileAccessed']; $objTemplate->label_path = $GLOBALS['TL_LANG']['MSC']['filePath']; $objTemplate->download = specialchars($GLOBALS['TL_LANG']['MSC']['fileDownload']); \Config::set('debugMode', false); $objTemplate->output(); }
function mb_convert_encoding($str, $to, $from = null) { if ($from === null) { return utf8_convert_encoding($str, $to); } return utf8_convert_encoding($str, $to, $from); }
/** * Render the file tree and return it as HTML string * * @param string $path * @param integer $intMargin * @param boolean $mount * @param boolean $blnProtected * @param array $arrClipboard * * @return string */ protected function generateTree($path, $intMargin, $mount = false, $blnProtected = false, $arrClipboard = null) { static $session; $session = $this->Session->getData(); // Get the session data and toggle the nodes if (\Input::get('tg')) { $session['filetree'][\Input::get('tg')] = isset($session['filetree'][\Input::get('tg')]) && $session['filetree'][\Input::get('tg')] == 1 ? 0 : 1; $this->Session->setData($session); $this->redirect(preg_replace('/(&(amp;)?|\\?)tg=[^& ]*/i', '', \Environment::get('request'))); } $return = ''; $files = array(); $folders = array(); $intSpacing = 20; $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_file($path . '/' . $v)) { $files[] = $path . '/' . $v; } else { if ($v == '__new__') { $this->Files->rmdir(str_replace(TL_ROOT . '/', '', $path) . '/' . $v); } else { $folders[] = $path . '/' . $v; } } } natcasesort($folders); $folders = array_values($folders); natcasesort($files); $files = array_values($files); } // Folders for ($f = 0, $c = count($folders); $f < $c; $f++) { $md5 = substr(md5($folders[$f]), 0, 8); $content = scan($folders[$f]); $currentFolder = str_replace(TL_ROOT . '/', '', $folders[$f]); $session['filetree'][$md5] = is_numeric($session['filetree'][$md5]) ? $session['filetree'][$md5] : 0; $currentEncoded = $this->urlEncode($currentFolder); $countFiles = count($content); // Subtract files that will not be shown foreach ($content as $file) { if (strncmp($file, '.', 1) === 0) { --$countFiles; } elseif (!empty($this->arrValidFileTypes) && is_file($folders[$f] . '/' . $file) && !in_array(strtolower(substr($file, strrpos($file, '.') + 1)), $this->arrValidFileTypes)) { --$countFiles; } } $return .= "\n " . '<li class="tl_folder click2edit toggle_select" onmouseover="Theme.hoverDiv(this,1)" onmouseout="Theme.hoverDiv(this,0)"><div class="tl_left" style="padding-left:' . ($intMargin + ($countFiles < 1 ? 20 : 0)) . 'px">'; // Add a toggle button if there are childs if ($countFiles > 0) { $img = $session['filetree'][$md5] == 1 ? 'folMinus.gif' : 'folPlus.gif'; $alt = $session['filetree'][$md5] == 1 ? $GLOBALS['TL_LANG']['MSC']['collapseNode'] : $GLOBALS['TL_LANG']['MSC']['expandNode']; $return .= '<a href="' . $this->addToUrl('tg=' . $md5) . '" title="' . specialchars($alt) . '" onclick="Backend.getScrollOffset(); return AjaxRequest.toggleFileManager(this, \'filetree_' . $md5 . '\', \'' . $currentFolder . '\', ' . $level . ')">' . \Image::getHtml($img, '', 'style="margin-right:2px"') . '</a>'; } $protected = $blnProtected === true || array_search('.htaccess', $content) !== false ? true : false; $folderImg = $protected ? 'folderCP.gif' : 'folderC.gif'; // Add the current folder $strFolderNameEncoded = utf8_convert_encoding(specialchars(basename($currentFolder)), \Config::get('characterSet')); $return .= \Image::getHtml($folderImg, '') . ' <a href="' . $this->addToUrl('fn=' . $currentEncoded) . '" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['selectNode']) . '"><strong>' . $strFolderNameEncoded . '</strong></a></div> <div class="tl_right">'; // Paste buttons if ($arrClipboard !== false && \Input::get('act') != 'select') { $imagePasteInto = \Image::getHtml('pasteinto.gif', $GLOBALS['TL_LANG'][$this->strTable]['pasteinto'][0]); $return .= ($arrClipboard['mode'] == 'cut' || $arrClipboard['mode'] == 'copy') && preg_match('/^' . preg_quote($arrClipboard['id'], '/') . '/i', $currentFolder) ? \Image::getHtml('pasteinto_.gif') : '<a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&mode=2&pid=' . $currentEncoded . (!is_array($arrClipboard['id']) ? '&id=' . $arrClipboard['id'] : '')) . '" title="' . specialchars($GLOBALS['TL_LANG'][$this->strTable]['pasteinto'][1]) . '" onclick="Backend.getScrollOffset()">' . $imagePasteInto . '</a> '; } else { // Do not display buttons for mounted folders if ($this->User->isAdmin || !in_array($currentFolder, $this->User->filemounts)) { $return .= \Input::get('act') == 'select' ? '<input type="checkbox" name="IDS[]" id="ids_' . md5($currentEncoded) . '" class="tl_tree_checkbox" value="' . $currentEncoded . '">' : $this->generateButtons(array('id' => $currentEncoded, 'popupWidth' => 640, 'popupHeight' => 132, 'fileNameEncoded' => $strFolderNameEncoded), $this->strTable); } // Upload button if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable'] && \Input::get('act') != 'select') { $return .= ' <a href="' . $this->addToUrl('&act=move&mode=2&pid=' . $currentEncoded) . '" title="' . specialchars(sprintf($GLOBALS['TL_LANG']['tl_files']['uploadFF'], $currentEncoded)) . '">' . \Image::getHtml('new.gif', $GLOBALS['TL_LANG'][$this->strTable]['move'][0]) . '</a>'; } } $return .= '</div><div style="clear:both"></div></li>'; // Call the next node if (!empty($content) && $session['filetree'][$md5] == 1) { $return .= '<li class="parent" id="filetree_' . $md5 . '"><ul class="level_' . $level . '">'; $return .= $this->generateTree($folders[$f], $intMargin + $intSpacing, false, $protected, $arrClipboard); $return .= '</ul></li>'; } } // Process files for ($h = 0, $c = count($files); $h < $c; $h++) { $thumbnail = ''; $popupWidth = 600; $popupHeight = 161; $currentFile = str_replace(TL_ROOT . '/', '', $files[$h]); $objFile = new \File($currentFile, true); if (!empty($this->arrValidFileTypes) && !in_array($objFile->extension, $this->arrValidFileTypes)) { continue; } $currentEncoded = $this->urlEncode($currentFile); $return .= "\n " . '<li class="tl_file click2edit toggle_select" onmouseover="Theme.hoverDiv(this,1)" onmouseout="Theme.hoverDiv(this,0)"><div class="tl_left" style="padding-left:' . ($intMargin + $intSpacing) . 'px">'; // Generate the thumbnail if ($objFile->isImage) { if ($objFile->viewHeight > 0) { if ($objFile->width && $objFile->height) { $popupWidth = $objFile->width > 600 ? $objFile->width + 61 : 661; $popupHeight = $objFile->height + 210; } else { $popupWidth = 661; $popupHeight = 625 / $objFile->viewWidth * $objFile->viewHeight + 210; } $thumbnail .= ' <span class="tl_gray">(' . $this->getReadableSize($objFile->filesize); if ($objFile->width && $objFile->height) { $thumbnail .= ', ' . $objFile->width . 'x' . $objFile->height . ' px'; } $thumbnail .= ')</span>'; if (\Config::get('thumbnails') && ($objFile->isSvgImage || $objFile->height <= \Config::get('gdMaxImgHeight') && $objFile->width <= \Config::get('gdMaxImgWidth'))) { $thumbnail .= '<br>' . \Image::getHtml(\Image::get($currentEncoded, 400, $objFile->height && $objFile->height < 50 ? $objFile->height : 50, 'box'), '', 'style="margin:0 0 2px -19px"'); } } else { $popupHeight = 360; // dimensionless SVGs are rendered at 300x150px, so the popup needs to be 150px + 210px high } } else { $thumbnail .= ' <span class="tl_gray">(' . $this->getReadableSize($objFile->filesize) . ')</span>'; } $strFileNameEncoded = utf8_convert_encoding(specialchars(basename($currentFile)), \Config::get('characterSet')); // No popup links for templates and in the popup file manager if ($this->strTable == 'tl_templates' || \Input::get('popup')) { $return .= \Image::getHtml($objFile->icon) . ' ' . $strFileNameEncoded . $thumbnail . '</div> <div class="tl_right">'; } else { $return .= '<a href="' . $currentEncoded . '" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['view']) . '" target="_blank">' . \Image::getHtml($objFile->icon, $objFile->mime) . '</a> ' . $strFileNameEncoded . $thumbnail . '</div> <div class="tl_right">'; } // Buttons if ($arrClipboard !== false && \Input::get('act') != 'select') { $_buttons = ' '; } else { $_buttons = \Input::get('act') == 'select' ? '<input type="checkbox" name="IDS[]" id="ids_' . md5($currentEncoded) . '" class="tl_tree_checkbox" value="' . $currentEncoded . '">' : $this->generateButtons(array('id' => $currentEncoded, 'popupWidth' => $popupWidth, 'popupHeight' => $popupHeight, 'fileNameEncoded' => $strFileNameEncoded), $this->strTable); } $return .= $_buttons . '</div><div style="clear:both"></div></li>'; } return $return; }
/** * Render the file tree and return it as HTML string * @param string * @param integer * @param boolean * @param boolean * @param array * @return string */ protected function generateTree($path, $intMargin, $mount = false, $blnProtected = false, $arrClipboard = false) { static $session; $session = $this->Session->getData(); // Get session data and toggle nodes if ($this->Input->get('tg')) { $session['filetree'][$this->Input->get('tg')] = isset($session['filetree'][$this->Input->get('tg')]) && $session['filetree'][$this->Input->get('tg')] == 1 ? 0 : 1; $this->Session->setData($session); $this->redirect(preg_replace('/(&(amp;)?|\\?)tg=[^& ]*/i', '', $this->Environment->request)); } $return = ''; $files = array(); $folders = array(); $intSpacing = 20; $level = $intMargin / $intSpacing + 1; // Mount folder if ($mount) { $folders = array($path); } else { foreach (scan($path) as $v) { if (!is_dir($path . '/' . $v) && $v != '.DS_Store') { $files[] = $path . '/' . $v; continue; } if ($v == '__new__') { $this->Files->rmdir(str_replace(TL_ROOT . '/', '', $path) . '/' . $v); continue; } if (substr($v, 0, 1) != '.') { $folders[] = $path . '/' . $v; } } natcasesort($folders); $folders = array_values($folders); natcasesort($files); $files = array_values($files); } // Folders for ($f = 0; $f < count($folders); $f++) { $return .= "\n " . '<li class="tl_folder" onmouseover="Theme.hoverDiv(this, 1);" onmouseout="Theme.hoverDiv(this, 0);"><div class="tl_left" style="padding-left:' . $intMargin . 'px;">'; $md5 = md5($folders[$f]); $content = scan($folders[$f]); $folderAttribute = 'style="margin-left:20px;"'; $currentFolder = str_replace(TL_ROOT . '/', '', $folders[$f]); $session['filetree'][$md5] = is_numeric($session['filetree'][$md5]) ? $session['filetree'][$md5] : 0; $currentEncoded = $this->urlEncode($currentFolder); $countFiles = count($content); // Subtract files that will not be shown if (!empty($this->arrValidFileTypes)) { foreach ($content as $file) { // Folders if (is_dir($folders[$f] . '/' . $file)) { if ($file == '.svn') { --$countFiles; } } elseif (!in_array(strtolower(substr($file, strrpos($file, '.') + 1)), $this->arrValidFileTypes)) { --$countFiles; } } } // Add a toggle button if there are childs if ($countFiles > 0) { $folderAttribute = ''; $img = $session['filetree'][$md5] == 1 ? 'folMinus.gif' : 'folPlus.gif'; $alt = $session['filetree'][$md5] == 1 ? $GLOBALS['TL_LANG']['MSC']['collapseNode'] : $GLOBALS['TL_LANG']['MSC']['expandNode']; $return .= '<a href="' . $this->addToUrl('tg=' . $md5) . '" title="' . specialchars($alt) . '" onclick="Backend.getScrollOffset(); return AjaxRequest.toggleFileManager(this, \'filetree_' . $md5 . '\', \'' . $currentFolder . '\', ' . $level . ');">' . $this->generateImage($img, '', 'style="margin-right:2px;"') . '</a>'; } $protected = $blnProtected === true || array_search('.htaccess', $content) !== false ? true : false; $folderImg = $session['filetree'][$md5] == 1 && $countFiles > 0 ? $protected ? 'folderOP.gif' : 'folderO.gif' : ($protected ? 'folderCP.gif' : 'folderC.gif'); // Add the current folder $return .= $this->generateImage($folderImg, '', $folderAttribute) . ' <a href="' . $this->addToUrl('node=' . $currentEncoded) . '"><strong>' . specialchars(basename($currentFolder)) . '</strong></a></div> <div class="tl_right">'; // Paste buttons if ($arrClipboard !== false && $this->Input->get('act') != 'select') { $imagePasteInto = $this->generateImage('pasteinto.gif', $GLOBALS['TL_LANG'][$this->strTable]['pasteinto'][0], 'class="blink"'); $return .= ($arrClipboard['mode'] == 'cut' || $arrClipboard['mode'] == 'copy') && preg_match('/^' . preg_quote($arrClipboard['id'], '/') . '/i', $currentFolder) ? $this->generateImage('pasteinto_.gif', '', 'class="blink"') : '<a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&mode=2&pid=' . $currentEncoded . (!is_array($arrClipboard['id']) ? '&id=' . $arrClipboard['id'] : '')) . '" title="' . specialchars($GLOBALS['TL_LANG'][$this->strTable]['pasteinto'][1]) . '" onclick="Backend.getScrollOffset();">' . $imagePasteInto . '</a> '; } elseif (!$mount) { $return .= $this->Input->get('act') == 'select' ? '<input type="checkbox" name="IDS[]" id="ids_' . md5($currentEncoded) . '" class="tl_tree_checkbox" value="' . $currentEncoded . '">' : $this->generateButtons(array('id' => $currentEncoded), $this->strTable); } $return .= '</div><div style="clear:both;"></div></li>'; // Call next node if (count($content) > 0 && $session['filetree'][$md5] == 1) { $return .= '<li class="parent" id="filetree_' . $md5 . '"><ul class="level_' . $level . '">'; $return .= $this->generateTree($folders[$f], $intMargin + $intSpacing, false, $protected, $arrClipboard); $return .= '</ul></li>'; } } // Process files for ($h = 0; $h < count($files); $h++) { $thumbnail = ''; $popupWidth = 600; $popupHeight = 260; $currentFile = str_replace(TL_ROOT . '/', '', $files[$h]); $objFile = new File($currentFile); if (!empty($this->arrValidFileTypes) && !in_array($objFile->extension, $this->arrValidFileTypes)) { continue; } $currentEncoded = $this->urlEncode($currentFile); $return .= "\n " . '<li class="tl_file" onmouseover="Theme.hoverDiv(this, 1);" onmouseout="Theme.hoverDiv(this, 0);"><div class="tl_left" style="padding-left:' . ($intMargin + $intSpacing) . 'px;">'; // Generate the thumbnail if ($objFile->isGdImage && $objFile->height > 0) { $popupWidth = $objFile->width > 600 ? $objFile->width + 61 : 661; $popupHeight = $objFile->height + 305; $thumbnail .= ' <span class="tl_gray">(' . $this->getReadableSize($objFile->filesize) . ', ' . $objFile->width . 'x' . $objFile->height . ' px)</span>'; if ($GLOBALS['TL_CONFIG']['thumbnails'] && $objFile->height <= $GLOBALS['TL_CONFIG']['gdMaxImgHeight'] && $objFile->width <= $GLOBALS['TL_CONFIG']['gdMaxImgWidth']) { $_height = $objFile->height < 70 ? $objFile->height : 70; $_width = $objFile->width * $_height / $objFile->height > 400 ? 90 : ''; $thumbnail .= '<br><img src="' . TL_FILES_URL . $this->getImage($currentEncoded, $_width, $_height) . '" alt="" style="margin:0px 0px 2px 23px;">'; } } else { $thumbnail .= ' <span class="tl_gray">(' . $this->getReadableSize($objFile->filesize) . ')</span>'; } $_buttons = ' '; // No popup links for templates and in the popup file manager if ($this->strTable == 'tl_templates' || basename($this->Environment->scriptName) == 'files.php') { $return .= $this->generateImage($objFile->icon) . ' ' . utf8_convert_encoding(specialchars(basename($currentFile)), $GLOBALS['TL_CONFIG']['characterSet']) . $thumbnail . '</div> <div class="tl_right">'; } else { $return .= '<a href="contao/popup.php?src=' . base64_encode($currentEncoded) . '" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['view']) . '" rel="lightbox[details ' . $popupWidth . ' ' . $popupHeight . ']">' . $this->generateImage($objFile->icon, $objFile->mime) . '</a> ' . utf8_convert_encoding(specialchars(basename($currentFile)), $GLOBALS['TL_CONFIG']['characterSet']) . $thumbnail . '</div> <div class="tl_right">'; } // Buttons if ($arrClipboard !== false && $this->Input->get('act') != 'select') { $_buttons = ' '; } else { $_buttons = $this->Input->get('act') == 'select' ? '<input type="checkbox" name="IDS[]" id="ids_' . md5($currentEncoded) . '" class="tl_tree_checkbox" value="' . $currentEncoded . '">' : $this->generateButtons(array('id' => $currentEncoded), $this->strTable); } $return .= $_buttons . '</div><div style="clear:both;"></div></li>'; } return $return; }
/** * Output templates */ public function output() { // Clear all we want a clear array for this windows. $GLOBALS['TL_CSS'] = array(); $GLOBALS['TL_JAVASCRIPT'] = array(); // Set stylesheets $GLOBALS['TL_CSS'][] = 'system/themes/' . $this->getTheme() . '/basic.css'; $GLOBALS['TL_CSS'][] = 'system/modules/syncCto/assets/css/compare.css'; // Set javascript $GLOBALS['TL_JAVASCRIPT'][] = 'assets/mootools/core/' . MOOTOOLS . '/mootools-core.js'; $GLOBALS['TL_JAVASCRIPT'][] = 'assets/mootools/core/' . MOOTOOLS . '/mootools-more.js'; $GLOBALS['TL_JAVASCRIPT'][] = 'assets/mootools/mootao/Mootao.js'; $GLOBALS['TL_JAVASCRIPT'][] = 'assets/contao/js/core.js'; $GLOBALS['TL_JAVASCRIPT'][] = 'system/modules/syncCto/assets/js/compare.js'; // Set wrapper template information $this->popupTemplate = new BackendTemplate("be_syncCto_popup"); $this->popupTemplate->theme = $this->getTheme(); $this->popupTemplate->base = $this->Environment->base; $this->popupTemplate->language = $GLOBALS['TL_LANGUAGE']; $this->popupTemplate->title = $GLOBALS['TL_CONFIG']['websiteTitle']; $this->popupTemplate->charset = $GLOBALS['TL_CONFIG']['characterSet']; $this->popupTemplate->headline = basename(utf8_convert_encoding($this->strFile, $GLOBALS['TL_CONFIG']['characterSet'])); // Set default information $this->Template->id = $this->intClientID; $this->Template->step = $this->mixStep; $this->Template->direction = $this->strMode; // Output template $this->popupTemplate->content = $this->Template->parse(); $this->popupTemplate->output(); }
/** * Romanize a string * * Use the UTF-8 lookup table to replace non ascii characters with their * respective roman character. * @param string * @return string */ function utf8_romanize($str) { global $UTF8_LOOKUP_TABLE; if (!is_array($UTF8_LOOKUP_TABLE)) { require_once TL_ROOT . '/system/utf8_lookup.php'; } return strtr(utf8_convert_encoding($str, 'UTF-8'), $UTF8_LOOKUP_TABLE['romanize']); }
/** * Recursively render the file tree * @param string * @param integer * @param boolean * @return string */ protected function renderFiletree($path, $intMargin, $mount = false) { // 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; $session = $this->Session->getData(); $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 ($this->Input->get($flag . 'tg')) { $session[$node][$this->Input->get($flag . 'tg')] = isset($session[$node][$this->Input->get($flag . 'tg')]) && $session[$node][$this->Input->get($flag . 'tg')] == 1 ? 0 : 1; $this->Session->setData($session); $this->redirect(preg_replace('/(&(amp;)?|\\?)' . $flag . 'tg=[^& ]*/i', '', $this->Environment->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 (!is_dir($path . '/' . $v) && $v != '.DS_Store') { $files[] = $path . '/' . $v; continue; } if (substr($v, 0, 1) != '.') { $folders[] = $path . '/' . $v; } } } natcasesort($folders); $folders = array_values($folders); natcasesort($files); $files = array_values($files); $folderClass = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['files'] ? 'tl_folder' : 'tl_file'; // Process folders for ($f = 0; $f < count($folders); $f++) { $countFiles = 0; $return .= "\n " . '<li class="' . $folderClass . '" onmouseover="Theme.hoverDiv(this, 1)" onmouseout="Theme.hoverDiv(this, 0)"><div class="tl_left" style="padding-left:' . $intMargin . 'px">'; // Check whether there are subfolders or files foreach (scan($folders[$f]) as $v) { if (is_dir($folders[$f] . '/' . $v) || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['files']) { $countFiles++; } } $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 = $session[$node][$tid] == 1 || count(preg_grep('/^' . preg_quote($currentFolder, '/') . '\\//', $this->varValue)) > 0; // Add a toggle button if there are childs if ($countFiles > 0) { $folderAttribute = ''; $img = $blnIsOpen ? 'folMinus.gif' : 'folPlus.gif'; $alt = $blnIsOpen ? $GLOBALS['TL_LANG']['MSC']['collapseNode'] : $GLOBALS['TL_LANG']['MSC']['expandNode']; $return .= '<a href="' . $this->addToUrl($flag . 'tg=' . $tid) . '" title="' . specialchars($alt) . '" onclick="Backend.getScrollOffset();return AjaxRequest.toggleFiletree(this,\'' . $xtnode . '_' . $tid . '\',\'' . $currentFolder . '\',\'' . $this->strField . '\',\'' . $this->strName . '\',' . $level . ')">' . $this->generateImage($img, '', 'style="margin-right:2px"') . '</a>'; } $folderImg = $blnIsOpen && $countFiles > 0 ? 'folderO.gif' : 'folderC.gif'; $folderLabel = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['files'] ? '<strong>' . specialchars(basename($currentFolder)) . '</strong>' : specialchars(basename($currentFolder)); // Prevent folder selection if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['filesOnly']) { $return .= $this->generateImage($folderImg, '', $folderAttribute) . ' <label>' . $folderLabel . '</label></div> <div class="tl_right"> '; } else { $return .= $this->generateImage($folderImg, '', $folderAttribute) . ' <label for="' . $this->strName . '_' . md5($currentFolder) . '">' . $folderLabel . '</label></div> <div class="tl_right">'; switch ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['fieldType']) { case 'checkbox': $return .= '<input type="checkbox" name="' . $this->strName . '[]" id="' . $this->strName . '_' . md5($currentFolder) . '" class="tl_tree_checkbox" value="' . 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="' . specialchars($currentFolder) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFolder, $this->varValue) . '>'; break; } } $return .= '</div><div style="clear:both"></div></li>'; // Call the next node if ($countFiles > 0 && $blnIsOpen) { $return .= '<li class="parent" id="' . $xtnode . '_' . $tid . '"><ul class="level_' . $level . '">'; $return .= $this->renderFiletree($folders[$f], $intMargin + $intSpacing); $return .= '</ul></li>'; } } // Process files if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['files']) { $allowedExtensions = null; if (strlen($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['extensions'])) { $allowedExtensions = trimsplit(',', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['extensions']); } for ($h = 0; $h < count($files); $h++) { $thumbnail = ''; $popupWidth = 600; $popupHeight = 260; $currentFile = str_replace(TL_ROOT . '/', '', $files[$h]); $currentEncoded = $this->urlEncode($currentFile); $objFile = new File($currentFile); // Check file extension if (is_array($allowedExtensions) && !in_array($objFile->extension, $allowedExtensions)) { continue; } $return .= "\n " . '<li class="tl_file" onmouseover="Theme.hoverDiv(this, 1)" onmouseout="Theme.hoverDiv(this, 0)"><div class="tl_left" style="padding-left:' . ($intMargin + $intSpacing) . 'px">'; // Generate thumbnail if ($objFile->isGdImage && $objFile->height > 0) { $popupWidth = $objFile->width > 600 ? $objFile->width + 61 : 661; $popupHeight = $objFile->height + 305; $thumbnail .= ' <span class="tl_gray">(' . $objFile->width . 'x' . $objFile->height . ')</span>'; if ($GLOBALS['TL_CONFIG']['thumbnails'] && $objFile->height <= $GLOBALS['TL_CONFIG']['gdMaxImgHeight'] && $objFile->width <= $GLOBALS['TL_CONFIG']['gdMaxImgWidth']) { $_height = $objFile->height < 70 ? $objFile->height : 70; $_width = $objFile->width * $_height / $objFile->height > 400 ? 90 : ''; $thumbnail .= '<br><img src="' . TL_FILES_URL . $this->getImage($currentEncoded, $_width, $_height) . '" alt="" style="margin:0px 0px 2px 23px">'; } } $return .= '<a href="contao/popup.php?src=' . base64_encode($currentEncoded) . '" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['view']) . '" data-lightbox="details ' . $popupWidth . ' ' . $popupHeight . '">' . $this->generateImage($objFile->icon, $objFile->mime) . '</a> <label for="' . $this->strName . '_' . md5($currentFile) . '">' . utf8_convert_encoding(specialchars(basename($currentFile)), $GLOBALS['TL_CONFIG']['characterSet']) . '</label>' . $thumbnail . '</div> <div class="tl_right">'; // Add checkbox or radio button switch ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['fieldType']) { case 'checkbox': $return .= '<input type="checkbox" name="' . $this->strName . '[]" id="' . $this->strName . '_' . md5($currentFile) . '" class="tl_tree_checkbox" value="' . 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="' . specialchars($currentFile) . '" onfocus="Backend.getScrollOffset()"' . $this->optionChecked($currentFile, $this->varValue) . '>'; break; } $return .= '</div><div style="clear:both"></div></li>'; } } return $return; }
protected function getInfoAction(\File $objFile) { $strUrl = null; $strFileNameEncoded = utf8_convert_encoding($objFile->name, \Config::get('characterSet')); switch (TL_MODE) { case 'FE': $strHref = Url::getCurrentUrlWithoutParameters(); $strHref .= (\Config::get('disableAlias') || strpos($strHref, '?') !== false ? '&' : '?') . 'file=' . \System::urlEncode($objFile->value); return 'window.open("' . $strHref . '", "_blank");'; break; case 'BE': if (\Input::get('popup')) { return null; } else { $popupWidth = 664; $popupHeight = 299; $href = 'contao/popup.php?src=' . base64_encode($objFile->value); return 'Backend.openModalIframe({"width":"' . $popupWidth . '","title":"' . str_replace("'", "\\'", specialchars($strFileNameEncoded, false, true)) . '","url":"' . $href . '","height":"' . $popupHeight . '"});return false'; } break; } return $strUrl; }
/** * Romanize a string * * Use the UTF-8 lookup table to replace non ascii characters with their * respective roman character. * * @param string $str * * @return string */ function utf8_romanize($str) { if (utf8_detect_encoding($str) == 'ASCII') { return $str; } global $UTF8_LOOKUP_TABLE; if (!is_array($UTF8_LOOKUP_TABLE)) { require_once __DIR__ . '/utf8_lookup.php'; } return strtr(utf8_convert_encoding($str, 'UTF-8'), $UTF8_LOOKUP_TABLE['romanize']); }
/** * Output the template file */ protected function output() { $this->Template->theme = Backend::getTheme(); $this->Template->base = Environment::get('base'); $this->Template->language = $GLOBALS['TL_LANGUAGE']; $this->Template->title = specialchars($this->strFile); $this->Template->charset = Config::get('characterSet'); $this->Template->headline = basename(utf8_convert_encoding($this->strFile, Config::get('characterSet'))); $this->Template->label_uuid = $GLOBALS['TL_LANG']['MSC']['fileUuid']; $this->Template->label_imagesize = $GLOBALS['TL_LANG']['MSC']['fileImageSize']; $this->Template->label_filesize = $GLOBALS['TL_LANG']['MSC']['fileSize']; $this->Template->label_ctime = $GLOBALS['TL_LANG']['MSC']['fileCreated']; $this->Template->label_mtime = $GLOBALS['TL_LANG']['MSC']['fileModified']; $this->Template->label_atime = $GLOBALS['TL_LANG']['MSC']['fileAccessed']; $this->Template->label_path = $GLOBALS['TL_LANG']['MSC']['filePath']; $this->Template->download = specialchars($GLOBALS['TL_LANG']['MSC']['fileDownload']); Config::set('debugMode', false); $this->Template->output(); }
/** * Parse the meta.txt file of a folder. This is an altered version and differs from the * Contao core function as it also checks the fallback language. * * @param string $strPath The path where to look for the meta.txt. * * @param string $strLanguage The language of the meta.txt to be searched. * * @return void */ protected function parseMetaFile($strPath, $strLanguage = '') { $strFile = $strPath . DIRECTORY_SEPARATOR . 'meta' . (strlen($strLanguage) ? '_' . $strLanguage : '') . '.txt'; if (!file_exists(TL_ROOT . DIRECTORY_SEPARATOR . $strFile)) { return; } $strBuffer = file_get_contents(TL_ROOT . DIRECTORY_SEPARATOR . $strFile); $strBuffer = utf8_convert_encoding($strBuffer, $GLOBALS['TL_CONFIG']['characterSet']); $arrBuffer = array_filter(trimsplit('[\\n\\r]+', $strBuffer)); foreach ($arrBuffer as $v) { list($strLabel, $strValue) = array_map('trim', explode('=', $v, 2)); $this->metaInformation[$strPath][$strLabel] = array_map('trim', explode('|', $strValue)); if (!in_array($strPath . DIRECTORY_SEPARATOR . $strLabel, $this->metaSort)) { $this->metaSort[] = $strPath . DIRECTORY_SEPARATOR . $strLabel; } } }