Хранилища Subversion ant

Редакция

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

Редакция Автор № строки Строка
69 alex-w 1
<?php
2
/**
3
 * PEAR_PackageFile_v2, package.xml version 2.0, read/write version
4
 *
5
 * PHP versions 4 and 5
6
 *
7
 * LICENSE: This source file is subject to version 3.0 of the PHP license
8
 * that is available through the world-wide-web at the following URI:
9
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
10
 * the PHP License and are unable to obtain it through the web, please
11
 * send a note to license@php.net so we can mail you a copy immediately.
12
 *
13
 * @category   pear
14
 * @package    PEAR
15
 * @author     Greg Beaver <cellog@php.net>
16
 * @copyright  1997-2008 The PHP Group
17
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
18
 * @version    CVS: $Id: rw.php,v 1.22 2008/01/18 22:47:49 cellog Exp $
19
 * @link       http://pear.php.net/package/PEAR
20
 * @since      File available since Release 1.4.0a8
21
 */
22
/**
23
 * For base class
24
 */
25
require_once 'PEAR/PackageFile/v2.php';
26
/**
27
 * @category   pear
28
 * @package    PEAR
29
 * @author     Greg Beaver <cellog@php.net>
30
 * @copyright  1997-2008 The PHP Group
31
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
32
 * @version    Release: 1.7.2
33
 * @link       http://pear.php.net/package/PEAR
34
 * @since      Class available since Release 1.4.0a8
35
 */
36
class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2
37
{
38
    /**
39
     * @param string Extension name
40
     * @return bool success of operation
41
     */
42
    function setProvidesExtension($extension)
43
    {
44
        if (in_array($this->getPackageType(),
45
              array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
46
            if (!isset($this->_packageInfo['providesextension'])) {
47
                // ensure that the channel tag is set up in the right location
48
                $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
49
                    array('usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease',
50
                    'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
51
                    'bundle', 'changelog'),
52
                    $extension, 'providesextension');
53
            }
54
            $this->_packageInfo['providesextension'] = $extension;
55
            return true;
56
        }
57
        return false;
58
    }
59
 
60
    function setPackage($package)
61
    {
62
        $this->_isValid = 0;
63
        if (!isset($this->_packageInfo['attribs'])) {
64
            $this->_packageInfo = array_merge(array('attribs' => array(
65
                                 'version' => '2.0',
66
                                 'xmlns' => 'http://pear.php.net/dtd/package-2.0',
67
                                 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0',
68
                                 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
69
                                 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0
70
    http://pear.php.net/dtd/tasks-1.0.xsd
71
    http://pear.php.net/dtd/package-2.0
72
    http://pear.php.net/dtd/package-2.0.xsd',
73
                             )), $this->_packageInfo);
74
        }
75
        if (!isset($this->_packageInfo['name'])) {
76
            return $this->_packageInfo = array_merge(array('name' => $package),
77
                $this->_packageInfo);
78
        }
79
        $this->_packageInfo['name'] = $package;
80
    }
81
 
82
    /**
83
     * set this as a package.xml version 2.1
84
     * @access private
85
     */
86
    function _setPackageVersion2_1()
87
    {
88
        $info = array(
89
                                 'version' => '2.1',
90
                                 'xmlns' => 'http://pear.php.net/dtd/package-2.1',
91
                                 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0',
92
                                 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
93
                                 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0
94
    http://pear.php.net/dtd/tasks-1.0.xsd
95
    http://pear.php.net/dtd/package-2.1
96
    http://pear.php.net/dtd/package-2.1.xsd',
97
                             );
98
        if (!isset($this->_packageInfo['attribs'])) {
99
            $this->_packageInfo = array_merge(array('attribs' => $info), $this->_packageInfo);
100
        } else {
101
            $this->_packageInfo['attribs'] = $info;
102
        }
103
    }
104
 
105
    function setUri($uri)
106
    {
107
        unset($this->_packageInfo['channel']);
108
        $this->_isValid = 0;
109
        if (!isset($this->_packageInfo['uri'])) {
110
            // ensure that the uri tag is set up in the right location
111
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
112
                array('extends', 'summary', 'description', 'lead',
113
                'developer', 'contributor', 'helper', 'date', 'time', 'version',
114
                'stability', 'license', 'notes', 'contents', 'compatible',
115
                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
116
                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
117
                'extbinrelease', 'bundle', 'changelog'), $uri, 'uri');
118
        }
119
        $this->_packageInfo['uri'] = $uri;
120
    }
121
 
122
    function setChannel($channel)
123
    {
124
        unset($this->_packageInfo['uri']);
125
        $this->_isValid = 0;
126
        if (!isset($this->_packageInfo['channel'])) {
127
            // ensure that the channel tag is set up in the right location
128
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
129
                array('extends', 'summary', 'description', 'lead',
130
                'developer', 'contributor', 'helper', 'date', 'time', 'version',
131
                'stability', 'license', 'notes', 'contents', 'compatible',
132
                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
133
                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
134
                'extbinrelease', 'bundle', 'changelog'), $channel, 'channel');
135
        }
136
        $this->_packageInfo['channel'] = $channel;
137
    }
138
 
139
    function setExtends($extends)
140
    {
141
        $this->_isValid = 0;
142
        if (!isset($this->_packageInfo['extends'])) {
143
            // ensure that the extends tag is set up in the right location
144
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
145
                array('summary', 'description', 'lead',
146
                'developer', 'contributor', 'helper', 'date', 'time', 'version',
147
                'stability', 'license', 'notes', 'contents', 'compatible',
148
                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
149
                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
150
                'extbinrelease', 'bundle', 'changelog'), $extends, 'extends');
151
        }
152
        $this->_packageInfo['extends'] = $extends;
153
    }
154
 
155
    function setSummary($summary)
156
    {
157
        $this->_isValid = 0;
158
        if (!isset($this->_packageInfo['summary'])) {
159
            // ensure that the summary tag is set up in the right location
160
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
161
                array('description', 'lead',
162
                'developer', 'contributor', 'helper', 'date', 'time', 'version',
163
                'stability', 'license', 'notes', 'contents', 'compatible',
164
                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
165
                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
166
                'extbinrelease', 'bundle', 'changelog'), $summary, 'summary');
167
        }
168
        $this->_packageInfo['summary'] = $summary;
169
    }
170
 
171
    function setDescription($desc)
172
    {
173
        $this->_isValid = 0;
174
        if (!isset($this->_packageInfo['description'])) {
175
            // ensure that the description tag is set up in the right location
176
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
177
                array('lead',
178
                'developer', 'contributor', 'helper', 'date', 'time', 'version',
179
                'stability', 'license', 'notes', 'contents', 'compatible',
180
                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
181
                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
182
                'extbinrelease', 'bundle', 'changelog'), $desc, 'description');
183
        }
