[ Index ]
 

Code source de PHP PEAR 1.4.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/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.78 2006/10/31 02:54:40 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.5.0
 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 (!file_exists($descfile) || !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          fclose($fp);
 403          $data = file_get_contents($descfile);
 404          return $this->fromXmlString($data);
 405      }
 406  
 407      /**
 408       * Parse channel information from different sources
 409       *
 410       * This method is able to extract information about a channel
 411       * from an .xml file or a string
 412       *
 413       * @access public
 414       * @param  string Filename of the source or the source itself
 415       * @return bool
 416       */
 417      function fromAny($info)
 418      {
 419          if (is_string($info) && file_exists($info) && strlen($info) < 255) {
 420              $tmp = substr($info, -4);
 421              if ($tmp == '.xml') {
 422                  $info = $this->fromXmlFile($info);
 423              } else {
 424                  $fp = fopen($info, "r");
 425                  $test = fread($fp, 5);
 426                  fclose($fp);
 427                  if ($test == "<?xml") {
 428                      $info = $this->fromXmlFile($info);
 429                  }
 430              }
 431              if (PEAR::isError($info)) {
 432                  require_once  'PEAR.php';
 433                  return PEAR::raiseError($info);
 434              }
 435          }
 436          if (is_string($info)) {
 437              $info = $this->fromXmlString($info);
 438          }
 439          return $info;
 440      }
 441  
 442      /**
 443       * Return an XML document based on previous parsing and modifications
 444       *
 445       * @return string XML data
 446       *
 447       * @access public
 448       */
 449      function toXml()
 450      {
 451          if (!$this->_isValid && !$this->validate()) {
 452              $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID);
 453              return false;
 454          }
 455          if (!isset($this->_channelInfo['attribs']['version'])) {
 456              $this->_channelInfo['attribs']['version'] = '1.0';
 457          }
 458          $channelInfo = $this->_channelInfo;
 459          $ret = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n";
 460          $ret .= "<channel version=\"" .
 461              $channelInfo['attribs']['version'] . "\" xmlns=\"http://pear.php.net/channel-1.0\"
 462    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
 463    xsi:schemaLocation=\"http://pear.php.net/dtd/channel-"
 464              . $channelInfo['attribs']['version'] . " http://pear.php.net/dtd/channel-" .
 465              $channelInfo['attribs']['version'] . ".xsd\">
 466   <name>$channelInfo[name]</name>
 467   <summary>" . htmlspecialchars($channelInfo['summary'])."</summary>
 468  ";
 469          if (isset($channelInfo['suggestedalias'])) {
 470              $ret .= ' <suggestedalias>' . $channelInfo['suggestedalias'] . "</suggestedalias>\n";
 471          }
 472          if (isset($channelInfo['validatepackage'])) {
 473              $ret .= ' <validatepackage version="' .
 474                  $channelInfo['validatepackage']['attribs']['version']. '">' .
 475                  htmlspecialchars($channelInfo['validatepackage']['_content']) .
 476                  "</validatepackage>\n";
 477          }
 478          $ret .= " <servers>\n";
 479          $ret .= '  <primary';
 480          if (isset($channelInfo['servers']['primary']['attribs']['ssl'])) {
 481              $ret .= ' ssl="' . $channelInfo['servers']['primary']['attribs']['ssl'] . '"';
 482          }
 483          if (isset($channelInfo['servers']['primary']['attribs']['port'])) {
 484              $ret .= ' port="' . $channelInfo['servers']['primary']['attribs']['port'] . '"';
 485          }
 486          $ret .= ">\n";
 487          if (isset($channelInfo['servers']['primary']['xmlrpc'])) {
 488              $ret .= $this->_makeXmlrpcXml($channelInfo['servers']['primary']['xmlrpc'], '   ');
 489          }
 490          if (isset($channelInfo['servers']['primary']['rest'])) {
 491              $ret .= $this->_makeRestXml($channelInfo['servers']['primary']['rest'], '   ');
 492          }
 493          if (isset($channelInfo['servers']['primary']['soap'])) {
 494              $ret .= $this->_makeSoapXml($channelInfo['servers']['primary']['soap'], '   ');
 495          }
 496          $ret .= "  </primary>\n";
 497          if (isset($channelInfo['servers']['mirror'])) {
 498              $ret .= $this->_makeMirrorsXml($channelInfo);
 499          }
 500          $ret .= " </servers>\n";
 501          $ret .= "</channel>";
 502          return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret));
 503      }
 504  
 505      /**
 506       * Generate the <xmlrpc> tag
 507       * @access private
 508       */
 509      function _makeXmlrpcXml($info, $indent)
 510      {
 511          $ret = $indent . "<xmlrpc";
 512          if (isset($info['attribs']['path'])) {
 513              $ret .= ' path="' . htmlspecialchars($info['attribs']['path']) . '"';
 514          }
 515          $ret .= ">\n";
 516          $ret .= $this->_makeFunctionsXml($info['function'], "$indent ");
 517          $ret .= $indent . "</xmlrpc>\n";
 518          return $ret;
 519      }
 520  
 521      /**
 522       * Generate the <soap> tag
 523       * @access private
 524       */
 525      function _makeSoapXml($info, $indent)
 526      {
 527          $ret = $indent . "<soap";
 528          if (isset($info['attribs']['path'])) {
 529              $ret .= ' path="' . htmlspecialchars($info['attribs']['path']) . '"';
 530          }
 531          $ret .= ">\n";
 532          $ret .= $this->_makeFunctionsXml($info['function'], "$indent ");
 533          $ret .= $indent . "</soap>\n";
 534          return $ret;
 535      }
 536  
 537      /**
 538       * Generate the <rest> tag
 539       * @access private
 540       */
 541      function _makeRestXml($info, $indent)
 542      {
 543          $ret = $indent . "<rest>\n";
 544          if (!isset($info['baseurl'][0])) {
 545              $info['baseurl'] = array($info['baseurl']);
 546          }
 547          foreach ($info['baseurl'] as $url) {
 548              $ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\"";
 549              $ret .= ">" . $url['_content'] . "</baseurl>\n";
 550          }
 551          $ret .= $indent . "</rest>\n";
 552          return $ret;
 553      }
 554  
 555      /**
 556       * Generate the <mirrors> tag
 557       * @access private
 558       */
 559      function _makeMirrorsXml($channelInfo)
 560      {
 561          $ret = "";
 562          if (!isset($channelInfo['servers']['mirror'][0])) {
 563              $channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']);
 564          }
 565          foreach ($channelInfo['servers']['mirror'] as $mirror) {
 566              $ret .= '  <mirror host="' . $mirror['attribs']['host'] . '"';
 567              if (isset($mirror['attribs']['port'])) {
 568                  $ret .= ' port="' . $mirror['attribs']['port'] . '"';
 569              }
 570              if (isset($mirror['attribs']['ssl'])) {
 571                  $ret .= ' ssl="' . $mirror['attribs']['ssl'] . '"';
 572              }
 573              $ret .= ">\n";
 574              if (isset($mirror['xmlrpc']) || isset($mirror['soap'])) {
 575                  if (isset($mirror['xmlrpc'])) {
 576                      $ret .= $this->_makeXmlrpcXml($mirror['xmlrpc'], '   ');
 577                  }
 578                  if (isset($mirror['rest'])) {
 579                      $ret .= $this->_makeRestXml($mirror['rest'], '   ');
 580                  }
 581                  if (isset($mirror['soap'])) {
 582                      $ret .= $this->_makeSoapXml($mirror['soap'], '   ');
 583                  }
 584                  $ret .= "  </mirror>\n";
 585              } else {
 586                  $ret .= "/>\n";
 587              }
 588          }
 589          return $ret;
 590      }
 591  
 592      /**
 593       * Generate the <functions> tag
 594       * @access private
 595       */
 596      function _makeFunctionsXml($functions, $indent, $rest = false)
 597      {
 598          $ret = '';
 599          if (!isset($functions[0])) {
 600              $functions = array($functions);
 601          }
 602          foreach ($functions as $function) {
 603              $ret .= "$indent<function version=\"" . $function['attribs']['version'] . "\"";
 604              if ($rest) {
 605                  $ret .= ' uri="' . $function['attribs']['uri'] . '"';
 606              }
 607              $ret .= ">" . $function['_content'] . "</function>\n";
 608          }
 609          return $ret;
 610      }
 611  
 612      /**
 613       * Validation error.  Also marks the object contents as invalid
 614       * @param error code
 615       * @param array error information
 616       * @access private
 617       */
 618      function _validateError($code, $params = array())
 619      {
 620          $this->_stack->push($code, 'error', $params);
 621          $this->_isValid = false;
 622      }
 623  
 624      /**
 625       * Validation warning.  Does not mark the object contents invalid.
 626       * @param error code
 627       * @param array error information
 628       * @access private
 629       */
 630      function _validateWarning($code, $params = array())
 631      {
 632          $this->_stack->push($code, 'warning', $params);
 633      }
 634  
 635      /**
 636       * Validate parsed file.
 637       *
 638       * @access public
 639       * @return boolean
 640       */
 641      function validate()
 642      {
 643          $this->_isValid = true;
 644          $info = $this->_channelInfo;
 645          if (empty($info['name'])) {
 646              $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME);
 647          } elseif (!$this->validChannelServer($info['name'])) {
 648              if ($info['name'] != '__uri') {
 649                  $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name',
 650                      'name' => $info['name']));
 651              }
 652          }
 653          if (empty($info['summary'])) {
 654              $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
 655          } elseif (strpos(trim($info['summary']), "\n") !== false) {
 656              $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
 657                  array('summary' => $info['summary']));
 658          }
 659          if (isset($info['suggestedalias'])) {
 660              if (!$this->validChannelServer($info['suggestedalias'])) {
 661                  $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
 662                      array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias']));
 663              }
 664          }
 665          if (isset($info['localalias'])) {
 666              if (!$this->validChannelServer($info['localalias'])) {
 667                  $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
 668                      array('tag' => 'localalias', 'name' =>$info['localalias']));
 669              }
 670          }
 671          if (isset($info['validatepackage'])) {
 672              if (!isset($info['validatepackage']['_content'])) {
 673                  $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME);
 674              }
 675              if (!isset($info['validatepackage']['attribs']['version'])) {
 676                  $content = isset($info['validatepackage']['_content']) ?
 677                      $info['validatepackage']['_content'] :
 678                      null;
 679                  $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION,
 680                      array('package' => $content));
 681              }
 682          }
 683          if (isset($info['servers']['primary']['attribs']['port']) &&
 684                !is_numeric($info['servers']['primary']['attribs']['port'])) {
 685              $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT,
 686                  array('port' => $info['servers']['primary']['attribs']['port']));
 687          }
 688          if (isset($info['servers']['primary']['attribs']['ssl']) &&
 689                $info['servers']['primary']['attribs']['ssl'] != 'yes') {
 690              $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
 691                  array('ssl' => $info['servers']['primary']['attribs']['ssl'],
 692                      'server' => $info['name']));
 693          }
 694  
 695          if (isset($info['servers']['primary']['xmlrpc']) &&
 696                isset($info['servers']['primary']['xmlrpc']['function'])) {
 697              $this->_validateFunctions('xmlrpc', $info['servers']['primary']['xmlrpc']['function']);
 698          }
 699          if (isset($info['servers']['primary']['soap']) &&
 700                isset($info['servers']['primary']['soap']['function'])) {
 701              $this->_validateFunctions('soap', $info['servers']['primary']['soap']['function']);
 702          }
 703          if (isset($info['servers']['primary']['rest']) &&
 704                isset($info['servers']['primary']['rest']['baseurl'])) {
 705              $this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']);
 706          }
 707          if (isset($info['servers']['mirror'])) {
 708              if ($this->_channelInfo['name'] == '__uri') {
 709                  $this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR);
 710              }
 711              if (!isset($info['servers']['mirror'][0])) {
 712                  $info['servers']['mirror'] = array($info['servers']['mirror']);
 713              }
 714              $i = 0;
 715              foreach ($info['servers']['mirror'] as $mirror) {
 716                  if (!isset($mirror['attribs']['host'])) {
 717                      $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST,
 718                        array('type' => 'mirror'));
 719                  } elseif (!$this->validChannelServer($mirror['attribs']['host'])) {
 720                      $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST,
 721                          array('server' => $mirror['attribs']['host'], 'type' => 'mirror'));
 722                  }
 723                  if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') {
 724                      $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
 725                          array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host']));
 726                  }
 727                  if (isset($mirror['xmlrpc'])) {
 728                      $this->_validateFunctions('xmlrpc',
 729                          $mirror['xmlrpc']['function'], $mirror['attribs']['host']);
 730                  }
 731                  if (isset($mirror['soap'])) {
 732                      $this->_validateFunctions('soap', $mirror['soap']['function'],
 733                          $mirror['attribs']['host']);
 734                  }
 735                  if (isset($mirror['rest'])) {
 736                      $this->_validateFunctions('rest', $mirror['rest']['baseurl'],
 737                          $mirror['attribs']['host']);
 738                  }
 739              }
 740          }
 741          return $this->_isValid;
 742      }
 743  
 744      /**
 745       * @param string xmlrpc or soap - protocol name this function applies to
 746       * @param array the functions
 747       * @param string the name of the parent element (mirror name, for instance)
 748       */
 749      function _validateFunctions($protocol, $functions, $parent = '')
 750      {
 751          if (!isset($functions[0])) {
 752              $functions = array($functions);
 753          }
 754          foreach ($functions as $function) {
 755              if (!isset($function['_content']) || empty($function['_content'])) {
 756                  $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME,
 757                      array('parent' => $parent, 'protocol' => $protocol));
 758              }
 759              if ($protocol == 'rest') {
 760                  if (!isset($function['attribs']['type']) ||
 761                        empty($function['attribs']['type'])) {
 762                      $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_BASEURLTYPE,
 763                          array('parent' => $parent, 'protocol' => $protocol));
 764                  }
 765              } else {
 766                  if (!isset($function['attribs']['version']) ||
 767                        empty($function['attribs']['version'])) {
 768                      $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION,
 769                          array('parent' => $parent, 'protocol' => $protocol));
 770                  }
 771              }
 772          }
 773      }
 774  
 775      /**
 776       * Test whether a string contains a valid channel server.
 777       * @param string $ver the package version to test
 778       * @return bool
 779       */
 780      function validChannelServer($server)
 781      {
 782          if ($server == '__uri') {
 783              return true;
 784          }
 785          return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server);
 786      }
 787  
 788      /**
 789       * @return string|false
 790       */
 791      function getName()
 792      {
 793          if (isset($this->_channelInfo['name'])) {
 794              return $this->_channelInfo['name'];
 795          } else {
 796              return false;
 797          }
 798      }
 799  
 800      /**
 801       * @return string|false
 802       */
 803      function getServer()
 804      {
 805          if (isset($this->_channelInfo['name'])) {
 806              return $this->_channelInfo['name'];
 807          } else {
 808              return false;
 809          }
 810      }
 811  
 812      /**
 813       * @return int|80 port number to connect to
 814       */
 815      function getPort($mirror = false)
 816      {
 817          if ($mirror) {
 818              if ($mir = $this->getMirror($mirror)) {
 819                  if (isset($mir['attribs']['port'])) {
 820                      return $mir['attribs']['port'];
 821                  } else {
 822                      if ($this->getSSL($mirror)) {
 823                          return 443;
 824                      }
 825                      return 80;
 826                  }
 827              }
 828              return false;
 829          }
 830          if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) {
 831              return $this->_channelInfo['servers']['primary']['attribs']['port'];
 832          }
 833          if ($this->getSSL()) {
 834              return 443;
 835          }
 836          return 80;
 837      }
 838  
 839      /**
 840       * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel
 841       */
 842      function getSSL($mirror = false)
 843      {
 844          if ($mirror) {
 845              if ($mir = $this->getMirror($mirror)) {
 846                  if (isset($mir['attribs']['ssl'])) {
 847                      return true;
 848                  } else {
 849                      return false;
 850                  }
 851              }
 852              return false;
 853          }
 854          if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
 855              return true;
 856          }
 857          return false;
 858      }
 859  
 860      /**
 861       * @return string|false
 862       */
 863      function getSummary()
 864      {
 865          if (isset($this->_channelInfo['summary'])) {
 866              return $this->_channelInfo['summary'];
 867          } else {
 868              return false;
 869          }
 870      }
 871  
 872      /**
 873       * @param string xmlrpc or soap
 874       * @param string|false mirror name or false for primary server
 875       */
 876      function getPath($protocol, $mirror = false)
 877      {   
 878          if (!in_array($protocol, array('xmlrpc', 'soap'))) {
 879              return false;
 880          }
 881          if ($mirror) {
 882              if (!($mir = $this->getMirror($mirror))) {
 883                  return false;
 884              }
 885              if (isset($mir[$protocol]['attribs']['path'])) {
 886                  return $mir[$protocol]['attribs']['path'];
 887              } else {
 888                  return $protocol . '.php';
 889              }
 890          } elseif (isset($this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'])) {
 891              return $this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'];
 892          }
 893          return $protocol . '.php';
 894      }
 895  
 896      /**
 897       * @param string protocol type (xmlrpc, soap)
 898       * @param string Mirror name
 899       * @return array|false
 900       */
 901      function getFunctions($protocol, $mirror = false)
 902      {
 903          if ($this->getName() == '__uri') {
 904              return false;
 905          }
 906          if ($protocol == 'rest') {
 907              $function = 'baseurl';
 908          } else {
 909              $function = 'function';
 910          }
 911          if ($mirror) {
 912              if ($mir = $this->getMirror($mirror)) {
 913                  if (isset($mir[$protocol][$function])) {
 914                      return $mir[$protocol][$function];
 915                  }
 916              }
 917              return false;
 918          }
 919          if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) {
 920              return $this->_channelInfo['servers']['primary'][$protocol][$function];
 921          } else {
 922              return false;
 923          }
 924      }
 925  
 926      /**
 927       * @param string Protocol type
 928       * @param string Function name (null to return the
 929       *               first protocol of the type requested)
 930       * @param string Mirror name, if any
 931       * @return array
 932       */
 933       function getFunction($type, $name = null, $mirror = false)
 934       {
 935          $protocols = $this->getFunctions($type, $mirror);
 936          if (!$protocols) {
 937              return false;
 938          }
 939          foreach ($protocols as $protocol) {
 940              if ($name === null) {
 941                  return $protocol;
 942              }
 943              if ($protocol['_content'] != $name) {
 944                  continue;
 945              }
 946              return $protocol;
 947          }
 948          return false;
 949       }
 950  
 951      /**
 952       * @param string protocol type
 953       * @param string protocol name
 954       * @param string version
 955       * @param string mirror name
 956       * @return boolean
 957       */
 958      function supports($type, $name = null, $mirror = false, $version = '1.0')
 959      {
 960          $protocols = $this->getFunctions($type, $mirror);
 961          if (!$protocols) {
 962              return false;
 963          }
 964          foreach ($protocols as $protocol) {
 965              if ($protocol['attribs']['version'] != $version) {
 966                  continue;
 967              }
 968              if ($name === null) {
 969                  return true;
 970              }
 971              if ($protocol['_content'] != $name) {
 972                  continue;
 973              }
 974              return true;
 975          }
 976          return false;
 977      }
 978  
 979      /**
 980       * Determines whether a channel supports Representational State Transfer (REST) protocols
 981       * for retrieving channel information
 982       * @param string
 983       * @return bool
 984       */
 985      function supportsREST($mirror = false)
 986      {
 987          if ($mirror == $this->_channelInfo['name']) {
 988              $mirror = false;
 989          }
 990          if ($mirror) {
 991              if ($mir = $this->getMirror($mirror)) {
 992                  return isset($mir['rest']);
 993              }
 994              return false;
 995          }
 996          return isset($this->_channelInfo['servers']['primary']['rest']);
 997      }
 998  
 999      /**
1000       * Get the URL to access a base resource.
1001       *
1002       * Hyperlinks in the returned xml will be used to retrieve the proper information
1003       * needed.  This allows extreme extensibility and flexibility in implementation
1004       * @param string Resource Type to retrieve
1005       */
1006      function getBaseURL($resourceType, $mirror = false)
1007      {
1008          if ($mirror == $this->_channelInfo['name']) {
1009              $mirror = false;
1010          }
1011          if ($mirror) {
1012              if ($mir = $this->getMirror($mirror)) {
1013                  $rest = $mir['rest'];
1014              } else {
1015                  return false;
1016              }
1017              $server = $mirror;
1018          } else {
1019              $rest = $this->_channelInfo['servers']['primary']['rest'];
1020              $server = $this->getServer();
1021          }
1022          if (!isset($rest['baseurl'][0])) {
1023              $rest['baseurl'] = array($rest['baseurl']);
1024          }
1025          foreach ($rest['baseurl'] as $baseurl) {
1026              if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) {
1027                  return $baseurl['_content'];
1028              }
1029          }
1030          return false;
1031      }
1032  
1033      /**
1034       * Since REST does not implement RPC, provide this as a logical wrapper around
1035       * resetFunctions for REST
1036       * @param string|false mirror name, if any
1037       */
1038      function resetREST($mirror = false)
1039      {
1040          return $this->resetFunctions('rest', $mirror);
1041      }
1042  
1043      /**
1044       * Empty all protocol definitions
1045       * @param string protocol type (xmlrpc, soap)
1046       * @param string|false mirror name, if any
1047       */
1048      function resetFunctions($type, $mirror = false)
1049      {
1050          if ($mirror) {
1051              if (isset($this->_channelInfo['servers']['mirror'])) {
1052                  $mirrors = $this->_channelInfo['servers']['mirror'];
1053                  if (!isset($mirrors[0])) {
1054                      $mirrors = array($mirrors);
1055                  }
1056                  foreach ($mirrors as $i => $mir) {
1057                      if ($mir['attribs']['host'] == $mirror) {
1058                          if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) {
1059                              unset($this->_channelInfo['servers']['mirror'][$i][$type]);
1060                          }
1061                          return true;
1062                      }
1063                  }
1064                  return false;
1065              } else {
1066                  return false;
1067              }
1068          } else {
1069              if (isset($this->_channelInfo['servers']['primary'][$type])) {
1070                  unset($this->_channelInfo['servers']['primary'][$type]);
1071              }
1072              return true;
1073          }
1074      }
1075  
1076      /**
1077       * Set a channel's protocols to the protocols supported by pearweb
1078       */
1079      function setDefaultPEARProtocols($version = '1.0', $mirror = false)
1080      {
1081          switch ($version) {
1082              case '1.0' :
1083                  $this->resetFunctions('xmlrpc', $mirror);
1084                  $this->resetFunctions('soap', $mirror);
1085                  $this->resetREST($mirror);
1086                  $this->addFunction('xmlrpc', '1.0', 'logintest', $mirror);
1087                  $this->addFunction('xmlrpc', '1.0', 'package.listLatestReleases', $mirror);
1088                  $this->addFunction('xmlrpc', '1.0', 'package.listAll', $mirror);
1089                  $this->addFunction('xmlrpc', '1.0', 'package.info', $mirror);
1090                  $this->addFunction('xmlrpc', '1.0', 'package.getDownloadURL', $mirror);
1091                  $this->addFunction('xmlrpc', '1.1', 'package.getDownloadURL', $mirror);
1092                  $this->addFunction('xmlrpc', '1.0', 'package.getDepDownloadURL', $mirror);
1093                  $this->addFunction('xmlrpc', '1.1', 'package.getDepDownloadURL', $mirror);
1094                  $this->addFunction('xmlrpc', '1.0', 'package.search', $mirror);
1095                  $this->addFunction('xmlrpc', '1.0', 'channel.listAll', $mirror);
1096                  return true;
1097              break;
1098              default :
1099                  return false;
1100              break;
1101          }
1102      }
1103      
1104      /**
1105       * @return array
1106       */
1107      function getMirrors()
1108      {
1109          if (isset($this->_channelInfo['servers']['mirror'])) {
1110              $mirrors = $this->_channelInfo['servers']['mirror'];
1111              if (!isset($mirrors[0])) {
1112                  $mirrors = array($mirrors);
1113              }
1114              return $mirrors;
1115          } else {
1116              return array();
1117          }
1118      }
1119  
1120      /**
1121       * Get the unserialized XML representing a mirror
1122       * @return array|false
1123       */
1124      function getMirror($server)
1125      {
1126          foreach ($this->getMirrors() as $mirror) {
1127              if ($mirror['attribs']['host'] == $server) {
1128                  return $mirror;
1129              }
1130          }
1131          return false;
1132      }
1133  
1134      /**
1135       * @param string
1136       * @return string|false
1137       * @error PEAR_CHANNELFILE_ERROR_NO_NAME
1138       * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME
1139       */
1140      function setName($name)
1141      {
1142          return $this->setServer($name);
1143      }
1144  
1145      /**
1146       * Set the socket number (port) that is used to connect to this channel
1147       * @param integer
1148       * @param string|false name of the mirror server, or false for the primary
1149       */
1150      function setPort($port, $mirror = false)
1151      {
1152          if ($mirror) {
1153              if (!isset($this->_channelInfo['servers']['mirror'])) {
1154                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1155                      array('mirror' => $mirror));
1156                  return false;
1157              }
1158              $setmirror = false;
1159              if (isset($this->_channelInfo['servers']['mirror'][0])) {
1160                  foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1161                      if ($mirror == $mir['attribs']['host']) {
1162                          $this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port;
1163                          return true;
1164                      }
1165                  }
1166                  return false;
1167              } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1168                  $this->_channelInfo['servers']['mirror']['attribs']['port'] = $port;
1169                  $this->_isValid = false;
1170                  return true;
1171              }
1172          }
1173          $this->_channelInfo['servers']['primary']['attribs']['port'] = $port;
1174          $this->_isValid = false;
1175          return true;
1176      }
1177  
1178      /**
1179       * Set the socket number (port) that is used to connect to this channel
1180       * @param bool Determines whether to turn on SSL support or turn it off
1181       * @param string|false name of the mirror server, or false for the primary
1182       */
1183      function setSSL($ssl = true, $mirror = false)
1184      {
1185          if ($mirror) {
1186              if (!isset($this->_channelInfo['servers']['mirror'])) {
1187                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1188                      array('mirror' => $mirror));
1189                  return false;
1190              }
1191              $setmirror = false;
1192              if (isset($this->_channelInfo['servers']['mirror'][0])) {
1193                  foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1194                      if ($mirror == $mir['attribs']['host']) {
1195                          if (!$ssl) {
1196                              if (isset($this->_channelInfo['servers']['mirror'][$i]
1197                                    ['attribs']['ssl'])) {
1198                                  unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']);
1199                              }
1200                          } else {
1201                              $this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes';
1202                          }
1203                          return true;
1204                      }
1205                  }
1206                  return false;
1207              } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1208                  if (!$ssl) {
1209                      if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) {
1210                          unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']);
1211                      }
1212                  } else {
1213                      $this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes';
1214                  }
1215                  $this->_isValid = false;
1216                  return true;
1217              }
1218          }
1219          if ($ssl) {
1220              $this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes';
1221          } else {
1222              if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
1223                  unset($this->_channelInfo['servers']['primary']['attribs']['ssl']);
1224              }
1225          }
1226          $this->_isValid = false;
1227          return true;
1228      }
1229  
1230      /**
1231       * Set the socket number (port) that is used to connect to this channel
1232       * @param integer
1233       * @param string|false name of the mirror server, or false for the primary
1234       */
1235      function setPath($protocol, $path, $mirror = false)
1236      {
1237          if (!in_array($protocol, array('xmlrpc', 'soap'))) {
1238              return false;
1239          }
1240          if ($mirror) {
1241              if (!isset($this->_channelInfo['servers']['mirror'])) {
1242                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1243                      array('mirror' => $mirror));
1244                  return false;
1245              }
1246              $setmirror = false;
1247              if (isset($this->_channelInfo['servers']['mirror'][0])) {
1248                  foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1249                      if ($mirror == $mir['attribs']['host']) {
1250                          $this->_channelInfo['servers']['mirror'][$i][$protocol]['attribs']['path'] =
1251                              $path;
1252                          return true;
1253                      }
1254                  }
1255                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1256                      array('mirror' => $mirror));
1257                  return false;
1258              } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1259                  $this->_channelInfo['servers']['mirror'][$protocol]['attribs']['path'] = $path;
1260                  $this->_isValid = false;
1261                  return true;
1262              }
1263          }
1264          $this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'] = $path;
1265          $this->_isValid = false;
1266          return true;
1267      }
1268  
1269      /**
1270       * @param string
1271       * @return string|false
1272       * @error PEAR_CHANNELFILE_ERROR_NO_SERVER
1273       * @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER
1274       */
1275      function setServer($server, $mirror = false)
1276      {
1277          if (empty($server)) {
1278              $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER);
1279              return false;
1280          } elseif (!$this->validChannelServer($server)) {
1281              $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
1282                  array('tag' => 'name', 'name' => $server));
1283              return false;
1284          }
1285          if ($mirror) {
1286              $found = false;
1287              foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1288                  if ($mirror == $mir['attribs']['host']) {
1289                      $found = true;
1290                      break;
1291                  }
1292              }
1293              if (!$found) {
1294                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1295                      array('mirror' => $mirror));
1296                  return false;
1297              }
1298              $this->_channelInfo['mirror'][$i]['attribs']['host'] = $server;
1299              return true;
1300          }
1301          $this->_channelInfo['name'] = $server;
1302          return true;
1303      }
1304  
1305      /**
1306       * @param string
1307       * @return boolean success
1308       * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY
1309       * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY
1310       */
1311      function setSummary($summary)
1312      {
1313          if (empty($summary)) {
1314              $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
1315              return false;
1316          } elseif (strpos(trim($summary), "\n") !== false) {
1317              $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
1318                  array('summary' => $summary));
1319          }
1320          $this->_channelInfo['summary'] = $summary;
1321          return true;
1322      }
1323  
1324      /**
1325       * @param string
1326       * @param boolean determines whether the alias is in channel.xml or local
1327       * @return boolean success
1328       */
1329      function setAlias($alias, $local = false)
1330      {
1331          if (!$this->validChannelServer($alias)) {
1332              $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
1333                  array('tag' => 'suggestedalias', 'name' => $alias));
1334              return false;
1335          }
1336          if ($local) {
1337              $this->_channelInfo['localalias'] = $alias;
1338          } else {
1339              $this->_channelInfo['suggestedalias'] = $alias;
1340          }
1341          return true;
1342      }
1343  
1344      /**
1345       * @return string
1346       */
1347      function getAlias()
1348      {
1349          if (isset($this->_channelInfo['localalias'])) {
1350              return $this->_channelInfo['localalias'];
1351          }
1352          if (isset($this->_channelInfo['suggestedalias'])) {
1353              return $this->_channelInfo['suggestedalias'];
1354          }
1355          if (isset($this->_channelInfo['name'])) {
1356              return $this->_channelInfo['name'];
1357          }
1358      }
1359  
1360      /**
1361       * Set the package validation object if it differs from PEAR's default
1362       * The class must be includeable via changing _ in the classname to path separator,
1363       * but no checking of this is made.
1364       * @param string|false pass in false to reset to the default packagename regex
1365       * @return boolean success
1366       */
1367      function setValidationPackage($validateclass, $version)
1368      {
1369          if (empty($validateclass)) {
1370              unset($this->_channelInfo['validatepackage']);
1371          }
1372          $this->_channelInfo['validatepackage'] = array('_content' => $validateclass);
1373          $this->_channelInfo['validatepackage']['attribs'] = array('version' => $version);
1374      }
1375  
1376      /**
1377       * Add a protocol to the provides section
1378       * @param string protocol type
1379       * @param string protocol version
1380       * @param string protocol name, if any
1381       * @param string mirror name, if this is a mirror's protocol
1382       * @return bool
1383       */
1384      function addFunction($type, $version, $name = '', $mirror = false)
1385      {
1386          if ($mirror) {
1387              return $this->addMirrorFunction($mirror, $type, $version, $name);
1388          }
1389          $set = array('attribs' => array('version' => $version), '_content' => $name);
1390          if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) {
1391              if (!isset($this->_channelInfo['servers'])) {
1392                  $this->_channelInfo['servers'] = array('primary' =>
1393                      array($type => array()));
1394              } elseif (!isset($this->_channelInfo['servers']['primary'])) {
1395                  $this->_channelInfo['servers']['primary'] = array($type => array());
1396              }
1397              $this->_channelInfo['servers']['primary'][$type]['function'] = $set;
1398              $this->_isValid = false;
1399              return true;
1400          } elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) {
1401              $this->_channelInfo['servers']['primary'][$type]['function'] = array(
1402                  $this->_channelInfo['servers']['primary'][$type]['function']);
1403          }
1404          $this->_channelInfo['servers']['primary'][$type]['function'][] = $set;
1405          return true;
1406      }
1407      /**
1408       * Add a protocol to a mirror's provides section
1409       * @param string mirror name (server)
1410       * @param string protocol type
1411       * @param string protocol version
1412       * @param string protocol name, if any
1413       */
1414      function addMirrorFunction($mirror, $type, $version, $name = '')
1415      {
1416          $found = false;
1417          if (!isset($this->_channelInfo['servers']['mirror'])) {
1418              $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1419                  array('mirror' => $mirror));
1420              return false;
1421          }
1422          $setmirror = false;
1423          if (isset($this->_channelInfo['servers']['mirror'][0])) {
1424              foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1425                  if ($mirror == $mir['attribs']['host']) {
1426                      $setmirror = &$this->_channelInfo['servers']['mirror'][$i];
1427                      break;
1428                  }
1429              }
1430          } else {
1431              if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1432                  $setmirror = &$this->_channelInfo['servers']['mirror'];
1433              }
1434          }
1435          if (!$setmirror) {
1436              $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1437                  array('mirror' => $mirror));
1438              return false;
1439          }
1440          $set = array('attribs' => array('version' => $version), '_content' => $name);
1441          if (!isset($setmirror[$type]['function'])) {
1442              $setmirror[$type]['function'] = $set;
1443              $this->_isValid = false;
1444              return true;
1445          } elseif (!isset($setmirror[$type]['function'][0])) {
1446              $setmirror[$type]['function'] = array($setmirror[$type]['function']);
1447          }
1448          $setmirror[$type]['function'][] = $set;
1449          $this->_isValid = false;
1450          return true;
1451      }
1452  
1453      /**
1454       * @param string Resource Type this url links to
1455       * @param string URL
1456       * @param string|false mirror name, if this is not a primary server REST base URL
1457       */
1458      function setBaseURL($resourceType, $url, $mirror = false)
1459      {
1460          if ($mirror) {
1461              $found = false;
1462              if (!isset($this->_channelInfo['servers']['mirror'])) {
1463                  $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
1464                      array('mirror' => $mirror));
1465                  return false;
1466              }
1467              $setmirror = false;
1468              if (isset($this->_channelInfo['servers']['mirror'][0])) {
1469                  foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1470                      if ($mirror == $mir['attribs']['host']) {
1471                          $setmirror = &$this->_channelInfo['servers']['mirror'][$i];
1472                          break;
1473                      }
1474                  }
1475              } else {
1476                  if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
1477                      $setmirror = &$this->_channelInfo['servers']['mirror'];
1478                  }
1479              }
1480          } else {
1481              $setmirror = &$this->_channelInfo['servers']['primary'];
1482          }
1483          $set = array('attribs' => array('type' => $resourceType), '_content' => $url);
1484          if (!isset($setmirror['rest'])) {
1485              $setmirror['rest'] = array();
1486          }
1487          if (!isset($setmirror['rest']['baseurl'])) {
1488              $setmirror['rest']['baseurl'] = $set;
1489              $this->_isValid = false;
1490              return true;
1491          } elseif (!isset($setmirror['rest']['baseurl'][0])) {
1492              $setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']);
1493          }
1494          foreach ($setmirror['rest']['baseurl'] as $i => $url) {
1495              if ($url['attribs']['type'] == $resourceType) {
1496                  $this->_isValid = false;
1497                  $setmirror['rest']['baseurl'][$i] = $set;
1498                  return true;
1499              }
1500          }
1501          $setmirror['rest']['baseurl'][] = $set;
1502          $this->_isValid = false;
1503          return true;
1504      }
1505  
1506      /**
1507       * @param string mirror server
1508       * @param int mirror http port
1509       * @return boolean
1510       */
1511      function addMirror($server, $port = null)
1512      {
1513          if ($this->_channelInfo['name'] == '__uri') {
1514              return false; // the __uri channel cannot have mirrors by definition
1515          }
1516          $set = array('attribs' => array('host' => $server));
1517          if (is_numeric($port)) {
1518              $set['attribs']['port'] = $port;
1519          }
1520          if (!isset($this->_channelInfo['servers']['mirror'])) {
1521              $this->_channelInfo['servers']['mirror'] = $set;
1522              return true;
1523          } else {
1524              if (!isset($this->_channelInfo['servers']['mirror'][0])) {
1525                  $this->_channelInfo['servers']['mirror'] =
1526                      array($this->_channelInfo['servers']['mirror']);
1527              }
1528          }
1529          $this->_channelInfo['servers']['mirror'][] = $set;
1530          return true;
1531      }
1532  
1533      /**
1534       * Retrieve the name of the validation package for this channel
1535       * @return string|false
1536       */
1537      function getValidationPackage()
1538      {
1539          if (!$this->_isValid && !$this->validate()) {
1540              return false;
1541          }
1542          if (!isset($this->_channelInfo['validatepackage'])) {
1543              return array('attribs' => array('version' => 'default'),
1544                  '_content' => 'PEAR_Validate');
1545          }
1546          return $this->_channelInfo['validatepackage'];
1547      }
1548  
1549      /**
1550       * Retrieve the object that can be used for custom validation
1551       * @param string|false the name of the package to validate.  If the package is
1552       *                     the channel validation package, PEAR_Validate is returned
1553       * @return PEAR_Validate|false false is returned if the validation package
1554       *         cannot be located
1555       */
1556      function &getValidationObject($package = false)
1557      {
1558          if (!class_exists('PEAR_Validate')) {
1559              require_once  'PEAR/Validate.php';
1560          }
1561          if (!$this->_isValid) {
1562              if (!$this->validate()) {
1563                  $a = false;
1564                  return $a;
1565              }
1566          }
1567          if (isset($this->_channelInfo['validatepackage'])) {
1568              if ($package == $this->_channelInfo['validatepackage']) {
1569                  // channel validation packages are always validated by PEAR_Validate
1570                  $val = &new PEAR_Validate;
1571                  return $val;
1572              }
1573              if (!class_exists(str_replace('.', '_',
1574                    $this->_channelInfo['validatepackage']['_content']))) {
1575                  if ($this->isIncludeable(str_replace('_', '/',
1576                        $this->_channelInfo['validatepackage']['_content']) . '.php')) {
1577                      include_once str_replace('_', '/',
1578                          $this->_channelInfo['validatepackage']['_content']) . '.php';
1579                      $vclass = str_replace('.', '_',
1580                          $this->_channelInfo['validatepackage']['_content']);
1581                      $val = &new $vclass;
1582                  } else {
1583                      $a = false;
1584                      return $a;
1585                  }
1586              } else {
1587                  $vclass = str_replace('.', '_',
1588                      $this->_channelInfo['validatepackage']['_content']);
1589                  $val = &new $vclass;
1590              }
1591          } else {
1592              $val = &new PEAR_Validate;
1593          }
1594          return $val;
1595      }
1596  
1597      function isIncludeable($path)
1598      {
1599          $possibilities = explode(PATH_SEPARATOR, ini_get('include_path'));
1600          foreach ($possibilities as $dir) {
1601              if (file_exists($dir . DIRECTORY_SEPARATOR . $path)
1602                    && is_readable($dir . DIRECTORY_SEPARATOR . $path)) {
1603                  return true;
1604              }
1605          }
1606          return false;
1607      }
1608  
1609      /**
1610       * This function is used by the channel updater and retrieves a value set by
1611       * the registry, or the current time if it has not been set
1612       * @return string
1613       */
1614      function lastModified()
1615      {
1616          if (isset($this->_channelInfo['_lastmodified'])) {
1617              return $this->_channelInfo['_lastmodified'];
1618          }
1619          return time();
1620      }
1621  }
1622  ?>


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7