diff --git a/.gitignore b/.gitignore index c9f890f14444c4fa408c6df4cf67cbbd469f9efb..67212327e236469900e45d99ecdc9fc600dd6ddf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ ChangeLog \#* .\#* .php_cs_cache +module/finc/tests/.phpunit.result.cache .vagrant .vscode/* TAGS diff --git a/composer.json b/composer.json index db42315cf38decd4af085c072b21261fba4f98a1..a3f99c67e9cee2b2081adda8d9c4ab220920a5b9 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ "license": "GPL-2.0", "config": { "platform": { - "php": "7.2" + "php": "7.3" }, "process-timeout": 0, "allow-plugins": { @@ -30,7 +30,7 @@ "laminas/laminas-code": "3.4.1", "laminas/laminas-config": "3.3.0", "laminas/laminas-crypt": "3.3.1", - "laminas/laminas-db": "2.11.3", + "laminas/laminas-db": "2.12", "laminas/laminas-dependency-plugin": "2.0.0", "laminas/laminas-dom": "2.7.2", "laminas/laminas-escaper": "2.6.1", @@ -53,7 +53,7 @@ "laminas/laminas-servicemanager": "3.5.2", "laminas/laminas-session": "2.9.3", "laminas/laminas-soap": "2.8.0", - "laminas/laminas-stdlib": "3.2.1", + "laminas/laminas-stdlib": "3.7.1", "laminas/laminas-text": "2.7.1", "laminas/laminas-validator": "2.13.5", "laminas/laminas-view": "2.11.5", diff --git a/composer.lock b/composer.lock index 5f1633b9f39fa8948c88cee748ad38c9ab4471d5..f0886d24470e4a4f6d53f069bcfd6e74f1168949 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "412f682a3730304eb0fc5c2e150ed228", + "content-hash": "67d72e23ac5ac0e70a8bf8e534878b11", "packages": [ { "name": "ahand/mobileesp", @@ -2425,44 +2425,41 @@ }, { "name": "laminas/laminas-db", - "version": "2.11.3", + "version": "2.12.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-db.git", - "reference": "6c4238918b9204db1eb8cafae2c1940d40f4c007" + "reference": "80cbba4e749f9eb7d8036172acb9ad41e8b6923f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-db/zipball/6c4238918b9204db1eb8cafae2c1940d40f4c007", - "reference": "6c4238918b9204db1eb8cafae2c1940d40f4c007", + "url": "https://api.github.com/repos/laminas/laminas-db/zipball/80cbba4e749f9eb7d8036172acb9ad41e8b6923f", + "reference": "80cbba4e749f9eb7d8036172acb9ad41e8b6923f", "shasum": "" }, "require": { - "laminas/laminas-stdlib": "^2.7 || ^3.0", + "laminas/laminas-stdlib": "^3.3", "laminas/laminas-zendframework-bridge": "^1.0", - "php": "^5.6 || ^7.0" + "php": "^7.3 || ~8.0.0" }, "replace": { "zendframework/zend-db": "^2.11.0" }, "require-dev": { "laminas/laminas-coding-standard": "~1.0.0", - "laminas/laminas-eventmanager": "^2.6.2 || ^3.0", - "laminas/laminas-hydrator": "^1.1 || ^2.1 || ^3.0", - "laminas/laminas-servicemanager": "^2.7.5 || ^3.0.3", - "phpunit/phpunit": "^5.7.27 || ^6.5.14" + "laminas/laminas-eventmanager": "^3.3", + "laminas/laminas-hydrator": "^3.2 || ^4.0", + "laminas/laminas-servicemanager": "^3.3", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.3" }, "suggest": { "laminas/laminas-eventmanager": "Laminas\\EventManager component", - "laminas/laminas-hydrator": "Laminas\\Hydrator component for using HydratingResultSets", + "laminas/laminas-hydrator": "(^3.2 || ^4.0) Laminas\\Hydrator component for using HydratingResultSets", "laminas/laminas-servicemanager": "Laminas\\ServiceManager component" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "2.11.x-dev", - "dev-develop": "2.12.x-dev" - }, "laminas": { "component": "Laminas\\Db", "config-provider": "Laminas\\Db\\ConfigProvider" @@ -2483,15 +2480,7 @@ "db", "laminas" ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-db/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-db/issues", - "rss": "https://github.com/laminas/laminas-db/releases.atom", - "source": "https://github.com/laminas/laminas-db" - }, - "time": "2020-03-29T12:08:51+00:00" + "time": "2021-02-22T22:27:56+00:00" }, { "name": "laminas/laminas-dependency-plugin", @@ -3292,36 +3281,29 @@ }, { "name": "laminas/laminas-i18n-resources", - "version": "2.6.1", + "version": "2.8.0", "source": { "type": "git", - "url": "git@github.com:laminas/laminas-i18n-resources.git", - "reference": "7585cd3a4f9656814425b35689919a220c73834b" + "url": "https://github.com/laminas/laminas-i18n-resources.git", + "reference": "7d7062849064bb89e7cdd7193c43ef95e95fbe4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-i18n-resources/zipball/7585cd3a4f9656814425b35689919a220c73834b", - "reference": "7585cd3a4f9656814425b35689919a220c73834b", + "url": "https://api.github.com/repos/laminas/laminas-i18n-resources/zipball/7d7062849064bb89e7cdd7193c43ef95e95fbe4b", + "reference": "7d7062849064bb89e7cdd7193c43ef95e95fbe4b", "shasum": "" }, "require": { - "laminas/laminas-zendframework-bridge": "^1.0", - "php": "^5.6 || ^7.0" + "php": "^7.3 || ~8.0.0 || ~8.1.0" }, - "replace": { - "zendframework/zend-i18n-resources": "self.version" + "conflict": { + "zendframework/zend-i18n-resources": "*" }, "require-dev": { "laminas/laminas-coding-standard": "~1.0.0", - "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.5" + "phpunit/phpunit": "^9.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6.x-dev", - "dev-develop": "2.7.x-dev" - } - }, "autoload": { "classmap": [ "src/Resources.php" @@ -3331,7 +3313,7 @@ "license": [ "BSD-3-Clause" ], - "description": "Provides validator translations for laminas-i18n's Translator", + "description": "Provides validator and captcha translations for laminas-i18n's Translator", "homepage": "https://laminas.dev", "keywords": [ "laminas", @@ -3346,7 +3328,13 @@ "rss": "https://github.com/laminas/laminas-i18n-resources/releases.atom", "source": "https://github.com/laminas/laminas-i18n-resources" }, - "time": "2019-12-31T17:11:35+00:00" + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2021-09-14T04:16:52+00:00" }, { "name": "laminas/laminas-inputfilter", @@ -4771,37 +4759,32 @@ }, { "name": "laminas/laminas-stdlib", - "version": "3.2.1", + "version": "3.7.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-stdlib.git", - "reference": "2b18347625a2f06a1a485acfbc870f699dbe51c6" + "reference": "bcd869e2fe88d567800057c1434f2380354fe325" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/2b18347625a2f06a1a485acfbc870f699dbe51c6", - "reference": "2b18347625a2f06a1a485acfbc870f699dbe51c6", + "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/bcd869e2fe88d567800057c1434f2380354fe325", + "reference": "bcd869e2fe88d567800057c1434f2380354fe325", "shasum": "" }, "require": { - "laminas/laminas-zendframework-bridge": "^1.0", - "php": "^5.6 || ^7.0" + "php": "^7.3 || ~8.0.0 || ~8.1.0" }, - "replace": { - "zendframework/zend-stdlib": "self.version" + "conflict": { + "zendframework/zend-stdlib": "*" }, "require-dev": { - "laminas/laminas-coding-standard": "~1.0.0", - "phpbench/phpbench": "^0.13", - "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2" + "laminas/laminas-coding-standard": "~2.3.0", + "phpbench/phpbench": "^1.0", + "phpunit/phpunit": "^9.3.7", + "psalm/plugin-phpunit": "^0.16.0", + "vimeo/psalm": "^4.7" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2.x-dev", - "dev-develop": "3.3.x-dev" - } - }, "autoload": { "psr-4": { "Laminas\\Stdlib\\": "src/" @@ -4817,15 +4800,7 @@ "laminas", "stdlib" ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-stdlib/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-stdlib/issues", - "rss": "https://github.com/laminas/laminas-stdlib/releases.atom", - "source": "https://github.com/laminas/laminas-stdlib" - }, - "time": "2019-12-31T17:51:15+00:00" + "time": "2022-01-21T15:50:46+00:00" }, { "name": "laminas/laminas-text", @@ -10123,6 +10098,7 @@ "issues": "https://github.com/sebastianbergmann/phploc/issues", "source": "https://github.com/sebastianbergmann/phploc/tree/master" }, + "abandoned": true, "time": "2019-03-16T10:41:19+00:00" }, { @@ -12390,7 +12366,7 @@ "source": "https://github.com/theseer/fDOMDocument/tree/1.6.7" }, "abandoned": true, - "time": "2022-01-25T23:10:35+00:00" + "time": "2017-06-30T11:53:12+00:00" }, { "name": "theseer/tokenizer", @@ -12456,7 +12432,7 @@ }, "platform-dev": [], "platform-overrides": { - "php": "7.2" + "php": "7.3" }, "plugin-api-version": "2.3.0" } diff --git a/devops/docker/php8_0/Dockerfile b/devops/docker/php8_0/Dockerfile index 361d18e935ce8c245e201288e6e05807cba27be3..e903bb8e82cff6c497a6e550e15568ad12bff654 100644 --- a/devops/docker/php8_0/Dockerfile +++ b/devops/docker/php8_0/Dockerfile @@ -17,8 +17,10 @@ # @license https://opensource.org/licenses/GPL-3.0 GNU GPLv3 FROM php:8.0-fpm-alpine +# RUN docker-php-ext-install opcache +RUN apk add --update linux-headers RUN apk add --no-cache $PHPIZE_DEPS freetype-dev libxml2-dev icu-dev libxslt-dev \ - && pecl install xdebug-3.0.0 \ + && pecl install xdebug-3.2.0 \ && docker-php-ext-enable xdebug \ && docker-php-ext-install mysqli \ && docker-php-ext-install pdo_mysql \ @@ -36,4 +38,5 @@ RUN apk add --no-cache \ RUN docker-php-ext-configure gd --with-jpeg --with-webp --with-freetype RUN docker-php-ext-install gd -COPY php.ini /usr/local/etc/php/conf.d/php.ini \ No newline at end of file +COPY php.ini /usr/local/etc/php/conf.d/php.ini +COPY www.conf /usr/local/etc/php-fpm.d/www.conf \ No newline at end of file diff --git a/devops/docker/php8_0/php.ini b/devops/docker/php8_0/php.ini index 36c1f7030eb4e49c4c15bf9c1582926ca3d81579..250bc3972b858d8772ba6dd3fd0b9622e8ea1a5f 100644 --- a/devops/docker/php8_0/php.ini +++ b/devops/docker/php8_0/php.ini @@ -19,6 +19,22 @@ ; See https://www.php.net/manual/en/function.error-reporting.php for more details. error_reporting = E_ALL +[opcache] +; maximum memory that OPcache can use to store compiled PHP files, Symfony recommends 256 +opcache.memory_consumption=256 +; maximum number of files that can be stored in the cache +opcache.max_accelerated_files=20000 +; validate on every request +opcache.revalidate_freq=0 +; validate_timestamps should be 0 in prod +opcache.validate_timestamps=1 +opcache.interned_strings_buffer=16 +opcache.fast_shutdown=1 +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_buffer_size=256M + ; See https://xdebug.org/docs/all_settings for more details. xdebug.mode=debug xdebug.start_with_request=yes diff --git a/devops/docker/php8_0/www.conf b/devops/docker/php8_0/www.conf new file mode 100644 index 0000000000000000000000000000000000000000..8205b6667c0f1dcdff36fd2f2a45f0cb7d856d96 --- /dev/null +++ b/devops/docker/php8_0/www.conf @@ -0,0 +1,9 @@ +[www] +user = www-data +group = www-data +listen = 127.0.0.1:9000 +pm = dynamic +pm.max_children = 50 +pm.start_servers = 2 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 diff --git a/docker-compose.yml b/docker-compose.yml index b7ac4f464b3130889c1942eef6d4cda8a8912d23..f4ca7a18170e8f077ebd8cf1b2dd9e5c95c4ae8d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,6 +19,7 @@ services: - env entrypoint: devops/docker/${COMPOSER_VERSION:-composer1}/entrypoint.sh command: ["install"] + image: finc/composer php: build: devops/docker/${PHP_VERSION:-php7_2} @@ -30,6 +31,7 @@ services: - db entrypoint: devops/docker/${PHP_VERSION:-php7_2}/entrypoint.sh command: ["php-fpm"] + image: finc/${PHP_VERSION:-php7_2} httpd: build: devops/docker/httpd @@ -41,6 +43,7 @@ services: depends_on: - php tty: true + image: finc/httpd db: build: devops/docker/db/${DB_VERSION:-mariadb_10_3} @@ -59,6 +62,7 @@ services: "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci" ] + image: finc/db mail: image: useltmann/mailcollect:8-1 @@ -85,6 +89,7 @@ services: env_file: .env entrypoint: ["devops/docker/grunt/entrypoint.sh"] command: ["watch:scss"] + image: finc/grunt autoconfig: image: node:7.10.1-alpine diff --git a/local/config/vufind/config.ini b/local/config/vufind/config.ini index e40e2edcb2d6336de03bf49e86f3d16bafea0398..35ef9aa9cd83ff58b9f09ff9831084cc3ff8dd7b 100644 --- a/local/config/vufind/config.ini +++ b/local/config/vufind/config.ini @@ -1520,6 +1520,10 @@ skip_numeric = true ;file = /var/log/vufind.log:alert,error,notice,debug ;email = alerts@myuniversity.edu:alert-5,error-5 +; Log time measurement, see #24163, set file name +; also activate finc\HttpDebug\HttpService and finc\Log\PerformanceLogger in module.config.php +;file = data/cache/performance.csv:debug + ; Get URL from https://YOURSLACK.slack.com/apps/manage/custom-integrations ;slack = #channel_name:alert,error ;slackurl = https://hooks.slack.com/services/your-private-details diff --git a/local/languages/de.ini b/local/languages/de.ini index 19ccf522784f5622b8dd5c580198d3c146c4277c..783d95e6656c1c5260cc55151c151dab2ed66fb1 100644 --- a/local/languages/de.ini +++ b/local/languages/de.ini @@ -1848,7 +1848,7 @@ resolver_link_access_limited = "Im Campusnetz verfügbar" resolver_link_access_open = "verfügbar" resolver_link_access_unknown = "Titel ist beim Resolver-Service nicht bekannt" ; message to be shown upon empty resolver response -no_resolver_links = "Keine Online-Links verfügbar." +no_resolver_links = "Derzeit keine Zugangs-Links verfügbar." ; reset password reset_password_text = "Bitten füllen Sie dieses Formular aus, um Ihr Passwort zurücksetzen zu lassen. Sie erhalten an u.g. E-Mail-Adresse eine Benachrichtigung, nachdem wir das Passwort zurückgesetzt haben." @@ -2027,6 +2027,7 @@ skip-to = "Zu" Search type = "Suchtyp" License = "Lizenz" +LicenseIcon = "Lizenz Icon" fine_date_short = "Gebühr fällig" diff --git a/local/languages/en.ini b/local/languages/en.ini index cd1d79d9ad79a15933f21aa95c336c5f5078c468..475e3f954c65b69250af8f4bc130a6c4a9979bf7 100644 --- a/local/languages/en.ini +++ b/local/languages/en.ini @@ -1955,7 +1955,7 @@ resolver_link_access_limited = "Available in Campus network" resolver_link_access_open = "available" resolver_link_access_unknown = "Record unknown to resolver" ; message to be shown upon empty resolver response -no_resolver_links = "No online links available." +no_resolver_links = "No access link currently available." ; reset password reset_password_text = "Please complete the form below to reset your password. You will receive an email after we have completed resetting your password." @@ -2120,6 +2120,7 @@ skip-to = "Skip to " Skip to facet = "Skip to your selected search filter '%%filter_name%%'" License = "License" +LicenseIcon = "License icon" fine_date_short = "Fine Date" diff --git a/module/finc/config/dds-form.php b/module/finc/config/dds-form.php index ab191d6f2b64046c89de2d2075ee71173e3a5522..a035d80227a78fc8247cd562e3b44e0d718c9793 100644 --- a/module/finc/config/dds-form.php +++ b/module/finc/config/dds-form.php @@ -146,6 +146,7 @@ return [ ], ], ], + /* de_15: article is required */ 'article' => [ 'spec' => [ 'name' => 'article', @@ -154,11 +155,12 @@ return [ 'label' => 'form_field_title', ], 'attributes' => [ - 'required' => false, + 'required' => true, 'id' => 'article', ], ], ], + /* de_15: journal is required */ 'journal' => [ 'spec' => [ 'name' => 'journal', @@ -167,7 +169,7 @@ return [ 'label' => 'form_field_journal', ], 'attributes' => [ - 'required' => false, + 'required' => true, 'id' => 'journal', ], ], diff --git a/module/finc/config/module.config.php b/module/finc/config/module.config.php index c8dec95f9ecb81a88f96fb1af5b06978b0676291..ae9d02e7047e1f50349b46f5ceb7cad06906c509 100644 --- a/module/finc/config/module.config.php +++ b/module/finc/config/module.config.php @@ -17,7 +17,9 @@ $config = [ 'finc\ILS\Logic\Holds' => 'VuFind\ILS\Logic\LogicFactory', 'finc\Rewrite\EblRewrite' => 'finc\Rewrite\EblRewriteFactory', 'finc\Listener\I18nDataDirListener' => 'Laminas\ServiceManager\Factory\InvokableFactory', - 'finc\Cover\Loader' => 'VuFind\Cover\LoaderFactory' + 'finc\Cover\Loader' => 'VuFind\Cover\LoaderFactory', + //'finc\HttpDebug\HttpService' => 'VuFind\Service\HttpServiceFactory', + //'finc\Log\PerformanceLogger' => 'VuFind\Log\LoggerFactory' ], 'delegators' => [ 'VuFindSearch\Service' => [ @@ -33,7 +35,9 @@ $config = [ 'VuFind\Cache\Manager' => 'finc\Cache\Manager', 'VuFind\ILS\Connection' => 'finc\ILS\Connection', 'VuFind\ILS\Logic\Holds' => 'finc\ILS\Logic\Holds', - 'VuFind\Cover\Loader' => 'finc\Cover\Loader' + 'VuFind\Cover\Loader' => 'finc\Cover\Loader', + // 'VuFindHttp\HttpService' => 'finc\HttpDebug\HttpService', + // 'VuFind\Log\Logger' => 'finc\Log\PerformanceLogger' ] ], 'controllers' => [ diff --git a/module/finc/src/finc/Controller/Admin/I18nController.php b/module/finc/src/finc/Controller/Admin/I18nController.php index d6240cb5bf686d0e74da1e9e94dab0fa730b1f26..6d7860f2ab161c27a508b769a3f10f306d0ac776 100644 --- a/module/finc/src/finc/Controller/Admin/I18nController.php +++ b/module/finc/src/finc/Controller/Admin/I18nController.php @@ -103,6 +103,7 @@ class I18nController extends AbstractAdmin $translations = $this->getTranslations(); $defaultTranslations = $this->getDefaultTranslations(); + $domains = []; foreach (array_keys($translations[$this->locale]) as $name) { $selected = $name === $domain; $domains[$name] = compact('name', 'selected'); diff --git a/module/finc/src/finc/HttpDebug/HttpService.php b/module/finc/src/finc/HttpDebug/HttpService.php new file mode 100644 index 0000000000000000000000000000000000000000..af7e88c3c46bdf6e13a274cefccb52aba8692274 --- /dev/null +++ b/module/finc/src/finc/HttpDebug/HttpService.php @@ -0,0 +1,63 @@ +<?php +/** + * Copyright (C) 2023 Leipzig University Library + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see <http://www.gnu.org/licenses/>. + * + * @category Finc + * @package Http + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development + */ +namespace finc\HttpDebug; + +use Laminas\Http\Client; +use Laminas\Http\Response; + +/** + * VuFind HTTP service. + * + * @category VuFind + * @package Http + * @author David Maus <maus@hab.de> + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development + */ +class HttpService extends \VuFindHttp\HttpService implements \Laminas\Log\LoggerAwareInterface +{ + use \VuFind\Log\LoggerAwareTrait; + + /** + * Send Request + * + * @param Client $client http client + * + * @return Response + */ + protected function send(\Laminas\Http\Client $client) + { + $time = microtime(true); + $response = parent::send($client); + $time = microtime(true) - $time; + + $this->log( + 'performance', + ';' . $client->getUri() . ';' . intval($time * 1000) . ';' + ); + + return $response; + } +} diff --git a/module/finc/src/finc/ILS/Driver/PAIA.php b/module/finc/src/finc/ILS/Driver/PAIA.php index f19d32a0c96fd860e9d3d49607cb6105dd6fb337..4d1ec00d5f452ec279be8c382b79f741d2e5a2fd 100644 --- a/module/finc/src/finc/ILS/Driver/PAIA.php +++ b/module/finc/src/finc/ILS/Driver/PAIA.php @@ -1514,9 +1514,10 @@ class PAIA extends \VuFind\ILS\Driver\PAIA || (isset($values['address']) && !$this->paiaCheckScope(self::SCOPE_UPDATE_PATRON_ADDRESS)) ) { - throw new ILSException( - 'You are not allowed to update the desired patron information.' - ); + return [ + 'success' => false, + 'sysMessage' => 'Not allowed to update patron information.' + ]; } } diff --git a/module/finc/src/finc/ILS/Logic/Holds.php b/module/finc/src/finc/ILS/Logic/Holds.php index cafdd9476246d5001e6766221cef2aa4f3404484..c2c2d1db1df090c7f58dc1cb82ec7797652724a5 100644 --- a/module/finc/src/finc/ILS/Logic/Holds.php +++ b/module/finc/src/finc/ILS/Logic/Holds.php @@ -158,7 +158,7 @@ class Holds extends \VuFind\ILS\Logic\Holds = $patron && $this->catalog->checkCapability( $grb, - compact($patron) + compact('patron') ) ? $this->catalog->getRequestBlocks($patron) : false; diff --git a/module/finc/src/finc/Log/PerformanceLogger.php b/module/finc/src/finc/Log/PerformanceLogger.php new file mode 100644 index 0000000000000000000000000000000000000000..8bd35e2b1b1b5cd04e0dcc6f2b320db96ea50b01 --- /dev/null +++ b/module/finc/src/finc/Log/PerformanceLogger.php @@ -0,0 +1,83 @@ +<?php +/** + * Finc Logger for time measurement + * + * PHP version 7 + * + * Copyright (C) 2023 Leipzig University Library + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see <http://www.gnu.org/licenses/>. + * + * @category Finc + * @package Error_Logging + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development + */ +namespace finc\Log; + +use VuFind\Log\Logger as BaseLogger; + +/** + * This class wraps the BaseLogger class to allow for log verbosity + * + * @category VuFind + * @package Error_Logging + * @author Chris Hallberg <challber@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ +class PerformanceLogger extends BaseLogger +{ + public static $cache = []; + + /** + * {@inheritDoc} + * + * @param int $priority Priority + * @param mixed $message Message + * @param array|Traversable $extra Extras + * + * @return Logger + */ + public function log($priority, $message, $extra = []) + { + // ignore complex messages + if (!is_array($message)) { + if (!isset($extra['qtime'])) { + // cache until query was finished + array_push(self::$cache, $message); + } else { + // flush to log + $message = ';' . implode(" ", self::$cache) . ';' . $extra['qtime'] . ';'; + self::$cache = []; + return parent::log($priority, $message); + } + } + return $this; + } + + /** + * Log time measurement + * + * @param string $message log message + * @param array $extra additional values + * + * @return $this|PerformanceLogger + */ + public function performance($message, $extra = []) + { + return parent::log(self::DEBUG, $message, $extra); + } +} diff --git a/module/finc/src/finc/View/Helper/Root/EnhancedRenderArray.php b/module/finc/src/finc/View/Helper/Root/EnhancedRenderArray.php index 2cebac8943844ce9fcaf00447ca4d1c99732341d..526fe8ca69d562e2da4f6f4a7a49c61386513bcc 100644 --- a/module/finc/src/finc/View/Helper/Root/EnhancedRenderArray.php +++ b/module/finc/src/finc/View/Helper/Root/EnhancedRenderArray.php @@ -45,22 +45,25 @@ class EnhancedRenderArray extends AbstractHelper /** * Render a portion of an array. * - * @param string $tpl A template for displaying each row. This should - * include %%KEY&&, %%LABEL%%, %%VALUE%% and %%DISABLED%% placeholders - * @param array $arr An associative array of possible values to display - * @param array $rows A label => profile key associative array specifying + * @param string $tpl1 A template for displaying each row as read-only value. + * This should include %%LABEL%% and %%VALUE%% placeholders + * @param string $tpl2 A template for displaying each row as input field. + * A 2-dim-array including arrays for every line with label and autocomplete + * This should include %%KEY&&, %%LABEL%%, %%VALUE%%, %%AUTOCOMPLETE%% + * @param array $arr An associative array of possible values to display + * @param array $arrays A label => profile key associative array specifying * which rows of $arr to display * * @return string */ - public function __invoke($tpl1, $tpl2, $arr, $rows) + public function __invoke($tpl1, $tpl2, $arr, $arrays) { $html = ''; - foreach ($rows as $label => $key) { + foreach ($arrays as $key => $row) { $html .= str_replace( - ['%%KEY%%', '%%LABEL%%', '%%VALUE%%'], - [$key, $label, $this->view->escapeHtml((isset($arr[$key]) ? $arr[$key] : ''))], - (isset($arr['disabled'][$key]) && ($arr['disabled'][$key] === true) ? $tpl1 : $tpl2) + ['%%KEY%%', '%%LABEL%%', '%%VALUE%%', '%%AUTOCOMPLETE%%'], + [$key, $row['label'], $this->view->escapeHtml(($arr[$key] ?? '')), $row['autocomplete']], + (isset($arr['disabled'][$key]) && ($arr['disabled'][$key] === true) ? $tpl1 : $tpl2) ); } return $html; diff --git a/module/finc/tests/.phpunit.result.cache b/module/finc/tests/.phpunit.result.cache deleted file mode 100644 index be8380b33086124bb39bd1e3e151c42b742fb527..0000000000000000000000000000000000000000 --- a/module/finc/tests/.phpunit.result.cache +++ /dev/null @@ -1 +0,0 @@ -C:37:"PHPUnit\Runner\DefaultTestResultCache":5538:{a:2:{s:7:"defects";a:1:{s:65:"FincTest\View\Helper\Root\OpenUrlTest::testValidateParamsEzbFalse";i:3;}s:5:"times";a:70:{s:53:"fincTest\Config\SearchSpecsReaderTest::testParentYaml";d:0.442;s:58:"fincTest\Config\SearchSpecsReaderTest::testSearchSpecsRead";d:0.171;s:58:"fincTest\Config\SearchSpecsReaderTest::testMissingFileRead";d:0.001;s:51:"fincTest\Config\SearchSpecsReaderTest::testYamlLoad";d:0.002;s:52:"fincTest\Config\SearchSpecsReaderTest::testYamlMerge";d:0.001;s:50:"VuFindTest\ILS\Driver\PAIATest::testChangePassword";d:0.03;s:40:"VuFindTest\ILS\Driver\PAIATest::testFees";d:0.005;s:41:"VuFindTest\ILS\Driver\PAIATest::testHolds";d:0.004;s:44:"VuFindTest\ILS\Driver\PAIATest::testRequests";d:0.004;s:48:"VuFindTest\ILS\Driver\PAIATest::testTransactions";d:0.008;s:43:"VuFindTest\ILS\Driver\PAIATest::testProfile";d:0.004;s:48:"VuFindTest\ILS\Driver\PAIATest::testValidRequest";d:0.003;s:48:"VuFindTest\ILS\Driver\PAIATest::testRenewDetails";d:0.001;s:45:"VuFindTest\ILS\Driver\PAIATest::testPlaceHold";d:0.004;s:64:"VuFindTest\ILS\Driver\PAIATest::testPlaceStorageRetrievalRequest";d:0.004;s:41:"VuFindTest\ILS\Driver\PAIATest::testRenew";d:0.006;s:56:"VuFindTest\ILS\Driver\PAIATest::testMissingConfiguration";d:0.001;s:66:"VuFindTest\ILS\Driver\PAIAFincTest::testMapOptionsPickupBranchTrue";d:0;s:57:"VuFindTest\ILS\Driver\PAIAFincTest::testMapOptionsNewTrue";d:0;s:79:"VuFindTest\ILS\Driver\PAIAFincTest::testMapOptionsPickupBranchFalseNoConditions";d:0.001;s:81:"VuFindTest\ILS\Driver\PAIAFincTest::testMapOptionsPickupBranchTrueUnknownOptionId";d:0;s:83:"VuFindTest\ILS\Driver\PAIAFincTest::testGetMyHoldsWithoutOptionConfigurationDefined";d:0.004;s:76:"VuFindTest\ILS\Driver\PAIAFincTest::testGetMyHoldsWithoutPaiaResponseOptions";d:0.006;s:69:"VuFindTest\ILS\Driver\PAIAFincTest::testGetMyHoldsAllowUnknownOptions";d:0.004;s:63:"VuFindTest\ILS\Driver\PAIAFincTest::testGetMyHoldsWrongInstance";d:0.004;s:66:"VuFindTest\ILS\Driver\PAIAFincTest::testGetMyHoldsWithPickUpBranch";d:0.006;s:73:"VuFindTest\ILS\Driver\PAIAFincTest::testGetMyHoldsWithAnotherPickUpBranch";d:0.004;s:81:"VuFindTest\ILS\Driver\PAIAFincTest::testGetMyHoldsWithMultipleOptionsPickUpBranch";d:0.004;s:63:"VuFindTest\ILS\Driver\PAIAFincTest::testgetOptionsReturnsIDTrue";d:0.002;s:68:"VuFindTest\ILS\Driver\PAIAFincTest::testgetOptionsNotOnlyFirstButAll";d:0.002;s:66:"VuFindTest\ILS\Driver\PAIAFincTest::testgetOptionsReturnsLabelTrue";d:0.004;s:67:"VuFindTest\ILS\Driver\PAIAFincTest::testgetOptionsReturnsEmptyArray";d:0.003;s:58:"VuFindTest\ILS\Driver\PAIAFincTest::testCallMapOptionsTrue";d:0.005;s:59:"VuFindTest\ILS\Driver\PAIAFincTest::testCallMapOptionsFalse";d:0.007;s:54:"VuFindTest\ILS\Driver\PAIAFincTest::testChangePassword";d:0.004;s:44:"VuFindTest\ILS\Driver\PAIAFincTest::testFees";d:0.004;s:45:"VuFindTest\ILS\Driver\PAIAFincTest::testHolds";d:0.006;s:48:"VuFindTest\ILS\Driver\PAIAFincTest::testRequests";d:0.004;s:52:"VuFindTest\ILS\Driver\PAIAFincTest::testTransactions";d:0.008;s:47:"VuFindTest\ILS\Driver\PAIAFincTest::testProfile";d:0.005;s:52:"VuFindTest\ILS\Driver\PAIAFincTest::testValidRequest";d:0.003;s:52:"VuFindTest\ILS\Driver\PAIAFincTest::testRenewDetails";d:0.001;s:49:"VuFindTest\ILS\Driver\PAIAFincTest::testPlaceHold";d:0.004;s:68:"VuFindTest\ILS\Driver\PAIAFincTest::testPlaceStorageRetrievalRequest";d:0.009;s:45:"VuFindTest\ILS\Driver\PAIAFincTest::testRenew";d:0.004;s:60:"VuFindTest\ILS\Driver\PAIAFincTest::testMissingConfiguration";d:0;s:64:"fincTest\RecordDriver\SolrMarcNewerPreviousTest::testNewerTitles";d:0.015;s:67:"fincTest\RecordDriver\SolrMarcNewerPreviousTest::testPreviousTitles";d:0.011;s:64:"fincTest\RecordDriver\SolrMarcNewerPreviousTest::testGetUniqueId";d:0;s:65:"FincTest\View\Helper\Root\ExternalCatalogueLinkTest::testGetLinks";d:0.004;s:66:"FincTest\View\Helper\Root\OpenUrlTest::testAddCustomParamsNoParams";d:0.03;s:70:"FincTest\View\Helper\Root\OpenUrlTest::testAddCustomStaticParamsForEzb";d:0.005;s:75:"FincTest\View\Helper\Root\OpenUrlTest::testDONTOverrideExistingParamsForEzb";d:0.005;s:71:"FincTest\View\Helper\Root\OpenUrlTest::testAddCustomStaticParamsForRedi";d:0.005;s:76:"FincTest\View\Helper\Root\OpenUrlTest::testDONTOverrideExistingParamsForRedi";d:0.005;s:71:"FincTest\View\Helper\Root\OpenUrlTest::testAddCustomDynamicParamsForEzb";d:0.005;s:72:"FincTest\View\Helper\Root\OpenUrlTest::testAddCustomDynamicParamsForRedi";d:0.005;s:65:"FincTest\View\Helper\Root\OpenUrlTest::testValidateParamsEzbFalse";d:0.005;s:64:"FincTest\View\Helper\Root\OpenUrlTest::testValidateParamsEzbTrue";d:0.027;s:63:"FincTest\View\Helper\Root\OpenUrlTest::testIsActiveIsIdempotent";d:0.008;s:63:"FincTest\View\Helper\Root\OpenUrlTest::testCheckContextDefaults";d:0.028;s:68:"FincTest\View\Helper\Root\OpenUrlTest::testCheckContextWithOverrides";d:0.005;s:60:"FincTest\View\Helper\Root\OpenUrlTest::testCheckContextNoUrl";d:0.005;s:73:"FincTest\View\Helper\Root\OpenUrlTest::testCheckExcludedRecordsRulesFalse";d:0.003;s:72:"FincTest\View\Helper\Root\OpenUrlTest::testCheckExcludedRecordsRulesTrue";d:0.003;s:93:"FincTest\View\Helper\Root\OpenUrlTest::testCheckExcludedRecordsRulesFalseDueToWildcardFailure";d:0.031;s:74:"FincTest\View\Helper\Root\OpenUrlTest::testCheckSupportedRecordsRulesFalse";d:0.003;s:91:"FincTest\View\Helper\Root\OpenUrlTest::testCheckSupportedRecordsRulesWithWildcardStillFalse";d:0.003;s:73:"FincTest\View\Helper\Root\OpenUrlTest::testCheckSupportedRecordsRulesTrue";d:0.003;s:67:"FincTest\View\Helper\Root\OpenUrlTest::testRecordDriverClassInRules";d:0.005;}}} \ No newline at end of file diff --git a/module/finc/tests/selenium/docker-compose.yaml b/module/finc/tests/selenium/docker-compose.yaml index fc53c11bc8a1493fa0b661d68e941c2f2e1b7197..3c4432647985df39b2640a2e87d831c614b94b5f 100755 --- a/module/finc/tests/selenium/docker-compose.yaml +++ b/module/finc/tests/selenium/docker-compose.yaml @@ -10,16 +10,16 @@ services: - "4444:4444" extra_hosts: - "host.docker.internal:10.111.0.1" - chrome: - image: selenium/node-chrome - depends_on: - - selenium-hub - environment: - - SE_EVENT_BUS_HOST=selenium-hub - - SE_EVENT_BUS_PUBLISH_PORT=4442 - - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 - extra_hosts: - - "host.docker.internal:10.111.0.1" + #chrome: + # image: selenium/node-chrome + # depends_on: + # - selenium-hub + # environment: + # - SE_EVENT_BUS_HOST=selenium-hub + # - SE_EVENT_BUS_PUBLISH_PORT=4442 + # - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 + # extra_hosts: + # - "host.docker.internal:10.111.0.1" firefox: image: selenium/node-firefox depends_on: @@ -31,7 +31,7 @@ services: extra_hosts: - "host.docker.internal:10.111.0.1" php: - image: php:7.3-fpm + image: php:8.0-fpm working_dir: /usr/local/vufind depends_on: - selenium-hub diff --git a/module/finc/tests/selenium/tests/de_15/AccountTest.php b/module/finc/tests/selenium/tests/de_15/AccountTest.php index 202a22fd98efd627810e2ece5d4118e3c61853eb..f6f5b7e85d0941721a4e86366a846f91635439ae 100644 --- a/module/finc/tests/selenium/tests/de_15/AccountTest.php +++ b/module/finc/tests/selenium/tests/de_15/AccountTest.php @@ -47,8 +47,7 @@ class AccountTest extends FincBase #region helper methods protected function changeLanguage($lang = 'de') { - $this->wd->get(self::$host . self::$port); - $this->wd->executeScript("document.langForm.mylang.value='" . $lang . "';document.langForm.submit();"); + $this->wd->get(self::$host . self::$port . '/?lng=' . $lang); $this->waitForPartialLinkText('Katalogsuche'); } } diff --git a/module/finc/tests/selenium/tests/finc/FincBase.php b/module/finc/tests/selenium/tests/finc/FincBase.php index 96047cad735c7215f48c034174769a73c2051605..3444f950c58123b601c8a24cd75971307a67c80e 100644 --- a/module/finc/tests/selenium/tests/finc/FincBase.php +++ b/module/finc/tests/selenium/tests/finc/FincBase.php @@ -17,7 +17,8 @@ class FincBase extends AbstractTestCase public function initBaseUrl() { // Set base url according to environment - switch (ConfigProvider::getInstance()->env) { + $env = ConfigProvider::getInstance()->env; + switch ($env) { case 'staging': self::$host = 'https://staging.finc.info/vufind2/local'; break; @@ -25,7 +26,8 @@ class FincBase extends AbstractTestCase self::$host = 'http://host.docker.internal'; break; default: - throw new \RuntimeException(sprintf('Unknown environment "%s"', ConfigProvider::getInstance()->env)); + // assume alpha with syntax [instance]/[issue number] + self::$host = 'https://alpha.finc.info/vufind2/' . $env; } $this->debug('Base URL set to "%s"', self::$host); diff --git a/module/finc/tests/selenium/tests/performance/SearchBaseTest.php b/module/finc/tests/selenium/tests/performance/SearchBaseTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4f3795f996ecd34eb25d88b09abd5d9f0a90ae83 --- /dev/null +++ b/module/finc/tests/selenium/tests/performance/SearchBaseTest.php @@ -0,0 +1,113 @@ +<?php +/** + * Copyright (C) 2023 Leipzig University Library + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see <http://www.gnu.org/licenses/>. + * + * Run for local with via: + * docker exec -it selenium_php_1 sh -c "./vendor/bin/steward run local firefox --group performance-static --server-url http://selenium:4444/wd/hub -vvv" + * + * Run for alpha with via: + * docker exec -it selenium_php_1 sh -c "./vendor/bin/steward run de_15/12345 firefox --group performance-static --server-url http://selenium:4444/wd/hub -vvv" + * + * @category Finc + * @package Test + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development + */ +namespace Selenium\performance; + +use Lmc\Steward\ConfigProvider; +use Selenium\finc\FincBase; + +class SearchBaseTest extends FincBase +{ + public static $words = [ + 'Antenne', + 'Bach', + 'Cello', + 'Dach', + 'Eiche', + 'Fach', + 'Gans', + 'Haus', + 'Igel', + 'Jagd', + 'Kabel', + 'Lampe', + 'Maus', + 'Nacht', + 'Ohr', + 'Pferd', + 'Quelle', + 'Rabe', + 'Sonne', + 'Tisch', + 'Uhr', + 'Vogel', + 'Wald', + 'Xylophon', + 'Yoga', + 'Zebra' + ]; + + const STATIC_SEARCH_TERM = 'Medienkritik'; + + /** + * @before + */ + public function initBaseUrl() + { + // Set base url according to environment + $env = ConfigProvider::getInstance()->env; + switch ($env) { + case 'staging': + self::$host = 'https://staging.finc.info/vufind2/local'; + break; + case 'local': + self::$host = 'http://host.docker.internal'; + break; + default: + // assume alpha with syntax [instance]/[issue number] + self::$host = 'https://alpha.finc.info/vufind2/' . $env; + } + + $this->debug('Base URL set to "%s"', self::$host); + + if (ConfigProvider::getInstance()->env === 'production') { + $this->warn('The tests are run against production, so be careful!'); + } + } + + #region helper methods + protected function getBasePath() : string + { + return self::$host . self::$port . '/Search/Results?lookfor='; + } + + protected function getSearchTerm(bool $isDynamicSearch = true) : string + { + if ($isDynamicSearch) { + $rand_keys = array_rand(self::$words, 2); + $searchTerm = self::$words[$rand_keys[0]] . " " . self::$words[$rand_keys[1]]; + } else { + $searchTerm = self::STATIC_SEARCH_TERM; + } + + return urlencode($searchTerm); + } + + #endregion +} diff --git a/module/finc/tests/selenium/tests/performance/SearchRandomTest.php b/module/finc/tests/selenium/tests/performance/SearchRandomTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7520fdd3ddf08055a40dcb509e1271800a326736 --- /dev/null +++ b/module/finc/tests/selenium/tests/performance/SearchRandomTest.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright (C) 2023 Leipzig University Library + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see <http://www.gnu.org/licenses/>. + * + * Run for local with via: + * docker exec -it selenium_php_1 sh -c "./vendor/bin/steward run local firefox --group performance-random --server-url http://selenium:4444/wd/hub -vvv" + * + * Run for alpha with via: + * docker exec -it selenium_php_1 sh -c "./vendor/bin/steward run de_15/12345 firefox --group performance-random --server-url http://selenium:4444/wd/hub -vvv" + * + * @category Finc + * @package Test + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development + */ +namespace Selenium\performance; + +use Lmc\Steward\ConfigProvider; + +/** + * @group performance + * @group performance-random + */ +class SearchRandomTest extends SearchBaseTest +{ + /** + * @group performance + * @group performance-random + */ + public function testRandomSearches() + { + $start = floor(microtime(true) * 1000); + for ($i = 1; $i <= 100; $i++) { + $this->debug("Executing test no. $i"); + $this->wd->get($this->getBasePath() . $this->getSearchTerm()); + $this->waitForClass('result-body'); + } + $end = floor(microtime(true) * 1000); + $durationText = "Duration of random searches: " . ((intval($end)) - (intval($start)) . " ms"); + $this->debug($durationText); + } +} diff --git a/module/finc/tests/selenium/tests/performance/SearchStaticTest.php b/module/finc/tests/selenium/tests/performance/SearchStaticTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0d8c136241139e6c080e37ce1f4a400c60390a5e --- /dev/null +++ b/module/finc/tests/selenium/tests/performance/SearchStaticTest.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright (C) 2023 Leipzig University Library + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see <http://www.gnu.org/licenses/>. + * + * Run for local with via: + * docker exec -it selenium_php_1 sh -c "./vendor/bin/steward run local firefox --group performance-static --server-url http://selenium:4444/wd/hub -vvv" + * + * Run for alpha with via: + * docker exec -it selenium_php_1 sh -c "./vendor/bin/steward run de_15/12345 firefox --group performance-static --server-url http://selenium:4444/wd/hub -vvv" + * + * @category Finc + * @package Test + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development + */ +namespace Selenium\performance; + +use Lmc\Steward\ConfigProvider; + +/** + * @group performance + * @group performance-static + */ +class SearchStaticTest extends SearchBaseTest +{ + /** + * @group performance + * @group performance-static + */ + public function testStaticSearches() + { + $start = floor(microtime(true) * 1000); + for ($i = 1; $i <= 100; $i++) { + $this->debug("Executing test no. $i"); + $this->wd->get($this->getBasePath() . $this->getSearchTerm(false)); + $this->waitForClass('result-body'); + } + $end = floor(microtime(true) * 1000); + $durationText = "Duration of static searches: " . ((intval($end)) - (intval($start)) . " ms"); + $this->debug($durationText); + } +} diff --git a/themes/finc/scss/_customVariables.scss b/themes/finc/scss/_customVariables.scss index ecf5718bafa4876faf97f2515337d7ff60bee656..8a18c4aa6020f37255be86ae286d2daa5b109e17 100644 --- a/themes/finc/scss/_customVariables.scss +++ b/themes/finc/scss/_customVariables.scss @@ -465,8 +465,8 @@ $label-edit-favorites-list-padding-left: 0 !default; $input-border-focus: $brand-primary !default; // Inputs with labels -- top margin for better alignment $input-top-margin: .2rem !default; -// Invalid input AND textarea elements -$input-textarea-invalid-margin-right: 2px !default; +// Input AND textarea elements +$input-textarea-margin-right: 2px !default; // Invalid input highlighting on focus $input-invalid-focus-border-color: $brand-danger-transparent !default; $input-invalid-focus-box-shadow: 0 0 2px 1px $brand-danger-transparent !default; diff --git a/themes/finc/scss/components/_forms.scss b/themes/finc/scss/components/_forms.scss index 4a12349cebc9fe6cf654cbc74daa3d5274f0348f..50021e7047f40b815017853e4c57021fe3482857 100644 --- a/themes/finc/scss/components/_forms.scss +++ b/themes/finc/scss/components/_forms.scss @@ -139,6 +139,9 @@ label { // ***************************************************************** input { + // Same variable used for textarea as well! + margin-right: $input-textarea-margin-right; + // Set max-width to make sure boxes don't bleed over // the edge on XS (e.g. acquisitionpda, source_id:3) - same // variable used on textarea and select @@ -190,8 +193,6 @@ input { // show red border only when submitted empty or when in focus &:invalid { box-shadow: inherit; - // Same variable used for textarea as well! - margin-right: $input-textarea-invalid-margin-right; } &:focus { @@ -280,17 +281,15 @@ select { // ***************************************************************** textarea { + // Same variable used for input as well! + margin-right: $input-textarea-margin-right; + // Set max-width to make sure boxes don't bleed over // the edge on XS (e.g. acquisitionpda, source_id:3) - same // variable used on input and select @media (max-width: $screen-xs-max) { max-width: $input-select-textarea-xs-max-width; } - - &:invalid { - // Same variable used for input as well! - margin-right: $input-textarea-invalid-margin-right; - } } diff --git a/themes/finc/templates/RecordDriver/DefaultRecord/cover.phtml b/themes/finc/templates/RecordDriver/DefaultRecord/cover.phtml index 21d893f58b01b0894a6b6c40436df7527ba9722e..f7714d5a5d7762e5773da2e5bd051a18d3fcb1e3 100644 --- a/themes/finc/templates/RecordDriver/DefaultRecord/cover.phtml +++ b/themes/finc/templates/RecordDriver/DefaultRecord/cover.phtml @@ -23,7 +23,7 @@ aria-label="<?=$this->transEscAttr('Link-to')?> <?=$this->transEscAttr('Cover Image')?> <?=$this->transEscAttr('of')?> <?=$title?>" > <?php endif; ?> - <img alt="<?=$alt?>" <?php if ($linkPreview): ?>data-linkpreview="true" <?php endif; ?>class="recordcover" src="<?=$this->escapeHtmlAttr(($cover)); ?>" /> + <img alt="<?=$alt?>" <?php if ($linkPreview): ?>data-linkpreview="true" <?php endif; ?>class="recordcover" src="<?=$this->escapeHtmlAttr(($cover)); ?>"> <?php if ($this->link): ?> </a> <?php @@ -34,7 +34,7 @@ JS; <?=$this->inlineScript(\Laminas\View\Helper\HeadScript::SCRIPT, $coverDetailScript, 'SET'); ?> <?php endif; ?> <?php elseif ($cover === false): ?> - <img src="<?=$this->url('cover-unavailable')?>" <?php if ($linkPreview): ?>data-linkpreview="true" <?php endif; ?>class="nocover" alt="<?=$this->transEscAttr('No Cover Image')?>" aria-hidden="true" tabindex="-1" /> + <img src="<?=$this->url('cover-unavailable')?>" <?php if ($linkPreview): ?>data-linkpreview="true" <?php endif; ?>class="nocover" alt="<?=$this->transEscAttr('No Cover Image')?>" aria-hidden="true" tabindex="-1"> <?php else: ?> <?php /* load cover by ajax */ ?> <div id="<?=$coverId?>" class="ajaxcover"> @@ -42,7 +42,7 @@ JS; <div class="cover-container"> <?=$this->setIconText = false;?> <a class="coverlink hidden" href="javascript:" aria-hidden="true" tabindex="-1"> - <img <?php if ($linkPreview): ?>data-linkpreview="true" <?php endif; ?> class="recordcover ajax" src="<?=$this->url('cover-unavailable')?>" alt="<?=$this->escapeHtmlAttr($alt); ?>" /> + <img <?php if ($linkPreview): ?>data-linkpreview="true" <?php endif; ?> class="recordcover ajax" src="<?=$this->url('cover-unavailable')?>" alt="<?=$this->escapeHtmlAttr($alt); ?>"> <?php $coverScript = <<<JS loadCoverByElement( diff --git a/themes/finc/templates/RecordDriver/DefaultRecord/list-entry.phtml b/themes/finc/templates/RecordDriver/DefaultRecord/list-entry.phtml index 07cc27b547f514fcc90404a656b910234dd43399..26adabc9907a1e5e9277d87307b516bd74e54541 100644 --- a/themes/finc/templates/RecordDriver/DefaultRecord/list-entry.phtml +++ b/themes/finc/templates/RecordDriver/DefaultRecord/list-entry.phtml @@ -78,10 +78,6 @@ </div> <div class="resultItemLine2"> <?php if ($this->driver->isCollection()): ?> - <?php // finc: add closing div and header #23220 - was missing in #19396 ff. - // just hotfix - will be improved with #24265 ?> - </div> - </header> <?=implode('<br>', array_map([$this, 'escapeHtml'], $this->driver->getSummary())); ?> <?php else: ?> <?php diff --git a/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml b/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml index 3f3e2d21a6e3e9d0da658e4627ed5de24076dfad..c5f6bf12ef84cffb980062e5e86b6b72c2b2d807 100644 --- a/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml +++ b/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml @@ -221,7 +221,8 @@ if ($cover): <?php if ($this->cart()->isActiveInSearch() && isset($this->params) && $this->params->getOptions()->supportsCart() && $this->cart()->isActive()): ?> <?php /* finc: remove break after bookbag #22379 */ ?> - <?=$this->render('record/cart-buttons.phtml', ['id' => $this->driver->getUniqueId(), 'source' => $this->driver->getSourceIdentifier()]); ?> + <?php /* finc adds callFromTemplate for setting aria-describedby if use of book bag is with checkboxes #24358 */ ?> + <?=$this->render('record/cart-buttons.phtml', ['id' => $this->driver->getUniqueId(), 'source' => $this->driver->getSourceIdentifier(), 'callFromTemplate' => 'resultList']); ?> <?php endif; ?> <?php if ($this->userlist()->getMode() !== 'disabled'): ?> diff --git a/themes/finc/templates/RecordDriver/SolrAI/result-list.phtml b/themes/finc/templates/RecordDriver/SolrAI/result-list.phtml index 17bc7f3cac90a1c7db0286dd34061d585dc23768..d55926fcf661073a5df48c2ab9359b490ed9e3b5 100644 --- a/themes/finc/templates/RecordDriver/SolrAI/result-list.phtml +++ b/themes/finc/templates/RecordDriver/SolrAI/result-list.phtml @@ -204,7 +204,8 @@ if ($cover): <?php if ($this->cart()->isActiveInSearch() && isset($this->params) && $this->params->getOptions()->supportsCart() && $this->cart()->isActive()): ?> <?php /* finc: remove break after bookbag #22379 */ ?> - <?=$this->render('record/cart-buttons.phtml', ['id' => $this->driver->getUniqueId(), 'source' => $this->driver->getSourceIdentifier()]); ?> + <?php /* finc adds callFromTemplate for setting aria-describedby if use of book bag is with checkboxes #24358 */ ?> + <?=$this->render('record/cart-buttons.phtml', ['id' => $this->driver->getUniqueId(), 'source' => $this->driver->getSourceIdentifier(), 'callFromTemplate' => 'resultList' ]); ?> <?php endif; ?> <?php if ($this->userlist()->getMode() !== 'disabled'): ?> diff --git a/themes/finc/templates/RecordDriver/SolrDico/data-license.phtml b/themes/finc/templates/RecordDriver/SolrDico/data-license.phtml index ed4bbae530e134b5eae9cf18565c6f5122b0be1b..43009e3464fdaed01dc6515a18d8736afd95c603 100644 --- a/themes/finc/templates/RecordDriver/SolrDico/data-license.phtml +++ b/themes/finc/templates/RecordDriver/SolrDico/data-license.phtml @@ -4,7 +4,8 @@ <?php ob_start() ?> <?=$label ?> <?php if (isset($data['icon'])): ?> - <img class="collection-data collection-licence-image" src="<?=$data['icon']?>"/> + <?php /* finc: add alt-Tag #19697 */ ?> + <img class="collection-data collection-licence-image" src="<?=$data['icon']?>" alt="<?=$this->transEsc('LicenseIcon')?>"/> <?php endif; ?> <?php $label = ob_get_contents(); ob_end_clean(); diff --git a/themes/finc/templates/RecordTab/collectionlist.phtml b/themes/finc/templates/RecordTab/collectionlist.phtml index b44ba7c72df25decde5f1f7402a69fc8d8f36375..94cc9f912fa0f19bb5547bf4b4dd35b77b32cbe2 100644 --- a/themes/finc/templates/RecordTab/collectionlist.phtml +++ b/themes/finc/templates/RecordTab/collectionlist.phtml @@ -96,11 +96,12 @@ <?php endif; ?> */?> </div> - <form class="form-inline" method="post" name="bulkActionForm" action="<?=$this->url('cart-searchresultsbulk')?>"> + <?php /* de_15: do NOT render search/list-list into the <form>-element, it is causing W3C errors #19697 */ ?> + <?php /* <form class="form-inline" method="post" name="bulkActionForm" action="<?=$this->url('cart-searchresultsbulk')?>"> */ ?> <?=$this->context($this)->renderInContext('search/bulk-action-buttons.phtml', $searchDetails + ['idPrefix' => ''])?> <?=$this->render('search/list-' . $results->getParams()->getView() . '.phtml', $searchDetails)?> <?=$this->paginationControl($results->getPaginator(), 'Sliding', 'search/pagination.phtml', ['results' => $results])?> - </form> + <?php /* </form> */ ?> <?php else: ?> <?php /* finc: change h4 to h3 */ ?> <h3><?=$this->transEsc($params->getDisplayQuery() || ($filterCount ?? 0) > 0 ? 'nohit_heading' : 'collection_empty')?></h3> diff --git a/themes/finc/templates/cart/contents.phtml b/themes/finc/templates/cart/contents.phtml index 7eb666ee295792e8e8b5fa4dcac5a8036aa8f44a..9c08eb074bb04d1006c0d14d99989c1d93fcb530 100644 --- a/themes/finc/templates/cart/contents.phtml +++ b/themes/finc/templates/cart/contents.phtml @@ -1,7 +1,7 @@ <!-- finc: cart - contents --> <?php $records = $this->cart()->getRecordDetails(); if (!empty($records)): ?> - <hr/> + <hr> <ul class="list-unstyled"> <?php foreach ($records as $i => $record): ?> <li> diff --git a/themes/finc/templates/layout/layout.phtml b/themes/finc/templates/layout/layout.phtml index 4c24153662c9b61c0b1e5bb87f52755416f2c3cb..7a385760bedc49ad6cb866767c7b9bcb22ab55b7 100644 --- a/themes/finc/templates/layout/layout.phtml +++ b/themes/finc/templates/layout/layout.phtml @@ -285,7 +285,8 @@ if (!isset($this->layout()->searchbox)) { <?=$this->render('footer.phtml')?> <!-- MODAL IN CASE WE NEED ONE --> -<?php /* finc: move X button to logical pos. in structure + use 'aria-describedby' instead of 'aria-labelledby - CK */ ?> + <section> + <?php /* finc: move X button to logical pos. in structure + use 'aria-describedby' instead of 'aria-labelledby - CK */ ?> <div id="modal" class="modal fade hidden-print" tabindex="-1" role="dialog" aria-modal="true" aria-hidden="true" aria-describedby="modal-description"> <div class="modal-dialog"> <div class="modal-content"> @@ -298,6 +299,8 @@ if (!isset($this->layout()->searchbox)) { </div> </div> </div> + </section> + <div class="offcanvas-overlay" data-toggle="offcanvas"></div> <?=$this->googleanalytics()?> <?=$this->piwik()?> diff --git a/themes/finc/templates/myresearch/acquisition.phtml b/themes/finc/templates/myresearch/acquisition.phtml index 3c541783a3c94efcd3b711423c7cfeeb72d742b7..00c846d3b8b7d0f65f429632c7c9f03b60321235 100644 --- a/themes/finc/templates/myresearch/acquisition.phtml +++ b/themes/finc/templates/myresearch/acquisition.phtml @@ -14,7 +14,7 @@ $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . <h1><?=$this->transEsc('PDA::pda_form_subtitle')?></h1> <?=$this->flashmessages()?> - <form method="post" action="" name="acquisitionForm"> + <form method="post" name="acquisitionForm"> <h3><?=$this->transEsc('PDA::pda_form_suggestions_limit')?></h3> <div class="form-group"> @@ -30,13 +30,13 @@ $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . </div> <div class="form-group"> - <label class="control-label" for="acquistion_reasons"><?=$this->transEsc('PDA::pda_form_statement_label')?><span class="required">*</span></label> - <textarea id="acquisition_reasons" type="text" cols="50" rows="5" name="reasons" class="form-control"><?=(isset($acquisitionStatement) && !empty($acquisitionStatement)) ? $acquisitionStatement : ''?></textarea> + <label class="control-label" for="acquisition_reasons"><?=$this->transEsc('PDA::pda_form_statement_label')?><span class="required">*</span></label> + <textarea id="acquisition_reasons" cols="50" rows="5" name="reasons" class="form-control"><?=(isset($acquisitionStatement) && !empty($acquisitionStatement)) ? $acquisitionStatement : ''?></textarea> </div> <div class="form-group"> - <label class="control-label" for="acquistion_proposal"><?=$this->transEsc('PDA::pda_form_proposal_label')?><span class="required">*</span></label> - <textarea id="acquisition_proposal" class="form-control" type="text" cols="50" rows="5" name="proposal"><?=(isset($acquisitionProposal) && !empty($acquisitionProposal)) ? $acquisitionProposal : ''?></textarea> + <label class="control-label" for="acquisition_proposal"><?=$this->transEsc('PDA::pda_form_proposal_label')?><span class="required">*</span></label> + <textarea id="acquisition_proposal" class="form-control" cols="50" rows="5" name="proposal"><?=(isset($acquisitionProposal) && !empty($acquisitionProposal)) ? $acquisitionProposal : ''?></textarea> </div> <div class="form-group"> diff --git a/themes/finc/templates/myresearch/edit.phtml b/themes/finc/templates/myresearch/edit.phtml index 4ad763f6e5fed000d2857d04ed400cc49c3219d2..01023cf62d8d1b583d6567a6e79fc4d03dbd28ba 100644 --- a/themes/finc/templates/myresearch/edit.phtml +++ b/themes/finc/templates/myresearch/edit.phtml @@ -49,7 +49,7 @@ </div> <?php endif; ?> <?php if (count($this->lists) > 0): ?> - <hr/> + <hr> <div class="form-group"> <select name="addToList" class="form-control"> <option value="-1">- <?=$this->transEsc('Add to another list')?> -</option> diff --git a/themes/finc/templates/myresearch/newpassword.phtml b/themes/finc/templates/myresearch/newpassword.phtml index 334b80035ff83589128916e4a8229599a4ec12ec..f383da468b0e08987583a31affd209df50dda8a7 100644 --- a/themes/finc/templates/myresearch/newpassword.phtml +++ b/themes/finc/templates/myresearch/newpassword.phtml @@ -23,7 +23,7 @@ <?php elseif (!isset($this->hash)): ?> <div class="error"><?=$this->transEsc('recovery_user_not_found') ?></div> <?php else: ?> - <form id="newpassword" class="form-new-password" action="<?=$this->url('myresearch-newpassword') ?>" method="post" data-toggle="validator" role="form"> + <form id="newpassword" class="form-new-password" action="<?=$this->url('myresearch-newpassword') ?>" method="post" data-toggle="validator"> <input type="hidden" value="<?=$this->escapeHtmlAttr($this->auth()->getManager()->getCsrfHash())?>" name="csrf"/> <input type="hidden" value="<?=$this->escapeHtmlAttr($this->hash) ?>" name="hash"/> <input type="hidden" value="<?=$this->escapeHtmlAttr($this->username) ?>" name="username"/> diff --git a/themes/finc/templates/myresearch/setpin.phtml b/themes/finc/templates/myresearch/setpin.phtml index d3ec8d6401c54e2f5213ec0153490ac9bbd31b1d..e280dc9d634c5c7c8d6bfdbcd32c5fae98ed6058 100644 --- a/themes/finc/templates/myresearch/setpin.phtml +++ b/themes/finc/templates/myresearch/setpin.phtml @@ -23,7 +23,7 @@ $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . <?php elseif (!isset($this->hash)): ?> <div class="error"><?=$this->transEsc('recovery_user_not_found')?></div> <?php else: ?> - <form id="setpin" class="form-set-pin" action="<?=$this->url('myresearch-setpin')?>" method="post" data-toggle="validator" role="form"> + <form id="setpin" class="form-set-pin" action="<?=$this->url('myresearch-setpin')?>" method="post" data-toggle="validator"> <input type="hidden" value="<?=$this->escapeHtmlAttr($this->auth()->getManager()->getCsrfHash(true))?>" name="csrf"/> <input type="hidden" value="<?=$this->escapeHtmlAttr($this->hash)?>" name="hash"/> <input type="hidden" value="<?=$this->escapeHtmlAttr($this->username)?>" name="username"/> diff --git a/themes/finc/templates/record/cart-buttons.phtml b/themes/finc/templates/record/cart-buttons.phtml index 46a57cf85e0aa640109447372384761c3e2c5e7d..abb7910f42dfad7e1b6617c451b06e85f3613827 100644 --- a/themes/finc/templates/record/cart-buttons.phtml +++ b/themes/finc/templates/record/cart-buttons.phtml @@ -5,10 +5,11 @@ <?php /* finc changes span to div */ ?> <div class="btn-bookbag-toggle" data-cart-id="<?=$this->escapeHtmlAttr($this->id)?>" data-cart-source="<?=$this->escapeHtmlAttr($this->source)?>"> <?php /* finc makes add-to/remove-from bookbag accessible for keyboard navigation - CK */ ?> - <a href="javascript:" class="cart-add hidden<?php if (!$cart->contains($cartId)): ?> correct<?php endif ?>" aria-describedby="<?=$cartId?>"> + <?php /* finc adds callFromTemplate for setting aria-describedby if use of book bag is with checkboxes #24358 */ ?> + <a href="javascript:" class="cart-add hidden<?php if (!$cart->contains($cartId)): ?> correct<?php endif ?>" <?php if ($this->callFromTemplate == 'resultList'): ?>aria-describedby="<?=$cartId?>"<?php endif ?>> <span class="cart-link-label btn-type-add"><?=$this->transEsc('Add to Book Bag')?></span> </a> - <a href="javascript:" class="cart-remove hidden<?php if ($cart->contains($cartId)): ?> correct<?php endif ?>" aria-describedby="<?=$cartId?>"> + <a href="javascript:" class="cart-remove hidden<?php if ($cart->contains($cartId)): ?> correct<?php endif ?>" <?php if ($this->callFromTemplate == 'resultList'): ?>aria-describedby="<?=$cartId?>"<?php endif ?>> <span class="cart-link-label btn-type-minus"><?=$this->transEsc('Remove from Book Bag')?></span> </a> diff --git a/themes/finc/templates/record/save.phtml b/themes/finc/templates/record/save.phtml index a74f3371334ba1aec7e93b4b0718af3e6c34d6aa..f75be9a59327a88ead51fe64d13aef7ff0b443ba 100644 --- a/themes/finc/templates/record/save.phtml +++ b/themes/finc/templates/record/save.phtml @@ -19,7 +19,7 @@ <?php foreach ($this->containingLists as $i => $list): ?> <a href="<?=$this->url('userList', ['id' => $list['id']]) ?>" data-lightbox-ignore><?=$this->escapeHtml($list['title'])?></a><?php if($i < count($this->containingLists) - 1): ?>, <?php endif; ?> <?php endforeach; ?> - </p><hr/> + </p><hr> <?php endif; ?> <?php /* Only display the list drop-down if the user has lists that do not contain