Несколько лет назад я работал с TYPO3 CMS, сама система меня не впечатлила ни по скорости работы, ни по коду.
От комментариев насчет качества кода воздержусь, это не тема данного поста :)

Все расширения для данной CMS идут в архиве собственного формата .t3x - самописное подобие TAR-а + gzip сжатие.
Руками распаковывать очень неудобно, поэтому родился следующий скрипт:

<?php

class ErrorHandler
{
    const HANDLER_METHOD_SUFFIX = "Handler";
    protected static $instance = null;
    protected static $instanceCalled = false;
   
    private $errors = array();
   
    protected function addError()
    {
        $this->errors[] = func_get_args();
    }
   
    protected function clearErrors()
    {
        $this->errors = array();
    }
   
    public function getErrors($clear = true)
    {
        $out = $this->errors;
        if($clear) {
            $this->clearErrors();
        }
        return $out;
    }
   
   
    public static function instance($classname = __CLASS__)
    {
        if(is_null(self::$instance))  {
            self::$instanceCalled = true;
            self::$instance = new $classname();
        }
        return self::$instance;
    }
   
    public function hook($handler="exception", $errorTypes = null)
    {
        if(is_null($errorTypes)) {
            $errorTypes = E_ALL | E_STRICT;
        }
        $method = $handler.self::HANDLER_METHOD_SUFFIX;
        $class = get_class($this);
        if(!method_exists($this, $method)) {
            throw new Exception("Method $class::$method doesn't exist");
        }
        set_error_handler(array($this, $method), $errorTypes);
    }
   
    public function unhook()
    {
        restore_error_handler();
    }

    public function exceptionHandler($errno, $errstr, $errfile, $errline)
    {   
        $this->addError(func_get_args());   
        throw new Exception($errstr, $errno);
    }
   
    public function verboseHandler($errno, $errstr, $errfile, $errline)
    {   
        $this->addError(func_get_args());
    }
}

class Dir
{
    public static function create($path, $mode = 0777, $recursive = true)
    {
        $path = self::normalize($path);
        if(file_exists($path) && is_dir($path)) {
            return;
        }                 
        mkdir($path, 0777, true);       
    }
   
    public static function normalize($path)
    {
        $path = trim($path);       
        $path = rtrim($path, ".");       
        $path = str_replace(array("/","\\"), DIRECTORY_SEPARATOR, $path);
        $path = rtrim($path, DIRECTORY_SEPARATOR);
        return $path;   
    }

}

class Dumper
{
    private $fileMode = "w";
   
    public function setAppendMode($arg = true)
    {
        $this->fileMode = (bool) $arg ? "a" : "w";
    }

    public function varDump($data, $file)
    {
        ob_start();
        var_dump($data);
        $out = ob_get_contents();
        ob_end_clean();
        $this->writeToFile($out, $file);
    }
   
    public function writeToFile($data, $f)
    {
        $f = fopen($f, $this->fileMode);
        if(!$f) {
            throw new Exception("Cannot write to $f");
        }       
        fwrite($f, $data);
        fclose($f);
    }
}

class TypoExtension
{
    const HEADER_SIZE = 44;
    private $isValid = false;
    private $fileObj = null;
    private $data = array();

    public function __construct()
    {
       
    }

    public function unpack($targetDir)
    {
        if(!isset($this->data['FILES'])) {
            return;
        }
        $targetDir = Dir::normalize($targetDir);               
        foreach($this->data['FILES'] as $row) {
            $dir = $targetDir.DIRECTORY_SEPARATOR.dirname($row['name']);
            Dir::create($dir);
            $file = Dir::normalize($targetDir.DIRECTORY_SEPARATOR.$row['name']);
            file_put_contents($file, $row['content']);
        }
   
    }
   
    public function read($file)
    {
        if(!file_exists($file)) {
            throw new Exception("No such file: '{$file}'");
        }
        if(!is_readable($file)) {
            throw new Exception("File is not readable: '{$file}'");
        }
        $f = @fopen($file, "r");   
        if(false === $f) {
            throw new Exception("Cannot open file: '{$file}'");
        }
       
        $size = $fileSize = filesize($file);
        if($fileSize < self::HEADER_SIZE) {
            throw new Exception("Size of file should be > ".self::HEADER_SIZE.": '{$file}'");
        }
       
        $size -= self::HEADER_SIZE;
        $head = fread($f, self::HEADER_SIZE);   
       
        /**
         * Parse params
         */

        $params  = explode(":", $head, 3);
        $gzencode = array_pop($params);
        $gzencode = array_pop($params);
        $fictiveCrc = array_pop($params);
        if($gzencode !== 'gzcompress') {
            throw new Exception("Invalid header found in file: '{$file}'");
        }
        $data = @fread($f, $size);       
        if(false === $data) {
            throw new Exception("Cannot read data from file: '{$file}'");
        }       
        $data = @gzuncompress  ($data);
        if(false === $data) {
            throw new Exception("Invalid data (not gzcompressed) in file: '{$file}'");
        }
        $this->data = @unserialize($data);
        if(unserialize(false) === $this->data) {
            throw new Exception("Invalid data (gzcompressed, but not serialized) in file: '{$file}'");           
        }
        return $this;
    }
}

