|   1:  | <?php
 | 
|   2:  |  | 
|   3:  |  | 
|   4:  |  | 
|   5:  |  | 
|   6:  |  | 
|   7:  |  | 
|   8:  |  | 
|   9:  |  | 
|  10:  |  | 
|  11:  |  | 
|  12:  |  | 
|  13:  |  | 
|  14:  |  | 
|  15:  |  | 
|  16:  |  | 
|  17:  |  | 
|  18:  | 
 | 
|  19:  | 
 | 
|  20:  |  | 
|  21:  |  | 
|  22:  |  | 
|  23:  |  | 
|  24:  |  | 
|  25:  |  | 
|  26:  |  | 
|  27:  |  | 
|  28:  |  | 
|  29:  |  | 
|  30:  |  | 
|  31:  |  | 
|  32:  |  | 
|  33:  |  | 
|  34:  |  | 
|  35:  |  | 
|  36:  |  | 
|  37:  |  | 
|  38:  |  | 
|  39:  |  | 
|  40:  |  | 
|  41:  |  | 
|  42:  | 
 | 
|  43:  | 
 | 
|  44:  |  | 
|  45:  |  | 
|  46:  |  | 
|  47:  |  | 
|  48:  |  | 
|  49:  |  | 
|  50:  |  | 
|  51:  | 
 | 
|  52:  | class XoopsFolderHandler
 | 
