[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * DokuWiki Plugin extension (Helper Component) 5 * 6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 7 * @author Michael Hamann <michael@content-space.de> 8 */ 9 10 use dokuwiki\Extension\Plugin; 11 use dokuwiki\Cache\Cache; 12 use dokuwiki\HTTP\DokuHTTPClient; 13 use dokuwiki\Extension\PluginController; 14 15 /** 16 * Class helper_plugin_extension_repository provides access to the extension repository on dokuwiki.org 17 */ 18 class helper_plugin_extension_repository extends Plugin 19 { 20 public const EXTENSION_REPOSITORY_API = 'https://www.dokuwiki.org/lib/plugins/pluginrepo/api.php'; 21 22 private $loaded_extensions = []; 23 private $has_access; 24 25 /** 26 * Initialize the repository (cache), fetches data for all installed plugins 27 */ 28 public function init() 29 { 30 /* @var PluginController $plugin_controller */ 31 global $plugin_controller; 32 if ($this->hasAccess()) { 33 $list = $plugin_controller->getList('', true); 34 $request_data = ['fmt' => 'php']; 35 $request_needed = false; 36 foreach ($list as $name) { 37 $cache = new Cache('##extension_manager##' . $name, '.repo'); 38 39 if ( 40 !isset($this->loaded_extensions[$name]) && 41 $this->hasAccess() && 42 !$cache->useCache(['age' => 3600 * 24]) 43 ) { 44 $this->loaded_extensions[$name] = true; 45 $request_data['ext'][] = $name; 46 $request_needed = true; 47 } 48 } 49 50 if ($request_needed) { 51 $httpclient = new DokuHTTPClient(); 52 $data = $httpclient->post(self::EXTENSION_REPOSITORY_API, $request_data); 53 if ($data !== false) { 54 $extensions = unserialize($data); 55 foreach ($extensions as $extension) { 56 $cache = new Cache('##extension_manager##' . $extension['plugin'], '.repo'); 57 $cache->storeCache(serialize($extension)); 58 } 59 } else { 60 $this->has_access = false; 61 } 62 } 63 } 64 } 65 66 /** 67 * If repository access is available 68 * 69 * @param bool $usecache use cached result if still valid 70 * @return bool If repository access is available 71 */ 72 public function hasAccess($usecache = true) 73 { 74 if ($this->has_access === null) { 75 $cache = new Cache('##extension_manager###hasAccess', '.repo'); 76 77 if (!$cache->useCache(['age' => 60 * 10, 'purge' => !$usecache])) { 78 $httpclient = new DokuHTTPClient(); 79 $httpclient->timeout = 5; 80 $data = $httpclient->get(self::EXTENSION_REPOSITORY_API . '?cmd=ping'); 81 if ($data !== false) { 82 $this->has_access = true; 83 $cache->storeCache(1); 84 } else { 85 $this->has_access = false; 86 $cache->storeCache(0); 87 } 88 } else { 89 $this->has_access = ($cache->retrieveCache(false) == 1); 90 } 91 } 92 return $this->has_access; 93 } 94 95 /** 96 * Get the remote data of an individual plugin or template 97 * 98 * @param string $name The plugin name to get the data for, template names need to be prefix by 'template:' 99 * @return array The data or null if nothing was found (possibly no repository access) 100 */ 101 public function getData($name) 102 { 103 $cache = new Cache('##extension_manager##' . $name, '.repo'); 104 105 if ( 106 !isset($this->loaded_extensions[$name]) && 107 $this->hasAccess() && 108 !$cache->useCache(['age' => 3600 * 24]) 109 ) { 110 $this->loaded_extensions[$name] = true; 111 $httpclient = new DokuHTTPClient(); 112 $data = $httpclient->get(self::EXTENSION_REPOSITORY_API . '?fmt=php&ext[]=' . urlencode($name)); 113 if ($data !== false) { 114 $result = unserialize($data); 115 if (count($result)) { 116 $cache->storeCache(serialize($result[0])); 117 return $result[0]; 118 } 119 return []; 120 } else { 121 $this->has_access = false; 122 } 123 } 124 if (file_exists($cache->cache)) { 125 return unserialize($cache->retrieveCache(false)); 126 } 127 return []; 128 } 129 130 /** 131 * Search for plugins or templates using the given query string 132 * 133 * @param string $q the query string 134 * @return array a list of matching extensions 135 */ 136 public function search($q) 137 { 138 $query = $this->parseQuery($q); 139 $query['fmt'] = 'php'; 140 141 $httpclient = new DokuHTTPClient(); 142 $data = $httpclient->post(self::EXTENSION_REPOSITORY_API, $query); 143 if ($data === false) return []; 144 $result = unserialize($data); 145 146 $ids = []; 147 148 // store cache info for each extension 149 foreach ($result as $ext) { 150 $name = $ext['plugin']; 151 $cache = new Cache('##extension_manager##' . $name, '.repo'); 152 $cache->storeCache(serialize($ext)); 153 $ids[] = $name; 154 } 155 156 return $ids; 157 } 158 159 /** 160 * Parses special queries from the query string 161 * 162 * @param string $q 163 * @return array 164 */ 165 protected function parseQuery($q) 166 { 167 $parameters = ['tag' => [], 'mail' => [], 'type' => [], 'ext' => []]; 168 169 // extract tags 170 if (preg_match_all('/(^|\s)(tag:([\S]+))/', $q, $matches, PREG_SET_ORDER)) { 171 foreach ($matches as $m) { 172 $q = str_replace($m[2], '', $q); 173 $parameters['tag'][] = $m[3]; 174 } 175 } 176 // extract author ids 177 if (preg_match_all('/(^|\s)(authorid:([\S]+))/', $q, $matches, PREG_SET_ORDER)) { 178 foreach ($matches as $m) { 179 $q = str_replace($m[2], '', $q); 180 $parameters['mail'][] = $m[3]; 181 } 182 } 183 // extract extensions 184 if (preg_match_all('/(^|\s)(ext:([\S]+))/', $q, $matches, PREG_SET_ORDER)) { 185 foreach ($matches as $m) { 186 $q = str_replace($m[2], '', $q); 187 $parameters['ext'][] = $m[3]; 188 } 189 } 190 // extract types 191 if (preg_match_all('/(^|\s)(type:([\S]+))/', $q, $matches, PREG_SET_ORDER)) { 192 foreach ($matches as $m) { 193 $q = str_replace($m[2], '', $q); 194 $parameters['type'][] = $m[3]; 195 } 196 } 197 198 // FIXME make integer from type value 199 200 $parameters['q'] = trim($q); 201 return $parameters; 202 } 203 } 204 205 // vim:ts=4:sw=4:et:
title
Description
Body
title
Description
Body
title
Description
Body
title
Body