Subversion Repositories Applications.gtt

Rev

Rev 94 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 94 Rev 187
1
<?php
1
<?php
2
/**
2
/**
3
 * PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download,
3
 * PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download,
4
 * clear-cache commands)
4
 * clear-cache commands)
5
 *
5
 *
6
 * PHP versions 4 and 5
6
 * PHP versions 4 and 5
7
 *
7
 *
8
 * LICENSE: This source file is subject to version 3.0 of the PHP license
-
 
9
 * that is available through the world-wide-web at the following URI:
-
 
10
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
-
 
11
 * the PHP License and are unable to obtain it through the web, please
-
 
12
 * send a note to license@php.net so we can mail you a copy immediately.
-
 
13
 *
-
 
14
 * @category   pear
8
 * @category   pear
15
 * @package    PEAR
9
 * @package    PEAR
16
 * @author     Stig Bakken <ssb@php.net>
10
 * @author     Stig Bakken <ssb@php.net>
17
 * @author     Greg Beaver <cellog@php.net>
11
 * @author     Greg Beaver <cellog@php.net>
18
 * @copyright  1997-2006 The PHP Group
12
 * @copyright  1997-2009 The Authors
19
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
13
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
20
 * @version    CVS: $Id: Remote.php,v 1.96 2006/09/24 03:08:57 cellog Exp $
-
 
21
 * @link       http://pear.php.net/package/PEAR
14
 * @link       http://pear.php.net/package/PEAR
22
 * @since      File available since Release 0.1
15
 * @since      File available since Release 0.1
23
 */
16
 */
24
 
17
 
25
/**
18
/**
26
 * base class
19
 * base class
27
 */
20
 */
28
require_once 'PEAR/Command/Common.php';
21
require_once 'PEAR/Command/Common.php';
29
require_once 'PEAR/REST.php';
22
require_once 'PEAR/REST.php';
30
 
23
 
31
/**
24
/**
32
 * PEAR commands for remote server querying
25
 * PEAR commands for remote server querying
33
 *
26
 *
34
 * @category   pear
27
 * @category   pear
35
 * @package    PEAR
28
 * @package    PEAR
36
 * @author     Stig Bakken <ssb@php.net>
29
 * @author     Stig Bakken <ssb@php.net>
37
 * @author     Greg Beaver <cellog@php.net>
30
 * @author     Greg Beaver <cellog@php.net>
38
 * @copyright  1997-2006 The PHP Group
31
 * @copyright  1997-2009 The Authors
39
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
32
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
40
 * @version    Release: 1.5.1
33
 * @version    Release: 1.10.1
41
 * @link       http://pear.php.net/package/PEAR
34
 * @link       http://pear.php.net/package/PEAR
42
 * @since      Class available since Release 0.1
35
 * @since      Class available since Release 0.1
43
 */
36
 */
44
class PEAR_Command_Remote extends PEAR_Command_Common
37
class PEAR_Command_Remote extends PEAR_Command_Common
45
{
38
{
46
    // {{{ command definitions
-
 
47
 
-
 
48
    var $commands = array(
39
    var $commands = array(
49
        'remote-info' => array(
40
        'remote-info' => array(
50
            'summary' => 'Information About Remote Packages',
41
            'summary' => 'Information About Remote Packages',
51
            'function' => 'doRemoteInfo',
42
            'function' => 'doRemoteInfo',
52
            'shortcut' => 'ri',
43
            'shortcut' => 'ri',
53
            'options' => array(),
44
            'options' => array(),
54
            'doc' => '<package>
45
            'doc' => '<package>
55
Get details on a package from the server.',
46
Get details on a package from the server.',
56
            ),
47
            ),
57
        'list-upgrades' => array(
48
        'list-upgrades' => array(
58
            'summary' => 'List Available Upgrades',
49
            'summary' => 'List Available Upgrades',
59
            'function' => 'doListUpgrades',
50
            'function' => 'doListUpgrades',
60
            'shortcut' => 'lu',
51
            'shortcut' => 'lu',
61
            'options' => array(),
52
            'options' => array(
-
 
53
                'channelinfo' => array(
-
 
54
                    'shortopt' => 'i',
-
 
55
                    'doc' => 'output fully channel-aware data, even on failure',
-
 
56
                    ),
-
 
57
            ),
62
            'doc' => '[preferred_state]
58
            'doc' => '[preferred_state]
63
List releases on the server of packages you have installed where
59
List releases on the server of packages you have installed where
64
a newer version is available with the same release state (stable etc.)
60
a newer version is available with the same release state (stable etc.)
65
or the state passed as the second parameter.'
61
or the state passed as the second parameter.'
66
            ),
62
            ),
67
        'remote-list' => array(
63
        'remote-list' => array(
68
            'summary' => 'List Remote Packages',
64
            'summary' => 'List Remote Packages',
69
            'function' => 'doRemoteList',
65
            'function' => 'doRemoteList',
70
            'shortcut' => 'rl',
66
            'shortcut' => 'rl',
71
            'options' => array(
67
            'options' => array(
72
                'channel' =>
68
                'channel' =>
73
                    array(
69
                    array(
74
                    'shortopt' => 'c',
70
                    'shortopt' => 'c',
75
                    'doc' => 'specify a channel other than the default channel',
71
                    'doc' => 'specify a channel other than the default channel',
76
                    'arg' => 'CHAN',
72
                    'arg' => 'CHAN',
77
                    )
73
                    )
78
                ),
74
                ),
79
            'doc' => '
75
            'doc' => '
80
Lists the packages available on the configured server along with the
76
Lists the packages available on the configured server along with the
81
latest stable release of each package.',
77
latest stable release of each package.',
82
            ),
78
            ),
83
        'search' => array(
79
        'search' => array(
84
            'summary' => 'Search remote package database',
80
            'summary' => 'Search remote package database',
85
            'function' => 'doSearch',
81
            'function' => 'doSearch',
86
            'shortcut' => 'sp',
82
            'shortcut' => 'sp',
87
            'options' => array(
83
            'options' => array(
88
                'channel' =>
84
                'channel' =>
89
                    array(
85
                    array(
90
                    'shortopt' => 'c',
86
                    'shortopt' => 'c',
91
                    'doc' => 'specify a channel other than the default channel',
87
                    'doc' => 'specify a channel other than the default channel',
92
                    'arg' => 'CHAN',
88
                    'arg' => 'CHAN',
93
                    )
89
                    ),
-
 
90
                'allchannels' => array(
-
 
91
                    'shortopt' => 'a',
-
 
92
                    'doc' => 'search packages from all known channels',
-
 
93
                    ),
-
 
94
                'channelinfo' => array(
-
 
95
                    'shortopt' => 'i',
-
 
96
                    'doc' => 'output fully channel-aware data, even on failure',
-
 
97
                    ),
94
                ),
98
                ),
95
            'doc' => '[packagename] [packageinfo]
99
            'doc' => '[packagename] [packageinfo]
96
Lists all packages which match the search parameters.  The first
100
Lists all packages which match the search parameters.  The first
97
parameter is a fragment of a packagename.  The default channel
101
parameter is a fragment of a packagename.  The default channel
98
will be used unless explicitly overridden.  The second parameter
102
will be used unless explicitly overridden.  The second parameter
99
will be used to match any portion of the summary/description',
103
will be used to match any portion of the summary/description',
100
            ),
104
            ),
101
        'list-all' => array(
105
        'list-all' => array(
102
            'summary' => 'List All Packages',
106
            'summary' => 'List All Packages',
103
            'function' => 'doListAll',
107
            'function' => 'doListAll',
104
            'shortcut' => 'la',
108
            'shortcut' => 'la',
105
            'options' => array(
109
            'options' => array(
106
                'channel' =>
110
                'channel' =>
107
                    array(
111
                    array(
108
                    'shortopt' => 'c',
112
                    'shortopt' => 'c',
109
                    'doc' => 'specify a channel other than the default channel',
113
                    'doc' => 'specify a channel other than the default channel',
110
                    'arg' => 'CHAN',
114
                    'arg' => 'CHAN',
111
                    )
115
                    ),
-
 
116
                'channelinfo' => array(
-
 
117
                    'shortopt' => 'i',
-
 
118
                    'doc' => 'output fully channel-aware data, even on failure',
-
 
119
                    ),
112
                ),
120
                ),
113
            'doc' => '
121
            'doc' => '
114
Lists the packages available on the configured server along with the
122
Lists the packages available on the configured server along with the
115
latest stable release of each package.',
123
latest stable release of each package.',
116
            ),
124
            ),
117
        'download' => array(
125
        'download' => array(
118
            'summary' => 'Download Package',
126
            'summary' => 'Download Package',
119
            'function' => 'doDownload',
127
            'function' => 'doDownload',
120
            'shortcut' => 'd',
128
            'shortcut' => 'd',
121
            'options' => array(
129
            'options' => array(
122
                'nocompress' => array(
130
                'nocompress' => array(
123
                    'shortopt' => 'Z',
131
                    'shortopt' => 'Z',
124
                    'doc' => 'download an uncompressed (.tar) file',
132
                    'doc' => 'download an uncompressed (.tar) file',
125
                    ),
133
                    ),
126
                ),
134
                ),
127
            'doc' => '<package>...
135
            'doc' => '<package>...
128
Download package tarballs.  The files will be named as suggested by the
136
Download package tarballs.  The files will be named as suggested by the
129
server, for example if you download the DB package and the latest stable
137
server, for example if you download the DB package and the latest stable
130
version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.',
138
version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.',
131
            ),
139
            ),
132
        'clear-cache' => array(
140
        'clear-cache' => array(
133
            'summary' => 'Clear Web Services Cache',
141
            'summary' => 'Clear Web Services Cache',
134
            'function' => 'doClearCache',
142
            'function' => 'doClearCache',
135
            'shortcut' => 'cc',
143
            'shortcut' => 'cc',
136
            'options' => array(),
144
            'options' => array(),
137
            'doc' => '
145
            'doc' => '
138
Clear the XML-RPC/REST cache.  See also the cache_ttl configuration
146
Clear the REST cache. See also the cache_ttl configuration
139
parameter.
147
parameter.
140
',
148
',
141
            ),
149
            ),
142
        );
150
        );
143
 
-
 
144
    // }}}
-
 
145
    // {{{ constructor
-
 
146
 
151
 
147
    /**
152
    /**
148
     * PEAR_Command_Remote constructor.
153
     * PEAR_Command_Remote constructor.
149
     *
154
     *
150
     * @access public
155
     * @access public
151
     */
156
     */
152
    function PEAR_Command_Remote(&$ui, &$config)
157
    function __construct(&$ui, &$config)
153
    {
158
    {
154
        parent::PEAR_Command_Common($ui, $config);
159
        parent::__construct($ui, $config);
155
    }
160
    }
156
 
-
 
157
    // }}}
-
 
158
 
161
 
159
    function _checkChannelForStatus($channel, $chan)
162
    function _checkChannelForStatus($channel, $chan)
160
    {
163
    {
161
        if (PEAR::isError($chan)) {
164
        if (PEAR::isError($chan)) {
162
            $this->raiseError($chan);
165
            $this->raiseError($chan);
163
        }
166
        }
164
        if (!is_a($chan, 'PEAR_ChannelFile')) {
167
        if (!is_a($chan, 'PEAR_ChannelFile')) {
165
            return $this->raiseError('Internal corruption error: invalid channel "' .
168
            return $this->raiseError('Internal corruption error: invalid channel "' .
166
                $channel . '"');
169
                $channel . '"');
167
        }
170
        }
168
        $rest = new PEAR_REST($this->config);
171
        $rest = new PEAR_REST($this->config);
169
        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
172
        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
-
 
173
        $mirror = $this->config->get('preferred_mirror', null,
-
 
174
                                     $channel);
170
        $a = $rest->downloadHttp('http://' . $channel .
175
        $a = $rest->downloadHttp('http://' . $channel .
171
            '/channel.xml', $chan->lastModified());
176
            '/channel.xml', $chan->lastModified());
172
        PEAR::staticPopErrorHandling();
177
        PEAR::staticPopErrorHandling();
173
        if (!PEAR::isError($a) && $a) {
178
        if (!PEAR::isError($a) && $a) {
174
            $this->ui->outputData('WARNING: channel "' . $channel . '" has ' .
179
            $this->ui->outputData('WARNING: channel "' . $channel . '" has ' .
175
                'updated its protocols, use "channel-update ' . $channel .
180
                'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $channel .
176
                '" to update');
181
                '" to update');
177
        }
182
        }
178
    }
183
    }
179
 
-
 
180
    // {{{ doRemoteInfo()
-
 
181
 
184
 
182
    function doRemoteInfo($command, $options, $params)
185
    function doRemoteInfo($command, $options, $params)
183
    {
186
    {
184
        if (sizeof($params) != 1) {
187
        if (sizeof($params) != 1) {
185
            return $this->raiseError("$command expects one param: the remote package name");
188
            return $this->raiseError("$command expects one param: the remote package name");
186
        }
189
        }
187
        $savechannel = $channel = $this->config->get('default_channel');
190
        $savechannel = $channel = $this->config->get('default_channel');
188
        $reg = &$this->config->getRegistry();
191
        $reg = &$this->config->getRegistry();
189
        $package = $params[0];
192
        $package = $params[0];
190
        $parsed = $reg->parsePackageName($package, $channel);
193
        $parsed = $reg->parsePackageName($package, $channel);
191
        if (PEAR::isError($parsed)) {
194
        if (PEAR::isError($parsed)) {
192
            return $this->raiseError('Invalid package name "' . $package . '"');
195
            return $this->raiseError('Invalid package name "' . $package . '"');
193
        }
196
        }
194
        
197
 
195
        $channel = $parsed['channel'];
198
        $channel = $parsed['channel'];
196
        $this->config->set('default_channel', $channel);
199
        $this->config->set('default_channel', $channel);
197
        $chan = $reg->getChannel($channel);
200
        $chan = $reg->getChannel($channel);
198
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
201
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
199
            return $e;
202
            return $e;
200
        }
203
        }
-
 
204
 
201
        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
205
        $mirror = $this->config->get('preferred_mirror');
202
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
206
        if ($chan->supportsREST($mirror) && $base = $chan->getBaseURL('REST1.0', $mirror)) {
203
            $rest = &$this->config->getREST('1.0', array());
207
            $rest = &$this->config->getREST('1.0', array());
204
            $info = $rest->packageInfo($base, $parsed['package']);
208
            $info = $rest->packageInfo($base, $parsed['package'], $channel);
205
        } else {
209
        }
-
 
210
 
206
            $r = &$this->config->getRemote();
211
        if (!isset($info)) {
207
            $info = $r->call('package.info', $parsed['package']);
212
            return $this->raiseError('No supported protocol was found');
208
        }
213
        }
-
 
214
 
209
        if (PEAR::isError($info)) {
215
        if (PEAR::isError($info)) {
210
            $this->config->set('default_channel', $savechannel);
216
            $this->config->set('default_channel', $savechannel);
211
            return $this->raiseError($info);
217
            return $this->raiseError($info);
212
        }
218
        }
-
 
219
 
213
        if (!isset($info['name'])) {
220
        if (!isset($info['name'])) {
214
            return $this->raiseError('No remote package "' . $package . '" was found');
221
            return $this->raiseError('No remote package "' . $package . '" was found');
215
        }
222
        }
216
 
223
 
217
        $installed = $reg->packageInfo($info['name'], null, $channel);
224
        $installed = $reg->packageInfo($info['name'], null, $channel);
218
        $info['installed'] = $installed['version'] ? $installed['version'] : '- no -';
225
        $info['installed'] = $installed['version'] ? $installed['version'] : '- no -';
219
        if (is_array($info['installed'])) {
226
        if (is_array($info['installed'])) {
220
            $info['installed'] = $info['installed']['release'];
227
            $info['installed'] = $info['installed']['release'];
221
        }
228
        }
222
 
229
 
223
        $this->ui->outputData($info, $command);
230
        $this->ui->outputData($info, $command);
224
        $this->config->set('default_channel', $savechannel);
231
        $this->config->set('default_channel', $savechannel);
225
 
232
 
226
        return true;
233
        return true;
227
    }
234
    }
228
 
-
 
229
    // }}}
-
 
230
    // {{{ doRemoteList()
-
 
231
 
235
 
232
    function doRemoteList($command, $options, $params)
236
    function doRemoteList($command, $options, $params)
233
    {
237
    {
234
        $savechannel = $channel = $this->config->get('default_channel');
238
        $savechannel = $channel = $this->config->get('default_channel');
235
        $reg = &$this->config->getRegistry();
239
        $reg = &$this->config->getRegistry();
236
        if (isset($options['channel'])) {
240
        if (isset($options['channel'])) {
237
            $channel = $options['channel'];
241
            $channel = $options['channel'];
238
            if ($reg->channelExists($channel)) {
242
            if (!$reg->channelExists($channel)) {
239
                $this->config->set('default_channel', $channel);
-
 
240
            } else {
-
 
241
                return $this->raiseError('Channel "' . $channel . '" does not exist');
243
                return $this->raiseError('Channel "' . $channel . '" does not exist');
242
            }
244
            }
-
 
245
 
-
 
246
            $this->config->set('default_channel', $channel);
243
        }
247
        }
-
 
248
 
244
        $chan = $reg->getChannel($channel);
249
        $chan = $reg->getChannel($channel);
245
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
250
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
246
            return $e;
251
            return $e;
247
        }
252
        }
-
 
253
 
248
        $list_options = false;
254
        $list_options = false;
249
        if ($this->config->get('preferred_state') == 'stable') {
255
        if ($this->config->get('preferred_state') == 'stable') {
250
            $list_options = true;
256
            $list_options = true;
251
        }
257
        }
-
 
258
 
-
 
259
        $available = array();
252
        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
260
        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
253
              $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
261
              $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))
-
 
262
        ) {
254
            // use faster list-all if available
263
            // use faster list-all if available
255
            $rest = &$this->config->getREST('1.1', array());
264
            $rest = &$this->config->getREST('1.1', array());
256
            $available = $rest->listAll($base, $list_options);
265
            $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName());
257
        } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
266
        } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
258
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
267
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
259
            $rest = &$this->config->getREST('1.0', array());
268
            $rest = &$this->config->getREST('1.0', array());
260
            $available = $rest->listAll($base, $list_options);
269
            $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName());
261
        } else {
-
 
262
            $r = &$this->config->getRemote();
-
 
263
            if ($channel == 'pear.php.net') {
-
 
264
                // hack because of poor pearweb design
-
 
265
                $available = $r->call('package.listAll', true, $list_options, false);
-
 
266
            } else {
-
 
267
                $available = $r->call('package.listAll', true, $list_options);
-
 
268
            }
-
 
269
        }
270
        }
-
 
271
 
270
        if (PEAR::isError($available)) {
272
        if (PEAR::isError($available)) {
271
            $this->config->set('default_channel', $savechannel);
273
            $this->config->set('default_channel', $savechannel);
272
            return $this->raiseError($available);
274
            return $this->raiseError($available);
273
        }
275
        }
-
 
276
 
274
        $i = $j = 0;
277
        $i = $j = 0;
275
        $data = array(
278
        $data = array(
276
            'caption' => 'Channel ' . $channel . ' Available packages:',
279
            'caption' => 'Channel ' . $channel . ' Available packages:',
277
            'border' => true,
280
            'border' => true,
278
            'headline' => array('Package', 'Version'),
281
            'headline' => array('Package', 'Version'),
-
 
282
            'channel' => $channel
279
            );
283
            );
-
 
284
 
280
        if (count($available)==0) {
285
        if (count($available) == 0) {
281
            $data = '(no packages available yet)';
286
            $data = '(no packages available yet)';
282
        } else {
287
        } else {
283
            foreach ($available as $name => $info) {
288
            foreach ($available as $name => $info) {
284
                $data['data'][] = array($name, (isset($info['stable']) && $info['stable'])
289
                $version = (isset($info['stable']) && $info['stable']) ? $info['stable'] : '-n/a-';
285
                    ? $info['stable'] : '-n/a-');
290
                $data['data'][] = array($name, $version);
286
            }
291
            }
287
        }
292
        }
288
        $this->ui->outputData($data, $command);
293
        $this->ui->outputData($data, $command);
289
        $this->config->set('default_channel', $savechannel);
294
        $this->config->set('default_channel', $savechannel);
290
        return true;
295
        return true;
291
    }
296
    }
292
 
-
 
293
    // }}}
-
 
294
    // {{{ doListAll()
-
 
295
 
297
 
296
    function doListAll($command, $options, $params)
298
    function doListAll($command, $options, $params)
297
    {
299
    {
298
        $savechannel = $channel = $this->config->get('default_channel');
300
        $savechannel = $channel = $this->config->get('default_channel');
299
        $reg = &$this->config->getRegistry();
301
        $reg = &$this->config->getRegistry();
300
        if (isset($options['channel'])) {
302
        if (isset($options['channel'])) {
301
            $channel = $options['channel'];
303
            $channel = $options['channel'];
302
            if ($reg->channelExists($channel)) {
304
            if (!$reg->channelExists($channel)) {
303
                $this->config->set('default_channel', $channel);
-
 
304
            } else {
-
 
305
                return $this->raiseError("Channel \"$channel\" does not exist");
305
                return $this->raiseError("Channel \"$channel\" does not exist");
306
            }
306
            }
-
 
307
 
-
 
308
            $this->config->set('default_channel', $channel);
307
        }
309
        }
-
 
310
 
308
        $list_options = false;
311
        $list_options = false;
309
        if ($this->config->get('preferred_state') == 'stable') {
312
        if ($this->config->get('preferred_state') == 'stable') {
310
            $list_options = true;
313
            $list_options = true;
311
        }
314
        }
-
 
315
 
312
        $chan = $reg->getChannel($channel);
316
        $chan = $reg->getChannel($channel);
313
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
317
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
314
            return $e;
318
            return $e;
315
        }
319
        }
-
 
320
 
316
        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
321
        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
317
              $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
322
              $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
318
            // use faster list-all if available
323
            // use faster list-all if available
319
            $rest = &$this->config->getREST('1.1', array());
324
            $rest = &$this->config->getREST('1.1', array());
320
            $available = $rest->listAll($base, $list_options, false);
325
            $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName());
321
        } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
326
        } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
322
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
327
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
323
            $rest = &$this->config->getREST('1.0', array());
328
            $rest = &$this->config->getREST('1.0', array());
324
            $available = $rest->listAll($base, $list_options, false);
329
            $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName());
325
        } else {
-
 
326
            $r = &$this->config->getRemote();
-
 
327
            if ($channel == 'pear.php.net') {
-
 
328
                // hack because of poor pearweb design
-
 
329
                $available = $r->call('package.listAll', true, $list_options, false);
-
 
330
            } else {
-
 
331
                $available = $r->call('package.listAll', true, $list_options);
-
 
332
            }
-
 
333
        }
330
        }
-
 
331
 
334
        if (PEAR::isError($available)) {
332
        if (PEAR::isError($available)) {
335
            $this->config->set('default_channel', $savechannel);
333
            $this->config->set('default_channel', $savechannel);
336
            return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")');
334
            return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")');
337
        }
335
        }
-
 
336
 
338
        $data = array(
337
        $data = array(
339
            'caption' => 'All packages:',
338
            'caption' => 'All packages [Channel ' . $channel . ']:',
340
            'border' => true,
339
            'border' => true,
341
            'headline' => array('Package', 'Latest', 'Local'),
340
            'headline' => array('Package', 'Latest', 'Local'),
-
 
341
            'channel' => $channel,
342
            );
342
            );
-
 
343
 
-
 
344
        if (isset($options['channelinfo'])) {
-
 
345
            // add full channelinfo
-
 
346
            $data['caption'] = 'Channel ' . $channel . ' All packages:';
-
 
347
            $data['headline'] = array('Channel', 'Package', 'Latest', 'Local',
-
 
348
                'Description', 'Dependencies');
-
 
349
        }
343
        $local_pkgs = $reg->listPackages($channel);
350
        $local_pkgs = $reg->listPackages($channel);
344
 
351
 
345
        foreach ($available as $name => $info) {
352
        foreach ($available as $name => $info) {
346
            $installed = $reg->packageInfo($name, null, $channel);
353
            $installed = $reg->packageInfo($name, null, $channel);
347
            if (is_array($installed['version'])) {
354
            if (is_array($installed['version'])) {
348
                $installed['version'] = $installed['version']['release'];
355
                $installed['version'] = $installed['version']['release'];
349
            }
356
            }
350
            $desc = $info['summary'];
357
            $desc = $info['summary'];
351
            if (isset($params[$name])) {
358
            if (isset($params[$name])) {
352
                $desc .= "\n\n".$info['description'];
359
                $desc .= "\n\n".$info['description'];
353
            }
360
            }
354
            if (isset($options['mode']))
361
            if (isset($options['mode']))
355
            {
362
            {
356
                if ($options['mode'] == 'installed' && !isset($installed['version'])) {
363
                if ($options['mode'] == 'installed' && !isset($installed['version'])) {
357
                    continue;
364
                    continue;
358
                }
365
                }
359
                if ($options['mode'] == 'notinstalled' && isset($installed['version'])) {
366
                if ($options['mode'] == 'notinstalled' && isset($installed['version'])) {
360
                    continue;
367
                    continue;
361
                }
368
                }
362
                if ($options['mode'] == 'upgrades'
369
                if ($options['mode'] == 'upgrades'
363
                      && (!isset($installed['version']) || version_compare($installed['version'],
370
                      && (!isset($installed['version']) || version_compare($installed['version'],
364
                      $info['stable'], '>='))) {
371
                      $info['stable'], '>='))) {
365
                    continue;
372
                    continue;
366
                }
373
                }
367
            }
374
            }
368
            $pos = array_search(strtolower($name), $local_pkgs);
375
            $pos = array_search(strtolower($name), $local_pkgs);
369
            if ($pos !== false) {
376
            if ($pos !== false) {
370
                unset($local_pkgs[$pos]);
377
                unset($local_pkgs[$pos]);
371
            }
378
            }
372
 
379
 
373
            if (isset($info['stable']) && !$info['stable']) {
380
            if (isset($info['stable']) && !$info['stable']) {
374
                $info['stable'] = null;
381
                $info['stable'] = null;
375
            }
382
            }
-
 
383
 
376
            $data['data'][$info['category']][] = array(
384
            if (isset($options['channelinfo'])) {
377
                $reg->channelAlias($channel) . '/' . $name,
385
                // add full channelinfo
378
                isset($info['stable']) ? $info['stable'] : null,
386
                if ($info['stable'] === $info['unstable']) {
-
 
387
                    $state = $info['state'];
-
 
388
                } else {
-
 
389
                    $state = 'stable';
-
 
390
                }
-
 
391
                $latest = $info['stable'].' ('.$state.')';
-
 
392
                $local = '';
379
                isset($installed['version']) ? $installed['version'] : null,
393
                if (isset($installed['version'])) {
-
 
394
                    $inst_state = $reg->packageInfo($name, 'release_state', $channel);
-
 
395
                    $local = $installed['version'].' ('.$inst_state.')';
-
 
396
                }
-
 
397
 
-
 
398
                $packageinfo = array(
-
 
399
                    $channel,
-
 
400
                    $name,
-
 
401
                    $latest,
-
 
402
                    $local,
380
                isset($desc) ? $desc : null,
403
                    isset($desc) ? $desc : null,
381
                isset($info['deps']) ? $info['deps'] : null,
404
                    isset($info['deps']) ? $info['deps'] : null,
382
                );
405
                );
-
 
406
            } else {
-
 
407
                $packageinfo = array(
-
 
408
                    $reg->channelAlias($channel) . '/' . $name,
-
 
409
                    isset($info['stable']) ? $info['stable'] : null,
-
 
410
                    isset($installed['version']) ? $installed['version'] : null,
-
 
411
                    isset($desc) ? $desc : null,
-
 
412
                    isset($info['deps']) ? $info['deps'] : null,
-
 
413
                );
-
 
414
            }
-
 
415
            $data['data'][$info['category']][] = $packageinfo;
383
        }
416
        }
384
 
417
 
385
        if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) {
418
        if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) {
386
            $this->config->set('default_channel', $savechannel);
419
            $this->config->set('default_channel', $savechannel);
387
            $this->ui->outputData($data, $command);
420
            $this->ui->outputData($data, $command);
388
            return true;
421
            return true;
389
        }
422
        }
-
 
423
 
390
        foreach ($local_pkgs as $name) {
424
        foreach ($local_pkgs as $name) {
391
            $info = &$reg->getPackage($name, $channel);
425
            $info = &$reg->getPackage($name, $channel);
392
            $data['data']['Local'][] = array(
426
            $data['data']['Local'][] = array(
393
                $reg->channelAlias($channel) . '/' . $info->getPackage(),
427
                $reg->channelAlias($channel) . '/' . $info->getPackage(),
394
                '',
428
                '',
395
                $info->getVersion(),
429
                $info->getVersion(),
396
                $info->getSummary(),
430
                $info->getSummary(),
397
                $info->getDeps()
431
                $info->getDeps()
398
                );
432
                );
399
        }
433
        }
400
 
434
 
401
        $this->config->set('default_channel', $savechannel);
435
        $this->config->set('default_channel', $savechannel);
402
        $this->ui->outputData($data, $command);
436
        $this->ui->outputData($data, $command);
403
        return true;
437
        return true;
404
    }
438
    }
405
 
-
 
406
    // }}}
-
 
407
    // {{{ doSearch()
-
 
408
 
439
 
409
    function doSearch($command, $options, $params)
440
    function doSearch($command, $options, $params)
410
    {
441
    {
411
        if ((!isset($params[0]) || empty($params[0]))
442
        if ((!isset($params[0]) || empty($params[0]))
412
            && (!isset($params[1]) || empty($params[1])))
443
            && (!isset($params[1]) || empty($params[1])))
413
        {
444
        {
414
            return $this->raiseError('no valid search string supplied');
445
            return $this->raiseError('no valid search string supplied');
415
        };
446
        }
416
 
447
 
417
        $savechannel = $channel = $this->config->get('default_channel');
448
        $channelinfo = isset($options['channelinfo']);
-
 
449
        $reg = &$this->config->getRegistry();
-
 
450
        if (isset($options['allchannels'])) {
-
 
451
            // search all channels
-
 
452
            unset($options['allchannels']);
-
 
453
            $channels = $reg->getChannels();
-
 
454
            $errors = array();
-
 
455
            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
-
 
456
            foreach ($channels as $channel) {
-
 
457
                if ($channel->getName() != '__uri') {
-
 
458
                    $options['channel'] = $channel->getName();
-
 
459
                    $ret = $this->doSearch($command, $options, $params);
-
 
460
                    if (PEAR::isError($ret)) {
-
 
461
                        $errors[] = $ret;
-
 
462
                    }
-
 
463
                }
-
 
464
            }
-
 
465
 
-
 
466
            PEAR::staticPopErrorHandling();
-
 
467
            if (count($errors) !== 0) {
-
 
468
                // for now, only give first error
-
 
469
                return PEAR::raiseError($errors[0]);
-
 
470
            }
-
 
471
 
-
 
472
            return true;
-
 
473
        }
-
 
474
 
418
        $reg = &$this->config->getRegistry();
475
        $savechannel = $channel = $this->config->get('default_channel');
419
        $package = $params[0];
476
        $package = strtolower($params[0]);
420
        $summary = isset($params[1]) ? $params[1] : false;
477
        $summary = isset($params[1]) ? $params[1] : false;
421
        if (isset($options['channel'])) {
478
        if (isset($options['channel'])) {
422
            $reg = &$this->config->getRegistry();
479
            $reg = &$this->config->getRegistry();
423
            $channel = $options['channel'];
480
            $channel = $options['channel'];
424
            if ($reg->channelExists($channel)) {
481
            if (!$reg->channelExists($channel)) {
425
                $this->config->set('default_channel', $channel);
-
 
426
            } else {
-
 
427
                return $this->raiseError('Channel "' . $channel . '" does not exist');
482
                return $this->raiseError('Channel "' . $channel . '" does not exist');
428
            }
483
            }
-
 
484
 
-
 
485
            $this->config->set('default_channel', $channel);
429
        }
486
        }
-
 
487
 
430
        $chan = $reg->getChannel($channel);
488
        $chan = $reg->getChannel($channel);
431
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
489
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
432
            return $e;
490
            return $e;
433
        }
491
        }
-
 
492
 
434
        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
493
        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
435
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
494
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
436
            $rest = &$this->config->getREST('1.0', array());
495
            $rest = &$this->config->getREST('1.0', array());
437
            $available = $rest->listAll($base, false, false, $package, $summary);
496
            $available = $rest->listAll($base, false, false, $package, $summary, $chan->getName());
438
        } else {
-
 
439
            $r = &$this->config->getRemote();
-
 
440
            $available = $r->call('package.search', $package, $summary, true, 
-
 
441
                $this->config->get('preferred_state') == 'stable', true);
-
 
442
        }
497
        }
-
 
498
 
443
        if (PEAR::isError($available)) {
499
        if (PEAR::isError($available)) {
444
            $this->config->set('default_channel', $savechannel);
500
            $this->config->set('default_channel', $savechannel);
445
            return $this->raiseError($available);
501
            return $this->raiseError($available);
446
        }
502
        }
-
 
503
 
-
 
504
        if (!$available && !$channelinfo) {
-
 
505
            // clean exit when not found, no error !
-
 
506
            $data = 'no packages found that match pattern "' . $package . '", for channel '.$channel.'.';
-
 
507
            $this->ui->outputData($data);
-
 
508
            $this->config->set('default_channel', $channel);
-
 
509
            return true;
-
 
510
        }
-
 
511
 
447
        if (!$available) {
512
        if ($channelinfo) {
-
 
513
            $data = array(
-
 
514
                'caption' => 'Matched packages, channel ' . $channel . ':',
-
 
515
                'border' => true,
-
 
516
                'headline' => array('Channel', 'Package', 'Stable/(Latest)', 'Local'),
-
 
517
                'channel' => $channel
-
 
518
                );
-
 
519
        } else {
-
 
520
            $data = array(
-
 
521
                'caption' => 'Matched packages, channel ' . $channel . ':',
-
 
522
                'border' => true,
-
 
523
                'headline' => array('Package', 'Stable/(Latest)', 'Local'),
-
 
524
                'channel' => $channel
-
 
525
                );
-
 
526
        }
-
 
527
 
-
 
528
        if (!$available && $channelinfo) {
-
 
529
            unset($data['headline']);
448
            return $this->raiseError('no packages found that match pattern "' . $package . '"');
530
            $data['data'] = 'No packages found that match pattern "' . $package . '".';
-
 
531
            $available = array();
449
        }
532
        }
450
        $data = array(
-
 
451
            'caption' => 'Matched packages, channel ' . $channel . ':',
-
 
452
            'border' => true,
-
 
453
            'headline' => array('Package', 'Stable/(Latest)', 'Local'),
-
 
454
            );
-
 
455
 
533
 
456
        foreach ($available as $name => $info) {
534
        foreach ($available as $name => $info) {
457
            $installed = $reg->packageInfo($name, null, $channel);
535
            $installed = $reg->packageInfo($name, null, $channel);
458
            $desc = $info['summary'];
536
            $desc = $info['summary'];
459
            if (isset($params[$name]))
537
            if (isset($params[$name]))
460
                $desc .= "\n\n".$info['description'];
538
                $desc .= "\n\n".$info['description'];
461
 
-
 
462
            $unstable = '';
-
 
463
            if ($info['unstable']) {
-
 
464
                $unstable = '/(' . $info['unstable'] . ' ' . $info['state'] . ')';
-
 
465
            }
539
 
466
            if (!isset($info['stable']) || !$info['stable']) {
540
            if (!isset($info['stable']) || !$info['stable']) {
-
 
541
                $version_remote = 'none';
-
 
542
            } else {
-
 
543
                if ($info['unstable']) {
-
 
544
                    $version_remote = $info['unstable'];
-
 
545
                } else {
-
 
546
                    $version_remote = $info['stable'];
-
 
547
                }
467
                $info['stable'] = 'none';
548
                $version_remote .= ' ('.$info['state'].')';
468
            }
549
            }
469
            $version = is_array($installed['version']) ? $installed['version']['release'] :
550
            $version = is_array($installed['version']) ? $installed['version']['release'] :
470
                $installed['version'];
551
                $installed['version'];
-
 
552
            if ($channelinfo) {
471
            $data['data'][$info['category']][] = array(
553
                $packageinfo = array(
-
 
554
                    $channel,
472
                $name,
555
                    $name,
-
 
556
                    $version_remote,
-
 
557
                    $version,
-
 
558
                    $desc,
-
 
559
                );
-
 
560
            } else {
473
                $info['stable'] . $unstable,
561
                $packageinfo = array(
-
 
562
                    $name,
-
 
563
                    $version_remote,
474
                $version,
564
                    $version,
475
                $desc,
565
                    $desc,
476
                );
566
                );
-
 
567
            }
-
 
568
            $data['data'][$info['category']][] = $packageinfo;
477
        }
569
        }
-
 
570
 
478
        $this->ui->outputData($data, $command);
571
        $this->ui->outputData($data, $command);
479
        $this->config->set('default_channel', $channel);
572
        $this->config->set('default_channel', $channel);
480
        return true;
573
        return true;
481
    }
574
    }
482
 
-
 
483
    // }}}
575
 
484
    function &getDownloader($options)
576
    function &getDownloader($options)
485
    {
577
    {
486
        if (!class_exists('PEAR_Downloader')) {
578
        if (!class_exists('PEAR_Downloader')) {
487
            require_once 'PEAR/Downloader.php';
579
            require_once 'PEAR/Downloader.php';
488
        }
580
        }
489
        $a = &new PEAR_Downloader($this->ui, $options, $this->config);
581
        $a = new PEAR_Downloader($this->ui, $options, $this->config);
490
        return $a;
582
        return $a;
491
    }
583
    }
492
    // {{{ doDownload()
-
 
493
 
584
 
494
    function doDownload($command, $options, $params)
585
    function doDownload($command, $options, $params)
495
    {
586
    {
496
        // make certain that dependencies are ignored
587
        // make certain that dependencies are ignored
497
        $options['downloadonly'] = 1;
588
        $options['downloadonly'] = 1;
498
 
589
 
499
        // eliminate error messages for preferred_state-related errors
590
        // eliminate error messages for preferred_state-related errors
500
        /* TODO: Should be an option, but until now download does respect
591
        /* TODO: Should be an option, but until now download does respect
501
           prefered state */
592
           prefered state */
502
        /* $options['ignorepreferred_state'] = 1; */
593
        /* $options['ignorepreferred_state'] = 1; */
503
        // eliminate error messages for preferred_state-related errors
594
        // eliminate error messages for preferred_state-related errors
504
 
595
 
505
        $downloader = &$this->getDownloader($options);
596
        $downloader = &$this->getDownloader($options);
-
 
597
        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
506
        $downloader->setDownloadDir(getcwd());
598
        $e = $downloader->setDownloadDir(getcwd());
-
 
599
        PEAR::staticPopErrorHandling();
-
 
600
        if (PEAR::isError($e)) {
-
 
601
            return $this->raiseError('Current directory is not writeable, cannot download');
-
 
602
        }
-
 
603
 
507
        $errors = array();
604
        $errors = array();
508
        $downloaded = array();
605
        $downloaded = array();
509
        $err = $downloader->download($params);
606
        $err = $downloader->download($params);
510
        if (PEAR::isError($err)) {
607
        if (PEAR::isError($err)) {
511
            return $err;
608
            return $err;
512
        }
609
        }
-
 
610
 
513
        $errors = $downloader->getErrorMsgs();
611
        $errors = $downloader->getErrorMsgs();
514
        if (count($errors)) {
612
        if (count($errors)) {
515
            foreach ($errors as $error) {
613
            foreach ($errors as $error) {
-
 
614
                if ($error !== null) {
516
                $this->ui->outputData($error);
615
                    $this->ui->outputData($error);
-
 
616
                }
517
            }
617
            }
-
 
618
 
518
            return $this->raiseError("$command failed");
619
            return $this->raiseError("$command failed");
519
        }
620
        }
-
 
621
 
520
        $downloaded = $downloader->getDownloadedPackages();
622
        $downloaded = $downloader->getDownloadedPackages();
521
        foreach ($downloaded as $pkg) {
623
        foreach ($downloaded as $pkg) {
522
            $this->ui->outputData("File $pkg[file] downloaded", $command);
624
            $this->ui->outputData("File $pkg[file] downloaded", $command);
523
        }
625
        }
-
 
626
 
524
        return true;
627
        return true;
525
    }
628
    }
526
 
629
 
527
    function downloadCallback($msg, $params = null)
630
    function downloadCallback($msg, $params = null)
528
    {
631
    {
529
        if ($msg == 'done') {
632
        if ($msg == 'done') {
530
            $this->bytes_downloaded = $params;
633
            $this->bytes_downloaded = $params;
531
        }
634
        }
532
    }
635
    }
533
 
-
 
534
    // }}}
-
 
535
    // {{{ doListUpgrades()
-
 
536
 
636
 
537
    function doListUpgrades($command, $options, $params)
637
    function doListUpgrades($command, $options, $params)
538
    {
638
    {
539
        require_once 'PEAR/Common.php';
639
        require_once 'PEAR/Common.php';
540
        if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) {
640
        if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) {
541
            return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"');
641
            return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"');
542
        }
642
        }
-
 
643
 
543
        $savechannel = $channel = $this->config->get('default_channel');
644
        $savechannel = $channel = $this->config->get('default_channel');
544
        $reg = &$this->config->getRegistry();
645
        $reg = &$this->config->getRegistry();
545
        foreach ($reg->listChannels() as $channel) {
646
        foreach ($reg->listChannels() as $channel) {
546
            $inst = array_flip($reg->listPackages($channel));
647
            $inst = array_flip($reg->listPackages($channel));
547
            if (!count($inst)) {
648
            if (!count($inst)) {
548
                continue;
649
                continue;
549
            }
650
            }
-
 
651
 
550
            if ($channel == '__uri') {
652
            if ($channel == '__uri') {
551
                continue;
653
                continue;
552
            }
654
            }
-
 
655
 
553
            $this->config->set('default_channel', $channel);
656
            $this->config->set('default_channel', $channel);
554
            if (empty($params[0])) {
-
 
555
                $state = $this->config->get('preferred_state');
657
            $state = empty($params[0]) ? $this->config->get('preferred_state') : $params[0];
556
            } else {
-
 
557
                $state = $params[0];
-
 
558
            }
658
 
559
            $caption = $channel . ' Available Upgrades';
659
            $caption = $channel . ' Available Upgrades';
560
            $chan = $reg->getChannel($channel);
660
            $chan = $reg->getChannel($channel);
561
            if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
661
            if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
562
                return $e;
662
                return $e;
563
            }
663
            }
-
 
664
 
-
 
665
            $latest = array();
-
 
666
            $base2  = false;
-
 
667
            $preferred_mirror = $this->config->get('preferred_mirror');
564
            if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
668
            if ($chan->supportsREST($preferred_mirror) &&
-
 
669
                (
565
                  $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
670
                   ($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror))
-
 
671
                   || ($base  = $chan->getBaseURL('REST1.0', $preferred_mirror))
-
 
672
                )
-
 
673
 
-
 
674
            ) {
-
 
675
                if ($base2) {
-
 
676
                    $rest = &$this->config->getREST('1.3', array());
-
 
677
                    $base = $base2;
-
 
678
                } else {
566
                $rest = &$this->config->getREST('1.0', array());
679
                    $rest = &$this->config->getREST('1.0', array());
-
 
680
                }
-
 
681
 
567
                if (empty($state) || $state == 'any') {
682
                if (empty($state) || $state == 'any') {
568
                    $state = false;
683
                    $state = false;
569
                } else {
684
                } else {
570
                    $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
685
                    $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
571
                }
686
                }
-
 
687
 
572
                PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
688
                PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
573
                $latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg);
689
                $latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg);
574
                PEAR::staticPopErrorHandling();
690
                PEAR::staticPopErrorHandling();
575
            } else {
-
 
576
                $remote = &$this->config->getRemote();
-
 
577
                $remote->pushErrorHandling(PEAR_ERROR_RETURN);
-
 
578
                if (empty($state) || $state == 'any') {
-
 
579
                    $latest = $remote->call("package.listLatestReleases");
-
 
580
                } else {
-
 
581
                    $latest = $remote->call("package.listLatestReleases", $state);
-
 
582
                    $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
-
 
583
                }
-
 
584
                $remote->popErrorHandling();
-
 
585
            }
691
            }
-
 
692
 
586
            if (PEAR::isError($latest)) {
693
            if (PEAR::isError($latest)) {
587
                $this->ui->outputData($latest->getMessage());
694
                $this->ui->outputData($latest->getMessage());
588
                continue;
695
                continue;
589
            }
696
            }
-
 
697
 
590
            $caption .= ':';
698
            $caption .= ':';
591
            if (PEAR::isError($latest)) {
699
            if (PEAR::isError($latest)) {
592
                $this->config->set('default_channel', $savechannel);
700
                $this->config->set('default_channel', $savechannel);
593
                return $latest;
701
                return $latest;
594
            }
702
            }
-
 
703
 
595
            $data = array(
704
            $data = array(
596
                'caption' => $caption,
705
                'caption' => $caption,
597
                'border' => 1,
706
                'border' => 1,
598
                'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'),
707
                'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'),
-
 
708
                'channel' => $channel
599
                );
709
                );
-
 
710
 
600
            foreach ((array)$latest as $pkg => $info) {
711
            foreach ((array)$latest as $pkg => $info) {
601
                $package = strtolower($pkg);
712
                $package = strtolower($pkg);
602
                if (!isset($inst[$package])) {
713
                if (!isset($inst[$package])) {
603
                    // skip packages we don't have installed
714
                    // skip packages we don't have installed
604
                    continue;
715
                    continue;
605
                }
716
                }
-
 
717
 
606
                extract($info);
718
                extract($info);
607
                $inst_version = $reg->packageInfo($package, 'version', $channel);
719
                $inst_version = $reg->packageInfo($package, 'version', $channel);
608
                $inst_state   = $reg->packageInfo($package, 'release_state', $channel);
720
                $inst_state   = $reg->packageInfo($package, 'release_state', $channel);
609
                if (version_compare("$version", "$inst_version", "le")) {
721
                if (version_compare("$version", "$inst_version", "le")) {
610
                    // installed version is up-to-date
722
                    // installed version is up-to-date
611
                    continue;
723
                    continue;
612
                }
724
                }
-
 
725
 
613
                if ($filesize >= 20480) {
726
                if ($filesize >= 20480) {
614
                    $filesize += 1024 - ($filesize % 1024);
727
                    $filesize += 1024 - ($filesize % 1024);
615
                    $fs = sprintf("%dkB", $filesize / 1024);
728
                    $fs = sprintf("%dkB", $filesize / 1024);
616
                } elseif ($filesize > 0) {
729
                } elseif ($filesize > 0) {
617
                    $filesize += 103 - ($filesize % 103);
730
                    $filesize += 103 - ($filesize % 103);
618
                    $fs = sprintf("%.1fkB", $filesize / 1024.0);
731
                    $fs = sprintf("%.1fkB", $filesize / 1024.0);
619
                } else {
732
                } else {
620
                    $fs = "  -"; // XXX center instead
733
                    $fs = "  -"; // XXX center instead
621
                }
734
                }
-
 
735
 
622
                $data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs);
736
                $data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs);
623
            }
737
            }
-
 
738
 
-
 
739
            if (isset($options['channelinfo'])) {
624
            if (empty($data['data'])) {
740
                if (empty($data['data'])) {
-
 
741
                    unset($data['headline']);
-
 
742
                    if (count($inst) == 0) {
-
 
743
                        $data['data'] = '(no packages installed)';
-
 
744
                    } else {
625
                $this->ui->outputData('Channel ' . $channel . ': No upgrades available');
745
                        $data['data'] = '(no upgrades available)';
-
 
746
                    }
626
            } else {
747
                }
627
                $this->ui->outputData($data, $command);
748
                $this->ui->outputData($data, $command);
-
 
749
            } else {
-
 
750
                if (empty($data['data'])) {
-
 
751
                    $this->ui->outputData('Channel ' . $channel . ': No upgrades available');
-
 
752
                } else {
-
 
753
                    $this->ui->outputData($data, $command);
-
 
754
                }
628
            }
755
            }
629
        }
756
        }
-
 
757
 
630
        $this->config->set('default_channel', $savechannel);
758
        $this->config->set('default_channel', $savechannel);
631
        return true;
759
        return true;
632
    }
760
    }
633
 
-
 
634
    // }}}
-
 
635
    // {{{ doClearCache()
-
 
636
 
761
 
637
    function doClearCache($command, $options, $params)
762
    function doClearCache($command, $options, $params)
638
    {
763
    {
639
        $cache_dir = $this->config->get('cache_dir');
764
        $cache_dir = $this->config->get('cache_dir');
640
        $verbose = $this->config->get('verbose');
765
        $verbose   = $this->config->get('verbose');
641
        $output = '';
766
        $output = '';
642
        if (!file_exists($cache_dir) || !is_dir($cache_dir)) {
767
        if (!file_exists($cache_dir) || !is_dir($cache_dir)) {
643
            return $this->raiseError("$cache_dir does not exist or is not a directory");
768
            return $this->raiseError("$cache_dir does not exist or is not a directory");
644
        }
769
        }
-
 
770
 
645
        if (!($dp = @opendir($cache_dir))) {
771
        if (!($dp = @opendir($cache_dir))) {
646
            return $this->raiseError("opendir($cache_dir) failed: $php_errormsg");
772
            return $this->raiseError("opendir($cache_dir) failed: $php_errormsg");
647
        }
773
        }
-
 
774
 
648
        if ($verbose >= 1) {
775
        if ($verbose >= 1) {
649
            $output .= "reading directory $cache_dir\n";
776
            $output .= "reading directory $cache_dir\n";
650
        }
777
        }
-
 
778
 
651
        $num = 0;
779
        $num = 0;
652
        while ($ent = readdir($dp)) {
780
        while ($ent = readdir($dp)) {
653
            if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}$/', $ent) ||
-
 
654
                  preg_match('/rest.cache(file|id)$/', $ent)) {
781
            if (preg_match('/rest.cache(file|id)\\z/', $ent)) {
655
                $path = $cache_dir . DIRECTORY_SEPARATOR . $ent;
782
                $path = $cache_dir . DIRECTORY_SEPARATOR . $ent;
656
                if (file_exists($path)) {
783
                if (file_exists($path)) {
657
                    $ok = @unlink($path);
784
                    $ok = @unlink($path);
658
                } else {
785
                } else {
659
                    $ok = false;
786
                    $ok = false;
660
                    $php_errormsg = '';
787
                    $php_errormsg = '';
661
                }
788
                }
-
 
789
 
662
                if ($ok) {
790
                if ($ok) {
663
                    if ($verbose >= 2) {
791
                    if ($verbose >= 2) {
664
                        $output .= "deleted $path\n";
792
                        $output .= "deleted $path\n";
665
                    }
793
                    }
666
                    $num++;
794
                    $num++;
667
                } elseif ($verbose >= 1) {
795
                } elseif ($verbose >= 1) {
668
                    $output .= "failed to delete $path $php_errormsg\n";
796
                    $output .= "failed to delete $path $php_errormsg\n";
669
                }
797
                }
670
            }
798
            }
671
        }
799
        }
-
 
800
 
672
        closedir($dp);
801
        closedir($dp);
673
        if ($verbose >= 1) {
802
        if ($verbose >= 1) {
674
            $output .= "$num cache entries cleared\n";
803
            $output .= "$num cache entries cleared\n";
675
        }
804
        }
-
 
805
 
676
        $this->ui->outputData(rtrim($output), $command);
806
        $this->ui->outputData(rtrim($output), $command);
677
        return $num;
807
        return $num;
678
    }
808
    }
679
 
-
 
680
    // }}}
-
 
681
}
809
}
682
 
-
 
683
?>
-