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  6pharcommandclicommand.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