Example #1
0
 public function verifyAndUpdatePlugins()
 {
     $plugins = Plugin::where('active', '=', 1)->get();
     // Going to compare checksums
     // for each of these plugins
     $n = 0;
     foreach ($plugins as $num => $plugin) {
         $n++;
         // Defaults not to update
         $update = false;
         // fetching via http
         $xml = @file_get_contents($plugin->xml_url);
         if (!$xml) {
             echo 'Plugin (' . $n . '/' . sizeof($plugins) . "): \"" . $plugin->name . "\" Cannot get XML file via HTTP, Skipping.\n";
             continue;
         }
         $crc = md5($xml);
         // compute crc
         if ($plugin->xml_crc != $crc || $plugin->name == NULL) {
             $update = true;
             // if we got
             // missing name or changing
             // crc, then we're going to
             // update that one
         } else {
             echo 'Plugin (' . $n . '/' . sizeof($plugins) . "): \"" . $plugin->name . "\" Already updated, Skipping.\n";
             continue;
         }
         // loading XML OO-style with simplemxl
         $xml = new ValidableXMLPluginDescription($xml);
         if (!$xml->isValid()) {
             echo 'Plugin (' . $n . '/' . sizeof($plugins) . "): \"" . $plugin->name . "\" Unreadable/Non validable XML, Skipping.\n";
             echo "Errors: \n";
             foreach ($xml->errors as $error) {
                 echo " - " . $error . "\n";
             }
             continue;
         }
         $xml = $xml->contents;
         echo 'Plugin (' . $n . '/' . sizeof($plugins) . '): Updating ... ';
         $this->updatePlugin($plugin, $xml, $crc);
     }
 }
Example #2
0
/**
 * Download
 *
 * This REST module hooks on
 * following URLs
 *
 * /download/:plugin_id
 */
