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.2 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.2
      • 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

Classes

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