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

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

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