<?php
/**
 * Copyright Zikula Foundation 2009 - Zikula Application Framework
 *
 * This work is contributed to the Zikula Foundation under one or more
 * Contributor Agreements and licensed to You under the following license:
 *
 * @license GNU/LGPLv3 (or at your option, any later version).
 * @package Zikula
 *
 * Please see the NOTICE file distributed with this source code for further
 * information regarding copyright and licensing.
 */

/**
 * Extensions_Controller_Admin class.
 */
class Extensions_Controller_Admin extends Zikula_AbstractController
{
    /**
     * Post initialise.
     *
     * @return void
     */
    protected function postInitialize()
    {
        // In this controller we do not want caching.
        $this->view->setCaching(Zikula_View::CACHE_DISABLED);
    }

    /**
     * Extensions Module main admin function
     *
     * @return string HTML output string
     */
    public function main()
    {
        // Security check will be done in view()
        $this->redirect(ModUtil::url('Extensions', 'admin', 'view'));
    }

    /**
     * Extensions_admin_modify - modify a module.
     *
     * @return string HTML output string.
     */
    public function modify()
    {
        $id = (int) FormUtil::getPassedValue('id', null, 'GET');
        if (!is_numeric($id)) {
            return LogUtil::registerArgsError(ModUtil::url('Extensions', 'admin', 'view'));
        }

        $obj = ModUtil::getInfo($id);
        if (!isset($id) || $obj == false) {
            return LogUtil::registerError($this->__('Error! No such module ID exists.'),
                    404,
                    ModUtil::url('Extensions', 'admin', 'modify', array('id' => $id)));
        }

        if (!SecurityUtil::checkPermission('Extensions::', "$obj[name]::$id", ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        $restore = (bool)FormUtil::getPassedValue('restore', false, 'GET');
        if ($restore) {
            // load the version array
            $baseDir = ($obj['type'] == ModUtil::TYPE_SYSTEM) ? 'system' : 'modules';

            // load gettext domain for 3rd party modules
            if ($baseDir == 'modules' && is_dir("modules/$obj[directory]/locale")) {
                // This is required here since including pnversion automatically executes the pnversion code
                // this results in $this->__() caching the result before the domain is bounded.  Will not occur in zOO
                // since loading is self contained in each zOO application.
                ZLanguage::bindModuleDomain($obj['directory']);
            }

            $modversion = Extensions_Util::getVersionMeta($obj['directory'], $baseDir);

            // load defaults
            $name = (isset($modversion['name']) ? $modversion['name'] : '');
            $displayname = (isset($modversion['displayname']) ? $modversion['displayname'] : $name);
            $url = (isset($modversion['url']) ? $modversion['url'] : $displayname);
            $description = (isset($modversion['description']) ? $modversion['description'] : '');

            $obj = array(
                    'id' => $id,
                    'displayname' => $displayname,
                    'url' => $url,
                    'description' => $description);
        }

        $this->view->assign($obj);

        // Return the output that has been generated by this function
        return $this->view->fetch('extensions_admin_modify.tpl');
    }

    /**
     * Extensions_admin_update - update a module
     * @return string HTML output string
     * @param int 'id' module id
     * @param string 'newdisplayname' new display name of the module
     * @param string 'newdescription' new description of the module
     */
    public function update()
    {
        $this->checkCsrfToken();

        // Get parameters
        $id = (int) FormUtil::getPassedValue('id', null, 'POST');
        $newdisplayname = FormUtil::getPassedValue('newdisplayname', null, 'POST');
        $newdescription = FormUtil::getPassedValue('newdescription', null, 'POST');
        $newurl = FormUtil::getPassedValue('newurl', null, 'POST');

        // Pass to API
        if (ModUtil::apiFunc('Extensions', 'admin', 'update', array(
        'id' => $id,
        'displayname' => $newdisplayname,
        'description' => $newdescription,
        'url' => $newurl))) {
            // Success
            LogUtil::registerStatus($this->__('Done! Saved module information.'));
        } else {
            $this->redirect(ModUtil::url('Extensions', 'admin', 'modify', array('id' => $id)));
        }

        $this->redirect(ModUtil::url('Extensions', 'admin', 'view'));
    }

    /**
     * Extensions_admin_update hooks
     * update hooks for a module
     * @param int 'id' module id
     * @return bool true if successful, false otherwise
     */
    public function updatehooks()
    {
        $this->checkCsrfToken();

        // Get parameters
        $id = (int) FormUtil::getPassedValue('id', null, 'REQUEST');

        // Pass to API
        if (ModUtil::apiFunc('Extensions', 'admin', 'updatehooks', array(
        'id' => $id))) {
            // Success
            LogUtil::registerStatus($this->__('Done! Saved module information.'));
        }

        $this->redirect(ModUtil::url('Extensions', 'admin', 'view'));
    }

    /**
     * Extensions_admin_update hooks, extended version
     * update hooks for a module
     * @param int 'id' module id
     * @return bool true if successful, false otherwise
     */
    public function extendedupdatehooks()
    {
        $this->checkCsrfToken();

        // Get parameters
        $id = (int) FormUtil::getPassedValue('id', null, 'REQUEST');

        // Pass to API
        if (ModUtil::apiFunc('Extensions', 'admin', 'extendedupdatehooks', array(
        'id' => $id))) {
            // Success
            LogUtil::registerStatus($this->__('Done! Saved module information.'));
        }

        $this->redirect(ModUtil::url('Extensions', 'admin', 'view'));
    }

    /**
     * Extensions_admin_view - list modules and current settings
     * @return string HTML output string
     */
    public function view()
    {
        // Security check
        if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // Get parameters from whatever input we need.
        $modinfo = $this->getModInfo();
        $startnum = (int) FormUtil::getPassedValue('startnum', null, 'GET');
        $letter = FormUtil::getPassedValue('letter', null, 'GET');
        $state = FormUtil::getPassedValue('state', (!strstr(System::serverGetVar('HTTP_REFERER'), 'module='.$modinfo['url'])) ? null : SessionUtil::getVar('state', null), 'GETPOST');
        $sort = FormUtil::getPassedValue('sort', (!strstr(System::serverGetVar('HTTP_REFERER'), 'module='.$modinfo['url'])) ? null : SessionUtil::getVar('sort', null), 'GET');
        $sortdir = FormUtil::getPassedValue('sortdir', (!strstr(System::serverGetVar('HTTP_REFERER'), 'module='.$modinfo['url'])) ? null : SessionUtil::getVar('sortdir', null), 'GET');

        // parameter for used sort order
        if ($sort != 'name' && $sort != 'displayname') $sort = 'name';
        if ($sortdir != 'ASC' && $sortdir != 'DESC') $sortdir = 'ASC';

        // save the current values
        SessionUtil::setVar('state', $state);
        SessionUtil::setVar('sort', $sort);
        SessionUtil::setVar('sortdir', $sortdir);

        // do some clean up
        SessionUtil::delVar('interactive_init');
        SessionUtil::delVar('interactive_remove');
        SessionUtil::delVar('interactive_upgrade');

        if ($this->serviceManager['multisites.enabled'] != 1 || ($this->serviceManager['multisites.mainsiteurl'] == FormUtil::getPassedValue('sitedns', null, 'GET') && $this->serviceManager['multisites.based_on_domains'] == 0) || ($this->serviceManager['multisites.mainsiteurl'] == $_SERVER['HTTP_HOST'] && $this->serviceManager['multisites.based_on_domains'] == 1)) {
            // always regenerate modules list
            $filemodules = ModUtil::apiFunc('Extensions', 'admin', 'getfilemodules');
            $inconsistencies = ModUtil::apiFunc('Extensions', 'admin', 'checkconsistency', array('filemodules' => $filemodules));

            if (!(empty($inconsistencies['errors_modulenames']) && empty($inconsistencies['errors_displaynames']))) {
                $this->view->assign('errors_modulenames', $inconsistencies['errors_modulenames'])
                           ->assign('errors_displaynames', $inconsistencies['errors_displaynames']);

                return $this->view->fetch('extensions_admin_regenerate_errors.tpl');
            }

            // No inconsistencies, so we can regenerate modules
            $defaults = (int) FormUtil::getPassedValue('defaults', false, 'GET');
            if (!ModUtil::apiFunc('Extensions', 'admin', 'regenerate', array('filemodules' => $filemodules, 'defaults' => $defaults))) {
                LogUtil::registerError($this->__('Errors were detected regenerating the modules list from file system.'));
            }
        }

        // assign the state filter
        $this->view->assign('state', $state);

        // Get list of modules
        $mods = ModUtil::apiFunc('Extensions', 'admin', 'listmodules',
                                 array('startnum' => $startnum,
                                       'letter' => $letter,
                                       'state' => $state,
                                       'numitems' => $this->getVar('itemsperpage'),
                                       'sortdir' => $sortdir,
                                       'sort' => $sort));

        // generate an auth key to use in urls
        $csrftoken = SecurityUtil::generateCsrfToken($this->serviceManager, true);

        $moduleinfo = array();
        if (!empty($mods)) {
            foreach ($mods as $mod) {
                // Add applicable actions
                $actions = array();

                if (SecurityUtil::checkPermission('Extensions::', "$mod[name]::$mod[id]", ACCESS_ADMIN)) {
                    switch ($mod['state']) {
                        case ModUtil::STATE_ACTIVE:
                            if (!ModUtil::apiFunc('Extensions', 'admin', 'iscoremodule', array('modulename' => $mod['name']))) {
                                $actions[] = array(
                                        'url' => ModUtil::url('Extensions', 'admin', 'deactivate', array(
                                        'id' => $mod['id'],
                                        'startnum' => $startnum,
                                        'csrftoken' => $csrftoken,
                                        'letter' => $letter,
                                        'state' => $state)),
                                        'image' => 'folder_red.png',
                                        'title' => $this->__f('Deactivate \'%s\' module', $mod['name']));
                            }

                            if (System::isLegacyMode() && !ModUtil::isOO($mod['name'])) {
                                $actions[] = array(
                                        'url' => ModUtil::url('Extensions', 'admin', 'legacyhooks', array(
                                        'id' => $mod['id'])),
                                        'image' => 'attach.png',
                                        'title' => $this->__f('Legacy hook settings for \'%s\'', $mod['name']));
                            }

                            if (PluginUtil::hasModulePlugins($mod['name'])) {
                                $actions[] = array(
                                        'url' => ModUtil::url('Extensions', 'admin', 'viewPlugins', array(
                                        'bymodule' => $mod['name'])),
                                        'image' => 'blockdevice.png',
                                        'title' => $this->__f('Plugins for \'%s\'', $mod['name']));
                            }
                            break;

                        case ModUtil::STATE_INACTIVE:
                            $actions[] = array(
                                    'url' => ModUtil::url('Extensions', 'admin', 'activate', array(
                                    'id' => $mod['id'],
                                    'startnum' => $startnum,
                                    'csrftoken' => $csrftoken,
                                    'letter' => $letter,
                                    'state' => $state)),
                                    'image' => 'folder_green.png',
                                    'title' => $this->__f('Activate \'%s\'', $mod['name']));
                            $actions[] = array(
                                    'url' => ModUtil::url('Extensions', 'admin', 'remove', array(
                                    'id' => $mod['id'],
                                    'startnum' => $startnum,
                                    'letter' => $letter,
                                    'state' => $state)),
                                    'image' => '14_layer_deletelayer.png',
                                    'title' => $this->__f('Uninstall \'%s\' module', $mod['name']));
                            break;

                        case ModUtil::STATE_MISSING:
                            $actions[] = array(
                                    'url' => ModUtil::url('Extensions', 'admin', 'remove', array(
                                    'id' => $mod['id'],
                                    'startnum' => $startnum,
                                    'letter' => $letter,
                                    'state' => $state)),
                                    'image' => '14_layer_deletelayer.png',
                                    'title' => $this->__f('Remove \'%s\' module', $mod['name']));
                            break;
                        case ModUtil::STATE_UPGRADED:
                            $actions[] = array(
                                    'url' => ModUtil::url('Extensions', 'admin', 'upgrade', array(
                                    'id' => $mod['id'],
                                    'startnum' => $startnum,
                                    'csrftoken' => $csrftoken,
                                    'letter' => $letter,
                                    'state' => $state)),
                                    'image' => 'folder_favorites.png',
                                    'title' => $this->__f('Upgrade \'%s\'', $mod['name']));
                            break;

                        case ModUtil::STATE_INVALID:
                        // nothing to do, remove manually
                        // future wish list, allow removal if FS is writable
                        /*
                        $actions[] = array(
                            'url' => ModUtil::url('Extensions', 'admin', 'remove', array(
                                'id' => $mod['id'],
                                'startnum' => $startnum,
                                'authid' => $authid,
                                'letter' => $letter,
                                'state' => $state)),
                            'image' => '14_layer_deletelayer.png',
                            'title' => $this->__('Remove module')); */
                            break;

                        case ModUtil::STATE_NOTALLOWED:
                            $actions[] = array(
                                    'url' => ModUtil::url('Extensions', 'admin', 'remove', array(
                                    'id' => $mod['id'],
                                    'startnum' => $startnum,
                                    'csrftoken' => $csrftoken,
                                    'letter' => $letter,
                                    'state' => $state)),
                                    'image' => '14_layer_deletelayer.png',
                                    'title' => $this->__f('Remove \'%s\' module', $mod['name']));
                            break;

                        case ModUtil::STATE_UNINITIALISED:
                        default:
                            if ($mod['state'] < 10) {
                                $actions[] = array(
                                        'url' => ModUtil::url('Extensions', 'admin', 'initialise', array(
                                        'id' => $mod['id'],
                                        'startnum' => $startnum,
                                        'csrftoken' => $csrftoken,
                                        'letter' => $letter,
                                        'state' => $state)),
                                        'image' => 'folder_new.png',
                                        'title' => $this->__f('Install \'%s\'', $mod['name']));
//                                if ($this->serviceManager['multisites.enabled'] != 1 || ($this->serviceManager['multisites.mainsiteurl'] == FormUtil::getPassedValue('sitedns', null, 'GET') && $this->serviceManager['multisites.based_on_domains'] == 0) || ($this->serviceManager['multisites.mainsiteurl'] == $_SERVER['HTTP_HOST'] && $this->serviceManager['multisites.based_on_domains'] == 1)) {
//                                    $actions[] = array(
//                                            'url' => ModUtil::url('Extensions', 'admin', 'remove', array(
//                                            'id' => $mod['id'],
//                                            'startnum' => $startnum,
//                                            'authid' => $authid,
//                                            'letter' => $letter,
//                                            'state' => $state)),
//                                            'image' => '14_layer_deletelayer.png',
//                                            'title' => $this->__('Remove module'));
//                                }
                            } else {
                                $actions[] = array(
                                        'url' => ModUtil::url('Extensions', 'admin', 'compinfo', array(
                                        'id' => $mod['id'],
                                        'startnum' => $startnum,
                                        'letter' => $letter,
                                        'state' => $state)),
                                        'image' => 'documentinfo.png',
                                        'title' => $this->__f('Incompatible version: \'%s\'', $mod['name']));
                            }
                            break;
                    }

                    // RNG: can't edit an invalid module
                    if ($mod['state'] != ModUtil::STATE_INVALID) {
                        $actions[] = array(
                                'url' => ModUtil::url('Extensions', 'admin', 'modify', array(
                                'id' => $mod['id'])),
                                'image' => 'xedit.png',
                                'title' => $this->__f('Edit \'%s\'', $mod['name']));
                    }
                }

                // Translate state
                switch ($mod['state']) {
                    case ModUtil::STATE_INACTIVE:
                        $status = $this->__('Inactive');
                        $statusimage = 'yellowled.png';
                        break;

                    case ModUtil::STATE_ACTIVE:
                        $status = $this->__('Active');
                        $statusimage = 'greenled.png';
                        break;

                    case ModUtil::STATE_MISSING:
                        $status = $this->__('Files missing');
                        $statusimage = 'redled.png';
                        break;

                    case ModUtil::STATE_UPGRADED:
                        $status = $this->__('New version');
                        $statusimage = 'redled.png';
                        break;

                    case ModUtil::STATE_INVALID:
                        $status = $this->__('Invalid structure');
                        $statusimage = 'redled.png';
                        break;

                    case ModUtil::STATE_NOTALLOWED:
                        $status = $this->__('Not allowed');
                        $statusimage = 'folder_red.png';
                        break;

                    case ModUtil::STATE_UNINITIALISED:
                    default:
                        if ($mod['state'] > 10) {
                            $status = $this->__('Incompatible');
                            $statusimage = 'folder_red.png';
                        } else {
                            $status = $this->__('Not installed');
                            $statusimage = 'redled.png';
                        }
                        break;
                }

                // get new version number for ModUtil::STATE_UPGRADED
                if ($mod['state'] == ModUtil::STATE_UPGRADED) {
                    $mod['newversion'] = $filemodules[$mod['directory']]['version'];
                }

                $moduleinfo[] = array(
                        'modinfo' => $mod,
                        'status' => $status,
                        'statusimage' => $statusimage,
                        'options' => $actions);
            }
        }

        $this->view->assign('multi', $this->serviceManager['multisites.enabled'])
                   ->assign('sort', $sort)
                   ->assign('sortdir', $sortdir)
                   ->assign('modules', $moduleinfo);

        // Assign the values for the smarty plugin to produce a pager.
        $this->view->assign('pager', array('numitems' => ModUtil::apiFunc('Extensions', 'admin', 'countitems', array('letter' => $letter, 'state' => $state)),
                                           'itemsperpage' => $this->getVar('itemsperpage')));

        // Return the output that has been generated by this function
        return $this->view->fetch('extensions_admin_view.tpl');
    }

    /**
     * Extensions_admin_view - list modules and current settings
     *
     * This function is an alias to extensions_admin_view as pnphpbb calls this
     * function name directly on the install
     *
     * @see extensions_admin_view
     * @return string HTML output string
     */
    public function listview()
    {
        $this->redirect(ModUtil::url('Extensions', 'admin', 'view'));
    }

    /**
     * Initialise a module.
     *
     * @param int 'id' module id
     * @return bool true
     */
    public function initialise()
    {
        $csrftoken = FormUtil::getPassedValue('csrftoken');
        $this->checkCsrfToken($csrftoken);

        // Get parameters from whatever input we need
        $id = (int) FormUtil::getPassedValue('id', 0);
        $objectid = (int) FormUtil::getPassedValue('objectid', 0);
        $confirmation = (bool) FormUtil::getPassedValue('confirmation', false);
        $startnum = (int) FormUtil::getPassedValue('startnum');
        $letter = FormUtil::getPassedValue('letter');
        $state = (int)FormUtil::getPassedValue('state');
        if ($objectid) {
            $id = $objectid;
        }

        // assign any dependencies - filtering out non-active module dependents
        // when getting here without a valid id we are in interactive init mode and then
        // the dependencies checks have been done before already
        $fataldependency = false;
        if ($id != 0) {
            $dependencies = ModUtil::apiFunc('Extensions', 'admin', 'getdependencies', array('modid' => $id));

            $modulenotfound = false;
            if (!$confirmation && $dependencies) {
                foreach ($dependencies as $key => $dependency) {
                    $dependencies[$key]['insystem'] = true;
                    $modinfo = ModUtil::getInfoFromName($dependency['modname']);
                    $base = ($modinfo['type'] == ModUtil::TYPE_MODULE) ? 'modules' : 'system';
                    if (is_dir("$base/$dependency[modname]")) {
                        $minok = 0;
                        $maxok = 0;
                        $modversion = Extensions_Util::getVersionMeta($dependency['modname'], $base);

                        if (!empty($dependency['minversion'])) {
                            $minok = version_compare($modversion['version'], $dependency['minversion']);
                        }

                        if (!empty($dependency['maxversion'])) {
                            $maxok = version_compare($dependency['maxversion'], $modversion['version']);
                        }

                        if ($minok == -1 || $maxok == -1) {
                            if ($dependency['status'] == ModUtil::DEPENDENCY_REQUIRED) {
                                $fataldependency = true;
                            } else {
                                unset($dependencies[$key]);
                            }
                        } else {
                            $dependencies[$key] = array_merge($dependencies[$key], $modinfo);
                            // if this module is already installed, don't display it in the list of dependencies.
                            if (isset($dependencies[$key]['state']) && ($dependencies[$key]['state'] > ModUtil::STATE_UNINITIALISED && $dependencies[$key]['state'] < ModUtil::STATE_NOTALLOWED)) {
                                unset($dependencies[$key]);
                            }
                        }
                    } elseif (!empty($modinfo)) {
                        $dependencies[$key] = array_merge($dependencies[$key], $modinfo);
                    } else {
                        $dependencies[$key]['insystem'] = false;
                        $modulenotfound = true;
                        if ($dependency['status'] == ModUtil::DEPENDENCY_REQUIRED) {
                            $fataldependency = true;
                        }
                    }
                }

                $this->view->assign('fataldependency', $fataldependency);

                // we have some dependencies so let's warn the user about these
                if (!empty($dependencies)) {
                    return $this->view->assign('id', $id)
                                      ->assign('dependencies', $dependencies)
                                      ->assign('modulenotfound', $modulenotfound)
                                      ->fetch('extensions_admin_initialise.tpl');
                }
            } else {
                $dependencies = (array)$this->request->request->get('dependencies', array());
            }
        }

        $interactive_init = SessionUtil::getVar('interactive_init');
        $interactive_init = (empty($interactive_init)) ? false : true;
        if ($interactive_init == false) {
            SessionUtil::setVar('modules_id', $id);
            SessionUtil::setVar('modules_startnum', $startnum);
            SessionUtil::setVar('modules_letter', $letter);
            SessionUtil::setVar('modules_state', $state);
            $activate = false;
        } else {
            $id = SessionUtil::getVar('modules_id');
            $startnum = SessionUtil::getVar('modules_startnum');
            $letter = SessionUtil::getVar('modules_letter');
            $state = SessionUtil::getVar('modules_state');
            $activate = (bool) FormUtil::getPassedValue('activate');
        }

        if (empty($id) || !is_numeric($id)) {
            return LogUtil::registerError($this->__('Error! No module ID provided.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
        }

        // initialise and activate any dependencies
        if (isset($dependencies) && is_array($dependencies)) {
            foreach ($dependencies as $dependency) {
                if (!ModUtil::apiFunc('Extensions', 'admin', 'initialise',
                                      array('id' => $dependency))) {
                    $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
                            'startnum' => $startnum,
                            'letter' => $letter,
                            'state' => $state)));
                }
                if (!ModUtil::apiFunc('Extensions', 'admin', 'setstate',
                                      array('id' => $dependency,
                                            'state' => ModUtil::STATE_ACTIVE))) {
                    $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
                            'startnum' => $startnum,
                            'letter' => $letter,
                            'state' => $state)));
                }
            }
        }

        // Now we've initialised the dependencies initialise the main module
        $res = ModUtil::apiFunc('Extensions', 'admin', 'initialise',
                                array('id' => $id,
                                      'interactive_init' => $interactive_init));

        if (is_bool($res) && $res == true) {
            // Success
            SessionUtil::delVar('modules_id');
            SessionUtil::delVar('modules_startnum');
            SessionUtil::delVar('modules_letter');
            SessionUtil::delVar('modules_state');
            SessionUtil::delVar('interactive_init');
            LogUtil::registerStatus($this->__('Done! Installed module.'));

            if ($activate == true) {
                if (ModUtil::apiFunc('Extensions', 'admin', 'setstate',
                                     array('id' => $id,
                                           'state' => ModUtil::STATE_ACTIVE))) {
                    // Success
                    LogUtil::registerStatus($this->__('Done! Activated module.'));
                }
            }
            $this->redirect(ModUtil::url('Extensions', 'admin', 'view',
                                                 array('startnum' => $startnum,
                                                       'letter' => $letter,
                                                       'state' => $state)));
        } elseif (is_bool($res)) {
            $this->redirect(ModUtil::url('Extensions', 'admin', 'view',
                                                 array('startnum' => $startnum,
                                                       'letter' => $letter,
                                                       'state' => $state)));
        } else {
            return $res;
        }
    }

    /**
     * Activate a module
     * @param int 'id' module id
     * @return bool true
     */
    public function activate()
    {
        $csrftoken = FormUtil::getPassedValue('csrftoken');
        $this->checkCsrfToken($csrftoken);

        $id = (int) FormUtil::getPassedValue('id', null, 'GET');
        $startnum = (int) FormUtil::getPassedValue('startnum', null, 'GET');
        $letter = FormUtil::getPassedValue('letter', null, 'GET');
        $state = FormUtil::getPassedValue('state', null, 'GET');
        if (empty($id) || !is_numeric($id)) {
            return LogUtil::registerError($this->__('Error! No module ID provided.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
        }

        $moduleinfo = ModUtil::getInfo($id);
        if ($moduleinfo['state'] == 6) {
            LogUtil::registerError($this->__('Error! Module not allowed.'));
            $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
                    'startnum' => $startnum,
                    'letter' => $letter,
                    'state' => $state)));
        }

        // Update state
        if (ModUtil::apiFunc('Extensions', 'admin', 'setstate',
                             array('id' => $id,
                                   'state' => ModUtil::STATE_ACTIVE))) {
            // Success
            LogUtil::registerStatus($this->__('Done! Activated module.'));
        }

        $this->redirect(ModUtil::url('Extensions', 'admin', 'view',
                                             array('startnum' => $startnum,
                                                   'letter' => $letter,
                                                   'state' => $state)));
    }

    /**
     * Upgrade a module
     * @param int 'id' module id
     * @return bool true
     */
    public function upgrade()
    {
        $csrftoken = FormUtil::getPassedValue('csrftoken');
        $this->checkCsrfToken($csrftoken);

        $interactive_upgrade = SessionUtil::getVar('interactive_upgrade');
        $interactive_upgrade = (empty($interactive_upgrade)) ? false : true;
        if ($interactive_upgrade == false) {
            $id = (int) FormUtil::getPassedValue('id', null, 'GET');
            $startnum = (int) FormUtil::getPassedValue('startnum', null, 'GET');
            $letter = FormUtil::getPassedValue('letter', null, 'GET');
            $state = FormUtil::getPassedValue('state', null, 'GET');
            SessionUtil::setVar('modules_id', $id);
            SessionUtil::setVar('modules_startnum', $startnum);
            SessionUtil::setVar('modules_letter', $letter);
            SessionUtil::setVar('modules_state', $state);
            $activate = false;
        } else {
            $id = SessionUtil::getVar('modules_id');
            $startnum = SessionUtil::getVar('modules_startnum');
            $letter = SessionUtil::getVar('modules_letter');
            $state = SessionUtil::getVar('modules_state');
            $activate = (bool) FormUtil::getPassedValue('activate', null, 'POST');
        }
        if (empty($id) || !is_numeric($id)) {
            return LogUtil::registerError($this->__('Error! No module ID provided.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
        }

        // Upgrade module
        $res = ModUtil::apiFunc('Extensions', 'admin', 'upgrade',
                                array('id' => $id,
                                      'interactive_upgrade' => $interactive_upgrade));

        if (is_bool($res) && $res == true) {
            // Success
            SessionUtil::delVar('modules_id');
            SessionUtil::delVar('modules_startnum');
            SessionUtil::delVar('modules_letter');
            SessionUtil::delVar('modules_state');
            SessionUtil::setVar('interactive_upgrade', false);
            LogUtil::registerStatus($this->__('New version'));
            if ($activate == true) {
                if (ModUtil::apiFunc('Extensions', 'admin', 'setstate',
                                     array('id' => $id,
                                           'state' => ModUtil::STATE_ACTIVE))) {
                    // Success
                    LogUtil::registerStatus($this->__('Activated'));
                }
            }

            // Clear the Zikula_View cached/compiled files and Themes cached/compiled/cssjs combination files
            $theme = Zikula_View_Theme::getInstance('Theme');
            $theme->clear_compiled();
            $theme->clear_all_cache();
            $theme->clear_cssjscombinecache();

            $this->view->clear_compiled();
            $this->view->clear_all_cache();

            $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
                    'startnum' => $startnum,
                    'letter' => $letter,
                    'state' => $state)));
        } elseif (is_bool($res)) {
            $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
                    'startnum' => $startnum,
                    'letter' => $letter,
                    'state' => $state)));
        } else {
            return $res;
        }
    }

    /**
     * Deactivate a module
     * @param int 'id' module id
     * @return bool true
     */
    public function deactivate()
    {
        $csrftoken = FormUtil::getPassedValue('csrftoken');
        $this->checkCsrfToken($csrftoken);

        $id = (int) FormUtil::getPassedValue('id', null, 'GET');
        $startnum = (int) FormUtil::getPassedValue('startnum', null, 'GET');
        $letter = FormUtil::getPassedValue('letter', null, 'GET');
        $state = FormUtil::getPassedValue('state', null, 'GET');
        if (empty($id) || !is_numeric($id)) {
            return LogUtil::registerError($this->__('Error! No module ID provided.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
        }

        // check if the modules is the systems start module
        $modinfo = ModUtil::getInfo($id);
        if ($modinfo == false) {
            return LogUtil::registerError($this->__('Error! No such module ID exists.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
        }
        $startmod = System::getVar('startpage');
        if ($startmod == $modinfo['name']) {
            return LogUtil::registerError($this->__('Error! This module is currently set as the site\'s home page. You must choose another module for the home page before you can deactivate this one.'), null, ModUtil::url('Extensions', 'admin', 'view'));
        }

        if (ModUtil::apiFunc('Extensions', 'admin', 'iscoremodule',array('modulename' => $modinfo['name']))) {
            return LogUtil::registerError($this->__('Error! You cannot deactivate this module. It is a mandatory core module, and is needed by the system.'), null, ModUtil::url('Extensions', 'admin', 'view'));
        }

        // Update state
        if (ModUtil::apiFunc('Extensions', 'admin', 'setstate', array(
        'id' => $id,
        'state' => ModUtil::STATE_INACTIVE))) {
            // Success
            LogUtil::registerStatus($this->__('Done! Deactivated module.'));
        }

        $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
                'startnum' => $startnum,
                'letter' => $letter,
                'state' => $state)));
    }

    /**
     * Remove a module
     * @param int 'id' module id
     * @return bool true if successful
     */
    public function remove()
    {
        // Get parameters from whatever input we need
        $id = (int) FormUtil::getPassedValue('id', 0);
        $objectid = (int) FormUtil::getPassedValue('objectid', 0);
        $confirmation = (bool) FormUtil::getPassedValue('confirmation', false);
        $dependents = (array) FormUtil::getPassedValue('dependents');
        $startnum = (int) FormUtil::getPassedValue('startnum');
        $letter = FormUtil::getPassedValue('letter');
        $state = FormUtil::getPassedValue('state');
        if ($objectid) {
            $id = $objectid;
        }

        $interactive_remove = SessionUtil::getVar('interactive_remove');
        $interactive_remove = (empty($interactive_remove)) ? false : true;

        if ($interactive_remove == false) {
            SessionUtil::setVar('modules_id', $id);
            SessionUtil::setVar('modules_startnum', $startnum);
            SessionUtil::setVar('modules_letter', $letter);
            SessionUtil::setVar('modules_state', $state);
        } else {
            $id = SessionUtil::getVar('modules_id');
            $startnum = SessionUtil::getVar('modules_startnum');
            $letter = SessionUtil::getVar('modules_letter');
            $state = SessionUtil::getVar('modules_state');
            $confirmation = 1;
        }

        if (empty($id) || !is_numeric($id) || !ModUtil::getInfo($id)) {
            return LogUtil::registerError($this->__('Error! No module ID provided.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
        }

        // Check for confirmation.
        if (empty($confirmation)) {
            // No confirmation yet
            // Add a hidden field for the item ID to the output
            $this->view->assign('id', $id);

            // assign any dependencies - filtering out non-active module dependents
            $dependents = ModUtil::apiFunc('Extensions', 'admin', 'getdependents', array(
                    'modid' => $id));
            foreach ($dependents as $key => $dependent) {
                $modinfo = ModUtil::getInfo($dependent['modid']);
                if (!ModUtil::available($modinfo['name'])) {
                    unset($dependents[$key]);
                } else {
                    $dependents[$key] = array_merge($dependents[$key], $modinfo);
                }
            }
            // check the blocks module for existing blocks
            $blocks = ModUtil::apiFunc('Blocks', 'user', 'getall', array(
                    'modid' => $id));
            $this->view->assign('hasBlocks', count($blocks));

            $this->view->assign('dependents', $dependents)
                       ->assign('startnum', $startnum)
                       ->assign('letter', $letter)
                       ->assign('state', $state);

            // Return the output that has been generated by this function
            return $this->view->fetch('extensions_admin_remove.tpl');
        }

        // If we get here it means that the user has confirmed the action

        $csrftoken = FormUtil::getPassedValue('csrftoken');
        $this->checkCsrfToken($csrftoken);

        // remove dependent modules
        foreach ($dependents as $dependent) {
            if (!ModUtil::apiFunc('Extensions', 'admin', 'remove', array(
            'id' => $dependent))) {
                $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
                        'startnum' => $startnum,
                        'letter' => $letter,
                        'state' => $state)));
            }
        }

        // remove the module blocks
        $blocks = ModUtil::apiFunc('Blocks', 'user', 'getall', array(
                'modid' => $id));
        foreach ($blocks as $block) {
            if (!ModUtil::apiFunc('Blocks', 'admin', 'delete', array(
            'bid' => $block['bid']))) {
                LogUtil::registerError($this->__f('Error! Deleting the block %s .', $block['title']));
                $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
                        'startnum' => $startnum,
                        'letter' => $letter,
                        'state' => $state)));
            }
        }

        // Now we've removed dependents and associated blocks remove the main module
        $res = ModUtil::apiFunc('Extensions', 'admin', 'remove', array(
                'id' => $id,
                'interactive_remove' => $interactive_remove));
        if (is_bool($res) && $res == true) {
            // Success
            SessionUtil::delVar('modules_id');
            SessionUtil::delVar('modules_startnum');
            SessionUtil::delVar('modules_letter');
            SessionUtil::delVar('modules_state');
            SessionUtil::delVar('interactive_remove');
            LogUtil::registerStatus($this->__('Done! Uninstalled module.'));
            $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
                    'startnum' => $startnum,
                    'letter' => $letter,
                    'state' => $state)));
        } elseif (is_bool($res)) {
            $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
                    'startnum' => $startnum,
                    'letter' => $letter,
                    'state' => $state)));
        } else {
            return $res;
        }
    }


    /**
     * Display available hooks.
     *
     * @param int 'id' module id.
     *
     * @return string HTML output string
     */
    public function legacyhooks()
    {
        // get our input
        $id = (int) FormUtil::getPassedValue('id', null, 'GET');

        // check the input
        if (!is_numeric($id)) {
            return LogUtil::registerArgsError(ModUtil::url('Extensions', 'admin', 'view'));
        }

        // get the modules information
        $modinfo = ModUtil::getInfo($id);
        if ($modinfo == false) {
            return LogUtil::registerError($this->__('Error! No such module ID exists.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
        }

        if (!SecurityUtil::checkPermission('Extensions::', "$modinfo[name]::$id", ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // assign the modinfo to the template
        $this->view->assign('modinfo', $modinfo);

        // add module id to form
        $this->view->assign('id', $id);

        $hooks = ModUtil::apiFunc('Extensions', 'admin', 'getmoduleshooks', array(
                'modid' => $id));

        $this->view->assign('hooks', $hooks);

        // Return the output that has been generated by this function
        return $this->view->fetch('extensions_admin_hooks.tpl');

    }

    /**
     * display available hooks, extended version
     * @param int 'id' module id
     * @return string HTML output string
     */
    public function extendedhooks()
    {
        // get our input
        $id = (int) FormUtil::getPassedValue('id', null, 'GET');

        // check the input
        if (!is_numeric($id)) {
            return LogUtil::registerArgsError(ModUtil::url('Extensions', 'admin', 'view'));
        }

        // get the modules information
        $modinfo = ModUtil::getInfo($id);
        if ($modinfo == false) {
            return LogUtil::registerError($this->__('Error! No such module ID exists.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
        }

        if (!SecurityUtil::checkPermission('Extensions::', "$modinfo[name]::$id", ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // assign the modinfo to the template
        $this->view->assign('modinfo', $modinfo);

        // add module id to form
        $this->view->assign('id', $id);

        $grouped_hooks = ModUtil::apiFunc('Extensions', 'admin', 'getextendedmoduleshooks', array(
                'modid' => $id));
        $this->view->assign('grouped_hooks', $grouped_hooks);

        // Return the output that has been generated by this function
        return $this->view->fetch('extensions_admin_extendedhooks.tpl');

    }

    /**
     * This is a standard function to modify the configuration parameters of the
     * module
     * @return string HTML string
     */
    public function modifyconfig()
    {
        // Security check
        if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // assign all the module vars and return output
        return $this->view->assign($this->getVars())
                          ->fetch('extensions_admin_modifyconfig.tpl');
    }

    /**
     * This is a standard function to update the configuration parameters of the
     * module given the information passed back by the modification form
     * @return bool true
     */
    public function updateconfig()
    {
        $this->checkCsrfToken();

        // Security check
        if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // Update module variables.
        $itemsperpage = (int) FormUtil::getPassedValue('itemsperpage', 25, 'POST');
        if (!is_integer($itemsperpage) || $itemsperpage < 1) {
            LogUtil::registerError($this->__("Warning! The 'Items per page' setting must be a positive integer. The value you entered was corrected."));
            $itemsperpage = (int) $itemsperpage;
            if ($itemsperpage < 1) {
                $itemsperpage = 25;
            }
        }

        $this->setVar('itemsperpage', $itemsperpage);

        // the module configuration has been updated successfuly
        LogUtil::registerStatus($this->__('Done! Saved module configuration.'));

        // This function generated no output, and so now it is complete we redirect
        // the user to an appropriate page for them to carry on their work
        $this->redirect(ModUtil::url('Extensions', 'admin', 'view'));
    }

    /**
     * Display information of a module compatibility with the version of the core
     * @param  int 'id' identity of the module
     * @return string HTML output string
     */
    public function compinfo()
    {
        // get our input
        $id = (int) FormUtil::getPassedValue('id', null, 'GET');
        $startnum = (int) FormUtil::getPassedValue('startnum');
        $letter = FormUtil::getPassedValue('letter');
        $state = (int) FormUtil::getPassedValue('state');

        // check the input
        if (!is_numeric($id)) {
            return LogUtil::registerArgsError(ModUtil::url('Extensions', 'admin', 'view'));
        }

        // get the modules information from the data base
        $modinfo = ModUtil::getInfo($id);
        if ($modinfo == false) {
            return LogUtil::registerError($this->__('Error! No such module ID exists.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
        }

        if (!SecurityUtil::checkPermission('Extensions::', "$modinfo[name]::$id", ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // get the module information from the files system
        $moduleInfo = ModUtil::apiFunc('Extensions', 'admin', 'getfilemodules',
                array('name' => $modinfo['name']));

        // assign the module information and other variables to the template
        $this->view->assign('moduleInfo', $moduleInfo)
                   ->assign('id', $id)
                   ->assign('startnum', $startnum)
                   ->assign('letter', $letter)
                   ->assign('state', $state);

        // Return the output that has been generated by this function
        return $this->view->fetch('extensions_admin_compinfo.tpl');
    }

    /**
     * Lists all plugins.
     * @return string HTML output string
     */
    public function viewPlugins()
    {
        // Security check
        if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        $state = FormUtil::getPassedValue('state', -1, 'GETPOST');
        $sort = FormUtil::getPassedValue('sort', null, 'GETPOST');
        $module = FormUtil::getPassedValue('bymodule', null, 'GETPOST');
        $systemplugins = FormUtil::getPassedValue('systemplugins', false, 'GETPOST')? true : null;

        $this->view->assign('state', $state);

        // generate an auth key to use in urls
        $csrfToken = SecurityUtil::generateCsrfToken($this->serviceManager, true);
        $plugins = array();
        $pluginClasses = ($systemplugins) ? PluginUtil::loadAllSystemPlugins() : PluginUtil::loadAllModulePlugins();

        foreach ($pluginClasses as $className) {
            $instance = PluginUtil::loadPlugin($className);
            $pluginstate = PluginUtil::getState($instance->getServiceId(), PluginUtil::getDefaultState());

            // Tweak UI if the plugin is AlwaysOn
            if ($instance instanceof Zikula_Plugin_AlwaysOnInterface) {
                $pluginstate['state'] = PluginUtil::ENABLED;
                $pluginstate['version'] = $instance->getMetaVersion();
            }

            // state filer
            if ($state >= 0 && $pluginstate['state'] != $state) {
                continue;
            }

            // module filter
            if (!empty($module) && $instance->getModuleName() != $module) {
                continue;
            }

            $actions = array();
            // Translate state
            switch ($pluginstate['state']) {
                case PluginUtil::NOTINSTALLED:
                    $status = $this->__('Not installed');
                    $statusimage = 'redled.png';

                    $actions[] = array('url' => ModUtil::url('Extensions', 'admin', 'initialisePlugin',
                                                    array('plugin' => $className,
                                                          'state'  => $state,
                                                          'bymodule' => $module,
                                                          'sort'   => $sort,
                                                          'systemplugins' => $systemplugins,
                                                          'csrftoken' => $csrfToken)
                                                ),
                                       'image' => 'folder_new.png',
                                       'title' => $this->__('Install'));
                    break;
                case PluginUtil::ENABLED:
                    $status = $this->__('Active');
                    $statusimage = 'greenled.png';
                    $pluginLink = array();
                    if (!$systemplugins) {
                        $pluginLink['_module'] = $instance->getModuleName();
                    }
                    $pluginLink['_plugin'] = $instance->getPluginName();
                    $pluginLink['_action'] = 'configure';

                    if ($instance instanceof Zikula_Plugin_ConfigurableInterface) {
                        $actions[] = array('url' => ModUtil::url('Extensions', 'adminplugin', 'dispatch', $pluginLink),
                                           'image' => 'configure.png',
                                           'title' => $this->__('Configure plugin'));
                    }

                    // Dont allow to disable/uninstall plugins that are AlwaysOn
                    if (!$instance instanceof Zikula_Plugin_AlwaysOnInterface) {
                        $actions[] = array('url' => ModUtil::url('Extensions', 'admin', 'deactivatePlugin',
                                                    array('plugin' => $className,
                                                          'state'  => $state,
                                                          'bymodule' => $module,
                                                          'sort'   => $sort,
                                                          'systemplugins' => $systemplugins,
                                                          'csrftoken' => $csrfToken)
                                                ),
                                       'image' => 'folder_red.png',
                                       'title' => $this->__('Deactivate'));

                        $actions[] = array('url' => ModUtil::url('Extensions', 'admin', 'removePlugin',
                                                    array('plugin' => $className,
                                                          'state'  => $state,
                                                          'bymodule' => $module,
                                                          'sort'   => $sort,
                                                          'systemplugins' => $systemplugins,
                                                          'csrftoken' => $csrfToken)
                                                ),
                                       'image' => '14_layer_deletelayer.png',
                                       'title' => $this->__('Remove plugin'));
                    }
                    break;
                case PluginUtil::DISABLED:
                    $status = $this->__('Inactive');
                    $statusimage = 'yellowled.png';

                    $actions[] = array('url' => ModUtil::url('Extensions', 'admin', 'activatePlugin',
                                                    array('plugin' => $className,
                                                          'state'  => $state,
                                                          'bymodule' => $module,
                                                          'sort'   => $sort,
                                                          'systemplugins' => $systemplugins,
                                                          'csrftoken' => $csrfToken)
                                                ),
                                       'image' => 'folder_green.png',
                                       'title' => $this->__('Activate'));

                    $actions[] = array('url' => ModUtil::url('Extensions', 'admin', 'removePlugin',
                                                    array('plugin' => $className,
                                                           'state' => $state,
                                                           'bymodule' => $module,
                                                           'sort'   => $sort,
                                                           'systemplugins' => $systemplugins,
                                                           'csrftoken' => $csrfToken)
                                                ),
                                       'image' => '14_layer_deletelayer.png',
                                       'title' => $this->__('Remove plugin'));

                    break;
            }

            // upgrade ?
            if ($pluginstate['state'] != PluginUtil::NOTINSTALLED
                && $pluginstate['version'] != $instance->getMetaVersion()) {

                $status = $this->__('New version');
                $statusimage = 'redled.png';

                $actions = array();
                $actions[] = array('url' => ModUtil::url('Extensions', 'admin', 'upgradePlugin',
                                                array('plugin' => $className,
                                                      'state'  => $state,
                                                      'bymodule' => $module,
                                                      'sort'   => $sort,
                                                      'systemplugins' => $systemplugins,
                                                      'csrftoken' => $csrfToken)
                                            ),
                                       'image' => 'folder_favorites.png',
                                       'title' => $this->__('Upgrade'));

                $actions[] = array('url' => ModUtil::url('Extensions', 'admin', 'removePlugin',
                                                array('plugin' => $className,
                                                       'state' => $state,
                                                       'bymodule' => $module,
                                                       'sort'   => $sort,
                                                       'systemplugins' => $systemplugins,
                                                       'csrftoken' => $csrfToken)
                                            ),
                                       'image' => '14_layer_deletelayer.png',
                                       'title' => $this->__('Remove plugin'));
            }

            $info =  array('instance'    => $instance,
                           'status'      => $status,
                           'statusimage' => $statusimage,
                           'actions'     => $actions,
                           'version'     => $pluginstate['state'] == PluginUtil::NOTINSTALLED ?
                                                 $instance->getMetaVersion() : $pluginstate['version']);

            // new version of plugin?
            if ($pluginstate['state'] != PluginUtil::NOTINSTALLED
                && $pluginstate['version'] != $instance->getMetaVersion()) {
                $info['newversion'] = $instance->getMetaVersion();
            }

            $plugins[] = $info;
        }

        // sort plugins array
        if (empty($sort) || $sort == 'module') {
            usort($plugins, array($this, 'viewPluginsSorter_byModule'));
        } elseif ($sort == 'name') {
            usort($plugins, array($this, 'viewPluginsSorter_byName'));
        }

        $this->view->assign('plugins', $plugins)
                   ->assign('module', $module)
                   ->assign('sort', $sort)
                   ->assign('state', $state)
                   ->assign('systemplugins', $systemplugins)
                   ->assign('_type', ($systemplugins) ? 'system' : 'module');

        // Return the output that has been generated by this function
        return $this->view->fetch('extensions_admin_viewPlugins.tpl');
    }

    /**
     * viewPlugins sorter: Sorting by module name
     */
    private function viewPluginsSorter_byModule($a, $b)
    {
        return strcmp($a['instance']->getModuleName(), $b['instance']->getModuleName());
    }

    /**
     * viewPlugins sorter: Sorting by plugin internal name
     */
    private function viewPluginsSorter_byName($a, $b)
    {
        return strcmp($a['instance']->getPluginName(), $b['instance']->getPluginName());
    }

    /**
     * Initialise a plugin
     * @return bool true
     */
    public function initialisePlugin()
    {
        $csrftoken = FormUtil::getPassedValue('csrftoken');
        $this->checkCsrfToken($csrftoken);

        // Security and sanity checks
        if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // Get parameters from whatever input we need
        $plugin = FormUtil::getPassedValue('plugin', null);
        $state = FormUtil::getPassedValue('state', -1);
        $sort = FormUtil::getPassedValue('sort', null);
        $module = FormUtil::getPassedValue('bymodule', null);
        $systemplugins = FormUtil::getPassedValue('systemplugins', false)? true : null;

        if (empty($plugin)) {
            return LogUtil::registerError($this->__('Error! No plugin class provided.'), 404, ModUtil::url('Extensions', 'admin', 'viewPlugins'));
        }

        PluginUtil::loadAllPlugins();
        if (PluginUtil::install($plugin)) {
            LogUtil::registerStatus($this->__('Done! Installed plugin.'));
        }

        $this->redirect(ModUtil::url('Extensions', 'admin', 'viewPlugins', array('state' => $state,
                                                                              'sort'  => $sort,
                                                                              'bymodule' => $module,
                                                                              'systemplugins' => $systemplugins)));
    }

    /**
     * Deactivate a plugin
     * @return bool true
     */
    public function deactivatePlugin()
    {
        $csrftoken = $this->request->query->get('csrftoken', false);
        $this->checkCsrfToken($csrftoken);

        // Security and sanity checks
        if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // Get parameters from whatever input we need
        $plugin = FormUtil::getPassedValue('plugin', null);
        $state = FormUtil::getPassedValue('state', -1);
        $sort = FormUtil::getPassedValue('sort', null);
        $module = FormUtil::getPassedValue('bymodule', null);
        $systemplugins = FormUtil::getPassedValue('systemplugins', false)? true : null;

        if (empty($plugin)) {
            return LogUtil::registerError($this->__('Error! No plugin class provided.'), 404, ModUtil::url('Extensions', 'admin', 'viewPlugins'));
        }

        PluginUtil::loadAllPlugins();
        if (PluginUtil::disable($plugin)) {
            LogUtil::registerStatus($this->__('Done! Deactivated plugin.'));
        }

        $this->redirect(ModUtil::url('Extensions', 'admin', 'viewPlugins', array('state' => $state,
                                                                              'sort'  => $sort,
                                                                              'bymodule' => $module,
                                                                              'systemplugins' => $systemplugins)));
    }

    /**
     * Activate a plugin
     * @return bool true
     */
    public function activatePlugin()
    {
        $csrftoken = $this->request->query->get('csrftoken', false);
        $this->checkCsrfToken($csrftoken);

        // Security and sanity checks
        if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // Get parameters from whatever input we need
        $plugin = FormUtil::getPassedValue('plugin', null);
        $state = FormUtil::getPassedValue('state', -1);
        $sort = FormUtil::getPassedValue('sort', null);
        $module = FormUtil::getPassedValue('bymodule', null);
        $systemplugins = FormUtil::getPassedValue('systemplugins', false)? true : null;

        if (empty($plugin)) {
            return LogUtil::registerError($this->__('Error! No plugin class provided.'), 404, ModUtil::url('Extensions', 'admin', 'viewPlugins'));
        }

        PluginUtil::loadAllPlugins();
        if (PluginUtil::enable($plugin)) {
            LogUtil::registerStatus($this->__('Done! Activated plugin.'));
        }

        $this->redirect(ModUtil::url('Extensions', 'admin', 'viewPlugins', array('state' => $state,
                                                                              'sort'  => $sort,
                                                                              'bymodule' => $module,
                                                                              'systemplugins' => $systemplugins)));
    }

    /**
     * Remove a plugin
     * @return bool true
     */
    public function removePlugin()
    {
        $csrftoken = FormUtil::getPassedValue('csrftoken');
        $this->checkCsrfToken($csrftoken);

        // Security and sanity checks
        if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // Get parameters from whatever input we need
        $plugin = FormUtil::getPassedValue('plugin', null);
        $state = FormUtil::getPassedValue('state', -1);
        $sort = FormUtil::getPassedValue('sort', null);
        $module = FormUtil::getPassedValue('bymodule', null);
        $systemplugins = FormUtil::getPassedValue('systemplugins', false)? true : null;

        if (empty($plugin)) {
            return LogUtil::registerError($this->__('Error! No plugin class provided.'), 404, ModUtil::url('Extensions', 'admin', 'viewPlugins'));
        }

        PluginUtil::loadAllPlugins();
        if (PluginUtil::uninstall($plugin)) {
           LogUtil::registerStatus($this->__('Done! De-installed plugin.'));
        }

        $this->redirect(ModUtil::url('Extensions', 'admin', 'viewPlugins', array('state' => $state,
                                                                              'sort'  => $sort,
                                                                              'bymodule' => $module,
                                                                              'systemplugins' => $systemplugins)));
    }

    /**
     * Upgrade a plugin
     * @return bool true
     */
    public function upgradePlugin()
    {
        $csrftoken = FormUtil::getPassedValue('csrftoken');
        $this->checkCsrfToken($csrftoken);

        // Security and sanity checks
        if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
            return LogUtil::registerPermissionError();
        }

        // Get parameters from whatever input we need
        $plugin = FormUtil::getPassedValue('plugin', null);
        $state = FormUtil::getPassedValue('state', -1);
        $sort = FormUtil::getPassedValue('sort', null);
        $module = FormUtil::getPassedValue('bymodule', null);
        $systemplugins = FormUtil::getPassedValue('systemplugins', false)? true : null;

        if (empty($plugin)) {
            return LogUtil::registerError($this->__('Error! No plugin class provided.'), 404, ModUtil::url('Extensions', 'admin', 'viewPlugins'));
        }

        PluginUtil::loadAllPlugins();
        if (PluginUtil::upgrade($plugin)) {
            LogUtil::registerStatus($this->__('Done! Upgraded plugin.'));
        }

        $this->redirect(ModUtil::url('Extensions', 'admin', 'viewPlugins', array('state' => $state,
                                                                              'sort'  => $sort,
                                                                              'bymodule' => $module,
                                                                              'systemplugins' => $systemplugins)));
    }

    public function upgradeall()
    {
        ModUtil::apiFunc('Extensions', 'admin', 'upgradeall');
        $this->redirect(ModUtil::url('Extensions', 'admin', 'view'));
    }
}
