Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Public Member Functions | Data Fields | Protected Member Functions | Static Protected Member Functions | Protected Attributes
Tar Class Reference
Inheritance diagram for Tar:
AbstractArchive ArchiveInterface Tar

Public Member Functions

 pack ($source, $destination, $skipRoot=false)
 
 unpack ($source, $destination)
 
 extract ($file, $source, $destination)
 
- Public Member Functions inherited from AbstractArchive
 getFilename ($source, $withExtension=false)
 
- Public Member Functions inherited from ArchiveInterface
 pack ($source, $destination)
 

Data Fields

const TAR_BLOCK_SIZE = 512
 

Protected Member Functions

 _initWriter ()
 
 _destroyWriter ()
 
 _getWriter ()
 
 _initReader ()
 
 _destroyReader ()
 
 _getReader ()
 
 _setSkipRoot ($skipRoot)
 
 _setCurrentFile ($file)
 
 _setDestinationFilePath ($destinationFilePath)
 
 _getCurrentFile ()
 
 _setCurrentPath ($path)
 
 _getCurrentPath ()
 
 _createTar ($skipRoot=false, $finalize=false)
 
 _packAndWriteCurrentFile ()
 
 _composeHeader ($long=false)
 
 _unpackCurrentTar ($destination)
 
 _extractFileHeader ()
 
 _extractAndWriteFile ($fileHeader, $destination)
 
- Protected Member Functions inherited from AbstractArchive
 _writeFile ($destination, $data)
 
 _readFile ($source)
 

Static Protected Member Functions

static _getFormatParseHeader ()
 

Protected Attributes

 $_currentFile
 
 $_currentPath
 
 $_skipRoot
 
 $_writer
 
 $_reader
 
 $_destinationFilePath
 

Detailed Description

Definition at line 16 of file Tar.php.

Member Function Documentation

◆ _composeHeader()

_composeHeader (   $long = false)
protected

Compose header for current file in TAR format. If length of file's name greater 100 characters, method breaks header into two pieces. First contains header and data with long name. Second contain only header.

Parameters
bool$long
Returns
string @SuppressWarnings(PHPMD.CyclomaticComplexity) @SuppressWarnings(PHPMD.NPathComplexity)

Definition at line 319 of file Tar.php.

320  {
321  $file = $this->_getCurrentFile();
322  $path = $this->_getCurrentPath();
323  $infoFile = stat($file);
324  $nameFile = str_replace($path, '', $file);
325  $nameFile = str_replace('\\', '/', $nameFile);
326  $packedHeader = '';
327  $longHeader = '';
328  if (!$long && strlen($nameFile) > 100) {
329  $longHeader = $this->_composeHeader(true);
330  $longHeader .= str_pad($nameFile, floor((strlen($nameFile) + 512 - 1) / 512) * 512, "\0");
331  }
332  $header = [];
333  $header['100-name'] = $long ? '././@LongLink' : substr($nameFile, 0, 100);
334  $header['8-mode'] = $long ? ' ' : str_pad(
335  substr(sprintf("%07o", $infoFile['mode']), -4),
336  6,
337  '0',
338  STR_PAD_LEFT
339  );
340  $header['8-uid'] = $long || $infoFile['uid'] == 0 ? "\0\0\0\0\0\0\0" : sprintf("%07o", $infoFile['uid']);
341  $header['8-gid'] = $long || $infoFile['gid'] == 0 ? "\0\0\0\0\0\0\0" : sprintf("%07o", $infoFile['gid']);
342  $header['12-size'] = $long ? sprintf(
343  "%011o",
344  strlen($nameFile)
345  ) : sprintf(
346  "%011o",
347  is_dir($file) ? 0 : filesize($file)
348  );
349  $header['12-mtime'] = $long ? '00000000000' : sprintf("%011o", $infoFile['mtime']);
350  $header['8-check'] = sprintf('% 8s', '');
351  $header['1-type'] = $long ? 'L' : (is_link($file) ? 2 : (is_dir($file) ? 5 : 0));
352  $header['100-symlink'] = is_link($file) ? readlink($file) : '';
353  $header['6-magic'] = 'ustar ';
354  $header['2-version'] = ' ';
355  $a = function_exists('posix_getpwuid') ? posix_getpwuid(fileowner($file)) : ['name' => ''];
356  $header['32-uname'] = $a['name'];
357  $a = function_exists('posix_getgrgid') ? posix_getgrgid(filegroup($file)) : ['name' => ''];
358  $header['32-gname'] = $a['name'];
359  $header['8-devmajor'] = '';
360  $header['8-devminor'] = '';
361  $header['155-prefix'] = '';
362  $header['12-closer'] = '';
363 
364  $packedHeader = '';
365  foreach ($header as $key => $element) {
366  $length = explode('-', $key);
367  $packedHeader .= pack('a' . $length[0], $element);
368  }
369 
370  $checksum = 0;
371  for ($i = 0; $i < 512; $i++) {
372  $checksum += ord(substr($packedHeader, $i, 1));
373  }
374  $packedHeader = substr_replace($packedHeader, sprintf("%07o", $checksum) . "\0", 148, 8);
375 
376  return $longHeader . $packedHeader;
377  }
_composeHeader($long=false)
Definition: Tar.php:319
pack($source, $destination, $skipRoot=false)
Definition: Tar.php:529
$i
Definition: gallery.phtml:31
$element
Definition: element.phtml:12