184
        $this->_packageInfo['description'] = $desc;
185
    }
186
 
187
    /**
188
     * Adds a new maintainer - no checking of duplicates is performed, use
189
     * updatemaintainer for that purpose.
190
     */
191
    function addMaintainer($role, $handle, $name, $email, $active = 'yes')
192
    {
193
        if (!in_array($role, array('lead', 'developer', 'contributor', 'helper'))) {
194
            return false;
195
        }
196
        if (isset($this->_packageInfo[$role])) {
197
            if (!isset($this->_packageInfo[$role][0])) {
198
                $this->_packageInfo[$role] = array($this->_packageInfo[$role]);
199
            }
200
            $this->_packageInfo[$role][] =
201
                array(
202
                    'name' => $name,
203
                    'user' => $handle,
204
                    'email' => $email,
205
                    'active' => $active,
206
                );
207
        } else {
208
            $testarr = array('lead',
209
                    'developer', 'contributor', 'helper', 'date', 'time', 'version',
210
                    'stability', 'license', 'notes', 'contents', 'compatible',
211
                    'dependencies', 'providesextension', 'usesrole', 'usestask',
212
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease',
213
                    'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog');
214
            foreach (array('lead', 'developer', 'contributor', 'helper') as $testrole) {
215
                array_shift($testarr);
216
                if ($role == $testrole) {
217
                    break;
218
                }
219
            }
220
            if (!isset($this->_packageInfo[$role])) {
221
                // ensure that the extends tag is set up in the right location
222
                $this->_packageInfo = $this->_insertBefore($this->_packageInfo, $testarr,
223
                    array(), $role);
224
            }
225
            $this->_packageInfo[$role] =
226
                array(
227
                    'name' => $name,
228
                    'user' => $handle,
229
                    'email' => $email,
230
                    'active' => $active,
231
                );
232
        }
233
        $this->_isValid = 0;
234
    }
235
 
236
    function updateMaintainer($newrole, $handle, $name, $email, $active = 'yes')
237
    {
238
        $found = false;
239
        foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
240
            if (!isset($this->_packageInfo[$role])) {
241
                continue;
242
            }
243
            $info = $this->_packageInfo[$role];
244
            if (!isset($info[0])) {
245
                if ($info['user'] == $handle) {
246
                    $found = true;
247
                    break;
248
                }
249
            }
250
            foreach ($info as $i => $maintainer) {
251
                if ($maintainer['user'] == $handle) {
252
                    $found = $i;
253
                    break 2;
254
                }
255
            }
256
        }
257
        if ($found === false) {
258
            return $this->addMaintainer($newrole, $handle, $name, $email, $active);
259
        }
260
        if ($found !== false) {
261
            if ($found === true) {
262
                unset($this->_packageInfo[$role]);
263
            } else {
264
                unset($this->_packageInfo[$role][$found]);
265
                $this->_packageInfo[$role] = array_values($this->_packageInfo[$role]);
266
            }
267
        }
268
        $this->addMaintainer($newrole, $handle, $name, $email, $active);
269
        $this->_isValid = 0;
270
    }
271
 
272
    function deleteMaintainer($handle)
273
    {
274
        $found = false;
275
        foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
276
            if (!isset($this->_packageInfo[$role])) {
277
                continue;
278
            }
279
            if (!isset($this->_packageInfo[$role][0])) {
280
                $this->_packageInfo[$role] = array($this->_packageInfo[$role]);
281
            }
282
            foreach ($this->_packageInfo[$role] as $i => $maintainer) {
283
                if ($maintainer['user'] == $handle) {
284
                    $found = $i;
285
                    break;
286
                }
287
            }
288
            if ($found !== false) {
289
                unset($this->_packageInfo[$role][$found]);
290
                if (!count($this->_packageInfo[$role]) && $role == 'lead') {
291
                    $this->_isValid = 0;
292
                }
293
                if (!count($this->_packageInfo[$role])) {
294
                    unset($this->_packageInfo[$role]);
295
                    return true;
296
                }
297
                $this->_packageInfo[$role] =
298
                    array_values($this->_packageInfo[$role]);
299
                if (count($this->_packageInfo[$role]) == 1) {
300
                    $this->_packageInfo[$role] = $this->_packageInfo[$role][0];
301
                }
302
                return true;
303
            }
304
            if (count($this->_packageInfo[$role]) == 1) {
305
                $this->_packageInfo[$role] = $this->_packageInfo[$role][0];
306
            }
307
        }
308
        return false;
309
    }
310
 
311
    function setReleaseVersion($version)
312
    {
313
        if (isset($this->_packageInfo['version']) &&
314
              isset($this->_packageInfo['version']['release'])) {
315
            unset($this->_packageInfo['version']['release']);
316
        }
317
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array(
318
            'version' => array('stability', 'license', 'notes', 'contents', 'compatible',
319
                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
320
                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
321
                'extbinrelease', 'bundle', 'changelog'),
322
            'release' => array('api')));
323
        $this->_isValid = 0;
324
    }
325
 
326
    function setAPIVersion($version)
327
    {
328
        if (isset($this->_packageInfo['version']) &&
329
              isset($this->_packageInfo['version']['api'])) {
330
            unset($this->_packageInfo['version']['api']);
331
        }
332
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array(
333
            'version' => array('stability', 'license', 'notes', 'contents', 'compatible',
334
                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
335
                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
336
                'extbinrelease', 'bundle', 'changelog'),
337
            'api' => array()));
338
        $this->_isValid = 0;
339
    }
340
 
341
    /**
342
     * snapshot|devel|alpha|beta|stable
343
     */
344
    function setReleaseStability($state)
345
    {
346
        if (isset($this->_packageInfo['stability']) &&
347
              isset($this->_packageInfo['stability']['release'])) {
348
            unset($this->_packageInfo['stability']['release']);
349
        }
350
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array(
351
            'stability' => array('license', 'notes', 'contents', 'compatible',
352
                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
353
                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
354
                'extbinrelease', 'bundle', 'changelog'),
355
            'release' => array('api')));
356
        $this->_isValid = 0;
357
    }
358
 
359
    /**
360
     * @param devel|alpha|beta|stable
361
     */
362
    function setAPIStability($state)
363
    {
364
        if (isset($this->_packageInfo['stability']) &&
365
              isset($this->_packageInfo['stability']['api'])) {
366
            unset($this->_packageInfo['stability']['api']);
367
        }
368
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array(
369
            'stability' => array('license', 'notes', 'contents', 'compatible',
370
                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
371
                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
372
                'extbinrelease', 'bundle', 'changelog'),
373
            'api' => array()));
374
        $this->_isValid = 0;
375
    }
376
 
377
    function setLicense($license, $uri = false, $filesource = false)
378
    {
379
        if (!isset($this->_packageInfo['license'])) {
380
            // ensure that the license tag is set up in the right location
381
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
382
                array('notes', 'contents', 'compatible',
383
                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
384
                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
385
                'extbinrelease', 'bundle', 'changelog'), 0, 'license');
386
        }
387
        if ($uri || $filesource) {
388
            $attribs = array();
389
            if ($uri) {
390
                $attribs['uri'] = $uri;
391
            }
392
            $uri = true; // for test below
393
            if ($filesource) {
394
                $attribs['filesource'] = $filesource;
395
            }
396
        }
397
        $license = $uri ? array('attribs' => $attribs, '_content' => $license) : $license;
398
        $this->_packageInfo['license'] = $license;
399
        $this->_isValid = 0;
400
    }
401
 
402
    function setNotes($notes)
403
    {
404
        $this->_isValid = 0;
405
        if (!isset($this->_packageInfo['notes'])) {
406
            // ensure that the notes tag is set up in the right location
407
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
408
                array('contents', 'compatible',
409
                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
410
                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
411
                'extbinrelease', 'bundle', 'changelog'), $notes, 'notes');
412
        }
413
        $this->_packageInfo['notes'] = $notes;
414
    }
415
 
416
    /**
417
     * This is only used at install-time, after all serialization
418
     * is over.
419
     * @param string file name
420
     * @param string installed path
421
     */
422
    function setInstalledAs($file, $path)
423
    {
424
        if ($path) {
425
            return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
426
        }
427
        unset($this->_packageInfo['filelist'][$file]['installed_as']);
428
    }
429
 
430
    /**
431
     * This is only used at install-time, after all serialization
432
     * is over.
433
     */
434
    function installedFile($file, $atts)
435
    {
436
        if (isset($this->_packageInfo['filelist'][$file])) {
437
            $this->_packageInfo['filelist'][$file] =
438
                array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']);
439
        } else {
440
            $this->_packageInfo['filelist'][$file] = $atts['attribs'];
441
        }
442
    }
443
 
444
    /**
445
     * Reset the listing of package contents
446
     * @param string base installation dir for the whole package, if any
447
     */
448
    function clearContents($baseinstall = false)
449
    {
450
        $this->_filesValid = false;
451
        $this->_isValid = 0;
452
        if (!isset($this->_packageInfo['contents'])) {
453
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
454
                array('compatible',
455
                    'dependencies', 'providesextension', 'usesrole', 'usestask',
456
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease',
457
                    'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
458
                    'bundle', 'changelog'), array(), 'contents');
459
        }
460
        if ($this->getPackageType() != 'bundle') {
461
            $this->_packageInfo['contents'] =
462
                array('dir' => array('attribs' => array('name' => '/')));
463
            if ($baseinstall) {
464
                $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'] = $baseinstall;
465
            }
466
        } else {
467
            $this->_packageInfo['contents'] = array('bundledpackage' => array());
468
        }
469
    }
470
 
471
    /**
472
     * @param string relative path of the bundled package.
473
     */
474
    function addBundledPackage($path)
475
    {
476
        if ($this->getPackageType() != 'bundle') {
477
            return false;
478
        }
479
        $this->_filesValid = false;
480
        $this->_isValid = 0;
481
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $path, array(
482
                'contents' => array('compatible', 'dependencies', 'providesextension',
483
                'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease',
484
                'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
485
                'bundle', 'changelog'),
486
                'bundledpackage' => array()));
487
    }
488
 
489
    /**
490
     * @param string file name
491
     * @param PEAR_Task_Common a read/write task
492
     */
493
    function addTaskToFile($filename, $task)
494
    {
495
        if (!method_exists($task, 'getXml')) {
496
            return false;
497
        }
498
        if (!method_exists($task, 'getName')) {
499
            return false;
500
        }
501
        if (!method_exists($task, 'validate')) {
502
            return false;
503
        }
504
        if (!$task->validate()) {
505
            return false;
506
        }
507
        if (!isset($this->_packageInfo['contents']['dir']['file'])) {
508
            return false;
509
        }
510
        $this->getTasksNs(); // discover the tasks namespace if not done already
511
        $files = $this->_packageInfo['contents']['dir']['file'];
512
        if (!isset($files[0])) {
513
            $files = array($files);
514
            $ind = false;
515
        } else {
516
            $ind = true;
517
        }
518
        foreach ($files as $i => $file) {
519
            if (isset($file['attribs'])) {
520
                if ($file['attribs']['name'] == $filename) {
521
                    if ($ind) {
522
                        $t = isset($this->_packageInfo['contents']['dir']['file'][$i]
523
                              ['attribs'][$this->_tasksNs .
524
                              ':' . $task->getName()]) ?
525
                              $this->_packageInfo['contents']['dir']['file'][$i]
526
                              ['attribs'][$this->_tasksNs .
527
                              ':' . $task->getName()] : false;
528
                        if ($t && !isset($t[0])) {
529
                            $this->_packageInfo['contents']['dir']['file'][$i]
530
                                [$this->_tasksNs . ':' . $task->getName()] = array($t);
531
                        }
532
                        $this->_packageInfo['contents']['dir']['file'][$i][$this->_tasksNs .
533
                            ':' . $task->getName()][] = $task->getXml();
534
                    } else {
535
                        $t = isset($this->_packageInfo['contents']['dir']['file']
536
                              ['attribs'][$this->_tasksNs .
537
                              ':' . $task->getName()]) ? $this->_packageInfo['contents']['dir']['file']
538
                              ['attribs'][$this->_tasksNs .
539
                              ':' . $task->getName()] : false;
540
                        if ($t && !isset($t[0])) {
541
                            $this->_packageInfo['contents']['dir']['file']
542
                                [$this->_tasksNs . ':' . $task->getName()] = array($t);
543
                        }
544
                        $this->_packageInfo['contents']['dir']['file'][$this->_tasksNs .
545
                            ':' . $task->getName()][] = $task->getXml();
546
                    }
547
                    return true;
548
                }
549
            }
550
        }
551
        return false;
552
    }
553
 
554
    /**
555
     * @param string path to the file
556
     * @param string filename
557
     * @param array extra attributes
558
     */
559
    function addFile($dir, $file, $attrs)
560
    {
561
        if ($this->getPackageType() == 'bundle') {
562
            return false;
563
        }
564
        $this->_filesValid = false;
565
        $this->_isValid = 0;
566
        $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
567
        if ($dir == '/' || $dir == '') {
568
            $dir = '';
569
        } else {
570
            $dir .= '/';
571
        }
572
        $attrs['name'] = $dir . $file;
573
        if (!isset($this->_packageInfo['contents'])) {
574
            // ensure that the contents tag is set up
575
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
576
                array('compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask',
577
                'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease',
578
                'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
579
                'bundle', 'changelog'), array(), 'contents');
580
        }
