PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/pear/php/PEAR/PackageFileManager.php

https://github.com/wrobel/horde-glue
PHP | 1761 lines | 1187 code | 31 blank | 543 comment | 123 complexity | 8ec9e86672da6ac49d3c7a637886b2a6 MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * PEAR_PackageFileManager is designed to create and manipulate
  4. * package.xml version 1.0 only.
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * @category PEAR
  9. * @package PEAR_PackageFileManager
  10. * @author Greg Beaver <cellog@php.net>
  11. * @copyright 2003-2009 The PEAR Group
  12. * @license New BSD, Revised
  13. * @version CVS: $Id: PackageFileManager.php,v 1.68 2008/12/29 04:57:55 dufuz Exp $
  14. * @link http://pear.php.net/package/PEAR_PackageFileManager
  15. * @since File available since Release 0.1
  16. */
  17. /**
  18. * PEAR installer
  19. */
  20. require_once 'PEAR/Common.php';
  21. /**#@+
  22. * Error Codes
  23. */
  24. define('PEAR_PACKAGEFILEMANAGER_NOSTATE', 1);
  25. define('PEAR_PACKAGEFILEMANAGER_NOVERSION', 2);
  26. define('PEAR_PACKAGEFILEMANAGER_NOPKGDIR', 3);
  27. define('PEAR_PACKAGEFILEMANAGER_NOBASEDIR', 4);
  28. define('PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND', 5);
  29. define('PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE', 6);
  30. define('PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE', 7);
  31. define('PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE', 8);
  32. define('PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE', 9);
  33. define('PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE', 10);
  34. define('PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST', 11);
  35. define('PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS', 14);
  36. define('PEAR_PACKAGEFILEMANAGER_NOPACKAGE', 15);
  37. define('PEAR_PACKAGEFILEMANAGER_WRONG_MROLE', 16);
  38. define('PEAR_PACKAGEFILEMANAGER_NOSUMMARY', 17);
  39. define('PEAR_PACKAGEFILEMANAGER_NODESC', 18);
  40. define('PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS', 19);
  41. define('PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE', 22);
  42. define('PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE', 23);
  43. define('PEAR_PACKAGEFILEMANAGER_INVALID_ROLE', 24);
  44. define('PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE', 25);
  45. define('PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED', 26);
  46. define('PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO', 27);
  47. define('PEAR_PACKAGEFILEMANAGER_NONOTES', 28);
  48. define('PEAR_PACKAGEFILEMANAGER_NOLICENSE', 29);
  49. /**#@-*/
  50. /**
  51. * Error messages
  52. * @global array $GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS']
  53. */
  54. $GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'] =
  55. array(
  56. 'en' =>
  57. array(
  58. PEAR_PACKAGEFILEMANAGER_NOSTATE =>
  59. 'Release State (option \'state\') must by specified in PEAR_PackageFileManager ' .
  60. 'setOptions (snapshot|devel|alpha|beta|stable)',
  61. PEAR_PACKAGEFILEMANAGER_NOVERSION =>
  62. 'Release Version (option \'version\') must be specified in PEAR_PackageFileManager setOptions',
  63. PEAR_PACKAGEFILEMANAGER_NOPKGDIR =>
  64. 'Package source base directory (option \'packagedirectory\') must be ' .
  65. 'specified in PEAR_PackageFileManager setOptions',
  66. PEAR_PACKAGEFILEMANAGER_NOBASEDIR =>
  67. 'Package install base directory (option \'baseinstalldir\') must be ' .
  68. 'specified in PEAR_PackageFileManager setOptions',
  69. PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND =>
  70. 'Base class "%s" can\'t be located',
  71. PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE =>
  72. 'Base class "%s" can\'t be located in default or user-specified directories',
  73. PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE =>
  74. 'Failed to write package.xml file to destination directory',
  75. PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE =>
  76. 'Destination directory "%s" is unwritable',
  77. PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE =>
  78. 'Failed to copy package.xml.tmp file to package.xml',
  79. PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE =>
  80. 'Failed to open temporary file "%s" for writing',
  81. PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST =>
  82. 'package.xml file path "%s" doesn\'t exist or isn\'t a directory',
  83. PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS =>
  84. 'Run $managerclass->setOptions() before any other methods',
  85. PEAR_PACKAGEFILEMANAGER_NOPACKAGE =>
  86. 'Package Name (option \'package\') must by specified in PEAR_PackageFileManager '.
  87. 'setOptions to create a new package.xml',
  88. PEAR_PACKAGEFILEMANAGER_NOSUMMARY =>
  89. 'Package Summary (option \'summary\') must by specified in PEAR_PackageFileManager' .
  90. ' setOptions to create a new package.xml',
  91. PEAR_PACKAGEFILEMANAGER_NODESC =>
  92. 'Detailed Package Description (option \'description\') must be' .
  93. ' specified in PEAR_PackageFileManager setOptions to create a new package.xml',
  94. PEAR_PACKAGEFILEMANAGER_WRONG_MROLE =>
  95. 'Maintainer role must be one of "%s", was "%s"',
  96. PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS =>
  97. 'Add maintainers to a package before generating the package.xml',
  98. PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE =>
  99. 'Package validation failed:%s%s',
  100. PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE =>
  101. 'Replacement Type must be one of "%s", was passed "%s"',
  102. PEAR_PACKAGEFILEMANAGER_INVALID_ROLE =>
  103. 'Invalid file role passed to addRole, must be one of "%s", was passed "%s"',
  104. PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE =>
  105. 'addDependency had PHP as a package, use type="php"',
  106. PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED =>
  107. 'path "%path%" contains CVS directory',
  108. PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO =>
  109. 'PHP_Compat is not installed, cannot detect dependencies',
  110. PEAR_PACKAGEFILEMANAGER_NONOTES =>
  111. 'Release Notes (option \'notes\') must be specified in PEAR_PackageFileManager setOptions',
  112. PEAR_PACKAGEFILEMANAGER_NOLICENSE =>
  113. 'Release License (option \'license\') must be specified in PEAR_PackageFileManager setOptions',
  114. ),
  115. // other language translations go here
  116. );
  117. /**
  118. * PEAR :: PackageFileManager updates the <filelist></filelist> section
  119. * of a PEAR package.xml file to reflect the current files in
  120. * preparation for a release.
  121. *
  122. * The PEAR_PackageFileManager class uses a plugin system to generate the
  123. * list of files in a package. This allows both standard recursive
  124. * directory parsing (plugin type file) and more intelligent options
  125. * such as the CVS browser {@link PEAR_PackageFileManager_Cvs}, which
  126. * grabs all files in a local CVS checkout to create the list, ignoring
  127. * any other local files.
  128. *
  129. * Other options include specifying roles for file extensions (all .php
  130. * files are role="php", for example), roles for directories (all directories
  131. * named "tests" are given role="tests" by default), and exceptions.
  132. * Exceptions are specific pathnames with * and ? wildcards that match
  133. * a default role, but should have another. For example, perhaps
  134. * a debug.tpl template would normally be data, but should be included
  135. * in the docs role. Along these lines, to exclude files entirely,
  136. * use the ignore option.
  137. *
  138. * Required options for a release include version, baseinstalldir, state,
  139. * and packagedirectory (the full path to the local location of the
  140. * package to create a package.xml file for)
  141. *
  142. * Example usage:
  143. * <code>
  144. * <?php
  145. * require_once('PEAR/PackageFileManager.php');
  146. * $packagexml = new PEAR_PackageFileManager;
  147. * $e = $packagexml->setOptions(
  148. * array('baseinstalldir' => 'PhpDocumentor',
  149. * 'version' => '1.2.1',
  150. * 'packagedirectory' => 'C:/Web Pages/chiara/phpdoc2/',
  151. * 'state' => 'stable',
  152. * 'filelistgenerator' => 'cvs', // generate from cvs, use file for directory
  153. * 'notes' => 'We\'ve implemented many new and exciting features',
  154. * 'ignore' => array('TODO', 'tests/'), // ignore TODO, all files in tests/
  155. * 'installexceptions' => array('phpdoc' => '/*'), // baseinstalldir ="/" for phpdoc
  156. * 'dir_roles' => array('tutorials' => 'doc'),
  157. * 'exceptions' => array('README' => 'doc', // README would be data, now is doc
  158. * 'PHPLICENSE.txt' => 'doc'))); // same for the license
  159. * if (PEAR::isError($e)) {
  160. * echo $e->getMessage();
  161. * die();
  162. * }
  163. * $e = $test->addPlatformException('pear-phpdoc.bat', 'windows');
  164. * if (PEAR::isError($e)) {
  165. * echo $e->getMessage();
  166. * exit;
  167. * }
  168. * $packagexml->addRole('pkg', 'doc'); // add a new role mapping
  169. * if (PEAR::isError($e)) {
  170. * echo $e->getMessage();
  171. * exit;
  172. * }
  173. * // replace @PHP-BIN@ in this file with the path to php executable! pretty neat
  174. * $e = $test->addReplacement('pear-phpdoc', 'pear-config', '@PHP-BIN@', 'php_bin');
  175. * if (PEAR::isError($e)) {
  176. * echo $e->getMessage();
  177. * exit;
  178. * }
  179. * $e = $test->addReplacement('pear-phpdoc.bat', 'pear-config', '@PHP-BIN@', 'php_bin');
  180. * if (PEAR::isError($e)) {
  181. * echo $e->getMessage();
  182. * exit;
  183. * }
  184. * // note use of {@link debugPackageFile()} - this is VERY important
  185. * if (isset($_GET['make']) || (isset($_SERVER['argv'][2]) &&
  186. * $_SERVER['argv'][2] == 'make')) {
  187. * $e = $packagexml->writePackageFile();
  188. * } else {
  189. * $e = $packagexml->debugPackageFile();
  190. * }
  191. * if (PEAR::isError($e)) {
  192. * echo $e->getMessage();
  193. * die();
  194. * }
  195. * ?>
  196. * </code>
  197. *
  198. * In addition, a package.xml file can now be generated from
  199. * scratch, with the usage of new options package, summary, description, and
  200. * the use of the {@link addMaintainer()} method
  201. *
  202. * @category PEAR
  203. * @package PEAR_PackageFileManager
  204. * @author Greg Beaver <cellog@php.net>
  205. * @copyright 2003-2009 The PEAR Group
  206. * @license New BSD, Revised
  207. * @version Release: 1.7.0
  208. * @link http://pear.php.net/package/PEAR_PackageFileManager
  209. * @since Class available since Release 0.1
  210. */
  211. class PEAR_PackageFileManager
  212. {
  213. /**
  214. * Format: array(array(regexp-ready string to search for whole path,
  215. * regexp-ready string to search for basename of ignore strings),...)
  216. * @var false|array
  217. * @access private
  218. * @since 0.1
  219. */
  220. var $_ignore = false;
  221. /**
  222. * Contents of the package.xml file
  223. * @var string
  224. * @access private
  225. * @since 0.1
  226. */
  227. var $_packageXml = false;
  228. /**
  229. * Contents of the original package.xml file, if any
  230. * @var string
  231. * @access private
  232. * @since 0.9
  233. */
  234. var $_oldPackageXml = false;
  235. /**
  236. * @access private
  237. * @var PEAR_Common
  238. * @since 0.9
  239. */
  240. var $_pear;
  241. /**
  242. * List of warnings
  243. * @var array
  244. * @access private
  245. * @since 1.1.0
  246. */
  247. var $_warningStack = array();
  248. /**
  249. * flag used to determine whether to use PHP_CompatInfo to detect deps
  250. * @var boolean
  251. * @access private
  252. * @since 1.3.0
  253. */
  254. var $_detectDependencies = false;
  255. /**
  256. * @access private
  257. * @var string
  258. * @since 0.1
  259. */
  260. var $_options = array(
  261. 'packagefile' => 'package.xml',
  262. 'doctype' => 'http://pear.php.net/dtd/package-1.0',
  263. 'filelistgenerator' => 'file',
  264. 'license' => 'New BSD License',
  265. 'changelogoldtonew' => true,
  266. 'roles' =>
  267. array(
  268. 'h' => 'src',
  269. 'c' => 'src',
  270. 'cpp' => 'src',
  271. 'm4' => 'src',
  272. 'w32' => 'src',
  273. 'dll' => 'ext',
  274. 'php' => 'php',
  275. 'html' => 'doc',
  276. '*' => 'data',
  277. ),
  278. 'dir_roles' =>
  279. array(
  280. 'docs' => 'doc',
  281. 'examples' => 'doc',
  282. 'tests' => 'test',
  283. ),
  284. 'exceptions' => array(),
  285. 'installexceptions' => array(),
  286. 'installas' => array(),
  287. 'platformexceptions' => array(),
  288. 'scriptphaseexceptions' => array(),
  289. 'ignore' => array(),
  290. 'include' => false,
  291. 'deps' => false,
  292. 'maintainers' => false,
  293. 'notes' => '',
  294. 'changelognotes' => false,
  295. 'outputdirectory' => false,
  296. 'pathtopackagefile' => false,
  297. 'lang' => 'en',
  298. 'configure_options' => array(),
  299. 'replacements' => array(),
  300. 'pearcommonclass' => false,
  301. 'simpleoutput' => false,
  302. 'addhiddenfiles' => false,
  303. 'cleardependencies' => false,
  304. );
  305. /**
  306. * Does nothing, use setOptions
  307. *
  308. * The constructor is not used in order to be able to
  309. * return a PEAR_Error from setOptions
  310. *
  311. * @see setOptions()
  312. * @access public
  313. * @since 0.1
  314. */
  315. function PEAR_PackageFileManager()
  316. {
  317. }
  318. /**
  319. * Set package.xml generation options
  320. *
  321. * The options array is indexed as follows:
  322. * <code>
  323. * $options = array('option_name' => <optionvalue>);
  324. * </code>
  325. *
  326. * The documentation below simplifies this description through
  327. * the use of option_name without quotes
  328. *
  329. * Configuration options:
  330. * - lang: lang controls the language in which error messages are
  331. * displayed. There are currently only English error messages,
  332. * but any contributed will be added over time.<br>
  333. * Possible values: en (default)
  334. * - packagefile: the name of the packagefile, defaults to package.xml
  335. * - pathtopackagefile: the path to an existing package file to read in,
  336. * if different from the packagedirectory
  337. * - packagedirectory: the path to the base directory of the package. For
  338. * package PEAR_PackageFileManager, this path is
  339. * /path/to/pearcvs/pear/PEAR_PackageFileManager where
  340. * /path/to/pearcvs is a local path on your hard drive
  341. * - outputdirectory: the path in which to place the generated package.xml
  342. * by default, this is ignored, and the package.xml is
  343. * created in the packagedirectory
  344. * - filelistgenerator: the <filelist> section plugin which will be used.
  345. * In this release, there are two generator plugins,
  346. * file and cvs. For details, see the docs for these
  347. * plugins
  348. * - usergeneratordir: For advanced users. If you write your own filelist
  349. * generator plugin, use this option to tell
  350. * PEAR_PackageFileManager where to find the file that
  351. * contains it. If the plugin is named foo, the class
  352. * must be named PEAR_PackageFileManager_Foo
  353. * no matter where it is located. By default, the Foo
  354. * plugin is located in PEAR/PackageFileManager/Foo.php.
  355. * If you pass /path/to/foo in this option, setOptions
  356. * will look for PEAR_PackageFileManager_Foo in
  357. * /path/to/foo/Foo.php
  358. * - doctype: Specifies the DTD of the package.xml file. Default is
  359. * http://pear.php.net/dtd/package-1.0
  360. * - pearcommonclass: Specifies the name of the class to instantiate, default
  361. * is PEAR_PackageFileManager_ComplexGenerator or PEAR_Common, but users can
  362. * override this with a custom class that implements
  363. * PEAR_Common's method interface
  364. * - changelogoldtonew: True if the ChangeLog should list from oldest entry to
  365. * newest. Set to false if you would like new entries first
  366. * - simpleoutput: True if the package.xml should not contain md5sum or <provides />
  367. * for readability
  368. * - addhiddenfiles: True if you wish to add hidden files/directories that begin with .
  369. * like .bashrc. This is only used by the File generator. The CVS
  370. * generator will use all files in CVS regardless of format
  371. *
  372. * package.xml simple options:
  373. * - baseinstalldir: The base directory to install this package in. For
  374. * package PEAR_PackageFileManager, this is "PEAR", for
  375. * package PEAR, this is "/"
  376. * - license: The license this release is released under. Default is
  377. * PHP License if left unspecified
  378. * - notes: Release notes, any text describing what makes this release unique
  379. * - changelognotes: notes for the changelog, this should be more detailed than
  380. * the release notes. By default, PEAR_PackageFileManager uses
  381. * the notes option for the changelog as well
  382. * - version: The version number for this release. Remember the convention for
  383. * numbering: initial alpha is between 0 and 1, add b<beta number> for
  384. * beta as in 1.0b1, the integer portion of the version should specify
  385. * backwards compatibility, as in 1.1 is backwards compatible with 1.0,
  386. * but 2.0 is not backwards compatible with 1.10. Also note that 1.10
  387. * is a greater release version than 1.1 (think of it as "one point ten"
  388. * and "one point one"). Bugfix releases should be a third decimal as in
  389. * 1.0.1, 1.0.2
  390. * - package: [optional] Package name. Use this to create a new package.xml, or
  391. * overwrite an existing one from another package used as a template
  392. * - summary: [optional] Summary of package purpose
  393. * - description: [optional] Description of package purpose. Note that the above
  394. * three options are not optional when creating a new package.xml
  395. * from scratch
  396. *
  397. * <b>WARNING</b>: all complex options that require a file path are case-sensitive
  398. *
  399. * package.xml complex options:
  400. * - cleardependencies: since version 1.3.0, this option will erase any existing
  401. * dependencies in the package.xml if set to true
  402. * - ignore: an array of filenames, directory names, or wildcard expressions specifying
  403. * files to exclude entirely from the package.xml. Wildcards are operating system
  404. * wildcards * and ?. file*foo.php will exclude filefoo.php, fileabrfoo.php and
  405. * filewho_is_thisfoo.php. file?foo.php will exclude fileafoo.php and will not
  406. * exclude fileaafoo.php. test/ will exclude all directories and subdirectories of
  407. * ANY directory named test encountered in directory parsing. *test* will exclude
  408. * all files and directories that contain test in their name
  409. * - include: an array of filenames, directory names, or wildcard expressions specifying
  410. * files to include in the listing. All other files will be ignored.
  411. * Wildcards are in the same format as ignore
  412. * - roles: this is an array mapping file extension to install role. This
  413. * specifies default behavior that can be overridden by the exceptions
  414. * option and dir_roles option. use {@link addRole()} to add a new
  415. * role to the pre-existing array
  416. * - dir_roles: this is an array mapping directory name to install role. All
  417. * files in a directory whose name matches the directory will be
  418. * given the install role specified. Single files can be excluded
  419. * from this using the exceptions option. The directory should be
  420. * a relative path from the baseinstalldir, or "/" for the baseinstalldir
  421. * - exceptions: specify file role for specific files. This array maps all files
  422. * matching the exact name of a file to a role as in "file.ext" => "role"
  423. * - deps: dependency array. Pass in an empty array to clear all dependencies, and use
  424. * {@link addDependency()} to add new ones/replace existing ones
  425. * - maintainers: maintainers array. Pass in an empty array to clear all maintainers, and
  426. * use {@link addMaintainer()} to add a new maintainer/replace existing maintainer
  427. * - installexceptions: array mapping of specific filenames to baseinstalldir values. Use
  428. * this to force the installation of a file into another directory,
  429. * such as forcing a script to be in the root scripts directory so that
  430. * it will be in the path. The filename must be a relative path to the
  431. * packagedirectory
  432. * - platformexceptions: array mapping of specific filenames to the platform they should be
  433. * installed on. Use this to specify unix-only files or windows-only
  434. * files. The format of the platform string must be
  435. * OS-version-cpu-extra if any more specific information is needed,
  436. * and the OS must be in lower case as in "windows." The match is
  437. * performed using a regular expression, but uses * and ? wildcards
  438. * instead of .* and .?. Note that hpux/aix/irix/linux are all
  439. * exclusive. To select non-windows, use (*ix|*ux)
  440. * - scriptphaseexceptions: array mapping of scripts to their install phase. This can be
  441. * one of: pre-install, post-install, pre-uninstall, post-uninstall,
  442. * pre-build, post-build, pre-setup, or post-setup
  443. * - installas: array mapping of specific filenames to the filename they should be installed as.
  444. * Use this to specify new filenames for files that should be installed. This will
  445. * often be used in conjunction with platformexceptions if there are two files for
  446. * different OSes that must have the same name when installed.
  447. * - replacements: array mapping of specific filenames to complex text search-and-replace that
  448. * should be performed upon install. The format is:
  449. * <pre>
  450. * filename => array('type' => php-const|pear-config|package-info
  451. * 'from' => text in file
  452. * 'to' => name of variable)
  453. * </pre>
  454. * if type is php-const, then 'to' must be the name of a PHP Constant.
  455. * If type is pear-config, then 'to' must be the name of a PEAR config
  456. * variable accessible through a PEAR_Config class->get() method. If
  457. * type is package-info, then 'to' must be the name of a section from
  458. * the package.xml file used to install this file.
  459. * - globalreplacements: a list of replacements that should be performed on every single file.
  460. * The format is the same as replacements (since 1.4.0)
  461. * - configure_options: array specifies build options for PECL packages (you should probably
  462. * use PECL_Gen instead, but it's here for completeness)
  463. *
  464. * @param array $options (optional) list of generation options
  465. * @param boolean $internal (optional) private function call
  466. *
  467. * @see PEAR_PackageFileManager_File
  468. * @see PEAR_PackageFileManager_CVS
  469. * @return void|PEAR_Error
  470. * @throws PEAR_PACKAGEFILEMANAGER_NOSTATE
  471. * @throws PEAR_PACKAGEFILEMANAGER_NOVERSION
  472. * @throws PEAR_PACKAGEFILEMANAGER_NOPKGDIR
  473. * @throws PEAR_PACKAGEFILEMANAGER_NOBASEDIR
  474. * @throws PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE
  475. * @throws PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND
  476. * @access public
  477. * @since 0.1
  478. */
  479. function setOptions($options = array(), $internal = false)
  480. {
  481. if (!$internal) {
  482. if (!isset($options['state']) || empty($options['state'])) {
  483. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOSTATE);
  484. }
  485. if (!isset($options['version']) || empty($options['version'])) {
  486. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOVERSION);
  487. }
  488. }
  489. if (!isset($options['packagedirectory']) && !$internal) {
  490. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOPKGDIR);
  491. } elseif (isset($options['packagedirectory'])
  492. && is_string($options['packagedirectory']) ) {
  493. $options['packagedirectory'] = str_replace(DIRECTORY_SEPARATOR,
  494. '/',
  495. realpath($options['packagedirectory']));
  496. if ($options['packagedirectory']{strlen($options['packagedirectory']) - 1} != '/') {
  497. $options['packagedirectory'] .= '/';
  498. }
  499. }
  500. if (isset($options['pathtopackagefile'])
  501. && is_string($options['pathtopackagefile'])) {
  502. $options['pathtopackagefile'] = str_replace(DIRECTORY_SEPARATOR,
  503. '/',
  504. realpath($options['pathtopackagefile']));
  505. if ($options['pathtopackagefile']{strlen($options['pathtopackagefile']) - 1} != '/') {
  506. $options['pathtopackagefile'] .= '/';
  507. }
  508. }
  509. if (!isset($options['baseinstalldir']) && !$internal) {
  510. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOBASEDIR);
  511. }
  512. $this->_options = array_merge($this->_options, $options);
  513. if (!isset($this->_options['roles']['*'])) {
  514. $this->_options['roles']['*'] = 'data';
  515. }
  516. if (!class_exists($this->_options['pearcommonclass'])) {
  517. if ($this->_options['simpleoutput']) {
  518. if ($this->isIncludeable('PEAR/PackageFile/Generator/v1.php')) {
  519. include_once 'PEAR/PackageFileManager/SimpleGenerator.php';
  520. $this->_options['pearcommonclass'] = 'PEAR_PackageFileManager_SimpleGenerator';
  521. } else {
  522. include_once 'PEAR/PackageFileManager/XMLOutput.php';
  523. $this->_options['pearcommonclass'] = 'PEAR_PackageFileManager_XMLOutput';
  524. }
  525. } else {
  526. if ($this->isIncludeable('PEAR/PackageFile/Generator/v1.php')) {
  527. include_once 'PEAR/PackageFileManager/ComplexGenerator.php';
  528. $this->_options['pearcommonclass'] = 'PEAR_PackageFileManager_ComplexGenerator';
  529. } else {
  530. $this->_options['pearcommonclass'] = 'PEAR_Common';
  531. }
  532. }
  533. }
  534. $this->_options['filelistgenerator'] =
  535. ucfirst(strtolower($this->_options['filelistgenerator']));
  536. if (!$internal) {
  537. $path = (is_dir($this->_options['pathtopackagefile']) ?
  538. $this->_options['pathtopackagefile'] :
  539. $this->_options['packagedirectory']);
  540. if (PEAR::isError($res =
  541. $this->_getExistingPackageXML($path, $this->_options['packagefile']))) {
  542. return $res;
  543. }
  544. }
  545. // file generator resource to load
  546. $resource = 'PEAR/PackageFileManager/' . $this->_options['filelistgenerator'] . '.php';
  547. // file generator class name
  548. $className = substr($resource, 0, -4);
  549. $className = str_replace('/', '_', $className);
  550. if (!class_exists($className)) {
  551. // attempt to load the interface from the standard PEAR location
  552. if ($this->isIncludeable($resource)) {
  553. include_once $resource;
  554. } elseif (isset($this->_options['usergeneratordir'])) {
  555. // attempt to load from a user-specified directory
  556. if (is_dir(realpath($this->_options['usergeneratordir']))) {
  557. $this->_options['usergeneratordir'] =
  558. str_replace(DIRECTORY_SEPARATOR,
  559. '/',
  560. realpath($this->_options['usergeneratordir']));
  561. if ($this->_options['usergeneratordir']{strlen($this->_options['usergeneratordir'])
  562. - 1} != '/') {
  563. $this->_options['usergeneratordir'] .= '/';
  564. }
  565. } else {
  566. $this->_options['usergeneratordir'] = '////';
  567. }
  568. $usergenerator = $this->_options['usergeneratordir'] .
  569. $this->_options['filelistgenerator'] . '.php';
  570. if (file_exists($usergenerator) && is_readable($usergenerator)) {
  571. include_once $usergenerator;
  572. }
  573. if (!class_exists($className)) {
  574. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE,
  575. $className);
  576. }
  577. } else {
  578. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND,
  579. $className);
  580. }
  581. }
  582. }
  583. /**
  584. * Import options from an existing package.xml
  585. *
  586. * @param string $packagefile name of package file
  587. * @param array $options (optional) list of generation options
  588. *
  589. * @return true|PEAR_Error
  590. * @access public
  591. * @since 1.5.0
  592. */
  593. function importOptions($packagefile, $options = array())
  594. {
  595. if (count($options) == 0) {
  596. // uses default options, when no custom given
  597. $options = $this->_options;
  598. }
  599. $options['deps'] = $options['maintainers'] = false;
  600. $this->setOptions($options, true);
  601. if (PEAR::isError($res = $this->_getExistingPackageXML(dirname($packagefile) .
  602. DIRECTORY_SEPARATOR, basename($packagefile)))) {
  603. return $res;
  604. }
  605. $options['package'] = $this->_oldPackageXml['package'];
  606. $options['summary'] = $this->_oldPackageXml['summary'];
  607. $options['description'] = $this->_oldPackageXml['description'];
  608. $options['date'] = $this->_oldPackageXml['release_date'];
  609. $options['version'] = $this->_oldPackageXml['version'];
  610. $options['license'] = $this->_oldPackageXml['release_license'];
  611. $options['state'] = $this->_oldPackageXml['release_state'];
  612. $options['notes'] = $this->_oldPackageXml['release_notes'];
  613. $this->setOptions($options, true);
  614. if (isset($this->_packageXml['release_deps'])) {
  615. $this->_options['deps'] = $this->_packageXml['release_deps'];
  616. }
  617. $this->_options['maintainers'] = $this->_oldPackageXml['maintainers'];
  618. return true;
  619. }
  620. /**
  621. * Get the existing options
  622. *
  623. * @return array
  624. * @access public
  625. * @since 1.5.0
  626. */
  627. function getOptions()
  628. {
  629. return $this->_options;
  630. }
  631. /**
  632. * Add an extension/role mapping to the role mapping option
  633. *
  634. * Roles influence both where a file is installed and how it is installed.
  635. * Files with role="data" are in a completely different directory hierarchy
  636. * from the program files of role="php"
  637. *
  638. * In PEAR 1.3b2, these roles are
  639. * - php (most common)
  640. * - data
  641. * - doc
  642. * - test
  643. * - script (gives the file an executable attribute)
  644. * - src
  645. *
  646. * @param string $extension file extension
  647. * @param string $role role
  648. *
  649. * @return void|PEAR_Error
  650. * @throws PEAR_PACKAGEFILEMANAGER_INVALID_ROLE
  651. * @access public
  652. * @since 0.1
  653. */
  654. function addRole($extension, $role)
  655. {
  656. $roles = call_user_func(array($this->_options['pearcommonclass'], 'getfileroles'));
  657. if (!in_array($role, $roles)) {
  658. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_ROLE, implode($roles, ', '), $role);
  659. }
  660. $this->_options['roles'][$extension] = $role;
  661. }
  662. /**
  663. * Add an install-time platform conditional install for a file
  664. *
  665. * The format of the platform string must be
  666. * OS-version-cpu-extra if any more specific information is needed,
  667. * and the OS must be in lower case as in "windows." The match is
  668. * performed using a regular expression, but uses * and ? wildcards
  669. * instead of .* and .?. Note that hpux/aix/irix/linux are all
  670. * exclusive. To select non-windows, use (*ix|*ux)
  671. *
  672. * This information is based on eyeing the source for OS/Guess.php, so
  673. * if you are unsure of what to do, read that file.
  674. *
  675. * @param string $path relative path of file (relative to packagedirectory option)
  676. * @param string $platform platform descriptor string
  677. *
  678. * @return void
  679. * @access public
  680. * @since 0.10
  681. */
  682. function addPlatformException($path, $platform)
  683. {
  684. if (!isset($this->_options['platformexceptions'])) {
  685. $this->_options['platformexceptions'] = array();
  686. }
  687. $this->_options['platformexceptions'][$path] = $platform;
  688. }
  689. /**
  690. * Add a replacement option for all files, or files matching the glob pattern
  691. *
  692. * This sets an install-time complex search-and-replace function
  693. * allowing the setting of platform-specific variables in all
  694. * installed files.
  695. *
  696. * if $type is php-const, then $to must be the name of a PHP Constant.
  697. * If $type is pear-config, then $to must be the name of a PEAR config
  698. * variable accessible through a {@link PEAR_Config::get()} method. If
  699. * type is package-info, then $to must be the name of a section from
  700. * the package.xml file used to install this file.
  701. *
  702. * @param string $type variable type, either php-const, pear-config or package-info
  703. * @param string $from text to replace in the source file
  704. * @param string $to variable name to use for replacement
  705. *
  706. * @return void|PEAR_Error
  707. * @throws PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE
  708. * @access public
  709. * @since 1.4.0
  710. */
  711. function addGlobalReplacement($type, $from, $to)
  712. {
  713. if (!isset($this->_options['globalreplacements'])) {
  714. $this->_options['globalreplacements'] = array();
  715. }
  716. $types = call_user_func(array($this->_options['pearcommonclass'], 'getreplacementtypes'));
  717. if (!in_array($type, $types)) {
  718. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE,
  719. implode($types, ', '), $type);
  720. }
  721. $glob = defined('GLOB_BRACE') ? glob($path, GLOB_BRACE) : glob($path);
  722. if (false !== $glob) {
  723. foreach ($glob as $pathItem) {
  724. $this->_options['replacements'][$pathItem][] = array(
  725. 'type' => $type,
  726. 'from' => $from,
  727. 'to' => $to
  728. );
  729. }
  730. }
  731. }
  732. /**
  733. * Add a replacement option for a file
  734. *
  735. * This sets an install-time complex search-and-replace function
  736. * allowing the setting of platform-specific variables in an
  737. * installed file.
  738. *
  739. * if $type is php-const, then $to must be the name of a PHP Constant.
  740. * If $type is pear-config, then $to must be the name of a PEAR config
  741. * variable accessible through a {@link PEAR_Config::get()} method. If
  742. * type is package-info, then $to must be the name of a section from
  743. * the package.xml file used to install this file.
  744. *
  745. * @param string $path relative path of file (relative to packagedirectory option)
  746. * @param string $type variable type, either php-const, pear-config or package-info
  747. * @param string $from text to replace in the source file
  748. * @param string $to variable name to use for replacement
  749. *
  750. * @return void|PEAR_Error
  751. * @throws PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE
  752. * @access public
  753. * @since 0.10
  754. */
  755. function addReplacement($path, $type, $from, $to)
  756. {
  757. if (!isset($this->_options['replacements'])) {
  758. $this->_options['replacements'] = array();
  759. }
  760. $types = call_user_func(array($this->_options['pearcommonclass'], 'getreplacementtypes'));
  761. if (!in_array($type, $types)) {
  762. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE,
  763. implode($types, ', '), $type);
  764. }
  765. $this->_options['replacements'][$path][] = array('type' => $type, 'from' => $from, 'to' => $to);
  766. }
  767. /**
  768. * Add a maintainer to the list of maintainers.
  769. *
  770. * Every maintainer must have a valid account at pear.php.net. The
  771. * first parameter is the account name (for instance, cellog is the
  772. * handle for Greg Beaver at pear.php.net). Every maintainer has
  773. * one of four possible roles:
  774. * - lead: the primary maintainer
  775. * - developer: an important developer on the project
  776. * - contributor: self-explanatory
  777. * - helper: ditto
  778. *
  779. * Finally, specify the name and email of the maintainer
  780. *
  781. * @param string $handle username on pear.php.net of maintainer
  782. * @param string $role lead|developer|contributor|helper role of maintainer
  783. * @param string $name full name of maintainer
  784. * @param string $email email address of maintainer
  785. *
  786. * @return void|PEAR_Error
  787. * @access public
  788. * @since 0.9
  789. */
  790. function addMaintainer($handle, $role, $name, $email)
  791. {
  792. if (!$this->_packageXml) {
  793. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
  794. }
  795. if (!in_array($role, $GLOBALS['_PEAR_Common_maintainer_roles'])) {
  796. $cb = array($this->_options['pearcommonclass'], 'getUserRoles');
  797. if (!is_callable($cb)) {
  798. $cb = array('PEAR_Common', 'getUserRoles');
  799. }
  800. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_WRONG_MROLE,
  801. implode(', ', call_user_func($cb)), $role);
  802. }
  803. if (!isset($this->_packageXml['maintainers'])) {
  804. $this->_packageXml['maintainers'] = array();
  805. }
  806. $found = false;
  807. foreach ($this->_packageXml['maintainers'] as $index => $maintainer) {
  808. if ($maintainer['handle'] == $handle) {
  809. $found = $index;
  810. break;
  811. }
  812. }
  813. $maintainer =
  814. array('handle' => $handle, 'role' => $role, 'name' => $name, 'email' => $email);
  815. if ($found !== false) {
  816. $this->_packageXml['maintainers'][$found] = $maintainer;
  817. } else {
  818. $this->_packageXml['maintainers'][] = $maintainer;
  819. }
  820. }
  821. /**
  822. * Add an install-time configuration option for building of source
  823. *
  824. * This option is only useful to PECL projects that are built upon
  825. * installation
  826. *
  827. * @param string $name name of the option
  828. * @param string $prompt prompt to display to the user
  829. * @param string $default (optional) default value
  830. *
  831. * @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
  832. * @return void|PEAR_Error
  833. * @access public
  834. * @since 0.9
  835. */
  836. function addConfigureOption($name, $prompt, $default = null)
  837. {
  838. if (!$this->_packageXml) {
  839. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
  840. }
  841. if (!isset($this->_packageXml['configure_options'])) {
  842. $this->_packageXml['configure_options'] = array();
  843. }
  844. $found = false;
  845. foreach ($this->_packageXml['configure_options'] as $index => $option) {
  846. if ($option['name'] == $name) {
  847. $found = $index;
  848. break;
  849. }
  850. }
  851. $option = array('name' => $name, 'prompt' => $prompt);
  852. if (isset($default)) {
  853. $option['default'] = $default;
  854. }
  855. if ($found !== false) {
  856. $this->_packageXml['configure_options'][$found] = $option;
  857. } else {
  858. $this->_packageXml['configure_options'][] = $option;
  859. }
  860. }
  861. /**
  862. * Uses PEAR::PHP_CompatInfo package to detect dependencies (extensions, php version)
  863. *
  864. * @return void|PEAR_Error
  865. * @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
  866. * @throws PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO
  867. * @access public
  868. * @since 1.3.0
  869. */
  870. function detectDependencies()
  871. {
  872. if (!$this->_packageXml) {
  873. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
  874. }
  875. if (!$this->isIncludeable('PHP/CompatInfo.php')) {
  876. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO);
  877. } else {
  878. include_once 'PHP/CompatInfo.php';
  879. $this->_detectDependencies = true;
  880. }
  881. }
  882. /**
  883. * Returns whether or not a file is in the include path.
  884. *
  885. * @param string $file path to filename
  886. *
  887. * @return boolean true if the file is in the include path, false otherwise
  888. * @access public
  889. * @since 1.3.0
  890. */
  891. function isIncludeable($file)
  892. {
  893. if (!defined('PATH_SEPARATOR')) {
  894. define('PATH_SEPARATOR', strtolower(substr(PHP_OS, 0, 3)) == 'win' ? ';' : ':');
  895. }
  896. foreach (explode(PATH_SEPARATOR, ini_get('include_path')) as $path) {
  897. if (file_exists($path . DIRECTORY_SEPARATOR . $file) &&
  898. is_readable($path . DIRECTORY_SEPARATOR . $file)) {
  899. return true;
  900. }
  901. }
  902. return false;
  903. }
  904. /**
  905. * Add a dependency on another package, or an extension/php
  906. *
  907. * This will overwrite an existing dependency if it is found. In
  908. * other words, if a dependency on PHP 4.1.0 exists, and
  909. * addDependency('php', '4.3.0', 'ge', 'php') is called, the existing
  910. * dependency on PHP 4.1.0 will be overwritten with the new one on PHP 4.3.0
  911. *
  912. * @param string $name Dependency element name
  913. * @param string $version (optional) Dependency version
  914. * @param string $operator A specific operator for the version, this can be one of:
  915. * 'has', 'not', 'lt', 'le', 'eq', 'ne', 'ge', or 'gt'
  916. * @param string $type (optional) Dependency type. This can be one of:
  917. * 'pkg', 'ext', 'php', 'prog', 'os', 'sapi', or 'zend'
  918. * @param boolean $optional (optional) true if dependency is optional
  919. *
  920. * @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
  921. * @throws PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE
  922. * @return void|PEAR_Error
  923. * @access public
  924. * @since 0.1
  925. */
  926. function addDependency($name, $version = false, $operator = 'ge', $type = 'pkg', $optional = false)
  927. {
  928. if (!$this->_packageXml) {
  929. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
  930. }
  931. if ((strtolower($name) == 'php') && (strtolower($type) == 'pkg')) {
  932. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE);
  933. }
  934. if (!isset($this->_packageXml['release_deps']) || !is_array($this->_packageXml['release_deps'])) {
  935. $this->_packageXml['release_deps'] = array();
  936. }
  937. $found = false;
  938. foreach ($this->_packageXml['release_deps'] as $index => $dep) {
  939. if ($type == 'php') {
  940. if ($dep['type'] == 'php') {
  941. $found = $index;
  942. break;
  943. }
  944. } else {
  945. if (isset($dep['name']) && $dep['name'] == $name && $dep['type'] == $type) {
  946. $found = $index;
  947. break;
  948. }
  949. }
  950. }
  951. $dep =
  952. array(
  953. 'name' => $name,
  954. 'type' => $type);
  955. if ($type == 'php') {
  956. unset($dep['name']);
  957. }
  958. if ($operator) {
  959. $dep['rel'] = $operator;
  960. if ($dep['rel'] != 'has' && $version) {
  961. $dep['version'] = $version;
  962. }
  963. }
  964. if ($optional) {
  965. $dep['optional'] = 'yes';
  966. } else {
  967. $dep['optional'] = 'no';
  968. }
  969. if ($found !== false) {
  970. $this->_packageXml['release_deps'][$found] = $dep; // overwrite existing dependency
  971. } else {
  972. $this->_packageXml['release_deps'][] = $dep; // add new dependency
  973. }
  974. }
  975. /**
  976. * Writes the package.xml file out with the newly created <release></release> tag
  977. *
  978. * ALWAYS use {@link debugPackageFile} to verify that output is correct before
  979. * overwriting your package.xml
  980. *
  981. * @param boolean $debuginterface (optional) null if no debugging, true if web interface, false if command-line
  982. *
  983. * @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
  984. * @throws PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS
  985. * @throws PEAR_PACKAGEFILEMANAGER_NONOTES
  986. * @throws PEAR_PACKAGEFILEMANAGER_NOLICENSE
  987. * @throws PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE
  988. * @throws PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE
  989. * @throws PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE
  990. * @throws PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE
  991. * @throws PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE
  992. * @return true|PEAR_Error
  993. * @access public
  994. * @since 0.1
  995. */
  996. function writePackageFile($debuginterface = null)
  997. {
  998. if (!$this->_packageXml) {
  999. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
  1000. }
  1001. if (!isset($this->_packageXml['maintainers']) || empty($this->_packageXml['maintainers'])) {
  1002. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS);
  1003. }
  1004. if (!isset($this->_options['notes']) || empty($this->_options['notes'])) {
  1005. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NONOTES);
  1006. }
  1007. if (!isset($this->_options['license']) || empty($this->_options['license'])) {
  1008. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOLICENSE);
  1009. }
  1010. extract($this->_options);
  1011. $date = date('Y-m-d');
  1012. if (isset($package)) {
  1013. $this->_packageXml['package'] = $package;
  1014. }
  1015. if (isset($summary)) {
  1016. $this->_packageXml['summary'] = $summary;
  1017. }
  1018. if (isset($description)) {
  1019. $this->_packageXml['description'] = $description;
  1020. }
  1021. $this->_packageXml['release_date'] = $date;
  1022. $this->_packageXml['version'] = $version;
  1023. $this->_packageXml['release_license'] = $license;
  1024. $this->_packageXml['release_state'] = $state;
  1025. $this->_packageXml['release_notes'] = $notes;
  1026. $PEAR_Common = $this->_options['pearcommonclass'];
  1027. $this->_pear = new $PEAR_Common;
  1028. if (method_exists($this->_pear, 'setPackageFileManager')) {
  1029. $this->_pear->setPackageFileManager($this);
  1030. }
  1031. $this->_packageXml['filelist'] = $this->_getFileList();
  1032. $warnings = $this->getWarnings();
  1033. if (count($warnings)) {
  1034. $nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n");
  1035. foreach ($warnings as $errmsg) {
  1036. echo 'WARNING: ' . $errmsg['message'] . $nl;
  1037. }
  1038. }
  1039. if (PEAR::isError($this->_packageXml['filelist'])) {
  1040. return $this->_packageXml['filelist'];
  1041. }
  1042. if (isset($this->_pear->pkginfo['provides'])) {
  1043. $this->_packageXml['provides'] = $this->_pear->pkginfo['provides'];
  1044. }
  1045. if ($this->_options['simpleoutput']) {
  1046. unset($this->_packageXml['provides']);
  1047. }
  1048. $this->_packageXml['release_deps'] = $this->_getDependencies();
  1049. $this->_updateChangeLog();
  1050. $common = &$this->_pear;
  1051. $warnings = $errors = array();
  1052. if (method_exists($common, 'setPackageFileManagerOptions')) {
  1053. $common->setPackageFileManagerOptions($this->_options);
  1054. }
  1055. $packagexml = $common->xmlFromInfo($this->_packageXml);
  1056. if (PEAR::isError($packagexml)) {
  1057. $errs = $packagexml->getUserinfo();
  1058. if (is_array($errs)) {
  1059. foreach ($errs as $error) {
  1060. if ($error['level'] == 'error') {
  1061. $errors[] = $error['message'];
  1062. } else {
  1063. $warnings[] = $error['message'];
  1064. }
  1065. }
  1066. }
  1067. } else {
  1068. $common->validatePackageInfo($packagexml, $warnings, $errors,
  1069. $this->_options['packagedirectory']);
  1070. }
  1071. if (count($errors)) {
  1072. $ret = '';
  1073. $nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n");
  1074. foreach ($errors as $errmsg) {
  1075. $ret .= $errmsg . $nl;
  1076. }
  1077. return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE, $nl, $ret);
  1078. }
  1079. if (count($warnings)) {
  1080. $nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n");
  1081. foreach ($warnings as $errmsg) {
  1082. echo $errmsg . $nl;
  1083. }
  1084. }
  1085. if (!strpos($packagexml, '<!DOCTYPE')) {
  1086. // hack to fix pear
  1087. $packagexml = str_replace('<package version="1.0">',
  1088. '<!DOCTYPE package SYSTEM "' . $this->_options['doctype'] .
  1089. "\">\n<package version=\"1.0\">",
  1090. $packagexml);
  1091. }
  1092. if (isset($debuginterface)) {
  1093. if ($debuginterface) {
  1094. echo '<pre>' . htmlentities($packagexml) . '</pre>';
  1095. } else {
  1096. echo $packagexml;

Large files files are truncated, but you can click here to view the full file