Virajsinh

unzipper

Jun 12th, 2021 (edited)
391
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 11.79 KB | None | 0 0
  1. <?php
  2. // Tutorial Link : https://www.youtube.com/watch?v=zB1zw2UIFOs
  3. // Download Link : https://github.com/ndeet/unzipper
  4.  
  5. /**
  6.  * The Unzipper extracts .zip or .rar archives and .gz files on webservers.
  7.  * It's handy if you do not have shell access. E.g. if you want to upload a lot
  8.  * of files (php framework or image collection) as an archive to save time.
  9.  * As of version 0.1.0 it also supports creating archives.
  10.  *
  11.  * @author  Andreas Tasch, at[tec], attec.at
  12.  * @license GNU GPL v3
  13.  * @package attec.toolbox
  14.  * @version 0.1.1
  15.  */
  16. define('VERSION', '0.1.1');
  17.  
  18. $timestart = microtime(TRUE);
  19. $GLOBALS['status'] = array();
  20.  
  21. $unzipper = new Unzipper;
  22. if (isset($_POST['dounzip'])) {
  23.     // Check if an archive was selected for unzipping.
  24.     $archive = isset($_POST['zipfile']) ? strip_tags($_POST['zipfile']) : '';
  25.     $destination = isset($_POST['extpath']) ? strip_tags($_POST['extpath']) : '';
  26.     $unzipper->prepareExtraction($archive, $destination);
  27. }
  28.  
  29. if (isset($_POST['dozip'])) {
  30.     $zippath = !empty($_POST['zippath']) ? strip_tags($_POST['zippath']) : '.';
  31.     // Resulting zipfile e.g. zipper--2016-07-23--11-55.zip.
  32.     $zipfile = 'zipper-' . date("Y-m-d--H-i") . '.zip';
  33.     Zipper::zipDir($zippath, $zipfile);
  34. }
  35.  
  36. $timeend = microtime(TRUE);
  37. $time = round($timeend - $timestart, 4);
  38.  
  39. /**
  40.  * Class Unzipper
  41.  */
  42. class Unzipper {
  43.     public $localdir = '.';
  44.     public $zipfiles = array();
  45.  
  46.     public function __construct() {
  47.         // Read directory and pick .zip, .rar and .gz files.
  48.         if ($dh = opendir($this->localdir)) {
  49.             while (($file = readdir($dh)) !== FALSE) {
  50.                 if (pathinfo($file, PATHINFO_EXTENSION) === 'zip'
  51.                     || pathinfo($file, PATHINFO_EXTENSION) === 'gz'
  52.                     || pathinfo($file, PATHINFO_EXTENSION) === 'rar'
  53.                 ) {
  54.                     $this->zipfiles[] = $file;
  55.             }
  56.         }
  57.         closedir($dh);
  58.  
  59.         if (!empty($this->zipfiles)) {
  60.             $GLOBALS['status'] = array('info' => '.zip or .gz or .rar files found, ready for extraction');
  61.         }
  62.         else {
  63.             $GLOBALS['status'] = array('info' => 'No .zip or .gz or rar files found. So only zipping functionality available.');
  64.         }
  65.     }
  66. }
  67.  
  68.     /**
  69.      * Prepare and check zipfile for extraction.
  70.      *
  71.      * @param string $archive
  72.      *   The archive name including file extension. E.g. my_archive.zip.
  73.      * @param string $destination
  74.      *   The relative destination path where to extract files.
  75.      */
  76.     public function prepareExtraction($archive, $destination = '') {
  77.         // Determine paths.
  78.         if (empty($destination)) {
  79.             $extpath = $this->localdir;
  80.         }
  81.         else {
  82.             $extpath = $this->localdir . '/' . $destination;
  83.             // Todo: move this to extraction function.
  84.             if (!is_dir($extpath)) {
  85.                 mkdir($extpath);
  86.             }
  87.         }
  88.         // Only local existing archives are allowed to be extracted.
  89.         if (in_array($archive, $this->zipfiles)) {
  90.             self::extract($archive, $extpath);
  91.         }
  92.     }
  93.  
  94.     /**
  95.      * Checks file extension and calls suitable extractor functions.
  96.      *
  97.      * @param string $archive
  98.      *   The archive name including file extension. E.g. my_archive.zip.
  99.      * @param string $destination
  100.      *   The relative destination path where to extract files.
  101.      */
  102.     public static function extract($archive, $destination) {
  103.         $ext = pathinfo($archive, PATHINFO_EXTENSION);
  104.         switch ($ext) {
  105.             case 'zip':
  106.             self::extractZipArchive($archive, $destination);
  107.             break;
  108.             case 'gz':
  109.             self::extractGzipFile($archive, $destination);
  110.             break;
  111.             case 'rar':
  112.             self::extractRarArchive($archive, $destination);
  113.             break;
  114.         }
  115.  
  116.     }
  117.  
  118.     /**
  119.      * Decompress/extract a zip archive using ZipArchive.
  120.      *
  121.      * @param $archive
  122.      * @param $destination
  123.      */
  124.     public static function extractZipArchive($archive, $destination) {
  125.         // Check if webserver supports unzipping.
  126.         if (!class_exists('ZipArchive')) {
  127.             $GLOBALS['status'] = array('error' => 'Error: Your PHP version does not support unzip functionality.');
  128.             return;
  129.         }
  130.  
  131.         $zip = new ZipArchive;
  132.  
  133.         // Check if archive is readable.
  134.         if ($zip->open($archive) === TRUE) {
  135.             // Check if destination is writable
  136.             if (is_writeable($destination . '/')) {
  137.                 $zip->extractTo($destination);
  138.                 $zip->close();
  139.                 $GLOBALS['status'] = array('success' => 'Files unzipped successfully');
  140.             }
  141.             else {
  142.                 $GLOBALS['status'] = array('error' => 'Error: Directory not writeable by webserver.');
  143.             }
  144.         }
  145.         else {
  146.             $GLOBALS['status'] = array('error' => 'Error: Cannot read .zip archive.');
  147.         }
  148.     }
  149.  
  150.     /**
  151.      * Decompress a .gz File.
  152.      *
  153.      * @param string $archive
  154.      *   The archive name including file extension. E.g. my_archive.zip.
  155.      * @param string $destination
  156.      *   The relative destination path where to extract files.
  157.      */
  158.     public static function extractGzipFile($archive, $destination) {
  159.         // Check if zlib is enabled
  160.         if (!function_exists('gzopen')) {
  161.             $GLOBALS['status'] = array('error' => 'Error: Your PHP has no zlib support enabled.');
  162.             return;
  163.         }
  164.  
  165.         $filename = pathinfo($archive, PATHINFO_FILENAME);
  166.         $gzipped = gzopen($archive, "rb");
  167.         $file = fopen($destination . '/' . $filename, "w");
  168.  
  169.         while ($string = gzread($gzipped, 4096)) {
  170.             fwrite($file, $string, strlen($string));
  171.         }
  172.         gzclose($gzipped);
  173.         fclose($file);
  174.  
  175.         // Check if file was extracted.
  176.         if (file_exists($destination . '/' . $filename)) {
  177.             $GLOBALS['status'] = array('success' => 'File unzipped successfully.');
  178.  
  179.             // If we had a tar.gz file, let's extract that tar file.
  180.             if (pathinfo($destination . '/' . $filename, PATHINFO_EXTENSION) == 'tar') {
  181.                 $phar = new PharData($destination . '/' . $filename);
  182.                 if ($phar->extractTo($destination)) {
  183.                     $GLOBALS['status'] = array('success' => 'Extracted tar.gz archive successfully.');
  184.                     // Delete .tar.
  185.                     unlink($destination . '/' . $filename);
  186.                 }
  187.             }
  188.         }
  189.         else {
  190.             $GLOBALS['status'] = array('error' => 'Error unzipping file.');
  191.         }
  192.  
  193.     }
  194.  
  195.     /**
  196.      * Decompress/extract a Rar archive using RarArchive.
  197.      *
  198.      * @param string $archive
  199.      *   The archive name including file extension. E.g. my_archive.zip.
  200.      * @param string $destination
  201.      *   The relative destination path where to extract files.
  202.      */
  203.     public static function extractRarArchive($archive, $destination) {
  204.         // Check if webserver supports unzipping.
  205.         if (!class_exists('RarArchive')) {
  206.             $GLOBALS['status'] = array('error' => 'Error: Your PHP version does not support .rar archive functionality. <a class="info" href="http://php.net/manual/en/rar.installation.php" target="_blank">How to install RarArchive</a>');
  207.             return;
  208.         }
  209.         // Check if archive is readable.
  210.         if ($rar = RarArchive::open($archive)) {
  211.             // Check if destination is writable
  212.             if (is_writeable($destination . '/')) {
  213.                 $entries = $rar->getEntries();
  214.                 foreach ($entries as $entry) {
  215.                     $entry->extract($destination);
  216.                 }
  217.                 $rar->close();
  218.                 $GLOBALS['status'] = array('success' => 'Files extracted successfully.');
  219.             }
  220.             else {
  221.                 $GLOBALS['status'] = array('error' => 'Error: Directory not writeable by webserver.');
  222.             }
  223.         }
  224.         else {
  225.             $GLOBALS['status'] = array('error' => 'Error: Cannot read .rar archive.');
  226.         }
  227.     }
  228.  
  229. }
  230.  
  231. /**
  232.  * Class Zipper
  233.  *
  234.  * Copied and slightly modified from http://at2.php.net/manual/en/class.ziparchive.php#110719
  235.  * @author umbalaconmeogia
  236.  */
  237. class Zipper {
  238.     /**
  239.      * Add files and sub-directories in a folder to zip file.
  240.      *
  241.      * @param string $folder
  242.      *   Path to folder that should be zipped.
  243.      *
  244.      * @param ZipArchive $zipFile
  245.      *   Zipfile where files end up.
  246.      *
  247.      * @param int $exclusiveLength
  248.      *   Number of text to be exclusived from the file path.
  249.      */
  250.     private static function folderToZip($folder, &$zipFile, $exclusiveLength) {
  251.         $handle = opendir($folder);
  252.  
  253.         while (FALSE !== $f = readdir($handle)) {
  254.             // Check for local/parent path or zipping file itself and skip.
  255.             if ($f != '.' && $f != '..' && $f != basename(__FILE__)) {
  256.                 $filePath = "$folder/$f";
  257.                 // Remove prefix from file path before add to zip.
  258.                 $localPath = substr($filePath, $exclusiveLength);
  259.  
  260.                 if (is_file($filePath)) {
  261.                     $zipFile->addFile($filePath, $localPath);
  262.                 }
  263.                 elseif (is_dir($filePath)) {
  264.                     // Add sub-directory.
  265.                     $zipFile->addEmptyDir($localPath);
  266.                     self::folderToZip($filePath, $zipFile, $exclusiveLength);
  267.                 }
  268.             }
  269.         }
  270.         closedir($handle);
  271.     }
  272.  
  273.     /**
  274.      * Zip a folder (including itself).
  275.      *
  276.      * Usage:
  277.      *   Zipper::zipDir('path/to/sourceDir', 'path/to/out.zip');
  278.      *
  279.      * @param string $sourcePath
  280.      *   Relative path of directory to be zipped.
  281.      *
  282.      * @param string $outZipPath
  283.      *   Relative path of the resulting output zip file.
  284.      */
  285.     public static function zipDir($sourcePath, $outZipPath) {
  286.         $pathInfo = pathinfo($sourcePath);
  287.         $parentPath = $pathInfo['dirname'];
  288.         $dirName = $pathInfo['basename'];
  289.  
  290.         $z = new ZipArchive();
  291.         $z->open($outZipPath, ZipArchive::CREATE);
  292.         $z->addEmptyDir($dirName);
  293.         if ($sourcePath == $dirName) {
  294.             self::folderToZip($sourcePath, $z, 0);
  295.         }
  296.         else {
  297.             self::folderToZip($sourcePath, $z, strlen("$parentPath/"));
  298.         }
  299.         $z->close();
  300.  
  301.         $GLOBALS['status'] = array('success' => 'Successfully created archive ' . $outZipPath);
  302.     }
  303. }
  304. ?>
  305.  
  306. <!DOCTYPE html>
  307. <html>
  308. <head>
  309.     <title>File Unzipper + Zipper</title>
  310.     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  311.     <style type="text/css">
  312.         <!--
  313.         body {
  314.             font-family: Arial, sans-serif;
  315.             line-height: 150%;
  316.         }
  317.  
  318.         label {
  319.             display: block;
  320.             margin-top: 20px;
  321.         }
  322.  
  323.         fieldset {
  324.             border: 0;
  325.             background-color: #EEE;
  326.             margin: 10px 0 10px 0;
  327.         }
  328.  
  329.         .select {
  330.             padding: 5px;
  331.             font-size: 110%;
  332.         }
  333.  
  334.         .status {
  335.             margin: 0;
  336.             margin-bottom: 20px;
  337.             padding: 10px;
  338.             font-size: 80%;
  339.             background: #EEE;
  340.             border: 1px dotted #DDD;
  341.         }
  342.  
  343.         .status--ERROR {
  344.             background-color: red;
  345.             color: white;
  346.             font-size: 120%;
  347.         }
  348.  
  349.         .status--SUCCESS {
  350.             background-color: green;
  351.             font-weight: bold;
  352.             color: white;
  353.             font-size: 120%
  354.         }
  355.  
  356.         .small {
  357.             font-size: 0.7rem;
  358.             font-weight: normal;
  359.         }
  360.  
  361.         .version {
  362.             font-size: 80%;
  363.         }
  364.  
  365.         .form-field {
  366.             border: 1px solid #AAA;
  367.             padding: 8px;
  368.             width: 280px;
  369.         }
  370.  
  371.         .info {
  372.             margin-top: 0;
  373.             font-size: 80%;
  374.             color: #777;
  375.         }
  376.  
  377.         .submit {
  378.             background-color: #378de5;
  379.             border: 0;
  380.             color: #ffffff;
  381.             font-size: 15px;
  382.             padding: 10px 24px;
  383.             margin: 20px 0 20px 0;
  384.             text-decoration: none;
  385.         }
  386.  
  387.         .submit:hover {
  388.             background-color: #2c6db2;
  389.             cursor: pointer;
  390.         }
  391.         -->
  392.     </style>
  393. </head>
  394. <body>
  395.     <p class="status status--<?php echo strtoupper(key($GLOBALS['status'])); ?>">
  396.         Status: <?php echo reset($GLOBALS['status']); ?><br/>
  397.         <span class="small">Processing Time: <?php echo $time; ?> seconds</span>
  398.     </p>
  399.     <form action="" method="POST">
  400.         <fieldset>
  401.             <h1>Archive Unzipper</h1>
  402.             <label for="zipfile">Select .zip or .rar archive or .gz file you want to extract:</label>
  403.             <select name="zipfile" size="1" class="select">
  404.                 <?php foreach ($unzipper->zipfiles as $zip) {
  405.                     echo "<option>$zip</option>";
  406.                 }
  407.                 ?>
  408.             </select>
  409.             <label for="extpath">Extraction path (optional):</label>
  410.             <input type="text" name="extpath" class="form-field" />
  411.             <p class="info">Enter extraction path without leading or trailing slashes (e.g. "mypath"). If left empty current directory will be used.</p>
  412.             <input type="submit" name="dounzip" class="submit" value="Unzip Archive"/>
  413.         </fieldset>
  414.  
  415.         <fieldset>
  416.             <h1>Archive Zipper</h1>
  417.             <label for="zippath">Path that should be zipped (optional):</label>
  418.             <input type="text" name="zippath" class="form-field" />
  419.             <p class="info">Enter path to be zipped without leading or trailing slashes (e.g. "zippath"). If left empty current directory will be used.</p>
  420.             <input type="submit" name="dozip" class="submit" value="Zip Archive"/>
  421.         </fieldset>
  422.     </form>
  423.     <p class="version">Unzipper version: <?php echo VERSION; ?></p>
  424. </body>
  425. </html>
Add Comment
Please, Sign In to add comment