[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/joomla/archive/src/ -> Gzip.php (source)

   1  <?php
   2  /**
   3   * Part of the Joomla Framework Archive Package
   4   *
   5   * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved.
   6   * @license    GNU General Public License version 2 or later; see LICENSE
   7   */
   8  
   9  namespace Joomla\Archive;
  10  
  11  use Joomla\Filesystem\File;
  12  use Joomla\Filesystem\Stream;
  13  
  14  /**
  15   * Gzip format adapter for the Archive package
  16   *
  17   * This class is inspired from and draws heavily in code and concept from the Compress package of
  18   * The Horde Project <http://www.horde.org>
  19   *
  20   * @contributor  Michael Slusarz <[email protected]>
  21   * @contributor  Michael Cochrane <[email protected]>
  22   *
  23   * @since  1.0
  24   */
  25  class Gzip implements ExtractableInterface
  26  {
  27      /**
  28       * Gzip file flags.
  29       *
  30       * @var    array
  31       * @since  1.0
  32       */
  33      private const FLAGS = ['FTEXT' => 0x01, 'FHCRC' => 0x02, 'FEXTRA' => 0x04, 'FNAME' => 0x08, 'FCOMMENT' => 0x10];
  34  
  35      /**
  36       * Gzip file data buffer
  37       *
  38       * @var    string
  39       * @since  1.0
  40       */
  41      private $data;
  42  
  43      /**
  44       * Holds the options array.
  45       *
  46       * @var    array|\ArrayAccess
  47       * @since  1.0
  48       */
  49      protected $options = [];
  50  
  51      /**
  52       * Create a new Archive object.
  53       *
  54       * @param   array|\ArrayAccess  $options  An array of options
  55       *
  56       * @since   1.0
  57       * @throws  \InvalidArgumentException
  58       */
  59  	public function __construct($options = [])
  60      {
  61          if (!\is_array($options) && !($options instanceof \ArrayAccess))
  62          {
  63              throw new \InvalidArgumentException(
  64                  'The options param must be an array or implement the ArrayAccess interface.'
  65              );
  66          }
  67  
  68          $this->options = $options;
  69      }
  70  
  71      /**
  72       * Extract a Gzip compressed file to a given path
  73       *
  74       * @param   string  $archive      Path to ZIP archive to extract
  75       * @param   string  $destination  Path to extract archive to
  76       *
  77       * @return  boolean  True if successful
  78       *
  79       * @since   1.0
  80       * @throws  \RuntimeException
  81       */
  82  	public function extract($archive, $destination)
  83      {
  84          $this->data = null;
  85  
  86          if (!isset($this->options['use_streams']) || $this->options['use_streams'] == false)
  87          {
  88              $this->data = file_get_contents($archive);
  89  
  90              if (!$this->data)
  91              {
  92                  throw new \RuntimeException('Unable to read archive');
  93              }
  94  
  95              $position = $this->getFilePosition();
  96              $buffer   = gzinflate(substr($this->data, $position, \strlen($this->data) - $position));
  97  
  98              if (empty($buffer))
  99              {
 100                  throw new \RuntimeException('Unable to decompress data');
 101              }
 102  
 103              if (!File::write($destination, $buffer))
 104              {
 105                  throw new \RuntimeException('Unable to write archive to file ' . $destination);
 106              }
 107          }
 108          else
 109          {
 110              // New style! streams!
 111              $input = Stream::getStream();
 112  
 113              // Use gz
 114              $input->set('processingmethod', 'gz');
 115  
 116              if (!$input->open($archive))
 117              {
 118                  throw new \RuntimeException('Unable to read archive');
 119              }
 120  
 121              $output = Stream::getStream();
 122  
 123              if (!$output->open($destination, 'w'))
 124              {
 125                  $input->close();
 126  
 127                  throw new \RuntimeException('Unable to open file "' . $destination . '" for writing');
 128              }
 129  
 130              do
 131              {
 132                  $this->data = $input->read($input->get('chunksize', 8196));
 133  
 134                  if ($this->data)
 135                  {
 136                      if (!$output->write($this->data))
 137                      {
 138                          $input->close();
 139  
 140                          throw new \RuntimeException('Unable to write archive to file ' . $destination);
 141                      }
 142                  }
 143              }
 144              while ($this->data);
 145  
 146              $output->close();
 147              $input->close();
 148          }
 149  
 150          return true;
 151      }
 152  
 153      /**
 154       * Tests whether this adapter can unpack files on this computer.
 155       *
 156       * @return  boolean  True if supported
 157       *
 158       * @since   1.0
 159       */
 160  	public static function isSupported()
 161      {
 162          return \extension_loaded('zlib');
 163      }
 164  
 165      /**
 166       * Get file data offset for archive
 167       *
 168       * @return  integer  Data position marker for archive
 169       *
 170       * @since   1.0
 171       * @throws  \RuntimeException
 172       */
 173  	public function getFilePosition()
 174      {
 175          // Gzipped file... unpack it first
 176          $position = 0;
 177          $info     = @ unpack('CCM/CFLG/VTime/CXFL/COS', substr($this->data, $position + 2));
 178  
 179          if (!$info)
 180          {
 181              throw new \RuntimeException('Unable to decompress data.');
 182          }
 183  
 184          $position += 10;
 185  
 186          if ($info['FLG'] & self::FLAGS['FEXTRA'])
 187          {
 188              $XLEN = unpack('vLength', substr($this->data, $position + 0, 2));
 189              $XLEN = $XLEN['Length'];
 190              $position += $XLEN + 2;
 191          }
 192  
 193          if ($info['FLG'] & self::FLAGS['FNAME'])
 194          {
 195              $filenamePos = strpos($this->data, "\x0", $position);
 196              $position    = $filenamePos + 1;
 197          }
 198  
 199          if ($info['FLG'] & self::FLAGS['FCOMMENT'])
 200          {
 201              $commentPos = strpos($this->data, "\x0", $position);
 202              $position   = $commentPos + 1;
 203          }
 204  
 205          if ($info['FLG'] & self::FLAGS['FHCRC'])
 206          {
 207              $hcrc = unpack('vCRC', substr($this->data, $position + 0, 2));
 208              $hcrc = $hcrc['CRC'];
 209              $position += 2;
 210          }
 211  
 212          return $position;
 213      }
 214  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer