Subversion Repositories Applications.gtt

Rev

Rev 94 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
94 jpm 1
<?php
2
/**
3
 * PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download,
4
 * clear-cache commands)
5
 *
6
 * PHP versions 4 and 5
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
15
 * @package    PEAR
16
 * @author     Stig Bakken <ssb@php.net>
17
 * @author     Greg Beaver <cellog@php.net>
18
 * @copyright  1997-2006 The PHP Group
19
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
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
22
 * @since      File available since Release 0.1
23
 */
24
 
25
/**
26
 * base class
27
 */
28
require_once 'PEAR/Command/Common.php';
29
require_once 'PEAR/REST.php';
30
 
31
/**
32
 * PEAR commands for remote server querying
33
 *
34
 * @category   pear
35
 * @package    PEAR
36
 * @author     Stig Bakken <ssb@php.net>
37
 * @author     Greg Beaver <cellog@php.net>
38
 * @copyright  1997-2006 The PHP Group
39
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
40
 * @version    Release: 1.5.1
41
 * @link       http://pear.php.net/package/PEAR
42
 * @since      Class available since Release 0.1
43
 */
44
class PEAR_Command_Remote extends PEAR_Command_Common
45
{
46
    // {{{ command definitions
47
 
48
    var $commands = array(
49
        'remote-info' => array(
50
            'summary' => 'Information About Remote Packages',
51
            'function' => 'doRemoteInfo',
52
            'shortcut' => 'ri',
53
            'options' => array(),
54
            'doc' => '<package>
55
Get details on a package from the server.',
56
            ),
57
        'list-upgrades' => array(
58
            'summary' => 'List Available Upgrades',
59
            'function' => 'doListUpgrades',
60
            'shortcut' => 'lu',
61
            'options' => array(),
62
            'doc' => '[preferred_state]
63
List releases on the server of packages you have installed where
64
a newer version is available with the same release state (stable etc.)
65
or the state passed as the second parameter.'
66
            ),
67
        'remote-list' => array(
68
            'summary' => 'List Remote Packages',
69
            'function' => 'doRemoteList',
70
            'shortcut' => 'rl',
71
            'options' => array(
72
                'channel' =>
73
                    array(
74
                    'shortopt' => 'c',
75
                    'doc' => 'specify a channel other than the default channel',
76
                    'arg' => 'CHAN',
77
                    )
78
                ),
79
            'doc' => '
80
Lists the packages available on the configured server along with the
81
latest stable release of each package.',
82
            ),
83
        'search' => array(
84
            'summary' => 'Search remote package database',
85
            'function' => 'doSearch',
86
            'shortcut' => 'sp',
87
            'options' => array(
88
                'channel' =>
89
                    array(
90
                    'shortopt' => 'c',
91
                    'doc' => 'specify a channel other than the default channel',
92
                    'arg' => 'CHAN',
93
                    )
94
                ),
95
            'doc' => '[packagename] [packageinfo]
96
Lists all packages which match the search parameters.  The first
97
parameter is a fragment of a packagename.  The default channel
98
will be used unless explicitly overridden.  The second parameter
99
will be used to match any portion of the summary/description',
100
            ),
101
        'list-all' => array(
102
            'summary' => 'List All Packages',
103
            'function' => 'doListAll',
104
            'shortcut' => 'la',
105
            'options' => array(
106
                'channel' =>
107
                    array(
108
                    'shortopt' => 'c',
109
                    'doc' => 'specify a channel other than the default channel',
110
                    'arg' => 'CHAN',
111
                    )
112
                ),
113
            'doc' => '
114
Lists the packages available on the configured server along with the
115
latest stable release of each package.',
116
            ),
117
        'download' => array(
118
            'summary' => 'Download Package',
119
            'function' => 'doDownload',
120
            'shortcut' => 'd',
121
            'options' => array(
122
                'nocompress' => array(
123
                    'shortopt' => 'Z',
124
                    'doc' => 'download an uncompressed (.tar) file',
125
                    ),
126
                ),
127
            'doc' => '<package>...
128
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
130
version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.',
131
            ),
132
        'clear-cache' => array(
133
            'summary' => 'Clear Web Services Cache',
134
            'function' => 'doClearCache',
135
            'shortcut' => 'cc',
136
            'options' => array(),
137
            'doc' => '
138
Clear the XML-RPC/REST cache.  See also the cache_ttl configuration
139
parameter.
140
',
141
            ),
142
        );
143
 
144
    // }}}
145
    // {{{ constructor
146
 
147
    /**
148
     * PEAR_Command_Remote constructor.
149
     *
150
     * @access public
151
     */
152
    function PEAR_Command_Remote(&$ui, &$config)
153
    {
154
        parent::PEAR_Command_Common($ui, $config);
155
    }
156
 
157
    // }}}
158
 
159
    function _checkChannelForStatus($channel, $chan)
160
    {
161
        if (PEAR::isError($chan)) {
162
            $this->raiseError($chan);
163
        }
164
        if (!is_a($chan, 'PEAR_ChannelFile')) {
165
            return $this->raiseError('Internal corruption error: invalid channel "' .
166
                $channel . '"');
167
        }
168
        $rest = new PEAR_REST($this->config);
169
        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
170
        $a = $rest->downloadHttp('http://' . $channel .
171
            '/channel.xml', $chan->lastModified());
172
        PEAR::staticPopErrorHandling();
173
        if (!PEAR::isError($a) && $a) {
174
            $this->ui->outputData('WARNING: channel "' . $channel . '" has ' .
175
                'updated its protocols, use "channel-update ' . $channel .
176
                '" to update');
177
        }
178
    }
179
 
180
    // {{{ doRemoteInfo()
181
 
182
    function doRemoteInfo($command, $options, $params)
183
    {
184
        if (sizeof($params) != 1) {
185
            return $this->raiseError("$command expects one param: the remote package name");
186
        }
187
        $savechannel = $channel = $this->config->get('default_channel');
188
        $reg = &$this->config->getRegistry();
189
        $package = $params[0];
190
        $parsed = $reg->parsePackageName($package, $channel);
191
        if (PEAR::isError($parsed)) {
192
            return $this->raiseError('Invalid package name "' . $package . '"');
193
        }
194
 
195
        $channel = $parsed['channel'];
196
        $this->config->set('default_channel', $channel);
197
        $chan = $reg->getChannel($channel);
198
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
199
            return $e;
200
        }
201
        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
202
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
203
            $rest = &$this->config->getREST('1.0', array());
204
            $info = $rest->packageInfo($base, $parsed['package']);
205
        } else {
206
            $r = &$this->config->getRemote();
207
            $info = $r->call('package.info', $parsed['package']);
208
        }
