Хранилища Subversion ant

Редакция

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

Редакция 69 Редакция 94
1
<?php
1
<?php
2
/**
2
/**
3
 * PEAR_PackageFile_v1, package.xml version 1.0
3
 * PEAR_PackageFile_v1, package.xml version 1.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: v1.php,v 1.74 2008/01/03 20:26:36 cellog Exp $
18
 * @version    CVS: $Id: v1.php,v 1.74 2008/01/03 20:26:36 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
/**
27
/**
28
 * Error code if parsing is attempted with no xml extension
28
 * Error code if parsing is attempted with no xml extension
29
 */
29
 */
30
define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3);
30
define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3);
31
31
32
/**
32
/**
33
 * Error code if creating the xml parser resource fails
33
 * Error code if creating the xml parser resource fails
34
 */
34
 */
35
define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4);
35
define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4);
36
36
37
/**
37
/**
38
 * Error code used for all sax xml parsing errors
38
 * Error code used for all sax xml parsing errors
39
 */
39
 */
40
define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5);
40
define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5);
41
41
42
/**
42
/**
43
 * Error code used when there is no name
43
 * Error code used when there is no name
44
 */
44
 */
45
define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6);
45
define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6);
46
46
47
/**
47
/**
48
 * Error code when a package name is not valid
48
 * Error code when a package name is not valid
49
 */
49
 */
50
define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7);
50
define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7);
51
51
52
/**
52
/**
53
 * Error code used when no summary is parsed
53
 * Error code used when no summary is parsed
54
 */
54
 */
55
define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8);
55
define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8);
56
56
57
/**
57
/**
58
 * Error code for summaries that are more than 1 line
58
 * Error code for summaries that are more than 1 line
59
 */
59
 */
60
define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9);
60
define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9);
61
61
62
/**
62
/**
63
 * Error code used when no description is present
63
 * Error code used when no description is present
64
 */
64
 */
65
define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10);
65
define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10);
66
66
67
/**
67
/**
68
 * Error code used when no license is present
68
 * Error code used when no license is present
69
 */
69
 */
70
define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11);
70
define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11);
71
71
72
/**
72
/**
73
 * Error code used when a <version> version number is not present
73
 * Error code used when a <version> version number is not present
74
 */
74
 */
75
define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12);
75
define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12);
76
76
77
/**
77
/**
78
 * Error code used when a <version> version number is invalid
78
 * Error code used when a <version> version number is invalid
79
 */
79
 */
80
define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13);
80
define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13);
81
81
82
/**
82
/**
83
 * Error code when release state is missing
83
 * Error code when release state is missing
84
 */
84
 */
85
define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14);
85
define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14);
86
86
87
/**
87
/**
88
 * Error code when release state is invalid
88
 * Error code when release state is invalid
89
 */
89
 */
90
define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15);
90
define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15);
91
91
92
/**
92
/**
93
 * Error code when release state is missing
93
 * Error code when release state is missing
94
 */
94
 */
95
define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16);
95
define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16);
96
96
97
/**
97
/**
98
 * Error code when release state is invalid
98
 * Error code when release state is invalid
99
 */
99
 */
100
define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17);
100
define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17);
101
101
102
/**
102
/**
103
 * Error code when no release notes are found
103
 * Error code when no release notes are found
104
 */
104
 */
105
define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18);
105
define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18);
106
106
107
/**
107
/**
108
 * Error code when no maintainers are found
108
 * Error code when no maintainers are found
109
 */
109
 */
110
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19);
110
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19);
111
111
112
/**
112
/**
113
 * Error code when a maintainer has no handle
113
 * Error code when a maintainer has no handle
114
 */
114
 */
115
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20);
115
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20);
116
116
117
/**
117
/**
118
 * Error code when a maintainer has no handle
118
 * Error code when a maintainer has no handle
119
 */
119
 */
120
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21);
120
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21);
121
121
122
/**
122
/**
123
 * Error code when a maintainer has no name
123
 * Error code when a maintainer has no name
124
 */
124
 */
125
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22);
125
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22);
126
126
127
/**
127
/**
128
 * Error code when a maintainer has no email
128
 * Error code when a maintainer has no email
129
 */
129
 */
130
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23);
130
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23);
131
131
132
/**
132
/**
133
 * Error code when a maintainer has no handle
133
 * Error code when a maintainer has no handle
134
 */
134
 */
135
define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24);
135
define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24);
136
136
137
/**
137
/**
138
 * Error code when a dependency is not a PHP dependency, but has no name
138
 * Error code when a dependency is not a PHP dependency, but has no name
139
 */
139
 */
140
define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25);
140
define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25);
141
141
142
/**
142
/**
143
 * Error code when a dependency has no type (pkg, php, etc.)
143
 * Error code when a dependency has no type (pkg, php, etc.)
144
 */
144
 */
145
define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26);
145
define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26);
146
146
147
/**
147
/**
148
 * Error code when a dependency has no relation (lt, ge, has, etc.)
148
 * Error code when a dependency has no relation (lt, ge, has, etc.)
149
 */
149
 */
150
define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27);
150
define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27);
151
151
152
/**
152
/**
153
 * Error code when a dependency is not a 'has' relation, but has no version
153
 * Error code when a dependency is not a 'has' relation, but has no version
154
 */
154
 */
155
define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28);
155
define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28);
156
156
157
/**
157
/**
158
 * Error code when a dependency has an invalid relation
158
 * Error code when a dependency has an invalid relation
159
 */
159
 */
160
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29);
160
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29);
161
161
162
/**
162
/**
163
 * Error code when a dependency has an invalid type
163
 * Error code when a dependency has an invalid type
164
 */
164
 */
165
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30);
165
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30);
166
166
167
/**
167
/**
168
 * Error code when a dependency has an invalid optional option
168
 * Error code when a dependency has an invalid optional option
169
 */
169
 */
170
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31);
170
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31);
171
171
172
/**
172
/**
173
 * Error code when a dependency is a pkg dependency, and has an invalid package name
173
 * Error code when a dependency is a pkg dependency, and has an invalid package name
174
 */
174
 */
175
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32);
175
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32);
176
176
177
/**
177
/**
178
 * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel
178
 * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel
179
 */
179
 */
180
define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33);
180
define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33);
181
181
182
/**
182
/**
183
 * Error code when rel="has" and version attribute is present.
183
 * Error code when rel="has" and version attribute is present.
184
 */
184
 */
185
define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34);
185
define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34);
186
186
187
/**
187
/**
188
 * Error code when type="php" and dependency name is present
188
 * Error code when type="php" and dependency name is present
189
 */
189
 */
190
define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35);
190
define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35);
191
191
192
/**
192
/**
193
 * Error code when a configure option has no name
193
 * Error code when a configure option has no name
194
 */
194
 */
195
define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36);
195
define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36);
196
196
197
/**
197
/**
198
 * Error code when a configure option has no name
198
 * Error code when a configure option has no name
199
 */
199
 */
200
define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37);
200
define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37);
201
201
202
/**
202
/**
203
 * Error code when a file in the filelist has an invalid role
203
 * Error code when a file in the filelist has an invalid role
204
 */
204
 */
205
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38);
205
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38);
206
206
207
/**
207
/**
208
 * Error code when a file in the filelist has no role
208
 * Error code when a file in the filelist has no role
209
 */
209
 */
210
define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39);
210
define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39);
211
211
212
/**
212
/**
213
 * Error code when analyzing a php source file that has parse errors
213
 * Error code when analyzing a php source file that has parse errors
214
 */
214
 */
215
define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40);
215
define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40);
216
216
217
/**
217
/**
218
 * Error code when analyzing a php source file reveals a source element
218
 * Error code when analyzing a php source file reveals a source element
219
 * without a package name prefix
219
 * without a package name prefix
220
 */
220
 */
221
define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41);
221
define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41);
222
222
223
/**
223
/**
224
 * Error code when an unknown channel is specified
224
 * Error code when an unknown channel is specified
225
 */
225
 */
226
define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42);
226
define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42);
227
227
228
/**
228
/**
229
 * Error code when no files are found in the filelist
229
 * Error code when no files are found in the filelist
230
 */
230
 */
231
define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43);
231
define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43);
232
232
233
/**
233
/**
234
 * Error code when a file is not valid php according to _analyzeSourceCode()
234
 * Error code when a file is not valid php according to _analyzeSourceCode()
235
 */
235
 */
236
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44);
236
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44);
237
237
238
/**
238
/**
239
 * Error code when the channel validator returns an error or warning
239
 * Error code when the channel validator returns an error or warning
240
 */
240
 */
241
define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45);
241
define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45);
242
242
243
/**
243
/**
244
 * Error code when a php5 package is packaged in php4 (analysis doesn't work)
244
 * Error code when a php5 package is packaged in php4 (analysis doesn't work)
245
 */
245
 */
246
define('PEAR_PACKAGEFILE_ERROR_PHP5', 46);
246
define('PEAR_PACKAGEFILE_ERROR_PHP5', 46);
247
247
248
/**
248
/**
249
 * Error code when a file is listed in package.xml but does not exist
249
 * Error code when a file is listed in package.xml but does not exist
250
 */
250
 */
251
define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47);
251
define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47);
252
252
253
/**
253
/**
254
 * Error code when a <dep type="php" rel="not"... is encountered (use rel="ne")
254
 * Error code when a <dep type="php" rel="not"... is encountered (use rel="ne")
255
 */
255
 */
256
define('PEAR_PACKAGEFILE_PHP_NO_NOT', 48);
256
define('PEAR_PACKAGEFILE_PHP_NO_NOT', 48);
257
257
258
/**
258
/**
259
 * Error code when a package.xml contains non-ISO-8859-1 characters
259
 * Error code when a package.xml contains non-ISO-8859-1 characters
260
 */
260
 */
261
define('PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS', 49);
261
define('PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS', 49);
262
262
263
/**
263
/**
264
 * Error code when a dependency is not a 'has' relation, but has no version
264
 * Error code when a dependency is not a 'has' relation, but has no version
265
 */
265
 */
266
define('PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION', 50);
266
define('PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION', 50);
267
267
268
/**
268
/**
269
 * Error code when a package has no lead developer
269
 * Error code when a package has no lead developer
270
 */
270
 */
271
define('PEAR_PACKAGEFILE_ERROR_NO_LEAD', 51);
271
define('PEAR_PACKAGEFILE_ERROR_NO_LEAD', 51);
272
272
273
/**
273
/**
274
 * Error code when a filename begins with "."
274
 * Error code when a filename begins with "."
275
 */
275
 */
276
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME', 52);
276
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME', 52);
277
/**
277
/**
278
 * package.xml encapsulator
278
 * package.xml encapsulator
279
 * @category   pear
279
 * @category   pear
280
 * @package    PEAR
280
 * @package    PEAR
281
 * @author     Greg Beaver <cellog@php.net>
281
 * @author     Greg Beaver <cellog@php.net>
282
 * @copyright  1997-2008 The PHP Group
282
 * @copyright  1997-2008 The PHP Group
283
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
283
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
284
 * @version    Release: 1.7.2
284
 * @version    Release: 1.7.2
285
 * @link       http://pear.php.net/package/PEAR
285
 * @link       http://pear.php.net/package/PEAR
286
 * @since      Class available since Release 1.4.0a1
286
 * @since      Class available since Release 1.4.0a1
287
 */
287
 */
