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_Registry (list, list-files, shell-test, info commands)
4
 *
5
 * PHP versions 4 and 5
6
 *
7
 * @category   pear
8
 * @package    PEAR
9
 * @author     Stig Bakken <ssb@php.net>
10
 * @author     Greg Beaver <cellog@php.net>
187 mathias 11
 * @copyright  1997-2009 The Authors
12
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
94 jpm 13
 * @link       http://pear.php.net/package/PEAR
14
 * @since      File available since Release 0.1
15
 */
16
 
17
/**
18
 * base class
19
 */
20
require_once 'PEAR/Command/Common.php';
21
 
22
/**
23
 * PEAR commands for registry manipulation
24
 *
25
 * @category   pear
26
 * @package    PEAR
27
 * @author     Stig Bakken <ssb@php.net>
28
 * @author     Greg Beaver <cellog@php.net>
187 mathias 29
 * @copyright  1997-2009 The Authors
30
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
31
 * @version    Release: 1.10.1
94 jpm 32
 * @link       http://pear.php.net/package/PEAR
33
 * @since      Class available since Release 0.1
34
 */
35
class PEAR_Command_Registry extends PEAR_Command_Common
36
{
37
    var $commands = array(
38
        'list' => array(
39
            'summary' => 'List Installed Packages In The Default Channel',
40
            'function' => 'doList',
41
            'shortcut' => 'l',
42
            'options' => array(
43
                'channel' => array(
44
                    'shortopt' => 'c',
45
                    'doc' => 'list installed packages from this channel',
46
                    'arg' => 'CHAN',
47
                    ),
48
                'allchannels' => array(
49
                    'shortopt' => 'a',
50
                    'doc' => 'list installed packages from all channels',
51
                    ),
187 mathias 52
                'channelinfo' => array(
53
                    'shortopt' => 'i',
54
                    'doc' => 'output fully channel-aware data, even on failure',
55
                    ),
94 jpm 56
                ),
57
            'doc' => '<package>
58
If invoked without parameters, this command lists the PEAR packages
59
installed in your php_dir ({config php_dir}).  With a parameter, it
60
lists the files in a package.
61
',
62
            ),
63
        'list-files' => array(
64
            'summary' => 'List Files In Installed Package',
65
            'function' => 'doFileList',
66
            'shortcut' => 'fl',
67
            'options' => array(),
68
            'doc' => '<package>
69
List the files in an installed package.
70
'
71
            ),
72
        'shell-test' => array(
73
            'summary' => 'Shell Script Test',
74
            'function' => 'doShellTest',
75
            'shortcut' => 'st',
76
            'options' => array(),
77
            'doc' => '<package> [[relation] version]
78
Tests if a package is installed in the system. Will exit(1) if it is not.
79
   <relation>   The version comparison operator. One of:
80
                <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne
81
   <version>    The version to compare with
82
'),
83
        'info' => array(
84
            'summary'  => 'Display information about a package',
85
            'function' => 'doInfo',
86
            'shortcut' => 'in',
87
            'options'  => array(),
88
            'doc'      => '<package>
89
Displays information about a package. The package argument may be a
90
local package file, an URL to a package file, or the name of an
91
installed package.'
92
            )
93
        );
94
 
95
    /**
96
     * PEAR_Command_Registry constructor.
97
     *
98
     * @access public
99
     */
187 mathias 100
    function __construct(&$ui, &$config)
94 jpm 101
    {
187 mathias 102
        parent::__construct($ui, $config);
94 jpm 103
    }
104
 
105
    function _sortinfo($a, $b)
106
    {
107
        $apackage = isset($a['package']) ? $a['package'] : $a['name'];
108
        $bpackage = isset($b['package']) ? $b['package'] : $b['name'];
109
        return strcmp($apackage, $bpackage);
110
    }
111
 
112
    function doList($command, $options, $params)
113
    {
187 mathias 114
        $reg = &$this->config->getRegistry();
115
        $channelinfo = isset($options['channelinfo']);
116
        if (isset($options['allchannels']) && !$channelinfo) {
94 jpm 117
            return $this->doListAll($command, array(), $params);
118
        }
187 mathias 119
 
120
        if (isset($options['allchannels']) && $channelinfo) {
121
            // allchannels with $channelinfo
122
            unset($options['allchannels']);
123
            $channels = $reg->getChannels();
124
            $errors = array();
125
            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
126
            foreach ($channels as $channel) {
127
                $options['channel'] = $channel->getName();
128
                $ret = $this->doList($command, $options, $params);
129
 
130
                if (PEAR::isError($ret)) {
131
                    $errors[] = $ret;
132
                }
133
            }
134
 
135
            PEAR::staticPopErrorHandling();
136
            if (count($errors)) {
137
                // for now, only give first error
138
                return PEAR::raiseError($errors[0]);
139
            }
140
 
141
            return true;
142
        }
143
 
144
        if (count($params) === 1) {
94 jpm 145
            return $this->doFileList($command, $options, $params);
146
        }
187 mathias 147
 
94 jpm 148
        if (isset($options['channel'])) {
187 mathias 149
            if (!$reg->channelExists($options['channel'])) {
94 jpm 150
                return $this->raiseError('Channel "' . $options['channel'] .'" does not exist');
151
            }
187 mathias 152
 
153
            $channel = $reg->channelName($options['channel']);
94 jpm 154
        } else {
155
            $channel = $this->config->get('default_channel');
156
        }
187 mathias 157
 
94 jpm 158
        $installed = $reg->packageInfo(null, null, $channel);
159
        usort($installed, array(&$this, '_sortinfo'));
187 mathias 160
 
94 jpm 161
        $data = array(
162
            'caption' => 'Installed packages, channel ' .
163
                $channel . ':',
164
            'border' => true,
187 mathias 165
            'headline' => array('Package', 'Version', 'State'),
166
            'channel' => $channel,
94 jpm 167
            );
187 mathias 168
        if ($channelinfo) {
169
            $data['headline'] = array('Channel', 'Package', 'Version', 'State');
170
        }
171
 
172
        if (count($installed) && !isset($data['data'])) {
173
            $data['data'] = array();
174
        }
175
 
94 jpm 176
        foreach ($installed as $package) {
177
            $pobj = $reg->getPackage(isset($package['package']) ?
178
                                        $package['package'] : $package['name'], $channel);
187 mathias 179
            if ($channelinfo) {
180
                $packageinfo = array($pobj->getChannel(), $pobj->getPackage(), $pobj->getVersion(),
94 jpm 181
                                    $pobj->getState() ? $pobj->getState() : null);
187 mathias 182
            } else {
183
                $packageinfo = array($pobj->getPackage(), $pobj->getVersion(),
184
                                    $pobj->getState() ? $pobj->getState() : null);
185
            }
186
            $data['data'][] = $packageinfo;
94 jpm 187
        }
187 mathias 188
 
189
        if (count($installed) === 0) {
190
            if (!$channelinfo) {
191
                $data = '(no packages installed from channel ' . $channel . ')';
192
            } else {
193
                $data = array(
194
                    'caption' => 'Installed packages, channel ' .
195
                        $channel . ':',
196
                    'border' => true,
197
                    'channel' => $channel,
198
                    'data' => array(array('(no packages installed)')),
199
                );
200
            }
94 jpm 201
        }
187 mathias 202
 
94 jpm 203
        $this->ui->outputData($data, $command);
204
        return true;
205
    }
187 mathias 206
 
94 jpm 207
    function doListAll($command, $options, $params)
208
    {
187 mathias 209
        // This duplicate code is deprecated over
210
        // list --channelinfo, which gives identical
211
        // output for list and list --allchannels.
94 jpm 212
        $reg = &$this->config->getRegistry();
213
        $installed = $reg->packageInfo(null, null, null);
214
        foreach ($installed as $channel => $packages) {
215
            usort($packages, array($this, '_sortinfo'));
216
            $data = array(
187 mathias 217
                'caption'  => 'Installed packages, channel ' . $channel . ':',
218
                'border'   => true,
219
                'headline' => array('Package', 'Version', 'State'),
220
                'channel'  => $channel
221
            );
222
 
94 jpm 223
            foreach ($packages as $package) {
187 mathias 224
                $p = isset($package['package']) ? $package['package'] : $package['name'];
225
                $pobj = $reg->getPackage($p, $channel);
94 jpm 226
                $data['data'][] = array($pobj->getPackage(), $pobj->getVersion(),
227
                                        $pobj->getState() ? $pobj->getState() : null);
228
            }
187 mathias 229
 
230
            // Adds a blank line after each section
231
            $data['data'][] = array();
232
 
233
            if (count($packages) === 0) {
94 jpm 234
                $data = array(
235
                    'caption' => 'Installed packages, channel ' . $channel . ':',
236
                    'border' => true,
187 mathias 237
                    'data' => array(array('(no packages installed)'), array()),
238
                    'channel' => $channel
94 jpm 239
                    );
240
            }
241
            $this->ui->outputData($data, $command);
242
        }
243
        return true;
244
    }
187 mathias 245
 
94 jpm 246
    function doFileList($command, $options, $params)
247
    {
187 mathias 248
        if (count($params) !== 1) {
94 jpm 249
            return $this->raiseError('list-files expects 1 parameter');
250
        }
187 mathias 251
 
94 jpm 252
        $reg = &$this->config->getRegistry();
253
        $fp = false;
187 mathias 254
        if (!is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0], 'r'))) {
94 jpm 255
            if ($fp) {
256
                fclose($fp);
257
            }
187 mathias 258
 
94 jpm 259
            if (!class_exists('PEAR_PackageFile')) {
260
                require_once 'PEAR/PackageFile.php';
261
            }
187 mathias 262
 
263
            $pkg = new PEAR_PackageFile($this->config, $this->_debug);
94 jpm 264
            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
265
            $info = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
266
            PEAR::staticPopErrorHandling();
267
            $headings = array('Package File', 'Install Path');
268
            $installed = false;
269
        } else {
270
            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
271
            $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
272
            PEAR::staticPopErrorHandling();
273
            if (PEAR::isError($parsed)) {
274
                return $this->raiseError($parsed);
275
            }
187 mathias 276
 
94 jpm 277
            $info = &$reg->getPackage($parsed['package'], $parsed['channel']);
278
            $headings = array('Type', 'Install Path');
279
            $installed = true;
280
        }