209
        if (PEAR::isError($info)) {
210
            $this->config->set('default_channel', $savechannel);
211
            return $this->raiseError($info);
212
        }
213
        if (!isset($info['name'])) {
214
            return $this->raiseError('No remote package "' . $package . '" was found');
215
        }
216
 
217
        $installed = $reg->packageInfo($info['name'], null, $channel);
218
        $info['installed'] = $installed['version'] ? $installed['version'] : '- no -';
219
        if (is_array($info['installed'])) {
220
            $info['installed'] = $info['installed']['release'];
221
        }
222
 
223
        $this->ui->outputData($info, $command);
224
        $this->config->set('default_channel', $savechannel);
225
 
226
        return true;
227
    }
228
 
229
    // }}}
230
    // {{{ doRemoteList()
231
 
232
    function doRemoteList($command, $options, $params)
233
    {
234
        $savechannel = $channel = $this->config->get('default_channel');
235
        $reg = &$this->config->getRegistry();
236
        if (isset($options['channel'])) {
237
            $channel = $options['channel'];
238
            if ($reg->channelExists($channel)) {
239
                $this->config->set('default_channel', $channel);
240
            } else {
241
                return $this->raiseError('Channel "' . $channel . '" does not exist');
242
            }
243
        }
244
        $chan = $reg->getChannel($channel);
245
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
246
            return $e;
247
        }
248
        $list_options = false;
249
        if ($this->config->get('preferred_state') == 'stable') {
250
            $list_options = true;
251
        }
252
        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
253
              $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
254
            // use faster list-all if available
255
            $rest = &$this->config->getREST('1.1', array());
256
            $available = $rest->listAll($base, $list_options);
257
        } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
258
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
259
            $rest = &$this->config->getREST('1.0', array());
260
            $available = $rest->listAll($base, $list_options);
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
        if (PEAR::isError($available)) {
271
            $this->config->set('default_channel', $savechannel);
272
            return $this->raiseError($available);
273
        }
274
        $i = $j = 0;