288
class PEAR_PackageFile_v1
288
class PEAR_PackageFile_v1
289
{
289
{
290
    /**
290
    /**
291
     * @access private
291
     * @access private
292
     * @var PEAR_ErrorStack
292
     * @var PEAR_ErrorStack
293
     * @access private
293
     * @access private
294
     */
294
     */
295
    var $_stack;
295
    var $_stack;
296
296
297
    /**
297
    /**
298
     * A registry object, used to access the package name validation regex for non-standard channels
298
     * A registry object, used to access the package name validation regex for non-standard channels
299
     * @var PEAR_Registry
299
     * @var PEAR_Registry
300
     * @access private
300
     * @access private
301
     */
301
     */
302
    var $_registry;
302
    var $_registry;
303
303
304
    /**
304
    /**
305
     * An object that contains a log method that matches PEAR_Common::log's signature
305
     * An object that contains a log method that matches PEAR_Common::log's signature
306
     * @var object
306
     * @var object
307
     * @access private
307
     * @access private
308
     */
308
     */
309
    var $_logger;
309
    var $_logger;
310
310
311
    /**
311
    /**
312
     * Parsed package information
312
     * Parsed package information
313
     * @var array
313
     * @var array
314
     * @access private
314
     * @access private
315
     */
315
     */
316
    var $_packageInfo;
316
    var $_packageInfo;
317
317
318
    /**
318
    /**
319
     * path to package.xml
319
     * path to package.xml
320
     * @var string
320
     * @var string
321
     * @access private
321
     * @access private
322
     */
322
     */
323
    var $_packageFile;
323
    var $_packageFile;
324
324
325
    /**
325
    /**
326
     * path to package .tgz or false if this is a local/extracted package.xml
326
     * path to package .tgz or false if this is a local/extracted package.xml
327
     * @var string
327
     * @var string
328
     * @access private
328
     * @access private
329
     */
329
     */
330
    var $_archiveFile;
330
    var $_archiveFile;
331
331
332
    /**
332
    /**
333
     * @var int
333
     * @var int
334
     * @access private
334
     * @access private
335
     */
335
     */
336
    var $_isValid = 0;
336
    var $_isValid = 0;
337
337
338
    /**
338
    /**
339
     * Determines whether this packagefile was initialized only with partial package info
339
     * Determines whether this packagefile was initialized only with partial package info
340
     *
340
     *
341
     * If this package file was constructed via parsing REST, it will only contain
341
     * If this package file was constructed via parsing REST, it will only contain
342
     *
342
     *
343
     * - package name
343
     * - package name
344
     * - channel name
344
     * - channel name
345
     * - dependencies
345
     * - dependencies
346
     * @var boolean
346
     * @var boolean
347
     * @access private
347
     * @access private
348
     */
348
     */
349
    var $_incomplete = true;
349
    var $_incomplete = true;
350
350
351
    /**
351
    /**
352
     * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack
352
     * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack
353
     * @param string Name of Error Stack class to use.
353
     * @param string Name of Error Stack class to use.
354
     */
354
     */
355
    function PEAR_PackageFile_v1()
355
    function PEAR_PackageFile_v1()
356
    {
356
    {
357
        $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1');
357
        $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1');
358
        $this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
358
        $this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
359
        $this->_isValid = 0;
359
        $this->_isValid = 0;
360
    }
360
    }
361
361
362
    function installBinary($installer)
362
    function installBinary($installer)
363
    {
363
    {
364
        return false;
364
        return false;
365
    }
365
    }
366
366
367
    function isExtension($name)
367
    function isExtension($name)
368
    {
368
    {
369
        return false;
369
        return false;
370
    }
370
    }
371
371
372
    function setConfig(&$config)
372
    function setConfig(&$config)
373
    {
373
    {
374
        $this->_config = &$config;
374
        $this->_config = &$config;
375
        $this->_registry = &$config->getRegistry();
375
        $this->_registry = &$config->getRegistry();
376
    }
376
    }
377
377
378
    function setRequestedGroup()
378
    function setRequestedGroup()
379
    {
379
    {
380
        // placeholder
380
        // placeholder
381
    }
381
    }
382
382
383
    /**
383
    /**
384
     * For saving in the registry.
384
     * For saving in the registry.
385
     *
385
     *
386
     * Set the last version that was installed
386
     * Set the last version that was installed
387
     * @param string
387
     * @param string
388
     */
388
     */
389
    function setLastInstalledVersion($version)
389
    function setLastInstalledVersion($version)
390
    {
390
    {
391
        $this->_packageInfo['_lastversion'] = $version;
391
        $this->_packageInfo['_lastversion'] = $version;
392
    }
392
    }
393
393
394
    /**
394
    /**
395
     * @return string|false
395
     * @return string|false
396
     */
396
     */
397
    function getLastInstalledVersion()
397
    function getLastInstalledVersion()
398
    {
398
    {
399
        if (isset($this->_packageInfo['_lastversion'])) {
399
        if (isset($this->_packageInfo['_lastversion'])) {
400
            return $this->_packageInfo['_lastversion'];
400
            return $this->_packageInfo['_lastversion'];
401
        }
401
        }
402
        return false;
402
        return false;
403
    }
403
    }
404
404
405
    function getInstalledBinary()
405
    function getInstalledBinary()
406
    {
406
    {
407
        return false;
407
        return false;
408
    }
408
    }
409
409
410
    function listPostinstallScripts()
410
    function listPostinstallScripts()
411
    {
411
    {
412
        return false;
412
        return false;
413
    }
413
    }
414
414
415
    function initPostinstallScripts()
415
    function initPostinstallScripts()
416
    {
416
    {
417
        return false;
417
        return false;
418
    }
418
    }
419
419
420
    function setLogger(&$logger)
420
    function setLogger(&$logger)
421
    {
421
    {
422
        if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) {
422
        if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) {
423
            return PEAR::raiseError('Logger must be compatible with PEAR_Common::log');
423
            return PEAR::raiseError('Logger must be compatible with PEAR_Common::log');
424
        }
424
        }
425
        $this->_logger = &$logger;
425
        $this->_logger = &$logger;
426
    }
426
    }
427
427
428
    function setPackagefile($file, $archive = false)
428
    function setPackagefile($file, $archive = false)
429
    {
429
    {
430
        $this->_packageFile = $file;
430
        $this->_packageFile = $file;
431
        $this->_archiveFile = $archive ? $archive : $file;
431
        $this->_archiveFile = $archive ? $archive : $file;
432
    }
432
    }
433
433
434
    function getPackageFile()
434
    function getPackageFile()
435
    {
435
    {
436
        return isset($this->_packageFile) ? $this->_packageFile : false;
436
        return isset($this->_packageFile) ? $this->_packageFile : false;
437
    }
437
    }
438
438
439
    function getPackageType()
439
    function getPackageType()
440
    {
440
    {
441
        return 'php';
441
        return 'php';
442
    }
442
    }
443
443
444
    function getArchiveFile()
444
    function getArchiveFile()
445
    {
445
    {
446
        return $this->_archiveFile;
446
        return $this->_archiveFile;
447
    }
447
    }
448
448
449
    function packageInfo($field)
449
    function packageInfo($field)
450
    {
450
    {
451
        if (!is_string($field) || empty($field) ||
451
        if (!is_string($field) || empty($field) ||
452
            !isset($this->_packageInfo[$field])) {
452
            !isset($this->_packageInfo[$field])) {
453
            return false;
453
            return false;
454
        }
454
        }
455
        return $this->_packageInfo[$field];
455
        return $this->_packageInfo[$field];
456
    }
456
    }
457
457
458
    function setDirtree($path)
458
    function setDirtree($path)
459
    {
459
    {
460
        if (!isset($this->_packageInfo['dirtree'])) {
460
        if (!isset($this->_packageInfo['dirtree'])) {
461
            $this->_packageInfo['dirtree'] = array();
461
            $this->_packageInfo['dirtree'] = array();
462
        }
462
        }
463
        $this->_packageInfo['dirtree'][$path] = true;
463
        $this->_packageInfo['dirtree'][$path] = true;
464
    }
464
    }
465
465
466
    function getDirtree()
466
    function getDirtree()
467
    {
467
    {
468
        if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) {
468
        if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) {
469
            return $this->_packageInfo['dirtree'];
469
            return $this->_packageInfo['dirtree'];
470
        }
470
        }
471
        return false;
471
        return false;
472
    }
472
    }
473
473
474
    function resetDirtree()
474
    function resetDirtree()
475
    {
475
    {
476
        unset($this->_packageInfo['dirtree']);
476
        unset($this->_packageInfo['dirtree']);
477
    }
477
    }
478
478
479
    function fromArray($pinfo)
479
    function fromArray($pinfo)
480
    {
480
    {
481
        $this->_incomplete = false;
481
        $this->_incomplete = false;
482
        $this->_packageInfo = $pinfo;
482
        $this->_packageInfo = $pinfo;
483
    }
483
    }
484
484
485
    function isIncomplete()
485
    function isIncomplete()
486
    {
486
    {
487
        return $this->_incomplete;
487
        return $this->_incomplete;
488
    }
488
    }
489
489
490
    function getChannel()
490
    function getChannel()
491
    {
491
    {
492
        return 'pear.php.net';
492
        return 'pear.php.net';
493
    }
493
    }
494
494
495
    function getUri()
495
    function getUri()
496
    {
496
    {
497
        return false;
497
        return false;
498
    }
498
    }
499
499
500
    function getTime()
500
    function getTime()
501
    {
501
    {
502
        return false;
502
        return false;
503
    }
503
    }
504
504
505
    function getExtends()
505
    function getExtends()
506
    {
506
    {
507
        if (isset($this->_packageInfo['extends'])) {
507
        if (isset($this->_packageInfo['extends'])) {
508
            return $this->_packageInfo['extends'];
508
            return $this->_packageInfo['extends'];
509
        }
509
        }
510
        return false;
510
        return false;
511
    }
511
    }
512
512
513
    /**
513
    /**
514
     * @return array
514
     * @return array
515
     */
515
     */
516
    function toArray()
516
    function toArray()
517
    {
517
    {
518
        if (!$this->validate(PEAR_VALIDATE_NORMAL)) {
518
        if (!$this->validate(PEAR_VALIDATE_NORMAL)) {
519
            return false;
519
            return false;
520
        }
520
        }
521
        return $this->getArray();
521
        return $this->getArray();
522
    }
522
    }
523
523
524
    function getArray()
524
    function getArray()
525
    {
525
    {
526
        return $this->_packageInfo;
526
        return $this->_packageInfo;
527
    }
527
    }
528
528
529
    function getName()
529
    function getName()
530
    {
530
    {
531
        return $this->getPackage();
531
        return $this->getPackage();
532
    }
532
    }
533
533
534
    function getPackage()
534
    function getPackage()
535
    {
535
    {
536
        if (isset($this->_packageInfo['package'])) {
536
        if (isset($this->_packageInfo['package'])) {
537
            return $this->_packageInfo['package'];
537
            return $this->_packageInfo['package'];
538
        }
538
        }
539
        return false;
539
        return false;
540
    }
540
    }
541
541
542
    /**
542
    /**
543
     * WARNING - don't use this unless you know what you are doing
543
     * WARNING - don't use this unless you know what you are doing
544
     */
544
     */
545
    function setRawPackage($package)
545
    function setRawPackage($package)
546
    {
546
    {
547
        $this->_packageInfo['package'] = $package;
547
        $this->_packageInfo['package'] = $package;
548
    }
548
    }
549
549
550
    function setPackage($package)
550
    function setPackage($package)
551
    {
551
    {
552
        $this->_packageInfo['package'] = $package;
552
        $this->_packageInfo['package'] = $package;
553
        $this->_isValid = false;
553
        $this->_isValid = false;
554
    }
554
    }