581
        if (isset($this->_packageInfo['contents']['dir']['file'])) {
582
            if (!isset($this->_packageInfo['contents']['dir']['file'][0])) {
583
                $this->_packageInfo['contents']['dir']['file'] =
584
                    array($this->_packageInfo['contents']['dir']['file']);
585
            }
586
            $this->_packageInfo['contents']['dir']['file'][]['attribs'] = $attrs;
587
        } else {
588
            $this->_packageInfo['contents']['dir']['file']['attribs'] = $attrs;
589
        }
590
    }
591
 
592
    /**
593
     * @param string Dependent package name
594
     * @param string Dependent package's channel name
595
     * @param string minimum version of specified package that this release is guaranteed to be
596
     *               compatible with
597
     * @param string maximum version of specified package that this release is guaranteed to be
598
     *               compatible with
599
     * @param string versions of specified package that this release is not compatible with
600
     */
601
    function addCompatiblePackage($name, $channel, $min, $max, $exclude = false)
602
    {
603
        $this->_isValid = 0;
604
        $set = array(
605
            'name' => $name,
606
            'channel' => $channel,
607
            'min' => $min,
608
            'max' => $max,
609
        );
610
        if ($exclude) {
611
            $set['exclude'] = $exclude;
612
        }
613
        $this->_isValid = 0;
614
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
615
                'compatible' => array('dependencies', 'providesextension', 'usesrole', 'usestask',
616
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
617
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
618
            ));
619
    }
620
 
621
    /**
622
     * Removes the <usesrole> tag entirely
623
     */
624
    function resetUsesrole()
625
    {
626
        if (isset($this->_packageInfo['usesrole'])) {
627
            unset($this->_packageInfo['usesrole']);
628
        }
629
    }
630
 
631
    /**
632
     * @param string
633
     * @param string package name or uri
634
     * @param string channel name if non-uri
635
     */
636
    function addUsesrole($role, $packageOrUri, $channel = false) {
637
        $set = array('role' => $role);
638
        if ($channel) {
639
            $set['package'] = $packageOrUri;
640
            $set['channel'] = $channel;
641
        } else {
642
            $set['uri'] = $packageOrUri;
643
        }
644
        $this->_isValid = 0;
645
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
646
                'usesrole' => array('usestask', 'srcpackage', 'srcuri',
647
                    'phprelease', 'extsrcrelease', 'extbinrelease',
648
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
649
            ));
650
    }
651
 
652
    /**
653
     * Removes the <usestask> tag entirely
654
     */
655
    function resetUsestask()
656
    {
657
        if (isset($this->_packageInfo['usestask'])) {
658
            unset($this->_packageInfo['usestask']);
659
        }
660
    }
661
 
662
 
663
    /**
664
     * @param string
665
     * @param string package name or uri
666
     * @param string channel name if non-uri
667
     */
668
    function addUsestask($task, $packageOrUri, $channel = false) {
669
        $set = array('task' => $task);
670
        if ($channel) {
671
            $set['package'] = $packageOrUri;
672
            $set['channel'] = $channel;
673
        } else {
674
            $set['uri'] = $packageOrUri;
675
        }
676
        $this->_isValid = 0;
677
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
678
                'usestask' => array('srcpackage', 'srcuri',
679
                    'phprelease', 'extsrcrelease', 'extbinrelease',
680
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
681
            ));
682
    }
683
 
684
    /**
685
     * Remove all compatible tags
686
     */
687
    function clearCompatible()
688
    {
689
        unset($this->_packageInfo['compatible']);
690
    }
691
 
692
    /**
693
     * Reset dependencies prior to adding new ones
694
     */
695
    function clearDeps()
696
    {
697
        if (!isset($this->_packageInfo['dependencies'])) {
698
            $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(),
699
                array(
700
                    'dependencies' => array('providesextension', 'usesrole', 'usestask',
701
                        'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
702
                        'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')));
703
        }
704
        $this->_packageInfo['dependencies'] = array();
705
    }
706
 
707
    /**
708
     * @param string minimum PHP version allowed
709
     * @param string maximum PHP version allowed
710
     * @param array $exclude incompatible PHP versions
711
     */
712
    function setPhpDep($min, $max = false, $exclude = false)
713
    {
714
        $this->_isValid = 0;
715
        $dep =
716
            array(
717
                'min' => $min,
718
            );
719
        if ($max) {
720
            $dep['max'] = $max;
721
        }
722
        if ($exclude) {
723
            if (count($exclude) == 1) {
724
                $exclude = $exclude[0];
725
            }
726
            $dep['exclude'] = $exclude;
727
        }
728
        if (isset($this->_packageInfo['dependencies']['required']['php'])) {
729
            $this->_stack->push(__FUNCTION__, 'warning', array('dep' =>
730
            $this->_packageInfo['dependencies']['required']['php']),
731
                'warning: PHP dependency already exists, overwriting');
732
            unset($this->_packageInfo['dependencies']['required']['php']);
733
        }
734
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
735
            array(
736
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
737
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
738
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
739
                'required' => array('optional', 'group'),
740
                'php' => array('pearinstaller', 'package', 'subpackage', 'extension', 'os', 'arch')
741
            ));
742
        return true;
743
    }
744
 
745
    /**
746
     * @param string minimum allowed PEAR installer version
747
     * @param string maximum allowed PEAR installer version
748
     * @param string recommended PEAR installer version
749
     * @param array incompatible version of the PEAR installer
750
     */
751
    function setPearinstallerDep($min, $max = false, $recommended = false, $exclude = false)
752
    {
753
        $this->_isValid = 0;
754
        $dep =
755
            array(
756
                'min' => $min,
757
            );
758
        if ($max) {
759
            $dep['max'] = $max;
760
        }
761
        if ($recommended) {
762
            $dep['recommended'] = $recommended;
763
        }
764
        if ($exclude) {
765
            if (count($exclude) == 1) {
766
                $exclude = $exclude[0];
767
            }
768
            $dep['exclude'] = $exclude;
769
        }
770
        if (isset($this->_packageInfo['dependencies']['required']['pearinstaller'])) {
771
            $this->_stack->push(__FUNCTION__, 'warning', array('dep' =>
772
            $this->_packageInfo['dependencies']['required']['pearinstaller']),
773
                'warning: PEAR Installer dependency already exists, overwriting');
774
            unset($this->_packageInfo['dependencies']['required']['pearinstaller']);
775
        }
776
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
777
            array(
778
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
779
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
780
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
781
                'required' => array('optional', 'group'),
782
                'pearinstaller' => array('package', 'subpackage', 'extension', 'os', 'arch')
783
            ));
784
    }
785
 
