[ Index ]
 

Code source de GeekLog 1.4.1

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/system/pear/PEAR/ -> ChannelFile.php (source)

   1  <?php
   2  /**
   3   * PEAR_ChannelFile, the channel handling class
   4   *
   5   * PHP versions 4 and 5
   6   *
   7   * LICENSE: This source file is subject to version 3.0 of the PHP license
   8   * that is available through the world-wide-web at the following URI:
   9   * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10   * the PHP License and are unable to obtain it through the web, please
  11   * send a note to license@php.net so we can mail you a copy immediately.
  12   *
  13   * @category   pear
  14   * @package    PEAR
  15   * @author     Greg Beaver <cellog@php.net>
  16   * @copyright  1997-2006 The PHP Group
  17   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  18   * @version    CVS: $Id: ChannelFile.php,v 1.75 2006/03/02 18:14:12 cellog Exp $
  19   * @link       http://pear.php.net/package/PEAR
  20   * @since      File available since Release 1.4.0a1
  21   */
  22  
  23  /**
  24   * Needed for error handling
  25   */
  26  require_once 'PEAR/ErrorStack.php';
  27  require_once 'PEAR/XMLParser.php';
  28  require_once 'PEAR/Common.php';
  29  
  30  /**
  31   * Error code if the channel.xml <channel> tag does not contain a valid version
  32   */
  33  define('PEAR_CHANNELFILE_ERROR_NO_VERSION', 1);
  34  /**
  35   * Error code if the channel.xml <channel> tag version is not supported (version 1.0 is the only supported version,
  36   * currently
  37   */
  38  define('PEAR_CHANNELFILE_ERROR_INVALID_VERSION', 2);
  39  
  40  /**
  41   * Error code if parsing is attempted with no xml extension
  42   */
  43  define('PEAR_CHANNELFILE_ERROR_NO_XML_EXT', 3);
  44  
  45  /**
  46   * Error code if creating the xml parser resource fails
  47   */
  48  define('PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER', 4);
  49  
  50  /**
  51   * Error code used for all sax xml parsing errors
  52   */
  53  define('PEAR_CHANNELFILE_ERROR_PARSER_ERROR', 5);
  54  
  55  /**#@+
  56   * Validation errors
  57   */
  58  /**
  59   * Error code when channel name is missing
  60   */
  61  define('PEAR_CHANNELFILE_ERROR_NO_NAME', 6);
  62  /**
  63   * Error code when channel name is invalid
  64   */
  65  define('PEAR_CHANNELFILE_ERROR_INVALID_NAME', 7);
  66  /**
  67   * Error code when channel summary is missing
  68   */
  69  define('PEAR_CHANNELFILE_ERROR_NO_SUMMARY', 8);
  70  /**
  71   * Error code when channel summary is multi-line
  72   */
  73  define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9);
  74  /**
  75   * Error code when channel server is missing for xmlrpc or soap protocol
  76   */
  77  define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10);
  78  /**
  79   * Error code when channel server is invalid for xmlrpc or soap protocol
  80   */
  81  define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11);
  82  /**
  83   * Error code when a mirror name is invalid
  84   */
  85  define('PEAR_CHANNELFILE_ERROR_INVALID_MIRROR', 21);
  86  /**
  87   * Error code when a mirror type is invalid
  88   */
  89  define('PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE', 22);
  90  /**
  91   * Error code when an attempt is made to generate xml, but the parsed content is invalid
  92   */
  93  define('PEAR_CHANNELFILE_ERROR_INVALID', 23);
  94  /**
  95   * Error code when an empty package name validate regex is passed in
  96   */
  97  define('PEAR_CHANNELFILE_ERROR_EMPTY_REGEX', 24);
  98  /**
  99   * Error code when a <function> tag has no version
 100   */
 101  define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION', 25);
 102  /**
 103   * Error code when a <function> tag has no name
 104   */
 105  define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME', 26);
 106  /**
 107   * Error code when a <validatepackage> tag has no name
 108   */
 109  define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME', 27);
 110  /**
 111   * Error code when a <validatepackage> tag has no version attribute
 112   */
 113  define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION', 28);
 114  /**
 115   * Error code when a mirror does not exist but is called for in one of the set*
 116   * methods.
 117   */
 118  define('PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND', 32);
 119  /**
 120   * Error code when a server port is not numeric
 121   */
 122  define('PEAR_CHANNELFILE_ERROR_INVALID_PORT', 33);
 123  /**
 124   * Error code when <static> contains no version attribute
 125   */
 126  define('PEAR_CHANNELFILE_ERROR_NO_STATICVERSION', 34);
 127  /**
 128   * Error code when <baseurl> contains no type attribute in a <rest> protocol definition
 129   */
 130  define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35);
 131  /** 
 132   * Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel
 133   */
 134  define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36);
 135  /** 
 136   * Error code when ssl attribute is present and is not "yes"
 137   */
 138  define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37);
 139  /**#@-*/
 140  
 141  /**
 142   * Mirror types allowed.  Currently only internet servers are recognized.
 143   */
 144  $GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] =  array('server');
 145  
 146  
 147  /**
 148   * The Channel handling class
 149   *
 150   * @category   pear
 151   * @package    PEAR
 152   * @author     Greg Beaver <cellog@php.net>
 153   * @copyright  1997-2006 The PHP Group
 154   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
 155   * @version    Release: 1.4.11
 156   * @link       http://pear.php.net/package/PEAR
 157   * @since      Class available since Release 1.4.0a1
 158   */
 159  class PEAR_ChannelFile {
 160      /**
 161       * @access private
 162       * @var PEAR_ErrorStack
 163       * @access private
 164       */
 165      var $_stack;
 166      
 167      /**
 168       * Supported channel.xml versions, for parsing
 169       * @var array
 170       * @access private
 171       */
 172      var $_supportedVersions = array('1.0');
 173  
 174      /**
 175       * Parsed channel information
 176       * @var array
 177       * @access private
 178       */
 179      var $_channelInfo;
 180  
 181      /**
 182       * index into the subchannels array, used for parsing xml
 183       * @var int
 184       * @access private
 185       */
 186      var $_subchannelIndex;
 187  
 188      /**
 189       * index into the mirrors array, used for parsing xml
 190       * @var int
 191       * @access private
 192       */
 193      var $_mirrorIndex;
 194      
 195      /**
 196       * Flag used to determine the validity of parsed content
 197       * @var boolean
 198       * @access private
 199       */
 200      var $_isValid = false;
 201  
 202      function PEAR_ChannelFile()
 203      {
 204          $this->_stack = &new PEAR_ErrorStack('PEAR_ChannelFile');
 205          $this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
 206          $this->_isValid = false;
 207      }
 208      
 209      /**
 210       * @return array
 211       * @access protected
 212       */
 213      function _getErrorMessage()
 214      {
 215          return
 216              array(
 217                  PEAR_CHANNELFILE_ERROR_INVALID_VERSION =>
 218                      'While parsing channel.xml, an invalid version number "%version% was passed in, expecting one of %versions%',
 219                  PEAR_CHANNELFILE_ERROR_NO_VERSION =>
 220                      'No version number found in <channel> tag',
 221                  PEAR_CHANNELFILE_ERROR_NO_XML_EXT =>
 222                      '%error%',
 223                  PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER =>
 224                      'Unable to create XML parser',
 225                  PEAR_CHANNELFILE_ERROR_PARSER_ERROR =>
 226                      '%error%',
 227                  PEAR_CHANNELFILE_ERROR_NO_NAME =>
 228                      'Missing channel name',
 229                  PEAR_CHANNELFILE_ERROR_INVALID_NAME =>
 230                      'Invalid channel %tag% "%name%"',
 231                  PEAR_CHANNELFILE_ERROR_NO_SUMMARY =>
 232                      'Missing channel summary',
 233                  PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY =>
 234                      'Channel summary should be on one line, but is multi-line',
 235                  PEAR_CHANNELFILE_ERROR_NO_HOST =>
 236                      'Missing channel server for %type% server',
 237                  PEAR_CHANNELFILE_ERROR_INVALID_HOST =>
 238                      'Server name "%server%" is invalid for %type% server',
 239                  PEAR_CHANNELFILE_ERROR_INVALID_MIRROR =>
 240                      'Invalid mirror name "%name%", mirror type %type%',
 241                  PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE =>
 242                      'Invalid mirror type "%type%"',
 243                  PEAR_CHANNELFILE_ERROR_INVALID =>
 244                      'Cannot generate xml, contents are invalid',
 245                  PEAR_CHANNELFILE_ERROR_EMPTY_REGEX =>
 246                      'packagenameregex cannot be empty',
 247                  PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION =>
 248                      '%parent% %protocol% function has no version',
 249                  PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME =>
 250                      '%parent% %protocol% function has no name',
 251                  PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE =>
 252                      '%parent% rest baseurl has no type',
 253                  PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME =>
 254                      'Validation package has no name in <validatepackage> tag',
 255                  PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION =>
 256                      'Validation package "%package%" has no version',
 257                  PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND =>
 258                      'Mirror "%mirror%" does not exist',
 259                  PEAR_CHANNELFILE_ERROR_INVALID_PORT =>
 260                      'Port "%port%" must be numeric',
 261                  PEAR_CHANNELFILE_ERROR_NO_STATICVERSION =>
 262                      '<static> tag must contain version attribute',
 263                  PEAR_CHANNELFILE_URI_CANT_MIRROR =>
 264                      'The __uri pseudo-channel cannot have mirrors',
 265                  PEAR_CHANNELFILE_ERROR_INVALID_SSL =>
 266                      '%server% has invalid ssl attribute "%ssl%" can only be yes or not present',
 267              );
 268      }
 269  
 270      /**
 271       * @param string contents of package.xml file
 272       * @return bool success of parsing
 273       */
 274      function fromXmlString($data)
 275      {
 276          if (preg_match('/<channel\s+version="([0-9]+\.[0-9]+)"/', $data, $channelversion)) {
 277              if (!in_array($channelversion[1], $this->_supportedVersions)) {
 278                  $this->_stack->push(PEAR_CHANNELFILE_ERROR_INVALID_VERSION, 'error',
 279                      array('version' => $channelversion[1]));
 280                  return false;
 281              }
 282              $parser = new PEAR_XMLParser;
 283              $result = $parser->parse($data);
 284              if ($result !== true) {
 285                  if ($result->getCode() == 1) {
 286                      $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error',
 287                          array('error' => $error));
 288                  } else {
 289                      $this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error');
 290                  }
 291                  return false;
 292              }
 293              $this->_channelInfo = $parser->getData();
 294              return true;
 295          } else {
 296              $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_VERSION, 'error', array('xml' => $data));
 297              return false;
 298          }
 299      }
 300      
 301      /**
 302       * @return array
 303       */
 304      function toArray()
 305      {
 306          if (!$this->_isValid && !$this->validate()) {
 307              return false;
 308          }
 309          return $this->_channelInfo;
 310      }
 311      
 312      /**
 313       * @param array
 314       * @static
 315       * @return PEAR_ChannelFile|false false if invalid
 316       */
 317      function &fromArray($data, $compatibility = false, $stackClass = 'PEAR_ErrorStack')
 318      {
 319          $a = new PEAR_ChannelFile($compatibility, $stackClass);
 320          $a->_fromArray($data);
 321          if (!$a->validate()) {
 322              $a = false;
 323              return $a;
 324          }
 325          return $a;
 326      }
 327  
 328      /**
 329       * Unlike {@link fromArray()} this does not do any validation
 330       * @param array
 331       * @static
 332       * @return PEAR_ChannelFile
 333       */
 334      function &fromArrayWithErrors($data, $compatibility = false,
 335                                    $stackClass = 'PEAR_ErrorStack')
 336      {
 337          $a = new PEAR_ChannelFile($compatibility, $stackClass);
 338          $a->_fromArray($data);
 339          return $a;
 340      }
 341      
 342      /**
 343       * @param array
 344       * @access private
 345       */
 346      function _fromArray($data)
 347      {
 348          $this->_channelInfo = $data;
 349      }
 350      
 351      /**
 352       * Wrapper to {@link PEAR_ErrorStack::getErrors()}
 353       * @param boolean determines whether to purge the error stack after retrieving
 354       * @return array
 355       */
 356      function getErrors($purge = false)
 357      {
 358          return $this->_stack->getErrors($purge);
 359      }
 360  
 361      /**
 362       * Unindent given string (?)
 363       *
 364       * @param string $str The string that has to be unindented.
 365       * @return string
 366       * @access private
 367       */
 368      function _unIndent($str)
 369      {
 370          // remove leading newlines
 371          $str = preg_replace('/^[\r\n]+/', '', $str);
 372          // find whitespace at the beginning of the first line
 373          $indent_len = strspn($str, " \t");
 374          $indent = substr($str, 0, $indent_len);
 375          $data = '';
 376          // remove the same amount of whitespace from following lines
 377          foreach (explode("\n", $str) as $line) {
 378              if (substr($line, 0, $indent_len) == $indent) {
 379                  $data .= substr($line, $indent_len) . "\n";
 380              }
 381          }
 382          return $data;
 383      }
 384  
 385      /**
 386       * Parse a channel.xml file.  Expects the name of
 387       * a channel xml file as input.
 388       *
 389       * @param string  $descfile  name of channel xml file
 390       * @return bool success of parsing
 391       */
 392      function fromXmlFile($descfile)
 393      {
 394          if (!@is_file($descfile) || !is_readable($descfile) ||
 395               (!$fp = @fopen($descfile, 'r'))) {
 396              require_once  'PEAR.php';
 397              return PEAR::raiseError("Unable to open $descfile");
 398          }
 399  
 400          // read the whole thing so we only get one cdata callback
 401          // for each block of cdata
 402          if (function_exists('file_get_contents')) {
 403              fclose($fp);
 404              $data = file_get_contents($descfile);
 405          } else {
 406              $data = fread($fp, filesize($descfile));
 407              fclose($fp);
 408          }
 409          return $this->fromXmlString($data);
 410      }
 411  
 412      /**
 413       * Parse channel information from different sources
 414       *
 415       * This method is able to extract information about a channel
 416       * from an .xml file or a string
 417       *
 418       * @access public
 419       * @param  string Filename of the source or the source itself
 420       * @return bool
 421       */
 422      function fromAny($info)
 423      {
 424          if (is_string($info) && file_exists($info) && strlen($info) < 255) {
 425              $tmp = substr($info, -4);
 426              if ($tmp == '.xml') {
 427                  $info = $this->fromXmlFile($info);
 428              } else {
 429                  $fp = fopen($info, "r");
 430                  $test = fread($fp, 5);
 431                  fclose($fp);
 432                  if ($test == "<?xml") {
 433                      $info = $this->fromXmlFile($info);
 434                  }
 435              }
 436              if (PEAR::isError($info)) {
 437                  require_once  'PEAR.php';
 438                  return PEAR::raiseError($info);
 439              }
 440          }
 441          if (is_string($info)) {
 442              $info = $this->fromXmlString($info);
 443          }
 444          return $info;
 445      }
 446  
 447      /**
 448       * Return an XML document based on previous parsing and modifications
 449       *
 450       * @return string XML data
 451       *
 452       * @access public
 453       */
 454      function toXml()
 455      {
 456          if (!$this->_isValid && !$this->validate()) {
 457              $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID);
 458              return false;
 459          }
 460          if (!isset($this->_channelInfo['attribs']['version'])) {
 461              $this->_channelInfo['attribs']['version'] = '1.0';
 462          }
 463          $channelInfo = $this->_channelInfo;
 464          $ret = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n";
 465          $ret .= "<channel version=\"" .
 466              $channelInfo['attribs']['version'] . "\" xmlns=\"http://pear.php.net/channel-1.0\"
 467    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
 468    xsi:schemaLocation=\"http://pear.php.net/dtd/channel-"
 469              . $channelInfo['attribs']['version'] . " http://pear.php.net/dtd/channel-" .
 470              $channelInfo['attribs']['version'] . ".xsd\">
 471   <name>$channelInfo[name]</name>
 472   <summary>" . htmlspecialchars($channelInfo['summary'])."</summary>
 473  ";
 474          if (isset($channelInfo['suggestedalias'])) {
 475              $ret .= ' <suggestedalias>' . $channelInfo['suggestedalias'] . "</suggestedalias>\n";
 476          }
 477          if (isset($channelInfo['validatepackage'])) {
 478              $ret .= ' <validatepackage version="' .
 479                  $channelInfo['validatepackage']['attribs']['version']. '">' .
 480                  htmlspecialchars($channelInfo['validatepackage']['_content']) .
 481                  "</validatepackage>\n";
 482          }
 483          $ret .= " <servers>\n";
 484          $ret .= '  <primary';
 485          if (isset($channelInfo['servers']['primary']['attribs']['ssl'])) {
 486              $ret .= ' ssl="' . $channelInfo['servers']['primary']['attribs']['ssl'] . '"';
 487          }
 488          if (isset($channelInfo['servers']['primary']['attribs']['port'])) {
 489              $ret .= ' port="' . $channelInfo['servers']['primary']['attribs']['port'] . '"';
 490          }
 491          $ret .= ">\n";
 492          if (isset($channelInfo['servers']['primary']['xmlrpc'])) {
 493              $ret .= $this->_makeXmlrpcXml($channelInfo['servers']['primary']['xmlrpc'], '   ');
 494          }
 495          if (isset($channelInfo['servers']['primary']['rest'])) {
 496              $ret .= $this->_makeRestXml($channelInfo['servers']['primary']['rest'], '   ');
 497          }
 498          if (isset($channelInfo['servers']['primary']['soap'])) {
 499              $ret .= $this->_makeSoapXml($channelInfo['servers']['primary']['soap'], '   ');
 500          }
 501          $ret .= "  </primary>\n";
 502          if (isset($channelInfo['servers']['mirror'])) {
 503              $ret .= $this->_makeMirrorsXml($channelInfo);
 504          }
 505          $ret .= " </servers>\n";
 506          $ret .= "</channel>";
 507          return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret));
 508      }
 509  
 510      /**
 511       * Generate the <xmlrpc> tag
 512       * @access private
 513       */
 514      function _makeXmlrpcXml($info, $indent)
 515      {
 516          $ret = $indent . "<xmlrpc";
 517          if (isset($info['attribs']['path'])) {
 518              $ret .= ' path="' . htmlspecialchars($info['attribs']['path']) . '"';
 519          }
 520          $ret .= ">\n";
 521          $ret .= $this->_makeFunctionsXml($info['function'], "$indent ");
 522          $ret .= $indent . "</xmlrpc>\n";
 523          return $ret;
 524      }
 525  
 526      /**
 527       * Generate the <soap> tag
 528       * @access private
 529       */
 530      function _makeSoapXml($info, $indent)
 531      {
 532          $ret = $indent . "<soap";
 533          if (isset($info['attribs']['path'])) {
 534              $ret .= ' path="' . htmlspecialchars($info['attribs']['path']) . '"';
 535          }
 536          $ret .= ">\n";
 537          $ret .= $this->_makeFunctionsXml($info['function'], "$indent ");
 538          $ret .= $indent . "</soap>\n";
 539          return $ret;
 540      }
 541  
 542      /**
 543       * Generate the <rest> tag
 544       * @access private
 545       */
 546      function _makeRestXml($info, $indent)
 547      {
 548          $ret = $indent . "<rest>\n";
 549          if (!isset($info['baseurl'][0])) {
 550              $info['baseurl'] = array($info['baseurl']);
 551          }
 552          foreach ($info['baseurl'] as $url) {
 553              $ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\"";
 554              $ret .= ">" . $url['_content'] . "</baseurl>\n";
 555          }
 556          $ret .= $indent . "</rest>\n";
 557          return $ret;
 558      }
 559  
 560      /**
 561       * Generate the <mirrors> tag
 562       * @access private
 563       */
 564      function _makeMirrorsXml($channelInfo)
 565      {
 566          $ret = "";
 567          if (!isset($channelInfo['servers']['mirror'][0])) {
 568              $channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']);
 569          }
 570          foreach ($channelInfo['servers']['mirror'] as $mirror) {
 571              $ret .= '  <mirror host="' . $mirror['attribs']['host'] . '"';
 572              if (isset($mirror['attribs']['port'])) {
 573                  $ret .= ' port="' . $mirror['attribs']['port'] . '"';
 574              }
 575              if (isset($mirror['attribs']['ssl'])) {
 576                  $ret .= ' ssl="' . $mirror['attribs']['ssl'] . '"';
 577              }
 578              $ret .= ">\n";
 579              if (isset($mirror['xmlrpc']) || isset($mirror['soap'])) {
 580                  if (isset($mirror['xmlrpc'])) {
 581                      $ret .= $this->_makeXmlrpcXml($mirror['xmlrpc'], '   ');
 582                  }
 583                  if (isset($mirror['rest'])) {
 584                      $ret .= $this->_makeRestXml($mirror['rest'], '   ');
 585                  }
 586                  if (isset($mirror['soap'])) {
 587                      $ret .= $this->_makeSoapXml($mirror['soap'], '   ');
 588                  }
 589                  $ret .= "  </mirror>\n";
 590              } else {
 591                  $ret .= "/>\n";
 592              }
 593          }
 594          return $ret;
 595      }
 596  
 597      /**
 598       * Generate the <functions> tag
 599       * @access private
 600       */
 601      function _makeFunctionsXml($functions, $indent, $rest = false)
 602      {
 603          $ret = '';
 604          if (!isset($functions[0])) {
 605              $functions = array($functions);
 606          }
 607          foreach ($functions as $function) {
 608              $ret .= "$indent<function version=\"" . $function['attribs']['version'] . "\"";
 609              if ($rest) {
 610                  $ret .= ' uri="' . $function['attribs']['uri'] . '"';
 611              }
 612              $ret .= ">" . $function['_content'] . "</function>\n";
 613          }
 614          return $ret;
 615      }
 616  
 617      /**
 618       * Validation error.  Also marks the object contents as invalid
 619       * @param error code
 620       * @param array error information
 621       * @access private
 622       */
 623      function _validateError($code, $params = array())
 624      {
 625          $this->_stack->push($code, 'error', $params);
 626          $this->_isValid = false;
 627      }
 628  
 629      /**
 630       * Validation warning.  Does not mark the object contents invalid.
 631       * @param error code
 632       * @param array error information
 633       * @access private
 634       */
 635      function _validateWarning($code, $params = array())
 636      {
 637          $this->_stack->push($code, 'warning', $params);
 638      }
 639  
 640      /**
 641       * Validate parsed file.
 642       *
 643       * @access public
 644       * @return boolean
 645       */
 646      function validate()
 647      {
 648          $this->_isValid = true;
 649          $info = $this->_channelInfo;
 650          if (empty($info['name'])) {
 651              $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME);
 652          } elseif (!$this->validChannelServer($info['name'])) {
 653              if ($info['name'] != '__uri') {
 654                  $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name',
 655                      'name' => $info['name']));
 656              }
 657          }
 658          if (empty($info['summary'])) {
 659              $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
 660          } elseif (strpos(trim($info['summary']), "\n") !== false) {
 661              $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
 662                  array('summary' => $info['summary']));
 663          }
 664          if (isset($info['suggestedalias'])) {
 665              if (!$this->validChannelServer($info['suggestedalias'])) {
 666                  $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
 667                      array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias']));
 668              }
 669          }
 670          if (isset($info['localalias'])) {
 671              if (!$this->validChannelServer($info['localalias'])) {
 672                  $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
 673                      array('tag' => 'localalias', 'name' =>$info['localalias']));
 674              }
 675          }
 676          if (isset($info['validatepackage'])) {
 677              if (!isset($info['validatepackage']['_content'])) {
 678                  $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME);
 679              }
 680              if (!isset($info['validatepackage']['attribs']['version'])) {
 681                  $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION,
 682                      array('package' => @$info['validatepackage']['_content']));
 683              }
 684          }
 685          if (isset($info['servers']['primary']['attribs']['port']) &&
 686                !is_numeric($info['servers']['primary']['attribs']['port'])) {
 687              $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT,
 688                  array('port' => $info['servers']['primary']['attribs']['port']));
 689          }
 690          if (isset($info['servers']['primary']['attribs']['ssl']) &&
 691                $info['servers']['primary']['attribs']['ssl'] != 'yes') {
 692              $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
 693                  array('ssl' => $info['servers']['primary']['attribs']['ssl'],
 694                      'server' => $info['name']));
 695          }
 696  
 697          if (isset($info['servers']['primary']['xmlrpc']) &&
 698                isset($info['servers']['primary']['xmlrpc']['function'])) {
 699              $this->_validateFunctions('xmlrpc', $info['servers']['primary']['xmlrpc']['function']);
 700          }
 701          if (isset($info['servers']['primary']['soap']) &&
 702                isset($info['servers']['primary']['soap']['function'])) {
 703              $this->_validateFunctions('soap', $info['servers']['primary']['soap']['function']);
 704          }
 705          if (isset($info['servers']['primary']['rest']) &&
 706                isset($info['servers']['primary']['rest']['baseurl'])) {
 707              $this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']);
 708          }
 709          if (isset($info['servers']['mirror'])) {
 710              if ($this->_channelInfo['name'] == '__uri') {
 711                  $this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR);
 712              }
 713              if (!isset($info['servers']['mirror'][0])) {
 714                  $info['servers']['mirror'] = array($info['servers']['mirror']);
 715              }
 716              $i = 0;
 717              foreach ($info['servers']['mirror'] as $mirror) {
 718                  if (!isset($mirror['attribs']['host'])) {
 719                      $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST,
 720                        array('type' => 'mirror'));
 721                  } elseif (!$this->validChannelServer($mirror['attribs']['host'])) {
 722                      $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST,
 723                          array('server' => $mirror['attribs']['host'], 'type' => 'mirror'));
 724                  }
 725                  if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') {
 726                      $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
 727                          array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host']));
 728                  }
 729                  if (isset($mirror['xmlrpc'])) {
 730                      $this->_validateFunctions('xmlrpc',
 731                          $mirror['xmlrpc']['function'], $mirror['attribs']['host']);
 732                  }
 733                  if (isset($mirror['soap'])) {
 734                      $this->_validateFunctions('soap', $mirror['soap']['function'],
 735                          $mirror['attribs']['host']);
 736                  }
 737                  if (isset($mirror['rest'])) {
 738                      $this->_validateFunctions('rest', $mirror['rest']['baseurl'],
 739                          $mirror['attribs']['host']);
 740                  }
 741              }
 742          }
 743          return $this->_isValid;
 744      }
 745  
 746      /**
 747       * @param string xmlrpc or soap - protocol name this function applies to
 748       * @param array the functions
 749       * @param string the name of the parent element (mirror name, for instance)
 750       */
 751      function _validateFunctions($protocol, $functions, $parent = '')
 752      {
 753          if (!isset($functions[0])) {
 754              $functions = array($functions);
 755          }
 756          foreach ($functions as $function) {
 757              if (!isset($function['_content']) || empty($function['_content'])) {
 758                  $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME,
 759                      array('parent' => $parent, 'protocol' => $protocol));
 760              }
 761              if ($protocol == 'rest') {
 762                  if (!isset($function['attribs']['type']) ||
 763                        empty($function['attribs']['type'])) {
 764                      $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_BASEURLTYPE,
 765                          array('parent' => $parent, 'protocol' => $protocol));
 766                  }
 767              } else {
 768                  if (!isset($function['attribs']['version']) ||
 769                        empty($function['attribs']['version'])) {
 770                      $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION,
 771                          array('parent' => $parent, 'protocol' => $protocol));
 772                  }
 773              }
 774          }
 775      }
 776  
 777      /**
 778       * Test whether a string contains a valid channel server.
 779       * @param string $ver the package version to test
 780       * @return bool
 781       */
 782      function validChannelServer($server)
 783      {
 784          if ($server == '__uri') {
 785              return true;
 786          }
 787          return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server);
 788      }
 789  
 790      /**
 791       * @return string|false
 792       */
 793      function getName()
 794      {
 795          if (isset($this->_channelInfo['name'])) {
 796              return $this->_channelInfo['name'];
 797          } else {
 798              return false;
 799          }
 800      }
 801  
 802      /**
 803       * @return string|false
 804       */
 805      function getServer()
 806      {
 807          if (isset($this->_channelInfo['name'])) {
 808              return $this->_channelInfo['name'];
 809          } else {
 810              return false;
 811          }
 812      }
 813  
 814      /**
 815       * @return int|80 port number to connect to
 816       */
 817      function getPort($mirror = false)
 818      {
 819          if ($mirror) {
 820              if ($mir = $this->getMirror($mirror)) {
 821                  if (isset($mir['attribs']['port'])) {
 822                      return $mir['attribs']['port'];
 823                  } else {
 824                      if ($this->getSSL($mirror)) {
 825                          return 443;
 826                      }
 827                      return 80;
 828                  }
 829              }
 830              return false;
 831          }
 832          if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) {
 833              return $this->_channelInfo['servers']['primary']['attribs']['port'];
 834          }
 835          if ($this->getSSL()) {
 836              return 443;
 837          }
 838          return 80;
 839      }
 840  
 841      /**
 842       * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel
 843       */
 844      function getSSL($mirror = false)
 845      {
 846          if ($mirror) {
 847              if ($mir = $this->getMirror($mirror)) {
 848                  if (isset($mir['attribs']['ssl'])) {
 849                      return true;
 850                  } else {
 851                      return false;
 852                  }
 853              }
 854              return false;
 855          }
 856          if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
 857              return true;
 858          }
 859          return false;
 860      }
 861  
 862      /**
 863       * @return string|false
 864       */
 865      function getSummary()
 866      {
 867          if (isset($this->_channelInfo['summary'])) {
 868              return $this->_channelInfo['summary'];
 869          } else {
 870              return false;
 871          }
 872      }
 873  
 874      /**
 875       * @param string xmlrpc or soap
 876       * @param string|false mirror name or false for primary server
 877       */
 878      function getPath($protocol, $mirror = false)
 879      {   
 880          if (!in_array($protocol, array('xmlrpc', 'soap'))) {
 881              return false;
 882          }
 883          if ($mirror) {
 884              if (!($mir = $this->getMirror($mirror))) {
 885                  return false;
 886              }
 887              if (isset($mir[$protocol]['attribs']['path'])) {
 888                  return $mir[$protocol]['attribs']['path'];
 889              } else {
 890                  return $protocol . '.php';
 891              }
 892          } elseif (isset($this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'])) {
 893              return $this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'];
 894          }
 895          return $protocol . '.php';
 896      }
 897  
 898      /**
 899       * @param string protocol type (xmlrpc, soap)
 900       * @param string Mirror name
 901       * @return array|false
 902       */
 903      function getFunctions($protocol, $mirror = false)
 904      {
 905          if ($this->getName() == '__uri') {
 906              return false;
 907          }
 908          if ($protocol == 'rest') {
 909              $function = 'baseurl';
 910          } else {
 911              $function = 'function';
 912          }
 913          if ($mirror) {
 914              if ($mir = $this->getMirror($mirror)) {
 915                  if (isset($mir[$protocol][$function])) {
 916                      return $mir[$protocol][$function];
 917                  }
 918              }
 919              return false;
 920          }
 921          if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) {
 922              return $this->_channelInfo['servers']['primary'][$protocol][$function];
 923          } else {
 924              return false;
 925          }
 926      }
 927  
 928      /**
 929       * @param string Protocol type
 930       * @param string Function name (null to return the
 931       *               first protocol of the type requested)
 932       * @param string Mirror name, if any
 933       * @return array
 934       */
 935       function getFunction($type, $name = null, $mirror = false)
 936       {
 937          $protocols = $this->getFunctions($type, $mirror);
 938          if (!$protocols) {
 939              return false;
 940          }
 941          foreach ($protocols as $protocol) {
 942              if ($name === null) {
 943                  return $protocol;
 944              }
 945              if ($protocol['_content'] != $name) {
 946                  continue;
 947              }
 948              return $protocol;
 949          }
 950          return false;
 951       }
 952  
 953      /**
 954       * @param string protocol type
 955       * @param string protocol name
 956       * @param string version
 957       * @param string mirror name
 958       * @return boolean
 959       */
 960      function supports($type, $name = null, $mirror = false, $version = '1.0')
 961      {
 962          $protocols = $this->getFunctions($type, $mirror);
 963          if (!$protocols) {
 964              return false;
 965          }
 966          foreach ($protocols as $protocol) {
 967              if ($protocol['attribs']['version'] != $version) {
 968                  continue;
 969              }
 970              if ($name === null) {
 971                  return true;
 972              }
 973              if ($protocol['_content'] != $name) {
 974                  continue;
 975              }
 976              return true;
 977          }
 978          return false;
 979      }
 980  
 981      /**
 982       * Determines whether a channel supports Representational State Transfer (REST) protocols
 983       * for retrieving channel information
 984       * @param string
 985       * @return bool
 986       */
 987      function supportsREST($mirror = false)
 988      {
 989          if ($mirror == $this->_channelInfo['name']) {
 990              $mirror = false;
 991          }
 992          if ($mirror) {
 993              if ($mir = $this->getMirror($mirror)) {
 994                  return isset($mir['rest']);
 995              }
 996              return false;
 997          }
 998          return isset($this->_channelInfo['servers']['primary']['rest']);
 999      }
1000  
1001      /**
1002       * Get the URL to access a base resource.
1003       *
1004       * Hyperlinks in the returned xml will be used to retrieve the proper information
1005       * needed.  This allows extreme extensibility and flexibility in implementation
1006       * @param string Resource Type to retrieve
1007       */
1008      function getBaseURL($resourceType, $mirror = false)
1009      {
1010          if ($mirror == $this->_channelInfo['name']) {
1011              $mirror = false;
1012          }
1013          if ($mirror) {
1014              if ($mir = $this->getMirror($mirror)) {
1015                  $rest = $mir['rest'];
1016              } else {
1017                  return false;
1018              }
1019              $server = $mirror;
1020          } else {
1021              $rest = $this->_channelInfo['servers']['primary']['rest'];
1022              $server = $this->getServer();
1023          }
1024          if (!isset($rest['baseurl'][0])) {
1025              $rest['baseurl'] = array($rest['baseurl']);
1026          }
1027          foreach ($rest['baseurl'] as $baseurl) {
1028              if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) {
1029                  return $baseurl['_content'];
1030              }
1031          }
1032          return false;
1033      }
1034  
1035      /**
1036       * Since REST does not implement RPC, provide this as a logical wrapper around
1037       * resetFunctions for REST
1038       * @param string|false mirror name, if any
1039       */
1040      function resetREST($mirror = false)
1041      {
1042          return $this->resetFunctions('rest', $mirror);
1043      }
1044  
1045      /**
1046       * Empty all protocol definitions
1047       * @param string protocol type (xmlrpc, soap)
1048       * @param string|false mirror name, if any
1049       */
1050      function resetFunctions($type, $mirror = false)
1051      {
1052          if ($mirror) {
1053              if (isset($this->_channelInfo['servers']['mirror'])) {
1054                  $mirrors = $this->_channelInfo['servers']['mirror'];
1055                  if (!isset($mirrors[0])) {
1056                      $mirrors = array($mirrors);
1057                  }
1058                  foreach ($mirrors as $i => $mir) {
1059                      if ($mir['attribs']['host'] == $mirror) {
1060                          if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) {
1061                              unset($this->_channelInfo['servers']['mirror'][$i][$type]);
1062                          }
1063                          return true;
1064                      }
1065                  }
1066                  return false;
1067              } else {
1068                  return false;
1069              }
1070          } else {
1071              if (isset($this->_channelInfo['servers']['primary'][$type])) {
1072                  unset($this->_channelInfo['servers']['primary'][$type]);
1073              }
1074              return true;
1075          }
1076      }
1077  
1078      /**
1079       * Set a channel's protocols to the protocols supported by pearweb
1080       */
1081      function setDefaultPEARProtocols($version = '1.0', $mirror = false)
1082      {
1083          switch ($version) {
1084              case '1.0' :
1085                  $this->resetFunctions('xmlrpc', $mirror);
1086                  $this->resetFunctions('soap', $mirror);
1087                  $this->resetREST($mirror);
1088                  $this->addFunction('xmlrpc', '1.0', 'logintest', $mirror);
1089                  $this->addFunction('xmlrpc', '1.0', 'package.listLatestReleases', $mirror);
1090                  $this->addFunction('xmlrpc', '1.0', 'package.listAll', $mirror);
1091                  $this->addFunction('xmlrpc', '1.0', 'package.info', $mirror);
1092                  $this->addFunction('xmlrpc', '1.0', 'package.getDownloadURL', $mirror);
1093                  $this->addFunction('xmlrpc', '1.1', 'package.getDownloadURL', $mirror);
1094                  $this->addFunction('xmlrpc', '1.0', 'package.getDepDownloadURL', $mirror);
1095                  $this->addFunction('xmlrpc', '1.1', 'package.getDepDownloadURL', $mirror);
1096                  $this->addFunction('xmlrpc', '1.0', 'package.search', $mirror);
1097                  $this->addFunction('xmlrpc', '1.0', 'channel.listAll', $mirror);
1098                  return true;
1099              break;
1100              default :
1101                  return false;
1102              break;
1103          }
1104      }
1105      
1106      /**
1107       * @return array
1108       */
1109      function getMirrors()
1110      {
1111          if (isset($this->_channelInfo['servers']['mirror'])) {
1112              $mirrors = $this->_channelInfo['servers']['mirror'];
1113              if (!isset($mirrors[0])) {
1114                  $mirrors = array($mirrors);
1115              }
1116              return $mirrors;
1117          } else {
1118              return array();
1119          }
1120      }
1121  
1122      /**
1123       * Get the unserialized XML representing a mirror
1124       * @return array|false
1125       */
1126      function getMirror($server)
1127      {
1128          foreach ($this->getMirrors() as $mirror) {
1129              if ($mirror['attribs']['host'] == $server) {
1130                  return $mirror;
1131              }
1132          }
1133          return false;
1134      }
1135  
1136      /**
1137       * @param string
1138       * @return string|false
1139       * @error PEAR_CHANNELFILE_ERROR_NO_NAME
1140       * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME
1141       */
1142      function setName($name)
1143      {
1144          return $this->setServer($name);
1145      }
1146  
1147      /**
1148       * Set the socket number (port) that is used to connect to this channel
1149       * @param integer
1150       * @param string|false name of the mirror server, or false for the primary
1151       */
1152      function setPort($port, $mirror = false)
1153      {
1154          if ($mirror) {
1155              if (!isset($this->_channelInfo['servers']['mirror'])) {
1156                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1157                      array('mirror' => $mirror));
1158                  return false;
1159              }
1160              $setmirror = false;
1161              if (isset($this->_channelInfo['servers']['mirror'][0])) {
1162                  foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1163                      if ($mirror == $mir['attribs']['host']) {
1164                          $this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port;
1165                          return true;
1166                      }
1167                  }
1168                  return false;
1169              } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1170                  $this->_channelInfo['servers']['mirror']['attribs']['port'] = $port;
1171                  $this->_isValid = false;
1172                  return true;
1173              }
1174          }
1175          $this->_channelInfo['servers']['primary']['attribs']['port'] = $port;
1176          $this->_isValid = false;
1177          return true;
1178      }
1179  
1180      /**
1181       * Set the socket number (port) that is used to connect to this channel
1182       * @param bool Determines whether to turn on SSL support or turn it off
1183       * @param string|false name of the mirror server, or false for the primary
1184       */
1185      function setSSL($ssl = true, $mirror = false)
1186      {
1187          if ($mirror) {
1188              if (!isset($this->_channelInfo['servers']['mirror'])) {
1189                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1190                      array('mirror' => $mirror));
1191                  return false;
1192              }
1193              $setmirror = false;
1194              if (isset($this->_channelInfo['servers']['mirror'][0])) {
1195                  foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1196                      if ($mirror == $mir['attribs']['host']) {
1197                          if (!$ssl) {
1198                              if (isset($this->_channelInfo['servers']['mirror'][$i]
1199                                    ['attribs']['ssl'])) {
1200                                  unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']);
1201                              }
1202                          } else {
1203                              $this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes';
1204                          }
1205                          return true;
1206                      }
1207                  }
1208                  return false;
1209              } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1210                  if (!$ssl) {
1211                      if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) {
1212                          unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']);
1213                      }
1214                  } else {
1215                      $this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes';
1216                  }
1217                  $this->_isValid = false;
1218                  return true;
1219              }
1220          }
1221          if ($ssl) {
1222              $this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes';
1223          } else {
1224              if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
1225                  unset($this->_channelInfo['servers']['primary']['attribs']['ssl']);
1226              }
1227          }
1228          $this->_isValid = false;
1229          return true;
1230      }
1231  
1232      /**
1233       * Set the socket number (port) that is used to connect to this channel
1234       * @param integer
1235       * @param string|false name of the mirror server, or false for the primary
1236       */
1237      function setPath($protocol, $path, $mirror = false)
1238      {
1239          if (!in_array($protocol, array('xmlrpc', 'soap'))) {
1240              return false;
1241          }
1242          if ($mirror) {
1243              if (!isset($this->_channelInfo['servers']['mirror'])) {
1244                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1245                      array('mirror' => $mirror));
1246                  return false;
1247              }
1248              $setmirror = false;
1249              if (isset($this->_channelInfo['servers']['mirror'][0])) {
1250                  foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1251                      if ($mirror == $mir['attribs']['host']) {
1252                          $this->_channelInfo['servers']['mirror'][$i][$protocol]['attribs']['path'] =
1253                              $path;
1254                          return true;
1255                      }
1256                  }
1257                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1258                      array('mirror' => $mirror));
1259                  return false;
1260              } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1261                  $this->_channelInfo['servers']['mirror'][$protocol]['attribs']['path'] = $path;
1262                  $this->_isValid = false;
1263                  return true;
1264              }
1265          }
1266          $this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'] = $path;
1267          $this->_isValid = false;
1268          return true;
1269      }
1270  
1271      /**
1272       * @param string
1273       * @return string|false
1274       * @error PEAR_CHANNELFILE_ERROR_NO_SERVER
1275       * @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER
1276       */
1277      function setServer($server, $mirror = false)
1278      {
1279          if (empty($server)) {
1280              $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER);
1281              return false;
1282          } elseif (!$this->validChannelServer($server)) {
1283              $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
1284                  array('tag' => 'name', 'name' => $server));
1285              return false;
1286          }
1287          if ($mirror) {
1288              $found = false;
1289              foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1290                  if ($mirror == $mir['attribs']['host']) {
1291                      $found = true;
1292                      break;
1293                  }
1294              }
1295              if (!$found) {
1296                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1297                      array('mirror' => $mirror));
1298                  return false;
1299              }
1300              $this->_channelInfo['mirror'][$i]['attribs']['host'] = $server;
1301              return true;
1302          }
1303          $this->_channelInfo['name'] = $server;
1304          return true;
1305      }
1306  
1307      /**
1308       * @param string
1309       * @return boolean success
1310       * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY
1311       * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY
1312       */
1313      function setSummary($summary)
1314      {
1315          if (empty($summary)) {
1316              $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
1317              return false;
1318          } elseif (strpos(trim($summary), "\n") !== false) {
1319              $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
1320                  array('summary' => $summary));
1321          }
1322          $this->_channelInfo['summary'] = $summary;
1323          return true;
1324      }
1325  
1326      /**
1327       * @param string
1328       * @param boolean determines whether the alias is in channel.xml or local
1329       * @return boolean success
1330       */
1331      function setAlias($alias, $local = false)
1332      {
1333          if (!$this->validChannelServer($alias)) {
1334              $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
1335                  array('tag' => 'suggestedalias', 'name' => $alias));
1336              return false;
1337          }
1338          if ($local) {
1339              $this->_channelInfo['localalias'] = $alias;
1340          } else {
1341              $this->_channelInfo['suggestedalias'] = $alias;
1342          }
1343          return true;
1344      }
1345  
1346      /**
1347       * @return string
1348       */
1349      function getAlias()
1350      {
1351          if (isset($this->_channelInfo['localalias'])) {
1352              return $this->_channelInfo['localalias'];
1353          }
1354          if (isset($this->_channelInfo['suggestedalias'])) {
1355              return $this->_channelInfo['suggestedalias'];
1356          }
1357          if (isset($this->_channelInfo['name'])) {
1358              return $this->_channelInfo['name'];
1359          }
1360      }
1361  
1362      /**
1363       * Set the package validation object if it differs from PEAR's default
1364       * The class must be includeable via changing _ in the classname to path separator,
1365       * but no checking of this is made.
1366       * @param string|false pass in false to reset to the default packagename regex
1367       * @return boolean success
1368       */
1369      function setValidationPackage($validateclass, $version)
1370      {
1371          if (empty($validateclass)) {
1372              unset($this->_channelInfo['validatepackage']);
1373          }
1374          $this->_channelInfo['validatepackage'] = array('_content' => $validateclass);
1375          $this->_channelInfo['validatepackage']['attribs'] = array('version' => $version);
1376      }
1377  
1378      /**
1379       * Add a protocol to the provides section
1380       * @param string protocol type
1381       * @param string protocol version
1382       * @param string protocol name, if any
1383       * @param string mirror name, if this is a mirror's protocol
1384       * @return bool
1385       */
1386      function addFunction($type, $version, $name = '', $mirror = false)
1387      {
1388          if ($mirror) {
1389              return $this->addMirrorFunction($mirror, $type, $version, $name);
1390          }
1391          $set = array('attribs' => array('version' => $version), '_content' => $name);
1392          if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) {
1393              $this->_channelInfo['servers']['primary'][$type]['function'] = $set;
1394              $this->_isValid = false;
1395              return true;
1396          } elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) {
1397              $this->_channelInfo['servers']['primary'][$type]['function'] = array(
1398                  $this->_channelInfo['servers']['primary'][$type]['function']);
1399          }
1400          $this->_channelInfo['servers']['primary'][$type]['function'][] = $set;
1401          return true;
1402      }
1403      /**
1404       * Add a protocol to a mirror's provides section
1405       * @param string mirror name (server)
1406       * @param string protocol type
1407       * @param string protocol version
1408       * @param string protocol name, if any
1409       */
1410      function addMirrorFunction($mirror, $type, $version, $name = '')
1411      {
1412          $found = false;
1413          if (!isset($this->_channelInfo['servers']['mirror'])) {
1414              $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1415                  array('mirror' => $mirror));
1416              return false;
1417          }
1418          $setmirror = false;
1419          if (isset($this->_channelInfo['servers']['mirror'][0])) {
1420              foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1421                  if ($mirror == $mir['attribs']['host']) {
1422                      $setmirror = &$this->_channelInfo['servers']['mirror'][$i];
1423                      break;
1424                  }
1425              }
1426          } else {
1427              if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1428                  $setmirror = &$this->_channelInfo['servers']['mirror'];
1429              }
1430          }
1431          if (!$setmirror) {
1432              $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1433                  array('mirror' => $mirror));
1434              return false;
1435          }
1436          $set = array('attribs' => array('version' => $version), '_content' => $name);
1437          if (!isset($setmirror[$type]['function'])) {
1438              $setmirror[$type]['function'] = $set;
1439              $this->_isValid = false;
1440              return true;
1441          } elseif (!isset($setmirror[$type]['function'][0])) {
1442              $setmirror[$type]['function'] = array($setmirror[$type]['function']);
1443          }
1444          $setmirror[$type]['function'][] = $set;
1445          $this->_isValid = false;
1446          return true;
1447      }
1448  
1449      /**
1450       * @param string Resource Type this url links to
1451       * @param string URL
1452       * @param string|false mirror name, if this is not a primary server REST base URL
1453       */
1454      function setBaseURL($resourceType, $url, $mirror = false)
1455      {
1456          if ($mirror) {
1457              $found = false;
1458              if (!isset($this->_channelInfo['servers']['mirror'])) {
1459                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1460                      array('mirror' => $mirror));
1461                  return false;
1462              }
1463              $setmirror = false;
1464              if (isset($this->_channelInfo['servers']['mirror'][0])) {
1465                  foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1466                      if ($mirror == $mir['attribs']['host']) {
1467                          $setmirror = &$this->_channelInfo['servers']['mirror'][$i];
1468                          break;
1469                      }
1470                  }
1471              } else {
1472                  if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1473                      $setmirror = &$this->_channelInfo['servers']['mirror'];
1474                  }
1475              }
1476          } else {
1477              $setmirror = &$this->_channelInfo['servers']['primary'];
1478          }
1479          $set = array('attribs' => array('type' => $resourceType), '_content' => $url);
1480          if (!isset($setmirror['rest']['baseurl'])) {
1481              $setmirror['rest']['baseurl'] = $set;
1482              $this->_isValid = false;
1483              return true;
1484          } elseif (!isset($setmirror['rest']['baseurl'][0])) {
1485              $setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']);
1486          }
1487          foreach ($setmirror['rest']['baseurl'] as $i => $url) {
1488              if ($url['attribs']['type'] == $resourceType) {
1489                  $this->_isValid = false;
1490                  $setmirror['rest']['baseurl'][$i] = $set;
1491                  return true;
1492              }
1493          }
1494          $setmirror['rest']['baseurl'][] = $set;
1495          $this->_isValid = false;
1496          return true;
1497      }
1498  
1499      /**
1500       * @param string mirror server
1501       * @param int mirror http port
1502       * @return boolean
1503       */
1504      function addMirror($server, $port = null)
1505      {
1506          if ($this->_channelInfo['name'] == '__uri') {
1507              return false; // the __uri channel cannot have mirrors by definition
1508          }
1509          $set = array('attribs' => array('host' => $server));
1510          if (is_numeric($port)) {
1511              $set['attribs']['port'] = $port;
1512          }
1513          if (!isset($this->_channelInfo['servers']['mirror'])) {
1514              $this->_channelInfo['servers']['mirror'] = $set;
1515              return true;
1516          } else {
1517              if (!isset($this->_channelInfo['servers']['mirror'][0])) {
1518                  $this->_channelInfo['servers']['mirror'] =
1519                      array($this->_channelInfo['servers']['mirror']);
1520              }
1521          }
1522          $this->_channelInfo['servers']['mirror'][] = $set;
1523          return true;
1524      }
1525  
1526      /**
1527       * Retrieve the name of the validation package for this channel
1528       * @return string|false
1529       */
1530      function getValidationPackage()
1531      {
1532          if (!$this->_isValid && !$this->validate()) {
1533              return false;
1534          }
1535          if (!isset($this->_channelInfo['validatepackage'])) {
1536              return array('attribs' => array('version' => 'default'),
1537                  '_content' => 'PEAR_Validate');
1538          }
1539          return $this->_channelInfo['validatepackage'];
1540      }
1541  
1542      /**
1543       * Retrieve the object that can be used for custom validation
1544       * @param string|false the name of the package to validate.  If the package is
1545       *                     the channel validation package, PEAR_Validate is returned
1546       * @return PEAR_Validate|false false is returned if the validation package
1547       *         cannot be located
1548       */
1549      function &getValidationObject($package = false)
1550      {
1551          if (!class_exists('PEAR_Validate')) {
1552              require_once 'PEAR/Validate.php';
1553          }
1554          if (!$this->_isValid) {
1555              if (!$this->validate()) {
1556                  $a = false;
1557                  return $a;
1558              }
1559          }
1560          if (isset($this->_channelInfo['validatepackage'])) {
1561              if ($package == $this->_channelInfo['validatepackage']) {
1562                  // channel validation packages are always validated by PEAR_Validate
1563                  $val = &new PEAR_Validate;
1564                  return $val;
1565              }
1566              if (!class_exists(str_replace('.', '_',
1567                    $this->_channelInfo['validatepackage']['_content']))) {
1568                  if ($this->isIncludeable(str_replace('_', '/',
1569                        $this->_channelInfo['validatepackage']['_content']) . '.php')) {
1570                      include_once str_replace('_', '/',
1571                          $this->_channelInfo['validatepackage']['_content']) . '.php';
1572                      $vclass = str_replace('.', '_',
1573                          $this->_channelInfo['validatepackage']['_content']);
1574                      $val = &new $vclass;
1575                  } else {
1576                      $a = false;
1577                      return $a;
1578                  }
1579              } else {
1580                  $vclass = str_replace('.', '_',
1581                      $this->_channelInfo['validatepackage']['_content']);
1582                  $val = &new $vclass;
1583              }
1584          } else {
1585              $val = &new PEAR_Validate;
1586          }
1587          return $val;
1588      }
1589  
1590      function isIncludeable($path)
1591      {
1592          $possibilities = explode(PATH_SEPARATOR, ini_get('include_path'));
1593          foreach ($possibilities as $dir) {
1594              if (file_exists($dir . DIRECTORY_SEPARATOR . $path)
1595                    && is_readable($dir . DIRECTORY_SEPARATOR . $path)) {
1596                  return true;
1597              }
1598          }
1599          return false;
1600      }
1601  
1602      /**
1603       * This function is used by the channel updater and retrieves a value set by
1604       * the registry, or the current time if it has not been set
1605       * @return string
1606       */
1607      function lastModified()
1608      {
1609          if (isset($this->_channelInfo['_lastmodified'])) {
1610              return $this->_channelInfo['_lastmodified'];
1611          }
1612          return time();
1613      }
1614  }
1615  ?>


Généré le : Wed Nov 21 12:27:40 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics