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