Subversion Repositories Applications.gtt

Rev

Rev 94 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
94 jpm 1
<?php
2
/**
3
 * PEAR_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-2006 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.19 2006/10/30 04:12:02 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-2006 The PHP Group
31
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
32
 * @version    Release: 1.5.1
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
        }
467
    }
468
 
469
    /**
470
     * @param string relative path of the bundled package.
471
     */
472
    function addBundledPackage($path)
473
    {
474
        if ($this->getPackageType() != 'bundle') {
475
            return false;
476
        }
477
        $this->_filesValid = false;
478
        $this->_isValid = 0;
479
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $path, array(
480
                'contents' => array('compatible', 'dependencies', 'providesextension',
481
                'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease',
482
                'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
483
                'bundle', 'changelog'),
484
                'bundledpackage' => array()));
485
    }
486
 
487
    /**
488
     * @param string file name
489
     * @param PEAR_Task_Common a read/write task
490
     */
491
    function addTaskToFile($filename, $task)
492
    {
493
        if (!method_exists($task, 'getXml')) {
494
            return false;
495
        }
496
        if (!method_exists($task, 'getName')) {
497
            return false;
498
        }
499
        if (!method_exists($task, 'validate')) {
500
            return false;
501
        }
502
        if (!$task->validate()) {
503
            return false;
504
        }
505
        if (!isset($this->_packageInfo['contents']['dir']['file'])) {
506
            return false;
507
        }
508
        $this->getTasksNs(); // discover the tasks namespace if not done already
509
        $files = $this->_packageInfo['contents']['dir']['file'];
510
        if (!isset($files[0])) {
511
            $files = array($files);
512
            $ind = false;
513
        } else {
514
            $ind = true;
515
        }
516
        foreach ($files as $i => $file) {
517
            if (isset($file['attribs'])) {
518
                if ($file['attribs']['name'] == $filename) {
519
                    if ($ind) {
520
                        $t = isset($this->_packageInfo['contents']['dir']['file'][$i]
521
                              ['attribs'][$this->_tasksNs .
522
                              ':' . $task->getName()]) ?
523
                              $this->_packageInfo['contents']['dir']['file'][$i]
524
                              ['attribs'][$this->_tasksNs .
525
                              ':' . $task->getName()] : false;
526
                        if ($t && !isset($t[0])) {
527
                            $this->_packageInfo['contents']['dir']['file'][$i]
528
                                [$this->_tasksNs . ':' . $task->getName()] = array($t);
529
                        }
530
                        $this->_packageInfo['contents']['dir']['file'][$i][$this->_tasksNs .
531
                            ':' . $task->getName()][] = $task->getXml();
532
                    } else {
533
                        $t = isset($this->_packageInfo['contents']['dir']['file']
534
                              ['attribs'][$this->_tasksNs .
535
                              ':' . $task->getName()]) ? $this->_packageInfo['contents']['dir']['file']
536
                              ['attribs'][$this->_tasksNs .
537
                              ':' . $task->getName()] : false;
538
                        if ($t && !isset($t[0])) {
539
                            $this->_packageInfo['contents']['dir']['file']
540
                                [$this->_tasksNs . ':' . $task->getName()] = array($t);
541
                        }
542
                        $this->_packageInfo['contents']['dir']['file'][$this->_tasksNs .
543
                            ':' . $task->getName()][] = $task->getXml();
544
                    }
545
                    return true;
546
                }
547
            }
548
        }
549
        return false;
550
    }
551
 
552
    /**
553
     * @param string path to the file
554
     * @param string filename
555
     * @param array extra attributes
556
     */
557
    function addFile($dir, $file, $attrs)
558
    {
559
        if ($this->getPackageType() == 'bundle') {
560
            return false;
561
        }
562
        $this->_filesValid = false;
563
        $this->_isValid = 0;
564
        $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
565
        if ($dir == '/' || $dir == '') {
566
            $dir = '';
567
        } else {
568
            $dir .= '/';
569
        }
570
        $attrs['name'] = $dir . $file;
571
        if (!isset($this->_packageInfo['contents'])) {
572
            // ensure that the contents tag is set up
573
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
574
                array('compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask',
575
                'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease',
576
                'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
577
                'bundle', 'changelog'), array(), 'contents');
578
        }
579
        if (isset($this->_packageInfo['contents']['dir']['file'])) {
580
            if (!isset($this->_packageInfo['contents']['dir']['file'][0])) {
581
                $this->_packageInfo['contents']['dir']['file'] =
582
                    array($this->_packageInfo['contents']['dir']['file']);
583
            }
584
            $this->_packageInfo['contents']['dir']['file'][]['attribs'] = $attrs;
585
        } else {
586
            $this->_packageInfo['contents']['dir']['file']['attribs'] = $attrs;
587
        }
