Хранилища Subversion ant

Редакция

Редакция 69 | Только различия | Не учитывать пробелы | Содержимое файла | Авторство | Последнее изменение | Открыть журнал | RSS

Редакция 69 Редакция 87
1
<?php
1
<?php
2
/**
2
/**
3
 * PEAR_PackageFile_v2, package.xml version 2.0
3
 * PEAR_PackageFile_v2, package.xml version 2.0
4
 *
4
 *
5
 * PHP versions 4 and 5
5
 * PHP versions 4 and 5
6
 *
6
 *
7
 * LICENSE: This source file is subject to version 3.0 of the PHP license
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:
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
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
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.
11
 * send a note to license@php.net so we can mail you a copy immediately.
12
 *
12
 *
13
 * @category   pear
13
 * @category   pear
14
 * @package    PEAR
14
 * @package    PEAR
15
 * @author     Greg Beaver <cellog@php.net>
15
 * @author     Greg Beaver <cellog@php.net>
16
 * @copyright  1997-2008 The PHP Group
16
 * @copyright  1997-2008 The PHP Group
17
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
17
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
18
 * @version    CVS: $Id: v2.php,v 1.143 2008/05/13 05:28:51 cellog Exp $
18
 * @version    CVS: $Id: v2.php,v 1.143 2008/05/13 05:28:51 cellog Exp $
19
 * @link       http://pear.php.net/package/PEAR
19
 * @link       http://pear.php.net/package/PEAR
20
 * @since      File available since Release 1.4.0a1
20
 * @since      File available since Release 1.4.0a1
21
 */
21
 */
22
/**
22
/**
23
 * For error handling
23
 * For error handling
24
 */
24
 */
25
require_once 'PEAR/ErrorStack.php';
25
require_once 'PEAR/ErrorStack.php';
26
/**
26
/**
27
 * @category   pear
27
 * @category   pear
28
 * @package    PEAR
28
 * @package    PEAR
29
 * @author     Greg Beaver <cellog@php.net>
29
 * @author     Greg Beaver <cellog@php.net>
30
 * @copyright  1997-2008 The PHP Group
30
 * @copyright  1997-2008 The PHP Group
31
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
31
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
32
 * @version    Release: 1.7.2
32
 * @version    Release: 1.7.2
33
 * @link       http://pear.php.net/package/PEAR
33
 * @link       http://pear.php.net/package/PEAR
34
 * @since      Class available since Release 1.4.0a1
34
 * @since      Class available since Release 1.4.0a1
35
 */
35
 */
36
class PEAR_PackageFile_v2
36
class PEAR_PackageFile_v2
37
{
37
{
38
38
39
    /**
39
    /**
40
     * Parsed package information
40
     * Parsed package information
41
     * @var array
41
     * @var array
42
     * @access private
42
     * @access private
43
     */
43
     */
44
    var $_packageInfo = array();
44
    var $_packageInfo = array();
45
45
46
    /**
46
    /**
47
     * path to package .tgz or false if this is a local/extracted package.xml
47
     * path to package .tgz or false if this is a local/extracted package.xml
48
     * @var string|false
48
     * @var string|false
49
     * @access private
49
     * @access private
50
     */
50
     */
51
    var $_archiveFile;
51
    var $_archiveFile;
52
52
53
    /**
53
    /**
54
     * path to package .xml or false if this is an abstract parsed-from-string xml
54
     * path to package .xml or false if this is an abstract parsed-from-string xml
55
     * @var string|false
55
     * @var string|false
56
     * @access private
56
     * @access private
57
     */
57
     */
58
    var $_packageFile;
58
    var $_packageFile;
59
59
60
    /**
60
    /**
61
     * This is used by file analysis routines to log progress information
61
     * This is used by file analysis routines to log progress information
62
     * @var PEAR_Common
62
     * @var PEAR_Common
63
     * @access protected
63
     * @access protected
64
     */
64
     */
65
    var $_logger;
65
    var $_logger;
66
66
67
    /**
67
    /**
68
     * This is set to the highest validation level that has been validated
68
     * This is set to the highest validation level that has been validated
69
     *
69
     *
70
     * If the package.xml is invalid or unknown, this is set to 0.  If
70
     * If the package.xml is invalid or unknown, this is set to 0.  If
71
     * normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL.  If
71
     * normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL.  If
72
     * downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING
72
     * downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING
73
     * or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING.  This allows validation
73
     * or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING.  This allows validation
74
     * "caching" to occur, which is particularly important for package validation, so
74
     * "caching" to occur, which is particularly important for package validation, so
75
     * that PHP files are not validated twice
75
     * that PHP files are not validated twice
76
     * @var int
76
     * @var int
77
     * @access private
77
     * @access private
78
     */
78
     */
79
    var $_isValid = 0;
79
    var $_isValid = 0;
80
80
81
    /**
81
    /**
82
     * True if the filelist has been validated
82
     * True if the filelist has been validated
83
     * @param bool
83
     * @param bool
84
     */
84
     */
85
    var $_filesValid = false;
85
    var $_filesValid = false;
86
86
87
    /**
87
    /**
88
     * @var PEAR_Registry
88
     * @var PEAR_Registry
89
     * @access protected
89
     * @access protected
90
     */
90
     */
91
    var $_registry;
91
    var $_registry;
92
92
93
    /**
93
    /**
94
     * @var PEAR_Config
94
     * @var PEAR_Config
95
     * @access protected
95
     * @access protected
96
     */
96
     */
97
    var $_config;
97
    var $_config;
98
98
99
    /**
99
    /**
100
     * Optional Dependency group requested for installation
100
     * Optional Dependency group requested for installation
101
     * @var string
101
     * @var string
102
     * @access private
102
     * @access private
103
     */
103
     */
104
    var $_requestedGroup = false;
104
    var $_requestedGroup = false;
105
105
106
    /**
106
    /**
107
     * @var PEAR_ErrorStack
107
     * @var PEAR_ErrorStack
108
     * @access protected
108
     * @access protected
109
     */
109
     */
110
    var $_stack;
110
    var $_stack;
111
111
112
    /**
112
    /**
113
     * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible
113
     * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible
114
     */
114
     */
115
    var $_tasksNs;
115
    var $_tasksNs;
116
116
117
    /**
117
    /**
118
     * Determines whether this packagefile was initialized only with partial package info
118
     * Determines whether this packagefile was initialized only with partial package info
119
     *
119
     *
120
     * If this package file was constructed via parsing REST, it will only contain
120
     * If this package file was constructed via parsing REST, it will only contain
121
     *
121
     *
122
     * - package name
122
     * - package name
123
     * - channel name
123
     * - channel name
124
     * - dependencies
124
     * - dependencies
125
     * @var boolean
125
     * @var boolean
126
     * @access private
126
     * @access private
127
     */
127
     */
128
    var $_incomplete = true;
128
    var $_incomplete = true;
129
129
130
    /**
130
    /**
131
     * @var PEAR_PackageFile_v2_Validator
131
     * @var PEAR_PackageFile_v2_Validator
132
     */
132
     */
133
    var $_v2Validator;
133
    var $_v2Validator;
134
134
135
    /**
135
    /**
136
     * The constructor merely sets up the private error stack
136
     * The constructor merely sets up the private error stack
137
     */
137
     */
138
    function PEAR_PackageFile_v2()
138
    function PEAR_PackageFile_v2()
139
    {
139
    {
140
        $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null);
140
        $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null);
141
        $this->_isValid = false;
141
        $this->_isValid = false;
142
    }
142
    }
143
143
144
    /**
144
    /**
145
     * To make unit-testing easier
145
     * To make unit-testing easier
146
     * @param PEAR_Frontend_*
146
     * @param PEAR_Frontend_*
147
     * @param array options
147
     * @param array options
148
     * @param PEAR_Config
148
     * @param PEAR_Config
149
     * @return PEAR_Downloader
149
     * @return PEAR_Downloader
150
     * @access protected
150
     * @access protected
151
     */
151
     */
152
    function &getPEARDownloader(&$i, $o, &$c)
152
    function &getPEARDownloader(&$i, $o, &$c)
153
    {
153
    {
154
        $z = &new PEAR_Downloader($i, $o, $c);
154
        $z = &new PEAR_Downloader($i, $o, $c);
155
        return $z;
155
        return $z;
156
    }
156
    }
157
157
158
    /**
158
    /**
159
     * To make unit-testing easier
159
     * To make unit-testing easier
160
     * @param PEAR_Config
160
     * @param PEAR_Config
161
     * @param array options
161
     * @param array options
162
     * @param array package name as returned from {@link PEAR_Registry::parsePackageName()}
162
     * @param array package name as returned from {@link PEAR_Registry::parsePackageName()}
163
     * @param int PEAR_VALIDATE_* constant
163
     * @param int PEAR_VALIDATE_* constant
164
     * @return PEAR_Dependency2
164
     * @return PEAR_Dependency2
165
     * @access protected
165
     * @access protected
166
     */
166
     */
167
    function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING)
167
    function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING)
168
    {
168
    {
169
        if (!class_exists('PEAR_Dependency2')) {
169
        if (!class_exists('PEAR_Dependency2')) {
170
            require_once 'PEAR/Dependency2.php';
170
            require_once 'PEAR/Dependency2.php';
171
        }
171
        }
172
        $z = &new PEAR_Dependency2($c, $o, $p, $s);
172
        $z = &new PEAR_Dependency2($c, $o, $p, $s);
173
        return $z;
173
        return $z;
174
    }
174
    }
175
175
176
    function getInstalledBinary()
176
    function getInstalledBinary()
177
    {
177
    {
178
        return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] :
178
        return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] :
179
            false;
179
            false;
180
    }
180
    }
181
181
182
    /**
182
    /**
183
     * Installation of source package has failed, attempt to download and install the
183
     * Installation of source package has failed, attempt to download and install the
184
     * binary version of this package.
184
     * binary version of this package.
185
     * @param PEAR_Installer
185
     * @param PEAR_Installer
186
     * @return array|false
186
     * @return array|false
187
     */
187
     */
188
    function installBinary(&$installer)
188
    function installBinary(&$installer)
189
    {
189
    {
190
        if (!OS_WINDOWS) {
190
        if (!OS_WINDOWS) {
191
            $a = false;
191
            $a = false;
192
            return $a;
192
            return $a;
193
        }
193
        }
194
        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
194
        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
195
            $releasetype = $this->getPackageType() . 'release';
195
            $releasetype = $this->getPackageType() . 'release';
196
            if (!is_array($installer->getInstallPackages())) {
196
            if (!is_array($installer->getInstallPackages())) {
197
                $a = false;
197
                $a = false;
198
                return $a;
198
                return $a;
199
            }
199
            }
200
            foreach ($installer->getInstallPackages() as $p) {
200
            foreach ($installer->getInstallPackages() as $p) {
201
                if ($p->isExtension($this->_packageInfo['providesextension'])) {
201
                if ($p->isExtension($this->_packageInfo['providesextension'])) {
202
                    if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') {
202
                    if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') {
203
                        $a = false;
203
                        $a = false;
204
                        return $a; // the user probably downloaded it separately
204
                        return $a; // the user probably downloaded it separately
205
                    }
205
                    }
206
                }
206
                }
207
            }
207
            }
208
            if (isset($this->_packageInfo[$releasetype]['binarypackage'])) {
208
            if (isset($this->_packageInfo[$releasetype]['binarypackage'])) {
209
                $installer->log(0, 'Attempting to download binary version of extension "' .
209
                $installer->log(0, 'Attempting to download binary version of extension "' .
210
                    $this->_packageInfo['providesextension'] . '"');
210
                    $this->_packageInfo['providesextension'] . '"');
211
                $params = $this->_packageInfo[$releasetype]['binarypackage'];
211
                $params = $this->_packageInfo[$releasetype]['binarypackage'];
212
                if (!is_array($params) || !isset($params[0])) {
212
                if (!is_array($params) || !isset($params[0])) {
213
                    $params = array($params);
213
                    $params = array($params);
214
                }
214
                }
215
                if (isset($this->_packageInfo['channel'])) {
215
                if (isset($this->_packageInfo['channel'])) {
216
                    foreach ($params as $i => $param) {
216
                    foreach ($params as $i => $param) {
217
                        $params[$i] = array('channel' => $this->_packageInfo['channel'],
217
                        $params[$i] = array('channel' => $this->_packageInfo['channel'],
218
                            'package' => $param, 'version' => $this->getVersion());
218
                            'package' => $param, 'version' => $this->getVersion());
219
                    }
219
                    }
220
                }
220
                }
221
                $dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(),
221
                $dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(),
222
                    $installer->config);
222
                    $installer->config);
223
                $verbose = $dl->config->get('verbose');
223
                $verbose = $dl->config->get('verbose');
224
                $dl->config->set('verbose', -1);
224
                $dl->config->set('verbose', -1);
225
                foreach ($params as $param) {
225
                foreach ($params as $param) {
226
                    PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
226
                    PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
227
                    $ret = $dl->download(array($param));
227
                    $ret = $dl->download(array($param));
228
                    PEAR::popErrorHandling();
228
                    PEAR::popErrorHandling();
229
                    if (is_array($ret) && count($ret)) {
229
                    if (is_array($ret) && count($ret)) {
230
                        break;
230
                        break;
231
                    }
231
                    }
232
                }
232
                }
233
                $dl->config->set('verbose', $verbose);
233
                $dl->config->set('verbose', $verbose);
234
                if (is_array($ret)) {
234
                if (is_array($ret)) {
235
                    if (count($ret) == 1) {
235
                    if (count($ret) == 1) {
236
                        $pf = $ret[0]->getPackageFile();
236
                        $pf = $ret[0]->getPackageFile();
237
                        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
237
                        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
238
                        $err = $installer->install($ret[0]);
238
                        $err = $installer->install($ret[0]);
239
                        PEAR::popErrorHandling();
239
                        PEAR::popErrorHandling();
240
                        if (is_array($err)) {
240
                        if (is_array($err)) {
241
                            $this->_packageInfo['#binarypackage'] = $ret[0]->getPackage();
241
                            $this->_packageInfo['#binarypackage'] = $ret[0]->getPackage();
242
                            // "install" self, so all dependencies will work transparently
242
                            // "install" self, so all dependencies will work transparently
243
                            $this->_registry->addPackage2($this);
243
                            $this->_registry->addPackage2($this);
244
                            $installer->log(0, 'Download and install of binary extension "' .
244
                            $installer->log(0, 'Download and install of binary extension "' .
245
                                $this->_registry->parsedPackageNameToString(
245
                                $this->_registry->parsedPackageNameToString(
246
                                    array('channel' => $pf->getChannel(),
246
                                    array('channel' => $pf->getChannel(),
247
                                          'package' => $pf->getPackage()), true) . '" successful');
247
                                          'package' => $pf->getPackage()), true) . '" successful');
248
                            $a = array($ret[0], $err);
248
                            $a = array($ret[0], $err);
249
                            return $a;
249
                            return $a;
250
                        }
250
                        }
251
                        $installer->log(0, 'Download and install of binary extension "' .
251
                        $installer->log(0, 'Download and install of binary extension "' .
252
                            $this->_registry->parsedPackageNameToString(
252
                            $this->_registry->parsedPackageNameToString(
253
                                    array('channel' => $pf->getChannel(),
253
                                    array('channel' => $pf->getChannel(),
254
                                          'package' => $pf->getPackage()), true) . '" failed');
254
                                          'package' => $pf->getPackage()), true) . '" failed');
255
                    }
255
                    }
256
                }
256
                }
257
            }
257
            }
258
        }
258
        }
259
        $a = false;
259
        $a = false;
260
        return $a;
260
        return $a;
261
    }
261
    }
262
262
263
    /**
263
    /**
264
     * @return string|false Extension name
264
     * @return string|false Extension name
265
     */
265
     */
266
    function getProvidesExtension()
266
    function getProvidesExtension()
