| @@ -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()); | |||
| } | |||
| } | |||