275
        $data = array(
276
            'caption' => 'Channel ' . $channel . ' Available packages:',
277
            'border' => true,
278
            'headline' => array('Package', 'Version'),
279
            );
280
        if (count($available)==0) {
281
            $data = '(no packages available yet)';
282
        } else {
283
            foreach ($available as $name => $info) {
284
                $data['data'][] = array($name, (isset($info['stable']) && $info['stable'])
285
                    ? $info['stable'] : '-n/a-');
286
            }
287
        }
288
        $this->ui->outputData($data, $command);
289
        $this->config->set('default_channel', $savechannel);
290
        return true;
291
    }
292
 
293
    // }}}
294
    // {{{ doListAll()
295
 
296
    function doListAll($command, $options, $params)
297
    {
298
        $savechannel = $channel = $this->config->get('default_channel');
299
        $reg = &$this->config->getRegistry();
300
        if (isset($options['channel'])) {
301
            $channel = $options['channel'];
302
            if ($reg->channelExists($channel)) {
303
                $this->config->set('default_channel', $channel);
304
            } else {
305
                return $this->raiseError("Channel \"$channel\" does not exist");
306
            }
307
        }
308
        $list_options = false;
309
        if ($this->config->get('preferred_state') == 'stable') {
310
            $list_options = true;
311
        }
312
        $chan = $reg->getChannel($channel);
313
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
314
            return $e;
315
        }
316
        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
317
              $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
318
            // use faster list-all if available
319
            $rest = &$this->config->getREST('1.1', array());
320
            $available = $rest->listAll($base, $list_options, false);
321
        } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
322
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
323
            $rest = &$this->config->getREST('1.0', array());
324
            $available = $rest->listAll($base, $list_options, false);
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
        }
334
        if (PEAR::isError($available)) {
335
            $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() . '")');
337
        }
338
        $data = array(
339
            'caption' => 'All packages:',
340
            'border' => true,
341
            'headline' => array('Package', 'Latest', 'Local'),
342
            );
343
        $local_pkgs = $reg->listPackages($channel);
344
 
345
        foreach ($available as $name => $info) {
346
            $installed = $reg->packageInfo($name, null, $channel);
347
            if (is_array($installed['version'])) {
348
                $installed['version'] = $installed['version']['release'];
349
            }
350
            $desc = $info['summary'];
351
            if (isset($params[$name])) {
352
                $desc .= "\n\n".$info['description'];
353
            }
354
            if (isset($options['mode']))
355
            {
356
                if ($options['mode'] == 'installed' && !isset($installed['version'])) {
357
                    continue;
358
                }
359
                if ($options['mode'] == 'notinstalled' && isset($installed['version'])) {
360
                    continue;
361
                }
362
                if ($options['mode'] == 'upgrades'
363
                      && (!isset($installed['version']) || version_compare($installed['version'],
364
                      $info['stable'], '>='))) {
365
                    continue;
366
                }
367
            }
368
            $pos = array_search(strtolower($name), $local_pkgs);
369
            if ($pos !== false) {
370
                unset($local_pkgs[$pos]);
371
            }
372
 
373
            if (isset($info['stable']) && !$info['stable']) {
374
                $info['stable'] = null;
375
            }
376
            $data['data'][$info['category']][] = array(
377
                $reg->channelAlias($channel) . '/' . $name,
378
                isset($info['stable']) ? $info['stable'] : null,
379
                isset($installed['version']) ? $installed['version'] : null,
380
                isset($desc) ? $desc : null,
381
                isset($info['deps']) ? $info['deps'] : null,
382
                );
383
        }
384
 
385
        if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) {
386
            $this->config->set('default_channel', $savechannel);
387
            $this->ui->outputData($data, $command);
388
            return true;
389
        }
390
        foreach ($local_pkgs as $name) {
391
            $info = &$reg->getPackage($name, $channel);
392
            $data['data']['Local'][] = array(
393
                $reg->channelAlias($channel) . '/' . $info->getPackage(),
394
                '',
395
                $info->getVersion(),
396
                $info->getSummary(),
397
                $info->getDeps()
398
                );
399
        }
400
 
401
        $this->config->set('default_channel', $savechannel);
402
        $this->ui->outputData($data, $command);
403
        return true;
404
    }
405
 
406
    // }}}
407
    // {{{ doSearch()
408
 
409
    function doSearch($command, $options, $params)
