예제 #1
0
 /**
  * Upgrade a module.
  *
  * @param array $args All parameters passed to this function.
  *                      numeric $args['id']                  The module ID.
  *                      boolean $args['interactive_upgrade'] Whether or not to upgrade in interactive mode.
  *
  * @return boolean True on success, false on failure.
  */
 public function upgrade($args)
 {
     // Argument check
     if (!isset($args['id']) || !is_numeric($args['id'])) {
         return LogUtil::registerArgsError();
     }
     // Get module information
     $modinfo = ModUtil::getInfo($args['id']);
     if (empty($modinfo)) {
         return LogUtil::registerError($this->__('Error! No such module ID exists.'));
     }
     switch ($modinfo['state']) {
         case ModUtil::STATE_NOTALLOWED:
             return LogUtil::registerError($this->__f('Error! No permission to upgrade %s.', $modinfo['name']));
             break;
         default:
             if ($modinfo['state'] > 10) {
                 return LogUtil::registerError($this->__f('Error! %s is not compatible with this version of Zikula.', $modinfo['name']));
             }
     }
     $osdir = DataUtil::formatForOS($modinfo['directory']);
     ModUtil::dbInfoLoad($modinfo['name'], $osdir);
     $modpath = $modinfo['type'] == ModUtil::TYPE_SYSTEM ? 'system' : 'modules';
     // load module maintainence functions
     $oomod = ModUtil::isOO($modinfo['name']);
     if ($oomod) {
         ZLoader::addAutoloader($osdir, "{$modpath}/{$osdir}/lib");
     }
     $bootstrap = "{$modpath}/{$osdir}/bootstrap.php";
     if (file_exists($bootstrap)) {
         include_once $bootstrap;
     }
     if ($modinfo['type'] == ModUtil::TYPE_MODULE) {
         if (is_dir("modules/{$osdir}/locale")) {
             ZLanguage::bindModuleDomain($modinfo['name']);
         }
     }
     if (!$oomod && file_exists($file = "{$modpath}/{$osdir}/pninit.php")) {
         if (!(include_once $file)) {
             LogUtil::registerError($this->__f("Error! Could not load a required file: '%s'.", $file));
         }
     }
     if ($oomod) {
         $className = ucwords($modinfo['name']) . '_Installer';
         $reflectionInstaller = new ReflectionClass($className);
         if (!$reflectionInstaller->isSubclassOf('Zikula_AbstractInstaller')) {
             LogUtil::registerError($this->__f("%s must be an instance of Zikula_AbstractInstaller", $className));
         }
         $installer = $reflectionInstaller->newInstanceArgs(array($this->serviceManager));
         $interactiveClass = ucwords($modinfo['name']) . '_Controller_Interactiveinstaller';
         $interactiveController = null;
         if (class_exists($interactiveClass)) {
             $reflectionInteractive = new ReflectionClass($interactiveClass);
             if (!$reflectionInteractive->isSubclassOf('Zikula_Controller_AbstractInteractiveInstaller')) {
                 LogUtil::registerError($this->__f("%s must be an instance of Zikula_Controller_AbstractInteractiveInstaller", $className));
             }
             $interactiveController = $reflectionInteractive->newInstance($this->serviceManager);
         }
     }
     // perform the actual upgrade of the module
     $func = $oomod ? array($installer, 'upgrade') : $modinfo['name'] . '_upgrade';
     $interactive_func = $oomod ? array($interactiveController, 'upgrade') : $modinfo['name'] . '_init_interactiveupgrade';
     // allow bypass of interactive upgrade during a new installation only.
     if (System::isInstalling() && is_callable($interactive_func) && !is_callable($func)) {
         return;
         // return void here
     }
     if (isset($args['interactive_upgrade']) && $args['interactive_upgrade'] == false && is_callable($interactive_func)) {
         if (is_array($interactive_func)) {
             // This must be an OO controller since callable is an array.
             // Because interactive installers extend the Zikula_AbstractController, is_callable will always return true because of the __call()
             // so we must check if the method actually exists by reflection - drak
             if ($reflectionInteractive->hasMethod('upgrade')) {
                 SessionUtil::setVar('interactive_upgrade', true);
                 return call_user_func($interactive_func, array('oldversion' => $modinfo['version']));
             }
         } else {
             // this is enclosed in the else so that if both conditions fail, execution will pass onto the non-interactive execution below.
             SessionUtil::setVar('interactive_upgrade', true);
             return call_user_func($interactive_func, array('oldversion' => $modinfo['version']));
         }
     }
     // non-interactive
     if (is_callable($func)) {
         $result = call_user_func($func, $modinfo['version']);
         if (is_string($result)) {
             if ($result != $modinfo['version']) {
                 // update the last successful updated version
                 $modinfo['version'] = $result;
                 $obj = DBUtil::updateObject($modinfo, 'modules', '', 'id', true);
             }
             return false;
         } elseif ($result != true) {
             return false;
         }
     }
     $modversion['version'] = '0';
     $modversion = Extensions_Util::getVersionMeta($osdir, $modpath);
     $version = $modversion['version'];
     // Update state of module
     $result = $this->setState(array('id' => $args['id'], 'state' => ModUtil::STATE_ACTIVE));
     if ($result) {
         LogUtil::registerStatus($this->__("Done! Module has been upgraded. Its status is now 'Active'."));
     } else {
         return false;
     }
     // Note the changes in the database...
     // Get module database info
     ModUtil::dbInfoLoad('Extensions');
     $obj = array('id' => $args['id'], 'version' => $version);
     DBUtil::updateObject($obj, 'modules');
     // legacy to be removed from 1.4 - remove hooks during upgrade since we cannot rely on
     // module authors to do this - drak
     if ($oomod) {
         $tables = DBUtil::getTables();
         $hooksCol = $tables['hooks_column'];
         $where = "{$hooksCol['smodule']} = '{$modinfo['name']}' OR {$hooksCol['tmodule']} = '{$modinfo['name']}'";
         $hooks = DBUtil::selectObjectArray('hooks', $where);
         if ($hooks) {
             foreach ($hooks as $hook) {
                 DBUtil::deleteObject($hook, 'hooks');
             }
             LogUtil::registerStatus($this->__f("NOTICE! Legacy hook configurations for %s have been removed.", $modinfo['name']));
         }
     }
     // Upgrade succeeded, issue event.
     $event = new Zikula_Event('installer.module.upgraded', null, $modinfo);
     $this->eventManager->notify($event);
     // Success
     return true;
 }
예제 #2
0
    /**
     * 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;
        }
    }