786
    /**
787
     * Mark a package as conflicting with this package
788
     * @param string package name
789
     * @param string package channel
790
     * @param string extension this package provides, if any
791
     * @param string|false minimum version required
792
     * @param string|false maximum version allowed
793
     * @param array|false versions to exclude from installation
794
     */
795
    function addConflictingPackageDepWithChannel($name, $channel,
796
                $providesextension = false, $min = false, $max = false, $exclude = false)
797
    {
798
        $this->_isValid = 0;
799
        $dep = $this->_constructDep($name, $channel, false, $min, $max, false,
800
            $exclude, $providesextension, false, true);
801
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
802
            array(
803
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
804
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
805
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
806
                'required' => array('optional', 'group'),
807
                'package' => array('subpackage', 'extension', 'os', 'arch')
808
            ));
809
    }
810
 
811
    /**
812
     * Mark a package as conflicting with this package
813
     * @param string package name
814
     * @param string package channel
815
     * @param string extension this package provides, if any
816
     */
817
    function addConflictingPackageDepWithUri($name, $uri, $providesextension = false)
818
    {
819
        $this->_isValid = 0;
820
        $dep =
821
            array(
822
                'name' => $name,
823
                'uri' => $uri,
824
                'conflicts' => '',
825
            );
826
        if ($providesextension) {
827
            $dep['providesextension'] = $providesextension;
828
        }
829
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
830
            array(
831
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
832
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
833
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
834
                'required' => array('optional', 'group'),
835
                'package' => array('subpackage', 'extension', 'os', 'arch')
836
            ));
837
    }
838
 
839
    function addDependencyGroup($name, $hint)
840
    {
841
        $this->_isValid = 0;
842
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo,
843
            array('attribs' => array('name' => $name, 'hint' => $hint)),
844
            array(
845
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
846
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
847
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
848
                'group' => array(),
849
            ));
850
    }
851
 
852
    /**
853
     * @param string package name
854
     * @param string|false channel name, false if this is a uri
855
     * @param string|false uri name, false if this is a channel
856
     * @param string|false minimum version required
857
     * @param string|false maximum version allowed
858
     * @param string|false recommended installation version
859
     * @param array|false versions to exclude from installation
860
     * @param string extension this package provides, if any
861
     * @param bool if true, tells the installer to ignore the default optional dependency group
862
     *             when installing this package
863
     * @param bool if true, tells the installer to negate this dependency (conflicts)
864
     * @return array
865
     * @access private
866
     */
867
    function _constructDep($name, $channel, $uri, $min, $max, $recommended, $exclude,
868
                           $providesextension = false, $nodefault = false,
869
                           $conflicts = false)
870
    {
871
        $dep =
872
            array(
873
                'name' => $name,
874
            );
875
        if ($channel) {
876
            $dep['channel'] = $channel;
877
        } elseif ($uri) {
878
            $dep['uri'] = $uri;
879
        }
880
        if ($min) {
881
            $dep['min'] = $min;
882
        }
883
        if ($max) {
884
            $dep['max'] = $max;
885
        }
886
        if ($recommended) {
887
            $dep['recommended'] = $recommended;
888
        }
889
        if ($exclude) {
890
            if (is_array($exclude) && count($exclude) == 1) {
891
                $exclude = $exclude[0];
892
            }
893
            $dep['exclude'] = $exclude;
894
        }
895
        if ($conflicts) {
896
            $dep['conflicts'] = '';
897
        }
898
        if ($nodefault) {
899
            $dep['nodefault'] = '';
900
        }
901
        if ($providesextension) {
902
            $dep['providesextension'] = $providesextension;
903
        }
904
        return $dep;
905
    }
906
 
907
    /**
908
     * @param package|subpackage
909
     * @param string group name
910
     * @param string package name
911
     * @param string package channel
912
     * @param string minimum version
913
     * @param string maximum version
914
     * @param string recommended version
915
     * @param array|false optional excluded versions
916
     * @param string extension this package provides, if any
917
     * @param bool if true, tells the installer to ignore the default optional dependency group
918
     *             when installing this package
919
     * @return bool false if the dependency group has not been initialized with
920
     *              {@link addDependencyGroup()}, or a subpackage is added with
921
     *              a providesextension
922
     */
923
    function addGroupPackageDepWithChannel($type, $groupname, $name, $channel, $min = false,
924
                                      $max = false, $recommended = false, $exclude = false,
925
                                      $providesextension = false, $nodefault = false)
926
    {
927
        if ($type == 'subpackage' && $providesextension) {
928
            return false; // subpackages must be php packages
929
        }
930
        $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
931
            $providesextension, $nodefault);
932
        return $this->_addGroupDependency($type, $dep, $groupname);
933
    }
934
 
935
    /**
936
     * @param package|subpackage
937
     * @param string group name
938
     * @param string package name
939
     * @param string package uri
940
     * @param string extension this package provides, if any
941
     * @param bool if true, tells the installer to ignore the default optional dependency group
942
     *             when installing this package
943
     * @return bool false if the dependency group has not been initialized with
944
     *              {@link addDependencyGroup()}
945
     */
946
    function addGroupPackageDepWithURI($type, $groupname, $name, $uri, $providesextension = false,
947
                                       $nodefault = false)
948
    {
949
        if ($type == 'subpackage' && $providesextension) {
950
            return false; // subpackages must be php packages
951
        }
952
        $dep = $this->_constructDep($name, false, $uri, false, false, false, false,
953
            $providesextension, $nodefault);
954
        return $this->_addGroupDependency($type, $dep, $groupname);
955
    }
956
 
957
    /**
958
     * @param string group name (must be pre-existing)
959
     * @param string extension name
960
     * @param string minimum version allowed
961
     * @param string maximum version allowed
962
     * @param string recommended version
963
     * @param array incompatible versions
964
     */
965
    function addGroupExtensionDep($groupname, $name, $min = false, $max = false,
966
                                         $recommended = false, $exclude = false)
967
    {
968
        $this->_isValid = 0;
969
        $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
970
        return $this->_addGroupDependency('extension', $dep, $groupname);
971
    }
972
 
973
    /**
974
     * @param package|subpackage|extension
975
     * @param array dependency contents
976
     * @param string name of the dependency group to add this to
977
     * @return boolean
978
     * @access private
979
     */
980
    function _addGroupDependency($type, $dep, $groupname)
981
    {
982
        $arr = array('subpackage', 'extension');
983
        if ($type != 'package') {
984
            array_shift($arr);
985
        }
986
        if ($type == 'extension') {
987
            array_shift($arr);
988
        }
989
        if (!isset($this->_packageInfo['dependencies']['group'])) {
990
            return false;
991
        } else {
992
            if (!isset($this->_packageInfo['dependencies']['group'][0])) {
993
                if ($this->_packageInfo['dependencies']['group']['attribs']['name'] == $groupname) {
994
                    $this->_packageInfo['dependencies']['group'] = $this->_mergeTag(
995
                        $this->_packageInfo['dependencies']['group'], $dep,
996
                        array(
997
                            $type => $arr
998
                        ));
999
                    $this->_isValid = 0;
1000
                    return true;
1001
                } else {
1002
                    return false;
1003
                }
1004
            } else {
1005
                foreach ($this->_packageInfo['dependencies']['group'] as $i => $group) {
1006
                    if ($group['attribs']['name'] == $groupname) {
1007
                    $this->_packageInfo['dependencies']['group'][$i] = $this->_mergeTag(
1008
                        $this->_packageInfo['dependencies']['group'][$i], $dep,
1009
                        array(
1010
                            $type => $arr
1011
                        ));
1012
                        $this->_isValid = 0;
1013
                        return true;
1014
                    }
1015
                }
1016
                return false;
1017
            }
1018
        }
1019
    }
1020
 
1021
    /**
1022
     * @param optional|required
1023
     * @param string package name
1024
     * @param string package channel
1025
     * @param string minimum version
1026
     * @param string maximum version
1027
     * @param string recommended version
1028
     * @param string extension this package provides, if any
1029
     * @param bool if true, tells the installer to ignore the default optional dependency group
1030
     *             when installing this package
1031
     * @param array|false optional excluded versions
1032
     */
1033
    function addPackageDepWithChannel($type, $name, $channel, $min = false, $max = false,
1034
                                      $recommended = false, $exclude = false,
1035
                                      $providesextension = false, $nodefault = false)
1036
    {
1037
        if (!in_array($type, array('optional', 'required'), true)) {
1038
            $type = 'required';
1039
        }
1040
        $this->_isValid = 0;
1041
        $arr = array('optional', 'group');
1042
        if ($type != 'required') {
1043
            array_shift($arr);
1044
        }
1045
        $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
1046
            $providesextension, $nodefault);
1047
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1048
            array(
1049
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1050
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1051
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1052
                $type => $arr,
1053
                'package' => array('subpackage', 'extension', 'os', 'arch')
1054
            ));
1055
    }
1056
 
1057
    /**
1058
     * @param optional|required
1059
     * @param string name of the package
1060
     * @param string uri of the package
1061
     * @param string extension this package provides, if any
1062
     * @param bool if true, tells the installer to ignore the default optional dependency group
1063
     *             when installing this package
1064
     */
1065
    function addPackageDepWithUri($type, $name, $uri, $providesextension = false,
1066
                                  $nodefault = false)
1067
    {
1068
        $this->_isValid = 0;
1069
        $arr = array('optional', 'group');
1070
        if ($type != 'required') {
1071
            array_shift($arr);
1072
        }
1073
        $dep = $this->_constructDep($name, false, $uri, false, false, false, false,
1074
            $providesextension, $nodefault);
1075
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1076
            array(
1077
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1078
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1079
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1080
                $type => $arr,
1081
                'package' => array('subpackage', 'extension', 'os', 'arch')
1082
            ));
1083
    }
1084
 
1085
    /**
1086
     * @param optional|required optional, required
1087
     * @param string package name
1088
     * @param string package channel
1089
     * @param string minimum version
1090
     * @param string maximum version
1091
     * @param string recommended version
1092
     * @param array incompatible versions
1093
     * @param bool if true, tells the installer to ignore the default optional dependency group
1094
     *             when installing this package
1095
     */
1096
    function addSubpackageDepWithChannel($type, $name, $channel, $min = false, $max = false,
1097
                                         $recommended = false, $exclude = false,
1098
                                         $nodefault = false)
1099
    {
1100
        $this->_isValid = 0;
1101
        $arr = array('optional', 'group');
1102
        if ($type != 'required') {
1103
            array_shift($arr);
1104
        }
1105
        $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
1106
            $nodefault);
1107
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1108
            array(
1109
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1110
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1111
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1112
                $type => $arr,
1113
                'subpackage' => array('extension', 'os', 'arch')
1114
            ));
1115
    }
1116
 
1117
    /**
1118
     * @param optional|required optional, required
1119
     * @param string package name
1120
     * @param string package uri for download
1121
     * @param bool if true, tells the installer to ignore the default optional dependency group
1122
     *             when installing this package
1123
     */
1124
    function addSubpackageDepWithUri($type, $name, $uri, $nodefault = false)
1125
    {
1126
        $this->_isValid = 0;
1127
        $arr = array('optional', 'group');
1128
        if ($type != 'required') {
1129
            array_shift($arr);
1130
        }
1131
        $dep = $this->_constructDep($name, false, $uri, false, false, false, false, $nodefault);
1132
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1133
            array(
1134
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1135
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1136
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1137
                $type => $arr,
1138
                'subpackage' => array('extension', 'os', 'arch')
1139
            ));
1140
    }
1141
 
1142
    /**
1143
     * @param optional|required optional, required
1144
     * @param string extension name
1145
     * @param string minimum version
1146
     * @param string maximum version
1147
     * @param string recommended version
1148
     * @param array incompatible versions
1149
     */
1150
    function addExtensionDep($type, $name, $min = false, $max = false, $recommended = false,
1151
                             $exclude = false)
1152
    {
1153
        $this->_isValid = 0;
1154
        $arr = array('optional', 'group');
1155
        if ($type != 'required') {
1156
            array_shift($arr);
1157
        }
1158
        $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
1159
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1160
            array(
1161
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1162
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1163
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1164
                $type => $arr,
1165
                'extension' => array('os', 'arch')
1166
            ));
1167
    }
1168
 
1169
    /**
1170
     * @param string Operating system name
1171
     * @param boolean true if this package cannot be installed on this OS
1172
     */
1173
    function addOsDep($name, $conflicts = false)
1174
    {
1175
        $this->_isValid = 0;
1176
        $dep = array('name' => $name);
1177
        if ($conflicts) {
1178
            $dep['conflicts'] = '';
1179
        }
1180
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1181
            array(
1182
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1183
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1184
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1185
                'required' => array('optional', 'group'),
1186
                'os' => array('arch')
1187
            ));
1188
    }
1189
 
1190
    /**
1191
     * @param string Architecture matching pattern
1192
     * @param boolean true if this package cannot be installed on this architecture
1193
     */
1194
    function addArchDep($pattern, $conflicts = false)
1195
    {
1196
        $this->_isValid = 0;
1197
        $dep = array('pattern' => $pattern);
1198
        if ($conflicts) {
1199
            $dep['conflicts'] = '';
1200
        }
1201
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1202
            array(
1203
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1204
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1205
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1206
                'required' => array('optional', 'group'),
1207
                'arch' => array()
1208
            ));
1209
    }
1210
 
