Source for file tar.php

Documentation is available at tar.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Platform
  4.  * @subpackage  Archive
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE
  8.  */
  9.  
  10. defined('JPATH_PLATFORM'or die;
  11.  
  12. jimport('joomla.filesystem.file');
  13. jimport('joomla.filesystem.folder');
  14. jimport('joomla.filesystem.path');
  15.  
  16. /**
  17.  * Tar format adapter for the JArchive class
  18.  *
  19.  * This class is inspired from and draws heavily in code and concept from the Compress package of
  20.  * The Horde Project <http://www.horde.org>
  21.  *
  22.  * @contributor  Michael Slusarz <slusarz@horde.org>
  23.  * @contributor  Michael Cochrane <mike@graftonhall.co.nz>
  24.  *
  25.  * @package     Joomla.Platform
  26.  * @subpackage  Archive
  27.  * @since       11.1
  28.  */
  29. class JArchiveTar implements JArchiveExtractable
  30. {
  31.     /**
  32.      * Tar file types.
  33.      *
  34.      * @var    array 
  35.      * @since  11.1
  36.      */
  37.     private $_types array(
  38.         0x0 => 'Unix file',
  39.         0x30 => 'File',
  40.         0x31 => 'Link',
  41.         0x32 => 'Symbolic link',
  42.         0x33 => 'Character special file',
  43.         0x34 => 'Block special file',
  44.         0x35 => 'Directory',
  45.         0x36 => 'FIFO special file',
  46.         0x37 => 'Contiguous file');
  47.  
  48.     /**
  49.      * Tar file data buffer
  50.      *
  51.      * @var    string 
  52.      * @since  11.1
  53.      */
  54.     private $_data null;
  55.  
  56.     /**
  57.      * Tar file metadata array
  58.      *
  59.      * @var    array 
  60.      * @since  11.1
  61.      */
  62.     private $_metadata null;
  63.  
  64.     /**
  65.      * Extract a ZIP compressed file to a given path
  66.      *
  67.      * @param   string  $archive      Path to ZIP archive to extract
  68.      * @param   string  $destination  Path to extract archive into
  69.      * @param   array   $options      Extraction options [unused]
  70.      *
  71.      * @return  boolean True if successful
  72.      *
  73.      * @throws  RuntimeException
  74.      * @since   11.1
  75.      */
  76.     public function extract($archive$destinationarray $options array())
  77.     {
  78.         $this->_data null;
  79.         $this->_metadata null;
  80.  
  81.         $this->_data file_get_contents($archive);
  82.  
  83.         if (!$this->_data)
  84.         {
  85.             if (class_exists('JError'))
  86.             {
  87.                 return JError::raiseWarning(100'Unable to read archive');
  88.             }
  89.             else
  90.             {
  91.                 throw new RuntimeException('Unable to read archive');
  92.             }
  93.         }
  94.  
  95.         $this->_getTarInfo($this->_data);
  96.  
  97.         for ($i 0$n count($this->_metadata)$i $n$i++)
  98.         {
  99.             $type strtolower($this->_metadata[$i]['type']);
  100.  
  101.             if ($type == 'file' || $type == 'unix file')
  102.             {
  103.                 $buffer $this->_metadata[$i]['data'];
  104.                 $path JPath::clean($destination '/' $this->_metadata[$i]['name']);
  105.  
  106.                 // Make sure the destination folder exists
  107.                 if (!JFolder::create(dirname($path)))
  108.                 {
  109.                     if (class_exists('JError'))
  110.                     {
  111.                         return JError::raiseWarning(100'Unable to create destination');
  112.                     }
  113.                     else
  114.                     {
  115.                         throw new RuntimeException('Unable to create destination');
  116.                     }
  117.                 }
  118.                 if (JFile::write($path$buffer=== false)
  119.                 {
  120.                     if (class_exists('JError'))
  121.                     {
  122.                         return JError::raiseWarning(100'Unable to write entry');
  123.                     }
  124.                     else
  125.                     {
  126.                         throw new RuntimeException('Unable to write entry');
  127.                     }
  128.                 }
  129.             }
  130.         }
  131.         return true;
  132.     }
  133.  
  134.     /**
  135.      * Tests whether this adapter can unpack files on this computer.
  136.      *
  137.      * @return  boolean  True if supported
  138.      *
  139.      * @since   11.3
  140.      */
  141.     public static function isSupported()
  142.     {
  143.         return true;
  144.     }
  145.  
  146.     /**
  147.      * Get the list of files/data from a Tar archive buffer.
  148.      *
  149.      * @param   string  &$data  The Tar archive buffer.
  150.      *
  151.      * @return   array  Archive metadata array
  152.      *  <pre>
  153.      *  KEY: Position in the array
  154.      *  VALUES: 'attr'  --  File attributes
  155.      *  'data'  --  Raw file contents
  156.      *  'date'  --  File modification time
  157.      *  'name'  --  Filename
  158.      *  'size'  --  Original file size
  159.      *  'type'  --  File type
  160.      *  </pre>
  161.      *
  162.      * @since    11.1
  163.      */
  164.     protected function _getTarInfo($data)
  165.     {
  166.         $position 0;
  167.         $return_array array();
  168.  
  169.         while ($position strlen($data))
  170.         {
  171.             $info @unpack(
  172.                 "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/Ctypeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor",
  173.                 substr($data$position)
  174.             );
  175.  
  176.             if (!$info)
  177.             {
  178.                 if (class_exists('JError'))
  179.                 {
  180.                     return JError::raiseWarning(100'Unable to decompress data');
  181.                 }
  182.                 else
  183.                 {
  184.                     throw new RuntimeException('Unable to decompress data');
  185.                 }
  186.             }
  187.  
  188.             $position += 512;
  189.             $contents substr($data$positionoctdec($info['size']));
  190.             $position += ceil(octdec($info['size']512512;
  191.  
  192.             if ($info['filename'])
  193.             {
  194.                 $file array(
  195.                     'attr' => null,
  196.                     'data' => null,
  197.                     'date' => octdec($info['mtime']),
  198.                     'name' => trim($info['filename']),
  199.                     'size' => octdec($info['size']),
  200.                     'type' => isset($this->_types[$info['typeflag']]$this->_types[$info['typeflag']] null);
  201.  
  202.                 if (($info['typeflag'== 0|| ($info['typeflag'== 0x30|| ($info['typeflag'== 0x35))
  203.                 {
  204.                     /* File or folder. */
  205.                     $file['data'$contents;
  206.  
  207.                     $mode hexdec(substr($info['mode']43));
  208.                     $file['attr'(($info['typeflag'== 0x35'd' '-'(($mode 0x400'r' '-'(($mode 0x200'w' '-'.
  209.                         (($mode 0x100'x' '-'(($mode 0x040'r' '-'(($mode 0x020'w' '-'(($mode 0x010'x' '-'.
  210.                         (($mode 0x004'r' '-'(($mode 0x002'w' '-'(($mode 0x001'x' '-');
  211.                 }
  212.                 else
  213.                 {
  214.                     /* Some other type. */
  215.                 }
  216.                 $return_array[$file;
  217.             }
  218.         }
  219.         $this->_metadata $return_array;
  220.  
  221.         return true;
  222.     }
  223. }

Documentation generated on Tue, 19 Nov 2013 15:15:20 +0100 by phpDocumentor 1.4.3