410
    {
411
        if ((!isset($params[0]) || empty($params[0]))
412
            && (!isset($params[1]) || empty($params[1])))
413
        {
414
            return $this->raiseError('no valid search string supplied');
415
        };
416
 
417
        $savechannel = $channel = $this->config->get('default_channel');
418
        $reg = &$this->config->getRegistry();
419
        $package = $params[0];
420
        $summary = isset($params[1]) ? $params[1] : false;
421
        if (isset($options['channel'])) {
422
            $reg = &$this->config->getRegistry();
423
            $channel = $options['channel'];
424
            if ($reg->channelExists($channel)) {
425
                $this->config->set('default_channel', $channel);
426
            } else {
427
                return $this->raiseError('Channel "' . $channel . '" does not exist');
428
            }
429
        }
430
        $chan = $reg->getChannel($channel);
431
        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
432
            return $e;
433
        }
434
        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
435
              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
436
            $rest = &$this->config->getREST('1.0', array());
437
            $available = $rest->listAll($base, false, false, $package, $summary);
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
        }
443
        if (PEAR::isError($available)) {
444
            $this->config->set('default_channel', $savechannel);
445
            return $this->raiseError($available);
446
        }
447
        if (!$available) {
448
            return $this->raiseError('no packages found that match pattern "' . $package . '"');
449
        }
450
        $data = array(
451
            'caption' => 'Matched packages, channel ' . $channel . ':',
452
            'border' => true,
453
            'headline' => array('Package', 'Stable/(Latest)', 'Local'),
454
            );
455
 
456
        foreach ($available as $name => $info) {
457
            $installed = $reg->packageInfo($name, null, $channel);
458
            $desc = $info['summary'];
459
            if (isset($params[$name]))
460
                $desc .= "\n\n".$info['description'];
461
 
462
            $unstable = '';
463
            if ($info['unstable']) {
464
                $unstable = '/(' . $info['unstable'] . ' ' . $info['state'] . ')';
465
            }
466
            if (!isset($info['stable']) || !$info['stable']) {
467
                $info['stable'] = 'none';
468
            }
469
            $version = is_array($installed['version']) ? $installed['version']['release'] :
470
                $installed['version'];
471
            $data['data'][$info['category']][] = array(
472
                $name,
473
                $info['stable'] . $unstable,
474
                $version,
475
                $desc,
476
                );
477
        }
478
        $this->ui->outputData($data, $command);
479
        $this->config->set('default_channel', $channel);
480
        return true;
481
    }
482
 
483
    // }}}
484
    function &getDownloader($options)
485
    {
486
        if (!class_exists('PEAR_Downloader')) {
487
            require_once 'PEAR/Downloader.php';
488
        }
489
        $a = &new PEAR_Downloader($this->ui, $options, $this->config);
490
        return $a;
491
    }
492
    // {{{ doDownload()
493
 
494
    function doDownload($command, $options, $params)
495
    {
496
        // make certain that dependencies are ignored
497
        $options['downloadonly'] = 1;
498
 
499
        // eliminate error messages for preferred_state-related errors
500
        /* TODO: Should be an option, but until now download does respect
501
           prefered state */
502
        /* $options['ignorepreferred_state'] = 1; */
503
        // eliminate error messages for preferred_state-related errors
504
 
505
        $downloader = &$this->getDownloader($options);
506
        $downloader->setDownloadDir(getcwd());
507
        $errors = array();
508
        $downloaded = array();
509
        $err = $downloader->download($params);
510
        if (PEAR::isError($err)) {
511
            return $err;
512
        }
513
        $errors = $downloader->getErrorMsgs();
514
        if (count($errors)) {
515
            foreach ($errors as $error) {
516
                $this->ui->outputData($error);
517
            }
518
            return $this->raiseError("$command failed");
519
        }
520
        $downloaded = $downloader->getDownloadedPackages();
521
        foreach ($downloaded as $pkg) {
522
            $this->ui->outputData("File $pkg[file] downloaded", $command);
523
        }
524
        return true;
525
    }
526
 
527
    function downloadCallback($msg, $params = null)
528
    {
529
        if ($msg == 'done') {
530
            $this->bytes_downloaded = $params;
531
        }
532
    }
533
 
534
    // }}}
535
    // {{{ doListUpgrades()
536
 
537
    function doListUpgrades($command, $options, $params)
538
    {
539
        require_once 'PEAR/Common.php';
540
        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"');
542
        }
543
        $savechannel = $channel = $this->config->get('default_channel');
