3 * PEAR_PackageFile_v2, package.xml version 2.0, read/write version
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 * @link http://pear.php.net/package/PEAR
13 * @since File available since Release 1.4.0a8
18 require_once 'PEAR/PackageFile/v2.php';
22 * @author Greg Beaver <cellog@php.net>
23 * @copyright 1997-2009 The Authors
24 * @license http://opensource.org/licenses/bsd-license.php New BSD License
25 * @version Release: 1.10.1
26 * @link http://pear.php.net/package/PEAR
27 * @since Class available since Release 1.4.0a8
29 class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2
32 * @param string Extension name
33 * @return bool success of operation
35 function setProvidesExtension($extension)
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');
47 $this->_packageInfo['providesextension'] = $extension;
53 function setPackage($package)
56 if (!isset($this->_packageInfo['attribs'])) {
57 $this->_packageInfo = array_merge(array('attribs' => array(
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);
68 if (!isset($this->_packageInfo['name'])) {
69 return $this->_packageInfo = array_merge(array('name' => $package),
72 $this->_packageInfo['name'] = $package;
76 * set this as a package.xml version 2.1
79 function _setPackageVersion2_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',
91 if (!isset($this->_packageInfo['attribs'])) {
92 $this->_packageInfo = array_merge(array('attribs' => $info), $this->_packageInfo);
94 $this->_packageInfo['attribs'] = $info;
100 unset($this->_packageInfo['channel']);
102 if (!isset($this->_packageInfo['uri'])) {
103 // ensure that the uri tag is set up in the right location
104 $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
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');
112 $this->_packageInfo['uri'] = $uri;
115 function setChannel($channel)
117 unset($this->_packageInfo['uri']);
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');
129 $this->_packageInfo['channel'] = $channel;
132 function setExtends($extends)
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');
145 $this->_packageInfo['extends'] = $extends;
148 function setSummary($summary)
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');
161 $this->_packageInfo['summary'] = $summary;
164 function setDescription($desc)
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,
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');
177 $this->_packageInfo['description'] = $desc;
181 * Adds a new maintainer - no checking of duplicates is performed, use
182 * updatemaintainer for that purpose.
184 function addMaintainer($role, $handle, $name, $email, $active = 'yes')
186 if (!in_array($role, array('lead', 'developer', 'contributor', 'helper'))) {
189 if (isset($this->_packageInfo[$role])) {
190 if (!isset($this->_packageInfo[$role][0])) {
191 $this->_packageInfo[$role] = array($this->_packageInfo[$role]);
193 $this->_packageInfo[$role][] =
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) {
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,
218 $this->_packageInfo[$role] =
229 function updateMaintainer($newrole, $handle, $name, $email, $active = 'yes')
232 foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
233 if (!isset($this->_packageInfo[$role])) {
236 $info = $this->_packageInfo[$role];
237 if (!isset($info[0])) {
238 if ($info['user'] == $handle) {
243 foreach ($info as $i => $maintainer) {
244 if (is_array($maintainer) && $maintainer['user'] == $handle) {
250 if ($found === false) {
251 return $this->addMaintainer($newrole, $handle, $name, $email, $active);
253 if ($found !== false) {
254 if ($found === true) {
255 unset($this->_packageInfo[$role]);
257 unset($this->_packageInfo[$role][$found]);
258 $this->_packageInfo[$role] = array_values($this->_packageInfo[$role]);
261 $this->addMaintainer($newrole, $handle, $name, $email, $active);
265 function deleteMaintainer($handle)
268 foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
269 if (!isset($this->_packageInfo[$role])) {
272 if (!isset($this->_packageInfo[$role][0])) {
273 $this->_packageInfo[$role] = array($this->_packageInfo[$role]);
275 foreach ($this->_packageInfo[$role] as $i => $maintainer) {
276 if ($maintainer['user'] == $handle) {
281 if ($found !== false) {
282 unset($this->_packageInfo[$role][$found]);
283 if (!count($this->_packageInfo[$role]) && $role == 'lead') {
286 if (!count($this->_packageInfo[$role])) {
287 unset($this->_packageInfo[$role]);
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];
297 if (count($this->_packageInfo[$role]) == 1) {
298 $this->_packageInfo[$role] = $this->_packageInfo[$role][0];
304 function setReleaseVersion($version)
306 if (isset($this->_packageInfo['version']) &&
307 isset($this->_packageInfo['version']['release'])) {
308 unset($this->_packageInfo['version']['release']);
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')));
319 function setAPIVersion($version)
321 if (isset($this->_packageInfo['version']) &&
322 isset($this->_packageInfo['version']['api'])) {
323 unset($this->_packageInfo['version']['api']);
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'),
335 * snapshot|devel|alpha|beta|stable
337 function setReleaseStability($state)
339 if (isset($this->_packageInfo['stability']) &&
340 isset($this->_packageInfo['stability']['release'])) {
341 unset($this->_packageInfo['stability']['release']);
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')));
353 * @param devel|alpha|beta|stable
355 function setAPIStability($state)
357 if (isset($this->_packageInfo['stability']) &&
358 isset($this->_packageInfo['stability']['api'])) {
359 unset($this->_packageInfo['stability']['api']);
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'),
370 function setLicense($license, $uri = false, $filesource = false)
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');
380 if ($uri || $filesource) {
383 $attribs['uri'] = $uri;
385 $uri = true; // for test below
387 $attribs['filesource'] = $filesource;
390 $license = $uri ? array('attribs' => $attribs, '_content' => $license) : $license;
391 $this->_packageInfo['license'] = $license;
395 function setNotes($notes)
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');
406 $this->_packageInfo['notes'] = $notes;
410 * This is only used at install-time, after all serialization
412 * @param string file name
413 * @param string installed path
415 function setInstalledAs($file, $path)
418 return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
420 unset($this->_packageInfo['filelist'][$file]['installed_as']);
424 * This is only used at install-time, after all serialization
427 function installedFile($file, $atts)
429 if (isset($this->_packageInfo['filelist'][$file])) {
430 $this->_packageInfo['filelist'][$file] =
431 array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']);
433 $this->_packageInfo['filelist'][$file] = $atts['attribs'];
438 * Reset the listing of package contents
439 * @param string base installation dir for the whole package, if any
441 function clearContents($baseinstall = false)
443 $this->_filesValid = false;
445 if (!isset($this->_packageInfo['contents'])) {
446 $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
448 'dependencies', 'providesextension', 'usesrole', 'usestask',
449 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease',
450 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
451 'bundle', 'changelog'), array(), 'contents');
453 if ($this->getPackageType() != 'bundle') {
454 $this->_packageInfo['contents'] =
455 array('dir' => array('attribs' => array('name' => '/')));
457 $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'] = $baseinstall;
460 $this->_packageInfo['contents'] = array('bundledpackage' => array());
465 * @param string relative path of the bundled package.
467 function addBundledPackage($path)
469 if ($this->getPackageType() != 'bundle') {
472 $this->_filesValid = false;
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()));
483 * @param string file name
484 * @param PEAR_Task_Common a read/write task
486 function addTaskToFile($filename, $task)
488 if (!method_exists($task, 'getXml')) {
491 if (!method_exists($task, 'getName')) {
494 if (!method_exists($task, 'validate')) {
497 if (!$task->validate()) {
500 if (!isset($this->_packageInfo['contents']['dir']['file'])) {
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);
511 foreach ($files as $i => $file) {
512 if (isset($file['attribs'])) {
513 if ($file['attribs']['name'] == $filename) {
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);
525 $this->_packageInfo['contents']['dir']['file'][$i][$this->_tasksNs .
526 ':' . $task->getName()][] = $task->getXml();
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);
537 $this->_packageInfo['contents']['dir']['file'][$this->_tasksNs .
538 ':' . $task->getName()][] = $task->getXml();
548 * @param string path to the file
549 * @param string filename
550 * @param array extra attributes
552 function addFile($dir, $file, $attrs)
554 if ($this->getPackageType() == 'bundle') {
557 $this->_filesValid = false;
559 $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
560 if ($dir == '/' || $dir == '') {
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');
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']);
579 $this->_packageInfo['contents']['dir']['file'][]['attribs'] = $attrs;
581 $this->_packageInfo['contents']['dir']['file']['attribs'] = $attrs;
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
590 * @param string maximum version of specified package that this release is guaranteed to be
592 * @param string versions of specified package that this release is not compatible with
594 function addCompatiblePackage($name, $channel, $min, $max, $exclude = false)
599 'channel' => $channel,
604 $set['exclude'] = $exclude;
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')
615 * Removes the <usesrole> tag entirely
617 function resetUsesrole()
619 if (isset($this->_packageInfo['usesrole'])) {
620 unset($this->_packageInfo['usesrole']);
626 * @param string package name or uri
627 * @param string channel name if non-uri
629 function addUsesrole($role, $packageOrUri, $channel = false) {
630 $set = array('role' => $role);
632 $set['package'] = $packageOrUri;
633 $set['channel'] = $channel;
635 $set['uri'] = $packageOrUri;
638 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
639 'usesrole' => array('usestask', 'srcpackage', 'srcuri',
640 'phprelease', 'extsrcrelease', 'extbinrelease',
641 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
646 * Removes the <usestask> tag entirely
648 function resetUsestask()
650 if (isset($this->_packageInfo['usestask'])) {
651 unset($this->_packageInfo['usestask']);
658 * @param string package name or uri
659 * @param string channel name if non-uri
661 function addUsestask($task, $packageOrUri, $channel = false) {
662 $set = array('task' => $task);
664 $set['package'] = $packageOrUri;
665 $set['channel'] = $channel;
667 $set['uri'] = $packageOrUri;
670 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
671 'usestask' => array('srcpackage', 'srcuri',
672 'phprelease', 'extsrcrelease', 'extbinrelease',
673 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
678 * Remove all compatible tags
680 function clearCompatible()
682 unset($this->_packageInfo['compatible']);
686 * Reset dependencies prior to adding new ones
690 if (!isset($this->_packageInfo['dependencies'])) {
691 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(),
693 'dependencies' => array('providesextension', 'usesrole', 'usestask',
694 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
695 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')));
697 $this->_packageInfo['dependencies'] = array();
701 * @param string minimum PHP version allowed
702 * @param string maximum PHP version allowed
703 * @param array $exclude incompatible PHP versions
705 function setPhpDep($min, $max = false, $exclude = false)
716 if (count($exclude) == 1) {
717 $exclude = $exclude[0];
719 $dep['exclude'] = $exclude;
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']);
727 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
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')
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
744 function setPearinstallerDep($min, $max = false, $recommended = false, $exclude = false)
755 $dep['recommended'] = $recommended;
758 if (count($exclude) == 1) {
759 $exclude = $exclude[0];
761 $dep['exclude'] = $exclude;
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']);
769 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
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')
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
788 function addConflictingPackageDepWithChannel($name, $channel,
789 $providesextension = false, $min = false, $max = false, $exclude = false)
792 $dep = $this->_constructDep($name, $channel, false, $min, $max, false,
793 $exclude, $providesextension, false, true);
794 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
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')
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
810 function addConflictingPackageDepWithUri($name, $uri, $providesextension = false)
819 if ($providesextension) {
820 $dep['providesextension'] = $providesextension;
822 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
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')
832 function addDependencyGroup($name, $hint)
835 $this->_packageInfo = $this->_mergeTag($this->_packageInfo,
836 array('attribs' => array('name' => $name, 'hint' => $hint)),
838 'dependencies' => array('providesextension', 'usesrole', 'usestask',
839 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
840 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
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)
860 function _constructDep($name, $channel, $uri, $min, $max, $recommended, $exclude,
861 $providesextension = false, $nodefault = false,
869 $dep['channel'] = $channel;
880 $dep['recommended'] = $recommended;
883 if (is_array($exclude) && count($exclude) == 1) {
884 $exclude = $exclude[0];
886 $dep['exclude'] = $exclude;
889 $dep['conflicts'] = '';
892 $dep['nodefault'] = '';
894 if ($providesextension) {
895 $dep['providesextension'] = $providesextension;
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
916 function addGroupPackageDepWithChannel($type, $groupname, $name, $channel, $min = false,
917 $max = false, $recommended = false, $exclude = false,
918 $providesextension = false, $nodefault = false)
920 if ($type == 'subpackage' && $providesextension) {
921 return false; // subpackages must be php packages
923 $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
924 $providesextension, $nodefault);
925 return $this->_addGroupDependency($type, $dep, $groupname);
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()}
939 function addGroupPackageDepWithURI($type, $groupname, $name, $uri, $providesextension = false,
942 if ($type == 'subpackage' && $providesextension) {
943 return false; // subpackages must be php packages
945 $dep = $this->_constructDep($name, false, $uri, false, false, false, false,
946 $providesextension, $nodefault);
947 return $this->_addGroupDependency($type, $dep, $groupname);
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
958 function addGroupExtensionDep($groupname, $name, $min = false, $max = false,
959 $recommended = false, $exclude = false)
962 $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
963 return $this->_addGroupDependency('extension', $dep, $groupname);
967 * @param package|subpackage|extension
968 * @param array dependency contents
969 * @param string name of the dependency group to add this to
973 function _addGroupDependency($type, $dep, $groupname)
975 $arr = array('subpackage', 'extension');
976 if ($type != 'package') {
979 if ($type == 'extension') {
982 if (!isset($this->_packageInfo['dependencies']['group'])) {
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,
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,
1005 $this->_isValid = 0;
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
1026 function addPackageDepWithChannel($type, $name, $channel, $min = false, $max = false,
1027 $recommended = false, $exclude = false,
1028 $providesextension = false, $nodefault = false)
1030 if (!in_array($type, array('optional', 'required'), true)) {
1033 $this->_isValid = 0;
1034 $arr = array('optional', 'group');
1035 if ($type != 'required') {
1038 $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
1039 $providesextension, $nodefault);
1040 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1042 'dependencies' => array('providesextension', 'usesrole', 'usestask',
1043 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1044 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1046 'package' => array('subpackage', 'extension', 'os', 'arch')
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
1058 function addPackageDepWithUri($type, $name, $uri, $providesextension = false,
1061 $this->_isValid = 0;
1062 $arr = array('optional', 'group');
1063 if ($type != 'required') {
1066 $dep = $this->_constructDep($name, false, $uri, false, false, false, false,
1067 $providesextension, $nodefault);
1068 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1070 'dependencies' => array('providesextension', 'usesrole', 'usestask',
1071 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1072 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1074 'package' => array('subpackage', 'extension', 'os', 'arch')
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
1089 function addSubpackageDepWithChannel($type, $name, $channel, $min = false, $max = false,
1090 $recommended = false, $exclude = false,
1093 $this->_isValid = 0;
1094 $arr = array('optional', 'group');
1095 if ($type != 'required') {
1098 $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
1100 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1102 'dependencies' => array('providesextension', 'usesrole', 'usestask',
1103 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1104 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1106 'subpackage' => array('extension', 'os', 'arch')
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
1117 function addSubpackageDepWithUri($type, $name, $uri, $nodefault = false)
1119 $this->_isValid = 0;
1120 $arr = array('optional', 'group');
1121 if ($type != 'required') {
1124 $dep = $this->_constructDep($name, false, $uri, false, false, false, false, $nodefault);
1125 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1127 'dependencies' => array('providesextension', 'usesrole', 'usestask',
1128 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1129 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1131 'subpackage' => array('extension', 'os', 'arch')
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
1143 function addExtensionDep($type, $name, $min = false, $max = false, $recommended = false,
1146 $this->_isValid = 0;
1147 $arr = array('optional', 'group');
1148 if ($type != 'required') {
1151 $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
1152 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1154 'dependencies' => array('providesextension', 'usesrole', 'usestask',
1155 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1156 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1158 'extension' => array('os', 'arch')
1163 * @param string Operating system name
1164 * @param boolean true if this package cannot be installed on this OS
1166 function addOsDep($name, $conflicts = false)
1168 $this->_isValid = 0;
1169 $dep = array('name' => $name);
1171 $dep['conflicts'] = '';
1173 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
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')
1184 * @param string Architecture matching pattern
1185 * @param boolean true if this package cannot be installed on this architecture
1187 function addArchDep($pattern, $conflicts = false)
1189 $this->_isValid = 0;
1190 $dep = array('pattern' => $pattern);
1192 $dep['conflicts'] = '';
1194 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
1196 'dependencies' => array('providesextension', 'usesrole', 'usestask',
1197 'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
1198 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
1199 'required' => array('optional', 'group'),
1205 * Set the kind of package, and erase all release tags
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
1216 function setPackageType($type)
1218 $this->_isValid = 0;
1219 if (!in_array($type, array('php', 'extbin', 'extsrc', 'zendextsrc',
1220 'zendextbin', 'bundle'))) {
1224 if (in_array($type, array('zendextsrc', 'zendextbin'))) {
1225 $this->_setPackageVersion2_1();
1228 if ($type != 'bundle') {
1232 foreach (array('phprelease', 'extbinrelease', 'extsrcrelease',
1233 'zendextsrcrelease', 'zendextbinrelease', 'bundle') as $test) {
1234 unset($this->_packageInfo[$test]);
1237 if (!isset($this->_packageInfo[$type])) {
1238 // ensure that the release tag is set up
1239 $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('changelog'),
1243 $this->_packageInfo[$type] = array();
1248 * @return bool true if package type is set up
1250 function addRelease()
1252 if ($type = $this->getPackageType()) {
1253 if ($type != 'bundle') {
1256 $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(),
1257 array($type => array('changelog')));
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
1268 function &_getCurrentRelease($strict = true)
1270 if ($p = $this->getPackageType()) {
1272 if ($p == 'extsrc' || $p == 'zendextsrc') {
1277 if ($p != 'bundle') {
1280 if (isset($this->_packageInfo[$p][0])) {
1281 return $this->_packageInfo[$p][count($this->_packageInfo[$p]) - 1];
1283 return $this->_packageInfo[$p];
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
1296 function addInstallAs($path, $as)
1298 $r = &$this->_getCurrentRelease();
1302 $this->_isValid = 0;
1303 $r = $this->_mergeTag($r, array('attribs' => array('name' => $path, 'as' => $as)),
1305 'filelist' => array(),
1306 'install' => array('ignore')
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
1315 function addIgnore($path)
1317 $r = &$this->_getCurrentRelease();
1321 $this->_isValid = 0;
1322 $r = $this->_mergeTag($r, array('attribs' => array('name' => $path)),
1324 'filelist' => array(),
1330 * Add an extension binary package for this extension source code release
1332 * Note that the package must be from the same channel as the extension source package
1335 function addBinarypackage($package)
1337 if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
1340 $r = &$this->_getCurrentRelease(false);
1344 $this->_isValid = 0;
1345 $r = $this->_mergeTag($r, $package,
1347 'binarypackage' => array('filelist'),
1352 * Add a configureoption to an extension source package
1357 function addConfigureOption($name, $prompt, $default = null)
1359 if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
1363 $r = &$this->_getCurrentRelease(false);
1368 $opt = array('attribs' => array('name' => $name, 'prompt' => $prompt));
1369 if ($default !== null) {
1370 $opt['attribs']['default'] = $default;
1373 $this->_isValid = 0;
1374 $r = $this->_mergeTag($r, $opt,
1376 'configureoption' => array('binarypackage', 'filelist'),
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
1386 function setPhpInstallCondition($min, $max, $exclude = false)
1388 $r = &$this->_getCurrentRelease();
1392 $this->_isValid = 0;
1393 if (isset($r['installconditions']['php'])) {
1394 unset($r['installconditions']['php']);
1396 $dep = array('min' => $min, 'max' => $max);
1398 if (is_array($exclude) && count($exclude) == 1) {
1399 $exclude = $exclude[0];
1401 $dep['exclude'] = $exclude;
1403 if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
1404 $r = $this->_mergeTag($r, $dep,
1406 'installconditions' => array('configureoption', 'binarypackage',
1408 'php' => array('extension', 'os', 'arch')
1411 $r = $this->_mergeTag($r, $dep,
1413 'installconditions' => array('filelist'),
1414 'php' => array('extension', 'os', 'arch')
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
1427 function addExtensionInstallCondition($name, $min = false, $max = false, $recommended = false,
1430 $r = &$this->_getCurrentRelease();
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,
1439 'installconditions' => array('configureoption', 'binarypackage',
1441 'extension' => array('os', 'arch')
1444 $r = $this->_mergeTag($r, $dep,
1446 'installconditions' => array('filelist'),
1447 'extension' => array('os', 'arch')
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
1457 function setOsInstallCondition($name, $conflicts = false)
1459 $r = &$this->_getCurrentRelease();
1463 $this->_isValid = 0;
1464 if (isset($r['installconditions']['os'])) {
1465 unset($r['installconditions']['os']);
1467 $dep = array('name' => $name);
1469 $dep['conflicts'] = '';
1471 if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
1472 $r = $this->_mergeTag($r, $dep,
1474 'installconditions' => array('configureoption', 'binarypackage',
1476 'os' => array('arch')
1479 $r = $this->_mergeTag($r, $dep,
1481 'installconditions' => array('filelist'),
1482 'os' => array('arch')
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
1492 function setArchInstallCondition($pattern, $conflicts = false)
1494 $r = &$this->_getCurrentRelease();
1498 $this->_isValid = 0;
1499 if (isset($r['installconditions']['arch'])) {
1500 unset($r['installconditions']['arch']);
1502 $dep = array('pattern' => $pattern);
1504 $dep['conflicts'] = '';
1506 if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
1507 $r = $this->_mergeTag($r, $dep,
1509 'installconditions' => array('configureoption', 'binarypackage',
1514 $r = $this->_mergeTag($r, $dep,
1516 'installconditions' => array('filelist'),
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)
1528 function setSourcePackage($packageOrUri)
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');
1537 $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease',
1538 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
1539 'bundle', 'changelog'), $packageOrUri, 'srcuri');
1544 * Generate a valid change log entry from the current package.xml
1545 * @param string|false
1547 function generateChangeLogEntry($notes = false)
1552 'release' => $this->getVersion('release'),
1553 'api' => $this->getVersion('api'),
1556 $this->getStability(),
1557 'date' => $this->getDate(),
1558 'license' => $this->getLicense(true),
1559 'notes' => $notes ? $notes : $this->getNotes()
1564 * @param string release version to set change log notes for
1565 * @param array output of {@link generateChangeLogEntry()}
1567 function setChangelogEntry($releaseversion, $contents)
1569 if (!isset($this->_packageInfo['changelog'])) {
1570 $this->_packageInfo['changelog']['release'] = $contents;
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']);
1578 $this->_packageInfo['changelog']['release'] = array(
1579 $this->_packageInfo['changelog']['release']);
1580 return $this->_packageInfo['changelog']['release'][] = $contents;
1583 foreach($this->_packageInfo['changelog']['release'] as $index => $changelog) {
1584 if (isset($changelog['version']) &&
1585 strnatcasecmp($changelog['version']['release'], $releaseversion) == 0) {
1589 if (isset($curlog)) {
1590 $this->_packageInfo['changelog']['release'][$curlog] = $contents;
1592 $this->_packageInfo['changelog']['release'][] = $contents;
1597 * Remove the changelog entirely
1599 function clearChangeLog()
1601 unset($this->_packageInfo['changelog']);