[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |