<?php
class PharCommand extends CLICommand
{
public function cli_get_SP2($l1, $arg_inf)
{
return str_repeat(' ', $l1 + 2 + 4 + 9);
}
function cli_get_SP3($l1, $l2, $arg_inf)
{
return str_repeat(' ', $l1 + 2 + 4 + 9 + 2 + $l2 + 2);
}
static function phar_args($which, $phartype)
{
$phar_args = array(
'a' => array(
'typ' => 'alias',
'val' => NULL,
'inf' => '<alias> Provide an alias name for the phar file.'
),
'b' => array(
'typ' => 'any',
'val' => NULL,
'inf' => '<bang> Hash-bang line to start the archive (e.g. #!/usr/bin/php). The hash '
.' mark itself \'#!\' and the newline character are optional.'
),
'c' => array(
'typ' => 'compalg',
'val' => NULL,
'inf' => '<algo> Compression algorithm.',
'select' => array(
'0' => 'No compression',
'none' => 'No compression',
'auto' => 'Automatically select compression algorithm'
)
),
'e' => array(
'typ' => 'entry',
'val' => NULL,
'inf' => '<entry> Name of entry to work on (must include PHAR internal directory name if any).'
),
'f' => array(
'typ' => $phartype,
'val' => NULL,
'inf' => '<file> Specifies the phar file to work on.'
),
'h' => array(
'typ' => 'select',
'val' => NULL,
'inf' => '<method> Selects the hash algorithm.',
'select' => array('md5' => 'MD5','sha1' => 'SHA1')
),
'i' => array(
'typ' => 'regex',
'val' => NULL,
'inf' => '<regex> Specifies a regular expression for input files.'
),
'k' => array(
'typ' => 'any',
'val' => NULL,
'inf' => '<index> Subscription index to work on.',
),
'l' => array(
'typ' => 'int',
'val' => 0,
'inf' => '<level> Number of preceding subdirectories to strip from file entries',
),
'm' => array(
'typ' => 'any',
'val' => NULL,
'inf' => '<meta> Meta data to store with entry (serialized php data).'
),
'p' => array(
'typ' => 'loader',
'val' => NULL,
'inf' => '<loader> Location of PHP_Archive class file (pear list-files PHP_Archive).'
.'You can use \'0\' or \'1\' to locate it automatically using the mentioned '
.'pear command. When using \'0\' the command does not error out when the '
.'class file cannot be located. This switch also adds some code around the '
.'stub so that class PHP_Archive gets registered as phar:// stream wrapper '
.'if necessary. And finally this switch will add the file phar.inc from '
.'this package and load it to ensure class Phar is present.'
,
),
's' => array(
'typ' => 'file',
'val' => NULL,
'inf' => '<stub> Select the stub file.'
),
'x' => array(
'typ' => 'regex',
'val' => NULL,
'inf' => '<regex> Regular expression for input files to exclude.'
),
'y' => array(
'typ' => 'privkey',
'val' => NULL,
'inf' => '<key> Private key for OpenSSL signing.',
),
);
if (extension_loaded('zlib')) {
$phar_args['c']['select']['gz'] = 'GZip compression';
$phar_args['c']['select']['gzip'] = 'GZip compression';
}
if (extension_loaded('bz2')) {
$phar_args['c']['select']['bz2'] = 'BZip2 compression';
$phar_args['c']['select']['bzip2'] = 'BZip2 compression';
}
$hash_avail = Phar::getSupportedSignatures();
$hash_optional = array('SHA-256' => 'SHA256',
'SHA-512' => 'SHA512',
'OpenSSL' => 'OpenSSL');
if (!in_array('OpenSSL', $hash_avail)) {
unset($phar_args['y']);
}
foreach($hash_optional as $key => $name) {
if (in_array($key, $hash_avail)) {
$phar_args['h']['select'][strtolower($name)] = $name;
}
}
$args = array();
foreach($phar_args as $lkey => $cfg) {
$ukey = strtoupper($lkey);
$required = strpos($which, $ukey) !== false;
$optional = strpos($which, $lkey) !== false;
if ($required || $optional) {
$args[$lkey] = $cfg;
$args[$lkey]['required'] = $required;
}
}
return $args;
}
static function strEndsWith($haystack, $needle)
{
return substr($haystack, -strlen($needle)) == $needle;
}
static function cli_arg_typ_loader($arg, $cfg, $key)
{
if (($arg == '0' || $arg == '1') && !file_exists($arg) && substr(PHP_OS, 0, 3) != 'WIN') {
$found = NULL;
$apiver = false;
$path = explode(PATH_SEPARATOR, $_ENV['PATH']);
$pear = false;
foreach ($path as $component) {
if (file_exists($component . DIRECTORY_SEPARATOR . 'pear')
&& is_executable($component . DIRECTORY_SEPARATOR . 'pear')) {
$pear = true;
break;
}
}
if ($pear) {
$apiver = `pear -q info PHP_Archive 2>/dev/null|grep 'API Version'`;
$apiver = trim(substr($apiver, strlen('API Version')));
}
if ($apiver) {
self::notice("PEAR package PHP_Archive: API Version: $apiver.\n");
$files = explode("\n", `pear list-files PHP_Archive`);
$phpdir = `pear config-get php_dir 2>/dev/null`;
$phpdir = trim($phpdir);
self::notice("PEAR package PHP_Archive: $phpdir.\n");
if (is_dir($phpdir)) {
foreach($files as $ent) {
$matches = NULL;
if (preg_match(",^php[ \t]+([^ \t].*[\\\\/]PHP[\\\\/]Archive\.php)$,", $ent, $matches)) {
$sub = $matches[1];
if (strpos($sub, $phpdir) !== 0) {
$found = NULL;
break;
}
$found = $sub;
break;
}
}
} else {
self::notice("PEAR package PHP_Archive: corrupt or inaccessible base dir: $php_dir.\n");
}
}
if (isset($found)) {
self::notice("PEAR package PHP_Archive: $found.\n");
} else {
$msg = "PEAR package PHP_Archive not installed: generated phar will require PHP's phar extension be enabled.\n";
if ($arg == '0') {
self::notice($msg);
} else {
self::error($msg);
}
}
$arg = $found;
}
return self::cli_arg_typ_file($arg);
}
static function cli_arg_typ_pharnew($arg, $cfg, $key)
{
$arg = self::cli_arg_typ_filenew($arg, $cfg, $key);
if (!Phar::isValidPharFilename($arg)) {
self::error("Phar files must have file extension '.phar', '.phar.php', '.phar.bz2' or '.phar.gz'.\n");
}
return $arg;
}
static function cli_arg_typ_pharfile($arg, $cfg, $key)
{
try {
$pharfile = self::cli_arg_typ_file($arg, $cfg, $key);
if (!Phar::loadPhar($pharfile)) {
self::error("Unable to open phar '$arg'\n");
}
return $pharfile;
} catch(Exception $e) {
self::error("Exception while opening phar '$arg':\n" . $e->getMessage() . "\n");
}
}
static function cli_arg_typ_pharurl($arg, $cfg, $key)
{
return 'phar://' . self::cli_arg_typ_pharfile($arg, $cfg, $key);
}
static function cli_arg_typ_phar($arg, $cfg, $key)
{
try {
return new Phar(self::cli_arg_typ_pharfile($arg, $cfg, $key));
} catch(Exception $e) {
self::error("Exception while opening phar '$argv':\n" . $e->getMessage() . "\n");
}
}
static function cli_arg_typ_entry($arg, $cfg, $key)
{
return $arg;
}
static function cli_arg_typ_compalg($arg, $cfg, $key)
{
$arg = self::cli_arg_typ_select($arg, $cfg, $key);
switch($arg) {
case 'auto':
if (extension_loaded('zlib')) {
$arg = 'gz';
} elseif (extension_loaded('bz2')) {
$arg = 'bz2';
} else {
$arg = '0';
}
break;
}
return $arg;
}
static function cli_arg_typ_privkey($arg, $cfg, $key)
{
$arg = self::cli_arg_typ_filecont($arg, $cfg, $key);
$hash_avail = Phar::getSupportedSignatures();
if ($arg && !in_array('OpenSSL', $hash_avail))
{
self::error("Cannot specifiy private key without OpenSSL support.\n");
}
return $arg;
}
function phar_check_hash($hash, $privkey)
{
switch($hash) {
case 'md5':
return Phar::MD5;
case 'sha1':
return Phar::SHA1;
case 'sha256':
return Phar::SHA256;
case 'sha512':
return Phar::SHA512;
case 'openssl':
if (!$privkey) {
self::error("Cannot use OpenSSL signing without key.\n");
}
return Phar::OPENSSL;
}
}
static function cli_cmd_inf_pack()
{
return "Pack files into a PHAR archive.\n" .
"When using -s <stub>, then the stub file is being " .
"excluded from the list of input files/dirs." .
"To create an archive that contains PEAR class PHP_Archive " .
"then point -p argument to PHP/Archive.php.\n";
}
static function cli_cmd_arg_pack()
{
$args = self::phar_args('abcFhilpsxy', 'pharnew');
$args[''] = array(
'typ' => 'any',
'val' => NULL,
'required' => 1,
'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.',
);
return $args;
}
public function phar_set_stub_begin(Phar $phar, $stub, $loader = NULL, $hashbang = NULL)
{
if (isset($stub)) {
$c = file_get_contents($stub);
if (substr($c, 0, 2) == '#!') {
if (strpos($c, "\n") !== false) {
if (!isset($hashbang)) {
$hashbang = substr($c, 0, strpos($c, "\n") + 1);
}
$c = substr($c, strpos($c, "\n") + 1);
} else {
if (!isset($hashbang)) {
$hashbang = $c;
}
$c = NULL;
}
}
if (isset($hashbang)) {
if (substr($hashbang, 0, 2) != '#!') {
$hashbang = '#!' . $hashbang;
}
if (substr($hashbang, -1) != "\n") {
$hashbang .= "\n";
}
} else {
$hashbang = "";
}
if (isset($loader)) {
$s = "<?php if (!class_exists('PHP_Archive')) {\n?>";
if (is_file($loader)) {
$s .= file_get_contents($loader);
}
$s .= "<?php\n";
$s .= "}\n";
$s .= "if (!in_array('phar', stream_get_wrappers())) {\n";
$s .= "\tstream_wrapper_register('phar', 'PHP_Archive');\n";
$s .= "}\n";
$s .= "if (!class_exists('Phar',0)) {\n";
$s .= "\tinclude 'phar://'.__FILE__.'/phar.inc';\n";
$s .= "}\n";
$s .= '?>';
$s .= $c;
$phar->setStub($hashbang . $s);
} else {
$phar->setStub($hashbang . $c);
}
return new SplFileInfo($stub);
}
return NULL;
}
public function phar_set_stub_end(Phar $phar, $stub, $loader = NULL)
{
if (isset($stub) && isset($loader)) {
if (substr(__FILE__, -15) == 'pharcommand.inc') {
self::phar_add_file($phar, 0, 'phar.inc', 'phar://'.__FILE__.'/phar.inc', NULL);
} else {
self::phar_add_file($phar, 0, 'phar.inc', dirname(__FILE__).'/phar/phar.inc', NULL);
}
}
}
public function cli_cmd_run_pack()
{
if (ini_get('phar.readonly')) {
self::error("Creating phar files is disabled by ini setting 'phar.readonly'.\n");
}
if (!Phar::canWrite()) {
self::error("Creating phar files is disabled, Phar::canWrite() returned false.\n");
}
$alias = $this->args['a']['val'];
$hashbang = $this->args['b']['val'];
$archive = $this->args['f']['val'];
$hash = $this->args['h']['val'];
$privkey = $this->args['y']['val'];
$regex = $this->args['i']['val'];
$level = $this->args['l']['val'];
$loader = $this->args['p']['val'];
$stub = $this->args['s']['val'];
$invregex = $this->args['x']['val'];
$input = $this->args['']['val'];
$hash = self::phar_check_hash($hash, $privkey);
$phar = new Phar($archive, 0, $alias);
$phar->startBuffering();
$stub = $this->phar_set_stub_begin($phar, $stub, $loader, $hashbang);
if (!is_array($input)) {
$this->phar_add($phar, $level, $input, $regex, $invregex, $stub, NULL, isset($loader));
} else {
foreach($input as $i) {
$this->phar_add($phar, $level, $i, $regex, $invregex, $stub, NULL, isset($loader));
}
}
$this->phar_set_stub_end($phar, $stub, $loader);
switch($this->args['c']['val']) {
case 'gz':
case 'gzip':
$phar->compressFiles(Phar::GZ);
break;
case 'bz2':
case 'bzip2':
$phar->compressFiles(Phar::BZ2);
break;
default:
$phar->decompressFiles();
break;
}
if ($hash) {
$phar->setSignatureAlgorithm($hash, $privkey);
}
$phar->stopBuffering();
exit(0);
}
static function phar_add(Phar $phar, $level, $input, $regex, $invregex, SplFileInfo $stub = NULL, $compress = NULL, $noloader = false)
{
if ($input && is_file($input) && !is_dir($input)) {
return self::phar_add_file($phar, $level, $input, $input, $compress);
}
$dir = new RecursiveDirectoryIterator($input);
$dir = new RecursiveIteratorIterator($dir);
if (isset($regex)) {
$dir = new RegexIterator($dir, $regex);
}
if (isset($invregex)) {
$dir = new InvertedRegexIterator($dir, $invregex);
}
try {
foreach($dir as $file) {
if ((empty($stub) || $file->getRealPath() != $stub->getRealPath()) && !is_dir($file)) {
self::phar_add_file($phar, $level, $dir->getSubPathName(), $file, $compress, $noloader);
}
}
} catch(Excpetion $e) {
self::error("Unable to complete operation on file '$file'\n" . $e->getMessage() . "\n");
}
}
static function phar_add_file(Phar $phar, $level, $entry, $file, $compress, $noloader = false)
{
$entry = str_replace('//', '/', $entry);
while($level-- > 0 && ($p = strpos($entry, '/')) !== false) {
$entry = substr($entry, $p+1);
}
if ($noloader && $entry == 'phar.inc') {
return;
}
echo "$entry\n";
$phar[$entry] = file_get_contents($file);
switch($compress) {
case 'gz':
case 'gzip':
$phar[$entry]->compress(Phar::GZ);
break;
case 'bz2':
case 'bzip2':
$phar[$entry]->compress(Phar::BZ2);
break;
case '0':
$phar[$entry]->decompress();
break;
default:
break;
}
}
public function phar_dir_echo($pn, $f)
{
echo "$f\n";
}
public function phar_dir_operation(RecursiveIteratorIterator $dir, $func, array $args = array())
{
$regex = $this->args['i']['val'];
$invregex= $this->args['x']['val'];
if (isset($regex)) {
$dir = new RegexIterator($dir, $regex);
}
if (isset($invregex)) {
$dir = new InvertedRegexIterator($dir, $invregex);
}
$any = false;
foreach($dir as $pn => $f) {
$any = true;
call_user_func($func, $pn, $f, $args);
}
return $any;
}
static function cli_cmd_inf_list()
{
return "List contents of a PHAR archive.";
}
static function cli_cmd_arg_list()
{
return self::phar_args('Fix', 'pharurl');
}
public function cli_cmd_run_list()
{
$this->phar_dir_operation(
new DirectoryTreeIterator(
$this->args['f']['val']),
array($this, 'phar_dir_echo')
);
}
static function cli_cmd_inf_tree()
{
return "Get a directory tree for a PHAR archive.";
}
static function cli_cmd_arg_tree()
{
return self::phar_args('Fix', 'pharurl');
}
public function cli_cmd_run_tree()
{
$a = $this->phar_dir_operation(
new DirectoryGraphIterator(
$this->args['f']['val']),
array($this, 'phar_dir_echo')
);
if (!$a) {
echo "|-<root directory>\n";
}
}
static function cli_cmd_inf_extract()
{
return "Extract a PHAR package to a directory.";
}
static function cli_cmd_arg_extract()
{
$args = self::phar_args('Fix', 'phar');
$args[''] = array(
'type' => 'dir',
'val' => '.',
'inf' => ' Directory to extract to (defaults to \'.\').',
);
return $args;
}
public function cli_cmd_run_extract()
{
$dir = $this->args['']['val'];
if (is_array($dir)) {
if (count($dir) != 1) {
self::error("Only one target directory allowed.\n");
} else {
$dir = $dir[0];
}
}
$phar = $this->args['f']['val'];
$base = $phar->getPathname();
$bend = strpos($base, '.phar');
$bend = strpos($base, '/', $bend);
$base = substr($base, 0, $bend + 1);
$blen = strlen($base);
$this->phar_dir_operation(
new RecursiveIteratorIterator($phar),
array($this, 'phar_dir_extract'),
array($blen, $dir)
);
}
public function phar_dir_extract($pn, $f, $args)
{
$blen = $args[0];
$dir = $args[1];
$sub = substr($pn, $blen);
$target = $dir . '/' . $sub;
if (!file_exists(dirname($target))) {
@mkdir(dirname($target), 0777, true);
}
if (!file_exists(dirname($target))) {
self::error("Operation could not be completed\n");
}
echo "$sub";
if (!@copy($f, $target)) {
echo " ...error\n";
} else {
echo " ...ok\n";
}
}
static function cli_cmd_inf_delete()
{
return 'Delete entry from a PHAR archive';
}
static function cli_cmd_arg_delete()
{
return self::phar_args('FE', 'phar');
}
public function cli_cmd_run_delete()
{
$phar = $this->args['f']['val'];
$entry = $this->args['e']['val'];
$phar->startBuffering();
unset($phar[$entry]);
$phar->stopBuffering();
}
static function cli_cmd_inf_add()
{
return "Add entries to a PHAR package.";
}
static function cli_cmd_arg_add()
{
$args = self::phar_args('acFilx', 'phar');
$args[''] = array(
'type' => 'any',
'val' => NULL,
'required' => 1,
'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.',
);
return $args;
}
public function cli_cmd_run_add()
{
$compress= $this->args['c']['val'];
$phar = $this->args['f']['val'];
$regex = $this->args['i']['val'];
$level = $this->args['l']['val'];
$invregex= $this->args['x']['val'];
$input = $this->args['']['val'];
$phar->startBuffering();
if (!is_array($input)) {
$this->phar_add($phar, $level, $input, $regex, $invregex, NULL, $compress);
} else {
foreach($input as $i) {
$this->phar_add($phar, $level, $i, $regex, $invregex, NULL, $compress);
}
}
$phar->stopBuffering();
exit(0);
}
public function cli_cmd_inf_stub_set()
{
return "Set the stub of a PHAR file. " .
"If no input file is specified as stub then stdin is being used.";
}
public function cli_cmd_arg_stub_set()
{
$args = self::phar_args('bFps', 'phar');
$args['s']['val'] = 'php://stdin';
return $args;
}
public function cli_cmd_run_stub_set()
{
$hashbang = $this->args['b']['val'];
$phar = $this->args['f']['val'];
$stub = $this->args['s']['val'];
$loader = $this->args['p']['val'];
$this->phar_set_stub_begin($phar, $stub, $loader, $hashbang);
$this->phar_set_stub_end($phar, $stub, $loader);
}
public function cli_cmd_inf_stub_get()
{
return "Get the stub of a PHAR file. " .
"If no output file is specified as stub then stdout is being used.";
}
public function cli_cmd_arg_stub_get()
{
$args = self::phar_args('Fs', 'phar');
$args['s']['val'] = 'php://stdin';
return $args;
}
public function cli_cmd_run_stub_get($args)
{
$phar = $this->args['f']['val'];
$stub = $this->args['s']['val'];
file_put_contents($stub, $phar->getStub());
}
public function cli_cmd_inf_compress()
{
return "Compress or uncompress all files or a selected entry.";
}
public function cli_cmd_arg_compress()
{
return self::phar_args('FCe', 'phar');
}
public function cli_cmd_run_compress()
{
$phar = $this->args['f']['val'];
$entry = $this->args['e']['val'];
switch($this->args['c']['val']) {
case 'gz':
case 'gzip':
if (isset($entry)) {
$phar[$entry]->compress(Phar::GZ);
} else {
$phar->compressFiles(Phar::GZ);
}
break;
case 'bz2':
case 'bzip2':
if (isset($entry)) {
$phar[$entry]->compress(Phar::BZ2);
} else {
$phar->compressFiles(Phar::BZ2);
}
break;
default:
if (isset($entry)) {
$phar[$entry]->decompress();
} else {
$phar->decompressFiles();
}
break;
}
}
public function cli_cmd_inf_sign()
{
return "Set signature hash algorithm.";
}
public function cli_cmd_arg_sign()
{
return self::phar_args('FHy', 'phar');
}
public function cli_cmd_run_sign()
{
$phar = $this->args['f']['val'];
$hash = $this->args['h']['val'];
$privkey = $this->args['y']['val'];
$hash = self::phar_check_hash($hash, $privkey);
$phar->setSignatureAlgorithm($hash, $privkey);
}
public function cli_cmd_inf_meta_set()
{
return "Set meta data of a PHAR entry or a PHAR package using serialized input. " .
"If no input file is specified for meta data then stdin is being used." .
"You can also specify a particular index using -k. In that case the metadata is " .
"expected to be an array and the value of the given index is being set. If " .
"the metadata is not present or empty a new array will be created. If the " .
"metadata is present and a flat value then the return value is 1. Also using -k " .
"the input is been taken directly rather then being serialized.";
}
public function cli_cmd_arg_meta_set()
{
return self::phar_args('FekM', 'phar');
}
public function cli_cmd_run_meta_set()
{
$phar = $this->args['f']['val'];
$entry = $this->args['e']['val'];
$index = $this->args['k']['val'];
$meta = $this->args['m']['val'];
$phar->startBuffering();
if (isset($index)) {
if (isset($entry)) {
if ($phar[$entry]->hasMetadata()) {
$old = $phar[$entry]->getMetadata();
} else {
$old = array();
}
} else {
if ($phar->hasMetadata()) {
$old = $phar->getMetadata();
} else {
$old = array();
}
}
if (!is_array($old)) {
self::error('Metadata is a flat value while an index operation was issued.');
}
$old[$index] = $meta;
$meta = $old;
} else {
$meta = unserialize($meta);
}
if (isset($entry)) {
$phar[$entry]->setMetadata($meta);
} else {
$phar->setMetadata($meta);
}
$phar->stopBuffering();
}
public function cli_cmd_inf_meta_get()
{
return "Get meta information of a PHAR entry or a PHAR package in serialized from. " .
"If no output file is specified for meta data then stdout is being used.\n" .
"You can also specify a particular index using -k. In that case the metadata is " .
"expected to be an array and the value of the given index is returned using echo " .
"rather than using serialize. If that index does not exist or no meta data is " .
"present then the return value is 1.";
}
public function cli_cmd_arg_meta_get()
{
return self::phar_args('Fek', 'phar');
}
public function cli_cmd_run_meta_get()
{
$phar = $this->args['f']['val'];
$entry = $this->args['e']['val'];
$index = $this->args['k']['val'];
if (isset($entry)) {
if (!$phar[$entry]->hasMetadata()) {
echo "No Metadata\n";
exit(1);
}
echo serialize($phar[$entry]->getMetadata());
} else {
if (!$phar->hasMetadata()) {
echo "No Metadata\n";
exit(1);
}
$meta = $phar->getMetadata();
}
if (isset($index)) {
if (isset($index)) {
if (isset($meta[$index])) {
echo $meta[$index];
exit(0);
} else {
echo "No Metadata\n";
exit(1);
}
} else {
echo serialize($meta);
}
}
}
public function cli_cmd_inf_meta_del()
{
return "Delete meta information of a PHAR entry or a PHAR package.\n" .
"If -k is given then the metadata is expected to be an array " .
"and the given index is being deleted.\n" .
"If something was deleted the return value is 0 otherwise it is 1.";
}
public function cli_cmd_arg_meta_del()
{
return self::phar_args('Fek', 'phar');
}
public function cli_cmd_run_meta_del()
{
$phar = $this->args['f']['val'];
$entry = $this->args['e']['val'];
$index = $this->args['k']['val'];
if (isset($entry)) {
if (isset($index)) {
if (!$phar[$entry]->hasMetadata()) {
exit(1);
}
$meta = $phar[$entry]->getMetadata();
if (!is_array($meta)) {
exit(1);
}
unset($meta[$index]);
$phar[$entry]->setMetadata($meta);
} else {
exit($phar[$entry]->delMetadata() ? 0 : 1);
}
} else {
if (isset($index)) {
if (!$phar->hasMetadata()) {
exit(1);
}
$meta = $phar->getMetadata();
if (!is_array($meta)) {
exit(1);
}
unset($meta[$index]);
$phar->setMetadata($meta);
} else {
exit($phar->delMetadata() ? 0 : 1);
}
}
}
public function cli_cmd_inf_info()
{
return "Get information about a PHAR package.\n" .
"By using -k it is possible to return a single value.";
}
public function cli_cmd_arg_info()
{
return self::phar_args('Fk', 'phar');
}
public function cli_cmd_run_info()
{
$phar = $this->args['f']['val'];
$index = $this->args['k']['val'];
$hash = $phar->getSignature();
$infos = array();
if ($phar->getAlias()) {
$infos['Alias'] = $phar->getAlias();
}
if (!$hash) {
$infos['Hash-type'] = 'NONE';
} else {
$infos['Hash-type'] = $hash['hash_type'];
$infos['Hash'] = $hash['hash'];
}
$csize = 0;
$usize = 0;
$count = 0;
$ccount = 0;
$ucount = 0;
$mcount = 0;
$compalg = array('GZ'=>0, 'BZ2'=>0);
foreach(new RecursiveIteratorIterator($phar) as $ent) {
$count++;
if ($ent->isCompressed()) {
$ccount++;
$csize += $ent->getCompressedSize();
if ($ent->isCompressed(Phar::GZ)) {
$compalg['GZ']++;
} elseif ($ent->isCompressed(Phar::BZ2)) {
$compalg['BZ2']++;
}
} else {
$ucount++;
$csize += $ent->getSize();
}
$usize += $ent->getSize();
if ($ent->hasMetadata()) {
$mcount++;
}
}
$infos['Entries'] = $count;
$infos['Uncompressed-files'] = $ucount;
$infos['Compressed-files'] = $ccount;
$infos['Compressed-gz'] = $compalg['GZ'];
$infos['Compressed-bz2'] = $compalg['BZ2'];
$infos['Uncompressed-size'] = $usize;
$infos['Compressed-size'] = $csize;
$infos['Compression-ratio'] = sprintf('%.3g%%', $usize ? ($csize * 100) / $usize : 100);
$infos['Metadata-global'] = $phar->hasMetadata() * 1;
$infos['Metadata-files'] = $mcount;
$infos['Stub-size'] = strlen($phar->getStub());
if (isset($index)) {
if (!isset($infos[$index])) {
self::error("Requested value does not exist.\n");
}
echo $infos[$index];
exit(0);
}
$l = 0;
foreach($infos as $which => $val) {
$l = max(strlen($which), $l);
}
foreach($infos as $which => $val) {
echo $which . ':' . str_repeat(' ', $l + 1 - strlen($which)) . $val . "\n";
}
}
public function cli_cmd_inf_version()
{
return "Get information about the PHAR environment and the tool version.";
}
public function cli_cmd_arg_version()
{
return self::phar_args('', NULL);
}
public function cli_cmd_run_version()
{
$use_ext = extension_loaded('phar');
$version = array(
'PHP Version' => phpversion(),
'phar.phar version' => '$Id: a58a9f060a207c567585aa4858b862d9278df83d $',
'Phar EXT version' => $use_ext ? phpversion('phar') : 'Not available',
'Phar API version' => Phar::apiVersion(),
'Phar-based phar archives' => true,
'Tar-based phar archives' => $use_ext,
'ZIP-based phar archives' => $use_ext,
'gzip compression' => extension_loaded('zlib'),
'bzip2 compression' => extension_loaded('bz2'),
'supported signatures' => $use_ext ? join(', ', Phar::getSupportedSignatures()) : '',
);
$klen = 0;
foreach($version as $k => $v)
{
$klen = max($klen, strlen($k));
}
++$klen;
foreach($version as $k => $v) {
if (is_bool($v)) {
$v = $v ? 'enabled' : 'disabled';
}
printf("%-${klen}s %s\n", $k.':', $v);
}
}
}
?>