CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.8 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.8
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
      • Validator
    • Network
      • Email
      • Http
    • Routing
      • Filter
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper
  • None

Classes

  • CakeNumber
  • CakeText
  • CakeTime
  • ClassRegistry
  • Debugger
  • File
  • Folder
  • Hash
  • Inflector
  • ObjectCollection
  • Sanitize
  • Security
  • Set
  • String
  • Validation
  • Xml
  1: <?php
  2: /**
  3:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4:  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5:  *
  6:  * Licensed under The MIT License
  7:  * For full copyright and license information, please see the LICENSE.txt
  8:  * Redistributions of files must retain the above copyright notice.
  9:  *
 10:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 11:  * @link          http://cakephp.org CakePHP(tm) Project
 12:  * @package       Cake.Utility
 13:  * @since         CakePHP(tm) v 0.2.9
 14:  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 15:  */
 16: 
 17: /**
 18:  * Folder structure browser, lists folders and files.
 19:  * Provides an Object interface for Common directory related tasks.
 20:  *
 21:  * @package       Cake.Utility
 22:  */
 23: class Folder {
 24: 
 25: /**
 26:  * Default scheme for Folder::copy
 27:  * Recursively merges subfolders with the same name
 28:  *
 29:  * @var string
 30:  */
 31:     const MERGE = 'merge';
 32: 
 33: /**
 34:  * Overwrite scheme for Folder::copy
 35:  * subfolders with the same name will be replaced
 36:  *
 37:  * @var string
 38:  */
 39:     const OVERWRITE = 'overwrite';
 40: 
 41: /**
 42:  * Skip scheme for Folder::copy
 43:  * if a subfolder with the same name exists it will be skipped
 44:  *
 45:  * @var string
 46:  */
 47:     const SKIP = 'skip';
 48: 
 49: /**
 50:  * Sort mode by name
 51:  */
 52:     const SORT_NAME = 'name';
 53: 
 54: /**
 55:  * Sort mode by time
 56:  */
 57:     const SORT_TIME = 'time';
 58: 
 59: /**
 60:  * Path to Folder.
 61:  *
 62:  * @var string
 63:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::$path
 64:  */
 65:     public $path = null;
 66: 
 67: /**
 68:  * Sortedness. Whether or not list results
 69:  * should be sorted by name.
 70:  *
 71:  * @var bool
 72:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::$sort
 73:  */
 74:     public $sort = false;
 75: 
 76: /**
 77:  * Mode to be used on create. Does nothing on Windows platforms.
 78:  *
 79:  * @var int
 80:  * http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::$mode
 81:  */
 82:     public $mode = 0755;
 83: 
 84: /**
 85:  * Functions array to be called depending on the sort type chosen.
 86:  */
 87:     protected $_fsorts = array(
 88:         self::SORT_NAME => 'getPathname',
 89:         self::SORT_TIME => 'getCTime'
 90:     );
 91: 
 92: /**
 93:  * Holds messages from last method.
 94:  *
 95:  * @var array
 96:  */
 97:     protected $_messages = array();
 98: 
 99: /**
100:  * Holds errors from last method.
101:  *
102:  * @var array
103:  */
104:     protected $_errors = array();
105: 
106: /**
107:  * Holds array of complete directory paths.
108:  *
109:  * @var array
110:  */
111:     protected $_directories;
112: 
113: /**
114:  * Holds array of complete file paths.
115:  *
116:  * @var array
117:  */
118:     protected $_files;
119: 
120: /**
121:  * Constructor.
122:  *
123:  * @param string $path Path to folder
124:  * @param bool $create Create folder if not found
125:  * @param string|bool $mode Mode (CHMOD) to apply to created folder, false to ignore
126:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder
127:  */
128:     public function __construct($path = false, $create = false, $mode = false) {
129:         if (empty($path)) {
130:             $path = TMP;
131:         }
132:         if ($mode) {
133:             $this->mode = $mode;
134:         }
135: 
136:         if (!file_exists($path) && $create === true) {
137:             $this->create($path, $this->mode);
138:         }
139:         if (!Folder::isAbsolute($path)) {
140:             $path = realpath($path);
141:         }
142:         if (!empty($path)) {
143:             $this->cd($path);
144:         }
145:     }
146: 
147: /**
148:  * Return current path.
149:  *
150:  * @return string Current path
151:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::pwd
152:  */
153:     public function pwd() {
154:         return $this->path;
155:     }
156: 
157: /**
158:  * Change directory to $path.
159:  *
160:  * @param string $path Path to the directory to change to
161:  * @return string The new path. Returns false on failure
162:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::cd
163:  */
164:     public function cd($path) {
165:         $path = $this->realpath($path);
166:         if (is_dir($path)) {
167:             return $this->path = $path;
168:         }
169:         return false;
170:     }
171: 
172: /**
173:  * Returns an array of the contents of the current directory.
174:  * The returned array holds two arrays: One of directories and one of files.
175:  *
176:  * @param string|bool $sort Whether you want the results sorted, set this and the sort property
177:  *   to false to get unsorted results.
178:  * @param array|bool $exceptions Either an array or boolean true will not grab dot files
179:  * @param bool $fullPath True returns the full path
180:  * @return mixed Contents of current directory as an array, an empty array on failure
181:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::read
182:  */
183:     public function read($sort = self::SORT_NAME, $exceptions = false, $fullPath = false) {
184:         $dirs = $files = array();
185: 
186:         if (!$this->pwd()) {
187:             return array($dirs, $files);
188:         }
189:         if (is_array($exceptions)) {
190:             $exceptions = array_flip($exceptions);
191:         }
192:         $skipHidden = isset($exceptions['.']) || $exceptions === true;
193: 
194:         try {
195:             $iterator = new DirectoryIterator($this->path);
196:         } catch (Exception $e) {
197:             return array($dirs, $files);
198:         }
199:         if (!is_bool($sort) && isset($this->_fsorts[$sort])) {
200:             $methodName = $this->_fsorts[$sort];
201:         } else {
202:             $methodName = $this->_fsorts[self::SORT_NAME];
203:         }
204: 
205:         foreach ($iterator as $item) {
206:             if ($item->isDot()) {
207:                 continue;
208:             }
209:             $name = $item->getFileName();
210:             if ($skipHidden && $name[0] === '.' || isset($exceptions[$name])) {
211:                 continue;
212:             }
213:             if ($fullPath) {
214:                 $name = $item->getPathName();
215:             }
216:             if ($item->isDir()) {
217:                 $dirs[$item->{$methodName}()][] = $name;
218:             } else {
219:                 $files[$item->{$methodName}()][] = $name;
220:             }
221:         }
222: 
223:         if ($sort || $this->sort) {
224:             ksort($dirs);
225:             ksort($files);
226:         }
227: 
228:         if ($dirs) {
229:             $dirs = call_user_func_array('array_merge', $dirs);
230:         }
231:         if ($files) {
232:             $files = call_user_func_array('array_merge', $files);
233:         }
234:         return array($dirs, $files);
235:     }
236: 
237: /**
238:  * Returns an array of all matching files in current directory.
239:  *
240:  * @param string $regexpPattern Preg_match pattern (Defaults to: .*)
241:  * @param bool $sort Whether results should be sorted.
242:  * @return array Files that match given pattern
243:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::find
244:  */
245:     public function find($regexpPattern = '.*', $sort = false) {
246:         list(, $files) = $this->read($sort);
247:         return array_values(preg_grep('/^' . $regexpPattern . '$/i', $files));
248:     }
249: 
250: /**
251:  * Returns an array of all matching files in and below current directory.
252:  *
253:  * @param string $pattern Preg_match pattern (Defaults to: .*)
254:  * @param bool $sort Whether results should be sorted.
255:  * @return array Files matching $pattern
256:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::findRecursive
257:  */
258:     public function findRecursive($pattern = '.*', $sort = false) {
259:         if (!$this->pwd()) {
260:             return array();
261:         }
262:         $startsOn = $this->path;
263:         $out = $this->_findRecursive($pattern, $sort);
264:         $this->cd($startsOn);
265:         return $out;
266:     }
267: 
268: /**
269:  * Private helper function for findRecursive.
270:  *
271:  * @param string $pattern Pattern to match against
272:  * @param bool $sort Whether results should be sorted.
273:  * @return array Files matching pattern
274:  */
275:     protected function _findRecursive($pattern, $sort = false) {
276:         list($dirs, $files) = $this->read($sort);
277:         $found = array();
278: 
279:         foreach ($files as $file) {
280:             if (preg_match('/^' . $pattern . '$/i', $file)) {
281:                 $found[] = Folder::addPathElement($this->path, $file);
282:             }
283:         }
284:         $start = $this->path;
285: 
286:         foreach ($dirs as $dir) {
287:             $this->cd(Folder::addPathElement($start, $dir));
288:             $found = array_merge($found, $this->findRecursive($pattern, $sort));
289:         }
290:         return $found;
291:     }
292: 
293: /**
294:  * Returns true if given $path is a Windows path.
295:  *
296:  * @param string $path Path to check
297:  * @return bool true if Windows path, false otherwise
298:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::isWindowsPath
299:  */
300:     public static function isWindowsPath($path) {
301:         return (preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) === '\\\\');
302:     }
303: 
304: /**
305:  * Returns true if given $path is an absolute path.
306:  *
307:  * @param string $path Path to check
308:  * @return bool true if path is absolute.
309:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::isAbsolute
310:  */
311:     public static function isAbsolute($path) {
312:         if (empty($path)) {
313:             return false;
314:         }
315: 
316:         return $path[0] === '/' ||
317:             preg_match('/^[A-Z]:\\\\/i', $path) ||
318:             substr($path, 0, 2) === '\\\\' ||
319:             static::isRegisteredStreamWrapper($path);
320:     }
321: 
322: /**
323:  * Returns true if given $path is a registered stream wrapper.
324:  *
325:  * @param string $path Path to check
326:  * @return boo true If path is registered stream wrapper.
327:  */
328:     public static function isRegisteredStreamWrapper($path) {
329:         if (preg_match('/^[A-Z]+(?=:\/\/)/i', $path, $matches) &&
330:             in_array($matches[0], stream_get_wrappers())
331:         ) {
332:             return true;
333:         }
334:         return false;
335:     }
336: 
337: /**
338:  * Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.)
339:  *
340:  * @param string $path Path to check
341:  * @return string Set of slashes ("\\" or "/")
342:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::normalizePath
343:  */
344:     public static function normalizePath($path) {
345:         return Folder::correctSlashFor($path);
346:     }
347: 
348: /**
349:  * Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.)
350:  *
351:  * @param string $path Path to check
352:  * @return string Set of slashes ("\\" or "/")
353:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::correctSlashFor
354:  */
355:     public static function correctSlashFor($path) {
356:         return (Folder::isWindowsPath($path)) ? '\\' : '/';
357:     }
358: 
359: /**
360:  * Returns $path with added terminating slash (corrected for Windows or other OS).
361:  *
362:  * @param string $path Path to check
363:  * @return string Path with ending slash
364:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::slashTerm
365:  */
366:     public static function slashTerm($path) {
367:         if (Folder::isSlashTerm($path)) {
368:             return $path;
369:         }
370:         return $path . Folder::correctSlashFor($path);
371:     }
372: 
373: /**
374:  * Returns $path with $element added, with correct slash in-between.
375:  *
376:  * @param string $path Path
377:  * @param string|array $element Element to add at end of path
378:  * @return string Combined path
379:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::addPathElement
380:  */
381:     public static function addPathElement($path, $element) {
382:         $element = (array)$element;
383:         array_unshift($element, rtrim($path, DS));
384:         return implode(DS, $element);
385:     }
386: 
387: /**
388:  * Returns true if the Folder is in the given Cake path.
389:  *
390:  * @param string $path The path to check.
391:  * @return bool
392:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::inCakePath
393:  */
394:     public function inCakePath($path = '') {
395:         $dir = substr(Folder::slashTerm(ROOT), 0, -1);
396:         $newdir = $dir . $path;
397: 
398:         return $this->inPath($newdir);
399:     }
400: 
401: /**
402:  * Returns true if the Folder is in the given path.
403:  *
404:  * @param string $path The absolute path to check that the current `pwd()` resides within.
405:  * @param bool $reverse Reverse the search, check if the given `$path` resides within the current `pwd()`.
406:  * @return bool
407:  * @throws \InvalidArgumentException When the given `$path` argument is not an absolute path.
408:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::inPath
409:  */
410:     public function inPath($path = '', $reverse = false) {
411:         if (!Folder::isAbsolute($path)) {
412:             throw new InvalidArgumentException(__d('cake_dev', 'The $path argument is expected to be an absolute path.'));
413:         }
414: 
415:         $dir = Folder::slashTerm($path);
416:         $current = Folder::slashTerm($this->pwd());
417: 
418:         if (!$reverse) {
419:             $return = preg_match('/^' . preg_quote($dir, '/') . '(.*)/', $current);
420:         } else {
421:             $return = preg_match('/^' . preg_quote($current, '/') . '(.*)/', $dir);
422:         }
423:         return (bool)$return;
424:     }
425: 
426: /**
427:  * Change the mode on a directory structure recursively. This includes changing the mode on files as well.
428:  *
429:  * @param string $path The path to chmod.
430:  * @param int $mode Octal value, e.g. 0755.
431:  * @param bool $recursive Chmod recursively, set to false to only change the current directory.
432:  * @param array $exceptions Array of files, directories to skip.
433:  * @return bool Success.
434:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::chmod
435:  */
436:     public function chmod($path, $mode = false, $recursive = true, $exceptions = array()) {
437:         if (!$mode) {
438:             $mode = $this->mode;
439:         }
440: 
441:         if ($recursive === false && is_dir($path)) {
442:             //@codingStandardsIgnoreStart
443:             if (@chmod($path, intval($mode, 8))) {
444:                 //@codingStandardsIgnoreEnd
445:                 $this->_messages[] = __d('cake_dev', '%s changed to %s', $path, $mode);
446:                 return true;
447:             }
448: 
449:             $this->_errors[] = __d('cake_dev', '%s NOT changed to %s', $path, $mode);
450:             return false;
451:         }
452: 
453:         if (is_dir($path)) {
454:             $paths = $this->tree($path);
455: 
456:             foreach ($paths as $type) {
457:                 foreach ($type as $fullpath) {
458:                     $check = explode(DS, $fullpath);
459:                     $count = count($check);
460: 
461:                     if (in_array($check[$count - 1], $exceptions)) {
462:                         continue;
463:                     }
464: 
465:                     //@codingStandardsIgnoreStart
466:                     if (@chmod($fullpath, intval($mode, 8))) {
467:                         //@codingStandardsIgnoreEnd
468:                         $this->_messages[] = __d('cake_dev', '%s changed to %s', $fullpath, $mode);
469:                     } else {
470:                         $this->_errors[] = __d('cake_dev', '%s NOT changed to %s', $fullpath, $mode);
471:                     }
472:                 }
473:             }
474: 
475:             if (empty($this->_errors)) {
476:                 return true;
477:             }
478:         }
479:         return false;
480:     }
481: 
482: /**
483:  * Returns an array of nested directories and files in each directory
484:  *
485:  * @param string $path the directory path to build the tree from
486:  * @param array|bool $exceptions Either an array of files/folder to exclude
487:  *   or boolean true to not grab dot files/folders
488:  * @param string $type either 'file' or 'dir'. null returns both files and directories
489:  * @return mixed array of nested directories and files in each directory
490:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::tree
491:  */
492:     public function tree($path = null, $exceptions = false, $type = null) {
493:         if (!$path) {
494:             $path = $this->path;
495:         }
496:         $files = array();
497:         $directories = array($path);
498: 
499:         if (is_array($exceptions)) {
500:             $exceptions = array_flip($exceptions);
501:         }
502:         $skipHidden = false;
503:         if ($exceptions === true) {
504:             $skipHidden = true;
505:         } elseif (isset($exceptions['.'])) {
506:             $skipHidden = true;
507:             unset($exceptions['.']);
508:         }
509: 
510:         try {
511:             $directory = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME | RecursiveDirectoryIterator::CURRENT_AS_SELF);
512:             $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST);
513:         } catch (Exception $e) {
514:             if ($type === null) {
515:                 return array(array(), array());
516:             }
517:             return array();
518:         }
519: 
520:         foreach ($iterator as $itemPath => $fsIterator) {
521:             if ($skipHidden) {
522:                 $subPathName = $fsIterator->getSubPathname();
523:                 if ($subPathName{0} === '.' || strpos($subPathName, DS . '.') !== false) {
524:                     continue;
525:                 }
526:             }
527:             $item = $fsIterator->current();
528:             if (!empty($exceptions) && isset($exceptions[$item->getFilename()])) {
529:                 continue;
530:             }
531: 
532:             if ($item->isFile()) {
533:                 $files[] = $itemPath;
534:             } elseif ($item->isDir() && !$item->isDot()) {
535:                 $directories[] = $itemPath;
536:             }
537:         }
538:         if ($type === null) {
539:             return array($directories, $files);
540:         }
541:         if ($type === 'dir') {
542:             return $directories;
543:         }
544:         return $files;
545:     }
546: 
547: /**
548:  * Create a directory structure recursively.
549:  *
550:  * Can be used to create deep path structures like `/foo/bar/baz/shoe/horn`
551:  *
552:  * @param string $pathname The directory structure to create. Either an absolute or relative
553:  *   path. If the path is relative and exists in the process' cwd it will not be created.
554:  *   Otherwise relative paths will be prefixed with the current pwd().
555:  * @param int $mode octal value 0755
556:  * @return bool Returns TRUE on success, FALSE on failure
557:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::create
558:  */
559:     public function create($pathname, $mode = false) {
560:         if (is_dir($pathname) || empty($pathname)) {
561:             return true;
562:         }
563: 
564:         if (!static::isAbsolute($pathname)) {
565:             $pathname = static::addPathElement($this->pwd(), $pathname);
566:         }
567: 
568:         if (!$mode) {
569:             $mode = $this->mode;
570:         }
571: 
572:         if (is_file($pathname)) {
573:             $this->_errors[] = __d('cake_dev', '%s is a file', $pathname);
574:             return false;
575:         }
576:         $pathname = rtrim($pathname, DS);
577:         $nextPathname = substr($pathname, 0, strrpos($pathname, DS));
578: 
579:         if ($this->create($nextPathname, $mode)) {
580:             if (!file_exists($pathname)) {
581:                 $old = umask(0);
582:                 if (mkdir($pathname, $mode)) {
583:                     umask($old);
584:                     $this->_messages[] = __d('cake_dev', '%s created', $pathname);
585:                     return true;
586:                 }
587:                 umask($old);
588:                 $this->_errors[] = __d('cake_dev', '%s NOT created', $pathname);
589:                 return false;
590:             }
591:         }
592:         return false;
593:     }
594: 
595: /**
596:  * Returns the size in bytes of this Folder and its contents.
597:  *
598:  * @return int size in bytes of current folder
599:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::dirsize
600:  */
601:     public function dirsize() {
602:         $size = 0;
603:         $directory = Folder::slashTerm($this->path);
604:         $stack = array($directory);
605:         $count = count($stack);
606:         for ($i = 0, $j = $count; $i < $j; ++$i) {
607:             if (is_file($stack[$i])) {
608:                 $size += filesize($stack[$i]);
609:             } elseif (is_dir($stack[$i])) {
610:                 $dir = dir($stack[$i]);
611:                 if ($dir) {
612:                     while (false !== ($entry = $dir->read())) {
613:                         if ($entry === '.' || $entry === '..') {
614:                             continue;
615:                         }
616:                         $add = $stack[$i] . $entry;
617: 
618:                         if (is_dir($stack[$i] . $entry)) {
619:                             $add = Folder::slashTerm($add);
620:                         }
621:                         $stack[] = $add;
622:                     }
623:                     $dir->close();
624:                 }
625:             }
626:             $j = count($stack);
627:         }
628:         return $size;
629:     }
630: 
631: /**
632:  * Recursively Remove directories if the system allows.
633:  *
634:  * @param string $path Path of directory to delete
635:  * @return bool Success
636:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::delete
637:  */
638:     public function delete($path = null) {
639:         if (!$path) {
640:             $path = $this->pwd();
641:         }
642:         if (!$path) {
643:             return false;
644:         }
645:         $path = Folder::slashTerm($path);
646:         if (is_dir($path)) {
647:             try {
648:                 $directory = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::CURRENT_AS_SELF);
649:                 $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::CHILD_FIRST);
650:             } catch (Exception $e) {
651:                 return false;
652:             }
653: 
654:             foreach ($iterator as $item) {
655:                 $filePath = $item->getPathname();
656:                 if ($item->isFile() || $item->isLink()) {
657:                     //@codingStandardsIgnoreStart
658:                     if (@unlink($filePath)) {
659:                         //@codingStandardsIgnoreEnd
660:                         $this->_messages[] = __d('cake_dev', '%s removed', $filePath);
661:                     } else {
662:                         $this->_errors[] = __d('cake_dev', '%s NOT removed', $filePath);
663:                     }
664:                 } elseif ($item->isDir() && !$item->isDot()) {
665:                     //@codingStandardsIgnoreStart
666:                     if (@rmdir($filePath)) {
667:                         //@codingStandardsIgnoreEnd
668:                         $this->_messages[] = __d('cake_dev', '%s removed', $filePath);
669:                     } else {
670:                         $this->_errors[] = __d('cake_dev', '%s NOT removed', $filePath);
671:                         return false;
672:                     }
673:                 }
674:             }
675: 
676:             $path = rtrim($path, DS);
677:             //@codingStandardsIgnoreStart
678:             if (@rmdir($path)) {
679:                 //@codingStandardsIgnoreEnd
680:                 $this->_messages[] = __d('cake_dev', '%s removed', $path);
681:             } else {
682:                 $this->_errors[] = __d('cake_dev', '%s NOT removed', $path);
683:                 return false;
684:             }
685:         }
686:         return true;
687:     }
688: 
689: /**
690:  * Recursive directory copy.
691:  *
692:  * ### Options
693:  *
694:  * - `to` The directory to copy to.
695:  * - `from` The directory to copy from, this will cause a cd() to occur, changing the results of pwd().
696:  * - `mode` The mode to copy the files/directories with as integer, e.g. 0775.
697:  * - `skip` Files/directories to skip.
698:  * - `scheme` Folder::MERGE, Folder::OVERWRITE, Folder::SKIP
699:  *
700:  * @param array|string $options Either an array of options (see above) or a string of the destination directory.
701:  * @return bool Success.
702:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::copy
703:  */
704:     public function copy($options) {
705:         if (!$this->pwd()) {
706:             return false;
707:         }
708:         $to = null;
709:         if (is_string($options)) {
710:             $to = $options;
711:             $options = array();
712:         }
713:         $options += array(
714:             'to' => $to,
715:             'from' => $this->path,
716:             'mode' => $this->mode,
717:             'skip' => array(),
718:             'scheme' => Folder::MERGE
719:         );
720: 
721:         $fromDir = $options['from'];
722:         $toDir = $options['to'];
723:         $mode = $options['mode'];
724: 
725:         if (!$this->cd($fromDir)) {
726:             $this->_errors[] = __d('cake_dev', '%s not found', $fromDir);
727:             return false;
728:         }
729: 
730:         if (!is_dir($toDir)) {
731:             $this->create($toDir, $mode);
732:         }
733: 
734:         if (!is_writable($toDir)) {
735:             $this->_errors[] = __d('cake_dev', '%s not writable', $toDir);
736:             return false;
737:         }
738: 
739:         $exceptions = array_merge(array('.', '..', '.svn'), $options['skip']);
740:         //@codingStandardsIgnoreStart
741:         if ($handle = @opendir($fromDir)) {
742:             //@codingStandardsIgnoreEnd
743:             while (($item = readdir($handle)) !== false) {
744:                 $to = Folder::addPathElement($toDir, $item);
745:                 if (($options['scheme'] != Folder::SKIP || !is_dir($to)) && !in_array($item, $exceptions)) {
746:                     $from = Folder::addPathElement($fromDir, $item);
747:                     if (is_file($from) && (!is_file($to) || $options['scheme'] != Folder::SKIP)) {
748:                         if (copy($from, $to)) {
749:                             chmod($to, intval($mode, 8));
750:                             touch($to, filemtime($from));
751:                             $this->_messages[] = __d('cake_dev', '%s copied to %s', $from, $to);
752:                         } else {
753:                             $this->_errors[] = __d('cake_dev', '%s NOT copied to %s', $from, $to);
754:                         }
755:                     }
756: 
757:                     if (is_dir($from) && file_exists($to) && $options['scheme'] === Folder::OVERWRITE) {
758:                         $this->delete($to);
759:                     }
760: 
761:                     if (is_dir($from) && !file_exists($to)) {
762:                         $old = umask(0);
763:                         if (mkdir($to, $mode)) {
764:                             umask($old);
765:                             $old = umask(0);
766:                             chmod($to, $mode);
767:                             umask($old);
768:                             $this->_messages[] = __d('cake_dev', '%s created', $to);
769:                             $options = array('to' => $to, 'from' => $from) + $options;
770:                             $this->copy($options);
771:                         } else {
772:                             $this->_errors[] = __d('cake_dev', '%s not created', $to);
773:                         }
774:                     } elseif (is_dir($from) && $options['scheme'] === Folder::MERGE) {
775:                         $options = array('to' => $to, 'from' => $from) + $options;
776:                         $this->copy($options);
777:                     }
778:                 }
779:             }
780:             closedir($handle);
781:         } else {
782:             return false;
783:         }
784: 
785:         if (!empty($this->_errors)) {
786:             return false;
787:         }
788:         return true;
789:     }
790: 
791: /**
792:  * Recursive directory move.
793:  *
794:  * ### Options
795:  *
796:  * - `to` The directory to copy to.
797:  * - `from` The directory to copy from, this will cause a cd() to occur, changing the results of pwd().
798:  * - `chmod` The mode to copy the files/directories with.
799:  * - `skip` Files/directories to skip.
800:  * - `scheme` Folder::MERGE, Folder::OVERWRITE, Folder::SKIP
801:  *
802:  * @param array $options (to, from, chmod, skip, scheme)
803:  * @return bool Success
804:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::move
805:  */
806:     public function move($options) {
807:         $to = null;
808:         if (is_string($options)) {
809:             $to = $options;
810:             $options = (array)$options;
811:         }
812:         $options += array('to' => $to, 'from' => $this->path, 'mode' => $this->mode, 'skip' => array());
813: 
814:         if ($this->copy($options)) {
815:             if ($this->delete($options['from'])) {
816:                 return (bool)$this->cd($options['to']);
817:             }
818:         }
819:         return false;
820:     }
821: 
822: /**
823:  * get messages from latest method
824:  *
825:  * @param bool $reset Reset message stack after reading
826:  * @return array
827:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::messages
828:  */
829:     public function messages($reset = true) {
830:         $messages = $this->_messages;
831:         if ($reset) {
832:             $this->_messages = array();
833:         }
834:         return $messages;
835:     }
836: 
837: /**
838:  * get error from latest method
839:  *
840:  * @param bool $reset Reset error stack after reading
841:  * @return array
842:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::errors
843:  */
844:     public function errors($reset = true) {
845:         $errors = $this->_errors;
846:         if ($reset) {
847:             $this->_errors = array();
848:         }
849:         return $errors;
850:     }
851: 
852: /**
853:  * Get the real path (taking ".." and such into account)
854:  *
855:  * @param string $path Path to resolve
856:  * @return string The resolved path
857:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::realpath
858:  */
859:     public function realpath($path) {
860:         if (strpos($path, '..') === false) {
861:             if (!Folder::isAbsolute($path)) {
862:                 $path = Folder::addPathElement($this->path, $path);
863:             }
864:             return $path;
865:         }
866:         $path = str_replace('/', DS, trim($path));
867:         $parts = explode(DS, $path);
868:         $newparts = array();
869:         $newpath = '';
870:         if ($path[0] === DS) {
871:             $newpath = DS;
872:         }
873: 
874:         while (($part = array_shift($parts)) !== null) {
875:             if ($part === '.' || $part === '') {
876:                 continue;
877:             }
878:             if ($part === '..') {
879:                 if (!empty($newparts)) {
880:                     array_pop($newparts);
881:                     continue;
882:                 }
883:                 return false;
884:             }
885:             $newparts[] = $part;
886:         }
887:         $newpath .= implode(DS, $newparts);
888: 
889:         return Folder::slashTerm($newpath);
890:     }
891: 
892: /**
893:  * Returns true if given $path ends in a slash (i.e. is slash-terminated).
894:  *
895:  * @param string $path Path to check
896:  * @return bool true if path ends with slash, false otherwise
897:  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::isSlashTerm
898:  */
899:     public static function isSlashTerm($path) {
900:         $lastChar = $path[strlen($path) - 1];
901:         return $lastChar === '/' || $lastChar === '\\';
902:     }
903: 
904: }
905: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs