Aggregate Code Coverage for all tests
1 : <?php 2 : /** 3 : * PEAR2_Pyrus_ChannelRegistry_Base 4 : * 5 : * PHP version 5 6 : * 7 : * @category PEAR2 8 : * @package PEAR2_Pyrus 9 : * @author Greg Beaver <cellog@php.net> 10 : * @copyright 2008 The PEAR Group 11 : * @license http://www.opensource.org/licenses/bsd-license.php New BSD License 12 : * @version SVN: $Id$ 13 : * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ 14 : */ 15 : 16 : /** 17 : * Base class for Pyrus managed channel registries 18 : * 19 : * @category PEAR2 20 : * @package PEAR2_Pyrus 21 : * @author Greg Beaver <cellog@php.net> 22 : * @copyright 2008 The PEAR Group 23 : * @license http://www.opensource.org/licenses/bsd-license.php New BSD License 24 : * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ 25 : */ 26 : abstract class PEAR2_Pyrus_ChannelRegistry_Base 27 1 : implements PEAR2_Pyrus_IChannelRegistry, Iterator 28 : { 29 : /** 30 : * Parse a package name, or validate a parsed package name array 31 : * @param string|array pass in an array of format 32 : * array( 33 : * 'package' => 'pname', 34 : * ['channel' => 'channame',] 35 : * ['version' => 'version',] 36 : * ['state' => 'state',] 37 : * ['group' => 'groupname']) 38 : * or a string of format 39 : * [channel://][channame/]pname[-version|-state][/group=groupname] 40 : * 41 : * @return array 42 : */ 43 : public function parseName($param, $defaultchannel = 'pear.php.net') 44 : { 45 : $saveparam = $param; 46 : if (is_array($param)) { 47 : // convert to string for error messages 48 : $saveparam = self::parsedNameToString($param); 49 : // process the array 50 : if (!isset($param['package'])) { 51 : throw new PEAR2_Pyrus_ChannelRegistry_ParseException('parsePackageName(): array $param ' . 52 : 'must contain a valid package name in index "param"', 'package'); 53 : } 54 : if (!isset($param['uri'])) { 55 : if (!isset($param['channel'])) { 56 : $param['channel'] = $defaultchannel; 57 : } 58 : } else { 59 : $param['channel'] = '__uri'; 60 : } 61 : } else { 62 : $components = @parse_url((string) $param); 63 : if (isset($components['scheme'])) { 64 : if ($components['scheme'] == 'http') { 65 : // uri package 66 : $param = array('uri' => $param, 'channel' => '__uri'); 67 : } elseif($components['scheme'] != 'channel') { 68 : throw new PEAR2_Pyrus_ChannelRegistry_ParseException('parsePackageName(): only channel:// uris may ' . 69 : 'be downloaded, not "' . $param . '"', 'scheme'); 70 : } 71 : } 72 : if (!isset($components['path'])) { 73 : throw new PEAR2_Registry_Exception('parsePackageName(): array $param ' . 74 : 'must contain a valid package name in "' . $param . '"'); 75 : } 76 : if (isset($components['host'])) { 77 : // remove the leading "/" 78 : $components['path'] = substr($components['path'], 1); 79 : } 80 : if (!isset($components['scheme'])) { 81 : if (strpos($components['path'], '/') !== false) { 82 : if ($components['path']{0} == '/') { 83 : throw new PEAR2_Pyrus_ChannelRegistry_ParseException('parsePackageName(): this is not ' . 84 : 'a package name, it begins with "/" in "' . $param . '"', 'invalid'); 85 : } 86 : $parts = explode('/', $components['path']); 87 : $components['host'] = array_shift($parts); 88 : if (count($parts) > 1) { 89 : $components['path'] = array_pop($parts); 90 : $components['host'] .= '/' . implode('/', $parts); 91 : } else { 92 : $components['path'] = implode('/', $parts); 93 : } 94 : } else { 95 : $components['host'] = $defaultchannel; 96 : } 97 : } else { 98 : if (strpos($components['path'], '/')) { 99 : $parts = explode('/', $components['path']); 100 : $components['path'] = array_pop($parts); 101 : $components['host'] .= '/' . implode('/', $parts); 102 : } 103 : } 104 : 105 : if (is_array($param)) { 106 : $param['package'] = $components['path']; 107 : } else { 108 : $param = array( 109 : 'package' => $components['path'] 110 : ); 111 : if (isset($components['host'])) { 112 : $param['channel'] = $components['host']; 113 : } 114 : } 115 : if (isset($components['fragment'])) { 116 : $param['group'] = $components['fragment']; 117 : } 118 : if (isset($components['user'])) { 119 : $param['user'] = $components['user']; 120 : } 121 : if (isset($components['pass'])) { 122 : $param['pass'] = $components['pass']; 123 : } 124 : if (isset($components['query'])) { 125 : parse_str($components['query'], $param['opts']); 126 : } 127 : // check for extension 128 : $pathinfo = pathinfo($param['package']); 129 : if (isset($pathinfo['extension']) && 130 : in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) { 131 : $param['extension'] = $pathinfo['extension']; 132 : $param['package'] = substr($pathinfo['basename'], 0, 133 : strlen($pathinfo['basename']) - 4); 134 : } 135 : // check for version 136 : if (strpos($param['package'], '-')) { 137 : $test = explode('-', $param['package']); 138 : if (count($test) != 2) { 139 : throw new PEAR2_Pyrus_ChannelRegistry_ParseException('parsePackageName(): only one version/state ' . 140 : 'delimiter "-" is allowed in "' . $saveparam . '"', 'invalid'); 141 : } 142 : list($param['package'], $param['version']) = $test; 143 : } 144 : } 145 : // validation 146 : $info = $this->exists($param['channel'], false); 147 : if (!$info) { 148 : throw new PEAR2_Pyrus_ChannelRegistry_ParseException('unknown channel "' . $param['channel'] . 149 : '" in "' . $saveparam . '"', 'channel'); 150 : } 151 : try { 152 : $chan = $this->get($param['channel'], false); 153 : } catch (Exception $e) { 154 : throw new PEAR2_Pyrus_ChannelRegistry_ParseException("Exception: corrupt registry, could not " . 155 : "retrieve channel " . $param['channel'] . " information", 'other', $e); 156 : } 157 : $param['channel'] = $chan->getName(); 158 : $validate = $chan->getValidationObject(false); 159 : $vpackage = $chan->getValidationPackage(false); 160 : // validate package name 161 : if (!$validate->validPackageName($param['package'], $vpackage['_content'])) { 162 : throw new PEAR2_Pyrus_ChannelRegistry_ParseException('parsePackageName(): invalid package name "' . 163 : $param['package'] . '" in "' . $saveparam . '"', 'package'); 164 : } 165 : if (isset($param['group'])) { 166 : if (!PEAR2_Pyrus_Validate::validGroupName($param['group'])) { 167 : throw new PEAR2_Pyrus_ChannelRegistry_ParseException('parsePackageName(): dependency group "' . $param['group'] . 168 : '" is not a valid group name in "' . $saveparam . '"', 'group'); 169 : } 170 : } 171 : if (isset($param['state'])) { 172 : if (!in_array(strtolower($param['state']), $validate->getValidStates())) { 173 : throw new PEAR2_Pyrus_ChannelRegistry_ParseException('parsePackageName(): state "' . $param['state'] 174 : . '" is not a valid state in "' . $saveparam . '"', 'version/state'); 175 : } 176 : } 177 : if (isset($param['version'])) { 178 : if (isset($param['state'])) { 179 : throw new PEAR2_Pyrus_ChannelRegistry_ParseException('parsePackageName(): cannot contain both ' . 180 : 'a version and a stability (state) in "' . $saveparam . '"', 181 : 'version/state'); 182 : } 183 : // check whether version is actually a state 184 : if (in_array(strtolower($param['version']), $validate->getValidStates())) { 185 : $param['state'] = strtolower($param['version']); 186 : unset($param['version']); 187 : } else { 188 : if (!$validate->validVersion($param['version'])) { 189 : throw new PEAR2_Pyrus_ChannelRegistry_ParseException('parsePackageName(): "' . $param['version'] . 190 : '" is neither a valid version nor a valid state in "' . 191 : $saveparam . '"', 'version/state'); 192 : } 193 : } 194 : } 195 : return $param; 196 : } 197 : 198 : /** 199 : * @param array 200 : * @return string 201 : */ 202 : function parsedNameToString($parsed, $brief = false) 203 : { 204 : if (is_string($parsed)) { 205 : return $parsed; 206 : } 207 : if (is_object($parsed)) { 208 : $p = $parsed; 209 : $parsed = array( 210 : 'package' => $p->getPackage(), 211 : 'channel' => $p->getChannel(), 212 : 'version' => $p->getVersion(), 213 : ); 214 : } 215 : if (isset($parsed['uri'])) { 216 : return $parsed['uri']; 217 : } 218 : if ($brief) { 219 : if ($channel = $this->getAlias($parsed['channel'])) { 220 : return $channel . '/' . $parsed['package']; 221 : } 222 : } 223 : $upass = ''; 224 : if (isset($parsed['user'])) { 225 : $upass = $parsed['user']; 226 : if (isset($parsed['pass'])) { 227 : $upass .= ':' . $parsed['pass']; 228 : } 229 : $upass = "$upass@"; 230 : } 231 : $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package']; 232 : if (isset($parsed['version']) || isset($parsed['state'])) { 233 : $ver = isset($parsed['version']) ? $parsed['version'] : ''; 234 : $ver .= isset($parsed['state']) ? $parsed['state'] : ''; 235 : $ret .= '-' . $ver; 236 : } 237 : if (isset($parsed['extension'])) { 238 : $ret .= '.' . $parsed['extension']; 239 : } 240 : if (isset($parsed['opts'])) { 241 : $ret .= '?'; 242 : foreach ($parsed['opts'] as $name => $value) { 243 : $parsed['opts'][$name] = "$name=$value"; 244 : } 245 : $ret .= implode('&', $parsed['opts']); 246 : } 247 : if (isset($parsed['group'])) { 248 : $ret .= '#' . $parsed['group']; 249 : } 250 : return $ret; 251 : } 252 : 253 : function current() 254 : { 255 : return $this->get(current($this->channelList)); 256 : } 257 : 258 : function key() 259 : { 260 : return key($this->channelList); 261 : } 262 : 263 : function valid() 264 : { 265 : return current($this->channelList); 266 : } 267 : 268 : function next() 269 : { 270 : return next($this->channelList); 271 : } 272 : 273 : function rewind() 274 : { 275 : $this->channelList = $this->listChannels(); 276 : } 277 : 278 : public function getPearChannel() 279 : { 280 1 : return new PEAR2_Pyrus_Channel('<?xml version="1.0" encoding="ISO-8859-1"?> 281 : <channel version="1.0" xmlns="http://pear.php.net/channel-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/channel-1.0 282 : http://pear.php.net/dtd/channel-1.0.xsd"> 283 : <name>pear.php.net</name> 284 : <suggestedalias>pear</suggestedalias> 285 : <summary>PHP Extension and Application Repository</summary> 286 : <servers> 287 : <primary> 288 : <rest> 289 : 290 : <baseurl type="REST1.0">http://pear.php.net/rest/</baseurl> 291 : <baseurl type="REST1.1">http://pear.php.net/rest/</baseurl> 292 : <baseurl type="REST1.2">http://pear.php.net/rest/</baseurl> 293 : <baseurl type="REST1.3">http://pear.php.net/rest/</baseurl> 294 : </rest> 295 : </primary> 296 : <mirror host="us.pear.php.net"> 297 : 298 : <rest> 299 : <baseurl type="REST1.0">http://us.pear.php.net/rest/</baseurl> 300 : <baseurl type="REST1.1">http://us.pear.php.net/rest/</baseurl> 301 : <baseurl type="REST1.2">http://us.pear.php.net/rest/</baseurl> 302 : <baseurl type="REST1.3">http://us.pear.php.net/rest/</baseurl> 303 : </rest> 304 : </mirror> 305 : 306 : <mirror host="de.pear.php.net" ssl="yes" port="3452"> 307 : <rest> 308 : <baseurl type="REST1.0">https://de.pear.php.net:3452/rest/</baseurl> 309 : <baseurl type="REST1.1">https://de.pear.php.net:3452/rest/</baseurl> 310 : <baseurl type="REST1.2">https://de.pear.php.net:3452/rest/</baseurl> 311 : <baseurl type="REST1.3">https://de.pear.php.net:3452/rest/</baseurl> 312 : </rest> 313 : 314 : </mirror> 315 : </servers> 316 : </channel> 317 1 : '); 318 : } 319 : 320 : public function getPear2Channel() 321 : { 322 1 : return new PEAR2_Pyrus_Channel('<?xml version="1.0" encoding="ISO-8859-1"?> 323 : <channel version="1.0" xmlns="http://pear.php.net/channel-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/channel-1.0 324 : http://pear.php.net/dtd/channel-1.0.xsd"> 325 : <name>pear2.php.net</name> 326 : <suggestedalias>pear2</suggestedalias> 327 : <summary>PEAR packages for PHP 5.3+ installed by Pyrus</summary> 328 : <servers> 329 : <primary> 330 : <rest> 331 : 332 : <baseurl type="REST1.0">http://pear2.php.net/rest/</baseurl> 333 : <baseurl type="REST1.1">http://pear2.php.net/rest/</baseurl> 334 : <baseurl type="REST1.2">http://pear2.php.net/rest/</baseurl> 335 : <baseurl type="REST1.3">http://pear2.php.net/rest/</baseurl> 336 : </rest> 337 : </primary> 338 : </servers> 339 : </channel> 340 1 : '); 341 : } 342 : 343 : public function getPeclChannel() 344 : { 345 1 : return new PEAR2_Pyrus_Channel('<?xml version="1.0" encoding="ISO-8859-1"?> 346 : <channel version="1.0" xmlns="http://pear.php.net/channel-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/channel-1.0 347 : http://pear.php.net/dtd/channel-1.0.xsd"> 348 : <name>pecl.php.net</name> 349 : <suggestedalias>pecl</suggestedalias> 350 : <summary>PHP Extension Community Library</summary> 351 : <validatepackage version="1.0">PEAR_Validator_PECL</validatepackage> 352 : <servers> 353 : <primary> 354 : 355 : <xmlrpc> 356 : <function version="1.0">logintest</function> 357 : <function version="1.0">package.listLatestReleases</function> 358 : <function version="1.0">package.listAll</function> 359 : <function version="1.0">package.info</function> 360 : <function version="1.0">package.getDownloadURL</function> 361 : 362 : <function version="1.0">package.getDepDownloadURL</function> 363 : <function version="1.0">package.search</function> 364 : <function version="1.0">channel.listAll</function> 365 : </xmlrpc> 366 : <rest> 367 : <baseurl type="REST1.0">http://pecl.php.net/rest/</baseurl> 368 : <baseurl type="REST1.1">http://pecl.php.net/rest/</baseurl> 369 : 370 : </rest> 371 : </primary> 372 : </servers> 373 : </channel> 374 1 : '); 375 : } 376 : 377 : public function getUriChannel() 378 : { 379 1 : return new PEAR2_Pyrus_Channel('<?xml version="1.0" encoding="ISO-8859-1"?> 380 : <channel version="1.0" xmlns="http://pear.php.net/channel-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/channel-1.0 381 : http://pear.php.net/dtd/channel-1.0.xsd"> 382 : <name>__uri</name> 383 : <suggestedalias>__uri</suggestedalias> 384 : <summary>Pseudo-channel for static packages</summary> 385 : <servers> 386 : <primary> 387 : <xmlrpc> 388 : <function version="1.0">****</function> 389 : </xmlrpc> 390 : </primary> 391 : </servers> 392 : </channel> 393 1 : '); 394 : } 395 : 396 : /** 397 : * Set up default channels, for uninitialized channel registries 398 : */ 399 : protected function initDefaultChannels() 400 : { 401 1 : $pear = $this->getPearChannel(); 402 1 : $pear2 = $this->getPear2Channel(); 403 1 : $pecl = $this->getPeclChannel(); 404 1 : $__uri = $this->getUriChannel(); 405 1 : $this->add($pear); 406 1 : $this->add($pear2); 407 1 : $this->add($pecl); 408 1 : $this->add($__uri); 409 1 : } 410 : }