555
555
556
    function getVersion()
556
    function getVersion()
557
    {
557
    {
558
        if (isset($this->_packageInfo['version'])) {
558
        if (isset($this->_packageInfo['version'])) {
559
            return $this->_packageInfo['version'];
559
            return $this->_packageInfo['version'];
560
        }
560
        }
561
        return false;
561
        return false;
562
    }
562
    }
563
563
564
    function setVersion($version)
564
    function setVersion($version)
565
    {
565
    {
566
        $this->_packageInfo['version'] = $version;
566
        $this->_packageInfo['version'] = $version;
567
        $this->_isValid = false;
567
        $this->_isValid = false;
568
    }
568
    }
569
569
570
    function clearMaintainers()
570
    function clearMaintainers()
571
    {
571
    {
572
        unset($this->_packageInfo['maintainers']);
572
        unset($this->_packageInfo['maintainers']);
573
    }
573
    }
574
574
575
    function getMaintainers()
575
    function getMaintainers()
576
    {
576
    {
577
        if (isset($this->_packageInfo['maintainers'])) {
577
        if (isset($this->_packageInfo['maintainers'])) {
578
            return $this->_packageInfo['maintainers'];
578
            return $this->_packageInfo['maintainers'];
579
        }
579
        }
580
        return false;
580
        return false;
581
    }
581
    }
582
582
583
    /**
583
    /**
584
     * Adds a new maintainer - no checking of duplicates is performed, use
584
     * Adds a new maintainer - no checking of duplicates is performed, use
585
     * updatemaintainer for that purpose.
585
     * updatemaintainer for that purpose.
586
     */
586
     */
587
    function addMaintainer($role, $handle, $name, $email)
587
    function addMaintainer($role, $handle, $name, $email)
588
    {
588
    {
589
        $this->_packageInfo['maintainers'][] =
589
        $this->_packageInfo['maintainers'][] =
590
            array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name);
590
            array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name);
591
        $this->_isValid = false;
591
        $this->_isValid = false;
592
    }
592
    }
593
593
594
    function updateMaintainer($role, $handle, $name, $email)
594
    function updateMaintainer($role, $handle, $name, $email)
595
    {
595
    {
596
        $found = false;
596
        $found = false;
597
        if (!isset($this->_packageInfo['maintainers']) ||
597
        if (!isset($this->_packageInfo['maintainers']) ||
598
              !is_array($this->_packageInfo['maintainers'])) {
598
              !is_array($this->_packageInfo['maintainers'])) {
599
            return $this->addMaintainer($role, $handle, $name, $email);
599
            return $this->addMaintainer($role, $handle, $name, $email);
600
        }
600
        }
601
        foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
601
        foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
602
            if ($maintainer['handle'] == $handle) {
602
            if ($maintainer['handle'] == $handle) {
603
                $found = $i;
603
                $found = $i;
604
                break;
604
                break;
605
            }
605
            }
606
        }
606
        }
607
        if ($found !== false) {
607
        if ($found !== false) {
608
            unset($this->_packageInfo['maintainers'][$found]);
608
            unset($this->_packageInfo['maintainers'][$found]);
609
            $this->_packageInfo['maintainers'] =
609
            $this->_packageInfo['maintainers'] =
610
                array_values($this->_packageInfo['maintainers']);
610
                array_values($this->_packageInfo['maintainers']);
611
        }
611
        }
612
        $this->addMaintainer($role, $handle, $name, $email);
612
        $this->addMaintainer($role, $handle, $name, $email);
613
    }
613
    }
614
614
615
    function deleteMaintainer($handle)
615
    function deleteMaintainer($handle)
616
    {
616
    {
617
        $found = false;
617
        $found = false;
618
        foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
618
        foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
619
            if ($maintainer['handle'] == $handle) {
619
            if ($maintainer['handle'] == $handle) {
620
                $found = $i;
620
                $found = $i;
621
                break;
621
                break;
622
            }
622
            }
623
        }
623
        }
624
        if ($found !== false) {
624
        if ($found !== false) {
625
            unset($this->_packageInfo['maintainers'][$found]);
625
            unset($this->_packageInfo['maintainers'][$found]);
626
            $this->_packageInfo['maintainers'] =
626
            $this->_packageInfo['maintainers'] =
627
                array_values($this->_packageInfo['maintainers']);
627
                array_values($this->_packageInfo['maintainers']);
628
            return true;
628
            return true;
629
        }
629
        }
630
        return false;
630
        return false;
631
    }
631
    }
632
632
633
    function getState()
633
    function getState()
634
    {
634
    {
635
        if (isset($this->_packageInfo['release_state'])) {
635
        if (isset($this->_packageInfo['release_state'])) {
636
            return $this->_packageInfo['release_state'];
636
            return $this->_packageInfo['release_state'];
637
        }
637
        }
638
        return false;
638
        return false;
639
    }
639
    }
640
640
641
    function setRawState($state)
641
    function setRawState($state)
642
    {
642
    {
643
        $this->_packageInfo['release_state'] = $state;
643
        $this->_packageInfo['release_state'] = $state;
644
    }
644
    }
645
645
646
    function setState($state)
646
    function setState($state)
647
    {
647
    {
648
        $this->_packageInfo['release_state'] = $state;
648
        $this->_packageInfo['release_state'] = $state;
649
        $this->_isValid = false;
649
        $this->_isValid = false;
650
    }
650
    }
651
651
652
    function getDate()
652
    function getDate()
653
    {
653
    {
654
        if (isset($this->_packageInfo['release_date'])) {
654
        if (isset($this->_packageInfo['release_date'])) {
655
            return $this->_packageInfo['release_date'];
655
            return $this->_packageInfo['release_date'];
656
        }
656
        }
657
        return false;
657
        return false;
658
    }
658
    }
659
659
660
    function setDate($date)
660
    function setDate($date)
661
    {
661
    {
662
        $this->_packageInfo['release_date'] = $date;
662
        $this->_packageInfo['release_date'] = $date;
663
        $this->_isValid = false;
663
        $this->_isValid = false;
664
    }
664
    }
665
665
666
    function getLicense()
666
    function getLicense()
667
    {
667
    {
668
        if (isset($this->_packageInfo['release_license'])) {
668
        if (isset($this->_packageInfo['release_license'])) {
669
            return $this->_packageInfo['release_license'];
669
            return $this->_packageInfo['release_license'];
670
        }
670
        }
671
        return false;
671
        return false;
672
    }
672
    }
673
673
674
    function setLicense($date)
674
    function setLicense($date)
675
    {
675
    {
676
        $this->_packageInfo['release_license'] = $date;
676
        $this->_packageInfo['release_license'] = $date;
677
        $this->_isValid = false;
677
        $this->_isValid = false;
678
    }
678
    }
679
679
680
    function getSummary()
680
    function getSummary()
681
    {
681
    {
682
        if (isset($this->_packageInfo['summary'])) {
682
        if (isset($this->_packageInfo['summary'])) {
683
            return $this->_packageInfo['summary'];
683
            return $this->_packageInfo['summary'];
684
        }
684
        }
685
        return false;
685
        return false;
686
    }
686
    }
687
687
688
    function setSummary($summary)
688
    function setSummary($summary)
689
    {
689
    {
690
        $this->_packageInfo['summary'] = $summary;
690
        $this->_packageInfo['summary'] = $summary;
691
        $this->_isValid = false;
691
        $this->_isValid = false;
692
    }
692
    }
693
693
694
    function getDescription()
694
    function getDescription()
695
    {
695
    {
696
        if (isset($this->_packageInfo['description'])) {
696
        if (isset($this->_packageInfo['description'])) {
697
            return $this->_packageInfo['description'];
697
            return $this->_packageInfo['description'];
698
        }
698
        }
699
        return false;
699
        return false;
700
    }
700
    }
701
701
702
    function setDescription($desc)
702
    function setDescription($desc)
703
    {
703
    {
704
        $this->_packageInfo['description'] = $desc;
704
        $this->_packageInfo['description'] = $desc;
705
        $this->_isValid = false;
705
        $this->_isValid = false;
706
    }
706
    }
707
707
708
    function getNotes()
708
    function getNotes()
709
    {
709
    {
710
        if (isset($this->_packageInfo['release_notes'])) {
710
        if (isset($this->_packageInfo['release_notes'])) {
711
            return $this->_packageInfo['release_notes'];
711
            return $this->_packageInfo['release_notes'];
712
        }
712
        }
713
        return false;
713
        return false;
714
    }
714
    }
715
715
716
    function setNotes($notes)
716
    function setNotes($notes)
717
    {
717
    {
718
        $this->_packageInfo['release_notes'] = $notes;
718
        $this->_packageInfo['release_notes'] = $notes;
719
        $this->_isValid = false;
719
        $this->_isValid = false;
720
    }
720
    }
721
721
722
    function getDeps()
722
    function getDeps()
723
    {
723
    {
724
        if (isset($this->_packageInfo['release_deps'])) {
724
        if (isset($this->_packageInfo['release_deps'])) {
725
            return $this->_packageInfo['release_deps'];
725
            return $this->_packageInfo['release_deps'];
726
        }
726
        }
727
        return false;
727
        return false;
728
    }
728
    }
729
729
730
    /**
730
    /**
731
     * Reset dependencies prior to adding new ones
731
     * Reset dependencies prior to adding new ones
732
     */
732
     */
733
    function clearDeps()
733
    function clearDeps()
734
    {
734
    {
735
        unset($this->_packageInfo['release_deps']);
735
        unset($this->_packageInfo['release_deps']);
736
    }
736
    }
737
737
738
    function addPhpDep($version, $rel)
738
    function addPhpDep($version, $rel)
739
    {
739
    {
740
        $this->_isValid = false;
740
        $this->_isValid = false;
741
        $this->_packageInfo['release_deps'][] =
741
        $this->_packageInfo['release_deps'][] =
742
            array('type' => 'php',
742
            array('type' => 'php',
743
                  'rel' => $rel,
743
                  'rel' => $rel,
744
                  'version' => $version);
744
                  'version' => $version);
745
    }
745
    }
746
746
747
    function addPackageDep($name, $version, $rel, $optional = 'no')
747
    function addPackageDep($name, $version, $rel, $optional = 'no')
748
    {
748
    {
749
        $this->_isValid = false;
749
        $this->_isValid = false;
750
        $dep =
750
        $dep =
751
            array('type' => 'pkg',
751
            array('type' => 'pkg',
752
                  'name' => $name,
752
                  'name' => $name,
753
                  'rel' => $rel,
753
                  'rel' => $rel,
754
                  'optional' => $optional);
754
                  'optional' => $optional);
755
        if ($rel != 'has' && $rel != 'not') {
755
        if ($rel != 'has' && $rel != 'not') {
756
            $dep['version'] = $version;
756
            $dep['version'] = $version;
757
        }
757
        }
758
        $this->_packageInfo['release_deps'][] = $dep;
758
        $this->_packageInfo['release_deps'][] = $dep;
759
    }
759
    }
760
760
761
    function addExtensionDep($name, $version, $rel, $optional = 'no')
761
    function addExtensionDep($name, $version, $rel, $optional = 'no')
762
    {
762
    {
763
        $this->_isValid = false;
763
        $this->_isValid = false;
764
        $this->_packageInfo['release_deps'][] =
764
        $this->_packageInfo['release_deps'][] =
765
            array('type' => 'ext',
765
            array('type' => 'ext',
766
                  'name' => $name,
766
                  'name' => $name,
767
                  'rel' => $rel,
767
                  'rel' => $rel,
768
                  'version' => $version,
768
                  'version' => $version,
769
                  'optional' => $optional);
769
                  'optional' => $optional);
770
    }
770
    }
