diff --git a/composer.json b/composer.json index 7da1e1e9492c16eb20dd1d4b123e0b3ee6010975..7b394c41ac88ce5c232b840cd30c503d5002e939 100644 --- a/composer.json +++ b/composer.json @@ -15,13 +15,15 @@ }, "require": { "php": ">=7.0.8", - "aferrandini/phpqrcode": "1.0.1", - "jasig/phpcas": "1.3.5", - "cap60552/php-sip2": "1.0.0", "ahand/mobileesp": "dev-master", + "cap60552/php-sip2": "1.0.0", + "endroid/qr-code": "2.5.0", + "ghislainf/zf2-whoops": "dev-master#2649cf7caf400409942ddc3f8fe15b89381fc74e", + "jasig/phpcas": "1.3.5", "matthiasmullie/minify": "1.3.60", "ocramius/proxy-manager": "2.0.4", "oyejorge/less.php": "1.7.0.14", + "pear/archive_tar": "^1.4", "pear/file_marc": "1.2.0", "pear/http_request2": "2.3.0", "pear/validate_ispn": "dev-master", @@ -68,9 +70,7 @@ "zendframework/zendrest": "2.0.2", "zendframework/zendservice-amazon": "2.3.0", "zendframework/zendservice-recaptcha": "3.1.0", - "zf-commons/zfc-rbac": "2.6.3", - "ghislainf/zf2-whoops": "dev-master#2649cf7caf400409942ddc3f8fe15b89381fc74e", - "pear/archive_tar": "^1.4" + "zf-commons/zfc-rbac": "2.6.3" }, "require-dev": { "behat/mink": "1.7.1", diff --git a/composer.lock b/composer.lock index 96fd7b853186d4caebd54d2a329242749f51bc82..3cc4d6945ba748d2986fe40899db55b8558282a4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,53 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "9706d8ee125df82ee07e87ac799d82a1", + "content-hash": "f6c0185abbc60228a15ead1b186270f6", "packages": [ - { - "name": "aferrandini/phpqrcode", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/aferrandini/PHPQRCode.git", - "reference": "3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/aferrandini/PHPQRCode/zipball/3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46", - "reference": "3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "PHPQRCode": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ariel Ferrandini", - "email": "arielferrandini@gmail.com", - "homepage": "http://www.ferrandini.com/", - "role": "Developer" - } - ], - "description": "PHPQRCode porting and changed for PHP 5.3 compatibility", - "homepage": "https://github.com/aferrandini/PHPQRCode", - "keywords": [ - "barcode", - "php", - "qrcode" - ], - "abandoned": "endroid/qr-code", - "time": "2013-07-08T09:39:08+00:00" - }, { "name": "ahand/mobileesp", "version": "dev-master", @@ -105,6 +60,52 @@ ], "time": "2017-06-06T22:20:56+00:00" }, + { + "name": "bacon/bacon-qr-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "5a91b62b9d37cee635bbf8d553f4546057250bee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/5a91b62b9d37cee635bbf8d553f4546057250bee", + "reference": "5a91b62b9d37cee635bbf8d553f4546057250bee", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": "^5.4|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8" + }, + "suggest": { + "ext-gd": "to generate QR code images" + }, + "type": "library", + "autoload": { + "psr-0": { + "BaconQrCode": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "http://www.dasprids.de", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "time": "2017-10-17T09:59:25+00:00" + }, { "name": "cap60552/php-sip2", "version": "v1.0.0", @@ -171,6 +172,75 @@ "homepage": "https://github.com/container-interop/container-interop", "time": "2017-02-14T19:40:03+00:00" }, + { + "name": "endroid/qr-code", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/endroid/qr-code.git", + "reference": "a9a57ab57ac75928fcdcfb2a71179963ff6fe573" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/endroid/qr-code/zipball/a9a57ab57ac75928fcdcfb2a71179963ff6fe573", + "reference": "a9a57ab57ac75928fcdcfb2a71179963ff6fe573", + "shasum": "" + }, + "require": { + "bacon/bacon-qr-code": "^1.0.3", + "ext-gd": "*", + "khanamiryan/qrcode-detector-decoder": "^1.0", + "myclabs/php-enum": "^1.5", + "php": ">=5.6", + "symfony/options-resolver": ">=2.7", + "symfony/property-access": ">=2.7" + }, + "require-dev": { + "phpunit/phpunit": ">=5.7", + "symfony/asset": ">=2.7", + "symfony/browser-kit": ">=2.7", + "symfony/finder": ">=2.7", + "symfony/framework-bundle": ">=2.7", + "symfony/http-kernel": ">=2.7", + "symfony/templating": ">=2.7", + "symfony/twig-bundle": ">=2.7", + "symfony/yaml": ">=2.7" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Endroid\\QrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeroen van den Enden", + "email": "info@endroid.nl", + "homepage": "http://endroid.nl/" + } + ], + "description": "Endroid QR Code", + "homepage": "https://github.com/endroid/QrCode", + "keywords": [ + "bundle", + "code", + "endroid", + "flex", + "qr", + "qrcode", + "symfony" + ], + "time": "2017-10-22T18:56:00+00:00" + }, { "name": "filp/whoops", "version": "2.1.14", @@ -344,6 +414,56 @@ ], "time": "2017-04-10T19:12:45+00:00" }, + { + "name": "khanamiryan/qrcode-detector-decoder", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/khanamiryan/php-qrcode-detector-decoder.git", + "reference": "a75482d3bc804e3f6702332bfda6cccbb0dfaa76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/khanamiryan/php-qrcode-detector-decoder/zipball/a75482d3bc804e3f6702332bfda6cccbb0dfaa76", + "reference": "a75482d3bc804e3f6702332bfda6cccbb0dfaa76", + "shasum": "" + }, + "require": { + "php": "^5.6|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Zxing\\": "lib/" + }, + "files": [ + "lib/Common/customFunctions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ashot Khanamiryan", + "email": "a.khanamiryan@gmail.com", + "homepage": "https://github.com/khanamiryan", + "role": "Developer" + } + ], + "description": "QR code decoder / reader", + "homepage": "https://github.com/khanamiryan/php-qrcode-detector-decoder/", + "keywords": [ + "barcode", + "qr", + "zxing" + ], + "time": "2018-04-26T11:41:33+00:00" + }, { "name": "matthiasmullie/minify", "version": "1.3.60", @@ -453,6 +573,50 @@ ], "time": "2018-02-02T11:30:10+00:00" }, + { + "name": "myclabs/php-enum", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/php-enum.git", + "reference": "8c5649e4ed99acd53a40eada270154dcac089f7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/8c5649e4ed99acd53a40eada270154dcac089f7e", + "reference": "8c5649e4ed99acd53a40eada270154dcac089f7e", + "shasum": "" + }, + "require": { + "php": ">=5.4" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|^5.7|^6.0", + "squizlabs/php_codesniffer": "1.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "MyCLabs\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP Enum contributors", + "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" + } + ], + "description": "PHP Enum implementation", + "homepage": "http://github.com/myclabs/php-enum", + "keywords": [ + "enum" + ], + "time": "2018-05-09T08:09:15+00:00" + }, { "name": "ocramius/package-versions", "version": "1.2.0", @@ -1535,6 +1699,118 @@ ], "time": "2017-01-05T08:57:09+00:00" }, + { + "name": "symfony/inflector", + "version": "v3.4.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/inflector.git", + "reference": "bc27e8f793a571313132923b5ad10fdf2843e26c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/inflector/zipball/bc27e8f793a571313132923b5ad10fdf2843e26c", + "reference": "bc27e8f793a571313132923b5ad10fdf2843e26c", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Inflector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Inflector Component", + "homepage": "https://symfony.com", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string", + "symfony", + "words" + ], + "time": "2018-05-01T22:53:27+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v3.4.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "f3109a6aedd20e35c3a33190e932c2b063b7b50e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/f3109a6aedd20e35c3a33190e932c2b063b7b50e", + "reference": "f3109a6aedd20e35c3a33190e932c2b063b7b50e", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "time": "2018-01-11T07:56:07+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.8.0", @@ -1590,6 +1866,133 @@ ], "time": "2018-04-30T19:57:29+00:00" }, + { + "name": "symfony/polyfill-php70", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "77454693d8f10dd23bb24955cffd2d82db1007a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/77454693d8f10dd23bb24955cffd2d82db1007a6", + "reference": "77454693d8f10dd23bb24955cffd2d82db1007a6", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-04-26T10:06:28+00:00" + }, + { + "name": "symfony/property-access", + "version": "v3.4.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "a6e8c778b220dfd5cd5f5dcb09f87ee232dd608a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/a6e8c778b220dfd5cd5f5dcb09f87ee232dd608a", + "reference": "a6e8c778b220dfd5cd5f5dcb09f87ee232dd608a", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/inflector": "~3.1|~4.0", + "symfony/polyfill-php70": "~1.0" + }, + "require-dev": { + "symfony/cache": "~3.1|~4.0" + }, + "suggest": { + "psr/cache-implementation": "To cache access methods." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony PropertyAccess Component", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property path", + "reflection" + ], + "time": "2018-01-03T07:37:34+00:00" + }, { "name": "symfony/yaml", "version": "v3.4.10", @@ -7029,60 +7432,6 @@ "homepage": "https://symfony.com", "time": "2018-05-16T08:49:21+00:00" }, - { - "name": "symfony/options-resolver", - "version": "v3.4.10", - "source": { - "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "f3109a6aedd20e35c3a33190e932c2b063b7b50e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/f3109a6aedd20e35c3a33190e932c2b063b7b50e", - "reference": "f3109a6aedd20e35c3a33190e932c2b063b7b50e", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony OptionsResolver Component", - "homepage": "https://symfony.com", - "keywords": [ - "config", - "configuration", - "options" - ], - "time": "2018-01-11T07:56:07+00:00" - }, { "name": "symfony/polyfill-mbstring", "version": "v1.8.0", @@ -7142,65 +7491,6 @@ ], "time": "2018-04-26T10:06:28+00:00" }, - { - "name": "symfony/polyfill-php70", - "version": "v1.8.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "77454693d8f10dd23bb24955cffd2d82db1007a6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/77454693d8f10dd23bb24955cffd2d82db1007a6", - "reference": "77454693d8f10dd23bb24955cffd2d82db1007a6", - "shasum": "" - }, - "require": { - "paragonie/random_compat": "~1.0|~2.0", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-04-26T10:06:28+00:00" - }, { "name": "symfony/polyfill-php72", "version": "v1.8.0", @@ -7489,8 +7779,8 @@ "minimum-stability": "stable", "stability-flags": { "ahand/mobileesp": 20, - "pear/validate_ispn": 20, - "ghislainf/zf2-whoops": 20 + "ghislainf/zf2-whoops": 20, + "pear/validate_ispn": 20 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index e6e0f2ffd9e92b5c2505ed409a84de22820c34a5..06f3fecc0eab27563bf653fec14ba32f361fc568 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -138,7 +138,7 @@ $config = [ 'VuFind\Controller\Pazpar2Controller' => 'VuFind\Controller\AbstractBaseFactory', 'VuFind\Controller\PrimoController' => 'VuFind\Controller\AbstractBaseFactory', 'VuFind\Controller\PrimorecordController' => 'VuFind\Controller\AbstractBaseFactory', - 'VuFind\Controller\QRCodeController' => 'VuFind\Controller\AbstractBaseFactory', + 'VuFind\Controller\QRCodeController' => 'VuFind\Controller\QRCodeControllerFactory', 'VuFind\Controller\RecordController' => 'VuFind\Controller\AbstractBaseWithConfigFactory', 'VuFind\Controller\RecordsController' => 'VuFind\Controller\AbstractBaseFactory', 'VuFind\Controller\RelaisController' => 'VuFind\Controller\AbstractBaseFactory', @@ -332,6 +332,7 @@ $config = [ 'VuFind\Log\Logger' => 'VuFind\Log\LoggerFactory', 'VuFind\Mailer\Mailer' => 'VuFind\Mailer\Factory', 'VuFind\Net\IpAddressUtils' => 'Zend\ServiceManager\Factory\InvokableFactory', + 'VuFind\QRCode\Loader' => 'VuFind\QRCode\LoaderFactory', 'VuFind\Recommend\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', 'VuFind\Record\Cache' => 'VuFind\Record\CacheFactory', 'VuFind\Record\Loader' => 'VuFind\Record\LoaderFactory', diff --git a/module/VuFind/src/VuFind/Controller/QRCodeController.php b/module/VuFind/src/VuFind/Controller/QRCodeController.php index ad1714d36d55d28cad78007e4a8630028c22e3b5..81766dab4e9cf45a9502be0fbe8768c156c9a4bb 100644 --- a/module/VuFind/src/VuFind/Controller/QRCodeController.php +++ b/module/VuFind/src/VuFind/Controller/QRCodeController.php @@ -29,6 +29,7 @@ namespace VuFind\Controller; use VuFind\QRCode\Loader; +use VuFind\Session\Settings as SessionSettings; /** * Generates qrcodes @@ -40,7 +41,7 @@ use VuFind\QRCode\Loader; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org Main Page */ -class QRCodeController extends AbstractBase +class QRCodeController extends \Zend\Mvc\Controller\AbstractActionController { /** * QR Code loader @@ -50,22 +51,22 @@ class QRCodeController extends AbstractBase protected $loader = false; /** - * Get the cover loader object + * Session settings * - * @return Loader + * @var SessionSettings */ - protected function getLoader() + protected $sessionSettings = null; + + /** + * Constructor + * + * @param Loader $loader QR Code Loader + * @param SessionSettings $ss Session settings + */ + public function __construct(Loader $loader, SessionSettings $ss) { - // Construct object for QRCodes if it does not already exist: - if (!$this->loader) { - $this->loader = new Loader( - $this->getConfig(), - $this->serviceLocator->get('VuFindTheme\ThemeInfo') - ); - $initializer = new \VuFind\ServiceManager\ServiceInitializer(); - $initializer($this->serviceLocator, $this->loader); - } - return $this->loader; + $this->loader = $loader; + $this->sessionSettings = $ss; } /** @@ -75,16 +76,13 @@ class QRCodeController extends AbstractBase */ public function showAction() { - $this->disableSessionWrites(); // avoid session write timing bug + $this->sessionSettings->disableWrite(); // avoid session write timing bug - $this->getLoader()->loadQRCode( - $this->params()->fromQuery('text'), - [ - 'level' => $this->params()->fromQuery('level', "L"), - 'size' => $this->params()->fromQuery('size', "3"), - 'margin' => $this->params()->fromQuery('margin', "4"), - ] - ); + $params = []; + foreach ($this->loader->getDefaults() as $param => $default) { + $params[$param] = $this->params()->fromQuery($param, $default); + } + $this->loader->loadQRCode($this->params()->fromQuery('text'), $params); return $this->displayQRCode(); } @@ -95,8 +93,8 @@ class QRCodeController extends AbstractBase */ public function unavailableAction() { - $this->disableSessionWrites(); // avoid session write timing bug - $this->getLoader()->loadUnavailable(); + $this->sessionSettings->disableWrite(); // avoid session write timing bug + $this->loader->loadUnavailable(); return $this->displayQRCode(); } @@ -109,11 +107,10 @@ class QRCodeController extends AbstractBase protected function displayQRCode() { $response = $this->getResponse(); - $headers = $response->getHeaders(); - $headers->addHeaderLine( - 'Content-type', $this->getLoader()->getContentType() + $response->getHeaders()->addHeaderLine( + 'Content-type', $this->loader->getContentType() ); - $response->setContent($this->getLoader()->getImage()); + $response->setContent($this->loader->getImage()); return $response; } } diff --git a/module/VuFind/src/VuFind/Controller/QRCodeControllerFactory.php b/module/VuFind/src/VuFind/Controller/QRCodeControllerFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..dc3051698f5fd6defc126c1a7e0cd4ff759b98e2 --- /dev/null +++ b/module/VuFind/src/VuFind/Controller/QRCodeControllerFactory.php @@ -0,0 +1,69 @@ +<?php +/** + * QRCode controller factory. + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Controller + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\Controller; + +use Interop\Container\ContainerInterface; +use Zend\ServiceManager\Factory\FactoryInterface; + +/** + * QRCode controller factory. + * + * @category VuFind + * @package Controller + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class QRCodeControllerFactory implements FactoryInterface +{ + /** + * Create an object + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException if any other error occurs + */ + public function __invoke(ContainerInterface $container, $requestedName, + array $options = null + ) { + if (!empty($options)) { + throw new \Exception('Unexpected options sent to factory.'); + } + return new $requestedName( + $container->get('VuFind\QRCode\Loader'), + $container->get('VuFind\Session\Settings') + ); + } +} diff --git a/module/VuFind/src/VuFind/QRCode/Loader.php b/module/VuFind/src/VuFind/QRCode/Loader.php index b358a635aad8384783e6856b7647864c09d50550..e9ec2385471c7c1a1495dfc228dc554de71911f7 100644 --- a/module/VuFind/src/VuFind/QRCode/Loader.php +++ b/module/VuFind/src/VuFind/QRCode/Loader.php @@ -29,7 +29,8 @@ */ namespace VuFind\QRCode; -use PHPQRCode; +use Endroid\QrCode\ErrorCorrectionLevel; +use Endroid\QrCode\QrCode; /** * QR Code Generator @@ -45,27 +46,11 @@ use PHPQRCode; class Loader extends \VuFind\ImageLoader { /** - * VuFind configuration settings - * - * @var \Zend\Config\Config - */ - protected $config; - - /** - * The text used to generate the QRCode - * - * @var string - */ - protected $text = null; - - /** - * The params used to generate the QRCode + * The default params used to generate the QRCode * * @var string */ - protected $params = [ - 'level' => "L", 'size' => "3", 'margin' => "4" - ]; + protected $defaultParams = ['level' => 'L', 'size' => '3', 'margin' => '4']; /** * Constructor @@ -75,48 +60,123 @@ class Loader extends \VuFind\ImageLoader */ public function __construct($config, \VuFindTheme\ThemeInfo $theme) { - $this->config = $config; $this->setThemeInfo($theme); $this->configuredFailImage - = isset($this->config->QRCode->noQRCodeAvailableImage) - ? $this->config->QRCode->noQRCodeAvailableImage : null; + = $this->config->QRCode->noQRCodeAvailableImage ?? null; $this->defaultFailImage = 'images/noQRCode.gif'; } + /** + * Get default parameters. + * + * @return array + */ + public function getDefaults() + { + return $this->defaultParams; + } + /** * Set up a QR code image * - * @param string $text The QR code text - * @param array $params QR code parameters (level/size/margin) + * @param string $text The QR code text + * @param array $rawParams QR code parameters (level/size/margin) * * @return void */ - public function loadQRCode($text, - $params = ['level' => "L", 'size' => "3", 'margin' => "4"] - ) { + public function loadQRCode($text, $rawParams = []) + { + // Fill in defaults: + $params = $rawParams + $this->defaultParams; + + // Normalize parameters; when the size setting is less than 30 pixels, + // do some math to try to map old PHPQRCode-style settings to new + // Endroid\QrCode equivalents. When the size setting is 30 or higher, + // treat 'size' and 'margin' as literal pixel sizes. + $margin = $params['margin']; + $level = $this->mapErrorLevel($params['level']); + if ($params['size'] < 30) { + // In the old system, the margin was multiplied by the size.... + $margin *= $params['size']; + + // Do some magic math to adjust the QR code size to accommodate the + // length of the text and the quality level. This is probably not the + // smartest way to do this, but it seems good enough for VuFind's + // limited needs. + $sizeIncrement = ceil(ceil(sqrt(strlen($text))) / 10); + if ($level === ErrorCorrectionLevel::HIGH) { + $sizeIncrement *= 38; + } elseif ($level === ErrorCorrectionLevel::QUARTILE) { + $sizeIncrement *= 34; + } else { + $sizeIncrement *= 30; + } + + // Put it all together: + $size = $params['size'] * $sizeIncrement - $params['margin']; + } else { + $size = $params['size']; + } + // Sanitize parameters: - $this->text = $text; - $this->params = $params; - if (!$this->fetchQRCode()) { + if (!$this->fetchQRCode($text, $size, $margin, $level)) { $this->loadUnavailable(); } } + /** + * Map an incoming error correction level parameter to a valid constant. + * + * @param string $level Error correction level parameter + * + * @return string + */ + protected function mapErrorLevel($level) + { + switch (strtoupper(substr($level, 0, 1))) { + case '3': + case 'H': + return ErrorCorrectionLevel::HIGH; + case '2': + case 'Q': + return ErrorCorrectionLevel::QUARTILE; + case '1': + case 'M': + return ErrorCorrectionLevel::MEDIUM; + case '0': + case 'L': + default: + return ErrorCorrectionLevel::LOW; + } + } + /** * Generate a QR code image * + * @param string $text The QR code text + * @param int $size QR code width / height (in pixels) + * @param int $margin QR code margin (in pixels) + * @param string $level Error correction level constant + * * @return bool True if image displayed, false on failure. */ - protected function fetchQRCode() + protected function fetchQRCode($text, $size, $margin, $level) { - if (empty($this->text)) { + if (strlen(trim($text)) == 0) { return false; } - $this->contentType = 'image/png'; - $this->image = PHPQRCode\QRcode::PNG( - $this->text, false, - $this->params['level'], $this->params['size'], $this->params['margin'] - ); + + // Build the code: + $code = new QrCode($text); + $code->setWriterByName('png'); + $code->setMargin($margin); + $code->setErrorCorrectionLevel($level); + $code->setSize($size); + $code->setEncoding('UTF-8'); + + // Save the values. + $this->contentType = $code->getContentType(); + $this->image = $code->writeString(); return true; } } diff --git a/module/VuFind/src/VuFind/QRCode/LoaderFactory.php b/module/VuFind/src/VuFind/QRCode/LoaderFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..67d5db90f84b7016fd88f6a0da36adb24524365f --- /dev/null +++ b/module/VuFind/src/VuFind/QRCode/LoaderFactory.php @@ -0,0 +1,69 @@ +<?php +/** + * Factory for QR Code Generator + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package QRCode_Generator + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\QRCode; + +use Interop\Container\ContainerInterface; +use Zend\ServiceManager\Factory\FactoryInterface; + +/** + * Factory for QR Code Generator + * + * @category VuFind + * @package QRCode_Generator + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class LoaderFactory implements FactoryInterface +{ + /** + * Create an object + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException if any other error occurs + */ + public function __invoke(ContainerInterface $container, $requestedName, + array $options = null + ) { + if (!empty($options)) { + throw new \Exception('Unexpected options passed to factory.'); + } + return new $requestedName( + $container->get('VuFind\Config\PluginManager')->get('config'), + $container->get('VuFindTheme\ThemeInfo') + ); + } +}