Back to index

php5  5.3.10
pharcommand.inc
Go to the documentation of this file.
00001 <?php
00002 
00012 // {{{ class PharCommand extends CLICommand
00025 class PharCommand extends CLICommand
00026 {
00027        // {{{ public function cli_get_SP2
00028        public function cli_get_SP2($l1, $arg_inf)
00029        {
00030               return str_repeat(' ', $l1 + 2 + 4 + 9);
00031        }
00032        // }}}
00033        // {{{ public function cli_get_SP3
00042        function cli_get_SP3($l1, $l2, $arg_inf)
00043        {
00044               return str_repeat(' ', $l1 + 2 + 4 + 9 + 2 + $l2 + 2);
00045        }
00046        // }}}
00047        // {{{ static function phar_args
00057        static function phar_args($which, $phartype)
00058        {
00059               $phar_args = array(
00060                      'a' => array(
00061                             'typ' => 'alias',
00062                             'val' => NULL,
00063                             'inf' => '<alias>  Provide an alias name for the phar file.'
00064                      ),
00065                      'b' => array(
00066                             'typ' => 'any',
00067                             'val' => NULL,
00068                             'inf' => '<bang>   Hash-bang line to start the archive (e.g. #!/usr/bin/php). The hash '
00069                                            .'         mark itself \'#!\' and the newline character are optional.'
00070                      ),
00071                      'c' => array(
00072                             'typ' => 'compalg',
00073                             'val' => NULL,
00074                             'inf' => '<algo>   Compression algorithm.',
00075                             'select' => array(
00076                                    '0'    => 'No compression',
00077                                    'none' => 'No compression',
00078                                    'auto' => 'Automatically select compression algorithm'
00079                             )
00080                      ),
00081                      'e' => array(
00082                             'typ' => 'entry',
00083                             'val' => NULL,
00084                             'inf' => '<entry>  Name of entry to work on (must include PHAR internal directory name if any).'
00085                      ),
00086                      'f' => array(
00087                             'typ' => $phartype,
00088                             'val' => NULL,
00089                             'inf' => '<file>   Specifies the phar file to work on.'
00090                      ),
00091                      'h' => array(
00092                             'typ' => 'select',
00093                             'val' => NULL,
00094                             'inf' => '<method> Selects the hash algorithmn.',
00095                             'select' => array('md5' => 'MD5','sha1' => 'SHA1')
00096                      ),
00097                      'i' => array(
00098                             'typ' => 'regex',
00099                             'val' => NULL,
00100                             'inf' => '<regex>  Specifies a regular expression for input files.'
00101                      ),
00102                      'k' => array(
00103                             'typ' => 'any',
00104                             'val' => NULL,
00105                             'inf' => '<index>  Subscription index to work on.',
00106                      ),
00107                      'l' => array(
00108                             'typ' => 'int',
00109                             'val' => 0,
00110                             'inf' => '<level>  Number of preceeding subdirectories to strip from file entries',
00111                      ),
00112                      'm' => array(
00113                             'typ' => 'any',
00114                             'val' => NULL,
00115                             'inf' => '<meta>   Meta data to store with entry (serialized php data).'
00116                      ),
00117                      'p' => array(
00118                             'typ' => 'loader',
00119                             'val' => NULL,
00120                             'inf' => '<loader> Location of PHP_Archive class file (pear list-files PHP_Archive).'
00121                                            .'You can use \'0\' or \'1\' to locate it automatically using the mentioned '
00122                                            .'pear command. When using \'0\' the command does not error out when the '
00123                                            .'class file cannot be located. This switch also adds some code around the '
00124                                            .'stub so that class PHP_Archive gets registered as phar:// stream wrapper '
00125                                            .'if necessary. And finally this switch will add the file phar.inc from '
00126                                            .'this package and load it to ensure class Phar is present.'
00127                                            ,
00128                      ),
00129                      's' => array(
00130                             'typ' => 'file',
00131                             'val' => NULL,
00132                             'inf' => '<stub>   Select the stub file.'
00133                      ),
00134                      'x' => array(
00135                             'typ' => 'regex',
00136                             'val' => NULL,
00137                             'inf' => '<regex>  Regular expression for input files to exclude.'
00138                      ),
00139                      'y' => array(
00140                             'typ' => 'privkey',
00141                             'val' => NULL,
00142                             'inf' => '<key>    Private key for OpenSSL signing.',
00143                      ),
00144               );
00145 
00146               if (extension_loaded('zlib')) {
00147                      $phar_args['c']['select']['gz']    = 'GZip compression';
00148                      $phar_args['c']['select']['gzip']  = 'GZip compression';
00149               }
00150 
00151               if (extension_loaded('bz2')) {
00152                      $phar_args['c']['select']['bz2']   = 'BZip2 compression';
00153                      $phar_args['c']['select']['bzip2'] = 'BZip2 compression';
00154               }
00155 
00156               $hash_avail = Phar::getSupportedSignatures();
00157               $hash_optional = array('SHA-256' => 'SHA256',
00158                                                     'SHA-512' => 'SHA512',
00159                                                     'OpenSSL' => 'OpenSSL');
00160               if (!in_array('OpenSSL', $hash_avail)) {
00161                      unset($phar_args['y']);
00162               }
00163 
00164               foreach($hash_optional as $key => $name) {
00165                      if (in_array($key, $hash_avail)) {
00166                             $phar_args['h']['select'][strtolower($name)] = $name;
00167                      }
00168               }
00169 
00170               $args = array();
00171 
00172               foreach($phar_args as $lkey => $cfg) {
00173                      $ukey     = strtoupper($lkey);
00174                      $required = strpos($which, $ukey) !== false;
00175                      $optional = strpos($which, $lkey) !== false;
00176 
00177                      if ($required || $optional) {
00178                             $args[$lkey] = $cfg;
00179                             $args[$lkey]['required'] = $required;
00180                      }
00181               }
00182               return $args;
00183        }
00184        // }}}
00185        // {{{ static function strEndsWith
00196        static function strEndsWith($haystack, $needle)
00197        {
00198               return substr($haystack, -strlen($needle)) == $needle;
00199        }
00200        // }}}
00201        // {{{ static function cli_arg_typ_loader
00211        static function cli_arg_typ_loader($arg, $cfg, $key)
00212        {
00213               if (($arg == '0' || $arg == '1') && !file_exists($arg) && substr(PHP_OS, 0, 3) != 'WIN') {
00214                      $found = NULL;
00215                      $apiver = false;
00216                      $path = explode(PATH_SEPARATOR, $_ENV['PATH']);
00217                      $pear = false;
00218                      foreach ($path as $component) {
00219                             if (file_exists($component . DIRECTORY_SEPARATOR . 'pear')
00220                                    && is_executable($component . DIRECTORY_SEPARATOR . 'pear')) {
00221                                    $pear = true;
00222                                    break;
00223                             }
00224                      }
00225                      if ($pear) {
00226                             $apiver = `pear -q info PHP_Archive 2>/dev/null|grep 'API Version'`;
00227                             $apiver = trim(substr($apiver, strlen('API Version')));
00228                      }
00229                      if ($apiver) {
00230                             self::notice("PEAR package PHP_Archive: API Version: $apiver.\n");
00231                             $files  = explode("\n", `pear list-files PHP_Archive`);
00232                             $phpdir = `pear config-get php_dir 2>/dev/null`;
00233                             $phpdir = trim($phpdir);
00234                             self::notice("PEAR package PHP_Archive: $phpdir.\n");
00235                             if (is_dir($phpdir)) {
00236                                    foreach($files as $ent) {
00237                                           $matches = NULL;
00238                                           if (preg_match(",^php[ \t]+([^ \t].*[\\\\/]PHP[\\\\/]Archive\.php)$,", $ent, $matches)) {
00239                                                  $sub = $matches[1];
00240                                                  if (strpos($sub, $phpdir) !== 0) {
00241                                                         $found = NULL;
00242                                                         break;
00243                                                  }
00244                                                  $found = $sub;
00245                                                  break;
00246                                           }
00247                                    }
00248                             } else {
00249                                    self::notice("PEAR package PHP_Archive: corrupt or inaccessible base dir: $php_dir.\n");
00250                             }
00251                      }
00252                      if (isset($found)) {
00253                             self::notice("PEAR package PHP_Archive: $found.\n");
00254                      } else {
00255                             $msg = "PEAR package PHP_Archive not installed: generated phar will require PHP's phar extension be enabled.\n";
00256                             if ($arg == '0') {
00257                                    self::notice($msg);
00258                             } else {
00259                                    self::error($msg);
00260                             }
00261                      }
00262                      $arg = $found;
00263               }
00264               return self::cli_arg_typ_file($arg);
00265        }
00266        // }}}
00267        // {{{ static function cli_arg_typ_pharnew
00276        static function cli_arg_typ_pharnew($arg, $cfg, $key)
00277        {
00278               $arg = self::cli_arg_typ_filenew($arg, $cfg, $key);
00279               if (!Phar::isValidPharFilename($arg)) {
00280                      self::error("Phar files must have file extension '.phar', '.phar.php', '.phar.bz2' or '.phar.gz'.\n");
00281               }
00282               return $arg;
00283        }
00284        // }}}
00285        // {{{ static function cli_arg_typ_pharfile
00297        static function cli_arg_typ_pharfile($arg, $cfg, $key)
00298        {
00299               try {
00300                      $pharfile = self::cli_arg_typ_file($arg, $cfg, $key);
00301 
00302                      if (!Phar::loadPhar($pharfile)) {
00303                             self::error("Unable to open phar '$arg'\n");
00304                      }
00305 
00306                      return $pharfile;
00307               } catch(Exception $e) {
00308                      self::error("Exception while opening phar '$arg':\n" . $e->getMessage() . "\n");
00309               }
00310        }
00311        // }}}
00312        // {{{ static function cli_arg_typ_pharurl
00328        static function cli_arg_typ_pharurl($arg, $cfg, $key)
00329        {
00330               return 'phar://' . self::cli_arg_typ_pharfile($arg, $cfg, $key);
00331        }
00332        // }}}
00333        // {{{ static function cli_arg_typ_phar
00340        static function cli_arg_typ_phar($arg, $cfg, $key)
00341        {
00342               try {
00343                      return new Phar(self::cli_arg_typ_pharfile($arg, $cfg, $key));
00344               } catch(Exception $e) {
00345                      self::error("Exception while opening phar '$argv':\n" . $e->getMessage() . "\n");
00346               }
00347        }
00348        // }}}
00349        // {{{ static function cli_arg_typ_entry
00356        static function cli_arg_typ_entry($arg, $cfg, $key)
00357        {
00358               // no further check atm, maybe check for no '/' at beginning
00359               return $arg;
00360        }
00361        // }}}
00362        // {{{ static function cli_arg_typ_compalg
00371        static function cli_arg_typ_compalg($arg, $cfg, $key)
00372        {
00373               $arg = self::cli_arg_typ_select($arg, $cfg, $key);
00374 
00375               switch($arg) {
00376                      case 'auto':
00377                             if (extension_loaded('zlib')) {
00378                                    $arg = 'gz';
00379                             } elseif (extension_loaded('bz2')) {
00380                                    $arg = 'bz2';
00381                             } else {
00382                                    $arg = '0';
00383                             }
00384                             break;
00385               }
00386               return $arg;
00387        }
00388        // }}}
00389        // {{{ static function cli_arg_typ_privkey
00398        static function cli_arg_typ_privkey($arg, $cfg, $key)
00399        {
00400               $arg = self::cli_arg_typ_string($arg, $cfg, $key);
00401 
00402               $hash_avail = Phar::getSupportedSignatures();
00403               if ($arg && !in_array('OpenSSL', $hash_avail))
00404               {
00405                      self::error("Cannot specifiy private key without OpenSSL support.\n");
00406               }
00407               return $arg;
00408        }
00409        // }}}
00410        // {{{ static function phar_check_hash
00416        function phar_check_hash($hash, $privkey)
00417        {
00418               switch($hash) {
00419                      case 'md5':
00420                             return Phar::MD5;
00421                      case 'sha1':
00422                             return Phar::SHA1;
00423                      case 'sha256':
00424                             return Phar::SHA256;
00425                      case 'sha512':
00426                             return Phar::SHA512;
00427                      case 'openssl':
00428                             if (!$privkey) {
00429                                    self::error("Cannot use OpenSSL signing without key.\n");
00430                             }
00431                             return Phar::OPENSSL;
00432               }
00433        }
00434        // }}}
00435        // {{{ static function cli_cmd_inf_pack
00441        static function cli_cmd_inf_pack()
00442        {
00443               return "Pack files into a PHAR archive.\n" .
00444                         "When using -s <stub>, then the stub file is being " .
00445                         "excluded from the list of input files/dirs." .
00446                         "To create an archive that contains PEAR class PHP_Archive " .
00447                         "then point -p argument to PHP/Archive.php.\n";
00448        }
00449        // }}}
00450        // {{{ static function cli_cmd_arg_pack
00456        static function cli_cmd_arg_pack()
00457        {
00458               $args = self::phar_args('abcFhilpsxy', 'pharnew');
00459 
00460               $args[''] = array(
00461                      'typ'     => 'any',
00462                      'val'      => NULL,
00463                      'required' => 1,
00464                      'inf'      => '         Any number of input files and directories. If -i is in use then ONLY files and matching thegiven regular expression are being packed. If -x is given then files matching that regular expression are NOT being packed.',
00465               );
00466 
00467               return $args;
00468        }
00469        // }}}
00470        // {{{ function phar_set_stub_begin
00474        public function phar_set_stub_begin(Phar $phar, $stub, $loader = NULL, $hashbang = NULL)
00475        {
00476               if (isset($stub)) {
00477                      $c = file_get_contents($stub);
00478 
00479                      if (substr($c, 0, 2) == '#!') {
00480                             if (strpos($c, "\n") !== false) {
00481                                    if (!isset($hashbang)) {
00482                                           $hashbang = substr($c, 0, strpos($c, "\n") + 1);
00483                                    }
00484                                    $c = substr($c, strpos($c, "\n") + 1);
00485                             } else {
00486                                    if (!isset($hashbang)) {
00487                                           $hashbang = $c;
00488                                    }
00489                                    $c = NULL;
00490                             }
00491                      }
00492 
00493                      if (isset($hashbang)) {
00494                             if (substr($hashbang, 0, 2) != '#!') {
00495                                    $hashbang = '#!' . $hashbang;
00496                             }
00497                             if (substr($hashbang, -1) != "\n") {
00498                                    $hashbang .= "\n";
00499                             }
00500                      } else {
00501                             $hashbang = "";
00502                      }
00503 
00504                      if (isset($loader)) {
00505                             $s = "<?php if (!class_exists('PHP_Archive')) {\n?>";
00506                             if (is_file($loader)) {
00507                                    $s .= file_get_contents($loader);
00508                             }
00509                             $s .= "<?php\n";
00510                             $s .= "}\n";
00511                             $s .= "if (!in_array('phar', stream_get_wrappers())) {\n";
00512                             $s .= "\tstream_wrapper_register('phar', 'PHP_Archive');\n";
00513                             $s .= "}\n";
00514                             $s .= "if (!class_exists('Phar',0)) {\n";
00515                             $s .= "\tinclude 'phar://'.__FILE__.'/phar.inc';\n";
00516                             $s .= "}\n";
00517                             $s .= '?>';
00518                             $s .= $c;
00519 
00520                             $phar->setStub($hashbang . $s);
00521                      } else {
00522                             $phar->setStub($hashbang . $c);
00523                      }
00524                      return new SplFileInfo($stub);
00525               }
00526               return NULL;
00527        }
00528        // }}}
00529        // {{{ function phar_set_stub_end
00533        public function phar_set_stub_end(Phar $phar, $stub, $loader = NULL)
00534        {
00535               if (isset($stub) && isset($loader)) {
00536                      if (substr(__FILE__, -15) == 'pharcommand.inc') {
00537                             self::phar_add_file($phar, 0, 'phar.inc', 'phar://'.__FILE__.'/phar.inc', NULL);
00538                      } else {
00539                             self::phar_add_file($phar, 0, 'phar.inc', dirname(__FILE__).'/phar/phar.inc', NULL);
00540                      }
00541               }
00542        }
00543        // }}}
00544        // {{{ function cli_cmd_run_pack
00552        public function cli_cmd_run_pack()
00553        {
00554               if (ini_get('phar.readonly')) {
00555                      self::error("Creating phar files is disabled by ini setting 'phar.readonly'.\n");
00556               }
00557 
00558               if (!Phar::canWrite()) {
00559                      self::error("Creating phar files is disabled, Phar::canWrite() returned false.\n");
00560               }
00561 
00562               $alias    = $this->args['a']['val'];
00563               $hashbang = $this->args['b']['val'];
00564               $archive  = $this->args['f']['val'];
00565               $hash     = $this->args['h']['val'];
00566               $privkey  = $this->args['y']['val'];
00567               $regex    = $this->args['i']['val'];
00568               $level    = $this->args['l']['val'];
00569               $loader   = $this->args['p']['val'];
00570               $stub     = $this->args['s']['val'];
00571               $invregex = $this->args['x']['val'];
00572               $input    = $this->args['']['val'];
00573 
00574               $hash = self::phar_check_hash($hash, $privkey);
00575 
00576               $phar  = new Phar($archive, 0, $alias);
00577 
00578               $phar->startBuffering();
00579 
00580               $stub = $this->phar_set_stub_begin($phar, $stub, $loader, $hashbang);
00581 
00582               if (!is_array($input)) {
00583                      $this->phar_add($phar, $level, $input, $regex, $invregex, $stub, NULL, isset($loader));
00584               } else {
00585                      foreach($input as $i) {
00586                             $this->phar_add($phar, $level, $i, $regex, $invregex, $stub, NULL, isset($loader));
00587                      }
00588               }
00589 
00590               $this->phar_set_stub_end($phar, $stub, $loader);
00591 
00592               switch($this->args['c']['val']) {
00593                      case 'gz':
00594                      case 'gzip':
00595                             $phar->compressFiles(Phar::GZ);
00596                             break;
00597                      case 'bz2':
00598                      case 'bzip2':
00599                             $phar->compressFiles(Phar::BZ2);
00600                             break;
00601                      default:
00602                             $phar->decompressFiles();
00603                             break;
00604               }
00605 
00606               if ($hash) {
00607                      $phar->setSignatureAlgorithm($hash, $privkey);
00608               }
00609 
00610               $phar->stopBuffering();
00611               exit(0);
00612        }
00613        // }}}
00614        // {{{ static function phar_add
00629        static function phar_add(Phar $phar, $level, $input, $regex, $invregex, SplFileInfo $stub = NULL, $compress = NULL, $noloader = false)
00630        {
00631               if ($input && is_file($input) && !is_dir($input)) {
00632                      return self::phar_add_file($phar, $level, $input, $input, $compress);
00633               }
00634               $dir   = new RecursiveDirectoryIterator($input);
00635               $dir   = new RecursiveIteratorIterator($dir);
00636 
00637               if (isset($regex)) {
00638                      $dir = new RegexIterator($dir, $regex);
00639               }
00640 
00641               if (isset($invregex)) {
00642                      $dir = new InvertedRegexIterator($dir, $invregex);
00643               }
00644 
00645               try {
00646                      foreach($dir as $file) {
00647                             if ((empty($stub) || $file->getRealPath() != $stub->getRealPath()) && !is_dir($file)) {
00648                                    self::phar_add_file($phar, $level, $dir->getSubPathName(), $file, $compress, $noloader);
00649                             }
00650                      }
00651               } catch(Excpetion $e) {
00652                      self::error("Unable to complete operation on file '$file'\n" . $e->getMessage() . "\n");
00653               }
00654        }
00655        // }}}
00656        // {{{ static function phar_add_file
00669        static function phar_add_file(Phar $phar, $level, $entry, $file, $compress, $noloader = false)
00670        {
00671               $entry = str_replace('//', '/', $entry);
00672               while($level-- > 0 && ($p = strpos($entry, '/')) !== false) {
00673                      $entry = substr($entry, $p+1);
00674               }
00675 
00676        if ($noloader && $entry == 'phar.inc') {
00677               return;
00678        }
00679 
00680               echo "$entry\n";
00681 
00682               $phar[$entry] = file_get_contents($file);
00683               switch($compress) {
00684                      case 'gz':
00685                      case 'gzip':
00686                             $phar[$entry]->compress(Phar::GZ);
00687                             break;
00688                      case 'bz2':
00689                      case 'bzip2':
00690                             $phar[$entry]->compress(Phar::BZ2);
00691                             break;
00692                      case '0':
00693                             $phar[$entry]->decompress();
00694                             break;
00695                      default:
00696                             break;
00697               }
00698        }
00699        // }}}
00700        // {{{ public function phar_dir_echo
00707        public function phar_dir_echo($pn, $f)
00708        {
00709               echo "$f\n";
00710        }
00711        // }}}
00712        // {{{ public function phar_dir_operation
00722        public function phar_dir_operation(RecursiveIteratorIterator $dir, $func, array $args = array())
00723        {
00724               $regex   = $this->args['i']['val'];
00725               $invregex= $this->args['x']['val'];
00726 
00727               if (isset($regex)) {
00728                      $dir = new RegexIterator($dir, $regex);
00729               }
00730 
00731               if (isset($invregex)) {
00732                      $dir = new InvertedRegexIterator($dir, $invregex);
00733               }
00734 
00735               $any = false;
00736               foreach($dir as $pn => $f) {
00737                      $any = true;
00738                      call_user_func($func, $pn, $f, $args);
00739               }
00740               return $any;
00741        }
00742        // {{{ static function cli_cmd_inf_list
00748        static function cli_cmd_inf_list()
00749        {
00750               return "List contents of a PHAR archive.";
00751        }
00752        // }}}
00753        // {{{ static function cli_cmd_arg_list
00759        static function cli_cmd_arg_list()
00760        {
00761               return self::phar_args('Fix', 'pharurl');
00762        }
00763        // }}}
00764        // {{{ public function cli_cmd_run_list
00770        public function cli_cmd_run_list()
00771        {
00772               $this->phar_dir_operation(
00773                      new DirectoryTreeIterator(
00774                             $this->args['f']['val']),
00775                             array($this, 'phar_dir_echo')
00776                      );
00777        }
00778        // }}}
00779        // {{{ static function cli_command_inf_tree
00785        static function cli_cmd_inf_tree()
00786        {
00787               return "Get a directory tree for a PHAR archive.";
00788        }
00789        // }}}
00790        // {{{ static function cli_cmd_arg_tree
00796        static function cli_cmd_arg_tree()
00797        {
00798               return self::phar_args('Fix', 'pharurl');
00799        }
00800        // }}}
00801        // {{{ public function cli_cmd_run_tree
00811        public function cli_cmd_run_tree()
00812        {
00813               $a = $this->phar_dir_operation(
00814                      new DirectoryGraphIterator(
00815                             $this->args['f']['val']),
00816                             array($this, 'phar_dir_echo')
00817                      );
00818               if (!$a) {
00819                      echo "|-<root directory>\n";
00820               }
00821        }
00822        // }}}
00823        // {{{ cli_cmd_inf_extract
00829        static function cli_cmd_inf_extract()
00830        {
00831               return "Extract a PHAR package to a directory.";
00832        }
00833        // }}}
00834        // {{{ static function cli_cmd_arg_extract
00842        static function cli_cmd_arg_extract()
00843        {
00844               $args = self::phar_args('Fix', 'phar');
00845 
00846               $args[''] = array(
00847                      'type' => 'dir',
00848                      'val' => '.',
00849                      'inf' => '         Directory to extract to (defaults to \'.\').',
00850               );
00851 
00852               return $args;
00853        }
00854        // }}}
00855        // {{{ public function cli_cmd_run_extract
00863        public function cli_cmd_run_extract()
00864        {
00865               $dir = $this->args['']['val'];
00866 
00867               if (is_array($dir)) {
00868                      if (count($dir) != 1) {
00869                             self::error("Only one target directory allowed.\n");
00870                      } else {
00871                             $dir = $dir[0];
00872                      }
00873               }
00874 
00875               $phar = $this->args['f']['val'];
00876               $base = $phar->getPathname();
00877               $bend = strpos($base, '.phar');
00878               $bend = strpos($base, '/', $bend);
00879               $base = substr($base, 0, $bend + 1);
00880               $blen = strlen($base);
00881 
00882               $this->phar_dir_operation(
00883                      new RecursiveIteratorIterator($phar),
00884                      array($this, 'phar_dir_extract'),
00885                      array($blen, $dir)
00886               );
00887        }
00888        // }}}
00889        // {{{ public function phar_dir_extract
00901        public function phar_dir_extract($pn, $f, $args)
00902        {
00903               $blen   = $args[0];
00904               $dir    = $args[1];
00905               $sub    = substr($pn, $blen);
00906               $target = $dir . '/' . $sub;
00907 
00908               if (!file_exists(dirname($target))) {
00909                      @mkdir(dirname($target), 0777, true);
00910               }
00911               if (!file_exists(dirname($target))) {
00912                      self::error("Operation could not be completed\n");
00913               }
00914 
00915               echo "$sub";
00916 
00917               if (!@copy($f, $target)) {
00918                      echo " ...error\n";
00919               } else {
00920                      echo " ...ok\n";
00921               }
00922        }
00923        // }}}
00924        // {{{ static function cli_cmd_inf_delete
00930        static function cli_cmd_inf_delete()
00931        {
00932               return 'Delete entry from a PHAR archive';
00933        }
00934        // }}}
00935        // {{{ static function cli_cmd_arg_delete
00941        static function cli_cmd_arg_delete()
00942        {
00943               return self::phar_args('FE', 'phar');
00944        }
00945        // }}}
00946        // {{{ public function cli_cmd_run_delete
00952        public function cli_cmd_run_delete()
00953        {
00954               $phar  = $this->args['f']['val'];
00955               $entry = $this->args['e']['val'];
00956 
00957               $phar->startBuffering();
00958               unset($phar[$entry]);
00959               $phar->stopBuffering();
00960        }
00961        // }}}
00962        // {{{ static function cli_cmd_inf_add
00968        static function cli_cmd_inf_add()
00969        {
00970               return "Add entries to a PHAR package.";
00971        }
00972        // }}}
00973        // {{{ static function cli_cmd_arg_add
00977        static function cli_cmd_arg_add()
00978        {
00979               $args = self::phar_args('acFilx', 'phar');
00980               $args[''] = array(
00981                      'type'     => 'any',
00982                      'val'      => NULL,
00983                      'required' => 1,
00984                      'inf'      => '         Any number of input files and directories. If -i is in use then ONLY files and matching thegiven regular expression are being packed. If -x is given then files matching that regular expression are NOT being packed.',
00985               );
00986               return $args;
00987        }
00988        // }}}
00989        // {{{ public functio cli_cmd_run_add
00996        public function cli_cmd_run_add()
00997        {
00998               $compress= $this->args['c']['val'];
00999               $phar    = $this->args['f']['val'];
01000               $regex   = $this->args['i']['val'];
01001               $level   = $this->args['l']['val'];
01002               $invregex= $this->args['x']['val'];
01003               $input   = $this->args['']['val'];
01004 
01005               $phar->startBuffering();
01006 
01007               if (!is_array($input)) {
01008                      $this->phar_add($phar, $level, $input, $regex, $invregex, NULL, $compress);
01009               } else {
01010                      foreach($input as $i) {
01011                             $this->phar_add($phar, $level, $i, $regex, $invregex, NULL, $compress);
01012                      }
01013               }
01014               $phar->stopBuffering();
01015               exit(0);
01016        }
01017        // }}}
01018        // {{{ public function cli_cmd_inf_stub_set
01024        public function cli_cmd_inf_stub_set()
01025        {
01026               return "Set the stub of a PHAR file. " .
01027                         "If no input file is specified as stub then stdin is being used.";
01028        }
01029        // }}}
01030        // {{{ public function cli_cmd_arg_stub_set
01036        public function cli_cmd_arg_stub_set()
01037        {
01038               $args = self::phar_args('bFps', 'phar');
01039               $args['s']['val'] = 'php://stdin';
01040               return $args;
01041        }
01042        // }}}
01043        // {{{ public function cli_cmd_run_stub_set
01049        public function cli_cmd_run_stub_set()
01050        {
01051               $hashbang = $this->args['b']['val'];
01052               $phar     = $this->args['f']['val'];
01053               $stub     = $this->args['s']['val'];
01054               $loader   = $this->args['p']['val'];
01055 
01056               $this->phar_set_stub_begin($phar, $stub, $loader, $hashbang);
01057               $this->phar_set_stub_end($phar, $stub, $loader);
01058        }
01059        // }}}
01060        // {{{ public function cli_cmd_inf_stub_get
01066        public function cli_cmd_inf_stub_get()
01067        {
01068               return "Get the stub of a PHAR file. " .
01069                         "If no output file is specified as stub then stdout is being used.";
01070        }
01071        // }}}
01072        // {{{ public function cli_cmd_arg_stub_get
01078        public function cli_cmd_arg_stub_get()
01079        {
01080               $args = self::phar_args('Fs', 'phar');
01081               $args['s']['val'] = 'php://stdin';
01082               return $args;
01083        }
01084        // }}}
01085        // {{{ public function cli_cmd_run_stub_get
01094        public function cli_cmd_run_stub_get($args)
01095        {
01096               $phar = $this->args['f']['val'];
01097               $stub = $this->args['s']['val'];
01098 
01099               file_put_contents($stub, $phar->getStub());
01100        }
01101        // }}}
01102        // {{{ public function cli_cmd_inf_compress
01110        public function cli_cmd_inf_compress()
01111        {
01112               return "Compress or uncompress all files or a selected entry.";
01113        }
01114        // }}}
01115        // {{{ public function cli_cmd_arg_cmpress
01121        public function cli_cmd_arg_compress()
01122        {
01123               return self::phar_args('FCe', 'phar');
01124        }
01125        // }}}
01126        // {{{ public function cli_cmd_run_compress
01132        public function cli_cmd_run_compress()
01133        {
01134               $phar  = $this->args['f']['val'];
01135               $entry = $this->args['e']['val'];
01136 
01137               switch($this->args['c']['val']) {
01138                      case 'gz':
01139                      case 'gzip':
01140                             if (isset($entry)) {
01141                                    $phar[$entry]->compress(Phar::GZ);
01142                             } else {
01143                                    $phar->compressFiles(Phar::GZ);
01144                             }
01145                             break;
01146                      case 'bz2':
01147                      case 'bzip2':
01148                             if (isset($entry)) {
01149                                    $phar[$entry]->compress(Phar::BZ2);
01150                             } else {
01151                                    $phar->compressFiles(Phar::BZ2);
01152                             }
01153                             break;
01154                      default:
01155                             if (isset($entry)) {
01156                                    $phar[$entry]->decompress();
01157                             } else {
01158                                    $phar->decompressFiles();
01159                             }
01160                             break;
01161               }
01162        }
01163        // }}}
01164        // {{{ public function cli_cmd_inf_sign
01170        public function cli_cmd_inf_sign()
01171        {
01172               return "Set signature hash algorithm.";
01173        }
01174        // }}}
01175        // {{{ public function cli_cmd_arg_sign
01181        public function cli_cmd_arg_sign()
01182        {
01183               return self::phar_args('FHy', 'phar');
01184        }
01185        // }}}
01186        // {{{ public function cli_cmd_run_sign
01192        public function cli_cmd_run_sign()
01193        {
01194               $phar     = $this->args['f']['val'];
01195               $hash     = $this->args['h']['val'];
01196               $privkey  = $this->args['y']['val'];
01197 
01198               $hash = self::phar_check_hash($hash, $privkey);
01199 
01200               $phar->setSignatureAlgorithm($hash, $privkey);
01201        }
01202        // }}}
01203        // {{{ public function cli_cmd_inf_meta_set
01209        public function cli_cmd_inf_meta_set()
01210        {
01211               return "Set meta data of a PHAR entry or a PHAR package using serialized input. " .
01212                         "If no input file is specified for meta data then stdin is being used." .
01213                         "You can also specify a particular index using -k. In that case the metadata is " .
01214                         "expected to be an array and the value of the given index is being set. If " .
01215                         "the metadata is not present or empty a new array will be created. If the " .
01216                         "metadata is present and a flat value then the return value is 1. Also using -k " .
01217                         "the input is been taken directly rather then being serialized.";
01218        }
01219        // }}}
01220        // {{{ public function cli_cmd_arg_meta_set
01226        public function cli_cmd_arg_meta_set()
01227        {
01228               return self::phar_args('FekM', 'phar');
01229        }
01230        // }}}
01231        // {{{ public function cli_cmd_run_met_set
01239        public function cli_cmd_run_meta_set()
01240        {
01241               $phar  = $this->args['f']['val'];
01242               $entry = $this->args['e']['val'];
01243               $index = $this->args['k']['val'];
01244               $meta  = $this->args['m']['val'];
01245 
01246               $phar->startBuffering();
01247 
01248               if (isset($index)) {
01249                      if (isset($entry)) {
01250                             if ($phar[$entry]->hasMetadata()) {
01251                                    $old = $phar[$entry]->getMetadata();
01252                             } else {
01253                                    $old = array();
01254                             }
01255                      } else {
01256                             if ($phar->hasMetadata()) {
01257                                    $old = $phar->getMetadata();
01258                             } else {
01259                                    $old = array();
01260                             }
01261                      }
01262 
01263                      if (!is_array($old)) {
01264                             self::error('Metadata is a flat value while an index operation was issued.');
01265                      }
01266 
01267                      $old[$index] = $meta;
01268                      $meta = $old;
01269               } else {
01270                      $meta = unserialize($meta);
01271               }
01272 
01273               if (isset($entry)) {
01274                      $phar[$entry]->setMetadata($meta);
01275               } else {
01276                      $phar->setMetadata($meta);
01277               }
01278               $phar->stopBuffering();
01279        }
01280        // }}}
01281        // {{{ public function cli_cmd_inf_met_get
01287        public function cli_cmd_inf_meta_get()
01288        {
01289               return "Get meta information of a PHAR entry or a PHAR package in serialized from. " .
01290                         "If no output file is specified for meta data then stdout is being used.\n" .
01291                         "You can also specify a particular index using -k. In that case the metadata is " .
01292                         "expected to be an array and the value of the given index is returned using echo " .
01293                         "rather than using serialize. If that index does not exist or no meta data is " .
01294                         "present then the return value is 1.";
01295        }
01296        // }}}
01297        // {{{ public function cli_cmd_arg_meta_get
01303        public function cli_cmd_arg_meta_get()
01304        {
01305               return self::phar_args('Fek', 'phar');
01306        }
01307        // }}}
01308        // {{{ public function cli_cmd_run_meta_get
01316        public function cli_cmd_run_meta_get()
01317        {
01318               $phar  = $this->args['f']['val'];
01319               $entry = $this->args['e']['val'];
01320               $index = $this->args['k']['val'];
01321 
01322               if (isset($entry)) {
01323                      if (!$phar[$entry]->hasMetadata()) {
01324                             echo "No Metadata\n";
01325                             exit(1);
01326                      }
01327                      echo serialize($phar[$entry]->getMetadata());
01328               } else {
01329                      if (!$phar->hasMetadata()) {
01330                             echo "No Metadata\n";
01331                             exit(1);
01332                      }
01333                      $meta = $phar->getMetadata();
01334               }
01335 
01336               if (isset($index)) {
01337                      if (isset($index)) {
01338                             if (isset($meta[$index])) {
01339                                    echo $meta[$index];
01340                                    exit(0);
01341                             } else {
01342                                    echo "No Metadata\n";
01343                                    exit(1);
01344                             }
01345                      } else {
01346                             echo serialize($meta);
01347                      }
01348               }
01349        }
01350        // }}}
01351        // {{{ public function cli_cmd_inf_meta_del
01357        public function cli_cmd_inf_meta_del()
01358        {
01359               return "Delete meta information of a PHAR entry or a PHAR package.\n" .
01360                         "If -k is given then the metadata is expected to be an array " .
01361                         "and the given index is being deleted.\n" .
01362                         "If something was deleted the return value is 0 otherwise it is 1.";
01363        }
01364        // }}}
01365        // {{{ public function cli_cmd_arg_meta_del
01371        public function cli_cmd_arg_meta_del()
01372        {
01373               return self::phar_args('Fek', 'phar');
01374        }
01375        // }}}
01376        // {{{ public function cli_cmd_run_meta_del
01383        public function cli_cmd_run_meta_del()
01384        {
01385               $phar  = $this->args['f']['val'];
01386               $entry = $this->args['e']['val'];
01387               $index = $this->args['k']['val'];
01388 
01389               if (isset($entry)) {
01390                      if (isset($index)) {
01391                             if (!$phar[$entry]->hasMetadata()) {
01392                                    exit(1);
01393                             }
01394                             $meta = $phar[$entry]->getMetadata();
01395 
01396                             // @todo add error message here.
01397                             if (!is_array($meta)) {
01398                                    exit(1);
01399                             }
01400 
01401                             unset($meta[$index]);
01402                             $phar[$entry]->setMetadata($meta);
01403                      } else {
01404                             exit($phar[$entry]->delMetadata() ? 0 : 1);
01405                      }
01406               } else {
01407                      if (isset($index)) {
01408                             if (!$phar->hasMetadata()) {
01409                                    exit(1);
01410                             }
01411 
01412                             $meta = $phar->getMetadata();
01413 
01414                             // @todo Add error message
01415                             if (!is_array($meta)) {
01416                                    exit(1);
01417                             }
01418 
01419                             unset($meta[$index]);
01420                             $phar->setMetadata($meta);
01421                      } else {
01422                             exit($phar->delMetadata() ? 0 : 1);
01423                      }
01424               }
01425        }
01426        // }}}
01427        // {{{ public function cli_cmd_inf_info
01433        public function cli_cmd_inf_info()
01434        {
01435               return "Get information about a PHAR package.\n" .
01436                         "By using -k it is possible to return a single value.";
01437        }
01438        // }}}
01439        // {{{ public function cli_cmd_arg_info
01445        public function cli_cmd_arg_info()
01446        {
01447               return self::phar_args('Fk', 'phar');
01448        }
01449        // }}}
01450        // {{{ public function cli_cmd_run_info
01456        public function cli_cmd_run_info()
01457        {
01458               $phar  = $this->args['f']['val'];
01459               $index = $this->args['k']['val'];
01460 
01461               $hash  = $phar->getSignature();
01462               $infos = array();
01463 
01464               if ($phar->getAlias()) {
01465                      $infos['Alias'] = $phar->getAlias();
01466               }
01467 
01468               if (!$hash) {
01469                      $infos['Hash-type'] = 'NONE';
01470               } else {
01471                      $infos['Hash-type'] = $hash['hash_type'];
01472                      $infos['Hash'] = $hash['hash'];
01473               }
01474 
01475               $csize   = 0;
01476               $usize   = 0;
01477               $count   = 0;
01478               $ccount  = 0;
01479               $ucount  = 0;
01480               $mcount  = 0;
01481               $compalg = array('GZ'=>0, 'BZ2'=>0);
01482 
01483               foreach(new RecursiveIteratorIterator($phar) as $ent) {
01484                      $count++;
01485                      if ($ent->isCompressed()) {
01486                             $ccount++;
01487                             $csize += $ent->getCompressedSize();
01488                             if ($ent->isCompressed(Phar::GZ)) {
01489                                    $compalg['GZ']++;
01490                             } elseif ($ent->isCompressed(Phar::BZ2)) {
01491                                    $compalg['BZ2']++;
01492                             }
01493                      } else {
01494                             $ucount++;
01495                             $csize += $ent->getSize();
01496                      }
01497 
01498                      $usize += $ent->getSize();
01499 
01500                      if ($ent->hasMetadata()) {
01501                             $mcount++;
01502                      }
01503               }
01504 
01505               $infos['Entries']            = $count;
01506               $infos['Uncompressed-files'] = $ucount;
01507               $infos['Compressed-files']   = $ccount;
01508               $infos['Compressed-gz']      = $compalg['GZ'];
01509               $infos['Compressed-bz2']     = $compalg['BZ2'];
01510               $infos['Uncompressed-size']  = $usize;
01511               $infos['Compressed-size']    = $csize;
01512               $infos['Compression-ratio']  = sprintf('%.3g%%', $usize ? ($csize * 100) / $usize : 100);
01513               $infos['Metadata-global']    = $phar->hasMetadata() * 1;
01514               $infos['Metadata-files']     = $mcount;
01515               $infos['Stub-size']          = strlen($phar->getStub());
01516 
01517               if (isset($index)) {
01518                      if (!isset($infos[$index])) {
01519                             self::error("Requested value does not exist.\n");
01520                      }
01521 
01522                      echo $infos[$index];
01523                      exit(0);
01524               }
01525 
01526               $l = 0;
01527               foreach($infos as $which => $val) {
01528                      $l = max(strlen($which), $l);
01529               }
01530 
01531               foreach($infos as $which => $val) {
01532                      echo $which . ':' . str_repeat(' ', $l + 1 - strlen($which)) . $val . "\n";
01533               }
01534        }
01535        // }}}
01536        // {{{ public function cli_cmd_inf_version
01542        public function cli_cmd_inf_version()
01543        {
01544               return "Get information about the PHAR environment and the tool version.";
01545        }
01546        // }}}
01547        // {{{ public function cli_cmd_arg_version
01553        public function cli_cmd_arg_version()
01554        {
01555               return self::phar_args('', NULL);
01556        }
01557        // }}}
01558        // {{{ public function cli_cmd_run_info
01564        public function cli_cmd_run_version()
01565        {
01566               $use_ext = extension_loaded('phar');
01567               $version = array(
01568                      'PHP Version' => phpversion(),
01569                      'phar.phar version' => '$Revision: 282735 $',
01570                      'Phar EXT version' => $use_ext ? phpversion('phar') : 'Not available',
01571                      'Phar API version' => Phar::apiVersion(),
01572                      'Phar-based phar archives' => true,
01573                      'Tar-based phar archives' => $use_ext,
01574                      'ZIP-based phar archives' => $use_ext,
01575                      'gzip compression' => extension_loaded('zlib'),
01576                      'bzip2 compression' => extension_loaded('bz2'),
01577                      'supported signatures' => $use_ext ? join(', ', Phar::getSupportedSignatures()) : '',
01578                      );
01579               $klen = 0;
01580               foreach($version as $k => $v)
01581               {
01582                      $klen = max($klen, strlen($k));
01583               }
01584               ++$klen;
01585               foreach($version as $k => $v) {
01586                      if (is_bool($v)) {
01587                             $v = $v ? 'enabled' : 'disabled';
01588                      }
01589                      printf("%-${klen}s  %s\n", $k.':', $v);
01590               }
01591        }
01592        // }}}
01593 }
01594 // }}}
01595 ?>