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