771
771
772
    /**
772
    /**
773
     * WARNING - do not use this function directly unless you know what you're doing
773
     * WARNING - do not use this function directly unless you know what you're doing
774
     */
774
     */
775
    function setDeps($deps)
775
    function setDeps($deps)
776
    {
776
    {
777
        $this->_packageInfo['release_deps'] = $deps;
777
        $this->_packageInfo['release_deps'] = $deps;
778
    }
778
    }
779
779
780
    function hasDeps()
780
    function hasDeps()
781
    {
781
    {
782
        return isset($this->_packageInfo['release_deps']) &&
782
        return isset($this->_packageInfo['release_deps']) &&
783
            count($this->_packageInfo['release_deps']);
783
            count($this->_packageInfo['release_deps']);
784
    }
784
    }
785
785
786
    function getDependencyGroup($group)
786
    function getDependencyGroup($group)
787
    {
787
    {
788
        return false;
788
        return false;
789
    }
789
    }
790
790
791
    function isCompatible($pf)
791
    function isCompatible($pf)
792
    {
792
    {
793
        return false;
793
        return false;
794
    }
794
    }
795
795
796
    function isSubpackageOf($p)
796
    function isSubpackageOf($p)
797
    {
797
    {
798
        return $p->isSubpackage($this);
798
        return $p->isSubpackage($this);
799
    }
799
    }
800
800
801
    function isSubpackage($p)
801
    function isSubpackage($p)
802
    {
802
    {
803
        return false;
803
        return false;
804
    }
804
    }
805
805
806
    function dependsOn($package, $channel)
806
    function dependsOn($package, $channel)
807
    {
807
    {
808
        if (strtolower($channel) != 'pear.php.net') {
808
        if (strtolower($channel) != 'pear.php.net') {
809
            return false;
809
            return false;
810
        }
810
        }
811
        if (!($deps = $this->getDeps())) {
811
        if (!($deps = $this->getDeps())) {
812
            return false;
812
            return false;
813
        }
813
        }
814
        foreach ($deps as $dep) {
814
        foreach ($deps as $dep) {
815
            if ($dep['type'] != 'pkg') {
815
            if ($dep['type'] != 'pkg') {
816
                continue;
816
                continue;
817
            }
817
            }
818
            if (strtolower($dep['name']) == strtolower($package)) {
818
            if (strtolower($dep['name']) == strtolower($package)) {
819
                return true;
819
                return true;
820
            }
820
            }
821
        }
821
        }
822
        return false;
822
        return false;
823
    }
823
    }
824
824
825
    function getConfigureOptions()
825
    function getConfigureOptions()
826
    {
826
    {
827
        if (isset($this->_packageInfo['configure_options'])) {
827
        if (isset($this->_packageInfo['configure_options'])) {
828
            return $this->_packageInfo['configure_options'];
828
            return $this->_packageInfo['configure_options'];
829
        }
829
        }
830
        return false;
830
        return false;
831
    }
831
    }
832
832
833
    function hasConfigureOptions()
833
    function hasConfigureOptions()
834
    {
834
    {
835
        return isset($this->_packageInfo['configure_options']) &&
835
        return isset($this->_packageInfo['configure_options']) &&
836
            count($this->_packageInfo['configure_options']);
836
            count($this->_packageInfo['configure_options']);
837
    }
837
    }
838
838
839
    function addConfigureOption($name, $prompt, $default = false)
839
    function addConfigureOption($name, $prompt, $default = false)
840
    {
840
    {
841
        $o = array('name' => $name, 'prompt' => $prompt);
841
        $o = array('name' => $name, 'prompt' => $prompt);
842
        if ($default !== false) {
842
        if ($default !== false) {
843
            $o['default'] = $default;
843
            $o['default'] = $default;
844
        }
844
        }
845
        if (!isset($this->_packageInfo['configure_options'])) {
845
        if (!isset($this->_packageInfo['configure_options'])) {
846
            $this->_packageInfo['configure_options'] = array();
846
            $this->_packageInfo['configure_options'] = array();
847
        }
847
        }
848
        $this->_packageInfo['configure_options'][] = $o;
848
        $this->_packageInfo['configure_options'][] = $o;
849
    }
849
    }
850
850
851
    function clearConfigureOptions()
851
    function clearConfigureOptions()
852
    {
852
    {
853
        unset($this->_packageInfo['configure_options']);
853
        unset($this->_packageInfo['configure_options']);
854
    }
854
    }
855
855
856
    function getProvides()
856
    function getProvides()
857
    {
857
    {
858
        if (isset($this->_packageInfo['provides'])) {
858
        if (isset($this->_packageInfo['provides'])) {
859
            return $this->_packageInfo['provides'];
859
            return $this->_packageInfo['provides'];
860
        }
860
        }
861
        return false;
861
        return false;
862
    }
862
    }
863
863
864
    function getProvidesExtension()
864
    function getProvidesExtension()
865
    {
865
    {
866
        return false;
866
        return false;
867
    }
867
    }
868
868
869
    function addFile($dir, $file, $attrs)
869
    function addFile($dir, $file, $attrs)
870
    {
870
    {
871
        $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
871
        $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
872
        if ($dir == '/' || $dir == '') {
872
        if ($dir == '/' || $dir == '') {
873
            $dir = '';
873
            $dir = '';
874
        } else {
874
        } else {
875
            $dir .= '/';
875
            $dir .= '/';
876
        }
876
        }
877
        $file = $dir . $file;
877
        $file = $dir . $file;
878
        $file = preg_replace('![\\/]+!', '/', $file);
878
        $file = preg_replace('![\\/]+!', '/', $file);
879
        $this->_packageInfo['filelist'][$file] = $attrs;
879
        $this->_packageInfo['filelist'][$file] = $attrs;
880
    }
880
    }
881
881
882
    function getInstallationFilelist()
882
    function getInstallationFilelist()
883
    {
883
    {
884
        return $this->getFilelist();
884
        return $this->getFilelist();
885
    }
885
    }
886
886
887
    function getFilelist()
887
    function getFilelist()
888
    {
888
    {
889
        if (isset($this->_packageInfo['filelist'])) {
889
        if (isset($this->_packageInfo['filelist'])) {
890
            return $this->_packageInfo['filelist'];
890
            return $this->_packageInfo['filelist'];
891
        }
891
        }
892
        return false;
892
        return false;
893
    }
893
    }
894
894
895
    function setFileAttribute($file, $attr, $value)
895
    function setFileAttribute($file, $attr, $value)
896
    {
896
    {
897
        $this->_packageInfo['filelist'][$file][$attr] = $value;
897
        $this->_packageInfo['filelist'][$file][$attr] = $value;
898
    }
898
    }
899
899
900
    function resetFilelist()
900
    function resetFilelist()
901
    {
901
    {
902
        $this->_packageInfo['filelist'] = array();
902
        $this->_packageInfo['filelist'] = array();
903
    }
903
    }
904
904
905
    function setInstalledAs($file, $path)
905
    function setInstalledAs($file, $path)
906
    {
906
    {
907
        if ($path) {
907
        if ($path) {
908
            return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
908
            return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
909
        }
909
        }
910
        unset($this->_packageInfo['filelist'][$file]['installed_as']);
910
        unset($this->_packageInfo['filelist'][$file]['installed_as']);
911
    }
911
    }
912
912
913
    function installedFile($file, $atts)
913
    function installedFile($file, $atts)
914
    {
914
    {
915
        if (isset($this->_packageInfo['filelist'][$file])) {
915
        if (isset($this->_packageInfo['filelist'][$file])) {
916
            $this->_packageInfo['filelist'][$file] =
916
            $this->_packageInfo['filelist'][$file] =
917
                array_merge($this->_packageInfo['filelist'][$file], $atts);
917
                array_merge($this->_packageInfo['filelist'][$file], $atts);
918
        } else {
918
        } else {
919
            $this->_packageInfo['filelist'][$file] = $atts;
919
            $this->_packageInfo['filelist'][$file] = $atts;
920
        }
920
        }
921
    }
921
    }
922
922
923
    function getChangelog()
923
    function getChangelog()
924
    {
924
    {
925
        if (isset($this->_packageInfo['changelog'])) {
925
        if (isset($this->_packageInfo['changelog'])) {
926
            return $this->_packageInfo['changelog'];
926
            return $this->_packageInfo['changelog'];
927
        }
927
        }
928
        return false;
928
        return false;
929
    }
929
    }
930
930
931
    function getPackagexmlVersion()
931
    function getPackagexmlVersion()
932
    {
932
    {
933
        return '1.0';
933
        return '1.0';
934
    }
934
    }
935
935
936
    /**
936
    /**
937
     * Wrapper to {@link PEAR_ErrorStack::getErrors()}
937
     * Wrapper to {@link PEAR_ErrorStack::getErrors()}
938
     * @param boolean determines whether to purge the error stack after retrieving
938
     * @param boolean determines whether to purge the error stack after retrieving
939
     * @return array
939
     * @return array
940
     */
940
     */
941
    function getValidationWarnings($purge = true)
941
    function getValidationWarnings($purge = true)
942
    {
942
    {
943
        return $this->_stack->getErrors($purge);
943
        return $this->_stack->getErrors($purge);
944
    }
944
    }
945
945
946
    // }}}
946
    // }}}
947
    /**
947
    /**
948
     * Validation error.  Also marks the object contents as invalid
948
     * Validation error.  Also marks the object contents as invalid
949
     * @param error code
949
     * @param error code
950
     * @param array error information
950
     * @param array error information
951
     * @access private
951
     * @access private
952
     */
952
     */
953
    function _validateError($code, $params = array())
953
    function _validateError($code, $params = array())
954
    {
954
    {
955
        $this->_stack->push($code, 'error', $params, false, false, debug_backtrace());
955
        $this->_stack->push($code, 'error', $params, false, false, debug_backtrace());
956
        $this->_isValid = false;
956
        $this->_isValid = false;
957
    }
957
    }
958
958
959
    /**
959
    /**
960
     * Validation warning.  Does not mark the object contents invalid.
960
     * Validation warning.  Does not mark the object contents invalid.
961
     * @param error code
961
     * @param error code
962
     * @param array error information
962
     * @param array error information
963
     * @access private
963
     * @access private
964
     */
964
     */
965
    function _validateWarning($code, $params = array())
965
    function _validateWarning($code, $params = array())
966
    {
966
    {
967
        $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace());
967
        $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace());
968
    }
968
    }
969
969
970
    /**
970
    /**
971
     * @param integer error code
971
     * @param integer error code
972
     * @access protected
972
     * @access protected
973
     */
973
     */
974
    function _getErrorMessage()
974
    function _getErrorMessage()
