/php/plugins/filebrowser/classes/filebrowser.php
PHP | 431 lines | 348 code | 68 blank | 15 comment | 56 complexity | c59c4f7daa89f01fd0796bbd733f8743 MD5 | raw file
- <?php
- /**
- * @version $Id: filebrowser.php 292 2012-09-21 16:24:11Z cmb69 $
- */
- /* utf-8 marker: äöü */
- setlocale(LC_ALL, 'en_US.UTF8');
- class XHFileBrowser {
- var $linkPrefix = '';
- var $browseBase = '';
- var $baseDirectory;
- var $currentDirectory;
- var $linkType;
- var $folders = array();
- var $files = array();
- var $baseDirectories = array();
- var $allowedExtensions = array();
- var $maxFilesizes = array();
- var $view;
- var $message = '';
- var $browserPath = '';
-
- function XHFileBrowser() {
- global $pth, $plugin_cf, $cf;
- $image_extensions = array();
- $temp = explode(',', $plugin_cf['filebrowser']['extensions_images']);
- foreach ($temp as $ext) {
- $extension = trim($ext, ' ./');
- if ((bool) $extension) {
- $image_extensions[] = strtolower($extension);
- }
- }
- $download_extensions = array();
- $temp = explode(',', $plugin_cf['filebrowser']['extensions_downloads']);
- foreach ($temp as $ext) {
- $extension = trim($ext, ' ./');
- if ((bool) $extension) {
- $download_extensions[] = strtolower($extension);
- }
- }
- $userfiles_extensions = array();
- $temp = explode(',', $plugin_cf['filebrowser']['extensions_userfiles']);
- foreach ($temp as $ext) {
- $extension = trim($ext, ' ./');
- if ((bool) $extension) {
- $userfiles_extensions[] = strtolower($extension);
- }
- }
- $media_extensions = array();
- $temp = explode(',', $plugin_cf['filebrowser']['extensions_media']);
- foreach ($temp as $ext) {
- $extension = trim($ext, ' ./');
- if ((bool) $extension) {
- $media_extensions[] = strtolower($extension);
- }
- }
- $this->browserPath = $pth['folder']['plugins'] . basename(dirname(dirname(__FILE__))) . '/';
- $this->view = new XHFileBrowserView();
- $this->baseDirectories['images'] = rtrim($cf['folders']['images'], '/') . '/';
- $this->baseDirectories['downloads'] = rtrim($cf['folders']['downloads'], '/') . '/';
- $this->baseDirectories['userfiles'] = rtrim($cf['folders']['userfiles'], '/') . '/';
- $this->baseDirectories['media'] = rtrim($cf['folders']['media'], '/') . '/';
- $this->allowedExtensions['images'] = $image_extensions;
- $this->allowedExtensions['downloads'] = $download_extensions;
- $this->allowedExtensions['userfiles'] = $userfiles_extensions;
- $this->allowedExtensions['media'] = $media_extensions;
- }
- // 上傳檔案是否被用於頁面的查驗函式
- function fileIsLinked($file) {
- global $h, $c, $u;
- // 將檔案的空白轉為 %20 其餘保留 utf8 格式
- $file=str_replace(" ","%20",$file);
- $i = 0;
- $usages = array();
- // TODO: improve regex for better performance
- $regex = '#<.*(?:src|href|download)=(["\']).*' . preg_quote($file, '#') . '\\1.*>#is';
- foreach ($c as $page) {
- if (preg_match($regex, $page) > 0) {
- $usages[] = '<a href="?' . $u[$i] . '">' . $h[$i] . '</a>';
- }
- $i++;
- }
- $usages = array_unique($usages);
- if (count($usages) > 0) {
- return $usages;
- }
- return false;
- }
- // 上傳影像檔案是否被用於頁面的查驗函式
- function usedImages()
- {
- global $c, $h, $cl;
-
- $images = array();
- for ($i = 0; $i < $cl; $i++) {
- preg_match_all('/<img.*?src=(["\'])(.*?)\\1.*?>/is', $c[$i], $m);
- foreach ($m[2] as $fn) {
- if ($fn{0} == '.' && $fn{1} == '/') {
- $fn = substr($fn, 2);
- }
- if (array_key_exists($fn, $images)) {
- if (!in_array($h[$i], $images[$fn])) {
- $images[$fn][] = $h[$i];
- }
- } else {
- $images[$fn] = array($h[$i]);
- }
- }
- }
- return $images;
- }
-
- function readDirectory() {
- $dir = $this->browseBase . $this->currentDirectory;
- $this->files = array();
- $handle = opendir($dir);
- if ($handle) {
- while (false !== ($file = readdir($handle))) {
- if (strpos($file, '.') === 0) {
- continue;
- }
- if (is_dir($dir . $file)) {
- $this->folders[] = $this->currentDirectory . $file;
- continue;
- }
- if ($this->isAllowedFile($file)) {
- $this->files[] = $file;
- }
- }
- closedir($handle);
- natcasesort($this->folders);
- natcasesort($this->files);
- }
- }
- function getFolders($directory) {
- $folders = array();
- $handle = opendir($directory);
- if ($handle) {
- while (false !== ($file = readdir($handle))) {
- if (strpos($file, '.') === 0) {
- continue;
- }
- if (is_dir($directory . $file)) {
- $folders[] = str_replace($this->browseBase, '', $directory . $file);
- foreach ($this->getFolders($directory . $file . '/') as $subfolder) {
- $folders[] = $subfolder;
- }
- }
- }
- closedir($handle);
- natcasesort($folders);
- }
- return $folders;
- }
- function isAllowedFile($file) {
- $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
- if ($extension == $file) {
- return false;
- }
- if (!in_array($extension, $this->allowedExtensions[$this->linkType])
- && !in_array('*', $this->allowedExtensions[$this->linkType])) {
- return false;
- }
- return true;
- }
- function foldersArray($all = true) {
- $folders = array();
- $temp = $this->getFolders($this->browseBase . $this->baseDirectory);
- $baseDepth = count(explode('/', $this->baseDirectory)) - 2;
- foreach ($temp as $i => $folder) {
- $ar = explode('/', $folder);
- $level = count($ar);
- $parent = '';
- for ($i = 0; $i < $level - 1; $i++) {
- $parent .= '/' . $ar[$i];
- }
- $parent = substr($parent, 1);
- $folders[$folder]['level'] = count($ar) - $baseDepth;
- $folders[$folder]['parent'] = $parent;
- $folders[$folder]['children'] = array();
- $linkList = '';
- }
- foreach ($folders as $folder => $data) {
- $folders[$folder]['children'] = $this->gatherChildren($folder, $folders);
- }
- $this->view->currentDirectory = $this->currentDirectory;
- foreach ($folders as $folder => $data) {
- $folders[$folder]['linkList'] = $this->view->folderLink($folder, $folders);
- }
- return $folders;
- }
- function gatherChildren($parent, $folders) {
- $children = array();
- foreach ($folders as $key => $folder) {
- if ($folder['parent'] == $parent) {
- $children[] = $key;
- }
- }
- return $children;
- }
-
- function deleteFile($file) {
-
- $file = $this->browseBase . $this->currentDirectory . basename($file);
- $pages = $this->fileIsLinked($file);
- if (is_array($pages)) {
- $this->view->error('error_not_deleted', $file);
- $this->view->error('error_file_is_used', $file);
- foreach ($pages as $page) {
- $this->view->message .= '<li>' . $page . '</li>';
- }
- $this->view->message .= '</ul>';
- return;
- }
- // 設法在 Windows 能夠儲存中文命名檔案
- if (substr(php_uname(), 0, 7) == "Windows")
- {
- $yenname=iconv("utf-8","big-5",$file);
- }
- else
- {
- $yenname=$file;
- }
- if (@unlink($yenname)) {
- $this->view->success('success_deleted', $file);
- } else {
- $this->view->error('error_not_deleted', $file);
- }
- }
- function uploadFile() {
- $file = $_FILES['fbupload'];
-
- if ($file['error'] != 0) {
- switch ($file['error']) {
- case UPLOAD_ERR_INI_SIZE:
- $this->view->error('error_not_uploaded', $file['name']);
- $this->view->error('error_file_too_big', array('?', ini_get('upload_max_filesize')));
- return;
- default:
- $this->view->error('error_not_uploaded', $file['name']);
- return;
- }
- }
-
- $type = @getimagesize($file['tmp_name']) !== FALSE ? 'images' : 'downloads';
- // alternatively the following might be used:
- // $type = $this->linkType == 'images' ? 'images' : 'downloads';
- if (isset($this->maxFilesizes[$type])) {
- if ($file['size'] > $this->maxFilesizes[$type]) {
- $this->view->error('error_not_uploaded', $file['name']);
- $this->view->error('error_file_too_big', array(number_format($file['size']/1000, 2), number_format($this->maxFilesizes[$type]/1000, 2) . ' kb'));
- return;
- }
- }
-
- if ($this->isAllowedFile($file['name']) == false) {
- $this->view->error('error_not_uploaded', $file['name']);
- $this->view->error('error_no_proper_extension', pathinfo($file['name'], PATHINFO_EXTENSION));
- return;
- }
-
- $filename = $this->browseBase . $this->currentDirectory . basename($file['name']);
- if (file_exists($filename)) {
- $this->view->error('error_not_uploaded', $file['name']);
- $this->view->error('error_file_already_exists', $filename);
- return;
- }
- // 設法在 Windows 能夠儲存中文命名檔案
- if (substr(php_uname(), 0, 7) == "Windows")
- {
- $yenname=iconv("utf-8","big-5",$filename);
- }
- else
- {
- $yenname=$filename;
- }
- if (move_uploaded_file($_FILES['fbupload']['tmp_name'], $yenname)) {
- chmod($filename, 0644);
- $this->view->success('success_uploaded', $file['name']);
- return;
- }
-
- $this->view->error('error_not_uploaded', $file['name']);
- }
- function createFolder() {
- $folder = basename($_POST['createFolder']);
- $folder = str_replace(array(':', '*', '?', '"', '<', '>', '|', ' '), '', $folder);
- $folder = $this->browseBase . $this->currentDirectory . $folder;
- if (is_dir($folder)) {
- $this->view->error('error_folder_already_exists', basename($folder));
- return;
- }
- if (!mkdir($folder)) {
- $this->view->error('error_unknown');
- }
- $this->view->success('success_folder_created', basename($folder));
- return;
- }
- function deleteFolder() {
- $folder = $this->browseBase . $this->currentDirectory . basename($_POST['folder']);
- if (!rmdir($folder)) {
- $this->view->error('error_not_deleted', basename($folder));
- return;
- }
- $this->view->success('success_deleted', basename($folder));
- return;
- }
- function renameFile() {
- $newName = str_replace(array('..', '<', '>', ':', '?', ' '), '', basename($_POST['renameFile']));
- $oldName = $_POST['oldName'];
- if ($oldName == $newName) {
- return;
- }
- if (pathinfo($newName, PATHINFO_EXTENSION) !== pathinfo($oldName, PATHINFO_EXTENSION)) {
- $this->view->message = 'You can not change the file extension!';
- return;
- }
- // 這裡也會牽涉 big5 與 utf8 存在檔案的查驗
- if (file_exists($this->browseBase . $this->currentDirectory . '/' . $newName)) {
- $this->view->error('error_file_already_exists', $newName);
- return;
- }
- $pages = $this->fileIsLinked($oldName);
- if (is_array($pages)) {
- $this->view->error('error_cant_rename', $oldName);
- $this->view->error('error_file_is_used', $oldName);
- foreach ($pages as $page) {
- $this->view->message .= '<li>' . $page . '</li>';
- }
- $this->view->message .= '</ul>';
- return;
- }
-
- // 這裡也會因為檔案更名而存在 big5 與 utf8 格式的問題
- if (rename($this->browseBase . $this->currentDirectory . '/' . $oldName, $this->browseBase . $this->currentDirectory . '/' . $newName)) {
- $this->view->message = 'Renamed ' . $oldName . ' to ' . $newName . '!';
- return;
- }
-
- $this->view->message = 'Something went wrong (XHFilebrowser::renameFile())';
- return;
- }
- function render($template) {
- $template = str_replace(array('.', '/', '\\', '<', ' '), '', $template);
- if (!file_exists($this->browserPath . 'tpl/' . $template . '.html')) {
- return "<p>XHFileBrowser::render() - Template not found: {$this->browserPath}tpl/$template.html'</p>";
- }
- $this->view->baseDirectory = $this->baseDirectory;
- // $this->view->basePath = '';
- $this->view->baseLink = $this->linkType;
- $this->view->folders = $this->foldersArray();
- $this->view->subfolders = $this->folders;
- $this->view->files = $this->files;
- return $this->view->loadTemplate($this->browserPath . 'tpl/' . $template . '.html');
- }
- function setLinkParams($paramsString) {
- $this->view->linkParams = $paramsString;
- }
- function setLinkPrefix($prefix) {
- $this->view->linkPrefix = $prefix;
- }
- function setBrowseBase($path) {
- $this->browseBase = $path;
- $this->view->basePath = $path;
- }
- function setBrowserPath($path) {
- $this->view->browserPath = $path;
- }
-
- function setMaxFileSize($folder = '', $bytes) {
- if (key_exists($folder, $this->baseDirectories)){
- $this->maxFilesizes[$folder] = (int) $bytes;
- }
- }
- }