1211
    /**
1212
     * Set the kind of package, and erase all release tags
1213
     *
1214
     * - a php package is a PEAR-style package
1215
     * - an extbin package is a PECL-style extension binary
1216
     * - an extsrc package is a PECL-style source for a binary
1217
     * - an zendextbin package is a PECL-style zend extension binary
1218
     * - an zendextsrc package is a PECL-style source for a zend extension binary
1219
     * - a bundle package is a collection of other pre-packaged packages
1220
     * @param php|extbin|extsrc|zendextsrc|zendextbin|bundle
1221
     * @return bool success
1222
     */
1223
    function setPackageType($type)
1224
    {
1225
        $this->_isValid = 0;
1226
        if (!in_array($type, array('php', 'extbin', 'extsrc', 'zendextsrc',
1227
                                   'zendextbin', 'bundle'))) {
1228
            return false;
1229
        }
1230
        if (in_array($type, array('zendextsrc', 'zendextbin'))) {
1231
            $this->_setPackageVersion2_1();
1232
        }
1233
        if ($type != 'bundle') {
1234
            $type .= 'release';
1235
        }
1236
        foreach (array('phprelease', 'extbinrelease', 'extsrcrelease',
1237
                       'zendextsrcrelease', 'zendextbinrelease', 'bundle') as $test) {
1238
            unset($this->_packageInfo[$test]);
1239
        }
1240
        if (!isset($this->_packageInfo[$type])) {
1241
            // ensure that the release tag is set up
1242
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('changelog'),
1243
                array(), $type);
1244
        }
1245
        $this->_packageInfo[$type] = array();
1246
        return true;
1247
    }
1248
 
1249
    /**
1250
     * @return bool true if package type is set up
1251
     */
1252
    function addRelease()
1253
    {
1254
        if ($type = $this->getPackageType()) {
1255
            if ($type != 'bundle') {
1256
                $type .= 'release';
1257
            }
1258
            $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(),
1259
                array($type => array('changelog')));
1260
            return true;
1261
        }
1262
        return false;
1263
    }
1264
 
1265
    /**
1266
     * Get the current release tag in order to add to it
1267
     * @param bool returns only releases that have installcondition if true
1268
     * @return array|null
1269
     */
1270
    function &_getCurrentRelease($strict = true)
1271
    {
1272
        if ($p = $this->getPackageType()) {
1273
            if ($strict) {
1274
                if ($p == 'extsrc' || $p == 'zendextsrc') {
1275
                    $a = null;
1276
                    return $a;
1277
                }
1278
            }
1279
            if ($p != 'bundle') {
1280
                $p .= 'release';
1281
            }
1282
            if (isset($this->_packageInfo[$p][0])) {
1283
                return $this->_packageInfo[$p][count($this->_packageInfo[$p]) - 1];
1284
            } else {
1285
                return $this->_packageInfo[$p];
1286
            }
1287
        } else {
1288
            $a = null;
1289
            return $a;
1290
        }
1291
    }
1292
 
1293
    /**
1294
     * Add a file to the current release that should be installed under a different name
1295
     * @param string <contents> path to file
1296
     * @param string name the file should be installed as
1297
     */
1298
    function addInstallAs($path, $as)
1299
    {
1300
        $r = &$this->_getCurrentRelease();
1301
        if ($r === null) {
1302
            return false;
1303
        }
1304
        $this->_isValid = 0;
1305
        $r = $this->_mergeTag($r, array('attribs' => array('name' => $path, 'as' => $as)),
1306
            array(
1307
                'filelist' => array(),
1308
                'install' => array('ignore')
1309
            ));
1310
    }
1311
 
1312
    /**
1313
     * Add a file to the current release that should be ignored
1314
     * @param string <contents> path to file
1315
     * @return bool success of operation
1316
     */
1317
    function addIgnore($path)
1318
    {
1319
        $r = &$this->_getCurrentRelease();
1320
        if ($r === null) {
1321
            return false;
1322
        }
1323
        $this->_isValid = 0;
1324
        $r = $this->_mergeTag($r, array('attribs' => array('name' => $path)),
1325
            array(
1326
                'filelist' => array(),
1327
                'ignore' => array()
1328
            ));
1329
    }
1330
 
1331
    /**
1332
     * Add an extension binary package for this extension source code release
1333
     *
1334
     * Note that the package must be from the same channel as the extension source package
1335
     * @param string
1336
     */
1337
    function addBinarypackage($package)
1338
    {
1339
        if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
1340
            return false;
1341
        }
1342
        $r = &$this->_getCurrentRelease(false);
1343
        if ($r === null) {
1344
            return false;
1345
        }
1346
        $this->_isValid = 0;
1347
        $r = $this->_mergeTag($r, $package,
1348
            array(
1349
                'binarypackage' => array('filelist'),
1350
            ));
1351
    }
1352
 
1353
    /**
1354
     * Add a configureoption to an extension source package
1355
     * @param string
1356
     * @param string
1357
     * @param string
1358
     */
1359
    function addConfigureOption($name, $prompt, $default = null)
1360
    {
1361
        if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
1362
            return false;
1363
        }
1364
        $r = &$this->_getCurrentRelease(false);
1365
        if ($r === null) {
1366
            return false;
1367
        }
1368
        $opt = array('attribs' => array('name' => $name, 'prompt' => $prompt));
1369
        if ($default !== null) {
1370
            $opt['attribs']['default'] = $default;
1371
        }
1372
        $this->_isValid = 0;
1373
        $r = $this->_mergeTag($r, $opt,
1374
            array(
1375
                'configureoption' => array('binarypackage', 'filelist'),
1376
            ));
1377
    }
1378
 
1379
    /**
1380
     * Set an installation condition based on php version for the current release set
1381
     * @param string minimum version
1382
     * @param string maximum version
1383
     * @param false|array incompatible versions of PHP
1384
     */
1385
    function setPhpInstallCondition($min, $max, $exclude = false)
1386
    {
1387
        $r = &$this->_getCurrentRelease();
1388
        if ($r === null) {
1389
            return false;
1390
        }
1391
        $this->_isValid = 0;
1392
        if (isset($r['installconditions']['php'])) {
1393
            unset($r['installconditions']['php']);
1394
        }
1395
        $dep = array('min' => $min, 'max' => $max);
1396
        if ($exclude) {
1397
            if (is_array($exclude) && count($exclude) == 1) {
1398
                $exclude = $exclude[0];
1399
            }
1400
            $dep['exclude'] = $exclude;
1401
        }
1402
        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
1403
            $r = $this->_mergeTag($r, $dep,
1404
                array(
1405
                    'installconditions' => array('configureoption', 'binarypackage',
1406
                        'filelist'),
1407
                    'php' => array('extension', 'os', 'arch')
1408
                ));
1409
        } else {
1410
            $r = $this->_mergeTag($r, $dep,
1411
                array(
1412
                    'installconditions' => array('filelist'),
1413
                    'php' => array('extension', 'os', 'arch')
1414
                ));
1415
        }
