readMetadata($url); } else { foreach ($GLOBALS['PLUGIN_REPOSITORIES'] as $url) { $this->readMetadata($url); } } } /** * Read plugin meta data from the given URL (using XML format). * The structure of the XML is: * * * * * [...] * * * @param string $url plugin repository url */ public function readMetadata($url) { $cache = \Studip\Cache\Factory::getCache(); $cache_key = 'plugin_metadata/'.$url; $metadata = $cache->read($cache_key); if ($metadata === false) { // Set small timeout for the rare case that the repository is not // available $context = get_default_http_stream_context($url); stream_context_set_option($context, ['http' => [ 'timeout' => 5, ]]); $metadata = @file_get_contents($url, false, $context); if ($metadata === false) { throw new Exception(sprintf(_('Fehler beim Zugriff auf %s'), $url)); } $cache->write($cache_key, $metadata, 3600); } $xml = new SimpleXMLElement($metadata); if (!isset($xml->plugin)) { $cache->expire($cache_key); throw new Exception(_('Keine Plugin Meta-Daten gefunden')); } foreach ($xml->plugin as $plugin) { foreach ($plugin->release as $release) { $min_version = trim($release['studipMinVersion']); $max_version = trim($release['studipMaxVersion']); if (($min_version && StudipVersion::olderThan($min_version)) || ($max_version && StudipVersion::newerThan($max_version))) { // plugin is not compatible, so skip it continue; } $meta_data = [ 'version' => (string) $release['version'], 'url' => (string) $release['url'], 'description' => (string) $plugin['description'], 'plugin_url' => (string) $plugin['homepage'], 'image' => (string) $plugin['image'], 'score' => (float) $plugin['score'], 'marketplace_url' => (string) $plugin['marketplace_url'], ]; $this->registerPlugin((string) $plugin['name'], $meta_data); } } } /** * Register a new plugin in this repository. * * @param string $name plugin name * @param array $meta_data plugin meta data */ protected function registerPlugin($name, $meta_data) { $old_data = $this->plugins[$name] ?? null; if (!isset($old_data) || version_compare($meta_data['version'], $old_data['version']) > 0) { $this->plugins[$name] = $meta_data; } } /** * Get meta data for the plugin with the given name (if available). * Always chooses the newest compatible version of the plugin. * @param string $name name of the plgin * @return array meta data for plugin (or null) */ public function getPlugin($name) { return $this->plugins[$name] ?? null; } /** * Get meta data for all plugins whose names contain the given * string. You may omit the search string to get a list of all * available plugins. Returns the newest compatible version of * each plugin. * @param string $search search string * @return array array of meta data for matching plugins */ public function getPlugins($search = null) { $result = []; foreach ($this->plugins as $name => $data) { if ($search === null || $search === '' || is_int(mb_stripos($name, $search)) || is_int(mb_stripos($data['description'], $search))) { $result[$name] = $data; } } return $result; } }