pharcommand.phar 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191
  1. <?php
  2. /** @file phar.php
  3. * @ingroup Phar
  4. * @brief class CLICommand
  5. * @author Marcus Boerger
  6. * @date 2007 - 2008
  7. *
  8. * Phar Command
  9. */
  10. if (!extension_loaded('phar'))
  11. {
  12. if (!class_exists('PHP_Archive', 0)) {
  13. echo "Neither Extension Phar nor class PHP_Archive are available.\n";
  14. exit(1);
  15. }
  16. if (!in_array('phar', stream_get_wrappers())) {
  17. stream_wrapper_register('phar', 'PHP_Archive');
  18. }
  19. if (!class_exists('Phar',0)) {
  20. require 'phar://'.__FILE__.'/phar.inc';
  21. }
  22. }
  23. foreach(array("SPL", "Reflection") as $ext)
  24. {
  25. if (!extension_loaded($ext)) {
  26. echo "$argv[0] requires PHP extension $ext.\n";
  27. exit(1);
  28. }
  29. }
  30. function command_include($file)
  31. {
  32. $file = 'phar://' . __FILE__ . '/' . $file;
  33. if (file_exists($file)) {
  34. include($file);
  35. }
  36. }
  37. function command_autoload($classname)
  38. {
  39. command_include(strtolower($classname) . '.inc');
  40. }
  41. Phar::mapPhar();
  42. spl_autoload_register('command_autoload');
  43. new PharCommand($argc, $argv);
  44. __HALT_COMPILER(); ?>
  45. 6��������� ���pharcommand�������clicommand.incü!��¾<€Xü!��Çší¶���������directorygraphiterator.incÑ��¾<€XÑ��ƒò@Ķ���������directorytreeiterator.incè��¾<€Xè��1s»ã¶���������invertedregexiterator.inc»��¾<€X»��Ñar¶���������phar.inc��¾<€X��CbcD¶���������pharcommand.incRœ��¾<€XRœ��?Œgp¶������<?php
  46. /** @file clicommand.inc
  47. * @ingroup Phar
  48. * @brief class CLICommand
  49. * @author Marcus Boerger
  50. * @date 2007 - 2008
  51. *
  52. * Phar Command
  53. */
  54. /** @ingroup Phar
  55. * @brief Abstract base console command implementation
  56. * @author Marcus Boerger
  57. * @version 1.0
  58. */
  59. abstract class CLICommand
  60. {
  61. protected $argc;
  62. protected $argv;
  63. protected $cmds = array();
  64. protected $args = array();
  65. protected $typs = array();
  66. function __construct($argc, array $argv)
  67. {
  68. $this->argc = $argc;
  69. $this->argv = $argv;
  70. $this->cmds = self::getCommands($this);
  71. $this->typs = self::getArgTyps($this);
  72. if ($argc < 2) {
  73. self::error("No command given, check ${argv[0]} help\n");
  74. } elseif (!isset($this->cmds[$argv[1]]['run'])) {
  75. self::error("Unknown command '${argv[1]}', check ${argv[0]} help\n");
  76. } else {
  77. $command = $argv[1];
  78. }
  79. if (isset($this->cmds[$command]['arg'])) {
  80. $this->args = call_user_func(array($this, $this->cmds[$command]['arg']));
  81. $i = 1;
  82. $missing = false;
  83. while (++$i < $argc) {
  84. if ($argv[$i][0] == '-') {
  85. if (strlen($argv[$i]) == 2 && isset($this->args[$argv[$i][1]])) {
  86. $arg = $argv[$i][1];
  87. if (++$i >= $argc) {
  88. self::error("Missing argument to parameter '$arg' of command '$command', check ${argv[0]} help\n");
  89. } else {
  90. $this->args[$arg]['val'] = $this->checkArgTyp($arg, $i, $argc, $argv);
  91. }
  92. } else {
  93. self::error("Unknown parameter '${argv[$i]}' to command $command, check ${argv[0]} help\n");
  94. }
  95. } else {
  96. break;
  97. }
  98. }
  99. if (isset($this->args[''])) {
  100. if ($i >= $argc) {
  101. if (isset($this->args['']['require']) && $this->args['']['require']) {
  102. self::error("Missing default trailing arguments to command $command, check ${argv[0]} help\n");
  103. }
  104. } else {
  105. $this->args['']['val'] = array();
  106. while($i < $argc) {
  107. $this->args['']['val'][] = $argv[$i++];
  108. }
  109. }
  110. } else if ($i < $argc) {
  111. self::error("Unexpected default arguments to command $command, check ${argv[0]} help\n");
  112. }
  113. foreach($this->args as $arg => $inf) {
  114. if (strlen($arg) && !isset($inf['val']) && isset($inf['required']) && $inf['required']) {
  115. $missing .= "Missing parameter '-$arg' to command $command, check ${argv[0]} help\n";
  116. }
  117. }
  118. if (strlen($missing)) {
  119. self::error($missing);
  120. }
  121. }
  122. call_user_func(array($this, $this->cmds[$command]['run']), $this->args);
  123. }
  124. static function notice ($msg)
  125. {
  126. fprintf(STDERR, $msg);
  127. }
  128. static function error ($msg, $exit_code = 1)
  129. {
  130. self::notice($msg);
  131. exit($exit_code);
  132. }
  133. function checkArgTyp($arg, $i, $argc, $argv)
  134. {
  135. $typ = $this->args[$arg]['typ'];
  136. if (isset($this->typs[$typ]['typ'])) {
  137. return call_user_func(array($this, $this->typs[$typ]['typ']), $argv[$i], $this->args[$arg], $arg);
  138. } else {
  139. return $argv[$i];
  140. }
  141. }
  142. static function getSubFuncs(CLICommand $cmdclass, $prefix, array $subs)
  143. {
  144. $a = array();
  145. $r = new ReflectionClass($cmdclass);
  146. $l = strlen($prefix);
  147. foreach($r->getMethods() as $m) {
  148. if (substr($m->name, 0, $l) == $prefix) {
  149. foreach($subs as $sub) {
  150. $what = substr($m->name, $l+strlen($sub)+1);
  151. $func = $prefix . $sub . '_' . $what;
  152. $what = str_replace('_', '-', $what);
  153. if ($r->hasMethod($func)) {
  154. if (!isset($a[$what])) {
  155. $a[$what] = array();
  156. }
  157. $a[$what][$sub] = /*$m->class . '::' .*/ $func;
  158. }
  159. }
  160. }
  161. }
  162. return $a;
  163. }
  164. static function getCommands(CLICommand $cmdclass)
  165. {
  166. return self::getSubFuncs($cmdclass, 'cli_cmd_', array('arg','inf','run'));
  167. }
  168. static function getArgTyps(CLICommand $cmdclass)
  169. {
  170. return self::getSubFuncs($cmdclass, 'cli_arg_', array('typ'));
  171. }
  172. static function cli_arg_typ_bool($arg, $cfg, $key)
  173. {
  174. return (bool)$arg;
  175. }
  176. static function cli_arg_typ_int($arg, $cfg, $key)
  177. {
  178. if ((int)$arg != $arg) {
  179. self::error("Argument to -$key must be an integer.\n");
  180. }
  181. return (int)$arg;
  182. }
  183. static function cli_arg_typ_regex($arg, $cfg, $key)
  184. {
  185. if (strlen($arg)) {
  186. if (strlen($arg) > 1 && $arg[0] == $arg[strlen($arg)-1] && strpos('/,', $arg) !== false) {
  187. return $arg;
  188. } else {
  189. return '/' . $arg . '/';
  190. }
  191. } else {
  192. return NULL;
  193. }
  194. }
  195. static function cli_arg_typ_select($arg, $cfg, $key)
  196. {
  197. if (!in_array($arg, array_keys($cfg['select']))) {
  198. self::error("Parameter value '$arg' not one of '" . join("', '", array_keys($cfg['select'])) . "'.\n");
  199. }
  200. return $arg;
  201. }
  202. static function cli_arg_typ_dir($arg, $cfg, $key)
  203. {
  204. $f = realpath($arg);
  205. if ($f===false || !file_exists($f) || !is_dir($f)) {
  206. self::error("Requested path '$arg' does not exist.\n");
  207. }
  208. return $f;
  209. }
  210. static function cli_arg_typ_file($arg)
  211. {
  212. $f = new SplFileInfo($arg);
  213. $f = $f->getRealPath();
  214. if ($f===false || !file_exists($f)) {
  215. echo "Requested file '$arg' does not exist.\n";
  216. exit(1);
  217. }
  218. return $f;
  219. }
  220. static function cli_arg_typ_filenew($arg, $cfg, $key)
  221. {
  222. $d = dirname($arg);
  223. $f = realpath($d);
  224. if ($f === false) {
  225. self::error("Path for file '$arg' does not exist.\n");
  226. }
  227. return $f . '/' . basename($arg);
  228. }
  229. static function cli_arg_typ_filecont($arg, $cfg, $key)
  230. {
  231. return file_get_contents(self::cli_arg_typ_file($arg, $cfg, $key));
  232. }
  233. function cli_get_SP2($l1, $arg_inf)
  234. {
  235. return str_repeat(' ', $l1 + 2 + 4 + 8);
  236. }
  237. function cli_get_SP3($l1, $l2, $arg_inf)
  238. {
  239. return str_repeat(' ', $l1 + 2 + 4 + 8 + 2 + $l2 + 2);
  240. }
  241. static function cli_cmd_inf_help()
  242. {
  243. return "This help or help for a selected command.";
  244. }
  245. private function cli_wordwrap($what, $l, $sp)
  246. {
  247. $p = max(79 - $l, 40); // minimum length for paragraph
  248. $b = substr($what, 0, $l); // strip out initial $l
  249. $r = substr($what, $l); // remainder
  250. $r = str_replace("\n", "\n".$sp, $r); // in remainder replace \n's
  251. return $b . wordwrap($r, $p, "\n".$sp);
  252. }
  253. private function cli_help_get_args($func, $l, $sp, $required)
  254. {
  255. $inf = "";
  256. foreach(call_user_func($func, $l, $sp) as $arg => $conf) {
  257. if ((isset($conf['required']) && $conf['required']) != $required) {
  258. continue;
  259. }
  260. if (strlen($arg)) {
  261. $arg = "-$arg ";
  262. } else {
  263. $arg = "... ";
  264. }
  265. $sp2 = $this->cli_get_SP2($l, $inf);
  266. $l2 = strlen($sp2);
  267. $inf .= $this->cli_wordwrap($sp . $arg . $conf['inf'], $l2, $sp2) . "\n";
  268. if (isset($conf['select']) && count($conf['select'])) {
  269. $ls = 0;
  270. foreach($conf['select'] as $opt => $what) {
  271. $ls = max($ls, strlen($opt));
  272. }
  273. $sp3 = $this->cli_get_SP3($l, $ls, $inf);
  274. $l3 = strlen($sp3);
  275. foreach($conf['select'] as $opt => $what) {
  276. $inf .= $this->cli_wordwrap($sp2 . " " . sprintf("%-${ls}s ", $opt) . $what, $l3, $sp3) . "\n";
  277. }
  278. }
  279. }
  280. if (strlen($inf)) {
  281. if ($required) {
  282. return $sp . "Required arguments:\n\n" . $inf;
  283. } else {
  284. return $sp . "Optional arguments:\n\n". $inf;
  285. }
  286. }
  287. }
  288. function cli_cmd_arg_help()
  289. {
  290. return array('' => array('typ'=>'any','val'=>NULL,'inf'=>'Optional command to retrieve help for.'));
  291. }
  292. function cli_cmd_run_help()
  293. {
  294. $argv = $this->argv;
  295. $which = $this->args['']['val'];
  296. if (isset($which)) {
  297. if (count($which) != 1) {
  298. self::error("More than one command given.\n");
  299. }
  300. $which = $which[0];
  301. if (!array_key_exists($which, $this->cmds)) {
  302. if (strtolower($which) == 'commands') {
  303. self::cli_cmd_run_help_list();
  304. exit(0);
  305. }
  306. self::error("Unknown command, cannot retrieve help.\n");
  307. }
  308. $l = strlen($which);
  309. $cmds = array($which => $this->cmds[$which]);
  310. } else {
  311. echo "\n$argv[0] <command> [options]\n\n";
  312. $l = 0;
  313. ksort($this->cmds);
  314. foreach($this->cmds as $name => $funcs) {
  315. $l = max($l, strlen($name));
  316. }
  317. $inf = "Commands:";
  318. $lst = "";
  319. $ind = strlen($inf) + 1;
  320. foreach($this->cmds as $name => $funcs) {
  321. $lst .= ' ' . $name;
  322. }
  323. echo $this->cli_wordwrap($inf.$lst, $ind, str_repeat(' ', $ind)) . "\n\n";
  324. $cmds = $this->cmds;
  325. }
  326. $sp = str_repeat(' ', $l + 2);
  327. foreach($cmds as $name => $funcs) {
  328. $inf = $name . substr($sp, strlen($name));
  329. if (isset($funcs['inf'])) {
  330. $inf .= $this->cli_wordwrap(call_user_func(array($this, $funcs['inf'])), $l, $sp) . "\n";
  331. if (isset($funcs['arg'])) {
  332. $inf .= "\n";
  333. $inf .= $this->cli_help_get_args(array($this, $funcs['arg']), $l, $sp, true);
  334. $inf .= "\n";
  335. $inf .= $this->cli_help_get_args(array($this, $funcs['arg']), $l, $sp, false);
  336. }
  337. }
  338. echo "$inf\n\n";
  339. }
  340. exit(0);
  341. }
  342. static function cli_cmd_inf_help_list()
  343. {
  344. return "Lists available commands.";
  345. }
  346. function cli_cmd_run_help_list()
  347. {
  348. ksort($this->cmds);
  349. echo join(' ', array_keys($this->cmds)) . "\n";
  350. }
  351. }
  352. ?>
  353. <?php
  354. /** @file directorygraphiterator.inc
  355. * @ingroup Examples
  356. * @brief class DirectoryGraphIterator
  357. * @author Marcus Boerger
  358. * @date 2003 - 2008
  359. *
  360. * SPL - Standard PHP Library
  361. */
  362. /** @ingroup Examples
  363. * @brief A tree iterator that only shows directories.
  364. * @author Marcus Boerger
  365. * @version 1.1
  366. */
  367. class DirectoryGraphIterator extends DirectoryTreeIterator
  368. {
  369. function __construct($path)
  370. {
  371. RecursiveIteratorIterator::__construct(
  372. new RecursiveCachingIterator(
  373. new ParentIterator(
  374. new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME
  375. )
  376. ),
  377. CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
  378. ),
  379. parent::SELF_FIRST
  380. );
  381. }
  382. }
  383. ?><?php
  384. /** @file directorytreeiterator.inc
  385. * @ingroup Examples
  386. * @brief class DirectoryTreeIterator
  387. * @author Marcus Boerger
  388. * @date 2003 - 2008
  389. *
  390. * SPL - Standard PHP Library
  391. */
  392. /** @ingroup Examples
  393. * @brief DirectoryIterator to generate ASCII graphic directory trees
  394. * @author Marcus Boerger
  395. * @version 1.1
  396. */
  397. class DirectoryTreeIterator extends RecursiveIteratorIterator
  398. {
  399. /** Construct from a path.
  400. * @param $path directory to iterate
  401. */
  402. function __construct($path)
  403. {
  404. parent::__construct(
  405. new RecursiveCachingIterator(
  406. new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME
  407. ),
  408. CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
  409. ),
  410. parent::SELF_FIRST
  411. );
  412. }
  413. /** @return the current element prefixed with ASCII graphics
  414. */
  415. function current()
  416. {
  417. $tree = '';
  418. for ($l=0; $l < $this->getDepth(); $l++) {
  419. $tree .= $this->getSubIterator($l)->hasNext() ? '| ' : ' ';
  420. }
  421. return $tree . ($this->getSubIterator($l)->hasNext() ? '|-' : '\-')
  422. . $this->getSubIterator($l)->__toString();
  423. }
  424. /** Aggregates the inner iterator
  425. */
  426. function __call($func, $params)
  427. {
  428. return call_user_func_array(array($this->getSubIterator(), $func), $params);
  429. }
  430. }
  431. ?><?php
  432. /** @file invertedregexiterator.inc
  433. * @ingroup Phar
  434. * @brief class InvertedRegexIterator
  435. * @author Marcus Boerger
  436. * @date 2007 - 2008
  437. *
  438. * Inverted RegexIterator
  439. */
  440. /** @ingroup Phar
  441. * @brief Inverted RegexIterator
  442. * @author Marcus Boerger
  443. * @version 1.0
  444. */
  445. class InvertedRegexIterator extends RegexIterator
  446. {
  447. /** @return !RegexIterator::accept()
  448. */
  449. function accept()
  450. {
  451. return !RegexIterator::accept();
  452. }
  453. }
  454. ?><?php
  455. /**
  456. * @file phar.inc
  457. * @ingroup Phar
  458. * @brief class Phar
  459. * @author Marcus Boerger
  460. * @date 2007 - 2008
  461. *
  462. * Phar Command
  463. */
  464. // {{{ class Phar extends PHP_Archive
  465. /**
  466. * Phar class
  467. *
  468. * @ingroup Phar
  469. * @brief Phar implementation
  470. * @author Marcus Boerger
  471. * @version 1.0
  472. */
  473. class Phar extends PHP_Archive implements RecursiveIterator
  474. {
  475. function getSignature()
  476. {
  477. return false;
  478. }
  479. function getAlias()
  480. {
  481. return false;
  482. }
  483. function rewind()
  484. {
  485. }
  486. function valid()
  487. {
  488. return false;
  489. }
  490. function current()
  491. {
  492. }
  493. function key()
  494. {
  495. }
  496. function next()
  497. {
  498. }
  499. function hasChildren()
  500. {
  501. return false;
  502. }
  503. function getChildren()
  504. {
  505. }
  506. function hasMetadata()
  507. {
  508. }
  509. function getMetadata()
  510. {
  511. }
  512. function getStub()
  513. {
  514. }
  515. function setStub()
  516. {
  517. }
  518. }
  519. ?><?php
  520. /**
  521. * @file pharcommand.inc
  522. * @ingroup Phar
  523. * @brief class CLICommand
  524. * @author Marcus Boerger
  525. * @date 2007 - 2008
  526. *
  527. * Phar Command
  528. */
  529. // {{{ class PharCommand extends CLICommand
  530. /**
  531. * PharCommand class
  532. *
  533. * This class handles the handling of the phar
  534. * commands. It will be used from command line/console
  535. * in order to retrieve and execute phar functions.
  536. *
  537. * @ingroup Phar
  538. * @brief Phar console command implementation
  539. * @author Marcus Boerger
  540. * @version 1.0
  541. */
  542. class PharCommand extends CLICommand
  543. {
  544. // {{{ public function cli_get_SP2
  545. public function cli_get_SP2($l1, $arg_inf)
  546. {
  547. return str_repeat(' ', $l1 + 2 + 4 + 9);
  548. }
  549. // }}}
  550. // {{{ public function cli_get_SP3
  551. /**
  552. * Cli Get SP3
  553. *
  554. * @param string $l1 Eleven
  555. * @param string $l2 Twelve
  556. * @param string $arg_inf
  557. * @return string The repeated string.
  558. */
  559. function cli_get_SP3($l1, $l2, $arg_inf)
  560. {
  561. return str_repeat(' ', $l1 + 2 + 4 + 9 + 2 + $l2 + 2);
  562. }
  563. // }}}
  564. // {{{ static function phar_args
  565. /**
  566. * Phar arguments
  567. *
  568. * This function contains all the phar commands
  569. *
  570. * @param string $which Which argument is chosen.
  571. * @param string $phartype The type of phar, specific file to work on
  572. * @return unknown
  573. */
  574. static function phar_args($which, $phartype)
  575. {
  576. $phar_args = array(
  577. 'a' => array(
  578. 'typ' => 'alias',
  579. 'val' => NULL,
  580. 'inf' => '<alias> Provide an alias name for the phar file.'
  581. ),
  582. 'b' => array(
  583. 'typ' => 'any',
  584. 'val' => NULL,
  585. 'inf' => '<bang> Hash-bang line to start the archive (e.g. #!/usr/bin/php). The hash '
  586. .' mark itself \'#!\' and the newline character are optional.'
  587. ),
  588. 'c' => array(
  589. 'typ' => 'compalg',
  590. 'val' => NULL,
  591. 'inf' => '<algo> Compression algorithm.',
  592. 'select' => array(
  593. '0' => 'No compression',
  594. 'none' => 'No compression',
  595. 'auto' => 'Automatically select compression algorithm'
  596. )
  597. ),
  598. 'e' => array(
  599. 'typ' => 'entry',
  600. 'val' => NULL,
  601. 'inf' => '<entry> Name of entry to work on (must include PHAR internal directory name if any).'
  602. ),
  603. 'f' => array(
  604. 'typ' => $phartype,
  605. 'val' => NULL,
  606. 'inf' => '<file> Specifies the phar file to work on.'
  607. ),
  608. 'h' => array(
  609. 'typ' => 'select',
  610. 'val' => NULL,
  611. 'inf' => '<method> Selects the hash algorithm.',
  612. 'select' => array('md5' => 'MD5','sha1' => 'SHA1')
  613. ),
  614. 'i' => array(
  615. 'typ' => 'regex',
  616. 'val' => NULL,
  617. 'inf' => '<regex> Specifies a regular expression for input files.'
  618. ),
  619. 'k' => array(
  620. 'typ' => 'any',
  621. 'val' => NULL,
  622. 'inf' => '<index> Subscription index to work on.',
  623. ),
  624. 'l' => array(
  625. 'typ' => 'int',
  626. 'val' => 0,
  627. 'inf' => '<level> Number of preceding subdirectories to strip from file entries',
  628. ),
  629. 'm' => array(
  630. 'typ' => 'any',
  631. 'val' => NULL,
  632. 'inf' => '<meta> Meta data to store with entry (serialized php data).'
  633. ),
  634. 'p' => array(
  635. 'typ' => 'loader',
  636. 'val' => NULL,
  637. 'inf' => '<loader> Location of PHP_Archive class file (pear list-files PHP_Archive).'
  638. .'You can use \'0\' or \'1\' to locate it automatically using the mentioned '
  639. .'pear command. When using \'0\' the command does not error out when the '
  640. .'class file cannot be located. This switch also adds some code around the '
  641. .'stub so that class PHP_Archive gets registered as phar:// stream wrapper '
  642. .'if necessary. And finally this switch will add the file phar.inc from '
  643. .'this package and load it to ensure class Phar is present.'
  644. ,
  645. ),
  646. 's' => array(
  647. 'typ' => 'file',
  648. 'val' => NULL,
  649. 'inf' => '<stub> Select the stub file.'
  650. ),
  651. 'x' => array(
  652. 'typ' => 'regex',
  653. 'val' => NULL,
  654. 'inf' => '<regex> Regular expression for input files to exclude.'
  655. ),
  656. 'y' => array(
  657. 'typ' => 'privkey',
  658. 'val' => NULL,
  659. 'inf' => '<key> Private key for OpenSSL signing.',
  660. ),
  661. );
  662. if (extension_loaded('zlib')) {
  663. $phar_args['c']['select']['gz'] = 'GZip compression';
  664. $phar_args['c']['select']['gzip'] = 'GZip compression';
  665. }
  666. if (extension_loaded('bz2')) {
  667. $phar_args['c']['select']['bz2'] = 'BZip2 compression';
  668. $phar_args['c']['select']['bzip2'] = 'BZip2 compression';
  669. }
  670. $hash_avail = Phar::getSupportedSignatures();
  671. $hash_optional = array('SHA-256' => 'SHA256',
  672. 'SHA-512' => 'SHA512',
  673. 'OpenSSL' => 'OpenSSL');
  674. if (!in_array('OpenSSL', $hash_avail)) {
  675. unset($phar_args['y']);
  676. }
  677. foreach($hash_optional as $key => $name) {
  678. if (in_array($key, $hash_avail)) {
  679. $phar_args['h']['select'][strtolower($name)] = $name;
  680. }
  681. }
  682. $args = array();
  683. foreach($phar_args as $lkey => $cfg) {
  684. $ukey = strtoupper($lkey);
  685. $required = strpos($which, $ukey) !== false;
  686. $optional = strpos($which, $lkey) !== false;
  687. if ($required || $optional) {
  688. $args[$lkey] = $cfg;
  689. $args[$lkey]['required'] = $required;
  690. }
  691. }
  692. return $args;
  693. }
  694. // }}}
  695. // {{{ static function strEndsWith
  696. /**
  697. * String Ends With
  698. *
  699. * Whether a string ends with another needle.
  700. *
  701. * @param string $haystack The haystack
  702. * @param string $needle The needle.
  703. * @return mixed false if doesn't end with anything, the string
  704. * substr'ed if the string ends with the needle.
  705. */
  706. static function strEndsWith($haystack, $needle)
  707. {
  708. return substr($haystack, -strlen($needle)) == $needle;
  709. }
  710. // }}}
  711. // {{{ static function cli_arg_typ_loader
  712. /**
  713. * Argument type loader
  714. *
  715. * @param string $arg Either 'auto', 'optional' or an filename that
  716. * contains class PHP_Archive
  717. * @param string $cfg Configuration to pass to a new file
  718. * @param string $key The key
  719. * @return string $arg The argument.
  720. */
  721. static function cli_arg_typ_loader($arg, $cfg, $key)
  722. {
  723. if (($arg == '0' || $arg == '1') && !file_exists($arg) && substr(PHP_OS, 0, 3) != 'WIN') {
  724. $found = NULL;
  725. $apiver = false;
  726. $path = explode(PATH_SEPARATOR, $_ENV['PATH']);
  727. $pear = false;
  728. foreach ($path as $component) {
  729. if (file_exists($component . DIRECTORY_SEPARATOR . 'pear')
  730. && is_executable($component . DIRECTORY_SEPARATOR . 'pear')) {
  731. $pear = true;
  732. break;
  733. }
  734. }
  735. if ($pear) {
  736. $apiver = `pear -q info PHP_Archive 2>/dev/null|grep 'API Version'`;
  737. $apiver = trim(substr($apiver, strlen('API Version')));
  738. }
  739. if ($apiver) {
  740. self::notice("PEAR package PHP_Archive: API Version: $apiver.\n");
  741. $files = explode("\n", `pear list-files PHP_Archive`);
  742. $phpdir = `pear config-get php_dir 2>/dev/null`;
  743. $phpdir = trim($phpdir);
  744. self::notice("PEAR package PHP_Archive: $phpdir.\n");
  745. if (is_dir($phpdir)) {
  746. foreach($files as $ent) {
  747. $matches = NULL;
  748. if (preg_match(",^php[ \t]+([^ \t].*[\\\\/]PHP[\\\\/]Archive\.php)$,", $ent, $matches)) {
  749. $sub = $matches[1];
  750. if (strpos($sub, $phpdir) !== 0) {
  751. $found = NULL;
  752. break;
  753. }
  754. $found = $sub;
  755. break;
  756. }
  757. }
  758. } else {
  759. self::notice("PEAR package PHP_Archive: corrupt or inaccessible base dir: $php_dir.\n");
  760. }
  761. }
  762. if (isset($found)) {
  763. self::notice("PEAR package PHP_Archive: $found.\n");
  764. } else {
  765. $msg = "PEAR package PHP_Archive not installed: generated phar will require PHP's phar extension be enabled.\n";
  766. if ($arg == '0') {
  767. self::notice($msg);
  768. } else {
  769. self::error($msg);
  770. }
  771. }
  772. $arg = $found;
  773. }
  774. return self::cli_arg_typ_file($arg);
  775. }
  776. // }}}
  777. // {{{ static function cli_arg_typ_pharnew
  778. /**
  779. * Argument type new phar
  780. *
  781. * @param string $arg The new phar component.
  782. * @param string $cfg Configuration to pass to a new file
  783. * @param string $key The key
  784. * @return string $arg The new argument file.
  785. */
  786. static function cli_arg_typ_pharnew($arg, $cfg, $key)
  787. {
  788. $arg = self::cli_arg_typ_filenew($arg, $cfg, $key);
  789. if (!Phar::isValidPharFilename($arg)) {
  790. self::error("Phar files must have file extension '.phar', '.phar.php', '.phar.bz2' or '.phar.gz'.\n");
  791. }
  792. return $arg;
  793. }
  794. // }}}
  795. // {{{ static function cli_arg_typ_pharfile
  796. /**
  797. * Argument type existing Phar file
  798. *
  799. * Return filename of an existing Phar.
  800. *
  801. * @param string $arg The file in the phar to open.
  802. * @param string $cfg The configuration information
  803. * @param string $key The key information.
  804. * @return string $pharfile The name of the loaded Phar file.
  805. * @note The Phar will be loaded
  806. */
  807. static function cli_arg_typ_pharfile($arg, $cfg, $key)
  808. {
  809. try {
  810. $pharfile = self::cli_arg_typ_file($arg, $cfg, $key);
  811. if (!Phar::loadPhar($pharfile)) {
  812. self::error("Unable to open phar '$arg'\n");
  813. }
  814. return $pharfile;
  815. } catch(Exception $e) {
  816. self::error("Exception while opening phar '$arg':\n" . $e->getMessage() . "\n");
  817. }
  818. }
  819. // }}}
  820. // {{{ static function cli_arg_typ_pharurl
  821. /**
  822. * Argument type Phar url-like
  823. *
  824. * Check the argument as cli_arg_Typ_phar and return its name prefixed
  825. * with phar://
  826. *
  827. * Ex:
  828. * <code>
  829. * $arg = 'pharchive.phar/file.php';
  830. * cli_arg_typ_pharurl($arg)
  831. * </code>
  832. *
  833. * @param string $arg The url-like phar archive to retrieve.
  834. * @return string The phar file-archive.
  835. */
  836. static function cli_arg_typ_pharurl($arg, $cfg, $key)
  837. {
  838. return 'phar://' . self::cli_arg_typ_pharfile($arg, $cfg, $key);
  839. }
  840. // }}}
  841. // {{{ static function cli_arg_typ_phar
  842. /**
  843. * Cli argument type phar
  844. *
  845. * @param string $arg The phar archive to use.
  846. * @return object new Phar of the passed argument.
  847. */
  848. static function cli_arg_typ_phar($arg, $cfg, $key)
  849. {
  850. try {
  851. return new Phar(self::cli_arg_typ_pharfile($arg, $cfg, $key));
  852. } catch(Exception $e) {
  853. self::error("Exception while opening phar '$argv':\n" . $e->getMessage() . "\n");
  854. }
  855. }
  856. // }}}
  857. // {{{ static function cli_arg_typ_entry
  858. /**
  859. * Argument type Entry name
  860. *
  861. * @param string $arg The argument (the entry)
  862. * @return string $arg The entry itself.
  863. */
  864. static function cli_arg_typ_entry($arg, $cfg, $key)
  865. {
  866. // no further check atm, maybe check for no '/' at beginning
  867. return $arg;
  868. }
  869. // }}}
  870. // {{{ static function cli_arg_typ_compalg
  871. /**
  872. * Argument type compression algorithm
  873. *
  874. * @param string $arg The phar selection
  875. * @param string $cfg The config option.
  876. * @param string $key The key information.
  877. * @return string $arg The selected algorithm
  878. */
  879. static function cli_arg_typ_compalg($arg, $cfg, $key)
  880. {
  881. $arg = self::cli_arg_typ_select($arg, $cfg, $key);
  882. switch($arg) {
  883. case 'auto':
  884. if (extension_loaded('zlib')) {
  885. $arg = 'gz';
  886. } elseif (extension_loaded('bz2')) {
  887. $arg = 'bz2';
  888. } else {
  889. $arg = '0';
  890. }
  891. break;
  892. }
  893. return $arg;
  894. }
  895. // }}}
  896. // {{{ static function cli_arg_typ_privkey
  897. /**
  898. * Argument type private key (for OpenSSL signing)
  899. *
  900. * @param string $arg The phar selection
  901. * @param string $cfg The config option.
  902. * @param string $key The key information.
  903. * @return string $arg The private key.
  904. */
  905. static function cli_arg_typ_privkey($arg, $cfg, $key)
  906. {
  907. $arg = self::cli_arg_typ_filecont($arg, $cfg, $key);
  908. $hash_avail = Phar::getSupportedSignatures();
  909. if ($arg && !in_array('OpenSSL', $hash_avail))
  910. {
  911. self::error("Cannot specifiy private key without OpenSSL support.\n");
  912. }
  913. return $arg;
  914. }
  915. // }}}
  916. // {{{ static function phar_check_hash
  917. /**
  918. * Check whether hash method is valid.
  919. *
  920. * @return Hash constant to be used.
  921. */
  922. function phar_check_hash($hash, $privkey)
  923. {
  924. switch($hash) {
  925. case 'md5':
  926. return Phar::MD5;
  927. case 'sha1':
  928. return Phar::SHA1;
  929. case 'sha256':
  930. return Phar::SHA256;
  931. case 'sha512':
  932. return Phar::SHA512;
  933. case 'openssl':
  934. if (!$privkey) {
  935. self::error("Cannot use OpenSSL signing without key.\n");
  936. }
  937. return Phar::OPENSSL;
  938. }
  939. }
  940. // }}}
  941. // {{{ static function cli_cmd_inf_pack
  942. /**
  943. * Information pack
  944. *
  945. * @return string A description about packing files into a Phar archive.
  946. */
  947. static function cli_cmd_inf_pack()
  948. {
  949. return "Pack files into a PHAR archive.\n" .
  950. "When using -s <stub>, then the stub file is being " .
  951. "excluded from the list of input files/dirs." .
  952. "To create an archive that contains PEAR class PHP_Archive " .
  953. "then point -p argument to PHP/Archive.php.\n";
  954. }
  955. // }}}
  956. // {{{ static function cli_cmd_arg_pack
  957. /**
  958. * Pack a new phar infos
  959. *
  960. * @return array $args The arguments for a new Phar archive.
  961. */
  962. static function cli_cmd_arg_pack()
  963. {
  964. $args = self::phar_args('abcFhilpsxy', 'pharnew');
  965. $args[''] = array(
  966. 'typ' => 'any',
  967. 'val' => NULL,
  968. 'required' => 1,
  969. 'inf' => ' Any number of input files and directories. If -i is in use then ONLY files and matching the given regular expression are being packed. If -x is given then files matching that regular expression are NOT being packed.',
  970. );
  971. return $args;
  972. }
  973. // }}}
  974. // {{{ function phar_set_stub_begin
  975. /**
  976. * Set the stub
  977. */
  978. public function phar_set_stub_begin(Phar $phar, $stub, $loader = NULL, $hashbang = NULL)
  979. {
  980. if (isset($stub)) {
  981. $c = file_get_contents($stub);
  982. if (substr($c, 0, 2) == '#!') {
  983. if (strpos($c, "\n") !== false) {
  984. if (!isset($hashbang)) {
  985. $hashbang = substr($c, 0, strpos($c, "\n") + 1);
  986. }
  987. $c = substr($c, strpos($c, "\n") + 1);
  988. } else {
  989. if (!isset($hashbang)) {
  990. $hashbang = $c;
  991. }
  992. $c = NULL;
  993. }
  994. }
  995. if (isset($hashbang)) {
  996. if (substr($hashbang, 0, 2) != '#!') {
  997. $hashbang = '#!' . $hashbang;
  998. }
  999. if (substr($hashbang, -1) != "\n") {
  1000. $hashbang .= "\n";
  1001. }
  1002. } else {
  1003. $hashbang = "";
  1004. }
  1005. if (isset($loader)) {
  1006. $s = "<?php if (!class_exists('PHP_Archive')) {\n?>";
  1007. if (is_file($loader)) {
  1008. $s .= file_get_contents($loader);
  1009. }
  1010. $s .= "<?php\n";
  1011. $s .= "}\n";
  1012. $s .= "if (!in_array('phar', stream_get_wrappers())) {\n";
  1013. $s .= "\tstream_wrapper_register('phar', 'PHP_Archive');\n";
  1014. $s .= "}\n";
  1015. $s .= "if (!class_exists('Phar',0)) {\n";
  1016. $s .= "\tinclude 'phar://'.__FILE__.'/phar.inc';\n";
  1017. $s .= "}\n";
  1018. $s .= '?>';
  1019. $s .= $c;
  1020. $phar->setStub($hashbang . $s);
  1021. } else {
  1022. $phar->setStub($hashbang . $c);
  1023. }
  1024. return new SplFileInfo($stub);
  1025. }
  1026. return NULL;
  1027. }
  1028. // }}}
  1029. // {{{ function phar_set_stub_end
  1030. /**
  1031. * Set stub end
  1032. */
  1033. public function phar_set_stub_end(Phar $phar, $stub, $loader = NULL)
  1034. {
  1035. if (isset($stub) && isset($loader)) {
  1036. if (substr(__FILE__, -15) == 'pharcommand.inc') {
  1037. self::phar_add_file($phar, 0, 'phar.inc', 'phar://'.__FILE__.'/phar.inc', NULL);
  1038. } else {
  1039. self::phar_add_file($phar, 0, 'phar.inc', dirname(__FILE__).'/phar/phar.inc', NULL);
  1040. }
  1041. }
  1042. }
  1043. // }}}
  1044. // {{{ function cli_cmd_run_pack
  1045. /**
  1046. * Pack a new Phar
  1047. *
  1048. * This function will try to pack a new Phar archive.
  1049. *
  1050. * @see Exit to make sure that we are done.
  1051. */
  1052. public function cli_cmd_run_pack()
  1053. {
  1054. if (ini_get('phar.readonly')) {
  1055. self::error("Creating phar files is disabled by ini setting 'phar.readonly'.\n");
  1056. }
  1057. if (!Phar::canWrite()) {
  1058. self::error("Creating phar files is disabled, Phar::canWrite() returned false.\n");
  1059. }
  1060. $alias = $this->args['a']['val'];
  1061. $hashbang = $this->args['b']['val'];
  1062. $archive = $this->args['f']['val'];
  1063. $hash = $this->args['h']['val'];
  1064. $privkey = $this->args['y']['val'];
  1065. $regex = $this->args['i']['val'];
  1066. $level = $this->args['l']['val'];
  1067. $loader = $this->args['p']['val'];
  1068. $stub = $this->args['s']['val'];
  1069. $invregex = $this->args['x']['val'];
  1070. $input = $this->args['']['val'];
  1071. $hash = self::phar_check_hash($hash, $privkey);
  1072. $phar = new Phar($archive, 0, $alias);
  1073. $phar->startBuffering();
  1074. $stub = $this->phar_set_stub_begin($phar, $stub, $loader, $hashbang);
  1075. if (!is_array($input)) {
  1076. $this->phar_add($phar, $level, $input, $regex, $invregex, $stub, NULL, isset($loader));
  1077. } else {
  1078. foreach($input as $i) {
  1079. $this->phar_add($phar, $level, $i, $regex, $invregex, $stub, NULL, isset($loader));
  1080. }
  1081. }
  1082. $this->phar_set_stub_end($phar, $stub, $loader);
  1083. switch($this->args['c']['val']) {
  1084. case 'gz':
  1085. case 'gzip':
  1086. $phar->compressFiles(Phar::GZ);
  1087. break;
  1088. case 'bz2':
  1089. case 'bzip2':
  1090. $phar->compressFiles(Phar::BZ2);
  1091. break;
  1092. default:
  1093. $phar->decompressFiles();
  1094. break;
  1095. }
  1096. if ($hash) {
  1097. $phar->setSignatureAlgorithm($hash, $privkey);
  1098. }
  1099. $phar->stopBuffering();
  1100. exit(0);
  1101. }
  1102. // }}}
  1103. // {{{ static function phar_add
  1104. /**
  1105. * Add files to a phar archive.
  1106. *
  1107. * This function will take a directory and iterate through
  1108. * it and get the files to insert into the Phar archive.
  1109. *
  1110. * @param Phar $phar The phar object.
  1111. * @param string $input The input directory
  1112. * @param string $regex The regex used in RegexIterator.
  1113. * @param string $invregex The InvertedRegexIterator expression.
  1114. * @param SplFileInfo $stub Stub file object
  1115. * @param mixed $compress Compression algorithm or NULL
  1116. * @param boolean $noloader Whether to prevent adding the loader
  1117. */
  1118. static function phar_add(Phar $phar, $level, $input, $regex, $invregex, SplFileInfo $stub = NULL, $compress = NULL, $noloader = false)
  1119. {
  1120. if ($input && is_file($input) && !is_dir($input)) {
  1121. return self::phar_add_file($phar, $level, $input, $input, $compress);
  1122. }
  1123. $dir = new RecursiveDirectoryIterator($input);
  1124. $dir = new RecursiveIteratorIterator($dir);
  1125. if (isset($regex)) {
  1126. $dir = new RegexIterator($dir, $regex);
  1127. }
  1128. if (isset($invregex)) {
  1129. $dir = new InvertedRegexIterator($dir, $invregex);
  1130. }
  1131. try {
  1132. foreach($dir as $file) {
  1133. if ((empty($stub) || $file->getRealPath() != $stub->getRealPath()) && !is_dir($file)) {
  1134. self::phar_add_file($phar, $level, $dir->getSubPathName(), $file, $compress, $noloader);
  1135. }
  1136. }
  1137. } catch(Excpetion $e) {
  1138. self::error("Unable to complete operation on file '$file'\n" . $e->getMessage() . "\n");
  1139. }
  1140. }
  1141. // }}}
  1142. // {{{ static function phar_add_file
  1143. /**
  1144. * Add a phar file
  1145. *
  1146. * This function adds a file to a phar archive.
  1147. *
  1148. * @param Phar $phar The phar object
  1149. * @param string $level The level of the file.
  1150. * @param string $entry The entry point
  1151. * @param string $file The file to add to the archive
  1152. * @param string $compress The compression scheme for the file.
  1153. * @param boolean $noloader Whether to prevent adding the loader
  1154. */
  1155. static function phar_add_file(Phar $phar, $level, $entry, $file, $compress, $noloader = false)
  1156. {
  1157. $entry = str_replace('//', '/', $entry);
  1158. while($level-- > 0 && ($p = strpos($entry, '/')) !== false) {
  1159. $entry = substr($entry, $p+1);
  1160. }
  1161. if ($noloader && $entry == 'phar.inc') {
  1162. return;
  1163. }
  1164. echo "$entry\n";
  1165. $phar[$entry] = file_get_contents($file);
  1166. switch($compress) {
  1167. case 'gz':
  1168. case 'gzip':
  1169. $phar[$entry]->compress(Phar::GZ);
  1170. break;
  1171. case 'bz2':
  1172. case 'bzip2':
  1173. $phar[$entry]->compress(Phar::BZ2);
  1174. break;
  1175. case '0':
  1176. $phar[$entry]->decompress();
  1177. break;
  1178. default:
  1179. break;
  1180. }
  1181. }
  1182. // }}}
  1183. // {{{ public function phar_dir_echo
  1184. /**
  1185. * Echo directory
  1186. *
  1187. * @param string $pn
  1188. * @param unknown_type $f
  1189. */
  1190. public function phar_dir_echo($pn, $f)
  1191. {
  1192. echo "$f\n";
  1193. }
  1194. // }}}
  1195. // {{{ public function phar_dir_operation
  1196. /**
  1197. * Directory operations
  1198. *
  1199. * Phar directory operations.
  1200. *
  1201. * @param RecursiveIteratorIterator $dir The recursiveIteratorIterator object.
  1202. * @param string $func Function to call on the iterations
  1203. * @param array $args Function arguments.
  1204. */
  1205. public function phar_dir_operation(RecursiveIteratorIterator $dir, $func, array $args = array())
  1206. {
  1207. $regex = $this->args['i']['val'];
  1208. $invregex= $this->args['x']['val'];
  1209. if (isset($regex)) {
  1210. $dir = new RegexIterator($dir, $regex);
  1211. }
  1212. if (isset($invregex)) {
  1213. $dir = new InvertedRegexIterator($dir, $invregex);
  1214. }
  1215. $any = false;
  1216. foreach($dir as $pn => $f) {
  1217. $any = true;
  1218. call_user_func($func, $pn, $f, $args);
  1219. }
  1220. return $any;
  1221. }
  1222. // {{{ static function cli_cmd_inf_list
  1223. /**
  1224. * Cli Command Info List
  1225. *
  1226. * @return string What inf does
  1227. */
  1228. static function cli_cmd_inf_list()
  1229. {
  1230. return "List contents of a PHAR archive.";
  1231. }
  1232. // }}}
  1233. // {{{ static function cli_cmd_arg_list
  1234. /**
  1235. * Cli Command Argument List
  1236. *
  1237. * @return arguments list
  1238. */
  1239. static function cli_cmd_arg_list()
  1240. {
  1241. return self::phar_args('Fix', 'pharurl');
  1242. }
  1243. // }}}
  1244. // {{{ public function cli_cmd_run_list
  1245. /**
  1246. * Cli Command Run List
  1247. *
  1248. * @see $this->phar_dir_operation
  1249. */
  1250. public function cli_cmd_run_list()
  1251. {
  1252. $this->phar_dir_operation(
  1253. new DirectoryTreeIterator(
  1254. $this->args['f']['val']),
  1255. array($this, 'phar_dir_echo')
  1256. );
  1257. }
  1258. // }}}
  1259. // {{{ static function cli_command_inf_tree
  1260. /**
  1261. * Cli Command Inf Tree
  1262. *
  1263. * @return string The description of a directory tree for a Phar archive.
  1264. */
  1265. static function cli_cmd_inf_tree()
  1266. {
  1267. return "Get a directory tree for a PHAR archive.";
  1268. }
  1269. // }}}
  1270. // {{{ static function cli_cmd_arg_tree
  1271. /**
  1272. * Cli Command Argument Tree
  1273. *
  1274. * @return string Arguments in URL format.
  1275. */
  1276. static function cli_cmd_arg_tree()
  1277. {
  1278. return self::phar_args('Fix', 'pharurl');
  1279. }
  1280. // }}}
  1281. // {{{ public function cli_cmd_run_tree
  1282. /**
  1283. * Cli Command Run Tree
  1284. *
  1285. * Set the phar_dir_operation with a directorygraphiterator.
  1286. *
  1287. * @see DirectoryGraphIterator
  1288. * @see $this->phar_dir_operation
  1289. *
  1290. */
  1291. public function cli_cmd_run_tree()
  1292. {
  1293. $a = $this->phar_dir_operation(
  1294. new DirectoryGraphIterator(
  1295. $this->args['f']['val']),
  1296. array($this, 'phar_dir_echo')
  1297. );
  1298. if (!$a) {
  1299. echo "|-<root directory>\n";
  1300. }
  1301. }
  1302. // }}}
  1303. // {{{ cli_cmd_inf_extract
  1304. /**
  1305. * Cli Command Inf Extract
  1306. *
  1307. * @return string The description of the command extra to a directory.
  1308. */
  1309. static function cli_cmd_inf_extract()
  1310. {
  1311. return "Extract a PHAR package to a directory.";
  1312. }
  1313. // }}}
  1314. // {{{ static function cli_cmd_arg_extract
  1315. /**
  1316. * Cli Command Arguments Extract
  1317. *
  1318. * The arguments for the extract function.
  1319. *
  1320. * @return array The arguments for the extraction.
  1321. */
  1322. static function cli_cmd_arg_extract()
  1323. {
  1324. $args = self::phar_args('Fix', 'phar');
  1325. $args[''] = array(
  1326. 'type' => 'dir',
  1327. 'val' => '.',
  1328. 'inf' => ' Directory to extract to (defaults to \'.\').',
  1329. );
  1330. return $args;
  1331. }
  1332. // }}}
  1333. // {{{ public function cli_cmd_run_extract
  1334. /**
  1335. * Run Extract
  1336. *
  1337. * Run the extraction of a phar Archive.
  1338. *
  1339. * @see $this->phar_dir_operation
  1340. */
  1341. public function cli_cmd_run_extract()
  1342. {
  1343. $dir = $this->args['']['val'];
  1344. if (is_array($dir)) {
  1345. if (count($dir) != 1) {
  1346. self::error("Only one target directory allowed.\n");
  1347. } else {
  1348. $dir = $dir[0];
  1349. }
  1350. }
  1351. $phar = $this->args['f']['val'];
  1352. $base = $phar->getPathname();
  1353. $bend = strpos($base, '.phar');
  1354. $bend = strpos($base, '/', $bend);
  1355. $base = substr($base, 0, $bend + 1);
  1356. $blen = strlen($base);
  1357. $this->phar_dir_operation(
  1358. new RecursiveIteratorIterator($phar),
  1359. array($this, 'phar_dir_extract'),
  1360. array($blen, $dir)
  1361. );
  1362. }
  1363. // }}}
  1364. // {{{ public function phar_dir_extract
  1365. /**
  1366. * Extract to a directory
  1367. *
  1368. * This function will extract the content of a Phar
  1369. * to a directory and create new files and directories
  1370. * depending on the permissions on that folder.
  1371. *
  1372. * @param string $pn
  1373. * @param string $f The file name
  1374. * @param array $args The directory and Blen informations
  1375. */
  1376. public function phar_dir_extract($pn, $f, $args)
  1377. {
  1378. $blen = $args[0];
  1379. $dir = $args[1];
  1380. $sub = substr($pn, $blen);
  1381. $target = $dir . '/' . $sub;
  1382. if (!file_exists(dirname($target))) {
  1383. @mkdir(dirname($target), 0777, true);
  1384. }
  1385. if (!file_exists(dirname($target))) {
  1386. self::error("Operation could not be completed\n");
  1387. }
  1388. echo "$sub";
  1389. if (!@copy($f, $target)) {
  1390. echo " ...error\n";
  1391. } else {
  1392. echo " ...ok\n";
  1393. }
  1394. }
  1395. // }}}
  1396. // {{{ static function cli_cmd_inf_delete
  1397. /**
  1398. * Delete an entry from a phar information.
  1399. *
  1400. * @return string The information
  1401. */
  1402. static function cli_cmd_inf_delete()
  1403. {
  1404. return 'Delete entry from a PHAR archive';
  1405. }
  1406. // }}}
  1407. // {{{ static function cli_cmd_arg_delete
  1408. /**
  1409. * The cli command argument for deleting.
  1410. *
  1411. * @return array informations about the arguments to use.
  1412. */
  1413. static function cli_cmd_arg_delete()
  1414. {
  1415. return self::phar_args('FE', 'phar');
  1416. }
  1417. // }}}
  1418. // {{{ public function cli_cmd_run_delete
  1419. /**
  1420. * Deleting execution
  1421. *
  1422. * Execute the deleting of the file from the phar archive.
  1423. */
  1424. public function cli_cmd_run_delete()
  1425. {
  1426. $phar = $this->args['f']['val'];
  1427. $entry = $this->args['e']['val'];
  1428. $phar->startBuffering();
  1429. unset($phar[$entry]);
  1430. $phar->stopBuffering();
  1431. }
  1432. // }}}
  1433. // {{{ static function cli_cmd_inf_add
  1434. /**
  1435. * Client comment add file information
  1436. *
  1437. * @return string The description of the feature
  1438. */
  1439. static function cli_cmd_inf_add()
  1440. {
  1441. return "Add entries to a PHAR package.";
  1442. }
  1443. // }}}
  1444. // {{{ static function cli_cmd_arg_add
  1445. /**
  1446. * Add a file arguments
  1447. */
  1448. static function cli_cmd_arg_add()
  1449. {
  1450. $args = self::phar_args('acFilx', 'phar');
  1451. $args[''] = array(
  1452. 'type' => 'any',
  1453. 'val' => NULL,
  1454. 'required' => 1,
  1455. 'inf' => ' Any number of input files and directories. If -i is in use then ONLY files and matching the given regular expression are being packed. If -x is given then files matching that regular expression are NOT being packed.',
  1456. );
  1457. return $args;
  1458. }
  1459. // }}}
  1460. // {{{ public functio cli_cmd_run_add
  1461. /**
  1462. * Add a file
  1463. *
  1464. * Run the action of adding a file to
  1465. * a phar archive.
  1466. */
  1467. public function cli_cmd_run_add()
  1468. {
  1469. $compress= $this->args['c']['val'];
  1470. $phar = $this->args['f']['val'];
  1471. $regex = $this->args['i']['val'];
  1472. $level = $this->args['l']['val'];
  1473. $invregex= $this->args['x']['val'];
  1474. $input = $this->args['']['val'];
  1475. $phar->startBuffering();
  1476. if (!is_array($input)) {
  1477. $this->phar_add($phar, $level, $input, $regex, $invregex, NULL, $compress);
  1478. } else {
  1479. foreach($input as $i) {
  1480. $this->phar_add($phar, $level, $i, $regex, $invregex, NULL, $compress);
  1481. }
  1482. }
  1483. $phar->stopBuffering();
  1484. exit(0);
  1485. }
  1486. // }}}
  1487. // {{{ public function cli_cmd_inf_stub_set
  1488. /**
  1489. * Set the stup of a phar file.
  1490. *
  1491. * @return string The stub set description.
  1492. */
  1493. public function cli_cmd_inf_stub_set()
  1494. {
  1495. return "Set the stub of a PHAR file. " .
  1496. "If no input file is specified as stub then stdin is being used.";
  1497. }
  1498. // }}}
  1499. // {{{ public function cli_cmd_arg_stub_set
  1500. /**
  1501. * Set the argument stub
  1502. *
  1503. * @return string arguments for a stub
  1504. */
  1505. public function cli_cmd_arg_stub_set()
  1506. {
  1507. $args = self::phar_args('bFps', 'phar');
  1508. $args['s']['val'] = 'php://stdin';
  1509. return $args;
  1510. }
  1511. // }}}
  1512. // {{{ public function cli_cmd_run_stub_set
  1513. /**
  1514. * Cli Command run stub set
  1515. *
  1516. * @see $phar->setStub()
  1517. */
  1518. public function cli_cmd_run_stub_set()
  1519. {
  1520. $hashbang = $this->args['b']['val'];
  1521. $phar = $this->args['f']['val'];
  1522. $stub = $this->args['s']['val'];
  1523. $loader = $this->args['p']['val'];
  1524. $this->phar_set_stub_begin($phar, $stub, $loader, $hashbang);
  1525. $this->phar_set_stub_end($phar, $stub, $loader);
  1526. }
  1527. // }}}
  1528. // {{{ public function cli_cmd_inf_stub_get
  1529. /**
  1530. * Get the command stub infos.
  1531. *
  1532. * @return string a description of the stub of a Phar file.
  1533. */
  1534. public function cli_cmd_inf_stub_get()
  1535. {
  1536. return "Get the stub of a PHAR file. " .
  1537. "If no output file is specified as stub then stdout is being used.";
  1538. }
  1539. // }}}
  1540. // {{{ public function cli_cmd_arg_stub_get
  1541. /**
  1542. * Get the argument stub
  1543. *
  1544. * @return array $args The arguments passed to the stub.
  1545. */
  1546. public function cli_cmd_arg_stub_get()
  1547. {
  1548. $args = self::phar_args('Fs', 'phar');
  1549. $args['s']['val'] = 'php://stdin';
  1550. return $args;
  1551. }
  1552. // }}}
  1553. // {{{ public function cli_cmd_run_stub_get
  1554. /**
  1555. * Cli Command Run Stub
  1556. *
  1557. * Get arguments and store them into a stub.
  1558. *
  1559. * @param arguments $args
  1560. * @see $this->args
  1561. */
  1562. public function cli_cmd_run_stub_get($args)
  1563. {
  1564. $phar = $this->args['f']['val'];
  1565. $stub = $this->args['s']['val'];
  1566. file_put_contents($stub, $phar->getStub());
  1567. }
  1568. // }}}
  1569. // {{{ public function cli_cmd_inf_compress
  1570. /**
  1571. * Cli Command Inf Compress
  1572. *
  1573. * Cli Command compress informations
  1574. *
  1575. * @return string A description of the command.
  1576. */
  1577. public function cli_cmd_inf_compress()
  1578. {
  1579. return "Compress or uncompress all files or a selected entry.";
  1580. }
  1581. // }}}
  1582. // {{{ public function cli_cmd_arg_cmpress
  1583. /**
  1584. * Cli Command Arg Compress
  1585. *
  1586. * @return array The arguments for compress
  1587. */
  1588. public function cli_cmd_arg_compress()
  1589. {
  1590. return self::phar_args('FCe', 'phar');
  1591. }
  1592. // }}}
  1593. // {{{ public function cli_cmd_run_compress
  1594. /**
  1595. * Cli Command Run Compress
  1596. *
  1597. * @see $this->args
  1598. */
  1599. public function cli_cmd_run_compress()
  1600. {
  1601. $phar = $this->args['f']['val'];
  1602. $entry = $this->args['e']['val'];
  1603. switch($this->args['c']['val']) {
  1604. case 'gz':
  1605. case 'gzip':
  1606. if (isset($entry)) {
  1607. $phar[$entry]->compress(Phar::GZ);
  1608. } else {
  1609. $phar->compressFiles(Phar::GZ);
  1610. }
  1611. break;
  1612. case 'bz2':
  1613. case 'bzip2':
  1614. if (isset($entry)) {
  1615. $phar[$entry]->compress(Phar::BZ2);
  1616. } else {
  1617. $phar->compressFiles(Phar::BZ2);
  1618. }
  1619. break;
  1620. default:
  1621. if (isset($entry)) {
  1622. $phar[$entry]->decompress();
  1623. } else {
  1624. $phar->decompressFiles();
  1625. }
  1626. break;
  1627. }
  1628. }
  1629. // }}}
  1630. // {{{ public function cli_cmd_inf_sign
  1631. /**
  1632. * Cli Command Info Signature
  1633. *
  1634. * @return string A description of the signature arguments.
  1635. */
  1636. public function cli_cmd_inf_sign()
  1637. {
  1638. return "Set signature hash algorithm.";
  1639. }
  1640. // }}}
  1641. // {{{ public function cli_cmd_arg_sign
  1642. /**
  1643. * Cli Command Argument Sign
  1644. *
  1645. * @return array Arguments for Signature
  1646. */
  1647. public function cli_cmd_arg_sign()
  1648. {
  1649. return self::phar_args('FHy', 'phar');
  1650. }
  1651. // }}}
  1652. // {{{ public function cli_cmd_run_sign
  1653. /**
  1654. * Cli Command Run Signature
  1655. *
  1656. * @see $phar->setSignaturealgorithm
  1657. */
  1658. public function cli_cmd_run_sign()
  1659. {
  1660. $phar = $this->args['f']['val'];
  1661. $hash = $this->args['h']['val'];
  1662. $privkey = $this->args['y']['val'];
  1663. $hash = self::phar_check_hash($hash, $privkey);
  1664. $phar->setSignatureAlgorithm($hash, $privkey);
  1665. }
  1666. // }}}
  1667. // {{{ public function cli_cmd_inf_meta_set
  1668. /**
  1669. * Cli Command Inf Meta Set
  1670. *
  1671. * @return string A description
  1672. */
  1673. public function cli_cmd_inf_meta_set()
  1674. {
  1675. return "Set meta data of a PHAR entry or a PHAR package using serialized input. " .
  1676. "If no input file is specified for meta data then stdin is being used." .
  1677. "You can also specify a particular index using -k. In that case the metadata is " .
  1678. "expected to be an array and the value of the given index is being set. If " .
  1679. "the metadata is not present or empty a new array will be created. If the " .
  1680. "metadata is present and a flat value then the return value is 1. Also using -k " .
  1681. "the input is been taken directly rather then being serialized.";
  1682. }
  1683. // }}}
  1684. // {{{ public function cli_cmd_arg_meta_set
  1685. /**
  1686. * Cli Command Argument Meta Set
  1687. *
  1688. * @return array The arguments for meta set
  1689. */
  1690. public function cli_cmd_arg_meta_set()
  1691. {
  1692. return self::phar_args('FekM', 'phar');
  1693. }
  1694. // }}}
  1695. // {{{ public function cli_cmd_run_met_set
  1696. /**
  1697. * Cli Command Run Metaset
  1698. *
  1699. * @see $phar->startBuffering
  1700. * @see $phar->setMetadata
  1701. * @see $phar->stopBuffering
  1702. */
  1703. public function cli_cmd_run_meta_set()
  1704. {
  1705. $phar = $this->args['f']['val'];
  1706. $entry = $this->args['e']['val'];
  1707. $index = $this->args['k']['val'];
  1708. $meta = $this->args['m']['val'];
  1709. $phar->startBuffering();
  1710. if (isset($index)) {
  1711. if (isset($entry)) {
  1712. if ($phar[$entry]->hasMetadata()) {
  1713. $old = $phar[$entry]->getMetadata();
  1714. } else {
  1715. $old = array();
  1716. }
  1717. } else {
  1718. if ($phar->hasMetadata()) {
  1719. $old = $phar->getMetadata();
  1720. } else {
  1721. $old = array();
  1722. }
  1723. }
  1724. if (!is_array($old)) {
  1725. self::error('Metadata is a flat value while an index operation was issued.');
  1726. }
  1727. $old[$index] = $meta;
  1728. $meta = $old;
  1729. } else {
  1730. $meta = unserialize($meta);
  1731. }
  1732. if (isset($entry)) {
  1733. $phar[$entry]->setMetadata($meta);
  1734. } else {
  1735. $phar->setMetadata($meta);
  1736. }
  1737. $phar->stopBuffering();
  1738. }
  1739. // }}}
  1740. // {{{ public function cli_cmd_inf_met_get
  1741. /**
  1742. * Cli Command Inf Metaget
  1743. *
  1744. * @return string A description of the metaget arguments
  1745. */
  1746. public function cli_cmd_inf_meta_get()
  1747. {
  1748. return "Get meta information of a PHAR entry or a PHAR package in serialized from. " .
  1749. "If no output file is specified for meta data then stdout is being used.\n" .
  1750. "You can also specify a particular index using -k. In that case the metadata is " .
  1751. "expected to be an array and the value of the given index is returned using echo " .
  1752. "rather than using serialize. If that index does not exist or no meta data is " .
  1753. "present then the return value is 1.";
  1754. }
  1755. // }}}
  1756. // {{{ public function cli_cmd_arg_meta_get
  1757. /**
  1758. * Cli Command arg metaget
  1759. *
  1760. * @return array The arguments for meta get.
  1761. */
  1762. public function cli_cmd_arg_meta_get()
  1763. {
  1764. return self::phar_args('Fek', 'phar');
  1765. }
  1766. // }}}
  1767. // {{{ public function cli_cmd_run_meta_get
  1768. /**
  1769. * Cli Command Run Metaget
  1770. *
  1771. * @see $this->args
  1772. * @see $phar[$x]->hasMetadata()
  1773. * @see $phar->getMetadata()
  1774. */
  1775. public function cli_cmd_run_meta_get()
  1776. {
  1777. $phar = $this->args['f']['val'];
  1778. $entry = $this->args['e']['val'];
  1779. $index = $this->args['k']['val'];
  1780. if (isset($entry)) {
  1781. if (!$phar[$entry]->hasMetadata()) {
  1782. echo "No Metadata\n";
  1783. exit(1);
  1784. }
  1785. echo serialize($phar[$entry]->getMetadata());
  1786. } else {
  1787. if (!$phar->hasMetadata()) {
  1788. echo "No Metadata\n";
  1789. exit(1);
  1790. }
  1791. $meta = $phar->getMetadata();
  1792. }
  1793. if (isset($index)) {
  1794. if (isset($index)) {
  1795. if (isset($meta[$index])) {
  1796. echo $meta[$index];
  1797. exit(0);
  1798. } else {
  1799. echo "No Metadata\n";
  1800. exit(1);
  1801. }
  1802. } else {
  1803. echo serialize($meta);
  1804. }
  1805. }
  1806. }
  1807. // }}}
  1808. // {{{ public function cli_cmd_inf_meta_del
  1809. /**
  1810. * Cli Command Inf Metadel
  1811. *
  1812. * @return string A description of the metadel function
  1813. */
  1814. public function cli_cmd_inf_meta_del()
  1815. {
  1816. return "Delete meta information of a PHAR entry or a PHAR package.\n" .
  1817. "If -k is given then the metadata is expected to be an array " .
  1818. "and the given index is being deleted.\n" .
  1819. "If something was deleted the return value is 0 otherwise it is 1.";
  1820. }
  1821. // }}}
  1822. // {{{ public function cli_cmd_arg_meta_del
  1823. /**
  1824. * CliC ommand Arg Metadelete
  1825. *
  1826. * @return array The arguments for metadel
  1827. */
  1828. public function cli_cmd_arg_meta_del()
  1829. {
  1830. return self::phar_args('Fek', 'phar');
  1831. }
  1832. // }}}
  1833. // {{{ public function cli_cmd_run_meta_del
  1834. /**
  1835. * Cli Command Run MetaDel
  1836. *
  1837. * @see $phar[$x]->delMetadata()
  1838. * @see $phar->delMetadata()
  1839. */
  1840. public function cli_cmd_run_meta_del()
  1841. {
  1842. $phar = $this->args['f']['val'];
  1843. $entry = $this->args['e']['val'];
  1844. $index = $this->args['k']['val'];
  1845. if (isset($entry)) {
  1846. if (isset($index)) {
  1847. if (!$phar[$entry]->hasMetadata()) {
  1848. exit(1);
  1849. }
  1850. $meta = $phar[$entry]->getMetadata();
  1851. // @todo add error message here.
  1852. if (!is_array($meta)) {
  1853. exit(1);
  1854. }
  1855. unset($meta[$index]);
  1856. $phar[$entry]->setMetadata($meta);
  1857. } else {
  1858. exit($phar[$entry]->delMetadata() ? 0 : 1);
  1859. }
  1860. } else {
  1861. if (isset($index)) {
  1862. if (!$phar->hasMetadata()) {
  1863. exit(1);
  1864. }
  1865. $meta = $phar->getMetadata();
  1866. // @todo Add error message
  1867. if (!is_array($meta)) {
  1868. exit(1);
  1869. }
  1870. unset($meta[$index]);
  1871. $phar->setMetadata($meta);
  1872. } else {
  1873. exit($phar->delMetadata() ? 0 : 1);
  1874. }
  1875. }
  1876. }
  1877. // }}}
  1878. // {{{ public function cli_cmd_inf_info
  1879. /**
  1880. * CLi Command Inf Info
  1881. *
  1882. * @return string A description about the info commands.
  1883. */
  1884. public function cli_cmd_inf_info()
  1885. {
  1886. return "Get information about a PHAR package.\n" .
  1887. "By using -k it is possible to return a single value.";
  1888. }
  1889. // }}}
  1890. // {{{ public function cli_cmd_arg_info
  1891. /**
  1892. * Cli Command Arg Infos
  1893. *
  1894. * @return array The arguments for info command.
  1895. */
  1896. public function cli_cmd_arg_info()
  1897. {
  1898. return self::phar_args('Fk', 'phar');
  1899. }
  1900. // }}}
  1901. // {{{ public function cli_cmd_run_info
  1902. /**
  1903. * Cli Command Run Info
  1904. *
  1905. * @param args $args
  1906. */
  1907. public function cli_cmd_run_info()
  1908. {
  1909. $phar = $this->args['f']['val'];
  1910. $index = $this->args['k']['val'];
  1911. $hash = $phar->getSignature();
  1912. $infos = array();
  1913. if ($phar->getAlias()) {
  1914. $infos['Alias'] = $phar->getAlias();
  1915. }
  1916. if (!$hash) {
  1917. $infos['Hash-type'] = 'NONE';
  1918. } else {
  1919. $infos['Hash-type'] = $hash['hash_type'];
  1920. $infos['Hash'] = $hash['hash'];
  1921. }
  1922. $csize = 0;
  1923. $usize = 0;
  1924. $count = 0;
  1925. $ccount = 0;
  1926. $ucount = 0;
  1927. $mcount = 0;
  1928. $compalg = array('GZ'=>0, 'BZ2'=>0);
  1929. foreach(new RecursiveIteratorIterator($phar) as $ent) {
  1930. $count++;
  1931. if ($ent->isCompressed()) {
  1932. $ccount++;
  1933. $csize += $ent->getCompressedSize();
  1934. if ($ent->isCompressed(Phar::GZ)) {
  1935. $compalg['GZ']++;
  1936. } elseif ($ent->isCompressed(Phar::BZ2)) {
  1937. $compalg['BZ2']++;
  1938. }
  1939. } else {
  1940. $ucount++;
  1941. $csize += $ent->getSize();
  1942. }
  1943. $usize += $ent->getSize();
  1944. if ($ent->hasMetadata()) {
  1945. $mcount++;
  1946. }
  1947. }
  1948. $infos['Entries'] = $count;
  1949. $infos['Uncompressed-files'] = $ucount;
  1950. $infos['Compressed-files'] = $ccount;
  1951. $infos['Compressed-gz'] = $compalg['GZ'];
  1952. $infos['Compressed-bz2'] = $compalg['BZ2'];
  1953. $infos['Uncompressed-size'] = $usize;
  1954. $infos['Compressed-size'] = $csize;
  1955. $infos['Compression-ratio'] = sprintf('%.3g%%', $usize ? ($csize * 100) / $usize : 100);
  1956. $infos['Metadata-global'] = $phar->hasMetadata() * 1;
  1957. $infos['Metadata-files'] = $mcount;
  1958. $infos['Stub-size'] = strlen($phar->getStub());
  1959. if (isset($index)) {
  1960. if (!isset($infos[$index])) {
  1961. self::error("Requested value does not exist.\n");
  1962. }
  1963. echo $infos[$index];
  1964. exit(0);
  1965. }
  1966. $l = 0;
  1967. foreach($infos as $which => $val) {
  1968. $l = max(strlen($which), $l);
  1969. }
  1970. foreach($infos as $which => $val) {
  1971. echo $which . ':' . str_repeat(' ', $l + 1 - strlen($which)) . $val . "\n";
  1972. }
  1973. }
  1974. // }}}
  1975. // {{{ public function cli_cmd_inf_version
  1976. /**
  1977. * CLi Command Inf Version
  1978. *
  1979. * @return string A description about the info commands.
  1980. */
  1981. public function cli_cmd_inf_version()
  1982. {
  1983. return "Get information about the PHAR environment and the tool version.";
  1984. }
  1985. // }}}
  1986. // {{{ public function cli_cmd_arg_version
  1987. /**
  1988. * Cli Command Arg Version
  1989. *
  1990. * @return array The arguments for version command.
  1991. */
  1992. public function cli_cmd_arg_version()
  1993. {
  1994. return self::phar_args('', NULL);
  1995. }
  1996. // }}}
  1997. // {{{ public function cli_cmd_run_info
  1998. /**
  1999. * Cli Command Run Info
  2000. *
  2001. * @param args $args
  2002. */
  2003. public function cli_cmd_run_version()
  2004. {
  2005. $use_ext = extension_loaded('phar');
  2006. $version = array(
  2007. 'PHP Version' => phpversion(),
  2008. 'phar.phar version' => '$Id: a58a9f060a207c567585aa4858b862d9278df83d $',
  2009. 'Phar EXT version' => $use_ext ? phpversion('phar') : 'Not available',
  2010. 'Phar API version' => Phar::apiVersion(),
  2011. 'Phar-based phar archives' => true,
  2012. 'Tar-based phar archives' => $use_ext,
  2013. 'ZIP-based phar archives' => $use_ext,
  2014. 'gzip compression' => extension_loaded('zlib'),
  2015. 'bzip2 compression' => extension_loaded('bz2'),
  2016. 'supported signatures' => $use_ext ? join(', ', Phar::getSupportedSignatures()) : '',
  2017. );
  2018. $klen = 0;
  2019. foreach($version as $k => $v)
  2020. {
  2021. $klen = max($klen, strlen($k));
  2022. }
  2023. ++$klen;
  2024. foreach($version as $k => $v) {
  2025. if (is_bool($v)) {
  2026. $v = $v ? 'enabled' : 'disabled';
  2027. }
  2028. printf("%-${klen}s %s\n", $k.':', $v);
  2029. }
  2030. }
  2031. // }}}
  2032. }
  2033. // }}}
  2034. ?>
  2035. ö||¼Ðáæ,z.-ô“ “¤¡¬Æ���GBMB