267
    {
267
    {
268
        if (in_array($this->getPackageType(),
268
        if (in_array($this->getPackageType(),
269
              array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
269
              array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
270
            if (isset($this->_packageInfo['providesextension'])) {
270
            if (isset($this->_packageInfo['providesextension'])) {
271
                return $this->_packageInfo['providesextension'];
271
                return $this->_packageInfo['providesextension'];
272
            }
272
            }
273
        }
273
        }
274
        return false;
274
        return false;
275
    }
275
    }
276
276
277
    /**
277
    /**
278
     * @param string Extension name
278
     * @param string Extension name
279
     * @return bool
279
     * @return bool
280
     */
280
     */
281
    function isExtension($extension)
281
    function isExtension($extension)
282
    {
282
    {
283
        if (in_array($this->getPackageType(),
283
        if (in_array($this->getPackageType(),
284
              array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
284
              array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
285
            return $this->_packageInfo['providesextension'] == $extension;
285
            return $this->_packageInfo['providesextension'] == $extension;
286
        }
286
        }
287
        return false;
287
        return false;
288
    }
288
    }
289
289
290
    /**
290
    /**
291
     * Tests whether every part of the package.xml 1.0 is represented in
291
     * Tests whether every part of the package.xml 1.0 is represented in
292
     * this package.xml 2.0
292
     * this package.xml 2.0
293
     * @param PEAR_PackageFile_v1
293
     * @param PEAR_PackageFile_v1
294
     * @return bool
294
     * @return bool
295
     */
295
     */
296
    function isEquivalent($pf1)
296
    function isEquivalent($pf1)
297
    {
297
    {
298
        if (!$pf1) {
298
        if (!$pf1) {
299
            return true;
299
            return true;
300
        }
300
        }
301
        if ($this->getPackageType() == 'bundle') {
301
        if ($this->getPackageType() == 'bundle') {
302
            return false;
302
            return false;
303
        }
303
        }
304
        $this->_stack->getErrors(true);
304
        $this->_stack->getErrors(true);
305
        if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) {
305
        if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) {
306
            return false;
306
            return false;
307
        }
307
        }
308
        $pass = true;
308
        $pass = true;
309
        if ($pf1->getPackage() != $this->getPackage()) {
309
        if ($pf1->getPackage() != $this->getPackage()) {
310
            $this->_differentPackage($pf1->getPackage());
310
            $this->_differentPackage($pf1->getPackage());
311
            $pass = false;
311
            $pass = false;
312
        }
312
        }
313
        if ($pf1->getVersion() != $this->getVersion()) {
313
        if ($pf1->getVersion() != $this->getVersion()) {
314
            $this->_differentVersion($pf1->getVersion());
314
            $this->_differentVersion($pf1->getVersion());
315
            $pass = false;
315
            $pass = false;
316
        }
316
        }
317
        if (trim($pf1->getSummary()) != $this->getSummary()) {
317
        if (trim($pf1->getSummary()) != $this->getSummary()) {
318
            $this->_differentSummary($pf1->getSummary());
318
            $this->_differentSummary($pf1->getSummary());
319
            $pass = false;
319
            $pass = false;
320
        }
320
        }
321
        if (preg_replace('/\s+/', '', $pf1->getDescription()) !=
321
        if (preg_replace('/\s+/', '', $pf1->getDescription()) !=
322
              preg_replace('/\s+/', '', $this->getDescription())) {
322
              preg_replace('/\s+/', '', $this->getDescription())) {
323
            $this->_differentDescription($pf1->getDescription());
323
            $this->_differentDescription($pf1->getDescription());
324
            $pass = false;
324
            $pass = false;
325
        }
325
        }
326
        if ($pf1->getState() != $this->getState()) {
326
        if ($pf1->getState() != $this->getState()) {
327
            $this->_differentState($pf1->getState());
327
            $this->_differentState($pf1->getState());
328
            $pass = false;
328
            $pass = false;
329
        }
329
        }
330
        if (!strstr(preg_replace('/\s+/', '', $this->getNotes()),
330
        if (!strstr(preg_replace('/\s+/', '', $this->getNotes()),
331
              preg_replace('/\s+/', '', $pf1->getNotes()))) {
331
              preg_replace('/\s+/', '', $pf1->getNotes()))) {
332
            $this->_differentNotes($pf1->getNotes());
332
            $this->_differentNotes($pf1->getNotes());
333
            $pass = false;
333
            $pass = false;
334
        }
334
        }
335
        $mymaintainers = $this->getMaintainers();
335
        $mymaintainers = $this->getMaintainers();
336
        $yourmaintainers = $pf1->getMaintainers();
336
        $yourmaintainers = $pf1->getMaintainers();
337
        for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) {
337
        for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) {
338
            $reset = false;
338
            $reset = false;
339
            for ($i2 = 0; $i2 < count($mymaintainers); $i2++) {
339
            for ($i2 = 0; $i2 < count($mymaintainers); $i2++) {
340
                if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) {
340
                if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) {
341
                    if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) {
341
                    if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) {
342
                        $this->_differentRole($mymaintainers[$i2]['handle'],
342
                        $this->_differentRole($mymaintainers[$i2]['handle'],
343
                            $yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']);
343
                            $yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']);
344
                        $pass = false;
344
                        $pass = false;
345
                    }
345
                    }
346
                    if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) {
346
                    if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) {
347
                        $this->_differentEmail($mymaintainers[$i2]['handle'],
347
                        $this->_differentEmail($mymaintainers[$i2]['handle'],
348
                            $yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']);
348
                            $yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']);
349
                        $pass = false;
349
                        $pass = false;
350
                    }
350
                    }
351
                    if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) {
351
                    if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) {
352
                        $this->_differentName($mymaintainers[$i2]['handle'],
352
                        $this->_differentName($mymaintainers[$i2]['handle'],
353
                            $yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']);
353
                            $yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']);
354
                        $pass = false;
354
                        $pass = false;
355
                    }
355
                    }
356
                    unset($mymaintainers[$i2]);
356
                    unset($mymaintainers[$i2]);
357
                    $mymaintainers = array_values($mymaintainers);
357
                    $mymaintainers = array_values($mymaintainers);
358
                    unset($yourmaintainers[$i1]);
358
                    unset($yourmaintainers[$i1]);
359
                    $yourmaintainers = array_values($yourmaintainers);
359
                    $yourmaintainers = array_values($yourmaintainers);
360
                    $reset = true;
360
                    $reset = true;
361
                    break;
361
                    break;
362
                }
362
                }
363
            }
363
            }
364
            if ($reset) {
364
            if ($reset) {
365
                $i1 = -1;
365
                $i1 = -1;
366
            }
366
            }
367
        }
367
        }
368
        $this->_unmatchedMaintainers($mymaintainers, $yourmaintainers);
368
        $this->_unmatchedMaintainers($mymaintainers, $yourmaintainers);
369
        $filelist = $this->getFilelist();
369
        $filelist = $this->getFilelist();
370
        foreach ($pf1->getFilelist() as $file => $atts) {
370
        foreach ($pf1->getFilelist() as $file => $atts) {
371
            if (!isset($filelist[$file])) {
371
            if (!isset($filelist[$file])) {
372
                $this->_missingFile($file);
372
                $this->_missingFile($file);
373
                $pass = false;
373
                $pass = false;
374
            }
374
            }
375
        }
375
        }
376
        return $pass;
376
        return $pass;
377
    }
377
    }
378
378
379
    function _differentPackage($package)
379
    function _differentPackage($package)
380
    {
380
    {
381
        $this->_stack->push(__FUNCTION__, 'error', array('package' => $package,
381
        $this->_stack->push(__FUNCTION__, 'error', array('package' => $package,
382
            'self' => $this->getPackage()),
382
            'self' => $this->getPackage()),
383
            'package.xml 1.0 package "%package%" does not match "%self%"');
383
            'package.xml 1.0 package "%package%" does not match "%self%"');
384
    }
384
    }
385
385
386
    function _differentVersion($version)
386
    function _differentVersion($version)
387
    {
387
    {
388
        $this->_stack->push(__FUNCTION__, 'error', array('version' => $version,
388
        $this->_stack->push(__FUNCTION__, 'error', array('version' => $version,
389
            'self' => $this->getVersion()),
389
            'self' => $this->getVersion()),
390
            'package.xml 1.0 version "%version%" does not match "%self%"');
390
            'package.xml 1.0 version "%version%" does not match "%self%"');
391
    }
391
    }
392
392
393
    function _differentState($state)
393
    function _differentState($state)
394
    {
394
    {
395
        $this->_stack->push(__FUNCTION__, 'error', array('state' => $state,
395
        $this->_stack->push(__FUNCTION__, 'error', array('state' => $state,
396
            'self' => $this->getState()),
396
            'self' => $this->getState()),
397
            'package.xml 1.0 state "%state%" does not match "%self%"');
397
            'package.xml 1.0 state "%state%" does not match "%self%"');
398
    }
398
    }
399
399
400
    function _differentRole($handle, $role, $selfrole)
400
    function _differentRole($handle, $role, $selfrole)
401
    {
401
    {
402
        $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
402
        $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
403
            'role' => $role, 'self' => $selfrole),
403
            'role' => $role, 'self' => $selfrole),
404
            'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"');
404
            'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"');
405
    }
405
    }
406
406
407
    function _differentEmail($handle, $email, $selfemail)
407
    function _differentEmail($handle, $email, $selfemail)
408
    {
408
    {
409
        $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
409
        $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
410
            'email' => $email, 'self' => $selfemail),
410
            'email' => $email, 'self' => $selfemail),
411
            'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"');
411
            'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"');
412
    }
412
    }
413
413
414
    function _differentName($handle, $name, $selfname)
414
    function _differentName($handle, $name, $selfname)
415
    {
415
    {
416
        $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
416
        $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
417
            'name' => $name, 'self' => $selfname),
417
            'name' => $name, 'self' => $selfname),
418
            'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"');
418
            'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"');
419
    }
419
    }
420
420
421
    function _unmatchedMaintainers($my, $yours)
421
    function _unmatchedMaintainers($my, $yours)
422
    {
422
    {
423
        if ($my) {
423
        if ($my) {
424
            array_walk($my, create_function('&$i, $k', '$i = $i["handle"];'));
424
            array_walk($my, create_function('&$i, $k', '$i = $i["handle"];'));
425
            $this->_stack->push(__FUNCTION__, 'error', array('handles' => $my),
425
            $this->_stack->push(__FUNCTION__, 'error', array('handles' => $my),
426
                'package.xml 2.0 has unmatched extra maintainers "%handles%"');
426
                'package.xml 2.0 has unmatched extra maintainers "%handles%"');
427
        }
427
        }
428
        if ($yours) {
428
        if ($yours) {
429
            array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];'));
429
            array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];'));
430
            $this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours),
430
            $this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours),
431
                'package.xml 1.0 has unmatched extra maintainers "%handles%"');
431
                'package.xml 1.0 has unmatched extra maintainers "%handles%"');
432
        }
432
        }
433
    }
433
    }
434
434
435
    function _differentNotes($notes)
435
    function _differentNotes($notes)
436
    {
436
    {
437
        $truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0, 24) . '...';
437
        $truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0, 24) . '...';
438
        $truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() :
438
        $truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() :
439
            substr($this->getNotes(), 0, 24) . '...';
439
            substr($this->getNotes(), 0, 24) . '...';
440
        $this->_stack->push(__FUNCTION__, 'error', array('notes' => $truncnotes,
440
        $this->_stack->push(__FUNCTION__, 'error', array('notes' => $truncnotes,
441
            'self' => $truncmynotes),
441
            'self' => $truncmynotes),
442
            'package.xml 1.0 release notes "%notes%" do not match "%self%"');
442
            'package.xml 1.0 release notes "%notes%" do not match "%self%"');
443
    }
443
    }
444
444
445
    function _differentSummary($summary)
445
    function _differentSummary($summary)
446
    {
446
    {
447
        $truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0, 24) . '...';
447
        $truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0, 24) . '...';
448
        $truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() :
448
        $truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() :
449
            substr($this->getsummary(), 0, 24) . '...';
449
            substr($this->getsummary(), 0, 24) . '...';
450
        $this->_stack->push(__FUNCTION__, 'error', array('summary' => $truncsummary,
450
        $this->_stack->push(__FUNCTION__, 'error', array('summary' => $truncsummary,
451
            'self' => $truncmysummary),
451
            'self' => $truncmysummary),
452
            'package.xml 1.0 summary "%summary%" does not match "%self%"');
452
            'package.xml 1.0 summary "%summary%" does not match "%self%"');
453
    }
453
    }
454
454
455
    function _differentDescription($description)
455
    function _differentDescription($description)
456
    {
456
    {
457
        $truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0, 24) . '...');
457
        $truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0, 24) . '...');
458
        $truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() :
458
        $truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() :
459
            substr($this->getdescription(), 0, 24) . '...');
459
            substr($this->getdescription(), 0, 24) . '...');
460
        $this->_stack->push(__FUNCTION__, 'error', array('description' => $truncdescription,
460
        $this->_stack->push(__FUNCTION__, 'error', array('description' => $truncdescription,
461
            'self' => $truncmydescription),
461
            'self' => $truncmydescription),
462
            'package.xml 1.0 description "%description%" does not match "%self%"');
462
            'package.xml 1.0 description "%description%" does not match "%self%"');
463
    }
463
    }
464
464
465
    function _missingFile($file)
465
    function _missingFile($file)
466
    {
466
    {
467
        $this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
467
        $this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
468
            'package.xml 1.0 file "%file%" is not present in <contents>');
468
            'package.xml 1.0 file "%file%" is not present in <contents>');
469
    }
469
    }
470
470
471
    /**
471
    /**
472
     * WARNING - do not use this function unless you know what you're doing
472
     * WARNING - do not use this function unless you know what you're doing
473
     */
473
     */
474
    function setRawState($state)
474
    function setRawState($state)
475
    {
475
    {
476
        if (!isset($this->_packageInfo['stability'])) {
476
        if (!isset($this->_packageInfo['stability'])) {
477
            $this->_packageInfo['stability'] = array();
477
            $this->_packageInfo['stability'] = array();
478
        }
478
        }
479
        $this->_packageInfo['stability']['release'] = $state;
479
        $this->_packageInfo['stability']['release'] = $state;
480
    }
480
    }
481
481
482
    /**
482
    /**
483
     * WARNING - do not use this function unless you know what you're doing
483
     * WARNING - do not use this function unless you know what you're doing
484
     */
484
     */
485
    function setRawCompatible($compatible)
485
    function setRawCompatible($compatible)
486
    {
486
    {
487
        $this->_packageInfo['compatible'] = $compatible;
487
        $this->_packageInfo['compatible'] = $compatible;
488
    }
488
    }
489
489
490
    /**
490
    /**
491
     * WARNING - do not use this function unless you know what you're doing
491
     * WARNING - do not use this function unless you know what you're doing
492
     */
492
     */
493
    function setRawPackage($package)
493
    function setRawPackage($package)
494
    {
494
    {
495
        $this->_packageInfo['name'] = $package;
495
        $this->_packageInfo['name'] = $package;
496
    }
496
    }
497
497
498
    /**
498
    /**
499
     * WARNING - do not use this function unless you know what you're doing
499
     * WARNING - do not use this function unless you know what you're doing
500
     */
500
     */
501
    function setRawChannel($channel)
501
    function setRawChannel($channel)
502
    {
502
    {
503
        $this->_packageInfo['channel'] = $channel;
503
        $this->_packageInfo['channel'] = $channel;
504
    }
504
    }
505
505
506
    function setRequestedGroup($group)
506
    function setRequestedGroup($group)
507
    {
507
    {
508
        $this->_requestedGroup = $group;
508
        $this->_requestedGroup = $group;
509
    }
509
    }
510
510
511
    function getRequestedGroup()
511
    function getRequestedGroup()
512
    {
512
    {
513
        if (isset($this->_requestedGroup)) {
513
        if (isset($this->_requestedGroup)) {
514
            return $this->_requestedGroup;
514
            return $this->_requestedGroup;
515
        }
515
        }
516
        return false;
516
        return false;
517
    }
517
    }
518
518
519
    /**
519
    /**
520
     * For saving in the registry.
520
     * For saving in the registry.
521
     *
521
     *
522
     * Set the last version that was installed
522
     * Set the last version that was installed
523
     * @param string
523
     * @param string
524
     */
524
     */
525
    function setLastInstalledVersion($version)
525
    function setLastInstalledVersion($version)
526
    {
526
    {
527
        $this->_packageInfo['_lastversion'] = $version;
527
        $this->_packageInfo['_lastversion'] = $version;
528
    }
528
    }
529
529
530
    /**
530
    /**
531
     * @return string|false
531
     * @return string|false
532
     */
532
     */
533
    function getLastInstalledVersion()
533
    function getLastInstalledVersion()
534
    {
534
    {
535
        if (isset($this->_packageInfo['_lastversion'])) {
535
        if (isset($this->_packageInfo['_lastversion'])) {
536
            return $this->_packageInfo['_lastversion'];
536
            return $this->_packageInfo['_lastversion'];
537
        }
537
        }
538
        return false;
538
        return false;
539
    }
539
    }
