Example #1
0
 /**
  * Perform the installation of plugins.
  *
  * If used for installation of remote plugins from the Moodle Plugins
  * directory, the $plugins must be list of {@link \core\update\remote_info}
  * object that represent installable remote plugins. The caller can use
  * {@link self::filter_installable()} to prepare the list.
  *
  * If used for installation of plugins from locally available ZIP files,
  * the $plugins should be list of objects with properties ->component and
  * ->zipfilepath.
  *
  * The method uses {@link mtrace()} to produce direct output and can be
  * used in both web and cli interfaces.
  *
  * @param array $plugins list of plugins
  * @param bool $confirmed should the files be really deployed into the dirroot?
  * @param bool $silent perform without output
  * @return bool true on success
  */
 public function install_plugins(array $plugins, $confirmed, $silent)
 {
     global $CFG, $OUTPUT;
     if (!empty($CFG->disableupdateautodeploy)) {
         return false;
     }
     if (empty($plugins)) {
         return false;
     }
     $ok = get_string('ok', 'core');
     // Let admins know they can expect more verbose output.
     $silent or $this->mtrace(get_string('packagesdebug', 'core_plugin'), PHP_EOL, DEBUG_NORMAL);
     // Download all ZIP packages if we do not have them yet.
     $zips = array();
     foreach ($plugins as $plugin) {
         if ($plugin instanceof \core\update\remote_info) {
             $zips[$plugin->component] = $this->get_remote_plugin_zip($plugin->version->downloadurl, $plugin->version->downloadmd5);
             $silent or $this->mtrace(get_string('packagesdownloading', 'core_plugin', $plugin->component), ' ... ');
             $silent or $this->mtrace(PHP_EOL . ' <- ' . $plugin->version->downloadurl, '', DEBUG_DEVELOPER);
             $silent or $this->mtrace(PHP_EOL . ' -> ' . $zips[$plugin->component], ' ... ', DEBUG_DEVELOPER);
             if (!$zips[$plugin->component]) {
                 $silent or $this->mtrace(get_string('error'));
                 return false;
             }
             $silent or $this->mtrace($ok);
         } else {
             if (empty($plugin->zipfilepath)) {
                 throw new coding_exception('Unexpected data structure provided');
             }
             $zips[$plugin->component] = $plugin->zipfilepath;
             $silent or $this->mtrace('ZIP ' . $plugin->zipfilepath, PHP_EOL, DEBUG_DEVELOPER);
         }
     }
     // Validate all downloaded packages.
     foreach ($plugins as $plugin) {
         $zipfile = $zips[$plugin->component];
         $silent or $this->mtrace(get_string('packagesvalidating', 'core_plugin', $plugin->component), ' ... ');
         list($plugintype, $pluginname) = core_component::normalize_component($plugin->component);
         $tmp = make_request_directory();
         $zipcontents = $this->unzip_plugin_file($zipfile, $tmp, $pluginname);
         if (empty($zipcontents)) {
             $silent or $this->mtrace(get_string('error'));
             $silent or $this->mtrace('Unable to unzip ' . $zipfile, PHP_EOL, DEBUG_DEVELOPER);
             return false;
         }
         $validator = \core\update\validator::instance($tmp, $zipcontents);
         $validator->assert_plugin_type($plugintype);
         $validator->assert_moodle_version($CFG->version);
         // TODO Check for missing dependencies during validation.
         $result = $validator->execute();
         if (!$silent) {
             $result ? $this->mtrace($ok) : $this->mtrace(get_string('error'));
             foreach ($validator->get_messages() as $message) {
                 if ($message->level === $validator::INFO) {
                     // Display [OK] validation messages only if debugging mode is DEBUG_NORMAL.
                     $level = DEBUG_NORMAL;
                 } else {
                     if ($message->level === $validator::DEBUG) {
                         // Display [Debug] validation messages only if debugging mode is DEBUG_ALL.
                         $level = DEBUG_ALL;
                     } else {
                         // Display [Warning] and [Error] always.
                         $level = null;
                     }
                 }
                 if ($message->level === $validator::WARNING and !CLI_SCRIPT) {
                     $this->mtrace('  <strong>[' . $validator->message_level_name($message->level) . ']</strong>', ' ', $level);
                 } else {
                     $this->mtrace('  [' . $validator->message_level_name($message->level) . ']', ' ', $level);
                 }
                 $this->mtrace($validator->message_code_name($message->msgcode), ' ', $level);
                 $info = $validator->message_code_info($message->msgcode, $message->addinfo);
                 if ($info) {
                     $this->mtrace('[' . s($info) . ']', ' ', $level);
                 } else {
                     if (is_string($message->addinfo)) {
                         $this->mtrace('[' . s($message->addinfo, true) . ']', ' ', $level);
                     } else {
                         $this->mtrace('[' . s(json_encode($message->addinfo, true)) . ']', ' ', $level);
                     }
                 }
                 if ($icon = $validator->message_help_icon($message->msgcode)) {
                     if (CLI_SCRIPT) {
                         $this->mtrace(PHP_EOL . '  ^^^ ' . get_string('help') . ': ' . get_string($icon->identifier . '_help', $icon->component), '', $level);
                     } else {
                         $this->mtrace($OUTPUT->render($icon), ' ', $level);
                     }
                 }
                 $this->mtrace(PHP_EOL, '', $level);
             }
         }
         if (!$result) {
             $silent or $this->mtrace(get_string('packagesvalidatingfailed', 'core_plugin'));
             return false;
         }
     }
     $silent or $this->mtrace(PHP_EOL . get_string('packagesvalidatingok', 'core_plugin'));
     if (!$confirmed) {
         return true;
     }
     // Extract all ZIP packs do the dirroot.
     foreach ($plugins as $plugin) {
         $silent or $this->mtrace(get_string('packagesextracting', 'core_plugin', $plugin->component), ' ... ');
         $zipfile = $zips[$plugin->component];
         list($plugintype, $pluginname) = core_component::normalize_component($plugin->component);
         $target = $this->get_plugintype_root($plugintype);
         if (file_exists($target . '/' . $pluginname)) {
             $this->remove_plugin_folder($this->get_plugin_info($plugin->component));
         }
         if (!$this->unzip_plugin_file($zipfile, $target, $pluginname)) {
             $silent or $this->mtrace(get_string('error'));
             $silent or $this->mtrace('Unable to unzip ' . $zipfile, PHP_EOL, DEBUG_DEVELOPER);
             if (function_exists('opcache_reset')) {
                 opcache_reset();
             }
             return false;
         }
         $silent or $this->mtrace($ok);
     }
     if (function_exists('opcache_reset')) {
         opcache_reset();
     }
     return true;
 }
 public function testable_parse_version_php($fullpath)
 {
     return parent::parse_version_php($fullpath);
 }