187 mathias 281
 
94 jpm 282
        if (PEAR::isError($info)) {
283
            return $this->raiseError($info);
284
        }
187 mathias 285
 
94 jpm 286
        if ($info === null) {
287
            return $this->raiseError("`$params[0]' not installed");
288
        }
187 mathias 289
 
94 jpm 290
        $list = ($info->getPackagexmlVersion() == '1.0' || $installed) ?
291
            $info->getFilelist() : $info->getContents();
292
        if ($installed) {
293
            $caption = 'Installed Files For ' . $params[0];
294
        } else {
295
            $caption = 'Contents of ' . basename($params[0]);
296
        }
187 mathias 297
 
94 jpm 298
        $data = array(
299
            'caption' => $caption,
300
            'border' => true,
301
            'headline' => $headings);
302
        if ($info->getPackagexmlVersion() == '1.0' || $installed) {
303
            foreach ($list as $file => $att) {
304
                if ($installed) {
305
                    if (empty($att['installed_as'])) {
306
                        continue;
307
                    }
308
                    $data['data'][] = array($att['role'], $att['installed_as']);
309
                } else {
310
                    if (isset($att['baseinstalldir']) && !in_array($att['role'],
311
                          array('test', 'data', 'doc'))) {
312
                        $dest = $att['baseinstalldir'] . DIRECTORY_SEPARATOR .
313
                            $file;
314
                    } else {
315
                        $dest = $file;
316
                    }
317
                    switch ($att['role']) {
318
                        case 'test':
319
                        case 'data':
320
                        case 'doc':
321
                            $role = $att['role'];
322
                            if ($role == 'test') {
323
                                $role .= 's';
324
                            }
325
                            $dest = $this->config->get($role . '_dir') . DIRECTORY_SEPARATOR .
326
                                $info->getPackage() . DIRECTORY_SEPARATOR . $dest;
327
                            break;
328
                        case 'php':
329
                        default:
330
                            $dest = $this->config->get('php_dir') . DIRECTORY_SEPARATOR .
331
                                $dest;
332
                    }
333
                    $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
334
                    $dest = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"),
335
                                                    array(DIRECTORY_SEPARATOR,
336
                                                          DIRECTORY_SEPARATOR,
337
                                                          DIRECTORY_SEPARATOR),
338
                                                    $dest);
339
                    $file = preg_replace('!/+!', '/', $file);
340
                    $data['data'][] = array($file, $dest);
341
                }
342
            }