540
540
541
    /**
541
    /**
542
     * Determines whether this package.xml has post-install scripts or not
542
     * Determines whether this package.xml has post-install scripts or not
543
     * @return array|false
543
     * @return array|false
544
     */
544
     */
545
    function listPostinstallScripts()
545
    function listPostinstallScripts()
546
    {
546
    {
547
        $filelist = $this->getFilelist();
547
        $filelist = $this->getFilelist();
548
        $contents = $this->getContents();
548
        $contents = $this->getContents();
549
        $contents = $contents['dir']['file'];
549
        $contents = $contents['dir']['file'];
550
        if (!is_array($contents) || !isset($contents[0])) {
550
        if (!is_array($contents) || !isset($contents[0])) {
551
            $contents = array($contents);
551
            $contents = array($contents);
552
        }
552
        }
553
        $taskfiles = array();
553
        $taskfiles = array();
554
        foreach ($contents as $file) {
554
        foreach ($contents as $file) {
555
            $atts = $file['attribs'];
555
            $atts = $file['attribs'];
556
            unset($file['attribs']);
556
            unset($file['attribs']);
557
            if (count($file)) {
557
            if (count($file)) {
558
                $taskfiles[$atts['name']] = $file;
558
                $taskfiles[$atts['name']] = $file;
559
            }
559
            }
560
        }
560
        }
561
        $common = new PEAR_Common;
561
        $common = new PEAR_Common;
562
        $common->debug = $this->_config->get('verbose');
562
        $common->debug = $this->_config->get('verbose');
563
        $this->_scripts = array();
563
        $this->_scripts = array();
564
        $ret = array();
564
        $ret = array();
565
        foreach ($taskfiles as $name => $tasks) {
565
        foreach ($taskfiles as $name => $tasks) {
566
            if (!isset($filelist[$name])) {
566
            if (!isset($filelist[$name])) {
567
                // ignored files will not be in the filelist
567
                // ignored files will not be in the filelist
568
                continue;
568
                continue;
569
            }
569
            }
570
            $atts = $filelist[$name];
570
            $atts = $filelist[$name];
571
            foreach ($tasks as $tag => $raw) {
571
            foreach ($tasks as $tag => $raw) {
572
                $task = $this->getTask($tag);
572
                $task = $this->getTask($tag);
573
                $task = &new $task($this->_config, $common, PEAR_TASK_INSTALL);
573
                $task = &new $task($this->_config, $common, PEAR_TASK_INSTALL);
574
                if ($task->isScript()) {
574
                if ($task->isScript()) {
575
                    $ret[] = $filelist[$name]['installed_as'];
575
                    $ret[] = $filelist[$name]['installed_as'];
576
                }
576
                }
577
            }
577
            }
578
        }
578
        }
579
        if (count($ret)) {
579
        if (count($ret)) {
580
            return $ret;
580
            return $ret;
581
        }
581
        }
582
        return false;
582
        return false;
583
    }
583
    }
584
584
585
    /**
585
    /**
586
     * Initialize post-install scripts for running
586
     * Initialize post-install scripts for running
587
     *
587
     *
588
     * This method can be used to detect post-install scripts, as the return value
588
     * This method can be used to detect post-install scripts, as the return value
589
     * indicates whether any exist
589
     * indicates whether any exist
590
     * @return bool
590
     * @return bool
591
     */
591
     */
592
    function initPostinstallScripts()
592
    function initPostinstallScripts()
593
    {
593
    {
594
        $filelist = $this->getFilelist();
594
        $filelist = $this->getFilelist();
595
        $contents = $this->getContents();
595
        $contents = $this->getContents();
596
        $contents = $contents['dir']['file'];
596
        $contents = $contents['dir']['file'];
597
        if (!is_array($contents) || !isset($contents[0])) {
597
        if (!is_array($contents) || !isset($contents[0])) {
598
            $contents = array($contents);
598
            $contents = array($contents);
599
        }
599
        }
600
        $taskfiles = array();
600
        $taskfiles = array();
601
        foreach ($contents as $file) {
601
        foreach ($contents as $file) {
602
            $atts = $file['attribs'];
602
            $atts = $file['attribs'];
603
            unset($file['attribs']);
603
            unset($file['attribs']);
604
            if (count($file)) {
604
            if (count($file)) {
605
                $taskfiles[$atts['name']] = $file;
605
                $taskfiles[$atts['name']] = $file;
606
            }
606
            }
607
        }
607
        }
608
        $common = new PEAR_Common;
608
        $common = new PEAR_Common;
609
        $common->debug = $this->_config->get('verbose');
609
        $common->debug = $this->_config->get('verbose');
610
        $this->_scripts = array();
610
        $this->_scripts = array();
611
        foreach ($taskfiles as $name => $tasks) {
611
        foreach ($taskfiles as $name => $tasks) {
612
            if (!isset($filelist[$name])) {
612
            if (!isset($filelist[$name])) {
613
                // file was not installed due to installconditions
613
                // file was not installed due to installconditions
614
                continue;
614
                continue;
615
            }
615
            }
616
            $atts = $filelist[$name];
616
            $atts = $filelist[$name];
617
            foreach ($tasks as $tag => $raw) {
617
            foreach ($tasks as $tag => $raw) {
618
                $taskname = $this->getTask($tag);
618
                $taskname = $this->getTask($tag);
619
                $task = &new $taskname($this->_config, $common, PEAR_TASK_INSTALL);
619
                $task = &new $taskname($this->_config, $common, PEAR_TASK_INSTALL);
620
                if (!$task->isScript()) {
620
                if (!$task->isScript()) {
621
                    continue; // scripts are only handled after installation
621
                    continue; // scripts are only handled after installation
622
                }
622
                }
623
                $lastversion = isset($this->_packageInfo['_lastversion']) ?
623
                $lastversion = isset($this->_packageInfo['_lastversion']) ?
624
                    $this->_packageInfo['_lastversion'] : null;
624
                    $this->_packageInfo['_lastversion'] : null;
625
                $task->init($raw, $atts, $lastversion);
625
                $task->init($raw, $atts, $lastversion);
626
                $res = $task->startSession($this, $atts['installed_as']);
626
                $res = $task->startSession($this, $atts['installed_as']);
627
                if (!$res) {
627
                if (!$res) {
628
                    continue; // skip this file
628
                    continue; // skip this file
629
                }
629
                }
630
                if (PEAR::isError($res)) {
630
                if (PEAR::isError($res)) {
631
                    return $res;
631
                    return $res;
632
                }
632
                }
633
                $assign = &$task;
633
                $assign = &$task;
634
                $this->_scripts[] = &$assign;
634
                $this->_scripts[] = &$assign;
635
            }
635
            }
636
        }
636
        }
637
        if (count($this->_scripts)) {
637
        if (count($this->_scripts)) {
638
            return true;
638
            return true;
639
        }
639
        }
640
        return false;
640
        return false;
641
    }
641
    }
642
642
643
    function runPostinstallScripts()
643
    function runPostinstallScripts()
644
    {
644
    {
645
        if ($this->initPostinstallScripts()) {
645
        if ($this->initPostinstallScripts()) {
646
            $ui = &PEAR_Frontend::singleton();
646
            $ui = &PEAR_Frontend::singleton();
647
            if ($ui) {
647
            if ($ui) {
648
                $ui->runPostinstallScripts($this->_scripts, $this);
648
                $ui->runPostinstallScripts($this->_scripts, $this);
649
            }
649
            }
650
        }
650
        }
651
    }
651
    }
652
652
653
653
654
    /**
654
    /**
655
     * Convert a recursive set of <dir> and <file> tags into a single <dir> tag with
655
     * Convert a recursive set of <dir> and <file> tags into a single <dir> tag with
656
     * <file> tags.
656
     * <file> tags.
657
     */
657
     */
658
    function flattenFilelist()
658
    function flattenFilelist()
659
    {
659
    {
660
        if (isset($this->_packageInfo['bundle'])) {
660
        if (isset($this->_packageInfo['bundle'])) {
661
            return;
661
            return;
662
        }
662
        }
663
        $filelist = array();
663
        $filelist = array();
664
        if (isset($this->_packageInfo['contents']['dir']['dir'])) {
664
        if (isset($this->_packageInfo['contents']['dir']['dir'])) {
665
            $this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']);
665
            $this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']);
666
            if (!isset($filelist[1])) {
666
            if (!isset($filelist[1])) {
667
                $filelist = $filelist[0];
667
                $filelist = $filelist[0];
668
            }
668
            }
669
            $this->_packageInfo['contents']['dir']['file'] = $filelist;
669
            $this->_packageInfo['contents']['dir']['file'] = $filelist;
670
            unset($this->_packageInfo['contents']['dir']['dir']);
670
            unset($this->_packageInfo['contents']['dir']['dir']);
671
        } else {
671
        } else {
672
            // else already flattened but check for baseinstalldir propagation
672
            // else already flattened but check for baseinstalldir propagation
673
            if (isset($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) {
673
            if (isset($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) {
674
                if (isset($this->_packageInfo['contents']['dir']['file'][0])) {
674
                if (isset($this->_packageInfo['contents']['dir']['file'][0])) {
675
                    foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) {
675
                    foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) {
676
                        if (isset($file['attribs']['baseinstalldir'])) {
676
                        if (isset($file['attribs']['baseinstalldir'])) {
677
                            continue;
677
                            continue;
678
                        }
678
                        }
679
                        $this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir']
679
                        $this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir']
680
                            = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'];
680
                            = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'];
681
                    }
681
                    }
682
                } else {
682
                } else {
683
                    if (!isset($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) {
683
                    if (!isset($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) {
684
                       $this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir']
684
                       $this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir']
685
                            = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'];
685
                            = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'];
686
                    }
686
                    }
687
                }
687
                }
688
            }
688
            }
689
        }
689
        }
690
    }
690
    }
691
691
692
    /**
692
    /**
693
     * @param array the final flattened file list
693
     * @param array the final flattened file list
694
     * @param array the current directory being processed
694
     * @param array the current directory being processed
695
     * @param string|false any recursively inherited baeinstalldir attribute
695
     * @param string|false any recursively inherited baeinstalldir attribute
696
     * @param string private recursion variable
696
     * @param string private recursion variable
697
     * @return array
697
     * @return array
698
     * @access protected
698
     * @access protected
699
     */
699
     */
700
    function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '')
700
    function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '')
701
    {
701
    {
702
        if (isset($dir['attribs']) && isset($dir['attribs']['baseinstalldir'])) {
702
        if (isset($dir['attribs']) && isset($dir['attribs']['baseinstalldir'])) {
703
            $baseinstall = $dir['attribs']['baseinstalldir'];
703
            $baseinstall = $dir['attribs']['baseinstalldir'];
704
        }
704
        }
705
        if (isset($dir['dir'])) {
705
        if (isset($dir['dir'])) {
706
            if (!isset($dir['dir'][0])) {
706
            if (!isset($dir['dir'][0])) {
707
                $dir['dir'] = array($dir['dir']);
707
                $dir['dir'] = array($dir['dir']);
708
            }
708
            }
709
            foreach ($dir['dir'] as $subdir) {
709
            foreach ($dir['dir'] as $subdir) {
710
                if (!isset($subdir['attribs']) || !isset($subdir['attribs']['name'])) {
710
                if (!isset($subdir['attribs']) || !isset($subdir['attribs']['name'])) {
711
                    $name = '*unknown*';
711
                    $name = '*unknown*';
712
                } else {
712
                } else {
713
                    $name = $subdir['attribs']['name'];
713
                    $name = $subdir['attribs']['name'];
714
                }
714
                }
715
                $newpath = empty($path) ? $name :
715
                $newpath = empty($path) ? $name :
716
                    $path . '/' . $name;
716
                    $path . '/' . $name;
717
                $this->_getFlattenedFilelist($files, $subdir,
717
                $this->_getFlattenedFilelist($files, $subdir,
718
                    $baseinstall, $newpath);
718
                    $baseinstall, $newpath);
719
            }
719
            }
720
        }
720
        }
721
        if (isset($dir['file'])) {
721
        if (isset($dir['file'])) {
722
            if (!isset($dir['file'][0])) {
722
            if (!isset($dir['file'][0])) {
723
                $dir['file'] = array($dir['file']);
723
                $dir['file'] = array($dir['file']);
724
            }
724
            }
725
            foreach ($dir['file'] as $file) {
725
            foreach ($dir['file'] as $file) {
726
                $attrs = $file['attribs'];
726
                $attrs = $file['attribs'];
727
                $name = $attrs['name'];
727
                $name = $attrs['name'];
728
                if ($baseinstall && !isset($attrs['baseinstalldir'])) {
728
                if ($baseinstall && !isset($attrs['baseinstalldir'])) {
729
                    $attrs['baseinstalldir'] = $baseinstall;
729
                    $attrs['baseinstalldir'] = $baseinstall;
730
                }
730
                }
731
                $attrs['name'] = empty($path) ? $name : $path . '/' . $name;
731
                $attrs['name'] = empty($path) ? $name : $path . '/' . $name;
732
                $attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
732
                $attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
733
                    $attrs['name']);
733
                    $attrs['name']);
734
                $file['attribs'] = $attrs;
734
                $file['attribs'] = $attrs;
735
                $files[] = $file;
735
                $files[] = $file;
736
            }
736
            }
737
        }
737
        }
738
    }
738
    }
739
739
740
    function setConfig(&$config)
740
    function setConfig(&$config)
741
    {
741
    {
742
        $this->_config = &$config;
742
        $this->_config = &$config;
743
        $this->_registry = &$config->getRegistry();
743
        $this->_registry = &$config->getRegistry();
744
    }
744
    }
745
745
746
    function setLogger(&$logger)
746
    function setLogger(&$logger)
747
    {
747
    {
748
        if (!is_object($logger) || !method_exists($logger, 'log')) {
748
        if (!is_object($logger) || !method_exists($logger, 'log')) {
749
            return PEAR::raiseError('Logger must be compatible with PEAR_Common::log');
749
            return PEAR::raiseError('Logger must be compatible with PEAR_Common::log');
750
        }
750
        }
751
        $this->_logger = &$logger;
751
        $this->_logger = &$logger;
752
    }
752
    }
753
753
754
    /**
754
    /**
755
     * WARNING - do not use this function directly unless you know what you're doing
755
     * WARNING - do not use this function directly unless you know what you're doing
756
     */
756
     */
757
    function setDeps($deps)
757
    function setDeps($deps)
758
    {
758
    {
759
        $this->_packageInfo['dependencies'] = $deps;
759
        $this->_packageInfo['dependencies'] = $deps;
760
    }
760
    }
761
761
762
    /**
762
    /**
763
     * WARNING - do not use this function directly unless you know what you're doing
763
     * WARNING - do not use this function directly unless you know what you're doing
764
     */
764
     */
765
    function setCompatible($compat)
765
    function setCompatible($compat)
766
    {
766
    {
767
        $this->_packageInfo['compatible'] = $compat;
767
        $this->_packageInfo['compatible'] = $compat;
768
    }
768
    }
769
769
770
    function setPackagefile($file, $archive = false)
770
    function setPackagefile($file, $archive = false)
771
    {
771
    {
772
        $this->_packageFile = $file;
772
        $this->_packageFile = $file;
773
        $this->_archiveFile = $archive ? $archive : $file;
773
        $this->_archiveFile = $archive ? $archive : $file;
774
    }
774
    }
775
775
776
    /**
776
    /**
777
     * Wrapper to {@link PEAR_ErrorStack::getErrors()}
777
     * Wrapper to {@link PEAR_ErrorStack::getErrors()}
778
     * @param boolean determines whether to purge the error stack after retrieving
778
     * @param boolean determines whether to purge the error stack after retrieving
779
     * @return array
779
     * @return array
780
     */
780
     */
781
    function getValidationWarnings($purge = true)
781
    function getValidationWarnings($purge = true)
782
    {
782
    {
783
        return $this->_stack->getErrors($purge);
783
        return $this->_stack->getErrors($purge);
784
    }
784
    }
785
785
786
    function getPackageFile()
786
    function getPackageFile()
787
    {
787
    {
788
        return $this->_packageFile;
788
        return $this->_packageFile;
789
    }
789
    }
790
790
791
    function getArchiveFile()
791
    function getArchiveFile()
792
    {
792
    {
793
        return $this->_archiveFile;
793
        return $this->_archiveFile;
794
    }
794
    }
