PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/htdocs/includes/lib/elfinder/php/elFinderVolumeLocalFileSystem.class.php

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