◆ _createTar()

_createTar (   $skipRoot = false,
  $finalize = false 
)
protected

Recursively walk through file tree and create tarball

Parameters
bool$skipRoot
bool$finalize
Returns
void
Exceptions

Definition at line 245 of file Tar.php.

246  {
247  if (!$skipRoot) {
248  $this->_packAndWriteCurrentFile();
249  }
250 
251  $file = $this->_getCurrentFile();
252 
253  if (is_dir($file)) {
254  $dirFiles = scandir($file, SCANDIR_SORT_NONE);
255 
256  if (false === $dirFiles) {
257  throw new \Magento\Framework\Exception\LocalizedException(
258  new \Magento\Framework\Phrase('Can\'t scan dir: %1', [$file])
259  );
260  }
261 
262  array_shift($dirFiles);
263  /* remove './'*/
264  array_shift($dirFiles);
265  /* remove '../'*/
266 
267  foreach ($dirFiles as $item) {
268  $this->_setCurrentFile($file . $item)->_createTar();
269  }
270  }
271 
272  if ($finalize) {
273  $this->_getWriter()->write(str_repeat("\0", self::TAR_BLOCK_SIZE * 12));
274  }
275  }

◆ _destroyReader()

_destroyReader ( )
protected

Destroy tarball reader

Returns
$this

Definition at line 139 of file Tar.php.

140  {
141  if ($this->_reader instanceof File) {
142  $this->_reader->close();
143  $this->_reader = null;
144  }
145 
146  return $this;
147  }

◆ _destroyWriter()

_destroyWriter ( )
protected

Destroy tarball writer

Returns
$this

Definition at line 97 of file Tar.php.

98  {
99  if ($this->_writer instanceof File) {
100  $this->_writer->close();
101  $this->_writer = null;
102  }
103 
104  return $this;
105  }

◆ _extractAndWriteFile()

_extractAndWriteFile (   $fileHeader,
  $destination 
)
protected

Extract next file from tarball by its $header information and save it to $destination

Parameters
array$fileHeader
string$destination
Returns
void

Definition at line 499 of file Tar.php.

500  {
501  $fileWriter = new File($destination);
502  $fileWriter->open('w', $fileHeader['mode']);
503 
504  $archiveReader = $this->_getReader();
505 
506  $filesize = $fileHeader['size'];
507  $bytesExtracted = 0;
508 
509  while ($filesize > $bytesExtracted && !$archiveReader->eof()) {
510  $block = $archiveReader->read(self::TAR_BLOCK_SIZE);
511  $nonExtractedBytesCount = $filesize - $bytesExtracted;
512 
513  $data = substr($block, 0, $nonExtractedBytesCount);
514  $fileWriter->write($data);
515 
516  $bytesExtracted += strlen($block);
517  }
518  }
$block
Definition: block.php:8

