MODX Revolution PHP Cross Reference Content Management Systems

Source: /core/xpdo/compression/xpdozip.class.php - 212 lines - 8805 bytes - Summary - Text - Print

Description: A class to abstract compression support for ZIP format. This file contains the xPDOZip class to represent ZIP archives.

   1  <?php
   2  /*
   3   * Copyright 2010-2013 by MODX, LLC.
   4   *
   5   * This file is part of xPDO.
   6   *
   7   * xPDO is free software; you can redistribute it and/or modify it under the
   8   * terms of the GNU General Public License as published by the Free Software
   9   * Foundation; either version 2 of the License, or (at your option) any later
  10   * version.
  11   *
  12   * xPDO is distributed in the hope that it will be useful, but WITHOUT ANY
  13   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  14   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  15   *
  16   * You should have received a copy of the GNU General Public License along with
  17   * xPDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
  18   * Suite 330, Boston, MA 02111-1307 USA
  19   */
  20  
  21  /**
  22   * A class to abstract compression support for ZIP format.
  23   *
  24   * This file contains the xPDOZip class to represent ZIP archives.
  25   *
  26   * @package xpdo
  27   * @subpackage compression
  28   */
  29  
  30  /**
  31   * Represents a compressed archive in ZIP format.
  32   *
  33   * @package xpdo
  34   * @subpackage compression
  35   */
  36  class xPDOZip {
  37      const CREATE = 'create';
  38      const OVERWRITE = 'overwrite';
  39      const ZIP_TARGET = 'zip_target';
  40  
  41      public $xpdo = null;
  42      protected $_filename = '';
  43      protected $_options = array();
  44      protected $_archive = null;
  45      protected $_errors = array();
  46  
  47      /**
  48       * Construct an instance representing a specific archive.
  49       *
  50       * @param xPDO &$xpdo A reference to an xPDO instance.
  51       * @param string $filename The name of the archive the instance will represent.
  52       * @param array $options An array of options for this instance.
  53       */
  54      public function __construct(xPDO &$xpdo, $filename, array $options = array()) {
  55          $this->xpdo =& $xpdo;
  56          $this->_filename = is_string($filename) ? $filename : '';
  57          $this->_options = is_array($options) ? $options : array();
  58          $this->_archive = new ZipArchive();
  59          if (!empty($this->_filename) && file_exists(dirname($this->_filename))) {
  60              if (file_exists($this->_filename)) {
  61                  if ($this->getOption(xPDOZip::OVERWRITE, null, false) && is_writable($this->_filename)) {
  62                      if ($this->_archive->open($this->_filename, ZIPARCHIVE::OVERWRITE) !== true) {
  63                          $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "xPDOZip: Error opening archive at {$this->_filename} for OVERWRITE");
  64                      }
  65                  } else {
  66                      if ($this->_archive->open($this->_filename) !== true) {
  67                          $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "xPDOZip: Error opening archive at {$this->_filename}");
  68                      }
  69                  }
  70              } elseif ($this->getOption(xPDOZip::CREATE, null, false) && is_writable(dirname($this->_filename))) {
  71                  if ($this->_archive->open($this->_filename, ZIPARCHIVE::CREATE) !== true) {
  72                      $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "xPDOZip: Could not create archive at {$this->_filename}");
  73                  }
  74              } else {
  75                  $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "xPDOZip: The location specified is not writable: {$this->_filename}");
  76              }
  77          } else {
  78              $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "xPDOZip: The location specified does not exist: {$this->_filename}");
  79          }
  80      }
  81  
  82      /**
  83       * Pack the contents from the source into the archive.
  84       *
  85       * @todo Implement custom file filtering options
  86       *
  87       * @param string $source The path to the source file(s) to pack.
  88       * @param array $options An array of options for the operation.
  89       * @return array An array of results for the operation.
  90       */
  91      public function pack($source, array $options = array()) {
  92          $results = array();
  93          if ($this->_archive) {
  94              $target = $this->getOption(xPDOZip::ZIP_TARGET, $options, '');
  95              if (is_dir($source)) {
  96                  if ($dh = opendir($source)) {
  97                      if ($source[strlen($source) - 1] !== '/') $source .= '/';
  98                      $targetDir = rtrim($target, '/');
  99                      if (!empty($targetDir)) {
 100                          if ($this->_archive->addEmptyDir($targetDir)) {
 101                              $results[$target] = "Successfully added directory {$target} from {$source}";
 102                          } else {
 103                              $results[$target] = "Error adding directory {$target} from {$source}";
 104                              $this->_errors[] = $results[$target];
 105                          }
 106                      }
 107                      while (($file = readdir($dh)) !== false) {
 108                          if (is_dir($source . $file)) {
 109                              if (($file !== '.') && ($file !== '..')) {
 110                                  $results = $results + $this->pack($source . $file . '/', array_merge($options, array(xPDOZip::ZIP_TARGET => $target . $file . '/')));
 111                              }
 112                          } elseif (is_file($source . $file)) {
 113                              if ($this->_archive->addFile($source . $file, $target . $file)) {
 114                                  $results[$target . $file] = "Successfully packed {$target}{$file} from {$source}{$file}";
 115                              } else {
 116                                  $results[$target . $file] = "Error packing {$target}{$file} from {$source}{$file}";
 117                                  $this->_errors[] = $results[$target . $file];
 118                              }
 119                          } else {
 120                              $results[$target . $file] = "Error packing {$target}{$file} from {$source}{$file}";
 121                              $this->_errors[] = $results[$target . $file];
 122                          }
 123                      }
 124                  }
 125              } elseif (is_file($source)) {
 126                  $file = basename($source);
 127                  if ($this->_archive->addFile($source, $target . $file)) {
 128                      $results[$target . $file] = "Successfully packed {$target}{$file} from {$source}";
 129                  } else {
 130                      $results[$target . $file] = "Error packing {$target}{$file} from {$source}";
 131                      $this->_errors[] = $results[$target . $file];
 132                  }
 133              } else {
 134                  $this->_errors[]= "Invalid source specified: {$source}";
 135              }
 136          }
 137          return $results;
 138      }
 139  
 140      /**
 141       * Unpack the compressed contents from the archive to the target.
 142       *
 143       * @param string $target The path of the target location to unpack the files.
 144       * @param array $options An array of options for the operation.
 145       * @return array An array of results for the operation.
 146       */
 147      public function unpack($target, $options = array()) {
 148          $results = false;
 149          if ($this->_archive) {
 150              if (is_dir($target) && is_writable($target)) {
 151                  $results = $this->_archive->extractTo($target);
 152              }
 153          }
 154          return $results;
 155      }
 156  
 157      /**
 158       * Close the archive.
 159       */
 160      public function close() {
 161          if ($this->_archive) {
 162              $this->_archive->close();
 163          }
 164      }
 165  
 166      /**
 167       * Get an option from supplied options, the xPDOZip instance options, or xpdo itself.
 168       *
 169       * @param string $key Unique identifier for the option.
 170       * @param array $options A set of explicit options to override those from xPDO or the
 171       * xPDOZip instance.
 172       * @param mixed $default An optional default value to return if no value is found.
 173       * @return mixed The value of the option.
 174       */
 175      public function getOption($key, $options = null, $default = null) {
 176          $option = $default;
 177          if (is_array($key)) {
 178              if (!is_array($option)) {
 179                  $default= $option;
 180                  $option= array();
 181              }
 182              foreach ($key as $k) {
 183                  $option[$k]= $this->getOption($k, $options, $default);
 184              }
 185          } elseif (is_string($key) && !empty($key)) {
 186              if (is_array($options) && !empty($options) && array_key_exists($key, $options)) {
 187                  $option = $options[$key];
 188              } elseif (is_array($this->_options) && !empty($this->_options) && array_key_exists($key, $this->_options)) {
 189                  $option = $this->_options[$key];
 190              } else {
 191                  $option = $this->xpdo->getOption($key, null, $default);
 192              }
 193          }
 194          return $option;
 195      }
 196  
 197      /**
 198       * Detect if errors occurred during any operations.
 199       *
 200       * @return boolean True if errors exist, otherwise false.
 201       */
 202      public function hasError() {
 203          return !empty($this->_errors);
 204      }
 205  
 206      /**
 207       * Return any errors from operations on the archive.
 208       */
 209      public function getErrors() {
 210          return $this->_errors;
 211      }
 212  }

title

Description

title

Description

title

Description

title

title

Body