Хранилища Subversion ant

Редакция

К новейшей редакции | Содержимое файла | Последнее изменение | Открыть журнал | RSS

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