Registry.php 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145
  1. <?php
  2. /**
  3. * PEAR_Command_Registry (list, list-files, shell-test, info commands)
  4. *
  5. * PHP versions 4 and 5
  6. *
  7. * @category pear
  8. * @package PEAR
  9. * @author Stig Bakken <ssb@php.net>
  10. * @author Greg Beaver <cellog@php.net>
  11. * @copyright 1997-2009 The Authors
  12. * @license http://opensource.org/licenses/bsd-license.php New BSD License
  13. * @version CVS: $Id: Registry.php 313023 2011-07-06 19:17:11Z dufuz $
  14. * @link http://pear.php.net/package/PEAR
  15. * @since File available since Release 0.1
  16. */
  17. /**
  18. * base class
  19. */
  20. require_once 'PEAR/Command/Common.php';
  21. /**
  22. * PEAR commands for registry manipulation
  23. *
  24. * @category pear
  25. * @package PEAR
  26. * @author Stig Bakken <ssb@php.net>
  27. * @author Greg Beaver <cellog@php.net>
  28. * @copyright 1997-2009 The Authors
  29. * @license http://opensource.org/licenses/bsd-license.php New BSD License
  30. * @version Release: 1.9.4
  31. * @link http://pear.php.net/package/PEAR
  32. * @since Class available since Release 0.1
  33. */
  34. class PEAR_Command_Registry extends PEAR_Command_Common
  35. {
  36. var $commands = array(
  37. 'list' => array(
  38. 'summary' => 'List Installed Packages In The Default Channel',
  39. 'function' => 'doList',
  40. 'shortcut' => 'l',
  41. 'options' => array(
  42. 'channel' => array(
  43. 'shortopt' => 'c',
  44. 'doc' => 'list installed packages from this channel',
  45. 'arg' => 'CHAN',
  46. ),
  47. 'allchannels' => array(
  48. 'shortopt' => 'a',
  49. 'doc' => 'list installed packages from all channels',
  50. ),
  51. 'channelinfo' => array(
  52. 'shortopt' => 'i',
  53. 'doc' => 'output fully channel-aware data, even on failure',
  54. ),
  55. ),
  56. 'doc' => '<package>
  57. If invoked without parameters, this command lists the PEAR packages
  58. installed in your php_dir ({config php_dir}). With a parameter, it
  59. lists the files in a package.
  60. ',
  61. ),
  62. 'list-files' => array(
  63. 'summary' => 'List Files In Installed Package',
  64. 'function' => 'doFileList',
  65. 'shortcut' => 'fl',
  66. 'options' => array(),
  67. 'doc' => '<package>
  68. List the files in an installed package.
  69. '
  70. ),
  71. 'shell-test' => array(
  72. 'summary' => 'Shell Script Test',
  73. 'function' => 'doShellTest',
  74. 'shortcut' => 'st',
  75. 'options' => array(),
  76. 'doc' => '<package> [[relation] version]
  77. Tests if a package is installed in the system. Will exit(1) if it is not.
  78. <relation> The version comparison operator. One of:
  79. <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne
  80. <version> The version to compare with
  81. '),
  82. 'info' => array(
  83. 'summary' => 'Display information about a package',
  84. 'function' => 'doInfo',
  85. 'shortcut' => 'in',
  86. 'options' => array(),
  87. 'doc' => '<package>
  88. Displays information about a package. The package argument may be a
  89. local package file, an URL to a package file, or the name of an
  90. installed package.'
  91. )
  92. );
  93. /**
  94. * PEAR_Command_Registry constructor.
  95. *
  96. * @access public
  97. */
  98. function PEAR_Command_Registry(&$ui, &$config)
  99. {
  100. parent::PEAR_Command_Common($ui, $config);
  101. }
  102. function _sortinfo($a, $b)
  103. {
  104. $apackage = isset($a['package']) ? $a['package'] : $a['name'];
  105. $bpackage = isset($b['package']) ? $b['package'] : $b['name'];
  106. return strcmp($apackage, $bpackage);
  107. }
  108. function doList($command, $options, $params)
  109. {
  110. $reg = &$this->config->getRegistry();
  111. $channelinfo = isset($options['channelinfo']);
  112. if (isset($options['allchannels']) && !$channelinfo) {
  113. return $this->doListAll($command, array(), $params);
  114. }
  115. if (isset($options['allchannels']) && $channelinfo) {
  116. // allchannels with $channelinfo
  117. unset($options['allchannels']);
  118. $channels = $reg->getChannels();
  119. $errors = array();
  120. PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  121. foreach ($channels as $channel) {
  122. $options['channel'] = $channel->getName();
  123. $ret = $this->doList($command, $options, $params);
  124. if (PEAR::isError($ret)) {
  125. $errors[] = $ret;
  126. }
  127. }
  128. PEAR::staticPopErrorHandling();
  129. if (count($errors)) {
  130. // for now, only give first error
  131. return PEAR::raiseError($errors[0]);
  132. }
  133. return true;
  134. }
  135. if (count($params) === 1) {
  136. return $this->doFileList($command, $options, $params);
  137. }
  138. if (isset($options['channel'])) {
  139. if (!$reg->channelExists($options['channel'])) {
  140. return $this->raiseError('Channel "' . $options['channel'] .'" does not exist');
  141. }
  142. $channel = $reg->channelName($options['channel']);
  143. } else {
  144. $channel = $this->config->get('default_channel');
  145. }
  146. $installed = $reg->packageInfo(null, null, $channel);
  147. usort($installed, array(&$this, '_sortinfo'));
  148. $data = array(
  149. 'caption' => 'Installed packages, channel ' .
  150. $channel . ':',
  151. 'border' => true,
  152. 'headline' => array('Package', 'Version', 'State'),
  153. 'channel' => $channel,
  154. );
  155. if ($channelinfo) {
  156. $data['headline'] = array('Channel', 'Package', 'Version', 'State');
  157. }
  158. if (count($installed) && !isset($data['data'])) {
  159. $data['data'] = array();
  160. }
  161. foreach ($installed as $package) {
  162. $pobj = $reg->getPackage(isset($package['package']) ?
  163. $package['package'] : $package['name'], $channel);
  164. if ($channelinfo) {
  165. $packageinfo = array($pobj->getChannel(), $pobj->getPackage(), $pobj->getVersion(),
  166. $pobj->getState() ? $pobj->getState() : null);
  167. } else {
  168. $packageinfo = array($pobj->getPackage(), $pobj->getVersion(),
  169. $pobj->getState() ? $pobj->getState() : null);
  170. }
  171. $data['data'][] = $packageinfo;
  172. }
  173. if (count($installed) === 0) {
  174. if (!$channelinfo) {
  175. $data = '(no packages installed from channel ' . $channel . ')';
  176. } else {
  177. $data = array(
  178. 'caption' => 'Installed packages, channel ' .
  179. $channel . ':',
  180. 'border' => true,
  181. 'channel' => $channel,
  182. 'data' => array(array('(no packages installed)')),
  183. );
  184. }
  185. }
  186. $this->ui->outputData($data, $command);
  187. return true;
  188. }
  189. function doListAll($command, $options, $params)
  190. {
  191. // This duplicate code is deprecated over
  192. // list --channelinfo, which gives identical
  193. // output for list and list --allchannels.
  194. $reg = &$this->config->getRegistry();
  195. $installed = $reg->packageInfo(null, null, null);
  196. foreach ($installed as $channel => $packages) {
  197. usort($packages, array($this, '_sortinfo'));
  198. $data = array(
  199. 'caption' => 'Installed packages, channel ' . $channel . ':',
  200. 'border' => true,
  201. 'headline' => array('Package', 'Version', 'State'),
  202. 'channel' => $channel
  203. );
  204. foreach ($packages as $package) {
  205. $p = isset($package['package']) ? $package['package'] : $package['name'];
  206. $pobj = $reg->getPackage($p, $channel);
  207. $data['data'][] = array($pobj->getPackage(), $pobj->getVersion(),
  208. $pobj->getState() ? $pobj->getState() : null);
  209. }
  210. // Adds a blank line after each section
  211. $data['data'][] = array();
  212. if (count($packages) === 0) {
  213. $data = array(
  214. 'caption' => 'Installed packages, channel ' . $channel . ':',
  215. 'border' => true,
  216. 'data' => array(array('(no packages installed)'), array()),
  217. 'channel' => $channel
  218. );
  219. }
  220. $this->ui->outputData($data, $command);
  221. }
  222. return true;
  223. }
  224. function doFileList($command, $options, $params)
  225. {
  226. if (count($params) !== 1) {
  227. return $this->raiseError('list-files expects 1 parameter');
  228. }
  229. $reg = &$this->config->getRegistry();
  230. $fp = false;
  231. if (!is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0], 'r'))) {
  232. if ($fp) {
  233. fclose($fp);
  234. }
  235. if (!class_exists('PEAR_PackageFile')) {
  236. require_once 'PEAR/PackageFile.php';
  237. }
  238. $pkg = &new PEAR_PackageFile($this->config, $this->_debug);
  239. PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  240. $info = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
  241. PEAR::staticPopErrorHandling();
  242. $headings = array('Package File', 'Install Path');
  243. $installed = false;
  244. } else {
  245. PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  246. $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
  247. PEAR::staticPopErrorHandling();
  248. if (PEAR::isError($parsed)) {
  249. return $this->raiseError($parsed);
  250. }
  251. $info = &$reg->getPackage($parsed['package'], $parsed['channel']);
  252. $headings = array('Type', 'Install Path');
  253. $installed = true;
  254. }
  255. if (PEAR::isError($info)) {
  256. return $this->raiseError($info);
  257. }
  258. if ($info === null) {
  259. return $this->raiseError("`$params[0]' not installed");
  260. }
  261. $list = ($info->getPackagexmlVersion() == '1.0' || $installed) ?
  262. $info->getFilelist() : $info->getContents();
  263. if ($installed) {
  264. $caption = 'Installed Files For ' . $params[0];
  265. } else {
  266. $caption = 'Contents of ' . basename($params[0]);
  267. }
  268. $data = array(
  269. 'caption' => $caption,
  270. 'border' => true,
  271. 'headline' => $headings);
  272. if ($info->getPackagexmlVersion() == '1.0' || $installed) {
  273. foreach ($list as $file => $att) {
  274. if ($installed) {
  275. if (empty($att['installed_as'])) {
  276. continue;
  277. }
  278. $data['data'][] = array($att['role'], $att['installed_as']);
  279. } else {
  280. if (isset($att['baseinstalldir']) && !in_array($att['role'],
  281. array('test', 'data', 'doc'))) {
  282. $dest = $att['baseinstalldir'] . DIRECTORY_SEPARATOR .
  283. $file;
  284. } else {
  285. $dest = $file;
  286. }
  287. switch ($att['role']) {
  288. case 'test':
  289. case 'data':
  290. case 'doc':
  291. $role = $att['role'];
  292. if ($role == 'test') {
  293. $role .= 's';
  294. }
  295. $dest = $this->config->get($role . '_dir') . DIRECTORY_SEPARATOR .
  296. $info->getPackage() . DIRECTORY_SEPARATOR . $dest;
  297. break;
  298. case 'php':
  299. default:
  300. $dest = $this->config->get('php_dir') . DIRECTORY_SEPARATOR .
  301. $dest;
  302. }
  303. $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
  304. $dest = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"),
  305. array(DIRECTORY_SEPARATOR,
  306. DIRECTORY_SEPARATOR,
  307. DIRECTORY_SEPARATOR),
  308. $dest);
  309. $file = preg_replace('!/+!', '/', $file);
  310. $data['data'][] = array($file, $dest);
  311. }
  312. }
  313. } else { // package.xml 2.0, not installed
  314. if (!isset($list['dir']['file'][0])) {
  315. $list['dir']['file'] = array($list['dir']['file']);
  316. }
  317. foreach ($list['dir']['file'] as $att) {
  318. $att = $att['attribs'];
  319. $file = $att['name'];
  320. $role = &PEAR_Installer_Role::factory($info, $att['role'], $this->config);
  321. $role->setup($this, $info, $att, $file);
  322. if (!$role->isInstallable()) {
  323. $dest = '(not installable)';
  324. } else {
  325. $dest = $role->processInstallation($info, $att, $file, '');
  326. if (PEAR::isError($dest)) {
  327. $dest = '(Unknown role "' . $att['role'] . ')';
  328. } else {
  329. list(,, $dest) = $dest;
  330. }
  331. }
  332. $data['data'][] = array($file, $dest);
  333. }
  334. }
  335. $this->ui->outputData($data, $command);
  336. return true;
  337. }
  338. function doShellTest($command, $options, $params)
  339. {
  340. if (count($params) < 1) {
  341. return PEAR::raiseError('ERROR, usage: pear shell-test packagename [[relation] version]');
  342. }
  343. PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  344. $reg = &$this->config->getRegistry();
  345. $info = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
  346. if (PEAR::isError($info)) {
  347. exit(1); // invalid package name
  348. }
  349. $package = $info['package'];
  350. $channel = $info['channel'];
  351. // "pear shell-test Foo"
  352. if (!$reg->packageExists($package, $channel)) {
  353. if ($channel == 'pecl.php.net') {
  354. if ($reg->packageExists($package, 'pear.php.net')) {
  355. $channel = 'pear.php.net'; // magically change channels for extensions
  356. }
  357. }
  358. }
  359. if (count($params) === 1) {
  360. if (!$reg->packageExists($package, $channel)) {
  361. exit(1);
  362. }
  363. // "pear shell-test Foo 1.0"
  364. } elseif (count($params) === 2) {
  365. $v = $reg->packageInfo($package, 'version', $channel);
  366. if (!$v || !version_compare("$v", "{$params[1]}", "ge")) {
  367. exit(1);
  368. }
  369. // "pear shell-test Foo ge 1.0"
  370. } elseif (count($params) === 3) {
  371. $v = $reg->packageInfo($package, 'version', $channel);
  372. if (!$v || !version_compare("$v", "{$params[2]}", $params[1])) {
  373. exit(1);
  374. }
  375. } else {
  376. PEAR::staticPopErrorHandling();
  377. $this->raiseError("$command: expects 1 to 3 parameters");
  378. exit(1);
  379. }
  380. }
  381. function doInfo($command, $options, $params)
  382. {
  383. if (count($params) !== 1) {
  384. return $this->raiseError('pear info expects 1 parameter');
  385. }
  386. $info = $fp = false;
  387. $reg = &$this->config->getRegistry();
  388. if (is_file($params[0]) && !is_dir($params[0]) &&
  389. (file_exists($params[0]) || $fp = @fopen($params[0], 'r'))
  390. ) {
  391. if ($fp) {
  392. fclose($fp);
  393. }
  394. if (!class_exists('PEAR_PackageFile')) {
  395. require_once 'PEAR/PackageFile.php';
  396. }
  397. $pkg = &new PEAR_PackageFile($this->config, $this->_debug);
  398. PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  399. $obj = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
  400. PEAR::staticPopErrorHandling();
  401. if (PEAR::isError($obj)) {
  402. $uinfo = $obj->getUserInfo();
  403. if (is_array($uinfo)) {
  404. foreach ($uinfo as $message) {
  405. if (is_array($message)) {
  406. $message = $message['message'];
  407. }
  408. $this->ui->outputData($message);
  409. }
  410. }
  411. return $this->raiseError($obj);
  412. }
  413. if ($obj->getPackagexmlVersion() != '1.0') {
  414. return $this->_doInfo2($command, $options, $params, $obj, false);
  415. }
  416. $info = $obj->toArray();
  417. } else {
  418. $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
  419. if (PEAR::isError($parsed)) {
  420. return $this->raiseError($parsed);
  421. }
  422. $package = $parsed['package'];
  423. $channel = $parsed['channel'];
  424. $info = $reg->packageInfo($package, null, $channel);
  425. if (isset($info['old'])) {
  426. $obj = $reg->getPackage($package, $channel);
  427. return $this->_doInfo2($command, $options, $params, $obj, true);
  428. }
  429. }
  430. if (PEAR::isError($info)) {
  431. return $info;
  432. }
  433. if (empty($info)) {
  434. $this->raiseError("No information found for `$params[0]'");
  435. return;
  436. }
  437. unset($info['filelist']);
  438. unset($info['dirtree']);
  439. unset($info['changelog']);
  440. if (isset($info['xsdversion'])) {
  441. $info['package.xml version'] = $info['xsdversion'];
  442. unset($info['xsdversion']);
  443. }
  444. if (isset($info['packagerversion'])) {
  445. $info['packaged with PEAR version'] = $info['packagerversion'];
  446. unset($info['packagerversion']);
  447. }
  448. $keys = array_keys($info);
  449. $longtext = array('description', 'summary');
  450. foreach ($keys as $key) {
  451. if (is_array($info[$key])) {
  452. switch ($key) {
  453. case 'maintainers': {
  454. $i = 0;
  455. $mstr = '';
  456. foreach ($info[$key] as $m) {
  457. if ($i++ > 0) {
  458. $mstr .= "\n";
  459. }
  460. $mstr .= $m['name'] . " <";
  461. if (isset($m['email'])) {
  462. $mstr .= $m['email'];
  463. } else {
  464. $mstr .= $m['handle'] . '@php.net';
  465. }
  466. $mstr .= "> ($m[role])";
  467. }
  468. $info[$key] = $mstr;
  469. break;
  470. }
  471. case 'release_deps': {
  472. $i = 0;
  473. $dstr = '';
  474. foreach ($info[$key] as $d) {
  475. if (isset($this->_deps_rel_trans[$d['rel']])) {
  476. $rel = $this->_deps_rel_trans[$d['rel']];
  477. } else {
  478. $rel = $d['rel'];
  479. }
  480. if (isset($this->_deps_type_trans[$d['type']])) {
  481. $type = ucfirst($this->_deps_type_trans[$d['type']]);
  482. } else {
  483. $type = $d['type'];
  484. }
  485. if (isset($d['name'])) {
  486. $name = $d['name'] . ' ';
  487. } else {
  488. $name = '';
  489. }
  490. if (isset($d['version'])) {
  491. $version = $d['version'] . ' ';
  492. } else {
  493. $version = '';
  494. }
  495. if (isset($d['optional']) && $d['optional'] == 'yes') {
  496. $optional = ' (optional)';
  497. } else {
  498. $optional = '';
  499. }
  500. $dstr .= "$type $name$rel $version$optional\n";
  501. }
  502. $info[$key] = $dstr;
  503. break;
  504. }
  505. case 'provides' : {
  506. $debug = $this->config->get('verbose');
  507. if ($debug < 2) {
  508. $pstr = 'Classes: ';
  509. } else {
  510. $pstr = '';
  511. }
  512. $i = 0;
  513. foreach ($info[$key] as $p) {
  514. if ($debug < 2 && $p['type'] != "class") {
  515. continue;
  516. }
  517. // Only print classes when verbosity mode is < 2
  518. if ($debug < 2) {
  519. if ($i++ > 0) {
  520. $pstr .= ", ";
  521. }
  522. $pstr .= $p['name'];
  523. } else {
  524. if ($i++ > 0) {
  525. $pstr .= "\n";
  526. }
  527. $pstr .= ucfirst($p['type']) . " " . $p['name'];
  528. if (isset($p['explicit']) && $p['explicit'] == 1) {
  529. $pstr .= " (explicit)";
  530. }
  531. }
  532. }
  533. $info[$key] = $pstr;
  534. break;
  535. }
  536. case 'configure_options' : {
  537. foreach ($info[$key] as $i => $p) {
  538. $info[$key][$i] = array_map(null, array_keys($p), array_values($p));
  539. $info[$key][$i] = array_map(create_function('$a',
  540. 'return join(" = ",$a);'), $info[$key][$i]);
  541. $info[$key][$i] = implode(', ', $info[$key][$i]);
  542. }
  543. $info[$key] = implode("\n", $info[$key]);
  544. break;
  545. }
  546. default: {
  547. $info[$key] = implode(", ", $info[$key]);
  548. break;
  549. }
  550. }
  551. }
  552. if ($key == '_lastmodified') {
  553. $hdate = date('Y-m-d', $info[$key]);
  554. unset($info[$key]);
  555. $info['Last Modified'] = $hdate;
  556. } elseif ($key == '_lastversion') {
  557. $info['Previous Installed Version'] = $info[$key] ? $info[$key] : '- None -';
  558. unset($info[$key]);
  559. } else {
  560. $info[$key] = trim($info[$key]);
  561. if (in_array($key, $longtext)) {
  562. $info[$key] = preg_replace('/ +/', ' ', $info[$key]);
  563. }
  564. }
  565. }
  566. $caption = 'About ' . $info['package'] . '-' . $info['version'];
  567. $data = array(
  568. 'caption' => $caption,
  569. 'border' => true);
  570. foreach ($info as $key => $value) {
  571. $key = ucwords(trim(str_replace('_', ' ', $key)));
  572. $data['data'][] = array($key, $value);
  573. }
  574. $data['raw'] = $info;
  575. $this->ui->outputData($data, 'package-info');
  576. }
  577. /**
  578. * @access private
  579. */
  580. function _doInfo2($command, $options, $params, &$obj, $installed)
  581. {
  582. $reg = &$this->config->getRegistry();
  583. $caption = 'About ' . $obj->getChannel() . '/' .$obj->getPackage() . '-' .
  584. $obj->getVersion();
  585. $data = array(
  586. 'caption' => $caption,
  587. 'border' => true);
  588. switch ($obj->getPackageType()) {
  589. case 'php' :
  590. $release = 'PEAR-style PHP-based Package';
  591. break;
  592. case 'extsrc' :
  593. $release = 'PECL-style PHP extension (source code)';
  594. break;
  595. case 'zendextsrc' :
  596. $release = 'PECL-style Zend extension (source code)';
  597. break;
  598. case 'extbin' :
  599. $release = 'PECL-style PHP extension (binary)';
  600. break;
  601. case 'zendextbin' :
  602. $release = 'PECL-style Zend extension (binary)';
  603. break;
  604. case 'bundle' :
  605. $release = 'Package bundle (collection of packages)';
  606. break;
  607. }
  608. $extends = $obj->getExtends();
  609. $extends = $extends ?
  610. $obj->getPackage() . ' (extends ' . $extends . ')' : $obj->getPackage();
  611. if ($src = $obj->getSourcePackage()) {
  612. $extends .= ' (source package ' . $src['channel'] . '/' . $src['package'] . ')';
  613. }
  614. $info = array(
  615. 'Release Type' => $release,
  616. 'Name' => $extends,
  617. 'Channel' => $obj->getChannel(),
  618. 'Summary' => preg_replace('/ +/', ' ', $obj->getSummary()),
  619. 'Description' => preg_replace('/ +/', ' ', $obj->getDescription()),
  620. );
  621. $info['Maintainers'] = '';
  622. foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
  623. $leads = $obj->{"get{$role}s"}();
  624. if (!$leads) {
  625. continue;
  626. }
  627. if (isset($leads['active'])) {
  628. $leads = array($leads);
  629. }
  630. foreach ($leads as $lead) {
  631. if (!empty($info['Maintainers'])) {
  632. $info['Maintainers'] .= "\n";
  633. }
  634. $active = $lead['active'] == 'no' ? ', inactive' : '';
  635. $info['Maintainers'] .= $lead['name'] . ' <';
  636. $info['Maintainers'] .= $lead['email'] . "> ($role$active)";
  637. }
  638. }
  639. $info['Release Date'] = $obj->getDate();
  640. if ($time = $obj->getTime()) {
  641. $info['Release Date'] .= ' ' . $time;
  642. }
  643. $info['Release Version'] = $obj->getVersion() . ' (' . $obj->getState() . ')';
  644. $info['API Version'] = $obj->getVersion('api') . ' (' . $obj->getState('api') . ')';
  645. $info['License'] = $obj->getLicense();
  646. $uri = $obj->getLicenseLocation();
  647. if ($uri) {
  648. if (isset($uri['uri'])) {
  649. $info['License'] .= ' (' . $uri['uri'] . ')';
  650. } else {
  651. $extra = $obj->getInstalledLocation($info['filesource']);
  652. if ($extra) {
  653. $info['License'] .= ' (' . $uri['filesource'] . ')';
  654. }
  655. }
  656. }
  657. $info['Release Notes'] = $obj->getNotes();
  658. if ($compat = $obj->getCompatible()) {
  659. if (!isset($compat[0])) {
  660. $compat = array($compat);
  661. }
  662. $info['Compatible with'] = '';
  663. foreach ($compat as $package) {
  664. $info['Compatible with'] .= $package['channel'] . '/' . $package['name'] .
  665. "\nVersions >= " . $package['min'] . ', <= ' . $package['max'];
  666. if (isset($package['exclude'])) {
  667. if (is_array($package['exclude'])) {
  668. $package['exclude'] = implode(', ', $package['exclude']);
  669. }
  670. if (!isset($info['Not Compatible with'])) {
  671. $info['Not Compatible with'] = '';
  672. } else {
  673. $info['Not Compatible with'] .= "\n";
  674. }
  675. $info['Not Compatible with'] .= $package['channel'] . '/' .
  676. $package['name'] . "\nVersions " . $package['exclude'];
  677. }
  678. }
  679. }
  680. $usesrole = $obj->getUsesrole();
  681. if ($usesrole) {
  682. if (!isset($usesrole[0])) {
  683. $usesrole = array($usesrole);
  684. }
  685. foreach ($usesrole as $roledata) {
  686. if (isset($info['Uses Custom Roles'])) {
  687. $info['Uses Custom Roles'] .= "\n";
  688. } else {
  689. $info['Uses Custom Roles'] = '';
  690. }
  691. if (isset($roledata['package'])) {
  692. $rolepackage = $reg->parsedPackageNameToString($roledata, true);
  693. } else {
  694. $rolepackage = $roledata['uri'];
  695. }
  696. $info['Uses Custom Roles'] .= $roledata['role'] . ' (' . $rolepackage . ')';
  697. }
  698. }
  699. $usestask = $obj->getUsestask();
  700. if ($usestask) {
  701. if (!isset($usestask[0])) {
  702. $usestask = array($usestask);
  703. }
  704. foreach ($usestask as $taskdata) {
  705. if (isset($info['Uses Custom Tasks'])) {
  706. $info['Uses Custom Tasks'] .= "\n";
  707. } else {
  708. $info['Uses Custom Tasks'] = '';
  709. }
  710. if (isset($taskdata['package'])) {
  711. $taskpackage = $reg->parsedPackageNameToString($taskdata, true);
  712. } else {
  713. $taskpackage = $taskdata['uri'];
  714. }
  715. $info['Uses Custom Tasks'] .= $taskdata['task'] . ' (' . $taskpackage . ')';
  716. }
  717. }
  718. $deps = $obj->getDependencies();
  719. $info['Required Dependencies'] = 'PHP version ' . $deps['required']['php']['min'];
  720. if (isset($deps['required']['php']['max'])) {
  721. $info['Required Dependencies'] .= '-' . $deps['required']['php']['max'] . "\n";
  722. } else {
  723. $info['Required Dependencies'] .= "\n";
  724. }
  725. if (isset($deps['required']['php']['exclude'])) {
  726. if (!isset($info['Not Compatible with'])) {
  727. $info['Not Compatible with'] = '';
  728. } else {
  729. $info['Not Compatible with'] .= "\n";
  730. }
  731. if (is_array($deps['required']['php']['exclude'])) {
  732. $deps['required']['php']['exclude'] =
  733. implode(', ', $deps['required']['php']['exclude']);
  734. }
  735. $info['Not Compatible with'] .= "PHP versions\n " .
  736. $deps['required']['php']['exclude'];
  737. }
  738. $info['Required Dependencies'] .= 'PEAR installer version';
  739. if (isset($deps['required']['pearinstaller']['max'])) {
  740. $info['Required Dependencies'] .= 's ' .
  741. $deps['required']['pearinstaller']['min'] . '-' .
  742. $deps['required']['pearinstaller']['max'];
  743. } else {
  744. $info['Required Dependencies'] .= ' ' .
  745. $deps['required']['pearinstaller']['min'] . ' or newer';
  746. }
  747. if (isset($deps['required']['pearinstaller']['exclude'])) {
  748. if (!isset($info['Not Compatible with'])) {
  749. $info['Not Compatible with'] = '';
  750. } else {
  751. $info['Not Compatible with'] .= "\n";
  752. }
  753. if (is_array($deps['required']['pearinstaller']['exclude'])) {
  754. $deps['required']['pearinstaller']['exclude'] =
  755. implode(', ', $deps['required']['pearinstaller']['exclude']);
  756. }
  757. $info['Not Compatible with'] .= "PEAR installer\n Versions " .
  758. $deps['required']['pearinstaller']['exclude'];
  759. }
  760. foreach (array('Package', 'Extension') as $type) {
  761. $index = strtolower($type);
  762. if (isset($deps['required'][$index])) {
  763. if (isset($deps['required'][$index]['name'])) {
  764. $deps['required'][$index] = array($deps['required'][$index]);
  765. }
  766. foreach ($deps['required'][$index] as $package) {
  767. if (isset($package['conflicts'])) {
  768. $infoindex = 'Not Compatible with';
  769. if (!isset($info['Not Compatible with'])) {
  770. $info['Not Compatible with'] = '';
  771. } else {
  772. $info['Not Compatible with'] .= "\n";
  773. }
  774. } else {
  775. $infoindex = 'Required Dependencies';
  776. $info[$infoindex] .= "\n";
  777. }
  778. if ($index == 'extension') {
  779. $name = $package['name'];
  780. } else {
  781. if (isset($package['channel'])) {
  782. $name = $package['channel'] . '/' . $package['name'];
  783. } else {
  784. $name = '__uri/' . $package['name'] . ' (static URI)';
  785. }
  786. }
  787. $info[$infoindex] .= "$type $name";
  788. if (isset($package['uri'])) {
  789. $info[$infoindex] .= "\n Download URI: $package[uri]";
  790. continue;
  791. }
  792. if (isset($package['max']) && isset($package['min'])) {
  793. $info[$infoindex] .= " \n Versions " .
  794. $package['min'] . '-' . $package['max'];
  795. } elseif (isset($package['min'])) {
  796. $info[$infoindex] .= " \n Version " .
  797. $package['min'] . ' or newer';
  798. } elseif (isset($package['max'])) {
  799. $info[$infoindex] .= " \n Version " .
  800. $package['max'] . ' or older';
  801. }
  802. if (isset($package['recommended'])) {
  803. $info[$infoindex] .= "\n Recommended version: $package[recommended]";
  804. }
  805. if (isset($package['exclude'])) {
  806. if (!isset($info['Not Compatible with'])) {
  807. $info['Not Compatible with'] = '';
  808. } else {
  809. $info['Not Compatible with'] .= "\n";
  810. }
  811. if (is_array($package['exclude'])) {
  812. $package['exclude'] = implode(', ', $package['exclude']);
  813. }
  814. $package['package'] = $package['name']; // for parsedPackageNameToString
  815. if (isset($package['conflicts'])) {
  816. $info['Not Compatible with'] .= '=> except ';
  817. }
  818. $info['Not Compatible with'] .= 'Package ' .
  819. $reg->parsedPackageNameToString($package, true);
  820. $info['Not Compatible with'] .= "\n Versions " . $package['exclude'];
  821. }
  822. }
  823. }
  824. }
  825. if (isset($deps['required']['os'])) {
  826. if (isset($deps['required']['os']['name'])) {
  827. $dep['required']['os']['name'] = array($dep['required']['os']['name']);
  828. }
  829. foreach ($dep['required']['os'] as $os) {
  830. if (isset($os['conflicts']) && $os['conflicts'] == 'yes') {
  831. if (!isset($info['Not Compatible with'])) {
  832. $info['Not Compatible with'] = '';
  833. } else {
  834. $info['Not Compatible with'] .= "\n";
  835. }
  836. $info['Not Compatible with'] .= "$os[name] Operating System";
  837. } else {
  838. $info['Required Dependencies'] .= "\n";
  839. $info['Required Dependencies'] .= "$os[name] Operating System";
  840. }
  841. }
  842. }
  843. if (isset($deps['required']['arch'])) {
  844. if (isset($deps['required']['arch']['pattern'])) {
  845. $dep['required']['arch']['pattern'] = array($dep['required']['os']['pattern']);
  846. }
  847. foreach ($dep['required']['arch'] as $os) {
  848. if (isset($os['conflicts']) && $os['conflicts'] == 'yes') {
  849. if (!isset($info['Not Compatible with'])) {
  850. $info['Not Compatible with'] = '';
  851. } else {
  852. $info['Not Compatible with'] .= "\n";
  853. }
  854. $info['Not Compatible with'] .= "OS/Arch matching pattern '/$os[pattern]/'";
  855. } else {
  856. $info['Required Dependencies'] .= "\n";
  857. $info['Required Dependencies'] .= "OS/Arch matching pattern '/$os[pattern]/'";
  858. }
  859. }
  860. }
  861. if (isset($deps['optional'])) {
  862. foreach (array('Package', 'Extension') as $type) {
  863. $index = strtolower($type);
  864. if (isset($deps['optional'][$index])) {
  865. if (isset($deps['optional'][$index]['name'])) {
  866. $deps['optional'][$index] = array($deps['optional'][$index]);
  867. }
  868. foreach ($deps['optional'][$index] as $package) {
  869. if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
  870. $infoindex = 'Not Compatible with';
  871. if (!isset($info['Not Compatible with'])) {
  872. $info['Not Compatible with'] = '';
  873. } else {
  874. $info['Not Compatible with'] .= "\n";
  875. }
  876. } else {
  877. $infoindex = 'Optional Dependencies';
  878. if (!isset($info['Optional Dependencies'])) {
  879. $info['Optional Dependencies'] = '';
  880. } else {
  881. $info['Optional Dependencies'] .= "\n";
  882. }
  883. }
  884. if ($index == 'extension') {
  885. $name = $package['name'];
  886. } else {
  887. if (isset($package['channel'])) {
  888. $name = $package['channel'] . '/' . $package['name'];
  889. } else {
  890. $name = '__uri/' . $package['name'] . ' (static URI)';
  891. }
  892. }
  893. $info[$infoindex] .= "$type $name";
  894. if (isset($package['uri'])) {
  895. $info[$infoindex] .= "\n Download URI: $package[uri]";
  896. continue;
  897. }
  898. if ($infoindex == 'Not Compatible with') {
  899. // conflicts is only used to say that all versions conflict
  900. continue;
  901. }
  902. if (isset($package['max']) && isset($package['min'])) {
  903. $info[$infoindex] .= " \n Versions " .
  904. $package['min'] . '-' . $package['max'];
  905. } elseif (isset($package['min'])) {
  906. $info[$infoindex] .= " \n Version " .
  907. $package['min'] . ' or newer';
  908. } elseif (isset($package['max'])) {
  909. $info[$infoindex] .= " \n Version " .
  910. $package['min'] . ' or older';
  911. }
  912. if (isset($package['recommended'])) {
  913. $info[$infoindex] .= "\n Recommended version: $package[recommended]";
  914. }
  915. if (isset($package['exclude'])) {
  916. if (!isset($info['Not Compatible with'])) {
  917. $info['Not Compatible with'] = '';
  918. } else {
  919. $info['Not Compatible with'] .= "\n";
  920. }
  921. if (is_array($package['exclude'])) {
  922. $package['exclude'] = implode(', ', $package['exclude']);
  923. }
  924. $info['Not Compatible with'] .= "Package $package\n Versions " .
  925. $package['exclude'];
  926. }
  927. }
  928. }
  929. }
  930. }
  931. if (isset($deps['group'])) {
  932. if (!isset($deps['group'][0])) {
  933. $deps['group'] = array($deps['group']);
  934. }
  935. foreach ($deps['group'] as $group) {
  936. $info['Dependency Group ' . $group['attribs']['name']] = $group['attribs']['hint'];
  937. $groupindex = $group['attribs']['name'] . ' Contents';
  938. $info[$groupindex] = '';
  939. foreach (array('Package', 'Extension') as $type) {
  940. $index = strtolower($type);
  941. if (isset($group[$index])) {
  942. if (isset($group[$index]['name'])) {
  943. $group[$index] = array($group[$index]);
  944. }
  945. foreach ($group[$index] as $package) {
  946. if (!empty($info[$groupindex])) {
  947. $info[$groupindex] .= "\n";
  948. }
  949. if ($index == 'extension') {
  950. $name = $package['name'];
  951. } else {
  952. if (isset($package['channel'])) {
  953. $name = $package['channel'] . '/' . $package['name'];
  954. } else {
  955. $name = '__uri/' . $package['name'] . ' (static URI)';
  956. }
  957. }
  958. if (isset($package['uri'])) {
  959. if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
  960. $info[$groupindex] .= "Not Compatible with $type $name";
  961. } else {
  962. $info[$groupindex] .= "$type $name";
  963. }
  964. $info[$groupindex] .= "\n Download URI: $package[uri]";
  965. continue;
  966. }
  967. if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
  968. $info[$groupindex] .= "Not Compatible with $type $name";
  969. continue;
  970. }
  971. $info[$groupindex] .= "$type $name";
  972. if (isset($package['max']) && isset($package['min'])) {
  973. $info[$groupindex] .= " \n Versions " .
  974. $package['min'] . '-' . $package['max'];
  975. } elseif (isset($package['min'])) {
  976. $info[$groupindex] .= " \n Version " .
  977. $package['min'] . ' or newer';
  978. } elseif (isset($package['max'])) {
  979. $info[$groupindex] .= " \n Version " .
  980. $package['min'] . ' or older';
  981. }
  982. if (isset($package['recommended'])) {
  983. $info[$groupindex] .= "\n Recommended version: $package[recommended]";
  984. }
  985. if (isset($package['exclude'])) {
  986. if (!isset($info['Not Compatible with'])) {
  987. $info['Not Compatible with'] = '';
  988. } else {
  989. $info[$groupindex] .= "Not Compatible with\n";
  990. }
  991. if (is_array($package['exclude'])) {
  992. $package['exclude'] = implode(', ', $package['exclude']);
  993. }
  994. $info[$groupindex] .= " Package $package\n Versions " .
  995. $package['exclude'];
  996. }
  997. }
  998. }
  999. }
  1000. }
  1001. }
  1002. if ($obj->getPackageType() == 'bundle') {
  1003. $info['Bundled Packages'] = '';
  1004. foreach ($obj->getBundledPackages() as $package) {
  1005. if (!empty($info['Bundled Packages'])) {
  1006. $info['Bundled Packages'] .= "\n";
  1007. }
  1008. if (isset($package['uri'])) {
  1009. $info['Bundled Packages'] .= '__uri/' . $package['name'];
  1010. $info['Bundled Packages'] .= "\n (URI: $package[uri]";
  1011. } else {
  1012. $info['Bundled Packages'] .= $package['channel'] . '/' . $package['name'];
  1013. }
  1014. }
  1015. }
  1016. $info['package.xml version'] = '2.0';
  1017. if ($installed) {
  1018. if ($obj->getLastModified()) {
  1019. $info['Last Modified'] = date('Y-m-d H:i', $obj->getLastModified());
  1020. }
  1021. $v = $obj->getLastInstalledVersion();
  1022. $info['Previous Installed Version'] = $v ? $v : '- None -';
  1023. }
  1024. foreach ($info as $key => $value) {
  1025. $data['data'][] = array($key, $value);
  1026. }
  1027. $data['raw'] = $obj->getArray(); // no validation needed
  1028. $this->ui->outputData($data, 'package-info');
  1029. }
  1030. }