PageRenderTime 52ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/backend/core/js/tiny_mce/plugins/filemanager/classes/CorePlugin.php

http://github.com/forkcms/forkcms
PHP | 925 lines | 602 code | 195 blank | 128 comment | 204 complexity | 4323abd3952d4b40806287b7f6e43980 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, MIT, AGPL-3.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * $Id: CorePlugin.php 751 2009-10-20 12:05:36Z spocke $
  4. *
  5. * @package MCManagerCore
  6. * @author Moxiecode
  7. * @copyright Copyright ďż˝ 2007, Moxiecode Systems AB, All rights reserved.
  8. */
  9. // Load local file system
  10. require_once(MCMANAGER_ABSPATH . "FileSystems/LocalFileImpl.php");
  11. require_once(MCMANAGER_ABSPATH . "FileSystems/RootFileImpl.php");
  12. /**
  13. * This plugin contains the Core logic shared between manager products.
  14. *
  15. * @package MCManagerCore
  16. */
  17. class Moxiecode_CorePlugin extends Moxiecode_ManagerPlugin {
  18. /**#@+
  19. * @access public
  20. */
  21. /**
  22. * Constructs a new MCManagerCore instance.
  23. */
  24. function Moxiecode_CorePlugin() {
  25. }
  26. /**
  27. * Register file system.
  28. */
  29. function onInit(&$man) {
  30. $config = $man->getConfig();
  31. // Register local and root file system
  32. $man->registerFileSystem('file', isset($config['filesystem']) ? $config['filesystem'] : 'Moxiecode_LocalFileImpl');
  33. $man->registerFileSystem('root', 'Moxiecode_RootFileImpl');
  34. return true;
  35. }
  36. /**
  37. * Gets executed when a RPC command is to be executed.
  38. *
  39. * @param MCManager $man MCManager reference that the plugin is assigned to.
  40. * @param string $cmd RPC Command to be executed.
  41. * @param object $input RPC input object data.
  42. * @return object Result data from RPC call or null if it should be passed to the next handler in chain.
  43. */
  44. function onRPC(&$man, $cmd, $input) {
  45. switch ($cmd) {
  46. case "deleteFiles":
  47. return $this->_deleteFile($man, $input);
  48. case "listFiles":
  49. return $this->_listFiles($man, $input);
  50. case "createDirs":
  51. return $this->_createDirs($man, $input);
  52. case "getConfig":
  53. return $this->_getConfig($man, $input);
  54. case "insertFiles":
  55. return $this->_insertFiles($man, $input);
  56. case "loopBack":
  57. return $this->_loopBack($input);
  58. case "keepAlive":
  59. return $this->_keepAlive($man, $input);
  60. }
  61. return null;
  62. }
  63. /**
  64. * Gets called when data is streamed to client. This method should setup
  65. * HTTP headers, content type etc and simply send out the binary data to the client and the return false
  66. * ones that is done.
  67. *
  68. * @param MCManager $man MCManager reference that the plugin is assigned to.
  69. * @param string $cmd Stream command that is to be performed.
  70. * @param string $input Array of input arguments.
  71. * @return bool true/false if the execution of the event chain should continue.
  72. */
  73. function onStream(&$man, $cmd, $input) {
  74. $config = $man->getConfig();
  75. // Download stream
  76. if ($cmd == "download") {
  77. if ($man->verifyPath($input["path"])) {
  78. $file =& $man->getFile($input["path"]);
  79. $config = $file->getConfig();
  80. if ($man->verifyFile($file, "download") > 0 && $file->exists()) {
  81. // Get the mimetype, need to go to ../ parent folder cause... well we have to.
  82. //$mimeType = mapMimeTypeFromUrl($file->getAbsolutePath(), "../". $config['stream.mimefile']);
  83. // These seems to be needed for some IE proxies
  84. header("Expires: 0");
  85. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  86. header("Cache-Control: private", false);
  87. header("Content-type: application/octet-stream");
  88. header("Content-Disposition: attachment; filename=\"" . $file->getName() . "\"");
  89. // Stream data
  90. $stream =& $file->open('rb');
  91. if ($stream) {
  92. while (($buff = $stream->read()) != null)
  93. echo $buff;
  94. $stream->close();
  95. }
  96. return false;
  97. }
  98. } else {
  99. header('HTTP/1.0 404 Not found');
  100. header('status: 404 Not found');
  101. echo "Requested resource could not be found. Or access was denied.";
  102. die();
  103. }
  104. // Do not pass to next
  105. return false;
  106. }
  107. // Normal stream
  108. if ($cmd == "streamFile") {
  109. if (!$man->verifyPath($input["path"]) < 0) {
  110. trigger_error("Path verification failed.", FATAL);
  111. die();
  112. }
  113. $file = $man->getFile($input["path"]);
  114. $config = $file->getConfig();
  115. if (!$file->exists()) {
  116. trigger_error("File not found.", FATAL);
  117. die();
  118. } else {
  119. if (getClassName($file) == 'moxiecode_localfileimpl') {
  120. // Redirect to data
  121. $url = $man->removeTrailingSlash($config['preview.urlprefix']) . $man->convertPathToURI($file->getParent() . "/" . str_replace("+", "%20", urlencode($file->getName())), $config["preview.wwwroot"]) . $config['preview.urlsuffix'];
  122. // Passthrough rnd
  123. if (isset($input["rnd"]))
  124. $url .= (strpos($url, "?") === false ? "?" : "&") . "rnd=" . $input["rnd"];
  125. header('location: ' . $url);
  126. die();
  127. } else {
  128. // Verify that we can stream this one
  129. if ($man->verifyFile($file, "stream") < 0) {
  130. header('HTTP/1.0 404 Not found');
  131. header('status: 404 Not found');
  132. echo "Requested resource could not be found. Or access was denied.";
  133. die();
  134. }
  135. // Get the mimetype, need to go to ../ parent folder cause... well we have to.
  136. $mimeType = mapMimeTypeFromUrl($file->getAbsolutePath(), "../". $config['stream.mimefile']);
  137. header("Content-type: " . $mimeType);
  138. // Stream data
  139. $stream =& $file->open('rb');
  140. if ($stream) {
  141. while (($buff = $stream->read()) != null)
  142. echo $buff;
  143. $stream->close();
  144. }
  145. }
  146. return false;
  147. }
  148. }
  149. // Devkit commands
  150. switch ($cmd) {
  151. case "viewServerInfo":
  152. if (!checkBool($config['general.debug']))
  153. die("You have to enable debugging in config by setting general.debug to true.");
  154. phpinfo();
  155. break;
  156. case "downloadServerInfo":
  157. if (!checkBool($config['general.debug']))
  158. die("You have to enable debugging in config by setting general.debug to true.");
  159. // Get all ini settings
  160. $data = ini_get_all();
  161. // Setup all headers
  162. header("Content-type: text/plain; charset=UTF-8");
  163. header("Content-Disposition: attachment; filename=dump.txt");
  164. header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  165. header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  166. header("Cache-Control: no-store, no-cache, must-revalidate");
  167. header("Cache-Control: post-check=0, pre-check=0", false);
  168. header("Pragma: no-cache");
  169. echo "# Config from config.php" . "\r\n\r\n";
  170. foreach ($config as $key => $value) {
  171. if (is_bool($value))
  172. echo $key . "=" . ($value ? "true" : "false") . "\r\n";
  173. else
  174. echo $key . "=" . $value . "\r\n";
  175. }
  176. // Dump INI settings
  177. echo "\r\n# PHP INI settings file\r\n\r\n";
  178. foreach ($data as $key => $value)
  179. echo $key . "=" . $value['local_value'] . "\r\n";
  180. // Dump function support
  181. echo "\r\n# Function check" . "\r\n\r\n";
  182. $functions = array(
  183. "ImagecreateFromJpeg",
  184. "ImageJpeg",
  185. "ImagecreateFromGif",
  186. "ImageGif",
  187. "ImagecreateFromPng",
  188. "ImagePng",
  189. "gzdeflate",
  190. "gzinflate"
  191. );
  192. foreach ($functions as $function)
  193. echo $function . "=" . (function_exists($function) ? "ok" : "missing") . "\r\n";
  194. // Dump rootpath access
  195. echo "\r\n# Rootpath access" . "\r\n\r\n";
  196. foreach ($man->getRootPaths() as $rootpath) {
  197. $stat = stat($rootpath);
  198. echo $rootpath . "\r\n";
  199. echo " is_readable=" . (is_readable($rootpath) ? "readable" : "not readable") . "\r\n";
  200. echo " is_writable=" . (is_writable($rootpath) ? "writable" : "not writable") . "\r\n";
  201. foreach ($stat as $key => $value)
  202. echo " " . $key . "=" . $value . "\r\n";
  203. }
  204. break;
  205. case "viewLog":
  206. if (!checkBool($config['general.debug']))
  207. die("You have to enable debugging in config by setting general.debug to true.");
  208. header('Content-type: text/plain');
  209. if ($input['level'] == "debug")
  210. echo @file_get_contents("../logs/debug.log");
  211. else
  212. echo @file_get_contents("../logs/error.log");
  213. break;
  214. case "clearLog":
  215. header('Content-type: text/plain');
  216. if (!checkBool($config['general.debug']))
  217. die("You have to enable debugging in config by setting general.debug to true.");
  218. if ($input['level'] == "debug")
  219. $log = "../logs/debug.log";
  220. else
  221. $log = "../logs/error.log";
  222. @unlink($log);
  223. for ($i=0; $i<10; $i++)
  224. @unlink($log . "." . $i);
  225. echo "Logs cleared.";
  226. break;
  227. }
  228. // Pass to next
  229. return true;
  230. }
  231. /**
  232. * Gets called when data is streamed/uploaded from client. This method should take care of
  233. * any uploaded files and move them to the correct location.
  234. *
  235. * @param MCManager $man MCManager reference that the plugin is assigned to.
  236. * @param string $cmd Upload command that is to be performed.
  237. * @param string $input Array of input arguments.
  238. * @return object Result object data or null if the event wasn't handled.
  239. */
  240. function onUpload(&$man, $cmd, $input) {
  241. if ($cmd == "upload") {
  242. // Setup response
  243. $result = new Moxiecode_ResultSet("status,file,message");
  244. $path = $man->decryptPath($input["path"]);
  245. $config = $man->getConfig();
  246. if ($man->verifyPath($path)) {
  247. $file =& $man->getFile($path);
  248. $config = $file->getConfig();
  249. $maxSizeBytes = preg_replace("/[^0-9]/", "", $config["upload.maxsize"]);
  250. if (strpos((strtolower($config["upload.maxsize"])), "k") > 0)
  251. $maxSizeBytes *= 1024;
  252. if (strpos((strtolower($config["upload.maxsize"])), "m") > 0)
  253. $maxSizeBytes *= (1024 * 1024);
  254. // Is chunked upload
  255. if (isset($input["chunk"])) {
  256. $filename = $input["name"];
  257. $chunk = intval($input["chunk"]);
  258. $chunks = intval($input["chunks"]);
  259. // No access, tool disabled
  260. if (in_array("upload", explode(',', $config['general.disabled_tools'])) || !$file->canWrite() || !checkBool($config["filesystem.writable"])) {
  261. $result->add("ACCESS_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.no_access}");
  262. return $result;
  263. }
  264. $file =& $man->getFile($path, $filename, MC_IS_FILE);
  265. if ($man->verifyFile($file, "upload") < 0) {
  266. $result->add("ACCESS_ERROR", $man->encryptPath($file->getAbsolutePath()), $man->getInvalidFileMsg());
  267. return $result;
  268. }
  269. // Hack attempt
  270. if ($filename == $config['filesystem.local.access_file_name']) {
  271. $result->add("MCACCESS_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.no_access}");
  272. return $result;
  273. }
  274. // Only peform IO when not in demo mode
  275. if (!checkBool($config['general.demo'])) {
  276. if ($chunk == 0 && $file->exists() && (!isset($config["upload.overwrite"]) || $config["upload.overwrite"] == false)) {
  277. $result->add("OVERWRITE_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.file_exists}");
  278. return $result;
  279. }
  280. if ($chunk == 0 && $file->exists() && $config["upload.overwrite"] == true)
  281. $file->delete();
  282. // Write file
  283. $stream =& $file->open($chunk == 0 ? 'wb' : 'ab');
  284. if ($stream) {
  285. $in = fopen("php://input", "rb");
  286. if ($in) {
  287. while ($buff = fread($in, 4096))
  288. $stream->write($buff);
  289. }
  290. $stream->close();
  291. }
  292. // Check file size
  293. if ($file->getLength() > $maxSizeBytes) {
  294. $file->delete();
  295. $result->add("SIZE_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.error_to_large}");
  296. return $result;
  297. }
  298. // Verify uploaded file, if it fails delete it
  299. $status = $man->verifyFile($file, "upload");
  300. if ($status < 0) {
  301. $file->delete();
  302. $result->add("FILTER_ERROR", $man->encryptPath($file->getAbsolutePath()), $man->getInvalidFileMsg());
  303. return $result;
  304. }
  305. // Import file when all chunks are complete
  306. if ($chunk == $chunks - 1) {
  307. clearstatcache();
  308. debug($chunk, $chunks, filesize($file->getAbsolutePath()), $chunk == 0 ? 'wb' : 'ab');
  309. $file->importFile();
  310. }
  311. }
  312. $result->add("OK", $man->encryptPath($file->getAbsolutePath()), "{#message.upload_ok}");
  313. return $result;
  314. } else {
  315. // Ok lets check the files array out.
  316. for ($i=0; isset($_FILES['file' . $i]['tmp_name']); $i++) {
  317. $filename = utf8_encode($input["name" . $i]);
  318. // Do nothing in demo mode
  319. if (checkBool($config['general.demo'])) {
  320. $result->add("DEMO_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.demo}");
  321. continue;
  322. }
  323. // No access, tool disabled
  324. if (in_array("upload", explode(',', $config['general.disabled_tools'])) || !$file->canWrite() || !checkBool($config["filesystem.writable"])) {
  325. $result->add("ACCESS_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.no_access}");
  326. continue;
  327. }
  328. // Get ext to glue back on
  329. $ext = "";
  330. if (strpos(basename($_FILES['file' . $i]['name']), ".") > 0) {
  331. $ar = explode('.', basename($_FILES['file' . $i]['name']));
  332. $ext = array_pop($ar);
  333. }
  334. $file =& $man->getFile($path, $filename . "." . $ext, "", MC_IS_FILE);
  335. if ($man->verifyFile($file, "upload") < 0) {
  336. $result->add("ACCESS_ERROR", $man->encryptPath($file->getAbsolutePath()), $man->getInvalidFileMsg());
  337. continue;
  338. }
  339. $config = $file->getConfig();
  340. if (is_uploaded_file($_FILES['file' . $i]['tmp_name'])) {
  341. // Hack attempt
  342. if ($filename == $config['filesystem.local.access_file_name']) {
  343. @unlink($_FILES['file' . $i]['tmp_name']);
  344. $result->add("MCACCESS_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.no_access}");
  345. continue;
  346. }
  347. if ($file->exists() && (!isset($config["upload.overwrite"]) || $config["upload.overwrite"] == false)) {
  348. @unlink($_FILES['file' . $i]['tmp_name']);
  349. $result->add("OVERWRITE_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.file_exists}");
  350. continue;
  351. }
  352. if ($file->exists() && $config["upload.overwrite"] == true)
  353. $file->delete();
  354. if (getClassName($file) == 'moxiecode_localfileimpl') {
  355. if (!move_uploaded_file($_FILES['file' . $i]['tmp_name'], $file->getAbsolutePath())) {
  356. $result->add("RW_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.upload_failed}");
  357. continue;
  358. }
  359. // Dispatch add event
  360. $file->importFile();
  361. } else
  362. $file->importFile($_FILES['file' . $i]['tmp_name']);
  363. if ($file->getLength() > $maxSizeBytes) {
  364. $file->delete();
  365. $result->add("SIZE_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.error_to_large}");
  366. continue;
  367. }
  368. // Verify uploaded file, if it fails delete it
  369. $status = $man->verifyFile($file, "upload");
  370. if ($status < 0) {
  371. $file->delete();
  372. $result->add("FILTER_ERROR", $man->encryptPath($file->getAbsolutePath()), $man->getInvalidFileMsg());
  373. continue;
  374. }
  375. $result->add("OK", $man->encryptPath($file->getAbsolutePath()), "{#message.upload_ok}");
  376. } else
  377. $result->add("GENERAL_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.upload_failed}");
  378. }
  379. }
  380. } else
  381. $result->add("PATH_ERROR", $man->encryptPath($path), "{#error.upload_failed}");
  382. return $result;
  383. }
  384. }
  385. // * * * * * * * * Private methods
  386. function _deleteFile(&$man, &$input) {
  387. $result = new Moxiecode_ResultSet("status,file,message");
  388. for ($i=0; isset($input["path" . $i]); $i++) {
  389. $file =& $man->getFile($input["path" . $i]);
  390. $config = $file->getConfig();
  391. if (checkBool($config['general.demo'])) {
  392. $result->add("FAILED", $man->encryptPath($file->getAbsolutePath()), "{#error.demo}");
  393. continue;
  394. }
  395. if (!$man->isToolEnabled("delete", $config)) {
  396. trigger_error("{#error.no_access}", FATAL);
  397. die();
  398. }
  399. if (!$file->exists()) {
  400. $result->add("FAILED", $man->encryptPath($file->getAbsolutePath()), "{#error.file_not_exists}");
  401. continue;
  402. }
  403. if ($man->verifyFile($file, "delete") < 0) {
  404. $result->add("FAILED", $man->encryptPath($file->getAbsolutePath()), $man->getInvalidFileMsg());
  405. continue;
  406. }
  407. if (!$file->canWrite()) {
  408. $result->add("FAILED", $man->encryptPath($file->getAbsolutePath()), "{#error.no_write_access}");
  409. continue;
  410. }
  411. if (!checkBool($config["filesystem.writable"])) {
  412. $result->add("FAILED", $man->encryptPath($file->getAbsolutePath()), "{#error.no_write_access}");
  413. continue;
  414. }
  415. if ($file->delete($config['filesystem.delete_recursive']))
  416. $result->add("OK", $man->encryptPath($file->getAbsolutePath()), "{#message.delete_success}");
  417. else
  418. $result->add("FAILED", $man->encryptPath($file->getAbsolutePath()), "{#error.delete_failed}");
  419. }
  420. return $result->toArray();
  421. }
  422. function _insertFiles(&$man, $input) {
  423. $result = new Moxiecode_ResultSet("name,path,url,size,type,created,modified,attribs,custom");
  424. $indata = array();
  425. for ($i=0; isset($input['path' . $i]); $i++) {
  426. $custom = array();
  427. $file = $man->getFile($input["path". $i]);
  428. if (!$file->exists()) {
  429. trigger_error("{#error.file_not_exists}", FATAL);
  430. die;
  431. }
  432. $ar = explode('.', $file->getName());
  433. $ext = array_pop($ar);
  434. $man->dispatchEvent("onCustomInfo", array(&$file, "insert", &$custom));
  435. $status = $man->dispatchEvent("onInsertFile", array(&$file));
  436. $config = $file->getConfig();
  437. $attribs = ($file->canRead() && checkBool($config["filesystem.readable"]) ? "R" : "-") . ($file->canWrite() && checkBool($config["filesystem.writable"]) ? "W" : "-");
  438. $url = $man->removeTrailingSlash($config['preview.urlprefix']) . $man->convertPathToURI($file->getAbsolutePath(), $config["preview.wwwroot"]);
  439. $result->add($file->getName(), $man->encryptPath($file->getAbsolutePath()), utf8_encode($url), $file->getLength(), $ext, $file->getCreationDate(), $file->getLastModified(), $attribs, $custom);
  440. }
  441. return $result->toArray();
  442. }
  443. function _listDefault(&$man, $file, $input, &$result, $filter_root_path) {
  444. $config = $man->getConfig();
  445. // Setup input file filter
  446. $inputFileFilter = new Moxiecode_BasicFileFilter();
  447. if (isset($input['include_directory_pattern']) && $input['include_directory_pattern'])
  448. $inputFileFilter->setIncludeDirectoryPattern($input['include_directory_pattern']);
  449. if (isset($input['exclude_directory_pattern']) && $input['exclude_directory_pattern'])
  450. $inputFileFilter->setExcludeDirectoryPattern($input['exclude_directory_pattern']);
  451. if (isset($input['include_file_pattern']) && $input['include_file_pattern'])
  452. $inputFileFilter->setIncludeFilePattern($input['include_file_pattern']);
  453. if (isset($input['exclude_file_pattern']) && $input['exclude_file_pattern'])
  454. $inputFileFilter->setExcludeFilePattern($input['exclude_file_pattern']);
  455. if (isset($input['extensions']) && $input['extensions'])
  456. $inputFileFilter->setIncludeExtensions($input['extensions']);
  457. // If file doesn't exists use default path
  458. if (!$file->exists()) {
  459. $file = $man->getFile($config['filesystem.path']);
  460. $result->setHeader("path", $man->encryptPath($file->getAbsolutePath()));
  461. $result->setHeader("visual_path", checkBool($config['general.user_friendly_paths']) ? $man->toVisualPath($file->getAbsolutePath()) : $man->encryptPath($file->getAbsolutePath()));
  462. }
  463. // List files
  464. $config = $file->getConfig();
  465. if ($file->isDirectory()) {
  466. // Setup file filter
  467. $fileFilter = new Moxiecode_BasicFileFilter();
  468. //$fileFilter->setDebugMode(true);
  469. $fileFilter->setIncludeDirectoryPattern($config['filesystem.include_directory_pattern']);
  470. $fileFilter->setExcludeDirectoryPattern($config['filesystem.exclude_directory_pattern']);
  471. $fileFilter->setIncludeFilePattern($config['filesystem.include_file_pattern']);
  472. $fileFilter->setExcludeFilePattern($config['filesystem.exclude_file_pattern']);
  473. $fileFilter->setIncludeExtensions($config['filesystem.extensions']);
  474. // If file is hidden then try the parent
  475. if ($fileFilter->accept($file) <= 0) {
  476. $file = $file->getParentFile();
  477. $result->setHeader("path", $man->encryptPath($file->getAbsolutePath()));
  478. $result->setHeader("visual_path", checkBool($config['general.user_friendly_paths']) ? $man->toVisualPath($file->getAbsolutePath()) : $man->encryptPath($file->getAbsolutePath()));
  479. }
  480. if (isset($input["filter"]) && $input["filter"] != null)
  481. $fileFilter->setIncludeWildcardPattern($input["filter"]);
  482. if (isset($input["only_dirs"]) && checkBool($input["only_dirs"]))
  483. $fileFilter->setOnlyDirs(true);
  484. else if (!checkBool($config["filesystem.list_directories"], true) || (isset($input["only_files"]) && checkBool($input["only_files"])))
  485. $fileFilter->setOnlyFiles(true);
  486. // List files
  487. $combinedFilter = new Moxiecode_CombinedFileFilter();
  488. $combinedFilter->addFilter($fileFilter);
  489. $combinedFilter->addFilter($inputFileFilter);
  490. $files =& $file->listFilesFiltered($combinedFilter);
  491. $showparent = isset($input["no_parent"]) ? checkBool($input["no_parent"]) : true;
  492. $showparent = $showparent && $man->verifyPath($file->getParent());
  493. if (!isset($input["only_dirs"]))
  494. $showparent = $showparent && checkBool($config["filesystem.list_directories"], true);
  495. // Add parent
  496. if ($showparent && !isset($input["only_files"])) {
  497. // Remove files below root
  498. if ($filter_root_path && getClassName($file) == 'moxiecode_localfileimpl') {
  499. if (!$man->isChildPath($filter_root_path, $file->getParent()))
  500. return $files;
  501. }
  502. if ($file->getAbsolutePath() != $filter_root_path)
  503. $result->add("..", $man->encryptPath($file->getParent()), -1, "parent", "", "", "", array());
  504. }
  505. } else
  506. trigger_error("The specified path is not a directory. Probably an incorrect setting for the filesystem.rootpath option.", FATAL);
  507. return $files;
  508. }
  509. /**
  510. * Lists files.
  511. */
  512. function _listFiles(&$man, $input) {
  513. $result = new Moxiecode_ResultSet("name,path,size,type,created,modified,attribs,custom");
  514. $config = $man->getConfig();
  515. $files = array();
  516. $rootNames = $man->_getRootNames();
  517. $filterRootPath = isset($input["root_path"]) && $input["root_path"] != null ? $man->toAbsPath($man->decryptPath($input["root_path"])) : null;
  518. if (isset($input["path"]) && $input["path"]) {
  519. // URL specified
  520. if (isset($input["url"]) && $input["path"] == '{default}')
  521. $input["path"] = $man->convertURIToPath($input["url"]);
  522. if (isset($input['remember_last_path'])) {
  523. if ($input['remember_last_path'] !== 'auto')
  524. $remember = checkBool($input['remember_last_path']);
  525. else
  526. $remember = checkBool($config['general.remember_last_path']);
  527. if ($remember) {
  528. if (isset($_COOKIE["MCManager_". $man->getType() . "_lastPath"]) && $input["path"] == '{default}') {
  529. $tmpPath = $_COOKIE["MCManager_". $man->getType() . "_lastPath"];
  530. if ($man->getFSFromPath($tmpPath) == "file" && $tmpPath)
  531. $input["path"] = $tmpPath;
  532. } else {
  533. if ($man->getFSFromPath($input["path"]) == "file")
  534. setcookie("MCManager_". $man->getType() . "_lastPath", $input["path"], time() + (3600*24*30)); // 30 days
  535. }
  536. }
  537. }
  538. $input["path"] = $man->toAbsPath($man->decryptPath($input["path"]));
  539. $result->setHeader("path", $man->encryptPath($input["path"]));
  540. $result->setHeader("visual_path", checkBool($config['general.user_friendly_paths']) ? $man->toVisualPath($input["path"]) : $man->encryptPath($input["path"]));
  541. // Move path inside rootpath if it's localfs
  542. if ($filterRootPath && $man->getFSFromPath($input["path"]) == 'file') {
  543. if (!$man->isChildPath($filterRootPath, $input["path"]))
  544. $input["path"] = $filterRootPath;
  545. $result->setHeader("path", $man->encryptPath($input["path"]));
  546. $result->setHeader("visual_path", checkBool($config['general.user_friendly_paths']) ? $man->toVisualPath($input["path"], $filterRootPath) : $man->encryptPath($input["path"]));
  547. }
  548. // Not valid path use default path
  549. if ($man->getFSFromPath($input["path"]) == 'file' && !$man->verifyPath($input["path"])) {
  550. $input["path"] = $config['filesystem.path'];
  551. $result->setHeader("path", $man->encryptPath($input["path"]));
  552. $result->setHeader("visual_path", checkBool($config['general.user_friendly_paths']) ? $man->toVisualPath($input["path"]) : $man->encryptPath($input["path"]));
  553. }
  554. $file =& $man->getFile($input["path"]);
  555. $config = $file->getConfig();
  556. $attribs = ($file->canRead() && checkBool($config["filesystem.readable"]) ? "R" : "-") . ($file->canWrite() && checkBool($config["filesystem.writable"]) ? "W" : "-");
  557. $result->setHeader("attribs", $attribs);
  558. $files = $this->_listDefault($man, $file, $input, $result, $filterRootPath);
  559. } else {
  560. trigger_error("ListFiles input not valid.", FATAL);
  561. die();
  562. }
  563. if (isset($input["page_size"])) {
  564. if ($file->getAbsolutePath() != $filterRootPath && $man->verifyPath($file->getParent()))
  565. $pageSize = $input["page_size"] - 1;
  566. else
  567. $pageSize = $input["page_size"];
  568. $pages = ceil(count($files) / $pageSize);
  569. // Setup response
  570. $result->setHeader("pages", $pages > 1 ? $pages : 1);
  571. $result->setHeader("count", count($files));
  572. if (!isset($input["page"]))
  573. $input["page"] = 0;
  574. // Remove non visible files
  575. $files = array_slice($files, ($input["page"] * $pageSize), $pageSize);
  576. }
  577. // Add directories
  578. $listFS = $man->getFSFromPath($input["path"]);
  579. foreach ($files as $file) {
  580. // Remove files below root
  581. if ($filterRootPath && $listFS == 'file') {
  582. if (!$man->isChildPath($filterRootPath, $file->getAbsolutePath()))
  583. continue;
  584. }
  585. // Setup fields
  586. $custom = array();
  587. // Attribs: R = Read, W = Write (cut/delete/rename), D = Download, S = Stream/Preview, I = Insert
  588. $attribs = ($file->canRead() && checkBool($config["filesystem.readable"]) ? "R" : "-") . ($file->canWrite() && checkBool($config["filesystem.writable"]) ? "W" : "-");
  589. $cdate = date($config['filesystem.datefmt'], $file->getCreationDate());
  590. $mdate = date($config['filesystem.datefmt'], $file->getLastModified());
  591. $filePath = $man->encryptPath($file->getAbsolutePath());
  592. if ($file->isFile())
  593. $type = getFileExt($file->getName());
  594. else
  595. $type = "folder";
  596. $man->dispatchEvent("onCustomInfo", array(&$file, "list", &$custom));
  597. // Special treatment of roots
  598. $name = $file->getName();
  599. if ($input["path"] == "root:///") {
  600. foreach ($rootNames as $rootPath => $rootName) {
  601. if ($file->getAbsolutePath() == $rootPath) {
  602. $name = $rootName;
  603. break;
  604. }
  605. }
  606. }
  607. $result->add(utf8_encode($name), $filePath, $file->isFile() ? $file->getLength() : -1, $type, $cdate, $mdate, $attribs, $custom);
  608. }
  609. if (isset($input["config"]))
  610. $result->setConfig($man->getJSConfig($config, $input["config"]));
  611. return $result->toArray();
  612. }
  613. function _filterFile(&$file, $input) {
  614. $config = $file->getConfig();
  615. // Setup file filter
  616. $fileFilter = new Moxiecode_BasicFileFilter();
  617. //$fileFilter->setDebugMode(true);
  618. $fileFilter->setIncludeDirectoryPattern($config['filesystem.include_directory_pattern']);
  619. $fileFilter->setExcludeDirectoryPattern($config['filesystem.exclude_directory_pattern']);
  620. $fileFilter->setIncludeFilePattern($config['filesystem.include_file_pattern']);
  621. $fileFilter->setExcludeFilePattern($config['filesystem.exclude_file_pattern']);
  622. $fileFilter->setIncludeExtensions($config['filesystem.extensions']);
  623. if (isset($input["only_dirs"]) && checkBool($input["only_dirs"]))
  624. $fileFilter->setOnlyDirs(true);
  625. return ($fileFilter->accept($file) > 0);
  626. }
  627. function _createDirs(&$man, $input) {
  628. $result = new Moxiecode_ResultSet("status,file,message");
  629. // Get input data
  630. $path = $man->decryptPath($input['path']);
  631. $dir =& $man->getFile($path);
  632. $config = $dir->getConfig();
  633. if (checkBool($config["general.demo"])) {
  634. $result->add("DEMO_ERROR", $man->encryptPath($dir->getAbsolutePath()), "{#error.demo}");
  635. return $result->toArray();
  636. }
  637. if (!$man->isToolEnabled("createdir", $config)) {
  638. trigger_error("{#error.no_access}", FATAL);
  639. die();
  640. }
  641. for ($i=0; isset($input['name' . $i]); $i++) {
  642. // Get dir info
  643. $name = $input['name' . $i];
  644. $template = false;
  645. if (isset($input['template' . $i]))
  646. $template = $man->decryptPath($input['template' . $i]);
  647. // Setup target file
  648. $file =& $man->getFile($path, $name, MC_IS_DIRECTORY);
  649. if ($man->verifyFile($file, "createdir") < 0) {
  650. $result->add("ACCESS_ERROR", $man->encryptPath($file->getAbsolutePath()), $man->getInvalidFileMsg());
  651. continue;
  652. }
  653. // Check write access
  654. if (!checkBool($config["filesystem.writable"])) {
  655. $result->add("FAILED", $man->encryptPath($file->getAbsolutePath()), "{#error.no_write_access}");
  656. continue;
  657. }
  658. // Setup template dir
  659. if ($template) {
  660. $templateFile =& $man->getFile($template, "", MC_IS_DIRECTORY);
  661. if (!$templateFile->exists()) {
  662. $result->add("TEMPLATE_ERROR", $man->encryptPath($templateFile->getAbsolutePath()), "{#error.template_missing}");
  663. continue;
  664. }
  665. if ($man->verifyFile($templateFile, "createdir") < 0) {
  666. $result->add("ACCESS_ERROR", $man->encryptPath($file->getAbsolutePath()), $man->getInvalidFileMsg());
  667. continue;
  668. }
  669. } else
  670. $templateFile = null;
  671. // Check if target exists
  672. if ($file->exists()) {
  673. $result->add("EXISTS_ERROR", $man->encryptPath($file->getAbsolutePath()), "{#error.folder_exists}");
  674. continue;
  675. }
  676. // Create directory
  677. if ($templateFile)
  678. $status = $templateFile->copyTo($file);
  679. else
  680. $status = $file->mkdir();
  681. if ($status)
  682. $result->add("OK", $man->encryptPath($file->getAbsolutePath()), "{#message.directory_ok}");
  683. else
  684. $result->add("FAILED", $man->encryptPath($file->getAbsolutePath()), "{#error.no_write_access}");
  685. }
  686. return $result->toArray();
  687. }
  688. function _getConfig(&$man, $input) {
  689. $globalConfig = $man->getConfig();
  690. if (!isset($input['prefixes']))
  691. $input["prefixes"] = "*";
  692. // If debug mode return all
  693. if (!isset($input['path']) && isset($input['debug']) && checkBool($globalConfig['general.debug']))
  694. return $man->getConfig();
  695. if (!isset($input['path'])) {
  696. trigger_error("{#error.file_not_exists}", FATAL);
  697. die;
  698. }
  699. $file =& $man->getFile($input['path']);
  700. if (!$file->exists()) {
  701. trigger_error("{#error.file_not_exists}", FATAL);
  702. die;
  703. }
  704. $config = $file->getConfig();
  705. // If debug mode return all
  706. if (isset($input['debug']) && checkBool($globalConfig['general.debug']))
  707. return $config;
  708. return $man->getJSConfig($config, $input["prefixes"]);
  709. }
  710. /**
  711. * Simple keepalive function.
  712. */
  713. function _keepAlive(&$man, $input) {
  714. $result = new Moxiecode_ResultSet("status,time,message");
  715. $man->dispatchEvent("onKeepAlive");
  716. // Return status KEEPALIVE, current time on server and message.
  717. $result->add("KEEPALIVE", time(), "{#message.keepalive}");
  718. return $result->toArray();
  719. }
  720. /**
  721. * Simple loopback function. Used for debugging purposes of the RPC functionality.
  722. */
  723. function _loopBack($input) {
  724. return $input;
  725. }
  726. /**#@-*/
  727. }
  728. // Add plugin to MCManager
  729. $man->registerPlugin("core", new Moxiecode_CorePlugin());
  730. ?>