Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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