343
        } else { // package.xml 2.0, not installed
344
            if (!isset($list['dir']['file'][0])) {
345
                $list['dir']['file'] = array($list['dir']['file']);
346
            }
187 mathias 347
 
94 jpm 348
            foreach ($list['dir']['file'] as $att) {
349
                $att = $att['attribs'];
350
                $file = $att['name'];
351
                $role = &PEAR_Installer_Role::factory($info, $att['role'], $this->config);
352
                $role->setup($this, $info, $att, $file);
353
                if (!$role->isInstallable()) {
354
                    $dest = '(not installable)';
355
                } else {
356
                    $dest = $role->processInstallation($info, $att, $file, '');
357
                    if (PEAR::isError($dest)) {
358
                        $dest = '(Unknown role "' . $att['role'] . ')';
359
                    } else {
360
                        list(,, $dest) = $dest;
361
                    }
362
                }
363
                $data['data'][] = array($file, $dest);
364
            }
365
        }
187 mathias 366
 
94 jpm 367
        $this->ui->outputData($data, $command);
368
        return true;
369
    }
370
 
371
    function doShellTest($command, $options, $params)
372
    {
373
        if (count($params) < 1) {
374
            return PEAR::raiseError('ERROR, usage: pear shell-test packagename [[relation] version]');
375
        }
187 mathias 376
 
94 jpm 377
        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
378
        $reg = &$this->config->getRegistry();
379
        $info = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
380
        if (PEAR::isError($info)) {
381
            exit(1); // invalid package name
382
        }
187 mathias 383
 
94 jpm 384
        $package = $info['package'];
385
        $channel = $info['channel'];
386
        // "pear shell-test Foo"
387
        if (!$reg->packageExists($package, $channel)) {
388
            if ($channel == 'pecl.php.net') {
389
                if ($reg->packageExists($package, 'pear.php.net')) {
390
                    $channel = 'pear.php.net'; // magically change channels for extensions
391
                }
392
            }
393
        }
187 mathias 394
 
395
        if (count($params) === 1) {
94 jpm 396
            if (!$reg->packageExists($package, $channel)) {
397
                exit(1);
398
            }
399
            // "pear shell-test Foo 1.0"
187 mathias 400
        } elseif (count($params) === 2) {
94 jpm 401
            $v = $reg->packageInfo($package, 'version', $channel);
402
            if (!$v || !version_compare("$v", "{$params[1]}", "ge")) {
403
                exit(1);
404
            }
405
            // "pear shell-test Foo ge 1.0"
187 mathias 406
        } elseif (count($params) === 3) {
94 jpm 407
            $v = $reg->packageInfo($package, 'version', $channel);
408
            if (!$v || !version_compare("$v", "{$params[2]}", $params[1])) {
409
                exit(1);
410
            }
411
        } else {
412
            PEAR::staticPopErrorHandling();
413
            $this->raiseError("$command: expects 1 to 3 parameters");
414
            exit(1);
415
        }
416
    }
417
 
418
    function doInfo($command, $options, $params)