◆ _extractFileHeader()

_extractFileHeader ( )
protected

Read and decode file header information from tarball

Returns
array|bool

Definition at line 441 of file Tar.php.

442  {
443  $archiveReader = $this->_getReader();
444 
445  $headerBlock = $archiveReader->read(self::TAR_BLOCK_SIZE);
446 
447  if (strlen($headerBlock) < self::TAR_BLOCK_SIZE) {
448  return false;
449  }
450 
451  $header = unpack(self::_getFormatParseHeader(), $headerBlock);
452 
453  $header['mode'] = octdec($header['mode']);
454  $header['uid'] = octdec($header['uid']);
455  $header['gid'] = octdec($header['gid']);
456  $header['size'] = octdec($header['size']);
457  $header['mtime'] = octdec($header['mtime']);
458  $header['checksum'] = octdec($header['checksum']);
459 
460  if ($header['type'] == "5") {
461  $header['size'] = 0;
462  }
463 
464  $checksum = 0;
465  $headerBlock = substr_replace($headerBlock, ' ', 148, 8);
466 
467  for ($i = 0; $i < 512; $i++) {
468  $checksum += ord(substr($headerBlock, $i, 1));
469  }
470 
471  $checksumOk = $header['checksum'] == $checksum;
472  if (isset($header['name']) && $checksumOk) {
473  $header['name'] = trim($header['name']);
474  if (!($header['name'] == '././@LongLink' && $header['type'] == 'L')) {
475  return $header;
476  }
477 
478  $realNameBlockSize = floor(
479  ($header['size'] + self::TAR_BLOCK_SIZE - 1) / self::TAR_BLOCK_SIZE
481  $realNameBlock = $archiveReader->read($realNameBlockSize);
482  $realName = substr($realNameBlock, 0, $header['size']);
483 
484  $headerMain = $this->_extractFileHeader();
485  $headerMain['name'] = trim($realName);
486  return $headerMain;
487  }
488 
489  return false;
490  }
unpack($source, $destination)
Definition: Tar.php:549
$i
Definition: gallery.phtml:31

◆ _getCurrentFile()

_getCurrentFile ( )
protected

Retrieve file which is packing.

Returns
string

Definition at line 205 of file Tar.php.

206  {
207  return $this->_currentFile;
208  }

◆ _getCurrentPath()

_getCurrentPath ( )
protected

Retrieve path to file which is packing.

Returns
string

Definition at line 232 of file Tar.php.

233  {
234  return $this->_currentPath;
235  }

◆ _getFormatParseHeader()

static _getFormatParseHeader ( )
staticprotected

Returns string that is used for tar's header parsing

Returns
string

Definition at line 86 of file Tar.php.

87  {
88  return 'a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100symlink/a6magic/a2version/' .
89  'a32uname/a32gname/a8devmajor/a8devminor/a155prefix/a12closer';
90  }

◆ _getReader()

_getReader ( )
protected

Get tarball reader

Returns
File

Definition at line 154 of file Tar.php.

155  {
156  if (!$this->_reader) {
157  $this->_initReader();
158  }
159 
160  return $this->_reader;
161  }

◆ _getWriter()

_getWriter ( )
protected

Get tarball writer

Returns
File

Definition at line 112 of file Tar.php.

113  {
114  if (!$this->_writer) {
115  $this->_initWriter();
116  }
117 
118  return $this->_writer;
119  }

◆ _initReader()

_initReader ( )
protected

Initialize tarball reader

Returns
$this

Definition at line 126 of file Tar.php.

127  {
128  $this->_reader = new File($this->_getCurrentFile());
129  $this->_reader->open('r');
130 
131  return $this;
132  }

◆ _initWriter()

_initWriter ( )
protected

Initialize tarball writer

Returns
$this

Definition at line 73 of file Tar.php.

74  {
75  $this->_writer = new File($this->_destinationFilePath);
76  $this->_writer->open('w');
77 
78  return $this;
79  }

◆ _packAndWriteCurrentFile()

_packAndWriteCurrentFile ( )
protected

Write current file to tarball

Returns
void

Definition at line 282 of file Tar.php.

283  {
284  $archiveWriter = $this->_getWriter();
285  $archiveWriter->write($this->_composeHeader());
286 
287  $currentFile = $this->_getCurrentFile();
288 
289  $fileSize = 0;
290 
291  if (is_file($currentFile) && !is_link($currentFile)) {
292  $fileReader = new File($currentFile);
293  $fileReader->open('r');
294 
295  while (!$fileReader->eof()) {
296  $archiveWriter->write($fileReader->read());
297  }
298 
299  $fileReader->close();
300 
301  $fileSize = filesize($currentFile);
302  }
303 
304  $appendZerosCount = (self::TAR_BLOCK_SIZE - $fileSize % self::TAR_BLOCK_SIZE) % self::TAR_BLOCK_SIZE;
305  $archiveWriter->write(str_repeat("\0", $appendZerosCount));
306  }
_composeHeader($long=false)
Definition: Tar.php:319

◆ _setCurrentFile()

_setCurrentFile (   $file)
protected

Set file which is packing.

Parameters
string$file
Returns
$this

Definition at line 181 of file Tar.php.

182  {
183  $file = str_replace('\\', '/', $file);
184  $this->_currentFile = $file . (!is_link($file) && is_dir($file) && substr($file, -1) != '/' ? '/' : '');
185  return $this;
186  }

◆ _setCurrentPath()

_setCurrentPath (   $path)
protected

Set path to file which is packing.

Parameters
string$path
Returns
$this

Definition at line 216 of file Tar.php.

217  {
218  $path = str_replace('\\', '/', $path);
219  if ($this->_skipRoot && is_dir($path)) {
220  $this->_currentPath = $path . (substr($path, -1) != '/' ? '/' : '');
221  } else {
222  $this->_currentPath = dirname($path) . '/';
223  }
224  return $this;
225  }

◆ _setDestinationFilePath()

_setDestinationFilePath (   $destinationFilePath)
protected

Set path to file where tarball should be placed

Parameters
string$destinationFilePath
Returns
$this

Definition at line 194 of file Tar.php.

195  {
196  $this->_destinationFilePath = $destinationFilePath;
197  return $this;
198  }

◆ _setSkipRoot()

_setSkipRoot (   $skipRoot)
protected

Set option that define ability skip first catalog level.

Parameters
bool$skipRoot
Returns
$this

Definition at line 169 of file Tar.php.

170  {
171  $this->_skipRoot = $skipRoot;
172  return $this;
173  }

◆ _unpackCurrentTar()

_unpackCurrentTar (   $destination)
protected

Read TAR string from file, and unpacked it. Create files and directories information about described in the string.

Parameters
string$destinationpath to file is unpacked
Returns
string[] list of files
Exceptions

Definition at line 389 of file Tar.php.

390  {
391  $archiveReader = $this->_getReader();
392  $list = [];
393 
394  while (!$archiveReader->eof()) {
395  $header = $this->_extractFileHeader();
396 
397  if (!$header) {
398  continue;
399  }
400 
401  $currentFile = $destination . $header['name'];
402  $dirname = dirname($currentFile);
403 
404  if (in_array($header['type'], ["0", chr(0), ''])) {
405  if (!file_exists($dirname)) {
406  $mkdirResult = @mkdir($dirname, 0777, true);
407 
408  if (false === $mkdirResult) {
409  throw new \Magento\Framework\Exception\LocalizedException(
410  new \Magento\Framework\Phrase('Failed to create directory %1', [$dirname])
411  );
412  }
413  }
414 
415  $this->_extractAndWriteFile($header, $currentFile);
416  $list[] = $currentFile;
417  } elseif ($header['type'] == '5') {
418  if (!file_exists($dirname)) {
419  $mkdirResult = @mkdir($currentFile, $header['mode'], true);
420 
421  if (false === $mkdirResult) {
422  throw new \Magento\Framework\Exception\LocalizedException(
423  new \Magento\Framework\Phrase('Failed to create directory %1', [$currentFile])
424  );
425  }
426  }
427  $list[] = $currentFile . '/';
428  } elseif ($header['type'] == '2') {
429  //we do not interrupt unpack process if symlink creation failed as symlinks are not so important
430  @symlink($header['symlink'], $currentFile);
431  }
432  }
433  return $list;
434  }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
_extractAndWriteFile($fileHeader, $destination)
Definition: Tar.php:499
mkdir($pathname, $mode=0777, $recursive=false, $context=null)
Definition: ioMock.php:25

◆ extract()

extract (   $file,
  $source,
  $destination 
)

Extract one file from TAR (Tape Archiver).

Parameters
string$file
string$source
string$destination
Returns
string

Definition at line 568 of file Tar.php.

569  {
570  $this->_setCurrentFile($source);
571  $this->_initReader();
572 
573  $archiveReader = $this->_getReader();
574  $extractedFile = '';
575 
576  while (!$archiveReader->eof()) {
577  $header = $this->_extractFileHeader();
578  if ($header['name'] == $file) {
579  $extractedFile = $destination . basename($header['name']);
580  $this->_extractAndWriteFile($header, $extractedFile);
581  break;
582  }
583 
584  if ($header['type'] != 5) {
585  $skipBytes = floor(
586  ($header['size'] + self::TAR_BLOCK_SIZE - 1) / self::TAR_BLOCK_SIZE
588  $archiveReader->read($skipBytes);
589  }
590  }
591 
592  $this->_destroyReader();
593  return $extractedFile;
594  }
$source
Definition: source.php:23
_extractAndWriteFile($fileHeader, $destination)
Definition: Tar.php:499

◆ pack()

pack (   $source,
  $destination,
  $skipRoot = false 
)

Pack file to TAR (Tape Archiver).

Parameters
string$source
string$destination
bool$skipRoot
Returns
string @SuppressWarnings(PHPMD.UnusedLocalVariable)

Definition at line 529 of file Tar.php.

530  {
531  $this->_setSkipRoot($skipRoot);
532  $source = realpath($source);
533  $tarData = $this->_setCurrentPath($source)->_setDestinationFilePath($destination)->_setCurrentFile($source);
534 
535  $this->_initWriter();
536  $this->_createTar($skipRoot, true);
537  $this->_destroyWriter();
538 
539  return $destination;
540  }
$source
Definition: source.php:23
_createTar($skipRoot=false, $finalize=false)
Definition: Tar.php:245

◆ unpack()

unpack (   $source,
  $destination 
)

Unpack file from TAR (Tape Archiver).

Parameters
string$source
string$destination
Returns
string

Implements ArchiveInterface.

Definition at line 549 of file Tar.php.

550  {
551  $this->_setCurrentFile($source)->_setCurrentPath($source);
552 
553  $this->_initReader();
554  $this->_unpackCurrentTar($destination);
555  $this->_destroyReader();
556 
557  return $destination;
558  }
$source
Definition: source.php:23
_unpackCurrentTar($destination)
Definition: Tar.php:389

Field Documentation

◆ $_currentFile

$_currentFile
protected

Definition at line 30 of file Tar.php.

◆ $_currentPath

$_currentPath
protected

Definition at line 37 of file Tar.php.

◆ $_destinationFilePath

$_destinationFilePath
protected

Definition at line 66 of file Tar.php.

◆ $_reader

$_reader
protected

Definition at line 59 of file Tar.php.

◆ $_skipRoot

$_skipRoot
protected

Definition at line 45 of file Tar.php.

◆ $_writer

$_writer
protected

Definition at line 52 of file Tar.php.

◆ TAR_BLOCK_SIZE

const TAR_BLOCK_SIZE = 512

Tar block size

@const int

Definition at line 23 of file Tar.php.


The documentation for this class was generated from the following file: