PEAR
[ class tree: PEAR ] [ index: PEAR ] [ all elements ]

Source for file Channels.php

Documentation is available at Channels.php

  1. <?php
  2. // /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. /**
  4.  * PEAR_Command_Channels (list-channels, update-channels, channel-delete, channel-add,
  5.  * channel-update, channel-info, channel-alias, channel-discover commands)
  6.  *
  7.  * PHP versions 4 and 5
  8.  *
  9.  * @category   pear
  10.  * @package    PEAR
  11.  * @author     Stig Bakken <ssb@php.net>
  12.  * @author     Greg Beaver <cellog@php.net>
  13.  * @copyright  1997-2009 The Authors
  14.  * @license    http://opensource.org/licenses/bsd-license.php New BSD License
  15.  * @version    CVS: $Id: Channels.php 313023 2011-07-06 19:17:11Z dufuz $
  16.  * @link       http://pear.php.net/package/PEAR
  17.  * @since      File available since Release 1.4.0a1
  18.  */
  19.  
  20. /**
  21.  * base class
  22.  */
  23. require_once 'PEAR/Command/Common.php';
  24.  
  25. define('PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS'-500);
  26.  
  27. /**
  28.  * PEAR commands for managing channels.
  29.  *
  30.  * @category   pear
  31.  * @package    PEAR
  32.  * @author     Greg Beaver <cellog@php.net>
  33.  * @copyright  1997-2009 The Authors
  34.  * @license    http://opensource.org/licenses/bsd-license.php New BSD License
  35.  * @version    Release: 1.9.4
  36.  * @link       http://pear.php.net/package/PEAR
  37.  * @since      Class available since Release 1.4.0a1
  38.  */
  39. {
  40.     var $commands = array(
  41.         'list-channels' => array(
  42.             'summary' => 'List Available Channels',
  43.             'function' => 'doList',
  44.             'shortcut' => 'lc',
  45.             'options' => array(),
  46.             'doc' => '
  47. List all available channels for installation.
  48. ',
  49.             ),
  50.         'update-channels' => array(
  51.             'summary' => 'Update the Channel List',
  52.             'function' => 'doUpdateAll',
  53.             'shortcut' => 'uc',
  54.             'options' => array(),
  55.             'doc' => '
  56. List all installed packages in all channels.
  57. '
  58.             ),
  59.         'channel-delete' => array(
  60.             'summary' => 'Remove a Channel From the List',
  61.             'function' => 'doDelete',
  62.             'shortcut' => 'cde',
  63.             'options' => array(),
  64.             'doc' => '<channel name>
  65. Delete a channel from the registry.  You may not
  66. remove any channel that has installed packages.
  67. '
  68.             ),
  69.         'channel-add' => array(
  70.             'summary' => 'Add a Channel',
  71.             'function' => 'doAdd',
  72.             'shortcut' => 'ca',
  73.             'options' => array(),
  74.             'doc' => '<channel.xml>
  75. Add a private channel to the channel list.  Note that all
  76. public channels should be synced using "update-channels".
  77. Parameter may be either a local file or remote URL to a
  78. channel.xml.
  79. '
  80.             ),
  81.         'channel-update' => array(
  82.             'summary' => 'Update an Existing Channel',
  83.             'function' => 'doUpdate',
  84.             'shortcut' => 'cu',
  85.             'options' => array(
  86.                 'force' => array(
  87.                     'shortopt' => 'f',
  88.                     'doc' => 'will force download of new channel.xml if an existing channel name is used',
  89.                     ),
  90.                 'channel' => array(
  91.                     'shortopt' => 'c',
  92.                     'arg' => 'CHANNEL',
  93.                     'doc' => 'will force download of new channel.xml if an existing channel name is used',
  94.                     ),
  95. ),
  96.             'doc' => '[<channel.xml>|<channel name>]
  97. Update a channel in the channel list directly.  Note that all
  98. public channels can be synced using "update-channels".
  99. Parameter may be a local or remote channel.xml, or the name of
  100. an existing channel.
  101. '
  102.             ),
  103.         'channel-info' => array(
  104.             'summary' => 'Retrieve Information on a Channel',
  105.             'function' => 'doInfo',
  106.             'shortcut' => 'ci',
  107.             'options' => array(),
  108.             'doc' => '<package>
  109. List the files in an installed package.
  110. '
  111.             ),
  112.         'channel-alias' => array(
  113.             'summary' => 'Specify an alias to a channel name',
  114.             'function' => 'doAlias',
  115.             'shortcut' => 'cha',
  116.             'options' => array(),
  117.             'doc' => '<channel> <alias>
  118. Specify a specific alias to use for a channel name.
  119. The alias may not be an existing channel name or
  120. alias.
  121. '
  122.             ),
  123.         'channel-discover' => array(
  124.             'summary' => 'Initialize a Channel from its server',
  125.             'function' => 'doDiscover',
  126.             'shortcut' => 'di',
  127.             'options' => array(),
  128.             'doc' => '[<channel.xml>|<channel name>]
  129. Initialize a channel from its server and create a local channel.xml.
  130. If <channel name> is in the format "<username>:<password>@<channel>" then
  131. <username> and <password> will be set as the login username/password for
  132. <channel>. Use caution when passing the username/password in this way, as
  133. it may allow other users on your computer to briefly view your username/
  134. password via the system\'s process list.
  135. '
  136.             ),
  137.         'channel-login' => array(
  138.             'summary' => 'Connects and authenticates to remote channel server',
  139.             'shortcut' => 'cli',
  140.             'function' => 'doLogin',
  141.             'options' => array(),
  142.             'doc' => '<channel name>
  143. Log in to a remote channel server.  If <channel name> is not supplied,
  144. the default channel is used. To use remote functions in the installer
  145. that require any kind of privileges, you need to log in first.  The
  146. username and password you enter here will be stored in your per-user
  147. PEAR configuration (~/.pearrc on Unix-like systems).  After logging
  148. in, your username and password will be sent along in subsequent
  149. operations on the remote server.',
  150.             ),
  151.         'channel-logout' => array(
  152.             'summary' => 'Logs out from the remote channel server',
  153.             'shortcut' => 'clo',
  154.             'function' => 'doLogout',
  155.             'options' => array(),
  156.             'doc' => '<channel name>
  157. Logs out from a remote channel server.  If <channel name> is not supplied,
  158. the default channel is used. This command does not actually connect to the
  159. remote server, it only deletes the stored username and password from your user
  160. configuration.',
  161.             ),
  162.         );
  163.  
  164.     /**
  165.      * PEAR_Command_Registry constructor.
  166.      *
  167.      * @access public
  168.      */
  169.     function PEAR_Command_Channels(&$ui&$config)
  170.     {
  171.         parent::PEAR_Command_Common($ui$config);
  172.     }
  173.  
  174.     function _sortChannels($a$b)
  175.     {
  176.         return strnatcasecmp($a->getName()$b->getName());
  177.     }
  178.  
  179.     function doList($command$options$params)
  180.     {
  181.         $reg &$this->config->getRegistry();
  182.         $registered $reg->getChannels();
  183.         usort($registeredarray(&$this'_sortchannels'));
  184.         $i $j = 0;
  185.         $data = array(
  186.             'caption' => 'Registered Channels:',
  187.             'border' => true,
  188.             'headline' => array('Channel''Alias''Summary')
  189.             );
  190.         foreach ($registered as $channel{
  191.             $data['data'][= array($channel->getName(),
  192.                                     $channel->getAlias(),
  193.                                     $channel->getSummary());
  194.         }
  195.  
  196.         if (count($registered=== 0{
  197.             $data '(no registered channels)';
  198.         }
  199.         $this->ui->outputData($data$command);
  200.         return true;
  201.     }
  202.  
  203.     function doUpdateAll($command$options$params)
  204.     {
  205.         $reg &$this->config->getRegistry();
  206.         $channels $reg->getChannels();
  207.  
  208.         $success = true;
  209.         foreach ($channels as $channel{
  210.             if ($channel->getName(!= '__uri'{
  211.                 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  212.                 $err $this->doUpdate('channel-update',
  213.                                           $options,
  214.                                           array($channel->getName()));
  215.                 if (PEAR::isError($err)) {
  216.                     $this->ui->outputData($err->getMessage()$command);
  217.                     $success = false;
  218.                 else {
  219.                     $success &= $err;
  220.                 }
  221.             }
  222.         }
  223.         return $success;
  224.     }
  225.  
  226.     function doInfo($command$options$params)
  227.     {
  228.         if (count($params!== 1{
  229.             return $this->raiseError("No channel specified");
  230.         }
  231.  
  232.         $reg     &$this->config->getRegistry();
  233.         $channel strtolower($params[0]);
  234.         if ($reg->channelExists($channel)) {
  235.             $chan $reg->getChannel($channel);
  236.             if (PEAR::isError($chan)) {
  237.                 return $this->raiseError($chan);
  238.             }
  239.         else {
  240.             if (strpos($channel'://')) {
  241.                 $downloader &$this->getDownloader();
  242.                 $tmpdir $this->config->get('temp_dir');
  243.                 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  244.                 $loc $downloader->downloadHttp($channel$this->ui$tmpdir);
  245.                 PEAR::staticPopErrorHandling();
  246.                 if (PEAR::isError($loc)) {
  247.                     return $this->raiseError('Cannot open "' $channel .
  248.                         '" (' $loc->getMessage(')');
  249.                 else {
  250.                     $contents implode(''file($loc));
  251.                 }
  252.             else {
  253.                 if (!file_exists($params[0])) {
  254.                     return $this->raiseError('Unknown channel "' $channel '"');
  255.                 }
  256.  
  257.                 $fp fopen($params[0]'r');
  258.                 if (!$fp{
  259.                     return $this->raiseError('Cannot open "' $params[0'"');
  260.                 }
  261.  
  262.                 $contents '';
  263.                 while (!feof($fp)) {
  264.                     $contents .= fread($fp1024);
  265.                 }
  266.                 fclose($fp);
  267.             }
  268.  
  269.             if (!class_exists('PEAR_ChannelFile')) {
  270.                 require_once 'PEAR/ChannelFile.php';
  271.             }
  272.  
  273.             $chan = new PEAR_ChannelFile;
  274.             $chan->fromXmlString($contents);
  275.             $chan->validate();
  276.             if ($errs $chan->getErrors(true)) {
  277.                 foreach ($errs as $err{
  278.                     $this->ui->outputData($err['level'': ' $err['message']);
  279.                 }
  280.                 return $this->raiseError('Channel file "' $params[0'" is not valid');
  281.             }
  282.         }
  283.  
  284.         if (!$chan{
  285.             return $this->raiseError('Serious error: Channel "' $params[0.
  286.                 '" has a corrupted registry entry');
  287.         }
  288.  
  289.         $channel $chan->getName();
  290.         $caption 'Channel ' $channel ' Information:';
  291.         $data1 = array(
  292.             'caption' => $caption,
  293.             'border' => true);
  294.         $data1['data']['server'= array('Name and Server'$chan->getName());
  295.         if ($chan->getAlias(!= $chan->getName()) {
  296.             $data1['data']['alias'= array('Alias'$chan->getAlias());
  297.         }
  298.  
  299.         $data1['data']['summary'= array('Summary'$chan->getSummary());
  300.         $validate $chan->getValidationPackage();
  301.         $data1['data']['vpackage'= array('Validation Package Name'$validate['_content']);
  302.         $data1['data']['vpackageversion'=
  303.             array('Validation Package Version'$validate['attribs']['version']);
  304.         $d = array();
  305.         $d['main'$data1;
  306.  
  307.         $data['data'= array();
  308.         $data['caption''Server Capabilities';
  309.         $data['headline'= array('Type''Version/REST type''Function Name/REST base');
  310.         if ($chan->supportsREST()) {
  311.             if ($chan->supportsREST()) {
  312.                 $funcs $chan->getFunctions('rest');
  313.                 if (!isset($funcs[0])) {
  314.                     $funcs = array($funcs);
  315.                 }
  316.                 foreach ($funcs as $protocol{
  317.                     $data['data'][= array('rest'$protocol['attribs']['type'],
  318.                         $protocol['_content']);
  319.                 }
  320.             }
  321.         else {
  322.             $data['data'][= array('No supported protocols');
  323.         }
  324.  
  325.         $d['protocols'$data;
  326.         $data['data'= array();
  327.         $mirrors $chan->getMirrors();
  328.         if ($mirrors{
  329.             $data['caption''Channel ' $channel ' Mirrors:';
  330.             unset($data['headline']);
  331.             foreach ($mirrors as $mirror{
  332.                 $data['data'][= array($mirror['attribs']['host']);
  333.                 $d['mirrors'$data;
  334.             }
  335.  
  336.             foreach ($mirrors as $i => $mirror{
  337.                 $data['data'= array();
  338.                 $data['caption''Mirror ' $mirror['attribs']['host'' Capabilities';
  339.                 $data['headline'= array('Type''Version/REST type''Function Name/REST base');
  340.                 if ($chan->supportsREST($mirror['attribs']['host'])) {
  341.                     if ($chan->supportsREST($mirror['attribs']['host'])) {
  342.                         $funcs $chan->getFunctions('rest'$mirror['attribs']['host']);
  343.                         if (!isset($funcs[0])) {
  344.                             $funcs = array($funcs);
  345.                         }
  346.  
  347.                         foreach ($funcs as $protocol{
  348.                             $data['data'][= array('rest'$protocol['attribs']['type'],
  349.                                 $protocol['_content']);
  350.                         }
  351.                     }
  352.                 else {
  353.                     $data['data'][= array('No supported protocols');
  354.                 }
  355.                 $d['mirrorprotocols' $i$data;
  356.             }
  357.         }
  358.         $this->ui->outputData($d'channel-info');
  359.     }
  360.  
  361.     // }}}
  362.  
  363.     function doDelete($command$options$params)
  364.     {
  365.         if (count($params!== 1{
  366.             return $this->raiseError('channel-delete: no channel specified');
  367.         }
  368.  
  369.         $reg &$this->config->getRegistry();
  370.         if (!$reg->channelExists($params[0])) {
  371.             return $this->raiseError('channel-delete: channel "' $params[0'" does not exist');
  372.         }
  373.  
  374.         $channel $reg->channelName($params[0]);
  375.         if ($channel == 'pear.php.net'{
  376.             return $this->raiseError('Cannot delete the pear.php.net channel');
  377.         }
  378.  
  379.         if ($channel == 'pecl.php.net'{
  380.             return $this->raiseError('Cannot delete the pecl.php.net channel');
  381.         }
  382.  
  383.         if ($channel == 'doc.php.net'{
  384.             return $this->raiseError('Cannot delete the doc.php.net channel');
  385.         }
  386.  
  387.         if ($channel == '__uri'{
  388.             return $this->raiseError('Cannot delete the __uri pseudo-channel');
  389.         }
  390.  
  391.         if (PEAR::isError($err $reg->listPackages($channel))) {
  392.             return $err;
  393.         }
  394.  
  395.         if (count($err)) {
  396.             return $this->raiseError('Channel "' $channel .
  397.                 '" has installed packages, cannot delete');
  398.         }
  399.  
  400.         if (!$reg->deleteChannel($channel)) {
  401.             return $this->raiseError('Channel "' $channel '" deletion failed');
  402.         else {
  403.             $this->config->deleteChannel($channel);
  404.             $this->ui->outputData('Channel "' $channel '" deleted'$command);
  405.         }
  406.     }
  407.  
  408.     function doAdd($command$options$params)
  409.     {
  410.         if (count($params!== 1{
  411.             return $this->raiseError('channel-add: no channel file specified');
  412.         }
  413.  
  414.         if (strpos($params[0]'://')) {
  415.             $downloader &$this->getDownloader();
  416.             $tmpdir $this->config->get('temp_dir');
  417.             if (!file_exists($tmpdir)) {
  418.                 require_once 'System.php';
  419.                 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  420.                 $err System::mkdir(array('-p'$tmpdir));
  421.                 PEAR::staticPopErrorHandling();
  422.                 if (PEAR::isError($err)) {
  423.                     return $this->raiseError('channel-add: temp_dir does not exist: "' .
  424.                         $tmpdir .
  425.                         '" - You can change this location with "pear config-set temp_dir"');
  426.                 }
  427.             }
  428.  
  429.             if (!is_writable($tmpdir)) {
  430.                 return $this->raiseError('channel-add: temp_dir is not writable: "' .
  431.                     $tmpdir .
  432.                     '" - You can change this location with "pear config-set temp_dir"');
  433.             }
  434.  
  435.             $loc $downloader->downloadHttp($params[0]$this->ui$tmpdirnullfalse);
  436.             PEAR::staticPopErrorHandling();
  437.             if (PEAR::isError($loc)) {
  438.                 return $this->raiseError('channel-add: Cannot open "' $params[0.
  439.                     '" (' $loc->getMessage(')');
  440.             }
  441.  
  442.             list($loc$lastmodified$loc;
  443.             $contents implode(''file($loc));
  444.         else {
  445.             $lastmodified $fp = false;
  446.             if (file_exists($params[0])) {
  447.                 $fp fopen($params[0]'r');
  448.             }
  449.  
  450.             if (!$fp{
  451.                 return $this->raiseError('channel-add: cannot open "' $params[0'"');
  452.             }
  453.  
  454.             $contents '';
  455.             while (!feof($fp)) {
  456.                 $contents .= fread($fp1024);
  457.             }
  458.             fclose($fp);
  459.         }
  460.  
  461.         if (!class_exists('PEAR_ChannelFile')) {
  462.             require_once 'PEAR/ChannelFile.php';
  463.         }
  464.  
  465.         $channel = new PEAR_ChannelFile;
  466.         $result $channel->fromXmlString($contents);
  467.         PEAR::staticPopErrorHandling();
  468.         if (!$result{
  469.             $exit = false;
  470.             if (count($errors $channel->getErrors(true))) {
  471.                 foreach ($errors as $error{
  472.                     $this->ui->outputData(ucfirst($error['level'': ' $error['message']));
  473.                     if (!$exit{
  474.                         $exit $error['level'== 'error' ? true : false;
  475.                     }
  476.                 }
  477.                 if ($exit{
  478.                     return $this->raiseError('channel-add: invalid channel.xml file');
  479.                 }
  480.             }
  481.         }
  482.  
  483.         $reg &$this->config->getRegistry();
  484.         if ($reg->channelExists($channel->getName())) {
  485.             return $this->raiseError('channel-add: Channel "' $channel->getName(.
  486.                 '" exists, use channel-update to update entry'PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS);
  487.         }
  488.  
  489.         $ret $reg->addChannel($channel$lastmodified);
  490.         if (PEAR::isError($ret)) {
  491.             return $ret;
  492.         }
  493.  
  494.         if (!$ret{
  495.             return $this->raiseError('channel-add: adding Channel "' $channel->getName(.
  496.                 '" to registry failed');
  497.         }
  498.  
  499.         $this->config->setChannels($reg->listChannels());
  500.         $this->config->writeConfigFile();
  501.         $this->ui->outputData('Adding Channel "' $channel->getName('" succeeded'$command);
  502.     }
  503.  
  504.     function doUpdate($command$options$params)
  505.     {
  506.         if (count($params!== 1{
  507.             return $this->raiseError("No channel file specified");
  508.         }
  509.  
  510.         $tmpdir $this->config->get('temp_dir');
  511.         if (!file_exists($tmpdir)) {
  512.             require_once 'System.php';
  513.             $err System::mkdir(array('-p'$tmpdir));
  514.             PEAR::staticPopErrorHandling();
  515.             if (PEAR::isError($err)) {
  516.                 return $this->raiseError('channel-add: temp_dir does not exist: "' .
  517.                     $tmpdir .
  518.                     '" - You can change this location with "pear config-set temp_dir"');
  519.             }
  520.         }
  521.  
  522.         if (!is_writable($tmpdir)) {
  523.             return $this->raiseError('channel-add: temp_dir is not writable: "' .
  524.                 $tmpdir .
  525.                 '" - You can change this location with "pear config-set temp_dir"');
  526.         }
  527.  
  528.         $reg &$this->config->getRegistry();
  529.         $lastmodified = false;
  530.         if ((!file_exists($params[0]|| is_dir($params[0]))
  531.               && $reg->channelExists(strtolower($params[0]))) {
  532.             $c $reg->getChannel(strtolower($params[0]));
  533.             if (PEAR::isError($c)) {
  534.                 return $this->raiseError($c);
  535.             }
  536.  
  537.             $this->ui->outputData("Updating channel \"$params[0]\""$command);
  538.             $dl &$this->getDownloader(array());
  539.             // if force is specified, use a timestamp of "1" to force retrieval
  540.             $lastmodified = isset($options['force']? false : $c->lastModified();
  541.             $contents $dl->downloadHttp('http://' $c->getName('/channel.xml',
  542.                 $this->ui$tmpdirnull$lastmodified);
  543.             PEAR::staticPopErrorHandling();
  544.             if (PEAR::isError($contents)) {
  545.                 // Attempt to fall back to https
  546.                 $this->ui->outputData("Channel \"$params[0]\" is not responding over http://, failed with message: " . $contents->getMessage());
  547.                 $this->ui->outputData("Trying channel \"$params[0]\" over https:// instead");
  548.                 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  549.                 $contents $dl->downloadHttp('https://' $c->getName('/channel.xml',
  550.                     $this->ui$tmpdirnull$lastmodified);
  551.                 PEAR::staticPopErrorHandling();
  552.                 if (PEAR::isError($contents)) {
  553.                     return $this->raiseError('Cannot retrieve channel.xml for channel "' .
  554.                         $c->getName('" (' $contents->getMessage(')');
  555.                 }
  556.             }
  557.  
  558.             list($contents$lastmodified$contents;
  559.             if (!$contents{
  560.                 $this->ui->outputData("Channel \"$params[0]\" is up to date");
  561.                 return;
  562.             }
  563.  
  564.             $contents implode(''file($contents));
  565.             if (!class_exists('PEAR_ChannelFile')) {
  566.                 require_once 'PEAR/ChannelFile.php';
  567.             }
  568.  
  569.             $channel = new PEAR_ChannelFile;
  570.             $channel->fromXmlString($contents);
  571.             if (!$channel->getErrors()) {
  572.                 // security check: is the downloaded file for the channel we got it from?
  573.                 if (strtolower($channel->getName()) != strtolower($c->getName())) {
  574.                     if (!isset($options['force'])) {
  575.                         return $this->raiseError('ERROR: downloaded channel definition file' .
  576.                             ' for channel "' $channel->getName('" from channel "' .
  577.                             strtolower($c->getName()) '"');
  578.                     }
  579.  
  580.                     $this->ui->log(0'WARNING: downloaded channel definition file' .
  581.                         ' for channel "' $channel->getName('" from channel "' .
  582.                         strtolower($c->getName()) '"');
  583.                 }
  584.             }
  585.         else {
  586.             if (strpos($params[0]'://')) {
  587.                 $dl &$this->getDownloader();
  588.                 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  589.                 $loc $dl->downloadHttp($params[0],
  590.                     $this->ui$tmpdirnull$lastmodified);
  591.                 PEAR::staticPopErrorHandling();
  592.                 if (PEAR::isError($loc)) {
  593.                     return $this->raiseError("Cannot open " $params[0.
  594.                          ' (' $loc->getMessage(')');
  595.                 }
  596.  
  597.                 list($loc$lastmodified$loc;
  598.                 $contents implode(''file($loc));
  599.             else {
  600.                 $fp = false;
  601.                 if (file_exists($params[0])) {
  602.                     $fp fopen($params[0]'r');
  603.                 }
  604.  
  605.                 if (!$fp{
  606.                     return $this->raiseError("Cannot open " $params[0]);
  607.                 }
  608.  
  609.                 $contents '';
  610.                 while (!feof($fp)) {
  611.                     $contents .= fread($fp1024);
  612.                 }
  613.                 fclose($fp);
  614.             }
  615.  
  616.             if (!class_exists('PEAR_ChannelFile')) {
  617.                 require_once 'PEAR/ChannelFile.php';
  618.             }
  619.  
  620.             $channel = new PEAR_ChannelFile;
  621.             $channel->fromXmlString($contents);
  622.         }
  623.  
  624.         $exit = false;
  625.         if (count($errors $channel->getErrors(true))) {
  626.             foreach ($errors as $error{
  627.                 $this->ui->outputData(ucfirst($error['level'': ' $error['message']));
  628.                 if (!$exit{
  629.                     $exit $error['level'== 'error' ? true : false;
  630.                 }
  631.             }
  632.             if ($exit{
  633.                 return $this->raiseError('Invalid channel.xml file');
  634.             }
  635.         }
  636.  
  637.         if (!$reg->channelExists($channel->getName())) {
  638.             return $this->raiseError('Error: Channel "' $channel->getName(.
  639.                 '" does not exist, use channel-add to add an entry');
  640.         }
  641.  
  642.         $ret $reg->updateChannel($channel$lastmodified);
  643.         if (PEAR::isError($ret)) {
  644.             return $ret;
  645.         }
  646.  
  647.         if (!$ret{
  648.             return $this->raiseError('Updating Channel "' $channel->getName(.
  649.                 '" in registry failed');
  650.         }
  651.  
  652.         $this->config->setChannels($reg->listChannels());
  653.         $this->config->writeConfigFile();
  654.         $this->ui->outputData('Update of Channel "' $channel->getName('" succeeded');
  655.     }
  656.  
  657.     function &getDownloader()
  658.     {
  659.         if (!class_exists('PEAR_Downloader')) {
  660.             require_once 'PEAR/Downloader.php';
  661.         }
  662.         $a = new PEAR_Downloader($this->uiarray()$this->config);
  663.         return $a;
  664.     }
  665.  
  666.     function doAlias($command$options$params)
  667.     {
  668.         if (count($params=== 1{
  669.             return $this->raiseError('No channel alias specified');
  670.         }
  671.  
  672.         if (count($params!== 2 || (!empty($params[1]&& $params[1]{0== '-')) {
  673.             return $this->raiseError(
  674.                 'Invalid format, correct is: channel-alias channel alias');
  675.         }
  676.  
  677.         $reg &$this->config->getRegistry();
  678.         if (!$reg->channelExists($params[0]true)) {
  679.             $extra '';
  680.             if ($reg->isAlias($params[0])) {
  681.                 $extra ' (use "channel-alias ' $reg->channelName($params[0]' ' .
  682.                     strtolower($params[1]'")';
  683.             }
  684.  
  685.             return $this->raiseError('"' $params[0'" is not a valid channel' $extra);
  686.         }
  687.  
  688.         if ($reg->isAlias($params[1])) {
  689.             return $this->raiseError('Channel "' $reg->channelName($params[1]'" is ' .
  690.                 'already aliased to "' strtolower($params[1]'", cannot re-alias');
  691.         }
  692.  
  693.         $chan &$reg->getChannel($params[0]);
  694.         if (PEAR::isError($chan)) {
  695.             return $this->raiseError('Corrupt registry?  Error retrieving channel "' $params[0.
  696.                 '" information (' $chan->getMessage(')');
  697.         }
  698.  
  699.         // make it a local alias
  700.         if (!$chan->setAlias(strtolower($params[1])true)) {
  701.             return $this->raiseError('Alias "' strtolower($params[1].
  702.                 '" is not a valid channel alias');
  703.         }
  704.  
  705.         $reg->updateChannel($chan);
  706.         $this->ui->outputData('Channel "' $chan->getName('" aliased successfully to "' .
  707.             strtolower($params[1]'"');
  708.     }
  709.  
  710.     /**
  711.      * The channel-discover command
  712.      *
  713.      * @param string $command command name
  714.      * @param array  $options option_name => value
  715.      * @param array  $params  list of additional parameters.
  716.      *                $params[0] should contain a string with either:
  717.      *                - <channel name> or
  718.      *                - <username>:<password>@<channel name>
  719.      * @return null|PEAR_Error
  720.      */
  721.     function doDiscover($command$options$params)
  722.     {
  723.         if (count($params!== 1{
  724.             return $this->raiseError("No channel server specified");
  725.         }
  726.  
  727.         // Look for the possible input format "<username>:<password>@<channel>"
  728.         if (preg_match('/^(.+):(.+)@(.+)\\z/'$params[0]$matches)) {
  729.             $username $matches[1];
  730.             $password $matches[2];
  731.             $channel  $matches[3];
  732.         else {
  733.             $channel $params[0];
  734.         }
  735.  
  736.         $reg &$this->config->getRegistry();
  737.         if ($reg->channelExists($channel)) {
  738.             if (!$reg->isAlias($channel)) {
  739.                 return $this->raiseError("Channel \"$channel\" is already initialized"PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS);
  740.             }
  741.  
  742.             return $this->raiseError("A channel alias named \"$channel\" " .
  743.                 'already exists, aliasing channel "' $reg->channelName($channel)
  744.                 . '"');
  745.         }
  746.  
  747.         $this->pushErrorHandling(PEAR_ERROR_RETURN);
  748.         $err $this->doAdd($command$optionsarray('http://' $channel '/channel.xml'));
  749.         $this->popErrorHandling();
  750.         if (PEAR::isError($err)) {
  751.             if ($err->getCode(=== PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS{
  752.                 return $this->raiseError("Discovery of channel \"$channel\" failed (" .
  753.                     $err->getMessage(')');
  754.             }
  755.             // Attempt fetch via https
  756.             $this->ui->outputData("Discovering channel $channel over http:// failed with message: " . $err->getMessage());
  757.             $this->ui->outputData("Trying to discover channel $channel over https:// instead");
  758.             $this->pushErrorHandling(PEAR_ERROR_RETURN);
  759.             $err $this->doAdd($command$optionsarray('https://' $channel '/channel.xml'));
  760.             $this->popErrorHandling();
  761.             if (PEAR::isError($err)) {
  762.                 return $this->raiseError("Discovery of channel \"$channel\" failed (" .
  763.                     $err->getMessage(')');
  764.             }
  765.         }
  766.  
  767.         // Store username/password if they were given
  768.         // Arguably we should do a logintest on the channel here, but since
  769.         // that's awkward on a REST-based channel (even "pear login" doesn't
  770.         // do it for those), and XML-RPC is deprecated, it's fairly pointless.
  771.         if (isset($username)) {
  772.             $this->config->set('username'$username'user'$channel);
  773.             $this->config->set('password'$password'user'$channel);
  774.             $this->config->store();
  775.             $this->ui->outputData("Stored login for channel \"$channel\" using username \"$username\""$command);
  776.         }
  777.  
  778.         $this->ui->outputData("Discovery of channel \"$channel\" succeeded"$command);
  779.     }
  780.  
  781.     /**
  782.      * Execute the 'login' command.
  783.      *
  784.      * @param string $command command name
  785.      * @param array $options option_name => value
  786.      * @param array $params list of additional parameters
  787.      *
  788.      * @return bool TRUE on success or
  789.      *  a PEAR error on failure
  790.      *
  791.      * @access public
  792.      */
  793.     function doLogin($command$options$params)
  794.     {
  795.         $reg &$this->config->getRegistry();
  796.  
  797.         // If a parameter is supplied, use that as the channel to log in to
  798.         $channel = isset($params[0]$params[0$this->config->get('default_channel');
  799.  
  800.         $chan $reg->getChannel($channel);
  801.         if (PEAR::isError($chan)) {
  802.             return $this->raiseError($chan);
  803.         }
  804.  
  805.         $server   $this->config->get('preferred_mirror'null$channel);
  806.         $username $this->config->get('username',         null$channel);
  807.         if (empty($username)) {
  808.             $username = isset($_ENV['USER']$_ENV['USER': null;
  809.         }
  810.         $this->ui->outputData("Logging in to $server."$command);
  811.  
  812.         list($username$password$this->ui->userDialog(
  813.             $command,
  814.             array('Username''Password'),
  815.             array('text',     'password'),
  816.             array($username,  '')
  817.             );
  818.         $username trim($username);
  819.         $password trim($password);
  820.  
  821.         $ourfile $this->config->getConfFile('user');
  822.         if (!$ourfile{
  823.             $ourfile $this->config->getConfFile('system');
  824.         }
  825.  
  826.         $this->config->set('username'$username'user'$channel);
  827.         $this->config->set('password'$password'user'$channel);
  828.  
  829.         if ($chan->supportsREST()) {
  830.             $ok = true;
  831.         }
  832.  
  833.         if ($ok !== true{
  834.             return $this->raiseError('Login failed!');
  835.         }
  836.  
  837.         $this->ui->outputData("Logged in."$command);
  838.         // avoid changing any temporary settings changed with -d
  839.         $ourconfig = new PEAR_Config($ourfile$ourfile);
  840.         $ourconfig->set('username'$username'user'$channel);
  841.         $ourconfig->set('password'$password'user'$channel);
  842.         $ourconfig->store();
  843.  
  844.         return true;
  845.     }
  846.  
  847.     /**
  848.      * Execute the 'logout' command.
  849.      *
  850.      * @param string $command command name
  851.      * @param array $options option_name => value
  852.      * @param array $params list of additional parameters
  853.      *
  854.      * @return bool TRUE on success or
  855.      *  a PEAR error on failure
  856.      *
  857.      * @access public
  858.      */
  859.     function doLogout($command$options$params)
  860.     {
  861.         $reg     &$this->config->getRegistry();
  862.  
  863.         // If a parameter is supplied, use that as the channel to log in to
  864.         $channel = isset($params[0]$params[0$this->config->get('default_channel');
  865.  
  866.         $chan    $reg->getChannel($channel);
  867.         if (PEAR::isError($chan)) {
  868.             return $this->raiseError($chan);
  869.         }
  870.  
  871.         $server $this->config->get('preferred_mirror'null$channel);
  872.         $this->ui->outputData("Logging out from $server."$command);
  873.         $this->config->remove('username''user'$channel);
  874.         $this->config->remove('password''user'$channel);
  875.         $this->config->store();
  876.         return true;
  877.     }
  878. }

Documentation generated on Wed, 06 Jul 2011 23:30:31 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.