975
    {
975
    {
976
        return array(
976
        return array(
977
                PEAR_PACKAGEFILE_ERROR_NO_NAME =>
977
                PEAR_PACKAGEFILE_ERROR_NO_NAME =>
978
                    'Missing Package Name',
978
                    'Missing Package Name',
979
                PEAR_PACKAGEFILE_ERROR_NO_SUMMARY =>
979
                PEAR_PACKAGEFILE_ERROR_NO_SUMMARY =>
980
                    'No summary found',
980
                    'No summary found',
981
                PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY =>
981
                PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY =>
982
                    'Summary should be on one line',
982
                    'Summary should be on one line',
983
                PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION =>
983
                PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION =>
984
                    'Missing description',
984
                    'Missing description',
985
                PEAR_PACKAGEFILE_ERROR_NO_LICENSE =>
985
                PEAR_PACKAGEFILE_ERROR_NO_LICENSE =>
986
                    'Missing license',
986
                    'Missing license',
987
                PEAR_PACKAGEFILE_ERROR_NO_VERSION =>
987
                PEAR_PACKAGEFILE_ERROR_NO_VERSION =>
988
                    'No release version found',
988
                    'No release version found',
989
                PEAR_PACKAGEFILE_ERROR_NO_STATE =>
989
                PEAR_PACKAGEFILE_ERROR_NO_STATE =>
990
                    'No release state found',
990
                    'No release state found',
991
                PEAR_PACKAGEFILE_ERROR_NO_DATE =>
991
                PEAR_PACKAGEFILE_ERROR_NO_DATE =>
992
                    'No release date found',
992
                    'No release date found',
993
                PEAR_PACKAGEFILE_ERROR_NO_NOTES =>
993
                PEAR_PACKAGEFILE_ERROR_NO_NOTES =>
994
                    'No release notes found',
994
                    'No release notes found',
995
                PEAR_PACKAGEFILE_ERROR_NO_LEAD =>
995
                PEAR_PACKAGEFILE_ERROR_NO_LEAD =>
996
                    'Package must have at least one lead maintainer',
996
                    'Package must have at least one lead maintainer',
997
                PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS =>
997
                PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS =>
998
                    'No maintainers found, at least one must be defined',
998
                    'No maintainers found, at least one must be defined',
999
                PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE =>
999
                PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE =>
1000
                    'Maintainer %index% has no handle (user ID at channel server)',
1000
                    'Maintainer %index% has no handle (user ID at channel server)',
1001
                PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE =>
1001
                PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE =>
1002
                    'Maintainer %index% has no role',
1002
                    'Maintainer %index% has no role',
1003
                PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME =>
1003
                PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME =>
1004
                    'Maintainer %index% has no name',
1004
                    'Maintainer %index% has no name',
1005
                PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL =>
1005
                PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL =>
1006
                    'Maintainer %index% has no email',
1006
                    'Maintainer %index% has no email',
1007
                PEAR_PACKAGEFILE_ERROR_NO_DEPNAME =>
1007
                PEAR_PACKAGEFILE_ERROR_NO_DEPNAME =>
1008
                    'Dependency %index% is not a php dependency, and has no name',
1008
                    'Dependency %index% is not a php dependency, and has no name',
1009
                PEAR_PACKAGEFILE_ERROR_NO_DEPREL =>
1009
                PEAR_PACKAGEFILE_ERROR_NO_DEPREL =>
1010
                    'Dependency %index% has no relation (rel)',
1010
                    'Dependency %index% has no relation (rel)',
1011
                PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE =>
1011
                PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE =>
1012
                    'Dependency %index% has no type',
1012
                    'Dependency %index% has no type',
1013
                PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED =>
1013
                PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED =>
1014
                    'PHP Dependency %index% has a name attribute of "%name%" which will be' .
1014
                    'PHP Dependency %index% has a name attribute of "%name%" which will be' .
1015
                        ' ignored!',
1015
                        ' ignored!',
1016
                PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION =>
1016
                PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION =>
1017
                    'Dependency %index% is not a rel="has" or rel="not" dependency, ' .
1017
                    'Dependency %index% is not a rel="has" or rel="not" dependency, ' .
1018
                        'and has no version',
1018
                        'and has no version',
1019
                PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION =>
1019
                PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION =>
1020
                    'Dependency %index% is a type="php" dependency, ' .
1020
                    'Dependency %index% is a type="php" dependency, ' .
1021
                        'and has no version',
1021
                        'and has no version',
1022
                PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED =>
1022
                PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED =>
1023
                    'Dependency %index% is a rel="%rel%" dependency, versioning is ignored',
1023
                    'Dependency %index% is a rel="%rel%" dependency, versioning is ignored',
1024
                PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL =>
1024
                PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL =>
1025
                    'Dependency %index% has invalid optional value "%opt%", should be yes or no',
1025
                    'Dependency %index% has invalid optional value "%opt%", should be yes or no',
1026
                PEAR_PACKAGEFILE_PHP_NO_NOT =>
1026
                PEAR_PACKAGEFILE_PHP_NO_NOT =>
1027
                    'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' .
1027
                    'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' .
1028
                        ' to exclude specific versions',
1028
                        ' to exclude specific versions',
1029
                PEAR_PACKAGEFILE_ERROR_NO_CONFNAME =>
1029
                PEAR_PACKAGEFILE_ERROR_NO_CONFNAME =>
1030
                    'Configure Option %index% has no name',
1030
                    'Configure Option %index% has no name',
1031
                PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT =>
1031
                PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT =>
1032
                    'Configure Option %index% has no prompt',
1032
                    'Configure Option %index% has no prompt',
1033
                PEAR_PACKAGEFILE_ERROR_NO_FILES =>
1033
                PEAR_PACKAGEFILE_ERROR_NO_FILES =>
1034
                    'No files in <filelist> section of package.xml',
1034
                    'No files in <filelist> section of package.xml',
1035
                PEAR_PACKAGEFILE_ERROR_NO_FILEROLE =>
1035
                PEAR_PACKAGEFILE_ERROR_NO_FILEROLE =>
1036
                    'File "%file%" has no role, expecting one of "%roles%"',
1036
                    'File "%file%" has no role, expecting one of "%roles%"',
1037
                PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE =>
1037
                PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE =>
1038
                    'File "%file%" has invalid role "%role%", expecting one of "%roles%"',
1038
                    'File "%file%" has invalid role "%role%", expecting one of "%roles%"',
1039
                PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME =>
1039
                PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME =>
1040
                    'File "%file%" cannot start with ".", cannot package or install',
1040
                    'File "%file%" cannot start with ".", cannot package or install',
1041
                PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE =>
1041
                PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE =>
1042
                    'Parser error: invalid PHP found in file "%file%"',
1042
                    'Parser error: invalid PHP found in file "%file%"',
1043
                PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX =>
1043
                PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX =>
1044
                    'in %file%: %type% "%name%" not prefixed with package name "%package%"',
1044
                    'in %file%: %type% "%name%" not prefixed with package name "%package%"',
1045
                PEAR_PACKAGEFILE_ERROR_INVALID_FILE =>
1045
                PEAR_PACKAGEFILE_ERROR_INVALID_FILE =>
1046
                    'Parser error: invalid PHP file "%file%"',
1046
                    'Parser error: invalid PHP file "%file%"',
1047
                PEAR_PACKAGEFILE_ERROR_CHANNELVAL =>
1047
                PEAR_PACKAGEFILE_ERROR_CHANNELVAL =>
1048
                    'Channel validator error: field "%field%" - %reason%',
1048
                    'Channel validator error: field "%field%" - %reason%',
1049
                PEAR_PACKAGEFILE_ERROR_PHP5 =>
1049
                PEAR_PACKAGEFILE_ERROR_PHP5 =>
1050
                    'Error, PHP5 token encountered in %file%, analysis should be in PHP5',
1050
                    'Error, PHP5 token encountered in %file%, analysis should be in PHP5',
1051
                PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND =>
1051
                PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND =>
1052
                    'File "%file%" in package.xml does not exist',
1052
                    'File "%file%" in package.xml does not exist',
1053
                PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS =>
1053
                PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS =>
1054
                    'Package.xml contains non-ISO-8859-1 characters, and may not validate',
1054
                    'Package.xml contains non-ISO-8859-1 characters, and may not validate',
1055
            );
1055
            );
1056
    }
1056
    }
1057
1057
1058
    /**
1058
    /**
1059
     * Validate XML package definition file.
1059
     * Validate XML package definition file.
1060
     *
1060
     *
1061
     * @access public
1061
     * @access public
1062
     * @return boolean
1062
     * @return boolean
1063
     */
1063
     */
1064
    function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false)
1064
    function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false)
1065
    {
1065
    {
1066
        if (($this->_isValid & $state) == $state) {
1066
        if (($this->_isValid & $state) == $state) {
1067
            return true;
1067
            return true;
1068
        }
1068
        }
1069
        $this->_isValid = true;
1069
        $this->_isValid = true;
1070
        $info = $this->_packageInfo;
1070
        $info = $this->_packageInfo;
1071
        if (empty($info['package'])) {
1071
        if (empty($info['package'])) {
1072
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME);
1072
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME);
1073
            $this->_packageName = $pn = 'unknown';
1073
            $this->_packageName = $pn = 'unknown';
1074
        } else {
1074
        } else {
1075
            $this->_packageName = $pn = $info['package'];
1075
            $this->_packageName = $pn = $info['package'];
1076
        }
1076
        }
1077
1077
1078
        if (empty($info['summary'])) {
1078
        if (empty($info['summary'])) {
1079
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY);
1079
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY);
1080
        } elseif (strpos(trim($info['summary']), "\n") !== false) {
1080
        } elseif (strpos(trim($info['summary']), "\n") !== false) {
1081
            $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY,
1081
            $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY,
1082
                array('summary' => $info['summary']));
1082
                array('summary' => $info['summary']));
1083
        }
1083
        }
1084
        if (empty($info['description'])) {
1084
        if (empty($info['description'])) {
1085
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION);
1085
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION);
1086
        }
1086
        }
1087
        if (empty($info['release_license'])) {
1087
        if (empty($info['release_license'])) {
1088
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE);
1088
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE);
1089
        }
1089
        }
1090
        if (empty($info['version'])) {
1090
        if (empty($info['version'])) {
1091
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION);
1091
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION);
1092
        }
1092
        }
1093
        if (empty($info['release_state'])) {
1093
        if (empty($info['release_state'])) {
1094
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE);
1094
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE);
1095
        }
1095
        }
1096
        if (empty($info['release_date'])) {
1096
        if (empty($info['release_date'])) {
1097
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE);
1097
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE);
1098
        }
1098
        }
1099
        if (empty($info['release_notes'])) {
1099
        if (empty($info['release_notes'])) {
1100
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES);
1100
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES);
1101
        }
1101
        }
1102
        if (empty($info['maintainers'])) {
1102
        if (empty($info['maintainers'])) {
1103
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS);
1103
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS);
1104
        } else {
1104
        } else {
1105
            $haslead = false;
1105
            $haslead = false;
1106
            $i = 1;
1106
            $i = 1;
1107
            foreach ($info['maintainers'] as $m) {
1107
            foreach ($info['maintainers'] as $m) {
1108
                if (empty($m['handle'])) {
1108
                if (empty($m['handle'])) {
1109
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE,
1109
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE,
1110
                        array('index' => $i));
1110
                        array('index' => $i));
1111
                }
1111
                }
1112
                if (empty($m['role'])) {
1112
                if (empty($m['role'])) {
1113
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE,
1113
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE,
1114
                        array('index' => $i, 'roles' => PEAR_Common::getUserRoles()));
1114
                        array('index' => $i, 'roles' => PEAR_Common::getUserRoles()));
1115
                } elseif ($m['role'] == 'lead') {
1115
                } elseif ($m['role'] == 'lead') {
1116
                    $haslead = true;
1116
                    $haslead = true;
1117
                }
1117
                }
1118
                if (empty($m['name'])) {
1118
                if (empty($m['name'])) {
1119
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME,
1119
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME,
1120
                        array('index' => $i));
1120
                        array('index' => $i));
1121
                }
1121
                }
1122
                if (empty($m['email'])) {
1122
                if (empty($m['email'])) {
1123
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL,
1123
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL,
1124
                        array('index' => $i));
1124
                        array('index' => $i));
