MDL-21432 backup - file handling and other changes. Saving before changes tomorrow...
[moodle.git] / backup / util / helper / backup_file_manager.class.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * @package    moodlecore
20  * @subpackage backup-helper
21  * @copyright  2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 /**
26  * Collection of helper functions to handle files
27  *
28  * This class implements various functions related with moodle storage
29  * handling (get file from storage, put it there...) and some others
30  * to use the zip/unzip facilities.
31  *
32  * Note: It's supposed that, some day, files implementation will offer
33  * those functions without needeing to know storage internals at all.
34  * That day, we'll move related functions here to proper file api ones.
35  *
36  * TODO: Unse File API facilities when available instead of har-coded
37  * storage access here.
38  *
39  * TODO: Finish phpdocs
40  */
41 class backup_file_manager {
43     /**
44      * Returns the full path to the storage base dir
45      */
46     public static function get_moodle_storage_base_dir() {
47         global $CFG;
49         if (isset($CFG->filedir)) {
50             return $CFG->filedir;
51         } else {
52             return $CFG->dataroot.'/filedir';
53         }
54     }
56     /**
57      * Returns the full path to backup storage base dir
58      */
59     public static function get_backup_storage_base_dir($backupid) {
60         global $CFG;
62         return $CFG->dataroot . '/temp/backup/' . $backupid . '/files';
63     }
65     /**
66      * Given one file content hash, returns the path (relative to filedir)
67      * to the file.
68      */
69     public static function get_content_file_location($contenthash) {
70         $l1 = $contenthash[0].$contenthash[1];
71         $l2 = $contenthash[2].$contenthash[3];
72         $l3 = $contenthash[4].$contenthash[5];
73         return "$l1/$l2/$l3/$contenthash";
74     }
76     /**
77      * Copy one file from moodle storage to backup storage
78      */
79     public static function copy_file_moodle2backup($backupid, $filerecorid) {
80         global $DB;
82         // Normalise param
83         if (!is_object($filerecorid)) {
84             $filerecorid = $DB->get_record('files', array('id' => $filerecorid));
85         }
87         // Directory, nothing to do
88         if ($filerecorid->filename === '.') {
89             return;
90         }
92         // Calculate source and target paths (use same subdirs strategy for both)
93         $sourcefilepath = self::get_moodle_storage_base_dir() . '/' .
94                           self::get_content_file_location($filerecorid->contenthash);
95         $targetfilepath = self::get_backup_storage_base_dir($backupid) . '/' .
96                           self::get_content_file_location($filerecorid->contenthash);
98         // Check source exists and is readable
99         if (!file_exists($sourcefilepath) || !is_readable($sourcefilepath)) {
100             throw new backup_helper_exception('cannot_read_file_from_filepool', $sourcefilepath);
101         }
103         // Create target dir if necessary
104         if (!file_exists(dirname($targetfilepath))) {
105             if (!check_dir_exists(dirname($targetfilepath), true, true)) {
106                 throw new backup_helper_exception('cannot_create_directory', dirname($targetfilepath));
107             }
108         }
110         // And copy the file (if doesn't exist already)
111         if (!file_exists($targetfilepath)) {
112             if (!copy($sourcefilepath, $targetfilepath)) {
113                 throw new backup_helper_exception('cannot_copy_file', $sourcefilepath, $targetfilepath);
114             }
115         }
116     }