795
795
796
796
797
    /**
797
    /**
798
     * Directly set the array that defines this packagefile
798
     * Directly set the array that defines this packagefile
799
     *
799
     *
800
     * WARNING: no validation.  This should only be performed by internal methods
800
     * WARNING: no validation.  This should only be performed by internal methods
801
     * inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2
801
     * inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2
802
     * @param array
802
     * @param array
803
     */
803
     */
804
    function fromArray($pinfo)
804
    function fromArray($pinfo)
805
    {
805
    {
806
        unset($pinfo['old']);
806
        unset($pinfo['old']);
807
        unset($pinfo['xsdversion']);
807
        unset($pinfo['xsdversion']);
808
        $this->_incomplete = false;
808
        $this->_incomplete = false;
809
        $this->_packageInfo = $pinfo;
809
        $this->_packageInfo = $pinfo;
810
    }
810
    }
811
811
812
    function isIncomplete()
812
    function isIncomplete()
813
    {
813
    {
814
        return $this->_incomplete;
814
        return $this->_incomplete;
815
    }
815
    }
816
816
817
    /**
817
    /**
818
     * @return array
818
     * @return array
819
     */
819
     */
820
    function toArray($forreg = false)
820
    function toArray($forreg = false)
821
    {
821
    {
822
        if (!$this->validate(PEAR_VALIDATE_NORMAL)) {
822
        if (!$this->validate(PEAR_VALIDATE_NORMAL)) {
823
            return false;
823
            return false;
824
        }
824
        }
825
        return $this->getArray($forreg);
825
        return $this->getArray($forreg);
826
    }
826
    }
827
827
828
    function getArray($forReg = false)
828
    function getArray($forReg = false)
829
    {
829
    {
830
        if ($forReg) {
830
        if ($forReg) {
831
            $arr = $this->_packageInfo;
831
            $arr = $this->_packageInfo;
832
            $arr['old'] = array();
832
            $arr['old'] = array();
833
            $arr['old']['version'] = $this->getVersion();
833
            $arr['old']['version'] = $this->getVersion();
834
            $arr['old']['release_date'] = $this->getDate();
834
            $arr['old']['release_date'] = $this->getDate();
835
            $arr['old']['release_state'] = $this->getState();
835
            $arr['old']['release_state'] = $this->getState();
836
            $arr['old']['release_license'] = $this->getLicense();
836
            $arr['old']['release_license'] = $this->getLicense();
837
            $arr['old']['release_notes'] = $this->getNotes();
837
            $arr['old']['release_notes'] = $this->getNotes();
838
            $arr['old']['release_deps'] = $this->getDeps();
838
            $arr['old']['release_deps'] = $this->getDeps();
839
            $arr['old']['maintainers'] = $this->getMaintainers();
839
            $arr['old']['maintainers'] = $this->getMaintainers();
840
            $arr['xsdversion'] = '2.0';
840
            $arr['xsdversion'] = '2.0';
841
            return $arr;
841
            return $arr;
842
        } else {
842
        } else {
843
            $info = $this->_packageInfo;
843
            $info = $this->_packageInfo;
844
            unset($info['dirtree']);
844
            unset($info['dirtree']);
845
            if (isset($info['_lastversion'])) {
845
            if (isset($info['_lastversion'])) {
846
                unset($info['_lastversion']);
846
                unset($info['_lastversion']);
847
            }
847
            }
848
            if (isset($info['#binarypackage'])) {
848
            if (isset($info['#binarypackage'])) {
849
                unset($info['#binarypackage']);
849
                unset($info['#binarypackage']);
850
            }
850
            }
851
            return $info;
851
            return $info;
852
        }
852
        }
853
    }
853
    }
854
854
855
    function packageInfo($field)
855
    function packageInfo($field)
856
    {
856
    {
857
        $arr = $this->getArray(true);
857
        $arr = $this->getArray(true);
858
        if ($field == 'state') {
858
        if ($field == 'state') {
859
            return $arr['stability']['release'];
859
            return $arr['stability']['release'];
860
        }
860
        }
861
        if ($field == 'api-version') {
861
        if ($field == 'api-version') {
862
            return $arr['version']['api'];
862
            return $arr['version']['api'];
863
        }
863
        }
864
        if ($field == 'api-state') {
864
        if ($field == 'api-state') {
865
            return $arr['stability']['api'];
865
            return $arr['stability']['api'];
866
        }
866
        }
867
        if (isset($arr['old'][$field])) {
867
        if (isset($arr['old'][$field])) {
868
            if (!is_string($arr['old'][$field])) {
868
            if (!is_string($arr['old'][$field])) {
869
                return null;
869
                return null;
870
            }
870
            }
871
            return $arr['old'][$field];
871
            return $arr['old'][$field];
872
        }
872
        }
873
        if (isset($arr[$field])) {
873
        if (isset($arr[$field])) {
874
            if (!is_string($arr[$field])) {
874
            if (!is_string($arr[$field])) {
875
                return null;
875
                return null;
876
            }
876
            }
877
            return $arr[$field];
877
            return $arr[$field];
878
        }
878
        }
879
        return null;
879
        return null;
880
    }
880
    }
881
881
882
    function getName()
882
    function getName()
883
    {
883
    {
884
        return $this->getPackage();
884
        return $this->getPackage();
885
    }
885
    }
886
886
887
    function getPackage()
887
    function getPackage()
888
    {
888
    {
889
        if (isset($this->_packageInfo['name'])) {
889
        if (isset($this->_packageInfo['name'])) {
890
            return $this->_packageInfo['name'];
890
            return $this->_packageInfo['name'];
891
        }
891
        }
892
        return false;
892
        return false;
893
    }
893
    }
894
894
895
    function getChannel()
895
    function getChannel()
896
    {
896
    {
897
        if (isset($this->_packageInfo['uri'])) {
897
        if (isset($this->_packageInfo['uri'])) {
898
            return '__uri';
898
            return '__uri';
899
        }
899
        }
900
        if (isset($this->_packageInfo['channel'])) {
900
        if (isset($this->_packageInfo['channel'])) {
901
            return strtolower($this->_packageInfo['channel']);
901
            return strtolower($this->_packageInfo['channel']);
902
        }
902
        }
903
        return false;
903
        return false;
904
    }
904
    }
905
905
906
    function getUri()
906
    function getUri()
907
    {
907
    {
908
        if (isset($this->_packageInfo['uri'])) {
908
        if (isset($this->_packageInfo['uri'])) {
909
            return $this->_packageInfo['uri'];
909
            return $this->_packageInfo['uri'];
910
        }
910
        }
911
        return false;
911
        return false;
912
    }
912
    }
913
913
914
    function getExtends()
914
    function getExtends()
915
    {
915
    {
916
        if (isset($this->_packageInfo['extends'])) {
916
        if (isset($this->_packageInfo['extends'])) {
917
            return $this->_packageInfo['extends'];
917
            return $this->_packageInfo['extends'];
918
        }
918
        }
919
        return false;
919
        return false;
920
    }
920
    }
921
921
922
    function getSummary()
922
    function getSummary()
923
    {
923
    {
924
        if (isset($this->_packageInfo['summary'])) {
924
        if (isset($this->_packageInfo['summary'])) {
925
            return $this->_packageInfo['summary'];
925
            return $this->_packageInfo['summary'];
926
        }
926
        }
927
        return false;
927
        return false;
928
    }
928
    }
929
929
930
    function getDescription()
930
    function getDescription()
931
    {
931
    {
932
        if (isset($this->_packageInfo['description'])) {
932
        if (isset($this->_packageInfo['description'])) {
933
            return $this->_packageInfo['description'];
933
            return $this->_packageInfo['description'];
934
        }
934
        }
935
        return false;
935
        return false;
936
    }
936
    }
937
937
938
    function getMaintainers($raw = false)
938
    function getMaintainers($raw = false)
939
    {
939
    {
940
        if (!isset($this->_packageInfo['lead'])) {
940
        if (!isset($this->_packageInfo['lead'])) {
941
            return false;
941
            return false;
942
        }
942
        }
943
        if ($raw) {
943
        if ($raw) {
944
            $ret = array('lead' => $this->_packageInfo['lead']);
944
            $ret = array('lead' => $this->_packageInfo['lead']);
945
            (isset($this->_packageInfo['developer'])) ?
945
            (isset($this->_packageInfo['developer'])) ?
946
                $ret['developer'] = $this->_packageInfo['developer'] :null;
946
                $ret['developer'] = $this->_packageInfo['developer'] :null;
947
            (isset($this->_packageInfo['contributor'])) ?
947
            (isset($this->_packageInfo['contributor'])) ?
948
                $ret['contributor'] = $this->_packageInfo['contributor'] :null;
948
                $ret['contributor'] = $this->_packageInfo['contributor'] :null;
949
            (isset($this->_packageInfo['helper'])) ?
949
            (isset($this->_packageInfo['helper'])) ?
950
                $ret['helper'] = $this->_packageInfo['helper'] :null;
950
                $ret['helper'] = $this->_packageInfo['helper'] :null;
951
            return $ret;
951
            return $ret;
952
        } else {
952
        } else {
953
            $ret = array();
953
            $ret = array();
954
            $leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] :
954
            $leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] :
955
                array($this->_packageInfo['lead']);
955
                array($this->_packageInfo['lead']);
956
            foreach ($leads as $lead) {
956
            foreach ($leads as $lead) {
957
                $s = $lead;
957
                $s = $lead;
958
                $s['handle'] = $s['user'];
958
                $s['handle'] = $s['user'];
959
                unset($s['user']);
959
                unset($s['user']);
960
                $s['role'] = 'lead';
960
                $s['role'] = 'lead';
961
                $ret[] = $s;
961
                $ret[] = $s;
962
            }
962
            }
963
            if (isset($this->_packageInfo['developer'])) {
963
            if (isset($this->_packageInfo['developer'])) {
964
                $leads = isset($this->_packageInfo['developer'][0]) ?
964
                $leads = isset($this->_packageInfo['developer'][0]) ?
965
                    $this->_packageInfo['developer'] :
965
                    $this->_packageInfo['developer'] :
966
                    array($this->_packageInfo['developer']);
966
                    array($this->_packageInfo['developer']);
967
                foreach ($leads as $maintainer) {
967
                foreach ($leads as $maintainer) {
968
                    $s = $maintainer;
968
                    $s = $maintainer;
969
                    $s['handle'] = $s['user'];
969
                    $s['handle'] = $s['user'];
970
                    unset($s['user']);
970
                    unset($s['user']);
971
                    $s['role'] = 'developer';
971
                    $s['role'] = 'developer';
972
                    $ret[] = $s;
972
                    $ret[] = $s;
973
                }
973
                }
974
            }
974
            }
975
            if (isset($this->_packageInfo['contributor'])) {
975
            if (isset($this->_packageInfo['contributor'])) {
976
                $leads = isset($this->_packageInfo['contributor'][0]) ?
976
                $leads = isset($this->_packageInfo['contributor'][0]) ?
977
                    $this->_packageInfo['contributor'] :
977
                    $this->_packageInfo['contributor'] :
978
                    array($this->_packageInfo['contributor']);
978
                    array($this->_packageInfo['contributor']);
979
                foreach ($leads as $maintainer) {
979
                foreach ($leads as $maintainer) {
980
                    $s = $maintainer;
980
                    $s = $maintainer;
981
                    $s['handle'] = $s['user'];
981
                    $s['handle'] = $s['user'];
982
                    unset($s['user']);
982
                    unset($s['user']);
983
                    $s['role'] = 'contributor';
983
                    $s['role'] = 'contributor';
984
                    $ret[] = $s;
984
                    $ret[] = $s;
985
                }
985
                }
986
            }
986
            }
987
            if (isset($this->_packageInfo['helper'])) {
987
            if (isset($this->_packageInfo['helper'])) {
988
                $leads = isset($this->_packageInfo['helper'][0]) ?
988
                $leads = isset($this->_packageInfo['helper'][0]) ?
989
                    $this->_packageInfo['helper'] :
989
                    $this->_packageInfo['helper'] :
990
                    array($this->_packageInfo['helper']);
990
                    array($this->_packageInfo['helper']);
991
                foreach ($leads as $maintainer) {
991
                foreach ($leads as $maintainer) {
992
                    $s = $maintainer;
992
                    $s = $maintainer;
993
                    $s['handle'] = $s['user'];
993
                    $s['handle'] = $s['user'];
994
                    unset($s['user']);
994
                    unset($s['user']);
995
                    $s['role'] = 'helper';
995
                    $s['role'] = 'helper';
996
                    $ret[] = $s;
996
                    $ret[] = $s;
997
                }
997
                }
998
            }
998
            }
999
            return $ret;
999
            return $ret;
1000
        }
1000
        }
1001
        return false;
1001
        return false;
1002
    }
1002
    }
1003
1003
1004
    function getLeads()
1004
    function getLeads()
1005
    {
1005
    {
1006
        if (isset($this->_packageInfo['lead'])) {
1006
        if (isset($this->_packageInfo['lead'])) {
1007
            return $this->_packageInfo['lead'];
1007
            return $this->_packageInfo['lead'];
1008
        }
1008
        }
1009
        return false;
1009
        return false;
1010
    }
1010
    }
1011
1011
1012
    function getDevelopers()
1012
    function getDevelopers()
1013
    {
1013
    {
1014
        if (isset($this->_packageInfo['developer'])) {
1014
        if (isset($this->_packageInfo['developer'])) {
1015
            return $this->_packageInfo['developer'];
1015
            return $this->_packageInfo['developer'];
1016
        }
1016
        }
1017
        return false;
1017
        return false;
1018
    }
1018
    }
1019
1019
1020
    function getContributors()
1020
    function getContributors()
1021
    {
1021
    {
1022
        if (isset($this->_packageInfo['contributor'])) {
1022
        if (isset($this->_packageInfo['contributor'])) {
1023
            return $this->_packageInfo['contributor'];
1023
            return $this->_packageInfo['contributor'];
1024
        }
1024
        }
1025
        return false;
1025
        return false;
1026
    }
1026
    }
1027
1027
1028
    function getHelpers()
1028
    function getHelpers()
1029
    {
1029
    {
1030
        if (isset($this->_packageInfo['helper'])) {
1030
        if (isset($this->_packageInfo['helper'])) {
1031
            return $this->_packageInfo['helper'];
1031
            return $this->_packageInfo['helper'];
1032
        }
1032
        }
1033
        return false;
1033
        return false;
1034
    }
1034
    }
1035
1035
1036
    function setDate($date)
1036
    function setDate($date)
1037
    {
1037
    {
1038
        if (!isset($this->_packageInfo['date'])) {
1038
        if (!isset($this->_packageInfo['date'])) {
1039
            // ensure that the extends tag is set up in the right location
1039
            // ensure that the extends tag is set up in the right location
1040
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
1040
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
1041
                array('time', 'version',
1041
                array('time', 'version',
1042
                    'stability', 'license', 'notes', 'contents', 'compatible',
1042
                    'stability', 'license', 'notes', 'contents', 'compatible',
1043
                    'dependencies', 'providesextension', 'srcpackage', 'srcuri',
1043
                    'dependencies', 'providesextension', 'srcpackage', 'srcuri',
1044
                    'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease',
1044
                    'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease',
1045
                    'zendextbinrelease', 'bundle', 'changelog'), array(), 'date');
1045
                    'zendextbinrelease', 'bundle', 'changelog'), array(), 'date');
1046
        }
1046
        }
1047
        $this->_packageInfo['date'] = $date;
1047
        $this->_packageInfo['date'] = $date;
1048
        $this->_isValid = 0;
1048
        $this->_isValid = 0;
1049
    }
1049
    }
1050
1050
1051
    function setTime($time)
1051
    function setTime($time)
1052
    {
1052
    {
1053
        $this->_isValid = 0;
1053
        $this->_isValid = 0;
1054
        if (!isset($this->_packageInfo['time'])) {
1054
        if (!isset($this->_packageInfo['time'])) {
1055
            // ensure that the time tag is set up in the right location
1055
            // ensure that the time tag is set up in the right location
1056
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
1056
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
1057
                    array('version',
1057
                    array('version',
1058
                    'stability', 'license', 'notes', 'contents', 'compatible',
1058
                    'stability', 'license', 'notes', 'contents', 'compatible',
1059
                    'dependencies', 'providesextension', 'srcpackage', 'srcuri',
1059
                    'dependencies', 'providesextension', 'srcpackage', 'srcuri',
1060
                    'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease',
1060
                    'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease',
1061
                    'zendextbinrelease', 'bundle', 'changelog'), $time, 'time');
1061
                    'zendextbinrelease', 'bundle', 'changelog'), $time, 'time');
1062
        }
1062
        }