588
    }
589
 
590
    /**
591
     * @param string Dependent package name
592
     * @param string Dependent package's channel name
593
     * @param string minimum version of specified package that this release is guaranteed to be
594
     *               compatible with
595
     * @param string maximum version of specified package that this release is guaranteed to be
596
     *               compatible with
597
     * @param string versions of specified package that this release is not compatible with
598
     */
599
    function addCompatiblePackage($name, $channel, $min, $max, $exclude = false)
600
    {
601
        $this->_isValid = 0;
602
        $set = array(
603
            'name' => $name,
604
            'channel' => $channel,
605
            'min' => $min,
606
            'max' => $max,
607
        );
608
        if ($exclude) {
609
            $set['exclude'] = $exclude;
610
        }
611
        $this->_isValid = 0;
612
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
613
                'compatible' => array('dependencies', 'providesextension', 'usesrole', 'usestask',
614
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
615
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
616
            ));
617
    }
618
 
619
    /**
620
     * Removes the <usesrole> tag entirely
621
     */
622
    function resetUsesrole()
623
    {
624
        if (isset($this->_packageInfo['usesrole'])) {
625
            unset($this->_packageInfo['usesrole']);
626
        }
627
    }
628
 
629
    /**
630
     * @param string
631
     * @param string package name or uri
632
     * @param string channel name if non-uri
633
     */
634
    function addUsesrole($role, $packageOrUri, $channel = false) {
635
        $set = array('role' => $role);
636
        if ($channel) {
637
            $set['package'] = $packageOrUri;
638
            $set['channel'] = $channel;
639
        } else {
640
            $set['uri'] = $packageOrUri;
641
        }
642
        $this->_isValid = 0;
643
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
644
                'usesrole' => array('usestask', 'srcpackage', 'srcuri',
645
                    'phprelease', 'extsrcrelease', 'extbinrelease',
646
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
647
            ));
648
    }
649
 
650
    /**
651
     * Removes the <usestask> tag entirely
652
     */
653
    function resetUsestask()
654
    {
655
        if (isset($this->_packageInfo['usestask'])) {
656
            unset($this->_packageInfo['usestask']);
657
        }
658
    }
659
 
660
 
661
    /**
662
     * @param string
663
     * @param string package name or uri
664
     * @param string channel name if non-uri
665
     */
666
    function addUsestask($task, $packageOrUri, $channel = false) {
667
        $set = array('task' => $task);
668
        if ($channel) {
669
            $set['package'] = $packageOrUri;
670
            $set['channel'] = $channel;
671
        } else {
672
            $set['uri'] = $packageOrUri;
673
        }
674
        $this->_isValid = 0;
675
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
676
                'usestask' => array('srcpackage', 'srcuri',
677
                    'phprelease', 'extsrcrelease', 'extbinrelease',
678
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
679
            ));
680
    }
681
 
682
    /**
683
     * Remove all compatible tags
684
     */
685
    function clearCompatible()
686
    {
687
        unset($this->_packageInfo['compatible']);
688
    }
689
 
690
    /**
691
     * Reset dependencies prior to adding new ones
692
     */
693
    function clearDeps()
694
    {
695
        if (!isset($this->_packageInfo['dependencies'])) {
696
            $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(),
697
                array(
698
                    'dependencies' => array('providesextension', 'usesrole', 'usestask',
699
                        'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
700
                        'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')));
701
        }
702
        $this->_packageInfo['dependencies'] = array();
703
    }
704
 
705
    /**
706
     * @param string minimum PHP version allowed
707
     * @param string maximum PHP version allowed
708
     * @param array $exclude incompatible PHP versions
709
     */
710
    function setPhpDep($min, $max = false, $exclude = false)
711
    {
712
        $this->_isValid = 0;
713
        $dep =
714
            array(
715
                'min' => $min,
716
            );
717
        if ($max) {
718
            $dep['max'] = $max;
719
        }
720
        if ($exclude) {
721
            if (count($exclude) == 1) {
722
                $exclude = $exclude[0];
723
            }
724
            $dep['exclude'] = $exclude;
725
        }
726
        if (isset($this->_packageInfo['dependencies']['required']['php'])) {
727
            $this->_stack->push(__FUNCTION__, 'warning', array('dep' =>
728
            $this->_packageInfo['dependencies']['required']['php']),
729
                'warning: PHP dependency already exists, overwriting');
730
            unset($this->_packageInfo['dependencies']['required']['php']);
731
        }
732
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
733
            array(
734
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
735
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
736
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
737
                'required' => array('optional', 'group'),
738
                'php' => array('pearinstaller', 'package', 'subpackage', 'extension', 'os', 'arch')
739
            ));
740
        return true;
741
    }
742
 
