Example #1
0
/** Installs or upgrades a module from it's directory
 * Checks dependencies, and enables
 * @param string   The name of the module to install
 * @param bool     If true, skips status and dependency checks
 * @return mixed   True if succesful, array of error messages if not succesful
 */
function module_install($modulename, $force = false)
{
    global $db, $amp_conf;
    if ($time_limit = ini_get('max_execution_time')) {
        set_time_limit($time_limit);
    }
    $modules = module_getinfo($modulename);
    // make sure we have a directory, to begin with
    $dir = $amp_conf['AMPWEBROOT'] . '/admin/modules/' . $modulename;
    if (!is_dir($dir)) {
        return array(_("Cannot find module"));
    }
    // read the module.xml file
    $modules = module_getinfo($modulename);
    if (!isset($modules[$modulename])) {
        return array(_("Could not read module.xml"));
    }
    // don't force this bit - we can't install a broken module (missing files)
    if ($modules[$modulename]['status'] == MODULE_STATUS_BROKEN) {
        return array(_("Module " . $modules[$modulename]['rawname'] . " is broken and cannot be installed. You should try to download it again."));
    }
    if (!$force) {
        if (!in_array($modules[$modulename]['status'], array(MODULE_STATUS_NOTINSTALLED, MODULE_STATUS_NEEDUPGRADE))) {
            //return array(_("This module is already installed."));
            // This isn't really an error, we just exit
            return true;
        }
        // check dependencies
        if (is_array($errors = module_checkdepends($modules[$modulename]))) {
            return $errors;
        }
    }
    // run the scripts
    if (!_module_runscripts($modulename, 'install')) {
        return array(_("Failed to run installation scripts"));
    }
    if ($modules[$modulename]['status'] == MODULE_STATUS_NOTINSTALLED) {
        // customize INSERT query
        $sql = "INSERT INTO modules (modulename, version, enabled) values ('" . $db->escapeSimple($modules[$modulename]['rawname']) . "','" . $db->escapeSimple($modules[$modulename]['version']) . "', 1);";
    } else {
        // just need to update the version
        $sql = "UPDATE modules SET version='" . $db->escapeSimple($modules[$modulename]['version']) . "' WHERE modulename = '" . $db->escapeSimple($modules[$modulename]['rawname']) . "'";
    }
    // run query
    $results = $db->query($sql);
    if (DB::IsError($results)) {
        return array(sprintf(_("Error updating database. Command was: %s; error was: %s "), $sql, $results->getMessage()));
    }
    // module is now installed & enabled, invalidate the modulelist class since it is now stale
    $modulelist =& modulelist::create($db);
    $modulelist->invalidate();
    // edit the notification table to list any remaining upgrades available or clear
    // it if none are left. It requres a copy of the most recent module_xml to compare
    // against the installed modules.
    //
    $sql = 'SELECT data FROM module_xml WHERE id = "xml"';
    $data = sql($sql, "getOne");
    $parser = new xml2ModuleArray($data);
    $xmlarray = $parser->parseAdvanced($data);
    $new_modules = array();
    if (count($xmlarray)) {
        foreach ($xmlarray['xml']['module'] as $mod) {
            $new_modules[$mod['rawname']] = $mod;
        }
    }
    module_upgrade_notifications($new_modules, 'PASSIVE');
    needreload();
    return true;
}
 /**
  * Installs or upgrades a module from it's directory
  * Checks dependencies, and enables
  * @param string   The name of the module to install
  * @param bool     If true, skips status and dependency checks
  * @return mixed   True if succesful, array of error messages if not succesful
  */
 function install($modulename, $force = false)
 {
     $this->modDepends = array();
     $this->notFound = false;
     global $db, $amp_conf;
     set_time_limit($this->maxTimeLimit);
     $modules = $this->getinfo($modulename);
     // make sure we have a directory, to begin with
     $dir = $amp_conf['AMPWEBROOT'] . '/admin/modules/' . $modulename;
     if (!is_dir($dir)) {
         $this->notFound = true;
         return array(_("Cannot find module"));
     }
     // read the module.xml file
     $modules = $this->getinfo($modulename);
     if (!isset($modules[$modulename])) {
         return array(_("Could not read module.xml"));
     }
     // don't force this bit - we can't install a broken module (missing files)
     if ($modules[$modulename]['status'] == MODULE_STATUS_BROKEN) {
         return array(_("Module " . $modules[$modulename]['rawname'] . " is broken and cannot be installed. You should try to download it again."));
     }
     $mod = FreePBX::GPG()->verifyModule($modulename);
     $revoked = $mod['status'] & GPG::STATE_REVOKED;
     if ($revoked) {
         return array(_("Module " . $modulename . " has a revoked signature and cannot be installed"));
     }
     if (!$force) {
         if (!in_array($modules[$modulename]['status'], array(MODULE_STATUS_ENABLED, MODULE_STATUS_NOTINSTALLED, MODULE_STATUS_NEEDUPGRADE))) {
             //return array(_("This module is already installed."));
             // This isn't really an error, we just exit
             return true;
         }
         // check dependencies
         if (is_array($errors = $this->checkdepends($modules[$modulename]))) {
             return $errors;
         }
     }
     // Check if another module wants this install to be rejected
     // The module must have a callback: [modulename]_module_install_check_callback() that takes
     // a single modules array from module_getinfo() about the module to be installed
     // and it must pass back boolean true if the installation can proceed, or a message
     // indicating why the installation must fail
     //
     $rejects = array();
     //We need to include developer files before the callback happens during an install
     if (!$this->_runscripts_include($modules, 'install')) {
         return array(_("Failed to run installation scripts"));
     }
     foreach (mod_func_iterator('module_install_check_callback', $modules) as $mod => $res) {
         if ($res !== true) {
             $rejects[] = $res;
         }
     }
     if (!empty($rejects)) {
         return $rejects;
     }
     //Developer mode, remind them they need to run install_amp manually
     //run this before the install scripts below because they end up removing install.php...yup
     if ($modulename == 'framework' && !file_exists($dir . '/install.php')) {
         out(_("Framework has been detected as being in Developer mode, Please make sure to run './install_amp --update-links' manually so that any database or system settings can be updated"));
     }
     // run the scripts
     if (!$this->_runscripts($modulename, 'install', $modules)) {
         return array(_("Failed to run installation scripts"));
     }
     if ($modules[$modulename]['status'] == MODULE_STATUS_NOTINSTALLED) {
         // customize INSERT query
         $sql = "INSERT INTO modules (modulename, version, enabled) values ('" . $db->escapeSimple($modules[$modulename]['rawname']) . "','" . $db->escapeSimple($modules[$modulename]['version']) . "', 1);";
     } else {
         // just need to update the version
         $sql = "UPDATE modules SET version='" . $db->escapeSimple($modules[$modulename]['version']) . "' WHERE modulename = '" . $db->escapeSimple($modules[$modulename]['rawname']) . "'";
     }
     // run query
     $results = $db->query($sql);
     if (DB::IsError($results)) {
         return array(sprintf(_("Error updating database. Command was: %s; error was: %s "), $sql, $results->getMessage()));
     }
     // If module is framework then update the framework version
     // normally this is done inside of the funky upgrade script runner but we are changing this now as
     // framework and freepbx versions are the same
     if ($modulename == 'framework' && !empty($modules[$modulename]['version']) && getVersion() != $modules[$modulename]['version']) {
         out(sprintf(_("Framework Detected, Setting FreePBX Version to %s"), $modules[$modulename]['version']));
         $sql = "UPDATE admin SET value = '" . $db->escapeSimple($modules[$modulename]['version']) . "' WHERE variable = 'version'";
         $result = $db->query($sql);
         if (DB::IsError($result)) {
             die($result->getMessage());
         }
         if (getVersion() != $modules[$modulename]['version']) {
             die(_('Internal Error. Function getVersion did not match the Framework version, even after it was suppose to be applied'));
         }
     }
     // module is now installed & enabled, invalidate the modulelist class since it is now stale
     $modulelist =& modulelist::create($db);
     $modulelist->invalidate();
     // edit the notification table to list any remaining upgrades available or clear
     // it if none are left. It requres a copy of the most recent module_xml to compare
     // against the installed modules.
     //
     $sql = 'SELECT data FROM module_xml WHERE id = "xml"';
     $data = sql($sql, "getOne");
     $parser = new xml2ModuleArray($data);
     $xmlarray = $parser->parseAdvanced($data);
     $new_modules = array();
     if (count($xmlarray)) {
         foreach ($xmlarray['xml']['module'] as $mod) {
             $new_modules[$mod['rawname']] = $mod;
         }
     }
     $this->upgrade_notifications($new_modules, 'PASSIVE');
     needreload();
     FreePBX::Config()->update("SIGNATURECHECK", true);
     $db->query("DELETE FROM admin WHERE variable = 'unsigned' LIMIT 1");
     //Generate LESS on install
     //http://issues.freepbx.org/browse/FREEPBX-8287
     outn(_("Generating CSS..."));
     try {
         if ($modulename == 'framework') {
             FreePBX::Less()->generateMainStyles();
         } else {
             FreePBX::Less()->generateModuleStyles($modulename);
         }
     } catch (\Exception $e) {
     }
     out(_("Done"));
     return true;
 }