419
    {
187 mathias 420
        if (count($params) !== 1) {
94 jpm 421
            return $this->raiseError('pear info expects 1 parameter');
422
        }
187 mathias 423
 
94 jpm 424
        $info = $fp = false;
425
        $reg = &$this->config->getRegistry();
187 mathias 426
        if (is_file($params[0]) && !is_dir($params[0]) &&
427
            (file_exists($params[0]) || $fp = @fopen($params[0], 'r'))
428
        ) {
94 jpm 429
            if ($fp) {
430
                fclose($fp);
431
            }
187 mathias 432
 
94 jpm 433
            if (!class_exists('PEAR_PackageFile')) {
434
                require_once 'PEAR/PackageFile.php';
435
            }
187 mathias 436
 
437
            $pkg = new PEAR_PackageFile($this->config, $this->_debug);
94 jpm 438
            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
439
            $obj = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
440
            PEAR::staticPopErrorHandling();
441
            if (PEAR::isError($obj)) {
442
                $uinfo = $obj->getUserInfo();
443
                if (is_array($uinfo)) {
444
                    foreach ($uinfo as $message) {
445
                        if (is_array($message)) {
446
                            $message = $message['message'];
447
                        }
448
                        $this->ui->outputData($message);
449
                    }
450
                }
187 mathias 451
 
94 jpm 452
                return $this->raiseError($obj);
453
            }
187 mathias 454
 
455
            if ($obj->getPackagexmlVersion() != '1.0') {
94 jpm 456
                return $this->_doInfo2($command, $options, $params, $obj, false);
457
            }
187 mathias 458
 
459
            $info = $obj->toArray();
94 jpm 460
        } else {
461
            $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
462
            if (PEAR::isError($parsed)) {
463
                return $this->raiseError($parsed);
464
            }
187 mathias 465
 
94 jpm 466
            $package = $parsed['package'];
467
            $channel = $parsed['channel'];
468
            $info = $reg->packageInfo($package, null, $channel);
469
            if (isset($info['old'])) {
470
                $obj = $reg->getPackage($package, $channel);
471
                return $this->_doInfo2($command, $options, $params, $obj, true);
472
            }
473
        }
187 mathias 474
 
94 jpm 475
        if (PEAR::isError($info)) {
476
            return $info;
477
        }
187 mathias 478
 
94 jpm 479
        if (empty($info)) {
480
            $this->raiseError("No information found for `$params[0]'");
481
            return;
482
        }
187 mathias 483
 
94 jpm 484
        unset($info['filelist']);
485
        unset($info['dirtree']);
486
        unset($info['changelog']);
487
        if (isset($info['xsdversion'])) {
488
            $info['package.xml version'] = $info['xsdversion'];
489
            unset($info['xsdversion']);
490
        }
187 mathias 491
 
94 jpm 492
        if (isset($info['packagerversion'])) {
493
            $info['packaged with PEAR version'] = $info['packagerversion'];
494
            unset($info['packagerversion']);
495
        }
187 mathias 496
 
94 jpm 497
        $keys = array_keys($info);
498
        $longtext = array('description', 'summary');
499
        foreach ($keys as $key) {
500
            if (is_array($info[$key])) {
501
                switch ($key) {
502
                    case 'maintainers': {
503
                        $i = 0;
504
                        $mstr = '';
505
                        foreach ($info[$key] as $m) {
506
                            if ($i++ > 0) {
507
                                $mstr .= "\n";
508
                            }
509
                            $mstr .= $m['name'] . " <";
510
                            if (isset($m['email'])) {
511
                                $mstr .= $m['email'];
512
                            } else {
513
                                $mstr .= $m['handle'] . '@php.net';
514
                            }
515
                            $mstr .= "> ($m[role])";
516
                        }
517
                        $info[$key] = $mstr;
518
                        break;
519
                    }
520
                    case 'release_deps': {
521
                        $i = 0;
522
                        $dstr = '';
523
                        foreach ($info[$key] as $d) {
524
                            if (isset($this->_deps_rel_trans[$d['rel']])) {
525
                                $rel = $this->_deps_rel_trans[$d['rel']];
526
                            } else {
527
                                $rel = $d['rel'];
528
                            }
529
                            if (isset($this->_deps_type_trans[$d['type']])) {
530
                                $type = ucfirst($this->_deps_type_trans[$d['type']]);
531
                            } else {
532
                                $type = $d['type'];
533
                            }
534
                            if (isset($d['name'])) {
535
                                $name = $d['name'] . ' ';
536
                            } else {
537
                                $name = '';
538
                            }
539
                            if (isset($d['version'])) {
540
                                $version = $d['version'] . ' ';
541
                            } else {
542
                                $version = '';
543
                            }
544
                            if (isset($d['optional']) && $d['optional'] == 'yes') {
545
                                $optional = ' (optional)';
546
                            } else {
547
                                $optional = '';
548
                            }
549
                            $dstr .= "$type $name$rel $version$optional\n";
550
                        }
551
                        $info[$key] = $dstr;
552
                        break;
553
                    }
554
                    case 'provides' : {
555
                        $debug = $this->config->get('verbose');
556
                        if ($debug < 2) {
557
                            $pstr = 'Classes: ';
558
                        } else {
559
                            $pstr = '';
560
                        }
561
                        $i = 0;
562
                        foreach ($info[$key] as $p) {
563
                            if ($debug < 2 && $p['type'] != "class") {
564
                                continue;
565
                            }
566
                            // Only print classes when verbosity mode is < 2
567
                            if ($debug < 2) {
568
                                if ($i++ > 0) {
569
                                    $pstr .= ", ";
570
                                }
571
                                $pstr .= $p['name'];
572
                            } else {
573
                                if ($i++ > 0) {
574
                                    $pstr .= "\n";
575
                                }
576
                                $pstr .= ucfirst($p['type']) . " " . $p['name'];
577
                                if (isset($p['explicit']) && $p['explicit'] == 1) {
578
                                    $pstr .= " (explicit)";
579
                                }
580
                            }
581
                        }
582
                        $info[$key] = $pstr;
583
                        break;
584
                    }
585
                    case 'configure_options' : {
586
                        foreach ($info[$key] as $i => $p) {
587
                            $info[$key][$i] = array_map(null, array_keys($p), array_values($p));
588
                            $info[$key][$i] = array_map(create_function('$a',
589
                                'return join(" = ",$a);'), $info[$key][$i]);
590
                            $info[$key][$i] = implode(', ', $info[$key][$i]);
591
                        }
592
                        $info[$key] = implode("\n", $info[$key]);
593
                        break;
594
                    }
595
                    default: {
596
                        $info[$key] = implode(", ", $info[$key]);
597
                        break;
598
                    }
599
                }
600
            }
187 mathias 601
 
94 jpm 602
            if ($key == '_lastmodified') {
603
                $hdate = date('Y-m-d', $info[$key]);
604
                unset($info[$key]);
605
                $info['Last Modified'] = $hdate;
606
            } elseif ($key == '_lastversion') {
607
                $info['Previous Installed Version'] = $info[$key] ? $info[$key] : '- None -';
608
                unset($info[$key]);
609
            } else {
610
                $info[$key] = trim($info[$key]);
611
                if (in_array($key, $longtext)) {
612
                    $info[$key] = preg_replace('/  +/', ' ', $info[$key]);
613
                }
614
            }
615
        }
187 mathias 616
 
94 jpm 617
        $caption = 'About ' . $info['package'] . '-' . $info['version'];
618
        $data = array(
619
            'caption' => $caption,
620
            'border' => true);
621
        foreach ($info as $key => $value) {
622
            $key = ucwords(trim(str_replace('_', ' ', $key)));
623
            $data['data'][] = array($key, $value);
624
        }
625
        $data['raw'] = $info;
626
 
627
        $this->ui->outputData($data, 'package-info');
628
    }