743
    /**
744
     * @param string minimum allowed PEAR installer version
745
     * @param string maximum allowed PEAR installer version
746
     * @param string recommended PEAR installer version
747
     * @param array incompatible version of the PEAR installer
748
     */
749
    function setPearinstallerDep($min, $max = false, $recommended = false, $exclude = false)
750
    {
751
        $this->_isValid = 0;
752
        $dep =
753
            array(
754
                'min' => $min,
755
            );
756
        if ($max) {
757
            $dep['max'] = $max;
758
        }
759
        if ($recommended) {
760
            $dep['recommended'] = $recommended;
761
        }
762
        if ($exclude) {
763
            if (count($exclude) == 1) {
764
                $exclude = $exclude[0];
765
            }
766
            $dep['exclude'] = $exclude;
767
        }
768
        if (isset($this->_packageInfo['dependencies']['required']['pearinstaller'])) {
769
            $this->_stack->push(__FUNCTION__, 'warning', array('dep' =>
770
            $this->_packageInfo['dependencies']['required']['pearinstaller']),
771
                'warning: PEAR Installer dependency already exists, overwriting');
772
            unset($this->_packageInfo['dependencies']['required']['pearinstaller']);
773
        }
774
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
775
            array(
776
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
777
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
778
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
779
                'required' => array('optional', 'group'),
780
                'pearinstaller' => array('package', 'subpackage', 'extension', 'os', 'arch')
781
            ));
782
    }
783
 
784
    /**
785
     * Mark a package as conflicting with this package
786
     * @param string package name
787
     * @param string package channel
788
     * @param string extension this package provides, if any
789
     * @param string|false minimum version required
790
     * @param string|false maximum version allowed
791
     * @param array|false versions to exclude from installation
792
     */
793
    function addConflictingPackageDepWithChannel($name, $channel,
794
                $providesextension = false, $min = false, $max = false, $exclude = false)
795
    {
796
        $this->_isValid = 0;
797
        $dep = $this->_constructDep($name, $channel, false, $min, $max, false,
798
            $exclude, $providesextension, false, true);
799
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
800
            array(
801
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
802
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
803
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
804
                'required' => array('optional', 'group'),
805
                'package' => array('subpackage', 'extension', 'os', 'arch')
806
            ));
807
    }
808
 
809
    /**
810
     * Mark a package as conflicting with this package
811
     * @param string package name
812
     * @param string package channel
813
     * @param string extension this package provides, if any
814
     */
815
    function addConflictingPackageDepWithUri($name, $uri, $providesextension = false)
816
    {
817
        $this->_isValid = 0;
818
        $dep =
819
            array(
820
                'name' => $name,
821
                'uri' => $uri,
822
                'conflicts' => '',
823
            );
824
        if ($providesextension) {
825
            $dep['providesextension'] = $providesextension;
826
        }
827
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
828
            array(
829
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
830
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
831
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
832
                'required' => array('optional', 'group'),
833
                'package' => array('subpackage', 'extension', 'os', 'arch')
834
            ));
835
    }
836
 
837
    function addDependencyGroup($name, $hint)
838
    {
839
        $this->_isValid = 0;
840
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo,
841
            array('attribs' => array('name' => $name, 'hint' => $hint)),
842
            array(
843
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
844
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
845
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
846
                'group' => array(),
847
            ));
848
    }
849
 
850
    /**
851
     * @param string package name
852
     * @param string|false channel name, false if this is a uri
853
     * @param string|false uri name, false if this is a channel
854
     * @param string|false minimum version required
855
     * @param string|false maximum version allowed
856
     * @param string|false recommended installation version
857
     * @param array|false versions to exclude from installation
858
     * @param string extension this package provides, if any
859
     * @param bool if true, tells the installer to ignore the default optional dependency group
860
     *             when installing this package
861
     * @param bool if true, tells the installer to negate this dependency (conflicts)
862
     * @return array
863
     * @access private
864
     */
865
    function _constructDep($name, $channel, $uri, $min, $max, $recommended, $exclude,
866
                           $providesextension = false, $nodefault = false,
867
                           $conflicts = false)
868
    {
869
        $dep =
870
            array(
871
                'name' => $name,
872
            );
873
        if ($channel) {
874
            $dep['channel'] = $channel;
875
        } elseif ($uri) {
876
            $dep['uri'] = $uri;
877
        }
878
        if ($min) {
879
            $dep['min'] = $min;
880
        }
881
        if ($max) {
882
            $dep['max'] = $max;
883
        }
884
        if ($recommended) {
885
            $dep['recommended'] = $recommended;
886
        }
887
        if ($exclude) {
888
            if (is_array($exclude) && count($exclude) == 1) {
889
                $exclude = $exclude[0];
890
            }
891
            $dep['exclude'] = $exclude;
892
        }
893
        if ($conflicts) {
894
            $dep['conflicts'] = '';
895
        }
896
        if ($nodefault) {
897
            $dep['nodefault'] = '';
898
        }
899
        if ($providesextension) {
900
            $dep['providesextension'] = $providesextension;
901
        }
902
        return $dep;
903
    }