class __app
{
    private static $singleton = null;
    private $argc;
    private $argv;
   
    public function instance()
    {
        if(is_null(self::$singleton)) {
            self::$singleton = new self();           
        }
        return self::$singleton;
    }
   
    public function setArgs($argv, $argc)
    {
        $this->argc = (int) $argc;
        $this->argv = (array) $argv;
    }
   
    public function checkArgs()
    {
        if(3 !== $this->argc) {       
            throw new Exception("Arguments should be: <file> <target>");
        }       
    }
   
    public function getArgs()
    {
        $this->checkArgs();
        return array($this->argv[1], $this->argv[2]);
    }

    public function run($argv, $argc)
    {       
        try {
            $this->setArgs($argv, $argc);           
            list($file, $dir) = $this->getArgs();           
            $c = new TypoExtension();
            $c->read($file)->unpack($dir);
        } catch (Exception $e) {
            printf("Error: %s\n", $e->getMessage());
            exit(1);
        }
        print "OK\n";
        exit(0);   
    }
}

if(empty($argv)) {
    print "Not running from command line\n";
    exit(0);
}
__app::instance()->run($argv, $argc);

?>



































































































































































































































Читайте также

  • Утилита для выбора зеркал пакетов в Archlinux
  • Домашнее задание № 3
  • бред двух прсиханутиков
  • ДЕБИЛОФИЛИЯ
  • Один вход - два выхода



  • Последние новости


    План занятий

    Обучение детей от года до 3 лет плаванию, как правило, проходит в три этапа. На первом этапе ребенок должен адаптироваться к воде, избавиться от страха перед глубиной, неизвестной средой. Намного проще дети привыкают к бассейну, где есть бортики, вода теплая и прозрачная. Чуть сложнее дети адаптируются к открытым водоемам с темной и прохладной ...
    Читать далее »

    Гимнастика от 2 лет до 2 лет 6 месяцев

    1. Самостоятельная ходьба. 2. Бег вдогонку за взрослым или к взрослому в разном темпе. 3. Руки вверх, потянуться – «деревья большие большие», развести руки в стороны. 4. Ходьба по доске, приподнятой над полом на 15–20 см. 5. Приседания. 6. Подъем туловища с опорой на ладони в положении лежа на животе. 7. Хлопк...
    Читать далее »

    Проблема: ожоги, ушибы, травмы

    Немного повзрослев, ребенок начинает интересоваться источниками огня, что чревато ожогом. При незначительном ожоге необходимо поврежденный участок тела поместить под холодную проточную воду, а затем обработать антиожоговым аэрозолем. В период выздоровления применяют массаж, который способствует улучшению лимфо– и кровотока. В резуль...
    Читать далее »

    Проблема: плоскостопие

    Когда ребенок начинает ходить, его первые шаги могут быть омрачены плоскостопием. К сожалению, если эта болезнь наследственная, то волнения вполне обоснованны. И здесь без посещения детского врача ортопеда не обойтись. Его рекомендации относятся к укреплению подошвенного свода стопы вашего ребенка. Костная структура стопы ребенка ...
    Читать далее »

    Рефлекторные движения

    Рефлекторные гимнастические упражнения, В основе которых лежат врожденные двигательные рефлекторные реакции, проводятся первые три пять месяцев жизни ребенка, когда еще не утрачены безусловные двигательные рефлексы – «автоматическая походка», ладонно ротовой рефлекс, хоботковый рефлекс, сохранение равновесия, защитно оборонительные рефлексы. Рефлекторные гимнасти...
    Читать далее »

    Техника выполнения: растирание

    Прямолинейное растирание Выполняется концевыми фалангами одного или нескольких пальцев. Движение проводится прямолинейно одной рукой или обеими, иногда с отягощением. Круговое растирание Проводится с помощью круговых движений концевыми фалангами одного или нескольких пальцев. Кисть располагается с опорой на основании ладони, а манипуляции выполняют в сторону мизинца одной рук...
    Читать далее »

    Проблема: пупочная грыжа

    Пупочная грыжа – это патологическое состояние, в котором через несколько расширенное пупочное кольцо происходит выпячивание брюшины, сальника и даже кишечника. Причина заболевания следующая: вследствие дефекта передней брюшной стенки и пупочного кольца проявляется округлое или овальное выпячивание. Чаще факторами, провоцирующими повышение внутрибрюшного давления, являются кашель, запоры ...
    Читать далее »