629
 
630
    /**
631
     * @access private
632
     */
633
    function _doInfo2($command, $options, $params, &$obj, $installed)
634
    {
635
        $reg = &$this->config->getRegistry();
636
        $caption = 'About ' . $obj->getChannel() . '/' .$obj->getPackage() . '-' .
637
            $obj->getVersion();
638
        $data = array(
639
            'caption' => $caption,
640
            'border' => true);
641
        switch ($obj->getPackageType()) {
642
            case 'php' :
643
                $release = 'PEAR-style PHP-based Package';
644
            break;
645
            case 'extsrc' :
646
                $release = 'PECL-style PHP extension (source code)';
647
            break;
648
            case 'zendextsrc' :
649
                $release = 'PECL-style Zend extension (source code)';
650
            break;
651
            case 'extbin' :
652
                $release = 'PECL-style PHP extension (binary)';
653
            break;
654
            case 'zendextbin' :
655
                $release = 'PECL-style Zend extension (binary)';
656
            break;
657
            case 'bundle' :
658
                $release = 'Package bundle (collection of packages)';
659
            break;
660
        }
661
        $extends = $obj->getExtends();
662
        $extends = $extends ?
663
            $obj->getPackage() . ' (extends ' . $extends . ')' : $obj->getPackage();
664
        if ($src = $obj->getSourcePackage()) {
665
            $extends .= ' (source package ' . $src['channel'] . '/' . $src['package'] . ')';
666
        }
187 mathias 667
 
94 jpm 668
        $info = array(
669
            'Release Type' => $release,
670
            'Name' => $extends,
671
            'Channel' => $obj->getChannel(),
672
            'Summary' => preg_replace('/  +/', ' ', $obj->getSummary()),
673
            'Description' => preg_replace('/  +/', ' ', $obj->getDescription()),
674
            );
675
        $info['Maintainers'] = '';
676
        foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
677
            $leads = $obj->{"get{$role}s"}();
678
            if (!$leads) {
679
                continue;
680
            }
187 mathias 681
 
94 jpm 682
            if (isset($leads['active'])) {
683
                $leads = array($leads);
684
            }
187 mathias 685
 
94 jpm 686
            foreach ($leads as $lead) {
687
                if (!empty($info['Maintainers'])) {
688
                    $info['Maintainers'] .= "\n";
689
                }
187 mathias 690
 
691
                $active = $lead['active'] == 'no' ? ', inactive' : '';
94 jpm 692
                $info['Maintainers'] .= $lead['name'] . ' <';
187 mathias 693
                $info['Maintainers'] .= $lead['email'] . "> ($role$active)";
94 jpm 694
            }
695
        }
187 mathias 696
 
94 jpm 697
        $info['Release Date'] = $obj->getDate();
698
        if ($time = $obj->getTime()) {
699
            $info['Release Date'] .= ' ' . $time;
700
        }
187 mathias 701
 
94 jpm 702
        $info['Release Version'] = $obj->getVersion() . ' (' . $obj->getState() . ')';
703
        $info['API Version'] = $obj->getVersion('api') . ' (' . $obj->getState('api') . ')';
704
        $info['License'] = $obj->getLicense();
705
        $uri = $obj->getLicenseLocation();
706
        if ($uri) {
707
            if (isset($uri['uri'])) {
708
                $info['License'] .= ' (' . $uri['uri'] . ')';
709
            } else {
710
                $extra = $obj->getInstalledLocation($info['filesource']);
711
                if ($extra) {
712
                    $info['License'] .= ' (' . $uri['filesource'] . ')';
713
                }
714
            }
715
        }
187 mathias 716
 
94 jpm 717
        $info['Release Notes'] = $obj->getNotes();
718
        if ($compat = $obj->getCompatible()) {
187 mathias 719
            if (!isset($compat[0])) {
720
                $compat = array($compat);
721
            }
722
 
94 jpm 723
            $info['Compatible with'] = '';
724
            foreach ($compat as $package) {
187 mathias 725
                $info['Compatible with'] .= $package['channel'] . '/' . $package['name'] .
94 jpm 726
                    "\nVersions >= " . $package['min'] . ', <= ' . $package['max'];
727
                if (isset($package['exclude'])) {
728
                    if (is_array($package['exclude'])) {
729
                        $package['exclude'] = implode(', ', $package['exclude']);
730
                    }
187 mathias 731
 
94 jpm 732
                    if (!isset($info['Not Compatible with'])) {
733
                        $info['Not Compatible with'] = '';
734
                    } else {
735
                        $info['Not Compatible with'] .= "\n";
736
                    }
737
                    $info['Not Compatible with'] .= $package['channel'] . '/' .
187 mathias 738
                        $package['name'] . "\nVersions " . $package['exclude'];
94 jpm 739
                }
740
            }
741
        }
187 mathias 742
 
94 jpm 743
        $usesrole = $obj->getUsesrole();
