ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
AbstractFtpAdapter.php
Go to the documentation of this file.
1<?php
2
4
5use DateTime;
10use RuntimeException;
11
12abstract class AbstractFtpAdapter extends AbstractAdapter
13{
17 protected $connection;
18
22 protected $host;
23
27 protected $port = 21;
28
32 protected $ssl = false;
33
37 protected $timeout = 90;
38
42 protected $passive = true;
43
47 protected $separator = '/';
48
52 protected $root;
53
57 protected $permPublic = 0744;
58
62 protected $permPrivate = 0700;
63
67 protected $configurable = [];
68
72 protected $systemType;
73
77 protected $alternativeRecursion = false;
78
82 protected $safeStorage;
83
89 public function __construct(array $config)
90 {
91 $this->safeStorage = new SafeStorage();
92 $this->setConfig($config);
93 }
94
102 public function setConfig(array $config)
103 {
104 foreach ($this->configurable as $setting) {
105 if ( ! isset($config[$setting])) {
106 continue;
107 }
108
109 $method = 'set' . ucfirst($setting);
110
111 if (method_exists($this, $method)) {
112 $this->$method($config[$setting]);
113 }
114 }
115
116 return $this;
117 }
118
124 public function getHost()
125 {
126 return $this->host;
127 }
128
136 public function setHost($host)
137 {
138 $this->host = $host;
139
140 return $this;
141 }
142
150 public function setPermPublic($permPublic)
151 {
152 $this->permPublic = $permPublic;
153
154 return $this;
155 }
156
165 {
166 $this->permPrivate = $permPrivate;
167
168 return $this;
169 }
170
176 public function getPort()
177 {
178 return $this->port;
179 }
180
186 public function getRoot()
187 {
188 return $this->root;
189 }
190
198 public function setPort($port)
199 {
200 $this->port = (int) $port;
201
202 return $this;
203 }
204
212 public function setRoot($root)
213 {
214 $this->root = rtrim($root, '\\/') . $this->separator;
215
216 return $this;
217 }
218
224 public function getUsername()
225 {
226 $username = $this->safeStorage->retrieveSafely('username');
227
228 return $username !== null ? $username : 'anonymous';
229 }
230
238 public function setUsername($username)
239 {
240 $this->safeStorage->storeSafely('username', $username);
241
242 return $this;
243 }
244
250 public function getPassword()
251 {
252 return $this->safeStorage->retrieveSafely('password');
253 }
254
262 public function setPassword($password)
263 {
264 $this->safeStorage->storeSafely('password', $password);
265
266 return $this;
267 }
268
274 public function getTimeout()
275 {
276 return $this->timeout;
277 }
278
286 public function setTimeout($timeout)
287 {
288 $this->timeout = (int) $timeout;
289
290 return $this;
291 }
292
298 public function getSystemType()
299 {
300 return $this->systemType;
301 }
302
310 public function setSystemType($systemType)
311 {
312 $this->systemType = strtolower($systemType);
313
314 return $this;
315 }
316
320 public function listContents($directory = '', $recursive = false)
321 {
322 return $this->listDirectoryContents($directory, $recursive);
323 }
324
325 abstract protected function listDirectoryContents($directory, $recursive = false);
326
335 protected function normalizeListing(array $listing, $prefix = '')
336 {
337 $base = $prefix;
338 $result = [];
339 $listing = $this->removeDotDirectories($listing);
340
341 while ($item = array_shift($listing)) {
342 if (preg_match('#^.*:$#', $item)) {
343 $base = trim($item, ':');
344 continue;
345 }
346
347 $result[] = $this->normalizeObject($item, $base);
348 }
349
350 return $this->sortListing($result);
351 }
352
360 protected function sortListing(array $result)
361 {
362 $compare = function ($one, $two) {
363 return strnatcmp($one['path'], $two['path']);
364 };
365
366 usort($result, $compare);
367
368 return $result;
369 }
370
381 protected function normalizeObject($item, $base)
382 {
383 $systemType = $this->systemType ?: $this->detectSystemType($item);
384
385 if ($systemType === 'unix') {
386 return $this->normalizeUnixObject($item, $base);
387 } elseif ($systemType === 'windows') {
388 return $this->normalizeWindowsObject($item, $base);
389 }
390
392 }
393
402 protected function normalizeUnixObject($item, $base)
403 {
404 $item = preg_replace('#\s+#', ' ', trim($item), 7);
405
406 if (count(explode(' ', $item, 9)) !== 9) {
407 throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts.");
408 }
409
410 list($permissions, /* $number */, /* $owner */, /* $group */, $size, /* $month */, /* $day */, /* $time*/, $name) = explode(' ', $item, 9);
411 $type = $this->detectType($permissions);
412 $path = empty($base) ? $name : $base . $this->separator . $name;
413
414 if ($type === 'dir') {
415 return compact('type', 'path');
416 }
417
418 $permissions = $this->normalizePermissions($permissions);
420 $size = (int) $size;
421
422 return compact('type', 'path', 'visibility', 'size');
423 }
424
433 protected function normalizeWindowsObject($item, $base)
434 {
435 $item = preg_replace('#\s+#', ' ', trim($item), 3);
436
437 if (count(explode(' ', $item, 4)) !== 4) {
438 throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts.");
439 }
440
441 list($date, $time, $size, $name) = explode(' ', $item, 4);
442 $path = empty($base) ? $name : $base . $this->separator . $name;
443
444 // Check for the correct date/time format
445 $format = strlen($date) === 8 ? 'm-d-yH:iA' : 'Y-m-dH:i';
446 $dt = DateTime::createFromFormat($format, $date . $time);
447 $timestamp = $dt ? $dt->getTimestamp() : (int) strtotime("$date $time");
448
449 if ($size === '<DIR>') {
450 $type = 'dir';
451
452 return compact('type', 'path', 'timestamp');
453 }
454
455 $type = 'file';
457 $size = (int) $size;
458
459 return compact('type', 'path', 'visibility', 'size', 'timestamp');
460 }
461
469 protected function detectSystemType($item)
470 {
471 return preg_match('/^[0-9]{2,4}-[0-9]{2}-[0-9]{2}/', $item) ? 'windows' : 'unix';
472 }
473
481 protected function detectType($permissions)
482 {
483 return substr($permissions, 0, 1) === 'd' ? 'dir' : 'file';
484 }
485
493 protected function normalizePermissions($permissions)
494 {
495 // remove the type identifier
496 $permissions = substr($permissions, 1);
497
498 // map the string rights to the numeric counterparts
499 $map = ['-' => '0', 'r' => '4', 'w' => '2', 'x' => '1'];
500 $permissions = strtr($permissions, $map);
501
502 // split up the permission groups
503 $parts = str_split($permissions, 3);
504
505 // convert the groups
506 $mapper = function ($part) {
507 return array_sum(str_split($part));
508 };
509
510 // get the sum of the groups
511 return array_sum(array_map($mapper, $parts));
512 }
513
521 public function removeDotDirectories(array $list)
522 {
523 $filter = function ($line) {
524 if ( ! empty($line) && ! preg_match('#.* \.(\.)?$|^total#', $line)) {
525 return true;
526 }
527
528 return false;
529 };
530
531 return array_filter($list, $filter);
532 }
533
537 public function has($path)
538 {
539 return $this->getMetadata($path);
540 }
541
545 public function getSize($path)
546 {
547 return $this->getMetadata($path);
548 }
549
553 public function getVisibility($path)
554 {
555 return $this->getMetadata($path);
556 }
557
563 public function ensureDirectory($dirname)
564 {
565 if ( ! empty($dirname) && ! $this->has($dirname)) {
566 $this->createDir($dirname, new Config());
567 }
568 }
569
573 public function getConnection()
574 {
575 $tries = 0;
576
577 while ( ! $this->isConnected() && $tries < 3) {
578 $tries++;
579 $this->disconnect();
580 $this->connect();
581 }
582
583 return $this->connection;
584 }
585
591 public function getPermPublic()
592 {
593 return $this->permPublic;
594 }
595
601 public function getPermPrivate()
602 {
603 return $this->permPrivate;
604 }
605
609 public function __destruct()
610 {
611 $this->disconnect();
612 }
613
617 abstract public function connect();
618
622 abstract public function disconnect();
623
629 abstract public function isConnected();
630}
$result
$size
Definition: RandomTest.php:84
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
An exception for terminatinating execution or to throw for unit testing.
normalizeListing(array $listing, $prefix='')
Normalize a directory listing.
getRoot()
Returns the root folder to work from.
sortListing(array $result)
Sort a directory listing.
normalizePermissions($permissions)
Normalize a permissions string.
setTimeout($timeout)
Set the amount of seconds before the connection should timeout.
setSystemType($systemType)
Set the FTP system type (windows or unix).
listContents($directory='', $recursive=false)
List contents of a directory.array
ensureDirectory($dirname)
Ensure a directory exists.
getTimeout()
Returns the amount of seconds before the connection will timeout.
getVisibility($path)
Get the visibility of a file.array|false
getSize($path)
Get the size of a file.array|false
getPermPublic()
Get the public permission value.
removeDotDirectories(array $list)
Filter out dot-directories.
setRoot($root)
Set the root folder to work from.
getPermPrivate()
Get the private permission value.
listDirectoryContents($directory, $recursive=false)
setPermPrivate($permPrivate)
Set the private permission value.
has($path)
Check whether a file exists.array|bool|null
setPermPublic($permPublic)
Set the public permission value.
detectType($permissions)
Get the file type from the permissions.
isConnected()
Check if a connection is active.
setPassword($password)
Set the ftp password.
detectSystemType($item)
Get the system type from a listing item.
normalizeWindowsObject($item, $base)
Normalize a Windows/DOS file entry.
normalizeUnixObject($item, $base)
Normalize a Unix file entry.
normalizeObject($item, $base)
Normalize a file entry.
static forFtpSystemType($systemType)
Create a new exception for a link.
const VISIBILITY_PUBLIC
@const VISIBILITY_PUBLIC public visibility
createDir($dirname, Config $config)
Create a directory.
const VISIBILITY_PRIVATE
@const VISIBILITY_PRIVATE private visibility
getMetadata($path)
Get all the meta data of a file or directory.
$base
Definition: index.php:4
$time
Definition: cron.php:21
if($format !==null) $name
Definition: metadata.php:146
$format
Definition: metadata.php:141
$type
$password
Definition: pwgen.php:17
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41