1416
    }
1417
 
1418
    /**
1419
     * @param optional|required optional, required
1420
     * @param string extension name
1421
     * @param string minimum version
1422
     * @param string maximum version
1423
     * @param string recommended version
1424
     * @param array incompatible versions
1425
     */
1426
    function addExtensionInstallCondition($name, $min = false, $max = false, $recommended = false,
1427
                                          $exclude = false)
1428
    {
1429
        $r = &$this->_getCurrentRelease();
1430
        if ($r === null) {
1431
            return false;
1432
        }
1433
        $this->_isValid = 0;
1434
        $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
1435
        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
1436
            $r = $this->_mergeTag($r, $dep,
1437
                array(
1438
                    'installconditions' => array('configureoption', 'binarypackage',
1439
                        'filelist'),
1440
                    'extension' => array('os', 'arch')
1441
                ));
1442
        } else {
1443
            $r = $this->_mergeTag($r, $dep,
1444
                array(
1445
                    'installconditions' => array('filelist'),
1446
                    'extension' => array('os', 'arch')
1447
                ));
1448
        }
1449
    }
1450
 
1451
    /**
1452
     * Set an installation condition based on operating system for the current release set
1453
     * @param string OS name
1454
     * @param bool whether this OS is incompatible with the current release
1455
     */
1456
    function setOsInstallCondition($name, $conflicts = false)
1457
    {
1458
        $r = &$this->_getCurrentRelease();
1459
        if ($r === null) {
1460
            return false;
1461
        }
1462
        $this->_isValid = 0;
1463
        if (isset($r['installconditions']['os'])) {
1464
            unset($r['installconditions']['os']);
1465
        }
1466
        $dep = array('name' => $name);
1467
        if ($conflicts) {
1468
            $dep['conflicts'] = '';
1469
        }
1470
        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
1471
            $r = $this->_mergeTag($r, $dep,
1472
                array(
1473
                    'installconditions' => array('configureoption', 'binarypackage',
1474
                        'filelist'),
1475
                    'os' => array('arch')
1476
                ));
1477
        } else {
1478
            $r = $this->_mergeTag($r, $dep,
1479
                array(
1480
                    'installconditions' => array('filelist'),
1481
                    'os' => array('arch')
1482
                ));
1483
        }
1484
    }
1485
 
1486
    /**
1487
     * Set an installation condition based on architecture for the current release set
1488
     * @param string architecture pattern
1489
     * @param bool whether this arch is incompatible with the current release
1490
     */
1491
    function setArchInstallCondition($pattern, $conflicts = false)
1492
    {
1493
        $r = &$this->_getCurrentRelease();
1494
        if ($r === null) {
1495
            return false;
1496
        }
1497
        $this->_isValid = 0;
1498
        if (isset($r['installconditions']['arch'])) {
1499
            unset($r['installconditions']['arch']);
1500
        }
1501
        $dep = array('pattern' => $pattern);
1502
        if ($conflicts) {
1503
            $dep['conflicts'] = '';
1504
        }
1505
        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
1506
            $r = $this->_mergeTag($r, $dep,
1507
                array(
1508
                    'installconditions' => array('configureoption', 'binarypackage',
1509
                        'filelist'),
1510
                    'arch' => array()
1511
                ));
1512
        } else {
1513
            $r = $this->_mergeTag($r, $dep,
1514
                array(
1515
                    'installconditions' => array('filelist'),
1516
                    'arch' => array()
1517
                ));
1518
        }
1519
    }
1520
 
1521
    /**
1522
     * For extension binary releases, this is used to specify either the
1523
     * static URI to a source package, or the package name and channel of the extsrc/zendextsrc
1524
     * package it is based on.
1525
     * @param string Package name, or full URI to source package (extsrc/zendextsrc type)
1526
     */
1527
    function setSourcePackage($packageOrUri)
1528
    {
1529
        $this->_isValid = 0;
1530
        if (isset($this->_packageInfo['channel'])) {
1531
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease',
1532
                'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
1533
                'bundle', 'changelog'),
1534
                $packageOrUri, 'srcpackage');
1535
        } else {
1536
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease',
1537
                'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
1538
                'bundle', 'changelog'), $packageOrUri, 'srcuri');
1539
        }
1540
    }
1541
 
1542
    /**
1543
     * Generate a valid change log entry from the current package.xml
1544
     * @param string|false
1545
     */
1546
    function generateChangeLogEntry($notes = false)
1547
    {
1548
        return array(
1549
            'version' =>
1550
                array(
1551
                    'release' => $this->getVersion('release'),
1552
                    'api' => $this->getVersion('api'),
1553
                    ),
1554
            'stability' =>
1555
                $this->getStability(),
1556
            'date' => $this->getDate(),
1557
            'license' => $this->getLicense(true),
1558
            'notes' => $notes ? $notes : $this->getNotes()
1559
            );
1560
    }
1561
 
1562
    /**
1563
     * @param string release version to set change log notes for
1564
     * @param array output of {@link generateChangeLogEntry()}
1565
     */
1566
    function setChangelogEntry($releaseversion, $contents)
1567
    {
1568
        if (!isset($this->_packageInfo['changelog'])) {
1569
            $this->_packageInfo['changelog']['release'] = $contents;
1570
            return;
1571
        }
1572
        if (!isset($this->_packageInfo['changelog']['release'][0])) {
1573
            if ($this->_packageInfo['changelog']['release']['version']['release'] == $releaseversion) {
1574
                $this->_packageInfo['changelog']['release'] = array(
1575
                    $this->_packageInfo['changelog']['release']);
1576
            } else {
1577
                $this->_packageInfo['changelog']['release'] = array(
1578
                    $this->_packageInfo['changelog']['release']);
1579
                return $this->_packageInfo['changelog']['release'][] = $contents;
1580
            }
1581
        }
1582
        foreach($this->_packageInfo['changelog']['release'] as $index => $changelog) {
1583
            if (isset($changelog['version']) &&
1584
                  strnatcasecmp($changelog['version']['release'], $releaseversion) == 0) {
1585
                $curlog = $index;
1586
            }
1587
        }
1588
        if (isset($curlog)) {
1589
            $this->_packageInfo['changelog']['release'][$curlog] = $contents;
1590
        } else {
1591
            $this->_packageInfo['changelog']['release'][] = $contents;
1592
        }
1593
    }
1594
 
1595
    /**
1596
     * Remove the changelog entirely
1597
     */
1598
    function clearChangeLog()
1599
    {
1600
        unset($this->_packageInfo['changelog']);
1601
    }
1602
}
1603
?>