744
        if ($usesrole) {
745
            if (!isset($usesrole[0])) {
746
                $usesrole = array($usesrole);
747
            }
187 mathias 748
 
94 jpm 749
            foreach ($usesrole as $roledata) {
750
                if (isset($info['Uses Custom Roles'])) {
751
                    $info['Uses Custom Roles'] .= "\n";
752
                } else {
753
                    $info['Uses Custom Roles'] = '';
754
                }
187 mathias 755
 
94 jpm 756
                if (isset($roledata['package'])) {
757
                    $rolepackage = $reg->parsedPackageNameToString($roledata, true);
758
                } else {
759
                    $rolepackage = $roledata['uri'];
760
                }
761
                $info['Uses Custom Roles'] .= $roledata['role'] . ' (' . $rolepackage . ')';
762
            }
763
        }
187 mathias 764
 
94 jpm 765
        $usestask = $obj->getUsestask();
766
        if ($usestask) {
767
            if (!isset($usestask[0])) {
768
                $usestask = array($usestask);
769
            }
187 mathias 770
 
94 jpm 771
            foreach ($usestask as $taskdata) {
772
                if (isset($info['Uses Custom Tasks'])) {
773
                    $info['Uses Custom Tasks'] .= "\n";
774
                } else {
775
                    $info['Uses Custom Tasks'] = '';
776
                }
187 mathias 777
 
94 jpm 778
                if (isset($taskdata['package'])) {
779
                    $taskpackage = $reg->parsedPackageNameToString($taskdata, true);
780
                } else {
781
                    $taskpackage = $taskdata['uri'];
782
                }
783
                $info['Uses Custom Tasks'] .= $taskdata['task'] . ' (' . $taskpackage . ')';
784
            }
785
        }
187 mathias 786
 
94 jpm 787
        $deps = $obj->getDependencies();
788
        $info['Required Dependencies'] = 'PHP version ' . $deps['required']['php']['min'];
789
        if (isset($deps['required']['php']['max'])) {
790
            $info['Required Dependencies'] .= '-' . $deps['required']['php']['max'] . "\n";
791
        } else {
792
            $info['Required Dependencies'] .= "\n";
793
        }
187 mathias 794
 
94 jpm 795
        if (isset($deps['required']['php']['exclude'])) {
796
            if (!isset($info['Not Compatible with'])) {
797
                $info['Not Compatible with'] = '';
798
            } else {
799
                $info['Not Compatible with'] .= "\n";
800
            }
187 mathias 801
 
94 jpm 802
            if (is_array($deps['required']['php']['exclude'])) {
803
                $deps['required']['php']['exclude'] =
804
                    implode(', ', $deps['required']['php']['exclude']);
805
            }
806
            $info['Not Compatible with'] .= "PHP versions\n  " .
807
                $deps['required']['php']['exclude'];
808
        }
187 mathias 809
 
94 jpm 810
        $info['Required Dependencies'] .= 'PEAR installer version';
811
        if (isset($deps['required']['pearinstaller']['max'])) {
812
            $info['Required Dependencies'] .= 's ' .
813
                $deps['required']['pearinstaller']['min'] . '-' .
814
                $deps['required']['pearinstaller']['max'];
815
        } else {
816
            $info['Required Dependencies'] .= ' ' .
817
                $deps['required']['pearinstaller']['min'] . ' or newer';
818
        }
187 mathias 819
 
94 jpm 820
        if (isset($deps['required']['pearinstaller']['exclude'])) {
821
            if (!isset($info['Not Compatible with'])) {
822
                $info['Not Compatible with'] = '';
823
            } else {
824
                $info['Not Compatible with'] .= "\n";
825
            }
187 mathias 826
 
94 jpm 827
            if (is_array($deps['required']['pearinstaller']['exclude'])) {
828
                $deps['required']['pearinstaller']['exclude'] =
829
                    implode(', ', $deps['required']['pearinstaller']['exclude']);
830
            }
831
            $info['Not Compatible with'] .= "PEAR installer\n  Versions " .
832
                $deps['required']['pearinstaller']['exclude'];
833
        }
187 mathias 834
 
94 jpm 835
        foreach (array('Package', 'Extension') as $type) {
836
            $index = strtolower($type);
837
            if (isset($deps['required'][$index])) {
838
                if (isset($deps['required'][$index]['name'])) {
839
                    $deps['required'][$index] = array($deps['required'][$index]);
840
                }
187 mathias 841
 
94 jpm 842
                foreach ($deps['required'][$index] as $package) {
843
                    if (isset($package['conflicts'])) {
844
                        $infoindex = 'Not Compatible with';
845
                        if (!isset($info['Not Compatible with'])) {
846
                            $info['Not Compatible with'] = '';
847
                        } else {
848
                            $info['Not Compatible with'] .= "\n";
849
                        }
850
                    } else {
851
                        $infoindex = 'Required Dependencies';
852
                        $info[$infoindex] .= "\n";
853
                    }
187 mathias 854
 
94 jpm 855
                    if ($index == 'extension') {
856
                        $name = $package['name'];
857
                    } else {
858
                        if (isset($package['channel'])) {
859
                            $name = $package['channel'] . '/' . $package['name'];
860
                        } else {
861
                            $name = '__uri/' . $package['name'] . ' (static URI)';
862
                        }
863
                    }
187 mathias 864
 
94 jpm 865
                    $info[$infoindex] .= "$type $name";
866
                    if (isset($package['uri'])) {
867
                        $info[$infoindex] .= "\n  Download URI: $package[uri]";
868
                        continue;
869
                    }
187 mathias 870
 
94 jpm 871
                    if (isset($package['max']) && isset($package['min'])) {
872
                        $info[$infoindex] .= " \n  Versions " .
873
                            $package['min'] . '-' . $package['max'];
874
                    } elseif (isset($package['min'])) {
875
                        $info[$infoindex] .= " \n  Version " .
876
                            $package['min'] . ' or newer';
877
                    } elseif (isset($package['max'])) {
878
                        $info[$infoindex] .= " \n  Version " .
879
                            $package['max'] . ' or older';
880
                    }
187 mathias 881
 
94 jpm 882
                    if (isset($package['recommended'])) {
883
                        $info[$infoindex] .= "\n  Recommended version: $package[recommended]";
884
                    }
187 mathias 885
 
94 jpm 886
                    if (isset($package['exclude'])) {
887
                        if (!isset($info['Not Compatible with'])) {
888
                            $info['Not Compatible with'] = '';
889
                        } else {
890
                            $info['Not Compatible with'] .= "\n";
891
                        }
187 mathias 892
 
94 jpm 893
                        if (is_array($package['exclude'])) {
894
                            $package['exclude'] = implode(', ', $package['exclude']);
895
                        }
187 mathias 896
 
94 jpm 897
                        $package['package'] = $package['name']; // for parsedPackageNameToString
898
                         if (isset($package['conflicts'])) {
899
                            $info['Not Compatible with'] .= '=> except ';
900
                        }
901
                       $info['Not Compatible with'] .= 'Package ' .
902
                            $reg->parsedPackageNameToString($package, true);
903
                        $info['Not Compatible with'] .= "\n  Versions " . $package['exclude'];
904
                    }
905
                }
906
            }
907
        }