|  53:  | {
 | 
|  54:  |      | 
|  55:  |  | 
|  56:  |  | 
|  57:  |  | 
|  58:  |  | 
|  59:  | 
 | 
|  60:  |     public $path;
 | 
|  61:  | 
 | 
|  62:  |      | 
|  63:  |  | 
|  64:  |  | 
|  65:  |  | 
|  66:  |  | 
|  67:  | 
 | 
|  68:  |     public $sort = false;
 | 
|  69:  | 
 | 
|  70:  |      | 
|  71:  |  | 
|  72:  |  | 
|  73:  |  | 
|  74:  |  | 
|  75:  | 
 | 
|  76:  |     public $mode = '0755';
 | 
|  77:  | 
 | 
|  78:  |      | 
|  79:  |  | 
|  80:  |  | 
|  81:  |  | 
|  82:  |  | 
|  83:  | 
 | 
|  84:  |     public $messages = array();
 | 
|  85:  | 
 | 
|  86:  |      | 
|  87:  |  | 
|  88:  |  | 
|  89:  |  | 
|  90:  |  | 
|  91:  | 
 | 
|  92:  |     public $errors = array();
 | 
|  93:  | 
 | 
|  94:  |      | 
|  95:  |  | 
|  96:  |  | 
|  97:  |  | 
|  98:  |  | 
|  99:  | 
 | 
| 100:  |     public $directories;
 | 
| 101:  | 
 | 
| 102:  |      | 
| 103:  |  | 
| 104:  |  | 
| 105:  |  | 
| 106:  |  | 
| 107:  | 
 | 
| 108:  |     public $files;
 | 
| 109:  | 
 | 
| 110:  |      | 
| 111:  |  | 
| 112:  |  | 
| 113:  |  | 
| 114:  |  | 
| 115:  |  | 
| 116:  | 
 | 
| 117:  |     public function __construct($path = false, $create = true, $mode = false)
 | 
| 118:  |     {
 | 
| 119:  |         if (empty($path)) {
 | 
| 120:  |             $path = XOOPS_VAR_PATH . '/caches/xoops_cache';
 | 
| 121:  |         }
 | 
| 122:  |         if ($mode) {
 | 
| 123:  |             $this->mode = intval($mode, 8);
 | 
| 124:  |         }
 | 
| 125:  |         if (!file_exists($path) && $create == true) {
 | 
| 126:  |             $this->create($path, $this->mode);
 | 
| 127:  |         }
 | 
| 128:  |         if (!$this->isAbsolute($path)) {
 | 
| 129:  |             $path = realpath($path);
 | 
| 130:  |         }
 | 
| 131:  |         $this->cd($path);
 | 
| 132:  |     }
 | 
| 133:  | 
 | 
| 134:  |      | 
| 135:  |  | 
| 136:  |  | 
| 137:  |  | 
| 138:  |  | 
| 139:  | 
 | 
| 140:  |     public function pwd()
 | 
| 141:  |     {
 | 
| 142:  |         return $this->path;
 | 
| 143:  |     }
 | 
| 144:  | 
 | 
| 145:  |      | 
| 146:  |  | 
| 147:  |  | 
| 148:  |  | 
| 149:  |  | 
| 150:  |  | 
| 151:  |  | 
| 152:  | 
 | 
| 153:  |     public function cd($path)
 | 
| 154:  |     {
 | 
| 155:  |         $path = $this->realpath($path);
 | 
| 156:  |         if (is_string($path) && is_dir($path) && file_exists($path)) {
 | 
| 157:  |             return $this->path = $path;
 | 
| 158:  |         }
 | 
| 159:  | 
 | 
| 160:  |         return false;
 | 
| 161:  |     }
 | 
| 162:  | 
 | 
| 163:  |      | 
| 164:  |  | 
| 165:  |  | 
| 166:  |  | 
| 167:  |  | 
| 168:  |  | 
| 169:  |  | 
| 170:  |  | 
| 171:  |  | 
| 172:  | 
 | 
| 173:  |     public function read($sort = true, $exceptions = false)
 | 
| 174:  |     {
 | 
| 175:  |         $dirs = $files = array();
 | 
| 176:  |         $dir  = opendir($this->path);
 | 
| 177:  |         if ($dir !== false) {
 | 
| 178:  |             while (false !== ($n = readdir($dir))) {
 | 
| 179:  |                 $item = false;
 | 
| 180:  |                 if (is_array($exceptions)) {
 | 
| 181:  |                     if (!in_array($n, $exceptions)) {
 | 
| 182:  |                         $item = $n;
 | 
| 183:  |                     }
 | 
| 184:  |                 } else {
 | 
| 185:  |                     if ((!preg_match('/^\\.+$/', $n) && $exceptions === false) || ($exceptions === true && !preg_match('/^\\.(.*)$/', $n))) {
 | 
| 186:  |                         $item = $n;
 | 
| 187:  |                     }
 | 
| 188:  |                 }
 | 
| 189:  |                 if ($item !== false) {
 | 
| 190:  |                     if (is_dir($this->addPathElement($this->path, $item))) {
 | 
| 191:  |                         $dirs[] = $item;
 | 
| 192:  |                     } else {
 | 
| 193:  |                         $files[] = $item;
 | 
| 194:  |                     }
 | 
| 195:  |                 }
 | 
| 196:  |             }
 | 
| 197:  |             if ($sort || $this->sort) {
 | 
| 198:  |                 sort($dirs);
 | 
| 199:  |                 sort($files);
 | 
| 200:  |             }
 | 
| 201:  |             closedir($dir);
 | 
| 202:  |         }
 | 
| 203:  | 
 | 
| 204:  |         return array(
 | 
| 205:  |             $dirs,
 | 
| 206:  |             $files);
 | 
| 207:  |     }
 | 
| 208:  | 
 | 
| 209:  |      | 
| 210:  |  | 
| 211:  |  | 
| 212:  |  | 
| 213:  |  | 
| 214:  |  | 
| 215:  |  | 
| 216:  |  | 
| 217:  | 
 | 
| 218:  |     public function find($regexp_pattern = '.*', $sort = false)
 | 
| 219:  |     {
 | 
| 220:  |         $data = $this->read($sort);
 | 
| 221:  |         if (!is_array($data)) {
 | 
| 222:  |             return array();
 | 
| 223:  |         }
 | 
| 224:  |         list($dirs, $files) = $data;
 | 
| 225:  |         $found = array();
 | 
| 226:  |         foreach ($files as $file) {
 | 
| 227:  |             if (preg_match("/^{$regexp_pattern}$/i", $file)) {
 | 
| 228:  |                 $found[] = $file;
 | 
| 229:  |             }
 | 
| 230:  |         }
 | 
| 231:  | 
 | 
| 232:  |         return $found;
 | 
| 233:  |     }
 | 
| 234:  | 
 | 
| 235:  |      | 
| 236:  |  | 
| 237:  |  | 
| 238:  |  | 
| 239:  |  | 
| 240:  |  | 
| 241:  |  | 
| 242:  |  | 
| 243:  | 
 | 
| 244:  |     public function findRecursive($pattern = '.*', $sort = false)
 | 
| 245:  |     {
 | 
| 246:  |         $startsOn = $this->path;
 | 
| 247:  |         $out      = $this->_findRecursive($pattern, $sort);
 | 
| 248:  |         $this->cd($startsOn);
 | 
| 249:  | 
 | 
| 250:  |         return $out;
 | 
| 251:  |     }
 | 
| 252:  | 
 | 
| 253:  |      | 
| 254:  |  | 
| 255:  |  | 
| 256:  |  | 
| 257:  |  | 
| 258:  |  | 
| 259:  |  | 
| 260:  |  | 
| 261:  | 
 | 
| 262:  |     public function _findRecursive($pattern, $sort = false)
 | 
| 263:  |     {
 | 
| 264:  |         list($dirs, $files) = $this->read($sort);
 | 
| 265:  |         $found = array();
 | 
| 266:  |         foreach ($files as $file) {
 | 
| 267:  |             if (preg_match("/^{$pattern}$/i", $file)) {
 | 
| 268:  |                 $found[] = $this->addPathElement($this->path, $file);
 | 
| 269:  |             }
 | 
| 270:  |         }
 | 
| 271:  |         $start = $this->path;
 | 
| 272:  |         foreach ($dirs as $dir) {
 | 
| 273:  |             $this->cd($this->addPathElement($start, $dir));
 | 
| 274:  |             $newFound = $this->findRecursive($pattern);
 | 
| 275:  | 
 | 
| 276:  |             foreach ($newFound as $item) {
 | 
| 277:  |                 $found[] = $item;
 | 
| 278:  |             }
 | 
| 279:  |         }
 | 
| 280:  | 
 | 
| 281:  |         return $found;
 | 
| 282:  |     }
 | 
| 283:  | 
 | 
| 284:  |      | 
| 285:  |  | 
| 286:  |  | 
| 287:  |  | 
| 288:  |  | 
| 289:  |  | 
| 290:  |  | 
| 291:  |  | 
| 292:  | 
 | 
| 293:  |     public function isWindowsPath($path)
 | 
| 294:  |     {
 | 
| 295:  |         if (preg_match('/^[A-Z]:\\\\/i', (string)$path)) {
 | 
| 296:  |             return true;
 | 
| 297:  |         }
 | 
| 298:  | 
 | 
| 299:  |         return false;
 | 
| 300:  |     }
 | 
| 301:  | 
 | 
| 302:  |      | 
| 303:  |  | 
| 304:  |  | 
| 305:  |  | 
| 306:  |  | 
| 307:  |  | 
| 308:  |  | 
| 309:  |  | 
| 310:  | 
 | 
| 311:  |     public function isAbsolute($path)
 | 
| 312:  |     {
 | 
| 313:  |         $match = preg_match('/^\\//', $path) || preg_match('/^[A-Z]:\\//i', $path);
 | 
| 314:  | 
 | 
| 315:  |         return $match;
 | 
| 316:  |     }
 | 
| 317:  | 
 | 
| 318:  |      | 
| 319:  |  | 
| 320:  |  | 
| 321:  |  | 
| 322:  |  | 
| 323:  |  | 
| 324:  |  | 
| 325:  |  | 
| 326:  | 
 | 
| 327:  |     public function normalizePath($path)
 | 
| 328:  |     {
 | 
| 329:  |         if ($this->isWindowsPath($path)) {
 | 
| 330:  |             return '\\';
 | 
| 331:  |         }
 | 
| 332:  | 
 | 
| 333:  |         return '/';
 | 
| 334:  |     }
 | 
| 335:  | 
 | 
| 336:  |      | 
| 337:  |  | 
| 338:  |  | 
| 339:  |  | 
| 340:  |  | 
| 341:  |  | 
| 342:  |  | 
| 343:  |  | 
| 344:  | 
 | 
| 345:  |     public function correctSlashFor($path)
 | 
| 346:  |     {
 | 
| 347:  |         if ($this->isWindowsPath($path)) {
 | 
| 348:  |             return '\\';
 | 
| 349:  |         }
 | 
| 350:  | 
 | 
| 351:  |         return '/';
 | 
| 352:  |     }
 | 
| 353:  | 
 | 
| 354:  |      | 
| 355:  |  | 
| 356:  |  | 
| 357:  |  | 
| 358:  |  | 
| 359:  |  | 
| 360:  |  | 
| 361:  |  | 
| 362:  | 
 | 
| 363:  |     public function slashTerm($path)
 | 
| 364:  |     {
 | 
| 365:  |         if ($this->isSlashTerm($path)) {
 | 
| 366:  |             return $path;
 | 
| 367:  |         }
 | 
| 368:  | 
 | 
| 369:  |         return $path . $this->correctSlashFor($path);
 | 
| 370:  |     }
 | 
| 371:  | 
 | 
| 372:  |      | 
| 373:  |  | 
| 374:  |  | 
| 375:  |  | 
| 376:  |  | 
| 377:  |  | 
| 378:  |  | 
| 379:  |  | 
| 380:  |  | 
| 381:  | 
 | 
| 382:  |     public function addPathElement($path, $element)
 | 
| 383:  |     {
 | 
| 384:  |         return $this->slashTerm($path) . $element;
 | 
| 385:  |     }
 | 
| 386:  | 
 | 
| 387:  |      | 
| 388:  |  | 
| 389:  |  | 
| 390:  |  | 
| 391:  |  | 
| 392:  |  | 
| 393:  |  | 
| 394:  | 
 | 
| 395:  |     public function inXoopsPath($path = '')
 | 
| 396:  |     {
 | 
| 397:  |         $dir    = substr($this->slashTerm(XOOPS_ROOT_PATH), 0, -1);
 | 
| 398:  |         $newdir = $dir . $path;
 | 
| 399:  | 
 | 
| 400:  |         return $this->inPath($newdir);
 | 
| 401:  |     }
 | 
| 402:  | 
 | 
| 403:  |      | 
| 404:  |  | 
| 405:  |  | 
| 406:  |  | 
| 407:  |  | 
| 408:  |  | 
| 409:  |  | 
| 410:  |  | 
| 411:  | 
 | 
| 412:  |     public function inPath($path = '', $reverse = false)
 | 
| 413:  |     {
 | 
| 414:  |         $dir     = $this->slashTerm($path);
 | 
| 415:  |         $current = $this->slashTerm($this->pwd());
 | 
| 416:  |         if (!$reverse) {
 | 
| 417:  |             $return = preg_match('/^(.*)' . preg_quote($dir, '/') . '(.*)/', $current);
 | 
| 418:  |         } else {
 | 
| 419:  |             $return = preg_match('/^(.*)' . preg_quote($current, '/') . '(.*)/', $dir);
 | 
| 420:  |         }
 | 
| 421:  |         if ($return == 1) {
 | 
| 422:  |             return true;
 | 
| 423:  |         } else {
 | 
| 424:  |             return false;
 | 
| 425:  |         }
 | 
| 426:  |     }
 | 
| 427:  | 
 | 
| 428:  |      | 
| 429:  |  | 
| 430:  |  | 
| 431:  |  | 
| 432:  |  | 
| 433:  |  | 
| 434:  |  | 
| 435:  |  | 
| 436:  |  | 
| 437:  |  | 
| 438:  | 
 | 
| 439:  |     public function chmod($path, $mode = false, $recursive = true, $exceptions = array())
 | 
| 440:  |     {
 | 
| 441:  |         if (!$mode) {
 | 
| 442:  |             $mode = $this->mode;
 | 
| 443:  |         }
 | 
| 444:  |         if ($recursive === false && is_dir($path)) {
 | 
| 445:  |             if (chmod($path, intval($mode, 8))) {
 | 
| 446:  |                 $this->messages[] = sprintf('%s changed to %s', $path, $mode);
 | 
| 447:  | 
 | 
| 448:  |                 return true;
 | 
| 449:  |             } else {
 | 
| 450:  |                 $this->errors[] = sprintf('%s NOT changed to %s', $path, $mode);
 | 
| 451:  | 
 | 
| 452:  |                 return false;
 | 
| 453:  |             }
 | 
| 454:  |         }
 | 
| 455:  |         if (is_dir($path)) {
 | 
| 456:  |             list($paths) = $this->tree($path);
 | 
| 457:  |             foreach ($paths as $key => $fullpath) {
 | 
| 458:  |                 $check = explode('/', $fullpath);
 | 
| 459:  |                 $count = count($check);
 | 
| 460:  | 
 | 
| 461:  |                 if (in_array($check[$count - 1], $exceptions)) {
 | 
| 462:  |                     continue;
 | 
| 463:  |                 }
 | 
| 464:  | 
 | 
| 465:  |                 if (chmod($fullpath, intval($mode, 8))) {
 | 
| 466:  |                     $this->messages[] = sprintf('%s changed to %s', $fullpath, $mode);
 | 
| 467:  |                 } else {
 | 
| 468:  |                     $this->errors[] = sprintf('%s NOT changed to %s', $fullpath, $mode);
 | 
| 469:  |                 }
 | 
| 470:  |             }
 | 
| 471:  |             if (empty($this->errors)) {
 | 
| 472:  |                 return true;
 | 
| 473:  |             }
 | 
| 474:  |         }
 | 
| 475:  | 
 | 
| 476:  |         return false;
 | 
| 477:  |     }
 | 
| 478:  | 
 | 
| 479:  |      | 
| 480:  |  | 
| 481:  |  | 
| 482:  |  | 
| 483:  |  | 
| 484:  |  | 
| 485:  |  | 
| 486:  |  | 
| 487:  |  | 
| 488:  | 
 | 
| 489:  |     public function tree($path, $hidden = true, $type = null)
 | 
| 490:  |     {
 | 
| 491:  |         $path              = rtrim($path, '/');
 | 
| 492:  |         $this->files       = array();
 | 
| 493:  |         $this->directories = array(
 | 
| 494:  |             $path);
 | 
| 495:  |         $directories       = array();
 | 
| 496:  |         while (count($this->directories)) {
 | 
| 497:  |             $dir = array_pop($this->directories);
 | 
| 498:  |             $this->_tree($dir, $hidden);
 | 
| 499:  |             $directories[] =  $dir;
 | 
| 500:  |         }
 | 
| 501:  |         if ($type === null) {
 | 
| 502:  |             return array(
 | 
| 503:  |                 $directories,
 | 
| 504:  |                 $this->files);
 | 
| 505:  |         }
 | 
| 506:  |         if ($type === 'dir') {
 | 
| 507:  |             return $directories;
 | 
| 508:  |         }
 | 
| 509:  | 
 | 
| 510:  |         return $this->files;
 | 
| 511:  |     }
 | 
| 512:  | 
 | 
| 513:  |      | 
| 514:  |  | 
| 515:  |  | 
| 516:  |  | 
| 517:  |  | 
| 518:  |  | 
| 519:  |  | 
| 520:  |  | 
| 521:  | 
 | 
| 522:  |     public function _tree($path, $hidden)
 | 
| 523:  |     {
 | 
| 524:  |         if (is_dir($path)) {
 | 
| 525:  |             $dirHandle = opendir($path);
 | 
| 526:  |             while (false !== ($item = readdir($dirHandle))) {
 | 
| 527:  |                 $found = false;
 | 
| 528:  |                 if (($hidden === true && $item !== '.' && $item !== '..') || ($hidden === false && !preg_match('/^\\.(.*)$/', $item))) {
 | 
| 529:  |                     $found = $path . '/' . $item;
 | 
| 530:  |                 }
 | 
| 531:  |                 if ($found !== false) {
 | 
| 532:  |                     if (is_dir($found)) {
 | 
| 533:  |                         $this->directories[] =  $found;
 | 
| 534:  |                     } else {
 | 
| 535:  |                         $this->files[] =  $found;
 | 
| 536:  |                     }
 | 
| 537:  |                 }
 | 
| 538:  |             }
 | 
| 539:  |             closedir($dirHandle);
 | 
| 540:  |         }
 | 
| 541:  |     }
 | 
| 542:  | 
 | 
| 543:  |      | 
| 544:  |  | 
| 545:  |  | 
| 546:  |  | 
| 547:  |  | 
| 548:  |  | 
| 549:  |  | 
| 550:  |  | 
| 551:  | 
 | 
| 552:  |     public function create($pathname, $mode = false)
 | 
| 553:  |     {
 | 
| 554:  |         if (is_dir($pathname) || empty($pathname)) {
 | 
| 555:  |             return true;
 | 
| 556:  |         }
 | 
| 557:  |         if (!$mode) {
 | 
| 558:  |             $mode = $this->mode;
 | 
| 559:  |         }
 | 
| 560:  |         if (is_file($pathname)) {
 | 
| 561:  |             $this->errors[] = sprintf('%s is a file', $pathname);
 | 
| 562:  | 
 | 
| 563:  |             return true;
 | 
| 564:  |         }
 | 
| 565:  |         $nextPathname = substr($pathname, 0, strrpos($pathname, '/'));
 | 
| 566:  |         if ($this->create($nextPathname, $mode)) {
 | 
| 567:  |             if (!file_exists($pathname)) {
 | 
| 568:  |                 if (mkdir($pathname, intval($mode, 8))) {
 | 
| 569:  |                     $this->messages[] = sprintf('%s created', $pathname);
 | 
| 570:  | 
 | 
| 571:  |                     return true;
 | 
| 572:  |                 } else {
 | 
| 573:  |                     $this->errors[] = sprintf('%s NOT created', $pathname);
 | 
| 574:  | 
 | 
| 575:  |                     return false;
 | 
| 576:  |                 }
 | 
| 577:  |             }
 | 
| 578:  |         }
 | 
| 579:  | 
 | 
| 580:  |         return true;
 | 
| 581:  |     }
 | 
| 582:  | 
 | 
| 583:  |      | 
| 584:  |  | 
| 585:  |  | 
| 586:  |  | 
| 587:  |  | 
| 588:  | 
 | 
| 589:  |     public function dirsize()
 | 
| 590:  |     {
 | 
| 591:  |         $size      = 0;
 | 
| 592:  |         $directory = $this->slashTerm($this->path);
 | 
| 593:  |         $stack     = array($directory);
 | 
| 594:  |         $count     = count($stack);
 | 
| 595:  |         for ($i = 0, $j = $count; $i < $j; ++$i) {
 | 
| 596:  |             if (is_file($stack[$i])) {
 | 
| 597:  |                 $size += filesize($stack[$i]);
 | 
| 598:  |             } else {
 | 
| 599:  |                 if (is_dir($stack[$i])) {
 | 
| 600:  |                     $dir = dir($stack[$i]);
 | 
| 601:  |                     if ($dir) {
 | 
| 602:  |                         while (false !== ($entry = $dir->read())) {
 | 
| 603:  |                             if ($entry === '.' || $entry === '..') {
 | 
| 604:  |                                 continue;
 | 
| 605:  |                             }
 | 
| 606:  |                             $add = $stack[$i] . $entry;
 | 
| 607:  |                             if (is_dir($stack[$i] . $entry)) {
 | 
| 608:  |                                 $add = $this->slashTerm($add);
 | 
| 609:  |                             }
 | 
| 610:  |                             $stack[] = $add;
 | 
| 611:  |                         }
 | 
| 612:  |                         $dir->close();
 | 
| 613:  |                     }
 | 
| 614:  |                 }
 | 
| 615:  |             }
 | 
| 616:  |             $j = count($stack);
 | 
| 617:  |         }
 | 
| 618:  | 
 | 
| 619:  |         return $size;
 | 
| 620:  |     }
 | 
| 621:  | 
 | 
| 622:  |      | 
| 623:  |  | 
| 624:  |  | 
| 625:  |  | 
| 626:  |  | 
| 627:  |  | 
| 628:  |  | 
| 629:  | 
 | 
| 630:  |     public function delete($path)
 | 
| 631:  |     {
 | 
| 632:  |         $path = $this->slashTerm($path);
 | 
| 633:  |         if (is_dir($path) === true) {
 | 
| 634:  |             $files        = glob($path . '*', GLOB_NOSORT);
 | 
| 635:  |             $normal_files = glob($path . '*');
 | 
| 636:  |             $hidden_files = glob($path . '\.?*');
 | 
| 637:  |             $files        = array_merge($normal_files, $hidden_files);
 | 
| 638:  |             if (is_array($files)) {
 | 
| 639:  |                 foreach ($files as $file) {
 | 
| 640:  |                     if (preg_match("/(\.|\.\.)$/", $file)) {
 | 
| 641:  |                         continue;
 | 
| 642:  |                     }
 | 
| 643:  |                     if (is_file($file) === true) {
 | 
| 644:  |                         if (unlink($file)) {
 | 
| 645:  |                             $this->messages[] = sprintf('%s removed', $path);
 | 
| 646:  |                         } else {
 | 
| 647:  |                             $this->errors[] = sprintf('%s NOT removed', $path);
 | 
| 648:  |                         }
 | 
| 649:  |                     } else {
 | 
| 650:  |                         if (is_dir($file) === true) {
 | 
| 651:  |                             if ($this->delete($file) === false) {
 | 
| 652:  |                                 return false;
 | 
| 653:  |                             }
 | 
| 654:  |                         }
 | 
| 655:  |                     }
 | 
| 656:  |                 }
 | 
| 657:  |             }
 | 
| 658:  |             $path = substr($path, 0, strlen($path) - 1);
 | 
| 659:  |             if (rmdir($path) === false) {
 | 
| 660:  |                 $this->errors[] = sprintf('%s NOT removed', $path);
 | 
| 661:  | 
 | 
| 662:  |                 return false;
 | 
| 663:  |             } else {
 | 
| 664:  |                 $this->messages[] = sprintf('%s removed', $path);
 | 
| 665:  |             }
 | 
| 666:  |         }
 | 
| 667:  | 
 | 
| 668:  |         return true;
 | 
| 669:  |     }
 | 
| 670:  | 
 | 
| 671:  |      | 
| 672:  |  | 
| 673:  |  | 
| 674:  |  | 
| 675:  |  | 
| 676:  |  | 
| 677:  | 
 | 
| 678:  |     public function copy($options = array())
 | 
| 679:  |     {
 | 
| 680:  |         $to = null;
 | 
| 681:  |         if (is_string($options)) {
 | 
| 682:  |             $to      = $options;
 | 
| 683:  |             $options = array();
 | 
| 684:  |         }
 | 
| 685:  |         $options = array_merge(array(
 | 
| 686:  |                                    'to'   => $to,
 | 
| 687:  |                                    'from' => $this->path,
 | 
| 688:  |                                    'mode' => $this->mode,
 | 
| 689:  |                                    'skip' => array()), $options);
 | 
| 690:  | 
 | 
| 691:  |         $fromDir = $options['from'];
 | 
| 692:  |         $toDir   = $options['to'];
 | 
| 693:  |         $mode    = $options['mode'];
 | 
| 694:  |         if (!$this->cd($fromDir)) {
 | 
| 695:  |             $this->errors[] = sprintf('%s not found', $fromDir);
 | 
| 696:  | 
 | 
| 697:  |             return false;
 | 
| 698:  |         }
 | 
| 699:  |         if (!is_dir($toDir)) {
 | 
| 700:  |             mkdir($toDir, $mode);
 | 
| 701:  |         }
 | 
| 702:  |         if (!is_writable($toDir)) {
 | 
| 703:  |             $this->errors[] = sprintf('%s not writable', $toDir);
 | 
| 704:  | 
 | 
| 705:  |             return false;
 | 
| 706:  |         }
 | 
| 707:  |         $exceptions = array_merge(array(
 | 
| 708:  |                                       '.',
 | 
| 709:  |                                       '..',
 | 
| 710:  |                                       '.svn'), $options['skip']);
 | 
| 711:  |         $handle     = opendir($fromDir);
 | 
| 712:  |         if ($handle) {
 | 
| 713:  |             while (false !== ($item = readdir($handle))) {
 | 
| 714:  |                 if (!in_array($item, $exceptions)) {
 | 
| 715:  |                     $from = $this->addPathElement($fromDir, $item);
 | 
| 716:  |                     $to   = $this->addPathElement($toDir, $item);
 | 
| 717:  |                     if (is_file($from)) {
 | 
| 718:  |                         if (copy($from, $to)) {
 | 
| 719:  |                             chmod($to, intval($mode, 8));
 | 
| 720:  |                             touch($to, filemtime($from));
 | 
| 721:  |                             $this->messages[] = sprintf('%s copied to %s', $from, $to);
 | 
| 722:  |                         } else {
 | 
| 723:  |                             $this->errors[] = sprintf('%s NOT copied to %s', $from, $to);
 | 
| 724:  |                         }
 | 
| 725:  |                     }
 | 
| 726:  | 
 | 
| 727:  |                     if (is_dir($from)) {
 | 
| 728:  |                         if (!is_dir($to)) {
 | 
| 729:  |                             if (mkdir($to, intval($mode, 8)) || is_dir($to)) {
 | 
| 730:  |                                 chmod($to, intval($mode, 8));
 | 
| 731:  |                                 $this->messages[] = sprintf('%s created', $to);
 | 
| 732:  | 
 | 
| 733:  |                                 $options['to'] = $to;
 | 
| 734:  |                                 $options['from'] = $from;
 | 
| 735:  | 
 | 
| 736:  |                                 $this->copy($options);
 | 
| 737:  |                             } else {
 | 
| 738:  |                                 
 | 
| 739:  |                                 if (is_array($this->errors)) {
 | 
| 740:  |                                     $this->errors[] = sprintf('%s not created', $to);
 | 
| 741:  |                                 }
 | 
| 742:  |                             }
 | 
| 743:  |                         }
 | 
| 744:  |                     }
 | 
| 745:  |                 }
 | 
| 746:  |             }
 | 
| 747:  |             closedir($handle);
 | 
| 748:  |         } else {
 | 
| 749:  |             return false;
 | 
| 750:  |         }
 | 
| 751:  |         if (!empty($this->errors)) {
 | 
| 752:  |             return false;
 | 
| 753:  |         }
 | 
| 754:  | 
 | 
| 755:  |         return true;
 | 
| 756:  |     }
 | 
| 757:  | 
 | 
| 758:  |      | 
| 759:  |  | 
| 760:  |  | 
| 761:  |  | 
| 762:  |  | 
| 763:  |  | 
| 764:  |  | 
| 765:  | 
 | 
| 766:  |     public function move($options)
 | 
| 767:  |     {
 | 
| 768:  |         $to = null;
 | 
| 769:  |         if (is_string($options)) {
 | 
| 770:  |             $to      = $options;
 | 
| 771:  |             $options = (array)$options;
 | 
| 772:  |         }
 | 
| 773:  |         $options = array_merge(array(
 | 
| 774:  |                                    'to'   => $to,
 | 
| 775:  |                                    'from' => $this->path,
 | 
| 776:  |                                    'mode' => $this->mode,
 | 
| 777:  |                                    'skip' => array()), $options);
 | 
| 778:  |         if ($this->copy($options)) {
 | 
| 779:  |             if ($this->delete($options['from'])) {
 | 
| 780:  |                 return $this->cd($options['to']);
 | 
| 781:  |             }
 | 
| 782:  |         }
 | 
| 783:  | 
 | 
| 784:  |         return false;
 | 
| 785:  |     }
 | 
| 786:  | 
 | 
| 787:  |      | 
| 788:  |  | 
| 789:  |  | 
| 790:  |  | 
| 791:  |  | 
| 792:  | 
 | 
| 793:  |     public function messages()
 | 
| 794:  |     {
 | 
| 795:  |         return $this->messages;
 | 
| 796:  |     }
 | 
| 797:  | 
 | 
| 798:  |      | 
| 799:  |  | 
| 800:  |  | 
| 801:  |  | 
| 802:  |  | 
| 803:  | 
 | 
| 804:  |     public function errors()
 | 
| 805:  |     {
 | 
| 806:  |         return $this->errors;
 | 
| 807:  |     }
 | 
| 808:  | 
 | 
| 809:  |      | 
| 810:  |  | 
| 811:  |  | 
| 812:  |  | 
| 813:  |  | 
| 814:  |  | 
| 815:  | 
 | 
| 816:  |     public function realpath($path)
 | 
| 817:  |     {
 | 
| 818:  |         $path = trim($path);
 | 
| 819:  |         if (strpos($path, '..') === false) {
 | 
| 820:  |             if (!$this->isAbsolute($path)) {
 | 
| 821:  |                 $path = $this->addPathElement($this->path, $path);
 | 
| 822:  |             }
 | 
| 823:  | 
 | 
| 824:  |             return $path;
 | 
| 825:  |         }
 | 
| 826:  |         $parts    = explode('/', $path);
 | 
| 827:  |         $newparts = array();
 | 
| 828:  |         $newpath  = $path[0] === '/' ? '/' : '';
 | 
| 829:  |         while (($part = array_shift($parts)) !== null) {
 | 
| 830:  |             if ($part === '.' || $part == '') {
 | 
| 831:  |                 continue;
 | 
| 832:  |             }
 | 
| 833:  |             if ($part === '..') {
 | 
| 834:  |                 if (count($newparts) > 0) {
 | 
| 835:  |                     array_pop($newparts);
 | 
| 836:  |                     continue;
 | 
| 837:  |                 } else {
 | 
| 838:  |                     return false;
 | 
| 839:  |                 }
 | 
| 840:  |             }
 | 
| 841:  |             $newparts[] = $part;
 | 
| 842:  |         }
 | 
| 843:  |         $newpath .= implode('/', $newparts);
 | 
| 844:  |         if ((strlen($path) > 1) && $path[strlen($path) - 1] === '/') {
 | 
| 845:  |             $newpath .= '/';
 | 
| 846:  |         }
 | 
| 847:  | 
 | 
| 848:  |         return $newpath;
 | 
| 849:  |     }
 | 
| 850:  | 
 | 
| 851:  |      | 
| 852:  |  | 
| 853:  |  | 
| 854:  |  | 
| 855:  |  | 
| 856:  |  | 
| 857:  |  | 
| 858:  |  | 
| 859:  | 
 | 
| 860:  |     public function isSlashTerm($path)
 | 
| 861:  |     {
 | 
| 862:  |         if (preg_match('/[\/\\\]$/', (string)$path)) {
 | 
| 863:  |             return true;
 | 
| 864:  |         }
 | 
| 865:  | 
 | 
| 866:  |         return false;
 | 
| 867:  |     }
 | 
| 868:  | }
 | 
| 869:  |  |