Example #3
0
     freepbx::out("Done");
     $vars['log'] = true;
 }
 fix_publisher($module);
 //add changelog if requested
 if ($vars['log'] && !$vars['debug']) {
     freepbx::outn("\tUpdating Changelog...");
     $msg = $vars['msg'] ? $vars['msg'] : 'Packaging of ver ' . $ver;
     package_update_changelog($module, $msg);
     freepbx::out("Done");
 }
 // Run xml script through the exact method that FreePBX currently uses. There have
 // been cases where XML is valid but this method still fails so it won't be caught
 // with the proper XML checer, better here then breaking the online repository
 // -Philippe L.
 $parser = new xml2ModuleArray();
 $xmlarray = $parser->parseAdvanced(file_get_contents($mod_dir . '/module.xml'));
 //Check XML File one more time to be safe
 freepbx::outn("\tChecking Modified Module XML...");
 //test xml file and get some of its values
 list($rawname, $ver, $supported, $license, $licenselink) = freepbx::check_xml_file($mod_dir);
 //dont continue if there is an issue with the xml
 if ($rawname == false || $ver == false || $supported == false || $license == false || $licenselink == false) {
     $missing = $rawname == false ? 'rawname' : ($ver == false ? 'version' : ($supported == false ? 'supported' : ($license == false ? 'license' : ($licenselink == false ? 'licenselink' : 'Unknown'))));
     freepbx::out('module.xml is missing ' . $missing);
     freepbx::out("Module " . $module . " will not be tagged!");
     continue;
 }
 //sanity check
 if ($rawname != $xmlarray['module']['rawname'] || $ver != $xmlarray['module']['version']) {
     freepbx::out('simple_xml_object and xml2modulearray mismatch');