1063
        $this->_packageInfo['time'] = $time;
1063
        $this->_packageInfo['time'] = $time;
1064
    }
1064
    }
1065
1065
1066
    function getDate()
1066
    function getDate()
1067
    {
1067
    {
1068
        if (isset($this->_packageInfo['date'])) {
1068
        if (isset($this->_packageInfo['date'])) {
1069
            return $this->_packageInfo['date'];
1069
            return $this->_packageInfo['date'];
1070
        }
1070
        }
1071
        return false;
1071
        return false;
1072
    }
1072
    }
1073
1073
1074
    function getTime()
1074
    function getTime()
1075
    {
1075
    {
1076
        if (isset($this->_packageInfo['time'])) {
1076
        if (isset($this->_packageInfo['time'])) {
1077
            return $this->_packageInfo['time'];
1077
            return $this->_packageInfo['time'];
1078
        }
1078
        }
1079
        return false;
1079
        return false;
1080
    }
1080
    }
1081
1081
1082
    /**
1082
    /**
1083
     * @param package|api version category to return
1083
     * @param package|api version category to return
1084
     */
1084
     */
1085
    function getVersion($key = 'release')
1085
    function getVersion($key = 'release')
1086
    {
1086
    {
1087
        if (isset($this->_packageInfo['version'][$key])) {
1087
        if (isset($this->_packageInfo['version'][$key])) {
1088
            return $this->_packageInfo['version'][$key];
1088
            return $this->_packageInfo['version'][$key];
1089
        }
1089
        }
1090
        return false;
1090
        return false;
1091
    }
1091
    }
1092
1092
1093
    function getStability()
1093
    function getStability()
1094
    {
1094
    {
1095
        if (isset($this->_packageInfo['stability'])) {
1095
        if (isset($this->_packageInfo['stability'])) {
1096
            return $this->_packageInfo['stability'];
1096
            return $this->_packageInfo['stability'];
1097
        }
1097
        }
1098
        return false;
1098
        return false;
1099
    }
1099
    }
1100
1100
1101
    function getState($key = 'release')
1101
    function getState($key = 'release')
1102
    {
1102
    {
1103
        if (isset($this->_packageInfo['stability'][$key])) {
1103
        if (isset($this->_packageInfo['stability'][$key])) {
1104
            return $this->_packageInfo['stability'][$key];
1104
            return $this->_packageInfo['stability'][$key];
1105
        }
1105
        }
1106
        return false;
1106
        return false;
1107
    }
1107
    }
1108
1108
1109
    function getLicense($raw = false)
1109
    function getLicense($raw = false)
1110
    {
1110
    {
1111
        if (isset($this->_packageInfo['license'])) {
1111
        if (isset($this->_packageInfo['license'])) {
1112
            if ($raw) {
1112
            if ($raw) {
1113
                return $this->_packageInfo['license'];
1113
                return $this->_packageInfo['license'];
1114
            }
1114
            }
1115
            if (is_array($this->_packageInfo['license'])) {
1115
            if (is_array($this->_packageInfo['license'])) {
1116
                return $this->_packageInfo['license']['_content'];
1116
                return $this->_packageInfo['license']['_content'];
1117
            } else {
1117
            } else {
1118
                return $this->_packageInfo['license'];
1118
                return $this->_packageInfo['license'];
1119
            }
1119
            }
1120
        }
1120
        }
1121
        return false;
1121
        return false;
1122
    }
1122
    }
1123
1123
1124
    function getLicenseLocation()
1124
    function getLicenseLocation()
1125
    {
1125
    {
1126
        if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) {
1126
        if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) {
1127
            return false;
1127
            return false;
1128
        }
1128
        }
1129
        return $this->_packageInfo['license']['attribs'];
1129
        return $this->_packageInfo['license']['attribs'];
1130
    }
1130
    }
1131
1131
1132
    function getNotes()
1132
    function getNotes()
1133
    {
1133
    {
1134
        if (isset($this->_packageInfo['notes'])) {
1134
        if (isset($this->_packageInfo['notes'])) {
1135
            return $this->_packageInfo['notes'];
1135
            return $this->_packageInfo['notes'];
1136
        }
1136
        }
1137
        return false;
1137
        return false;
1138
    }
1138
    }
1139
1139
1140
    /**
1140
    /**
1141
     * Return the <usesrole> tag contents, if any
1141
     * Return the <usesrole> tag contents, if any
1142
     * @return array|false
1142
     * @return array|false
1143
     */
1143
     */
1144
    function getUsesrole()
1144
    function getUsesrole()
1145
    {
1145
    {
1146
        if (isset($this->_packageInfo['usesrole'])) {
1146
        if (isset($this->_packageInfo['usesrole'])) {
1147
            return $this->_packageInfo['usesrole'];
1147
            return $this->_packageInfo['usesrole'];
1148
        }
1148
        }
1149
        return false;
1149
        return false;
1150
    }
1150
    }
1151
1151
1152
    /**
1152
    /**
1153
     * Return the <usestask> tag contents, if any
1153
     * Return the <usestask> tag contents, if any
1154
     * @return array|false
1154
     * @return array|false
1155
     */
1155
     */
1156
    function getUsestask()
1156
    function getUsestask()
1157
    {
1157
    {
1158
        if (isset($this->_packageInfo['usestask'])) {
1158
        if (isset($this->_packageInfo['usestask'])) {
1159
            return $this->_packageInfo['usestask'];
1159
            return $this->_packageInfo['usestask'];
1160
        }
1160
        }
1161
        return false;
1161
        return false;
1162
    }
1162
    }
1163
1163
1164
    /**
1164
    /**
1165
     * This should only be used to retrieve filenames and install attributes
1165
     * This should only be used to retrieve filenames and install attributes
1166
     */
1166
     */
1167
    function getFilelist($preserve = false)
1167
    function getFilelist($preserve = false)
1168
    {
1168
    {
1169
        if (isset($this->_packageInfo['filelist']) && !$preserve) {
1169
        if (isset($this->_packageInfo['filelist']) && !$preserve) {
1170
            return $this->_packageInfo['filelist'];
1170
            return $this->_packageInfo['filelist'];
1171
        }
1171
        }
1172
        $this->flattenFilelist();
1172
        $this->flattenFilelist();
1173
        if ($contents = $this->getContents()) {
1173
        if ($contents = $this->getContents()) {
1174
            $ret = array();
1174
            $ret = array();
1175
            if (!isset($contents['dir'])) {
1175
            if (!isset($contents['dir'])) {
1176
                return false;
1176
                return false;
1177
            }
1177
            }
1178
            if (!isset($contents['dir']['file'][0])) {
1178
            if (!isset($contents['dir']['file'][0])) {
1179
                $contents['dir']['file'] = array($contents['dir']['file']);
1179
                $contents['dir']['file'] = array($contents['dir']['file']);
1180
            }
1180
            }
1181
            foreach ($contents['dir']['file'] as $file) {
1181
            foreach ($contents['dir']['file'] as $file) {
1182
                $name = $file['attribs']['name'];
1182
                $name = $file['attribs']['name'];
1183
                if (!$preserve) {
1183
                if (!$preserve) {
1184
                    $file = $file['attribs'];
1184
                    $file = $file['attribs'];
1185
                }
1185
                }
1186
                $ret[$name] = $file;
1186
                $ret[$name] = $file;
1187
            }
1187
            }
1188
            if (!$preserve) {
1188
            if (!$preserve) {
1189
                $this->_packageInfo['filelist'] = $ret;
1189
                $this->_packageInfo['filelist'] = $ret;
1190
            }
1190
            }
1191
            return $ret;
1191
            return $ret;
1192
        }
1192
        }
1193
        return false;
1193
        return false;
1194
    }
1194
    }
1195
1195
1196
    /**
1196
    /**
1197
     * Return configure options array, if any
1197
     * Return configure options array, if any
1198
     *
1198
     *
1199
     * @return array|false
1199
     * @return array|false
1200
     */
1200
     */
1201
    function getConfigureOptions()
1201
    function getConfigureOptions()
1202
    {
1202
    {
1203
        if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
1203
        if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
1204
            return false;
1204
            return false;
1205
        }
1205
        }
1206
        $releases = $this->getReleases();
1206
        $releases = $this->getReleases();
1207
        if (isset($releases[0])) {
1207
        if (isset($releases[0])) {
1208
            $releases = $releases[0];
1208
            $releases = $releases[0];
1209
        }
1209
        }
1210
        if (isset($releases['configureoption'])) {
1210
        if (isset($releases['configureoption'])) {
1211
            if (!isset($releases['configureoption'][0])) {
1211
            if (!isset($releases['configureoption'][0])) {
1212
                $releases['configureoption'] = array($releases['configureoption']);
1212
                $releases['configureoption'] = array($releases['configureoption']);
1213
            }
1213
            }
1214
            for ($i = 0; $i < count($releases['configureoption']); $i++) {
1214
            for ($i = 0; $i < count($releases['configureoption']); $i++) {
1215
                $releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs'];
1215
                $releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs'];
1216
            }
1216
            }
1217
            return $releases['configureoption'];
1217
            return $releases['configureoption'];
1218
        }
1218
        }
1219
        return false;
1219
        return false;
1220
    }
1220
    }
1221
1221
1222
    /**
1222
    /**
1223
     * This is only used at install-time, after all serialization
1223
     * This is only used at install-time, after all serialization
1224
     * is over.
1224
     * is over.
1225
     */
1225
     */
1226
    function resetFilelist()
1226
    function resetFilelist()
1227
    {
1227
    {
1228
        $this->_packageInfo['filelist'] = array();
1228
        $this->_packageInfo['filelist'] = array();
1229
    }
1229
    }
1230
1230
1231
    /**
1231
    /**
1232
     * Retrieve a list of files that should be installed on this computer
1232
     * Retrieve a list of files that should be installed on this computer
1233
     * @return array
1233
     * @return array
1234
     */
1234
     */
1235
    function getInstallationFilelist($forfilecheck = false)
1235
    function getInstallationFilelist($forfilecheck = false)
1236
    {
1236
    {
1237
        $contents = $this->getFilelist(true);
1237
        $contents = $this->getFilelist(true);
1238
        if (isset($contents['dir']['attribs']['baseinstalldir'])) {
1238
        if (isset($contents['dir']['attribs']['baseinstalldir'])) {
1239
            $base = $contents['dir']['attribs']['baseinstalldir'];
1239
            $base = $contents['dir']['attribs']['baseinstalldir'];
1240
        }
1240
        }
1241
        if (isset($this->_packageInfo['bundle'])) {
1241
        if (isset($this->_packageInfo['bundle'])) {
1242
            return PEAR::raiseError(
1242
            return PEAR::raiseError(
1243
                'Exception: bundles should be handled in download code only');
1243
                'Exception: bundles should be handled in download code only');
1244
        }
1244
        }
1245
        $release = $this->getReleases();
1245
        $release = $this->getReleases();
1246
        if ($release) {
1246
        if ($release) {
1247
            if (!isset($release[0])) {
1247
            if (!isset($release[0])) {
1248
                if (!isset($release['installconditions']) && !isset($release['filelist'])) {
1248
                if (!isset($release['installconditions']) && !isset($release['filelist'])) {
1249
                    if ($forfilecheck) {
1249
                    if ($forfilecheck) {
1250
                        return $this->getFilelist();
1250
                        return $this->getFilelist();
1251
                    }
1251
                    }
1252
                    return $contents;
1252
                    return $contents;
1253
                }
1253
                }
1254
                $release = array($release);
1254
                $release = array($release);
1255
            }
1255
            }
1256
            $depchecker = &$this->getPEARDependency2($this->_config, array(),
1256
            $depchecker = &$this->getPEARDependency2($this->_config, array(),
1257
                array('channel' => $this->getChannel(), 'package' => $this->getPackage()),
1257
                array('channel' => $this->getChannel(), 'package' => $this->getPackage()),
1258
                PEAR_VALIDATE_INSTALLING);
1258
                PEAR_VALIDATE_INSTALLING);
1259
            foreach ($release as $instance) {
1259
            foreach ($release as $instance) {
1260
                if (isset($instance['installconditions'])) {
1260
                if (isset($instance['installconditions'])) {
1261
                    $installconditions = $instance['installconditions'];
1261
                    $installconditions = $instance['installconditions'];
1262
                    if (is_array($installconditions)) {
1262
                    if (is_array($installconditions)) {
1263
                        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
1263
                        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
1264
                        foreach ($installconditions as $type => $conditions) {
1264
                        foreach ($installconditions as $type => $conditions) {
1265
                            if (!isset($conditions[0])) {
1265
                            if (!isset($conditions[0])) {
1266
                                $conditions = array($conditions);
1266
                                $conditions = array($conditions);
1267
                            }
1267
                            }
1268
                            foreach ($conditions as $condition) {
1268
                            foreach ($conditions as $condition) {
1269
                                $ret = $depchecker->{"validate{$type}Dependency"}($condition);
1269
                                $ret = $depchecker->{"validate{$type}Dependency"}($condition);
1270
                                if (PEAR::isError($ret)) {
1270
                                if (PEAR::isError($ret)) {
1271
                                    PEAR::popErrorHandling();
1271
                                    PEAR::popErrorHandling();
1272
                                    continue 3; // skip this release
1272
                                    continue 3; // skip this release
1273
                                }
1273
                                }
1274
                            }
1274
                            }
1275
                        }
1275
                        }
1276
                        PEAR::popErrorHandling();
1276
                        PEAR::popErrorHandling();
1277
                    }
1277
                    }
1278
                }
1278
                }
1279
                // this is the release to use
1279
                // this is the release to use
1280
                if (isset($instance['filelist'])) {
1280
                if (isset($instance['filelist'])) {
1281
                    // ignore files
1281
                    // ignore files
1282
                    if (isset($instance['filelist']['ignore'])) {
1282
                    if (isset($instance['filelist']['ignore'])) {
1283
                        $ignore = isset($instance['filelist']['ignore'][0]) ?
1283
                        $ignore = isset($instance['filelist']['ignore'][0]) ?
1284
                            $instance['filelist']['ignore'] :
1284
                            $instance['filelist']['ignore'] :
1285
                            array($instance['filelist']['ignore']);
1285
                            array($instance['filelist']['ignore']);
1286
                        foreach ($ignore as $ig) {
1286
                        foreach ($ignore as $ig) {
1287
                            unset ($contents[$ig['attribs']['name']]);
1287
                            unset ($contents[$ig['attribs']['name']]);
1288
                        }
1288
                        }
1289
                    }
1289
                    }
1290
                    // install files as this name
1290
                    // install files as this name
1291
                    if (isset($instance['filelist']['install'])) {
1291
                    if (isset($instance['filelist']['install'])) {
1292
                        $installas = isset($instance['filelist']['install'][0]) ?
1292
                        $installas = isset($instance['filelist']['install'][0]) ?
1293
                            $instance['filelist']['install'] :
1293
                            $instance['filelist']['install'] :
1294
                            array($instance['filelist']['install']);
1294
                            array($instance['filelist']['install']);
1295
                        foreach ($installas as $as) {
1295
                        foreach ($installas as $as) {
1296
                            $contents[$as['attribs']['name']]['attribs']['install-as'] =
1296
                            $contents[$as['attribs']['name']]['attribs']['install-as'] =
1297
                                $as['attribs']['as'];
1297
                                $as['attribs']['as'];
1298
                        }
1298
                        }
1299
                    }
1299
                    }
1300
                }
1300
                }
1301
                if ($forfilecheck) {
1301
                if ($forfilecheck) {
1302
                    foreach ($contents as $file => $attrs) {
1302
                    foreach ($contents as $file => $attrs) {
1303
                        $contents[$file] = $attrs['attribs'];
1303
                        $contents[$file] = $attrs['attribs'];
1304
                    }
1304
                    }
1305
                }
1305
                }
1306
                return $contents;
1306
                return $contents;
1307
            }
1307
            }
1308
        } else { // simple release - no installconditions or install-as
1308
        } else { // simple release - no installconditions or install-as
1309
            if ($forfilecheck) {
1309
            if ($forfilecheck) {
1310
                return $this->getFilelist();
1310
                return $this->getFilelist();
1311
            }
1311
            }
1312
            return $contents;
1312
            return $contents;
1313
        }
1313
        }
1314
        // no releases matched
1314
        // no releases matched
1315
        return PEAR::raiseError('No releases in package.xml matched the existing operating ' .
1315
        return PEAR::raiseError('No releases in package.xml matched the existing operating ' .
1316
            'system, extensions installed, or architecture, cannot install');
1316
            'system, extensions installed, or architecture, cannot install');
1317
    }
1317
    }
