XOOPS  2.6.0
folder.php
Go to the documentation of this file.
1 <?php
2 /*
3  You may not change or alter any portion of this comment or credits
4  of supporting developers from this source code or any supporting source code
5  which is considered copyrighted (c) material of the original comment or credit authors.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 */
11 /*
12  * Convenience class for handling directories.
13  *
14  *
15  * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
16  * Copyright 2005-2008, Cake Software Foundation, Inc.
17  * 1785 E. Sahara Avenue, Suite 490-204
18  * Las Vegas, Nevada 89104
19  *
20  * Licensed under The MIT License
21  * Redistributions of files must retain the above copyright notice.
22  */
23 
38 {
45  public $path = null;
46 
53  public $sort = false;
54 
61  public $mode = '0755';
62 
69  private $messages = array();
70 
77  private $errors = false;
78 
85  private $directories;
86 
93  private $files;
94 
102  public function __construct($path = '', $create = true, $mode = false)
103  {
104  if (empty($path)) {
105  $path = \XoopsBaseConfig::get('var-path') . '/caches/xoops_cache';
106  }
107  if ($mode) {
108  $this->mode = intval($mode, 8);
109  }
110  if (!XoopsLoad::fileExists($path) && $create == true) {
111  $this->create($path, $this->mode);
112  }
113  if (!$this->isAbsolute($path)) {
114  $path = realpath($path);
115  }
116  $this->cd($path);
117  }
118 
125  public function pwd()
126  {
127  return $this->path;
128  }
129 
138  public function cd($path)
139  {
140  $path = $this->realpath($path);
141  if (is_dir($path) && XoopsLoad::fileExists($path)) {
142  return $this->path = $path;
143  }
144  return false;
145  }
146 
157  public function read($sort = true, $exceptions = false)
158  {
159  $dirs = $files = array();
160  $dir = opendir($this->path);
161  if ($dir !== false) {
162  while (false !== ($n = readdir($dir))) {
163  $item = false;
164  if (is_array($exceptions)) {
165  if (!in_array($n, $exceptions)) {
166  $item = $n;
167  }
168  } else {
169  if ((!preg_match('/^\\.+$/', $n) && $exceptions == false)
170  || ($exceptions == true && !preg_match('/^\\.(.*)$/', $n))
171  ) {
172  $item = $n;
173  }
174  }
175  if ($item !== false) {
176  if (is_dir($this->addPathElement($this->path, $item))) {
177  $dirs[] = $item;
178  } else {
179  $files[] = $item;
180  }
181  }
182  }
183  if ($sort || $this->sort) {
184  sort($dirs);
185  sort($files);
186  }
187  closedir($dir);
188  }
189  return array(
190  $dirs, $files
191  );
192  }
193 
203  public function find($regexp_pattern = '.*', $sort = false)
204  {
205  $data = $this->read($sort);
206  if (!is_array($data)) {
207  return array();
208  }
209  list ($dirs, $files) = $data;
210  $found = array();
211  foreach ($files as $file) {
212  if (preg_match("/^{$regexp_pattern}$/i", $file)) {
213  $found[] = $file;
214  }
215  }
216  return $found;
217  }
218 
228  public function findRecursive($pattern = '.*', $sort = false)
229  {
230  $startsOn = $this->path;
231  $out = $this->findRecursiveHelper($pattern, $sort);
232  $this->cd($startsOn);
233  return $out;
234  }
235 
245  private function findRecursiveHelper($pattern, $sort = false)
246  {
247  list ($dirs, $files) = $this->read($sort);
248  $found = array();
249  foreach ($files as $file) {
250  if (preg_match("/^{$pattern}$/i", $file)) {
251  $found[] = $this->addPathElement($this->path, $file);
252  }
253  }
255  foreach ($dirs as $dir) {
256  $this->cd($this->addPathElement($start, $dir));
257  $found = array_merge($found, $this->findRecursive($pattern));
258  }
259  return $found;
260  }
261 
271  public static function isWindowsPath($path)
272  {
273  if (preg_match('/^[A-Z]:\\\\/i', $path)) {
274  return true;
275  }
276  return false;
277  }
278 
288  public static function isAbsolute($path)
289  {
290  $match = preg_match('/^(\/|[A-Z]:)/', $path);
291  return ($match == 1);
292  }
293 
303  public static function normalizePath($path)
304  {
305  if (self::isWindowsPath($path)) {
306  return '\\';
307  }
308  return '/';
309  }
310 
320  public static function correctSlashFor($path)
321  {
322  if (self::isWindowsPath($path)) {
323  return '\\';
324  }
325  return '/';
326  }
327 
337  public static function slashTerm($path)
338  {
339  if (self::isSlashTerm($path)) {
340  return $path;
341  }
342  return $path . self::correctSlashFor($path);
343  }
344 
355  public static function addPathElement($path, $element)
356  {
357  return self::slashTerm($path) . $element;
358  }
359 
368  public function inXoopsPath($path = '')
369  {
371  $dir = substr($this->slashTerm($xoops_root_path), 0, -1);
372  $newdir = $dir . $path;
373  return $this->inPath($newdir);
374  }
375 
384  public function inPath($path = '', $reverse = false)
385  {
386  $dir = $this->slashTerm($path);
387  $current = $this->slashTerm($this->pwd());
388  if (!$reverse) {
389  $return = preg_match('/^(.*)' . preg_quote($dir, '/') . '(.*)/', $current);
390  } else {
391  $return = preg_match('/^(.*)' . preg_quote($current, '/') . '(.*)/', $dir);
392  }
393  return ($return == 1);
394  }
395 
407  public function chmod($path, $mode = false, $recursive = true, $exceptions = array())
408  {
409  if (!$mode) {
410  $mode = $this->mode;
411  }
412  if ($recursive === false && is_dir($path)) {
413  if (chmod($path, intval($mode, 8))) {
414  $this->messages[] = sprintf('%s changed to %s', $path, $mode);
415  return true;
416  } else {
417  $this->errors[] = sprintf('%s NOT changed to %s', $path, $mode);
418  return false;
419  }
420  }
421  if (is_dir($path)) {
422  list ($paths) = $this->tree($path);
423  foreach ($paths as $fullpath) {
424  $check = explode('/', $fullpath);
425  $count = count($check);
426 
427  if (in_array($check[$count - 1], $exceptions)) {
428  continue;
429  }
430 
431  if (chmod($fullpath, intval($mode, 8))) {
432  $this->messages[] = sprintf('%s changed to %s', $fullpath, $mode);
433  } else {
434  $this->errors[] = sprintf('%s NOT changed to %s', $fullpath, $mode);
435  }
436  }
437  if (empty($this->errors)) {
438  return true;
439  }
440  }
441  return false;
442  }
443 
454  public function tree($path, $hidden = true, $type = null)
455  {
456  $path = rtrim($path, '/');
457  $this->files = array();
458  $this->directories = array(
459  $path
460  );
461  $directories = array();
462  while (count($this->directories)) {
463  $dir = array_pop($this->directories);
464  $this->treeHelper($dir, $hidden);
465  array_push($directories, $dir);
466  }
467  if ($type === null) {
468  return array(
469  $directories, $this->files
470  );
471  }
472  if ($type === 'dir') {
473  return $directories;
474  }
475  return $this->files;
476  }
477 
488  private function treeHelper($path, $hidden)
489  {
490  if (is_dir($path)) {
491  $dirHandle = opendir($path);
492  while (false !== ($item = readdir($dirHandle))) {
493  $found = false;
494  if (($hidden === true && $item != '.' && $item != '..')
495  || ($hidden === false && !preg_match('/^\\.(.*)$/', $item))
496  ) {
497  $found = $path . '/' . $item;
498  }
499  if ($found !== false) {
500  if (is_dir($found)) {
501  array_push($this->directories, $found);
502  } else {
503  array_push($this->files, $found);
504  }
505  }
506  }
507  closedir($dirHandle);
508  }
509  }
510 
520  public function create($pathname, $mode = false)
521  {
522  if (is_dir($pathname) || empty($pathname)) {
523  return true;
524  }
525  if (!$mode) {
526  $mode = $this->mode;
527  }
528  if (is_file($pathname)) {
529  $this->errors[] = sprintf('%s is a file', $pathname);
530  return true;
531  }
532  $nextPathname = substr($pathname, 0, strrpos($pathname, '/'));
533  if ($this->create($nextPathname, $mode)) {
534  if (!XoopsLoad::fileExists($pathname)) {
535  if (mkdir($pathname, intval($mode, 8))) {
536  $this->messages[] = sprintf('%s created', $pathname);
537  return true;
538  } else {
539  $this->errors[] = sprintf('%s NOT created', $pathname);
540  return false;
541  }
542  }
543  }
544  return true;
545  }
546 
552  public function dirsize()
553  {
554  $size = 0;
555  $directory = $this->slashTerm($this->path);
556  $stack = array($directory);
557  $count = count($stack);
558  for ($i = 0, $j = $count; $i < $j; ++$i) {
559  if (is_file($stack[$i])) {
560  $size += filesize($stack[$i]);
561  } else {
562  if (is_dir($stack[$i])) {
563  $dir = dir($stack[$i]);
564  if ($dir) {
565  while (false !== ($entry = $dir->read())) {
566  if ($entry == '.' || $entry == '..') {
567  continue;
568  }
569  $add = $stack[$i] . $entry;
570  if (is_dir($stack[$i] . $entry)) {
571  $add = $this->slashTerm($add);
572  }
573  $stack[] = $add;
574  }
575  $dir->close();
576  }
577  }
578  }
579  $j = count($stack);
580  }
581  return $size;
582  }
583 
592  public function delete($path)
593  {
594  $path = $this->slashTerm($path);
595  if (is_dir($path) === true) {
596  $normal_files = glob($path . '*');
597  $hidden_files = glob($path . '\.?*');
598  $files = array_merge($normal_files, $hidden_files);
599  if (is_array($files)) {
600  foreach ($files as $file) {
601  if (preg_match("/(\.|\.\.)$/", $file)) {
602  continue;
603  }
604  if (is_file($file) === true) {
605  if (unlink($file)) {
606  $this->messages[] = sprintf('%s removed', $path);
607  } else {
608  $this->errors[] = sprintf('%s NOT removed', $path);
609  }
610  } else {
611  if (is_dir($file) === true) {
612  if ($this->delete($file) === false) {
613  return false;
614  }
615  }
616  }
617  }
618  }
619  $path = substr($path, 0, strlen($path) - 1);
620  if (rmdir($path) === false) {
621  $this->errors[] = sprintf('%s NOT removed', $path);
622  return false;
623  } else {
624  $this->messages[] = sprintf('%s removed', $path);
625  }
626  }
627  return true;
628  }
629 
638  public function copy($options = array())
639  {
640  $to = null;
641  if (is_string($options)) {
642  $to = $options;
643  $options = array();
644  }
645  $options = array_merge(
646  array(
647  'to' => $to,
648  'from' => $this->path,
649  'mode' => $this->mode,
650  'skip' => array()
651  ),
652  $options
653  );
654 
655  $fromDir = $options['from'];
656  $toDir = $options['to'];
657  $mode = $options['mode'];
658  if (!$this->cd($fromDir)) {
659  $this->errors[] = sprintf('%s not found', $fromDir);
660  return false;
661  }
662  if (!is_dir($toDir)) {
663  mkdir($toDir, $mode);
664  }
665  if (!is_writable($toDir)) {
666  $this->errors[] = sprintf('%s not writable', $toDir);
667  return false;
668  }
669  $exceptions = array_merge(array('.', '..', '.svn'), $options['skip']);
670  $handle = opendir($fromDir);
671  if ($handle) {
672  while (false !== ($item = readdir($handle))) {
673  if (!in_array($item, $exceptions)) {
674  $from = $this->addPathElement($fromDir, $item);
675  $to = $this->addPathElement($toDir, $item);
676  if (is_file($from)) {
677  if (copy($from, $to)) {
678  chmod($to, intval($mode, 8));
679  touch($to, filemtime($from));
680  $this->messages[] = sprintf('%s copied to %s', $from, $to);
681  } else {
682  $this->errors[] = sprintf('%s NOT copied to %s', $from, $to);
683  }
684  }
685  if (is_dir($from) && !XoopsLoad::fileExists($to)) {
686  if (mkdir($to, intval($mode, 8))) {
687  chmod($to, intval($mode, 8));
688  $this->messages[] = sprintf('%s created', $to);
689  $options = array_merge($options, array('to' => $to, 'from' => $from));
690  $this->copy($options);
691  } else {
692  $this->errors[] = sprintf('%s not created', $to);
693  }
694  }
695  }
696  }
697  closedir($handle);
698  } else {
699  return false;
700  }
701  if (!empty($this->errors)) {
702  return false;
703  }
704  return true;
705  }
706 
715  public function move($options)
716  {
717  $to = null;
718  if (is_string($options)) {
719  $to = $options;
720  $options = (array)$options;
721  }
722  $options = array_merge(
723  array(
724  'to' => $to,
725  'from' => $this->path,
726  'mode' => $this->mode,
727  'skip' => array()
728  ),
729  $options
730  );
731  if ($this->copy($options)) {
732  if ($this->delete($options['from'])) {
733  return $this->cd($options['to']);
734  }
735  }
736  return false;
737  }
738 
745  public function messages()
746  {
747  return $this->messages;
748  }
749 
756  public function errors()
757  {
758  return $this->errors;
759  }
760 
768  public function realpath($path)
769  {
770  $path = trim($path);
771  if (strpos($path, '..') === false) {
772  if (!$this->isAbsolute($path)) {
773  $path = $this->addPathElement($this->path, $path);
774  }
775  return $path;
776  }
777  $parts = explode('/', $path);
778  $newparts = array();
779  $newpath = $path{0} == '/' ? '/' : '';
780  while (($part = array_shift($parts)) !== null) {
781  if ($part == '.' || $part == '') {
782  continue;
783  }
784  if ($part == '..') {
785  if (count($newparts) > 0) {
786  array_pop($newparts);
787  continue;
788  } else {
789  return false;
790  }
791  }
792  $newparts[] = $part;
793  }
794  $newpath .= implode('/', $newparts);
795  if (strlen($path > 1) && $path{strlen($path) - 1} == '/') {
796  $newpath .= '/';
797  }
798  return $newpath;
799  }
800 
810  public static function isSlashTerm($path)
811  {
812  if (preg_match('/[\/\\\]$/', $path)) {
813  return true;
814  }
815  return false;
816  }
817 }
findRecursiveHelper($pattern, $sort=false)
Definition: folder.php:245
static isAbsolute($path)
Definition: folder.php:288
$i
Definition: dialog.php:68
if(!isset($xoops->paths[$path_type])) if($path_type== 'var') $file
Definition: browse.php:55
$options['editor']
static normalizePath($path)
Definition: folder.php:303
tree($path, $hidden=true, $type=null)
Definition: folder.php:454
static isSlashTerm($path)
Definition: folder.php:810
chmod($path, $mode=false, $recursive=true, $exceptions=array())
Definition: folder.php:407
read($sort=true, $exceptions=false)
Definition: folder.php:157
if(DIRECTORY_SEPARATOR!="/") $xoops_root_path
Definition: config.php:7
findRecursive($pattern= '.*', $sort=false)
Definition: folder.php:228
create($pathname, $mode=false)
Definition: folder.php:520
static fileExists($file)
Definition: xoopsload.php:506
static get($name)
static slashTerm($path)
Definition: folder.php:337
treeHelper($path, $hidden)
Definition: folder.php:488
move($options)
Definition: folder.php:715
find($regexp_pattern= '.*', $sort=false)
Definition: folder.php:203
__construct($path= '', $create=true, $mode=false)
Definition: folder.php:102
$type
Definition: misc.php:33
$hidden_files
Definition: config.php:192
static addPathElement($path, $element)
Definition: folder.php:355
copy($options=array())
Definition: folder.php:638
static correctSlashFor($path)
Definition: folder.php:320
$current
Definition: install_tpl.php:38
$start
$dir
Definition: browse.php:56
$j
Definition: help.php:169
inXoopsPath($path= '')
Definition: folder.php:368
static isWindowsPath($path)
Definition: folder.php:271
inPath($path= '', $reverse=false)
Definition: folder.php:384