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