Advertisement
Guest User

T3X Reader

a guest
Oct 7th, 2014
54
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. define('PATH_T3X', 't3x');
  3. error_reporting(E_ALL & ~E_NOTICE);
  4.  
  5. class T3xProcessor {
  6.     private $t3xFile = '';
  7.     private $content = array();
  8.     private $viewableFiles = array(
  9.         // Images
  10.         'gif','png','jpg',
  11.         // PHP source
  12.         'php',
  13.         // HTML
  14.         'html','htm','tmpl',
  15.         // Plain Text
  16.         'txt','ts','sql', 'js','css','xml'
  17.     );
  18.  
  19.     private $type = 't3x';
  20.     private $compression = array();
  21.     private $t3dChunks = array();
  22.  
  23.     public function __construct($t3xFile) {
  24.         $this->t3xFile = $t3xFile;
  25.         $fileParts = explode('.', $t3xFile);
  26.         $this->type    = strtolower(array_pop($fileParts));
  27.  
  28.         switch($this->type) {
  29.             case 't3x':
  30.                 list($md5, $compress, $this->content) = explode(':', file_get_contents($t3xFile), 3);
  31.                 break;
  32.             case 't3d':
  33.                 $content = file_get_contents($t3xFile);
  34.                 while ($chunk = $this->parseT3dChunk($content)) {
  35.                     $this->t3dChunks[] = $chunk;
  36.                 }
  37.                 break;
  38.             default:
  39.                 throw new Exception('Unknown type: '.$this->type);
  40.         }
  41.  
  42.         switch($compress) {
  43.             case 'gzcompress':
  44.                 $this->compression[] = 'gzip';
  45.                 $this->content = gzuncompress($this->content);
  46.                 $contentMd5 = md5($this->content);
  47.                 break;
  48.             default:
  49.                 $contentMd5 = NULL;
  50.         }
  51.  
  52.         if ($contentMd5 && $md5 != $contentMd5) {
  53.             throw new Exception('Checksum failed, expected '.$md5.', have '.$contentMd5);
  54.         }
  55.  
  56.         if ($this->type=='t3x') {
  57.             $this->content = unserialize($this->content);
  58.         }
  59.     }
  60.  
  61.  
  62.     private function parseT3dChunk(&$content) {
  63.  
  64.         list($md5, $compress, $length, $content) = explode(':', $content, 4);
  65.  
  66.         if (!$content) {
  67.             return FALSE;
  68.         }
  69.  
  70.         $chunkLength = intval($length);
  71.         $chunk = substr($content, 0, $chunkLength);
  72.         $contentMd5 = md5($chunk);
  73.  
  74.         if ($md5 != $contentMd5) {
  75.             throw new Exception('Checksum failed, expected '.$md5.', have '.$contentMd5);
  76.         }
  77.  
  78.         if (intval($compress)) {
  79.             $chunk = gzuncompress($chunk);
  80.             $this->compression[] = 'gzip';
  81.         } else {
  82.             $this->compression[] = 'none';
  83.         }
  84.  
  85.         $content = substr($content, $chunkLength+1);
  86.  
  87.         return unserialize($chunk);
  88.     }
  89.  
  90.     private function setDownloadHeaders() {
  91.         header('Last-Modified: '.gmdate('D, d M Y H:i:s', $file['mtime']) . ' GMT');
  92.         header('Expires: Mon, 31 Jan 1996 00:13:37 GMT');
  93.         header('Pragma: no-cache');
  94.         header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
  95.         header('Content-Type: application/octet-stream');
  96.         header('Content-Transfer-Encoding: binary');
  97.         header('Connection: close');
  98.     }
  99.  
  100.     private function getExtension($filename) {
  101.         $filename = explode('.', $filename);
  102.         return strtolower(array_pop($filename));
  103.     }
  104.  
  105.     public function getFilename($path) {
  106.         $path = explode('/', $path);
  107.         return strtolower(array_pop($path));
  108.     }
  109.  
  110.     private function isViewable($filename) {
  111.         $filename = $this->getFilename($filename);
  112.         $ext = $this->getExtension($filename);
  113.  
  114.         $isDot = substr($filename, 0, 1)==='.';
  115.  
  116.         return (!$isDot && in_array($ext, $this->viewableFiles));
  117.     }
  118.  
  119.     public function showHeader() {
  120.         echo '<h2>Displaying '.substr($this->t3xFile,4)."</h2>\n";
  121.     }
  122.  
  123.     public function showProperties() {
  124.         echo '<div id="tab5"><ul>';
  125.  
  126.         $properties = array(
  127.             'Type: '.$this->type,
  128.             'Filesize: '.filesize($this->t3xFile).'B',
  129.             'Compression: '.implode(', ', array_unique($this->compression)),
  130.         );
  131.  
  132.         foreach ($properties as $property) {
  133.             echo '<li>'.$property."</li>\n";
  134.         }
  135.         echo '<li><a href="http://typo3.org/extensions/repository/view/' . $this->content['EM_CONF']['title'] . '" target="_blank">TER</a></li>';
  136.         echo '</ul></div>';
  137.     }
  138.  
  139.     public function showEmConf() {
  140.         echo '<div id="tab2">';
  141.         echo '<table cellspacing=0>';
  142.         echo '<tr><th>Key</th><th>&nbsp; Value</th></tr>';
  143.         if (is_array($this->content['EM_CONF'])) {
  144.             foreach($this->content['EM_CONF'] as $k=>$v) {
  145.                 echo '<tr class="data"><td>'.$k;
  146.                 echo '</td><td>: '.(is_array($v) ? '<pre>'.var_export($v).'</pre>' : $v);
  147.                 echo "</td></tr>\n";
  148.             }
  149.         }
  150.         echo "</table></div>\n\n";
  151.     }
  152.  
  153.     public function showFileIndex() {
  154.         echo '<div id="tab3">';
  155.         echo '<table cellspacing=0>';
  156.         echo "<tr><th>Name</th><th>Size</th><th>MTime</th><th>IsExec?</th><th>Valid?</th><th>Download</th></tr>\n";
  157.         foreach ($this->content['FILES'] as $filename=>$info) {
  158.  
  159.             if (substr(strtolower($info['name']),-4)=='.t3d') {
  160.                 $name = '<a href="t3x_reader.php?current_t3x='.$info['name'].'&extractfrom='.$this->t3xFile.'">'.$info['name'].'</a>';
  161.             } else {
  162.                 $name = $info['name'];
  163.             }
  164.  
  165.             echo '<tr class="data"><td>'.$name;
  166.             echo "</td><td>".$info['size'];
  167.             echo "</td><td>".date('Y-m-d H:i:s', $info['mtime']);
  168.             echo "</td><td>".($info['is_executable'] ? 'Yes' : 'No');
  169.             echo "</td><td>".($info['content_md5'] == md5($info['content']) ? 'Yes' : 'No');
  170.             echo '</td><td><a href="t3x_reader.php?t3x='.$this->t3xFile.'&a=dl&f='.$info['name'].'"><img src="../../famfamfam_silk_icons_v013/icons/bullet_disk.png" /></a>';
  171.             if ($this->isViewable($info['name'])) {
  172.                 echo ' &nbsp; <a href="t3x_reader.php?t3x='.$this->t3xFile.'&a=vw&f='.$info['name'].'" target="_blank"><img src="../../famfamfam_silk_icons_v013/icons/magnifier.png" /></a>';
  173.             }
  174.             echo "</td></tr>\n";
  175.         }
  176.         echo '</table></div>';
  177.     }
  178.  
  179.     public function showConvert() {
  180.         echo '<div id="tab4"><ul>';
  181.  
  182.         echo '<li><a href="t3x_reader.php?t3x='.$this->t3xFile.'&a=ar&t=zip">Download as ZIP</a>'."</li>\n";
  183.  
  184.         echo '</ul></div>';
  185.     }
  186.  
  187.     public function getFileContent($filename) {
  188.         return $this->content['FILES'][$filename]['content'];
  189.     }
  190.  
  191.     public function download($filename) {
  192.         $file = $this->content['FILES'][$filename];
  193.         $dlname = $this->getFilename($filename);
  194.  
  195.         $this->setDownloadHeaders();
  196.         header('Content-Length: '.$file['size']);
  197.         header('Content-Disposition: attachment; filename="'.$dlname.'"');
  198.  
  199.         echo $this->getFileContent($filename);
  200.  
  201.         flush();
  202.         exit();
  203.     }
  204.  
  205.     public function view($filename) {
  206.         $file = $this->content['FILES'][$filename];
  207.         $ext = explode('.', $filename);
  208.         $ext = strtolower($ext[count($ext)-1]);
  209.  
  210.         $mimetype = $content = null;
  211.  
  212.         switch ($ext) {
  213.             case 'gif':
  214.                 $mimetype = 'image/gif';
  215.                 $content  = $file['content'];
  216.                 break;
  217.             case 'png':
  218.                 $mimetype = 'image/png';
  219.                 $content  = $file['content'];
  220.                 break;
  221.             case 'jpg':
  222.                 $mimetype = 'image/jpg';
  223.                 $content  = $file['content'];
  224.                 break;
  225.             case 'php':
  226.                 $mimetype = 'text/html';
  227.                 $content  = highlight_string($file['content'], TRUE);
  228.                 break;
  229.             case 'html':
  230.             case 'htm':
  231.             case 'tmpl':
  232.                 $mimetype = 'text/html';
  233.                 $content  = $file['content'];
  234.                 break;
  235.             case 'txt':
  236.             case 'sql':
  237.             case 'ts':
  238.                 $mimetype = 'text/plain';
  239.                 $content  = $file['content'];
  240.                 break;
  241.             default:
  242.         }
  243.  
  244.  
  245.         if ($mimetype) {
  246.             header('Content-Type: '.$mimetype);
  247.             echo $content;
  248.             exit();
  249.         }
  250.     }
  251.  
  252.     public function archive($type) {
  253.         switch ($type) {
  254.             case 'zip':
  255.                 $this->archiveZip();
  256.                 break;
  257.         }
  258.     }
  259.  
  260.     public function archiveZip() {
  261.         $zip = new ZipArchive();
  262.         $zipFile = tempnam('.', 'tmp').'.zip';
  263.         if (TRUE !== ($r=$zip->open($zipFile, ZIPARCHIVE::CREATE))) {
  264.             throw new Exception('can not create zip archive '.$zipFile.' err='.$r);
  265.         }
  266.         foreach($this->content['FILES'] as $file) {
  267.             $zip->addFromString($file['name'], $file['content']);
  268.         }
  269.         $zip->close();
  270.  
  271.         $this->setDownloadHeaders();
  272.         header('Content-Length: '.filesize($zipFile));
  273.         header('Content-Disposition: attachment; filename="'.$this->getFilename($this->t3xFile).'.zip"');
  274.  
  275.         @readfile($zipFile);
  276.         flush();
  277.         unlink($zipFile);
  278.         exit();
  279.     }
  280. }
  281.  
  282. if (count($_GET)) {
  283.     switch ($_GET['a']) {
  284.         case 'dl':
  285.             $tp = new T3xProcessor($_GET['t3x']);
  286.             $tp->download($_GET['f']);
  287.             break;
  288.         case 'vw':
  289.             $tp = new T3xProcessor($_GET['t3x']);
  290.             $tp->view($_GET['f']);
  291.             break;
  292.         case 'ar':
  293.             $tp = new T3xProcessor($_GET['t3x']);
  294.             $tp->archive($_GET['t']);
  295.             break;
  296.     }
  297.     exit('invalid headers');
  298. }
  299.  
  300. @mkdir(PATH_T3X);
  301.  
  302. $t3x = NULL;
  303. if ($_SERVER['REQUEST_METHOD']=="POST") {
  304.     $up = $_FILES['upload_t3x'];
  305.  
  306.     if (filter_var($_POST['download_t3x'], FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED)) {
  307.         $path = parse_url($_POST['download_t3x'], PHP_URL_PATH);
  308.         $path = explode('/', $path);
  309.         array_pop($path);
  310.         $filename = implode('.', array_slice($path, 4));
  311.  
  312.         $content = file_get_contents($_POST['download_t3x']);
  313.         file_put_contents(PATH_T3X.DIRECTORY_SEPARATOR.$filename, $content);
  314.  
  315.         $t3x = PATH_T3X.DIRECTORY_SEPARATOR.$filename;
  316.         $_POST['current_t3x'] = $filename;
  317.  
  318.     } elseif (!$up['error'] && in_array(strtolower(substr($up['name'], -4)), array('.t3x','.t3d'))) { // file upload
  319.         // upload_t3x
  320.         $t3x = PATH_T3X.DIRECTORY_SEPARATOR.$up['name'];
  321.         copy($up['tmp_name'], $t3x);
  322.         $_POST['current_t3x'] = $up['name'];
  323.  
  324.     } elseif ($_POST['current_t3x']) {
  325.         $t3x = PATH_T3X.DIRECTORY_SEPARATOR.$_POST['current_t3x'];
  326.     }
  327. } elseif ($_GET['current_t3x']) {
  328.     $t3x = PATH_T3X.DIRECTORY_SEPARATOR.$_GET['current_t3x'];
  329.     if ($_GET['extractfrom']) {
  330.         $tp = new T3xProcessor($_GET['extractfrom']);
  331.         $t3x = PATH_T3X.DIRECTORY_SEPARATOR.$tp->getFilename($_GET['current_t3x']);
  332.         file_put_content($t3x, $tp->getFileContent($_GET['current_t3x']));
  333.         unset($tp);
  334.     }
  335. }
  336.  
  337. $options = '<option value="">-- Select T3X/T3D --</option>';
  338. $di = new DirectoryIterator(PATH_T3X);
  339. $files = array();
  340. foreach ($di as $fileInfo) {
  341.     if (!$fileInfo->isFile()) {
  342.         continue;
  343.     }
  344.     $ext = strtolower(substr($fileInfo->getFilename(), -4));
  345.     if (!in_array($ext, array('.t3x','.t3d'))) {
  346.         continue;
  347.     }
  348.     $files[] = $fileInfo->getFilename();
  349. }
  350. sort($files);
  351. foreach ($files as $filename) {
  352.     $selected = ($filename==$_POST['current_t3x'] ? 'selected="selected"' : '');
  353.     $options .= '<option value="'.$filename.'" '.$selected.'>'.$filename."</option>\n";
  354. }
  355.  
  356.  
  357.  
  358. if ($t3x) {
  359.     $tp = new T3xProcessor($t3x);
  360. }
  361. ?>
  362. <html>
  363. <head>
  364.     <title>T3X Reader</title>
  365.      <link href="https://code.jquery.com/ui/1.11.1/themes/blitzer/jquery-ui.css" rel="stylesheet" type="text/css" />
  366.  
  367.     <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
  368.     <script type="text/javascript" src="https://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
  369.     <style type="text/css">
  370. table {
  371.     padding: 0px;
  372. }
  373. th {
  374.     text-align: left;
  375.     background-color: silver;
  376.     padding-right: 10px;
  377. }
  378. td {
  379.     padding-right: 25px;
  380. }
  381. tr.data > td {
  382.     font-size: 11px;
  383. }
  384.  
  385. a > img {
  386.     border: 0;
  387. }
  388. div#tabs > div {
  389.     max-height: 380px;
  390.     overflow-y: scroll;
  391. }
  392. tr.even {
  393.     background-color: white;
  394. }
  395.     </style>
  396.     <script type="text/javascript">
  397.     jQuery.noConflict();
  398.     jQuery(document).ready(function(){
  399.         jQuery('#tabs').tabs();
  400.         jQuery('#tab3 table tr.data:even').addClass('even');
  401.     });
  402.     </script>
  403. </head>
  404. <body>
  405. <h1>T3X reader</h1>
  406. <?php
  407. if ($tp instanceof T3xProcessor) {
  408.     $tp->showHeader();
  409. }
  410.  
  411. ?>
  412. <div id="tabs" style="display:block">
  413.     <ul>
  414.         <li><a href="#tab1">Select T3X</a></li>
  415. <?php if ($tp instanceof T3xProcessor) { ?>
  416.         <li><a href="#tab5">Properties</a></li>
  417.         <li><a href="#tab2">EM-Conf</a></li>
  418.         <li><a href="#tab3">File list</a></li>
  419.         <li><a href="#tab4">Convert</a></li>
  420. <?php } ?>
  421.     </ul>
  422. <div id="tab1">
  423.     <p>Pick a T3X file to process or upload:</p>
  424.     <form method="POST" action="t3x_reader.php" enctype="multipart/form-data">
  425.     <table>
  426.         <tr><td>Process already uploaded file</td><td>: <select name="current_t3x"><?php echo $options; ?></select></td></tr>
  427.         <tr><td>URL to download T3X</td><td>: <input type="text" name="download_t3x" value="" /></td></tr>
  428.         <tr><td>Upload T3X file</td><td>: <input type="file" name="upload_t3x" value="" /></td></tr>
  429.         <tr><td>&nbsp;</td><td><input type="submit" value=" GO " /></td></tr>
  430.     </table>
  431.     </form>
  432. </div>
  433. <?php
  434. if ($tp instanceof T3xProcessor) {
  435.     $tp->showEmConf();
  436.     $tp->showProperties();
  437.     $tp->showFileIndex();
  438.     $tp->showConvert();
  439. }
  440. ?>
  441. </div>
  442. </body>
  443. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement