3 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
20 * Abstraction of general file archives.
23 * @subpackage filestorage
24 * @copyright 2008 Petr Skoda (http://skodak.org)
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28 defined('MOODLE_INTERNAL') ||
die();
31 * Each file archive type must extend this class.
34 * @subpackage filestorage
35 * @copyright 2008 Petr Skoda (http://skodak.org)
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 abstract class file_archive
implements Iterator
{
40 /** Open archive if exists, fail if does not exist. */
43 /** Open archive if exists, create if does not. */
46 /** Always create new archive */
49 /** Encoding of file names - windows usually expects DOS single-byte charset*/
50 protected $encoding = 'utf-8';
53 * Open or create archive (depending on $mode)
54 * @param string $archivepathname
55 * @param int $mode OPEN, CREATE or OVERWRITE constant
56 * @param string $encoding archive local paths encoding
57 * @return bool success
59 public abstract function open($archivepathname, $mode=file_archive
::CREATE
, $encoding='utf-8');
63 * @return bool success
65 public abstract function close();
68 * Returns file stream for reading of content
69 * @param int $index of file
70 * @return stream or false if error
72 public abstract function get_stream($index);
75 * Returns file information
76 * @param int $index of file
77 * @return info object or false if error
79 public abstract function get_info($index);
82 * Returns array of info about all files in archive
83 * @return array of file infos
85 public abstract function list_files();
88 * Returns number of files in archive
89 * @return int number of files
91 public abstract function count();
94 * Add file into archive
95 * @param string $localname name of file in archive
96 * @param string $pathname location of file
97 * @return bool success
99 public abstract function add_file_from_pathname($localname, $pathname);
102 * Add content of string into archive
103 * @param string $localname name of file in archive
104 * @param string $contents
105 * @return bool success
107 public abstract function add_file_from_string($localname, $contents);
110 * Add empty directory into archive
111 * @param string $local
112 * @return bool success
114 public abstract function add_directory($localname);
117 * Tries to convert $localname into another encoding,
118 * please note that it may fail really badly.
119 * @param string $localname in utf-8 encoding
122 protected function mangle_pathname($localname) {
123 if ($this->encoding
=== 'utf-8') {
126 $textlib = textlib_get_instance();
128 $converted = $textlib->convert($localname, 'utf-8', $this->encoding
);
129 $original = $textlib->convert($converted, $this->encoding
, 'utf-8');
131 if ($original === $localname) {
132 $result = $converted;
135 // try ascii conversion
136 $converted2 = $textlib->specialtoascii($localname);
137 $converted2 = $textlib->convert($converted2, 'utf-8', $this->encoding
);
138 $original2 = $textlib->convert($converted, $this->encoding
, 'utf-8');
140 if ($original2 === $localname) {
141 //this looks much better
142 $result = $converted2;
144 //bad luck - the file name may not be usable at all
145 $result = $converted;
149 $result = preg_replace('/\.\.+/', '', $result);
150 $result = ltrim($result); // no leading /
152 if ($result === '.') {
160 * Tries to convert $localname into utf-8
161 * please note that it may fail really badly.
162 * The resulting file name is cleaned.
164 * @param string $localname in $this->encoding
165 * @return string in utf-8
167 protected function unmangle_pathname($localname) {
168 $result = str_replace('\\', '/', $localname); // no MS \ separators
169 $result = ltrim($result, '/'); // no leading /
171 if ($this->encoding
!== 'utf-8') {
172 $result = textlib_get_instance()->convert($result, $this->encoding
, 'utf-8');
175 return clean_param($result, PARAM_PATH
);
179 * Returns current file info
182 //public abstract function current();
185 * Returns the index of current file
186 * @return int current file index
188 //public abstract function key();
191 * Moves forward to next file
194 //public abstract function next();
197 * Rewinds back to the first file
200 //public abstract function rewind();
203 * Did we reach the end?
206 //public abstract function valid();