Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/filestorage/zip_archive.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00018 
00028 defined('MOODLE_INTERNAL') || die();
00029 
00030 require_once("$CFG->libdir/filestorage/file_archive.php");
00031 
00040 class zip_archive extends file_archive {
00041 
00043     protected $archivepathname = null;
00044 
00046     protected $usedmem = 0;
00047 
00049     protected $pos = 0;
00050 
00052     protected $za;
00053 
00061     public function open($archivepathname, $mode=file_archive::CREATE, $encoding='utf-8') {
00062         $this->close();
00063 
00064         $this->usedmem = 0;
00065         $this->pos     = 0;
00066 
00067         $this->za = new ZipArchive();
00068 
00069         switch($mode) {
00070             case file_archive::OPEN:      $flags = 0; break;
00071             case file_archive::OVERWRITE: $flags = ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE; break; //changed in PHP 5.2.8
00072             case file_archive::CREATE:
00073             default :                     $flags = ZIPARCHIVE::CREATE; break;
00074         }
00075 
00076         $result = $this->za->open($archivepathname, $flags);
00077 
00078         if ($result === true) {
00079             $this->encoding    = $encoding;
00080             if (file_exists($archivepathname)) {
00081                 $this->archivepathname = realpath($archivepathname);
00082             } else {
00083                 $this->archivepathname = $archivepathname;
00084             }
00085             return true;
00086 
00087         } else {
00088             $this->za = null;
00089             $this->archivepathname = null;
00090             $this->encooding       = 'utf-8';
00091             // TODO: maybe we should return some error info
00092             return false;
00093         }
00094     }
00095 
00100     public function close() {
00101         if (!isset($this->za)) {
00102             return false;
00103         }
00104 
00105         $res = $this->za->close();
00106         $this->za = null;
00107 
00108         return $res;
00109     }
00110 
00116     public function get_stream($index) {
00117         if (!isset($this->za)) {
00118             return false;
00119         }
00120 
00121         $name = $this->za->getNameIndex($index);
00122         if ($name === false) {
00123             return false;
00124         }
00125 
00126         return $this->za->getStream($name);
00127     }
00128 
00134     public function get_info($index) {
00135         if (!isset($this->za)) {
00136             return false;
00137         }
00138 
00139         if ($index < 0 or $index >=$this->count()) {
00140             return false;
00141         }
00142 
00143         $result = $this->za->statIndex($index);
00144 
00145         if ($result === false) {
00146             return false;
00147         }
00148 
00149         $info = new stdClass();
00150         $info->index             = $index;
00151         $info->original_pathname = $result['name'];
00152         $info->pathname          = $this->unmangle_pathname($result['name']);
00153         $info->mtime             = (int)$result['mtime'];
00154 
00155         if ($info->pathname[strlen($info->pathname)-1] === '/') {
00156             $info->is_directory = true;
00157             $info->size         = 0;
00158         } else {
00159             $info->is_directory = false;
00160             $info->size         = (int)$result['size'];
00161         }
00162 
00163         return $info;
00164     }
00165 
00170     public function list_files() {
00171         if (!isset($this->za)) {
00172             return false;
00173         }
00174 
00175         $infos = array();
00176 
00177         for ($i=0; $i<$this->count(); $i++) {
00178             $info = $this->get_info($i);
00179             if ($info === false) {
00180                 continue;
00181             }
00182             $infos[$i] = $info;
00183         }
00184 
00185         return $infos;
00186     }
00187 
00192     public function count() {
00193         if (!isset($this->za)) {
00194             return false;
00195         }
00196 
00197         return $this->za->numFiles;
00198     }
00199 
00206     public function add_file_from_pathname($localname, $pathname) {
00207         if (!isset($this->za)) {
00208             return false;
00209         }
00210 
00211         if ($this->archivepathname === realpath($pathname)) {
00212             // do not add self into archive
00213             return false;
00214         }
00215 
00216         if (is_null($localname)) {
00217             $localname = clean_param($pathname, PARAM_PATH);
00218         }
00219         $localname = trim($localname, '/'); // no leading slashes in archives
00220         $localname = $this->mangle_pathname($localname);
00221 
00222         if ($localname === '') {
00223             //sorry - conversion failed badly
00224             return false;
00225         }
00226 
00227         if (!check_php_version('5.2.8')) {
00228             // workaround for open file handles problem, ZipArchive uses file locking in order to prevent file modifications before the close() (strange, eh?)
00229             if ($this->count() > 0 and $this->count() % 500 === 0) {
00230                 $this->close();
00231                 $res = $this->open($this->archivepathname, file_archive::OPEN, $this->encoding);
00232                 if ($res !== true) {
00233                     print_error('cannotopenzip'); //TODO ??
00234                 }
00235             }
00236         }
00237 
00238         return $this->za->addFile($pathname, $localname);
00239     }
00240 
00247     public function add_file_from_string($localname, $contents) {
00248         if (!isset($this->za)) {
00249             return false;
00250         }
00251 
00252         $localname = trim($localname, '/'); // no leading slashes in archives
00253         $localname = $this->mangle_pathname($localname);
00254 
00255         if ($localname === '') {
00256             //sorry - conversion failed badly
00257             return false;
00258         }
00259 
00260         if ($this->usedmem > 2097151) {
00262             $this->close();
00263             $res = $this->open($this->archivepathname, file_archive::OPEN, $this->encoding);
00264             if ($res !== true) {
00265                 print_error('cannotopenzip'); //TODO ??
00266             }
00267         }
00268         $this->usedmem += strlen($contents);
00269 
00270         return $this->za->addFromString($localname, $contents);
00271 
00272     }
00273 
00279     public function add_directory($localname) {
00280         if (!isset($this->za)) {
00281             return false;
00282         }
00283         $localname = ltrim($localname, '/'). '/';
00284         $localname = $this->mangle_pathname($localname);
00285 
00286         if ($localname === '/') {
00287             //sorry - conversion failed badly
00288             return false;
00289         }
00290 
00291         return $this->za->addEmptyDir($localname);
00292     }
00293 
00298     public function current() {
00299         if (!isset($this->za)) {
00300             return false;
00301         }
00302 
00303         return $this->get_info($this->pos);
00304     }
00305 
00310     public function key() {
00311         return $this->pos;
00312     }
00313 
00318     public function next() {
00319         $this->pos++;
00320     }
00321 
00326     public function rewind() {
00327         $this->pos = 0;
00328     }
00329 
00334     public function valid() {
00335         if (!isset($this->za)) {
00336             return false;
00337         }
00338 
00339         return ($this->pos < $this->count());
00340     }
00341 }
 All Data Structures Namespaces Files Functions Variables Enumerations