Инсталятор модулей для Yii

Написано May 1, 2012

Довольно часто проекты на Yii используют модульную архитектуру, особенно, если это CMS. Но нигде не встречалось хорошего менеджера модулей для Yii. Хочется, что бы загрузил архив и все само распаковалось и выполнилось. Погрустил и решил реализовать хотя бы базовый принцип - упаковку и распаковку модулей. В будущем, собираюсь реализовать выполнение SQL при установке и удалении модуля. Все, что получилось выложено на гитхаб.

Упаковка модулей

Начнем с малого. Научим наш менеджер модулей упаковывать модули. Для этого добавим в каждую папку с модулем файлик "manifest.php", в котором будут описанны основные параметры нашего модуля:

<?php
return array(
    'title' => 'Alias Module',
    'description' => 'This module allows you to add and manage articles organized into categories.',
);

Список всех модулей выводится на главной странице приложения. Возле каждого модуля есть кнопка "упаковать". По нажатию на эту кнопку будет сгенерирован zip архив и отдан пользователю. Самое интересное в этом всем - это функция, которая делает zip:

function zip($source, $destination)
{

    $zip = new ZipArchive();

    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }

    if (is_dir($source) === true)
    {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        foreach ($files as $file)
        {

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

Работает эта функция вот так:

zip('path/to/zipfolder/', 'archive.zip');

В принципе, на этом с упаковкой все.

Распаковка

Тут все еще проще. Деалем форму с полем для загрузке архива;

class UploadForm extends CFormModel
{
    public $archive;

     public function rules(){
        return array(
            array('archive', 'file', 'types'=>'zip'),
        );
    }
}

Обрабатываем загрузку файла:

if (isset($_POST['UploadForm']))
{
    $form->archive = CUploadedFile::getInstance($form,'archive');
    $form->archive->saveAs(Yii::app()->params['uploadsFolder'] . '/' . $form->archive);
    $this->_unpack($form->archive);
}

И самам функция распаковки:

$archive = new ZipArchive();

$archive->open(Yii::app()->params['uploadsFolder'] . '/' . $archiveName);

$moduleName = str_replace('.zip', '',  $archiveName);

for ($i = 0; $i < $archive->numFiles; $i++) 
{
    @$archive->extractTo(Yii::app()->params['modulesFolder'] . '/' . $moduleName, array($archive->getNameIndex($i)));
}

$archive->close();

Я знаю, что @ - не самая лучшая практика, но это пока не страшно:)

Установка менеджера.

  • Скачать файлы в подпапку вашего приложения /install.
  • Указать актуальный путь к фреймворку(к yii.php) в файле /install/index.php
  • Указать актуальные пути в файле /install/config/params.php (modulesFolder, uploadsFolder)

Кроме этого, не забываем, что нужно ограничить доступ к нашему установщику. Это можно сделать по анологии с gii

Весь исходный код выложен на гитхабе

comments powered by Disqus