/** * 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"); } }
} else { $tags = $tags->withLang(Tool::getRequestLang()); } Tool::endWithJson($tags->get()); }); $tag_single = Tool::makeEndpoint(function ($key) use($app) { OAuthHelper::needsScopes(['tag']); $tag = Tag::where('key', '=', $key)->first(); if ($tag == NULL) { throw new \API\Exception\ResourceNotFound('Tag', $key); } Tool::endWithJson($tag); }); $tag_plugins = Tool::makeEndpoint(function ($key) use($app) { OAuthHelper::needsScopes(['tag', 'plugins']); $tag = Tag::where('key', '=', $key)->first(); if ($tag == NULL) { throw new \API\Exception\ResourceNotFound('Tag', $key); } $plugins = Tool::paginateCollection(Plugin::with('versions', 'authors')->short()->withAverageNote()->descWithLang(Tool::getRequestLang())->withTag($tag)); Tool::endWithJson($plugins); }); // HTTP rest map $app->get('/tags', $tags_all); $app->get('/tags/top', $tags_top); $app->get('/tags/:id/plugin', $tag_plugins); $app->get('/tags/:id', $tag_single); $app->options('/tags', function () { }); $app->options('/tags/top', function () { });
public function updatePlugin($plugin, $xml, $new_crc) { if (strlen($plugin->name) == 0) { echo "first time update, found name \"" . $xml->name . "\"..."; $firstTimeUpdate = true; } else { if ($plugin->name != $xml->name) { echo "\"" . $plugin->name . "\" going to become \"" . $xml->name . "\" ..."; } else { echo "\"" . $xml->name . "\" going to be updated ..."; } } // 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 = $this->fixParseAuthors((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); } } // new crc $plugin->xml_crc = $new_crc; // new timestamp if (!isset($firstTimeUpdate)) { $plugin->date_updated = DB::raw('NOW()'); } $plugin->save(); echo " OK\n"; }