use API\Core\Tool;
use API\Model\Plugin;
use API\Model\PluginDownload;
use Illuminate\Database\Capsule\Manager as DB;
use API\OAuthServer\OAuthHelper;
$download = Tool::makeEndpoint(function ($key) use($app) {
    $plugin = Plugin::where('key', '=', $key)->first();
    $plugin->download_count = DB::raw('download_count + 1');
    $plugin->save();
    $plugin_download = new PluginDownload();
    $plugin_download->downloaded_at = DB::raw('NOW()');
    $plugin_download->plugin_id = $plugin->id;
    $plugin_download->save();
    /**
     * @MonkeyPatch
     * @todo remove this as soon as possible once
     * all our famous, star, since-day-one
     * contributors took the time
     * to update their XML file.
     */
    $indepnetFixSearchPattern = '/https:\\/\\/forge\\.indepnet\\.net/';
    if (preg_match($indepnetFixSearchPattern, $plugin->download_url)) {
Example #3
0
 /**
  * Task : updatePlugin()
  *
  * Note: This function does direct output,
  * in fact it builds the log string
  * that concerns the update of a
  * plugin.
  */
 private function updatePlugin($plugin, $index = null, $length = null, $subtasks)
 {
     // Displaying index / length
     $this->outputStr('Plugin (' . $index . '/' . $length . ') (id #' . $plugin->id . '): ');
     $update = false;
     // This can be used to detect the state
     // in some way (think about it)
     $this->currentXml = null;
     $this->currentPluginState = null;
     // fetching via http
     $unableToFetch = false;
     $httpClient = new GuzzleHttpClient();
     try {
         $pluginXmlRequest = $httpClient->get($plugin->xml_url, ["headers" => ["User-Agent" => Tool::getConfig()['glpi_plugin_directory_user_agent']]]);
     } catch (\GuzzleHttp\Exception\ConnectException $e) {
         $unableToFetch = true;
     } finally {
         if ($unableToFetch || !$unableToFetch && $pluginXmlRequest->getStatusCode() != 200) {
             if ($this->pluginMaxConsecutiveXmlFetchFails) {
                 $fetchFailCount = $plugin->incrementXmlFetchFailCount();
                 if ($fetchFailCount == $this->pluginMaxConsecutiveXmlFetchFails) {
                     $this->triggerPluginXmlStateChange($plugin, 'bad_xml_url', true, in_array('alert_plugin_team_on_xml_state_change', $subtasks));
                     $plugin->resetXmlFetchFailCount();
                 }
             } else {
                 $this->triggerPluginXmlStateChange($plugin, 'bad_xml_url', true, in_array('alert_plugin_team_on_xml_state_change', $subtasks));
             }
             $this->outputStr($plugin->xml_url . "\" Cannot get XML file via HTTP, Skipping.\n");
             if ($this->throwsExceptions) {
                 throw new InvalidXML('url', $plugin->xml_url);
             }
             return false;
         } else {
             $plugin->resetXmlFetchFailCount();
         }
     }
     $xml = $pluginXmlRequest->getBody();
     $this->currentXml = (string) $xml;
     $crc = md5($xml);
     // compute crc
     if ($plugin->xml_crc != $crc || $plugin->name == NULL) {
         $update = true;
         // if we got
         // missing name or changing
         // crc, then we're going to
         // update that one.
         // missing name means it's
         // the first time the plugin
         // is updated
     } else {
         $this->outputStr("\"" . $plugin->name . "\" Already up-to-date, Skipping.\n");
         $this->triggerPluginXmlStateChange($plugin, 'passing', true, in_array('alert_plugin_team_on_xml_state_change', $subtasks));
         return false;
     }
     try {
         $xml = new ValidableXMLPluginDescription($xml);
         $xml->validate();
     } catch (\API\Exception\InvalidXML $e) {
         $_unreadable = '';
         if (isset($xml->contents) && $xml->contents->name && sizeof($xml->contents->name->children()) < 1 && strlen((string) $xml->contents->name) < 80) {
             $_unreadable .= '"' . (string) $xml->contents->key . '" ';
         } elseif ($plugin->name) {
             $_unreadable .= '"' . $plugin->name . '" ';
         }
         $this->triggerPluginXmlStateChange($plugin, 'xml_error', true, in_array('alert_plugin_team_on_xml_state_change', $subtasks));
         $_unreadable .= "Unreadable/Non validable XML, error: " . $e->getRepresentation() . " Skipping.\n";
         $this->outputStr($_unreadable);
         if ($this->throwsExceptions) {
             throw $e;
         }
         return false;
     }
     $xml = $xml->contents;
     if (!$plugin->name) {
         $this->outputStr("first time update, found name \"" . $xml->name . "\"...");
         if (Plugin::where('name', '=', $xml->name)->first()) {
             $this->outputStr(" already exists. skipping.");
             // this would be amazing to alert the administrators
             // of that. new Mailer; ?
             return false;
         }
         $firstTimeUpdate = true;
     } else {
         if ($plugin->name != $xml->name) {
             $this->outputStr(" requested name change to \"" . $xml->name . "\" ...");
             if (Plugin::where('name', '=', $xml->name)->first()) {
                 $this->outputStr(" but name already exists. skipping.");
                 // this would be amazing to alert the administrators
                 // of that. new Mailer; ?
                 return false;
             }
         }
         $firstTimeUpdate = false;
         $this->outputStr("\"" . $plugin->name . "\"");
     }
     $this->outputStr(" going to be synced with xml ...");
     $this->triggerPluginXmlStateChange($plugin, 'passing', true, in_array('alert_plugin_team_on_xml_state_change', $subtasks));
     // Updating basic infos
     $plugin->logo_url = $xml->logo;
     $plugin->name = $xml->name;
     $plugin->key = $xml->key;
     $plugin->homepage_url = $xml->homepage;
     $plugin->download_url = $xml->download;
     $plugin->issues_url = $xml->issues;
     $plugin->readme_url = $xml->readme;
     $plugin->license = $xml->license;
     // reading descriptions,
     // mapping type=>lang relation to lang=>type
     $descriptions = [];
     foreach ($xml->description->children() as $type => $descs) {
         if (in_array($type, ['short', 'long'])) {
             foreach ($descs->children() as $_lang => $content) {
                 $descriptions[$_lang][$type] = (string) $content;
             }
         }
     }
     // Delete current descriptions
     $plugin->descriptions()->delete();
     // Refreshing descriptions
     foreach ($descriptions as $lang => $_type) {
         $description = new PluginDescription();
         $description->lang = $lang;
         foreach ($_type as $type => $html) {
             $description[$type . '_description'] = $html;
         }
         $description->plugin_id = $plugin->id;
         $description->save();
     }
     // Refreshing authors
     $plugin->authors()->detach();
     $clean_authors = [];
     foreach ($xml->authors->children() as $author) {
         $_clean_authors = Author::fixKnownDuplicates((string) $author);
         foreach ($_clean_authors as $author) {
             $clean_authors[] = $author;
         }
     }
     foreach ($clean_authors as $_author) {
         $found = Author::where('name', '=', $_author)->first();
         if (sizeof($found) < 1) {
             $author = new Author();
             $author->name = $_author;
             $author->save();
         } else {
             $author = $found;
         }
         if (!$plugin->authors->find($author->id)) {
             $plugin->authors()->attach($author);
         }
     }
     // Refreshing versions
     $plugin->versions()->delete();
     foreach ($xml->versions->children() as $_version) {
         foreach ($_version->compatibility as $compat) {
             $version = new PluginVersion();
             $version->num = trim((string) $_version->num);
             $version->compatibility = trim((string) $compat);
             $version->plugin_id = $plugin->id;
             $version->save();
         }
     }
     // Refreshing screenshots
     if (isset($xml->screenshots)) {
         $plugin->screenshots()->delete();
         foreach ($xml->screenshots->children() as $url) {
             $screenshot = new PluginScreenshot();
             $screenshot->url = (string) $url;
             $screenshot->plugin_id = $plugin->id;
             $screenshot->save();
         }
     }
     // Reassociating plugin to tags
     $plugin->tags()->detach();
     foreach ($xml->tags->children() as $lang => $tags) {
         foreach ($tags->children() as $_tag) {
             $found = Tag::where('tag', '=', (string) $_tag)->where('lang', '=', $lang)->first();
             if (sizeof($found) < 1) {
                 $tag = new Tag();
                 $tag->tag = (string) $_tag;
                 $tag->lang = $lang;
                 $tag->key = Tool::getUrlSlug((string) $_tag);
                 $tag->save();
             } else {
                 $tag = $found;
             }
             $tag->plugins()->attach($plugin);
         }
     }
     // Reassociating plugin to langs
     $plugin->langs()->detach();
     foreach ($xml->langs->children() as $lang) {
         $lang = (string) $lang;
         $_lang = PluginLang::where('lang', '=', $lang)->first();
         if (!$_lang) {
             $_lang = new PluginLang();
             $_lang->lang = $lang;
             $_lang->save();
         }
         $_lang->plugins()->attach($plugin);
     }
     // new crc
     $plugin->xml_crc = $crc;
     // new updated timestamp
     $plugin->date_updated = \Illuminate\Database\Capsule\Manager::raw('NOW()');
     $plugin->save();
     $this->outputStr(" OK.");
     if (in_array('alert_watchers', $subtasks)) {
         $this->alertWatchers($plugin);
         $this->outputStr("\n");
     } else {
         $this->outputStr("\n");
     }
 }
Example #4
0
     }
 }
 // Quickly validating
 if (Plugin::where('xml_url', '=', $body->plugin_url)->count() > 0) {
     return Tool::endWithJson(["error" => "That plugin XML URL has already been submitted."]);
 }
 $xml = @file_get_contents($body->plugin_url);
 if (!$xml) {
     return Tool::endWithJson(["error" => "We cannot fetch that URL."]);
 }
 $xml = new ValidableXMLPluginDescription($xml);
 if (!$xml->isValid()) {
     return Tool::endWithJson(["error" => "Unreadable/Non validable XML.", "details" => $xml->errors]);
 }
 $xml = $xml->contents;
 if (Plugin::where('key', '=', $xml->key)->count() > 0) {
     return Tool::endWithJson(["error" => "Your XML describe a plugin whose key already exists in our database."]);
 }
 $plugin = new Plugin();
 $plugin->xml_url = $body->plugin_url;
 $plugin->date_added = DB::raw('NOW()');
 $plugin->active = false;
 $plugin->save();
 $msg_alerts_settings = Tool::getConfig()['msg_alerts'];
 $recipients = '';
 $i = 0;
 foreach ($msg_alerts_settings['recipients'] as $recipient) {
     if ($i > 0) {
         $recipients .= ', ';
     }
     $recipients .= $recipient;