From caa18b3936c995d5f0ea0aad690863003d6bf7c3 Mon Sep 17 00:00:00 2001 From: Gustavo Arnosti Neves Date: Mon, 11 Jul 2016 07:12:57 -0300 Subject: [PATCH] First commit, creates barcodes from cli using PHP. Supports many formats and barcode encodings. --- .gitignore | 42 + Makefile | 21 + barcode | 15 + barcode.php | 298 ++ composer.json | 6 + composer.lock | 120 + vendor/autoload.php | 7 + vendor/composer/ClassLoader.php | 413 +++ vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 9 + vendor/composer/autoload_namespaces.php | 10 + vendor/composer/autoload_psr4.php | 10 + vendor/composer/autoload_real.php | 45 + vendor/composer/installed.json | 107 + .../picqer/php-barcode-generator/.gitignore | 2 + vendor/picqer/php-barcode-generator/Readme.md | 76 + .../php-barcode-generator/composer.json | 22 + .../picqer/php-barcode-generator/examples.php | 14 + .../src/BarcodeGenerator.php | 2833 +++++++++++++++++ .../src/BarcodeGeneratorHTML.php | 44 + .../src/BarcodeGeneratorJPG.php | 74 + .../src/BarcodeGeneratorPNG.php | 74 + .../src/BarcodeGeneratorSVG.php | 49 + vendor/ulrichsg/getopt-php/.gitignore | 6 + vendor/ulrichsg/getopt-php/.travis.yml | 10 + vendor/ulrichsg/getopt-php/CHANGELOG.md | 77 + vendor/ulrichsg/getopt-php/LICENSE | 17 + vendor/ulrichsg/getopt-php/Makefile | 35 + vendor/ulrichsg/getopt-php/README.markdown | 28 + vendor/ulrichsg/getopt-php/composer.json | 24 + vendor/ulrichsg/getopt-php/phpunit.xml | 35 + .../src/Ulrichsg/Getopt/Argument.php | 115 + .../src/Ulrichsg/Getopt/CommandLineParser.php | 233 ++ .../getopt-php/src/Ulrichsg/Getopt/Getopt.php | 295 ++ .../getopt-php/src/Ulrichsg/Getopt/Option.php | 162 + .../src/Ulrichsg/Getopt/OptionParser.php | 137 + .../test/Ulrichsg/Getopt/ArgumentTest.php | 40 + .../Ulrichsg/Getopt/CommandLineParserTest.php | 341 ++ .../test/Ulrichsg/Getopt/GetoptTest.php | 199 ++ .../test/Ulrichsg/Getopt/OptionParserTest.php | 112 + .../test/Ulrichsg/Getopt/OptionTest.php | 72 + 41 files changed, 6250 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100755 barcode create mode 100755 barcode.php create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 vendor/autoload.php create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/installed.json create mode 100644 vendor/picqer/php-barcode-generator/.gitignore create mode 100644 vendor/picqer/php-barcode-generator/Readme.md create mode 100644 vendor/picqer/php-barcode-generator/composer.json create mode 100644 vendor/picqer/php-barcode-generator/examples.php create mode 100644 vendor/picqer/php-barcode-generator/src/BarcodeGenerator.php create mode 100644 vendor/picqer/php-barcode-generator/src/BarcodeGeneratorHTML.php create mode 100644 vendor/picqer/php-barcode-generator/src/BarcodeGeneratorJPG.php create mode 100644 vendor/picqer/php-barcode-generator/src/BarcodeGeneratorPNG.php create mode 100644 vendor/picqer/php-barcode-generator/src/BarcodeGeneratorSVG.php create mode 100644 vendor/ulrichsg/getopt-php/.gitignore create mode 100644 vendor/ulrichsg/getopt-php/.travis.yml create mode 100644 vendor/ulrichsg/getopt-php/CHANGELOG.md create mode 100644 vendor/ulrichsg/getopt-php/LICENSE create mode 100644 vendor/ulrichsg/getopt-php/Makefile create mode 100644 vendor/ulrichsg/getopt-php/README.markdown create mode 100644 vendor/ulrichsg/getopt-php/composer.json create mode 100644 vendor/ulrichsg/getopt-php/phpunit.xml create mode 100644 vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Argument.php create mode 100644 vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/CommandLineParser.php create mode 100644 vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Getopt.php create mode 100644 vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Option.php create mode 100644 vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/OptionParser.php create mode 100644 vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/ArgumentTest.php create mode 100644 vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/CommandLineParserTest.php create mode 100644 vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/GetoptTest.php create mode 100644 vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/OptionParserTest.php create mode 100644 vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/OptionTest.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f39258 --- /dev/null +++ b/.gitignore @@ -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 + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..249da8f --- /dev/null +++ b/Makefile @@ -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} diff --git a/barcode b/barcode new file mode 100755 index 0000000..8143793 --- /dev/null +++ b/barcode @@ -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" "$@" diff --git a/barcode.php b/barcode.php new file mode 100755 index 0000000..60e390c --- /dev/null +++ b/barcode.php @@ -0,0 +1,298 @@ +#!/usr/bin/env php + 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 -f [options] \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 = <<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 \n"; + echo " -f \n"; + echo " \n"; + echo " \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); + +?> \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..de1134b --- /dev/null +++ b/composer.json @@ -0,0 +1,6 @@ +{ + "require": { + "picqer/php-barcode-generator": "^0.1.0", + "ulrichsg/getopt-php": "^2.3" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..9d542a0 --- /dev/null +++ b/composer.lock @@ -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": [] +} diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 0000000..f04aae1 --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * 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 + * @author Jordi Boggiano + * @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; +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 0000000..1a28124 --- /dev/null +++ b/vendor/composer/LICENSE @@ -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. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..7a91153 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + array($vendorDir . '/ulrichsg/getopt-php/src'), +); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php new file mode 100644 index 0000000..8db6e97 --- /dev/null +++ b/vendor/composer/autoload_psr4.php @@ -0,0 +1,10 @@ + array($vendorDir . '/picqer/php-barcode-generator/src'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 0000000..e5e2427 --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,45 @@ + $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; + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 0000000..f89632d --- /dev/null +++ b/vendor/composer/installed.json @@ -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" + } +] diff --git a/vendor/picqer/php-barcode-generator/.gitignore b/vendor/picqer/php-barcode-generator/.gitignore new file mode 100644 index 0000000..090a1f0 --- /dev/null +++ b/vendor/picqer/php-barcode-generator/.gitignore @@ -0,0 +1,2 @@ +.idea +.DS_Store diff --git a/vendor/picqer/php-barcode-generator/Readme.md b/vendor/picqer/php-barcode-generator/Readme.md new file mode 100644 index 0000000..e8306db --- /dev/null +++ b/vendor/picqer/php-barcode-generator/Readme.md @@ -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 ''; +``` \ No newline at end of file diff --git a/vendor/picqer/php-barcode-generator/composer.json b/vendor/picqer/php-barcode-generator/composer.json new file mode 100644 index 0000000..6cc12a8 --- /dev/null +++ b/vendor/picqer/php-barcode-generator/composer.json @@ -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" + } + } +} \ No newline at end of file diff --git a/vendor/picqer/php-barcode-generator/examples.php b/vendor/picqer/php-barcode-generator/examples.php new file mode 100644 index 0000000..dae318d --- /dev/null +++ b/vendor/picqer/php-barcode-generator/examples.php @@ -0,0 +1,14 @@ +getBarcode('081231723897', $generatorPNG::TYPE_CODE_128); +echo $generatorSVG->getBarcode('081231723897', $generatorPNG::TYPE_EAN_13); +echo ''; \ No newline at end of file diff --git a/vendor/picqer/php-barcode-generator/src/BarcodeGenerator.php b/vendor/picqer/php-barcode-generator/src/BarcodeGenerator.php new file mode 100644 index 0000000..d05684f --- /dev/null +++ b/vendor/picqer/php-barcode-generator/src/BarcodeGenerator.php @@ -0,0 +1,2833 @@ +barcode_code39($code, false, false); + break; + } + case self::TYPE_CODE_39_CHECKSUM: { // CODE 39 with checksum + $arrcode = $this->barcode_code39($code, false, true); + break; + } + case self::TYPE_CODE_39E: { // CODE 39 EXTENDED + $arrcode = $this->barcode_code39($code, true, false); + break; + } + case self::TYPE_CODE_39E_CHECKSUM: { // CODE 39 EXTENDED + CHECKSUM + $arrcode = $this->barcode_code39($code, true, true); + break; + } + case self::TYPE_CODE_93: { // CODE 93 - USS-93 + $arrcode = $this->barcode_code93($code); + break; + } + case self::TYPE_STANDARD_2_5: { // Standard 2 of 5 + $arrcode = $this->barcode_s25($code, false); + break; + } + case self::TYPE_STANDARD_2_5_CHECKSUM: { // Standard 2 of 5 + CHECKSUM + $arrcode = $this->barcode_s25($code, true); + break; + } + case self::TYPE_INTERLEAVED_2_5: { // Interleaved 2 of 5 + $arrcode = $this->barcode_i25($code, false); + break; + } + case self::TYPE_INTERLEAVED_2_5_CHECKSUM: { // Interleaved 2 of 5 + CHECKSUM + $arrcode = $this->barcode_i25($code, true); + break; + } + case self::TYPE_CODE_128: { // CODE 128 + $arrcode = $this->barcode_c128($code, ''); + break; + } + case self::TYPE_CODE_128_A: { // CODE 128 A + $arrcode = $this->barcode_c128($code, 'A'); + break; + } + case self::TYPE_CODE_128_B: { // CODE 128 B + $arrcode = $this->barcode_c128($code, 'B'); + break; + } + case self::TYPE_CODE_128_C: { // CODE 128 C + $arrcode = $this->barcode_c128($code, 'C'); + break; + } + case self::TYPE_EAN_2: { // 2-Digits UPC-Based Extention + $arrcode = $this->barcode_eanext($code, 2); + break; + } + case self::TYPE_EAN_5: { // 5-Digits UPC-Based Extention + $arrcode = $this->barcode_eanext($code, 5); + break; + } + case self::TYPE_EAN_8: { // EAN 8 + $arrcode = $this->barcode_eanupc($code, 8); + break; + } + case self::TYPE_EAN_13: { // EAN 13 + $arrcode = $this->barcode_eanupc($code, 13); + break; + } + case self::TYPE_UPC_A: { // UPC-A + $arrcode = $this->barcode_eanupc($code, 12); + break; + } + case self::TYPE_UPC_E: { // UPC-E + $arrcode = $this->barcode_eanupc($code, 6); + break; + } + case self::TYPE_MSI: { // MSI (Variation of Plessey code) + $arrcode = $this->barcode_msi($code, false); + break; + } + case self::TYPE_MSI_CHECKSUM: { // MSI + CHECKSUM (modulo 11) + $arrcode = $this->barcode_msi($code, true); + break; + } + case self::TYPE_POSTNET: { // POSTNET + $arrcode = $this->barcode_postnet($code, false); + break; + } + case self::TYPE_PLANET: { // PLANET + $arrcode = $this->barcode_postnet($code, true); + break; + } + case self::TYPE_RMS4CC: { // RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code) + $arrcode = $this->barcode_rms4cc($code, false); + break; + } + case self::TYPE_KIX: { // KIX (Klant index - Customer index) + $arrcode = $this->barcode_rms4cc($code, true); + break; + } + case self::TYPE_IMB: { // IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200 + $arrcode = $this->barcode_imb($code); + break; + } + case self::TYPE_CODABAR: { // CODABAR + $arrcode = $this->barcode_codabar($code); + break; + } + case self::TYPE_CODE_11: { // CODE 11 + $arrcode = $this->barcode_code11($code); + break; + } + case self::TYPE_PHARMA_CODE: { // PHARMACODE + $arrcode = $this->barcode_pharmacode($code); + break; + } + case self::TYPE_PHARMA_CODE_TWO_TRACKS: { // PHARMACODE TWO-TRACKS + $arrcode = $this->barcode_pharmacode2t($code); + break; + } + default: { + $arrcode = false; + break; + } + } + + $arrcode = $this->convertBarcodeArrayToNewStyle($arrcode); + + return $arrcode; + } + + /** + * CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9. + * General-purpose code in very wide use world-wide + * + * @param $code (string) code to represent. + * @param $extended (boolean) if true uses the extended mode. + * @param $checksum (boolean) if true add a checksum to the code. + * @return array barcode representation. + * @protected + */ + protected function barcode_code39($code, $extended = false, $checksum = false) + { + $chr = []; + $chr['0'] = '111331311'; + $chr['1'] = '311311113'; + $chr['2'] = '113311113'; + $chr['3'] = '313311111'; + $chr['4'] = '111331113'; + $chr['5'] = '311331111'; + $chr['6'] = '113331111'; + $chr['7'] = '111311313'; + $chr['8'] = '311311311'; + $chr['9'] = '113311311'; + $chr['A'] = '311113113'; + $chr['B'] = '113113113'; + $chr['C'] = '313113111'; + $chr['D'] = '111133113'; + $chr['E'] = '311133111'; + $chr['F'] = '113133111'; + $chr['G'] = '111113313'; + $chr['H'] = '311113311'; + $chr['I'] = '113113311'; + $chr['J'] = '111133311'; + $chr['K'] = '311111133'; + $chr['L'] = '113111133'; + $chr['M'] = '313111131'; + $chr['N'] = '111131133'; + $chr['O'] = '311131131'; + $chr['P'] = '113131131'; + $chr['Q'] = '111111333'; + $chr['R'] = '311111331'; + $chr['S'] = '113111331'; + $chr['T'] = '111131331'; + $chr['U'] = '331111113'; + $chr['V'] = '133111113'; + $chr['W'] = '333111111'; + $chr['X'] = '131131113'; + $chr['Y'] = '331131111'; + $chr['Z'] = '133131111'; + $chr['-'] = '131111313'; + $chr['.'] = '331111311'; + $chr[' '] = '133111311'; + $chr['$'] = '131313111'; + $chr['/'] = '131311131'; + $chr['+'] = '131113131'; + $chr['%'] = '111313131'; + $chr['*'] = '131131311'; + + $code = strtoupper($code); + + if ($extended) { + // extended mode + $code = $this->encode_code39_ext($code); + } + + if ($code === false) { + return false; + } + + if ($checksum) { + // checksum + $code .= $this->checksum_code39($code); + } + + // add start and stop codes + $code = '*' . $code . '*'; + + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + $k = 0; + $clen = strlen($code); + for ($i = 0; $i < $clen; ++$i) { + $char = $code{$i}; + if ( ! isset($chr[$char])) { + // invalid character + return false; + } + for ($j = 0; $j < 9; ++$j) { + if (($j % 2) == 0) { + $t = true; // bar + } else { + $t = false; // space + } + $w = $chr[$char]{$j}; + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); + $bararray['maxw'] += $w; + ++$k; + } + // intercharacter gap + $bararray['bcode'][$k] = array('t' => false, 'w' => 1, 'h' => 1, 'p' => 0); + $bararray['maxw'] += 1; + ++$k; + } + + return $bararray; + } + + /** + * Encode a string to be used for CODE 39 Extended mode. + * + * @param string $code code to represent. + * @return bool|string encoded string. + * @protected + */ + protected function encode_code39_ext($code) + { + $encode = array( + chr(0) => '%U', + chr(1) => '$A', + chr(2) => '$B', + chr(3) => '$C', + chr(4) => '$D', + chr(5) => '$E', + chr(6) => '$F', + chr(7) => '$G', + chr(8) => '$H', + chr(9) => '$I', + chr(10) => '$J', + chr(11) => '£K', + chr(12) => '$L', + chr(13) => '$M', + chr(14) => '$N', + chr(15) => '$O', + chr(16) => '$P', + chr(17) => '$Q', + chr(18) => '$R', + chr(19) => '$S', + chr(20) => '$T', + chr(21) => '$U', + chr(22) => '$V', + chr(23) => '$W', + chr(24) => '$X', + chr(25) => '$Y', + chr(26) => '$Z', + chr(27) => '%A', + chr(28) => '%B', + chr(29) => '%C', + chr(30) => '%D', + chr(31) => '%E', + chr(32) => ' ', + chr(33) => '/A', + chr(34) => '/B', + chr(35) => '/C', + chr(36) => '/D', + chr(37) => '/E', + chr(38) => '/F', + chr(39) => '/G', + chr(40) => '/H', + chr(41) => '/I', + chr(42) => '/J', + chr(43) => '/K', + chr(44) => '/L', + chr(45) => '-', + chr(46) => '.', + chr(47) => '/O', + chr(48) => '0', + chr(49) => '1', + chr(50) => '2', + chr(51) => '3', + chr(52) => '4', + chr(53) => '5', + chr(54) => '6', + chr(55) => '7', + chr(56) => '8', + chr(57) => '9', + chr(58) => '/Z', + chr(59) => '%F', + chr(60) => '%G', + chr(61) => '%H', + chr(62) => '%I', + chr(63) => '%J', + chr(64) => '%V', + chr(65) => 'A', + chr(66) => 'B', + chr(67) => 'C', + chr(68) => 'D', + chr(69) => 'E', + chr(70) => 'F', + chr(71) => 'G', + chr(72) => 'H', + chr(73) => 'I', + chr(74) => 'J', + chr(75) => 'K', + chr(76) => 'L', + chr(77) => 'M', + chr(78) => 'N', + chr(79) => 'O', + chr(80) => 'P', + chr(81) => 'Q', + chr(82) => 'R', + chr(83) => 'S', + chr(84) => 'T', + chr(85) => 'U', + chr(86) => 'V', + chr(87) => 'W', + chr(88) => 'X', + chr(89) => 'Y', + chr(90) => 'Z', + chr(91) => '%K', + chr(92) => '%L', + chr(93) => '%M', + chr(94) => '%N', + chr(95) => '%O', + chr(96) => '%W', + chr(97) => '+A', + chr(98) => '+B', + chr(99) => '+C', + chr(100) => '+D', + chr(101) => '+E', + chr(102) => '+F', + chr(103) => '+G', + chr(104) => '+H', + chr(105) => '+I', + chr(106) => '+J', + chr(107) => '+K', + chr(108) => '+L', + chr(109) => '+M', + chr(110) => '+N', + chr(111) => '+O', + chr(112) => '+P', + chr(113) => '+Q', + chr(114) => '+R', + chr(115) => '+S', + chr(116) => '+T', + chr(117) => '+U', + chr(118) => '+V', + chr(119) => '+W', + chr(120) => '+X', + chr(121) => '+Y', + chr(122) => '+Z', + chr(123) => '%P', + chr(124) => '%Q', + chr(125) => '%R', + chr(126) => '%S', + chr(127) => '%T' + ); + $code_ext = ''; + $clen = strlen($code); + for ($i = 0; $i < $clen; ++$i) { + if (ord($code{$i}) > 127) { + return false; + } + $code_ext .= $encode[$code{$i}]; + } + + return $code_ext; + } + + /** + * Calculate CODE 39 checksum (modulo 43). + * + * @param string $code code to represent. + * @return string char checksum. + * @protected + */ + protected function checksum_code39($code) + { + $chars = array( + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + '-', + '.', + ' ', + '$', + '/', + '+', + '%' + ); + $sum = 0; + $clen = strlen($code); + for ($i = 0; $i < $clen; ++$i) { + $k = array_keys($chars, $code{$i}); + $sum += $k[0]; + } + $j = ($sum % 43); + + return $chars[$j]; + } + + /** + * CODE 93 - USS-93 + * Compact code similar to Code 39 + * + * @param $code (string) code to represent. + * @return array barcode representation. + * @protected + */ + protected function barcode_code93($code) + { + $chr = []; + $chr[48] = '131112'; // 0 + $chr[49] = '111213'; // 1 + $chr[50] = '111312'; // 2 + $chr[51] = '111411'; // 3 + $chr[52] = '121113'; // 4 + $chr[53] = '121212'; // 5 + $chr[54] = '121311'; // 6 + $chr[55] = '111114'; // 7 + $chr[56] = '131211'; // 8 + $chr[57] = '141111'; // 9 + $chr[65] = '211113'; // A + $chr[66] = '211212'; // B + $chr[67] = '211311'; // C + $chr[68] = '221112'; // D + $chr[69] = '221211'; // E + $chr[70] = '231111'; // F + $chr[71] = '112113'; // G + $chr[72] = '112212'; // H + $chr[73] = '112311'; // I + $chr[74] = '122112'; // J + $chr[75] = '132111'; // K + $chr[76] = '111123'; // L + $chr[77] = '111222'; // M + $chr[78] = '111321'; // N + $chr[79] = '121122'; // O + $chr[80] = '131121'; // P + $chr[81] = '212112'; // Q + $chr[82] = '212211'; // R + $chr[83] = '211122'; // S + $chr[84] = '211221'; // T + $chr[85] = '221121'; // U + $chr[86] = '222111'; // V + $chr[87] = '112122'; // W + $chr[88] = '112221'; // X + $chr[89] = '122121'; // Y + $chr[90] = '123111'; // Z + $chr[45] = '121131'; // - + $chr[46] = '311112'; // . + $chr[32] = '311211'; // + $chr[36] = '321111'; // $ + $chr[47] = '112131'; // / + $chr[43] = '113121'; // + + $chr[37] = '211131'; // % + $chr[128] = '121221'; // ($) + $chr[129] = '311121'; // (/) + $chr[130] = '122211'; // (+) + $chr[131] = '312111'; // (%) + $chr[42] = '111141'; // start-stop + $code = strtoupper($code); + $encode = array( + chr(0) => chr(131) . 'U', + chr(1) => chr(128) . 'A', + chr(2) => chr(128) . 'B', + chr(3) => chr(128) . 'C', + chr(4) => chr(128) . 'D', + chr(5) => chr(128) . 'E', + chr(6) => chr(128) . 'F', + chr(7) => chr(128) . 'G', + chr(8) => chr(128) . 'H', + chr(9) => chr(128) . 'I', + chr(10) => chr(128) . 'J', + chr(11) => '£K', + chr(12) => chr(128) . 'L', + chr(13) => chr(128) . 'M', + chr(14) => chr(128) . 'N', + chr(15) => chr(128) . 'O', + chr(16) => chr(128) . 'P', + chr(17) => chr(128) . 'Q', + chr(18) => chr(128) . 'R', + chr(19) => chr(128) . 'S', + chr(20) => chr(128) . 'T', + chr(21) => chr(128) . 'U', + chr(22) => chr(128) . 'V', + chr(23) => chr(128) . 'W', + chr(24) => chr(128) . 'X', + chr(25) => chr(128) . 'Y', + chr(26) => chr(128) . 'Z', + chr(27) => chr(131) . 'A', + chr(28) => chr(131) . 'B', + chr(29) => chr(131) . 'C', + chr(30) => chr(131) . 'D', + chr(31) => chr(131) . 'E', + chr(32) => ' ', + chr(33) => chr(129) . 'A', + chr(34) => chr(129) . 'B', + chr(35) => chr(129) . 'C', + chr(36) => chr(129) . 'D', + chr(37) => chr(129) . 'E', + chr(38) => chr(129) . 'F', + chr(39) => chr(129) . 'G', + chr(40) => chr(129) . 'H', + chr(41) => chr(129) . 'I', + chr(42) => chr(129) . 'J', + chr(43) => chr(129) . 'K', + chr(44) => chr(129) . 'L', + chr(45) => '-', + chr(46) => '.', + chr(47) => chr(129) . 'O', + chr(48) => '0', + chr(49) => '1', + chr(50) => '2', + chr(51) => '3', + chr(52) => '4', + chr(53) => '5', + chr(54) => '6', + chr(55) => '7', + chr(56) => '8', + chr(57) => '9', + chr(58) => chr(129) . 'Z', + chr(59) => chr(131) . 'F', + chr(60) => chr(131) . 'G', + chr(61) => chr(131) . 'H', + chr(62) => chr(131) . 'I', + chr(63) => chr(131) . 'J', + chr(64) => chr(131) . 'V', + chr(65) => 'A', + chr(66) => 'B', + chr(67) => 'C', + chr(68) => 'D', + chr(69) => 'E', + chr(70) => 'F', + chr(71) => 'G', + chr(72) => 'H', + chr(73) => 'I', + chr(74) => 'J', + chr(75) => 'K', + chr(76) => 'L', + chr(77) => 'M', + chr(78) => 'N', + chr(79) => 'O', + chr(80) => 'P', + chr(81) => 'Q', + chr(82) => 'R', + chr(83) => 'S', + chr(84) => 'T', + chr(85) => 'U', + chr(86) => 'V', + chr(87) => 'W', + chr(88) => 'X', + chr(89) => 'Y', + chr(90) => 'Z', + chr(91) => chr(131) . 'K', + chr(92) => chr(131) . 'L', + chr(93) => chr(131) . 'M', + chr(94) => chr(131) . 'N', + chr(95) => chr(131) . 'O', + chr(96) => chr(131) . 'W', + chr(97) => chr(130) . 'A', + chr(98) => chr(130) . 'B', + chr(99) => chr(130) . 'C', + chr(100) => chr(130) . 'D', + chr(101) => chr(130) . 'E', + chr(102) => chr(130) . 'F', + chr(103) => chr(130) . 'G', + chr(104) => chr(130) . 'H', + chr(105) => chr(130) . 'I', + chr(106) => chr(130) . 'J', + chr(107) => chr(130) . 'K', + chr(108) => chr(130) . 'L', + chr(109) => chr(130) . 'M', + chr(110) => chr(130) . 'N', + chr(111) => chr(130) . 'O', + chr(112) => chr(130) . 'P', + chr(113) => chr(130) . 'Q', + chr(114) => chr(130) . 'R', + chr(115) => chr(130) . 'S', + chr(116) => chr(130) . 'T', + chr(117) => chr(130) . 'U', + chr(118) => chr(130) . 'V', + chr(119) => chr(130) . 'W', + chr(120) => chr(130) . 'X', + chr(121) => chr(130) . 'Y', + chr(122) => chr(130) . 'Z', + chr(123) => chr(131) . 'P', + chr(124) => chr(131) . 'Q', + chr(125) => chr(131) . 'R', + chr(126) => chr(131) . 'S', + chr(127) => chr(131) . 'T' + ); + $code_ext = ''; + $clen = strlen($code); + for ($i = 0; $i < $clen; ++$i) { + if (ord($code{$i}) > 127) { + return false; + } + $code_ext .= $encode[$code{$i}]; + } + // checksum + $code_ext .= $this->checksum_code93($code_ext); + // add start and stop codes + $code = '*' . $code_ext . '*'; + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + $k = 0; + $clen = strlen($code); + for ($i = 0; $i < $clen; ++$i) { + $char = ord($code{$i}); + if ( ! isset($chr[$char])) { + // invalid character + return false; + } + for ($j = 0; $j < 6; ++$j) { + if (($j % 2) == 0) { + $t = true; // bar + } else { + $t = false; // space + } + $w = $chr[$char]{$j}; + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); + $bararray['maxw'] += $w; + ++$k; + } + } + $bararray['bcode'][$k] = array('t' => true, 'w' => 1, 'h' => 1, 'p' => 0); + $bararray['maxw'] += 1; + + return $bararray; + } + + /** + * Calculate CODE 93 checksum (modulo 47). + * + * @param $code (string) code to represent. + * @return string checksum code. + * @protected + */ + protected function checksum_code93($code) + { + $chars = array( + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + '-', + '.', + ' ', + '$', + '/', + '+', + '%', + '<', + '=', + '>', + '?' + ); + // translate special characters + $code = strtr($code, chr(128) . chr(131) . chr(129) . chr(130), '<=>?'); + $len = strlen($code); + // calculate check digit C + $p = 1; + $check = 0; + for ($i = ($len - 1); $i >= 0; --$i) { + $k = array_keys($chars, $code{$i}); + $check += ($k[0] * $p); + ++$p; + if ($p > 20) { + $p = 1; + } + } + $check %= 47; + $c = $chars[$check]; + $code .= $c; + // calculate check digit K + $p = 1; + $check = 0; + for ($i = $len; $i >= 0; --$i) { + $k = array_keys($chars, $code{$i}); + $check += ($k[0] * $p); + ++$p; + if ($p > 15) { + $p = 1; + } + } + $check %= 47; + $k = $chars[$check]; + $checksum = $c . $k; + // resto respecial characters + $checksum = strtr($checksum, '<=>?', chr(128) . chr(131) . chr(129) . chr(130)); + + return $checksum; + } + + /** + * Checksum for standard 2 of 5 barcodes. + * + * @param $code (string) code to process. + * @return int checksum. + * @protected + */ + protected function checksum_s25($code) + { + $len = strlen($code); + $sum = 0; + for ($i = 0; $i < $len; $i += 2) { + $sum += $code{$i}; + } + $sum *= 3; + for ($i = 1; $i < $len; $i += 2) { + $sum += ($code{$i}); + } + $r = $sum % 10; + if ($r > 0) { + $r = (10 - $r); + } + + return $r; + } + + /** + * MSI. + * Variation of Plessey code, with similar applications + * Contains digits (0 to 9) and encodes the data only in the width of bars. + * + * @param $code (string) code to represent. + * @param $checksum (boolean) if true add a checksum to the code (modulo 11) + * @return array barcode representation. + * @protected + */ + protected function barcode_msi($code, $checksum = false) + { + $chr['0'] = '100100100100'; + $chr['1'] = '100100100110'; + $chr['2'] = '100100110100'; + $chr['3'] = '100100110110'; + $chr['4'] = '100110100100'; + $chr['5'] = '100110100110'; + $chr['6'] = '100110110100'; + $chr['7'] = '100110110110'; + $chr['8'] = '110100100100'; + $chr['9'] = '110100100110'; + $chr['A'] = '110100110100'; + $chr['B'] = '110100110110'; + $chr['C'] = '110110100100'; + $chr['D'] = '110110100110'; + $chr['E'] = '110110110100'; + $chr['F'] = '110110110110'; + if ($checksum) { + // add checksum + $clen = strlen($code); + $p = 2; + $check = 0; + for ($i = ($clen - 1); $i >= 0; --$i) { + $check += (hexdec($code{$i}) * $p); + ++$p; + if ($p > 7) { + $p = 2; + } + } + $check %= 11; + if ($check > 0) { + $check = 11 - $check; + } + $code .= $check; + } + $seq = '110'; // left guard + $clen = strlen($code); + for ($i = 0; $i < $clen; ++$i) { + $digit = $code{$i}; + if ( ! isset($chr[$digit])) { + // invalid character + return false; + } + $seq .= $chr[$digit]; + } + $seq .= '1001'; // right guard + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + + return $this->binseq_to_array($seq, $bararray); + } + + /** + * Standard 2 of 5 barcodes. + * Used in airline ticket marking, photofinishing + * Contains digits (0 to 9) and encodes the data only in the width of bars. + * + * @param $code (string) code to represent. + * @param $checksum (boolean) if true add a checksum to the code + * @return array barcode representation. + * @protected + */ + protected function barcode_s25($code, $checksum = false) + { + $chr['0'] = '10101110111010'; + $chr['1'] = '11101010101110'; + $chr['2'] = '10111010101110'; + $chr['3'] = '11101110101010'; + $chr['4'] = '10101110101110'; + $chr['5'] = '11101011101010'; + $chr['6'] = '10111011101010'; + $chr['7'] = '10101011101110'; + $chr['8'] = '10101110111010'; + $chr['9'] = '10111010111010'; + if ($checksum) { + // add checksum + $code .= $this->checksum_s25($code); + } + if ((strlen($code) % 2) != 0) { + // add leading zero if code-length is odd + $code = '0' . $code; + } + $seq = '11011010'; + $clen = strlen($code); + for ($i = 0; $i < $clen; ++$i) { + $digit = $code{$i}; + if ( ! isset($chr[$digit])) { + // invalid character + return false; + } + $seq .= $chr[$digit]; + } + $seq .= '1101011'; + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + + return $this->binseq_to_array($seq, $bararray); + } + + /** + * Convert binary barcode sequence to TCPDF barcode array. + * + * @param $seq (string) barcode as binary sequence. + * @param $bararray (array) barcode array. + * òparam array $bararray TCPDF barcode array to fill up + * @return array barcode representation. + * @protected + */ + protected function binseq_to_array($seq, $bararray) + { + $len = strlen($seq); + $w = 0; + $k = 0; + for ($i = 0; $i < $len; ++$i) { + $w += 1; + if (($i == ($len - 1)) OR (($i < ($len - 1)) AND ($seq{$i} != $seq{($i + 1)}))) { + if ($seq{$i} == '1') { + $t = true; // bar + } else { + $t = false; // space + } + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); + $bararray['maxw'] += $w; + ++$k; + $w = 0; + } + } + + return $bararray; + } + + /** + * Interleaved 2 of 5 barcodes. + * Compact numeric code, widely used in industry, air cargo + * Contains digits (0 to 9) and encodes the data in the width of both bars and spaces. + * + * @param $code (string) code to represent. + * @param $checksum (boolean) if true add a checksum to the code + * @return array barcode representation. + * @protected + */ + protected function barcode_i25($code, $checksum = false) + { + $chr['0'] = '11221'; + $chr['1'] = '21112'; + $chr['2'] = '12112'; + $chr['3'] = '22111'; + $chr['4'] = '11212'; + $chr['5'] = '21211'; + $chr['6'] = '12211'; + $chr['7'] = '11122'; + $chr['8'] = '21121'; + $chr['9'] = '12121'; + $chr['A'] = '11'; + $chr['Z'] = '21'; + if ($checksum) { + // add checksum + $code .= $this->checksum_s25($code); + } + if ((strlen($code) % 2) != 0) { + // add leading zero if code-length is odd + $code = '0' . $code; + } + // add start and stop codes + $code = 'AA' . strtolower($code) . 'ZA'; + + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + $k = 0; + $clen = strlen($code); + for ($i = 0; $i < $clen; $i = ($i + 2)) { + $char_bar = $code{$i}; + $char_space = $code{$i + 1}; + if (( ! isset($chr[$char_bar])) OR ( ! isset($chr[$char_space]))) { + // invalid character + return false; + } + // create a bar-space sequence + $seq = ''; + $chrlen = strlen($chr[$char_bar]); + for ($s = 0; $s < $chrlen; $s++) { + $seq .= $chr[$char_bar]{$s} . $chr[$char_space]{$s}; + } + $seqlen = strlen($seq); + for ($j = 0; $j < $seqlen; ++$j) { + if (($j % 2) == 0) { + $t = true; // bar + } else { + $t = false; // space + } + $w = $seq{$j}; + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); + $bararray['maxw'] += $w; + ++$k; + } + } + + return $bararray; + } + + /** + * C128 barcodes. + * Very capable code, excellent density, high reliability; in very wide use world-wide + * + * @param $code (string) code to represent. + * @param $type (string) barcode type: A, B, C or empty for automatic switch (AUTO mode) + * @return array barcode representation. + * @protected + */ + protected function barcode_c128($code, $type = '') + { + $chr = array( + '212222', /* 00 */ + '222122', /* 01 */ + '222221', /* 02 */ + '121223', /* 03 */ + '121322', /* 04 */ + '131222', /* 05 */ + '122213', /* 06 */ + '122312', /* 07 */ + '132212', /* 08 */ + '221213', /* 09 */ + '221312', /* 10 */ + '231212', /* 11 */ + '112232', /* 12 */ + '122132', /* 13 */ + '122231', /* 14 */ + '113222', /* 15 */ + '123122', /* 16 */ + '123221', /* 17 */ + '223211', /* 18 */ + '221132', /* 19 */ + '221231', /* 20 */ + '213212', /* 21 */ + '223112', /* 22 */ + '312131', /* 23 */ + '311222', /* 24 */ + '321122', /* 25 */ + '321221', /* 26 */ + '312212', /* 27 */ + '322112', /* 28 */ + '322211', /* 29 */ + '212123', /* 30 */ + '212321', /* 31 */ + '232121', /* 32 */ + '111323', /* 33 */ + '131123', /* 34 */ + '131321', /* 35 */ + '112313', /* 36 */ + '132113', /* 37 */ + '132311', /* 38 */ + '211313', /* 39 */ + '231113', /* 40 */ + '231311', /* 41 */ + '112133', /* 42 */ + '112331', /* 43 */ + '132131', /* 44 */ + '113123', /* 45 */ + '113321', /* 46 */ + '133121', /* 47 */ + '313121', /* 48 */ + '211331', /* 49 */ + '231131', /* 50 */ + '213113', /* 51 */ + '213311', /* 52 */ + '213131', /* 53 */ + '311123', /* 54 */ + '311321', /* 55 */ + '331121', /* 56 */ + '312113', /* 57 */ + '312311', /* 58 */ + '332111', /* 59 */ + '314111', /* 60 */ + '221411', /* 61 */ + '431111', /* 62 */ + '111224', /* 63 */ + '111422', /* 64 */ + '121124', /* 65 */ + '121421', /* 66 */ + '141122', /* 67 */ + '141221', /* 68 */ + '112214', /* 69 */ + '112412', /* 70 */ + '122114', /* 71 */ + '122411', /* 72 */ + '142112', /* 73 */ + '142211', /* 74 */ + '241211', /* 75 */ + '221114', /* 76 */ + '413111', /* 77 */ + '241112', /* 78 */ + '134111', /* 79 */ + '111242', /* 80 */ + '121142', /* 81 */ + '121241', /* 82 */ + '114212', /* 83 */ + '124112', /* 84 */ + '124211', /* 85 */ + '411212', /* 86 */ + '421112', /* 87 */ + '421211', /* 88 */ + '212141', /* 89 */ + '214121', /* 90 */ + '412121', /* 91 */ + '111143', /* 92 */ + '111341', /* 93 */ + '131141', /* 94 */ + '114113', /* 95 */ + '114311', /* 96 */ + '411113', /* 97 */ + '411311', /* 98 */ + '113141', /* 99 */ + '114131', /* 100 */ + '311141', /* 101 */ + '411131', /* 102 */ + '211412', /* 103 START A */ + '211214', /* 104 START B */ + '211232', /* 105 START C */ + '233111', /* STOP */ + '200000' /* END */ + ); + // ASCII characters for code A (ASCII 00 - 95) + $keys_a = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_'; + $keys_a .= chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5) . chr(6) . chr(7) . chr(8) . chr(9); + $keys_a .= chr(10) . chr(11) . chr(12) . chr(13) . chr(14) . chr(15) . chr(16) . chr(17) . chr(18) . chr(19); + $keys_a .= chr(20) . chr(21) . chr(22) . chr(23) . chr(24) . chr(25) . chr(26) . chr(27) . chr(28) . chr(29); + $keys_a .= chr(30) . chr(31); + // ASCII characters for code B (ASCII 32 - 127) + $keys_b = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~' . chr(127); + // special codes + $fnc_a = array(241 => 102, 242 => 97, 243 => 96, 244 => 101); + $fnc_b = array(241 => 102, 242 => 97, 243 => 96, 244 => 100); + // array of symbols + $code_data = array(); + // length of the code + $len = strlen($code); + switch (strtoupper($type)) { + case 'A': { // MODE A + $startid = 103; + for ($i = 0; $i < $len; ++$i) { + $char = $code{$i}; + $char_id = ord($char); + if (($char_id >= 241) AND ($char_id <= 244)) { + $code_data[] = $fnc_a[$char_id]; + } elseif (($char_id >= 0) AND ($char_id <= 95)) { + $code_data[] = strpos($keys_a, $char); + } else { + return false; + } + } + break; + } + case 'B': { // MODE B + $startid = 104; + for ($i = 0; $i < $len; ++$i) { + $char = $code{$i}; + $char_id = ord($char); + if (($char_id >= 241) AND ($char_id <= 244)) { + $code_data[] = $fnc_b[$char_id]; + } elseif (($char_id >= 32) AND ($char_id <= 127)) { + $code_data[] = strpos($keys_b, $char); + } else { + return false; + } + } + break; + } + case 'C': { // MODE C + $startid = 105; + if (ord($code[0]) == 241) { + $code_data[] = 102; + $code = substr($code, 1); + --$len; + } + if (($len % 2) != 0) { + // the length must be even + return false; + } + for ($i = 0; $i < $len; $i += 2) { + $chrnum = $code{$i} . $code{$i + 1}; + if (preg_match('/([0-9]{2})/', $chrnum) > 0) { + $code_data[] = intval($chrnum); + } else { + return false; + } + } + break; + } + default: { // MODE AUTO + // split code into sequences + $sequence = array(); + // get numeric sequences (if any) + $numseq = array(); + preg_match_all('/([0-9]{4,})/', $code, $numseq, PREG_OFFSET_CAPTURE); + if (isset($numseq[1]) AND ! empty($numseq[1])) { + $end_offset = 0; + foreach ($numseq[1] as $val) { + $offset = $val[1]; + if ($offset > $end_offset) { + // non numeric sequence + $sequence = array_merge($sequence, + $this->get128ABsequence(substr($code, $end_offset, ($offset - $end_offset)))); + } + // numeric sequence + $slen = strlen($val[0]); + if (($slen % 2) != 0) { + // the length must be even + --$slen; + } + $sequence[] = array('C', substr($code, $offset, $slen), $slen); + $end_offset = $offset + $slen; + } + if ($end_offset < $len) { + $sequence = array_merge($sequence, $this->get128ABsequence(substr($code, $end_offset))); + } + } else { + // text code (non C mode) + $sequence = array_merge($sequence, $this->get128ABsequence($code)); + } + // process the sequence + foreach ($sequence as $key => $seq) { + switch ($seq[0]) { + case 'A': { + if ($key == 0) { + $startid = 103; + } elseif ($sequence[($key - 1)][0] != 'A') { + if (($seq[2] == 1) AND ($key > 0) AND ($sequence[($key - 1)][0] == 'B') AND ( ! isset($sequence[($key - 1)][3]))) { + // single character shift + $code_data[] = 98; + // mark shift + $sequence[$key][3] = true; + } elseif ( ! isset($sequence[($key - 1)][3])) { + $code_data[] = 101; + } + } + for ($i = 0; $i < $seq[2]; ++$i) { + $char = $seq[1]{$i}; + $char_id = ord($char); + if (($char_id >= 241) AND ($char_id <= 244)) { + $code_data[] = $fnc_a[$char_id]; + } else { + $code_data[] = strpos($keys_a, $char); + } + } + break; + } + case 'B': { + if ($key == 0) { + $tmpchr = ord($seq[1][0]); + if (($seq[2] == 1) AND ($tmpchr >= 241) AND ($tmpchr <= 244) AND isset($sequence[($key + 1)]) AND ($sequence[($key + 1)][0] != 'B')) { + switch ($sequence[($key + 1)][0]) { + case 'A': { + $startid = 103; + $sequence[$key][0] = 'A'; + $code_data[] = $fnc_a[$tmpchr]; + break; + } + case 'C': { + $startid = 105; + $sequence[$key][0] = 'C'; + $code_data[] = $fnc_a[$tmpchr]; + break; + } + } + break; + } else { + $startid = 104; + } + } elseif ($sequence[($key - 1)][0] != 'B') { + if (($seq[2] == 1) AND ($key > 0) AND ($sequence[($key - 1)][0] == 'A') AND ( ! isset($sequence[($key - 1)][3]))) { + // single character shift + $code_data[] = 98; + // mark shift + $sequence[$key][3] = true; + } elseif ( ! isset($sequence[($key - 1)][3])) { + $code_data[] = 100; + } + } + for ($i = 0; $i < $seq[2]; ++$i) { + $char = $seq[1]{$i}; + $char_id = ord($char); + if (($char_id >= 241) AND ($char_id <= 244)) { + $code_data[] = $fnc_b[$char_id]; + } else { + $code_data[] = strpos($keys_b, $char); + } + } + break; + } + case 'C': { + if ($key == 0) { + $startid = 105; + } elseif ($sequence[($key - 1)][0] != 'C') { + $code_data[] = 99; + } + for ($i = 0; $i < $seq[2]; $i += 2) { + $chrnum = $seq[1]{$i} . $seq[1]{$i + 1}; + $code_data[] = intval($chrnum); + } + break; + } + } + } + } + } + // calculate check character + $sum = $startid; + foreach ($code_data as $key => $val) { + $sum += ($val * ($key + 1)); + } + // add check character + $code_data[] = ($sum % 103); + // add stop sequence + $code_data[] = 106; + $code_data[] = 107; + // add start code at the beginning + array_unshift($code_data, $startid); + // build barcode array + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + foreach ($code_data as $val) { + $seq = $chr[$val]; + for ($j = 0; $j < 6; ++$j) { + if (($j % 2) == 0) { + $t = true; // bar + } else { + $t = false; // space + } + $w = $seq{$j}; + $bararray['bcode'][] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); + $bararray['maxw'] += $w; + } + } + + return $bararray; + } + + /** + * Split text code in A/B sequence for 128 code + * + * @param $code (string) code to split. + * @return array sequence + * @protected + */ + protected function get128ABsequence($code) + { + $len = strlen($code); + $sequence = array(); + // get A sequences (if any) + $numseq = array(); + preg_match_all('/([\0-\31])/', $code, $numseq, PREG_OFFSET_CAPTURE); + if (isset($numseq[1]) AND ! empty($numseq[1])) { + $end_offset = 0; + foreach ($numseq[1] as $val) { + $offset = $val[1]; + if ($offset > $end_offset) { + // B sequence + $sequence[] = array( + 'B', + substr($code, $end_offset, ($offset - $end_offset)), + ($offset - $end_offset) + ); + } + // A sequence + $slen = strlen($val[0]); + $sequence[] = array('A', substr($code, $offset, $slen), $slen); + $end_offset = $offset + $slen; + } + if ($end_offset < $len) { + $sequence[] = array('B', substr($code, $end_offset), ($len - $end_offset)); + } + } else { + // only B sequence + $sequence[] = array('B', $code, $len); + } + + return $sequence; + } + + /** + * EAN13 and UPC-A barcodes. + * EAN13: European Article Numbering international retail product code + * UPC-A: Universal product code seen on almost all retail products in the USA and Canada + * UPC-E: Short version of UPC symbol + * + * @param $code (string) code to represent. + * @param $len (string) barcode type: 6 = UPC-E, 8 = EAN8, 13 = EAN13, 12 = UPC-A + * @return array barcode representation. + * @protected + */ + protected function barcode_eanupc($code, $len = 13) + { + $upce = false; + if ($len == 6) { + $len = 12; // UPC-A + $upce = true; // UPC-E mode + } + $data_len = $len - 1; + //Padding + $code = str_pad($code, $data_len, '0', STR_PAD_LEFT); + $code_len = strlen($code); + // calculate check digit + $sum_a = 0; + for ($i = 1; $i < $data_len; $i += 2) { + $sum_a += $code{$i}; + } + if ($len > 12) { + $sum_a *= 3; + } + $sum_b = 0; + for ($i = 0; $i < $data_len; $i += 2) { + $sum_b += ($code{$i}); + } + if ($len < 13) { + $sum_b *= 3; + } + $r = ($sum_a + $sum_b) % 10; + if ($r > 0) { + $r = (10 - $r); + } + if ($code_len == $data_len) { + // add check digit + $code .= $r; + } elseif ($r !== intval($code{$data_len})) { + // wrong checkdigit + return false; + } + if ($len == 12) { + // UPC-A + $code = '0' . $code; + ++$len; + } + if ($upce) { + // convert UPC-A to UPC-E + $tmp = substr($code, 4, 3); + if (($tmp == '000') OR ($tmp == '100') OR ($tmp == '200')) { + // manufacturer code ends in 000, 100, or 200 + $upce_code = substr($code, 2, 2) . substr($code, 9, 3) . substr($code, 4, 1); + } else { + $tmp = substr($code, 5, 2); + if ($tmp == '00') { + // manufacturer code ends in 00 + $upce_code = substr($code, 2, 3) . substr($code, 10, 2) . '3'; + } else { + $tmp = substr($code, 6, 1); + if ($tmp == '0') { + // manufacturer code ends in 0 + $upce_code = substr($code, 2, 4) . substr($code, 11, 1) . '4'; + } else { + // manufacturer code does not end in zero + $upce_code = substr($code, 2, 5) . substr($code, 11, 1); + } + } + } + } + //Convert digits to bars + $codes = array( + 'A' => array( // left odd parity + '0' => '0001101', + '1' => '0011001', + '2' => '0010011', + '3' => '0111101', + '4' => '0100011', + '5' => '0110001', + '6' => '0101111', + '7' => '0111011', + '8' => '0110111', + '9' => '0001011' + ), + 'B' => array( // left even parity + '0' => '0100111', + '1' => '0110011', + '2' => '0011011', + '3' => '0100001', + '4' => '0011101', + '5' => '0111001', + '6' => '0000101', + '7' => '0010001', + '8' => '0001001', + '9' => '0010111' + ), + 'C' => array( // right + '0' => '1110010', + '1' => '1100110', + '2' => '1101100', + '3' => '1000010', + '4' => '1011100', + '5' => '1001110', + '6' => '1010000', + '7' => '1000100', + '8' => '1001000', + '9' => '1110100' + ) + ); + $parities = array( + '0' => array('A', 'A', 'A', 'A', 'A', 'A'), + '1' => array('A', 'A', 'B', 'A', 'B', 'B'), + '2' => array('A', 'A', 'B', 'B', 'A', 'B'), + '3' => array('A', 'A', 'B', 'B', 'B', 'A'), + '4' => array('A', 'B', 'A', 'A', 'B', 'B'), + '5' => array('A', 'B', 'B', 'A', 'A', 'B'), + '6' => array('A', 'B', 'B', 'B', 'A', 'A'), + '7' => array('A', 'B', 'A', 'B', 'A', 'B'), + '8' => array('A', 'B', 'A', 'B', 'B', 'A'), + '9' => array('A', 'B', 'B', 'A', 'B', 'A') + ); + $upce_parities = array(); + $upce_parities[0] = array( + '0' => array('B', 'B', 'B', 'A', 'A', 'A'), + '1' => array('B', 'B', 'A', 'B', 'A', 'A'), + '2' => array('B', 'B', 'A', 'A', 'B', 'A'), + '3' => array('B', 'B', 'A', 'A', 'A', 'B'), + '4' => array('B', 'A', 'B', 'B', 'A', 'A'), + '5' => array('B', 'A', 'A', 'B', 'B', 'A'), + '6' => array('B', 'A', 'A', 'A', 'B', 'B'), + '7' => array('B', 'A', 'B', 'A', 'B', 'A'), + '8' => array('B', 'A', 'B', 'A', 'A', 'B'), + '9' => array('B', 'A', 'A', 'B', 'A', 'B') + ); + $upce_parities[1] = array( + '0' => array('A', 'A', 'A', 'B', 'B', 'B'), + '1' => array('A', 'A', 'B', 'A', 'B', 'B'), + '2' => array('A', 'A', 'B', 'B', 'A', 'B'), + '3' => array('A', 'A', 'B', 'B', 'B', 'A'), + '4' => array('A', 'B', 'A', 'A', 'B', 'B'), + '5' => array('A', 'B', 'B', 'A', 'A', 'B'), + '6' => array('A', 'B', 'B', 'B', 'A', 'A'), + '7' => array('A', 'B', 'A', 'B', 'A', 'B'), + '8' => array('A', 'B', 'A', 'B', 'B', 'A'), + '9' => array('A', 'B', 'B', 'A', 'B', 'A') + ); + $k = 0; + $seq = '101'; // left guard bar + if ($upce) { + $bararray = array('code' => $upce_code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + $p = $upce_parities[$code[1]][$r]; + for ($i = 0; $i < 6; ++$i) { + $seq .= $codes[$p[$i]][$upce_code{$i}]; + } + $seq .= '010101'; // right guard bar + } else { + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + $half_len = intval(ceil($len / 2)); + if ($len == 8) { + for ($i = 0; $i < $half_len; ++$i) { + $seq .= $codes['A'][$code{$i}]; + } + } else { + $p = $parities[$code[0]]; + for ($i = 1; $i < $half_len; ++$i) { + $seq .= $codes[$p[$i - 1]][$code{$i}]; + } + } + $seq .= '01010'; // center guard bar + for ($i = $half_len; $i < $len; ++$i) { + $seq .= $codes['C'][$code{$i}]; + } + $seq .= '101'; // right guard bar + } + $clen = strlen($seq); + $w = 0; + for ($i = 0; $i < $clen; ++$i) { + $w += 1; + if (($i == ($clen - 1)) OR (($i < ($clen - 1)) AND ($seq{$i} != $seq{($i + 1)}))) { + if ($seq{$i} == '1') { + $t = true; // bar + } else { + $t = false; // space + } + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); + $bararray['maxw'] += $w; + ++$k; + $w = 0; + } + } + + return $bararray; + } + + /** + * UPC-Based Extensions + * 2-Digit Ext.: Used to indicate magazines and newspaper issue numbers + * 5-Digit Ext.: Used to mark suggested retail price of books + * + * @param $code (string) code to represent. + * @param $len (string) barcode type: 2 = 2-Digit, 5 = 5-Digit + * @return array barcode representation. + * @protected + */ + protected function barcode_eanext($code, $len = 5) + { + //Padding + $code = str_pad($code, $len, '0', STR_PAD_LEFT); + // calculate check digit + if ($len == 2) { + $r = $code % 4; + } elseif ($len == 5) { + $r = (3 * ($code[0] + $code[2] + $code[4])) + (9 * ($code[1] + $code[3])); + $r %= 10; + } else { + return false; + } + //Convert digits to bars + $codes = array( + 'A' => array( // left odd parity + '0' => '0001101', + '1' => '0011001', + '2' => '0010011', + '3' => '0111101', + '4' => '0100011', + '5' => '0110001', + '6' => '0101111', + '7' => '0111011', + '8' => '0110111', + '9' => '0001011' + ), + 'B' => array( // left even parity + '0' => '0100111', + '1' => '0110011', + '2' => '0011011', + '3' => '0100001', + '4' => '0011101', + '5' => '0111001', + '6' => '0000101', + '7' => '0010001', + '8' => '0001001', + '9' => '0010111' + ) + ); + $parities = array(); + $parities[2] = array( + '0' => array('A', 'A'), + '1' => array('A', 'B'), + '2' => array('B', 'A'), + '3' => array('B', 'B') + ); + $parities[5] = array( + '0' => array('B', 'B', 'A', 'A', 'A'), + '1' => array('B', 'A', 'B', 'A', 'A'), + '2' => array('B', 'A', 'A', 'B', 'A'), + '3' => array('B', 'A', 'A', 'A', 'B'), + '4' => array('A', 'B', 'B', 'A', 'A'), + '5' => array('A', 'A', 'B', 'B', 'A'), + '6' => array('A', 'A', 'A', 'B', 'B'), + '7' => array('A', 'B', 'A', 'B', 'A'), + '8' => array('A', 'B', 'A', 'A', 'B'), + '9' => array('A', 'A', 'B', 'A', 'B') + ); + $p = $parities[$len][$r]; + $seq = '1011'; // left guard bar + $seq .= $codes[$p[0]][$code[0]]; + for ($i = 1; $i < $len; ++$i) { + $seq .= '01'; // separator + $seq .= $codes[$p[$i]][$code{$i}]; + } + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + + return $this->binseq_to_array($seq, $bararray); + } + + /** + * POSTNET and PLANET barcodes. + * Used by U.S. Postal Service for automated mail sorting + * + * @param $code (string) zip code to represent. Must be a string containing a zip code of the form DDDDD or + * DDDDD-DDDD. + * @param $planet (boolean) if true print the PLANET barcode, otherwise print POSTNET + * @return array barcode representation. + * @protected + */ + protected function barcode_postnet($code, $planet = false) + { + // bar length + if ($planet) { + $barlen = Array( + 0 => Array(1, 1, 2, 2, 2), + 1 => Array(2, 2, 2, 1, 1), + 2 => Array(2, 2, 1, 2, 1), + 3 => Array(2, 2, 1, 1, 2), + 4 => Array(2, 1, 2, 2, 1), + 5 => Array(2, 1, 2, 1, 2), + 6 => Array(2, 1, 1, 2, 2), + 7 => Array(1, 2, 2, 2, 1), + 8 => Array(1, 2, 2, 1, 2), + 9 => Array(1, 2, 1, 2, 2) + ); + } else { + $barlen = Array( + 0 => Array(2, 2, 1, 1, 1), + 1 => Array(1, 1, 1, 2, 2), + 2 => Array(1, 1, 2, 1, 2), + 3 => Array(1, 1, 2, 2, 1), + 4 => Array(1, 2, 1, 1, 2), + 5 => Array(1, 2, 1, 2, 1), + 6 => Array(1, 2, 2, 1, 1), + 7 => Array(2, 1, 1, 1, 2), + 8 => Array(2, 1, 1, 2, 1), + 9 => Array(2, 1, 2, 1, 1) + ); + } + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array()); + $k = 0; + $code = str_replace('-', '', $code); + $code = str_replace(' ', '', $code); + $len = strlen($code); + // calculate checksum + $sum = 0; + for ($i = 0; $i < $len; ++$i) { + $sum += intval($code{$i}); + } + $chkd = ($sum % 10); + if ($chkd > 0) { + $chkd = (10 - $chkd); + } + $code .= $chkd; + $len = strlen($code); + // start bar + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0); + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); + $bararray['maxw'] += 2; + for ($i = 0; $i < $len; ++$i) { + for ($j = 0; $j < 5; ++$j) { + $h = $barlen[$code{$i}][$j]; + $p = floor(1 / $h); + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); + $bararray['maxw'] += 2; + } + } + // end bar + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0); + $bararray['maxw'] += 1; + + return $bararray; + } + + /** + * RMS4CC - CBC - KIX + * RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code) - KIX (Klant index - Customer index) + * RM4SCC is the name of the barcode symbology used by the Royal Mail for its Cleanmail service. + * + * @param $code (string) code to print + * @param $kix (boolean) if true prints the KIX variation (doesn't use the start and end symbols, and the checksum) + * - in this case the house number must be sufficed with an X and placed at the end of the code. + * @return array barcode representation. + * @protected + */ + protected function barcode_rms4cc($code, $kix = false) + { + $notkix = ! $kix; + // bar mode + // 1 = pos 1, length 2 + // 2 = pos 1, length 3 + // 3 = pos 2, length 1 + // 4 = pos 2, length 2 + $barmode = array( + '0' => array(3, 3, 2, 2), + '1' => array(3, 4, 1, 2), + '2' => array(3, 4, 2, 1), + '3' => array(4, 3, 1, 2), + '4' => array(4, 3, 2, 1), + '5' => array(4, 4, 1, 1), + '6' => array(3, 1, 4, 2), + '7' => array(3, 2, 3, 2), + '8' => array(3, 2, 4, 1), + '9' => array(4, 1, 3, 2), + 'A' => array(4, 1, 4, 1), + 'B' => array(4, 2, 3, 1), + 'C' => array(3, 1, 2, 4), + 'D' => array(3, 2, 1, 4), + 'E' => array(3, 2, 2, 3), + 'F' => array(4, 1, 1, 4), + 'G' => array(4, 1, 2, 3), + 'H' => array(4, 2, 1, 3), + 'I' => array(1, 3, 4, 2), + 'J' => array(1, 4, 3, 2), + 'K' => array(1, 4, 4, 1), + 'L' => array(2, 3, 3, 2), + 'M' => array(2, 3, 4, 1), + 'N' => array(2, 4, 3, 1), + 'O' => array(1, 3, 2, 4), + 'P' => array(1, 4, 1, 4), + 'Q' => array(1, 4, 2, 3), + 'R' => array(2, 3, 1, 4), + 'S' => array(2, 3, 2, 3), + 'T' => array(2, 4, 1, 3), + 'U' => array(1, 1, 4, 4), + 'V' => array(1, 2, 3, 4), + 'W' => array(1, 2, 4, 3), + 'X' => array(2, 1, 3, 4), + 'Y' => array(2, 1, 4, 3), + 'Z' => array(2, 2, 3, 3) + ); + $code = strtoupper($code); + $len = strlen($code); + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array()); + if ($notkix) { + // table for checksum calculation (row,col) + $checktable = array( + '0' => array(1, 1), + '1' => array(1, 2), + '2' => array(1, 3), + '3' => array(1, 4), + '4' => array(1, 5), + '5' => array(1, 0), + '6' => array(2, 1), + '7' => array(2, 2), + '8' => array(2, 3), + '9' => array(2, 4), + 'A' => array(2, 5), + 'B' => array(2, 0), + 'C' => array(3, 1), + 'D' => array(3, 2), + 'E' => array(3, 3), + 'F' => array(3, 4), + 'G' => array(3, 5), + 'H' => array(3, 0), + 'I' => array(4, 1), + 'J' => array(4, 2), + 'K' => array(4, 3), + 'L' => array(4, 4), + 'M' => array(4, 5), + 'N' => array(4, 0), + 'O' => array(5, 1), + 'P' => array(5, 2), + 'Q' => array(5, 3), + 'R' => array(5, 4), + 'S' => array(5, 5), + 'T' => array(5, 0), + 'U' => array(0, 1), + 'V' => array(0, 2), + 'W' => array(0, 3), + 'X' => array(0, 4), + 'Y' => array(0, 5), + 'Z' => array(0, 0) + ); + $row = 0; + $col = 0; + for ($i = 0; $i < $len; ++$i) { + $row += $checktable[$code{$i}][0]; + $col += $checktable[$code{$i}][1]; + } + $row %= 6; + $col %= 6; + $chk = array_keys($checktable, array($row, $col)); + $code .= $chk[0]; + ++$len; + } + $k = 0; + if ($notkix) { + // start bar + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0); + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); + $bararray['maxw'] += 2; + } + for ($i = 0; $i < $len; ++$i) { + for ($j = 0; $j < 4; ++$j) { + switch ($barmode[$code{$i}][$j]) { + case 1: { + $p = 0; + $h = 2; + break; + } + case 2: { + $p = 0; + $h = 3; + break; + } + case 3: { + $p = 1; + $h = 1; + break; + } + case 4: { + $p = 1; + $h = 2; + break; + } + } + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); + $bararray['maxw'] += 2; + } + } + if ($notkix) { + // stop bar + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 3, 'p' => 0); + $bararray['maxw'] += 1; + } + + return $bararray; + } + + /** + * CODABAR barcodes. + * Older code often used in library systems, sometimes in blood banks + * + * @param $code (string) code to represent. + * @return array barcode representation. + * @protected + */ + protected function barcode_codabar($code) + { + $chr = array( + '0' => '11111221', + '1' => '11112211', + '2' => '11121121', + '3' => '22111111', + '4' => '11211211', + '5' => '21111211', + '6' => '12111121', + '7' => '12112111', + '8' => '12211111', + '9' => '21121111', + '-' => '11122111', + '$' => '11221111', + ':' => '21112121', + '/' => '21211121', + '.' => '21212111', + '+' => '11222221', + 'A' => '11221211', + 'B' => '12121121', + 'C' => '11121221', + 'D' => '11122211' + ); + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + $k = 0; + $w = 0; + $seq = ''; + $code = 'A' . strtoupper($code) . 'A'; + $len = strlen($code); + for ($i = 0; $i < $len; ++$i) { + if ( ! isset($chr[$code{$i}])) { + return false; + } + $seq = $chr[$code{$i}]; + for ($j = 0; $j < 8; ++$j) { + if (($j % 2) == 0) { + $t = true; // bar + } else { + $t = false; // space + } + $w = $seq{$j}; + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); + $bararray['maxw'] += $w; + ++$k; + } + } + + return $bararray; + } + + /** + * CODE11 barcodes. + * Used primarily for labeling telecommunications equipment + * + * @param $code (string) code to represent. + * @return array barcode representation. + * @protected + */ + protected function barcode_code11($code) + { + $chr = array( + '0' => '111121', + '1' => '211121', + '2' => '121121', + '3' => '221111', + '4' => '112121', + '5' => '212111', + '6' => '122111', + '7' => '111221', + '8' => '211211', + '9' => '211111', + '-' => '112111', + 'S' => '112211' + ); + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + $k = 0; + $w = 0; + $seq = ''; + $len = strlen($code); + // calculate check digit C + $p = 1; + $check = 0; + for ($i = ($len - 1); $i >= 0; --$i) { + $digit = $code{$i}; + if ($digit == '-') { + $dval = 10; + } else { + $dval = intval($digit); + } + $check += ($dval * $p); + ++$p; + if ($p > 10) { + $p = 1; + } + } + $check %= 11; + if ($check == 10) { + $check = '-'; + } + $code .= $check; + if ($len > 10) { + // calculate check digit K + $p = 1; + $check = 0; + for ($i = $len; $i >= 0; --$i) { + $digit = $code{$i}; + if ($digit == '-') { + $dval = 10; + } else { + $dval = intval($digit); + } + $check += ($dval * $p); + ++$p; + if ($p > 9) { + $p = 1; + } + } + $check %= 11; + $code .= $check; + ++$len; + } + $code = 'S' . $code . 'S'; + $len += 3; + for ($i = 0; $i < $len; ++$i) { + if ( ! isset($chr[$code{$i}])) { + return false; + } + $seq = $chr[$code{$i}]; + for ($j = 0; $j < 6; ++$j) { + if (($j % 2) == 0) { + $t = true; // bar + } else { + $t = false; // space + } + $w = $seq{$j}; + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); + $bararray['maxw'] += $w; + ++$k; + } + } + + return $bararray; + } + + /** + * Pharmacode + * Contains digits (0 to 9) + * + * @param $code (string) code to represent. + * @return array barcode representation. + * @protected + */ + protected function barcode_pharmacode($code) + { + $seq = ''; + $code = intval($code); + while ($code > 0) { + if (($code % 2) == 0) { + $seq .= '11100'; + $code -= 2; + } else { + $seq .= '100'; + $code -= 1; + } + $code /= 2; + } + $seq = substr($seq, 0, -2); + $seq = strrev($seq); + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); + + return $this->binseq_to_array($seq, $bararray); + } + + /** + * Pharmacode two-track + * Contains digits (0 to 9) + * + * @param $code (string) code to represent. + * @return array barcode representation. + * @protected + */ + protected function barcode_pharmacode2t($code) + { + $seq = ''; + $code = intval($code); + do { + switch ($code % 3) { + case 0: { + $seq .= '3'; + $code = ($code - 3) / 3; + break; + } + case 1: { + $seq .= '1'; + $code = ($code - 1) / 3; + break; + } + case 2: { + $seq .= '2'; + $code = ($code - 2) / 3; + break; + } + } + } while ($code != 0); + $seq = strrev($seq); + $k = 0; + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array()); + $len = strlen($seq); + for ($i = 0; $i < $len; ++$i) { + switch ($seq{$i}) { + case '1': { + $p = 1; + $h = 1; + break; + } + case '2': { + $p = 0; + $h = 1; + break; + } + case '3': { + $p = 0; + $h = 2; + break; + } + } + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); + $bararray['maxw'] += 2; + } + unset($bararray['bcode'][($k - 1)]); + --$bararray['maxw']; + + return $bararray; + } + + /** + * IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200 + * (requires PHP bcmath extension) + * Intelligent Mail barcode is a 65-bar code for use on mail in the United States. + * The fields are described as follows:
  • The Barcode Identifier shall be assigned by USPS to encode the + * presort identification that is currently printed in human readable form on the optional endorsement line (OEL) + * as well as for future USPS use. This shall be two digits, with the second digit in the range of 0–4. The + * allowable encoding ranges shall be 00–04, 10–14, 20–24, 30–34, 40–44, 50–54, 60–64, 70–74, 80–84, and + * 90–94.
  • The Service Type Identifier shall be assigned by USPS for any combination of services requested + * on the mailpiece. The allowable encoding range shall be 000http://it2.php.net/manual/en/function.dechex.php–999. + * Each 3-digit value shall correspond to a particular mail class with a particular combination of service(s). Each + * service program, such as OneCode Confirm and OneCode ACS, shall provide the list of Service Type Identifier + * values.
  • The Mailer or Customer Identifier shall be assigned by USPS as a unique, 6 or 9 digit number + * that identifies a business entity. The allowable encoding range for the 6 digit Mailer ID shall be 000000- + * 899999, while the allowable encoding range for the 9 digit Mailer ID shall be 900000000-999999999.
  • The + * Serial or Sequence Number shall be assigned by the mailer for uniquely identifying and tracking mailpieces. The + * allowable encoding range shall be 000000000–999999999 when used with a 6 digit Mailer ID and 000000-999999 when + * used with a 9 digit Mailer ID. e. The Delivery Point ZIP Code shall be assigned by the mailer for routing the + * mailpiece. This shall replace POSTNET for routing the mailpiece to its final delivery point. The length may be + * 0, 5, 9, or 11 digits. The allowable encoding ranges shall be no ZIP Code, 00000–99999, 000000000–999999999, + * and 00000000000–99999999999.
+ * + * @param $code (string) code to print, separate the ZIP (routing code) from the rest using a minus char '-' + * (BarcodeID_ServiceTypeID_MailerID_SerialNumber-RoutingCode) + * @return array barcode representation. + * @protected + */ + protected function barcode_imb($code) + { + $asc_chr = array( + 4, + 0, + 2, + 6, + 3, + 5, + 1, + 9, + 8, + 7, + 1, + 2, + 0, + 6, + 4, + 8, + 2, + 9, + 5, + 3, + 0, + 1, + 3, + 7, + 4, + 6, + 8, + 9, + 2, + 0, + 5, + 1, + 9, + 4, + 3, + 8, + 6, + 7, + 1, + 2, + 4, + 3, + 9, + 5, + 7, + 8, + 3, + 0, + 2, + 1, + 4, + 0, + 9, + 1, + 7, + 0, + 2, + 4, + 6, + 3, + 7, + 1, + 9, + 5, + 8 + ); + $dsc_chr = array( + 7, + 1, + 9, + 5, + 8, + 0, + 2, + 4, + 6, + 3, + 5, + 8, + 9, + 7, + 3, + 0, + 6, + 1, + 7, + 4, + 6, + 8, + 9, + 2, + 5, + 1, + 7, + 5, + 4, + 3, + 8, + 7, + 6, + 0, + 2, + 5, + 4, + 9, + 3, + 0, + 1, + 6, + 8, + 2, + 0, + 4, + 5, + 9, + 6, + 7, + 5, + 2, + 6, + 3, + 8, + 5, + 1, + 9, + 8, + 7, + 4, + 0, + 2, + 6, + 3 + ); + $asc_pos = array( + 3, + 0, + 8, + 11, + 1, + 12, + 8, + 11, + 10, + 6, + 4, + 12, + 2, + 7, + 9, + 6, + 7, + 9, + 2, + 8, + 4, + 0, + 12, + 7, + 10, + 9, + 0, + 7, + 10, + 5, + 7, + 9, + 6, + 8, + 2, + 12, + 1, + 4, + 2, + 0, + 1, + 5, + 4, + 6, + 12, + 1, + 0, + 9, + 4, + 7, + 5, + 10, + 2, + 6, + 9, + 11, + 2, + 12, + 6, + 7, + 5, + 11, + 0, + 3, + 2 + ); + $dsc_pos = array( + 2, + 10, + 12, + 5, + 9, + 1, + 5, + 4, + 3, + 9, + 11, + 5, + 10, + 1, + 6, + 3, + 4, + 1, + 10, + 0, + 2, + 11, + 8, + 6, + 1, + 12, + 3, + 8, + 6, + 4, + 4, + 11, + 0, + 6, + 1, + 9, + 11, + 5, + 3, + 7, + 3, + 10, + 7, + 11, + 8, + 2, + 10, + 3, + 5, + 8, + 0, + 3, + 12, + 11, + 8, + 4, + 5, + 1, + 3, + 0, + 7, + 12, + 9, + 8, + 10 + ); + $code_arr = explode('-', $code); + $tracking_number = $code_arr[0]; + if (isset($code_arr[1])) { + $routing_code = $code_arr[1]; + } else { + $routing_code = ''; + } + // Conversion of Routing Code + switch (strlen($routing_code)) { + case 0: { + $binary_code = 0; + break; + } + case 5: { + $binary_code = bcadd($routing_code, '1'); + break; + } + case 9: { + $binary_code = bcadd($routing_code, '100001'); + break; + } + case 11: { + $binary_code = bcadd($routing_code, '1000100001'); + break; + } + default: { + return false; + break; + } + } + $binary_code = bcmul($binary_code, 10); + $binary_code = bcadd($binary_code, $tracking_number[0]); + $binary_code = bcmul($binary_code, 5); + $binary_code = bcadd($binary_code, $tracking_number[1]); + $binary_code .= substr($tracking_number, 2, 18); + // convert to hexadecimal + $binary_code = $this->dec_to_hex($binary_code); + // pad to get 13 bytes + $binary_code = str_pad($binary_code, 26, '0', STR_PAD_LEFT); + // convert string to array of bytes + $binary_code_arr = chunk_split($binary_code, 2, "\r"); + $binary_code_arr = substr($binary_code_arr, 0, -1); + $binary_code_arr = explode("\r", $binary_code_arr); + // calculate frame check sequence + $fcs = $this->imb_crc11fcs($binary_code_arr); + // exclude first 2 bits from first byte + $first_byte = sprintf('%2s', dechex((hexdec($binary_code_arr[0]) << 2) >> 2)); + $binary_code_102bit = $first_byte . substr($binary_code, 2); + // convert binary data to codewords + $codewords = array(); + $data = $this->hex_to_dec($binary_code_102bit); + $codewords[0] = bcmod($data, 636) * 2; + $data = bcdiv($data, 636); + for ($i = 1; $i < 9; ++$i) { + $codewords[$i] = bcmod($data, 1365); + $data = bcdiv($data, 1365); + } + $codewords[9] = $data; + if (($fcs >> 10) == 1) { + $codewords[9] += 659; + } + // generate lookup tables + $table2of13 = $this->imb_tables(2, 78); + $table5of13 = $this->imb_tables(5, 1287); + // convert codewords to characters + $characters = array(); + $bitmask = 512; + foreach ($codewords as $k => $val) { + if ($val <= 1286) { + $chrcode = $table5of13[$val]; + } else { + $chrcode = $table2of13[($val - 1287)]; + } + if (($fcs & $bitmask) > 0) { + // bitwise invert + $chrcode = ((~$chrcode) & 8191); + } + $characters[] = $chrcode; + $bitmask /= 2; + } + $characters = array_reverse($characters); + // build bars + $k = 0; + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array()); + for ($i = 0; $i < 65; ++$i) { + $asc = (($characters[$asc_chr[$i]] & pow(2, $asc_pos[$i])) > 0); + $dsc = (($characters[$dsc_chr[$i]] & pow(2, $dsc_pos[$i])) > 0); + if ($asc AND $dsc) { + // full bar (F) + $p = 0; + $h = 3; + } elseif ($asc) { + // ascender (A) + $p = 0; + $h = 2; + } elseif ($dsc) { + // descender (D) + $p = 1; + $h = 2; + } else { + // tracker (T) + $p = 1; + $h = 1; + } + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); + $bararray['maxw'] += 2; + } + unset($bararray['bcode'][($k - 1)]); + --$bararray['maxw']; + + return $bararray; + } + + /** + * IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200 + * + * @param $code (string) pre-formatted IMB barcode (65 chars "FADT") + * @return array barcode representation. + * @protected + */ + protected function barcode_imb_pre($code) + { + if ( ! preg_match('/^[fadtFADT]{65}$/', $code) == 1) { + return false; + } + $characters = str_split(strtolower($code), 1); + // build bars + $k = 0; + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array()); + for ($i = 0; $i < 65; ++$i) { + switch ($characters[$i]) { + case 'f': { + // full bar + $p = 0; + $h = 3; + break; + } + case 'a': { + // ascender + $p = 0; + $h = 2; + break; + } + case 'd': { + // descender + $p = 1; + $h = 2; + break; + } + case 't': { + // tracker (short) + $p = 1; + $h = 1; + break; + } + } + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); + $bararray['maxw'] += 2; + } + unset($bararray['bcode'][($k - 1)]); + --$bararray['maxw']; + + return $bararray; + } + + /** + * Convert large integer number to hexadecimal representation. + * (requires PHP bcmath extension) + * + * @param $number (string) number to convert specified as a string + * @return string hexadecimal representation + */ + public function dec_to_hex($number) + { + $hex = array(); + if ($number == 0) { + return '00'; + } + while ($number > 0) { + if ($number == 0) { + array_push($hex, '0'); + } else { + array_push($hex, strtoupper(dechex(bcmod($number, '16')))); + $number = bcdiv($number, '16', 0); + } + } + $hex = array_reverse($hex); + + return implode($hex); + } + + /** + * Convert large hexadecimal number to decimal representation (string). + * (requires PHP bcmath extension) + * + * @param $hex (string) hexadecimal number to convert specified as a string + * @return string hexadecimal representation + */ + public function hex_to_dec($hex) + { + $dec = 0; + $bitval = 1; + $len = strlen($hex); + for ($pos = ($len - 1); $pos >= 0; --$pos) { + $dec = bcadd($dec, bcmul(hexdec($hex{$pos}), $bitval)); + $bitval = bcmul($bitval, 16); + } + + return $dec; + } + + /** + * Intelligent Mail Barcode calculation of Frame Check Sequence + * + * @param $code_arr (string) array of hexadecimal values (13 bytes holding 102 bits right justified). + * @return int 11 bit Frame Check Sequence as integer (decimal base) + * @protected + */ + protected function imb_crc11fcs($code_arr) + { + $genpoly = 0x0F35; // generator polynomial + $fcs = 0x07FF; // Frame Check Sequence + // do most significant byte skipping the 2 most significant bits + $data = hexdec($code_arr[0]) << 5; + for ($bit = 2; $bit < 8; ++$bit) { + if (($fcs ^ $data) & 0x400) { + $fcs = ($fcs << 1) ^ $genpoly; + } else { + $fcs = ($fcs << 1); + } + $fcs &= 0x7FF; + $data <<= 1; + } + // do rest of bytes + for ($byte = 1; $byte < 13; ++$byte) { + $data = hexdec($code_arr[$byte]) << 3; + for ($bit = 0; $bit < 8; ++$bit) { + if (($fcs ^ $data) & 0x400) { + $fcs = ($fcs << 1) ^ $genpoly; + } else { + $fcs = ($fcs << 1); + } + $fcs &= 0x7FF; + $data <<= 1; + } + } + + return $fcs; + } + + /** + * Reverse unsigned short value + * + * @param $num (int) value to reversr + * @return int reversed value + * @protected + */ + protected function imb_reverse_us($num) + { + $rev = 0; + for ($i = 0; $i < 16; ++$i) { + $rev <<= 1; + $rev |= ($num & 1); + $num >>= 1; + } + + return $rev; + } + + /** + * generate Nof13 tables used for Intelligent Mail Barcode + * + * @param $n (int) is the type of table: 2 for 2of13 table, 5 for 5of13table + * @param $size (int) size of table (78 for n=2 and 1287 for n=5) + * @return array requested table + * @protected + */ + protected function imb_tables($n, $size) + { + $table = array(); + $lli = 0; // LUT lower index + $lui = $size - 1; // LUT upper index + for ($count = 0; $count < 8192; ++$count) { + $bit_count = 0; + for ($bit_index = 0; $bit_index < 13; ++$bit_index) { + $bit_count += intval(($count & (1 << $bit_index)) != 0); + } + // if we don't have the right number of bits on, go on to the next value + if ($bit_count == $n) { + $reverse = ($this->imb_reverse_us($count) >> 3); + // if the reverse is less than count, we have already visited this pair before + if ($reverse >= $count) { + // If count is symmetric, place it at the first free slot from the end of the list. + // Otherwise, place it at the first free slot from the beginning of the list AND place $reverse ath the next free slot from the beginning of the list + if ($reverse == $count) { + $table[$lui] = $count; + --$lui; + } else { + $table[$lli] = $count; + ++$lli; + $table[$lli] = $reverse; + ++$lli; + } + } + } + } + + return $table; + } + + protected function convertBarcodeArrayToNewStyle($oldBarcodeArray) + { + $newBarcodeArray = []; + $newBarcodeArray['code'] = $oldBarcodeArray['code']; + $newBarcodeArray['maxWidth'] = $oldBarcodeArray['maxw']; + $newBarcodeArray['maxHeight'] = $oldBarcodeArray['maxh']; + $newBarcodeArray['bars'] = []; + foreach ($oldBarcodeArray['bcode'] as $oldbar) { + $newBar = []; + $newBar['width'] = $oldbar['w']; + $newBar['height'] = $oldbar['h']; + $newBar['positionVertical'] = $oldbar['p']; + $newBar['drawBar'] = $oldbar['t']; + $newBar['drawSpacing'] = ! $oldbar['t']; + + $newBarcodeArray['bars'][] = $newBar; + } + + return $newBarcodeArray; + } +} \ No newline at end of file diff --git a/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorHTML.php b/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorHTML.php new file mode 100644 index 0000000..d222ebe --- /dev/null +++ b/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorHTML.php @@ -0,0 +1,44 @@ +getBarcodeData($code, $type); + + $html = '
' . "\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 .= '
 
' . "\n"; + } + + $positionHorizontal += $barWidth; + } + + $html .= '
' . "\n"; + + return $html; + } +} \ No newline at end of file diff --git a/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorJPG.php b/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorJPG.php new file mode 100644 index 0000000..619e18c --- /dev/null +++ b/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorJPG.php @@ -0,0 +1,74 @@ +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; + } +} \ No newline at end of file diff --git a/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorPNG.php b/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorPNG.php new file mode 100644 index 0000000..6d1f1c3 --- /dev/null +++ b/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorPNG.php @@ -0,0 +1,74 @@ +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; + } +} \ No newline at end of file diff --git a/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorSVG.php b/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorSVG.php new file mode 100644 index 0000000..2e56608 --- /dev/null +++ b/vendor/picqer/php-barcode-generator/src/BarcodeGeneratorSVG.php @@ -0,0 +1,49 @@ +getBarcodeData($code, $type); + + // replace table for special characters + $repstr = array("\0" => '', '&' => '&', '<' => '<', '>' => '>'); + + $svg = '' . "\n"; + $svg .= '' . "\n"; + $svg .= '' . "\n"; + $svg .= "\t" . '' . strtr($barcodeData['code'], $repstr) . '' . "\n"; + $svg .= "\t" . '' . "\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" . '' . "\n"; + } + $positionHorizontal += $barWidth; + } + $svg .= "\t" . '' . "\n"; + $svg .= '' . "\n"; + + return $svg; + } +} \ No newline at end of file diff --git a/vendor/ulrichsg/getopt-php/.gitignore b/vendor/ulrichsg/getopt-php/.gitignore new file mode 100644 index 0000000..18c43b1 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/.gitignore @@ -0,0 +1,6 @@ +bin +build +composer.lock +vendor +nbproject +_site diff --git a/vendor/ulrichsg/getopt-php/.travis.yml b/vendor/ulrichsg/getopt-php/.travis.yml new file mode 100644 index 0000000..6c7b0e4 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/.travis.yml @@ -0,0 +1,10 @@ +language: php +php: + - 5.6 + - 5.5 + - 5.4 + - 5.3 + - hhvm + +before_script: + - composer install diff --git a/vendor/ulrichsg/getopt-php/CHANGELOG.md b/vendor/ulrichsg/getopt-php/CHANGELOG.md new file mode 100644 index 0000000..d9e097b --- /dev/null +++ b/vendor/ulrichsg/getopt-php/CHANGELOG.md @@ -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 + diff --git a/vendor/ulrichsg/getopt-php/LICENSE b/vendor/ulrichsg/getopt-php/LICENSE new file mode 100644 index 0000000..6520959 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/LICENSE @@ -0,0 +1,17 @@ +Copyright (c) 2011-2014 Ulrich Schmidt-Goertz + +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. diff --git a/vendor/ulrichsg/getopt-php/Makefile b/vendor/ulrichsg/getopt-php/Makefile new file mode 100644 index 0000000..e3d5698 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/Makefile @@ -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 + diff --git a/vendor/ulrichsg/getopt-php/README.markdown b/vendor/ulrichsg/getopt-php/README.markdown new file mode 100644 index 0000000..d48917a --- /dev/null +++ b/vendor/ulrichsg/getopt-php/README.markdown @@ -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). + +[![Build Status](https://travis-ci.org/ulrichsg/getopt-php.png)](https://travis-ci.org/ulrichsg/getopt-php) diff --git a/vendor/ulrichsg/getopt-php/composer.json b/vendor/ulrichsg/getopt-php/composer.json new file mode 100644 index 0000000..8ed9ee8 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/composer.json @@ -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" + } + } +} diff --git a/vendor/ulrichsg/getopt-php/phpunit.xml b/vendor/ulrichsg/getopt-php/phpunit.xml new file mode 100644 index 0000000..24e4942 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/phpunit.xml @@ -0,0 +1,35 @@ + + + + + + test + + + + + + src + + + + + + + + diff --git a/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Argument.php b/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Argument.php new file mode 100644 index 0000000..55dbe29 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Argument.php @@ -0,0 +1,115 @@ +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; + } +} diff --git a/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/CommandLineParser.php b/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/CommandLineParser.php new file mode 100644 index 0000000..2020680 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/CommandLineParser.php @@ -0,0 +1,233 @@ +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; + } +} diff --git a/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Getopt.php b/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Getopt.php new file mode 100644 index 0000000..bd6b7ad --- /dev/null +++ b/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Getopt.php @@ -0,0 +1,295 @@ +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: + *
    + *
  • null if the option is not given and does not have a default value
  • + *
  • the default value if it has been defined and the option is not given
  • + *
  • an integer if the option is given without argument. The + * returned value is the number of occurrences of the option.
  • + *
  • a string if the option is given with an argument. The returned value is that argument.
  • + *
+ * + * @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); + } +} diff --git a/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Option.php b/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Option.php new file mode 100644 index 0000000..c2924bc --- /dev/null +++ b/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/Option.php @@ -0,0 +1,162 @@ +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; + } +} diff --git a/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/OptionParser.php b/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/OptionParser.php new file mode 100644 index 0000000..6bad0a0 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/src/Ulrichsg/Getopt/OptionParser.php @@ -0,0 +1,137 @@ +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); + } +} diff --git a/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/ArgumentTest.php b/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/ArgumentTest.php new file mode 100644 index 0000000..a40f3e4 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/ArgumentTest.php @@ -0,0 +1,40 @@ +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(''); + } +} \ No newline at end of file diff --git a/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/CommandLineParserTest.php b/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/CommandLineParserTest.php new file mode 100644 index 0000000..8f5cb3d --- /dev/null +++ b/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/CommandLineParserTest.php @@ -0,0 +1,341 @@ +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'); + } +} diff --git a/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/GetoptTest.php b/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/GetoptTest.php new file mode 100644 index 0000000..0fc13f4 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/GetoptTest.php @@ -0,0 +1,199 @@ +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 [] Long option only with an optional argument\n"; + $expected .= " -c 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 [] \n"; + $expected .= " -c \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()); + } +} diff --git a/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/OptionParserTest.php b/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/OptionParserTest.php new file mode 100644 index 0000000..ad11332 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/OptionParserTest.php @@ -0,0 +1,112 @@ +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')); + } +} diff --git a/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/OptionTest.php b/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/OptionTest.php new file mode 100644 index 0000000..2c88107 --- /dev/null +++ b/vendor/ulrichsg/getopt-php/test/Ulrichsg/Getopt/OptionTest.php @@ -0,0 +1,72 @@ +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()); + } +}