PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/K2/administrator/components/com_k2/lib/elfinder/elFinderVolumeLocalFileSystem.class.php

http://joomlaworks.googlecode.com/
PHP | 783 lines | 345 code | 94 blank | 344 comment | 84 complexity | 849884df6692ed547ad2a260f150e534 MD5 | raw file
  1. <?php
  2. /**
  3. * @version $Id: elFinderVolumeLocalFileSystem.class.php 1090 2011-10-07 17:01:56Z lefteris.kavadas $
  4. * @package K2
  5. * @author JoomlaWorks http://www.joomlaworks.gr
  6. * @copyright Copyright (c) 2006 - 2011 JoomlaWorks Ltd. All rights reserved.
  7. * @license GNU/GPL license: http://www.gnu.org/copyleft/gpl.html
  8. */
  9. // no direct access
  10. defined('_JEXEC') or die('Restricted access');
  11. /**
  12. * elFinder driver for local filesystem.
  13. *
  14. * @author Dmitry (dio) Levashov
  15. * @author Troex Nevelin
  16. **/
  17. class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
  18. /**
  19. * Driver id
  20. * Must be started from letter and contains [a-z0-9]
  21. * Used as part of volume id
  22. *
  23. * @var string
  24. **/
  25. protected $driverId = 'l';
  26. /**
  27. * Constructor
  28. * Extend options with required fields
  29. *
  30. * @return void
  31. * @author Dmitry (dio) Levashov
  32. **/
  33. public function __construct() {
  34. $this->options['alias'] = ''; // alias to replace root dir name
  35. $this->options['dirMode'] = 0777;
  36. $this->options['fileMode'] = 0666;
  37. }
  38. /*********************************************************************/
  39. /* INIT AND CONFIGURE */
  40. /*********************************************************************/
  41. /**
  42. * Configure after successfull mount.
  43. *
  44. * @return void
  45. * @author Dmitry (dio) Levashov
  46. **/
  47. protected function configure() {
  48. // chek thumbnails path
  49. if ($this->options['tmbPath']) {
  50. $this->options['tmbPath'] = strpos($this->options['tmbPath'], DIRECTORY_SEPARATOR) === false
  51. // tmb path set as dirname under root dir
  52. ? $this->root.DIRECTORY_SEPARATOR.$this->options['tmbPath']
  53. // tmb path as full path
  54. : $this->_normpath($this->options['tmbPath']);
  55. }
  56. parent::configure();
  57. // if no thumbnails url - try detect it
  58. if ($this->attr($this->root, 'read') && !$this->tmbURL && $this->URL) {
  59. if (strpos($this->tmbPath, $this->root) === 0) {
  60. $this->tmbURL = $this->URL.str_replace(DIRECTORY_SEPARATOR, '/', substr($this->tmbPath, strlen($this->root)+1));
  61. if (preg_match("|[^/?&=]$|", $this->tmbURL)) {
  62. $this->tmbURL .= '/';
  63. }
  64. }
  65. }
  66. $this->aroot = realpath($this->root);
  67. }
  68. /*********************************************************************/
  69. /* FS API */
  70. /*********************************************************************/
  71. /*********************** paths/urls *************************/
  72. /**
  73. * Return parent directory path
  74. *
  75. * @param string $path file path
  76. * @return string
  77. * @author Dmitry (dio) Levashov
  78. **/
  79. protected function _dirname($path) {
  80. return dirname($path);
  81. }
  82. /**
  83. * Return file name
  84. *
  85. * @param string $path file path
  86. * @return string
  87. * @author Dmitry (dio) Levashov
  88. **/
  89. protected function _basename($path) {
  90. return basename($path);
  91. }
  92. /**
  93. * Join dir name and file name and retur full path
  94. *
  95. * @param string $dir
  96. * @param string $name
  97. * @return string
  98. * @author Dmitry (dio) Levashov
  99. **/
  100. protected function _joinPath($dir, $name) {
  101. return $dir.DIRECTORY_SEPARATOR.$name;
  102. }
  103. /**
  104. * Return normalized path, this works the same as os.path.normpath() in Python
  105. *
  106. * @param string $path path
  107. * @return string
  108. * @author Troex Nevelin
  109. **/
  110. protected function _normpath($path) {
  111. if (empty($path)) {
  112. return '.';
  113. }
  114. if (strpos($path, '/') === 0) {
  115. $initial_slashes = true;
  116. } else {
  117. $initial_slashes = false;
  118. }
  119. if (($initial_slashes)
  120. && (strpos($path, '//') === 0)
  121. && (strpos($path, '///') === false)) {
  122. $initial_slashes = 2;
  123. }
  124. $initial_slashes = (int) $initial_slashes;
  125. $comps = explode('/', $path);
  126. $new_comps = array();
  127. foreach ($comps as $comp) {
  128. if (in_array($comp, array('', '.'))) {
  129. continue;
  130. }
  131. if (($comp != '..')
  132. || (!$initial_slashes && !$new_comps)
  133. || ($new_comps && (end($new_comps) == '..'))) {
  134. array_push($new_comps, $comp);
  135. } elseif ($new_comps) {
  136. array_pop($new_comps);
  137. }
  138. }
  139. $comps = $new_comps;
  140. $path = implode('/', $comps);
  141. if ($initial_slashes) {
  142. $path = str_repeat('/', $initial_slashes) . $path;
  143. }
  144. return $path ? $path : '.';
  145. }
  146. /**
  147. * Return file path related to root dir
  148. *
  149. * @param string $path file path
  150. * @return string
  151. * @author Dmitry (dio) Levashov
  152. **/
  153. protected function _relpath($path) {
  154. return $path == $this->root ? '' : substr($path, strlen($this->root)+1);
  155. }
  156. /**
  157. * Convert path related to root dir into real path
  158. *
  159. * @param string $path file path
  160. * @return string
  161. * @author Dmitry (dio) Levashov
  162. **/
  163. protected function _abspath($path) {
  164. return $path == DIRECTORY_SEPARATOR ? $this->root : $this->root.DIRECTORY_SEPARATOR.$path;
  165. }
  166. /**
  167. * Return fake path started from root dir
  168. *
  169. * @param string $path file path
  170. * @return string
  171. * @author Dmitry (dio) Levashov
  172. **/
  173. protected function _path($path) {
  174. return $this->rootName.($path == $this->root ? '' : $this->separator.$this->_relpath($path));
  175. }
  176. /**
  177. * Return true if $path is children of $parent
  178. *
  179. * @param string $path path to check
  180. * @param string $parent parent path
  181. * @return bool
  182. * @author Dmitry (dio) Levashov
  183. **/
  184. protected function _inpath($path, $parent) {
  185. return $path == $parent || strpos($path, $parent.DIRECTORY_SEPARATOR) === 0;
  186. }
  187. /*********************** check type *************************/
  188. /**
  189. * Return true if file exists
  190. *
  191. * @param string $path file path
  192. * @return bool
  193. * @author Dmitry (dio) Levashov
  194. **/
  195. protected function _fileExists($path) {
  196. return file_exists($path);
  197. }
  198. /**
  199. * Return true if path is a directory
  200. *
  201. * @param string file path
  202. * @return bool
  203. * @author Dmitry (dio) Levashov
  204. **/
  205. protected function _isDir($path) {
  206. return is_dir($path);
  207. }
  208. /**
  209. * Return true if path is a file
  210. *
  211. * @param string file path
  212. * @return bool
  213. * @author Dmitry (dio) Levashov
  214. **/
  215. protected function _isFile($path) {
  216. return is_file($path);
  217. }
  218. /**
  219. * Return true if path is a symlink
  220. *
  221. * @param string file path
  222. * @return bool
  223. * @author Dmitry (dio) Levashov
  224. **/
  225. protected function _isLink($path) {
  226. return is_link($path);
  227. }
  228. /***************** file attributes ********************/
  229. /**
  230. * Return true if path is readable
  231. *
  232. * @param string file path
  233. * @return bool
  234. * @author Dmitry (dio) Levashov
  235. **/
  236. protected function _isReadable($path) {
  237. return is_readable($path);
  238. }
  239. /**
  240. * Return true if path is writable
  241. *
  242. * @param string file path
  243. * @return bool
  244. * @author Dmitry (dio) Levashov
  245. **/
  246. protected function _isWritable($path) {
  247. return is_writable($path);
  248. }
  249. /**
  250. * Return true if path is locked
  251. *
  252. * @param string file path
  253. * @return bool
  254. * @author Dmitry (dio) Levashov
  255. **/
  256. protected function _isLocked($path) {
  257. return false;
  258. }
  259. /**
  260. * Return true if path is hidden
  261. *
  262. * @param string file path
  263. * @return bool
  264. * @author Dmitry (dio) Levashov
  265. **/
  266. protected function _isHidden($path) {
  267. return false;
  268. }
  269. /***************** file stat ********************/
  270. /**
  271. * Return file size
  272. *
  273. * @param string $path file path
  274. * @return int
  275. * @author Dmitry (dio) Levashov
  276. **/
  277. protected function _filesize($path) {
  278. return @filesize($path);
  279. }
  280. /**
  281. * Return file modification time
  282. *
  283. * @param string $path file path
  284. * @return int
  285. * @author Dmitry (dio) Levashov
  286. **/
  287. protected function _filemtime($path) {
  288. return @filemtime($path);
  289. }
  290. /**
  291. * Return true if path is dir and has at least one childs directory
  292. *
  293. * @param string $path dir path
  294. * @return bool
  295. * @author Dmitry (dio) Levashov
  296. **/
  297. protected function _subdirs($path) {
  298. if (is_dir($path) && is_readable($path)) {
  299. $dir = dir($path);
  300. while (($entry = $dir->read()) !== false) {
  301. $p = $dir->path.DIRECTORY_SEPARATOR.$entry;
  302. if ($entry != '.' && $entry != '..' && is_dir($p) && !$this->attr($p, 'hidden')) {
  303. $dir->close();
  304. return true;
  305. }
  306. }
  307. $dir->close();
  308. }
  309. return false;
  310. }
  311. /**
  312. * Return object width and height
  313. * Ususaly used for images, but can be realize for video etc...
  314. *
  315. * @param string $path file path
  316. * @param string $mime file mime type
  317. * @return string
  318. * @author Dmitry (dio) Levashov
  319. **/
  320. protected function _dimensions($path, $mime) {
  321. return strpos($mime, 'image') === 0 && ($s = @getimagesize($path)) !== false
  322. ? $s[0].'x'.$s[1]
  323. : false;
  324. }
  325. /**
  326. * Return symlink stat (required only size and mtime)
  327. *
  328. * @param string $path link path
  329. * @return array
  330. * @author Dmitry (dio) Levashov
  331. **/
  332. protected function _lstat($path) {
  333. return lstat($path);
  334. }
  335. /******************** file/dir content *********************/
  336. /**
  337. * Return symlink target file
  338. *
  339. * @param string $path link path
  340. * @return string
  341. * @author Dmitry (dio) Levashov
  342. **/
  343. protected function _readlink($path) {
  344. if (!($target = @readlink($path))) {
  345. return false;
  346. }
  347. if (substr($target, 0, 1) != DIRECTORY_SEPARATOR) {
  348. $target = dirname($path).DIRECTORY_SEPARATOR.$target;
  349. }
  350. $atarget = realpath($target);
  351. if (!$atarget) {
  352. return false;
  353. }
  354. if ($this->_inpath($atarget, $this->aroot)) {
  355. return $this->_normpath($this->root.DIRECTORY_SEPARATOR.substr($atarget, strlen($this->aroot)+1));
  356. }
  357. // echo $path.'<br>';
  358. return false;
  359. }
  360. /**
  361. * Return files list in directory.
  362. *
  363. * @param string $path dir path
  364. * @return array
  365. * @author Dmitry (dio) Levashov
  366. **/
  367. protected function _scandir($path) {
  368. $files = array();
  369. foreach (scandir($path) as $name) {
  370. if ($name != '.' && $name != '..') {
  371. $files[] = $path.DIRECTORY_SEPARATOR.$name;
  372. }
  373. }
  374. return $files;
  375. }
  376. /**
  377. * Open file and return file pointer
  378. *
  379. * @param string $path file path
  380. * @param bool $write open file for writing
  381. * @return resource|false
  382. * @author Dmitry (dio) Levashov
  383. **/
  384. protected function _fopen($path, $mode='rb') {
  385. return @fopen($path, $mode);
  386. }
  387. /**
  388. * Close opened file
  389. *
  390. * @param resource $fp file pointer
  391. * @return bool
  392. * @author Dmitry (dio) Levashov
  393. **/
  394. protected function _fclose($fp, $path) {
  395. return @fclose($fp);
  396. }
  397. /******************** file/dir manipulations *************************/
  398. /**
  399. * Create dir
  400. *
  401. * @param string $path parent dir path
  402. * @param string $name new directory name
  403. * @return bool
  404. * @author Dmitry (dio) Levashov
  405. **/
  406. protected function _mkdir($path, $name) {
  407. $path = $path.DIRECTORY_SEPARATOR.$name;
  408. if (@mkdir($path)) {
  409. @chmod($path, $this->options['dirMode']);
  410. return true;
  411. }
  412. return false;
  413. }
  414. /**
  415. * Create file
  416. *
  417. * @param string $path parent dir path
  418. * @param string $name new file name
  419. * @return bool
  420. * @author Dmitry (dio) Levashov
  421. **/
  422. protected function _mkfile($path, $name) {
  423. $path = $path.DIRECTORY_SEPARATOR.$name;
  424. if (($fp = @fopen($path, 'w'))) {
  425. @fclose($fp);
  426. @chmod($path, $this->options['fileMode']);
  427. return true;
  428. }
  429. return false;
  430. }
  431. /**
  432. * Create symlink
  433. *
  434. * @param string $target link target
  435. * @param string $path symlink path
  436. * @return bool
  437. * @author Dmitry (dio) Levashov
  438. **/
  439. protected function _symlink($target, $path, $name='') {
  440. if (!$name) {
  441. $name = basename($path);
  442. }
  443. return @symlink('.'.DIRECTORY_SEPARATOR.$this->_relpath($target), $path.DIRECTORY_SEPARATOR.$name);
  444. }
  445. /**
  446. * Copy file into another file
  447. *
  448. * @param string $source source file path
  449. * @param string $targetDir target directory path
  450. * @param string $name new file name
  451. * @return bool
  452. * @author Dmitry (dio) Levashov
  453. **/
  454. protected function _copy($source, $targetDir, $name='') {
  455. $target = $targetDir.DIRECTORY_SEPARATOR.($name ? $name : basename($source));
  456. return copy($source, $target);
  457. }
  458. /**
  459. * Move file into another parent dir
  460. *
  461. * @param string $source source file path
  462. * @param string $target target dir path
  463. * @param string $name file name
  464. * @return bool
  465. * @author Dmitry (dio) Levashov
  466. **/
  467. protected function _move($source, $targetDir, $name='') {
  468. $target = $targetDir.DIRECTORY_SEPARATOR.($name ? $name : basename($source));
  469. return @rename($source, $target);
  470. }
  471. /**
  472. * Remove file
  473. *
  474. * @param string $path file path
  475. * @return bool
  476. * @author Dmitry (dio) Levashov
  477. **/
  478. protected function _unlink($path) {
  479. return @unlink($path);
  480. }
  481. /**
  482. * Remove dir
  483. *
  484. * @param string $path dir path
  485. * @return bool
  486. * @author Dmitry (dio) Levashov
  487. **/
  488. protected function _rmdir($path) {
  489. return @rmdir($path);
  490. }
  491. /**
  492. * Create new file and write into it from file pointer.
  493. * Return new file path or false on error.
  494. *
  495. * @param resource $fp file pointer
  496. * @param string $dir target dir path
  497. * @param string $name file name
  498. * @return bool|string
  499. * @author Dmitry (dio) Levashov
  500. **/
  501. protected function _save($fp, $dir, $name) {
  502. $path = $dir.DIRECTORY_SEPARATOR.$name;
  503. if (!($target = @fopen($path, 'wb'))) {
  504. return false;
  505. }
  506. while (!feof($fp)) {
  507. fwrite($target, fread($fp, 8192));
  508. }
  509. fclose($target);
  510. @chmod($path, $this->options['fileMode']);
  511. clearstatcache();
  512. return $path;
  513. }
  514. /**
  515. * Get file contents
  516. *
  517. * @param string $path file path
  518. * @return string|false
  519. * @author Dmitry (dio) Levashov
  520. **/
  521. protected function _getContents($path) {
  522. return file_get_contents($path);
  523. }
  524. /**
  525. * Write a string to a file
  526. *
  527. * @param string $path file path
  528. * @param string $content new file content
  529. * @return bool
  530. * @author Dmitry (dio) Levashov
  531. **/
  532. protected function _filePutContents($path, $content) {
  533. if (@file_put_contents($path, $content, LOCK_EX)) {
  534. clearstatcache();
  535. return true;
  536. }
  537. return false;
  538. }
  539. /**
  540. * Detect available archivers
  541. *
  542. * @return void
  543. **/
  544. protected function _checkArchivers() {
  545. if (!function_exists('exec')) {
  546. $this->options['archivers'] = $this->options['archive'] = array();
  547. return;
  548. }
  549. $arcs = array(
  550. 'create' => array(),
  551. 'extract' => array()
  552. );
  553. //exec('tar --version', $o, $ctar);
  554. $this->procExec('tar --version', $o, $ctar);
  555. if ($ctar == 0) {
  556. $arcs['create']['application/x-tar'] = array('cmd' => 'tar', 'argc' => '-cf', 'ext' => 'tar');
  557. $arcs['extract']['application/x-tar'] = array('cmd' => 'tar', 'argc' => '-xf', 'ext' => 'tar');
  558. //$test = exec('gzip --version', $o, $c);
  559. $test = $this->procExec('gzip --version', $o, $c);
  560. if ($c == 0) {
  561. $arcs['create']['application/x-gzip'] = array('cmd' => 'tar', 'argc' => '-czf', 'ext' => 'tgz');
  562. $arcs['extract']['application/x-gzip'] = array('cmd' => 'tar', 'argc' => '-xzf', 'ext' => 'tgz');
  563. }
  564. //$test = exec('bzip2 --version', $o, $c);
  565. $test = $this->procExec('bzip2 --version', $o, $c);
  566. if ($c == 0) {
  567. $arcs['create']['application/x-bzip2'] = array('cmd' => 'tar', 'argc' => '-cjf', 'ext' => 'tbz');
  568. $arcs['extract']['application/x-bzip2'] = array('cmd' => 'tar', 'argc' => '-xjf', 'ext' => 'tbz');
  569. }
  570. }
  571. //exec('zip --version', $o, $c);
  572. $this->procExec('zip --version', $o, $c);
  573. if ($c == 0) {
  574. $arcs['create']['application/zip'] = array('cmd' => 'zip', 'argc' => '-r9', 'ext' => 'zip');
  575. }
  576. $this->procExec('unzip --help', $o, $c);
  577. if ($c == 0) {
  578. $arcs['extract']['application/zip'] = array('cmd' => 'unzip', 'argc' => '', 'ext' => 'zip');
  579. }
  580. //exec('rar --version', $o, $c);
  581. $this->procExec('rar --version', $o, $c);
  582. if ($c == 0 || $c == 7) {
  583. $arcs['create']['application/x-rar'] = array('cmd' => 'rar', 'argc' => 'a -inul', 'ext' => 'rar');
  584. $arcs['extract']['application/x-rar'] = array('cmd' => 'rar', 'argc' => 'x -y', 'ext' => 'rar');
  585. } else {
  586. //$test = exec('unrar', $o, $c);
  587. $test = $this->procExec('unrar', $o, $c);
  588. if ($c==0 || $c == 7) {
  589. $arcs['extract']['application/x-rar'] = array('cmd' => 'unrar', 'argc' => 'x -y', 'ext' => 'rar');
  590. }
  591. }
  592. //exec('7za --help', $o, $c);
  593. $this->procExec('7za --help', $o, $c);
  594. if ($c == 0) {
  595. $arcs['create']['application/x-7z-compressed'] = array('cmd' => '7za', 'argc' => 'a', 'ext' => '7z');
  596. $arcs['extract']['application/x-7z-compressed'] = array('cmd' => '7za', 'argc' => 'e -y', 'ext' => '7z');
  597. if (empty($arcs['create']['application/x-gzip'])) {
  598. $arcs['create']['application/x-gzip'] = array('cmd' => '7za', 'argc' => 'a -tgzip', 'ext' => 'tar.gz');
  599. }
  600. if (empty($arcs['extract']['application/x-gzip'])) {
  601. $arcs['extract']['application/x-gzip'] = array('cmd' => '7za', 'argc' => 'e -tgzip -y', 'ext' => 'tar.gz');
  602. }
  603. if (empty($arcs['create']['application/x-bzip2'])) {
  604. $arcs['create']['application/x-bzip2'] = array('cmd' => '7za', 'argc' => 'a -tbzip2', 'ext' => 'tar.bz');
  605. }
  606. if (empty($arcs['extract']['application/x-bzip2'])) {
  607. $arcs['extract']['application/x-bzip2'] = array('cmd' => '7za', 'argc' => 'a -tbzip2 -y', 'ext' => 'tar.bz');
  608. }
  609. if (empty($arcs['create']['application/zip'])) {
  610. $arcs['create']['application/zip'] = array('cmd' => '7za', 'argc' => 'a -tzip -l', 'ext' => 'zip');
  611. }
  612. if (empty($arcs['extract']['application/zip'])) {
  613. $arcs['extract']['application/zip'] = array('cmd' => '7za', 'argc' => 'e -tzip -y', 'ext' => 'zip');
  614. }
  615. if (empty($arcs['create']['application/x-tar'])) {
  616. $arcs['create']['application/x-tar'] = array('cmd' => '7za', 'argc' => 'a -ttar -l', 'ext' => 'tar');
  617. }
  618. if (empty($arcs['extract']['application/x-tar'])) {
  619. $arcs['extract']['application/x-tar'] = array('cmd' => '7za', 'argc' => 'e -ttar -y', 'ext' => 'tar');
  620. }
  621. }
  622. $this->archivers = $arcs;
  623. }
  624. /**
  625. * Extract files from archive
  626. *
  627. * @param string $path archive path
  628. * @param array $arc archiver command and arguments (same as in $this->archivers)
  629. * @return true
  630. * @author Dmitry (dio) Levashov,
  631. * @author Alexey Sukhotin
  632. **/
  633. protected function _extract($path, $arc) {
  634. $cwd = getcwd();
  635. $dir = $this->_dirname($path);
  636. chdir($dir);
  637. $cmd = $arc['cmd'].' '.$arc['argc'].' '.escapeshellarg($this->_basename($path));
  638. $this->procExec($cmd, $o, $c);
  639. chdir($cwd);
  640. return true;
  641. }
  642. /**
  643. * Create archive and return its path
  644. *
  645. * @param string $dir target dir
  646. * @param array $files files names list
  647. * @param string $name archive name
  648. * @param array $arc archiver options
  649. * @return string|bool
  650. * @author Dmitry (dio) Levashov,
  651. * @author Alexey Sukhotin
  652. **/
  653. protected function _archive($dir, $files, $name, $arc) {
  654. $cwd = getcwd();
  655. chdir($dir);
  656. $files = array_map('escapeshellarg', $files);
  657. $cmd = $arc['cmd'].' '.$arc['argc'].' '.escapeshellarg($name).' '.implode(' ', $files);
  658. $this->procExec($cmd, $o, $c);
  659. chdir($cwd);
  660. $path = $dir.DIRECTORY_SEPARATOR.$name;
  661. return file_exists($path) ? $path : false;
  662. $this->checkArchivers();
  663. $dir = $this->decode($args['current']);
  664. $targets = $args['targets'];
  665. $files = array();
  666. $argc = '';
  667. foreach ($targets as $target) {
  668. $f = $this->file($target);
  669. $argc .= escapeshellarg($f['name']).' ';
  670. $files[] = $f;
  671. }
  672. $arc = $this->options['archivers']['create'][$args['type']];
  673. if ($arc) {
  674. $name = (count($files) == 1 ? basename($files[0]) : $args['name']) . '.' . $arc['ext'] ;
  675. $name = $this->uniqueName($dir, $name, '-', false);
  676. $cwd = getcwd();
  677. chdir($dir);
  678. $cmd = $arc['cmd'].' '.$arc['argc'].' '.escapeshellarg($name).' '.$argc;
  679. $this->procExec($cmd, $o, $c);
  680. chdir($cwd);
  681. if ($c == 0) {
  682. $finfo = $this->stat($dir . $this->options['separator'] . $name);
  683. return array($finfo);
  684. }
  685. return false;
  686. }
  687. return false;
  688. }
  689. } // END class