Forked from
Stud.IP / Stud.IP
3683 commits behind the upstream repository.
-
David Siegfried authoredDavid Siegfried authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
PluginRepository.class.php 5.00 KiB
<?php
/*
* PluginRepository.class.php - query plugin meta data
*
* Copyright (c) 2008 Elmar Ludwig
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
/**
* Class used to locate plugins available from a plugin repository.
*/
class PluginRepository
{
/**
* list and meta data of available plugins
*/
private $plugins = [];
/**
* Initialize a new PluginRepository and read meta data from
* the given URL or the default list of URLs (if $url is null).
*/
public function __construct($url = null)
{
if (isset($url)) {
$this->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:
*
* <plugins>
* <plugin name="DummyPlugin"
* <release
* version="2.0"
* url="http://plugins.example.com/dummy-2.0.zip"
* studipMinVersion="1.4"
* studipMaxVersion="1.9">
* </plugin>
* [...]
* </plugins>
*
* @param string $url given url for plugin
*/
public function readMetadata($url)
{
$cache = StudipCacheFactory::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];
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];
}
/**
* 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;
}
}