diff options
Diffstat (limited to 'lib/plugins/extension')
-rw-r--r-- | lib/plugins/extension/helper/extension.php | 188 | ||||
-rw-r--r-- | lib/plugins/extension/helper/repository.php | 112 |
2 files changed, 292 insertions, 8 deletions
diff --git a/lib/plugins/extension/helper/extension.php b/lib/plugins/extension/helper/extension.php index 2746837be..b8981cf91 100644 --- a/lib/plugins/extension/helper/extension.php +++ b/lib/plugins/extension/helper/extension.php @@ -17,6 +17,9 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { private $is_template; private $localInfo; private $remoteInfo; + private $managerData; + /** @var helper_plugin_extension_repository $repository */ + private $repository = null; /** * @return bool false, this component is not a singleton @@ -35,6 +38,28 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { public function setExtension($name, $is_template) { $this->name = $name; $this->is_template = $is_template; + $this->localInfo = array(); + $this->managerData = array(); + $this->remoteInfo = array(); + + if ($this->isInstalled()) { + if ($this->isTemplate()) { + $infopath = $this->getInstallDir().'/template.info.txt'; + } else { + $infopath = $this->getInstallDir().'/plugin.info.txt'; + } + if (is_readable($infopath)) { + $this->localInfo = confToHash($infopath); + } + + $this->readManagerData(); + } + + if ($this->repository == null) { + $this->repository = $this->loadHelper('extension_repository'); + } + + $this->remoteInfo = $this->repository->getData(($this->isTemplate() ? 'template:' : '').$this->getBase()); } /** @@ -43,6 +68,18 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return bool If the extension is installed locally */ public function isInstalled() { + return is_dir($this->getInstallDir()); + } + + /** + * If the extension is enabled + * + * @return bool If the extension is enabled + */ + public function isEnabled() { + /* @var Doku_Plugin_Controller $plugin_controller */ + global $plugin_controller; + return !$plugin_controller->isdisabled($this->name); } /** @@ -51,6 +88,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return bool If an update is available */ public function updateAvailable() { + $lastupdate = $this->getLastUpdate(); + if ($lastupdate === false) return false; return $this->getInstalledVersion() < $this->getLastUpdate(); } @@ -70,6 +109,7 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string The basename */ public function getBase() { + return $this->name; } /** @@ -78,6 +118,9 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string The display name */ public function getName() { + if (isset($this->localInfo['name'])) return $this->localInfo['name']; + if (isset($this->remoteInfo['name'])) return $this->remoteInfo['name']; + return $this->name; } /** @@ -86,14 +129,31 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string The name of the author */ public function getAuthor() { + if (isset($this->localInfo['author'])) return $this->localInfo['author']; + if (isset($this->remoteInfo['author'])) return $this->remoteInfo['author']; + return $this->getLang('unknownauthor'); } /** - * Get the email of the author of the extension + * Get the email of the author of the extension if there is any * - * @return string The email address + * @return string|bool The email address or false if there is none */ public function getEmail() { + // email is only in the local data + if (isset($this->localInfo['email'])) return $this->localInfo['email']; + return false; + } + + /** + * Get the email id, i.e. the md5sum of the email + * + * @return string|bool The md5sum of the email if there is any, false otherwise + */ + public function getEmailID() { + if (isset($this->remoteInfo['emailid'])) return $this->remoteInfo['emailid']; + if (isset($this->localInfo['email'])) return md5($this->localInfo['email']); + return false; } /** @@ -102,6 +162,9 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string The description */ public function getDescription() { + if (isset($this->localInfo['desc'])) return $this->localInfo['desc']; + if (isset($this->remoteInfo['description'])) return $this->remoteInfo['description']; + return ''; } /** @@ -110,14 +173,19 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string The URL */ public function getURL() { + if (isset($this->localInfo['url'])) return $this->localInfo['url']; + return 'https://www.dokuwiki.org/plugin:'.$this->name; } /** * Get the installed version of the extension * - * @return string The version, usually in the form yyyy-mm-dd + * @return string|bool The version, usually in the form yyyy-mm-dd if there is any */ public function getInstalledVersion() { + if (isset($this->localInfo['date'])) return $this->localInfo['date']; + if ($this->isInstalled()) return $this->getLang('unknownversion'); + return false; } /** @@ -126,6 +194,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return array The base names of the dependencies */ public function getDependencies() { + if (isset($this->remoteInfo['dependencies'])) return $this->remoteInfo['dependencies']; + return array(); } /** @@ -134,6 +204,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return array The names of the conflicting extensions */ public function getConflicts() { + if (isset($this->remoteInfo['conflicts'])) return $this->remoteInfo['dependencies']; + return array(); } /** @@ -141,7 +213,9 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * * @return array The names of similar extensions */ - public function getSimilarPlugins() { + public function getSimilarExtensions() { + if (isset($this->remoteInfo['similar'])) return $this->remoteInfo['similar']; + return array(); } /** @@ -150,6 +224,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return array The names of the tags of the extension */ public function getTags() { + if (isset($this->remoteInfo['tags'])) return $this->remoteInfo['tags']; + return array(); } /** @@ -158,6 +234,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string|bool The security warning if there is any, false otherwise */ public function getSecurityWarning() { + if (isset($this->remoteInfo['securitywarning'])) return $this->remoteInfo['securitywarning']; + return false; } /** @@ -166,6 +244,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string|bool The security issue if there is any, false otherwise */ public function getSecurityIssue() { + if (isset($this->remoteInfo['securityissue'])) return $this->remoteInfo['securityissue']; + return false; } /** @@ -174,6 +254,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string|bool The screenshot URL if there is any, false otherwise */ public function getScreenshotURL() { + if (isset($this->remoteInfo['screenshoturl'])) return $this->remoteInfo['screenshoturl']; + return false; } /** @@ -182,6 +264,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string|bool The previously used download URL, false if the extension has been installed manually */ public function getLastDownloadURL() { + if (isset($this->managerData['downloadurl'])) return $this->managerData['downloadurl']; + return false; } /** @@ -190,6 +274,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string|bool The download URL if there is any, false otherwise */ public function getDownloadURL() { + if (isset($this->remoteInfo['downloadurl'])) return $this->remoteInfo['downloadurl']; + return false; } /** @@ -198,6 +284,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string|bool The bug tracker URL if there is any, false otherwise */ public function getBugtrackerURL() { + if (isset($this->remoteInfo['bugtracker'])) return $this->remoteInfo['bugtracker']; + return false; } /** @@ -206,6 +294,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string|bool The URL of the source repository if there is any, false otherwise */ public function getSourcerepoURL() { + if (isset($this->remoteInfo['sourcerepo'])) return $this->remoteInfo['sourcerepo']; + return false; } /** @@ -214,6 +304,8 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string|bool The donation URL if there is any, false otherwise */ public function getDonationURL() { + if (isset($this->remoteInfo['donationurl'])) return $this->remoteInfo['donationurl']; + return false; } /** @@ -221,23 +313,30 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * * @return array The type(s) as array of strings */ - public function getType() { + public function getTypes() { + if (isset($this->remoteInfo['types'])) return explode(', ', $this->remoteInfo['types']); + if ($this->isTemplate()) return array(32 => 'template'); + return array(); } /** * Get a list of all DokuWiki versions this extension is compatible with * - * @return array The versions in the form yyyy-mm-dd + * @return array The versions in the form yyyy-mm-dd => ('label' => label, 'implicit' => implicit) */ public function getCompatibleVersions() { + if (isset($this->remoteInfo['compatible'])) return $this->remoteInfo['compatible']; + return array(); } /** * Get the date of the last available update * - * @return string The last available update in the form yyyy-mm-dd + * @return string|bool The last available update in the form yyyy-mm-dd if there is any, false otherwise */ public function getLastUpdate() { + if (isset($this->remoteInfo['lastupdate'])) return $this->remoteInfo['lastupdate']; + return false; } /** @@ -259,6 +358,10 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * @return string One of "none", "manual", "git" or "automatic" */ public function getInstallType() { + if (!$this->isInstalled()) return 'none'; + if (!empty($this->managerData)) return 'automatic'; + if (is_dir($this->getInstallDir().'/.git')) return 'git'; + return 'manual'; } /** @@ -282,7 +385,76 @@ class helper_plugin_extension_extension extends DokuWiki_Plugin { * * @return bool|string True or an error message */ - public function deleteExtension() { + public function uninstall() { + } + + /** + * Enable the extension + * + * @return bool|string True or an error message + */ + public function enable() { + if ($this->isTemplate()) return $this->getLang('notimplemented'); + /* @var Doku_Plugin_Controller $plugin_controller */ + global $plugin_controller; + if (!$this->isInstalled()) return $this->getLang('notinstalled'); + if (!$this->isEnabled()) return $this->getLang('alreadyenabled'); + if ($plugin_controller->enable($this->name)) { + return true; + } else { + return $this->getLang('pluginlistsaveerror'); + } + } + + /** + * Disable the extension + * + * @return bool|string True or an error message + */ + public function disable() { + if ($this->isTemplate()) return $this->getLang('notimplemented'); + + /* @var Doku_Plugin_Controller $plugin_controller */ + global $plugin_controller; + if (!$this->isInstalled()) return $this->getLang('notinstalled'); + if (!$this->isEnabled()) return $this->getLang('alreadydisabled'); + if ($plugin_controller->disable($this->name)) { + return true; + } else { + return $this->getLang('pluginlistsaveerror'); + } + } + + /** + * Read the manager.dat file + */ + protected function readManagerData() { + $managerpath = $this->getInstallDir().'/manager.dat'; + if (is_readable($managerpath)) { + $file = @file($managerpath); + if(!empty($file)) { + foreach($file as $line) { + list($key, $value) = explode('=', trim($line, PHP_EOL), 2); + $key = trim($key); + $value = trim($value); + // backwards compatible with old plugin manager + if($key == 'url') $key = 'downloadurl'; + $this->managerData[$key] = $value; + } + } + } + } + + /** + * Write the manager.data file + */ + protected function writeManagerData() { + $managerpath = $this->getInstallDir().'/manager.dat'; + $data = ''; + foreach ($this->managerData as $k => $v) { + $data .= $k.'='.$v.DOKU_LF; + } + io_saveFile($managerpath, $data); } } diff --git a/lib/plugins/extension/helper/repository.php b/lib/plugins/extension/helper/repository.php new file mode 100644 index 000000000..37b9bc02c --- /dev/null +++ b/lib/plugins/extension/helper/repository.php @@ -0,0 +1,112 @@ +<?php +/** + * DokuWiki Plugin extension (Helper Component) + * + * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html + * @author Michael Hamann <michael@content-space.de> + */ + +if (!defined('EXTENSION_REPOSITORY_API_ENDPOINT')) + define('EXTENSION_REPSITORY_API', 'http://www.dokuwiki.org/lib/plugins/pluginrepo/api.php'); + +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +/** + * Class helper_plugin_extension_repository provides access to the extension repository on dokuwiki.org + */ +class helper_plugin_extension_repository extends DokuWiki_Plugin { + private $loaded_extensions = array(); + private $has_access = null; + /** + * Initialize the repository (cache), fetches data for all installed plugins + */ + public function init() { + /* @var Doku_Plugin_Controller $plugin_controller */ + global $plugin_controller; + if ($this->hasAccess()) { + $list = $plugin_controller->getList('', true); + $request_data = array('fmt' => 'php'); + $request_needed = false; + foreach ($list as $name) { + $cache = new cache('##extension_manager##'.$name, 'repo'); + $result = null; + if (!isset($this->loaded_extensions[$name]) && $this->hasAccess() && !$cache->useCache(array('age' => 3600 * 24))) { + $this->loaded_extensions[$name] = true; + $request_data['ext'][] = $name; + $request_needed = true; + } + } + + if ($request_needed) { + $httpclient = new DokuHTTPClient(); + $data = $httpclient->post(EXTENSION_REPSITORY_API, $request_data); + if ($data !== false) { + $extensions = unserialize($data); + foreach ($extensions as $extension) { + $cache = new cache('##extension_manager##'.$extension['plugin'], 'repo'); + $cache->storeCache(serialize($extension)); + } + } else { + $this->has_access = false; + } + } + } + } + + /** + * If repository access is available + * + * @return bool If repository access is available + */ + public function hasAccess() { + if ($this->has_access === null) { + $cache = new cache('##extension_manager###hasAccess', 'repo'); + $result = null; + if (!$cache->useCache(array('age' => 3600 * 24))) { + $httpclient = new DokuHTTPClient(); + $httpclient->timeout = 5; + $data = $httpclient->get(EXTENSION_REPSITORY_API.'?cmd=ping'); + if ($data !== false) { + $this->has_access = true; + $cache->storeCache(1); + } else { + $this->has_access = false; + $cache->storeCache(0); + } + } else { + $this->has_access = ($cache->retrieveCache(false) == 1); + } + } + return $this->has_access; + } + + /** + * Get the remote data of an individual plugin or template + * + * @param string $name The plugin name to get the data for, template names need to be prefix by 'template:' + * @return array The data or null if nothing was found (possibly no repository access) + */ + public function getData($name) { + $cache = new cache('##extension_manager##'.$name, 'repo'); + $result = null; + if (!isset($this->loaded_extensions[$name]) && $this->hasAccess() && !$cache->useCache(array('age' => 3600 * 24))) { + $this->loaded_extensions[$name] = true; + $httpclient = new DokuHTTPClient(); + $data = $httpclient->get(EXTENSION_REPSITORY_API.'?fmt=php&ext[]='.urlencode($name)); + if ($data !== false) { + $result = unserialize($data); + $cache->storeCache(serialize($result[0])); + return $result[0]; + } else { + $this->has_access = false; + } + } + if (file_exists($cache->cache)) { + return unserialize($cache->retrieveCache(false)); + } + return array(); + } +} + +// vim:ts=4:sw=4:et: |