PluginProbe ʕ •ᴥ•ʔ
File Manager Pro – Filester / 2.0
File Manager Pro – Filester v2.0
2.1.1 trunk 1.6.1 1.7.6 1.8 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 2.0 2.0.1 2.0.2 2.1.0
filester / includes / File_manager / lib / php / elFinderVolumeSFTPphpseclib.class.php
filester / includes / File_manager / lib / php Last commit date
editors 9 months ago libs 9 months ago plugins 9 months ago resources 9 months ago MySQLStorage.sql 9 months ago autoload.php 9 months ago elFinder.class.php 9 months ago elFinderConnector.class.php 9 months ago elFinderFlysystemGoogleDriveNetmount.php 9 months ago elFinderPlugin.php 9 months ago elFinderSession.php 9 months ago elFinderSessionInterface.php 9 months ago elFinderVolumeBox.class.php 9 months ago elFinderVolumeDriver.class.php 9 months ago elFinderVolumeDropbox.class.php 9 months ago elFinderVolumeDropbox2.class.php 9 months ago elFinderVolumeFTP.class.php 9 months ago elFinderVolumeGoogleDrive.class.php 9 months ago elFinderVolumeGroup.class.php 9 months ago elFinderVolumeLocalFileSystem.class.php 9 months ago elFinderVolumeMySQL.class.php 9 months ago elFinderVolumeOneDrive.class.php 9 months ago elFinderVolumeSFTPphpseclib.class.php 9 months ago elFinderVolumeTrash.class.php 9 months ago elFinderVolumeTrashMySQL.class.php 9 months ago mime.types 9 months ago
elFinderVolumeSFTPphpseclib.class.php
854 lines
1 <?php
2
3 /**
4 * Simple elFinder driver for SFTP using phpseclib 1
5 *
6 * @author Dmitry (dio) Levashov
7 * @author Cem (discofever), sitecode
8 * @reference http://phpseclib.sourceforge.net/sftp/2.0/examples.html
9 **/
10 class elFinderVolumeSFTPphpseclib extends elFinderVolumeFTP {
11
12 /**
13 * Simple hack that could break for quick compatibility with phpseclib version 1-3
14 * Same value substitue for reference NET_SFTP_LOCAL_FILE and SFTP::SOURCE_LOCAL_FILE
15 */
16 const NET_SFTP_LOCAL_FILE = 1;
17
18 /**
19 * Constructor
20 * Extend options with required fields
21 *
22 * @author Dmitry (dio) Levashov
23 * @author Cem (DiscoFever)
24 */
25 public function __construct()
26 {
27 $opts = array(
28 'host' => 'localhost',
29 'user' => '',
30 'pass' => '',
31 'port' => 22,
32 'path' => '/',
33 'timeout' => 20,
34 'owner' => true,
35 'tmbPath' => '',
36 'tmpPath' => '',
37 'separator' => '/',
38 'phpseclibDir' => '../phpseclib/',
39 'connectCallback' => null, //provide your own already instantiated phpseclib $Sftp object returned by this callback
40 //'connectCallback'=> function($options) {
41 // //load and instantiate phpseclib $sftp
42 // return $sftp;
43 // },
44 'checkSubfolders' => -1,
45 'dirMode' => 0755,
46 'fileMode' => 0644,
47 'rootCssClass' => 'elfinder-navbar-root-ftp',
48 );
49 $this->options = array_merge($this->options, $opts);
50 $this->options['mimeDetect'] = 'internal';
51 }
52
53 /**
54 * Prepare
55 * Call from elFinder::netmout() before volume->mount()
56 *
57 * @param $options
58 *
59 * @return array volume root options
60 * @author Naoki Sawada
61 */
62 public function netmountPrepare($options)
63 {
64 $options['statOwner'] = true;
65 $options['allowChmodReadOnly'] = true;
66 $options['acceptedName'] = '#^[^/\\?*:|"<>]*[^./\\?*:|"<>]$#';
67 return $options;
68 }
69
70 /*********************************************************************/
71 /* INIT AND CONFIGURE */
72 /*********************************************************************/
73
74 /**
75 * Prepare SFTP connection
76 * Connect to remote server and check if credentials are correct, if so, store the connection
77 *
78 * @return bool
79 * @author Dmitry (dio) Levashov
80 * @author Cem (DiscoFever)
81 **/
82 protected function init()
83 {
84 if (!$this->options['connectCallback']) {
85 if (!$this->options['host']
86 || !$this->options['port']) {
87 return $this->setError('Required options undefined.');
88 }
89
90 if (!$this->options['path']) {
91 $this->options['path'] = '/';
92 }
93
94 // make net mount key
95 $this->netMountKey = md5(join('-', array('sftpphpseclib', $this->options['host'], $this->options['port'], $this->options['path'], $this->options['user'])));
96
97 set_include_path(get_include_path() . PATH_SEPARATOR . getcwd().'/'.$this->options['phpseclibDir']);
98 include_once('Net/SFTP.php');
99
100 if (!class_exists('Net_SFTP')) {
101 return $this->setError('SFTP extension not loaded. Install phpseclib version 1: http://phpseclib.sourceforge.net/ Set option "phpseclibDir" accordingly.');
102 }
103
104 // remove protocol from host
105 $scheme = parse_url($this->options['host'], PHP_URL_SCHEME);
106
107 if ($scheme) {
108 $this->options['host'] = substr($this->options['host'], strlen($scheme) + 3);
109 }
110 } else {
111 // make net mount key
112 $this->netMountKey = md5(join('-', array('sftpphpseclib', $this->options['path'])));
113 }
114
115 // normalize root path
116 $this->root = $this->options['path'] = $this->_normpath($this->options['path']);
117
118 if (empty($this->options['alias'])) {
119 $this->options['alias'] = $this->options['user'] . '@' . $this->options['host'];
120 if (!empty($this->options['netkey'])) {
121 elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'alias', $this->options['alias']);
122 }
123 }
124
125 $this->rootName = $this->options['alias'];
126 $this->options['separator'] = '/';
127
128 if (is_null($this->options['syncChkAsTs'])) {
129 $this->options['syncChkAsTs'] = true;
130 }
131
132 return $this->needOnline? $this->connect() : true;
133
134 }
135
136
137 /**
138 * Configure after successfull mount.
139 *
140 * @return void
141 * @throws elFinderAbortException
142 * @author Dmitry (dio) Levashov
143 */
144 protected function configure()
145 {
146 parent::configure();
147
148 if (!$this->tmp) {
149 $this->disabled[] = 'mkfile';
150 $this->disabled[] = 'paste';
151 $this->disabled[] = 'upload';
152 $this->disabled[] = 'edit';
153 //$this->disabled[] = 'archive';
154 //$this->disabled[] = 'extract';
155 }
156
157 $this->disabled[] = 'archive';
158 $this->disabled[] = 'extract';
159 }
160
161 /**
162 * Connect to sftp server
163 *
164 * @return bool
165 * @author sitecode
166 **/
167 protected function connect()
168 {
169 //use ca
170 if ($this->options['connectCallback']) {
171 $this->connect = $this->options['connectCallback']($this->options);
172 if (!$this->connect || !$this->connect->isConnected()) {
173 return $this->setError('Unable to connect successfully');
174 }
175
176 return true;
177 }
178
179 try{
180 $host = $this->options['host'] . ($this->options['port'] != 22 ? ':' . $this->options['port'] : '');
181 $this->connect = new Net_SFTP($host);
182 //TODO check fingerprint before login, fail if no match to last time
183 if (!$this->connect->login($this->options['user'], $this->options['pass'])) {
184 return $this->setError('Unable to connect to SFTP server ' . $host);
185 }
186 } catch (Exception $e) {
187 return $this->setError('Error while connecting to SFTP server ' . $host . ': ' . $e->getMessage());
188 }
189
190 if (!$this->connect->chdir($this->root)
191 /*|| $this->root != $this->connect->pwd()*/) {
192 //$this->umount();
193 return $this->setError('Unable to open root folder.');
194 }
195
196 return true;
197 }
198
199 /**
200 * Call rawlist
201 *
202 * @param string $path
203 *
204 * @return array
205 */
206 protected function ftpRawList($path)
207 {
208 return $this->connect->rawlist($path ?: '.') ?: [];
209 }
210
211 /*********************************************************************/
212 /* FS API */
213 /*********************************************************************/
214
215 /**
216 * Close opened connection
217 *
218 * @return void
219 * @author Dmitry (dio) Levashov
220 **/
221 public function umount()
222 {
223 $this->connect && $this->connect->disconnect();
224 }
225
226
227 /**
228 * Parse line from rawlist() output and return file stat (array)
229 *
230 * @param array $info from rawlist() output
231 * @param $base
232 * @param bool $nameOnly
233 *
234 * @return array
235 * @author Dmitry Levashov
236 */
237 protected function parseRaw($info, $base, $nameOnly = false)
238 {
239 $stat = array();
240
241 if ($info['filename'] == '.' || $info['filename'] == '..') {
242 return false;
243 }
244
245 $name = $info['filename'];
246 //for compatability with phpseclib version 2/3
247 if (empty($info['permissions'])) {
248 $info['permissions'] = $info['mode'];
249 }
250
251 if ($info['type'] === 3) {
252 // check recursive processing
253 if ($this->cacheDirTarget && $this->_joinPath($base, $name) !== $this->cacheDirTarget) {
254 return array();
255 }
256 if (!$nameOnly) {
257 $target = $this->connect->readlink($name);
258 if (substr($target, 0, 1) !== $this->separator) {
259 $target = $this->getFullPath($target, $base);
260 }
261 $target = $this->_normpath($target);
262 $stat['name'] = $name;
263 $stat['target'] = $target;
264 return $stat;
265 }
266 }
267
268 if ($nameOnly) {
269 return array('name' => $name);
270 }
271
272 $stat['ts'] = $info['mtime'];
273
274 if ($this->options['statOwner']) {
275 $stat['owner'] = $info['uid'];
276 $stat['group'] = $info['gid'];
277 $stat['perm'] = $info['permissions'];
278 $stat['isowner'] = isset($stat['owner']) ? ($this->options['owner'] ? true : ($stat['owner'] == $this->options['user'])) : true;
279 }
280
281 $owner_computed = isset($stat['isowner']) ? $stat['isowner'] : $this->options['owner'];
282 $perm = $this->parsePermissions($info['permissions'], $owner_computed);
283 $stat['name'] = $name;
284 if ($info['type'] === NET_SFTP_TYPE_DIRECTORY) {
285 $stat['mime'] = 'directory';
286 $stat['size'] = 0;
287
288 } elseif ($info['type'] === NET_SFTP_TYPE_SYMLINK) {
289 $stat['mime'] = 'symlink';
290 $stat['size'] = 0;
291
292 } else {
293 $stat['mime'] = $this->mimetype($stat['name'], true);
294 $stat['size'] = $info['size'];
295 }
296
297 $stat['read'] = $perm['read'];
298 $stat['write'] = $perm['write'];
299
300 return $stat;
301 }
302
303 /**
304 * Parse permissions string. Return array(read => true/false, write => true/false)
305 *
306 * @param int $perm
307 * The isowner parameter is computed by the caller.
308 * If the owner parameter in the options is true, the user is the actual owner of all objects even if the user used in the ftp Login
309 * is different from the file owner id.
310 * If the owner parameter is false to understand if the user is the file owner we compare the ftp user with the file owner id.
311 * @param Boolean $isowner . Tell if the current user is the owner of the object.
312 *
313 * @return array
314 * @author Dmitry (dio) Levashov
315 * @author sitecode
316 */
317 protected function parsePermissions($permissions, $isowner = true)
318 {
319 $permissions = decoct($permissions);
320 $perm = $isowner ? decbin((int)$permissions[-3]) : decbin((int)$permissions[-1]);
321
322 return array(
323 'read' => $perm[-3],
324 'write' => $perm[-2]
325 );
326 }
327
328 /**
329 * Cache dir contents
330 *
331 * @param string $path dir path
332 *
333 * @return void
334 * @author Dmitry Levashov, sitecode
335 **/
336 protected function cacheDir($path)
337 {
338 $this->dirsCache[$path] = array();
339 $hasDir = false;
340
341 $list = array();
342 $encPath = $this->convEncIn($path);
343 foreach ($this->ftpRawList($encPath) as $info) {
344 if (($stat = $this->parseRaw($info, $encPath))) {
345 $list[] = $stat;
346 }
347 }
348 $list = $this->convEncOut($list);
349 $prefix = ($path === $this->separator) ? $this->separator : $path . $this->separator;
350 $targets = array();
351 foreach ($list as $stat) {
352 $p = $prefix . $stat['name'];
353 if (isset($stat['target'])) {
354 // stat later
355 $targets[$stat['name']] = $stat['target'];
356 } else {
357 $stat = $this->updateCache($p, $stat);
358 if (empty($stat['hidden'])) {
359 if (!$hasDir && $stat['mime'] === 'directory') {
360 $hasDir = true;
361 } elseif (!$hasDir && $stat['mime'] === 'symlink') {
362 $hasDir = true;
363 }
364 $this->dirsCache[$path][] = $p;
365 }
366 }
367 }
368 // stat link targets
369 foreach ($targets as $name => $target) {
370 $stat = array();
371 $stat['name'] = $name;
372 $p = $prefix . $name;
373 $cacheDirTarget = $this->cacheDirTarget;
374 $this->cacheDirTarget = $this->convEncIn($target, true);
375 if ($tstat = $this->stat($target)) {
376 $stat['size'] = $tstat['size'];
377 $stat['alias'] = $target;
378 $stat['thash'] = $tstat['hash'];
379 $stat['mime'] = $tstat['mime'];
380 $stat['read'] = $tstat['read'];
381 $stat['write'] = $tstat['write'];
382
383 if (isset($tstat['ts'])) {
384 $stat['ts'] = $tstat['ts'];
385 }
386 if (isset($tstat['owner'])) {
387 $stat['owner'] = $tstat['owner'];
388 }
389 if (isset($tstat['group'])) {
390 $stat['group'] = $tstat['group'];
391 }
392 if (isset($tstat['perm'])) {
393 $stat['perm'] = $tstat['perm'];
394 }
395 if (isset($tstat['isowner'])) {
396 $stat['isowner'] = $tstat['isowner'];
397 }
398 } else {
399
400 $stat['mime'] = 'symlink-broken';
401 $stat['read'] = false;
402 $stat['write'] = false;
403 $stat['size'] = 0;
404
405 }
406 $this->cacheDirTarget = $cacheDirTarget;
407 $stat = $this->updateCache($p, $stat);
408 if (empty($stat['hidden'])) {
409 if (!$hasDir && $stat['mime'] === 'directory') {
410 $hasDir = true;
411 }
412 $this->dirsCache[$path][] = $p;
413 }
414 }
415
416 if (isset($this->sessionCache['subdirs'])) {
417 $this->sessionCache['subdirs'][$path] = $hasDir;
418 }
419 }
420
421
422 /***************** file stat ********************/
423
424 /**
425 * Return stat for given path.
426 * Stat contains following fields:
427 * - (int) size file size in b. required
428 * - (int) ts file modification time in unix time. required
429 * - (string) mime mimetype. required for folders, others - optionally
430 * - (bool) read read permissions. required
431 * - (bool) write write permissions. required
432 * - (bool) locked is object locked. optionally
433 * - (bool) hidden is object hidden. optionally
434 * - (string) alias for symlinks - link target path relative to root path. optionally
435 * - (string) target for symlinks - link target path. optionally
436 * If file does not exists - returns empty array or false.
437 *
438 * @param string $path file path
439 *
440 * @return array|false
441 * @author Dmitry (dio) Levashov
442 **/
443 protected function _stat($path)
444 {
445 $outPath = $this->convEncOut($path);
446 if (isset($this->cache[$outPath])) {
447 return $this->convEncIn($this->cache[$outPath]);
448 } else {
449 $this->convEncIn();
450 }
451 if ($path === $this->root) {
452 $res = array(
453 'name' => $this->root,
454 'mime' => 'directory',
455 'dirs' => -1
456 );
457 if ($this->needOnline && (($this->ARGS['cmd'] === 'open' && $this->ARGS['target'] === $this->encode($this->root)) || $this->isMyReload())) {
458 $check = array(
459 'ts' => true,
460 'dirs' => true,
461 );
462 $ts = 0;
463 foreach ($this->ftpRawList($path) as $info) {
464 if ($info['filename'] === '.') {
465 $info['filename'] = 'root';
466 if ($stat = $this->parseRaw($info, $path)) {
467 unset($stat['name']);
468 $res = array_merge($res, $stat);
469 if ($res['ts']) {
470 $ts = 0;
471 unset($check['ts']);
472 }
473 }
474 }
475 if ($check && ($stat = $this->parseRaw($info, $path))) {
476 if (isset($stat['ts']) && !empty($stat['ts'])) {
477 $ts = max($ts, $stat['ts']);
478 }
479 if (isset($stat['dirs']) && $stat['mime'] === 'directory') {
480 $res['dirs'] = 1;
481 unset($stat['dirs']);
482 }
483 if (!$check) {
484 break;
485 }
486 }
487 }
488 if ($ts) {
489 $res['ts'] = $ts;
490 }
491 $this->cache[$outPath] = $res;
492 }
493 return $res;
494 }
495
496 $pPath = $this->_dirname($path);
497 if ($this->_inPath($pPath, $this->root)) {
498 $outPPpath = $this->convEncOut($pPath);
499 if (!isset($this->dirsCache[$outPPpath])) {
500 $parentSubdirs = null;
501 if (isset($this->sessionCache['subdirs']) && isset($this->sessionCache['subdirs'][$outPPpath])) {
502 $parentSubdirs = $this->sessionCache['subdirs'][$outPPpath];
503 }
504 $this->cacheDir($outPPpath);
505 if ($parentSubdirs) {
506 $this->sessionCache['subdirs'][$outPPpath] = $parentSubdirs;
507 }
508 }
509 }
510
511 $stat = $this->convEncIn(isset($this->cache[$outPath]) ? $this->cache[$outPath] : array());
512 if (!$this->mounted) {
513 // dispose incomplete cache made by calling `stat` by 'startPath' option
514 $this->cache = array();
515 }
516
517 return $stat;
518 }
519
520 /**
521 * Return true if path is dir and has at least one childs directory
522 *
523 * @param string $path dir path
524 *
525 * @return bool
526 * @author Dmitry (dio) Levashov, sitecode
527 **/
528 protected function _subdirs($path)
529 {
530 foreach ($this->ftpRawList($path) as $info) {
531 $name = $info['filename'];
532 if ($name && $name !== '.' && $name !== '..' && $info['type'] == NET_SFTP_TYPE_DIRECTORY) {
533 return true;
534 }
535 if ($name && $name !== '.' && $name !== '..' && $info['type'] == NET_SFTP_TYPE_SYMLINK) {
536 //return true;
537 }
538 }
539
540 return false;
541 }
542
543
544 /******************** file/dir content *********************/
545
546 /**
547 * Open file and return file pointer
548 *
549 * @param string $path file path
550 * @param string $mode
551 *
552 * @return false|resource
553 * @throws elFinderAbortException
554 * @internal param bool $write open file for writing
555 * @author Dmitry (dio) Levashov
556 */
557 protected function _fopen($path, $mode = 'rb')
558 {
559 if ($this->tmp) {
560 $local = $this->getTempFile($path);
561 $this->connect->get($path, $local);
562 return @fopen($local, $mode);
563 }
564
565 return false;
566 }
567
568 /**
569 * Close opened file
570 *
571 * @param resource $fp file pointer
572 * @param string $path
573 *
574 * @return void
575 * @author Dmitry (dio) Levashov
576 */
577 protected function _fclose($fp, $path = '')
578 {
579 is_resource($fp) && fclose($fp);
580 if ($path) {
581 unlink($this->getTempFile($path));
582 }
583 }
584
585
586 /******************** file/dir manipulations *************************/
587
588 /**
589 * Create dir and return created dir path or false on failed
590 *
591 * @param string $path parent dir path
592 * @param string $name new directory name
593 *
594 * @return string|bool
595 * @author Dmitry (dio) Levashov
596 **/
597 protected function _mkdir($path, $name)
598 {
599 $path = $this->_joinPath($path, $this->_basename($name));
600 if ($this->connect->mkdir($path) === false) {
601 return false;
602 }
603
604 $this->options['dirMode'] && $this->connect->chmod($this->options['dirMode'], $path);
605 return $path;
606 }
607
608 /**
609 * Create file and return it's path or false on failed
610 *
611 * @param string $path parent dir path
612 * @param string $name new file name
613 *
614 * @return string|bool
615 * @author sitecode
616 **/
617 protected function _mkfile($path, $name)
618 {
619 $path = $this->_joinPath($path, $this->_basename($name));
620 return $this->connect->put($path, '') ? $path : false;
621 /*
622 if ($this->tmp) {
623 $path = $this->_joinPath($path, $name);
624 $local = $this->getTempFile();
625 $res = touch($local) && $this->connect->put($path, $local, self::NET_SFTP_LOCAL_FILE);
626 unlink($local);
627 return $res ? $path : false;
628 }
629
630 return false;
631 */
632 }
633
634 /**
635 * Copy file into another file
636 *
637 * @param string $source source file path
638 * @param string $targetDir target directory path
639 * @param string $name new file name
640 *
641 * @return bool
642 * @author Dmitry (dio) Levashov, sitecode
643 **/
644 protected function _copy($source, $targetDir, $name)
645 {
646 $res = false;
647
648 $target = $this->_joinPath($targetDir, $this->_basename($name));
649 if ($this->tmp) {
650 $local = $this->getTempFile();
651
652 if ($this->connect->get($source, $local)
653 && $this->connect->put($target, $local, self::NET_SFTP_LOCAL_FILE)) {
654 $res = true;
655 }
656 unlink($local);
657 } else {
658 //not memory efficient
659 $res = $this->_filePutContents($target, $this->_getContents($source));
660 }
661
662 return $res;
663 }
664
665 /**
666 * Move file into another parent dir.
667 * Return new file path or false.
668 *
669 * @param string $source source file path
670 * @param $targetDir
671 * @param string $name file name
672 *
673 * @return bool|string
674 * @internal param string $target target dir path
675 * @author Dmitry (dio) Levashov
676 */
677 protected function _move($source, $targetDir, $name)
678 {
679 $target = $this->_joinPath($targetDir, $this->_basename($name));
680 return $this->connect->rename($source, $target) ? $target : false;
681 }
682
683 /**
684 * Remove file
685 *
686 * @param string $path file path
687 *
688 * @return bool
689 * @author Dmitry (dio) Levashov
690 **/
691 protected function _unlink($path)
692 {
693 return $this->connect->delete($path, false);
694 }
695
696 /**
697 * Remove dir
698 *
699 * @param string $path dir path
700 *
701 * @return bool
702 * @author Dmitry (dio) Levashov
703 **/
704 protected function _rmdir($path)
705 {
706 return $this->connect->delete($path);
707 }
708
709 /**
710 * Create new file and write into it from file pointer.
711 * Return new file path or false on error.
712 *
713 * @param resource $fp file pointer
714 * @param string $dir target dir path
715 * @param string $name file name
716 * @param array $stat file stat (required by some virtual fs)
717 *
718 * @return bool|string
719 * @author Dmitry (dio) Levashov
720 **/
721 protected function _save($fp, $dir, $name, $stat)
722 {
723 //TODO optionally encrypt $fp before uploading if mime is not already encrypted type
724 $path = $this->_joinPath($dir, $this->_basename($name));
725 return $this->connect->put($path, $fp)
726 ? $path
727 : false;
728 }
729
730 /**
731 * Get file contents
732 *
733 * @param string $path file path
734 *
735 * @return string|false
736 * @throws elFinderAbortException
737 * @author Dmitry (dio) Levashov
738 */
739 protected function _getContents($path)
740 {
741 return $this->connect->get($path);
742 }
743
744 /**
745 * Write a string to a file
746 *
747 * @param string $path file path
748 * @param string $content new file content
749 *
750 * @return bool
751 * @author Dmitry (dio) Levashov
752 **/
753 protected function _filePutContents($path, $content)
754 {
755 return $this->connect->put($path, $content);
756 }
757
758 /**
759 * chmod availability
760 *
761 * @param string $path
762 * @param string $mode
763 *
764 * @return bool
765 */
766 protected function _chmod($path, $mode)
767 {
768 $modeOct = is_string($mode) ? octdec($mode) : octdec(sprintf("%04o", $mode));
769 return $this->connect->chmod($modeOct, $path);
770 }
771
772 /**
773 * Extract files from archive
774 *
775 * @param string $path archive path
776 * @param array $arc archiver command and arguments (same as in $this->archivers)
777 *
778 * @return true
779 * @throws elFinderAbortException
780 * @author Dmitry (dio) Levashov,
781 * @author Alexey Sukhotin
782 */
783 protected function _extract($path, $arc)
784 {
785 return false; //TODO
786 }
787
788 /**
789 * Create archive and return its path
790 *
791 * @param string $dir target dir
792 * @param array $files files names list
793 * @param string $name archive name
794 * @param array $arc archiver options
795 *
796 * @return string|bool
797 * @throws elFinderAbortException
798 * @author Dmitry (dio) Levashov,
799 * @author Alexey Sukhotin
800 */
801 protected function _archive($dir, $files, $name, $arc)
802 {
803 return false; //TODO
804 }
805
806 /**
807 * Gets an array of absolute remote SFTP paths of files and
808 * folders in $remote_directory omitting symbolic links.
809 *
810 * @param $remote_directory string remote SFTP path to scan for file and folders recursively
811 * @param $targets array Array of target item. `null` is to get all of items
812 *
813 * @return array of elements each of which is an array of two elements:
814 * <ul>
815 * <li>$item['path'] - absolute remote SFTP path</li>
816 * <li>$item['type'] - either 'f' for file or 'd' for directory</li>
817 * </ul>
818 */
819 protected function ftp_scan_dir($remote_directory, $targets = null)
820 {
821 $buff = $this->ftpRawList($remote_directory);
822 $items = array();
823 if ($targets && is_array($targets)) {
824 $targets = array_flip($targets);
825 } else {
826 $targets = false;
827 }
828 foreach ($buff as $info) {
829 $name = $info['filename'];
830 if ($name !== '.' && $name !== '..' && (!$targets || isset($targets[$name]))) {
831 switch ($info['type']) {
832 case NET_SFTP_TYPE_SYMLINK : //omit symbolic links
833 case NET_SFTP_TYPE_DIRECTORY :
834 $remote_file_path = $this->_joinPath($remote_directory, $name);
835 $item = array();
836 $item['path'] = $remote_file_path;
837 $item['type'] = 'd'; // normal file
838 $items[] = $item;
839 $items = array_merge($items, $this->ftp_scan_dir($remote_file_path));
840 break;
841 default:
842 $remote_file_path = $this->_joinPath($remote_directory, $name);
843 $item = array();
844 $item['path'] = $remote_file_path;
845 $item['type'] = 'f'; // normal file
846 $items[] = $item;
847 }
848 }
849 }
850 return $items;
851 }
852
853 } // END class
854