1125
                }
1125
                }
1126
                $i++;
1126
                $i++;
1127
            }
1127
            }
1128
            if (!$haslead) {
1128
            if (!$haslead) {
1129
                $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD);
1129
                $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD);
1130
            }
1130
            }
1131
        }
1131
        }
1132
        if (!empty($info['release_deps'])) {
1132
        if (!empty($info['release_deps'])) {
1133
            $i = 1;
1133
            $i = 1;
1134
            foreach ($info['release_deps'] as $d) {
1134
            foreach ($info['release_deps'] as $d) {
1135
                if (!isset($d['type']) || empty($d['type'])) {
1135
                if (!isset($d['type']) || empty($d['type'])) {
1136
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE,
1136
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE,
1137
                        array('index' => $i, 'types' => PEAR_Common::getDependencyTypes()));
1137
                        array('index' => $i, 'types' => PEAR_Common::getDependencyTypes()));
1138
                    continue;
1138
                    continue;
1139
                }
1139
                }
1140
                if (!isset($d['rel']) || empty($d['rel'])) {
1140
                if (!isset($d['rel']) || empty($d['rel'])) {
1141
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL,
1141
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL,
1142
                        array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations()));
1142
                        array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations()));
1143
                    continue;
1143
                    continue;
1144
                }
1144
                }
1145
                if (!empty($d['optional'])) {
1145
                if (!empty($d['optional'])) {
1146
                    if (!in_array($d['optional'], array('yes', 'no'))) {
1146
                    if (!in_array($d['optional'], array('yes', 'no'))) {
1147
                        $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL,
1147
                        $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL,
1148
                            array('index' => $i, 'opt' => $d['optional']));
1148
                            array('index' => $i, 'opt' => $d['optional']));
1149
                    }
1149
                    }
1150
                }
1150
                }
1151
                if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) {
1151
                if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) {
1152
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION,
1152
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION,
1153
                        array('index' => $i));
1153
                        array('index' => $i));
1154
                } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) {
1154
                } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) {
1155
                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED,
1155
                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED,
1156
                        array('index' => $i, 'rel' => $d['rel']));
1156
                        array('index' => $i, 'rel' => $d['rel']));
1157
                }
1157
                }
1158
                if ($d['type'] == 'php' && !empty($d['name'])) {
1158
                if ($d['type'] == 'php' && !empty($d['name'])) {
1159
                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED,
1159
                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED,
1160
                        array('index' => $i, 'name' => $d['name']));
1160
                        array('index' => $i, 'name' => $d['name']));
1161
                } elseif ($d['type'] != 'php' && empty($d['name'])) {
1161
                } elseif ($d['type'] != 'php' && empty($d['name'])) {
1162
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME,
1162
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME,
1163
                        array('index' => $i));
1163
                        array('index' => $i));
1164
                }
1164
                }
1165
                if ($d['type'] == 'php' && empty($d['version'])) {
1165
                if ($d['type'] == 'php' && empty($d['version'])) {
1166
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION,
1166
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION,
1167
                        array('index' => $i));
1167
                        array('index' => $i));
1168
                }
1168
                }
1169
                if (($d['rel'] == 'not') && ($d['type'] == 'php')) {
1169
                if (($d['rel'] == 'not') && ($d['type'] == 'php')) {
1170
                    $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT,
1170
                    $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT,
1171
                        array('index' => $i));
1171
                        array('index' => $i));
1172
                }
1172
                }
1173
                $i++;
1173
                $i++;
1174
            }
1174
            }
1175
        }
1175
        }
1176
        if (!empty($info['configure_options'])) {
1176
        if (!empty($info['configure_options'])) {
1177
            $i = 1;
1177
            $i = 1;
1178
            foreach ($info['configure_options'] as $c) {
1178
            foreach ($info['configure_options'] as $c) {
1179
                if (empty($c['name'])) {
1179
                if (empty($c['name'])) {
1180
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME,
1180
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME,
1181
                        array('index' => $i));
1181
                        array('index' => $i));
1182
                }
1182
                }
1183
                if (empty($c['prompt'])) {
1183
                if (empty($c['prompt'])) {
1184
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT,
1184
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT,
1185
                        array('index' => $i));
1185
                        array('index' => $i));
1186
                }
1186
                }
1187
                $i++;
1187
                $i++;
1188
            }
1188
            }
1189
        }
1189
        }
1190
        if (empty($info['filelist'])) {
1190
        if (empty($info['filelist'])) {
1191
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES);
1191
            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES);
1192
            $errors[] = 'no files';
1192
            $errors[] = 'no files';
1193
        } else {
1193
        } else {
1194
            foreach ($info['filelist'] as $file => $fa) {
1194
            foreach ($info['filelist'] as $file => $fa) {
1195
                if (empty($fa['role'])) {
1195
                if (empty($fa['role'])) {
1196
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE,
1196
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE,
1197
                        array('file' => $file, 'roles' => PEAR_Common::getFileRoles()));
1197
                        array('file' => $file, 'roles' => PEAR_Common::getFileRoles()));
1198
                    continue;
1198
                    continue;
1199
                } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) {
1199
                } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) {
1200
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE,
1200
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE,
1201
                        array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles()));
1201
                        array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles()));
1202
                }
1202
                }
1203
                if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) {
1203
                if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) {
1204
                    // file contains .. parent directory or . cur directory references
1204
                    // file contains .. parent directory or . cur directory references
1205
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
1205
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
1206
                        array('file' => $file));
1206
                        array('file' => $file));
1207
                }
1207
                }
1208
                if (isset($fa['install-as']) &&
1208
                if (isset($fa['install-as']) &&
1209
                      preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
1209
                      preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
1210
                                 str_replace('\\', '/', $fa['install-as']))) {
1210
                                 str_replace('\\', '/', $fa['install-as']))) {
1211
                    // install-as contains .. parent directory or . cur directory references
1211
                    // install-as contains .. parent directory or . cur directory references
1212
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
1212
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
1213
                        array('file' => $file . ' [installed as ' . $fa['install-as'] . ']'));
1213
                        array('file' => $file . ' [installed as ' . $fa['install-as'] . ']'));
1214
                }
1214
                }
1215
                if (isset($fa['baseinstalldir']) &&
1215
                if (isset($fa['baseinstalldir']) &&
1216
                      preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
1216
                      preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
1217
                                 str_replace('\\', '/', $fa['baseinstalldir']))) {
1217
                                 str_replace('\\', '/', $fa['baseinstalldir']))) {
1218
                    // install-as contains .. parent directory or . cur directory references
1218
                    // install-as contains .. parent directory or . cur directory references
1219
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
1219
                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
1220
                        array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']'));
1220
                        array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']'));
1221
                }
1221
                }
1222
            }
1222
            }
1223
        }
1223
        }
1224
        if (isset($this->_registry) && $this->_isValid) {
1224
        if (isset($this->_registry) && $this->_isValid) {
1225
            $chan = $this->_registry->getChannel('pear.php.net');
1225
            $chan = $this->_registry->getChannel('pear.php.net');
1226
            if (PEAR::isError($chan)) {
1226
            if (PEAR::isError($chan)) {
1227
                $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage());
1227
                $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage());
1228
                return $this->_isValid = 0;
1228
                return $this->_isValid = 0;
1229
            }
1229
            }
1230
            $validator = $chan->getValidationObject();
1230
            $validator = $chan->getValidationObject();
1231
            $validator->setPackageFile($this);
1231
            $validator->setPackageFile($this);
1232
            $validator->validate($state);
1232
            $validator->validate($state);
1233
            $failures = $validator->getFailures();
1233
            $failures = $validator->getFailures();
1234
            foreach ($failures['errors'] as $error) {
1234
            foreach ($failures['errors'] as $error) {
1235
                $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error);
1235
                $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error);
1236
            }
1236
            }
1237
            foreach ($failures['warnings'] as $warning) {
1237
            foreach ($failures['warnings'] as $warning) {
1238
                $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning);
1238
                $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning);
1239
            }
1239
            }
1240
        }
1240
        }
1241
        if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) {
1241
        if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) {
1242
            if ($this->_analyzePhpFiles()) {
1242
            if ($this->_analyzePhpFiles()) {
1243
                $this->_isValid = true;
1243
                $this->_isValid = true;
1244
            }
1244
            }
1245
        }
1245
        }
1246
        if ($this->_isValid) {
1246
        if ($this->_isValid) {
1247
            return $this->_isValid = $state;
1247
            return $this->_isValid = $state;
1248
        }
1248
        }
1249
        return $this->_isValid = 0;
1249
        return $this->_isValid = 0;
1250
    }
1250
    }
1251
1251
1252
    function _analyzePhpFiles()
1252
    function _analyzePhpFiles()
1253
    {
1253
    {
1254
        if (!$this->_isValid) {
1254
        if (!$this->_isValid) {
1255
            return false;
1255
            return false;
1256
        }
1256
        }
1257
        if (!isset($this->_packageFile)) {
1257
        if (!isset($this->_packageFile)) {
1258
            return false;
1258
            return false;
1259
        }
1259
        }
1260
        $dir_prefix = dirname($this->_packageFile);
1260
        $dir_prefix = dirname($this->_packageFile);
1261
        $common = new PEAR_Common;
1261
        $common = new PEAR_Common;
1262
        $log = isset($this->_logger) ? array(&$this->_logger, 'log') :
1262
        $log = isset($this->_logger) ? array(&$this->_logger, 'log') :
1263
            array($common, 'log');
1263
            array($common, 'log');
1264
        $info = $this->getFilelist();
1264
        $info = $this->getFilelist();
1265
        foreach ($info as $file => $fa) {
1265
        foreach ($info as $file => $fa) {
1266
            if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) {
1266
            if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) {
1267
                $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND,
1267
                $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND,
1268
                    array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file));
1268
                    array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file));
1269
                continue;
1269
                continue;
1270
            }
1270
            }
1271
            if ($fa['role'] == 'php' && $dir_prefix) {
1271
            if ($fa['role'] == 'php' && $dir_prefix) {
1272
                call_user_func_array($log, array(1, "Analyzing $file"));
1272
                call_user_func_array($log, array(1, "Analyzing $file"));
1273
                $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file);
1273
                $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file);
1274
                if ($srcinfo) {
1274
                if ($srcinfo) {
1275
                    $this->_buildProvidesArray($srcinfo);
1275
                    $this->_buildProvidesArray($srcinfo);
1276
                }
1276
                }
1277
            }
1277
            }
1278
        }
1278
        }
1279
        $this->_packageName = $pn = $this->getPackage();
1279
        $this->_packageName = $pn = $this->getPackage();
1280
        $pnl = strlen($pn);
1280
        $pnl = strlen($pn);
1281
        if (isset($this->_packageInfo['provides'])) {
1281
        if (isset($this->_packageInfo['provides'])) {
1282
            foreach ((array) $this->_packageInfo['provides'] as $key => $what) {
1282
            foreach ((array) $this->_packageInfo['provides'] as $key => $what) {
1283
                if (isset($what['explicit'])) {
1283
                if (isset($what['explicit'])) {
1284
                    // skip conformance checks if the provides entry is
1284
                    // skip conformance checks if the provides entry is
1285
                    // specified in the package.xml file
1285
                    // specified in the package.xml file
1286
                    continue;
1286
                    continue;
1287
                }
1287
                }
1288
                extract($what);
1288
                extract($what);
1289
                if ($type == 'class') {
1289
                if ($type == 'class') {
1290
                    if (!strncasecmp($name, $pn, $pnl)) {
1290
                    if (!strncasecmp($name, $pn, $pnl)) {
1291
                        continue;
1291
                        continue;
1292
                    }
1292
                    }
1293
                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
1293
                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
1294
                        array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
1294
                        array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
1295
                } elseif ($type == 'function') {
1295
                } elseif ($type == 'function') {
1296
                    if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) {
1296
                    if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) {
1297
                        continue;
1297
                        continue;
1298
                    }
1298
                    }
1299
                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
1299
                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
1300
                        array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
1300
                        array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
1301
                }
1301
                }
1302
            }
1302
            }
