Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Function expands all relative parts of supplied path string thus
  19   * removing things like ../../ or ./../.
  20   *
  21   * @param string $path
  22   * @param string $dirsep Character that represents directory separator should be
  23   *                       specified here. Default is DIRECTORY_SEPARATOR.
  24   * @return string
  25   */
  26  function fullPath($path,$dirsep=DIRECTORY_SEPARATOR) {
  27      $token = '$IMS-CC-FILEBASE$';
  28      $path = str_replace($token,'',$path);
  29      if ( is_string($path) && ($path != '') ) {
  30          $sep   = $dirsep;
  31          $dotDir= '.';
  32          $upDir = '..';
  33          $length= strlen($path);
  34          $rtemp= trim($path);
  35          $start = strrpos($path, $sep);
  36          $canContinue = ($start !== false);
  37          $result= $canContinue ? '': $path;
  38          $rcount=0;
  39          while ($canContinue) {
  40              $dirPart = ($start !== false) ? substr($rtemp,$start+1,$length-$start) : $rtemp;
  41              $canContinue = ($dirPart !== false);
  42              if ($canContinue) {
  43                  if ($dirPart != $dotDir) {
  44                      if ($dirPart == $upDir) {
  45                          $rcount++;
  46                      } else {
  47                          if ($rcount > 0) {
  48                              $rcount--;
  49                          } else {
  50                              $result = ($result == '') ? $dirPart : $dirPart.$sep.$result;
  51                          }
  52                      }
  53                  }
  54                  $rtemp = substr($path,0,$start);
  55                  $start = strrpos($rtemp, $sep);
  56                  $canContinue = (($start !== false) || (strlen($rtemp) > 0));
  57              }
  58          } //end while
  59      }
  60      return $result;
  61  }
  62  
  63  
  64  
  65  /**
  66   * Function strips url part from css link
  67   *
  68   * @param string $path
  69   * @param string $rootDir
  70   * @return string
  71   */
  72  function stripUrl($path, $rootDir='') {
  73      $result = $path;
  74      if ( is_string($path) && ($path != '') ) {
  75          $start=strpos($path,'(')+1;
  76          $length=strpos($path,')')-$start;
  77          $rut = $rootDir.substr($path,$start,$length);
  78          $result=fullPath($rut,'/');
  79      }
  80      return $result;
  81  }
  82  
  83  /**
  84   * Converts direcotry separator in given path to / to validate in CC
  85   * Value is passed byref hence variable itself is changed
  86   *
  87   * @param string $path
  88   */
  89  function toNativePath(&$path) {
  90      for ($count = 0 ; $count < strlen($path); ++$count) {
  91          $chr = $path[$count];
  92          if (($chr == '\\') || ($chr == '/')) {
  93              $path[$count] = '/';
  94          }
  95      }
  96  }
  97  
  98  
  99  /**
 100   * Converts direcotry separator in given path to the one on the server platform
 101   * Value is passed byref hence variable itself is changed
 102   *
 103   * @param string $path
 104   */
 105  function toNativePath2(&$path) {
 106      for ($count = 0 ; $count < strlen($path); ++$count) {
 107          $chr = $path[$count];
 108          if (($chr == '\\') || ($chr == '/')) {
 109              $path[$count] = DIRECTORY_SEPARATOR;
 110          }
 111      }
 112  }
 113  
 114  /**
 115   * Converts \ Directory separator to the / more suitable for URL
 116   *
 117   * @param string $path
 118   */
 119  function toUrlPath(&$path) {
 120      for ($count = 0 ; $count < strlen($path); ++$count) {
 121          $chr = $path[$count];
 122          if (($chr == '\\')) {
 123              $path[$count] = '/';
 124          }
 125      }
 126  }
 127  
 128  /**
 129   * Returns relative path from two directories with full path
 130   *
 131   * @param string $path1
 132   * @param string $path2
 133   * @return string
 134   */
 135  function pathDiff($path1, $path2) {
 136      toUrlPath($path1);
 137      toUrlPath($path2);
 138      $result = "";
 139      $bl2 = strlen($path2);
 140      $a = strpos($path1,$path2);
 141      if ($a !== false) {
 142          $result = trim(substr($path1,$bl2+$a),'/');
 143      }
 144      return $result;
 145  }
 146  
 147   /**
 148    * Copy a file, or recursively copy a folder and its contents
 149    *
 150    * @author      Aidan Lister <aidan@php.net>
 151    * @version     1.0.1
 152    * @link        http://aidanlister.com/repos/v/function.copyr.php
 153    * @param       string   $source    Source path
 154    * @param       string   $dest      Destination path
 155    * @return      bool     Returns TRUE on success, FALSE on failure
 156    */
 157   function copyr($source, $dest)
 158   {
 159       global $CFG;
 160       // Simple copy for a file
 161       if (is_file($source)) {
 162           return copy($source, $dest);
 163       }
 164  
 165       // Make destination directory
 166       if (!is_dir($dest)) {
 167           mkdir($dest, $CFG->directorypermissions, true);
 168       }
 169  
 170       // Loop through the folder
 171       $dir = dir($source);
 172       while (false !== $entry = $dir->read()) {
 173           // Skip pointers
 174           if ($entry == '.' || $entry == '..') {
 175               continue;
 176           }
 177  
 178           // Deep copy directories
 179           if ($dest !== "$source/$entry") {
 180               copyr("$source/$entry", "$dest/$entry");
 181           }
 182       }
 183  
 184       // Clean up
 185       $dir->close();
 186       return true;
 187   }
 188  
 189  /**
 190   * Function returns array with directories contained in folder (only first level)
 191   *
 192   * @param  string $rootDir  directory to look into
 193   * @param  string $contains which string to look for
 194   * @param  array  $excludeitems array of names to be excluded
 195   * @param  bool   $startswith should the $contains value be searched only from
 196   *                             beginning
 197   * @return array  Returns array of sub-directories. In case $rootDir path is
 198   *                invalid it returns FALSE.
 199   */
 200  function getDirectories($rootDir, $contains, $excludeitems = null, $startswith = true) {
 201      $result = is_dir($rootDir);
 202      if ($result) {
 203          $dirlist = dir($rootDir);
 204          $entry = null;
 205          $result = array();
 206          while(false !== ($entry = $dirlist->read())) {
 207              $currdir = $rootDir.$entry;
 208              if (is_dir($currdir)) {
 209                  $bret = strpos($entry,$contains);
 210                  if (($bret !== false)) {
 211                      if (($startswith && ($bret == 0)) || !$startswith) {
 212                          if (!( is_array($excludeitems) && in_array($entry,$excludeitems) )) {
 213                              $result[] = $entry;
 214                          }
 215                      }
 216                  }
 217              }
 218          }
 219      }
 220      return $result;
 221  }
 222  
 223  function getFilesOnly($rootDir, $contains, $excludeitems = null, $startswith = true,$extension=null) {
 224      $result = is_dir($rootDir);
 225      if ($result) {
 226          $filelist = dir($rootDir);
 227          $entry = null;
 228          $result = array();
 229          while(false !== ($entry = $filelist->read())) {
 230              $curritem = $rootDir.$entry;
 231              $pinfo = pathinfo($entry);
 232              $ext = array_key_exists('extension',$pinfo) ? $pinfo['extension'] : null;
 233              if (is_file($curritem) && (is_null($extension) || ($ext == $extension) )) {
 234                  $bret = strpos($entry,$contains);
 235                  if (($bret !== false)) {
 236                      if (($startswith && ($bret == 0)) || !$startswith) {
 237                          if (!( is_array($excludeitems) && in_array($entry,$excludeitems) )) {
 238                              $result[] = $entry;
 239                          }
 240                      }
 241                  }
 242              }
 243          }
 244      }
 245      natcasesort($result);
 246      return $result;
 247  }
 248  
 249  
 250  
 251  /**
 252   * Search an identifier in array
 253   *
 254   * @param array $array
 255   * @param string $name
 256   *
 257   */
 258  
 259  function search_ident_by_name($array,$name){
 260      if (empty($array)){
 261          throw new Exception('The array given is null');
 262      }
 263      $ident = null;
 264      foreach ($array as $k => $v){
 265          ($k);
 266          if ($v[1] == $name){
 267              $ident = $v[0];
 268              break;
 269          }
 270      }
 271      return $ident;
 272  }
 273  
 274  
 275  
 276  
 277  
 278  /**
 279   * Function returns files recursivly with appeneded relative path
 280   *
 281   * @param string $startDir
 282   * @param string $rootDir
 283   * @param array $excludedirs
 284   * @param array $excludefileext
 285   * @return array
 286   */
 287  function getRawFiles($startDir, &$fhandle, $rootDir='', $excludedirs = null, $excludefileext = null) {
 288      $result = is_dir($startDir);
 289      if ($result) {
 290          $dirlist = dir($startDir);
 291          $entry = null;
 292          while(false !== ($entry = $dirlist->read())) {
 293              $curritem = $startDir.$entry;
 294              if (($entry=='.') || ($entry =='..')) {
 295                  continue;
 296              }
 297              if (is_dir($curritem)) {
 298                  if (!( is_array($excludedirs) && in_array($entry,$excludedirs) )) {
 299                      getRawFiles($startDir.$entry."/",$fhandle,$rootDir.$entry."/",$excludedirs,$excludefileext);
 300                  }
 301                  continue;
 302              }
 303              if (is_file($curritem)){
 304                  $pinfo = pathinfo($entry);
 305                  $ext = array_key_exists('extension',$pinfo) ? $pinfo['extension'] : '';
 306                  if (!is_array($excludefileext) ||
 307                  (is_array($excludefileext) && !in_array($ext,$excludefileext))) {
 308                      fwrite($fhandle,$rootDir.$entry."\n");
 309                  }
 310              }
 311          }
 312      }
 313      return $result;
 314  }
 315  
 316  
 317  function getRawFiles2($startDir,&$arr, $rootDir='', $excludedirs = null, $excludefileext = null) {
 318  
 319      $result = is_dir($startDir);
 320      if ($result) {
 321          $dirlist = dir($startDir);
 322          $entry = null;
 323          while(false !== ($entry = $dirlist->read())) {
 324              $curritem = $startDir.$entry;
 325              if (($entry=='.') || ($entry =='..')) {
 326                  continue;
 327              }
 328              if (is_dir($curritem)) {
 329                  if (!( is_array($excludedirs) && in_array($entry,$excludedirs) )) {
 330                      getRawFiles2($startDir.$entry."/",$arr,$rootDir.$entry."/",$excludedirs,$excludefileext);
 331                  }
 332                  continue;
 333              }
 334              if (is_file($curritem)){
 335                  $pinfo = pathinfo($entry);
 336                  $ext = array_key_exists('extension',$pinfo) ? $pinfo['extension'] : '';
 337                  if (!is_array($excludefileext) ||
 338                  (is_array($excludefileext) && !in_array($ext,$excludefileext))) {
 339                      array_push($arr,$rootDir.$entry);
 340                     // fwrite($fhandle,$rootDir.$entry."\n");
 341                  }
 342              }
 343          }
 344      }
 345      return $result;
 346  }
 347  
 348  
 349  function GetFiles($startDir, $outfile, $rootDir='', $excludedirs = null, $excludefileext = null) {
 350      $fh = @fopen($outfile,"w+");
 351      if ($fh !== FALSE) {
 352          getRawFiles($startDir,$fh,$rootDir,$excludedirs,$excludefileext);
 353          @fclose($fh);
 354          @chmod($outfile,0777);
 355      }
 356  }
 357  
 358  
 359  /**
 360   * Function to get an array with all files in a directory and subdirectories
 361   *
 362   * @param string $startDir
 363   * @param string $rootDir
 364   * @param string $excludedirs
 365   * @param string $excludefileext
 366   * @return array
 367   */
 368  
 369  function GetFilesArray($startDir, $rootDir='', $excludedirs = null, $excludefileext = null) {
 370      $arr = array();
 371      getRawFiles2($startDir,$arr,$rootDir,$excludedirs,$excludefileext);
 372      return $arr;
 373  }
 374  
 375  
 376  
 377  /**
 378   * Function returns array with directories contained in folder (only first level)
 379   * simmilar to getDirectories but returned items are naturally sorted.
 380   *
 381   * @param string $rootDir
 382   * @param string $contains
 383   * @param array $excludeitems
 384   * @param bool $startswith
 385   * @return array
 386   */
 387  function getCourseDirs ($rootDir, $contains, $excludeitems=null, $startswith=true) {
 388      $result = getDirectories($rootDir,$contains,$excludeitems,$startswith);
 389      if ($result !== false) {
 390          natcasesort($result);
 391          $result = array_values($result);
 392      }
 393      return $result;
 394  }
 395  
 396  
 397  /**
 398   * Delete a directory recursive with files inside
 399   *
 400   * @param string $dirname
 401   * @return bool
 402   */
 403  function rmdirr($dirname)
 404  {
 405      if (!file_exists($dirname)) {
 406          return false;
 407      }
 408      if (is_file($dirname) || is_link($dirname)) {
 409          return unlink($dirname);
 410      }
 411      $dir = dir($dirname);
 412      while (false !== $entry = $dir->read()) {
 413          if ($entry == '.' || $entry == '..') {
 414              continue;
 415          }
 416          rmdirr($dirname . DIRECTORY_SEPARATOR . $entry);
 417      }
 418      $dir->close();
 419      return rmdir($dirname);
 420  }