904
 
905
    /**
906
     * @param package|subpackage
907
     * @param string group name
908
     * @param string package name
909
     * @param string package channel
910
     * @param string minimum version
911
     * @param string maximum version
912
     * @param string recommended version
913
     * @param array|false optional excluded versions
914
     * @param string extension this package provides, if any
915
     * @param bool if true, tells the installer to ignore the default optional dependency group
916
     *             when installing this package
917
     * @return bool false if the dependency group has not been initialized with
918
     *              {@link addDependencyGroup()}, or a subpackage is added with
919
     *              a providesextension
920
     */
921
    function addGroupPackageDepWithChannel($type, $groupname, $name, $channel, $min = false,
922
                                      $max = false, $recommended = false, $exclude = false,
923
                                      $providesextension = false, $nodefault = false)
924
    {
925
        if ($type == 'subpackage' && $providesextension) {
926
            return false; // subpackages must be php packages
927
        }
928
        $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
929
            $providesextension, $nodefault);
930
        return $this->_addGroupDependency($type, $dep, $groupname);
931
    }
932
 
933
    /**
934
     * @param package|subpackage
935
     * @param string group name
936
     * @param string package name
937
     * @param string package uri
938
     * @param string extension this package provides, if any
939
     * @param bool if true, tells the installer to ignore the default optional dependency group
940
     *             when installing this package
941
     * @return bool false if the dependency group has not been initialized with
942
     *              {@link addDependencyGroup()}
943
     */
944
    function addGroupPackageDepWithURI($type, $groupname, $name, $uri, $providesextension = false,
945
                                       $nodefault = false)
946
    {
947
        if ($type == 'subpackage' && $providesextension) {
948
            return false; // subpackages must be php packages
949
        }
950
        $dep = $this->_constructDep($name, false, $uri, false, false, false, false,
951
            $providesextension, $nodefault);
952
        return $this->_addGroupDependency($type, $dep, $groupname);
953
    }
954
 
955
    /**
956
     * @param string group name (must be pre-existing)
957
     * @param string extension name
958
     * @param string minimum version allowed
959
     * @param string maximum version allowed
960
     * @param string recommended version
961
     * @param array incompatible versions
962
     */
963
    function addGroupExtensionDep($groupname, $name, $min = false, $max = false,
964
                                         $recommended = false, $exclude = false)
965
    {
966
        $this->_isValid = 0;
967
        $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
968
        return $this->_addGroupDependency('extension', $dep, $groupname);
969
    }
970
 
971
    /**
972
     * @param package|subpackage|extension
973
     * @param array dependency contents
974
     * @param string name of the dependency group to add this to
975
     * @return boolean
976
     * @access private
977
     */
978
    function _addGroupDependency($type, $dep, $groupname)
979
    {
980
        $arr = array('subpackage', 'extension');
981
        if ($type != 'package') {
982
            array_shift($arr);
983
        }
984
        if ($type == 'extension') {
985
            array_shift($arr);
986
        }
987
        if (!isset($this->_packageInfo['dependencies']['group'])) {
988
            return false;
989
        } else {
990
            if (!isset($this->_packageInfo['dependencies']['group'][0])) {
991
                if ($this->_packageInfo['dependencies']['group']['attribs']['name'] == $groupname) {
992
                    $this->_packageInfo['dependencies']['group'] = $this->_mergeTag(
993
                        $this->_packageInfo['dependencies']['group'], $dep,
994
                        array(
995
                            $type => $arr
996
                        ));
997
                    $this->_isValid = 0;
998
                    return true;
999
                } else {
1000
                    return false;
1001
                }
1002
            } else {
1003
                foreach ($this->_packageInfo['dependencies']['group'] as $i => $group) {
1004
                    if ($group['attribs']['name'] == $groupname) {
1005
                    $this->_packageInfo['dependencies']['group'][$i] = $this->_mergeTag(
1006
                        $this->_packageInfo['dependencies']['group'][$i], $dep,
1007
                        array(
1008
                            $type => $arr
1009
                        ));
1010
                        $this->_isValid = 0;
1011
                        return true;
1012
                    }
1013
                }
1014
                return false;
1015
            }
1016
        }
1017
    }
1018
 
1019
    /**
1020
     * @param optional|required
1021
     * @param string package name
1022
     * @param string package channel
1023
     * @param string minimum version
1024
     * @param string maximum version
1025
     * @param string recommended version
1026
     * @param string extension this package provides, if any
1027
     * @param bool if true, tells the installer to ignore the default optional dependency group
1028
     *             when installing this package
1029
     * @param array|false optional excluded versions
1030
     */