1318
1318
1319
    /**
1319
    /**
1320
     * This is only used at install-time, after all serialization
1320
     * This is only used at install-time, after all serialization
1321
     * is over.
1321
     * is over.
1322
     * @param string file name
1322
     * @param string file name
1323
     * @param string installed path
1323
     * @param string installed path
1324
     */
1324
     */
1325
    function setInstalledAs($file, $path)
1325
    function setInstalledAs($file, $path)
1326
    {
1326
    {
1327
        if ($path) {
1327
        if ($path) {
1328
            return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
1328
            return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
1329
        }
1329
        }
1330
        unset($this->_packageInfo['filelist'][$file]['installed_as']);
1330
        unset($this->_packageInfo['filelist'][$file]['installed_as']);
1331
    }
1331
    }
1332
1332
1333
    function getInstalledLocation($file)
1333
    function getInstalledLocation($file)
1334
    {
1334
    {
1335
        if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) {
1335
        if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) {
1336
            return $this->_packageInfo['filelist'][$file]['installed_as'];
1336
            return $this->_packageInfo['filelist'][$file]['installed_as'];
1337
        }
1337
        }
1338
        return false;
1338
        return false;
1339
    }
1339
    }
1340
1340
1341
    /**
1341
    /**
1342
     * This is only used at install-time, after all serialization
1342
     * This is only used at install-time, after all serialization
1343
     * is over.
1343
     * is over.
1344
     */
1344
     */
1345
    function installedFile($file, $atts)
1345
    function installedFile($file, $atts)
1346
    {
1346
    {
1347
        if (isset($this->_packageInfo['filelist'][$file])) {
1347
        if (isset($this->_packageInfo['filelist'][$file])) {
1348
            $this->_packageInfo['filelist'][$file] =
1348
            $this->_packageInfo['filelist'][$file] =
1349
                array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']);
1349
                array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']);
1350
        } else {
1350
        } else {
1351
            $this->_packageInfo['filelist'][$file] = $atts['attribs'];
1351
            $this->_packageInfo['filelist'][$file] = $atts['attribs'];
1352
        }
1352
        }
1353
    }
1353
    }
1354
1354
1355
    /**
1355
    /**
1356
     * Retrieve the contents tag
1356
     * Retrieve the contents tag
1357
     */
1357
     */
1358
    function getContents()
1358
    function getContents()
1359
    {
1359
    {
1360
        if (isset($this->_packageInfo['contents'])) {
1360
        if (isset($this->_packageInfo['contents'])) {
1361
            return $this->_packageInfo['contents'];
1361
            return $this->_packageInfo['contents'];
1362
        }
1362
        }
1363
        return false;
1363
        return false;
1364
    }
1364
    }
1365
1365
1366
    /**
1366
    /**
1367
     * @param string full path to file
1367
     * @param string full path to file
1368
     * @param string attribute name
1368
     * @param string attribute name
1369
     * @param string attribute value
1369
     * @param string attribute value
1370
     * @param int risky but fast - use this to choose a file based on its position in the list
1370
     * @param int risky but fast - use this to choose a file based on its position in the list
1371
     *            of files.  Index is zero-based like PHP arrays.
1371
     *            of files.  Index is zero-based like PHP arrays.
1372
     * @return bool success of operation
1372
     * @return bool success of operation
1373
     */
1373
     */
1374
    function setFileAttribute($filename, $attr, $value, $index = false)
1374
    function setFileAttribute($filename, $attr, $value, $index = false)
1375
    {
1375
    {
1376
        $this->_isValid = 0;
1376
        $this->_isValid = 0;
1377
        if (in_array($attr, array('role', 'name', 'baseinstalldir'))) {
1377
        if (in_array($attr, array('role', 'name', 'baseinstalldir'))) {
1378
            $this->_filesValid = false;
1378
            $this->_filesValid = false;
1379
        }
1379
        }
1380
        if ($index !== false &&
1380
        if ($index !== false &&
1381
              isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) {
1381
              isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) {
1382
            $this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value;
1382
            $this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value;
1383
            return true;
1383
            return true;
1384
        }
1384
        }
1385
        if (!isset($this->_packageInfo['contents']['dir']['file'])) {
1385
        if (!isset($this->_packageInfo['contents']['dir']['file'])) {
1386
            return false;
1386
            return false;
1387
        }
1387
        }
1388
        $files = $this->_packageInfo['contents']['dir']['file'];
1388
        $files = $this->_packageInfo['contents']['dir']['file'];
1389
        if (!isset($files[0])) {
1389
        if (!isset($files[0])) {
1390
            $files = array($files);
1390
            $files = array($files);
1391
            $ind = false;
1391
            $ind = false;
1392
        } else {
1392
        } else {
1393
            $ind = true;
1393
            $ind = true;
1394
        }
1394
        }
1395
        foreach ($files as $i => $file) {
1395
        foreach ($files as $i => $file) {
1396
            if (isset($file['attribs'])) {
1396
            if (isset($file['attribs'])) {
1397
                if ($file['attribs']['name'] == $filename) {
1397
                if ($file['attribs']['name'] == $filename) {
1398
                    if ($ind) {
1398
                    if ($ind) {
1399
                        $this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value;
1399
                        $this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value;
1400
                    } else {
1400
                    } else {
1401
                        $this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value;
1401
                        $this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value;
1402
                    }
1402
                    }
1403
                    return true;
1403
                    return true;
1404
                }
1404
                }
1405
            }
1405
            }
1406
        }
1406
        }
1407
        return false;
1407
        return false;
1408
    }
1408
    }
1409
1409
1410
    function setDirtree($path)
1410
    function setDirtree($path)
1411
    {
1411
    {
1412
        if (!isset($this->_packageInfo['dirtree'])) {
1412
        if (!isset($this->_packageInfo['dirtree'])) {
1413
            $this->_packageInfo['dirtree'] = array();
1413
            $this->_packageInfo['dirtree'] = array();
1414
        }
1414
        }
1415
        $this->_packageInfo['dirtree'][$path] = true;
1415
        $this->_packageInfo['dirtree'][$path] = true;
1416
    }
1416
    }
1417
1417
1418
    function getDirtree()
1418
    function getDirtree()
1419
    {
1419
    {
1420
        if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) {
1420
        if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) {
1421
            return $this->_packageInfo['dirtree'];
1421
            return $this->_packageInfo['dirtree'];
1422
        }
1422
        }
1423
        return false;
1423
        return false;
1424
    }
1424
    }
1425
1425
1426
    function resetDirtree()
1426
    function resetDirtree()
1427
    {
1427
    {
1428
        unset($this->_packageInfo['dirtree']);
1428
        unset($this->_packageInfo['dirtree']);
1429
    }
1429
    }
1430
1430
1431
    /**
1431
    /**
1432
     * Determines whether this package claims it is compatible with the version of
1432
     * Determines whether this package claims it is compatible with the version of
1433
     * the package that has a recommended version dependency
1433
     * the package that has a recommended version dependency
1434
     * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package
1434
     * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package
1435
     * @return boolean
1435
     * @return boolean
1436
     */
1436
     */
1437
    function isCompatible($pf)
1437
    function isCompatible($pf)
1438
    {
1438
    {
1439
        if (!isset($this->_packageInfo['compatible'])) {
1439
        if (!isset($this->_packageInfo['compatible'])) {
1440
            return false;
1440
            return false;
1441
        }
1441
        }
1442
        if (!isset($this->_packageInfo['channel'])) {
1442
        if (!isset($this->_packageInfo['channel'])) {
1443
            return false;
1443
            return false;
1444
        }
1444
        }
1445
        $me = $pf->getVersion();
1445
        $me = $pf->getVersion();
1446
        $compatible = $this->_packageInfo['compatible'];
1446
        $compatible = $this->_packageInfo['compatible'];
1447
        if (!isset($compatible[0])) {
1447
        if (!isset($compatible[0])) {
1448
            $compatible = array($compatible);
1448
            $compatible = array($compatible);
1449
        }
1449
        }
1450
        $found = false;
1450
        $found = false;
1451
        foreach ($compatible as $info) {
1451
        foreach ($compatible as $info) {
1452
            if (strtolower($info['name']) == strtolower($pf->getPackage())) {
1452
            if (strtolower($info['name']) == strtolower($pf->getPackage())) {
1453
                if (strtolower($info['channel']) == strtolower($pf->getChannel())) {
1453
                if (strtolower($info['channel']) == strtolower($pf->getChannel())) {
1454
                    $found = true;
1454
                    $found = true;
1455
                    break;
1455
                    break;
1456
                }
1456
                }
1457
            }
1457
            }
1458
        }
1458
        }
1459
        if (!$found) {
1459
        if (!$found) {
1460
            return false;
1460
            return false;
1461
        }
1461
        }
1462
        if (isset($info['exclude'])) {
1462
        if (isset($info['exclude'])) {
1463
            if (!isset($info['exclude'][0])) {
1463
            if (!isset($info['exclude'][0])) {
1464
                $info['exclude'] = array($info['exclude']);
1464
                $info['exclude'] = array($info['exclude']);
1465
            }
1465
            }
1466
            foreach ($info['exclude'] as $exclude) {
1466
            foreach ($info['exclude'] as $exclude) {
1467
                if (version_compare($me, $exclude, '==')) {
1467
                if (version_compare($me, $exclude, '==')) {
1468
                    return false;
1468
                    return false;
1469
                }
1469
                }
1470
            }
1470
            }
1471
        }
1471
        }
1472
        if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) {
1472
        if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) {
1473
            return true;
1473
            return true;
1474
        }
1474
        }
1475
        return false;
1475
        return false;
1476
    }
1476
    }
1477
1477
1478
    /**
1478
    /**
1479
     * @return array|false
1479
     * @return array|false
1480
     */
1480
     */
1481
    function getCompatible()
1481
    function getCompatible()
1482
    {
1482
    {
1483
        if (isset($this->_packageInfo['compatible'])) {
1483
        if (isset($this->_packageInfo['compatible'])) {
1484
            return $this->_packageInfo['compatible'];
1484
            return $this->_packageInfo['compatible'];
1485
        }
1485
        }
1486
        return false;
1486
        return false;
1487
    }
1487
    }
1488
1488
1489
    function getDependencies()
1489
    function getDependencies()
1490
    {
1490
    {
1491
        if (isset($this->_packageInfo['dependencies'])) {
1491
        if (isset($this->_packageInfo['dependencies'])) {
1492
            return $this->_packageInfo['dependencies'];
1492
            return $this->_packageInfo['dependencies'];
1493
        }
1493
        }
1494
        return false;
1494
        return false;
1495
    }
1495
    }
1496
1496
1497
    function isSubpackageOf($p)
1497
    function isSubpackageOf($p)
1498
    {
1498
    {
1499
        return $p->isSubpackage($this);
1499
        return $p->isSubpackage($this);
1500
    }
1500
    }
1501
1501
1502
    /**
1502
    /**
1503
     * Determines whether the passed in package is a subpackage of this package.
1503
     * Determines whether the passed in package is a subpackage of this package.
1504
     *
1504
     *
1505
     * No version checking is done, only name verification.
1505
     * No version checking is done, only name verification.
1506
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
1506
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
1507
     * @return bool
1507
     * @return bool
1508
     */
1508
     */
1509
    function isSubpackage($p)
1509
    function isSubpackage($p)
1510
    {
1510
    {
1511
        $sub = array();
1511
        $sub = array();
1512
        if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) {
1512
        if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) {
1513
            $sub = $this->_packageInfo['dependencies']['required']['subpackage'];
1513
            $sub = $this->_packageInfo['dependencies']['required']['subpackage'];
1514
            if (!isset($sub[0])) {
1514
            if (!isset($sub[0])) {
1515
                $sub = array($sub);
1515
                $sub = array($sub);
1516
            }
1516
            }
1517
        }
1517
        }
1518
        if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) {
1518
        if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) {
1519
            $sub1 = $this->_packageInfo['dependencies']['optional']['subpackage'];
1519
            $sub1 = $this->_packageInfo['dependencies']['optional']['subpackage'];
1520
            if (!isset($sub1[0])) {
1520
            if (!isset($sub1[0])) {
1521
                $sub1 = array($sub1);
1521
                $sub1 = array($sub1);
1522
            }
1522
            }
1523
            $sub = array_merge($sub, $sub1);
1523
            $sub = array_merge($sub, $sub1);
1524
        }
1524
        }
1525
        if (isset($this->_packageInfo['dependencies']['group'])) {
1525
        if (isset($this->_packageInfo['dependencies']['group'])) {
1526
            $group = $this->_packageInfo['dependencies']['group'];
1526
            $group = $this->_packageInfo['dependencies']['group'];
1527
            if (!isset($group[0])) {
1527
            if (!isset($group[0])) {
1528
                $group = array($group);
1528
                $group = array($group);
1529
            }
1529
            }
1530
            foreach ($group as $deps) {
1530
            foreach ($group as $deps) {
1531
                if (isset($deps['subpackage'])) {
1531
                if (isset($deps['subpackage'])) {
1532
                    $sub2 = $deps['subpackage'];
1532
                    $sub2 = $deps['subpackage'];
1533
                    if (!isset($sub2[0])) {
1533
                    if (!isset($sub2[0])) {
1534
                        $sub2 = array($sub2);
1534
                        $sub2 = array($sub2);
1535
                    }
1535
                    }
1536
                    $sub = array_merge($sub, $sub2);
1536
                    $sub = array_merge($sub, $sub2);
1537
                }
1537
                }
1538
            }
1538
            }
1539
        }
1539
        }
1540
        foreach ($sub as $dep) {
1540
        foreach ($sub as $dep) {
1541
            if (strtolower($dep['name']) == strtolower($p->getPackage())) {
1541
            if (strtolower($dep['name']) == strtolower($p->getPackage())) {
1542
                if (isset($dep['channel'])) {
1542
                if (isset($dep['channel'])) {
1543
                    if (strtolower($dep['channel']) == strtolower($p->getChannel())) {
1543
                    if (strtolower($dep['channel']) == strtolower($p->getChannel())) {
1544
                        return true;
1544
                        return true;
1545
                    }
1545
                    }
1546
                } else {
1546
                } else {
1547
                    if ($dep['uri'] == $p->getURI()) {
1547
                    if ($dep['uri'] == $p->getURI()) {
1548
                        return true;
1548
                        return true;
1549
                    }
1549
                    }
1550
                }
1550
                }
1551
            }
1551
            }
1552
        }
1552
        }
1553
        return false;
1553
        return false;
1554
    }
1554
    }
1555
1555
1556
    function dependsOn($package, $channel)
1556
    function dependsOn($package, $channel)
1557
    {
1557
    {
1558
        if (!($deps = $this->getDependencies())) {
1558
        if (!($deps = $this->getDependencies())) {
1559
            return false;
1559
            return false;
1560
        }
1560
        }
1561
        foreach (array('package', 'subpackage') as $type) {
1561
        foreach (array('package', 'subpackage') as $type) {
1562
            foreach (array('required', 'optional') as $needed) {
1562
            foreach (array('required', 'optional') as $needed) {
1563
                if (isset($deps[$needed][$type])) {
1563
                if (isset($deps[$needed][$type])) {
1564
                    if (!isset($deps[$needed][$type][0])) {
1564
                    if (!isset($deps[$needed][$type][0])) {
1565
                        $deps[$needed][$type] = array($deps[$needed][$type]);
1565
                        $deps[$needed][$type] = array($deps[$needed][$type]);
1566
                    }
1566
                    }
1567
                    foreach ($deps[$needed][$type] as $dep) {
1567
                    foreach ($deps[$needed][$type] as $dep) {
1568
                        $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
1568
                        $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
1569
                        if (strtolower($dep['name']) == strtolower($package) &&
1569
                        if (strtolower($dep['name']) == strtolower($package) &&
1570
                              $depchannel == $channel) {
1570
                              $depchannel == $channel) {
1571
                            return true;
1571
                            return true;
1572
                        }
1572
                        }
1573
                    }
1573
                    }
1574
                }
1574
                }
1575
            }
1575
            }
1576
            if (isset($deps['group'])) {
1576
            if (isset($deps['group'])) {
1577
                if (!isset($deps['group'][0])) {
1577
                if (!isset($deps['group'][0])) {
1578
                    $dep['group'] = array($deps['group']);
1578
                    $dep['group'] = array($deps['group']);
1579
                }
1579
                }
1580
                foreach ($deps['group'] as $group) {
1580
                foreach ($deps['group'] as $group) {
1581
                    if (isset($group[$type])) {
1581
                    if (isset($group[$type])) {
1582
                        if (!is_array($group[$type])) {
1582
                        if (!is_array($group[$type])) {
1583
                            $group[$type] = array($group[$type]);
1583
                            $group[$type] = array($group[$type]);
1584
                        }
1584
                        }
1585
                        foreach ($group[$type] as $dep) {
1585
                        foreach ($group[$type] as $dep) {
1586
                            $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
1586
                            $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
1587
                            if (strtolower($dep['name']) == strtolower($package) &&
1587
                            if (strtolower($dep['name']) == strtolower($package) &&
1588
                                  $depchannel == $channel) {
1588
                                  $depchannel == $channel) {
1589
                                return true;
1589
                                return true;
1590
                            }
1590
                            }
1591
                        }
1591
                        }
1592
                    }
1592
                    }
1593
                }
1593
                }
1594
            }
1594
            }
1595
        }
1595
        }
1596
        return false;
1596
        return false;
1597
    }
1597
    }