1303
        }
1303
        }
1304
        return $this->_isValid;
1304
        return $this->_isValid;
1305
    }
1305
    }
1306
1306
1307
    /**
1307
    /**
1308
     * Get the default xml generator object
1308
     * Get the default xml generator object
1309
     *
1309
     *
1310
     * @return PEAR_PackageFile_Generator_v1
1310
     * @return PEAR_PackageFile_Generator_v1
1311
     */
1311
     */
1312
    function &getDefaultGenerator()
1312
    function &getDefaultGenerator()
1313
    {
1313
    {
1314
        if (!class_exists('PEAR_PackageFile_Generator_v1')) {
1314
        if (!class_exists('PEAR_PackageFile_Generator_v1')) {
1315
            require_once 'PEAR/PackageFile/Generator/v1.php';
1315
            require_once 'PEAR/PackageFile/Generator/v1.php';
1316
        }
1316
        }
1317
        $a = &new PEAR_PackageFile_Generator_v1($this);
1317
        $a = &new PEAR_PackageFile_Generator_v1($this);
1318
        return $a;
1318
        return $a;
1319
    }
1319
    }
1320
1320
1321
    /**
1321
    /**
1322
     * Get the contents of a file listed within the package.xml
1322
     * Get the contents of a file listed within the package.xml
1323
     * @param string
1323
     * @param string
1324
     * @return string
1324
     * @return string
1325
     */
1325
     */
1326
    function getFileContents($file)
1326
    function getFileContents($file)
1327
    {
1327
    {
1328
        if ($this->_archiveFile == $this->_packageFile) { // unpacked
1328
        if ($this->_archiveFile == $this->_packageFile) { // unpacked
1329
            $dir = dirname($this->_packageFile);
1329
            $dir = dirname($this->_packageFile);
1330
            $file = $dir . DIRECTORY_SEPARATOR . $file;
1330
            $file = $dir . DIRECTORY_SEPARATOR . $file;
1331
            $file = str_replace(array('/', '\\'),
1331
            $file = str_replace(array('/', '\\'),
1332
                array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
1332
                array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
1333
            if (file_exists($file) && is_readable($file)) {
1333
            if (file_exists($file) && is_readable($file)) {
1334
                return implode('', file($file));
1334
                return implode('', file($file));
1335
            }
1335
            }
1336
        } else { // tgz
1336
        } else { // tgz
1337
            if (!class_exists('Archive_Tar')) {
1337
            if (!class_exists('Archive_Tar')) {
1338
                require_once 'Archive/Tar.php';
1338
                require_once 'Archive/Tar.php';
1339
            }
1339
            }
1340
            $tar = &new Archive_Tar($this->_archiveFile);
1340
            $tar = &new Archive_Tar($this->_archiveFile);
1341
            $tar->pushErrorHandling(PEAR_ERROR_RETURN);
1341
            $tar->pushErrorHandling(PEAR_ERROR_RETURN);
1342
            if ($file != 'package.xml' && $file != 'package2.xml') {
1342
            if ($file != 'package.xml' && $file != 'package2.xml') {
1343
                $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
1343
                $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
1344
            }
1344
            }
1345
            $file = $tar->extractInString($file);
1345
            $file = $tar->extractInString($file);
1346
            $tar->popErrorHandling();
1346
            $tar->popErrorHandling();
1347
            if (PEAR::isError($file)) {
1347
            if (PEAR::isError($file)) {
1348
                return PEAR::raiseError("Cannot locate file '$file' in archive");
1348
                return PEAR::raiseError("Cannot locate file '$file' in archive");
1349
            }
1349
            }
1350
            return $file;
1350
            return $file;
1351
        }
1351
        }
1352
    }
1352
    }
1353
1353
1354
    // {{{ analyzeSourceCode()
1354
    // {{{ analyzeSourceCode()
1355
    /**
1355
    /**
1356
     * Analyze the source code of the given PHP file
1356
     * Analyze the source code of the given PHP file
1357
     *
1357
     *
1358
     * @param  string Filename of the PHP file
1358
     * @param  string Filename of the PHP file
1359
     * @return mixed
1359
     * @return mixed
1360
     * @access private
1360
     * @access private
1361
     */
1361
     */
1362
    function _analyzeSourceCode($file)
1362
    function _analyzeSourceCode($file)
1363
    {
1363
    {
1364
        if (!function_exists("token_get_all")) {
1364
        if (!function_exists("token_get_all")) {
1365
            return false;
1365
            return false;
1366
        }
1366
        }
1367
        if (!defined('T_DOC_COMMENT')) {
1367
        if (!defined('T_DOC_COMMENT')) {
1368
            define('T_DOC_COMMENT', T_COMMENT);
1368
            define('T_DOC_COMMENT', T_COMMENT);
1369
        }
1369
        }
1370
        if (!defined('T_INTERFACE')) {
1370
        if (!defined('T_INTERFACE')) {
1371
            define('T_INTERFACE', -1);
1371
            define('T_INTERFACE', -1);
1372
        }
1372
        }
1373
        if (!defined('T_IMPLEMENTS')) {
1373
        if (!defined('T_IMPLEMENTS')) {
1374
            define('T_IMPLEMENTS', -1);
1374
            define('T_IMPLEMENTS', -1);
1375
        }
1375
        }
1376
        if (!$fp = @fopen($file, "r")) {
1376
        if (!$fp = @fopen($file, "r")) {
1377
            return false;
1377
            return false;
1378
        }
1378
        }
1379
        fclose($fp);
1379
        fclose($fp);
1380
        $contents = file_get_contents($file);
1380
        $contents = file_get_contents($file);
1381
        $tokens = token_get_all($contents);
1381
        $tokens = token_get_all($contents);
1382
/*
1382
/*
1383
        for ($i = 0; $i < sizeof($tokens); $i++) {
1383
        for ($i = 0; $i < sizeof($tokens); $i++) {
1384
            @list($token, $data) = $tokens[$i];
1384
            @list($token, $data) = $tokens[$i];
1385
            if (is_string($token)) {
1385
            if (is_string($token)) {
1386
                var_dump($token);
1386
                var_dump($token);
1387
            } else {
1387
            } else {
1388
                print token_name($token) . ' ';
1388
                print token_name($token) . ' ';
1389
                var_dump(rtrim($data));
1389
                var_dump(rtrim($data));
1390
            }
1390
            }
1391
        }
1391
        }
1392
*/
1392
*/
1393
        $look_for = 0;
1393
        $look_for = 0;
1394
        $paren_level = 0;
1394
        $paren_level = 0;
1395
        $bracket_level = 0;
1395
        $bracket_level = 0;
1396
        $brace_level = 0;
1396
        $brace_level = 0;
1397
        $lastphpdoc = '';
1397
        $lastphpdoc = '';
1398
        $current_class = '';
1398
        $current_class = '';
1399
        $current_interface = '';
1399
        $current_interface = '';
1400
        $current_class_level = -1;
1400
        $current_class_level = -1;
1401
        $current_function = '';
1401
        $current_function = '';
1402
        $current_function_level = -1;
1402
        $current_function_level = -1;
1403
        $declared_classes = array();
1403
        $declared_classes = array();
1404
        $declared_interfaces = array();
1404
        $declared_interfaces = array();
1405
        $declared_functions = array();
1405
        $declared_functions = array();
1406
        $declared_methods = array();
1406
        $declared_methods = array();
1407
        $used_classes = array();
1407
        $used_classes = array();
1408
        $used_functions = array();
1408
        $used_functions = array();
1409
        $extends = array();
1409
        $extends = array();
1410
        $implements = array();
1410
        $implements = array();
1411
        $nodeps = array();
1411
        $nodeps = array();
1412
        $inquote = false;
1412
        $inquote = false;
1413
        $interface = false;
1413
        $interface = false;
1414
        for ($i = 0; $i < sizeof($tokens); $i++) {
1414
        for ($i = 0; $i < sizeof($tokens); $i++) {
1415
            if (is_array($tokens[$i])) {
1415
            if (is_array($tokens[$i])) {
1416
                list($token, $data) = $tokens[$i];
1416
                list($token, $data) = $tokens[$i];
1417
            } else {
1417
            } else {
1418
                $token = $tokens[$i];
1418
                $token = $tokens[$i];
1419
                $data = '';
1419
                $data = '';
1420
            }
1420
            }
1421
            if ($inquote) {
1421
            if ($inquote) {
1422
                if ($token != '"' && $token != T_END_HEREDOC) {
1422
                if ($token != '"' && $token != T_END_HEREDOC) {
1423
                    continue;
1423
                    continue;
1424
                } else {
1424
                } else {
1425
                    $inquote = false;
1425
                    $inquote = false;
1426
                    continue;
1426
                    continue;
1427
                }
1427
                }
1428
            }
1428
            }
1429
            switch ($token) {
1429
            switch ($token) {
1430
                case T_WHITESPACE :
1430
                case T_WHITESPACE :
1431
                    continue;
1431
                    continue;
1432
                case ';':
1432
                case ';':
1433
                    if ($interface) {
1433
                    if ($interface) {
1434
                        $current_function = '';
1434
                        $current_function = '';
1435
                        $current_function_level = -1;
1435
                        $current_function_level = -1;
1436
                    }
1436
                    }
1437
                    break;
1437
                    break;
1438
                case '"':
1438
                case '"':
1439
                case T_START_HEREDOC:
1439
                case T_START_HEREDOC:
1440
                    $inquote = true;
1440
                    $inquote = true;
1441
                    break;
1441
                    break;
1442
                case T_CURLY_OPEN:
1442
                case T_CURLY_OPEN:
1443
                case T_DOLLAR_OPEN_CURLY_BRACES:
1443
                case T_DOLLAR_OPEN_CURLY_BRACES:
1444
                case '{': $brace_level++; continue 2;
1444
                case '{': $brace_level++; continue 2;
1445
                case '}':
1445
                case '}':
1446
                    $brace_level--;
1446
                    $brace_level--;
1447
                    if ($current_class_level == $brace_level) {
1447
                    if ($current_class_level == $brace_level) {
1448
                        $current_class = '';
1448
                        $current_class = '';
1449
                        $current_class_level = -1;
1449
                        $current_class_level = -1;
1450
                    }
1450
                    }
1451
                    if ($current_function_level == $brace_level) {
1451
                    if ($current_function_level == $brace_level) {
1452
                        $current_function = '';
1452
                        $current_function = '';
1453
                        $current_function_level = -1;
1453
                        $current_function_level = -1;
1454
                    }
1454
                    }
1455
                    continue 2;
1455
                    continue 2;
1456
                case '[': $bracket_level++; continue 2;
1456
                case '[': $bracket_level++; continue 2;
1457
                case ']': $bracket_level--; continue 2;
1457
                case ']': $bracket_level--; continue 2;
1458
                case '(': $paren_level++;   continue 2;
1458
                case '(': $paren_level++;   continue 2;
1459
                case ')': $paren_level--;   continue 2;
1459
                case ')': $paren_level--;   continue 2;
1460
                case T_INTERFACE:
1460
                case T_INTERFACE:
1461
                    $interface = true;
1461
                    $interface = true;
1462
                case T_CLASS:
1462
                case T_CLASS:
1463
                    if (($current_class_level != -1) || ($current_function_level != -1)) {
1463
                    if (($current_class_level != -1) || ($current_function_level != -1)) {
1464
                        $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
1464
                        $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
1465
                            array('file' => $file));
1465
                            array('file' => $file));
1466
                        return false;
1466
                        return false;
1467
                    }
1467
                    }
1468
                case T_FUNCTION:
1468
                case T_FUNCTION:
1469
                case T_NEW:
1469
                case T_NEW:
1470
                case T_EXTENDS:
1470
                case T_EXTENDS:
1471
                case T_IMPLEMENTS:
1471
                case T_IMPLEMENTS:
1472
                    $look_for = $token;
1472
                    $look_for = $token;
1473
                    continue 2;
1473
                    continue 2;
1474
                case T_STRING:
1474
                case T_STRING:
1475
                    if (version_compare(zend_version(), '2.0', '<')) {
1475
                    if (version_compare(zend_version(), '2.0', '<')) {
1476
                        if (in_array(strtolower($data),
1476
                        if (in_array(strtolower($data),
1477
                            array('public', 'private', 'protected', 'abstract',
1477
                            array('public', 'private', 'protected', 'abstract',
1478
                                  'interface', 'implements', 'throw')
1478
                                  'interface', 'implements', 'throw')
1479
                                 )) {
1479
                                 )) {
1480
                            $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5,
1480
                            $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5,
1481
                                array($file));
1481
                                array($file));
1482
                        }
1482
                        }
1483
                    }
1483
                    }
1484
                    if ($look_for == T_CLASS) {
1484
                    if ($look_for == T_CLASS) {
1485
                        $current_class = $data;
1485
                        $current_class = $data;
1486
                        $current_class_level = $brace_level;
1486
                        $current_class_level = $brace_level;
1487
                        $declared_classes[] = $current_class;
1487
                        $declared_classes[] = $current_class;
1488
                    } elseif ($look_for == T_INTERFACE) {
1488
                    } elseif ($look_for == T_INTERFACE) {
1489
                        $current_interface = $data;
1489
                        $current_interface = $data;
1490
                        $current_class_level = $brace_level;
1490
                        $current_class_level = $brace_level;
1491
                        $declared_interfaces[] = $current_interface;
1491
                        $declared_interfaces[] = $current_interface;
1492
                    } elseif ($look_for == T_IMPLEMENTS) {
1492
                    } elseif ($look_for == T_IMPLEMENTS) {
1493
                        $implements[$current_class] = $data;
1493
                        $implements[$current_class] = $data;
1494
                    } elseif ($look_for == T_EXTENDS) {
1494
                    } elseif ($look_for == T_EXTENDS) {
1495
                        $extends[$current_class] = $data;
1495
                        $extends[$current_class] = $data;
1496
                    } elseif ($look_for == T_FUNCTION) {
1496
                    } elseif ($look_for == T_FUNCTION) {
1497
                        if ($current_class) {
1497
                        if ($current_class) {
1498
                            $current_function = "$current_class::$data";
1498
                            $current_function = "$current_class::$data";
1499
                            $declared_methods[$current_class][] = $data;
1499
                            $declared_methods[$current_class][] = $data;
1500
                        } elseif ($current_interface) {
1500
                        } elseif ($current_interface) {
1501
                            $current_function = "$current_interface::$data";
1501
                            $current_function = "$current_interface::$data";
1502
                            $declared_methods[$current_interface][] = $data;
1502
                            $declared_methods[$current_interface][] = $data;
1503
                        } else {
1503
                        } else {
1504
                            $current_function = $data;
1504
                            $current_function = $data;
1505
                            $declared_functions[] = $current_function;
1505
                            $declared_functions[] = $current_function;
1506
                        }
1506
                        }
1507
                        $current_function_level = $brace_level;
1507
                        $current_function_level = $brace_level;
1508
                        $m = array();
1508
                        $m = array();
1509
                    } elseif ($look_for == T_NEW) {
1509
                    } elseif ($look_for == T_NEW) {
1510
                        $used_classes[$data] = true;
1510
                        $used_classes[$data] = true;
1511
                    }
1511
                    }
1512
                    $look_for = 0;
1512
                    $look_for = 0;
1513
                    continue 2;
1513
                    continue 2;
1514
                case T_VARIABLE:
1514
                case T_VARIABLE:
1515
                    $look_for = 0;
1515
                    $look_for = 0;
1516
                    continue 2;
1516
                    continue 2;
1517
                case T_DOC_COMMENT:
1517
                case T_DOC_COMMENT:
1518
                case T_COMMENT:
1518
                case T_COMMENT:
1519
                    if (preg_match('!^/\*\*\s!', $data)) {
1519
                    if (preg_match('!^/\*\*\s!', $data)) {
1520
                        $lastphpdoc = $data;
1520
                        $lastphpdoc = $data;
1521
                        if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
1521
                        if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
1522
                            $nodeps = array_merge($nodeps, $m[1]);
1522
                            $nodeps = array_merge($nodeps, $m[1]);
1523
                        }
1523
                        }
1524
                    }
1524
                    }
1525
                    continue 2;
1525
                    continue 2;
1526
                case T_DOUBLE_COLON:
1526
                case T_DOUBLE_COLON:
1527
                    if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
1527
                    if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
1528
                        $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
1528
                        $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
1529
                            array('file' => $file));
1529
                            array('file' => $file));
