source: branches/version-2_13-dev/data/module/PEAR/PackageFile/v2/rw.php @ 23125

Revision 23125, 61.6 KB checked in by kimoto, 11 years ago (diff)

#2275 PEAR更新
不要なrequire_onceの削除
レガシーなPEARモジュールは使わない
SearchReplace?.phpのパスが間違っているので修正

Line 
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 */
19require_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 */
30class 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}
Note: See TracBrowser for help on using the repository browser.