1598
1598
1599
    /**
1599
    /**
1600
     * Get the contents of a dependency group
1600
     * Get the contents of a dependency group
1601
     * @param string
1601
     * @param string
1602
     * @return array|false
1602
     * @return array|false
1603
     */
1603
     */
1604
    function getDependencyGroup($name)
1604
    function getDependencyGroup($name)
1605
    {
1605
    {
1606
        $name = strtolower($name);
1606
        $name = strtolower($name);
1607
        if (!isset($this->_packageInfo['dependencies']['group'])) {
1607
        if (!isset($this->_packageInfo['dependencies']['group'])) {
1608
            return false;
1608
            return false;
1609
        }
1609
        }
1610
        $groups = $this->_packageInfo['dependencies']['group'];
1610
        $groups = $this->_packageInfo['dependencies']['group'];
1611
        if (!isset($groups[0])) {
1611
        if (!isset($groups[0])) {
1612
            $groups = array($groups);
1612
            $groups = array($groups);
1613
        }
1613
        }
1614
        foreach ($groups as $group) {
1614
        foreach ($groups as $group) {
1615
            if (strtolower($group['attribs']['name']) == $name) {
1615
            if (strtolower($group['attribs']['name']) == $name) {
1616
                return $group;
1616
                return $group;
1617
            }
1617
            }
1618
        }
1618
        }
1619
        return false;
1619
        return false;
1620
    }
1620
    }
1621
1621
1622
    /**
1622
    /**
1623
     * Retrieve a partial package.xml 1.0 representation of dependencies
1623
     * Retrieve a partial package.xml 1.0 representation of dependencies
1624
     *
1624
     *
1625
     * a very limited representation of dependencies is returned by this method.
1625
     * a very limited representation of dependencies is returned by this method.
1626
     * The <exclude> tag for excluding certain versions of a dependency is
1626
     * The <exclude> tag for excluding certain versions of a dependency is
1627
     * completely ignored.  In addition, dependency groups are ignored, with the
1627
     * completely ignored.  In addition, dependency groups are ignored, with the
1628
     * assumption that all dependencies in dependency groups are also listed in
1628
     * assumption that all dependencies in dependency groups are also listed in
1629
     * the optional group that work with all dependency groups
1629
     * the optional group that work with all dependency groups
1630
     * @param boolean return package.xml 2.0 <dependencies> tag
1630
     * @param boolean return package.xml 2.0 <dependencies> tag
1631
     * @return array|false
1631
     * @return array|false
1632
     */
1632
     */
1633
    function getDeps($raw = false, $nopearinstaller = false)
1633
    function getDeps($raw = false, $nopearinstaller = false)
1634
    {
1634
    {
1635
        if (isset($this->_packageInfo['dependencies'])) {
1635
        if (isset($this->_packageInfo['dependencies'])) {
1636
            if ($raw) {
1636
            if ($raw) {
1637
                return $this->_packageInfo['dependencies'];
1637
                return $this->_packageInfo['dependencies'];
1638
            }
1638
            }
1639
            $ret = array();
1639
            $ret = array();
1640
            $map = array(
1640
            $map = array(
1641
                'php' => 'php',
1641
                'php' => 'php',
1642
                'package' => 'pkg',
1642
                'package' => 'pkg',
1643
                'subpackage' => 'pkg',
1643
                'subpackage' => 'pkg',
1644
                'extension' => 'ext',
1644
                'extension' => 'ext',
1645
                'os' => 'os',
1645
                'os' => 'os',
1646
                'pearinstaller' => 'pkg',
1646
                'pearinstaller' => 'pkg',
1647
                );
1647
                );
1648
            foreach (array('required', 'optional') as $type) {
1648
            foreach (array('required', 'optional') as $type) {
1649
                $optional = ($type == 'optional') ? 'yes' : 'no';
1649
                $optional = ($type == 'optional') ? 'yes' : 'no';
1650
                if (!isset($this->_packageInfo['dependencies'][$type])
1650
                if (!isset($this->_packageInfo['dependencies'][$type])
1651
                    || empty($this->_packageInfo['dependencies'][$type])) {
1651
                    || empty($this->_packageInfo['dependencies'][$type])) {
1652
                    continue;
1652
                    continue;
1653
                }
1653
                }
1654
                foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) {
1654
                foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) {
1655
                    if ($dtype == 'pearinstaller' && $nopearinstaller) {
1655
                    if ($dtype == 'pearinstaller' && $nopearinstaller) {
1656
                        continue;
1656
                        continue;
1657
                    }
1657
                    }
1658
                    if (!isset($deps[0])) {
1658
                    if (!isset($deps[0])) {
1659
                        $deps = array($deps);
1659
                        $deps = array($deps);
1660
                    }
1660
                    }
1661
                    foreach ($deps as $dep) {
1661
                    foreach ($deps as $dep) {
1662
                        if (!isset($map[$dtype])) {
1662
                        if (!isset($map[$dtype])) {
1663
                            // no support for arch type
1663
                            // no support for arch type
1664
                            continue;
1664
                            continue;
1665
                        }
1665
                        }
1666
                        if ($dtype == 'pearinstaller') {
1666
                        if ($dtype == 'pearinstaller') {
1667
                            $dep['name'] = 'PEAR';
1667
                            $dep['name'] = 'PEAR';
1668
                            $dep['channel'] = 'pear.php.net';
1668
                            $dep['channel'] = 'pear.php.net';
1669
                        }
1669
                        }
1670
                        $s = array('type' => $map[$dtype]);
1670
                        $s = array('type' => $map[$dtype]);
1671
                        if (isset($dep['channel'])) {
1671
                        if (isset($dep['channel'])) {
1672
                            $s['channel'] = $dep['channel'];
1672
                            $s['channel'] = $dep['channel'];
1673
                        }
1673
                        }
1674
                        if (isset($dep['uri'])) {
1674
                        if (isset($dep['uri'])) {
1675
                            $s['uri'] = $dep['uri'];
1675
                            $s['uri'] = $dep['uri'];
1676
                        }
1676
                        }
1677
                        if (isset($dep['name'])) {
1677
                        if (isset($dep['name'])) {
1678
                            $s['name'] = $dep['name'];
1678
                            $s['name'] = $dep['name'];
1679
                        }
1679
                        }
1680
                        if (isset($dep['conflicts'])) {
1680
                        if (isset($dep['conflicts'])) {
1681
                            $s['rel'] = 'not';
1681
                            $s['rel'] = 'not';
1682
                        } else {
1682
                        } else {
1683
                            if (!isset($dep['min']) &&
1683
                            if (!isset($dep['min']) &&
1684
                                  !isset($dep['max'])) {
1684
                                  !isset($dep['max'])) {
1685
                                $s['rel'] = 'has';
1685
                                $s['rel'] = 'has';
1686
                                $s['optional'] = $optional;
1686
                                $s['optional'] = $optional;
1687
                            } elseif (isset($dep['min']) &&
1687
                            } elseif (isset($dep['min']) &&
1688
                                  isset($dep['max'])) {
1688
                                  isset($dep['max'])) {
1689
                                $s['rel'] = 'ge';
1689
                                $s['rel'] = 'ge';
1690
                                $s1 = $s;
1690
                                $s1 = $s;
1691
                                $s1['rel'] = 'le';
1691
                                $s1['rel'] = 'le';
1692
                                $s['version'] = $dep['min'];
1692
                                $s['version'] = $dep['min'];
1693
                                $s1['version'] = $dep['max'];
1693
                                $s1['version'] = $dep['max'];
1694
                                if (isset($dep['channel'])) {
1694
                                if (isset($dep['channel'])) {
1695
                                    $s1['channel'] = $dep['channel'];
1695
                                    $s1['channel'] = $dep['channel'];
1696
                                }
1696
                                }
1697
                                if ($dtype != 'php') {
1697
                                if ($dtype != 'php') {
1698
                                    $s['name'] = $dep['name'];
1698
                                    $s['name'] = $dep['name'];
1699
                                    $s1['name'] = $dep['name'];
1699
                                    $s1['name'] = $dep['name'];
1700
                                }
1700
                                }
1701
                                $s['optional'] = $optional;
1701
                                $s['optional'] = $optional;
1702
                                $s1['optional'] = $optional;
1702
                                $s1['optional'] = $optional;
1703
                                $ret[] = $s1;
1703
                                $ret[] = $s1;
1704
                            } elseif (isset($dep['min'])) {
1704
                            } elseif (isset($dep['min'])) {
1705
                                if (isset($dep['exclude']) &&
1705
                                if (isset($dep['exclude']) &&
1706
                                      $dep['exclude'] == $dep['min']) {
1706
                                      $dep['exclude'] == $dep['min']) {
1707
                                    $s['rel'] = 'gt';
1707
                                    $s['rel'] = 'gt';
1708
                                } else {
1708
                                } else {
1709
                                    $s['rel'] = 'ge';
1709
                                    $s['rel'] = 'ge';
1710
                                }
1710
                                }
1711
                                $s['version'] = $dep['min'];
1711
                                $s['version'] = $dep['min'];
1712
                                $s['optional'] = $optional;
1712
                                $s['optional'] = $optional;
1713
                                if ($dtype != 'php') {
1713
                                if ($dtype != 'php') {
1714
                                    $s['name'] = $dep['name'];
1714
                                    $s['name'] = $dep['name'];
1715
                                }
1715
                                }
1716
                            } elseif (isset($dep['max'])) {
1716
                            } elseif (isset($dep['max'])) {
1717
                                if (isset($dep['exclude']) &&
1717
                                if (isset($dep['exclude']) &&
1718
                                      $dep['exclude'] == $dep['max']) {
1718
                                      $dep['exclude'] == $dep['max']) {
1719
                                    $s['rel'] = 'lt';
1719
                                    $s['rel'] = 'lt';
1720
                                } else {
1720
                                } else {
1721
                                    $s['rel'] = 'le';
1721
                                    $s['rel'] = 'le';
1722
                                }
1722
                                }
1723
                                $s['version'] = $dep['max'];
1723
                                $s['version'] = $dep['max'];
1724
                                $s['optional'] = $optional;
1724
                                $s['optional'] = $optional;
1725
                                if ($dtype != 'php') {
1725
                                if ($dtype != 'php') {
1726
                                    $s['name'] = $dep['name'];
1726
                                    $s['name'] = $dep['name'];
1727
                                }
1727
                                }
1728
                            }
1728
                            }
1729
                        }
1729
                        }
1730
                        $ret[] = $s;
1730
                        $ret[] = $s;
1731
                    }
1731
                    }
1732
                }
1732
                }
1733
            }
1733
            }
1734
            if (count($ret)) {
1734
            if (count($ret)) {
1735
                return $ret;
1735
                return $ret;
1736
            }
1736
            }
1737
        }
1737
        }
1738
        return false;
1738
        return false;
1739
    }
1739
    }
1740
1740
1741
    /**
1741
    /**
1742
     * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false
1742
     * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false
1743
     */
1743
     */
1744
    function getPackageType()
1744
    function getPackageType()
1745
    {
1745
    {
1746
        if (isset($this->_packageInfo['phprelease'])) {
1746
        if (isset($this->_packageInfo['phprelease'])) {
1747
            return 'php';
1747
            return 'php';
1748
        }
1748
        }
1749
        if (isset($this->_packageInfo['extsrcrelease'])) {
1749
        if (isset($this->_packageInfo['extsrcrelease'])) {
1750
            return 'extsrc';
1750
            return 'extsrc';
1751
        }
1751
        }
1752
        if (isset($this->_packageInfo['extbinrelease'])) {
1752
        if (isset($this->_packageInfo['extbinrelease'])) {
1753
            return 'extbin';
1753
            return 'extbin';
1754
        }
1754
        }
1755
        if (isset($this->_packageInfo['zendextsrcrelease'])) {
1755
        if (isset($this->_packageInfo['zendextsrcrelease'])) {
1756
            return 'zendextsrc';
1756
            return 'zendextsrc';
1757
        }
1757
        }
1758
        if (isset($this->_packageInfo['zendextbinrelease'])) {
1758
        if (isset($this->_packageInfo['zendextbinrelease'])) {
1759
            return 'zendextbin';
1759
            return 'zendextbin';
1760
        }
1760
        }
1761
        if (isset($this->_packageInfo['bundle'])) {
1761
        if (isset($this->_packageInfo['bundle'])) {
1762
            return 'bundle';
1762
            return 'bundle';
1763
        }
1763
        }
1764
        return false;
1764
        return false;
1765
    }
1765
    }
1766
1766
1767
    /**
1767
    /**
1768
     * @return array|false
1768
     * @return array|false
1769
     */
1769
     */
1770
    function getReleases()
1770
    function getReleases()
1771
    {
1771
    {
1772
        $type = $this->getPackageType();
1772
        $type = $this->getPackageType();
1773
        if ($type != 'bundle') {
1773
        if ($type != 'bundle') {
1774
            $type .= 'release';
1774
            $type .= 'release';
1775
        }
1775
        }
1776
        if ($this->getPackageType() && isset($this->_packageInfo[$type])) {
1776
        if ($this->getPackageType() && isset($this->_packageInfo[$type])) {
1777
            return $this->_packageInfo[$type];
1777
            return $this->_packageInfo[$type];
1778
        }
1778
        }
1779
        return false;
1779
        return false;
1780
    }
1780
    }
1781
1781
1782
    /**
1782
    /**
1783
     * @return array
1783
     * @return array
1784
     */
1784
     */
1785
    function getChangelog()
1785
    function getChangelog()
1786
    {
1786
    {
1787
        if (isset($this->_packageInfo['changelog'])) {
1787
        if (isset($this->_packageInfo['changelog'])) {
1788
            return $this->_packageInfo['changelog'];
1788
            return $this->_packageInfo['changelog'];
1789
        }
1789
        }
1790
        return false;
1790
        return false;
1791
    }
1791
    }
1792
1792
1793
    function hasDeps()
1793
    function hasDeps()
1794
    {
1794
    {
1795
        return isset($this->_packageInfo['dependencies']);
1795
        return isset($this->_packageInfo['dependencies']);
1796
    }
1796
    }
1797
1797
1798
    function getPackagexmlVersion()
1798
    function getPackagexmlVersion()
1799
    {
1799
    {
1800
        if (isset($this->_packageInfo['zendextsrcrelease'])) {
1800
        if (isset($this->_packageInfo['zendextsrcrelease'])) {
1801
            return '2.1';
1801
            return '2.1';
1802
        }
1802
        }
1803
        if (isset($this->_packageInfo['zendextbinrelease'])) {
1803
        if (isset($this->_packageInfo['zendextbinrelease'])) {
1804
            return '2.1';
1804
            return '2.1';
1805
        }
1805
        }
1806
        return '2.0';
1806
        return '2.0';
1807
    }
1807
    }
1808
1808
1809
    /**
1809
    /**
1810
     * @return array|false
1810
     * @return array|false
1811
     */
1811
     */
1812
    function getSourcePackage()
1812
    function getSourcePackage()