187 mathias 908
 
94 jpm 909
        if (isset($deps['required']['os'])) {
910
            if (isset($deps['required']['os']['name'])) {
911
                $dep['required']['os']['name'] = array($dep['required']['os']['name']);
912
            }
187 mathias 913
 
94 jpm 914
            foreach ($dep['required']['os'] as $os) {
915
                if (isset($os['conflicts']) && $os['conflicts'] == 'yes') {
916
                    if (!isset($info['Not Compatible with'])) {
917
                        $info['Not Compatible with'] = '';
918
                    } else {
919
                        $info['Not Compatible with'] .= "\n";
920
                    }
921
                    $info['Not Compatible with'] .= "$os[name] Operating System";
922
                } else {
923
                    $info['Required Dependencies'] .= "\n";
924
                    $info['Required Dependencies'] .= "$os[name] Operating System";
925
                }
926
            }
927
        }
187 mathias 928
 
94 jpm 929
        if (isset($deps['required']['arch'])) {
930
            if (isset($deps['required']['arch']['pattern'])) {
931
                $dep['required']['arch']['pattern'] = array($dep['required']['os']['pattern']);
932
            }
187 mathias 933
 
94 jpm 934
            foreach ($dep['required']['arch'] as $os) {
935
                if (isset($os['conflicts']) && $os['conflicts'] == 'yes') {
936
                    if (!isset($info['Not Compatible with'])) {
937
                        $info['Not Compatible with'] = '';
938
                    } else {
939
                        $info['Not Compatible with'] .= "\n";
940
                    }
941
                    $info['Not Compatible with'] .= "OS/Arch matching pattern '/$os[pattern]/'";
942
                } else {
943
                    $info['Required Dependencies'] .= "\n";
944
                    $info['Required Dependencies'] .= "OS/Arch matching pattern '/$os[pattern]/'";
945
                }
946
            }
947
        }
187 mathias 948
 
94 jpm 949
        if (isset($deps['optional'])) {
950
            foreach (array('Package', 'Extension') as $type) {
951
                $index = strtolower($type);
952
                if (isset($deps['optional'][$index])) {
953
                    if (isset($deps['optional'][$index]['name'])) {
954
                        $deps['optional'][$index] = array($deps['optional'][$index]);
955
                    }
187 mathias 956
 
94 jpm 957
                    foreach ($deps['optional'][$index] as $package) {
958
                        if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
959
                            $infoindex = 'Not Compatible with';
960
                            if (!isset($info['Not Compatible with'])) {
961
                                $info['Not Compatible with'] = '';
962
                            } else {
963
                                $info['Not Compatible with'] .= "\n";
964
                            }
965
                        } else {
966
                            $infoindex = 'Optional Dependencies';
967
                            if (!isset($info['Optional Dependencies'])) {
968
                                $info['Optional Dependencies'] = '';
969
                            } else {
970
                                $info['Optional Dependencies'] .= "\n";
971
                            }
972
                        }
187 mathias 973
 
94 jpm 974
                        if ($index == 'extension') {
975
                            $name = $package['name'];
976
                        } else {
977
                            if (isset($package['channel'])) {
978
                                $name = $package['channel'] . '/' . $package['name'];
979
                            } else {
980
                                $name = '__uri/' . $package['name'] . ' (static URI)';
981
                            }
982
                        }
187 mathias 983
 
94 jpm 984
                        $info[$infoindex] .= "$type $name";
985
                        if (isset($package['uri'])) {
986
                            $info[$infoindex] .= "\n  Download URI: $package[uri]";
987
                            continue;
988
                        }
187 mathias 989
 
94 jpm 990
                        if ($infoindex == 'Not Compatible with') {
991
                            // conflicts is only used to say that all versions conflict
992
                            continue;
993
                        }
187 mathias 994
 
94 jpm 995
                        if (isset($package['max']) && isset($package['min'])) {
996
                            $info[$infoindex] .= " \n  Versions " .
997
                                $package['min'] . '-' . $package['max'];
998
                        } elseif (isset($package['min'])) {
999
                            $info[$infoindex] .= " \n  Version " .
1000
                                $package['min'] . ' or newer';
1001
                        } elseif (isset($package['max'])) {
1002
                            $info[$infoindex] .= " \n  Version " .
1003
                                $package['min'] . ' or older';
1004
                        }
187 mathias 1005
 
94 jpm 1006
                        if (isset($package['recommended'])) {
1007
                            $info[$infoindex] .= "\n  Recommended version: $package[recommended]";
1008
                        }
187 mathias 1009
 
94 jpm 1010
                        if (isset($package['exclude'])) {
1011
                            if (!isset($info['Not Compatible with'])) {
1012
                                $info['Not Compatible with'] = '';
1013
                            } else {
1014
                                $info['Not Compatible with'] .= "\n";
1015
                            }
187 mathias 1016
 
94 jpm 1017
                            if (is_array($package['exclude'])) {
1018
                                $package['exclude'] = implode(', ', $package['exclude']);
1019
                            }
187 mathias 1020
 
94 jpm 1021
                            $info['Not Compatible with'] .= "Package $package\n  Versions " .
1022
                                $package['exclude'];
1023
                        }
1024
                    }
1025
                }
1026
            }