1031
    function addPackageDepWithChannel($type, $name, $channel, $min = false, $max = false,
1032
                                      $recommended = false, $exclude = false,
1033
                                      $providesextension = false, $nodefault = false)
1034
    {
1035
        if (!in_array($type, array('optional', 'required'), true)) {
1036
            $type = 'required';
1037
        }
1038
        $this->_isValid = 0;
1039
        $arr = array('optional', 'group');
1040
        if ($type != 'required') {
1041
            array_shift($arr);
1042
        }
1043
        $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
1044
            $providesextension, $nodefault);
1045
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1046
            array(
1047
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1048
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1049
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1050
                $type => $arr,
1051
                'package' => array('subpackage', 'extension', 'os', 'arch')
1052
            ));
1053
    }
1054
 
1055
    /**
1056
     * @param optional|required
1057
     * @param string name of the package
1058
     * @param string uri of the package
1059
     * @param string extension this package provides, if any
1060
     * @param bool if true, tells the installer to ignore the default optional dependency group
1061
     *             when installing this package
1062
     */
1063
    function addPackageDepWithUri($type, $name, $uri, $providesextension = false,
1064
                                  $nodefault = false)
1065
    {
1066
        $this->_isValid = 0;
1067
        $arr = array('optional', 'group');
1068
        if ($type != 'required') {
1069
            array_shift($arr);
1070
        }
1071
        $dep = $this->_constructDep($name, false, $uri, false, false, false, false,
1072
            $providesextension, $nodefault);
1073
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1074
            array(
1075
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1076
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1077
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1078
                $type => $arr,
1079
                'package' => array('subpackage', 'extension', 'os', 'arch')
1080
            ));
1081
    }
1082
 
1083
    /**
1084
     * @param optional|required optional, required
1085
     * @param string package name
1086
     * @param string package channel
1087
     * @param string minimum version
1088
     * @param string maximum version
1089
     * @param string recommended version
1090
     * @param array incompatible versions
1091
     * @param bool if true, tells the installer to ignore the default optional dependency group
1092
     *             when installing this package
1093
     */
1094
    function addSubpackageDepWithChannel($type, $name, $channel, $min = false, $max = false,
1095
                                         $recommended = false, $exclude = false,
1096
                                         $nodefault = false)
1097
    {
1098
        $this->_isValid = 0;
1099
        $arr = array('optional', 'group');
1100
        if ($type != 'required') {
1101
            array_shift($arr);
1102
        }
1103
        $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
1104
            $nodefault);
1105
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1106
            array(
1107
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1108
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1109
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1110
                $type => $arr,
1111
                'subpackage' => array('extension', 'os', 'arch')
1112
            ));
1113
    }
1114
 
1115
    /**
1116
     * @param optional|required optional, required
1117
     * @param string package name
1118
     * @param string package uri for download
1119
     * @param bool if true, tells the installer to ignore the default optional dependency group
1120
     *             when installing this package
1121
     */
1122
    function addSubpackageDepWithUri($type, $name, $uri, $nodefault = false)
1123
    {
1124
        $this->_isValid = 0;
1125
        $arr = array('optional', 'group');
1126
        if ($type != 'required') {
1127
            array_shift($arr);
1128
        }
1129
        $dep = $this->_constructDep($name, false, $uri, false, false, false, false, $nodefault);
1130
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1131
            array(
1132
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1133
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1134
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1135
                $type => $arr,
1136
                'subpackage' => array('extension', 'os', 'arch')
1137
            ));
1138
    }
1139
 
1140
    /**
1141
     * @param optional|required optional, required
1142
     * @param string extension name
1143
     * @param string minimum version
1144
     * @param string maximum version
1145
     * @param string recommended version
1146
     * @param array incompatible versions
1147
     */
1148
    function addExtensionDep($type, $name, $min = false, $max = false, $recommended = false,
1149
                             $exclude = false)
1150
    {
1151
        $this->_isValid = 0;
1152
        $arr = array('optional', 'group');
1153
        if ($type != 'required') {
1154
            array_shift($arr);
1155
        }
1156
        $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
1157
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1158
            array(
1159
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1160
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1161
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1162
                $type => $arr,
1163
                'extension' => array('os', 'arch')
1164
            ));
1165
    }
1166
 
1167
    /**
1168
     * @param string Operating system name
1169
     * @param boolean true if this package cannot be installed on this OS
1170
     */
1171
    function addOsDep($name, $conflicts = false)
1172
    {
1173
        $this->_isValid = 0;
1174
        $dep = array('name' => $name);
1175
        if ($conflicts) {
1176
            $dep['conflicts'] = '';
1177
        }
1178
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1179
            array(
1180
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1181
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1182
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1183
                'required' => array('optional', 'group'),
1184
                'os' => array('arch')
1185
            ));
