Skip to content

Dev.Module Installation

taiwen edited this page Mar 14, 2013 · 1 revision

How To Customized Installing, Uninstalling and Updating Function of Module

Contents

  • Introduction
  • Install
  • Update
  • Uninstall

Introduction

Pi have provided us the common methods to install, uninstall and update a module, but sometimes users want to operate with a special module under some conditions, such as:

  1. Initializing data of the database when installs;
  2. Modifying table data, add or remove table when updates;
  3. Removing some data from table when uninstalls.

Pi can help users to achieve this tasks, but fortunately it provides users a interface to add custom class for installing, uninstalling and updating.

In order to realize the function, users should add an Installer package in the src folder. The file structure is list as follows:

{module name}
 |--src
     |--Installer
         |--Action
             |--Install.php
             |--Unintall.php
             |--Update.php

Install

The Install.php file is used to realize some function when installs. It inherits from Pi\Application\Installer\Action\Install.

namespace Module\Demo\Installer\Action;
use Pi;
use Pi\Application\Installer\Action\Install as BasicInstall;
use Zend\EventManager\Event;

class Install extends BasicInstall
{
    ...
}

In the Install class, there should have a attachDefaultListeners() method, this method will override that of Pi\Application\Installer\Action\Install class. This method is used to define the method to call when installs.

protected function attachDefaultListeners()
{
    $events = $this->events;
    $events->attach('install.pre', array($this, 'preInstall'), 1000);
    $events->attach('install.post', array($this, 'postInstall'), 1);
    parent::attachDefaultListeners();
    return $this;
}

In this method, the install.pre parameter describes that the preInstall method will be executed before installs, and the install.post show that the postInstall method will be executed after installs.

The third parameter of attach method defines the priority to execute the methods.

According to the codes above, users should to create two method: preInstall and postInstall.

public function preInstall(Event $e)
{
    $result = array(
        'status'    => true,
        'message'   => sprintf('Called from %s', __METHOD__),
    );
    $e->setParam('result', $result);
}

public function postInstall(Event $e)
{
    $model = Pi::model($this->module . '/test');
    $data = array(
        'message'   => sprintf(__('The module is installed on %s'), date('Y-m-d H:i:s')),
    );
    $model->insert($data);

    $model = Pi::model($this->module . '/page');
    $flag = 0;
    for ($page = 1; $page <= 1000; $page++) {
        $model->insert(array(
            'title' => sprintf('Page #%d', $page),
            'flag'  => $flag++ % 2,
        ));
    }

    $result = array(
        'status'    => true,
        'message'   => sprintf('Called from %s', __METHOD__),
    );
    $e->setParam('result', $result);
}

Update

The Update.php is used to update module when user choose update button on the board of Pi application. The definition of this class is as same as that of Install class.

This class is inherits from Pi\Application\Installer\Action\Update:

namespace Module\Demo\Installer\Action;
use Pi;
use Pi\Application\Installer\Action\Update as BasicUpdate;
use Zend\EventManager\Event;

class Update extends BasicUpdate
{
    ...
}

Methods define in Update class is as same as that of Install:

protected function attachDefaultListeners()
{
    $events = $this->events;
    $events->attach('install.post', array($this, 'postUpdate'));
    parent::attachDefaultListeners();
    return $this;
}

public function postUpdate(Event $e)
{
    $model = Pi::model($module = $e->getParam('directory') . '/test');
    $data = array(
        'message'   => sprintf(__('The module is updated on %s'), date('Y-m-d H:i:s')),
    );
    $model->insert($data);

    $result = array(
        'status'    => true,
        'message'   => sprintf('Called from %s', __METHOD__),
    );
    $e->setParam('result', $result);
}

Uninstall

The Uninstall.php is used when users want to operate something during uninstalls. The definition of this class has nothing special.

namespace Module\System\Installer\Action;
use Pi;
use Pi\Application\Installer\Action\Uninstall as BasicUninstall;
use Zend\EventManager\Event;

class Uninstall extends BasicUninstall
{
    protected function attachDefaultListeners()
    {
        $events = $this->events;
        $events->attach('uninstall.pre', array($this, 'checkModules'), 1000);
        $events->attach('uninstall.post', array($this, 'dropTables'), -1000);
        parent::attachDefaultListeners();
        return $this;
    }

    public function checkModules(Event $e)
    {
        $module = $this->event->getParam('module');
        $model = Pi::model('module');
        $rowset = $model->select(array('dirname <> ?' => $module));
        if ($rowset->count() > 0) {
            $result = array(
                'status'    => false,
                'message'   => 'Modules are not unistalled completely.'
            );
            $e->setParam('result', $result);
            return false;
        }
        return true;
    }

    public function dropTables(Event $e)
    {
        $module = $this->event->getParam('module');
        $modelTable = Pi::model('module_schema');
        $rowset = $modelTable->select(array('module' => $module));
        foreach ($rowset as $row) {
            Pi::db()->adapter()->query('DROP TABLE IF EXISTS ' . Pi::db()->prefix($row->name, ''), 'execute');
        }
        return;
    }
}

NOTE:

  1. This class is inherits from Pi\Application\Installer\Action\Uninstall.

  2. The first parameter of attach method must be uninstall.pre or uninstall.post.

Clone this wiki locally