1027
        }
187 mathias 1028
 
94 jpm 1029
        if (isset($deps['group'])) {
1030
            if (!isset($deps['group'][0])) {
1031
                $deps['group'] = array($deps['group']);
1032
            }
187 mathias 1033
 
94 jpm 1034
            foreach ($deps['group'] as $group) {
1035
                $info['Dependency Group ' . $group['attribs']['name']] = $group['attribs']['hint'];
1036
                $groupindex = $group['attribs']['name'] . ' Contents';
1037
                $info[$groupindex] = '';
1038
                foreach (array('Package', 'Extension') as $type) {
1039
                    $index = strtolower($type);
1040
                    if (isset($group[$index])) {
1041
                        if (isset($group[$index]['name'])) {
1042
                            $group[$index] = array($group[$index]);
1043
                        }
187 mathias 1044
 
94 jpm 1045
                        foreach ($group[$index] as $package) {
1046
                            if (!empty($info[$groupindex])) {
1047
                                $info[$groupindex] .= "\n";
1048
                            }
187 mathias 1049
 
94 jpm 1050
                            if ($index == 'extension') {
1051
                                $name = $package['name'];
1052
                            } else {
1053
                                if (isset($package['channel'])) {
1054
                                    $name = $package['channel'] . '/' . $package['name'];
1055
                                } else {
1056
                                    $name = '__uri/' . $package['name'] . ' (static URI)';
1057
                                }
1058
                            }
187 mathias 1059
 
94 jpm 1060
                            if (isset($package['uri'])) {
1061
                                if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
1062
                                    $info[$groupindex] .= "Not Compatible with $type $name";
1063
                                } else {
1064
                                    $info[$groupindex] .= "$type $name";
1065
                                }
187 mathias 1066
 
94 jpm 1067
                                $info[$groupindex] .= "\n  Download URI: $package[uri]";
1068
                                continue;
1069
                            }
187 mathias 1070
 
94 jpm 1071
                            if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
1072
                                $info[$groupindex] .= "Not Compatible with $type $name";
1073
                                continue;
1074
                            }
187 mathias 1075
 
94 jpm 1076
                            $info[$groupindex] .= "$type $name";
1077
                            if (isset($package['max']) && isset($package['min'])) {
1078
                                $info[$groupindex] .= " \n  Versions " .
1079
                                    $package['min'] . '-' . $package['max'];
1080
                            } elseif (isset($package['min'])) {
1081
                                $info[$groupindex] .= " \n  Version " .
1082
                                    $package['min'] . ' or newer';
1083
                            } elseif (isset($package['max'])) {
1084
                                $info[$groupindex] .= " \n  Version " .
1085
                                    $package['min'] . ' or older';
1086
                            }
187 mathias 1087
 
94 jpm 1088
                            if (isset($package['recommended'])) {
1089
                                $info[$groupindex] .= "\n  Recommended version: $package[recommended]";
1090
                            }
187 mathias 1091
 
94 jpm 1092
                            if (isset($package['exclude'])) {
1093
                                if (!isset($info['Not Compatible with'])) {
1094
                                    $info['Not Compatible with'] = '';
1095
                                } else {
1096
                                    $info[$groupindex] .= "Not Compatible with\n";
1097
                                }
187 mathias 1098
 
94 jpm 1099
                                if (is_array($package['exclude'])) {
1100
                                    $package['exclude'] = implode(', ', $package['exclude']);
1101
                                }
1102
                                $info[$groupindex] .= "  Package $package\n  Versions " .
1103
                                    $package['exclude'];
1104
                            }
1105
                        }
1106
                    }
1107
                }
1108
            }
1109
        }
187 mathias 1110
 
94 jpm 1111
        if ($obj->getPackageType() == 'bundle') {
1112
            $info['Bundled Packages'] = '';
1113
            foreach ($obj->getBundledPackages() as $package) {
1114
                if (!empty($info['Bundled Packages'])) {
1115
                    $info['Bundled Packages'] .= "\n";
1116
                }
187 mathias 1117
 
94 jpm 1118
                if (isset($package['uri'])) {
1119
                    $info['Bundled Packages'] .= '__uri/' . $package['name'];
1120
                    $info['Bundled Packages'] .= "\n  (URI: $package[uri]";
1121
                } else {
1122
                    $info['Bundled Packages'] .= $package['channel'] . '/' . $package['name'];
1123
                }
1124
            }
1125
        }
187 mathias 1126
 
94 jpm 1127
        $info['package.xml version'] = '2.0';
1128
        if ($installed) {
1129
            if ($obj->getLastModified()) {
1130
                $info['Last Modified'] = date('Y-m-d H:i', $obj->getLastModified());
1131
            }
187 mathias 1132
 
94 jpm 1133
            $v = $obj->getLastInstalledVersion();
1134
            $info['Previous Installed Version'] = $v ? $v : '- None -';
1135
        }
187 mathias 1136
 
94 jpm 1137
        foreach ($info as $key => $value) {
1138
            $data['data'][] = array($key, $value);
1139
        }
187 mathias 1140
 
94 jpm 1141
        $data['raw'] = $obj->getArray(); // no validation needed
1142
        $this->ui->outputData($data, 'package-info');
1143
    }
1144
}