1186
    }
1187
 
1188
    /**
1189
     * @param string Architecture matching pattern
1190
     * @param boolean true if this package cannot be installed on this architecture
1191
     */
1192
    function addArchDep($pattern, $conflicts = false)
1193
    {
1194
        $this->_isValid = 0;
1195
        $dep = array('pattern' => $pattern);
1196
        if ($conflicts) {
1197
            $dep['conflicts'] = '';
1198
        }
1199
        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1200
            array(
1201
                'dependencies' => array('providesextension', 'usesrole', 'usestask',
1202
                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1203
                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1204
                'required' => array('optional', 'group'),
1205
                'arch' => array()
1206
            ));
1207
    }
1208
 
1209
    /**
1210
     * Set the kind of package, and erase all release tags
1211
     *
1212
     * - a php package is a PEAR-style package
1213
     * - an extbin package is a PECL-style extension binary
1214
     * - an extsrc package is a PECL-style source for a binary
1215
     * - an zendextbin package is a PECL-style zend extension binary
1216
     * - an zendextsrc package is a PECL-style source for a zend extension binary
1217
     * - a bundle package is a collection of other pre-packaged packages
1218
     * @param php|extbin|extsrc|zendextsrc|zendextbin|bundle
1219
     * @return bool success
1220
     */
1221
    function setPackageType($type)
1222
    {
1223
        $this->_isValid = 0;
1224
        if (!in_array($type, array('php', 'extbin', 'extsrc', 'zendextsrc',
1225
                                   'zendextbin', 'bundle'))) {
1226
            return false;
1227
        }
1228
        if (in_array($type, array('zendextsrc', 'zendextbin'))) {
1229
            $this->_setPackageVersion2_1();
1230
        }
1231
        if ($type != 'bundle') {
1232
            $type .= 'release';
1233
        }
1234
        foreach (array('phprelease', 'extbinrelease', 'extsrcrelease',
1235
                       'zendextsrcrelease', 'zendextbinrelease', 'bundle') as $test) {
1236
            unset($this->_packageInfo[$test]);
1237
        }
1238
        if (!isset($this->_packageInfo[$type])) {
1239
            // ensure that the release tag is set up
1240
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('changelog'),
1241
                array(), $type);
1242
        }
1243
        $this->_packageInfo[$type] = array();
1244
        return true;
1245
    }
1246
 
1247
    /**
1248
     * @return bool true if package type is set up
1249
     */
1250
    function addRelease()
1251
    {
1252
        if ($type = $this->getPackageType()) {
1253
            if ($type != 'bundle') {
1254
                $type .= 'release';
1255
            }
1256
            $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(),
1257
                array($type => array('changelog')));
1258
            return true;
1259
        }
1260
        return false;
1261
    }
1262
 
1263
    /**
1264
     * Get the current release tag in order to add to it
1265
     * @param bool returns only releases that have installcondition if true
1266
     * @return array|null
1267
     */
1268
    function &_getCurrentRelease($strict = true)
1269
    {
1270
        if ($p = $this->getPackageType()) {
1271
            if ($strict) {
1272
                if ($p == 'extsrc' || $p == 'zendextsrc') {
1273
                    $a = null;
1274
                    return $a;
1275
                }
1276
            }
1277
            if ($p != 'bundle') {
1278
                $p .= 'release';
1279
            }
1280
            if (isset($this->_packageInfo[$p][0])) {
1281
                return $this->_packageInfo[$p][count($this->_packageInfo[$p]) - 1];
1282
            } else {
1283
                return $this->_packageInfo[$p];
1284
            }
1285
        } else {
1286
            $a = null;
1287
            return $a;
1288
        }
1289
    }
1290
 
1291
    /**
1292
     * Add a file to the current release that should be installed under a different name
1293
     * @param string <contents> path to file
1294
     * @param string name the file should be installed as
1295
     */
1296
    function addInstallAs($path, $as)
1297
    {
1298
        $r = &$this->_getCurrentRelease();
1299
        if ($r === null) {
1300
            return false;
1301
        }
1302
        $this->_isValid = 0;
1303
        $r = $this->_mergeTag($r, array('attribs' => array('name' => $path, 'as' => $as)),
1304
            array(
1305
                'filelist' => array(),
1306
                'install' => array('ignore')
1307
            ));
1308
    }
1309
 
1310
    /**
1311
     * Add a file to the current release that should be ignored
1312
     * @param string <contents> path to file
1313
     * @return bool success of operation
1314
     */
1315
    function addIgnore($path)
1316
    {
1317
        $r = &$this->_getCurrentRelease();
1318
        if ($r === null) {
1319
            return false;
1320
        }
1321
        $this->_isValid = 0;
1322
        $r = $this->_mergeTag($r, array('attribs' => array('name' => $path)),
1323
            array(
1324
                'filelist' => array(),
1325
                'ignore' => array()
1326
            ));
1327
    }
