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