544
        $reg = &$this->config->getRegistry();
545
        foreach ($reg->listChannels() as $channel) {
546
            $inst = array_flip($reg->listPackages($channel));
547
            if (!count($inst)) {
548
                continue;
549
            }
550
            if ($channel == '__uri') {
551
                continue;
552
            }
553
            $this->config->set('default_channel', $channel);
554
            if (empty($params[0])) {
555
                $state = $this->config->get('preferred_state');
556
            } else {
557
                $state = $params[0];
558
            }
559
            $caption = $channel . ' Available Upgrades';
560
            $chan = $reg->getChannel($channel);
561
            if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
562
                return $e;
563
            }
564
            if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
565
                  $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
566
                $rest = &$this->config->getREST('1.0', array());
567
                if (empty($state) || $state == 'any') {
568
                    $state = false;
569
                } else {
570
                    $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
571
                }
572
                PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
573
                $latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg);
574
                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
            }
586
            if (PEAR::isError($latest)) {
587
                $this->ui->outputData($latest->getMessage());
588
                continue;
589
            }
590
            $caption .= ':';
591
            if (PEAR::isError($latest)) {
592
                $this->config->set('default_channel', $savechannel);
593
                return $latest;
594
            }
595
            $data = array(
596
                'caption' => $caption,
597
                'border' => 1,
598
                'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'),
599
                );
600
            foreach ((array)$latest as $pkg => $info) {
601
                $package = strtolower($pkg);
602
                if (!isset($inst[$package])) {
603
                    // skip packages we don't have installed
604
                    continue;
605
                }
606
                extract($info);
607
                $inst_version = $reg->packageInfo($package, 'version', $channel);
608
                $inst_state   = $reg->packageInfo($package, 'release_state', $channel);
609
                if (version_compare("$version", "$inst_version", "le")) {
610
                    // installed version is up-to-date
611
                    continue;
612
                }
613
                if ($filesize >= 20480) {
614
                    $filesize += 1024 - ($filesize % 1024);
615
                    $fs = sprintf("%dkB", $filesize / 1024);
616
                } elseif ($filesize > 0) {
617
                    $filesize += 103 - ($filesize % 103);
618
                    $fs = sprintf("%.1fkB", $filesize / 1024.0);
619
                } else {
620
                    $fs = "  -"; // XXX center instead
621
                }
622
                $data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs);
623
            }
624
            if (empty($data['data'])) {
625
                $this->ui->outputData('Channel ' . $channel . ': No upgrades available');
626
            } else {
627
                $this->ui->outputData($data, $command);
628
            }
629
        }
630
        $this->config->set('default_channel', $savechannel);
631
        return true;
632
    }
633
 
634
    // }}}
635
    // {{{ doClearCache()
636
 
637
    function doClearCache($command, $options, $params)
638
    {
639
        $cache_dir = $this->config->get('cache_dir');
640
        $verbose = $this->config->get('verbose');
641
        $output = '';
642
        if (!file_exists($cache_dir) || !is_dir($cache_dir)) {
643
            return $this->raiseError("$cache_dir does not exist or is not a directory");
644
        }
645
        if (!($dp = @opendir($cache_dir))) {
646
            return $this->raiseError("opendir($cache_dir) failed: $php_errormsg");
647
        }
648
        if ($verbose >= 1) {
649
            $output .= "reading directory $cache_dir\n";
650
        }
651
        $num = 0;
652
        while ($ent = readdir($dp)) {
653
            if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}$/', $ent) ||
654
                  preg_match('/rest.cache(file|id)$/', $ent)) {
655
                $path = $cache_dir . DIRECTORY_SEPARATOR . $ent;
656
                if (file_exists($path)) {
657
                    $ok = @unlink($path);
658
                } else {
659
                    $ok = false;
660
                    $php_errormsg = '';
661
                }
662
                if ($ok) {
663
                    if ($verbose >= 2) {
664
                        $output .= "deleted $path\n";
665
                    }
666
                    $num++;
667
                } elseif ($verbose >= 1) {
668
                    $output .= "failed to delete $path $php_errormsg\n";
669
                }
670
            }
671
        }
672
        closedir($dp);
673
        if ($verbose >= 1) {
674
            $output .= "$num cache entries cleared\n";
675
        }
676
        $this->ui->outputData(rtrim($output), $command);
677
        return $num;
678
    }
679
 
680
    // }}}
681
}
682
 
683
?>