1328
 
1329
    /**
1330
     * Add an extension binary package for this extension source code release
1331
     *
1332
     * Note that the package must be from the same channel as the extension source package
1333
     * @param string
1334
     */
1335
    function addBinarypackage($package)
1336
    {
1337
        if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
1338
            return false;
1339
        }
1340
        $r = &$this->_getCurrentRelease(false);
1341
        if ($r === null) {
1342
            return false;
1343
        }
1344
        $this->_isValid = 0;
1345
        $r = $this->_mergeTag($r, $package,
1346
            array(
1347
                'binarypackage' => array('filelist'),
1348
            ));
1349
    }
1350
 
1351
    /**
1352
     * Add a configureoption to an extension source package
1353
     * @param string
1354
     * @param string
1355
     * @param string
1356
     */
1357
    function addConfigureOption($name, $prompt, $default = null)
1358
    {
1359
        if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
1360
            return false;
1361
        }
1362
        $r = &$this->_getCurrentRelease(false);
1363
        if ($r === null) {
1364
            return false;
1365
        }
1366
        $opt = array('attribs' => array('name' => $name, 'prompt' => $prompt));
1367
        if ($default !== null) {
1368
            $opt['default'] = $default;
1369
        }
1370
        $this->_isValid = 0;
1371
        $r = $this->_mergeTag($r, $opt,
1372
            array(
1373
                'configureoption' => array('binarypackage', 'filelist'),
1374
            ));
1375
    }
1376
 
1377
    /**
1378
     * Set an installation condition based on php version for the current release set
1379
     * @param string minimum version
1380
     * @param string maximum version
1381
     * @param false|array incompatible versions of PHP
1382
     */
1383
    function setPhpInstallCondition($min, $max, $exclude = false)
1384
    {
1385
        $r = &$this->_getCurrentRelease();
1386
        if ($r === null) {
1387
            return false;
1388
        }
1389
        $this->_isValid = 0;
1390
        if (isset($r['installconditions']['php'])) {
1391
            unset($r['installconditions']['php']);
1392
        }
1393
        $dep = array('min' => $min, 'max' => $max);
1394
        if ($exclude) {
1395
            if (is_array($exclude) && count($exclude) == 1) {
1396
                $exclude = $exclude[0];
1397
            }
1398
            $dep['exclude'] = $exclude;
1399
        }
1400
        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
1401
            $r = $this->_mergeTag($r, $dep,
1402
                array(
1403
                    'installconditions' => array('configureoption', 'binarypackage',
1404
                        'filelist'),
1405
                    'php' => array('extension', 'os', 'arch')
1406
                ));
1407
        } else {
1408
            $r = $this->_mergeTag($r, $dep,
1409
                array(
1410
                    'installconditions' => array('filelist'),
1411
                    'php' => array('extension', 'os', 'arch')
1412
                ));
1413
        }
1414
    }
1415
 
1416
    /**
1417
     * @param optional|required optional, required
1418
     * @param string extension name
1419
     * @param string minimum version
1420
     * @param string maximum version
1421
     * @param string recommended version
1422
     * @param array incompatible versions
1423
     */
1424
    function addExtensionInstallCondition($name, $min = false, $max = false, $recommended = false,
1425
                                          $exclude = false)
1426
    {
1427
        $r = &$this->_getCurrentRelease();
1428
        if ($r === null) {
1429
            return false;
1430
        }
1431
        $this->_isValid = 0;
1432
        $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
1433
        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
1434
            $r = $this->_mergeTag($r, $dep,
1435
                array(
1436
                    'installconditions' => array('configureoption', 'binarypackage',
1437
                        'filelist'),
1438
                    'extension' => array('os', 'arch')
1439
                ));
1440
        } else {
1441
            $r = $this->_mergeTag($r, $dep,
1442
                array(
1443
                    'installconditions' => array('filelist'),
1444
                    'extension' => array('os', 'arch')
1445
                ));
1446
        }
1447
    }
1448
 
1449
    /**
1450
     * Set an installation condition based on operating system for the current release set
1451
     * @param string OS name
1452
     * @param bool whether this OS is incompatible with the current release
1453
     */
1454
    function setOsInstallCondition($name, $conflicts = false)
1455
    {
1456
        $r = &$this->_getCurrentRelease();
1457
        if ($r === null) {
1458
            return false;
1459
        }
1460
        $this->_isValid = 0;
1461
        if (isset($r['installconditions']['os'])) {
1462
            unset($r['installconditions']['os']);
1463
        }
1464
        $dep = array('name' => $name);
1465
        if ($conflicts) {
1466
            $dep['conflicts'] = '';
1467
        }
1468
        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
1469
            $r = $this->_mergeTag($r, $dep,
1470
                array(
1471
                    'installconditions' => array('configureoption', 'binarypackage',
1472
                        'filelist'),
1473
                    'os' => array('arch')
1474
                ));
1475
        } else {
1476
            $r = $this->_mergeTag($r, $dep,
1477
                array(
1478
                    'installconditions' => array('filelist'),
1479
                    'os' => array('arch')
1480
                ));
1481
        }
