diff --git a/.gitignore b/.gitignore index ec879b1b6af547a67767c06161684e2dcdf66fa6..bdecbe9fd6421a2590cf9e840620548b7e69efda 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,4 @@ import/solrmarc.log* /core /.env /lessphp_*.list -/docker-compose.override.yml -/themes/finc-fid-* \ No newline at end of file +/docker-compose.override.yml \ No newline at end of file diff --git a/composer.json b/composer.json index dbf83f7f5de7c63f36d90a4a0ead3462e9270688..6537b2f1db902c6204f0eece24b1c82975269c75 100644 --- a/composer.json +++ b/composer.json @@ -82,7 +82,10 @@ "zf-commons/zfc-rbac": "2.6.3", "sabre/vobject": "3.5.3", "finc/rules-evaluator": "v0.0.3", - "finc/fid-core-module": "~0.0" + "finc/vufindhttp-psrcompat": "^0.0.2", + "finc/symfony-serializer-zend-bridge": "^0.0.1", + "phpdocumentor/reflection-docblock": "^4.3", + "zendframework/zend-i18n-resources": "^2.6" }, "require-dev": { "behat/mink": "1.7.1", @@ -94,19 +97,19 @@ "sebastian/phpcpd": "3.0.1", "squizlabs/php_codesniffer": "3.4.0" }, - "minimum-stability": "dev", - "prefer-stable": true, + "autoload": { + "psr-4": { + "fid\\": "module/fid/src" + } + }, "scripts": { "phing-install-dependencies": "phing installsolr installswaggerui", "phpcs-finc": [ "vendor/bin/phpcs --standard=tests/finc/phpcs.xml" ], "post-install-cmd": [ - "@copy-themes" ], "post-update-cmd": [ - "@copy-themes" - ], - "copy-themes": "php devops/composer/themes.php" + ] } } diff --git a/composer.lock b/composer.lock index 1872341901a462af4b517f41111e519f7caa0c5e..5f19d34a2269128ff994dc7ea4825d62ca9de72f 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": "f22e43716ecc8968790c241138a5b6fb", + "content-hash": "83611cf5ee4d75cda9820e29478ca128", "packages": [ { "name": "ahand/mobileesp", @@ -317,21 +317,24 @@ }, { "name": "doctrine/lexer", - "version": "v1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + "reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/1febd6c3ef84253d7c815bed85fc622ad207a9f8", + "reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8", "shasum": "" }, "require": { "php": ">=5.3.2" }, + "require-dev": { + "phpunit/phpunit": "^4.5" + }, "type": "library", "extra": { "branch-alias": { @@ -339,8 +342,8 @@ } }, "autoload": { - "psr-0": { - "Doctrine\\Common\\Lexer\\": "lib/" + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" } }, "notification-url": "https://packagist.org/downloads/", @@ -361,13 +364,16 @@ "email": "schmittjoh@gmail.com" } ], - "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "http://www.doctrine-project.org", + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", "keywords": [ + "annotations", + "docblock", "lexer", - "parser" + "parser", + "php" ], - "time": "2014-09-09T13:34:57+00:00" + "time": "2019-06-08T11:03:04+00:00" }, { "name": "endroid/qr-code", @@ -499,48 +505,6 @@ ], "time": "2018-10-23T09:00:00+00:00" }, - { - "name": "finc/fid-core-module", - "version": "v0.0.0", - "source": { - "type": "git", - "url": "https://git.sc.uni-leipzig.de/ubl/finc/fid/core-module.git", - "reference": "b9d680b18eeac0df7e46b87d23b04360c5d9887c" - }, - "require": { - "finc/symfony-serializer-zend-bridge": "dev-master#9b0c05c", - "finc/vufindhttp-psrcompat": "dev-master#71ef977", - "php": "^7.1", - "phpdocumentor/reflection-docblock": "^4.0", - "zendframework/zend-i18n-resources": "^2.6" - }, - "type": "library", - "extra": { - "vufind": { - "themes": { - "res/mixins/core": "finc-fid-core", - "res/mixins/registration": "finc-fid-registration" - } - } - }, - "autoload": { - "psr-4": { - "finc\\Fid\\Core\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0" - ], - "authors": [ - { - "name": "Sebastian Kehr", - "email": "kehr@ub.uni-leipzig.de" - } - ], - "description": "finc fid core module", - "time": "2019-05-17T12:13:48+00:00" - }, { "name": "finc/rules-evaluator", "version": "v0.0.3", @@ -577,11 +541,11 @@ }, { "name": "finc/symfony-serializer-zend-bridge", - "version": "dev-master", + "version": "v0.0.1", "source": { "type": "git", "url": "https://git.sc.uni-leipzig.de/ubl/finc/fid/symfony-serializer-zend-bridge.git", - "reference": "3bbbe492979cb4303eb61b7ca598886aaca9a67c" + "reference": "9b0c05c112c40a626f8bead49d9ad34b3916ce8c" }, "require": { "doctrine/annotations": "^1.4", @@ -609,18 +573,18 @@ } ], "description": "Reusable adapters for usage with zend-serializer.", - "time": "2019-04-01T15:12:38+00:00" + "time": "2019-05-07T12:27:13+00:00" }, { "name": "finc/vufindhttp-psrcompat", - "version": "dev-master", + "version": "v0.0.2", "source": { "type": "git", "url": "https://git.sc.uni-leipzig.de/ubl/finc/fid/vufindhttp-psrcompat.git", - "reference": "71ef977c8dcbf57cf55748d725fc0ecc4e5114e3" + "reference": "462ebd51d69f3e81e6c2167dda05f7ffa18fa942" }, "require": { - "finc/zend-psr18bridge": "dev-master", + "finc/zend-psr18bridge": "~0.0.1", "php": "^7.1", "vufind-org/vufindhttp": "~2.1" }, @@ -644,11 +608,11 @@ } ], "description": "PSR compatibility layer for vufind-org/vufindhttp", - "time": "2019-03-15T09:49:01+00:00" + "time": "2019-06-13T10:58:08+00:00" }, { "name": "finc/zend-psr18bridge", - "version": "dev-master", + "version": "v0.0.1", "source": { "type": "git", "url": "https://git.sc.uni-leipzig.de/ubl/finc/fid/zend-psr18bridge.git", @@ -1867,16 +1831,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.0", + "version": "4.3.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", "shasum": "" }, "require": { @@ -1914,7 +1878,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" + "time": "2019-04-30T17:48:53+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -2109,16 +2073,16 @@ }, { "name": "psr/http-factory", - "version": "1.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "378bfe27931ecc54ff824a20d6f6bfc303bbd04c" + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/378bfe27931ecc54ff824a20d6f6bfc303bbd04c", - "reference": "378bfe27931ecc54ff824a20d6f6bfc303bbd04c", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", "shasum": "" }, "require": { @@ -2157,7 +2121,7 @@ "request", "response" ], - "time": "2018-07-30T21:54:04+00:00" + "time": "2019-04-30T12:38:16+00:00" }, { "name": "psr/http-message", @@ -2446,16 +2410,16 @@ }, { "name": "symfony/cache", - "version": "v3.4.24", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "669270dc501fe3c5addcc306962958334c19652c" + "reference": "380b8395b43f60e7d26a32f84f80c0a7ba93e7c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/669270dc501fe3c5addcc306962958334c19652c", - "reference": "669270dc501fe3c5addcc306962958334c19652c", + "url": "https://api.github.com/repos/symfony/cache/zipball/380b8395b43f60e7d26a32f84f80c0a7ba93e7c5", + "reference": "380b8395b43f60e7d26a32f84f80c0a7ba93e7c5", "shasum": "" }, "require": { @@ -2512,7 +2476,7 @@ "caching", "psr6" ], - "time": "2019-04-01T07:08:40+00:00" + "time": "2019-04-16T09:03:16+00:00" }, { "name": "symfony/expression-language", @@ -2566,7 +2530,7 @@ }, { "name": "symfony/inflector", - "version": "v3.4.24", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/inflector.git", @@ -2910,7 +2874,7 @@ }, { "name": "symfony/property-access", - "version": "v3.4.24", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", @@ -2978,16 +2942,16 @@ }, { "name": "symfony/property-info", - "version": "v3.4.24", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "7a849a6765fc8481d9b7b79558ca0c5bc01972c2" + "reference": "1dac2fbcce08c3f476ac2d81b0acb77844e5ab34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/7a849a6765fc8481d9b7b79558ca0c5bc01972c2", - "reference": "7a849a6765fc8481d9b7b79558ca0c5bc01972c2", + "url": "https://api.github.com/repos/symfony/property-info/zipball/1dac2fbcce08c3f476ac2d81b0acb77844e5ab34", + "reference": "1dac2fbcce08c3f476ac2d81b0acb77844e5ab34", "shasum": "" }, "require": { @@ -3050,20 +3014,20 @@ "type", "validator" ], - "time": "2019-02-23T15:06:07+00:00" + "time": "2019-05-16T14:10:36+00:00" }, { "name": "symfony/serializer", - "version": "v3.4.24", + "version": "v3.4.28", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "c74469e1560e2d8926c068b319fcca66df8fdb4e" + "reference": "560e55b734cbed4f64b147f367794e72c90ed78a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/c74469e1560e2d8926c068b319fcca66df8fdb4e", - "reference": "c74469e1560e2d8926c068b319fcca66df8fdb4e", + "url": "https://api.github.com/repos/symfony/serializer/zipball/560e55b734cbed4f64b147f367794e72c90ed78a", + "reference": "560e55b734cbed4f64b147f367794e72c90ed78a", "shasum": "" }, "require": { @@ -3086,7 +3050,7 @@ "symfony/dependency-injection": "~3.2|~4.0", "symfony/http-foundation": "~2.8|~3.0|~4.0", "symfony/property-access": "~2.8|~3.0|~4.0", - "symfony/property-info": "~3.1|~4.0", + "symfony/property-info": "^3.4.13|~4.0", "symfony/yaml": "~3.4|~4.0" }, "suggest": { @@ -3129,7 +3093,7 @@ ], "description": "Symfony Serializer Component", "homepage": "https://symfony.com", - "time": "2019-03-30T07:48:10+00:00" + "time": "2019-05-11T09:57:38+00:00" }, { "name": "symfony/yaml", @@ -3941,16 +3905,16 @@ }, { "name": "zendframework/zend-diactoros", - "version": "2.1.1", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-diactoros.git", - "reference": "c3c330192bc9cc51b7e9ce968ff721dc32ffa986" + "reference": "37bf68b428850ee26ed7c3be6c26236dd95a95f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/c3c330192bc9cc51b7e9ce968ff721dc32ffa986", - "reference": "c3c330192bc9cc51b7e9ce968ff721dc32ffa986", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/37bf68b428850ee26ed7c3be6c26236dd95a95f1", + "reference": "37bf68b428850ee26ed7c3be6c26236dd95a95f1", "shasum": "" }, "require": { @@ -4003,7 +3967,7 @@ "psr", "psr-7" ], - "time": "2019-01-05T20:13:32+00:00" + "time": "2019-04-29T21:11:00+00:00" }, { "name": "zendframework/zend-dom", @@ -9493,13 +9457,13 @@ } ], "aliases": [], - "minimum-stability": "dev", + "minimum-stability": "stable", "stability-flags": { "ahand/mobileesp": 20, "ghislainf/zf2-whoops": 20, "pear/validate_ispn": 20 }, - "prefer-stable": true, + "prefer-stable": false, "prefer-lowest": false, "platform": { "php": "^7.1", diff --git a/config/application.config.php b/config/application.config.php index 7839ec47c30e1e18218d18149d49b5674817bb84..7187c0fc2b151b1c2138d948b469935f86031b8b 100644 --- a/config/application.config.php +++ b/config/application.config.php @@ -25,10 +25,10 @@ if ($localModules = getenv('VUFIND_LOCAL_MODULES')) { array_push($modules, ...[ 'Zend\Validator', 'Zend\Serializer', - 'finc', 'finc\VuFindHttpPsrCompat', 'finc\SymfonySerializerZendBridge', - 'finc\Fid\Core', + 'finc', + 'fid', 'fid_bbi', ]); /** End of temporarily necessary adjustments. */ diff --git a/docker-compose.override.yml.dist b/docker-compose.override.yml.dist index a191e240bd213f26382de7a0dcdd6821f07c79f7..be8f7b7eed7bd29eb81999dd975d874fea0a6ff6 100644 --- a/docker-compose.override.yml.dist +++ b/docker-compose.override.yml.dist @@ -3,10 +3,7 @@ version: '2.4' services: php: <<: &volumes - volumes: -# - path/to/core-module:/usr/local/vufind/vendor/finc/fid-core-module -# - path/to/core-module/res/mixins/core:/usr/local/vufind/themes/finc-fid-core -# - path/to/core-module/res/mixins/registration:/usr/local/vufind/themes/finc-fid-registration + volumes: [] httpd: <<: *volumes grunt: diff --git a/docker-compose.yml b/docker-compose.yml index 0859fab301fdb248aad28f1cdc72a492cf5c56dd..fda2feb99c2d112c82ac14a836c4ab73ec7caf95 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,7 +21,7 @@ services: VUFIND_LOCAL_DIR: /usr/local/vufind/fid_bbi/dev VUFIND_CACHE_DIR: /usr/local/vufind/data/cache VUFIND_ENV: development - PHP_IDE_CONFIG: serverName=finc-fid-frontend + PHP_IDE_CONFIG: serverName=fid XDEBUG_CONFIG: >- remote_autostart=1 remote_mode=req diff --git a/fid/config/vufind/config.ini b/fid/config/vufind/config.ini index b36982b610643bee14cc632657f8a48b69681c52..06a9525b6914bcd0420577b0fddd032eb255477b 100644 --- a/fid/config/vufind/config.ini +++ b/fid/config/vufind/config.ini @@ -22,10 +22,11 @@ relative_path = ../../../local/config/vufind/config.ini ;#################################################################### [Authentication] -method = finc\Fid\Core\VuFind\Auth\Authenticator +method = fid +recover_password = true [Catalog] -driver = finc\Fid\Core\VuFind\ILS\Driver +driver = fid [Index] url = https://index.ub.uni-leipzig.de/solr [Site] -theme = finc-fid +theme = fid diff --git a/fid/config/vufind/fid.ini b/fid/config/vufind/fid.ini new file mode 100644 index 0000000000000000000000000000000000000000..1307453b84bb97eecf21fbbc0f0fa9848614d626 --- /dev/null +++ b/fid/config/vufind/fid.ini @@ -0,0 +1,2 @@ +[Client] +baseUrl = http://172.18.113.133/bbi-alpha.1 \ No newline at end of file diff --git a/fid/config/vufind/finc-fid-core-api.ini b/fid/config/vufind/finc-fid-core-api.ini deleted file mode 100644 index 255d1eaaed10b8bae0d34920754b89622982ab32..0000000000000000000000000000000000000000 --- a/fid/config/vufind/finc-fid-core-api.ini +++ /dev/null @@ -1,2 +0,0 @@ -[Client] -baseUrl = http://172.18.113.133/fid-7101bb5 \ No newline at end of file diff --git a/fid/config/vufind/finc-fid-core-ils.ini b/fid/config/vufind/finc-fid-core-ils.ini deleted file mode 100644 index 3d13e0c664a9584bcea653aa850edd54908cf242..0000000000000000000000000000000000000000 --- a/fid/config/vufind/finc-fid-core-ils.ini +++ /dev/null @@ -1,2 +0,0 @@ -[Section] -param = value \ No newline at end of file diff --git a/module/fid/config/module.config.php b/module/fid/config/module.config.php new file mode 100644 index 0000000000000000000000000000000000000000..c3b4267b42ac5d9b84041e21cc2d38783a42d232 --- /dev/null +++ b/module/fid/config/module.config.php @@ -0,0 +1,222 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +use fid\Controller\UserController; +use fid\Controller\UserControllerFactory; +use fid\Helper\RegistrationFormLabel; +use fid\Helper\TranslatorDelegator; +use fid\Listener\ErrorListener; +use fid\Listener\ErrorListenerFactory; +use fid\Listener\LocaleListener; +use fid\Service\Client; +use fid\Service\ClientFactory; +use fid\VuFind\Auth\Authenticator; +use fid\VuFind\Auth\AuthenticatorFactory; +use fid\VuFind\Auth\ILSAuthenticator; +use fid\VuFind\Auth\ILSAuthenticatorFactory; +use fid\VuFind\Db\Row\User; +use fid\VuFind\Db\Row\UserDelegatorFactory; +use fid\VuFind\ILS\Fid; +use fid\VuFind\ILS\FidFactory; +use VuFind\Auth\ILSAuthenticator as BaseILSAuthenticator; +use VuFind\Db\Row\User as BaseUser; +use VuFind\Db\Row\UserFactory; +use Zend\Mvc\I18n\Translator; +use Zend\ServiceManager\Factory\InvokableFactory; + +return [ + 'controllers' => [ + 'factories' => [ + UserController::class => UserControllerFactory::class, + ] + ], + 'listeners' => [ + ErrorListener::class, + LocaleListener::class, + ], + 'view_helpers' => array( + 'invokables' => array( + 'formLabel' => RegistrationFormLabel::class, + ), + ), + 'service_manager' => [ + 'aliases' => [ + BaseILSAuthenticator::class => ILSAuthenticator::class, + 'MvcTranslator' => Translator::class, + ], + 'delegators' => [ + ILSAuthenticator::class => [ + ILSAuthenticatorFactory::class, + ], + Translator::class => [ + TranslatorDelegator::class, + ], + ], + 'factories' => [ + Client::class => ClientFactory::class, + ErrorListener::class => ErrorListenerFactory:: class, + ILSAuthenticator::class => ILSAuthenticatorFactory::class, + LocaleListener::class => InvokableFactory::class, + ], + ], + 'vufind' => [ + 'plugin_managers' => [ + 'auth' => [ + 'aliases' => [ + 'fid' => Authenticator::class, + ], + 'factories' => [ + Authenticator::class => AuthenticatorFactory::class, + ], + ], + 'db_row' => [ + 'aliases' => [ + BaseUser::class => User::class, + ], + 'delegators' => [ + User::class => [ + UserDelegatorFactory::class, + ], + ], + 'factories' => [ + User::class => UserFactory::class, + ], + ], + 'ils_driver' => [ + 'aliases' => [ + 'fid' => Fid::class, + ], + 'factories' => [ + Fid::class => FidFactory::class, + ], + ], + ], + ], + 'router' => [ + 'routes' => [ + 'fid' => [ + 'type' => 'literal', + 'may_terminate' => false, + 'options' => [ + 'route' => '/fid', + ], + 'child_routes' => [ + 'user' => [ + 'may_terminate' => false, + 'type' => 'literal', + 'options' => [ + 'route' => '/user', + ], + 'child_routes' => [ + 'init' => [ + 'may_terminate' => true, + 'type' => 'literal', + 'options' => [ + 'route' => '/init', + 'defaults' => [ + 'controller' => UserController::class, + 'action' => 'init', + ], + ], + ], + 'create' => [ + 'type' => 'literal', + 'options' => [ + 'route' => '/create', + 'defaults' => [ + 'controller' => UserController::class, + 'action' => 'create', + ], + ], + ], + 'update' => [ + 'type' => 'literal', + 'options' => [ + 'route' => '/update', + 'defaults' => [ + 'controller' => UserController::class, + 'action' => 'update', + ], + ], + ], + 'policy' => [ + 'type' => 'literal', + 'options' => [ + 'route' => '/policy', + 'defaults' => [ + 'controller' => UserController::class, + 'action' => 'policy', + ], + ], + ], + 'terms' => [ + 'type' => 'literal', + 'options' => [ + 'route' => '/terms', + 'defaults' => [ + 'controller' => UserController::class, + 'action' => 'terms', + ], + ], + ], + 'reset-password' => [ + 'type' => 'literal', + 'options' => [ + 'route' => '/reset-password', + 'defaults' => [ + 'controller' => UserController::class, + 'action' => 'resetPassword', + ], + ], + ], + 'change-password' => [ + 'type' => 'literal', + 'options' => [ + 'route' => '/change-password', + 'defaults' => [ + 'controller' => UserController::class, + 'action' => 'changePassword', + ], + ], + ] + ], + ], + ], + ], + 'myresearch-account' => [ + 'options' => [ + 'defaults' => [ + 'controller' => UserController::class, + 'action' => 'init', + ], + ], + ], + 'myresearch-recover' => [ + 'options' => [ + 'defaults' => [ + 'controller' => UserController::class, + 'action' => 'resetPassword', + ] + ] + ] + ], + ], +]; \ No newline at end of file diff --git a/module/fid/src/Controller/UserController.php b/module/fid/src/Controller/UserController.php new file mode 100644 index 0000000000000000000000000000000000000000..c726f461f9c8ca0d53e2c74b5abef3818b0681fa --- /dev/null +++ b/module/fid/src/Controller/UserController.php @@ -0,0 +1,476 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Controller; + +use fid\FormModel\PasswordChangeModel; +use fid\FormModel\PasswordResetModel; +use fid\FormModel\UserCreateModel; +use fid\FormModel\UserInitModel; +use fid\FormModel\UserUpdateModel; +use fid\Service\Client; +use fid\Service\ClientException; +use fid\Service\DataTransferObject\Library; +use fid\Service\DataTransferObject\User; +use Symfony\Component\Serializer\SerializerAwareTrait; +use Symfony\Component\Serializer\SerializerInterface; +use VuFind\Auth\Manager as Authenticator; +use VuFind\Controller\AbstractBase; +use VuFind\Exception\Auth as AuthException; +use Zend\Form\Annotation\AnnotationBuilder; +use Zend\Form\Form; +use Zend\Http\PhpEnvironment\Request; +use Zend\Http\Response; +use Zend\Mvc\Plugin\FlashMessenger\FlashMessenger; +use Zend\ServiceManager\ServiceLocatorInterface; +use Zend\View\Model\ViewModel; + +class UserController extends AbstractBase +{ + use SerializerAwareTrait; + + /** + * @var Authenticator + */ + protected $authenticator; + + /** + * @var SerializerInterface + */ + protected $serializer; + + /** + * @var AnnotationBuilder + */ + protected $builder; + + /** + * @var Client + */ + protected $client; + + /** + * RegistrationController constructor. + * + * @param ServiceLocatorInterface $serviceLocator + * @param SerializerInterface $serializer + * @param Authenticator $authenticator + * @param AnnotationBuilder $builder + * @param Client $client + */ + public function __construct( + ServiceLocatorInterface $serviceLocator, + SerializerInterface $serializer, + Authenticator $authenticator, + AnnotationBuilder $builder, + Client $client + ) { + parent::__construct($serviceLocator); + $this->authenticator = $authenticator; + $this->serializer = $serializer; + $this->builder = $builder; + $this->client = $client; + } + + /** + * @return ViewModel + */ + public function initAction() + { + /** @var Request $request */ + $request = $this->getRequest(); + $form = $this->builder->createForm(UserInitModel::class); + $forwarded = $this->params()->fromRoute('forwarded', false); + + if ($submitted = $this->formWasSubmitted()) { + $form->setData($request->getPost()); + if (!$forwarded && $form->isValid()) { + return $this->init($form); + } + } + + $view = $this->createViewModel(); + $view->setVariables(compact('form')); + $view->setTemplate('fid/user/init'); + + return $view; + } + + /** + * @return Response|ViewModel + */ + public function createAction() + { + /** @var Request $request */ + $request = $this->getRequest(); + $query = $request->getQuery(); + $messenger = $this->getMessenger(); + + if ($credentials = $query->get('logon')) { + try { + $this->client->logon($credentials); + } catch (ClientException $exception) { + $message = $exception->getCode() === 401 + ? 'fid::user_create_error_expired' + : 'fid::user_create_error'; + $messenger->addErrorMessage($this->translate($message)); + return $this->redirect()->toRoute('fid/user/init'); + } + + $query->offsetUnset('logon'); + return $this->redirect()->toRoute('fid/user/create', [], [ + 'query' => $query->toArray() + ]); + } + + $form = $this->builder->createForm(UserCreateModel::class); + + if ($this->formWasSubmitted()) { + $form->setData($request->getPost()); + if ($form->isValid()) { + return $this->create($form); + } + } else { + $form->setData($query); + } + + try { + $libraries = array_map(function (Library $libary) { + return $libary->getLabel(); + }, $this->client->requestLibraryList()); + } catch (ClientException $exception) { + $message = 'fid::user_create_error'; + $messenger->addErrorMessage($this->translate($message)); + return $this->redirect()->toRoute('fid/user/init'); + } + + $view = $this->createViewModel(); + $view->setVariables(compact('form', 'libraries')); + $view->setTemplate('fid/user/create'); + + return $view; + } + + public function updateAction() + { + /** @var Request $request */ + $request = $this->getRequest(); + $form = $this->builder->createForm(UserUpdateModel::class); + + if ($this->formWasSubmitted()) { + $form->setData($request->getPost()); + if ($form->isValid()) { + return $this->update($form); + } + } + + try { + $user = $this->client->requestUserDetails(); + $libraries = array_map(function (Library $libary) { + return $libary->getLabel(); + }, $this->client->requestLibraryList()); + } catch (ClientException $exception) { + $this->setFollowupUrlToReferer(); + $message = $exception->getCode() === 401 + ? 'fid::user_update_error_expired' + : 'fid::user_update_error'; + $this->getMessenger()->addErrorMessage($this->translate($message)); + return $this->redirect()->toRoute('myresearch-home'); + } + + $viewModel = $this->createViewModel(); + $viewModel->setVariables(compact('form', 'user', 'libraries')); + $viewModel->setTemplate('fid/user/update'); + + return $viewModel; + } + + public function policyAction() + { + $viewModel = $this->createViewModel(); + $viewModel->setTemplate('fid/user/policy'); + + return $viewModel; + } + + public function termsAction() + { + $viewModel = $this->createViewModel(); + $viewModel->setTemplate('fid/user/terms'); + + return $viewModel; + } + + /** + * Reset password action - Allows the reset password form to appear. + * + * @return ViewModel + */ + public function resetPasswordAction() + { + /** @var Request $request */ + $request = $this->getRequest(); + $form = $this->builder->createForm(PasswordResetModel::class); + $forwarded = $this->params()->fromRoute('forwarded', false); + + if ($submitted = $this->formWasSubmitted()) { + $form->setData($request->getPost()); + if (!$forwarded && $form->isValid()) { + return $this->sendResetPassword($form); + } + } + + $view = $this->createViewModel(); + $view->setVariables(compact('form')); + $view->setTemplate('fid/user/password-reset'); + + return $view; + } + + /** + * Reset password action - Allows the change password form to appear. + * + * @return Response|ViewModel + */ + public function changePasswordAction() + { + /** @var Request $request */ + $request = $this->getRequest(); + $query = $request->getQuery(); + $messenger = $this->getMessenger(); + + if ($credentials = $query->get('logon')) { + try { + $this->client->logon($credentials); + } catch (ClientException $exception) { + $message = $exception->getCode() === 401 + ? 'fid::password_change_error_expired' + : 'fid::password_change_error'; + $messenger->addErrorMessage($this->translate($message)); + return $this->redirect()->toRoute('fid/user/reset-password'); + } + + $query->offsetUnset('logon'); + return $this->redirect()->toRoute('fid/user/change-password', [], [ + 'query' => $query->toArray() + ]); + } + + $form = $this->builder->createForm(PasswordChangeModel::class); + + if ($this->formWasSubmitted()) { + $form->setData($request->getPost()); + if ($form->isValid()) { + return $this->changePassword($form); + } + } else { + $form->setData($query); + } + + $view = $this->createViewModel(); + $view->setVariables(compact('form')); + $view->setTemplate('fid/user/password-change'); + + return $view; + } + + /** + * @param Form $form + * + * @return mixed|Response + */ + protected function init(Form $form) + { + /** @var UserInitModel $model */ + $messenger = $this->getMessenger(); + $model = $form->getHydrator() + ->hydrate($form->getData(), new UserInitModel()); + + /** @noinspection PhpUndefinedFieldInspection */ + $query['lng'] = $this->layout()->userLang; + $username = $query['username'] = $model->getUsername(); + $firstname = $query['firstname'] = $model->getFirstname(); + $lastname = $query['lastname'] = $model->getLastname(); + $baseUrl = $this->url()->fromRoute('fid/user/create', + [], ['query' => $query, 'force_canonical' => true]); + + try { + $this->client->requestRegistrationLink($baseUrl, $username, + $firstname, $lastname); + } catch (ClientException $exception) { + $message = $exception->getCode() === 400 + ? 'fid::user_init_error_username' + : 'fid::user_init_error'; + $messenger->addErrorMessage($this->translate($message)); + return $this->forward()->dispatch(self::class, [ + 'action' => 'init', + 'forwarded' => true + ]); + } + + $message = $this->translate('fid::user_init_success'); + $messenger->addSuccessMessage(sprintf($message, $username)); + return $this->redirect()->toRoute('myresearch-home'); + } + + protected function create(Form $form) + { + $messenger = $this->getMessenger(); + /** @var UserCreateModel $model */ + $model = $form->getHydrator() + ->hydrate($form->getData(), new UserCreateModel()); + + $user = new User(); + $user->setUsername($username = $model->getUsername()); + $user->setPassword($password = $model->getPassword()); + $user->setHomeLibrary($model->getHomeLibrary()); + $user->setSalutation($model->getSalutation()); + $user->setAcademicTitle($model->getAcademicTitle()); + $user->setFirstname($model->getFirstname()); + $user->setLastname($model->getLastname()); + $user->setYearOfBirth($model->getYearOfBirth()); + $user->setCollege($model->getCollege()); + $user->setJobTitle($model->getJobTitle()); + + try { + $this->client->requestUserCreation($user); + $message = $this->translate('fid::user_create_success'); + $messenger->addSuccessMessage($message); + /** @noinspection PhpParamsInspection */ + $this->authenticator->create($this->getRequest()); + } catch (ClientException $exception) { + $message = $this->translate('fid::user_create_error'); + $messenger->addErrorMessage($message); + } catch (AuthException $e) { + $message = $this->translate('fid::user_create_error_autologon'); + $messenger->addWarningMessage($message); + } + + return $this->redirect()->toRoute('myresearch-home', [], [ + 'query' => ['redirect' => false] + ]); + } + + /** + * @param Form $form + * + * @return Response + */ + protected function update(Form $form) + { + $messenger = $this->getMessenger(); + /** @var UserUpdateModel $model */ + $model = $form->getHydrator()->hydrate($form->getData(), + new UserUpdateModel()); + + try { + $user = $this->client->requestUserDetails(); + $user->setHomeLibrary($model->getHomeLibrary()); + $user->setSalutation($model->getSalutation()); + $user->setAcademicTitle($model->getAcademicTitle()); + $user->setFirstname($model->getFirstname()); + $user->setLastname($model->getLastname()); + $user->setYearOfBirth($model->getYearOfBirth()); + $user->setCollege($model->getCollege()); + $user->setJobTitle($model->getJobTitle()); + $this->client->requestUserUpdate($user); + $message = $this->translate('fid::user_update_success'); + $messenger->addSuccessMessage($message); + } catch (ClientException $exception) { + $message = $this->translate('fid::user_update_error'); + $messenger->addErrorMessage($message); + } + + return $this->redirect()->toRoute('myresearch-home', [], [ + 'query' => ['redirect' => false] + ]); + } + + protected function sendResetPassword(Form $form) + { + /** @var PasswordResetModel $model */ + $messenger = $this->getMessenger(); + $model = $form->getHydrator()->hydrate( + $form->getData(), new PasswordResetModel()); + $username = $model->getUsername(); + + try { + /** @noinspection PhpUndefinedFieldInspection */ + $query['lng'] = $this->layout()->userLang; + $baseUrl = $this->url()->fromRoute('fid/user/change-password', + [], ['query' => $query, 'force_canonical' => true]); + $this->client->requestPasswordLink($baseUrl, $username); + $message = $this->translate('fid::password_reset_success'); + $messenger->addSuccessMessage(sprintf($message, $username)); + } catch (ClientException $exception) { + $message = $exception->getCode() === 400 + ? $this->translate('fid::password_reset_error_username') + : $this->translate('fid::password_reset_error'); + $messenger->addErrorMessage(sprintf($message, $username)); + return $this->redirect()->toRoute('fid/user/reset-password'); + } + + return $this->redirect()->toRoute('myresearch-home'); + } + + protected function changePassword(Form $form) + { + /** @var PasswordChangeModel $model */ + $messenger = $this->getMessenger(); + $model = $form->getHydrator()->hydrate( + $form->getData(), new PasswordChangeModel()); + + try { + $user = $this->client->requestUserDetails(); + $user->setPassword($password = $model->getPassword()); + $this->client->requestUserUpdate($user); + $message = $this->translate('fid::password_change_success'); + $message = sprintf($message, $username = $user->getUsername()); + $messenger->addSuccessMessage($message); + /** @var Request $request */ + $request = clone $this->getRequest(); + $params = clone $request->getPost(); + $params->set('username', $username); + $params->set('password', $password); + $request->setPost($params); + $this->authenticator->create($request); + } catch (ClientException $exception) { + $message = $this->translate('fid::password_change_error'); + $messenger->addErrorMessage($message); + } catch (AuthException $e) { + $message = $this->translate('fid::password_change_error_autologon'); + $messenger->addErrorMessage($message); + } + + return $this->redirect()->toRoute('myresearch-home', [], [ + 'query' => ['redirect' => false] + ]); + } + + + protected function getMessenger(): FlashMessenger + { + /** @noinspection PhpUndefinedMethodInspection */ + /** @var FlashMessenger $messenger */ + return $this->flashMessenger(); + } +} \ No newline at end of file diff --git a/module/fid/src/Controller/UserControllerFactory.php b/module/fid/src/Controller/UserControllerFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..3e029c1210dfd02520cbbe53d89f869125737c33 --- /dev/null +++ b/module/fid/src/Controller/UserControllerFactory.php @@ -0,0 +1,60 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Controller; + +use fid\Service\Client; +use Psr\Container\ContainerInterface; +use Symfony\Component\Serializer\SerializerInterface; +use VuFind\Auth\Manager as AuthManager; +use Zend\Form\Annotation\AnnotationBuilder; +use Zend\ServiceManager\ServiceLocatorInterface; +use Zend\Validator\ValidatorPluginManager; + +class UserControllerFactory +{ + /** + * @param ContainerInterface|ServiceLocatorInterface $container + * + * @return UserController + */ + public function __invoke(ContainerInterface $container) + { + /** @var ValidatorPluginManager $plugins */ + $plugins = $container->get(ValidatorPluginManager::class); + + $builder = new AnnotationBuilder(); + $builder->getFormFactory()->getInputFilterFactory() + ->getDefaultValidatorChain()->setPluginManager($plugins); + + /** @var Client $client */ + $client = $container->get(Client::class); + /** @var AuthManager $authManager */ + $authManager = $container->get(AuthManager::class); + + /** @var SerializerInterface $serializer */ + $serializer = $container->get(SerializerInterface::class); + + return new UserController($container, $serializer, $authManager, + $builder, $client); + } +} \ No newline at end of file diff --git a/module/fid/src/FormModel/PasswordChangeModel.php b/module/fid/src/FormModel/PasswordChangeModel.php new file mode 100644 index 0000000000000000000000000000000000000000..20d59851125710c0778c75bfbdb903ff71eaac7c --- /dev/null +++ b/module/fid/src/FormModel/PasswordChangeModel.php @@ -0,0 +1,129 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\FormModel; + +use Zend\Form\Annotation; + +/** + * @Annotation\Name("passwordchange") + * @Annotation\Hydrator("Zend\Hydrator\ClassMethods") + */ +class PasswordChangeModel +{ + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Password") + * @Annotation\Required({"required":"true"}) + * @Annotation\Filter({"name":"StringTrim"}) + * @Annotation\Validator({ + * "name":"StringLength", "options":{ + * "min":8, "max":255, + * "messages": { + * "stringLengthTooShort": "error_password_length", + * "stringLengthTooLong": "error_password_length" + * } + * } + * }) + * @Annotation\Validator({ + * "name": "Regex", "options": { + * "pattern": "/(?:.*[0-9].*[^\w].*|.*[^\w].*[0-9].*)/", + * "messages": { + * "regexNotMatch": "error_password_pattern" + * } + * } + * }) + * @Annotation\Validator({ + * "name": "Identical", "options": { + * "strict": false, + * "token": "passwordConfirmation", + * "messages": {"notSame": "error_password_confirmation"} + * } + * }) + * @Annotation\Options({"label": "label_password"}) + */ + protected $password; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Password") + * @Annotation\Required({"required":"true"}) + * @Annotation\AllowEmpty() + * @Annotation\Options({"label": "label_password_confirmation"}) + */ + protected $passwordConfirmation; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Submit") + * @Annotation\Attributes({"value": "label_submit"}) + */ + protected $submit; + + /** + * @return string + */ + public function getPassword(): string + { + return $this->password; + } + + /** + * @param string $password + */ + public function setPassword(string $password): void + { + $this->password = $password; + } + + /** + * @return string + */ + public function getPasswordConfirmation(): string + { + return $this->passwordConfirmation; + } + + /** + * @param string $passwordConfirmation + */ + public function setPasswordConfirmation(string $passwordConfirmation): void + { + $this->passwordConfirmation = $passwordConfirmation; + } + + /** + * @return string + */ + public function getSubmit(): string + { + return $this->submit; + } + + /** + * @param string $submit + */ + public function setSubmit(string $submit): void + { + $this->submit = $submit; + } +} diff --git a/module/fid/src/FormModel/PasswordResetModel.php b/module/fid/src/FormModel/PasswordResetModel.php new file mode 100644 index 0000000000000000000000000000000000000000..2089e06991f46360e4ccfca033dca187df9198d4 --- /dev/null +++ b/module/fid/src/FormModel/PasswordResetModel.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\FormModel; + +use Zend\Form\Annotation; + +/** + * @Annotation\Name("passwordreset") + * @Annotation\Hydrator("Zend\Hydrator\ClassMethods") + */ +class PasswordResetModel +{ + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Email") + * @Annotation\Required({"required":"true"}) + * @Annotation\Filter({"name": "StringTrim"}) + * @Annotation\Validator({ + * "name": "StringLength", + * "options": {"min": 1, "max": 255} + * }) + * @Annotation\Validator({"name": "Zend\Validator\EmailAddress"}) + * @Annotation\Options({"label": "label_username"}) + */ + protected $username; + + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Submit") + * @Annotation\Attributes({"value": "label_submit"}) + */ + protected $submit; + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * @param string $username + */ + public function setUsername(string $username): void + { + $this->username = $username; + } + + /** + * @return string + */ + public function getSubmit(): string + { + return $this->submit; + } + + /** + * @param string $submit + */ + public function setSubmit(string $submit): void + { + $this->submit = $submit; + } +} diff --git a/module/fid/src/FormModel/UserCreateModel.php b/module/fid/src/FormModel/UserCreateModel.php new file mode 100644 index 0000000000000000000000000000000000000000..ab2ae8adbd01c8e331576868983747e6ec419fd1 --- /dev/null +++ b/module/fid/src/FormModel/UserCreateModel.php @@ -0,0 +1,416 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\FormModel; + +use Zend\Form\Annotation; + +/** + * @Annotation\Name("user_create") + * @Annotation\Hydrator("Zend\Hydrator\ClassMethods") + */ +class UserCreateModel +{ + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(true) + * @Annotation\Options({"label": "label_username"}) + */ + protected $username; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Password") + * @Annotation\Required(true) + * @Annotation\Filter({"name":"StringTrim"}) + * @Annotation\Validator({ + * "name":"StringLength", "options":{ + * "min":8, "max":255, "messages": { + * "stringLengthTooShort": "error_password_length", + * "stringLengthTooLong": "error_password_length" + * } + * } + * }) + * @Annotation\Validator({ + * "name": "Regex", "options": { + * "pattern": "/(?:.*[0-9].*[^\w].*|.*[^\w].*[0-9].*)/", + * "messages": { + * "regexNotMatch": "error_password_pattern" + * } + * } + * }) + * @Annotation\Validator({ + * "name": "Identical", "options": { + * "strict": false, + * "token": "passwordConfirmation", + * "messages": {"notSame": "error_password_confirmation"} + * } + * }) + * @Annotation\Options({"label": "label_password"}) + */ + protected $password; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Password") + * @Annotation\Required(true) + * @Annotation\Validator({"name":"NotEmpty"}) + * @Annotation\Options({"label":"label_password_confirmation"}) + */ + protected $passwordConfirmation; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Select") + * @Annotation\Required(false) + * @Annotation\Options({ + * "label": "label_salutation", + * "empty_option": "", + * "options":{ + * {"value": "mr", "label": "label_salutation_mr"}, + * {"value": "mrs", "label": "label_salutation_mrs"} + * } + * }) + */ + protected $salutation; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(false) + * @Annotation\Filter({"name":"StringTrim"}) + * @Annotation\Options({"label": "label_academic_title"}) + */ + protected $academicTitle; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(true) + * @Annotation\Filter({"name":"StringTrim"}) + * @Annotation\Validator({ + * "name": "StringLength", + * "options": {"min": 1, "max": 255} + * }) + * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"}) + * @Annotation\Validator({ + * "name": "Regex", + * "options": {"pattern": "/^\D*$/"} + * }) + * @Annotation\Options({"label": "label_firstname"}) + */ + protected $firstname; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(true) + * @Annotation\Filter({"name": "StringTrim"}) + * @Annotation\Validator({ + * "name": "StringLength", + * "options": {"min":1, "max":255} + * }) + * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"}) + * @Annotation\Validator({ + * "name": "Regex", + * "options": {"pattern":"/^\D*$/"} + * }) + * @Annotation\Options({"label": "label_lastname"}) + */ + protected $lastname; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Select") + * @Annotation\Required(true) + * @Annotation\Validator({ + * "name": "StringLength", + * "options": {"min":1, "max":255} + * }) + * @Annotation\Options({ + * "label": "label_home_library", + * "disable_inarray_validator": true, + * "empty_option": "" + * }) + */ + protected $homeLibrary; + + /** + * @var int|null + * @Annotation\Type("Zend\Form\Element\Number") + * @Annotation\Required(false) + * @Annotation\Attributes({"min": 1900, "max": 2018}) + * @Annotation\Options({"label": "label_year_of_birth"}) + * @Annotation\Filter({"name": "ToNull"}) + * @Annotation\Filter({"name": "ToInt"}) + */ + protected $yearOfBirth; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(false) + * @Annotation\Filter({"name":"StringTrim"}) + * @Annotation\Options({"label": "label_job_title"}) + */ + protected $jobTitle; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Filter({"name":"StringTrim"}) + * @Annotation\Required(false) + * @Annotation\Options({"label": "label_college"}) + */ + protected $college; + + /** + * @var bool + * @Annotation\Type("Zend\Form\Element\Checkbox") + * @Annotation\Required(true) + * @Annotation\Filter({"name": "Boolean"}) + * @Annotation\Validator({ + * "name": "Identical", "options": { + * "token": true, + * "messages": {"notSame": "error_eula_accepted"} + * } + * }) + */ + protected $eulaAccepted; + + /** + * @var string + * @Annotation\Required(true) + * @Annotation\Type("Zend\Form\Element\Submit") + * @Annotation\Attributes({"value": "label_submit"}) + */ + protected $submit; + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * @param string $username + */ + public function setUsername(string $username): void + { + $this->username = $username; + } + + /** + * @return string + */ + public function getFirstname(): string + { + return $this->firstname; + } + + /** + * @param string $firstname + */ + public function setFirstname(string $firstname): void + { + $this->firstname = $firstname; + } + + /** + * @return string + */ + public function getLastname(): string + { + return $this->lastname; + } + + /** + * @param string $lastname + */ + public function setLastname(string $lastname): void + { + $this->lastname = $lastname; + } + + /** + * @return string + */ + public function getSalutation(): string + { + return $this->salutation; + } + + /** + * @param string $salutation + */ + public function setSalutation(string $salutation): void + { + $this->salutation = $salutation; + } + + /** + * @return string + */ + public function getAcademicTitle(): string + { + return $this->academicTitle; + } + + /** + * @param string $academicTitle + */ + public function setAcademicTitle(string $academicTitle): void + { + $this->academicTitle = $academicTitle; + } + + /** + * @return string + */ + public function getHomeLibrary(): string + { + return $this->homeLibrary; + } + + /** + * @param string $homeLibrary + */ + public function setHomeLibrary(string $homeLibrary): void + { + $this->homeLibrary = $homeLibrary; + } + + /** + * @return int|null + */ + public function getYearOfBirth(): ?int + { + return $this->yearOfBirth; + } + + /** + * @param int|null $yearOfBirth + */ + public function setYearOfBirth(?int $yearOfBirth): void + { + $this->yearOfBirth = $yearOfBirth; + } + + /** + * @return bool + */ + public function isEulaAccepted(): bool + { + return $this->eulaAccepted; + } + + /** + * @param bool $eulaAccepted + */ + public function setEulaAccepted(bool $eulaAccepted): void + { + $this->eulaAccepted = $eulaAccepted; + } + + /** + * @return string + */ + public function getSubmit(): string + { + return $this->submit; + } + + /** + * @param string $submit + */ + public function setSubmit(string $submit): void + { + $this->submit = $submit; + } + + /** + * @return string + */ + public function getJobTitle(): string + { + return $this->jobTitle; + } + + /** + * @param string $jobTitle + */ + public function setJobTitle(string $jobTitle): void + { + $this->jobTitle = $jobTitle; + } + + /** + * @return string + */ + public function getCollege(): string + { + return $this->college; + } + + /** + * @param string $college + */ + public function setCollege(string $college): void + { + $this->college = $college; + } + + /** + * @return string + */ + public function getPassword(): string + { + return $this->password; + } + + /** + * @param string $password + */ + public function setPassword(string $password): void + { + $this->password = $password; + } + + /** + * @return string + */ + public function getPasswordConfirmation(): string + { + return $this->passwordConfirmation; + } + + /** + * @param string $passwordConfirmation + */ + public function setPasswordConfirmation(string $passwordConfirmation): void + { + $this->passwordConfirmation = $passwordConfirmation; + } +} diff --git a/module/fid/src/FormModel/UserInitModel.php b/module/fid/src/FormModel/UserInitModel.php new file mode 100644 index 0000000000000000000000000000000000000000..bce1dcc44b598ebd2e3f2cbdb463c819131de1b1 --- /dev/null +++ b/module/fid/src/FormModel/UserInitModel.php @@ -0,0 +1,216 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\FormModel; + +use Zend\Form\Annotation; + +/** + * @Annotation\Name("user_init") + * @Annotation\Hydrator("Zend\Hydrator\ClassMethods") + */ +class UserInitModel +{ + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Email") + * @Annotation\Required(true) + * @Annotation\Filter({"name": "StringTrim"}) + * @Annotation\Validator({ + * "name": "StringLength", + * "options": {"min": 1, "max": 255} + * }) + * @Annotation\Validator({"name": "Zend\Validator\EmailAddress"}) + * @Annotation\Options({"label": "label_username"}) + */ + protected $username; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(true) + * @Annotation\Validator({ + * "name": "Zend\Validator\Identical", + * "options": { + * "strict": false, + * "token": "username", + * "messages": { "notSame": "error_username_confirmation" } + * } + * }) + * @Annotation\Options({"label": "label_username_confirmation"}) + */ + protected $usernameConfirmation; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(true) + * @Annotation\Filter({"name":"StringTrim"}) + * @Annotation\Validator({ + * "name": "StringLength", + * "options": {"min": 1, "max": 255} + * }) + * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"}) + * @Annotation\Validator({ + * "name": "Regex", + * "options": {"pattern": "/^\D*$/"} + * }) + * @Annotation\Options({"label": "label_firstname"}) + */ + protected $firstname; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(true) + * @Annotation\Filter({"name": "StringTrim"}) + * @Annotation\Validator({ + * "name": "StringLength", + * "options": {"min":1, "max":255} + * }) + * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"}) + * @Annotation\Validator({ + * "name": "Regex", + * "options": {"pattern":"/^\D*$/"} + * }) + * @Annotation\Options({"label": "label_lastname"}) + */ + protected $lastname; + + /** + * @var bool + * @Annotation\Type("Zend\Form\Element\Checkbox") + * @Annotation\Required(true) + * @Annotation\Validator({"name":"NotEmpty"}) + * @Annotation\Filter({"name": "Boolean"}) + * @Annotation\Validator({ + * "name": "Identical", "options": { + * "token": true, + * "messages": {"notSame": "error_eula_accepted"} + * } + * }) + */ + protected $eulaAccepted; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Submit") + * @Annotation\Attributes({"value": "label_submit"}) + */ + protected $submit; + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * @param string $username + */ + public function setUsername(string $username): void + { + $this->username = $username; + } + + /** + * @return string + */ + public function getUsernameConfirmation(): string + { + return $this->usernameConfirmation; + } + + /** + * @param string $usernameConfirmation + */ + public function setUsernameConfirmation(string $usernameConfirmation): void + { + $this->usernameConfirmation = $usernameConfirmation; + } + + /** + * @return string + */ + public function getFirstname(): string + { + return $this->firstname; + } + + /** + * @param string $firstname + */ + public function setFirstname(string $firstname): void + { + $this->firstname = $firstname; + } + + /** + * @return string + */ + public function getLastname(): string + { + return $this->lastname; + } + + /** + * @param string $lastname + */ + public function setLastname(string $lastname): void + { + $this->lastname = $lastname; + } + + /** + * @return bool + */ + public function isEulaAccepted(): bool + { + return $this->eulaAccepted; + } + + /** + * @param bool $eulaAccepted + */ + public function setEulaAccepted(bool $eulaAccepted): void + { + $this->eulaAccepted = $eulaAccepted; + } + + /** + * @return string + */ + public function getSubmit(): string + { + return $this->submit; + } + + /** + * @param string $submit + */ + public function setSubmit(string $submit): void + { + $this->submit = $submit; + } +} diff --git a/module/fid/src/FormModel/UserUpdateModel.php b/module/fid/src/FormModel/UserUpdateModel.php new file mode 100644 index 0000000000000000000000000000000000000000..28de1a1ef8af0a8ccd5469271517cfec6645b05a --- /dev/null +++ b/module/fid/src/FormModel/UserUpdateModel.php @@ -0,0 +1,288 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\FormModel; + +use Zend\Form\Annotation; + +/** + * @Annotation\Name("user_update") + * @Annotation\Hydrator("Zend\Hydrator\ClassMethods") + */ +class UserUpdateModel +{ + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Select") + * @Annotation\Required(false) + * @Annotation\Options({ + * "label": "label_salutation", + * "empty_option": "", + * "options":{ + * {"value": "mr", "label": "label_salutation_mr"}, + * {"value": "mrs", "label": "label_salutation_mrs"} + * } + * }) + */ + protected $salutation; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(false) + * @Annotation\Filter({"name":"StringTrim"}) + * @Annotation\Options({"label": "label_academic_title"}) + */ + protected $academicTitle; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(true) + * @Annotation\Filter({"name":"StringTrim"}) + * @Annotation\Validator({ + * "name": "StringLength", + * "options": {"min": 1, "max": 255} + * }) + * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"}) + * @Annotation\Validator({ + * "name": "Regex", + * "options": {"pattern": "/^\D*$/"} + * }) + * @Annotation\Options({"label": "label_firstname"}) + */ + protected $firstname; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(true) + * @Annotation\Filter({"name": "StringTrim"}) + * @Annotation\Validator({ + * "name": "StringLength", + * "options": {"min":1, "max":255} + * }) + * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"}) + * @Annotation\Validator({ + * "name": "Regex", + * "options": {"pattern":"/^\D*$/"} + * }) + * @Annotation\Options({"label": "label_lastname"}) + */ + protected $lastname; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Select") + * @Annotation\Required(true) + * @Annotation\Validator({ + * "name": "StringLength", + * "options": {"min":1, "max":255} + * }) + * @Annotation\Options({ + * "label": "label_home_library", + * "disable_inarray_validator": true, + * "empty_option": "" + * }) + */ + protected $homeLibrary; + + /** + * @var int|null + * @Annotation\Type("Zend\Form\Element\Number") + * @Annotation\Required(false) + * @Annotation\Attributes({"min": 1900, "max": 2018}) + * @Annotation\Options({"label": "label_year_of_birth"}) + * @Annotation\Filter({"name": "ToNull"}) + * @Annotation\Filter({"name": "ToInt"}) + */ + protected $yearOfBirth; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Required(false) + * @Annotation\Filter({"name":"StringTrim"}) + * @Annotation\Options({"label": "label_job_title"}) + */ + protected $jobTitle; + + /** + * @var string + * @Annotation\Type("Zend\Form\Element\Text") + * @Annotation\Filter({"name":"StringTrim"}) + * @Annotation\Required(false) + * @Annotation\Options({"label": "label_college"}) + */ + protected $college; + + /** + * @var string|null + * @Annotation\Type("Zend\Form\Element\Submit") + * @Annotation\Attributes({"value": "label_submit"}) + */ + protected $submit; + + /** + * @return string + */ + public function getSalutation(): ?string + { + return $this->salutation; + } + + /** + * @param string $salutation + */ + public function setSalutation(string $salutation): void + { + $this->salutation = $salutation; + } + + /** + * @return string|null + */ + public function getAcademicTitle(): ?string + { + return $this->academicTitle; + } + + /** + * @param string $academicTitle + */ + public function setAcademicTitle(string $academicTitle): void + { + $this->academicTitle = $academicTitle; + } + + /** + * @return string + */ + public function getFirstname(): string + { + return $this->firstname; + } + + /** + * @param string $firstname + */ + public function setFirstname(string $firstname): void + { + $this->firstname = $firstname; + } + + /** + * @return string + */ + public function getLastname(): string + { + return $this->lastname; + } + + /** + * @param string $lastname + */ + public function setLastname(string $lastname): void + { + $this->lastname = $lastname; + } + + /** + * @return string + */ + public function getHomeLibrary(): string + { + return $this->homeLibrary; + } + + /** + * @param string $homeLibrary + */ + public function setHomeLibrary(string $homeLibrary): void + { + $this->homeLibrary = $homeLibrary; + } + + /** + * @return int|null + */ + public function getYearOfBirth(): ?int + { + return $this->yearOfBirth; + } + + /** + * @param int|null $yearOfBirth + */ + public function setYearOfBirth(?int $yearOfBirth): void + { + $this->yearOfBirth = $yearOfBirth; + } + + /** + * @return string + */ + public function getJobTitle(): string + { + return $this->jobTitle; + } + + /** + * @param string $jobTitle + */ + public function setJobTitle(string $jobTitle): void + { + $this->jobTitle = $jobTitle; + } + + /** + * @return string + */ + public function getCollege(): string + { + return $this->college; + } + + /** + * @param string $college + */ + public function setCollege(string $college): void + { + $this->college = $college; + } + + /** + * @return string|null + */ + public function getSubmit(): ?string + { + return $this->submit; + } + + /** + * @param string|null $submit + */ + public function setSubmit(?string $submit): void + { + $this->submit = $submit; + } +} diff --git a/module/fid/src/Helper/RegistrationFormLabel.php b/module/fid/src/Helper/RegistrationFormLabel.php new file mode 100644 index 0000000000000000000000000000000000000000..d70914bd9fb22238d822ccd26cb72f1f7df27196 --- /dev/null +++ b/module/fid/src/Helper/RegistrationFormLabel.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Helper; + +use Zend\Form\View\Helper\FormLabel; +use Zend\Form\ElementInterface; + +class RegistrationFormLabel extends FormLabel +{ + /** + * Generate a form label, optionally with content + * + * Always generates a "for" statement, as we cannot assume the form input + * will be provided in the $labelContent. + * + * @param ElementInterface $element + * @param null|string $labelContent + * @param string $position + * @throws Exception\DomainException + * @return string|FormLabel + */ + public function __invoke(ElementInterface $element = null, $labelContent = null, $position = null) + { + if ($element && $element->getAttribute("required") && empty($labelContent)) { + $labelContent = '*'; + $position = self::PREPEND; + } + + return parent::__invoke($element, $labelContent, $position); + } +} diff --git a/module/fid/src/Helper/TranslatorDelegator.php b/module/fid/src/Helper/TranslatorDelegator.php new file mode 100644 index 0000000000000000000000000000000000000000..76fe0c9105f8bcb11e8926d8a8b8163b5ef6a0fb --- /dev/null +++ b/module/fid/src/Helper/TranslatorDelegator.php @@ -0,0 +1,49 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Helper; + +use Psr\Container\ContainerInterface; +use Zend\I18n\Translator\Resources; + +class TranslatorDelegator +{ + public function __invoke( + ContainerInterface $container, + $name, + callable $callback + ) { + $translator = call_user_func($callback); + + $translator->addTranslationFilePattern( + 'phpArray', + Resources::getBasePath(), + Resources::getPatternForValidator() + ); + $translator->addTranslationFilePattern( + 'phpArray', + Resources::getBasePath(), + Resources::getPatternForCaptcha() + ); + + return $translator; + } +} diff --git a/module/fid/src/Listener/ErrorListener.php b/module/fid/src/Listener/ErrorListener.php new file mode 100644 index 0000000000000000000000000000000000000000..4bfd059b814da87d8894e31f4693fc1096ff1424 --- /dev/null +++ b/module/fid/src/Listener/ErrorListener.php @@ -0,0 +1,80 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Listener; + +use fid\Service\ClientException; +use VuFind\Auth\Manager; +use Zend\EventManager\AbstractListenerAggregate; +use Zend\EventManager\EventInterface; +use Zend\EventManager\EventManagerInterface; +use Zend\Mvc\Controller\Plugin\Redirect; +use Zend\Mvc\MvcEvent; + +class ErrorListener extends AbstractListenerAggregate +{ + protected const ERROR_EVENTS + = [ + MvcEvent::EVENT_DISPATCH_ERROR, + MvcEvent::EVENT_RENDER_ERROR, + ]; + + /** + * @var Manager + */ + protected $manager; + + /** + * @var Redirect + */ + protected $redirect; + + public function __construct(Manager $manager, Redirect $redirect) + { + $this->manager = $manager; + $this->redirect = $redirect; + } + + public function attach(EventManagerInterface $events, $priority = 20000) + { + foreach (static::ERROR_EVENTS as $event) { + $events->attach($event, [$this, 'onError'], $priority); + } + } + + /** + * TODO: Do we still need this listener? + * + * @param EventInterface|MvcEvent $event + */ + public function onError(EventInterface $event): void + { + // $exception = $event->getParam('exception'); + // $logoutAndRefresh = $exception instanceof ClientException; + // // && $exception->getCode() === 401; + // + // if ($logoutAndRefresh) { + // $this->manager->logout(null, true); + // $event->setResponse($this->redirect->refresh()); + // $event->stopPropagation(); + // } + } +} \ No newline at end of file diff --git a/module/fid/src/Listener/ErrorListenerFactory.php b/module/fid/src/Listener/ErrorListenerFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..af3d0b75e34f86566fead9ba179895ff84347011 --- /dev/null +++ b/module/fid/src/Listener/ErrorListenerFactory.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Listener; + +use ProxyManager\Factory\LazyLoadingValueHolderFactory; +use Psr\Container\ContainerInterface; +use VuFind\Auth\Manager as AuthManager; +use Zend\Mvc\Controller\Plugin\Redirect; +use Zend\Mvc\Controller\PluginManager; + +class ErrorListenerFactory +{ + public function __invoke(ContainerInterface $container) + { + /** @var AuthManager $manager */ + $manager = $container->get(AuthManager::class); + $factory = new LazyLoadingValueHolderFactory(); + /** @var Redirect $redirect */ + $redirect = $factory->createProxy(Redirect::class, + function (&$instance, $proxy, $method, $params, &$initializer) + use ($container) { + $initializer = null; + $instance = $container->get(PluginManager::class) + ->get(Redirect::class); + }); + + return new ErrorListener($manager, $redirect); + } +} \ No newline at end of file diff --git a/module/fid/src/Listener/LocaleListener.php b/module/fid/src/Listener/LocaleListener.php new file mode 100644 index 0000000000000000000000000000000000000000..f69a9613582f971656068531c89ee35c0baebc21 --- /dev/null +++ b/module/fid/src/Listener/LocaleListener.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Listener; + +use fid\Service\Client; +use Zend\EventManager\AbstractListenerAggregate; +use Zend\EventManager\EventManagerInterface; +use Zend\Mvc\I18n\Translator; +use Zend\Mvc\MvcEvent; + +class LocaleListener extends AbstractListenerAggregate +{ + protected const EVENT = MvcEvent::EVENT_DISPATCH; + + public function attach(EventManagerInterface $events, $priority = 9000) + { + $events->attach(static::EVENT, [$this, 'onDispatch'], $priority); + } + + /** + * @param MvcEvent $event + */ + public function onDispatch(MvcEvent $event) + { + $container = $event->getApplication()->getServiceManager(); + /** @var Client $client */ + $client = $container->get(Client::class); + $locale = $container->get(Translator::class)->getLocale(); + $client->setLocale($locale); + } +} \ No newline at end of file diff --git a/module/fid/src/Module.php b/module/fid/src/Module.php new file mode 100644 index 0000000000000000000000000000000000000000..4f7205c813e1b4f2de2acb33dff19d14cd6c0946 --- /dev/null +++ b/module/fid/src/Module.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid; + +use Zend\ModuleManager\Feature\ConfigProviderInterface; + +class Module implements ConfigProviderInterface +{ + public function getConfig(): array + { + return require __DIR__ . '/../config/module.config.php'; + } +} diff --git a/module/fid/src/Service/Client.php b/module/fid/src/Service/Client.php new file mode 100644 index 0000000000000000000000000000000000000000..7bdb8eca18fe3c75f94a8479c1d673be48b7f754 --- /dev/null +++ b/module/fid/src/Service/Client.php @@ -0,0 +1,474 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Service; + +use fid\Service\DataTransferObject\Library; +use fid\Service\DataTransferObject\Logon; +use fid\Service\DataTransferObject\User; +use InvalidArgumentException; +use Psr\Http\Client\ClientExceptionInterface as HttpClientExceptionInterface; +use Psr\Http\Client\ClientInterface as HttpClientInterface; +use Psr\Http\Message\RequestFactoryInterface; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\UriFactoryInterface; +use Symfony\Component\Serializer\SerializerInterface; +use VuFind\Cookie\CookieManager; +use Zend\Session\Container as Session; + +class Client +{ + protected const ERRMSG_HTTPCLIENT + = 'An unexpected http client error occured.'; + + protected const ERRMSG_HTTPRESPONSE + = 'An unexcected http response occured.'; + + /** + * @var string + */ + protected $baseUrl; + + /** + * @var Session + */ + protected $session; + + + /** + * @var CookieManager + */ + protected $cookies; + + /** + * @var SerializerInterface + */ + protected $serializer; + + /** + * @var HttpClientInterface + */ + protected $httpClient; + + /** + * @var UriFactoryInterface + */ + protected $uriFactory; + + /** + * @var StreamFactoryInterface + */ + protected $streamFactory; + + /** + * @var RequestInterface + */ + protected $requestFactory; + + /** + * @var string + */ + protected $locale = 'en'; + + /** + * Client constructor. + * + * @param string $baseUrl + * @param Session $session + * @param CookieManager $cookies + * @param SerializerInterface $serializer + * @param HttpClientInterface $httpClient + * @param UriFactoryInterface $uriFactory + * @param StreamFactoryInterface $streamFactory + * @param RequestFactoryInterface $requestFactory + */ + public function __construct( + string $baseUrl, + Session $session, + CookieManager $cookies, + SerializerInterface $serializer, + HttpClientInterface $httpClient, + UriFactoryInterface $uriFactory, + StreamFactoryInterface $streamFactory, + RequestFactoryInterface $requestFactory + ) { + $this->baseUrl = $baseUrl; + $this->session = $session; + $this->cookies = $cookies; + $this->serializer = $serializer; + $this->httpClient = $httpClient; + $this->uriFactory = $uriFactory; + $this->streamFactory = $streamFactory; + $this->requestFactory = $requestFactory; + } + + /** + * @param string $locale + */ + public function setLocale(string $locale): void + { + $this->locale = $locale; + } + + public function isLoggedOn(): bool + { + try { + return !!$this->restoreLogon(); + } catch (ClientException $exception) { + return false; + } + } + + /** + * @param string[] $credentials + * + * @return Logon + * @throws ClientException + */ + public function logon(string ...$credentials): Logon + { + $this->logoff(); + + switch (count($credentials)) { + case 1: + $credentials = base64_decode(urldecode($credentials[0])); + $logon = $this->storeLogon($this->parseLogon($credentials)); + return $this->refreshLogon($logon); + + case 2: + list($username, $password) = $credentials; + $body = json_encode(compact('username', 'password')); + $request = $this->buildRequest('post', 'logons', $body); + $response = $this->sendRequest($request); + + if ($response->getStatusCode() !== 201) { + $this->throwException($response); + } + + $logon = $this->parseLogon((string)$response->getBody()); + return $this->storeLogon($logon); + + default: + throw new InvalidArgumentException(); + } + } + + /** + * @throws ClientException + */ + public function logoff(): void + { + try { + $logon = $this->restoreLogon(); + } catch (ClientException $exception) { + return; + } + + $username = $logon->getUsername(); + $request = $this->buildRequest('delete', "logons/$username"); + $this->cookies->set('finc_fid_logon', null); + $this->session->exchangeArray([]); + + $response = $this->sendRequest($request); + switch ($response->getStatusCode()) { + case 404: + case 204: + break; + default: + $this->throwException($response); + } + } + + /** + * @param string $baseUrl + * @param string $username + * @param string $firstname + * @param string $lastname + * + * @throws ClientException + */ + public function requestRegistrationLink( + string $baseUrl, + string $username, + string $firstname, + string $lastname + ): void { + $body = json_encode(compact('baseUrl', 'username', 'firstname', + 'lastname')); + $request = $this->buildRequest('post', 'mail/registration', $body); + $response = $this->sendRequest($request); + + if ($response->getStatusCode() !== 204) { + $this->throwException($response); + } + } + + /** + * @param string $baseUrl + * @param string $username + * + * @return void + * @throws ClientException + */ + public function requestPasswordLink(string $baseUrl, string $username): void + { + $body = json_encode(compact('baseUrl', 'username')); + $request = $this->buildRequest('post', 'mail/password', $body); + $response = $this->sendRequest($request); + + if ($response->getStatusCode() !== 204) { + $this->throwException($response); + } + } + + + /** + * @return User|null + * @throws ClientException + */ + public function requestUserDetails(): ?User + { + $logon = $this->restoreLogon(); + + /** @var User $user */ + if ($user = $this->session['user'] ?? null) { + return $user; + } + + $userId = $logon->getOwnerId(); + $request = $this->buildRequest('get', "users/$userId"); + $response = $this->sendAuthenticatedRequest($request); + + if ($response->getStatusCode() !== 200) { + $this->throwException($response); + } + + /** @var User $user */ + $user = $this->serializer->deserialize((string)$response->getBody(), + User::class, 'json', ['groups' => ['user:details:response']]); + + return $this->session['user'] = $user; + } + + /** + * @param User $user + * + * @return User + * @throws ClientException + */ + public function requestUserCreation(User $user): User + { + $body = $this->serializer->serialize($user, 'json', [ + 'groups' => ['user:creation:request'] + ]); + + $request = $this->buildRequest('post', 'users', $body); + $response = $this->sendAuthenticatedRequest($request); + + if ($response->getStatusCode() !== 201) { + $this->throwException($response); + } + /** @var User $result */ + $result = $this->serializer->deserialize((string)$response->getBody(), + User::class, 'json', ['groups' => ['user:creation:response']]); + + return $result; + } + + /** + * @param User $user + * + * @return User + * @throws ClientException + */ + public function requestUserUpdate(User $user): User + { + $body = $this->serializer->serialize($user, 'json', + ['groups' => ['user:update:request']]); + $request = $this->buildRequest('put', "users/{$user->getId()}", $body); + $response = $this->sendAuthenticatedRequest($request); + + if ($response->getStatusCode() !== 200) { + $this->throwException($response); + } + /** @var User $result */ + $result = $this->serializer->deserialize((string)$response->getBody(), + User::class, 'json', ['groups' => ['user:update:response']]); + + return $this->session['user'] = $result; + } + + /** + * @return Library[] + * @throws ClientException + */ + public function requestLibraryList(): array + { + if ($list = $this->session['libraries'] ?? null) { + return $list; + } + + $request = $this->buildRequest('get', 'libraries'); + $response = $this->sendAuthenticatedRequest($request); + + if ($response->getStatusCode() !== 200) { + $this->throwException($response); + } + /** @var Library[] $list */ + $list = $this->serializer->deserialize( + (string)$response->getBody(), Library::class . '[]', 'json'); + + $keys = array_map(function (Library $libary) { + return $libary->getId(); + }, $list); + + return $this->session['libraries'] = array_combine($keys, $list); + } + + + /** + * @return Logon + * @throws ClientException + */ + protected function refreshLogon(Logon $logon): Logon + { + if (time() < $logon->getStalesAt()) { + return $logon; + } + + $username = $logon->getUsername(); + $password = $logon->getPassword(); + $body = json_encode(compact('username', 'password')); + $request = $this->buildRequest('post', 'logons', $body); + $response = $this->sendAuthenticatedRequest($request, false); + + if ($response->getStatusCode() !== 201) { + $this->throwException($response); + } + + $logon = $this->parseLogon((string)$response->getBody()); + return $this->storeLogon($logon); + } + + /** + * @param RequestInterface $request + * @param bool $retryOn401 + * + * @return ResponseInterface + * @throws ClientException + */ + protected function sendAuthenticatedRequest( + RequestInterface $request, + bool $retryOn401 = true + ): ResponseInterface { + $token = $this->restoreLogon()->getToken(); + $request = $request->withHeader('Authorization', "Bearer $token"); + $response = $this->sendRequest($request); + + if ($response->getStatusCode() === 401 && $retryOn401) { + $this->refreshLogon(); + return $this->sendAuthenticatedRequest($request, false); + } + + return $response; + } + + /** + * @param RequestInterface $request + * + * @return ResponseInterface + * @throws ClientException + */ + protected function sendRequest(RequestInterface $request): ResponseInterface + { + try { + return $this->httpClient->sendRequest($request); + } catch (HttpClientExceptionInterface $exception) { + throw new ClientException(self::ERRMSG_HTTPCLIENT, 0, $exception); + } + } + + protected function buildRequest( + string $verb, + string $path, + string $body = '', + array $query = [] + ): RequestInterface { + $uri = $this->uriFactory->createUri("$this->baseUrl/$path") + ->withQuery(http_build_query($query)); + + return $this->requestFactory->createRequest($verb, $uri) + ->withBody($this->streamFactory->createStream($body)) + ->withHeader('Content-type', 'application/json') + ->withHeader('Accept', 'application/json') + ->withHeader('Accept-language', $this->locale); + } + + /** + * @param ResponseInterface $response + * + * @throws ClientException + */ + protected function throwException(ResponseInterface $response) + { + $errorCode = $response->getStatusCode(); + $error = json_decode((string)$response->getBody(), true); + throw new ClientException($error['message'], $errorCode); + } + + /** + * @return Logon + * @throws ClientException + */ + protected function restoreLogon(): Logon + { + /** @var Logon $logon */ + if ($logon = $this->session['logon'] ?? null) { + $logon->setToken($this->cookies->get('finc_fid_logon')); + if (time() < $logon->getExpiresAt()) { + return $logon; + } + } + + $this->session->exchangeArray([]); + $this->cookies->set('finc_fid_logon', null); + throw new ClientException('Missing or expired logon.', 401); + } + + protected function storeLogon(Logon $logon): Logon + { + $this->cookies->set('finc_fid_logon', $token = $logon->getToken()); + $logon->setToken(null); + $this->session->exchangeArray(compact('logon')); + $logon->setToken($token); + return $logon; + + } + + protected function parseLogon(string $logon): Logon + { + $logon = $this->serializer->deserialize($logon, Logon::class, 'json'); + /** @var Logon $logon */ + return $logon; + } +} diff --git a/module/fid/src/Service/ClientException.php b/module/fid/src/Service/ClientException.php new file mode 100644 index 0000000000000000000000000000000000000000..6566710e1383f9b7a90598593ea43c9adbebf209 --- /dev/null +++ b/module/fid/src/Service/ClientException.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Service; + +class ClientException extends \Exception +{ +} diff --git a/module/fid/src/Service/ClientFactory.php b/module/fid/src/Service/ClientFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..2afe4564f104b813ccf8508feed72b21ac17b81a --- /dev/null +++ b/module/fid/src/Service/ClientFactory.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Service; + +use Psr\Container\ContainerInterface; +use Psr\Http\Client\ClientInterface as HttpClientInterface; +use Psr\Http\Message\RequestFactoryInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\UriFactoryInterface; +use Symfony\Component\Serializer\SerializerInterface; +use VuFind\Config\PluginManager; +use VuFind\Cookie\CookieManager; +use Zend\Config\Config; +use Zend\Session\Container as Session; +use Zend\Session\SessionManager; + +class ClientFactory +{ + protected const CONFIG_KEY = 'fid'; + + protected const ERROR_CONFIG_FILE = 'Invalid configuration file "%s.ini".'; + + /** + * @param ContainerInterface $container + * + * @return Client + * @throws ClientException + */ + public function __invoke(ContainerInterface $container): Client + { + $config = $container->get(PluginManager::class) + ->get(self::CONFIG_KEY)->Client; + + if (!$config instanceof Config || !$config->baseUrl) { + $message = sprintf(self::ERROR_CONFIG_FILE, self::CONFIG_KEY); + throw new ClientException($message); + } + + /** @var SessionManager $sessionManager */ + $sessionManager = $container->get(SessionManager::class); + $session = new Session(Client::class, $sessionManager); + /** @var CookieManager $cookies */ + $cookies = $container->get(CookieManager::class); + /** @var SerializerInterface $serializer */ + $serializer = $container->get(SerializerInterface::class); + /** @var HttpClientInterface $httpClient */ + $httpClient = $container->get(HttpClientInterface::class); + /** @var UriFactoryInterface $uriFactory */ + $uriFactory = $container->get(UriFactoryInterface::class); + /** @var StreamFactoryInterface $streamFactory */ + $streamFactory = $container->get(StreamFactoryInterface::class); + /** @var RequestFactoryInterface $requestFactory */ + $requestFactory = $container->get(RequestFactoryInterface::class); + + return new Client($config->baseUrl, $session, $cookies, $serializer, + $httpClient, $uriFactory, $streamFactory, $requestFactory); + } +} \ No newline at end of file diff --git a/module/fid/src/Service/DataTransferObject/Address.php b/module/fid/src/Service/DataTransferObject/Address.php new file mode 100644 index 0000000000000000000000000000000000000000..e3f84c85e273cbdd21a963c164871b7120d62a8a --- /dev/null +++ b/module/fid/src/Service/DataTransferObject/Address.php @@ -0,0 +1,210 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Service\DataTransferObject; + +use Symfony\Component\Serializer\Annotation\Groups; + +class Address +{ + /** + * @var string|null + * @Groups({ + * "user:details:response", + * "user:creation:response", + * "user:update:request", + * "user:update:response", + * }) + */ + protected $id; + + /** + * @var User|null + */ + protected $user; + + /** + * @var string|null + * @Groups({ + * "user:details:response", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $line1; + + /** + * @var string|null + * @Groups({ + * "user:details:response", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $line2; + + /** + * @var string|null + * @Groups({ + * "user:details:response", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $zip; + + /** + * @var string|null + * @Groups({ + * "user:details:response", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $city; + + /** + * @var string|null + * @Groups({ + * "user:details:response", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $country; + + /** + * @return int|null + */ + public function getId(): ?int + { + return $this->id; + } + + /** + * @param int|null $id + */ + public function setId(?int $id): void + { + $this->id = $id; + } + + /** + * @return User|null + */ + public function getUser(): ?User + { + return $this->user; + } + + /** + * @param User|null $user + */ + public function setUser(?User $user): void + { + $this->user = $user; + } + + /** + * @return string|null + */ + public function getLine1(): ?string + { + return $this->line1; + } + + /** + * @param string|null $line1 + */ + public function setLine1(?string $line1): void + { + $this->line1 = $line1; + } + + /** + * @return string|null + */ + public function getLine2(): ?string + { + return $this->line2; + } + + /** + * @param string|null $line2 + */ + public function setLine2(?string $line2): void + { + $this->line2 = $line2; + } + + /** + * @return string|null + */ + public function getZip(): ?string + { + return $this->zip; + } + + /** + * @param string|null $zip + */ + public function setZip(?string $zip): void + { + $this->zip = $zip; + } + + /** + * @return string|null + */ + public function getCity(): ?string + { + return $this->city; + } + + /** + * @param string|null $city + */ + public function setCity(?string $city): void + { + $this->city = $city; + } + + /** + * @return string|null + */ + public function getCountry(): ?string + { + return $this->country; + } + + /** + * @param string|null $country + */ + public function setCountry(?string $country): void + { + $this->country = $country; + } +} \ No newline at end of file diff --git a/module/fid/src/Service/DataTransferObject/Library.php b/module/fid/src/Service/DataTransferObject/Library.php new file mode 100644 index 0000000000000000000000000000000000000000..05bdf494784b18feac3e601c98d571227a1e9aaf --- /dev/null +++ b/module/fid/src/Service/DataTransferObject/Library.php @@ -0,0 +1,151 @@ +<?php +/** + * Copyright (C) 2019 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/>. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license https://opensource.org/licenses/GPL-3.0 GNU GPLv3 + */ + +namespace fid\Service\DataTransferObject; + +class Library +{ + /** + * @var string + */ + protected $id; + + /** + * @var string + */ + protected $ezb = ''; + + /** + * @var string + */ + protected $dbis = ''; + + /** + * @var string + */ + protected $network = ''; + + /** + * @var string + */ + protected $boss = ''; + + /** + * @var string + */ + protected $label = ''; + + /** + * @return string + */ + public function getId(): string + { + return $this->id; + } + + /** + * @param string $id + */ + public function setId(string $id): void + { + $this->id = $id; + } + + /** + * @return string + */ + public function getEzb(): string + { + return $this->ezb; + } + + /** + * @param string $ezb + */ + public function setEzb(string $ezb): void + { + $this->ezb = $ezb; + } + + /** + * @return string + */ + public function getDbis(): string + { + return $this->dbis; + } + + /** + * @param string $dbis + */ + public function setDbis(string $dbis): void + { + $this->dbis = $dbis; + } + + /** + * @return string + */ + public function getNetwork(): string + { + return $this->network; + } + + /** + * @param string $network + */ + public function setNetwork(string $network): void + { + $this->network = $network; + } + + /** + * @return string + */ + public function getBoss(): string + { + return $this->boss; + } + + /** + * @param string $boss + */ + public function setBoss(string $boss): void + { + $this->boss = $boss; + } + + /** + * @return string + */ + public function getLabel(): string + { + return $this->label; + } + + /** + * @param string $label + */ + public function setLabel(string $label): void + { + $this->label = $label; + } +} \ No newline at end of file diff --git a/module/fid/src/Service/DataTransferObject/Logon.php b/module/fid/src/Service/DataTransferObject/Logon.php new file mode 100644 index 0000000000000000000000000000000000000000..bdefe036d16b0c0772a769b027b96b604a4030d4 --- /dev/null +++ b/module/fid/src/Service/DataTransferObject/Logon.php @@ -0,0 +1,151 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Service\DataTransferObject; + +class Logon +{ + /** + * @var string|null + */ + protected $username; + + /** + * @var string|null + */ + protected $password; + + /** + * @var int|null + */ + protected $stalesAt; + + /** + * @var int|null + */ + protected $expiresAt; + + /** + * @var string|null + */ + protected $token; + + /** + * @var string|null + */ + protected $ownerId; + + /** + * @return string|null + */ + public function getUsername(): ?string + { + return $this->username; + } + + /** + * @param string|null $username + */ + public function setUsername(?string $username): void + { + $this->username = $username; + } + + /** + * @return string|null + */ + public function getPassword(): ?string + { + return $this->password; + } + + /** + * @param string|null $password + */ + public function setPassword(?string $password): void + { + $this->password = $password; + } + + /** + * @return string|null + */ + public function getToken(): ?string + { + return $this->token; + } + + /** + * @return int|null + */ + public function getStalesAt(): ?int + { + return $this->stalesAt; + } + + /** + * @param int|null $stalesAt + */ + public function setStalesAt(?int $stalesAt): void + { + $this->stalesAt = $stalesAt; + } + + /** + * @return int|null + */ + public function getExpiresAt(): ?int + { + return $this->expiresAt; + } + + /** + * @param int|null $expiresAt + */ + public function setExpiresAt(?int $expiresAt): void + { + $this->expiresAt = $expiresAt; + } + + /** + * @param string|null $token + */ + public function setToken(?string $token): void + { + $this->token = $token; + } + + /** + * @return string|null + */ + public function getOwnerId(): ?string + { + return $this->ownerId; + } + + /** + * @param string|null $ownerId + */ + public function setOwnerId(?string $ownerId): void + { + $this->ownerId = $ownerId; + } +} diff --git a/module/fid/src/Service/DataTransferObject/User.php b/module/fid/src/Service/DataTransferObject/User.php new file mode 100644 index 0000000000000000000000000000000000000000..946aeaee983d74c3cf388716b81ad66b31bcbefe --- /dev/null +++ b/module/fid/src/Service/DataTransferObject/User.php @@ -0,0 +1,364 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\Service\DataTransferObject; + +use Symfony\Component\Serializer\Annotation\Groups; + +class User +{ + /** + * @var null|string + * @Groups({ + * "user:details:response", + * "user:creation:response", + * "user:update:response" + * }) + */ + protected $id; + + /** + * @var null|string + * @Groups({ + * "user:details:response", + * "user:creation:request", + * "user:creation:response", + * "user:update:response" + * }) + */ + protected $username; + + /** + * @var null|string + * @Groups({ + * "user:details:response", + * "user:creation:request", + * "user:update:request", + * "user:update:response", + * }) + */ + protected $password; + + /** + * @var string + * @Groups({ + * "user:details:response", + * "user:creation:request", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $salutation; + + /** + * @var string + * @Groups({ + * "user:details:response", + * "user:creation:request", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $academicTitle; + + /** + * @var null|string + * @Groups({ + * "user:details:response", + * "user:creation:request", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $firstname; + + /** + * @var null|string + * @Groups({ + * "user:details:response", + * "user:creation:request", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $lastname; + + /** + * @var null|int + * @Groups({ + * "user:details:response", + * "user:creation:request", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $yearOfBirth; + + /** + * @var null|string + * @Groups({ + * "user:details:response", + * "user:creation:request", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $homeLibrary; + + /** + * @var string + * @Groups({ + * "user:details:response", + * "user:creation:request", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $college; + + /** + * @var string + * @Groups({ + * "user:details:response", + * "user:creation:request", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $jobTitle; + + /** + * @var Address[] + * @Groups({ + * "user:details:response", + * "user:creation:request", + * "user:creation:response", + * "user:update:request", + * "user:update:response" + * }) + */ + protected $addresses = []; + + /** + * @return string|null + */ + public function getId(): ?string + { + return $this->id; + } + + /** + * @param string|null $id + */ + public function setId(?string $id): void + { + $this->id = $id; + } + + /** + * @return string|null + */ + public function getUsername(): ?string + { + return $this->username; + } + + /** + * @param string|null $username + */ + public function setUsername(?string $username): void + { + $this->username = $username; + } + + /** + * @return string|null + */ + public function getPassword(): ?string + { + return $this->password; + } + + /** + * @param string|null $password + */ + public function setPassword(?string $password): void + { + $this->password = $password; + } + + /** + * @return string|null + */ + public function getSalutation(): ?string + { + return $this->salutation; + } + + /** + * @param string|null $salutation + */ + public function setSalutation(?string $salutation): void + { + $this->salutation = $salutation; + } + + /** + * @return string|null + */ + public function getAcademicTitle(): ?string + { + return $this->academicTitle; + } + + /** + * @param string|null $academicTitle + */ + public function setAcademicTitle(?string $academicTitle): void + { + $this->academicTitle = $academicTitle; + } + + /** + * @return string|null + */ + public function getFirstname(): ?string + { + return $this->firstname; + } + + /** + * @param string|null $firstname + */ + public function setFirstname(?string $firstname): void + { + $this->firstname = $firstname; + } + + /** + * @return string|null + */ + public function getLastname(): ?string + { + return $this->lastname; + } + + /** + * @param string|null $lastname + */ + public function setLastname(?string $lastname): void + { + $this->lastname = $lastname; + } + + + /** + * @return int|null + */ + public function getYearOfBirth(): ?int + { + return $this->yearOfBirth; + } + + + /** + * @param int|null $yearOfBirth + */ + public function setYearOfBirth(?int $yearOfBirth): void + { + $this->yearOfBirth = $yearOfBirth; + } + + /** + * @return string + */ + public function getHomeLibrary(): string + { + return $this->homeLibrary; + } + + /** + * @param string $homeLibrary + */ + public function setHomeLibrary(string $homeLibrary): void + { + $this->homeLibrary = $homeLibrary; + } + + /** + * @return string + */ + public function getCollege(): string + { + return $this->college; + } + + /** + * @param string $college + */ + public function setCollege(string $college): void + { + $this->college = $college; + } + + /** + * @return string|null + */ + public function getJobTitle(): ?string + { + return $this->jobTitle; + } + + /** + * @param string|null $jobTitle + */ + public function setJobTitle(?string $jobTitle): void + { + $this->jobTitle = $jobTitle; + } + + /** + * @return Address[] + */ + public function getAddresses(): array + { + return $this->addresses; + } + + /** + * @param Address[] $addresses + */ + public function setAddresses(array $addresses): void + { + $this->addresses = $addresses; + foreach ($addresses as $address) { + $address->setUser($this); + } + } +} diff --git a/module/fid/src/VuFind/Auth/Authenticator.php b/module/fid/src/VuFind/Auth/Authenticator.php new file mode 100644 index 0000000000000000000000000000000000000000..bc518469402a520946fddd402ced6bb25d77b0d7 --- /dev/null +++ b/module/fid/src/VuFind/Auth/Authenticator.php @@ -0,0 +1,119 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\VuFind\Auth; + +use fid\Service\Client; +use fid\Service\ClientException; +use fid\VuFind\Db\Row\User as VuFindUser; +use VuFind\Auth\AbstractBase; +use VuFind\Exception\Auth; +use VuFind\Exception\Auth as AuthException; +use Zend\Http\PhpEnvironment\Request; + +class Authenticator extends AbstractBase +{ + protected const AUTH_ERROR_BAD_CREDENTIALS + = 'fid::auth_error_bad_credentials'; + + protected const AUTH_ERROR_UNKNOWN_REASON + = 'fid::auth_error_unknown_reason'; + + /** + * @var Client + */ + protected $client; + + public function __construct(Client $client) + { + $this->client = $client; + } + + public function create($request) + { + return $this->authenticate($request); + } + + + /** + * @param Request $request + * + * @return VuFindUser + * @throws AuthException + */ + public function authenticate($request) + { + $params = $request->getPost(); + $username = trim($params->get('username')); + $password = trim($params->get('password')); + + try { + $logon = $this->client->logon($username, $password); + } catch (ClientException $exception) { + switch ($exception->getCode()) { + case 401: + throw new AuthException(self::AUTH_ERROR_BAD_CREDENTIALS); + default: + throw new AuthException(self::AUTH_ERROR_UNKNOWN_REASON); + } + } + + if ($ownerId = $logon->getOwnerId()) { + /** @var VuFindUser $userRow */ + $userRow = $this->getUserTable()->getByUsername($ownerId); + + return $userRow; + } + + // May happen when trying to authenticate as non-database user. + throw new AuthException(self::AUTH_ERROR_UNKNOWN_REASON); + } + + /** + * @param string $url + * + * @return string + * @throws ClientException + */ + public function logout($url) + { + $this->client->logoff(); + return $url; + } + + /** + * @return bool + */ + public function isExpired() + { + return !$this->client->isLoggedOn(); + } + + public function supportsCreation() + { + return true; + } + + public function supportsPasswordRecovery() + { + return true; + } +} \ No newline at end of file diff --git a/module/fid/src/VuFind/Auth/AuthenticatorFactory.php b/module/fid/src/VuFind/Auth/AuthenticatorFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..21c868cfb64c9a966416c19ea0c4d622e5617034 --- /dev/null +++ b/module/fid/src/VuFind/Auth/AuthenticatorFactory.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\VuFind\Auth; + +use fid\Service\Client; +use Psr\Container\ContainerInterface; + +class AuthenticatorFactory +{ + public function __invoke(ContainerInterface $container) + { + /** @var Client $client */ + $client = $container->get(Client::class); + + return new Authenticator($client); + } +} \ No newline at end of file diff --git a/module/fid/src/VuFind/Auth/ILSAuthenticator.php b/module/fid/src/VuFind/Auth/ILSAuthenticator.php new file mode 100644 index 0000000000000000000000000000000000000000..8b4ad8e20a9b1e7518201e158348da6eb6418bc0 --- /dev/null +++ b/module/fid/src/VuFind/Auth/ILSAuthenticator.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\VuFind\Auth; + +use fid\Service\Client; +use fid\Service\ClientException; + +class ILSAuthenticator +{ + /** + * @var Client + */ + protected $client; + + public function __construct(Client $client) + { + $this->client = $client; + } + + /** + * @return array|null + * @throws ClientException + */ + public function storedCatalogLogin() + { + $user = $this->client->requestUserDetails(); + + if (!$user) { + return null; + } + + $data = [ + 'username' => $user->getUsername(), + 'firstname' => $user->getFirstname(), + 'lastname' => $user->getLastname(), + 'email' => $user->getUsername() + ]; + + if ($address = $user->getAddresses()[0] ?? null) { + $data['address1'] = implode(' ', array_filter([ + $address->getLine1() . ',', + $address->getZip(), + $address->getCity() . ',', + $address->getCountry() + ])); + } + + return $data; + } + +} \ No newline at end of file diff --git a/module/fid/src/VuFind/Auth/ILSAuthenticatorFactory.php b/module/fid/src/VuFind/Auth/ILSAuthenticatorFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..322e7c9f640f056bb0b90aa90bb36387a164da65 --- /dev/null +++ b/module/fid/src/VuFind/Auth/ILSAuthenticatorFactory.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\VuFind\Auth; + +use fid\Service\Client; +use ProxyManager\Factory\LazyLoadingValueHolderFactory; +use Psr\Container\ContainerInterface; +use VuFind\Auth\ILSAuthenticator as ProxyClass; + +class ILSAuthenticatorFactory +{ + public function __invoke(ContainerInterface $container) + { + $factory = new LazyLoadingValueHolderFactory(); + + return $factory->createProxy(ProxyClass::class, + function (&$object, $proxy, $method, $params, &$initializer) + use ($container) { + $initializer = null; + $client = $container->get(Client::class); + $object = new ILSAuthenticator($client); + }); + } +} \ No newline at end of file diff --git a/module/fid/src/VuFind/Db/Row/User.php b/module/fid/src/VuFind/Db/Row/User.php new file mode 100644 index 0000000000000000000000000000000000000000..42732432d04b6147a024bb786166ddc7789da77b --- /dev/null +++ b/module/fid/src/VuFind/Db/Row/User.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\VuFind\Db\Row; + +use fid\Service\Client; +use fid\Service\ClientException; +use VuFind\Db\Row\User as BaseUser; + +class User extends BaseUser +{ + /** + * @var Client + */ + protected $client; + + public function setClient(Client $client) + { + $this->client = $client; + } + + /** + * @param string $offset + * + * @return mixed|string|null + * @throws ClientException + */ + public function offsetGet($offset) + { + $user = $this->client->requestUserDetails(); + + switch ($offset) { + case 'firstname': + return $user->getFirstname(); + case 'lastname': + return $user->getLastname(); + case 'email': + return $user->getUsername(); + } + + return parent::offsetGet($offset); + } +} \ No newline at end of file diff --git a/module/fid/src/VuFind/Db/Row/UserDelegatorFactory.php b/module/fid/src/VuFind/Db/Row/UserDelegatorFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..4b55845265723a0d2ba745a5bf7c65a9460f6ccc --- /dev/null +++ b/module/fid/src/VuFind/Db/Row/UserDelegatorFactory.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\VuFind\Db\Row; + +use fid\Service\Client; +use Psr\Container\ContainerInterface; + +class UserDelegatorFactory +{ + public function __invoke( + ContainerInterface $container, + $name, + callable $callback + ) { + /** @var User $user */ + $user = call_user_func($callback); + $user->setClient($container->get(Client::class)); + + return $user; + } +} \ No newline at end of file diff --git a/module/fid/src/VuFind/ILS/Fid.php b/module/fid/src/VuFind/ILS/Fid.php new file mode 100644 index 0000000000000000000000000000000000000000..43ff21450b23702a321b83cded331f638580ec2c --- /dev/null +++ b/module/fid/src/VuFind/ILS/Fid.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\VuFind\ILS; + +use fid\Service\Client; +use fid\Service\ClientException; +use VuFind\Exception\ILS as ILSException; +use VuFind\ILS\Driver\AbstractBase; + +class Fid extends AbstractBase +{ + /** + * @var Client + */ + protected $client; + + public function __construct(Client $client) + { + $this->client = $client; + } + + public function init() + { + } + + /** + * @return array|null + * @throws ClientException + */ + public function patronLogin(): ?array + { + + $user = $this->client->requestUserDetails(); + + if (!$user) { + return null; + } + + return ['id' => $user->getId()]; + } + + public function getStatus($id) + { + throw new ILSException('Method not available'); + } + + public function getStatuses($ids) + { + throw new ILSException('Method not available'); + } + + public function getHolding($id, array $patron = null) + { + throw new ILSException('Method not available'); + } + + public function getPurchaseHistory($id) + { + throw new ILSException('Method not available'); + } + + public function getMyProfile($patron) + { + return $patron; + } + +} \ No newline at end of file diff --git a/module/fid/src/VuFind/ILS/FidFactory.php b/module/fid/src/VuFind/ILS/FidFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..0bdca0af98f9fb2e69689773936ea422372fb5b6 --- /dev/null +++ b/module/fid/src/VuFind/ILS/FidFactory.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +namespace fid\VuFind\ILS; + +use fid\Service\Client; +use Psr\Container\ContainerInterface; +use VuFind\Config\PluginManager as ConfigManager; + +class FidFactory +{ + public function __invoke(ContainerInterface $container): Fid + { + /** @var Client $client */ + $client = $container->get(Client::class); + + return new Fid($client); + } +} \ No newline at end of file diff --git a/themes/fid/css/.gitignore b/themes/fid/css/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ecd34d2f94d3375699b58fb65ea6fa5b0aba96d1 --- /dev/null +++ b/themes/fid/css/.gitignore @@ -0,0 +1 @@ +compiled.css \ No newline at end of file diff --git a/themes/fid/images/dfg_logo_text.png b/themes/fid/images/dfg_logo_text.png new file mode 100755 index 0000000000000000000000000000000000000000..c76cd0967ad16a87617e62afafde5e82df854dca Binary files /dev/null and b/themes/fid/images/dfg_logo_text.png differ diff --git a/themes/fid/images/finc_logo.png b/themes/fid/images/finc_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..60fe2d70accd82bbb295736da28e154b737da201 Binary files /dev/null and b/themes/fid/images/finc_logo.png differ diff --git a/themes/fid/images/headerlogo.png b/themes/fid/images/headerlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..e8f2483a48ea5a883570513a282a7e15cb251f22 Binary files /dev/null and b/themes/fid/images/headerlogo.png differ diff --git a/themes/fid/images/noCover2.gif b/themes/fid/images/noCover2.gif new file mode 100644 index 0000000000000000000000000000000000000000..5bc53f718151000dd685308578bf334338cc785e Binary files /dev/null and b/themes/fid/images/noCover2.gif differ diff --git a/themes/fid/images/sprite-mediaicons.png b/themes/fid/images/sprite-mediaicons.png new file mode 100644 index 0000000000000000000000000000000000000000..bef26e1f52b8b8c692e0b1825bd2135ace1e2a54 Binary files /dev/null and b/themes/fid/images/sprite-mediaicons.png differ diff --git a/themes/fid/images/vufind_logo.png b/themes/fid/images/vufind_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f293d40fb669e59ec5a7e5d90c62d2c52e22d39b Binary files /dev/null and b/themes/fid/images/vufind_logo.png differ diff --git a/themes/fid/images/wiso-transparent-70x20.png b/themes/fid/images/wiso-transparent-70x20.png new file mode 100644 index 0000000000000000000000000000000000000000..3eb191be82aae3862852b6a5e941d63dd22011f8 Binary files /dev/null and b/themes/fid/images/wiso-transparent-70x20.png differ diff --git a/themes/fid/languages/fid/de.ini b/themes/fid/languages/fid/de.ini new file mode 100644 index 0000000000000000000000000000000000000000..80a2527f6e780a3de1089659b800db45575e051e --- /dev/null +++ b/themes/fid/languages/fid/de.ini @@ -0,0 +1,70 @@ +auth_error_bad_credentials = Nutzername oder Passwort falsch. +auth_error_unknown_reason = Anmeldung derzeit nicht möglich. + +user_init_form_title = "Registrierung" +user_create_form_title = "Registrierung abschließen" +user_update_form_title = "Profildaten editieren." +password_reset_form_title = "Passwort zurücksetzen" +password_change_form_title = "Neues Passwort speichern" + +label_username = "E-Mail-Adresse" +label_username_confirmation = "E-Mail-Adresse wiederholen" +label_firstname = "Vorname" +label_lastname = "Nachname" +label_salutation = "Anrede" +label_salutation_mr = "Herr" +label_salutation_mrs = "Frau" +label_academic_title = "Akademischer Titel" +label_home_library = "Heimatbibliothek" +label_year_of_birth = "Geburtsjahr" +label_job_title = "Berufsbezeichnung" +label_college = "Hochschule" +label_password = "Passwort" +label_password_confirmation = "Passwort wiederholen" +label_access_level = "Ich gehöre folgender Nutzergruppe an" +label_access_level_default = "HochschullehrerInnen, wissenschaftliche MitarbeiterInnen, Mitglied einer Fachgesellschaft, DoktorandInnen, StipendiatInnen oder externe WissenschaftlerInnen (z. B. Lehrbeauftragte)" +label_access_level_other = "Studierende, Sonstige" + +label_delivery_address = "Privatadresse als Lieferadresse verwenden" +Business = "Dienstadresse" +Private = "Privatadresse" +label_line_1 = "Straße/Hausnummer" +label_line_2 = "Adr.zusatz/Fachbereich" +label_zip = "PLZ" +label_city = "Ort" +label_country = "Land" +label_submit = "Abschicken" +terms = "Nutzungsbedingungen" +policy = "Datenschutzerklärung" +policy_text = "Ich akzeptiere die " +terms_text = " und die " + +error_username = "Bitte geben Sie eine E-Mail-Adresse an." +error_username_confirmation = "Die angegebenen Email-Adressen stimmen nicht überein." +error_password_confirmation = "Die angegebenen Passwörter stimmen nicht überein." +error_password_pattern = "Das Passwort muss mindestens eine Ziffer und ein Sonderzeichen enthalten." +error_password_length = "Das Passwort muss mindestens 8 und höchstens 256 Zeichen enthalten." +error_eula_accepted = "Bitte bestätigen Sie die Datenschutzerklärung und die Nutzungsbedingungen." + +user_init_success = "Vielen Dank für Ihre Registrierung. Bitte verifizieren Sie Ihre E-Mail-Adresse über den Link, der soeben an Ihre angegebene E-Mail-Adresse (%s) gesendet wurde. Die Zustellung kann einige Minuten in Anspruch nehmen. Bitte schauen Sie ggf. auch in Ihren Spamordner." +user_init_error = "Es ist ein unerwarteter Fehler bei der Registrierung aufgetreten." +user_init_error_username = "Die von Ihnen gewählte E-Mail-Adresse ist schon vergeben." + +user_create_error = "Es ist ein unerwarteter Fehler beim Abschluss der Registrierung aufgetreten." +user_create_error_expired = "Ihr Verifikationslink ist abgelaufen. Bitte verifizieren Sie Ihre E-Mail-Adresse erneut." +user_create_error_autologon = "Vielen Dank. Ihre Registrierung war erfolgreich. Jedoch ist ein unerwarteteter Fehler bei der automatischen Anmeldung aufgetreten." +user_create_success = "Vielen Dank für Ihre Registrierung." + +user_update_error = "Es ist ein unerwarteter Fehler beim Aktualisieren Ihres Profils aufgetreten." +user_update_error_expired = "Bitte loggen Sie sich ein, um Ihr Profil zu editieren." +user_update_success = "Ihr Profil wurde erfolgreich aktualisiert." + +password_reset_error = "Es ist ein unerwarteter Fehler aufgetreten." +password_reset_error_username = "Bitte überprüfen Sie die angegebende E-Mail-Adresse %s." +password_reset_success = "Ein Link zum Ändern Ihres Passworts wurde soeben an Ihre angegebene E-Mail-Adresse %s gesendet. Die Zustellung kann einige Minuten in Anspruch nehmen. Bitte schauen Sie ggf. auch in Ihren Spamordner." + +password_change_error = "Es ist ein unerwarteter Fehler beim Aktualisieren des Passworts aufgetreten." +password_change_error_expired = "Der Link ist abgelaufen." +password_change_error_autologon = "Ihr Passwort wurde gespeichert. Jedoch ist ein unerwarteteter Fehler bei der automatischen Anmeldung aufgetreten." +password_change_success = "Passwort erfolgreich gespeichert." + diff --git a/themes/fid/languages/fid/en.ini b/themes/fid/languages/fid/en.ini new file mode 100644 index 0000000000000000000000000000000000000000..20c8bb8772b81fe7c8e7888c1e8d1c6c0ab99408 --- /dev/null +++ b/themes/fid/languages/fid/en.ini @@ -0,0 +1,70 @@ +auth_error_bad_credentials = Invalid username or password. +auth_error_unknown_reason = Login currently impossible. + +user_init_form_title = "Registration" +user_create_form_title = "Complete registration" +user_update_form_title = "Profile data" +password_reset_form_title = "Reset password" +password_change_form_title = "Save new password" + +label_username = "Email address" +label_username_confirmation = "Retype email address" +label_password = "Password" +label_password_confirmation = "Retype Password" +label_salutation = "Salutation" +label_salutation_mr = "Mr" +label_salutation_mrs = "Mrs" +label_academic_title = "Academic title" +label_firstname = "Firstname" +label_lastname = "Lastname" +label_home_library = "Home library" +label_year_of_birth = "Year of birth (YYYY)" +label_job_title = "Occupation" +label_college = "University" +label_access_level = "Please select your membership level" +label_access_level_default = "Professor, Research Associate/Assistant, Member of an Academic Association, PhD Student (also Scholarships), (Visiting) Lecturer" +label_access_level_other = "Student, Other" + +label_delivery_address = "Use the following address for deliveries" +Business = "Office Address" +Private = "Private Address" +label_line_1 = "Street" +label_line_2 = "Address Additional Postal" +label_zip = "Zip/City" +label_city = "City" +label_country = "Country" +label_submit = "Submit" +terms = "Terms of Use" +policy = "Privacy Policy" +policy_text = "I herby accept the " +terms_text = " and " + +error_username = "Please specify an email address." +error_username_confirmation = "The email addresses do not match." +error_password_confirmation = "The passwords do not match." +error_password_pattern = "The password needs to contain at least one digit and one special character." +error_password_length = "Thes password needs to contain at least 8 and at most 256 characters." +error_eula_accepted = "Please confirm the Terms of Use and Privacy Policy." + +user_init_success = "We have received your registration. We have sent you an e-mail with a validation link to %s. This may take several minutes. Please check also the junk folder of your mailbox." +user_init_error_username = "The specified email address is already taken." +user_init_error_unexpected = "An unexpected error has occurred during the process of registration." + +user_create_error = "An unexpected error has occurred during the process of completing your registration." +user_create_error_expired = "Your confirmation link has expired. Please reconfirm your email address." +user_create_error_autologon = "We have received your registration. However, an unexpected error has occurred during the process of logging on." +user_create_success = "We have received your registration." + +user_update_success = "Your profile has been successfully updated." +user_update_error = "An unexpected error has occurred when updating your profile." +user_update_error_expired = "Please log in to edit your profile." + +password_reset_error = "An unexpected error has occurred." +password_reset_error_username = "Please check if the email address %s is valid." +password_reset_success = "We have sent you an e-mail to %s containing a link for changing your password. This may take several minutes. Please check also the junk folder of your mailbox." + +password_change_success = "Password for '%s' has been successfully saved." +password_change_error = "An unexpected error has occurred." +password_change_error_expired = "The link has already expired." +password_change_error_autologon = "You password has been update. However, an unexpected error has occurred during the process of logging on." + diff --git a/themes/fid/scss/_customMixins.scss b/themes/fid/scss/_customMixins.scss new file mode 100644 index 0000000000000000000000000000000000000000..7eb29f76feb153715546e10d23be1777277c09d3 --- /dev/null +++ b/themes/fid/scss/_customMixins.scss @@ -0,0 +1,2 @@ +@import '../../finc/scss/_customMixins.scss'; + diff --git a/themes/fid/scss/_customVariables.scss b/themes/fid/scss/_customVariables.scss new file mode 100644 index 0000000000000000000000000000000000000000..793c90eb273256fba554e40c7042e920b055291f --- /dev/null +++ b/themes/fid/scss/_customVariables.scss @@ -0,0 +1,10 @@ +@import '../../finc/scss/customVariables.scss'; + +$input-height: 35px; +$input-max-width: 490px; +$margin-left-width: 5px; +$margin-right-width: 5px; +$content-left-padding: $grid-gutter-width; +$content-right-padding: $grid-gutter-width; +$button-left-margin: $margin-left-width; +$button-right-margin: $margin-right-width; diff --git a/themes/fid/scss/compiled.scss b/themes/fid/scss/compiled.scss new file mode 100644 index 0000000000000000000000000000000000000000..43d14ac7f5f6fa8c3ae9e31f53b956200aa5fbc6 --- /dev/null +++ b/themes/fid/scss/compiled.scss @@ -0,0 +1,46 @@ +// Create a compiled.SCSS file for your sub-theme which imports the respective parent theme's compiled.scss +// Your sub-theme's compiled.scss will extend it - this way we ALWAYS import an UP-TO-DATE compiled.CSS +// which includes finc plus all subsequent customizations +// i.e. finc's compiled.scss imports bootstrap3/scss/compiled - the house-specific branches such as +// de_15 will import finc/scss/compiled +// 1. Define or re-define KEY VARIABLES and MIXINS (under 1.1ff below) OR import your own (complex themes only) + +@import '../../finc/scss/compiled.scss'; + +// Create a compiled.SCSS file for all sub-themes which imports the respective parent theme's compiled.scss +// in the cascade plus extends it - this way we ALWAYS have an UP-TO-DATE compiled.CSS imported +// which includes finc plus all subsequent customizations +// i.e. finc's compiled.scss imports bootstrap3/scss/compiled - the house-specific branches such as +// de_15 then import finc/scss/compiled +// 0. Note for developers +// Do NOT EDIT compiled.css +// 1. Define or re-define KEY VARIABLES and MIXINS (see 1.1 ff below) OR import your own +@import 'customVariables'; +@import 'customMixins'; + +//.navbar { +// max-height: $navbar-height; +//} +// +//.mainbody { +// margin-left: $content-left-padding; +// margin-right: $content-right-padding; +//} +// +//.form-control { +// margin-right: $margin-right-width; +// max-width: $input-max-width; +//} +// +//.btn { +// margin-left: $button-left-margin; +// margin-right: $button-right-margin; +//} +// +form input:focus:required:invalid { + box-shadow: 0 0 2px 1px rgba(255,0,0,0.9); +} +// +//form input:invalid { +// box-shadow: none; +//} \ No newline at end of file diff --git a/themes/fid/templates/fid/user/create.phtml b/themes/fid/templates/fid/user/create.phtml new file mode 100644 index 0000000000000000000000000000000000000000..64be7935051af5577b89033652ef8dae309fafb0 --- /dev/null +++ b/themes/fid/templates/fid/user/create.phtml @@ -0,0 +1,255 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +use Zend\Form\Element\Checkbox; +use Zend\Form\Element\Submit; +use Zend\Form\Form; +use Zend\Form\Element as Element; +use Zend\Form\View\Helper\FormElementErrors; +use Zend\Form\View\Helper\FormLabel; +use Zend\Form\View\Helper\FormRadio; +use Zend\Form\View\Helper\FormSelect; +use Zend\Form\View\Helper\FormSubmit; +use Zend\I18n\Translator\TranslatorInterface; + +/** @var FormLabel $formLabel */ +$formLabel = $this->formLabel(); +/**@var FormRadio $formRadio */ +$formRadio = $this->formRadio(); +/**@var FormSelect $formSelect */ +$formSelect = $this->formSelect(); +/**@var FormSubmit $formSubmit */ +$formSubmit = $this->formSubmit(); +/** @var FormElementErrors $formElementErrors */ +$formElementErrors = $this->formElementErrors(); +$formLabel->setTranslatorTextDomain('fid'); +$formSelect->setTranslatorTextDomain('fid'); +$formRadio->setTranslatorTextDomain('fid'); +$formSubmit->setTranslatorTextDomain('fid'); +$formElementErrors->setTranslatorTextDomain('fid'); +/** @var TranslatorInterface $translator */ +$translator = $this->getHelperPluginManager()->get('translate') + ->getTranslator(); + +$formLabel->setTranslator($translator); +$formElementErrors->setTranslator($translator); + +/** @var Form $form */ +$form = $this->form; +$form->setAttribute('method', 'post'); +$form->setAttribute('action', $this->url('fid/user/create')); +$form->setAttribute('class', 'form-horizontal'); +$form->prepare(); + +$this->headTitle($this->translate('Profile Form')); +$this->headTitle($this->translate("fid::user_create_form_title")); +?> + +<h2><?= $this->translate("fid::user_create_form_title") ?></h2> +<?= $this->flashmessages() ?> +<?= $this->form()->openTag($form) ?> +<br/> +<? /* username */ ?> +<?php +/** @var Element\Text $elemUsername */ +$elemUsername = $form->get('username'); +$elemUsername->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemUsername->setAttributes(['class' => 'form-control', 'disabled' => 1]); +?> +<div class="form-group"> + <?= $this->formLabel($elemUsername) ?> + <?= $this->formElement($elemUsername) ?> + <?= $this->formElementErrors($elemUsername) ?> + <?php + $elemUsername->removeAttribute('disabled'); + $elemUsername->setAttribute('type', 'hidden'); + echo $this->formElement($elemUsername); + ?> +</div> + +<? /* password */ ?> +<?php +/** @var Element\Password $elemPassword */ +$elemPassword = $form->get('password'); +$elemPassword->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemPassword->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemPassword) ?> + <?= $this->formElement($elemPassword) ?> + <?= $this->formElementErrors($elemPassword) ?> +</div> + +<? /* password confirmation */ ?> +<?php +/** @var Element\Password $elemPasswordConfirmation */ +$elemPasswordConfirmation = $form->get('passwordConfirmation'); +$elemPasswordConfirmation->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemPasswordConfirmation->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemPasswordConfirmation) ?> + <?= $this->formElement($elemPasswordConfirmation) ?> + <?= $this->formElementErrors($elemPasswordConfirmation) ?> +</div> + +<? /* home library */ ?> +<?php +/** @var Element\Select $elemHomeLibrary */ +$elemHomeLibrary = $form->get('homeLibrary'); +$elemHomeLibrary->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemHomeLibrary->setAttributes(['class' => 'inline col-sm-6']); +$elemHomeLibrary->setValueOptions($this->libraries); +?> +<div class="form-group"> + <?= $this->formLabel($elemHomeLibrary) ?> + <?= $this->formSelect($elemHomeLibrary) ?> + <?= $this->formElementErrors($elemHomeLibrary) ?> +</div> + +<? /* salutation */ ?> +<?php +/** @var Element\Select $elemSalutation */ +$elemSalutation = $form->get('salutation'); +$elemSalutation->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemSalutation->setAttributes(['class' => 'inline col-sm-2']); +?> +<div class="form-group"> + <?= $this->formLabel($elemSalutation) ?> + <?= $this->formSelect($elemSalutation) ?> + +</div> + +<? /* academic title */ ?> +<?php +/** @var Element\Text $elemAcademicTitle */ +$elemAcademicTitle = $form->get('academicTitle'); +$elemAcademicTitle->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemAcademicTitle->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemAcademicTitle) ?> + <?= $this->formElement($elemAcademicTitle) ?> +</div> + +<? /* firstname */ ?> +<?php +/** @var Element\Text $elemFirstname */ +$elemFirstname = $form->get('firstname'); +$elemFirstname->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemFirstname->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemFirstname) ?> + <?= $this->formElement($elemFirstname) ?> + <?= $this->formElementErrors($elemFirstname) ?> +</div> + +<? /* lastname */ ?> +<?php +/** @var Element\Text $elemLastname */ +$elemLastname = $form->get('lastname'); +$elemLastname->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemLastname->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemLastname) ?> + <?= $this->formElement($elemLastname) ?> + <?= $this->formElementErrors($elemLastname) ?> +</div> + +<? /* year of birth */ ?> +<?php +/** @var Element\Text $elemYearOfBirth */ +$elemYearOfBirth = $form->get('yearOfBirth'); +$elemYearOfBirth->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemYearOfBirth->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemYearOfBirth) ?> + <?= $this->formElement($elemYearOfBirth) ?> + <?= $this->formElementErrors($elemYearOfBirth) ?> +</div> + +<? /* college */ ?> +<?php +/** @var Element\Text $elemCollege */ +$elemCollege = $form->get('college'); +$elemCollege->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemCollege->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemCollege) ?> + <?= $this->formElement($elemCollege) ?> + <?= $this->formElementErrors($elemCollege) ?> +</div> + +<? /* job title */ ?> +<?php +/** @var Element\Text $elemJobTitle */ +$elemJobTitle = $form->get('jobTitle'); +$elemJobTitle->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemJobTitle->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemJobTitle) ?> + <?= $this->formElement($elemJobTitle) ?> + <?= $this->formElementErrors($elemJobTitle) ?> +</div> + +<? /* eula privacy policy */ ?> +<?php +/** @var Checkbox $elemEulaAccepted */ +$elemEulaAccepted = $form->get('eulaAccepted'); +$elemEulaAccepted->setAttributes(['class' => 'inline']); +$elemEulaAccepted->setLabelAttributes(['class' => 'inline']); +?> +<div class="form-group"> + <?= $this->formElement($elemEulaAccepted) ?> + <?= $this->formLabel()->openTag($elemEulaAccepted) ?> + <?= $this->translate("fid::policy_text") ?> + <? $url = $this->url('fid/user/policy') ?> + <a data-lightbox href="<?= $url ?>"> + <?= $this->translate("fid::policy") ?> + </a> + <?= $this->translate("fid::terms_text") ?> + <? $url = $this->url('fid/user/terms') ?> + <a data-lightbox href="<?= $url ?>"> + <?= $this->translate("fid::terms") ?> + </a>. + <?= $this->formLabel()->closeTag($elemEulaAccepted) ?> + <?= $this->formElementErrors($elemEulaAccepted) ?> +</div> + +<? /* submit button */ ?> +<?php +/** @var Submit $elemSubmit */ +$elemSubmit = $form->get('submit'); +$elemSubmit->setAttributes(['class' => 'btn btn-primary right']); +?> +<div class="form-group"> + <div class="col-lg-11 col-md-9 col-sm-11 col-xs-12"> + <?= $this->formSubmit($elemSubmit) ?> + </div> +</div> + +<?= $this->form()->closeTag($form) ?> \ No newline at end of file diff --git a/themes/fid/templates/fid/user/init.phtml b/themes/fid/templates/fid/user/init.phtml new file mode 100644 index 0000000000000000000000000000000000000000..00b634df289576e33cb62c1a41a43225f5adbdd4 --- /dev/null +++ b/themes/fid/templates/fid/user/init.phtml @@ -0,0 +1,144 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +use Zend\Form\Element; +use Zend\Form\Form; +use Zend\Form\View\Helper\FormElementErrors; +use Zend\Form\View\Helper\FormLabel; +use Zend\Form\View\Helper\FormSubmit; +use Zend\I18n\Translator\TranslatorInterface; + +/** @var FormLabel $formLabel */ +$formLabel = $this->formLabel(); +/**@var FormSubmit $formSubmit */ +$formSubmit = $this->formSubmit(); +/** @var FormElementErrors $formElementErrors */ +$formElementErrors = $this->formElementErrors(); + +$formLabel->setTranslatorTextDomain('fid'); +$formSubmit->setTranslatorTextDomain('fid'); +$formElementErrors->setTranslatorTextDomain('fid'); +/** @var TranslatorInterface $translator */ +$translator = $this->getHelperPluginManager()->get('translate') + ->getTranslator(); +$formLabel->setTranslator($translator); +$formElementErrors->setTranslator($translator); + +/** @var Form $form */ +$form = $this->form; +$form->setAttribute('method', 'post'); +$form->setAttribute('action', $this->url('fid/user/init')); +$form->prepare(); + +$this->headTitle($this->translate("fid::user_init_form_title")); +?> + +<h2><?= $this->translate("fid::user_init_form_title") ?></h2> +<?= $this->flashmessages() ?> +<?= $this->form()->openTag($form) ?> +<br/> +<? /* username */ ?> +<?php +/** @var Element\Text $elemUsername */ +$elemUsername = $form->get('username'); +$elemUsername->setLabelAttributes(['class' => 'control-label']); +$elemUsername->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemUsername) ?> + <?= $this->formElement($elemUsername) ?> + <?= $this->formElementErrors($elemUsername) ?> +</div> + +<? /* username confirmation */ ?> +<?php +/** @var Element\Text $elemUsernameConfirmation */ +$elemUsernameConfirmation = $form->get('usernameConfirmation'); +$elemUsernameConfirmation->setLabelAttributes(['class' => 'control-label']); +$elemUsernameConfirmation->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemUsernameConfirmation) ?> + <?= $this->formElement($elemUsernameConfirmation) ?> + <?= $this->formElementErrors($elemUsernameConfirmation) ?> +</div> + +<? /* firstname */ ?> +<?php +/** @var Element\Text $elemFirstname */ +$elemFirstname = $form->get('firstname'); +$elemFirstname->setLabelAttributes(['class' => 'control-label']); +$elemFirstname->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemFirstname) ?> + <?= $this->formElement($elemFirstname) ?> + <?= $this->formElementErrors($elemFirstname) ?> +</div> + +<? /* lastname */ ?> +<?php +/** @var Element\Text $elemLastname */ +$elemLastname = $form->get('lastname'); +$elemLastname->setLabelAttributes(['class' => 'control-label']); +$elemLastname->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemLastname) ?> + <?= $this->formElement($elemLastname) ?> + <?= $this->formElementErrors($elemLastname) ?> +</div> + +<? /* eula privacy policy */ ?> +<?php +/** @var Element\Checkbox $elemEulaAccepted */ +$elemEulaAccepted = $form->get('eulaAccepted'); +?> +<div class="form-group"> + <?= $this->formElement($elemEulaAccepted) ?> + <?= $this->formLabel()->openTag($elemEulaAccepted) ?> + <?= $this->translate("fid::policy_text") ?> + <? $url = $this->url('fid/user/policy') ?> + <a data-lightbox href="<?= $url ?>"> + <?= $this->translate("fid::policy") ?> + </a> + <?= $this->translate("fid::terms_text") ?> + <? $url = $this->url('fid/user/terms') ?> + <a data-lightbox href="<?= $url ?>"> + <?= $this->translate("fid::terms") ?></a>. + <?= $this->formLabel()->closeTag($elemEulaAccepted) ?> + <?= $this->formElementErrors($elemEulaAccepted) ?> +</div> +<? /* submit button */ ?> +<?php +/** @var Element\Submit $elemSubmit */ +$elemSubmit = $form->get('submit'); +$elemSubmit->setAttributes(['class' => 'btn btn-primary']); +?> +<div class="form-group"> + <a class="back-to-login btn btn-link" href="<?=$this->url('myresearch-userlogin') ?>"> + <i class="fa fa-chevron-left" aria-hidden="true"></i> + <?=$this->transEsc('Back')?> + </a> + <?= $this->formElement($elemSubmit) ?> +</div> +<?= $this->form()->closeTag($form) ?> \ No newline at end of file diff --git a/themes/fid/templates/fid/user/password-change.phtml b/themes/fid/templates/fid/user/password-change.phtml new file mode 100644 index 0000000000000000000000000000000000000000..9965e72485518b1f3411a0722a8b16b481505276 --- /dev/null +++ b/themes/fid/templates/fid/user/password-change.phtml @@ -0,0 +1,101 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +use Zend\Form\Element; +use Zend\Form\Form; +use Zend\Form\View\Helper\FormElementErrors; +use Zend\Form\View\Helper\FormLabel; +use Zend\Form\View\Helper\FormSubmit; +use Zend\I18n\Translator\TranslatorInterface; + +/** @var FormLabel $formLabel */ +$formLabel = $this->formLabel(); +/**@var FormSubmit $formSubmit */ +$formSubmit = $this->formSubmit(); +/** @var FormElementErrors $formElementErrors */ +$formElementErrors = $this->formElementErrors(); + +$formLabel->setTranslatorTextDomain('fid'); +$formSubmit->setTranslatorTextDomain('fid'); +$formElementErrors->setTranslatorTextDomain('fid'); +/** @var TranslatorInterface $translator */ +$translator = $this->getHelperPluginManager()->get('translate') + ->getTranslator(); +$formLabel->setTranslator($translator); +$formElementErrors->setTranslator($translator); + +/** @var Form $form */ +$form = $this->form; +$form->setAttribute('method', 'post'); +$form->setAttribute('action', $this->url('fid/user/change-password')); +$form->setAttribute('class', 'form-horizontal'); +$form->prepare(); + +$this->headTitle($this->translate("fid::password_change_form_title")); +?> +<br/> +<div class="password-recovery"> + <div class="<?= $this->layoutClass('mainbody') ?>"> + <h2><?= $this->translate("fid::password_change_form_title") ?></h2> + <?= $this->flashmessages() ?> + <?= $this->form()->openTag($form) ?> + <br/> + <?php /* password */ ?> + <?php + /** @var Element\Password $elemPassword */ + $elemPassword = $form->get('password'); + $elemPassword->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); + $elemPassword->setAttributes(['class' => 'form-control']); + ?> + <div class="form-group"> + <?= $this->formLabel($elemPassword) ?> + <?= $this->formElement($elemPassword) ?> + <?= $this->formElementErrors($elemPassword) ?> + </div> + + <?php /* password confirmation */ ?> + <?php + /** @var Element\Password $elemPasswordConfirmation */ + $elemPasswordConfirmation = $form->get('passwordConfirmation'); + $elemPasswordConfirmation->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); + $elemPasswordConfirmation->setAttributes(['class' => 'form-control']); + ?> + <div class="form-group"> + <?= $this->formLabel($elemPasswordConfirmation) ?> + <?= $this->formElement($elemPasswordConfirmation) ?> + <?= $this->formElementErrors($elemPasswordConfirmation) ?> + </div> + + <?php /* submit button */ ?> + <?php + /** @var Element\Submit $elemSubmit */ + $elemSubmit = $form->get('submit'); + $elemSubmit->setAttributes(['class' => 'btn btn-primary right']); + ?> + <div class="form-group"> + <div class="col-lg-11 col-md-9 col-sm-11 col-xs-12"> + <?= $this->formElement($elemSubmit) ?> + </div> + </div> + <?= $this->form()->closeTag($form) ?> + </div> +</div> \ No newline at end of file diff --git a/themes/fid/templates/fid/user/password-reset.phtml b/themes/fid/templates/fid/user/password-reset.phtml new file mode 100644 index 0000000000000000000000000000000000000000..3bf4994ed40108c5a67ae37625d5a333745c156f --- /dev/null +++ b/themes/fid/templates/fid/user/password-reset.phtml @@ -0,0 +1,84 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Robert Lange <lange@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +use Zend\Form\Element; +use Zend\Form\Form; +use Zend\Form\View\Helper\FormElementErrors; +use Zend\Form\View\Helper\FormLabel; +use Zend\Form\View\Helper\FormSubmit; +use Zend\I18n\Translator\TranslatorInterface; + +/** @var FormLabel $formLabel */ +$formLabel = $this->formLabel(); +/**@var FormSubmit $formSubmit */ +$formSubmit = $this->formSubmit(); +/** @var FormElementErrors $formElementErrors */ +$formElementErrors = $this->formElementErrors(); + +$formLabel->setTranslatorTextDomain('fid'); +$formSubmit->setTranslatorTextDomain('fid'); +$formElementErrors->setTranslatorTextDomain('fid'); +/** @var TranslatorInterface $translator */ +$translator = $this->getHelperPluginManager()->get('translate') + ->getTranslator(); +$formLabel->setTranslator($translator); +$formElementErrors->setTranslator($translator); + +/** @var Form $form */ +$form = $this->form; +$form->setAttribute('method', 'post'); +$form->setAttribute('action', $this->url('fid/user/reset-password')); +$form->prepare(); + +$this->headTitle($this->translate("fid::password_reset_form_title")); +?> +<h2><?= $this->translate("fid::password_reset_form_title") ?></h2> +<?= $this->flashmessages() ?> +<?= $this->form()->openTag($form) ?> +<br/> +<?php /* username */ ?> +<?php +/** @var Element\Text $elemUsername */ +$elemUsername = $form->get('username'); +$elemUsername->setLabelAttributes(['class' => 'control-label']); +$elemUsername->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemUsername) ?> + <?= $this->formElement($elemUsername) ?> + <?= $this->formElementErrors($elemUsername) ?> +</div> + +<?php /* submit button */ ?> +<?php +/** @var Element\Submit $elemSubmit */ +$elemSubmit = $form->get('submit'); +$elemSubmit->setAttributes(['class' => 'btn btn-primary']); +?> +<div class="form-group"> + <a class="back-to-login btn btn-link" href="<?=$this->url('myresearch-userlogin') ?>"> + <i class="fa fa-chevron-left" aria-hidden="true"></i> + <?=$this->transEsc('Back')?> + </a> + <?= $this->formElement($elemSubmit) ?> +</div> +<?= $this->form()->closeTag($form) ?> \ No newline at end of file diff --git a/themes/fid/templates/fid/user/policy-de.phtml b/themes/fid/templates/fid/user/policy-de.phtml new file mode 100644 index 0000000000000000000000000000000000000000..42bd73758a7e342b0f2f765c12dc8bca50040a22 --- /dev/null +++ b/themes/fid/templates/fid/user/policy-de.phtml @@ -0,0 +1,580 @@ +<div class="adlr-policies"> + <br /> + <h2><strong>Datenschutzerklärung</strong></h2> + <ol> + <li><strong>Name und Anschrift des Verantwortlichen</strong></li> + <p>Der Verantwortliche im Sinne der Datenschutz-Grundverordnung und anderer nationaler Datenschutzgesetze der Mitgliedsstaaten sowie sonstiger datenschutzrechtlicher Bestimmungen ist:</p> + <p>Universitätsbibliothek Leipzig<br /> + vertreten durch den Direktor der Universitätsbibliothek Prof. Dr. Ulrich Johannes Schneider<br /> + Beethovenstraße 6<br /> + 04107 Leipzig<br /> + Tel.: +49 341-97 30577<br /> + E-Mail: info [at] adlr.link</p> + <li><strong>Name und Anschrift des Datenschutzbeauftragten</strong></li> + <p>Der Datenschutzbeauftragte des Verantwortlichen ist:<br /><br /> + Universität Leipzig<br /> + Datenschutzbeauftragter: Thomas Braatz<br /> + 04109 Leipzig<br /> + Tel.: +49 341 97-30081<br /> + E-Mail: dsb [at] uni-leipzig.de<br /> + Website: http://www.uni-leipzig.de/universitaet/profil/beauftragte.html#c2362</p> + <li><strong>Allgemeines zur Datenverarbeitung</strong></li> + <ol> + <li><strong>Umfang der Verarbeitung personenbezogener Daten</strong></li> + <p>Wir verarbeiten personenbezogene Daten unserer Nutzer grundsätzlich nur, soweit dies zur Bereitstellung einer funktionsfähigen Website sowie unserer Inhalte und Leistungen erforderlich ist. Die Verarbeitung personenbezogener Daten unserer Nutzer erfolgt regelmäßig nur nach Einwilligung des Nutzers. Eine Ausnahme gilt in solchen Fällen, in denen eine vorherige Einholung einer Einwilligung aus tatsächlichen Gründen nicht möglich ist und die Verarbeitung der Daten durch gesetzliche Vorschriften gestattet ist.</p> + <li><strong>Rechtsgrundlage für die Verarbeitung personenbezogener Daten</strong></li> + <p>Soweit wir für Verarbeitungsvorgänge personenbezogener Daten eine Einwilligung der betroffenen Person einholen, dient Art. 6 Abs. 1 lit. a EU-Datenschutzgrundverordnung (DSGVO) als Rechtsgrundlage.<br /> + Bei der Verarbeitung von personenbezogenen Daten, die zur Erfüllung eines Vertrages, dessen Vertragspartei die betroffene Person ist, erforderlich ist, dient Art. 6 Abs. 1 lit. b DSGVO als Rechtsgrundlage. Dies gilt auch für Verarbeitungsvorgänge, die zur Durchführung vorvertraglicher Maßnahmen erforderlich sind.<br /> + Soweit eine Verarbeitung personenbezogener Daten zur Erfüllung einer rechtlichen Verpflichtung erforderlich ist, der unser Unternehmen unterliegt, dient Art. 6 Abs. 1 lit. c DSGVO als Rechtsgrundlage.<br /> + Für den Fall, dass lebenswichtige Interessen der betroffenen Person oder einer anderen natürlichen Person eine Verarbeitung personenbezogener Daten erforderlich machen, dient Art. 6 Abs. 1 lit. d DSGVO als Rechtsgrundlage.<br /> + Ist die Verarbeitung zur Wahrung eines berechtigten Interesses unseres Unternehmens oder eines Dritten erforderlich und überwiegen die Interessen, Grundrechte und Grundfreiheiten des Betroffenen das erstgenannte Interesse nicht, so dient Art. 6 Abs. 1 lit. f DSGVO als Rechtsgrundlage für die Verarbeitung. </p> + <li><strong>Datenlöschung und Speicherdauer</strong></li> + <p>Die personenbezogenen Daten der betroffenen Person werden gelöscht oder gesperrt, sobald der Zweck der Speicherung entfällt. Eine Speicherung kann darüber hinaus erfolgen, wenn dies durch den europäischen oder nationalen Gesetzgeber in unionsrechtlichen Verordnungen, Gesetzen oder sonstigen Vorschriften, denen der Verantwortliche unterliegt, vorgesehen wurde. Eine Sperrung oder Löschung der Daten erfolgt auch dann, wenn eine durch die genannten Normen vorgeschriebene Speicherfrist abläuft, es sei denn, dass eine Erforderlichkeit zur weiteren Speicherung der Daten für einen Vertragsabschluss oder eine Vertragserfüllung besteht.</p> + </ol> + <li><strong>Bereitstellung der Website und Erstellung von Logfiles</strong></li> + <ol> + <li><strong>Beschreibung und Umfang der Datenverarbeitung</strong></li> + <p> + Bei der Nutzung der Website von adlr.link wird eine verschlüsselte Browserverbindung aufgebaut, um eine sichere Datenübertragung zu gewährleisten.<br /> + Grundsätzlich können Sie die Website von adlr.link besuchen, ohne uns mitzuteilen, wer Sie sind. Allerdings übermittelt bei jedem Aufruf unserer Internetseite Ihr Browser automatisiert Daten und Informationen Ihres Computersystems an uns.<br /> + Folgende Daten werden hierbei erhoben: + <ol> + <li>Informationen über den Browsertyp, -sprache und die verwendete Version</li> + <li>Das Betriebssystem des Nutzers</li> + <li>Die IP-Adresse des Nutzers</li> + <li>Datum und Uhrzeit des Zugriffs</li> + <li>Inhalt der Anforderung</li> + <li>Zugriffsstatus/Statuscode</li> + <li>Websites, von denen das System des Nutzers auf unsere Internetseite gelangt</li> + <li>Websites, die vom System des Nutzers über unsere Website aufgerufen werden</li> + <li>Ãœbertragene Datenmenge</li> + </ol> + Die Daten werden in den Logfiles unseres Systems gespeichert. Eine Speicherung dieser Daten zusammen mit anderen personenbezogenen Daten des Nutzers findet nicht statt. + </p> + <li><strong>Rechtsgrundlage für die Datenverarbeitung</strong></li> + <p>Rechtsgrundlage für die vorübergehende Speicherung der Daten und der Logfiles ist Art. 6 Abs. 1 lit. f DSGVO.</p> + <li><strong>Zweck der Datenverarbeitung</strong></li> + <p> + Die vorübergehende Speicherung der IP-Adresse durch das System ist notwendig, um eine Auslieferung der Website an den Rechner des Nutzers zu ermöglichen. Hierfür muss die IP-Adresse des Nutzers für die Dauer der Sitzung gespeichert bleiben.<br /> + Die Speicherung in Logfiles erfolgt, um die Funktionsfähigkeit der Website sicherzustellen. Zudem dienen uns die Daten zur Optimierung der Website und zur Sicherstellung der Sicherheit unserer informationstechnischen Systeme. Eine Auswertung der Daten zu Marketingzwecken findet in diesem Zusammenhang nicht statt.<br /> + In diesen Zwecken liegt auch unser berechtigtes Interesse an der Datenverarbeitung nach Art. 6 Abs. 1 lit. f DSGVO. + </p> + <li><strong>Dauer der Speicherung</strong></li> + <p> + Die Daten werden gelöscht, sobald sie für die Erreichung des Zweckes ihrer Erhebung nicht mehr erforderlich sind. Im Falle der Erfassung der Daten zur Bereitstellung der Website ist dies der Fall, wenn die jeweilige Sitzung beendet ist.<br /> + Im Falle der Speicherung der Daten in Logfiles ist dies nach spätestens sieben Tagen der Fall. Eine darüberhinausgehende Speicherung ist möglich. In diesem Fall werden die IP-Adressen der Nutzer gelöscht oder verfremdet, sodass eine Zuordnung des aufrufenden Clients nicht mehr möglich ist. + </p> + <li><strong>Widerspruchs- und Beseitigungsmöglichkeit</strong></li> + <p>Die Erfassung der Daten zur Bereitstellung der Website und die Speicherung der Daten in Logfiles ist für den Betrieb der Internetseite zwingend erforderlich. Es besteht folglich seitens des Nutzers keine Widerspruchsmöglichkeit.</p> + </ol> + <li><strong>Verwendung von Cookies</strong></li> + <ol> + <li><strong>Beschreibung und Umfang der Datenverarbeitung</strong></li> + <p> + Unsere Webseite verwendet Cookies. Bei Cookies handelt es sich um Textdateien, die im Internetbrowser bzw. vom Internetbrowser auf dem Computersystem des Nutzers gespeichert werden. Einige der von uns verwendeten Cookies sind so genannte „Session-Cookies", die automatisch gelöscht werden wenn Sie den Browser schließen. Daneben gibt es einige langlebige Cookies, mittels derer wir Sie als Besucher wiedererkennen. Cookies richten auf Ihrem Rechner keinen Schaden an und enthalten keine Viren. Ruft ein Nutzer eine Website auf, so kann ein Cookie auf dem Betriebssystem des Nutzers gespeichert werden. Dieser Cookie enthält eine charakteristische Zeichenfolge, die eine eindeutige Identifizierung des Browsers beim erneuten Aufrufen der Website ermöglicht.<br /> + Wir setzen Cookies ein, um unsere Website nutzerfreundlicher zu gestalten. Einige Elemente unserer Internetseite erfordern es, dass der aufrufende Browser auch nach einem Seitenwechsel identifiziert werden kann.<br /> + In den Cookies werden dabei folgende Daten gespeichert und übermittelt: + <ol> + <li>Spracheinstellungen</li> + <li>Log-In-Informationen/Session-ID (kein Passwort)</li> + </ol> + Wir verwenden auf unserer Website darüber hinaus Cookies, die eine Analyse des Surfverhaltens der Nutzer ermöglichen.<br /> + Auf diese Weise können folgende Daten übermittelt werden: + <ol> + <li>Eingegebene Suchbegriffe</li> + <li>Häufigkeit von Seitenaufrufen</li> + <li>Inanspruchnahme von Website-Funktionen</li> + </ol> + Die auf diese Weise erhobenen Daten der Nutzer werden durch technische Vorkehrungen pseudonymisiert. Daher ist eine Zuordnung der Daten zum aufrufenden Nutzer nicht mehr möglich. Die Daten werden nicht gemeinsam mit sonstigen personenbezogenen Daten der Nutzer gespeichert.<br /> + Beim Aufruf unserer Website werden Sie durch einen Infobanner über die Verwendung von Cookies zu Analysezwecken informiert und auf diese Datenschutzerklärung verwiesen. Mithin erfolgt auch ein Hinweis darauf, wie die Speicherung von Cookies in den Browsereinstellungen unterbunden werden kann. + </p> + <li><strong>Rechtsgrundlage für die Datenverarbeitung</strong></li> + <p> + Die Rechtsgrundlage für die Verarbeitung personenbezogener Daten unter Verwendung + technisch notwendiger Cookies ist Art. 6 Abs. 1 lit. f DSGVO.<br /> + Die Rechtsgrundlage für die Verarbeitung personenbezogener Daten unter Verwendung von + Cookies zu Analysezwecken ist bei Vorliegen einer diesbezüglichen Einwilligung des Nutzers + Art. 6 Abs. 1 lit. a DSGVO. + </p> + <li><strong>Zweck der Datenverarbeitung</strong></li> + <p> + Der Zweck der Verwendung technisch notwendiger Cookies ist, die Nutzung von Websites + für die Nutzer zu vereinfachen. Einige Funktionen unserer Internetseite können ohne den + Einsatz von Cookies nicht angeboten werden. Für diese ist es erforderlich, dass der Browser + auch nach einem Seitenwechsel wiedererkannt wird.<br /> + Für folgende Anwendungen benötigen wir Cookies: + <ol> + <li>Registrierung</li> + <li>Aufruf des eigenen Nutzerkontos</li> + <li>Ãœbernahme von Spracheinstellungen</li> + <li>Merken von Suchbegriffen</li> + </ol> + Die durch technisch notwendige Cookies erhobenen Nutzerdaten werden nicht zur + Erstellung von Nutzerprofilen verwendet.<br /> + Die Verwendung der Analyse-Cookies erfolgt zu dem Zweck, die Qualität unserer Website + und ihre Inhalte zu verbessern. Durch die Analyse-Cookies erfahren wir, wie die Website + genutzt wird und können so unser Angebot stetig optimieren.<br /> + In diesen Zwecken liegt auch unser berechtigtes Interesse in der Verarbeitung der + personenbezogenen Daten nach Art. 6 Abs. 1 lit. f DSGVO. + </p> + <li><strong>Dauer der Speicherung, Widerspruchs- und Beseitigungsmöglichkeit</strong></li> + <p> + Cookies werden auf dem Rechner des Nutzers gespeichert und von diesem an unserer Seite + übermittelt. Daher haben Sie als Nutzer auch die volle Kontrolle über die Verwendung von + Cookies. Durch eine Änderung der Einstellungen in Ihrem Internetbrowser können Sie die + Ãœbertragung von Cookies jederzeit deaktivieren oder einschränken. Bereits gespeicherte + Cookies können jederzeit gelöscht werden. Dies kann auch automatisiert erfolgen. Werden + Cookies für unsere Website deaktiviert, können möglicherweise nicht mehr alle Funktionen + der Website vollumfänglich genutzt werden. + </p> + </ol> + <li><strong>Newsletter</strong></li> + <ol> + <li><strong>Beschreibung und Umfang der Datenverarbeitung</strong></li> + <p> + Auf unserer Internetseite besteht die Möglichkeit einen kostenfreien Newsletter zu + abonnieren. Dabei werden bei der Anmeldung zum Newsletter die Daten aus der + Eingabemaske an uns übermittelt: + <ol> + <li>E-Mail-Adresse</li> + <li>Name (optional)</li><br /> + <p>Zudem werden folgende Daten bei der Anmeldung erhoben:</p> + <li>IP-Adresse des aufrufenden Rechners</li> + <li>Datum und Uhrzeit der Registrierung</li> + </ol> + Für die Verarbeitung der Daten wird im Rahmen des Anmeldevorgangs Ihre Einwilligung + eingeholt und auf diese Datenschutzerklärung verwiesen.<br /> + Es erfolgt im Zusammenhang mit der Datenverarbeitung für den Versand von Newslettern + keine Weitergabe der Daten an Dritte. Die Daten werden ausschließlich für den Versand des + Newsletters verwendet. + </p> + <li><strong>Rechtsgrundlage für die Datenverarbeitung</strong></li> + <p>Rechtsgrundlage für die Verarbeitung der Daten nach Anmeldung zum Newsletters durch + den Nutzer ist bei Vorliegen einer Einwilligung des Nutzers Art. 6 Abs. 1 lit. a DSGVO.</p> + <li><strong>Zweck der Datenverarbeitung</strong></li> + <p>Die Erhebung der E-Mail-Adresse des Nutzers dient dazu, den Newsletter zuzustellen. + Die Erhebung sonstiger personenbezogener Daten im Rahmen des Anmeldevorgangs dient + dazu, einen Missbrauch der Dienste oder der verwendeten E-Mail-Adresse zu verhindern.</p> + <li><strong>Dauer der Speicherung</strong></li> + <p>Die Daten werden gelöscht, sobald sie für die Erreichung des Zweckes ihrer Erhebung nicht + mehr erforderlich sind. Die E-Mail-Adresse des Nutzers wird demnach solange gespeichert, + wie das Abonnement des Newsletters aktiv ist.<br /> + Die sonstigen im Rahmen des Anmeldevorgangs erhobenen personenbezogenen Daten + werden in der Regel nach einer Frist von sieben Tagen gelöscht.</p> + <li><strong>Widerspruchs- und Beseitigungsmöglichkeit</strong></li> + <p>Das Abonnement des Newsletters können Sie jederzeit kündigen. Zu diesem Zweck findet + sich in jedem Newsletter ein entsprechender Link.<br /> + Hierdurch wird ebenfalls ein Widerruf der Einwilligung der Speicherung der während des + Anmeldevorgangs erhobenen personenbezogenen Daten ermöglicht.</p> + </ol> + <li><strong>Registrierung</strong></li> + <ol> + <li><strong>Beschreibung und Umfang der Datenverarbeitung</strong></li> + <p> + Für die Nutzung bestimmter Funktionen (nutzergesteuerte Erwerbung von gedruckten + Publikationen, Zugang zu speziell für den Fachinformationsdienst lizenzierten E-Books + und/oder Zeitschriften, Speicherung von Suchanfragen und/oder Favoriten) von adlr.link ist + eine vorherige Registrierung erforderlich.<br /> + Auf unserer Internetseite bieten wir Nutzern die Möglichkeit, sich unter Angabe + personenbezogener Daten für ein eigenes Nutzerkonto zu registrieren. Die Daten werden + dabei in eine Eingabemaske eingegeben und an uns übermittelt und gespeichert. Folgende + Daten werden im Rahmen des Registrierungsprozesses erhoben: + <ol> + <li>E-Mail-Adresse (zugleich Login)</li> + <li>Passwort (selbstgewählt)</li> + <li>Zugehörigkeit zu einer Nutzergruppe</li> + <li>Vor- und Zuname</li> + <li>Anrede und akademischer Titel (optional)</li> + <li>Geburtsjahr (optional)</li> + <li>Heimatbibliothek</li> + <li>Berufsangabe (optional)</li> + <li>Telefon (optional)</li> + <li>Adressinformationen (Straße/Hnr., PLZ/Ort) für maximal zwei Adressen</li><br /> + <p>Im Zeitpunkt der Registrierung werden zudem folgende Daten gespeichert:</p> + <li>Die IP-Adresse des Nutzers</li> + <li>Datum und Uhrzeit der Registrierung</li> + </ol> + Im Rahmen des Registrierungsprozesses wird eine Einwilligung des Nutzers zur Verarbeitung + dieser Daten eingeholt. + </p> + <li><strong>Rechtsgrundlage für die Datenverarbeitung</strong></li> + <p>Rechtsgrundlage für die Verarbeitung der Daten ist bei Vorliegen einer Einwilligung des + Nutzers Art. 6 Abs. 1 lit. a DSGVO.<br /> + Dient die Registrierung der Erfüllung eines Vertrages, dessen Vertragspartei der Nutzer ist + oder der Durchführung vorvertraglicher Maßnahmen, so ist zusätzliche Rechtsgrundlage für + die Verarbeitung der Daten Art. 6 Abs. 1 lit. b DSGVO.</p> + <li><strong>Zweck der Datenverarbeitung</strong></li> + <p> + Eine Registrierung des Nutzers ist zur Erfüllung eines Vertrages mit dem Nutzer oder zur Durchführung vorvertraglicher Maßnahmen erforderlich.<br /> + Wir benötigen Ihre E-Mail-Adresse, um mit Ihnen kommunizieren zu können, Ihnen den Newsletter zuzustellen und Ihnen auf elektronischem Wege auf Bestellung Dokumente zusenden zu können. Ihre E-Mail-Adresse ist zugleich Ihr Login (Benutzername) für Ihr Nutzerkonto.<br /> + Das Passwort wird aus Sicherheitsgründen nicht direkt gespeichert. Zu Authentifizierung der Nutzer wird aus dem Passwort ein Hashwert errechnet und nur dieser gespeichert. Ein Hashwert ist eine eindeutige Zeichenkette, die so berechnet wird, dass das ursprünglich eingegebene Passwort nicht wiederhergestellt werden kann. Um Sie bei späteren Logins authentifizieren zu können, wird Ihre Eingabe bei späteren Logins mit der gleichen Funktion berechnet und nur die beiden Hashwerte verglichen.<br /> + Ihren Namen und Ihre Adressinformationen benötigen wir, um Ihnen gedruckte Medien auf dem Postweg zusenden zu können. Sie können dabei bis zu zwei unterschiedliche Adressen angeben und jederzeit angeben, an welche Adresse wir die Lieferung senden sollen. Wir geben bei einer von Ihnen ausgelösten Bestellung eines gedruckten Mediums Ihren Namen, Ihre von Ihnen als Lieferanschrift bestimmte Adresse und Ihre E-Mail-Adresse an Lieferanten und Erfüllungsgehilfen weiter.<br /> + Wir nutzen die Angabe Ihrer Heimatbibliothek, um Ihnen anzeigen zu können, ob einzelne Medien in Ihrer eigenen Bibliothek bereits entweder physisch vorhanden oder elektronisch zugänglich sind. Dabei geben wir nur einen Identifikator für das jeweilige Medium (z. B. die ISBN) und einen Identifikator Ihrer Heimatbibliothek an einen Dienst des Bibliotheksservice-Zentrums Baden-Württemberg weiter, jedoch keine weiteren persönlichen Daten von Ihnen.<br /> + Wir nutzen Dienste des WorldCat, um Ihnen standortbezogen anzeigen zu können, ob einzelne Medien in einer Bibliothek in Ihrer Nähe verfügbar sind. Hierfür wird Ihre aktuelle IP-Adresse und ein Identifikator für das jeweilige Medium (z. B. die ISBN) an den WorldCat-Dienst übertragen. Die IP-Adresse wird nur zum Zweck des Geotargeting verwendet und nicht gespeichert oder anderweitig verwendet. Weitere persönliche Daten werden nicht übermittelt.<br /> + Sie können uns optional weitere Daten in Ihrem Nutzerkonto angeben. Ihre Anrede und Ihren akademischen Titel verwenden wir zur persönlichen Ansprache und geben diese Informationen auch zusammen mit Ihren Adressinformationen weiter. Ihre Telefonnummer können wir für die Möglichkeit nutzen, telefonische Rückfragen zu Ihren Fragen oder Bestellungen durchzuführen. Ihre Berufsangabe und Ihr Geburtsjahr verwenden wir ausschließlich anonymisiert für statistische Zwecke.<br /> + Bei der Weitergabe personenbezogener Informationen an Dritte stellen wir, dass die Informationen in Ãœbereinstimmung mit dieser Datenschutzerklärung erfolgen. Dritte, an denen die Datenübermittlung erfolgt, werden verpflichtet, die an sie übermittelten Daten nur für den jeweiligen Zweck zu verarbeiten, sie aber nicht darüber hinaus zu verwenden. + </p> + <li><strong>Dauer der Speicherung</strong></li> + <p> + Die Daten werden gelöscht, sobald sie für die Erreichung des Zweckes ihrer Erhebung nicht + mehr erforderlich sind.<br /> + Dies ist für die während des Registrierungsvorgangs zur Erfüllung eines Vertrags oder zur + Durchführung vorvertraglicher Maßnahmen dann der Fall, wenn die Daten für die + Durchführung des Vertrages nicht mehr erforderlich sind. Auch nach Abschluss des Vertrags + kann eine Erforderlichkeit, personenbezogene Daten des Vertragspartners zu speichern, + bestehen, um vertraglichen oder gesetzlichen Verpflichtungen nachzukommen. + </p> + <li><strong>Widerspruchs- und Beseitigungsmöglichkeit</strong></li> + <p> + Als Nutzer haben Sie jederzeit die Möglichkeit, die Registrierung und damit Ihr Nutzerkonto + aufzulösen. Die über Sie gespeicherten Daten können Sie jederzeit abändern lassen. + Die Änderung Ihrer Daten können Sie jederzeit selbst über die Website vornehmen. + Für eine vollständige Löschung der Daten schreiben Sie uns bitte eine E-Mail oder + kontaktieren uns über das Kontaktformular.<br /> + Sind die Daten zur Erfüllung eines Vertrages oder zur Durchführung vorvertraglicher + Maßnahmen erforderlich, ist eine vorzeitige Löschung der Daten nur möglich, soweit nicht + vertragliche oder gesetzliche Verpflichtungen einer Löschung entgegenstehen. + </p> + </ol> + <li><strong>Kontaktformular und E-Mail-Kontakt</strong></li> + <ol> + <li><strong>Beschreibung und Umfang der Datenverarbeitung</strong></li> + <p> + Auf unserer Internetseite ist ein Kontaktformular vorhanden, welches für die elektronische + Kontaktaufnahme genutzt werden kann. Nehmen Sie diese Möglichkeit wahr, so werden die + in der Eingabemaske eingegeben Daten an uns übermittelt und gespeichert. Diese Daten + sind: + <ol> + <li>E-Mail-Adresse</li> + <li>Name</li> + <li>Betreff und Nachrichteninhalt</li><br /> + <p>Im Zeitpunkt der Absendung der Nachricht werden zudem folgende Daten gespeichert:</p> + <li>Die IP-Adresse des Nutzers</li> + <li>Datum und Uhrzeit der Registrierung</li> + </ol> + Für die Verarbeitung der Daten wird im Rahmen des Absendevorgangs Ihre Einwilligung + eingeholt und auf diese Datenschutzerklärung verwiesen.<br /> + Alternativ ist eine Kontaktaufnahme über die bereitgestellte E-Mail-Adresse möglich. In + diesem Fall werden die mit der E-Mail übermittelten personenbezogenen Daten des Nutzers + gespeichert.<br /> + Es erfolgt in diesem Zusammenhang keine Weitergabe der Daten an Dritte. Die Daten + werden ausschließlich für die Verarbeitung der Konversation verwendet. + </p> + <li><strong>Rechtsgrundlage für die Datenverarbeitung</strong></li> + <p>Rechtsgrundlage für die Verarbeitung der Daten ist bei Vorliegen einer Einwilligung des + Nutzers Art. 6 Abs. 1 lit. a DSGVO.<br /> + Rechtsgrundlage für die Verarbeitung der Daten, die im Zuge einer Ãœbersendung einer E- + Mail übermittelt werden, ist Art. 6 Abs. 1 lit. f DSGVO. Zielt der E-Mail-Kontakt auf den + Abschluss eines Vertrages ab, so ist zusätzliche Rechtsgrundlage für die Verarbeitung Art. 6 + Abs. 1 lit. b DSGVO.</p> + <li><strong>Zweck der Datenverarbeitung</strong></li> + <p>Die Verarbeitung der personenbezogenen Daten aus der Eingabemaske dient uns allein zur + Bearbeitung der Kontaktaufnahme. Im Falle einer Kontaktaufnahme per E-Mail liegt hieran + auch das erforderliche berechtigte Interesse an der Verarbeitung der Daten.<br /> + Die sonstigen während des Absendevorgangs verarbeiteten personenbezogenen Daten + dienen dazu, einen Missbrauch des Kontaktformulars zu verhindern und die Sicherheit + unserer informationstechnischen Systeme sicherzustellen.</p> + <li><strong>Dauer der Speicherung</strong></li> + <p>Die Daten werden gelöscht, sobald sie für die Erreichung des Zweckes ihrer Erhebung nicht + mehr erforderlich sind. Für die personenbezogenen Daten aus der Eingabemaske des + Kontaktformulars und diejenigen, die per E-Mail übersandt wurden, ist dies dann der Fall, + wenn die jeweilige Konversation mit Ihnen beendet ist. Beendet ist die Konversation dann, + wenn sich aus den Umständen entnehmen lässt, dass der betroffene Sachverhalt + abschließend geklärt ist.<br /> + Die während des Absendevorgangs zusätzlich erhobenen personenbezogenen Daten werden + spätestens nach einer Frist von sieben Tagen gelöscht.</p> + <li><strong>Widerspruchs- und Beseitigungsmöglichkeit</strong></li> + <p>Sie haben jederzeit die Möglichkeit, Ihre Einwilligung zur Verarbeitung der + personenbezogenen Daten zu widerrufen. Nehmen Sie per E-Mail Kontakt mit uns auf, so + können Sie der Speicherung seiner personenbezogenen Daten jederzeit widersprechen. In + einem solchen Fall kann die Konversation nicht fortgeführt werden.<br /> + Für einen Widerspruch schreiben Sie uns bitte eine E-Mail oder kontaktieren uns über das + Kontaktformular.<br /> + Alle personenbezogenen Daten, die im Zuge der Kontaktaufnahme gespeichert wurden, + werden in diesem Fall gelöscht.</p> + </ol> + <li><strong>Webanalyse durch Matomo (ehemals Piwik)</strong></li> + <ol> + <li><strong>Umfang der Verarbeitung personenbezogener Daten</strong></li> + <p> + Wir nutzen auf unserer Website das Open-Source-Software-Tool Matomo (ehemals Piwik) + zur Analyse des Surfverhaltens unserer Nutzer. Die Software setzt ein Cookie auf dem + Rechner der Nutzer (zu Cookies siehe oben). Werden Einzelseiten unserer Website + aufgerufen, so werden folgende Daten gespeichert: + <ol> + <li>Zwei Bytes der IP-Adresse des aufrufenden Systems des Nutzers</li> + <li>Die aufgerufene Webseite</li> + <li>Die Website, von der der Nutzer auf die aufgerufene Webseite gelangt ist (Referrer)</li> + <li>Die Unterseiten, die von der aufgerufenen Webseite aus aufgerufen werden</li> + <li>Die Verweildauer auf der Webseite</li> + <li>Die Häufigkeit des Aufrufs der Webseite</li> + </ol> + Die Software läuft dabei ausschließlich auf den Servern unserer Webseite. Eine Speicherung + der personenbezogenen Daten der Nutzer findet nur dort statt. Eine Weitergabe der Daten + an Dritte erfolgt nicht.<br /> + Die Software ist so eingestellt, dass die IP-Adressen nicht vollständig gespeichert werden, + sondern 2 Bytes der IP-Adresse maskiert werden (Bsp.: 192.168.X.X). Auf diese Weise ist + eine Zuordnung der gekürzten IP-Adresse zum aufrufenden Rechner nicht mehr möglich. + </p> + <li><strong>Rechtsgrundlage für die Verarbeitung personenbezogener Daten</strong></li> + <p>Rechtsgrundlage für die Verarbeitung der personenbezogenen Daten der Nutzer ist Art. 6 + Abs. 1 lit. f DSGVO.</p> + <li><strong>Zweck der Datenverarbeitung</strong></li> + <p>Die Verarbeitung der personenbezogenen Daten der Nutzer ermöglicht uns eine Analyse des + Surfverhaltens unserer Nutzer. Wir sind in durch die Auswertung der gewonnen Daten in der + Lage, Informationen über die Nutzung der einzelnen Komponenten unserer Webseite + zusammenzustellen. Dies hilft uns dabei unsere Webseite und deren Nutzerfreundlichkeit + stetig zu verbessern. In diesen Zwecken liegt auch unser berechtigtes Interesse in der + Verarbeitung der Daten nach Art. 6 Abs. 1 lit. f DSGVO. Durch die Anonymisierung der IP- + Adresse wird dem Interesse der Nutzer an deren Schutz personenbezogener Daten + hinreichend Rechnung getragen.</p> + <li><strong>Dauer der Speicherung</strong></li> + <p>Die Daten werden gelöscht, sobald sie für unsere Aufzeichnungszwecke nicht mehr benötigt + werden.</p> + <li><strong>Widerspruchs- und Beseitigungsmöglichkeit</strong></li> + <p> + Cookies werden auf dem Rechner des Nutzers gespeichert und von diesem an unserer Seite + übermittelt. Daher haben Sie als Nutzer auch die volle Kontrolle über die Verwendung von + Cookies. Durch eine Änderung der Einstellungen in Ihrem Internetbrowser können Sie die + Ãœbertragung von Cookies deaktivieren oder einschränken. Bereits gespeicherte Cookies + können jederzeit gelöscht werden. Dies kann auch automatisiert erfolgen. Werden Cookies + für unsere Website deaktiviert, können möglicherweise nicht mehr alle Funktionen der + Website vollumfänglich genutzt werden.<br /> + Wir bieten unseren Nutzern auf dieser Website die Möglichkeit eines Opt-Out aus dem + Analyseverfahren. Auf diese Weise wird ein weiterer Cookie auf ihrem System gesetzt, der + unserem System signalisiert die Daten des Nutzers nicht zu speichern. Löscht der Nutzer den + entsprechenden Cookie zwischenzeitlich vom eigenen System, so muss er den Opt-Out- + Cookie erneut setzten.<br /> + Nähere Informationen zu den Privatsphäreeinstellungen der Matomo Software finden Sie + unter folgendem Link: https://matomo.org/docs/privacy/.<br /> + Hier können Sie das Tracking durch Matomo ein- oder ausschalten, sofern diese Einstellung + nicht bereits automatisch durch die Einstellungen Ihres Browsers bzw. eines Adblockers + gesteuert wird.<br /> + {if $url == "https://katalog.adlr.link"} + <iframe style="border: 0; height: 200px; width: 100%; margin-left:-.5rem" id="piwk" name="piwk" onLoad="addCSS()" src="https://piwik.ub.uni-leipzig.de/index.php?module=CoreAdminHome&action=optOut&language={$userLang}&idSite=6"></iframe> + {/if} + </p> + </ol> + <li><strong>Rechte der betroffenen Person</strong></li> + <p>Werden personenbezogene Daten von Ihnen verarbeitet, sind Sie Betroffener i.S.d. DSGVO + und es stehen Ihnen folgende Rechte gegenüber dem Verantwortlichen zu:</p> + <ol> + <li><strong>Auskunftsrecht</strong></li> + <p> + Sie können von dem Verantwortlichen eine Bestätigung darüber verlangen, ob + personenbezogene Daten, die Sie betreffen, von uns verarbeitet werden. + Liegt eine solche Verarbeitung vor, können Sie von dem Verantwortlichen über folgende + Informationen Auskunft verlangen: + <ol> + <li>die Zwecke, zu denen die personenbezogenen Daten verarbeitet werden;</li> + <li>die Kategorien von personenbezogenen Daten, welche verarbeitet werden;</li> + <li>die Empfänger bzw. die Kategorien von Empfängern, gegenüber denen die Sie + betreffenden personenbezogenen Daten offengelegt wurden oder noch offengelegt + werden;</li> + <li>die geplante Dauer der Speicherung der Sie betreffenden personenbezogenen Daten + oder, falls konkrete Angaben hierzu nicht möglich sind, Kriterien für die Festlegung + der Speicherdauer;</li> + <li>das Bestehen eines Rechts auf Berichtigung oder Löschung der Sie betreffenden + personenbezogenen Daten, eines Rechts auf Einschränkung der Verarbeitung durch + den Verantwortlichen oder eines Widerspruchsrechts gegen diese Verarbeitung;</li> + <li>das Bestehen eines Beschwerderechts bei einer Aufsichtsbehörde;</li> + <li>alle verfügbaren Informationen über die Herkunft der Daten, wenn die + personenbezogenen Daten nicht bei der betroffenen Person erhoben werden;</li> + <li>das Bestehen einer automatisierten Entscheidungsfindung einschließlich Profiling + gemäß Art. 22 Abs. 1 und 4 DSGVO und – zumindest in diesen Fällen – + aussagekräftige Informationen über die involvierte Logik sowie die Tragweite und die + angestrebten Auswirkungen einer derartigen Verarbeitung für die betroffene Person.</li> + </ol> + Ihnen steht das Recht zu, Auskunft darüber zu verlangen, ob die Sie betreffenden + personenbezogenen Daten in ein Drittland oder an eine internationale Organisation + übermittelt werden. In diesem Zusammenhang können Sie verlangen, über die geeigneten + Garantien gem. Art. 46 DSGVO im Zusammenhang mit der Ãœbermittlung unterrichtet zu + werden. + </p> + <li><strong>Recht auf Berichtigung</strong></li> + <p>Sie haben ein Recht auf Berichtigung und/oder Vervollständigung gegenüber dem + Verantwortlichen, sofern die verarbeiteten personenbezogenen Daten, die Sie betreffen, + unrichtig oder unvollständig sind. Der Verantwortliche hat die Berichtigung unverzüglich + vorzunehmen.</p> + <li><strong>Recht auf Einschränkung der Verarbeitung</strong></li> + <p> + Unter den folgenden Voraussetzungen können Sie die Einschränkung der Verarbeitung der + Sie betreffenden personenbezogenen Daten verlangen: + <ol> + <li>wenn Sie die Richtigkeit der Sie betreffenden personenbezogenen für eine Dauer + bestreiten, die es dem Verantwortlichen ermöglicht, die Richtigkeit der + personenbezogenen Daten zu überprüfen;</li> + <li>die Verarbeitung unrechtmäßig ist und Sie die Löschung der personenbezogenen + Daten ablehnen und stattdessen die Einschränkung der Nutzung der + personenbezogenen Daten verlangen;</li> + <li>der Verantwortliche die personenbezogenen Daten für die Zwecke der Verarbeitung + nicht länger benötigt, Sie diese jedoch zur Geltendmachung, Ausübung oder + Verteidigung von Rechtsansprüchen benötigen, oder</li> + <li>wenn Sie Widerspruch gegen die Verarbeitung gemäß Art. 21 Abs. 1 DSGVO eingelegt + haben und noch nicht feststeht, ob die berechtigten Gründe des Verantwortlichen + gegenüber Ihren Gründen überwiegen.</li> + </ol> + Wurde die Verarbeitung der Sie betreffenden personenbezogenen Daten eingeschränkt, + dürfen diese Daten – von ihrer Speicherung abgesehen – nur mit Ihrer Einwilligung oder zur + Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen oder zum Schutz der + Rechte einer anderen natürlichen oder juristischen Person oder aus Gründen eines wichtigen + öffentlichen Interesses der Union oder eines Mitgliedstaats verarbeitet werden.<br /> + Wurde die Einschränkung der Verarbeitung nach den o.g. Voraussetzungen eingeschränkt, + werden Sie von dem Verantwortlichen unterrichtet bevor die Einschränkung aufgehoben + wird. + </p> + <li><strong>Recht auf Löschung</strong></li> + <ol> + <li>Löschungspflicht</li> + <p>Sie können von dem Verantwortlichen verlangen, dass die Sie betreffenden + personenbezogenen Daten unverzüglich gelöscht werden, und der Verantwortliche ist + verpflichtet, diese Daten unverzüglich zu löschen, sofern einer der folgenden Gründe zutrifft:</p> + <ol> + <li>Die Sie betreffenden personenbezogenen Daten sind für die Zwecke, für + die sie erhoben oder auf sonstige Weise verarbeitet wurden, nicht mehr + notwendig.</li> + <li>Sie widerrufen Ihre Einwilligung, auf die sich die Verarbeitung gem. Art. 6 + Abs. 1 lit. a oder Art. 9 Abs. 2 lit. a DSGVO stützte, und es fehlt an einer + anderweitigen Rechtsgrundlage für die Verarbeitung.</li> + <li>Sie legen gem. Art. 21 Abs. 1 DSGVO Widerspruch gegen die Verarbeitung + ein und es liegen keine vorrangigen berechtigten Gründe für die + Verarbeitung vor, oder Sie legen gem. Art. 21 Abs. 2 DSGVO Widerspruch + gegen die Verarbeitung ein.</li> + <li>Die Sie betreffenden personenbezogenen Daten wurden unrechtmäßig + verarbeitet.</li> + <li>Die Löschung der Sie betreffenden personenbezogenen Daten ist zur + Erfüllung einer rechtlichen Verpflichtung nach dem Unionsrecht oder dem + Recht der Mitgliedstaaten erforderlich, dem der Verantwortliche + unterliegt.</li> + <li>Die Sie betreffenden personenbezogenen Daten wurden in Bezug auf + angebotene Dienste der Informationsgesellschaft gemäß Art. 8 Abs. 1 + DSGVO erhoben.</li> + </ol> + <li>Information an Dritte</li> + <p>Hat der Verantwortliche die Sie betreffenden personenbezogenen Daten öffentlich gemacht + und ist er gem. Art. 17 Abs. 1 DSGVO zu deren Löschung verpflichtet, so trifft er unter + Berücksichtigung der verfügbaren Technologie und der Implementierungskosten + angemessene Maßnahmen, auch technischer Art, um für die Datenverarbeitung + Verantwortliche, die die personenbezogenen Daten verarbeiten, darüber zu informieren, + dass Sie als betroffene Person von ihnen die Löschung aller Links zu diesen + personenbezogenen Daten oder von Kopien oder Replikationen dieser personenbezogenen + Daten verlangt haben.</p> + <li>Ausnahmen</li> + <p> + Das Recht auf Löschung besteht nicht, soweit die Verarbeitung erforderlich ist + <ol> + <li>zur Ausübung des Rechts auf freie Meinungsäußerung und Information;</li> + <li>zur Erfüllung einer rechtlichen Verpflichtung, die die Verarbeitung nach dem + Recht der Union oder der Mitgliedstaaten, dem der Verantwortliche unterliegt, + erfordert, oder zur Wahrnehmung einer Aufgabe, die im öffentlichen Interesse + liegt oder in Ausübung öffentlicher Gewalt erfolgt, die dem Verantwortlichen + übertragen wurde;</li> + <li>aus Gründen des öffentlichen Interesses im Bereich der öffentlichen Gesundheit + gemäß Art. 9 Abs. 2 lit. h und i sowie Art. 9 Abs. 3 DSGVO;</li> + <li>für im öffentlichen Interesse liegende Archivzwecke, wissenschaftliche oder + historische Forschungszwecke oder für statistische Zwecke gem. Art. 89 Abs. 1 + DSGVO, soweit das unter Abschnitt a) genannte Recht voraussichtlich die + Verwirklichung der Ziele dieser Verarbeitung unmöglich macht oder ernsthaft + beeinträchtigt, oder</li> + <li>zur Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen.</li> + </ol> + </p> + </ol> + <li><strong>Recht auf Unterrichtung</strong></li> + <p> + Haben Sie das Recht auf Berichtigung, Löschung oder Einschränkung der Verarbeitung + gegenüber dem Verantwortlichen geltend gemacht, ist dieser verpflichtet, allen Empfängern, + denen die Sie betreffenden personenbezogenen Daten offengelegt wurden, diese + Berichtigung oder Löschung der Daten oder Einschränkung der Verarbeitung mitzuteilen, es + sei denn, dies erweist sich als unmöglich oder ist mit einem unverhältnismäßigen Aufwand + verbunden.<br /> + Ihnen steht gegenüber dem Verantwortlichen das Recht zu, über diese Empfänger + unterrichtet zu werden. + </p> + <li><strong>Recht auf Datenübertragbarkeit</strong></li> + <p> + Sie haben das Recht, die Sie betreffenden personenbezogenen Daten, die Sie dem + Verantwortlichen bereitgestellt haben, in einem strukturierten, gängigen und + maschinenlesbaren Format zu erhalten. Außerdem haben Sie das Recht diese Daten einem + anderen Verantwortlichen ohne Behinderung durch den Verantwortlichen, dem die + personenbezogenen Daten bereitgestellt wurden, zu übermitteln, sofern + <ol> + <li>die Verarbeitung auf einer Einwilligung gem. Art. 6 Abs. 1 lit. a DSGVO oder Art. 9 + Abs. 2 lit. a DSGVO oder auf einem Vertrag gem. Art. 6 Abs. 1 lit. b DSGVO beruht + und</li> + <li>die Verarbeitung mithilfe automatisierter Verfahren erfolgt.</li> + </ol> + In Ausübung dieses Rechts haben Sie ferner das Recht, zu erwirken, dass die Sie + betreffenden personenbezogenen Daten direkt von einem Verantwortlichen einem anderen + Verantwortlichen übermittelt werden, soweit dies technisch machbar ist. Freiheiten und + Rechte anderer Personen dürfen hierdurch nicht beeinträchtigt werden.<br /> + Das Recht auf Datenübertragbarkeit gilt nicht für eine Verarbeitung personenbezogener + Daten, die für die Wahrnehmung einer Aufgabe erforderlich ist, die im öffentlichen Interesse + liegt oder in Ausübung öffentlicher Gewalt erfolgt, die dem Verantwortlichen übertragen + wurde. + </p> + <li><strong>Widerspruchsrecht</strong></li> + <p> + Sie haben das Recht, aus Gründen, die sich aus ihrer besonderen Situation ergeben, jederzeit + gegen die Verarbeitung der Sie betreffenden personenbezogenen Daten, die aufgrund von + Art. 6 Abs. 1 lit. e oder f DSGVO erfolgt, Widerspruch einzulegen; dies gilt auch für ein auf + diese Bestimmungen gestütztes Profiling.<br /> + Der Verantwortliche verarbeitet die Sie betreffenden personenbezogenen Daten nicht mehr, + es sei denn, er kann zwingende schutzwürdige Gründe für die Verarbeitung nachweisen, die + Ihre Interessen, Rechte und Freiheiten überwiegen, oder die Verarbeitung dient der + Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen.<br /> + Werden die Sie betreffenden personenbezogenen Daten verarbeitet, um Direktwerbung zu + betreiben, haben Sie das Recht, jederzeit Widerspruch gegen die Verarbeitung der Sie + betreffenden personenbezogenen Daten zum Zwecke derartiger Werbung einzulegen; dies + gilt auch für das Profiling, soweit es mit solcher Direktwerbung in Verbindung steht.<br /> + Widersprechen Sie der Verarbeitung für Zwecke der Direktwerbung, so werden die Sie + betreffenden personenbezogenen Daten nicht mehr für diese Zwecke verarbeitet.<br /> + Sie haben die Möglichkeit, im Zusammenhang mit der Nutzung von Diensten der + Informationsgesellschaft – ungeachtet der Richtlinie 2002/58/EG – Ihr Widerspruchsrecht + mittels automatisierter Verfahren auszuüben, bei denen technische Spezifikationen + verwendet werden. + </p> + <li><strong>Recht auf Widerruf der datenschutzrechtlichen Einwilligungserklärung</strong></li> + <p>Sie haben das Recht, Ihre datenschutzrechtliche Einwilligungserklärung jederzeit zu + widerrufen. Durch den Widerruf der Einwilligung wird die Rechtmäßigkeit der aufgrund der + Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt.</p> + <li><strong>Automatisierte Entscheidung im Einzelfall einschließlich Profiling</strong></li> + <p> + Sie haben das Recht, nicht einer ausschließlich auf einer automatisierten Verarbeitung – + einschließlich Profiling – beruhenden Entscheidung unterworfen zu werden, die Ihnen + gegenüber rechtliche Wirkung entfaltet oder Sie in ähnlicher Weise erheblich beeinträchtigt. + Dies gilt nicht, wenn die Entscheidung + <ol> + <li>für den Abschluss oder die Erfüllung eines Vertrags zwischen Ihnen und dem + Verantwortlichen erforderlich ist,</li> + <li>aufgrund von Rechtsvorschriften der Union oder der Mitgliedstaaten, denen der + Verantwortliche unterliegt, zulässig ist und diese Rechtsvorschriften + angemessene Maßnahmen zur Wahrung Ihrer Rechte und Freiheiten sowie Ihrer + berechtigten Interessen enthalten oder</li> + <li>mit Ihrer ausdrücklichen Einwilligung erfolgt.</li> + </ol> + Allerdings dürfen diese Entscheidungen nicht auf besonderen Kategorien + personenbezogener Daten nach Art. 9 Abs. 1 DSGVO beruhen, sofern nicht Art. 9 Abs. 2 lit. a + oder g DSGVO gilt und angemessene Maßnahmen zum Schutz der Rechte und Freiheiten + sowie Ihrer berechtigten Interessen getroffen wurden.<br /> + Hinsichtlich der in (1) und (3) genannten Fälle trifft der Verantwortliche angemessene + Maßnahmen, um die Rechte und Freiheiten sowie Ihre berechtigten Interessen zu wahren, + wozu mindestens das Recht auf Erwirkung des Eingreifens einer Person seitens des + Verantwortlichen, auf Darlegung des eigenen Standpunkts und auf Anfechtung der + Entscheidung gehört. + </p> + <li><strong>Recht auf Beschwerde bei einer Aufsichtsbehörde</strong></li> + <p> + Unbeschadet eines anderweitigen verwaltungsrechtlichen oder gerichtlichen Rechtsbehelfs + steht Ihnen das Recht auf Beschwerde bei einer Aufsichtsbehörde, insbesondere in dem + Mitgliedstaat ihres Aufenthaltsorts, ihres Arbeitsplatzes oder des Orts des mutmaßlichen + Verstoßes, zu, wenn Sie der Ansicht sind, dass die Verarbeitung der Sie betreffenden + personenbezogenen Daten gegen die DSGVO verstößt.<br /> + Die Aufsichtsbehörde, bei der die Beschwerde eingereicht wurde, unterrichtet den + Beschwerdeführer über den Stand und die Ergebnisse der Beschwerde einschließlich der + Möglichkeit eines gerichtlichen Rechtsbehelfs nach Art. 78 DSGVO. + </p> + </ol> + </ol> + <br /> +</div> \ No newline at end of file diff --git a/themes/fid/templates/fid/user/policy-en.phtml b/themes/fid/templates/fid/user/policy-en.phtml new file mode 100644 index 0000000000000000000000000000000000000000..7869bf7c7669fb58468c53b1786367d65a3c43dd --- /dev/null +++ b/themes/fid/templates/fid/user/policy-en.phtml @@ -0,0 +1,600 @@ +<div class="adlr-policies"> + <br /> + <h2><strong>Privacy Policy</strong></h2> + <p>Please note: The English version of our privacy policy is for informational purposes only. The + German version shall be legally binding only.</p> + <ol> + <li><strong>Name and address of the person responsible</strong></li> + <p>The person responsible within the meaning of the General Data Protection Regulation and + other national data protection laws of the member states as well as other data protection + regulations:</p> + <p>Leipzig University Library<br /> + represented by the Director of the University Library Prof. Dr. Ulrich Johannes Schneider<br /> + Beethovenstr. 6<br /> + 04107 Leipzig, Germany<br /> + Phone: +49 341-97 30577<br /> + E-mail: info[at] adlr.link</p> + <li><strong>Name and address of the data protection officer</strong></li> + <p>The data protection officer of the person responsible is:<br /><br /> + University of Leipzig<br /> + Data Protection Officer: Thomas Braatz<br /> + 04109 Leipzig, Germany<br /> + Phone: +49 341 97-30081<br /> + E-mail: dsb[at] uni-leipzig.de<br /> + Website: http://www.uni-leipzig.de/universitaet/profil/beauftragte.html#c2362</p> + <li><strong>General information on data processing</strong></li> + <ol> + <li><strong>Scope of the processing of personal data</strong></li> + <p>We only process personal data of our users if this is necessary to provide a functional + website as well as for our contents and services. The processing of personal data of our users + takes place regularly only after consent of the user. An exception applies in those cases + where prior consent cannot be obtained for real reasons and the processing of the data is + permitted by law.</p> + <li><strong>Legal basis for the processing of personal data</strong></li> + <p>Insofar as we obtain the consent of the data subject for the processing of personal data, Art. + 6 para. 1 lit. a EU General Data Protection Regulation (GDPR) serves as the legal basis.<br /> + In the processing of personal data required for the performance of a contract to which the + data subject is a party, Art. 6 para. 1 lit. b GDPR serves as the legal basis. This also applies to + processing operations that are necessary to carry out pre-contractual measures.<br /> + Insofar as the processing of personal data is required to fulfil a legal obligation to which our + company is subject, Art. 6 para. 1 lit. c GDPR serves as the legal basis.<br /> + In the event that the vital interests of the data subject or another natural person require the + processing of personal data, Article 6(1)(d) GDPR serves as the legal basis.<br /> + If processing is necessary to safeguard a legitimate interest of our company or a third party + and if the interests, fundamental rights and freedoms of the data subject do not outweigh + the first-mentioned interest, Art. 6 para. 1 lit. f GDPR serves as the legal basis for processing.</p> + <li><strong>Deletion of data and storage time</strong></li> + <p>The personal data of the person concerned will be deleted or blocked as soon as the purpose + of storage ceases to apply. Furthermore, data may be stored if this has been provided for by + the European or national legislator in EU regulations, laws or other provisions to which the + person responsible is subject. The data will also be blocked or deleted if a storage period + prescribed by the aforementioned standards expires, unless there is a need for further + storage of the data for the conclusion or fulfilment of a contract.</p> + </ol> + <li><strong>Provision of the website and creation of log files</strong></li> + <ol> + <li><strong>Description and scope of data processing</strong></li> + <p> + When using the adlr.link website, an encrypted browser connection is established to ensure + secure data transmission.<br /> + In principle, you can visit the adlr.link website without telling us who you are. However, + every time you visit our website, your browser automatically transmits data and information + from your computer system to us.<br /> + The following data is collected: + <ol> + <li>Information about the browser type, language and version used</li> + <li>The user's operating system</li> + <li>The IP address of the user</li> + <li>Date and time of access</li> + <li>Contents of the request</li> + <li>Access status code</li> + <li>Websites from which the user's system reaches our website</li> + <li>Websites accessed by the user's system via our website</li> + <li>Amount of data transmitted</li> + </ol> + The data is stored in the log files of our system. This data is not stored together with other + personal data of the user. + </p> + <li><strong>Legal basis for data processing</strong></li> + <p>The legal basis for the temporary storage of data and log files is Art. 6 para. 1 lit. f GDPR.</p> + <li><strong>Purpose of data processing</strong></li> + <p> + The temporary storage of the IP address by the system is necessary to enable the website to + be delivered to the user's computer. For this the IP address of the user must remain stored + for the duration of the session.<br /> + The data is stored in log files to ensure the functionality of the website. In addition, the data + serves us to optimize the website and to ensure the security of our information technology + systems. An evaluation of the data for marketing purposes does not take place in this + context.<br /> + Our legitimate interest in data processing pursuant to Art. 6 para. 1 lit. f GDPR also lies in + these purposes. + </p> + <li><strong>Duration of storage</strong></li> + <p> + The data will be deleted as soon as they are no longer necessary to achieve the purpose for + which they were collected. In the case of the collection of data for the provision of the + website, this is the case when the respective session has ended.<br /> + If the data is stored in log files, this is the case after seven days at the latest. Further storage + is possible. In this case, the IP addresses of the users are deleted or alienated so that an + assignment of the calling client is no longer possible. + </p> + <li><strong>Possibility of opt-out and deletion</strong></li> + <p>The collection of data for the provision of the website and the storage of data in log files is + absolutely necessary for the operation of the website. Consequently, there is no possibility + of objection on the part of the user.</p> + </ol> + <li><strong>Use of Cookies</strong></li> + <ol> + <li><strong>Description and scope of data processing</strong></li> + <p> + Our website uses cookies. Cookies are text files that are stored in the Internet browser or by + the Internet browser on the user's computer system. Some of the cookies we use are so- + called "session cookies", which are automatically deleted when you close your browser. In + addition, there are some persistent cookies that we use to recognize you as a visitor. Cookies + do not cause any damage to your computer and do not contain any viruses. If a user visits a + website, a cookie may be stored on the user's operating system. This cookie contains a + characteristic character string that enables a unique identification of the browser when the + website is called up again.<br /> + We use cookies to make our website more user-friendly. Some elements of our website + require that the calling browser can be identified even after a page change.<br /> + The following data is stored and transmitted in the cookies: + <ol> + <li>Language settings</li> + <li>Log-in information/Session-ID (no password)</li> + </ol> + We also use cookies on our website which enable an analysis of the user's surfing behaviour.<br /> + In this way, the following data can be transmitted: + <ol> + <li>Entered search terms</li> + <li>Frequency of page views</li> + <li>Use of website functions</li> + </ol> + The user data collected in this way is pseudonymised by technical precautions. Therefore, it + is no longer possible to assign the data to the calling user. The data will not be stored + together with other personal data of the users.<br /> + When you visit our website, an information banner informs you about the use of cookies for + analytical purposes and refers you to this data protection declaration. This also includes an + indication of how the storage of cookies can be prevented in the browser settings. + </p> + <li><strong>Legal basis for data processing</strong></li> + <p> + The legal basis for the processing of personal data using technically necessary cookies is Art. + 6 para. 1 lit. f GDPR.<br /> + The legal basis for the processing of personal data using cookies for analytical purposes is, + with the user's consent, Art. 6 para. 1 lit. a GDPR. + </p> + <li><strong>Purpose of data processing</strong></li> + <p> + The purpose of using technically necessary cookies is to simplify the use of websites for + users. Some functions of our website cannot be offered without the use of cookies. For this + it is necessary that the browser is recognized even after a page change.<br /> + We need cookies for the following applications: + <ol> + <li>Registration</li> + <li>Calling up your own user account</li> + <li>Accepting language settings</li> + <li>Remembering search terms</li> + </ol> + The user data collected by technically necessary cookies are not used to create user profiles. + The analysis cookies are used to improve the quality of our website and its content. Through + the analysis cookies we learn how the website is used and can thus continuously optimize + our offer.<br /> + For these purposes, our legitimate interest also lies in the processing of personal data + pursuant to Art. 6 para. 1 lit. f GDPR. + </p> + <li><strong>Duration of storage, Possibility of opt-out and deletion</strong></li> + <p> + Cookies are stored on the user's computer and transmitted to our site. Therefore, you as a + user also have full control over the use of cookies. By changing the settings in your Internet + browser, you can deactivate or restrict the transmission of cookies at any time. Cookies that + have already been saved can be deleted at any time. This can also be done automatically. If + cookies are deactivated for our website, it may no longer be possible to use all functions of + the website in full. + </p> + </ol> + <li><strong>Newsletter</strong></li> + <ol> + <li><strong>Description and scope of data processing</strong></li> + <p> + You can subscribe to a free newsletter on our website. When registering for the newsletter, + the data from the input mask is transmitted to us: + <ol> + <li>E-mail address</li> + <li>Name (optional)</li><br /> + <p>In addition, the following data is collected upon registration:</p> + <li>IP address of the calling computer</li> + <li>Date and time of registration</li> + </ol> + In the course of the registration process, your consent is obtained for the processing of the + data and reference is made to this data protection declaration.<br /> + In connection with data processing for the dispatch of newsletters, no data is passed on to + third parties. The data will only be used for sending the newsletter. + </p> + <li><strong>Legal basis for data processing</strong></li> + <p>The legal basis for the processing of data after registration for the newsletter by the user is, + with the user's consent, Art. 6 para. 1 lit. a GDPR.</p> + <li><strong>Purpose of data processing</strong></li> + <p>The collection of the user's e-mail address serves to send the newsletter. + The collection of other personal data within the registration process serves to prevent + misuse of the services or the e-mail address used.</p> + <li><strong>Duration of storage</strong></li> + <p>The data will be deleted as soon as they are no longer necessary to achieve the purpose for + which they were collected. The user's e-mail address will therefore be stored for as long as + the subscription to the newsletter is active.<br /> + The other personal data collected during the registration process will generally be deleted + after a period of seven days.</p> + <li><strong>Possibility of opt-out and deletion</strong></li> + <p>You can cancel your subscription to the newsletter at any time. For this purpose there is a + corresponding link in every newsletter.<br /> + This also makes it possible to revoke the consent to the storage of personal data collected + during the registration process.</p> + </ol> + <li><strong>Registration</strong></li> + <ol> + <li><strong>Description and scope of data processing</strong></li> + <p> + For the use of certain functions (user-controlled acquisition of printed publications, access to + e-books and/or journals licensed specifically for the subject information service, storage of + search queries and/or favorites) of adlr.link, prior registration is required.<br /> + On our website, we offer users the opportunity to register for their own user account by + entering personal data. The data is entered into an input mask and transmitted to us and + saved. The following data is collected during the registration process: + <ol> + <li>E-mail address (also login)</li> + <li>Password (self-defined)</li> + <li>Type of user group</li> + <li>First and last name</li> + <li>Form of address/Academic degree (optional)</li> + <li>Year of birth (optional)</li> + <li>Home library</li> + <li>Profession (optional)</li> + <li>Phone (optional)</li> + <li>Address information (street/no., postcode/city) for a maximum of two addresses</li><br /> + <p>At the time of registration, the following data is also stored:</p> + <li>The IP address of the user</li> + <li>Date and time of registration</li> + </ol> + In the course of the registration process, the user's consent to the processing of this data is + obtained.<br /> + The password is not stored for security reasons. For user authentication, a hash value is + calculated from the password and only this is stored. A hash value is a unique string that is + calculated so that the original password cannot be restored. To be able to authenticate you + for later logins, your input is calculated with the same function for later logins and only the + two hash values are compared. + </p> + <li><strong>Legal basis for data processing</strong></li> + <p>The legal basis for the processing of data is Art. 6 para. 1 lit. a GDPR if the user has given his + consent.<br /> + If the registration serves the fulfilment of a contract to which the user is a party or the + implementation of pre-contractual measures, the additional legal basis for the processing of + the data is Art. 6 para. 1 lit. b GDPR.</p> + <li><strong>Purpose of data processing</strong></li> + <p> + A registration of the user is necessary for the fulfilment of a contract with the user or for the + implementation of pre-contractual measures.<br /> + We need your e-mail address in order to communicate with you, to send you the newsletter + and to be able to send you documents by electronic means on order. Your e-mail address is + also your login (user name) for your user account.<br /> + The password is not stored for security reasons. For user authentication, a hash value is + calculated from the password and only this is stored. A hash value is a unique string that is + calculated so that the original password cannot be restored. To be able to authenticate you + for later logins, your input is calculated with the same function for later logins and only the + two hash values are compared.<br /> + We need your name and address information in order to send you printed media by post. + You can specify up to two different addresses and indicate at any time to which address we + should send the delivery. When you place an order for a printed medium, we pass on your + name, the address you have specified as the delivery address and your e-mail address to + suppliers and vicarious agents.<br /> + We use your home library to show you whether individual media in your library are either + physically available or electronically accessible. We only pass on an identifier for the + respective medium (e.g. the ISBN) and an identifier of your home library to a service of the + Bibliotheksservice-Zentrum Baden-Württemberg, but no further personal data from you. + We use WorldCat services to let you know if individual media are available in a library near + you, based on location. To do this, your current IP address and an identifier for each medium + (e.g. the ISBN) is transmitted to the WorldCat service. The IP address is only used for the + purpose of geotargeting and is not stored or otherwise used. No other personal data will be + transmitted.<br /> + You can optionally provide us with additional data in your user account. We use your form of + address and academic title for personal addressing and pass this information on together + with your address information. We can use your telephone number to answer your + questions or place orders over the phone. Your profession and year of birth will only be used + anonymously for statistical purposes.<br /> + When passing on personal information to third parties, we ensure that the information is + provided in accordance with this data protection declaration. Third parties to whom the data + are transmitted are obliged to process the data transmitted to them only for the respective + purpose, but not to use them beyond that. + </p> + <li><strong>Duration of storage</strong></li> + <p> + The data will be deleted as soon as they are no longer necessary to achieve the purpose for + which they were collected.<br /> + This is the case for those during the registration process to fulfill a contract or to carry out + pre-contractual measures when the data is no longer required for the execution of the + contract. Even after conclusion of the contract, it may still be necessary to store personal + data of the contractual partner in order to fulfil contractual or legal obligations. + </p> + <li><strong>Possibility of opt-out and deletion</strong></li> + <p> + As a user you have the possibility to cancel your registration and your user account at any + time. You can change the data stored about you at any time.<br /> + You can change your data yourself at any time via the website.<br /> + For a complete deletion of the data please write us an e-mail or contact us via the contact + form.<br /> + If the data is required to fulfil a contract or to carry out pre-contractual measures, + premature deletion of the data is only possible insofar as contractual or statutory obligations + do not prevent deletion. + </p> + </ol> + <li><strong>Contact form and e-mail contact</strong></li> + <ol> + <li><strong>Description and scope of data processing</strong></li> + <p> + There is a contact form on our website which can be used for electronic contact. If you take + advantage of this option, the data entered in the input mask will be transmitted to us and + saved. This data is: + <ol> + <li>E-mail address</li> + <li>Name</li> + <li>Subject and message content</li><br /> + <p>At the time the message is sent, the following data is also stored:</p> + <li>The IP address of the user</li> + <li>Date and time of registration</li> + </ol> + Your consent is obtained for the processing of the data within the scope of the sending + process and reference is made to this data protection declaration.<br /> + Alternatively, you can contact us via the e-mail address provided. In this case, the user's + personal data transmitted by e-mail will be stored.<br /> + In this context, the data will not be passed on to third parties. The data is used exclusively + for processing the conversation. + </p> + <li><strong>Legal basis for data processing</strong></li> + <p>The legal basis for the processing of data is Art. 6 para. 1 lit. a GDPR if the user has given his + consent.<br /> + The legal basis for the processing of data transmitted in the course of sending an e-mail is + Art. 6 para. 1 lit. f GDPR. If the e-mail contact is aimed at the conclusion of a contract, the + additional legal basis for the processing is Art. 6 para. 1 lit. b GDPR.</p> + <li><strong>Purpose of data processing</strong></li> + <p>The processing of the personal data from the input mask serves us only for the treatment of + the establishment of contact. In the event of contact by e-mail, this also constitutes the + necessary legitimate interest in the processing of the data.<br /> + The other personal data processed during the sending process serve to prevent misuse of + the contact form and to ensure the security of our information technology systems.</p> + <li><strong>Duration of storage</strong></li> + <p>The data will be deleted as soon as they are no longer necessary to achieve the purpose for + which they were collected. For the personal data from the input mask of the contact form + and those sent by e-mail, this is the case when the respective conversation with you has + ended. The conversation is terminated when it can be inferred from the circumstances that + the facts in question have been finally clarified.<br /> + The additional personal data collected during the sending process will be deleted at the + latest after a period of seven days.</p> + <li><strong>Possibility of opt-out and deletion</strong></li> + <p>You have the possibility to revoke your consent to the processing of personal data at any + time. If you contact us by e-mail, you can object to the storage of your personal data at any + time. In such a case, the conversation cannot be continued.<br /> + If you have any objections, please send us an e-mail or contact us using the contact form. + All personal data stored in the course of contacting us will be deleted in this case.</p> + </ol> + <li><strong>Web analysis by Matomo (formerly Piwik)</strong></li> + <ol> + <li><strong>Scope of the processing of personal data</strong></li> + <p> + On our website we use the open source software tool Matomo (formerly Piwik) to analyse + the surfing behaviour of our users. The software places a cookie on the user's computer (see + above for cookies). If individual pages of our website are accessed, the following data is + stored: + <ol> + <li>Two bytes of the IP address of the user's calling system</li> + <li>The accessed website</li> + <li>The website from which the user has accessed the accessed website (referrer)</li> + <li>The sub-pages accessed from the accessed website</li> + <li>The time spent on the website</li> + <li>The frequency with which the website is accessed</li> + </ol> + The software runs exclusively on the servers of our website. The personal data of users is + only stored there. The data will not be passed on to third parties.<br /> + The software is set so that the IP addresses are not completely stored, but 2 bytes of the IP + address are masked (e.g.: 192.168.X.X). In this way it is no longer possible to assign the + shortened IP address to the calling computer. + </p> + <li><strong>Legal basis for the processing of personal data</strong></li> + <p>The legal basis for the processing of users' personal data is Art. 6 para. 1 lit. f GDPR.</p> + <li><strong>Purpose of data processing</strong></li> + <p>The processing of users' personal data enables us to analyse the surfing behaviour of our + users. We are in a position to compile information about the use of the individual + components of our website by evaluating the data obtained. This helps us to continuously + improve our website and its user-friendliness. For these purposes, it is also in our legitimate + interest to process the data in accordance with Art. 6 para. 1 lit. f GDPR. By anonymizing the + IP address, the interest of the users in their protection of personal data is sufficiently taken + into account.</p> + <li><strong>Duration of storage</strong></li> + <p>The data will be deleted as soon as they are no longer needed for our recording purposes.</p> + <li><strong>Possibility of opt-out and deletion</strong></li> + <p> + Cookies are stored on the user's computer and transmitted to our site. Therefore, you as a + user also have full control over the use of cookies. You can deactivate or restrict the + transmission of cookies by changing the settings in your Internet browser. Cookies that have + already been saved can be deleted at any time. This can also be done automatically. If + cookies are deactivated for our website, it may no longer be possible to use all functions of + the website in full.<br /> + We offer our users on this website the possibility of an opt-out from the analysis procedure. + In this way, another cookie is placed on your system, which signals to our system not to + 10store the user's data. If the user deletes the corresponding cookie from his own system in + store the user's data. If the user deletes the corresponding cookie from his own system in + the meantime, he must set the opt-out cookie again.<br /> + More information about the privacy settings of the Matomo software can be found under + the following link: https://matomo.org/docs/privacy/.<br /> + Here you can switch tracking by Piwik on or off, if this setting is not already automatically + controlled by the settings of your browser or an adblocker.<br /> + {if $url == "https://katalog.adlr.link"} + <iframe style="border: 0; height: 200px; width: 100%; margin-left:-.5rem" id="piwk" name="piwk" onLoad="addCSS()" src="https://piwik.ub.uni-leipzig.de/index.php?module=CoreAdminHome&action=optOut&language={$userLang}&idSite=6"></iframe> + {/if} + </p> + </ol> + <li><strong>Rights of the person concerned</strong></li> + <p>If personal data are processed by you, you are affected within the meaning of the GDPR and + you have the following rights to the person responsible:</p> + <ol> + <li><strong>Right to information</strong></li> + <p> + You can ask the person in charge to confirm whether personal data concerning you will be + processed by us.<br /> + If such processing has taken place, you can request the following information from the + person responsible: + <ol> + <li>the purposes for which the personal data are processed;</li> + <li>the categories of personal data being processed;</li> + <li>the recipients or categories of recipients to whom the personal data concerning you have + been or are still being disclosed;</li> + <li>the planned duration of the storage of the personal data concerning you or, if specific + information on this is not possible, criteria for determining the storage period;</li> + <li>the existence of a right to rectification or deletion of personal data concerning you, a + right to limitation of processing by the controller or a right to object to such processing;</li> + <li>the existence of a right of appeal to a supervisory authority;</li> + <li>any available information on the origin of the data if the personal data are not collected + from the data subject;</li> + <li>the existence of automated decision-making including profiling in accordance with Art. 22 + para. 1 and 4 GDPR and - at least in these cases - meaningful information on the logic + involved and the scope and intended effects of such processing for the data subject.</li> + </ol> + You have the right to request information as to whether the personal data concerning you is + transferred to a third country or to an international organisation. In this context, you may + request to be informed of the appropriate guarantees in accordance with Art. 46 GDPR in + connection with the transmission. + </p> + <li><strong>Right to correction</strong></li> + <p>You have a right of rectification and/or completion to the person in charge if the personal + data processed concerning you are incorrect or incomplete. The person responsible shall + make the correction without delay.</p> + <li><strong>Right to restriction</strong></li> + <p> + Under the following conditions, you may request that the processing of personal data + concerning you be restricted: + <ol> + <li>if you dispute the accuracy of the personal data concerning you for a period that enables + the data controller to verify the accuracy of the personal data;</li> + <li>the processing is unlawful and you refuse to delete the personal data and instead request + that the use of the personal data be restricted;</li> + <li>the data controller no longer needs the personal data for the purposes of the processing, + but you do need them to assert, exercise or defend legal claims, or</li> + <li>if you have filed an objection to the processing pursuant to Art. 21 para. 1 GDPR and it + has not yet been determined whether the legitimate reasons of the person responsible + outweigh your reasons.</li> + </ol> + If the processing of personal data concerning you has been restricted, such data may only be + processed - apart from being stored - with your consent or for the purpose of asserting, + exercising or defending rights or protecting the rights of another natural or legal person or + on grounds of an important public interest of the Union or a Member State.<br /> + If the processing restriction has been restricted in accordance with the above conditions, you + will be informed by the person responsible before the restriction is lifted. + </p> + <li><strong>Right to deletion</strong></li> + <ol> + <li>Duty to delete</li> + <p>You may request the person in charge to delete the personal data relating to you without + delay and the controller is obliged to delete this data without delay if one of the + following reasons applies:</p> + <ol> + <li>The personal data concerning you are no longer necessary for the purposes for which + they were collected or otherwise processed.</li> + <li>You revoke your consent, on which the processing was based pursuant to Art. 6 para. + 1 lit. a or Art. 9 para. 2 lit. a GDPR, and there is no other legal basis for the processing.</li> + <li>You file an objection against the processing pursuant to Art. 21 para. 1 GDPR and + there are no overriding legitimate reasons for the processing, or you file an objection + against the processing pursuant to Art. 21 para. 2 GDPR.</li> + <li>The personal data concerning you have been processed unlawfully.</li> + <li>The deletion of personal data relating to you is necessary to fulfil a legal obligation + under Union law or the law of the Member States to which the data controller is subject.</li> + <li>The personal data concerning you were collected in relation to information society + services offered pursuant to Art. 8 para. 1 GDPR.</li> + </ol> + <li>Information to third parties</li> + <p>If the person in charge has made the personal data concerning you public and is obliged + to delete it pursuant to Art. 17 para. 1 GDPR, he shall take appropriate measures, + including technical measures, taking into account the available technology and the + implementation costs, to inform data processors who process the personal data that you + as the data subject have requested the deletion of all links to this personal data or of + copies or replications of this personal data.</p> + <li>Exceptions</li> + <p> + The right to cancellation does not exist insofar as the processing is necessary + <ol> + <li>to exercise freedom of expression and information;</li> + <li>for the performance of a legal obligation required for processing under the law of the + Union or of the Member States to which the controller is subject or for the performance + of a task in the public interest or in the exercise of official authority conferred on the + controller;</li> + <li>for reasons of public interest in the field of public health pursuant to Art. 9 para. 2 lit. + h and i and Art. 9 para. 3 GDPR;</li> + <li>for archiving purposes in the public interest, scientific or historical research purposes + or for statistical purposes pursuant to Art. 89 para. 1 GDPR, insofar as the law referred to + under a) is likely to make it impossible or seriously impair the attainment of the + objectives of such processing, or</li> + <li>to assert, exercise or defend legal claims.</li> + </ol> + </p> + </ol> + <li><strong>Right to information third parties</strong></li> + <p> + If you have exercised your right to have the person in charge correct, delete or limit the + processing, he/she is obliged to inform all recipients to whom the personal data concerning + you have been disclosed of this correction or deletion of the data or restriction on + processing, unless this proves impossible or involves a disproportionate effort.<br /> + You have the right to the person in charge to be informed of these recipients. + </p> + <li><strong>Right to data transferability</strong></li> + <p> + You have the right to receive the personal data concerning you that you have provided to + the person responsible in a structured, common and machine-readable format. In addition, + you have the right to pass this data on to another person in charge without obstruction by + the person in charge to whom the personal data was provided, provided that + <ol> + <li>processing is based on consent pursuant to Art. 6 para. 1 lit. a GDPR or Art. 9 para. 2 lit. a + GDPR or on a contract pursuant to Art. 6 para. 1 lit. b GDPR and</li> + <li>processing is carried out by means of automated methods.</li> + </ol> + In exercising this right, you also have the right to request that the personal data concerning + you be transferred directly from one person in charge to another, insofar as this is + technically feasible. The freedoms and rights of other persons must not be affected by this.<br /> + The right to transferability shall not apply to the processing of personal data necessary for + the performance of a task in the public interest or in the exercise of official authority + conferred on the controller. + </p> + <li><strong>Right to objection</strong></li> + <p> + You have the right to object at any time, for reasons arising from your particular situation, to + the processing of personal data concerning you under Article 6(1)(e) or (f) of the DSBER; this + also applies to profiling based on these provisions.<br /> + The person in charge no longer processes the personal data concerning you, unless he can + prove compelling reasons worthy of protection for the processing, which outweigh your + interests, rights and freedoms, or the processing serves to assert, exercise or defend legal + claims.<br /> + If the personal data concerning you are processed for direct marketing purposes, you have + the right to object at any time to the processing of the personal data concerning you for the + purpose of such advertising; this also applies to profiling, insofar as it is associated with such + direct marketing.<br /> + If you object to the processing for direct marketing purposes, the personal data concerning + you will no longer be processed for these purposes.<br /> + You have the possibility to exercise your right of objection in connection with the use of + Information Society services, notwithstanding Directive 2002/58/EC, by means of automated + procedures using technical specifications. + </p> + <li><strong>Right to revoke the data protection declaration of consent</strong></li> + <p>You have the right to revoke your data protection declaration of consent at any time. The + revocation of consent does not affect the legality of the processing carried out on the basis + of the consent until revocation.</p> + <li><strong>Automated decision in individual cases including profiling</strong></li> + <p> + You have the right not to be subject to a decision based exclusively on automated processing + - including profiling - that has legal effect against you or significantly impairs you in a similar + manner. This does not apply if the decision + <ol> + <li>is necessary for the conclusion or performance of a contract between you and the person + responsible,</li> + <li>the legislation of the Union or of the Member States to which the person responsible is + subject is admissible and that legislation contains appropriate measures to safeguard your + rights, freedoms and legitimate interests; or</li> + <li>with your express consent.</li> + </ol> + However, these decisions may not be based on special categories of personal data pursuant + to Art. 9 para. 1 GDPR, unless Art. 9 para. 2 lit. a or g GDPR applies and appropriate + measures have been taken to protect your rights and freedoms and your legitimate + interests.<br /> + In the cases referred to in (1) and (3), the person responsible shall take reasonable measures + to safeguard your rights, freedoms and legitimate interests, including at least the right to + obtain the intervention of a person by the person responsible, to state his own position and + to challenge the decision. + </p> + <li><strong>Right to complain to a supervisory authority</strong></li> + <p> + Without prejudice to any other administrative or judicial remedy, you have the right of + appeal to a supervisory authority, in particular in the Member State where you reside, work + or suspect of infringement, if you believe that the processing of personal data concerning + you is contrary to the GDPR.<br /> + The supervisory authority to which the complaint has been lodged shall inform the + complainant of the status and results of the complaint, including the possibility of a judicial + remedy under Article 78 GDPR. + </p> + </ol> + </ol> + <br /> +</div> \ No newline at end of file diff --git a/themes/fid/templates/fid/user/policy.phtml b/themes/fid/templates/fid/user/policy.phtml new file mode 100644 index 0000000000000000000000000000000000000000..806aedc38d6ad5b3cae080c98e66eb43ce471467 --- /dev/null +++ b/themes/fid/templates/fid/user/policy.phtml @@ -0,0 +1,9 @@ +<!-- fid - policy begin --> +<? $lang = $this->layout()->userLang; ?> +<? $fileExists = file_exists(dirname(__FILE__) . '/policy-'.$lang.'.phtml'); ?> +<? if ($fileExists): ?> + <?=$this->render('fid/user/policy-'.$lang.'.phtml')?> +<? else: ?> + <?=$this->render('fid/user/policy-en.phtml')?> +<? endif; ?> +<!-- fid - policy end --> diff --git a/themes/fid/templates/fid/user/terms-de.phtml b/themes/fid/templates/fid/user/terms-de.phtml new file mode 100644 index 0000000000000000000000000000000000000000..1959fb6dcda91cb33412c6074e3b12a8c63fd456 --- /dev/null +++ b/themes/fid/templates/fid/user/terms-de.phtml @@ -0,0 +1,22 @@ +<div class="adlr-policies"> +<br /> +<p><i>adlr.link</i>, der Fachinformationsdienst für Medien- und Kommunikationswissenschaften wird von der Universitätsbibliothek Leipzig betrieben und von der Deutschen Forschungsgemeinschaft (DFG) gefördert.</p> +<p>Der Dienst richtet sich entsprechend den Förderrichtlinien der DFG vorrangig an WissenschaftlerInnen der Kommunikations-, Medien- und Filmwissenschaften sowie angrenzender Fachgebiete in Deutschland für den schnellen und direkten Zugriff auf Spezialliteratur und forschungsrelevante Informationen unabhängig vom Standort der Tätigkeit.</p> +<p>Mit der Nutzung der Dienste von <i>adlr.link</i> erklären Sie sich mit den Nutzungsbedingungen und der Datenschutzerklärung einverstanden.</p> +<h2><strong>Nutzungsbedingungen</strong></h2> +<ol> +<li>Für die Suche im <i>adlr.link</i>-Katalog bedarf es keiner vorherigen Anmeldung oder Registrierung. Um jedoch alle Services von <i>adlr.link</i> vollumfänglich nutzen zu können, ist eine Registrierung erforderlich. Die Registrierung und die Inanspruchnahme der Dienstleistungen sind kostenfrei.</li> +<li>Bei der Registrierung müssen Sie uns persönliche Daten angeben, um Dienstleistungen in Anspruch nehmen zu können. Wir behandeln diese Daten gemäß unserer Datenschutzerklärung. Sie sind verpflichtet, Ihre Daten stets auf dem aktuellen Stand zu halten. Ein Nutzerkonto ist personengebunden; eine Weitergabe von Benutzername und Passwort ist nicht statthaft und führt zu einer vorübergehenden oder dauerhaften Sperrung des Kontos.</li> +<li>Mit der Registrierung versichern Sie, der von Ihnen angegebenen Nutzergruppe zugehörig zu sein. <i>adlr.link</i> verfügt über zwei Nutzergruppen: Nutzergruppe I umfasst alle wissenschaftlichen MitarbeiterInnen und Hochschullehrenden (z. B. ProfessorInnen), die an einer Hochschule oder Forschungseinrichtung beschäftigt und in den für <i>adlr.link</i> relevanten Fächern tätig sind, alle Mitglieder der einschlägigen Fachgesellschaften, DoktorandInnen, StipendiatInnen sowie externe WissenschaftlerInnen, bei denen kein Beschäftigungsverhältnis an einer Hochschule oder Forschungseinrichtung besteht. Nutzergruppe II umfasst Studierende und sonstige Nutzer. Ãœber den Authentifizierungsdienst Shibboleth kann <i>adlr.link</i> Ihre Zugehörigkeit zu Ihrer Einrichtung und zu der angegebenen Nutzergruppe prüfen, sofern dieser Dienst von Ihrer Einrichtung angeboten wird. Die endgültige Entscheidung, welcher Nutzergruppe Sie zugeordnet werden, obliegt <i>adlr.link</i>.</li> +<li>Die Registrierung ist nicht auf Personen in den Kommunikations-, Medien- und Filmwissenschaften beschränkt. Auch interdisziplinär arbeitende WissenschaftlerInnen können sich bei <i>adlr.link</i> registrieren, wenn sie zu Themen der Kommunikations-, Medien- oder Filmwissenschaft forschen.</li> +<li>Mit dem Abschluss der Registrierung verpflichten Sie sich, die angebotenen Dienstleistungen nicht missbräuchlich zu nutzen (z.B. Beschaffungsaufträge oder Bestellungen, die über das normale Maß hinausgehen) und alle lizenz- und urheberrechtlichen Bedingungen zu beachten (z.B. bei der Vervielfältigung oder Weitergabe von urheberrechtlich geschützten Werken, insbesondere auch bei frei verfügbaren Internetressourcen und/oder Open Access-Dokumenten).</li> +<li>Durch <i>adlr.link</i> bereitgestellte E-Books und z.B. über den Dokumentenlieferdienst per Mail oder Ausdruck für Sie bereitgestellte Zeitschriftenartikel sowie Inhalte aus speziell für <i>adlr.link</i>-NutzerInnen lizenzierten Quellen (z.B. Datenbanken) dürfen nur für den eigenen Gebrauch abgerufen werden. Eine Vervielfältigung (insbesondere durch Speicherung in andere Netze oder Datenbanken) ist nicht zulässig.</li> +<li>Bei der Nutzung von Daten aus für <i>adlr.link</i> lizenzierten Datenbanken versichern Sie, die Daten ausschließlich im Rahmen Ihrer Forschung zu verwenden und nicht an Dritte weiterzugeben sowie die Daten nur für nicht-kommerzielle Zwecke zu verwerten. Es ist nicht gestattet, Daten aus Datenbanken mittels Bots (oder ähnlicher technischer Hilfsmittel) automatisiert abzurufen.</li> +<li>Bei der Beschaffung von gedruckten Publikationen über die nutzergesteuerte Erwerbung (Print PDA) wird Ihnen das gewünschte Medium direkt vom Lieferanten als Leihexemplar zur Verfügung gestellt. Sie sind verpflichtet, das Medium innerhalb der Leihfrist auf Ihre Kosten der Universitätsbibliothek Leipzig zurückzusenden, in jedem Fall jedoch spätestens mit dem Ablauf Ihres Nutzerkontos. Leihexemplare sind sorgfältig zu behandeln und vor Beschädigung zu schützen. Als Beschädigungen gelten auch Eintragungen jeder Art, wie Anstreichungen und Berichtigungen von Fehlern, sowie Knicken von Blättern, Tafeln und Karten. Aus den Werken dürfen keine Teile entfernt werden. Für abhanden gekommene oder beschädigte Werke hat der Nutzer Ersatz zu leisten.</li> +<li><i>adlr.link</i> behält sich das Recht vor, einzelne oder alle Dienstleistungen nur für bestimmte Nutzergruppen anzubieten oder jederzeit ohne gesonderte Ankündigung einzustellen. <i>adlr.link</i> behält sich außerdem das Recht vor, Nutzerkonten bei wiederholter oder andauernder missbräuchlicher Nutzung vorübergehend oder ständig zu sperren.</li> +<li>Diese Nutzungsbedingungen und die Datenschutzerklärung können jederzeit durch <i>adlr.link</i> geändert werden. <i>adlr.link</i> wird registrierten NutzerInnen die Änderungen rechtzeitig ankündigen.</li> +</ol> +Stand: 1. Februar 2017 +<br /> +<br /> +</div> \ No newline at end of file diff --git a/themes/fid/templates/fid/user/terms-en.phtml b/themes/fid/templates/fid/user/terms-en.phtml new file mode 100644 index 0000000000000000000000000000000000000000..ad8f39a759b4e1da4a6d046f8c8f1b52f296b32f --- /dev/null +++ b/themes/fid/templates/fid/user/terms-en.phtml @@ -0,0 +1,22 @@ +<div class="adlr-policies"> +<br /> +<p><i>adlr.link</i> is operated by Leipzig University Library and funded by the Deutsche Forschungsgemeinschaft (DFG).</p> +<p>According to DFG funding guidelines, the service is primarily aimed at academics in the communication, media and film studies as well as related fields of study in Germany for immediate and direct access to specific literature and research-relevant information.</p> +<p>By using the services of <i>adlr.link</i>, you agree to our terms of use and privacy policy. Please note: The English version of our terms of use is for informational purposes only. The German version shall be legally binding only.</p> +<h2><strong>Terms of Use</strong></h2> +<ol> +<li>No prior registration is required for using <i>adlr.link</i>. However, in order to be able to use all adlr.link services, you have to sign up for an account. Account registration and use of the services are free of charge.</li> +<li>You have to provide certain personal details when signing up for an account. Our privacy policy apply. You are obliged to keep your account details up-to-date at all times. A user account is assigned to a single person. You must not reveal user name and password to other people. Any unauthorized use of an account will cause a temporary or permanent blocking of your account.</li> +<li>You have to choose a membership level when signing up for an account. There are two membership levels: Level I includes all scientific staff members and university lecturers (e.g. professors) who work at a university or research institution, all members of the relevant specialist associations, doctoral students , scholarship holders as well as external academics (with no formal employment at a university or research institution). Level II includes students and other users. <i>adlr.link</i> may re-check your affiliation with your organization and to the specified membership level by using Shibboleth single-sign-on service when applicable. <i>adlr.link</i> may re-assign you to another membership level at our sole discretion.</li> +<li>Registration is not restricted to academics in the field of communication, media and film studies. Interdisciplinary-based researchers may also sign up with <i>adlr.link</i> when conducting research within the respective field of study.</li> +<li>By signing up with <i>adlr.link</i> you agree not to misuse the services offered (e.g. orders that go beyond normal scope) and to respect all copyrights.</li> +<li>E-books provided by <i>adlr.link</i> and other documents delivered to you by <i>adlr.link</i> (either electronically or physically) are for your own personal use only. Any duplication or copying is not permitted.</li> +<li>When obtaining data from databases licensed by <i>adlr.link</i>, you assure that you use the data only within the framework of your research and you agree not to forward any data to third parties. You may use data for non-commercial purposes only. It is not permitted to retrieve data from databases using automated bots (or similar tools).</li> +<li>When purchasing printed publications via patron driven acquisition (Print PDA), the bookseller will send you the media as a loan copy. You are obliged to return the media at your own expense to Leipzig University Library within the loan period, but in any case when your account has been expired. Loan copies must be handled carefully. Any markings and corrections of errors as well as dog-ears are not allowed. No parts may be removed from the works. You may be held responsible to make a replacement for lost or damaged works.</li> +<li><i>adlr.link</i> reserves the right to restrict some or all services for certain membership levels or to cease operation for some or all services without notice at any time. <i>adlr.link</i> also reserves the right to temporarily or permanently disable user accounts in case of repeated or persistent abusive use.</li> +<li><i>adlr.link</i> may change these terms of use and our privacy policy may be changed at any time. <i>adlr.link</i> will announce changes to registered users in a timely manner.</li> +</ol> +Last changed: 1 February 2017 +<br /> +<br /> +</div> \ No newline at end of file diff --git a/themes/fid/templates/fid/user/terms.phtml b/themes/fid/templates/fid/user/terms.phtml new file mode 100644 index 0000000000000000000000000000000000000000..c51cba2bee239b06e6f8ce473e3c917d2e3464f5 --- /dev/null +++ b/themes/fid/templates/fid/user/terms.phtml @@ -0,0 +1,9 @@ +<!-- fid - terms begin --> +<? $lang = $this->layout()->userLang; ?> +<? $fileExists = file_exists(dirname(__FILE__) . '/terms-'.$lang.'.phtml'); ?> +<? if ($fileExists): ?> + <?=$this->render('fid/user/terms-'.$lang.'.phtml')?> +<? else: ?> + <?=$this->render('fid/user/terms-en.phtml')?> +<? endif; ?> +<!-- fid - terms end --> diff --git a/themes/fid/templates/fid/user/update.phtml b/themes/fid/templates/fid/user/update.phtml new file mode 100644 index 0000000000000000000000000000000000000000..95e3c1c37130fa4b558dd37dbe01da43c6e003b9 --- /dev/null +++ b/themes/fid/templates/fid/user/update.phtml @@ -0,0 +1,197 @@ +<?php +/** + * Copyright (C) 2019 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 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. + * + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ + +use fid\Service\DataTransferObject\User; +use Zend\Form\Element as Element; +use Zend\Form\Element\Submit; +use Zend\Form\Form; +use Zend\Form\View\Helper\FormElementErrors; +use Zend\Form\View\Helper\FormLabel; +use Zend\Form\View\Helper\FormRadio; +use Zend\Form\View\Helper\FormSelect; +use Zend\Form\View\Helper\FormSubmit; +use Zend\I18n\Translator\TranslatorInterface; + +/** @var FormLabel $formLabel */ +$formLabel = $this->formLabel(); +/**@var FormRadio $formRadio */ +$formRadio = $this->formRadio(); +/**@var FormSelect $formSelect */ +$formSelect = $this->formSelect(); +/**@var FormSubmit $formSubmit */ +$formSubmit = $this->formSubmit(); +/** @var FormElementErrors $formElementErrors */ +$formElementErrors = $this->formElementErrors(); +$formLabel->setTranslatorTextDomain('fid'); +$formSelect->setTranslatorTextDomain('fid'); +$formRadio->setTranslatorTextDomain('fid'); +$formSubmit->setTranslatorTextDomain('fid'); +$formElementErrors->setTranslatorTextDomain('fid'); +/** @var TranslatorInterface $translator */ +$translator = $this->getHelperPluginManager()->get('translate') + ->getTranslator(); + +$formLabel->setTranslator($translator); +$formElementErrors->setTranslator($translator); + +/** @var Form $form */ +/** @var User $user */ +$user = $this->user; +$form = $this->form; +$form->setAttribute('method', 'post'); +$form->setAttribute('action', $this->url('fid/user/update')); +$form->setAttribute('class', 'form-horizontal'); +$form->prepare(); + +$this->headTitle($this->translate('Profile Form')); +$this->headTitle($this->translate("fid::user_update_form_title")); +?> + +<h2><?= $this->translate("fid::user_update_form_title") ?></h2> +<?= $this->flashmessages() ?> +<?= $this->form()->openTag($form) ?> +<br/> + +<? /* home library */ ?> +<?php +/** @var Element\Select $elemHomeLibrary */ +$elemHomeLibrary = $form->get('homeLibrary'); +$elemHomeLibrary->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemHomeLibrary->setAttributes(['class' => 'inline col-sm-6']); +$elemHomeLibrary->setValueOptions($this->libraries); +$elemHomeLibrary->setValue($user->getHomeLibrary()); +?> +<div class="form-group"> + <?= $this->formLabel($elemHomeLibrary) ?> + <?= $this->formSelect($elemHomeLibrary) ?> + <?= $this->formElementErrors($elemHomeLibrary) ?> +</div> + +<? /* salutation */ ?> +<?php +/** @var Element\Select $elemSalutation */ +$elemSalutation = $form->get('salutation'); +$elemSalutation->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemSalutation->setAttributes(['class' => 'inline col-sm-2']); +$elemSalutation->setValue($user->getSalutation()); +?> +<div class="form-group"> + <?= $this->formLabel($elemSalutation) ?> + <?= $this->formSelect($elemSalutation) ?> + +</div> + +<? /* academic title */ ?> +<?php +/** @var Element\Text $elemAcademicTitle */ +$elemAcademicTitle = $form->get('academicTitle'); +$elemAcademicTitle->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemAcademicTitle->setAttributes(['class' => 'form-control']); +$elemAcademicTitle->setValue($user->getAcademicTitle()); +?> +<div class="form-group"> + <?= $this->formLabel($elemAcademicTitle) ?> + <?= $this->formElement($elemAcademicTitle) ?> +</div> + +<? /* firstname */ ?> +<?php +/** @var Element\Text $elemFirstname */ +$elemFirstname = $form->get('firstname'); +$elemFirstname->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemFirstname->setAttributes(['class' => 'form-control']); +$elemFirstname->setValue($user->getFirstname()); +?> +<div class="form-group"> + <?= $this->formLabel($elemFirstname) ?> + <?= $this->formElement($elemFirstname) ?> + <?= $this->formElementErrors($elemFirstname) ?> +</div> + +<? /* lastname */ ?> +<?php +/** @var Element\Text $elemLastname */ +$elemLastname = $form->get('lastname'); +$elemLastname->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemLastname->setAttributes(['class' => 'form-control']); +$elemLastname->setValue($user->getLastname()); +?> +<div class="form-group"> + <?= $this->formLabel($elemLastname) ?> + <?= $this->formElement($elemLastname) ?> + <?= $this->formElementErrors($elemLastname) ?> +</div> + +<? /* year of birth */ ?> +<?php +/** @var Element\Text $elemYearOfBirth */ +$elemYearOfBirth = $form->get('yearOfBirth'); +$elemYearOfBirth->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemYearOfBirth->setAttributes(['class' => 'form-control']); +$elemYearOfBirth->setValue($user->getYearOfBirth()); +?> +<div class="form-group"> + <?= $this->formLabel($elemYearOfBirth) ?> + <?= $this->formElement($elemYearOfBirth) ?> + <?= $this->formElementErrors($elemYearOfBirth) ?> +</div> + +<? /* college */ ?> +<?php +/** @var Element\Text $elemCollege */ +$elemCollege = $form->get('college'); +$elemCollege->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemCollege->setAttributes(['class' => 'form-control']); +?> +<div class="form-group"> + <?= $this->formLabel($elemCollege) ?> + <?= $this->formElement($elemCollege) ?> + <?= $this->formElementErrors($elemCollege) ?> +</div> + +<? /* job title */ ?> +<?php +/** @var Element\Text $elemJobTitle */ +$elemJobTitle = $form->get('jobTitle'); +$elemJobTitle->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']); +$elemJobTitle->setAttributes(['class' => 'form-control']); +$elemJobTitle->setValue($user->getJobTitle()); +?> +<div class="form-group"> + <?= $this->formLabel($elemJobTitle) ?> + <?= $this->formElement($elemJobTitle) ?> + <?= $this->formElementErrors($elemJobTitle) ?> +</div> + +<? /* submit button */ ?> +<?php +/** @var Submit $elemSubmit */ +$elemSubmit = $form->get('submit'); +$elemSubmit->setAttributes(['class' => 'btn btn-primary right']); +?> +<div class="form-group"> + <div class="col-lg-11 col-md-9 col-sm-11 col-xs-12"> + <?= $this->formSubmit($elemSubmit) ?> + </div> +</div> + +<?= $this->form()->closeTag($form) ?> \ No newline at end of file diff --git a/themes/fid/templates/myresearch/profile.phtml b/themes/fid/templates/myresearch/profile.phtml new file mode 100644 index 0000000000000000000000000000000000000000..23a563176f250ea6d5eb7e388fe4089b3a036762 --- /dev/null +++ b/themes/fid/templates/myresearch/profile.phtml @@ -0,0 +1,94 @@ +<!-- finc: myresearch - profile --> +<?php +// Set up page title: +$this->headTitle($this->translate('My Profile')); + +// Set up breadcrumbs: +$this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('Profile') . '</li>'; + +// Template for use by the renderArray helper: +$arrTemplate = '<tr><th>%%LABEL%%:</th><td> %%VALUE%%</td></tr>'; +?> + +<div class="<?=$this->layoutClass('mainbody')?>"> + <h2><?=$this->transEsc('Your Profile')?></h2> + <?=$this->flashmessages();?> + + <table class="table table-striped"> + <?=$this->renderArray( + $arrTemplate, $this->user, + [ + $this->transEsc('First Name') => 'firstname', + $this->transEsc('Last Name') => 'lastname', + // finc: show e-mail in table below + // $this->transEsc('Email') => 'email', + ] + )?> + <?php if (count($this->pickup ?? []) > 1): // Skip form if only one location: ?> + <tr><th><?=$this->transEsc('Preferred Library')?>:</th> + <?php + $selected = (strlen($this->profile['home_library'] ?? '') > 0) + ? $this->profile['home_library'] : $this->defaultPickupLocation + ?> + <td> + <form id="profile_form" class="form-inline" method="post"> + <select id="home_library" name="home_library" class="form-control"> + <?php foreach ($this->pickup as $lib): ?> + <option + value="<?=$this->escapeHtmlAttr($lib['locationID'])?>"<?=($selected == $lib['locationID']) ? ' selected="selected"' : ''?>><?=$this->transEsc('location_' . $lib['locationDisplay'], null, $lib['locationDisplay'])?></option> + <?php endforeach; ?> + </select> + <input class="btn btn-default" type="submit" value="<?=$this->transEsc('Save')?>"/> + </form> + </td> + <?php endif; ?> + </table> + + <div id="account-actions"> + <?php if ($this->auth()->getManager()->supportsPasswordChange()): ?> + <a class="btn btn-default" href="<?=$this->url('myresearch-changepassword') ?>"> + <i class="fa fa-fw fa-lock" aria-hidden="true"></i> <?=$this->transEsc('Change Password') ?> + </a> + <?php endif; ?> + + <?php if ($this->accountDeletion): ?> + <a class="btn btn-default" href="<?=$this->url('myresearch-deleteaccount') ?>" data-lightbox> + <i class="fa fa-times"></i> <?=$this->transEsc('delete_account_title') ?> + </a> + <?php endif; ?> + </div> + + <?php if (is_array($this->profile)): ?> + <h3><?=$this->transEsc('Library Catalog Profile')?></h3> + <p> + <?=$this->context($this)->renderInContext('librarycards/selectcard.phtml', ['user' => $this->user]); ?> + </p> + <table class="table table-striped"> + <?=$this->renderArray( + $arrTemplate, $this->profile, + [ + $this->transEsc('First Name') => 'firstname', + $this->transEsc('Last Name') => 'lastname', + $this->transEsc('Address') . ' 1' => 'address1', + $this->transEsc('Address') . ' 2' => 'address2', + $this->transEsc('Zip') => 'zip', + $this->transEsc('City') => 'city', + $this->transEsc('Country') => 'country', + // finc: show e-mail here + $this->transEsc('Email') => 'email', + $this->transEsc('Phone Number') => 'phone', + $this->transEsc('Mobile Number') => 'mobile_phone', + $this->transEsc('Group') => 'group', + $this->transEsc('Expires') => 'expiration_date' + ] + )?> + </table> + <?php elseif ('ils-none' !== $this->ils()->getOfflineMode() && $this->patronLoginView && !empty($this->patronLoginView->getTemplate())): ?> + <?=$this->partial($this->patronLoginView);?> + <?php endif; ?> +</div> + +<div class="<?=$this->layoutClass('sidebar')?>"> + <?=$this->context($this)->renderInContext("myresearch/menu.phtml", ['active' => 'profile'])?> +</div> +<!-- finc: myresearch - profile - END --> diff --git a/themes/finc-fid/theme.config.php b/themes/fid/theme.config.php similarity index 91% rename from themes/finc-fid/theme.config.php rename to themes/fid/theme.config.php index 34952145d067dfd81ea5eb8b1622249d7b038716..2cd775bdcd442540fc1eb8808fdadca1fbe2a419 100644 --- a/themes/finc-fid/theme.config.php +++ b/themes/fid/theme.config.php @@ -21,8 +21,4 @@ return [ 'extends' => 'finc', - 'mixins' => [ - 'finc-fid-core', - 'finc-fid-registration' - ], ]; \ No newline at end of file