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   * Implementation of .mbz packer.
  19   *
  20   * This packer supports .mbz files which can be either .zip or .tar.gz format
  21   * internally. A suitable format is chosen depending on system option when
  22   * creating new files.
  23   *
  24   * Internally this packer works by wrapping the existing .zip/.tar.gz packers.
  25   *
  26   * Backup filenames do not contain non-ASCII characters so packers that do not
  27   * support UTF-8 (like the current .tar.gz packer, and possibly external zip
  28   * software in some cases if used) can be used by this packer.
  29   *
  30   * @package core_files
  31   * @copyright 2013 The Open University
  32   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  
  35  defined('MOODLE_INTERNAL') || die();
  36  
  37  require_once("$CFG->libdir/filestorage/file_packer.php");
  38  
  39  /**
  40   * Utility class - handles all packing/unpacking of .mbz files.
  41   *
  42   * @package core_files
  43   * @category files
  44   * @copyright 2013 The Open University
  45   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  46   */
  47  class mbz_packer extends file_packer {
  48      /**
  49       * Archive files and store the result in file storage.
  50       *
  51       * Any existing file at that location will be overwritten.
  52       *
  53       * @param array $files array from archive path => pathname or stored_file
  54       * @param int $contextid context ID
  55       * @param string $component component
  56       * @param string $filearea file area
  57       * @param int $itemid item ID
  58       * @param string $filepath file path
  59       * @param string $filename file name
  60       * @param int $userid user ID
  61       * @param bool $ignoreinvalidfiles true means ignore missing or invalid files, false means abort on any error
  62       * @param file_progress $progress Progress indicator callback or null if not required
  63       * @return stored_file|bool false if error stored_file instance if ok
  64       * @throws file_exception If file operations fail
  65       * @throws coding_exception If any archive paths do not meet the restrictions
  66       */
  67      public function archive_to_storage(array $files, $contextid,
  68              $component, $filearea, $itemid, $filepath, $filename,
  69              $userid = null, $ignoreinvalidfiles = true, file_progress $progress = null) {
  70          return $this->get_packer_for_archive_operation()->archive_to_storage($files,
  71                  $contextid, $component, $filearea, $itemid, $filepath, $filename,
  72                  $userid, $ignoreinvalidfiles, $progress);
  73      }
  74  
  75      /**
  76       * Archive files and store the result in an OS file.
  77       *
  78       * @param array $files array from archive path => pathname or stored_file
  79       * @param string $archivefile path to target zip file
  80       * @param bool $ignoreinvalidfiles true means ignore missing or invalid files, false means abort on any error
  81       * @param file_progress $progress Progress indicator callback or null if not required
  82       * @return bool true if file created, false if not
  83       * @throws coding_exception If any archive paths do not meet the restrictions
  84       */
  85      public function archive_to_pathname(array $files, $archivefile,
  86              $ignoreinvalidfiles=true, file_progress $progress = null) {
  87          return $this->get_packer_for_archive_operation()->archive_to_pathname($files,
  88                  $archivefile, $ignoreinvalidfiles, $progress);
  89      }
  90  
  91      /**
  92       * Extract file to given file path (real OS filesystem), existing files are overwritten.
  93       *
  94       * @param stored_file|string $archivefile full pathname of zip file or stored_file instance
  95       * @param string $pathname target directory
  96       * @param array $onlyfiles only extract files present in the array
  97       * @param file_progress $progress Progress indicator callback or null if not required
  98       * @param bool $returnbool Whether to return a basic true/false indicating error state, or full per-file error
  99       * details.
 100       * @return array list of processed files (name=>true)
 101       * @throws moodle_exception If error
 102       */
 103      public function extract_to_pathname($archivefile, $pathname,
 104              array $onlyfiles = null, file_progress $progress = null, $returnbool = false) {
 105          return $this->get_packer_for_read_operation($archivefile)->extract_to_pathname(
 106                  $archivefile, $pathname, $onlyfiles, $progress, $returnbool);
 107      }
 108  
 109      /**
 110       * Extract file to given file path (real OS filesystem), existing files are overwritten.
 111       *
 112       * @param string|stored_file $archivefile full pathname of zip file or stored_file instance
 113       * @param int $contextid context ID
 114       * @param string $component component
 115       * @param string $filearea file area
 116       * @param int $itemid item ID
 117       * @param string $pathbase file path
 118       * @param int $userid user ID
 119       * @param file_progress $progress Progress indicator callback or null if not required
 120       * @return array list of processed files (name=>true)
 121       * @throws moodle_exception If error
 122       */
 123      public function extract_to_storage($archivefile, $contextid,
 124              $component, $filearea, $itemid, $pathbase, $userid = null,
 125              file_progress $progress = null) {
 126          return $this->get_packer_for_read_operation($archivefile)->extract_to_storage(
 127                  $archivefile, $contextid, $component, $filearea, $itemid, $pathbase,
 128                  $userid, $progress);
 129      }
 130  
 131      /**
 132       * Returns array of info about all files in archive.
 133       *
 134       * @param string|stored_file $archivefile
 135       * @return array of file infos
 136       */
 137      public function list_files($archivefile) {
 138          return $this->get_packer_for_read_operation($archivefile)->list_files($archivefile);
 139      }
 140  
 141      /**
 142       * Selects appropriate packer for new archive depending on system option
 143       * and whether required extension is available.
 144       *
 145       * @return file_packer Suitable packer
 146       */
 147      protected function get_packer_for_archive_operation() {
 148          global $CFG;
 149          require_once($CFG->dirroot . '/lib/filestorage/tgz_packer.php');
 150  
 151          if (!empty($CFG->usezipbackups)) {
 152              // Allow forced use of zip backups.
 153              return get_file_packer('application/zip');
 154          } else {
 155              return get_file_packer('application/x-gzip');
 156          }
 157      }
 158  
 159      /**
 160       * Selects appropriate packer for existing archive depending on file contents.
 161       *
 162       * @param string|stored_file $archivefile full pathname of zip file or stored_file instance
 163       * @return file_packer Suitable packer
 164       */
 165      protected function get_packer_for_read_operation($archivefile) {
 166          global $CFG;
 167          require_once($CFG->dirroot . '/lib/filestorage/tgz_packer.php');
 168  
 169          if (tgz_packer::is_tgz_file($archivefile)) {
 170              return get_file_packer('application/x-gzip');
 171          } else {
 172              return get_file_packer('application/zip');
 173          }
 174      }
 175  }