1482
    }
1483
 
1484
    /**
1485
     * Set an installation condition based on architecture for the current release set
1486
     * @param string architecture pattern
1487
     * @param bool whether this arch is incompatible with the current release
1488
     */
1489
    function setArchInstallCondition($pattern, $conflicts = false)
1490
    {
1491
        $r = &$this->_getCurrentRelease();
1492
        if ($r === null) {
1493
            return false;
1494
        }
1495
        $this->_isValid = 0;
1496
        if (isset($r['installconditions']['arch'])) {
1497
            unset($r['installconditions']['arch']);
1498
        }
1499
        $dep = array('pattern' => $pattern);
1500
        if ($conflicts) {
1501
            $dep['conflicts'] = '';
1502
        }
1503
        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
1504
            $r = $this->_mergeTag($r, $dep,
1505
                array(
1506
                    'installconditions' => array('configureoption', 'binarypackage',
1507
                        'filelist'),
1508
                    'arch' => array()
1509
                ));
1510
        } else {
1511
            $r = $this->_mergeTag($r, $dep,
1512
                array(
1513
                    'installconditions' => array('filelist'),
1514
                    'arch' => array()
1515
                ));
1516
        }
1517
    }
1518
 
1519
    /**
1520
     * For extension binary releases, this is used to specify either the
1521
     * static URI to a source package, or the package name and channel of the extsrc/zendextsrc
1522
     * package it is based on.
1523
     * @param string Package name, or full URI to source package (extsrc/zendextsrc type)
1524
     */
1525
    function setSourcePackage($packageOrUri)
1526
    {
1527
        $this->_isValid = 0;
1528
        if (isset($this->_packageInfo['channel'])) {
1529
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease',
1530
                'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
1531
                'bundle', 'changelog'),
1532
                $packageOrUri, 'srcpackage');
1533
        } else {
1534
            $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease',
1535
                'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
1536
                'bundle', 'changelog'), $packageOrUri, 'srcuri');
1537
        }
1538
    }
1539
 
1540
    /**
1541
     * Generate a valid change log entry from the current package.xml
1542
     * @param string|false
1543
     */
1544
    function generateChangeLogEntry($notes = false)
1545
    {
1546
        return array(
1547
            'version' =>
1548
                array(
1549
                    'release' => $this->getVersion('release'),
1550
                    'api' => $this->getVersion('api'),
1551
                    ),
1552
            'stability' =>
1553
                $this->getStability(),
1554
            'date' => $this->getDate(),
1555
            'license' => $this->getLicense(true),
1556
            'notes' => $notes ? $notes : $this->getNotes()
1557
            );
1558
    }
1559
 
1560
    /**
1561
     * @param string release version to set change log notes for
1562
     * @param array output of {@link generateChangeLogEntry()}
1563
     */
1564
    function setChangelogEntry($releaseversion, $contents)
1565
    {
1566
        if (!isset($this->_packageInfo['changelog'])) {
1567
            $this->_packageInfo['changelog']['release'] = $contents;
1568
            return;
1569
        }
1570
        if (!isset($this->_packageInfo['changelog']['release'][0])) {
1571
            if ($this->_packageInfo['changelog']['release']['version']['release'] == $releaseversion) {
1572
                $this->_packageInfo['changelog']['release'] = array(
1573
                    $this->_packageInfo['changelog']['release']);
1574
            } else {
1575
                $this->_packageInfo['changelog']['release'] = array(
1576
                    $this->_packageInfo['changelog']['release']);
1577
                return $this->_packageInfo['changelog']['release'][] = $contents;
1578
            }
1579
        }
1580
        foreach($this->_packageInfo['changelog']['release'] as $index => $changelog) {
1581
            if (isset($changelog['version']) &&
1582
                  strnatcasecmp($changelog['version']['release'], $releaseversion) == 0) {
1583
                $curlog = $index;
1584
            }
1585
        }
1586
        if (isset($curlog)) {
1587
            $this->_packageInfo['changelog']['release'][$curlog] = $contents;
1588
        } else {
1589
            $this->_packageInfo['changelog']['release'][] = $contents;
1590
        }
1591
    }
1592
 
1593
    /**
1594
     * Remove the changelog entirely
1595
     */
1596
    function clearChangeLog()
1597
    {
1598
        unset($this->_packageInfo['changelog']);
1599
    }
1600
}
1601
?>