1530
                        return false;
1530
                        return false;
1531
                    }
1531
                    }
1532
                    $class = $tokens[$i - 1][1];
1532
                    $class = $tokens[$i - 1][1];
1533
                    if (strtolower($class) != 'parent') {
1533
                    if (strtolower($class) != 'parent') {
1534
                        $used_classes[$class] = true;
1534
                        $used_classes[$class] = true;
1535
                    }
1535
                    }
1536
                    continue 2;
1536
                    continue 2;
1537
            }
1537
            }
1538
        }
1538
        }
1539
        return array(
1539
        return array(
1540
            "source_file" => $file,
1540
            "source_file" => $file,
1541
            "declared_classes" => $declared_classes,
1541
            "declared_classes" => $declared_classes,
1542
            "declared_interfaces" => $declared_interfaces,
1542
            "declared_interfaces" => $declared_interfaces,
1543
            "declared_methods" => $declared_methods,
1543
            "declared_methods" => $declared_methods,
1544
            "declared_functions" => $declared_functions,
1544
            "declared_functions" => $declared_functions,
1545
            "used_classes" => array_diff(array_keys($used_classes), $nodeps),
1545
            "used_classes" => array_diff(array_keys($used_classes), $nodeps),
1546
            "inheritance" => $extends,
1546
            "inheritance" => $extends,
1547
            "implements" => $implements,
1547
            "implements" => $implements,
1548
            );
1548
            );
1549
    }
1549
    }
1550
1550
1551
    /**
1551
    /**
1552
     * Build a "provides" array from data returned by
1552
     * Build a "provides" array from data returned by
1553
     * analyzeSourceCode().  The format of the built array is like
1553
     * analyzeSourceCode().  The format of the built array is like
1554
     * this:
1554
     * this:
1555
     *
1555
     *
1556
     *  array(
1556
     *  array(
1557
     *    'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
1557
     *    'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
1558
     *    ...
1558
     *    ...
1559
     *  )
1559
     *  )
1560
     *
1560
     *
1561
     *
1561
     *
1562
     * @param array $srcinfo array with information about a source file
1562
     * @param array $srcinfo array with information about a source file
1563
     * as returned by the analyzeSourceCode() method.
1563
     * as returned by the analyzeSourceCode() method.
1564
     *
1564
     *
1565
     * @return void
1565
     * @return void
1566
     *
1566
     *
1567
     * @access private
1567
     * @access private
1568
     *
1568
     *
1569
     */
1569
     */
1570
    function _buildProvidesArray($srcinfo)
1570
    function _buildProvidesArray($srcinfo)
1571
    {
1571
    {
1572
        if (!$this->_isValid) {
1572
        if (!$this->_isValid) {
1573
            return false;
1573
            return false;
1574
        }
1574
        }
1575
        $file = basename($srcinfo['source_file']);
1575
        $file = basename($srcinfo['source_file']);
1576
        $pn = $this->getPackage();
1576
        $pn = $this->getPackage();
1577
        $pnl = strlen($pn);
1577
        $pnl = strlen($pn);
1578
        foreach ($srcinfo['declared_classes'] as $class) {
1578
        foreach ($srcinfo['declared_classes'] as $class) {
1579
            $key = "class;$class";
1579
            $key = "class;$class";
1580
            if (isset($this->_packageInfo['provides'][$key])) {
1580
            if (isset($this->_packageInfo['provides'][$key])) {
1581
                continue;
1581
                continue;
1582
            }
1582
            }
1583
            $this->_packageInfo['provides'][$key] =
1583
            $this->_packageInfo['provides'][$key] =
1584
                array('file'=> $file, 'type' => 'class', 'name' => $class);
1584
                array('file'=> $file, 'type' => 'class', 'name' => $class);
1585
            if (isset($srcinfo['inheritance'][$class])) {
1585
            if (isset($srcinfo['inheritance'][$class])) {
1586
                $this->_packageInfo['provides'][$key]['extends'] =
1586
                $this->_packageInfo['provides'][$key]['extends'] =
1587
                    $srcinfo['inheritance'][$class];
1587
                    $srcinfo['inheritance'][$class];
1588
            }
1588
            }
1589
        }
1589
        }
1590
        foreach ($srcinfo['declared_methods'] as $class => $methods) {
1590
        foreach ($srcinfo['declared_methods'] as $class => $methods) {
1591
            foreach ($methods as $method) {
1591
            foreach ($methods as $method) {
1592
                $function = "$class::$method";
1592
                $function = "$class::$method";
1593
                $key = "function;$function";
1593
                $key = "function;$function";
1594
                if ($method{0} == '_' || !strcasecmp($method, $class) ||
1594
                if ($method{0} == '_' || !strcasecmp($method, $class) ||
1595
                    isset($this->_packageInfo['provides'][$key])) {
1595
                    isset($this->_packageInfo['provides'][$key])) {
1596
                    continue;
1596
                    continue;
1597
                }
1597
                }
1598
                $this->_packageInfo['provides'][$key] =
1598
                $this->_packageInfo['provides'][$key] =
1599
                    array('file'=> $file, 'type' => 'function', 'name' => $function);
1599
                    array('file'=> $file, 'type' => 'function', 'name' => $function);
1600
            }
1600
            }
1601
        }
1601
        }
1602
1602
1603
        foreach ($srcinfo['declared_functions'] as $function) {
1603
        foreach ($srcinfo['declared_functions'] as $function) {
1604
            $key = "function;$function";
1604
            $key = "function;$function";
1605
            if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) {
1605
            if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) {
1606
                continue;
1606
                continue;
1607
            }
1607
            }
1608
            if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
1608
            if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
1609
                $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
1609
                $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
1610
            }
1610
            }
1611
            $this->_packageInfo['provides'][$key] =
1611
            $this->_packageInfo['provides'][$key] =
1612
                array('file'=> $file, 'type' => 'function', 'name' => $function);
1612
                array('file'=> $file, 'type' => 'function', 'name' => $function);
1613
        }
1613
        }
1614
    }
1614
    }
1615
1615
1616
    // }}}
1616
    // }}}
1617
}
1617
}
1618
?>
1618
?>
1619
 
1619