@@ -0,0 +1,42 @@ | |||||
composer.phar | |||||
/old/ | |||||
# Compiled source # | |||||
################### | |||||
*.com | |||||
*.class | |||||
*.dll | |||||
*.exe | |||||
*.o | |||||
*.so | |||||
# Packages # | |||||
############ | |||||
# it's better to unpack these files and commit the raw source | |||||
# git has its own built in compression methods | |||||
*.7z | |||||
*.dmg | |||||
*.gz | |||||
*.iso | |||||
*.jar | |||||
*.rar | |||||
*.tar | |||||
*.zip | |||||
# Logs and databases # | |||||
###################### | |||||
*.log | |||||
*.sql | |||||
*.sqlite | |||||
# OS generated files # | |||||
###################### | |||||
.DS_Store | |||||
.DS_Store? | |||||
._* | |||||
.Spotlight-V100 | |||||
.Trashes | |||||
ehthumbs.db | |||||
Thumbs.db | |||||
@@ -0,0 +1,21 @@ | |||||
################################################## | |||||
# Gustavo Arnosti Neves - 2016 Jul 11 | |||||
# Simple makefile for system install / uninstall | |||||
# PHP cli-barcode-generator | |||||
# Change INSTDIR if you want to install somewhere else | |||||
INSTDIR=/usr/local/bin | |||||
BC_BASH=barcode | |||||
all: | |||||
install: | |||||
cp ${BC_BASH} ${INSTDIR}/${BC_BASH} | |||||
chmod 755 ${INSTDIR}/${BC_BASH} | |||||
permissions: | |||||
find . -type d -exec chmod 0755 {} \; | |||||
find . -type f -exec chmod 0644 {} \; | |||||
uninstall: | |||||
rm ${INSTDIR}/${BC_BASH} |
@@ -0,0 +1,15 @@ | |||||
#!/usr/bin/env bash | |||||
################################################## | |||||
# Gustavo Arnosti Neves - 2016 Jul 11 | |||||
# Simple bash script for global barcode executable | |||||
# PHP cli-barcode-generator | |||||
# | |||||
# Please run "./barcode.php --create-bash" to update this script | |||||
# You can then use sudo make install to copy it to /usr/local/bin | |||||
# | |||||
# This won't work on windows | |||||
# | |||||
BARCODE_LOCATION="./barcode.php" # enter full path here | |||||
/usr/bin/env php "$BARCODE_LOCATION" "$@" |
@@ -0,0 +1,298 @@ | |||||
#!/usr/bin/env php | |||||
<?php | |||||
########################################################################## | |||||
# Gustavo Arnosti Neves - 2016 Jul 11 | |||||
# guneves < a t > gmail < d o t > com | |||||
# | |||||
# PHP cli-barcode-generator | |||||
# | |||||
# Most of the work here is for option / argument parsing. | |||||
# Picqer's barcode framework makes it east on the bar coding generation. | |||||
# While ulrichsg's getopt-php helps with the cli part. | |||||
# | |||||
########################################################################## | |||||
require_once 'vendor/autoload.php'; | |||||
define("_BC_VERSION", "1.0.2"); | |||||
# permission to set to barcode files | |||||
define("_BC_PERMISSION", 0644); | |||||
# group to set to barcode files (disabled at bot) | |||||
define("_BC_SYSGROUP", "yourGrpHere"); | |||||
# default padding for barcode | |||||
define("_BC_PADDING", 30); | |||||
$verbose = false; | |||||
$quiet = false; | |||||
$encoding = null; | |||||
$format = null; | |||||
$bc_string = null; | |||||
$bc_file = null; | |||||
$width = 2; | |||||
$height = 30; | |||||
$color = '#000000'; | |||||
$encodings_list = array( | |||||
'CODE_39', | |||||
'CODE_39_CHECKSUM', | |||||
'CODE_39E', | |||||
'CODE_39E_CHECKSUM', | |||||
'CODE_93', | |||||
'STANDARD_2_5', | |||||
'STANDARD_2_5_CHECKSUM', | |||||
'INTERLEAVED_2_5', | |||||
'INTERLEAVED_2_5_CHECKSUM', | |||||
'CODE_128', | |||||
'CODE_128_A', | |||||
'CODE_128_B', | |||||
'CODE_128_C', | |||||
'EAN_2', | |||||
'EAN_5', | |||||
'EAN_8', | |||||
'EAN_13', | |||||
'UPC_A', | |||||
'UPC_E', | |||||
'MSI', | |||||
'MSI_CHECKSUM', | |||||
'POSTNET', | |||||
'PLANET', | |||||
'RMS4CC', | |||||
'KIX', | |||||
'IMB', | |||||
'CODABAR', | |||||
'CODE_11', | |||||
'PHARMA_CODE', | |||||
'PHARMA_CODE_TWO_TRACKS' | |||||
); | |||||
sort($encodings_list); | |||||
$formats_list = array( | |||||
'SVG', | |||||
'PNG', | |||||
'JPG', | |||||
'HTML' | |||||
); | |||||
sort($formats_list); | |||||
/////////////////// GETOPT STARTS | |||||
use Ulrichsg\Getopt\Getopt; | |||||
use Ulrichsg\Getopt\Option; | |||||
use Ulrichsg\Getopt\Argument; | |||||
// define and configure options | |||||
$getopt = new Getopt(array( | |||||
(new Option('e', 'encoding', Getopt::REQUIRED_ARGUMENT)) | |||||
->setDescription('Barcode encoding type selection') | |||||
->setValidation(function($value) { | |||||
global $encodings_list; | |||||
return in_array(strtoupper($value), $encodings_list); | |||||
}) | |||||
->setArgument(new Argument(null, null, 'bar-type')), | |||||
(new Option('f', 'format', Getopt::REQUIRED_ARGUMENT)) | |||||
->setDescription('Output format for the barcode') | |||||
->setValidation(function($value, $formats_list) { | |||||
global $formats_list; | |||||
return in_array(strtoupper($value), $formats_list); | |||||
}) | |||||
->setArgument(new Argument(null, null, 'file-type')), | |||||
(new Option('w', 'width', Getopt::REQUIRED_ARGUMENT)) | |||||
->setDescription('Width factor for bars to make wider, defaults to 2') | |||||
->setArgument(new Argument(2, 'is_numeric', 'points')), | |||||
(new Option('h', 'height', Getopt::REQUIRED_ARGUMENT)) | |||||
->setDescription('Total height of the barcode, defaults to 30') | |||||
->setArgument(new Argument(30, 'is_numeric', 'points')), | |||||
(new Option('c', 'color', Getopt::REQUIRED_ARGUMENT)) | |||||
->setDescription('Hex code of the foreground color, defaults to black') | |||||
->setArgument(new Argument('#000000', 'not_empty', 'hex-color')), | |||||
(new Option('v', 'verbose')) | |||||
->setDescription('Display extra information') | |||||
->setDefaultValue(false), | |||||
(new Option('q', 'quiet')) | |||||
->setDescription('Supress all messages') | |||||
->setDefaultValue(false), | |||||
(new Option(null, 'help')) | |||||
->setDescription('Help Information, including encodings and formats'), | |||||
(new Option(null, 'version')) | |||||
->setDescription('Display version information and exits'), | |||||
(new Option(null, 'create-bash')) | |||||
->setDescription('Creates a bash script named barcode that can call this script') | |||||
)); | |||||
$getopt->setBanner("Usage: barcode -e <encoding> -f <output_format> [options] <barcode string> <output file>\n"); | |||||
try { | |||||
$getopt->parse(); | |||||
if ($getopt['version']) { | |||||
echo "PHP-CLI Barcode v"._BC_VERSION."\n"; | |||||
exit(0); | |||||
} | |||||
if ($getopt['help']) { | |||||
print_help($getopt); | |||||
exit(0); | |||||
} | |||||
if ($getopt['create-bash']) { | |||||
create_bash_script(); | |||||
exit(1); | |||||
} | |||||
$verbose = $getopt['verbose']; | |||||
$quiet = $getopt['quiet']; | |||||
$encoding = $getopt['encoding']; | |||||
$format = $getopt['format']; | |||||
$width = $getopt['width']; | |||||
$height = $getopt['height']; | |||||
$color = $getopt['color']; | |||||
$bc_string = $getopt->getOperand(0); | |||||
$bc_file = $getopt->getOperand(1); | |||||
} catch (UnexpectedValueException $e) { | |||||
echo "Error: ".$e->getMessage()."\n"; | |||||
echo $getopt->getHelpText(_BC_PADDING); | |||||
exit(1); | |||||
} | |||||
// check if we can proceed | |||||
if (empty($encoding) || empty($format) || empty($bc_string) || empty($bc_file)) { | |||||
echo "Error: Invalid parameters or options.\n"; | |||||
echo $getopt->getHelpText(_BC_PADDING); | |||||
exit(1); | |||||
} | |||||
// Match case | |||||
$encoding = strtoupper($encoding); | |||||
$format = strtoupper($format); | |||||
/////////////////// GETOPT ENDS | |||||
/////////////////// CREATE BARCODE | |||||
// creates a bash script named barcode that will run this script | |||||
// from anywhere on the system. Assumes barcode.php is running | |||||
// on its final installation location | |||||
function create_bash_script() { | |||||
$error = true; | |||||
$bc_path = __FILE__; | |||||
$bash_path = dirname($bc_path) . DIRECTORY_SEPARATOR . "barcode"; | |||||
$bash_script = <<<EOF | |||||
#!/usr/bin/env bash | |||||
################################################## | |||||
# Gustavo Arnosti Neves - 2016 Jul 11 | |||||
# Simple bash script for global barcode executable | |||||
# PHP cli-barcode-generator | |||||
# | |||||
# Please run "./barcode.php --create-bash" to update this script | |||||
# You can then use sudo make install to copy it to /usr/local/bin | |||||
# | |||||
# This won't work on windows | |||||
# | |||||
BARCODE_LOCATION="$bc_path" # enter full path here | |||||
/usr/bin/env php "\$BARCODE_LOCATION" "\$@" | |||||
EOF; | |||||
if (file_exists($bash_path)) { | |||||
unlink($bash_path) or die("Could not remove old barcode script, are you running from it?"); | |||||
} | |||||
$error = file_put_contents($bash_path, $bash_script) === true ? false : true; | |||||
$error = chmod($bash_path, 0755) === true ? false : true; | |||||
if ($error) { | |||||
echo "\nAn error was detected during the process.\n"; | |||||
echo "Please check for permissions and try again.\n\n"; | |||||
exit(2); | |||||
} | |||||
echo "\nThe file \"$bash_path\" was successfully created.\n"; | |||||
echo "You may perform a system install to /usr/local/bin by issuing\n"; | |||||
echo "the command \"sudo make install\"\n\n"; | |||||
exit(0); | |||||
} | |||||
// get actual barcode type string | |||||
$bc_type = constant('Picqer\Barcode\BarcodeGenerator::TYPE_'.$encoding); | |||||
// add trailling zero if odd digits on Code128C | |||||
$bc_string = strlen($bc_string) % 2 == 0 && $encoding === 'CODE_128_C'? | |||||
$bc_string : '0'.$bc_string; | |||||
// create appropriate generator | |||||
$generator = null; | |||||
if ($format === 'SVG') { | |||||
$generator = new Picqer\Barcode\BarcodeGeneratorSVG(); | |||||
} else if ($format === 'PNG') { | |||||
$generator = new Picqer\Barcode\BarcodeGeneratorPNG(); | |||||
} else if ($format === 'JPG') { | |||||
$generator = new Picqer\Barcode\BarcodeGeneratorJPG(); | |||||
} else if ($format === 'HTML') { | |||||
$generator = new Picqer\Barcode\BarcodeGeneratorHTML(); | |||||
} else { | |||||
exit(1); | |||||
} | |||||
// generate de barcode | |||||
$bc_data = $generator->getBarcode($bc_string, $bc_type, $width, $height, $color); | |||||
// save to file | |||||
if (file_put_contents($bc_file, $bc_data) === false) { | |||||
echo "Error: could not save file $bc_file!\n"; | |||||
exit(1); | |||||
} | |||||
// set permissions and group | |||||
chmod($bc_file, _BC_PERMISSION); | |||||
#chgrp($bc_file, _BC_SYSGROUP); | |||||
// prints help information | |||||
function print_help($getopt) { | |||||
global $encodings_list; | |||||
global $formats_list; | |||||
echo $getopt->getHelpText(_BC_PADDING); | |||||
echo "\nRequired Options and Parameters:\n"; | |||||
echo " -e <encoding>\n"; | |||||
echo " -f <output format>\n"; | |||||
echo " <input string>\n"; | |||||
echo " <output file>\n"; | |||||
echo "\nOutput Formats:\n"; | |||||
foreach($formats_list as $for) { | |||||
echo " $for\n"; | |||||
} | |||||
echo "\nEncodings:\n"; | |||||
foreach($encodings_list as $enc) { | |||||
echo " $enc\n"; | |||||
} | |||||
echo "\nExamples:\n"; | |||||
echo " barcode -f HTML -e CODE_39 \"1234567890\" \"/tmp/1234567890.html\"\n"; | |||||
echo " barcode -e CODE_128 -f PNG -c \"#888\" -w 3 -h 50 \"AGREATBAR\" \"/tmp/AGREATBAR.png\"\n"; | |||||
echo " barcode \"1234567890\" \"/tmp/mybar.svg\" --encoding EAN_13 --format SVG\n"; | |||||
} | |||||
// check if empty (callback) | |||||
function not_empty($str) { | |||||
return (!empty($str)); | |||||
} | |||||
// done | |||||
exit(0); | |||||
?> |
@@ -0,0 +1,6 @@ | |||||
{ | |||||
"require": { | |||||
"picqer/php-barcode-generator": "^0.1.0", | |||||
"ulrichsg/getopt-php": "^2.3" | |||||
} | |||||
} |
@@ -0,0 +1,120 @@ | |||||
{ | |||||
"_readme": [ | |||||
"This file locks the dependencies of your project to a known state", | |||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", | |||||
"This file is @generated automatically" | |||||
], | |||||
"hash": "a723e9e5630e78d2303e845440a976b2", | |||||
"content-hash": "8180bfe7b58f0f40617b074b3efc026a", | |||||
"packages": [ | |||||
{ | |||||
"name": "picqer/php-barcode-generator", | |||||
"version": "v0.1", | |||||
"source": { | |||||
"type": "git", | |||||
"url": "https://github.com/picqer/php-barcode-generator.git", | |||||
"reference": "bd486cfb311989a506c62827fdee463b8a698002" | |||||
}, | |||||
"dist": { | |||||
"type": "zip", | |||||
"url": "https://api.github.com/repos/picqer/php-barcode-generator/zipball/bd486cfb311989a506c62827fdee463b8a698002", | |||||
"reference": "bd486cfb311989a506c62827fdee463b8a698002", | |||||
"shasum": "" | |||||
}, | |||||
"require": { | |||||
"php": ">=5.4.0" | |||||
}, | |||||
"type": "library", | |||||
"autoload": { | |||||
"psr-4": { | |||||
"Picqer\\Barcode\\": "src" | |||||
} | |||||
}, | |||||
"notification-url": "https://packagist.org/downloads/", | |||||
"license": [ | |||||
"MIT" | |||||
], | |||||
"authors": [ | |||||
{ | |||||
"name": "Casper Bakker", | |||||
"email": "info@picqer.com" | |||||
} | |||||
], | |||||
"description": "An easy to use, non-bloated, barcode generator in PHP. Creates SVG, PNG, JPG and HTML images from the most used 1D barcode standards.", | |||||
"homepage": "http://github.com/picqer/exact-php-client", | |||||
"keywords": [ | |||||
"CODABAR", | |||||
"Code11", | |||||
"Code93", | |||||
"EAN13", | |||||
"KIX", | |||||
"KIXCODE", | |||||
"MSI", | |||||
"POSTNET", | |||||
"Pharma", | |||||
"Standard 2 of 5", | |||||
"barcode", | |||||
"barcode generator", | |||||
"code128", | |||||
"code39", | |||||
"ean", | |||||
"html", | |||||
"jpeg", | |||||
"jpg", | |||||
"php", | |||||
"png", | |||||
"svg", | |||||
"upc" | |||||
], | |||||
"time": "2015-08-13 07:59:44" | |||||
}, | |||||
{ | |||||
"name": "ulrichsg/getopt-php", | |||||
"version": "2.3.0", | |||||
"source": { | |||||
"type": "git", | |||||
"url": "https://github.com/ulrichsg/getopt-php.git", | |||||
"reference": "a51554a16e206a6642bf1a0d7d1e4378ec2ba980" | |||||
}, | |||||
"dist": { | |||||
"type": "zip", | |||||
"url": "https://api.github.com/repos/ulrichsg/getopt-php/zipball/a51554a16e206a6642bf1a0d7d1e4378ec2ba980", | |||||
"reference": "a51554a16e206a6642bf1a0d7d1e4378ec2ba980", | |||||
"shasum": "" | |||||
}, | |||||
"require": { | |||||
"php": ">=5.3.0" | |||||
}, | |||||
"require-dev": { | |||||
"phpunit/phpunit": "3.7.*" | |||||
}, | |||||
"type": "library", | |||||
"autoload": { | |||||
"psr-0": { | |||||
"Ulrichsg\\": "src" | |||||
} | |||||
}, | |||||
"notification-url": "https://packagist.org/downloads/", | |||||
"license": [ | |||||
"MIT" | |||||
], | |||||
"authors": [ | |||||
{ | |||||
"name": "Ulrich Schmidt-Goertz", | |||||
"email": "ulrich@schmidt-goertz.de" | |||||
} | |||||
], | |||||
"description": "Command line arguments parser for PHP 5.3", | |||||
"homepage": "http://ulrichsg.github.io/getopt-php", | |||||
"time": "2015-03-28 14:09:20" | |||||
} | |||||
], | |||||
"packages-dev": [], | |||||
"aliases": [], | |||||
"minimum-stability": "stable", | |||||
"stability-flags": [], | |||||
"prefer-stable": false, | |||||
"prefer-lowest": false, | |||||
"platform": [], | |||||
"platform-dev": [] | |||||
} |
@@ -0,0 +1,7 @@ | |||||
<?php | |||||
// autoload.php @generated by Composer | |||||
require_once __DIR__ . '/composer' . '/autoload_real.php'; | |||||
return ComposerAutoloaderInitf17787d2ecff231b84857fe0d96cbca5::getLoader(); |
@@ -0,0 +1,413 @@ | |||||
<?php | |||||
/* | |||||
* This file is part of Composer. | |||||
* | |||||
* (c) Nils Adermann <naderman@naderman.de> | |||||
* Jordi Boggiano <j.boggiano@seld.be> | |||||
* | |||||
* For the full copyright and license information, please view the LICENSE | |||||
* file that was distributed with this source code. | |||||
*/ | |||||
namespace Composer\Autoload; | |||||
/** | |||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader. | |||||
* | |||||
* $loader = new \Composer\Autoload\ClassLoader(); | |||||
* | |||||
* // register classes with namespaces | |||||
* $loader->add('Symfony\Component', __DIR__.'/component'); | |||||
* $loader->add('Symfony', __DIR__.'/framework'); | |||||
* | |||||
* // activate the autoloader | |||||
* $loader->register(); | |||||
* | |||||
* // to enable searching the include path (eg. for PEAR packages) | |||||
* $loader->setUseIncludePath(true); | |||||
* | |||||
* In this example, if you try to use a class in the Symfony\Component | |||||
* namespace or one of its children (Symfony\Component\Console for instance), | |||||
* the autoloader will first look for the class under the component/ | |||||
* directory, and it will then fallback to the framework/ directory if not | |||||
* found before giving up. | |||||
* | |||||
* This class is loosely based on the Symfony UniversalClassLoader. | |||||
* | |||||
* @author Fabien Potencier <fabien@symfony.com> | |||||
* @author Jordi Boggiano <j.boggiano@seld.be> | |||||
* @see http://www.php-fig.org/psr/psr-0/ | |||||
* @see http://www.php-fig.org/psr/psr-4/ | |||||
*/ | |||||
class ClassLoader | |||||
{ | |||||
// PSR-4 | |||||
private $prefixLengthsPsr4 = array(); | |||||
private $prefixDirsPsr4 = array(); | |||||
private $fallbackDirsPsr4 = array(); | |||||
// PSR-0 | |||||
private $prefixesPsr0 = array(); | |||||
private $fallbackDirsPsr0 = array(); | |||||
private $useIncludePath = false; | |||||
private $classMap = array(); | |||||
private $classMapAuthoritative = false; | |||||
public function getPrefixes() | |||||
{ | |||||
if (!empty($this->prefixesPsr0)) { | |||||
return call_user_func_array('array_merge', $this->prefixesPsr0); | |||||
} | |||||
return array(); | |||||
} | |||||
public function getPrefixesPsr4() | |||||
{ | |||||
return $this->prefixDirsPsr4; | |||||
} | |||||
public function getFallbackDirs() | |||||
{ | |||||
return $this->fallbackDirsPsr0; | |||||
} | |||||
public function getFallbackDirsPsr4() | |||||
{ | |||||
return $this->fallbackDirsPsr4; | |||||
} | |||||
public function getClassMap() | |||||
{ | |||||
return $this->classMap; | |||||
} | |||||
/** | |||||
* @param array $classMap Class to filename map | |||||
*/ | |||||
public function addClassMap(array $classMap) | |||||
{ | |||||
if ($this->classMap) { | |||||
$this->classMap = array_merge($this->classMap, $classMap); | |||||
} else { | |||||
$this->classMap = $classMap; | |||||
} | |||||
} | |||||
/** | |||||
* Registers a set of PSR-0 directories for a given prefix, either | |||||
* appending or prepending to the ones previously set for this prefix. | |||||
* | |||||
* @param string $prefix The prefix | |||||
* @param array|string $paths The PSR-0 root directories | |||||
* @param bool $prepend Whether to prepend the directories | |||||
*/ | |||||
public function add($prefix, $paths, $prepend = false) | |||||
{ | |||||
if (!$prefix) { | |||||
if ($prepend) { | |||||
$this->fallbackDirsPsr0 = array_merge( | |||||
(array) $paths, | |||||
$this->fallbackDirsPsr0 | |||||
); | |||||
} else { | |||||
$this->fallbackDirsPsr0 = array_merge( | |||||
$this->fallbackDirsPsr0, | |||||
(array) $paths | |||||
); | |||||
} | |||||
return; | |||||
} | |||||
$first = $prefix[0]; | |||||
if (!isset($this->prefixesPsr0[$first][$prefix])) { | |||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths; | |||||
return; | |||||
} | |||||
if ($prepend) { | |||||
$this->prefixesPsr0[$first][$prefix] = array_merge( | |||||
(array) $paths, | |||||
$this->prefixesPsr0[$first][$prefix] | |||||
); | |||||
} else { | |||||
$this->prefixesPsr0[$first][$prefix] = array_merge( | |||||
$this->prefixesPsr0[$first][$prefix], | |||||
(array) $paths | |||||
); | |||||
} | |||||
} | |||||
/** | |||||
* Registers a set of PSR-4 directories for a given namespace, either | |||||
* appending or prepending to the ones previously set for this namespace. | |||||
* | |||||
* @param string $prefix The prefix/namespace, with trailing '\\' | |||||
* @param array|string $paths The PSR-4 base directories | |||||
* @param bool $prepend Whether to prepend the directories | |||||
* | |||||
* @throws \InvalidArgumentException | |||||
*/ | |||||
public function addPsr4($prefix, $paths, $prepend = false) | |||||
{ | |||||
if (!$prefix) { | |||||
// Register directories for the root namespace. | |||||
if ($prepend) { | |||||
$this->fallbackDirsPsr4 = array_merge( | |||||
(array) $paths, | |||||
$this->fallbackDirsPsr4 | |||||
); | |||||
} else { | |||||
$this->fallbackDirsPsr4 = array_merge( | |||||
$this->fallbackDirsPsr4, | |||||
(array) $paths | |||||
); | |||||
} | |||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) { | |||||
// Register directories for a new namespace. | |||||
$length = strlen($prefix); | |||||
if ('\\' !== $prefix[$length - 1]) { | |||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); | |||||
} | |||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; | |||||
$this->prefixDirsPsr4[$prefix] = (array) $paths; | |||||
} elseif ($prepend) { | |||||
// Prepend directories for an already registered namespace. | |||||
$this->prefixDirsPsr4[$prefix] = array_merge( | |||||
(array) $paths, | |||||
$this->prefixDirsPsr4[$prefix] | |||||
); | |||||
} else { | |||||
// Append directories for an already registered namespace. | |||||
$this->prefixDirsPsr4[$prefix] = array_merge( | |||||
$this->prefixDirsPsr4[$prefix], | |||||
(array) $paths | |||||
); | |||||
} | |||||
} | |||||
/** | |||||
* Registers a set of PSR-0 directories for a given prefix, | |||||
* replacing any others previously set for this prefix. | |||||
* | |||||
* @param string $prefix The prefix | |||||
* @param array|string $paths The PSR-0 base directories | |||||
*/ | |||||
public function set($prefix, $paths) | |||||
{ | |||||
if (!$prefix) { | |||||
$this->fallbackDirsPsr0 = (array) $paths; | |||||
} else { | |||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; | |||||
} | |||||
} | |||||
/** | |||||
* Registers a set of PSR-4 directories for a given namespace, | |||||
* replacing any others previously set for this namespace. | |||||
* | |||||
* @param string $prefix The prefix/namespace, with trailing '\\' | |||||
* @param array|string $paths The PSR-4 base directories | |||||
* | |||||
* @throws \InvalidArgumentException | |||||
*/ | |||||
public function setPsr4($prefix, $paths) | |||||
{ | |||||
if (!$prefix) { | |||||
$this->fallbackDirsPsr4 = (array) $paths; | |||||
} else { | |||||
$length = strlen($prefix); | |||||
if ('\\' !== $prefix[$length - 1]) { | |||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); | |||||
} | |||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; | |||||
$this->prefixDirsPsr4[$prefix] = (array) $paths; | |||||
} | |||||
} | |||||
/** | |||||
* Turns on searching the include path for class files. | |||||
* | |||||
* @param bool $useIncludePath | |||||
*/ | |||||
public function setUseIncludePath($useIncludePath) | |||||
{ | |||||
$this->useIncludePath = $useIncludePath; | |||||
} | |||||
/** | |||||
* Can be used to check if the autoloader uses the include path to check | |||||
* for classes. | |||||
* | |||||
* @return bool | |||||
*/ | |||||
public function getUseIncludePath() | |||||
{ | |||||
return $this->useIncludePath; | |||||
} | |||||
/** | |||||
* Turns off searching the prefix and fallback directories for classes | |||||
* that have not been registered with the class map. | |||||
* | |||||
* @param bool $classMapAuthoritative | |||||
*/ | |||||
public function setClassMapAuthoritative($classMapAuthoritative) | |||||
{ | |||||
$this->classMapAuthoritative = $classMapAuthoritative; | |||||
} | |||||
/** | |||||
* Should class lookup fail if not found in the current class map? | |||||
* | |||||
* @return bool | |||||
*/ | |||||
public function isClassMapAuthoritative() | |||||
{ | |||||
return $this->classMapAuthoritative; | |||||
} | |||||
/** | |||||
* Registers this instance as an autoloader. | |||||
* | |||||
* @param bool $prepend Whether to prepend the autoloader or not | |||||
*/ | |||||
public function register($prepend = false) | |||||
{ | |||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend); | |||||
} | |||||
/** | |||||
* Unregisters this instance as an autoloader. | |||||
*/ | |||||
public function unregister() | |||||
{ | |||||
spl_autoload_unregister(array($this, 'loadClass')); | |||||
} | |||||
/** | |||||
* Loads the given class or interface. | |||||
* | |||||
* @param string $class The name of the class | |||||
* @return bool|null True if loaded, null otherwise | |||||
*/ | |||||
public function loadClass($class) | |||||
{ | |||||
if ($file = $this->findFile($class)) { | |||||
includeFile($file); | |||||
return true; | |||||
} | |||||
} | |||||
/** | |||||
* Finds the path to the file where the class is defined. | |||||
* | |||||
* @param string $class The name of the class | |||||
* | |||||
* @return string|false The path if found, false otherwise | |||||
*/ | |||||
public function findFile($class) | |||||
{ | |||||
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731 | |||||
if ('\\' == $class[0]) { | |||||
$class = substr($class, 1); | |||||
} | |||||
// class map lookup | |||||
if (isset($this->classMap[$class])) { | |||||
return $this->classMap[$class]; | |||||
} | |||||
if ($this->classMapAuthoritative) { | |||||
return false; | |||||
} | |||||
$file = $this->findFileWithExtension($class, '.php'); | |||||
// Search for Hack files if we are running on HHVM | |||||
if ($file === null && defined('HHVM_VERSION')) { | |||||
$file = $this->findFileWithExtension($class, '.hh'); | |||||
} | |||||
if ($file === null) { | |||||
// Remember that this class does not exist. | |||||
return $this->classMap[$class] = false; | |||||
} | |||||
return $file; | |||||
} | |||||
private function findFileWithExtension($class, $ext) | |||||
{ | |||||
// PSR-4 lookup | |||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; | |||||
$first = $class[0]; | |||||
if (isset($this->prefixLengthsPsr4[$first])) { | |||||
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { | |||||
if (0 === strpos($class, $prefix)) { | |||||
foreach ($this->prefixDirsPsr4[$prefix] as $dir) { | |||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { | |||||
return $file; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// PSR-4 fallback dirs | |||||
foreach ($this->fallbackDirsPsr4 as $dir) { | |||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { | |||||
return $file; | |||||
} | |||||
} | |||||
// PSR-0 lookup | |||||
if (false !== $pos = strrpos($class, '\\')) { | |||||
// namespaced class name | |||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) | |||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); | |||||
} else { | |||||
// PEAR-like class name | |||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; | |||||
} | |||||
if (isset($this->prefixesPsr0[$first])) { | |||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { | |||||
if (0 === strpos($class, $prefix)) { | |||||
foreach ($dirs as $dir) { | |||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { | |||||
return $file; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// PSR-0 fallback dirs | |||||
foreach ($this->fallbackDirsPsr0 as $dir) { | |||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { | |||||
return $file; | |||||
} | |||||
} | |||||
// PSR-0 include paths. | |||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { | |||||
return $file; | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Scope isolated include. | |||||
* | |||||
* Prevents access to $this/self from included files. | |||||
*/ | |||||
function includeFile($file) | |||||
{ | |||||
include $file; | |||||
} |
@@ -0,0 +1,21 @@ | |||||
Copyright (c) 2016 Nils Adermann, Jordi Boggiano | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
of this software and associated documentation files (the "Software"), to deal | |||||
in the Software without restriction, including without limitation the rights | |||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
copies of the Software, and to permit persons to whom the Software is furnished | |||||
to do so, subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all | |||||
copies or substantial portions of the Software. | |||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||||
THE SOFTWARE. | |||||
@@ -0,0 +1,9 @@ | |||||
<?php | |||||
// autoload_classmap.php @generated by Composer | |||||
$vendorDir = dirname(dirname(__FILE__)); | |||||
$baseDir = dirname($vendorDir); | |||||
return array( | |||||
); |
@@ -0,0 +1,10 @@ | |||||
<?php | |||||
// autoload_namespaces.php @generated by Composer | |||||
$vendorDir = dirname(dirname(__FILE__)); | |||||
$baseDir = dirname($vendorDir); | |||||
return array( | |||||
'Ulrichsg\\' => array($vendorDir . '/ulrichsg/getopt-php/src'), | |||||
); |
@@ -0,0 +1,10 @@ | |||||
<?php | |||||
// autoload_psr4.php @generated by Composer | |||||
$vendorDir = dirname(dirname(__FILE__)); | |||||
$baseDir = dirname($vendorDir); | |||||
return array( | |||||
'Picqer\\Barcode\\' => array($vendorDir . '/picqer/php-barcode-generator/src'), | |||||
); |
@@ -0,0 +1,45 @@ | |||||
<?php | |||||
// autoload_real.php @generated by Composer | |||||
class ComposerAutoloaderInitf17787d2ecff231b84857fe0d96cbca5 | |||||
{ | |||||
private static $loader; | |||||
public static function loadClassLoader($class) | |||||
{ | |||||
if ('Composer\Autoload\ClassLoader' === $class) { | |||||
require __DIR__ . '/ClassLoader.php'; | |||||
} | |||||
} | |||||
public static function getLoader() | |||||
{ | |||||
if (null !== self::$loader) { | |||||
return self::$loader; | |||||
} | |||||
spl_autoload_register(array('ComposerAutoloaderInitf17787d2ecff231b84857fe0d96cbca5', 'loadClassLoader'), true, true); | |||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(); | |||||
spl_autoload_unregister(array('ComposerAutoloaderInitf17787d2ecff231b84857fe0d96cbca5', 'loadClassLoader')); | |||||
$map = require __DIR__ . '/autoload_namespaces.php'; | |||||
foreach ($map as $namespace => $path) { | |||||
$loader->set($namespace, $path); | |||||
} | |||||
$map = require __DIR__ . '/autoload_psr4.php'; | |||||
foreach ($map as $namespace => $path) { | |||||
$loader->setPsr4($namespace, $path); | |||||
} | |||||
$classMap = require __DIR__ . '/autoload_classmap.php'; | |||||
if ($classMap) { | |||||
$loader->addClassMap($classMap); | |||||
} | |||||
$loader->register(true); | |||||
return $loader; | |||||
} | |||||
} |
@@ -0,0 +1,107 @@ | |||||
[ | |||||
{ | |||||
"name": "picqer/php-barcode-generator", | |||||
"version": "v0.1", | |||||
"version_normalized": "0.1.0.0", | |||||
"source": { | |||||
"type": "git", | |||||
"url": "https://github.com/picqer/php-barcode-generator.git", | |||||
"reference": "bd486cfb311989a506c62827fdee463b8a698002" | |||||
}, | |||||
"dist": { | |||||
"type": "zip", | |||||
"url": "https://api.github.com/repos/picqer/php-barcode-generator/zipball/bd486cfb311989a506c62827fdee463b8a698002", | |||||
"reference": "bd486cfb311989a506c62827fdee463b8a698002", | |||||
"shasum": "" | |||||
}, | |||||
"require": { | |||||
"php": ">=5.4.0" | |||||
}, | |||||
"time": "2015-08-13 07:59:44", | |||||
"type": "library", | |||||
"installation-source": "dist", | |||||
"autoload": { | |||||
"psr-4": { | |||||
"Picqer\\Barcode\\": "src" | |||||
} | |||||
}, | |||||
"notification-url": "https://packagist.org/downloads/", | |||||
"license": [ | |||||
"MIT" | |||||
], | |||||
"authors": [ | |||||
{ | |||||
"name": "Casper Bakker", | |||||
"email": "info@picqer.com" | |||||
} | |||||
], | |||||
"description": "An easy to use, non-bloated, barcode generator in PHP. Creates SVG, PNG, JPG and HTML images from the most used 1D barcode standards.", | |||||
"homepage": "http://github.com/picqer/exact-php-client", | |||||
"keywords": [ | |||||
"CODABAR", | |||||
"Code11", | |||||
"Code93", | |||||
"EAN13", | |||||
"KIX", | |||||
"KIXCODE", | |||||
"MSI", | |||||
"POSTNET", | |||||
"Pharma", | |||||
"Standard 2 of 5", | |||||
"barcode", | |||||
"barcode generator", | |||||
"code128", | |||||
"code39", | |||||
"ean", | |||||
"html", | |||||
"jpeg", | |||||
"jpg", | |||||
"php", | |||||
"png", | |||||
"svg", | |||||
"upc" | |||||
] | |||||
}, | |||||
{ | |||||
"name": "ulrichsg/getopt-php", | |||||
"version": "2.3.0", | |||||
"version_normalized": "2.3.0.0", | |||||
"source": { | |||||
"type": "git", | |||||
"url": "https://github.com/ulrichsg/getopt-php.git", | |||||
"reference": "a51554a16e206a6642bf1a0d7d1e4378ec2ba980" | |||||
}, | |||||
"dist": { | |||||
"type": "zip", | |||||
"url": "https://api.github.com/repos/ulrichsg/getopt-php/zipball/a51554a16e206a6642bf1a0d7d1e4378ec2ba980", | |||||
"reference": "a51554a16e206a6642bf1a0d7d1e4378ec2ba980", | |||||
"shasum": "" | |||||
}, | |||||
"require": { | |||||
"php": ">=5.3.0" | |||||
}, | |||||
"require-dev": { | |||||
"phpunit/phpunit": "3.7.*" | |||||
}, | |||||
"time": "2015-03-28 14:09:20", | |||||
"type": "library", | |||||
"installation-source": "dist", | |||||
"autoload": { | |||||
"psr-0": { | |||||
"Ulrichsg\\": "src" | |||||
} | |||||
}, | |||||
"notification-url": "https://packagist.org/downloads/", | |||||
"license": [ | |||||
"MIT" | |||||
], | |||||
"authors": [ | |||||
{ | |||||
"name": "Ulrich Schmidt-Goertz", | |||||
"email": "ulrich@schmidt-goertz.de" | |||||
} | |||||
], | |||||
"description": "Command line arguments parser for PHP 5.3", | |||||
"homepage": "http://ulrichsg.github.io/getopt-php" | |||||
} | |||||
] |
@@ -0,0 +1,2 @@ | |||||
.idea | |||||
.DS_Store |
@@ -0,0 +1,76 @@ | |||||
# PHP Barcode Generator | |||||
This is an easy to use, non-bloated, framework independent, barcode generator in PHP. | |||||
It creates SVG, PNG, JPG and HTML images, from the most used 1D barcode standards. | |||||
*The codebase is largely from the TCPDF barcode generator. It is still a bit of a mess, bit I will clean it in the future. I do not expect the interface of this class will change during the clean ups.* | |||||
## Installation | |||||
Install through [composer](https://getcomposer.org/doc/00-intro.md): | |||||
``` | |||||
composer require picqer/php-barcode-generator | |||||
``` | |||||
## Usage | |||||
Initiate the barcode generator for the output you want, then call the ->getBarcode() routine as many times as you want. | |||||
```php | |||||
$generator = new Picqer\Barcode\BarcodeGeneratorHTML(); | |||||
echo $generator->getBarcode('081231723897', $generator::TYPE_CODE_128); | |||||
``` | |||||
The ->getBarcode() routine accepts the following: | |||||
- $code Data for the barcode | |||||
- $type Type of barcode, use the constants defined in the class | |||||
- $widthFactor Width is based on the length of the data, with this factor you can make the barcode bars wider then default | |||||
- $totalHeight The total height of the barcode | |||||
- $color Hex code of the foreground color | |||||
## Image types | |||||
```php | |||||
$generatorSVG = new Picqer\Barcode\BarcodeGeneratorSVG(); | |||||
$generatorPNG = new Picqer\Barcode\BarcodeGeneratorPNG(); | |||||
$generatorJPG = new Picqer\Barcode\BarcodeGeneratorJPG(); | |||||
$generatorHTML = new Picqer\Barcode\BarcodeGeneratorHTML(); | |||||
``` | |||||
## Accepted types | |||||
- TYPE_CODE_39 | |||||
- TYPE_CODE_39_CHECKSUM | |||||
- TYPE_CODE_39E | |||||
- TYPE_CODE_39E_CHECKSUM | |||||
- TYPE_CODE_93 | |||||
- TYPE_STANDARD_2_5 | |||||
- TYPE_STANDARD_2_5_CHECKSUM | |||||
- TYPE_INTERLEAVED_2_5 | |||||
- TYPE_INTERLEAVED_2_5_CHECKSUM | |||||
- TYPE_CODE_128 | |||||
- TYPE_CODE_128_A | |||||
- TYPE_CODE_128_B | |||||
- TYPE_CODE_128_C | |||||
- TYPE_EAN_2 | |||||
- TYPE_EAN_5 | |||||
- TYPE_EAN_8 | |||||
- TYPE_EAN_13 | |||||
- TYPE_UPC_A | |||||
- TYPE_UPC_E | |||||
- TYPE_MSI | |||||
- TYPE_MSI_CHECKSUM | |||||
- TYPE_POSTNET | |||||
- TYPE_PLANET | |||||
- TYPE_RMS4CC | |||||
- TYPE_KIX | |||||
- TYPE_IMB | |||||
- TYPE_CODABAR | |||||
- TYPE_CODE_11 | |||||
- TYPE_PHARMA_CODE | |||||
- TYPE_PHARMA_CODE_TWO_TRACKS | |||||
## Examples | |||||
Embedded PNG image in HTML: | |||||
```php | |||||
$generator = new Picqer\Barcode\BarcodeGeneratorPNG(); | |||||
echo '<img src="data:image/png;base64,' . base64_encode($generator->getBarcode('081231723897', $generator::TYPE_CODE_128)) . '">'; | |||||
``` |
@@ -0,0 +1,22 @@ | |||||
{ | |||||
"name": "picqer/php-barcode-generator", | |||||
"type": "library", | |||||
"description": "An easy to use, non-bloated, barcode generator in PHP. Creates SVG, PNG, JPG and HTML images from the most used 1D barcode standards.", | |||||
"keywords": [ "php", "barcode", "barcode generator", "EAN", "EAN13", "UPC", "Code39", "Code128", "Code93", "Standard 2 of 5", "MSI", "POSTNET", "KIX", "KIXCODE", "CODABAR", "PHARMA", "Code11", "SVG", "PNG", "HTML", "JPG", "JPEG" ], | |||||
"homepage": "http://github.com/picqer/exact-php-client", | |||||
"license": "MIT", | |||||
"authors": [ | |||||
{ | |||||
"name": "Casper Bakker", | |||||
"email": "info@picqer.com" | |||||
} | |||||
], | |||||
"require": { | |||||
"php": ">=5.4.0" | |||||
}, | |||||
"autoload": { | |||||
"psr-4": { | |||||
"Picqer\\Barcode\\": "src" | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,14 @@ | |||||
<?php | |||||
include('src/BarcodeGenerator.php'); | |||||
include('src/BarcodeGeneratorPNG.php'); | |||||
include('src/BarcodeGeneratorSVG.php'); | |||||
include('src/BarcodeGeneratorHTML.php'); | |||||
$generatorPNG = new Picqer\Barcode\BarcodeGeneratorPNG(); | |||||
$generatorSVG = new Picqer\Barcode\BarcodeGeneratorSVG(); | |||||
$generatorHTML = new Picqer\Barcode\BarcodeGeneratorHTML(); | |||||
echo $generatorHTML->getBarcode('081231723897', $generatorPNG::TYPE_CODE_128); | |||||
echo $generatorSVG->getBarcode('081231723897', $generatorPNG::TYPE_EAN_13); | |||||
echo '<img src="data:image/png;base64,' . base64_encode($generatorPNG->getBarcode('081231723897', $generatorPNG::TYPE_CODE_128)) . '">'; |
@@ -0,0 +1,44 @@ | |||||
<?php | |||||
namespace Picqer\Barcode; | |||||
class BarcodeGeneratorHTML extends BarcodeGenerator | |||||
{ | |||||
/** | |||||
* Return an HTML representation of barcode. | |||||
* | |||||
* @param string $code code to print | |||||
* @param string $type type of barcode | |||||
* @param int $widthFactor Width of a single bar element in pixels. | |||||
* @param int $totalHeight Height of a single bar element in pixels. | |||||
* @param int $color Foreground color for bar elements (background is transparent). | |||||
* @return string HTML code. | |||||
* @public | |||||
*/ | |||||
public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = 'black') | |||||
{ | |||||
$barcodeData = $this->getBarcodeData($code, $type); | |||||
$html = '<div style="font-size:0;position:relative;width:' . ($barcodeData['maxWidth'] * $widthFactor) . 'px;height:' . ($totalHeight) . 'px;">' . "\n"; | |||||
$positionHorizontal = 0; | |||||
foreach ($barcodeData['bars'] as $bar) { | |||||
$barWidth = round(($bar['width'] * $widthFactor), 3); | |||||
$barHeight = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3); | |||||
if ($bar['drawBar']) { | |||||
$positionVertical = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3); | |||||
// draw a vertical bar | |||||
$html .= '<div style="background-color:' . $color . ';width:' . $barWidth . 'px;height:' . $barHeight . 'px;position:absolute;left:' . $positionHorizontal . 'px;top:' . $positionVertical . 'px;"> </div>' . "\n"; | |||||
} | |||||
$positionHorizontal += $barWidth; | |||||
} | |||||
$html .= '</div>' . "\n"; | |||||
return $html; | |||||
} | |||||
} |
@@ -0,0 +1,74 @@ | |||||
<?php | |||||
namespace Picqer\Barcode; | |||||
class BarcodeGeneratorJPG extends BarcodeGenerator | |||||
{ | |||||
/** | |||||
* Return a JPG image representation of barcode (requires GD or Imagick library). | |||||
* | |||||
* @param string $code code to print | |||||
* @param string $type type of barcode: | |||||
* @param int $widthFactor Width of a single bar element in pixels. | |||||
* @param int $totalHeight Height of a single bar element in pixels. | |||||
* @param array $color RGB (0-255) foreground color for bar elements (background is transparent). | |||||
* @return string image data or false in case of error. | |||||
* @public | |||||
*/ | |||||
public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = array(0, 0, 0)) | |||||
{ | |||||
$barcodeData = $this->getBarcodeData($code, $type); | |||||
// calculate image size | |||||
$width = ($barcodeData['maxWidth'] * $widthFactor); | |||||
$height = $totalHeight; | |||||
if (function_exists('imagecreate')) { | |||||
// GD library | |||||
$imagick = false; | |||||
$jpg = imagecreate($width, $height); | |||||
$colorBackground = imagecolorallocate($jpg, 255, 255, 255); | |||||
imagecolortransparent($jpg, $colorBackground); | |||||
$colorForeground = imagecolorallocate($jpg, $color[0], $color[1], $color[2]); | |||||
} elseif (extension_loaded('imagick')) { | |||||
$imagick = true; | |||||
$colorForeground = new \imagickpixel('rgb(' . $color[0] . ',' . $color[1] . ',' . $color[2] . ')'); | |||||
$jpg = new \Imagick(); | |||||
$jpg->newImage($width, $height, 'none', 'jpg'); | |||||
$imageMagickObject = new \imagickdraw(); | |||||
$imageMagickObject->setfillcolor($colorForeground); | |||||
} else { | |||||
return false; | |||||
} | |||||
// print bars | |||||
$positionHorizontal = 0; | |||||
foreach ($barcodeData['bars'] as $bar) { | |||||
$bw = round(($bar['width'] * $widthFactor), 3); | |||||
$bh = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3); | |||||
if ($bar['drawBar']) { | |||||
$y = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3); | |||||
// draw a vertical bar | |||||
if ($imagick) { | |||||
$imageMagickObject->rectangle($positionHorizontal, $y, ($positionHorizontal + $bw), ($y + $bh)); | |||||
} else { | |||||
imagefilledrectangle($jpg, $positionHorizontal, $y, ($positionHorizontal + $bw) - 1, ($y + $bh), | |||||
$colorForeground); | |||||
} | |||||
} | |||||
$positionHorizontal += $bw; | |||||
} | |||||
ob_start(); | |||||
if ($imagick) { | |||||
$jpg->drawimage($imageMagickObject); | |||||
echo $jpg; | |||||
} else { | |||||
imagejpeg($jpg); | |||||
imagedestroy($jpg); | |||||
} | |||||
$image = ob_get_clean(); | |||||
return $image; | |||||
} | |||||
} |
@@ -0,0 +1,74 @@ | |||||
<?php | |||||
namespace Picqer\Barcode; | |||||
class BarcodeGeneratorPNG extends BarcodeGenerator | |||||
{ | |||||
/** | |||||
* Return a PNG image representation of barcode (requires GD or Imagick library). | |||||
* | |||||
* @param string $code code to print | |||||
* @param string $type type of barcode: | |||||
* @param int $widthFactor Width of a single bar element in pixels. | |||||
* @param int $totalHeight Height of a single bar element in pixels. | |||||
* @param array $color RGB (0-255) foreground color for bar elements (background is transparent). | |||||
* @return string image data or false in case of error. | |||||
* @public | |||||
*/ | |||||
public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = array(0, 0, 0)) | |||||
{ | |||||
$barcodeData = $this->getBarcodeData($code, $type); | |||||
// calculate image size | |||||
$width = ($barcodeData['maxWidth'] * $widthFactor); | |||||
$height = $totalHeight; | |||||
if (function_exists('imagecreate')) { | |||||
// GD library | |||||
$imagick = false; | |||||
$png = imagecreate($width, $height); | |||||
$colorBackground = imagecolorallocate($png, 255, 255, 255); | |||||
imagecolortransparent($png, $colorBackground); | |||||
$colorForeground = imagecolorallocate($png, $color[0], $color[1], $color[2]); | |||||
} elseif (extension_loaded('imagick')) { | |||||
$imagick = true; | |||||
$colorForeground = new \imagickpixel('rgb(' . $color[0] . ',' . $color[1] . ',' . $color[2] . ')'); | |||||
$png = new \Imagick(); | |||||
$png->newImage($width, $height, 'none', 'png'); | |||||
$imageMagickObject = new \imagickdraw(); | |||||
$imageMagickObject->setfillcolor($colorForeground); | |||||
} else { | |||||
return false; | |||||
} | |||||
// print bars | |||||
$positionHorizontal = 0; | |||||
foreach ($barcodeData['bars'] as $bar) { | |||||
$bw = round(($bar['width'] * $widthFactor), 3); | |||||
$bh = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3); | |||||
if ($bar['drawBar']) { | |||||
$y = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3); | |||||
// draw a vertical bar | |||||
if ($imagick) { | |||||
$imageMagickObject->rectangle($positionHorizontal, $y, ($positionHorizontal + $bw), ($y + $bh)); | |||||
} else { | |||||
imagefilledrectangle($png, $positionHorizontal, $y, ($positionHorizontal + $bw) - 1, ($y + $bh), | |||||
$colorForeground); | |||||
} | |||||
} | |||||
$positionHorizontal += $bw; | |||||
} | |||||
ob_start(); | |||||
if ($imagick) { | |||||
$png->drawimage($imageMagickObject); | |||||
echo $png; | |||||
} else { | |||||
imagepng($png); | |||||
imagedestroy($png); | |||||
} | |||||
$image = ob_get_clean(); | |||||
return $image; | |||||
} | |||||
} |
@@ -0,0 +1,49 @@ | |||||
<?php | |||||
namespace Picqer\Barcode; | |||||
class BarcodeGeneratorSVG extends BarcodeGenerator | |||||
{ | |||||
/** | |||||
* Return a SVG string representation of barcode. | |||||
* | |||||
* @param $code (string) code to print | |||||
* @param $type (const) type of barcode | |||||
* @param $widthFactor (int) Minimum width of a single bar in user units. | |||||
* @param $totalHeight (int) Height of barcode in user units. | |||||
* @param $color (string) Foreground color (in SVG format) for bar elements (background is transparent). | |||||
* @return string SVG code. | |||||
* @public | |||||
*/ | |||||
public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = 'black') | |||||
{ | |||||
$barcodeData = $this->getBarcodeData($code, $type); | |||||
// replace table for special characters | |||||
$repstr = array("\0" => '', '&' => '&', '<' => '<', '>' => '>'); | |||||
$svg = '<?xml version="1.0" standalone="no" ?>' . "\n"; | |||||
$svg .= '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' . "\n"; | |||||
$svg .= '<svg width="' . round(($barcodeData['maxWidth'] * $widthFactor), | |||||
3) . '" height="' . $totalHeight . '" version="1.1" xmlns="http://www.w3.org/2000/svg">' . "\n"; | |||||
$svg .= "\t" . '<desc>' . strtr($barcodeData['code'], $repstr) . '</desc>' . "\n"; | |||||
$svg .= "\t" . '<g id="bars" fill="' . $color . '" stroke="none">' . "\n"; | |||||
// print bars | |||||
$positionHorizontal = 0; | |||||
foreach ($barcodeData['bars'] as $bar) { | |||||
$barWidth = round(($bar['width'] * $widthFactor), 3); | |||||
$barHeight = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3); | |||||
if ($bar['drawBar']) { | |||||
$positionVertical = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3); | |||||
// draw a vertical bar | |||||
$svg .= "\t\t" . '<rect x="' . $positionHorizontal . '" y="' . $positionVertical . '" width="' . $barWidth . '" height="' . $barHeight . '" />' . "\n"; | |||||
} | |||||
$positionHorizontal += $barWidth; | |||||
} | |||||
$svg .= "\t" . '</g>' . "\n"; | |||||
$svg .= '</svg>' . "\n"; | |||||
return $svg; | |||||
} | |||||
} |
@@ -0,0 +1,6 @@ | |||||
bin | |||||
build | |||||
composer.lock | |||||
vendor | |||||
nbproject | |||||
_site |
@@ -0,0 +1,10 @@ | |||||
language: php | |||||
php: | |||||
- 5.6 | |||||
- 5.5 | |||||
- 5.4 | |||||
- 5.3 | |||||
- hhvm | |||||
before_script: | |||||
- composer install |
@@ -0,0 +1,77 @@ | |||||
## 2.3.0 (2015-03-28) | |||||
Features: | |||||
* Optional argument descriptions (courtesy of @sabl0r) | |||||
Bugfixes: | |||||
* Passing a single hyphen as an option value works now (courtesy of @tistre) | |||||
## 2.2.0 (2014-09-13) | |||||
Features: | |||||
* Added method to customize the help message (courtesy of @mfn) | |||||
* Option now has a static create method for call chaining in PHP 5.3 (courtesy of @kamermans) | |||||
## 2.1.0 (2014-02-28) | |||||
Features: | |||||
* Added setters for default values and validation to Option | |||||
## 2.0.0 (2014-01-30) | |||||
Features: | |||||
* Argument validation (courtesy of @jochenvdv) | |||||
## 2.0.0-RC.1 (2014-01-17) | |||||
Changes: | |||||
* Namespace is now Ulrichsg\Getopt | |||||
* Public API has been cleaned up, please refer to the documentation | |||||
## 1.4.1 (2013-12-13) | |||||
Bugfixes: | |||||
* Long options are required to be longer than 1 character | |||||
* Passing duplicate option names to the constructor is forbidden by default | |||||
## 1.4.0 (2013-12-13) | |||||
Features: | |||||
* Options can be numeric (courtesy of @patinthehat) | |||||
* Additional convenience methods for working with operands (ditto) | |||||
## 1.3.0 (2013-12-07) | |||||
Features: | |||||
* Default values for options | |||||
* ArrayAccess, Countable and Traversable support | |||||
* Can set program name to enhance help message (courtesy of @misterion) | |||||
## 1.2.0 (2013-11-14) | |||||
Features: | |||||
* Allow passing incomplete option arrays | |||||
## 1.1.0 (2013-06-19) | |||||
Features: | |||||
* Added help text printing functionality | |||||
Bugfixes: | |||||
* Fixed passing a mandatory argument to the last in a sequence of collapsed short options | |||||
## 1.0.1 (2012-05-20) | |||||
Bugfixes: | |||||
* Fixed bug where '0' could not be passed as an option value | |||||
@@ -0,0 +1,17 @@ | |||||
Copyright (c) 2011-2014 Ulrich Schmidt-Goertz <ulrich at schmidt-goertz.de> | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software | |||||
and associated documentation files (the "Software"), to deal in the Software without restriction, | |||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, | |||||
subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all copies or substantial | |||||
portions of the Software. | |||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
DEALINGS IN THE SOFTWARE. |
@@ -0,0 +1,35 @@ | |||||
# vim: tabstop=4:softtabstop=4:shiftwidth=4:noexpandtab | |||||
help: | |||||
@echo "Usual targets:" | |||||
@echo " test - run test suites" | |||||
@echo "" | |||||
@echo "Other targets:" | |||||
@echo " install-composer - install composer" | |||||
@echo " install-dependencies - install/update all vendor libraries using composer" | |||||
@echo " install-dev-dependencies - install/update all vendor libraries necessary for development" | |||||
@echo "" | |||||
@exit 0 | |||||
test: | |||||
@vendor/bin/phpunit | |||||
install-composer: | |||||
@if [ ! -d ./bin ]; then mkdir bin; fi | |||||
@if [ ! -f ./bin/composer.phar ]; then curl -s http://getcomposer.org/installer | php -n -d allow_url_fopen=1 -d date.timezone="Europe/Berlin" -- --install-dir=./bin/; fi | |||||
install-dependencies: | |||||
@make install-composer | |||||
@php -n -d allow_url_fopen=1 -d date.timezone="Europe/Berlin" ./bin/composer.phar -- update | |||||
install-dev-dependencies: | |||||
@make install-composer | |||||
@php -n -d allow_url_fopen=1 -d date.timezone="Europe/Berlin" ./bin/composer.phar update --dev | |||||
.PHONY: test help | |||||
@@ -0,0 +1,28 @@ | |||||
Getopt.PHP | |||||
========== | |||||
Getopt.PHP is a library for command-line argument processing. It supports PHP version 5.3 and above. | |||||
Features | |||||
-------- | |||||
* Supports both short (eg. `-v`) and long (eg. `--version`) options | |||||
* Option aliasing, ie. an option can have both a long and a short version | |||||
* Collapsed short options (eg. `-abc` instead of `-a -b -c`) | |||||
* Cumulative options (eg. `-vvv`) | |||||
* Options may take optional or mandatory arguments | |||||
* Two alternative notations for long options with arguments: `--option value` and `--option=value` | |||||
* Collapsed short options with mandatory argument at the end (eg. `-ab 1` instead of `-a -b 1`) | |||||
Documentation | |||||
------------- | |||||
* [Documentation for the current version (2.0+)](http://ulrichsg.github.io/getopt-php/) | |||||
* [Legacy documentation (1.4)](https://github.com/ulrichsg/getopt-php/blob/2aa8ab1be57200af4cc51447d2a6c244b75ca70b/README.markdown) | |||||
License | |||||
------- | |||||
Getopt.PHP is published under the [MIT License](http://www.opensource.org/licenses/mit-license.php). | |||||
[](https://travis-ci.org/ulrichsg/getopt-php) |
@@ -0,0 +1,24 @@ | |||||
{ | |||||
"name": "ulrichsg/getopt-php", | |||||
"type": "library", | |||||
"description": "Command line arguments parser for PHP 5.3", | |||||
"homepage": "http://ulrichsg.github.io/getopt-php", | |||||
"license": "MIT", | |||||
"authors": [ | |||||
{ | |||||
"name": "Ulrich Schmidt-Goertz", | |||||
"email": "ulrich@schmidt-goertz.de" | |||||
} | |||||
], | |||||
"require": { | |||||
"php": ">=5.3.0" | |||||
}, | |||||
"require-dev": { | |||||
"phpunit/phpunit": "3.7.*" | |||||
}, | |||||
"autoload": { | |||||
"psr-0": { | |||||
"Ulrichsg\\": "src" | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,35 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<phpunit | |||||
bootstrap="vendor/autoload.php" | |||||
colors="true" | |||||
convertErrorsToExceptions="true" | |||||
convertNoticesToExceptions="true" | |||||
convertWarningsToExceptions="true" | |||||
stopOnFailure="true" | |||||
syntaxCheck="true" | |||||
> | |||||
<testsuites> | |||||
<testsuite name="basic"> | |||||
<directory>test</directory> | |||||
</testsuite> | |||||
</testsuites> | |||||
<filter> | |||||
<whitelist> | |||||
<directory suffix=".php">src</directory> | |||||
</whitelist> | |||||
</filter> | |||||
<logging> | |||||
<log type="coverage-html" | |||||
target="build/coverage" | |||||
charset="UTF-8" | |||||
yui="true" | |||||
highlight="true" | |||||
lowUpperBound="40" | |||||
highLowerBound="70" | |||||
/> | |||||
</logging> | |||||
</phpunit> |
@@ -0,0 +1,115 @@ | |||||
<?php | |||||
namespace Ulrichsg\Getopt; | |||||
class Argument | |||||
{ | |||||
/** @var string */ | |||||
private $default; | |||||
/** @var callable */ | |||||
private $validation; | |||||
/** @var string */ | |||||
private $name; | |||||
/** | |||||
* Creates a new argument. | |||||
* | |||||
* @param scalar|null $default Default value or NULL | |||||
* @param callable|null $validation a validation function (optional) | |||||
* @throws \InvalidArgumentException | |||||
*/ | |||||
public function __construct($default = null, $validation = null, $name = "arg") | |||||
{ | |||||
if (!is_null($default)) { | |||||
$this->setDefaultValue($default); | |||||
} | |||||
if (!is_null($validation)) { | |||||
$this->setValidation($validation); | |||||
} | |||||
$this->name = $name; | |||||
} | |||||
/** | |||||
* Set the default value | |||||
* | |||||
* @param scalar $value | |||||
* @return Argument this object (for chaining calls) | |||||
* @throws \InvalidArgumentException | |||||
*/ | |||||
public function setDefaultValue($value) | |||||
{ | |||||
if (!is_scalar($value)) { | |||||
throw new \InvalidArgumentException("Default value must be scalar"); | |||||
} | |||||
$this->default = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set a validation function. | |||||
* The function must take a string and return true if it is valid, false otherwise. | |||||
* | |||||
* @param callable $callable | |||||
* @return Argument this object (for chaining calls) | |||||
* @throws \InvalidArgumentException | |||||
*/ | |||||
public function setValidation($callable) | |||||
{ | |||||
if (!is_callable($callable)) { | |||||
throw new \InvalidArgumentException("Validation must be a callable"); | |||||
} | |||||
$this->validation = $callable; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Check if an argument validates according to the specification. | |||||
* | |||||
* @param string $arg | |||||
* @return bool | |||||
*/ | |||||
public function validates($arg) | |||||
{ | |||||
return (bool)call_user_func($this->validation, $arg); | |||||
} | |||||
/** | |||||
* Check if the argument has a validation function | |||||
* | |||||
* @return bool | |||||
*/ | |||||
public function hasValidation() | |||||
{ | |||||
return isset($this->validation); | |||||
} | |||||
/** | |||||
* Check whether the argument has a default value | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function hasDefaultValue() | |||||
{ | |||||
return !empty($this->default); | |||||
} | |||||
/** | |||||
* Retrieve the default value | |||||
* | |||||
* @return scalar|null | |||||
*/ | |||||
public function getDefaultValue() | |||||
{ | |||||
return $this->default; | |||||
} | |||||
/** | |||||
* Retrieve the argument name | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getName() | |||||
{ | |||||
return $this->name; | |||||
} | |||||
} |
@@ -0,0 +1,233 @@ | |||||
<?php | |||||
namespace Ulrichsg\Getopt; | |||||
/** | |||||
* Parses command line arguments according to a list of allowed options. | |||||
*/ | |||||
class CommandLineParser | |||||
{ | |||||
/** @var Option[] */ | |||||
private $optionList; | |||||
private $options = array(); | |||||
private $operands = array(); | |||||
/** | |||||
* Creates a new instance. | |||||
* | |||||
* @param Option[] $optionList the list of allowed options | |||||
*/ | |||||
public function __construct(array $optionList) | |||||
{ | |||||
$this->optionList = $optionList; | |||||
} | |||||
/** | |||||
* Parses the given arguments and converts them into options and operands. | |||||
* | |||||
* @param mixed $arguments a string or an array with one argument per element | |||||
*/ | |||||
public function parse($arguments) | |||||
{ | |||||
if (!is_array($arguments)) { | |||||
$arguments = explode(' ', $arguments); | |||||
} | |||||
$operands = array(); | |||||
$numArgs = count($arguments); | |||||
for ($i = 0; $i < $numArgs; ++$i) { | |||||
$arg = trim($arguments[$i]); | |||||
if (empty($arg)) { | |||||
continue; | |||||
} | |||||
if (($arg === '--') || ($arg === '-') || (mb_substr($arg, 0, 1) !== '-')){ | |||||
// no more options, treat the remaining arguments as operands | |||||
$firstOperandIndex = ($arg == '--') ? $i + 1 : $i; | |||||
$operands = array_slice($arguments, $firstOperandIndex); | |||||
break; | |||||
} | |||||
if (mb_substr($arg, 0, 2) == '--') { | |||||
$this->addLongOption($arguments, $i); | |||||
} else { | |||||
$this->addShortOption($arguments, $i); | |||||
} | |||||
} // endfor | |||||
$this->addDefaultValues(); | |||||
// remove '--' from operands array | |||||
foreach ($operands as $operand) { | |||||
if ($operand !== '--') { | |||||
$this->operands[] = $operand; | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Returns the options created by a previous invocation of parse(). | |||||
* | |||||
* @return array | |||||
*/ | |||||
public function getOptions() | |||||
{ | |||||
return $this->options; | |||||
} | |||||
/** | |||||
* Returns the operands created by a previous invocation of parse(), | |||||
* | |||||
* @return array | |||||
*/ | |||||
public function getOperands() | |||||
{ | |||||
return $this->operands; | |||||
} | |||||
private function addShortOption($arguments, &$i) | |||||
{ | |||||
$numArgs = count($arguments); | |||||
$option = mb_substr($arguments[$i], 1); | |||||
if (mb_strlen($option) > 1) { | |||||
// multiple options strung together | |||||
$options = $this->splitString($option, 1); | |||||
foreach ($options as $j => $ch) { | |||||
if ($j < count($options) - 1 | |||||
|| !( | |||||
$i < $numArgs - 1 | |||||
&& ((mb_substr($arguments[$i + 1], 0, 1) !== '-') || ($arguments[$i + 1] === '-')) | |||||
&& $this->optionHasArgument($ch) | |||||
) | |||||
) { | |||||
$this->addOption($ch, null); | |||||
} else { // e.g. `ls -sw 100` | |||||
$value = $arguments[$i + 1]; | |||||
++$i; | |||||
$this->addOption($ch, $value); | |||||
} | |||||
} | |||||
} else { | |||||
if ($i < $numArgs - 1 | |||||
&& ((mb_substr($arguments[$i + 1], 0, 1) !== '-') || ($arguments[$i + 1] === '-')) | |||||
&& $this->optionHasArgument($option) | |||||
) { | |||||
$value = $arguments[$i + 1]; | |||||
++$i; | |||||
} else { | |||||
$value = null; | |||||
} | |||||
$this->addOption($option, $value); | |||||
} | |||||
} | |||||
private function addLongOption($arguments, &$i) | |||||
{ | |||||
$option = mb_substr($arguments[$i], 2); | |||||
if (strpos($option, '=') === false) { | |||||
if ($i < count($arguments) - 1 | |||||
&& ((mb_substr($arguments[$i + 1], 0, 1) !== '-') || ($arguments[$i + 1] === '-')) | |||||
&& $this->optionHasArgument($option) | |||||
) { | |||||
$value = $arguments[$i + 1]; | |||||
++$i; | |||||
} else { | |||||
$value = null; | |||||
} | |||||
} else { | |||||
list($option, $value) = explode('=', $option, 2); | |||||
} | |||||
$this->addOption($option, $value); | |||||
} | |||||
/** | |||||
* Add an option to the list of known options. | |||||
* | |||||
* @param string $string the option's name | |||||
* @param string $value the option's value (or null) | |||||
* @throws \UnexpectedValueException | |||||
* @return void | |||||
*/ | |||||
private function addOption($string, $value) | |||||
{ | |||||
foreach ($this->optionList as $option) { | |||||
if ($option->matches($string)) { | |||||
if ($option->mode() == Getopt::REQUIRED_ARGUMENT && !mb_strlen($value)) { | |||||
throw new \UnexpectedValueException("Option '$string' must have a value"); | |||||
} | |||||
if ($option->getArgument()->hasValidation()) { | |||||
if ((mb_strlen($value) > 0) && !$option->getArgument()->validates($value)) { | |||||
throw new \UnexpectedValueException("Option '$string' has an invalid value"); | |||||
} | |||||
} | |||||
// for no-argument options, check if they are duplicate | |||||
if ($option->mode() == Getopt::NO_ARGUMENT) { | |||||
$oldValue = isset($this->options[$string]) ? $this->options[$string] : null; | |||||
$value = is_null($oldValue) ? 1 : $oldValue + 1; | |||||
} | |||||
// for optional-argument options, set value to 1 if none was given | |||||
$value = (mb_strlen($value) > 0) ? $value : 1; | |||||
// add both long and short names (if they exist) to the option array to facilitate lookup | |||||
if ($option->short()) { | |||||
$this->options[$option->short()] = $value; | |||||
} | |||||
if ($option->long()) { | |||||
$this->options[$option->long()] = $value; | |||||
} | |||||
return; | |||||
} | |||||
} | |||||
throw new \UnexpectedValueException("Option '$string' is unknown"); | |||||
} | |||||
/** | |||||
* If there are options with default values that were not overridden by the parsed option string, | |||||
* add them to the list of known options. | |||||
*/ | |||||
private function addDefaultValues() | |||||
{ | |||||
foreach ($this->optionList as $option) { | |||||
if ($option->getArgument()->hasDefaultValue() | |||||
&& !isset($this->options[$option->short()]) | |||||
&& !isset($this->options[$option->long()]) | |||||
) { | |||||
if ($option->short()) { | |||||
$this->addOption($option->short(), $option->getArgument()->getDefaultValue()); | |||||
} | |||||
if ($option->long()) { | |||||
$this->addOption($option->long(), $option->getArgument()->getDefaultValue()); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Return true if the given option can take an argument, false if it can't or is unknown. | |||||
* | |||||
* @param string $name the option's name | |||||
* @return boolean | |||||
*/ | |||||
private function optionHasArgument($name) | |||||
{ | |||||
foreach ($this->optionList as $option) { | |||||
if ($option->matches($name)) { | |||||
return $option->mode() != Getopt::NO_ARGUMENT; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Split the string into individual characters, | |||||
* | |||||
* @param string $string string to split | |||||
* @return array | |||||
*/ | |||||
private function splitString($string) | |||||
{ | |||||
$result = array(); | |||||
for ($i = 0; $i < mb_strlen($string, "UTF-8"); ++$i) { | |||||
$result[] = mb_substr($string, $i, 1, "UTF-8"); | |||||
} | |||||
return $result; | |||||
} | |||||
} |
@@ -0,0 +1,295 @@ | |||||
<?php | |||||
namespace Ulrichsg\Getopt; | |||||
/** | |||||
* Getopt.PHP allows for easy processing of command-line arguments. | |||||
* It is a more powerful, object-oriented alternative to PHP's built-in getopt() function. | |||||
* | |||||
* @version 2.1.0 | |||||
* @license MIT | |||||
* @link http://ulrichsg.github.io/getopt-php | |||||
*/ | |||||
class Getopt implements \Countable, \ArrayAccess, \IteratorAggregate | |||||
{ | |||||
const NO_ARGUMENT = 0; | |||||
const REQUIRED_ARGUMENT = 1; | |||||
const OPTIONAL_ARGUMENT = 2; | |||||
/** @var OptionParser */ | |||||
private $optionParser; | |||||
/** @var string */ | |||||
private $scriptName; | |||||
/** @var Option[] */ | |||||
private $optionList = array(); | |||||
/** @var array */ | |||||
private $options = array(); | |||||
/** @var array */ | |||||
private $operands = array(); | |||||
/** @var string */ | |||||
private $banner = "Usage: %s [options] [operands]\n"; | |||||
/** | |||||
* Creates a new Getopt object. | |||||
* | |||||
* The argument $options can be either a string in the format accepted by the PHP library | |||||
* function getopt() or an array. | |||||
* | |||||
* @param mixed $options Array of options, a String, or null (see documentation for details) | |||||
* @param int $defaultType The default option type to use when omitted (optional) | |||||
* @throws \InvalidArgumentException | |||||
* | |||||
* @link https://www.gnu.org/s/hello/manual/libc/Getopt.html GNU Getopt manual | |||||
*/ | |||||
public function __construct($options = null, $defaultType = Getopt::NO_ARGUMENT) | |||||
{ | |||||
$this->optionParser = new OptionParser($defaultType); | |||||
if ($options !== null) { | |||||
$this->addOptions($options); | |||||
} | |||||
} | |||||
/** | |||||
* Extends the list of known options. Takes the same argument types as the constructor. | |||||
* | |||||
* @param mixed $options | |||||
* @throws \InvalidArgumentException | |||||
*/ | |||||
public function addOptions($options) | |||||
{ | |||||
if (is_string($options)) { | |||||
$this->mergeOptions($this->optionParser->parseString($options)); | |||||
} elseif (is_array($options)) { | |||||
$this->mergeOptions($this->optionParser->parseArray($options)); | |||||
} else { | |||||
throw new \InvalidArgumentException("Getopt(): argument must be string or array"); | |||||
} | |||||
} | |||||
/** | |||||
* Merges new options with the ones already in the Getopt optionList, making sure the resulting list is free of | |||||
* conflicts. | |||||
* | |||||
* @param Option[] $options The list of new options | |||||
* @throws \InvalidArgumentException | |||||
*/ | |||||
private function mergeOptions(array $options) | |||||
{ | |||||
/** @var Option[] $mergedList */ | |||||
$mergedList = array_merge($this->optionList, $options); | |||||
$duplicates = array(); | |||||
foreach ($mergedList as $option) { | |||||
foreach ($mergedList as $otherOption) { | |||||
if (($option === $otherOption) || in_array($otherOption, $duplicates)) { | |||||
continue; | |||||
} | |||||
if ($this->optionsConflict($option, $otherOption)) { | |||||
throw new \InvalidArgumentException('Failed to add options due to conflict'); | |||||
} | |||||
if (($option->short() === $otherOption->short()) && ($option->long() === $otherOption->long())) { | |||||
$duplicates[] = $option; | |||||
} | |||||
} | |||||
} | |||||
foreach ($mergedList as $index => $option) { | |||||
if (in_array($option, $duplicates)) { | |||||
unset($mergedList[$index]); | |||||
} | |||||
} | |||||
$this->optionList = array_values($mergedList); | |||||
} | |||||
private function optionsConflict(Option $option1, Option $option2) { | |||||
if ((is_null($option1->short()) && is_null($option2->short())) | |||||
|| (is_null($option1->long()) && is_null($option2->long()))) { | |||||
return false; | |||||
} | |||||
return ((($option1->short() === $option2->short()) && ($option1->long() !== $option2->long())) | |||||
|| (($option1->short() !== $option2->short()) && ($option1->long() === $option2->long()))); | |||||
} | |||||
/** | |||||
* Evaluate the given arguments. These can be passed either as a string or as an array. | |||||
* If nothing is passed, the running script's command line arguments are used. | |||||
* | |||||
* An {@link \UnexpectedValueException} or {@link \InvalidArgumentException} is thrown | |||||
* when the arguments are not well-formed or do not conform to the options passed by the user. | |||||
* | |||||
* @param mixed $arguments optional ARGV array or space separated string | |||||
*/ | |||||
public function parse($arguments = null) | |||||
{ | |||||
$this->options = array(); | |||||
if (!isset($arguments)) { | |||||
global $argv; | |||||
$arguments = $argv; | |||||
$this->scriptName = array_shift($arguments); // $argv[0] is the script's name | |||||
} elseif (is_string($arguments)) { | |||||
$this->scriptName = $_SERVER['PHP_SELF']; | |||||
$arguments = explode(' ', $arguments); | |||||
} | |||||
$parser = new CommandLineParser($this->optionList); | |||||
$parser->parse($arguments); | |||||
$this->options = $parser->getOptions(); | |||||
$this->operands = $parser->getOperands(); | |||||
} | |||||
/** | |||||
* Returns the value of the given option. Must be invoked after parse(). | |||||
* | |||||
* The return value can be any of the following: | |||||
* <ul> | |||||
* <li><b>null</b> if the option is not given and does not have a default value</li> | |||||
* <li><b>the default value</b> if it has been defined and the option is not given</li> | |||||
* <li><b>an integer</b> if the option is given without argument. The | |||||
* returned value is the number of occurrences of the option.</li> | |||||
* <li><b>a string</b> if the option is given with an argument. The returned value is that argument.</li> | |||||
* </ul> | |||||
* | |||||
* @param string $name The (short or long) option name. | |||||
* @return mixed | |||||
*/ | |||||
public function getOption($name) | |||||
{ | |||||
return isset($this->options[$name]) ? $this->options[$name] : null; | |||||
} | |||||
/** | |||||
* Returns the list of options. Must be invoked after parse() (otherwise it returns an empty array). | |||||
* | |||||
* @return array | |||||
*/ | |||||
public function getOptions() | |||||
{ | |||||
return $this->options; | |||||
} | |||||
/** | |||||
* Returns the list of operands. Must be invoked after parse(). | |||||
* | |||||
* @return array | |||||
*/ | |||||
public function getOperands() | |||||
{ | |||||
return $this->operands; | |||||
} | |||||
/** | |||||
* Returns the i-th operand (starting with 0), or null if it does not exist. Must be invoked after parse(). | |||||
* | |||||
* @param int $i | |||||
* @return string | |||||
*/ | |||||
public function getOperand($i) | |||||
{ | |||||
return ($i < count($this->operands)) ? $this->operands[$i] : null; | |||||
} | |||||
/** | |||||
* Returns the banner string | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getBanner() | |||||
{ | |||||
return $this->banner; | |||||
} | |||||
/** | |||||
* Set the banner string | |||||
* | |||||
* @param string $banner The banner string; will be passed to sprintf(), can include %s for current scripts name. | |||||
* Be sure to include a trailing line feed. | |||||
* @return Getopt | |||||
*/ | |||||
public function setBanner($banner) | |||||
{ | |||||
$this->banner = $banner; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Returns an usage information text generated from the given options. | |||||
* @param int $padding Number of characters to pad output of options to | |||||
* @return string | |||||
*/ | |||||
public function getHelpText($padding = 25) | |||||
{ | |||||
$helpText = sprintf($this->getBanner(), $this->scriptName); | |||||
$helpText .= "Options:\n"; | |||||
foreach ($this->optionList as $option) { | |||||
$mode = ''; | |||||
switch ($option->mode()) { | |||||
case self::NO_ARGUMENT: | |||||
$mode = ''; | |||||
break; | |||||
case self::REQUIRED_ARGUMENT: | |||||
$mode = "<".$option->getArgument()->getName().">"; | |||||
break; | |||||
case self::OPTIONAL_ARGUMENT: | |||||
$mode = "[<".$option->getArgument()->getName().">]"; | |||||
break; | |||||
} | |||||
$short = ($option->short()) ? '-'.$option->short() : ''; | |||||
$long = ($option->long()) ? '--'.$option->long() : ''; | |||||
if ($short && $long) { | |||||
$options = $short.', '.$long; | |||||
} else { | |||||
$options = $short ? : $long; | |||||
} | |||||
$padded = str_pad(sprintf(" %s %s", $options, $mode), $padding); | |||||
$helpText .= sprintf("%s %s\n", $padded, $option->getDescription()); | |||||
} | |||||
return $helpText; | |||||
} | |||||
/* | |||||
* Interface support functions | |||||
*/ | |||||
public function count() | |||||
{ | |||||
return count($this->options); | |||||
} | |||||
public function offsetExists($offset) | |||||
{ | |||||
return isset($this->options[$offset]); | |||||
} | |||||
public function offsetGet($offset) | |||||
{ | |||||
return $this->getOption($offset); | |||||
} | |||||
public function offsetSet($offset, $value) | |||||
{ | |||||
throw new \LogicException('Getopt is read-only'); | |||||
} | |||||
public function offsetUnset($offset) | |||||
{ | |||||
throw new \LogicException('Getopt is read-only'); | |||||
} | |||||
public function getIterator() | |||||
{ | |||||
// For options that have both short and long names, $this->options has two entries. | |||||
// We don't want this when iterating, so we have to filter the duplicates out. | |||||
$filteredOptions = array(); | |||||
foreach ($this->options as $name => $value) { | |||||
$keep = true; | |||||
foreach ($this->optionList as $option) { | |||||
if ($option->long() == $name && !is_null($option->short())) { | |||||
$keep = false; | |||||
} | |||||
} | |||||
if ($keep) { | |||||
$filteredOptions[$name] = $value; | |||||
} | |||||
} | |||||
return new \ArrayIterator($filteredOptions); | |||||
} | |||||
} |
@@ -0,0 +1,162 @@ | |||||
<?php | |||||
namespace Ulrichsg\Getopt; | |||||
/** | |||||
* Represents an option that Getopt accepts. | |||||
*/ | |||||
class Option | |||||
{ | |||||
private $short; | |||||
private $long; | |||||
private $mode; | |||||
private $description = ''; | |||||
private $argument; | |||||
/** | |||||
* Creates a new option. | |||||
* | |||||
* @param string $short the option's short name (a single letter or digit) or null for long-only options | |||||
* @param string $long the option's long name (a string of 2+ letter/digit/_/- characters, starting with a letter | |||||
* or digit) or null for short-only options | |||||
* @param int $mode whether the option can/must have an argument (one of the constants defined in the Getopt class) | |||||
* (optional, defaults to no argument) | |||||
* @throws \InvalidArgumentException if both short and long name are null | |||||
*/ | |||||
public function __construct($short, $long, $mode = Getopt::NO_ARGUMENT) | |||||
{ | |||||
if (!$short && !$long) { | |||||
throw new \InvalidArgumentException("The short and long name may not both be empty"); | |||||
} | |||||
$this->setShort($short); | |||||
$this->setLong($long); | |||||
$this->setMode($mode); | |||||
$this->argument = new Argument(); | |||||
} | |||||
/** | |||||
* Defines a description for the option. This is only used for generating usage information. | |||||
* | |||||
* @param string $description | |||||
* @return Option this object (for chaining calls) | |||||
*/ | |||||
public function setDescription($description) | |||||
{ | |||||
$this->description = $description; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Defines a default value for the option. | |||||
* | |||||
* @param mixed $value | |||||
* @return Option this object (for chaining calls) | |||||
*/ | |||||
public function setDefaultValue($value) | |||||
{ | |||||
$this->argument->setDefaultValue($value); | |||||
return $this; | |||||
} | |||||
/** | |||||
* Defines a validation function for the option. | |||||
* | |||||
* @param callable $function | |||||
* @return Option this object (for chaining calls) | |||||
*/ | |||||
public function setValidation($function) | |||||
{ | |||||
$this->argument->setValidation($function); | |||||
return $this; | |||||
} | |||||
/** | |||||
* Sets the argument object directly. | |||||
* | |||||
* @param Argument $arg | |||||
* @return Option this object (for chaining calls) | |||||
*/ | |||||
public function setArgument(Argument $arg) | |||||
{ | |||||
if ($this->mode == Getopt::NO_ARGUMENT) { | |||||
throw new \InvalidArgumentException("Option should not have any argument"); | |||||
} | |||||
$this->argument = $arg; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Returns true if the given string is equal to either the short or the long name. | |||||
* | |||||
* @param string $string | |||||
* @return bool | |||||
*/ | |||||
public function matches($string) | |||||
{ | |||||
return ($string === $this->short) || ($string === $this->long); | |||||
} | |||||
public function short() | |||||
{ | |||||
return $this->short; | |||||
} | |||||
public function long() | |||||
{ | |||||
return $this->long; | |||||
} | |||||
public function mode() | |||||
{ | |||||
return $this->mode; | |||||
} | |||||
public function getDescription() | |||||
{ | |||||
return $this->description; | |||||
} | |||||
/** | |||||
* Retrieve the argument object | |||||
* | |||||
* @return Argument | |||||
*/ | |||||
public function getArgument() | |||||
{ | |||||
return $this->argument; | |||||
} | |||||
/** | |||||
* Fluent interface for constructor so options can be added during construction | |||||
* @see Options::__construct() | |||||
*/ | |||||
public static function create($short, $long, $mode = Getopt::NO_ARGUMENT) | |||||
{ | |||||
return new self($short, $long, $mode); | |||||
} | |||||
private function setShort($short) | |||||
{ | |||||
if (!(is_null($short) || preg_match("/^[a-zA-Z0-9]$/", $short))) { | |||||
throw new \InvalidArgumentException("Short option must be null or a letter/digit, found '$short'"); | |||||
} | |||||
$this->short = $short; | |||||
} | |||||
private function setLong($long) | |||||
{ | |||||
if (!(is_null($long) || preg_match("/^[a-zA-Z0-9][a-zA-Z0-9_-]{1,}$/", $long))) { | |||||
throw new \InvalidArgumentException("Long option must be null or an alphanumeric string, found '$long'"); | |||||
} | |||||
$this->long = $long; | |||||
} | |||||
private function setMode($mode) | |||||
{ | |||||
if (!in_array($mode, array(Getopt::NO_ARGUMENT, Getopt::OPTIONAL_ARGUMENT, Getopt::REQUIRED_ARGUMENT), true)) { | |||||
throw new \InvalidArgumentException("Option mode must be one of " | |||||
."Getopt::NO_ARGUMENT, Getopt::OPTIONAL_ARGUMENT and Getopt::REQUIRED_ARGUMENT"); | |||||
} | |||||
$this->mode = $mode; | |||||
} | |||||
} |
@@ -0,0 +1,137 @@ | |||||
<?php | |||||
namespace Ulrichsg\Getopt; | |||||
/** | |||||
* Converts user-given option specifications into Option objects. | |||||
*/ | |||||
class OptionParser | |||||
{ | |||||
private $defaultMode; | |||||
/** | |||||
* Creates a new instance. | |||||
* | |||||
* @param int $defaultMode will be assigned to options when no mode is given for them. | |||||
*/ | |||||
public function __construct($defaultMode) { | |||||
$this->defaultMode = $defaultMode; | |||||
} | |||||
/** | |||||
* Parse a GNU-style option string. | |||||
* | |||||
* @param string $string the option string | |||||
* @return Option[] | |||||
* @throws \InvalidArgumentException | |||||
*/ | |||||
public function parseString($string) | |||||
{ | |||||
if (!mb_strlen($string)) { | |||||
throw new \InvalidArgumentException('Option string must not be empty'); | |||||
} | |||||
$options = array(); | |||||
$eol = mb_strlen($string) - 1; | |||||
$nextCanBeColon = false; | |||||
for ($i = 0; $i <= $eol; ++$i) { | |||||
$ch = $string[$i]; | |||||
if (!preg_match('/^[A-Za-z0-9]$/', $ch)) { | |||||
$colon = $nextCanBeColon ? " or ':'" : ''; | |||||
throw new \InvalidArgumentException("Option string is not well formed: " | |||||
."expected a letter$colon, found '$ch' at position ".($i + 1)); | |||||
} | |||||
if ($i == $eol || $string[$i + 1] != ':') { | |||||
$options[] = new Option($ch, null, Getopt::NO_ARGUMENT); | |||||
$nextCanBeColon = true; | |||||
} elseif ($i < $eol - 1 && $string[$i + 2] == ':') { | |||||
$options[] = new Option($ch, null, Getopt::OPTIONAL_ARGUMENT); | |||||
$i += 2; | |||||
$nextCanBeColon = false; | |||||
} else { | |||||
$options[] = new Option($ch, null, Getopt::REQUIRED_ARGUMENT); | |||||
++$i; | |||||
$nextCanBeColon = true; | |||||
} | |||||
} | |||||
return $options; | |||||
} | |||||
/** | |||||
* Processes an option array. The array elements can either be Option objects or arrays conforming to the format | |||||
* (short, long, mode [, description [, default]]). See documentation for details. | |||||
* | |||||
* Developer note: Please don't add any further elements to the array. Future features should be configured only | |||||
* through the Option class's methods. | |||||
* | |||||
* @param array $array | |||||
* @return Option[] | |||||
* @throws \InvalidArgumentException | |||||
*/ | |||||
public function parseArray(array $array) | |||||
{ | |||||
if (empty($array)) { | |||||
throw new \InvalidArgumentException('No options given'); | |||||
} | |||||
$options = array(); | |||||
foreach ($array as $row) { | |||||
if ($row instanceof Option) { | |||||
$options[] = $row; | |||||
} elseif (is_array($row)) { | |||||
$options[] = $this->createOption($row); | |||||
} else { | |||||
throw new \InvalidArgumentException("Invalid option type, must be Option or array"); | |||||
} | |||||
} | |||||
return $options; | |||||
} | |||||
/** | |||||
* @param array $row | |||||
* @return Option | |||||
*/ | |||||
private function createOption(array $row) | |||||
{ | |||||
$rowSize = count($row); | |||||
if ($rowSize < 3) { | |||||
$row = $this->completeOptionArray($row); | |||||
} | |||||
$option = new Option($row[0], $row[1], $row[2]); | |||||
if ($rowSize >= 4) { | |||||
$option->setDescription($row[3]); | |||||
} | |||||
if ($rowSize >= 5 && $row[2] != Getopt::NO_ARGUMENT) { | |||||
$option->setArgument(new Argument($row[4])); | |||||
} | |||||
return $option; | |||||
} | |||||
/** | |||||
* When using arrays, instead of a full option spec ([short, long, type]) users can leave out one or more of | |||||
* these parts and have Getopt fill them in intelligently: | |||||
* - If either the short or the long option string is left out, the first element of the given array is interpreted | |||||
* as either short (if it has length 1) or long, and the other one is set to null. | |||||
* - If the type is left out, it is set to NO_ARGUMENT. | |||||
* | |||||
* @param array $row | |||||
* @return array | |||||
*/ | |||||
private function completeOptionArray(array $row) | |||||
{ | |||||
$short = (strlen($row[0]) == 1) ? $row[0] : null; | |||||
$long = null; | |||||
if (is_null($short)) { | |||||
$long = $row[0]; | |||||
} elseif (count($row) > 1 && !is_int($row[1])) { | |||||
$long = $row[1]; | |||||
} | |||||
$mode = $this->defaultMode; | |||||
if (count($row) == 2 && is_int($row[1])) { | |||||
$mode = $row[1]; | |||||
} | |||||
return array($short, $long, $mode); | |||||
} | |||||
} |
@@ -0,0 +1,40 @@ | |||||
<?php | |||||
namespace Ulrichsg\Getopt; | |||||
class ArgumentTest extends \PHPUnit_Framework_TestCase | |||||
{ | |||||
public function testConstructor() | |||||
{ | |||||
$argument1 = new Argument(); | |||||
$argument2 = new Argument(10); | |||||
$this->assertFalse($argument1->hasDefaultValue()); | |||||
$this->assertEquals(10, $argument2->getDefaultValue()); | |||||
} | |||||
public function testSetDefaultValueNotScalar() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
$argument = new Argument(); | |||||
$argument->setDefaultValue(array()); | |||||
} | |||||
public function testValidates() | |||||
{ | |||||
$test = $this; | |||||
$argument = new Argument(); | |||||
$argument->setValidation(function($arg) use ($test, $argument) { | |||||
$test->assertEquals('test', $arg); | |||||
return true; | |||||
}); | |||||
$this->assertTrue($argument->hasValidation()); | |||||
$this->assertTrue($argument->validates('test')); | |||||
} | |||||
public function testSetValidationUncallable() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
$argument = new Argument(); | |||||
$argument->setValidation(''); | |||||
} | |||||
} |
@@ -0,0 +1,341 @@ | |||||
<?php | |||||
namespace Ulrichsg\Getopt; | |||||
class CommandLineParserTest extends \PHPUnit_Framework_TestCase | |||||
{ | |||||
public function testParseNoOptions() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null) | |||||
)); | |||||
$parser->parse('something'); | |||||
$this->assertCount(0, $parser->getOptions()); | |||||
$operands = $parser->getOperands(); | |||||
$this->assertCount(1, $operands); | |||||
$this->assertEquals('something', $operands[0]); | |||||
} | |||||
public function testParseUnknownOption() | |||||
{ | |||||
$this->setExpectedException('UnexpectedValueException'); | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null) | |||||
)); | |||||
$parser->parse('-b'); | |||||
} | |||||
public function testParseRequiredArgumentMissing() | |||||
{ | |||||
$this->setExpectedException('UnexpectedValueException'); | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null, Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$parser->parse('-a'); | |||||
} | |||||
public function testParseMultipleOptionsWithOneHyphen() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null), | |||||
new Option('b', null) | |||||
)); | |||||
$parser->parse('-ab'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals(1, $options['a']); | |||||
$this->assertEquals(1, $options['b']); | |||||
} | |||||
public function testParseCumulativeOption() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null), | |||||
new Option('b', null) | |||||
)); | |||||
$parser->parse('-a -b -a -a'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals(3, $options['a']); | |||||
$this->assertEquals(1, $options['b']); | |||||
} | |||||
public function testParseCumulativeOptionShort() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null), | |||||
new Option('b', null) | |||||
)); | |||||
$parser->parse('-abaa'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals(3, $options['a']); | |||||
$this->assertEquals(1, $options['b']); | |||||
} | |||||
public function testParseShortOptionWithArgument() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null, Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$parser->parse('-a value'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals('value', $options['a']); | |||||
} | |||||
public function testParseZeroArgument() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null, Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$parser->parse('-a 0'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals('0', $options['a']); | |||||
} | |||||
public function testParseNumericOption() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null, Getopt::REQUIRED_ARGUMENT), | |||||
new Option('2', null) | |||||
)); | |||||
$parser->parse('-a 2 -2'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals('2', $options['a']); | |||||
$this->assertEquals(1, $options['2']); | |||||
} | |||||
public function testParseCollapsedShortOptionsRequiredArgumentMissing() | |||||
{ | |||||
$this->setExpectedException('UnexpectedValueException'); | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null), | |||||
new Option('b', null, Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$parser->parse('-ab'); | |||||
} | |||||
public function testParseCollapsedShortOptionsWithArgument() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null), | |||||
new Option('b', null, Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$parser->parse('-ab value'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals(1, $options['a']); | |||||
$this->assertEquals('value', $options['b']); | |||||
} | |||||
public function testParseNoArgumentOptionAndOperand() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null), | |||||
)); | |||||
$parser->parse('-a b'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals(1, $options['a']); | |||||
$operands = $parser->getOperands(); | |||||
$this->assertCount(1, $operands); | |||||
$this->assertEquals('b', $operands[0]); | |||||
} | |||||
public function testParseOperandsOnly() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null, Getopt::REQUIRED_ARGUMENT), | |||||
new Option('b', null) | |||||
)); | |||||
$parser->parse('-- -a -b'); | |||||
$this->assertCount(0, $parser->getOptions()); | |||||
$operands = $parser->getOperands(); | |||||
$this->assertCount(2, $operands); | |||||
$this->assertEquals('-a', $operands[0]); | |||||
$this->assertEquals('-b', $operands[1]); | |||||
} | |||||
public function testParseLongOptionWithoutArgument() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('o', 'option', Getopt::OPTIONAL_ARGUMENT) | |||||
)); | |||||
$parser->parse('--option'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals(1, $options['option']); | |||||
} | |||||
public function testParseLongOptionWithoutArgumentAndOperand() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('o', 'option', Getopt::NO_ARGUMENT) | |||||
)); | |||||
$parser->parse('--option something'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals(1, $options['option']); | |||||
$operands = $parser->getOperands(); | |||||
$this->assertCount(1, $operands); | |||||
$this->assertEquals('something', $operands[0]); | |||||
} | |||||
public function testParseLongOptionWithArgument() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('o', 'option', Getopt::OPTIONAL_ARGUMENT) | |||||
)); | |||||
$parser->parse('--option value'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals('value', $options['option']); | |||||
$this->assertEquals('value', $options['o']); | |||||
} | |||||
public function testParseLongOptionWithEqualsSignAndArgument() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('o', 'option', Getopt::OPTIONAL_ARGUMENT) | |||||
)); | |||||
$parser->parse('--option=value something'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals('value', $options['option']); | |||||
$operands = $parser->getOperands(); | |||||
$this->assertCount(1, $operands); | |||||
$this->assertEquals('something', $operands[0]); | |||||
} | |||||
public function testParseLongOptionWithValueStartingWithHyphen() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('o', 'option', Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$parser->parse('--option=-value'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals('-value', $options['option']); | |||||
} | |||||
public function testParseNoValueStartingWithHyphenRequired() | |||||
{ | |||||
$this->setExpectedException('UnexpectedValueException'); | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null, Getopt::REQUIRED_ARGUMENT), | |||||
new Option('b', null) | |||||
)); | |||||
$parser->parse('-a -b'); | |||||
} | |||||
public function testParseNoValueStartingWithHyphenOptional() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null, Getopt::OPTIONAL_ARGUMENT), | |||||
new Option('b', null) | |||||
)); | |||||
$parser->parse('-a -b'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals(1, $options['a']); | |||||
$this->assertEquals(1, $options['b']); | |||||
} | |||||
public function testParseOptionWithDefaultValue() | |||||
{ | |||||
$optionA = new Option('a', null, Getopt::REQUIRED_ARGUMENT); | |||||
$optionA->setArgument(new Argument(10)); | |||||
$optionB = new Option('b', 'beta', Getopt::REQUIRED_ARGUMENT); | |||||
$optionB->setArgument(new Argument(20)); | |||||
$parser = new CommandLineParser(array($optionA, $optionB)); | |||||
$parser->parse('-a 12'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals(12, $options['a']); | |||||
$this->assertEquals(20, $options['b']); | |||||
$this->assertEquals(20, $options['beta']); | |||||
} | |||||
public function testDoubleHyphenNotInOperands() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null, Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$parser->parse('-a 0 foo -- bar baz'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals('0', $options['a']); | |||||
$operands = $parser->getOperands(); | |||||
$this->assertCount(3, $operands); | |||||
$this->assertEquals('foo', $operands[0]); | |||||
$this->assertEquals('bar', $operands[1]); | |||||
$this->assertEquals('baz', $operands[2]); | |||||
} | |||||
public function testSingleHyphenValue() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', 'alpha', Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$parser->parse('-a -'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals('-', $options['a']); | |||||
$operands = $parser->getOperands(); | |||||
$this->assertCount(0, $operands); | |||||
$parser->parse('--alpha -'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals('-', $options['a']); | |||||
$operands = $parser->getOperands(); | |||||
$this->assertCount(0, $operands); | |||||
} | |||||
public function testSingleHyphenOperand() | |||||
{ | |||||
$parser = new CommandLineParser(array( | |||||
new Option('a', null, Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$parser->parse('-a 0 -'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertEquals('0', $options['a']); | |||||
$operands = $parser->getOperands(); | |||||
$this->assertCount(1, $operands); | |||||
$this->assertEquals('-', $operands[0]); | |||||
} | |||||
public function testParseWithArgumentValidation() | |||||
{ | |||||
$validation = 'is_numeric'; | |||||
$optionA = new Option('a', null, Getopt::OPTIONAL_ARGUMENT); | |||||
$optionA->setArgument(new Argument(null, $validation)); | |||||
$optionB = new Option('b', null, Getopt::REQUIRED_ARGUMENT); | |||||
$optionB->setArgument(new Argument(null, $validation)); | |||||
$optionC = new Option('c', null, Getopt::OPTIONAL_ARGUMENT); | |||||
$optionC->setArgument(new Argument(null, $validation)); | |||||
$parser = new CommandLineParser(array($optionA, $optionB, $optionC)); | |||||
$parser->parse('-a 1 -b 2 -c'); | |||||
$options = $parser->getOptions(); | |||||
$this->assertSame('1', $options['a']); | |||||
$this->assertSame('2', $options['b']); | |||||
$this->assertSame(1, $options['c']); | |||||
} | |||||
public function testParseInvalidArgument() | |||||
{ | |||||
$this->setExpectedException('UnexpectedValueException'); | |||||
$validation = 'is_numeric'; | |||||
$option = new Option('a', null, Getopt::OPTIONAL_ARGUMENT); | |||||
$option->setArgument(new Argument(null, $validation)); | |||||
$parser = new CommandLineParser(array($option)); | |||||
$parser->parse('-a nonnumeric'); | |||||
} | |||||
} |
@@ -0,0 +1,199 @@ | |||||
<?php | |||||
namespace Ulrichsg\Getopt; | |||||
class GetoptTest extends \PHPUnit_Framework_TestCase | |||||
{ | |||||
public function testAddOptions() | |||||
{ | |||||
$getopt = new Getopt(); | |||||
$getopt->addOptions('a:'); | |||||
$getopt->addOptions( | |||||
array( | |||||
array('s', null, Getopt::OPTIONAL_ARGUMENT), | |||||
array(null, 'long', Getopt::OPTIONAL_ARGUMENT), | |||||
array('n', 'name', Getopt::OPTIONAL_ARGUMENT) | |||||
) | |||||
); | |||||
$getopt->parse('-a aparam -s sparam --long longparam'); | |||||
$this->assertEquals('aparam', $getopt->getOption('a')); | |||||
$this->assertEquals('longparam', $getopt->getOption('long')); | |||||
$this->assertEquals('sparam', $getopt->getOption('s')); | |||||
} | |||||
public function testAddOptionsChooseShortOrLongAutomatically() | |||||
{ | |||||
$getopt = new Getopt(); | |||||
$getopt->addOptions( | |||||
array( | |||||
array('s'), | |||||
array('long', Getopt::OPTIONAL_ARGUMENT) | |||||
) | |||||
); | |||||
$getopt->parse('-s --long longparam'); | |||||
$this->assertEquals('longparam', $getopt->getOption('long')); | |||||
$this->assertEquals('1', $getopt->getOption('s')); | |||||
} | |||||
public function testAddOptionsUseDefaultArgumentType() | |||||
{ | |||||
$getopt = new Getopt(null, Getopt::REQUIRED_ARGUMENT); | |||||
$getopt->addOptions( | |||||
array( | |||||
array('l', 'long') | |||||
) | |||||
); | |||||
$getopt->parse('-l something'); | |||||
$this->assertEquals('something', $getopt->getOption('l')); | |||||
$getopt->parse('--long someOtherThing'); | |||||
$this->assertEquals('someOtherThing', $getopt->getOption('long')); | |||||
} | |||||
public function testAddOptionsFailsOnInvalidArgument() | |||||
{ | |||||
$this->setExpectedException('\InvalidArgumentException'); | |||||
$getopt = new Getopt(null); | |||||
$getopt->addOptions(new Option('a', 'alpha')); | |||||
} | |||||
public function testAddOptionsOverwritesExistingOptions() | |||||
{ | |||||
$getopt = new Getopt(array( | |||||
array('a', null, Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$getopt->addOptions(array( | |||||
array('a', null, Getopt::NO_ARGUMENT) | |||||
)); | |||||
$getopt->parse('-a foo'); | |||||
$this->assertEquals(1, $getopt->getOption('a')); | |||||
$this->assertEquals('foo', $getopt->getOperand(0)); | |||||
} | |||||
public function testAddOptionsFailsOnConflict() | |||||
{ | |||||
$this->setExpectedException('\InvalidArgumentException'); | |||||
$getopt = new Getopt(array( | |||||
array('v', 'version') | |||||
)); | |||||
$getopt->addOptions(array( | |||||
array('v', 'verbose') | |||||
)); | |||||
} | |||||
public function testParseUsesGlobalArgvWhenNoneGiven() | |||||
{ | |||||
global $argv; | |||||
$argv = array('foo.php', '-a'); | |||||
$getopt = new Getopt('a'); | |||||
$getopt->parse(); | |||||
$this->assertEquals(1, $getopt->getOption('a')); | |||||
} | |||||
public function testAccessMethods() | |||||
{ | |||||
$getopt = new Getopt('a'); | |||||
$getopt->parse('-a foo'); | |||||
$options = $getopt->getOptions(); | |||||
$this->assertCount(1, $options); | |||||
$this->assertEquals(1, $options['a']); | |||||
$this->assertEquals(1, $getopt->getOption('a')); | |||||
$operands = $getopt->getOperands(); | |||||
$this->assertCount(1, $operands); | |||||
$this->assertEquals('foo', $operands[0]); | |||||
$this->assertEquals('foo', $getopt->getOperand(0)); | |||||
} | |||||
public function testCountable() | |||||
{ | |||||
$getopt = new Getopt('abc'); | |||||
$getopt->parse('-abc'); | |||||
$this->assertEquals(3, count($getopt)); | |||||
} | |||||
public function testArrayAccess() | |||||
{ | |||||
$getopt = new Getopt('q'); | |||||
$getopt->parse('-q'); | |||||
$this->assertEquals(1, $getopt['q']); | |||||
} | |||||
public function testIterable() | |||||
{ | |||||
$getopt = new Getopt(array( | |||||
array(null, 'alpha', Getopt::NO_ARGUMENT), | |||||
array('b', 'beta', Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$getopt->parse('--alpha -b foo'); | |||||
$expected = array('alpha' => 1, 'b' => 'foo'); // 'beta' should not occur | |||||
foreach ($getopt as $option => $value) { | |||||
$this->assertEquals($expected[$option], $value); | |||||
} | |||||
} | |||||
public function testHelpText() | |||||
{ | |||||
$getopt = new Getopt(array( | |||||
array('a', 'alpha', Getopt::NO_ARGUMENT, 'Short and long options with no argument'), | |||||
array(null, 'beta', Getopt::OPTIONAL_ARGUMENT, 'Long option only with an optional argument'), | |||||
array('c', null, Getopt::REQUIRED_ARGUMENT, 'Short option only with a mandatory argument') | |||||
)); | |||||
$getopt->parse(''); | |||||
$script = $_SERVER['PHP_SELF']; | |||||
$expected = "Usage: $script [options] [operands]\n"; | |||||
$expected .= "Options:\n"; | |||||
$expected .= " -a, --alpha Short and long options with no argument\n"; | |||||
$expected .= " --beta [<arg>] Long option only with an optional argument\n"; | |||||
$expected .= " -c <arg> Short option only with a mandatory argument\n"; | |||||
$this->assertEquals($expected, $getopt->getHelpText()); | |||||
} | |||||
public function testHelpTextWithoutDescriptions() | |||||
{ | |||||
$getopt = new Getopt(array( | |||||
array('a', 'alpha', Getopt::NO_ARGUMENT), | |||||
array(null, 'beta', Getopt::OPTIONAL_ARGUMENT), | |||||
array('c', null, Getopt::REQUIRED_ARGUMENT) | |||||
)); | |||||
$getopt->parse(''); | |||||
$script = $_SERVER['PHP_SELF']; | |||||
$expected = "Usage: $script [options] [operands]\n"; | |||||
$expected .= "Options:\n"; | |||||
$expected .= " -a, --alpha \n"; | |||||
$expected .= " --beta [<arg>] \n"; | |||||
$expected .= " -c <arg> \n"; | |||||
$this->assertEquals($expected, $getopt->getHelpText()); | |||||
} | |||||
public function testHelpTextNoParse() | |||||
{ | |||||
$getopt = new Getopt(); | |||||
$expected = "Usage: [options] [operands]\nOptions:\n"; | |||||
$this->assertSame($expected, $getopt->getHelpText()); | |||||
} | |||||
public function testHelpTextWithCustomBanner() | |||||
{ | |||||
$script = $_SERVER['PHP_SELF']; | |||||
$getopt = new Getopt(); | |||||
$getopt->setBanner("My custom Banner %s\n"); | |||||
$this->assertSame("My custom Banner \nOptions:\n", $getopt->getHelpText()); | |||||
$getopt->parse(''); | |||||
$this->assertSame("My custom Banner $script\nOptions:\n", $getopt->getHelpText()); | |||||
} | |||||
} |
@@ -0,0 +1,112 @@ | |||||
<?php | |||||
namespace Ulrichsg\Getopt; | |||||
class OptionParserTest extends \PHPUnit_Framework_TestCase | |||||
{ | |||||
/** @var OptionParser */ | |||||
private $parser; | |||||
public function setUp() | |||||
{ | |||||
$this->parser = new OptionParser(Getopt::REQUIRED_ARGUMENT); | |||||
} | |||||
public function testParseString() | |||||
{ | |||||
$options = $this->parser->parseString('ab:c::3'); | |||||
$this->assertInternalType('array', $options); | |||||
$this->assertCount(4, $options); | |||||
foreach ($options as $option) { | |||||
$this->assertInstanceOf('Ulrichsg\Getopt\Option', $option); | |||||
$this->assertNull($option->long()); | |||||
switch ($option->short()) { | |||||
case 'a': | |||||
case '3': | |||||
$this->assertEquals(Getopt::NO_ARGUMENT, $option->mode()); | |||||
break; | |||||
case 'b': | |||||
$this->assertEquals(Getopt::REQUIRED_ARGUMENT, $option->mode()); | |||||
break; | |||||
case 'c': | |||||
$this->assertEquals(Getopt::OPTIONAL_ARGUMENT, $option->mode()); | |||||
break; | |||||
default: | |||||
$this->fail('Unexpected option: '.$option->short()); | |||||
} | |||||
} | |||||
} | |||||
public function testParseStringEmpty() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
$this->parser->parseString(''); | |||||
} | |||||
public function testParseStringInvalidCharacter() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
$this->parser->parseString('ab:c::dä'); | |||||
} | |||||
public function testParseStringStartsWithColon() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
$this->parser->parseString(':ab:c::d'); | |||||
} | |||||
public function testParseStringTripleColon() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
$this->parser->parseString('ab:c:::d'); | |||||
} | |||||
public function testParseArray() | |||||
{ | |||||
$options = $this->parser->parseArray( | |||||
array( | |||||
array('a', 'alpha', Getopt::OPTIONAL_ARGUMENT, 'Description', 42), | |||||
new Option('b', 'beta'), | |||||
array('c') | |||||
) | |||||
); | |||||
$this->assertCount(3, $options); | |||||
foreach ($options as $option) { | |||||
$this->assertInstanceOf('Ulrichsg\Getopt\Option', $option); | |||||
switch ($option->short()) { | |||||
case 'a': | |||||
$this->assertEquals('alpha', $option->long()); | |||||
$this->assertEquals(Getopt::OPTIONAL_ARGUMENT, $option->mode()); | |||||
$this->assertEquals('Description', $option->getDescription()); | |||||
$this->assertEquals(42, $option->getArgument()->getDefaultValue()); | |||||
break; | |||||
case 'b': | |||||
$this->assertEquals('beta', $option->long()); | |||||
$this->assertEquals(Getopt::NO_ARGUMENT, $option->mode()); | |||||
$this->assertEquals('', $option->getDescription()); | |||||
break; | |||||
case 'c': | |||||
$this->assertNull($option->long()); | |||||
$this->assertEquals(Getopt::REQUIRED_ARGUMENT, $option->mode()); | |||||
$this->assertEquals('', $option->getDescription()); | |||||
$this->assertFalse($option->getArgument()->hasDefaultValue()); | |||||
break; | |||||
default: | |||||
$this->fail('Unexpected option: '.$option->short()); | |||||
} | |||||
} | |||||
} | |||||
public function testParseArrayEmpty() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
$this->parser->parseArray(array()); | |||||
} | |||||
public function testParseArrayInvalid() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
$this->parser->parseArray(array('a', 'b')); | |||||
} | |||||
} |
@@ -0,0 +1,72 @@ | |||||
<?php | |||||
namespace Ulrichsg\Getopt; | |||||
class OptionTest extends \PHPUnit_Framework_TestCase | |||||
{ | |||||
public function testConstruct() | |||||
{ | |||||
$option = new Option('a', 'az-AZ09_', Getopt::OPTIONAL_ARGUMENT); | |||||
$this->assertEquals('a', $option->short()); | |||||
$this->assertEquals('az-AZ09_', $option->long()); | |||||
$this->assertEquals(Getopt::OPTIONAL_ARGUMENT, $option->mode()); | |||||
} | |||||
public function testConstructEmptyOption() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
new Option(null, null, Getopt::NO_ARGUMENT); | |||||
} | |||||
public function testConstructNoLetter() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
new Option('?', null, Getopt::NO_ARGUMENT); | |||||
} | |||||
public function testConstructInvalidCharacter() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
new Option(null, 'öption', Getopt::NO_ARGUMENT); | |||||
} | |||||
public function testConstructInvalidArgumentType() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
new Option('a', null, 'no_argument'); | |||||
} | |||||
public function testConstructLongOptionTooShort() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
new Option(null, 'a', Getopt::REQUIRED_ARGUMENT); | |||||
} | |||||
public function testSetArgument() | |||||
{ | |||||
$option = new Option('a', null, Getopt::OPTIONAL_ARGUMENT); | |||||
$this->assertEquals($option, $option->setArgument(new Argument())); | |||||
$this->assertInstanceof('Ulrichsg\Getopt\Argument', $option->getArgument()); | |||||
} | |||||
public function testSetArgumentWrongMode() | |||||
{ | |||||
$this->setExpectedException('InvalidArgumentException'); | |||||
$option = new Option('a', null, Getopt::NO_ARGUMENT); | |||||
$option->setArgument(new Argument()); | |||||
} | |||||
public function testSetDefaultValue() | |||||
{ | |||||
$option = new Option('a', null, Getopt::OPTIONAL_ARGUMENT); | |||||
$this->assertEquals($option, $option->setDefaultValue(10)); | |||||
$this->assertEquals(10, $option->getArgument()->getDefaultValue()); | |||||
} | |||||
public function testSetValidation() | |||||
{ | |||||
$option = new Option('a', null, Getopt::OPTIONAL_ARGUMENT); | |||||
$this->assertEquals($option, $option->setValidation('is_numeric')); | |||||
$this->assertTrue($option->getArgument()->hasValidation()); | |||||
} | |||||
} |