1813
    {
1813
    {
1814
        if (isset($this->_packageInfo['extbinrelease']) ||
1814
        if (isset($this->_packageInfo['extbinrelease']) ||
1815
              isset($this->_packageInfo['zendextbinrelease'])) {
1815
              isset($this->_packageInfo['zendextbinrelease'])) {
1816
            return array('channel' => $this->_packageInfo['srcchannel'],
1816
            return array('channel' => $this->_packageInfo['srcchannel'],
1817
                         'package' => $this->_packageInfo['srcpackage']);
1817
                         'package' => $this->_packageInfo['srcpackage']);
1818
        }
1818
        }
1819
        return false;
1819
        return false;
1820
    }
1820
    }
1821
1821
1822
    function getBundledPackages()
1822
    function getBundledPackages()
1823
    {
1823
    {
1824
        if (isset($this->_packageInfo['bundle'])) {
1824
        if (isset($this->_packageInfo['bundle'])) {
1825
            return $this->_packageInfo['contents']['bundledpackage'];
1825
            return $this->_packageInfo['contents']['bundledpackage'];
1826
        }
1826
        }
1827
        return false;
1827
        return false;
1828
    }
1828
    }
1829
1829
1830
    function getLastModified()
1830
    function getLastModified()
1831
    {
1831
    {
1832
        if (isset($this->_packageInfo['_lastmodified'])) {
1832
        if (isset($this->_packageInfo['_lastmodified'])) {
1833
            return $this->_packageInfo['_lastmodified'];
1833
            return $this->_packageInfo['_lastmodified'];
1834
        }
1834
        }
1835
        return false;
1835
        return false;
1836
    }
1836
    }
1837
1837
1838
    /**
1838
    /**
1839
     * Get the contents of a file listed within the package.xml
1839
     * Get the contents of a file listed within the package.xml
1840
     * @param string
1840
     * @param string
1841
     * @return string
1841
     * @return string
1842
     */
1842
     */
1843
    function getFileContents($file)
1843
    function getFileContents($file)
1844
    {
1844
    {
1845
        if ($this->_archiveFile == $this->_packageFile) { // unpacked
1845
        if ($this->_archiveFile == $this->_packageFile) { // unpacked
1846
            $dir = dirname($this->_packageFile);
1846
            $dir = dirname($this->_packageFile);
1847
            $file = $dir . DIRECTORY_SEPARATOR . $file;
1847
            $file = $dir . DIRECTORY_SEPARATOR . $file;
1848
            $file = str_replace(array('/', '\\'),
1848
            $file = str_replace(array('/', '\\'),
1849
                array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
1849
                array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
1850
            if (file_exists($file) && is_readable($file)) {
1850
            if (file_exists($file) && is_readable($file)) {
1851
                return implode('', file($file));
1851
                return implode('', file($file));
1852
            }
1852
            }
1853
        } else { // tgz
1853
        } else { // tgz
1854
            $tar = &new Archive_Tar($this->_archiveFile);
1854
            $tar = &new Archive_Tar($this->_archiveFile);
1855
            $tar->pushErrorHandling(PEAR_ERROR_RETURN);
1855
            $tar->pushErrorHandling(PEAR_ERROR_RETURN);
1856
            if ($file != 'package.xml' && $file != 'package2.xml') {
1856
            if ($file != 'package.xml' && $file != 'package2.xml') {
1857
                $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
1857
                $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
1858
            }
1858
            }
1859
            $file = $tar->extractInString($file);
1859
            $file = $tar->extractInString($file);
1860
            $tar->popErrorHandling();
1860
            $tar->popErrorHandling();
1861
            if (PEAR::isError($file)) {
1861
            if (PEAR::isError($file)) {
1862
                return PEAR::raiseError("Cannot locate file '$file' in archive");
1862
                return PEAR::raiseError("Cannot locate file '$file' in archive");
1863
            }
1863
            }
1864
            return $file;
1864
            return $file;
1865
        }
1865
        }
1866
    }
1866
    }
1867
1867
1868
    function &getRW()
1868
    function &getRW()
1869
    {
1869
    {
1870
        if (!class_exists('PEAR_PackageFile_v2_rw')) {
1870
        if (!class_exists('PEAR_PackageFile_v2_rw')) {
1871
            require_once 'PEAR/PackageFile/v2/rw.php';
1871
            require_once 'PEAR/PackageFile/v2/rw.php';
1872
        }
1872
        }
1873
        $a = new PEAR_PackageFile_v2_rw;
1873
        $a = new PEAR_PackageFile_v2_rw;
1874
        foreach (get_object_vars($this) as $name => $unused) {
1874
        foreach (get_object_vars($this) as $name => $unused) {
1875
            if (!isset($this->$name)) {
1875
            if (!isset($this->$name)) {
1876
                continue;
1876
                continue;
1877
            }
1877
            }
1878
            if ($name == '_config' || $name == '_logger'|| $name == '_registry' ||
1878
            if ($name == '_config' || $name == '_logger'|| $name == '_registry' ||
1879
                  $name == '_stack') {
1879
                  $name == '_stack') {
1880
                $a->$name = &$this->$name;
1880
                $a->$name = &$this->$name;
1881
            } else {
1881
            } else {
1882
                $a->$name = $this->$name;
1882
                $a->$name = $this->$name;
1883
            }
1883
            }
1884
        }
1884
        }
1885
        return $a;
1885
        return $a;
1886
    }
1886
    }
1887
1887
1888
    function &getDefaultGenerator()
1888
    function &getDefaultGenerator()
1889
    {
1889
    {
1890
        if (!class_exists('PEAR_PackageFile_Generator_v2')) {
1890
        if (!class_exists('PEAR_PackageFile_Generator_v2')) {
1891
            require_once 'PEAR/PackageFile/Generator/v2.php';
1891
            require_once 'PEAR/PackageFile/Generator/v2.php';
1892
        }
1892
        }
1893
        $a = &new PEAR_PackageFile_Generator_v2($this);
1893
        $a = &new PEAR_PackageFile_Generator_v2($this);
1894
        return $a;
1894
        return $a;
1895
    }
1895
    }
1896
1896
1897
    function analyzeSourceCode($file, $string = false)
1897
    function analyzeSourceCode($file, $string = false)
1898
    {
1898
    {
1899
        if (!isset($this->_v2Validator) ||
1899
        if (!isset($this->_v2Validator) ||
1900
              !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) {
1900
              !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) {
1901
            if (!class_exists('PEAR_PackageFile_v2_Validator')) {
1901
            if (!class_exists('PEAR_PackageFile_v2_Validator')) {
1902
                require_once 'PEAR/PackageFile/v2/Validator.php';
1902
                require_once 'PEAR/PackageFile/v2/Validator.php';
1903
            }
1903
            }
1904
            $this->_v2Validator = new PEAR_PackageFile_v2_Validator;
1904
            $this->_v2Validator = new PEAR_PackageFile_v2_Validator;
1905
        }
1905
        }
1906
        return $this->_v2Validator->analyzeSourceCode($file, $string);
1906
        return $this->_v2Validator->analyzeSourceCode($file, $string);
1907
    }
1907
    }
1908
1908
1909
    function validate($state = PEAR_VALIDATE_NORMAL)
1909
    function validate($state = PEAR_VALIDATE_NORMAL)
1910
    {
1910
    {
1911
        if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) {
1911
        if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) {
1912
            return false;
1912
            return false;
1913
        }
1913
        }
1914
        if (!isset($this->_v2Validator) ||
1914
        if (!isset($this->_v2Validator) ||
1915
              !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) {
1915
              !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) {
1916
            if (!class_exists('PEAR_PackageFile_v2_Validator')) {
1916
            if (!class_exists('PEAR_PackageFile_v2_Validator')) {
1917
                require_once 'PEAR/PackageFile/v2/Validator.php';
1917
                require_once 'PEAR/PackageFile/v2/Validator.php';
1918
            }
1918
            }
1919
            $this->_v2Validator = new PEAR_PackageFile_v2_Validator;
1919
            $this->_v2Validator = new PEAR_PackageFile_v2_Validator;
1920
        }
1920
        }
1921
        if (isset($this->_packageInfo['xsdversion'])) {
1921
        if (isset($this->_packageInfo['xsdversion'])) {
1922
            unset($this->_packageInfo['xsdversion']);
1922
            unset($this->_packageInfo['xsdversion']);
1923
        }
1923
        }
1924
        return $this->_v2Validator->validate($this, $state);
1924
        return $this->_v2Validator->validate($this, $state);
1925
    }
1925
    }
1926
1926
1927
    function getTasksNs()
1927
    function getTasksNs()
1928
    {
1928
    {
1929
        if (!isset($this->_tasksNs)) {
1929
        if (!isset($this->_tasksNs)) {
1930
            if (isset($this->_packageInfo['attribs'])) {
1930
            if (isset($this->_packageInfo['attribs'])) {
1931
                foreach ($this->_packageInfo['attribs'] as $name => $value) {
1931
                foreach ($this->_packageInfo['attribs'] as $name => $value) {
1932
                    if ($value == 'http://pear.php.net/dtd/tasks-1.0') {
1932
                    if ($value == 'http://pear.php.net/dtd/tasks-1.0') {
1933
                        $this->_tasksNs = str_replace('xmlns:', '', $name);
1933
                        $this->_tasksNs = str_replace('xmlns:', '', $name);
1934
                        break;
1934
                        break;
1935
                    }
1935
                    }
1936
                }
1936
                }
1937
            }
1937
            }
1938
        }
1938
        }
1939
        return $this->_tasksNs;
1939
        return $this->_tasksNs;
1940
    }
1940
    }
1941
1941
1942
    /**
1942
    /**
1943
     * Determine whether a task name is a valid task.  Custom tasks may be defined
1943
     * Determine whether a task name is a valid task.  Custom tasks may be defined
1944
     * using subdirectories by putting a "-" in the name, as in <tasks:mycustom-task>
1944
     * using subdirectories by putting a "-" in the name, as in <tasks:mycustom-task>
1945
     *
1945
     *
1946
     * Note that this method will auto-load the task class file and test for the existence
1946
     * Note that this method will auto-load the task class file and test for the existence
1947
     * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class
1947
     * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class
1948
     * PEAR_Task_mycustom_task
1948
     * PEAR_Task_mycustom_task
1949
     * @param string
1949
     * @param string
1950
     * @return boolean
1950
     * @return boolean
1951
     */
1951
     */
1952
    function getTask($task)
1952
    function getTask($task)
1953
    {
1953
    {
1954
        $this->getTasksNs();
1954
        $this->getTasksNs();
1955
        // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace
1955
        // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace
1956
        $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task);
1956
        $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task);
1957
        $taskfile = str_replace(' ', '/', ucwords($task));
1957
        $taskfile = str_replace(' ', '/', ucwords($task));
1958
        $task = str_replace(array(' ', '/'), '_', ucwords($task));
1958
        $task = str_replace(array(' ', '/'), '_', ucwords($task));
1959
        if (class_exists("PEAR_Task_$task")) {
1959
        if (class_exists("PEAR_Task_$task")) {
1960
            return "PEAR_Task_$task";
1960
            return "PEAR_Task_$task";
1961
        }
1961
        }
1962
        $fp = @fopen("PEAR/Task/$taskfile.php", 'r', true);
1962
        $fp = @fopen("PEAR/Task/$taskfile.php", 'r', true);
1963
        if ($fp) {
1963
        if ($fp) {
1964
            fclose($fp);
1964
            fclose($fp);
1965
            require_once "PEAR/Task/$taskfile.php";
1965
            require_once "PEAR/Task/$taskfile.php";
1966
            return "PEAR_Task_$task";
1966
            return "PEAR_Task_$task";
1967
        }
1967
        }
1968
        return false;
1968
        return false;
1969
    }
1969
    }
1970
1970
1971
    /**
1971
    /**
1972
     * Key-friendly array_splice
1972
     * Key-friendly array_splice
1973
     * @param tagname to splice a value in before
1973
     * @param tagname to splice a value in before
1974
     * @param mixed the value to splice in
1974
     * @param mixed the value to splice in
1975
     * @param string the new tag name
1975
     * @param string the new tag name
1976
     */
1976
     */
1977
    function _ksplice($array, $key, $value, $newkey)
1977
    function _ksplice($array, $key, $value, $newkey)
1978
    {
1978
    {
1979
        $offset = array_search($key, array_keys($array));
1979
        $offset = array_search($key, array_keys($array));
1980
        $after = array_slice($array, $offset);
1980
        $after = array_slice($array, $offset);
1981
        $before = array_slice($array, 0, $offset);
1981
        $before = array_slice($array, 0, $offset);
1982
        $before[$newkey] = $value;
1982
        $before[$newkey] = $value;
1983
        return array_merge($before, $after);
1983
        return array_merge($before, $after);
1984
    }
1984
    }
1985
1985
1986
    /**
1986
    /**
1987
     * @param array a list of possible keys, in the order they may occur
1987
     * @param array a list of possible keys, in the order they may occur
1988
     * @param mixed contents of the new package.xml tag
1988
     * @param mixed contents of the new package.xml tag
1989
     * @param string tag name
1989
     * @param string tag name
1990
     * @access private
1990
     * @access private
1991
     */
1991
     */
1992
    function _insertBefore($array, $keys, $contents, $newkey)
1992
    function _insertBefore($array, $keys, $contents, $newkey)
1993
    {
1993
    {
1994
        foreach ($keys as $key) {
1994
        foreach ($keys as $key) {
1995
            if (isset($array[$key])) {
1995
            if (isset($array[$key])) {
1996
                return $array = $this->_ksplice($array, $key, $contents, $newkey);
1996
                return $array = $this->_ksplice($array, $key, $contents, $newkey);
1997
            }
1997
            }
1998
        }
1998
        }
1999
        $array[$newkey] = $contents;
1999
        $array[$newkey] = $contents;
2000
        return $array;
2000
        return $array;
2001
    }
2001
    }
2002
2002
2003
    /**
2003
    /**
2004
     * @param subsection of {@link $_packageInfo}
2004
     * @param subsection of {@link $_packageInfo}
2005
     * @param array|string tag contents
2005
     * @param array|string tag contents
2006
     * @param array format:
2006
     * @param array format:
2007
     * <pre>
2007
     * <pre>
2008
     * array(
2008
     * array(
2009
     *   tagname => array(list of tag names that follow this one),
2009
     *   tagname => array(list of tag names that follow this one),
2010
     *   childtagname => array(list of child tag names that follow this one),
2010
     *   childtagname => array(list of child tag names that follow this one),
2011
     * )
2011
     * )
2012
     * </pre>
2012
     * </pre>
2013
     *
2013
     *
2014
     * This allows construction of nested tags
2014
     * This allows construction of nested tags
2015
     * @access private
2015
     * @access private
2016
     */
2016
     */
2017
    function _mergeTag($manip, $contents, $order)
2017
    function _mergeTag($manip, $contents, $order)
2018
    {
2018
    {
2019
        if (count($order)) {
2019
        if (count($order)) {
2020
            foreach ($order as $tag => $curorder) {
2020
            foreach ($order as $tag => $curorder) {
2021
                if (!isset($manip[$tag])) {
2021
                if (!isset($manip[$tag])) {
2022
                    // ensure that the tag is set up
2022
                    // ensure that the tag is set up
2023
                    $manip = $this->_insertBefore($manip, $curorder, array(), $tag);
2023
                    $manip = $this->_insertBefore($manip, $curorder, array(), $tag);
2024
                }
2024
                }
2025
                if (count($order) > 1) {
2025
                if (count($order) > 1) {
2026
                    $manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1));
2026
                    $manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1));
2027
                    return $manip;
2027
                    return $manip;
2028
                }
2028
                }
2029
            }
2029
            }
2030
        } else {
2030
        } else {
2031
            return $manip;
2031
            return $manip;
2032
        }
2032
        }
2033
        if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) {
2033
        if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) {
2034
            $manip[$tag][] = $contents;
2034
            $manip[$tag][] = $contents;
2035
        } else {
2035
        } else {
2036
            if (!count($manip[$tag])) {
2036
            if (!count($manip[$tag])) {
2037
                $manip[$tag] = $contents;
2037
                $manip[$tag] = $contents;
2038
            } else {
2038
            } else {
2039
                $manip[$tag] = array($manip[$tag]);
2039
                $manip[$tag] = array($manip[$tag]);
2040
                $manip[$tag][] = $contents;
2040
                $manip[$tag][] = $contents;
2041
            }
2041
            }
2042
        }
2042
        }
2043
        return $manip;
2043
        return $manip;
2044
    }
2044
    }
2045
}
2045
}
2046
?>
2046
?>
2047
 
2047