diff --git a/devops/i18n-merge.sh b/devops/i18n-merge.sh new file mode 100755 index 0000000000000000000000000000000000000000..2dafe51188842c1a773d98377d6ae3500002850c --- /dev/null +++ b/devops/i18n-merge.sh @@ -0,0 +1,153 @@ +#!/usr/bin/env bash +# Copyright (C) 2021 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 Robert Lange <lange@ub.uni-leipzig.de> +# @license https://opensource.org/licenses/GPL-3.0 GNU GPLv3 + +# this script merges token files and removes unused / duplicate tokens with parent and target translation file *.ini +# assumes You are in projects base dir + +CACHE_FILE=$1; INSTANCE_FILE=$2; PARENT_FILE=$3; + +HAS_ERROR=0; +if [ -z "$CACHE_FILE" ] || [ -z "$INSTANCE_FILE" ]; then + SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" + HAS_ERROR=1 + echo "Usage: $0 path/to/language/with/new/tokens path/to/language/file/of/instance [path/to/parent/file/of/instance]" + echo "example command 1: \"devops/i18n-merge.sh data/i18n/languages/de.ini de_zi4/languages/de.ini local/languages/de.ini\""; +else + if [ ! -f "$CACHE_FILE" ] + then + echo "Language File "$CACHE_FILE" does not exist on your filesystem."; HAS_ERROR=1; + fi + + if [ ! -f "$INSTANCE_FILE" ] + then + echo "Language File "$INSTANCE_FILE" does not exist on your filesystem."; HAS_ERROR=1; + fi +fi + +if [ -z "$CACHE_FILE" ]; then + if [ ! -f "$PARENT_FILE" ]; then + echo "Parent Language File "$PARENT_FILE" does not exist on your filesystem."; + HAS_ERROR=1; + fi +fi + +if [ $HAS_ERROR = 1 ] +then + #echo "exit 1: aborting" + exit 1; +fi + +echo "Read new tokens from $CACHE_FILE." +declare -A newTokens +declare -a newTokensOrder +while IFS= read -r line || [ -n "$line" ] # handle possible missing newline in last line +do + key=$(echo "$line" | awk -F: '{ st = index($0,"=");print substr($0,0,st-1)}') + value=$(echo "$line" | awk -F: '{ st = index($0,"=");print substr($0,st+1)}') + newTokens["$key"]="$value" + newTokensOrder+=("$key"); +done < $CACHE_FILE + +echo "Reading and minify existing tokens from $INSTANCE_FILE" +declare -A instanceTokens +declare -A instanceComments +declare -a instanceTokensOrder +i=0 +while IFS= read -r line || [ -n "$line" ]; # handle possible missing newline in last line +do + if [ -z "$line" ]; then + #echo "empty" + instanceTokensOrder+=("X_empty_X"); + elif [[ ${line:0:1} == "#" ]] || [[ ${line:0:1} == ";" ]]; then + #echo "comment" + instanceTokensOrder+=("X_comment_$i") + instanceComments["X_comment_$i"]="$line" + elif [[ ${line:0:11} == "@parent_ini" ]]; then + #echo "relative path to parent ini" + instanceTokensOrder+=("X_comment_$i") + instanceComments["X_comment_$i"]="$line" + #PARENT_FILE=$(echo "$line" | awk -F: '{ st = index($0,"=");print substr($0,st+3)} ' | sed 's/.$//') + #PARENT_FILE=$(echo "${PARENT_FILE#@(.)}") + #PARENT_FILE="${INSTANCE_FILE}/${PARENT_FILE}" + #echo "$PARENT_FILE" + else + key=$(echo "$line" | awk -F: '{ st = index($0,"=");print substr($0,0,st-1)}') + value=$(echo "$line" | awk -F: '{ st = index($0,"=");print substr($0,st+1)}') + #echo "$line" + # only add to instanceTokensOrder when key entry is NOT already existing -> remove duplicates / ignored by letting latest entry win + if [[ -n "${instanceTokens["$key"]}" ]]; then + echo "* remove duplicate token \"${key}\" with obsolete value ${instanceTokens["$key"]} by $value." + else + instanceTokensOrder+=("$key"); + fi + instanceTokens["$key"]="$value"; + fi + ((i=i+1)) +done < $INSTANCE_FILE + +if [ -f "$PARENT_FILE" ]; then + echo "Reading and minifying existing tokens from $PARENT_FILE..." + declare -A parentTokens + declare -a parentTokensOrder + while IFS= read -r line || [ -n "$line" ] + do + if [ -z "$line" ] || [[ ${line:0:1} == "#" ]] || [[ ${line:0:1} == ";" ]] || [[ ${line:0:11} == "@parent_ini" ]]; then + continue + else + key=$(echo "$line" | awk -F: '{ st = index($0,"=");print substr($0,0,st-1)}') + value=$(echo "$line" | awk -F: '{ st = index($0,"=");print substr($0,st+1)}') + #echo "$line" + # only add to instanceTokensOrder when key entry is NOT already existing -> remove duplicates / ignored by letting latest entry win + if [[ ${instanceTokens["$key"]} == "$value" ]] ; then + #instanceTokens["$key"]="$value"; + echo "* remove duplicate token \"${key}\" and $value with parent file." + instanceTokens["$key"]="X_duplicate_X"; + fi + fi + done < $PARENT_FILE +fi + +echo "Adding new token translations..." +for i in "${!newTokensOrder[@]}" +do + if [[ -n "${instanceTokens[${newTokensOrder[$i]}]}" ]]; then + echo "* replace token \"${newTokensOrder[$i]}\" with old value ${instanceTokens[${newTokensOrder[$i]}]} by new value $value" + else + instanceTokensOrder+=("${newTokensOrder[$i]}"); + echo "* add new token \"${newTokensOrder[$i]}\" with value ${newTokens[${newTokensOrder[$i]}]}" + fi + instanceTokens["${newTokensOrder[$i]}"]="${newTokens[${newTokensOrder[$i]}]}"; +done + +echo "4) Writing merged translations to instance file..." +true > "${INSTANCE_FILE}" +for i in "${!instanceTokensOrder[@]}" +do + key="${instanceTokensOrder[$i]}" + if [[ "$key" == "X_empty_X" ]]; then + #echo "empty" + echo -en '\n' >> "${INSTANCE_FILE}" + elif [[ ${key:0:10} == "X_comment_" ]]; then + #echo "comment" + echo "${instanceComments[${key}]}" >> "${INSTANCE_FILE}" + elif [[ "${instanceTokens[${key}]}" != "X_duplicate_X" ]]; then + #echo "$key" + echo "${key}=${instanceTokens[${key}]}" >> "${INSTANCE_FILE}" + fi +done diff --git a/local/languages/de.ini b/local/languages/de.ini index 654d7be086de4d27bf9376af9f0a928533a9cb92..7092464c25bf1bf088c68424ebe6c66823c75944 100644 --- a/local/languages/de.ini +++ b/local/languages/de.ini @@ -87,7 +87,7 @@ TactileText = "taktiler Text" Collage = Collage Drawing = Zeichnung Painting = Gemälde -Print = Druck +Print = "Drucken" Photonegative = Photonegativ FlashCard = "Flash Card" Chart = "Tabelle / Grafik" @@ -270,7 +270,7 @@ Electronic Resource (Remote Access) = "Elektronische Ressource im Fernzugriff" Electronic Resources = Online-Ressourcen Electronic Serial = "Elektronische Zeitschrift" Electronic Thesis = "Elektronische Hochschulschrift" -Email = "E-Mail" +Email = "Mailen" Email Address = "E-Mail-Adresse" Email Record = "E-Mail-Eintrag" Email address is invalid = "Die E-Mail-Adresse ist ungültig" @@ -646,7 +646,7 @@ banner_link = "kommentieren Sie im Blog!" bookbag_confirm_empty = "Wollen Sie ihre Zwischenablage wirklich leeren?" bookbag_delete_selected = "Löschen" bookbag_delete = "Markiertes aus Zwischenablage löschen" -bookbag_email_selected = "E-Mail" +bookbag_email_selected = "Links zu ausgewählten Medien per E-Mail versenden" bookbag_email = "Markiertes per E-Mail versenden" bookbag_export_selected = "Export" bookbag_export = "Markiertes exportieren" @@ -715,7 +715,7 @@ errorcode_opac_error = "Es ist ein Fehler im Lokalsystem aufgetreten" errorcode_login_error = "Die Anmeldung des Benutzers am Lokalsystem ist gescheitert" errorcode_empty_member_code = "Es wurde keine Benutzernummer übergeben" errorcode_empty_password = "Es wurde kein Passwort übergeben" -errorcode_member_not_found = "Die Benutzernummer exisitiert nicht" +errorcode_member_not_found = "Die Benutzernummer existiert nicht" errorcode_password_validation_error = "Das übergebene Password ist nicht korrekt" errorcode_old_password_validation_error = "Die Kombination aus Benutzernummer und Kennwort ist nicht gültig. Bitte überprüfen Sie Ihre Eingabe." errorcode_empty_req_param_error = "Um das Formular erfolgreich zu senden, müssen alle erforderlichen Felder ausgefüllt sein" @@ -1989,7 +1989,7 @@ ReliefPrint = Druckgraphik ; Accessibility Modal_description = "Sie befinden sich in einem Dialogfenster, das über dem Hauptinhalt der Seiten liegt. Drücken Sie die Escape-Taste oder die Schaltfläche 'Dialogfenster schließen', um das Fenster zu schließen und auf der Hauptseite weiterzuarbeiten." -Skip_navigation_links = "Sprunglinks zum Inhalt" +Skip_navigation_links = "Sprunglinks zur Suche und zum Inhalt" Skip to search = "Zum Suchbereich" Skip to content = "Zum Inhalt" Skip to facet = "Zu ihrem ausgewählten Suchfilter "%%filter_name%%" springen" @@ -2056,15 +2056,6 @@ form-button-submit = "Ausgefülltes Formular abschicken" ; #17601 offcanvas-toggler-search-tips = "Suchtipps einblenden" -; #17993 -; only for German translation -Email = "Mailen" -Print = "Drucken" -bookbag_email_selected = "Links zu ausgewählten Medien per E-Mail versenden" - -; #18441 -Skip_navigation_links = "Sprunglinks zur Suche und zum Inhalt" - ; #18019 & #18754 select_item = "Titel wählen" select_item_search_result = "Titel zum Mailen, Exportieren, Drucken, Speichern oder Merken auswählen" diff --git a/local/languages/en.ini b/local/languages/en.ini index b8214638d2844e780925629d63b8b94b7c3793a0..72aea8c0e2167bd354421b1297e8f7d74bb709b7 100644 --- a/local/languages/en.ini +++ b/local/languages/en.ini @@ -151,7 +151,6 @@ Article, E-Article = Article, E-Article Audio = Audio Book, E-Book = Book, E-Book Card = Card -DBIS = DBIS Journal, E-Journal = Journal, E-Journal Map = Map Notated Music = Notated Music @@ -2139,7 +2138,6 @@ form-button-submit = "Submit the completed form" offcanvas-toggler-search-tips = "Show search help" ; #18441 -Skip_navigation_links = "Skip navigation links" ; #18019 & #18754 select_item = "Select item" diff --git a/module/fid/config/fid-acquisition-digitization-form.php b/module/fid/config/fid-acquisition-digitization-form.php index 2519d1199754a41d335bd4e8542a8807d63fda35..6000bfef364916f6655fa7bdd21f1773dd364b91 100644 --- a/module/fid/config/fid-acquisition-digitization-form.php +++ b/module/fid/config/fid-acquisition-digitization-form.php @@ -24,11 +24,39 @@ use Zend\Form\Element\Select; use Zend\Form\Element\Submit; use Zend\Form\Element\Textarea; use Zend\Validator\StringLength; +use Zend\Form\Element\Url; return [ 'name' => 'fid-acquisition-form', 'hydrator' => OrderHydrator::class, 'elements' => [ + 'library' => [ + 'spec' => [ + 'name' => 'library', + 'type' => Text::class, + 'options' => [ + 'label' => 'acquisition_label_library', + ], + ], + ], + 'signature' => [ + 'spec' => [ + 'name' => 'signature', + 'type' => Text::class, + 'options' => [ + 'label' => 'acquisition_label_signature', + ], + ], + ], + 'external_url' => [ + 'spec' => [ + 'name' => 'external_url', + 'type' => Url::class, + 'options' => [ + 'label' => 'acquisition_label_external_url', + ], + ], + ], 'format' => [ 'spec' => [ 'name' => 'format', @@ -71,6 +99,57 @@ return [ ], ], 'input_filter' => [ + 'library' => [ + 'name' => 'library', + 'required' => false, + 'filters' => [ + StringTrim::class => [ + 'name' => StringTrim::class, + ], + ], + 'validators' => [ + StringLength::class => [ + 'name' => StringLength::class, + 'options' => [ + 'max' => 1000 + ], + ], + ], + ], + 'signature' => [ + 'name' => 'signature', + 'required' => false, + 'filters' => [ + StringTrim::class => [ + 'name' => StringTrim::class, + ], + ], + 'validators' => [ + StringLength::class => [ + 'name' => StringLength::class, + 'options' => [ + 'max' => 1000 + ], + ], + ], + ], + 'external_url' => [ + 'name' => 'external_url', + 'required' => false, + 'filters' => [ + StringTrim::class => [ + 'name' => StringTrim::class, + ], + ], + 'validators' => [ + StringLength::class => [ + 'name' => StringLength::class, + 'options' => [ + 'max' => 1000 + ] + ], + ], + ], 'format' => [ 'name' => 'format', 'required' => true, diff --git a/module/fid/config/fid-acquisition-digitization-missing-record-form.php b/module/fid/config/fid-acquisition-digitization-missing-record-form.php new file mode 100644 index 0000000000000000000000000000000000000000..40b01e62a85337e60615635589a560f9fc28f34f --- /dev/null +++ b/module/fid/config/fid-acquisition-digitization-missing-record-form.php @@ -0,0 +1,149 @@ +<?php +/** + * Copyright (C) 2021 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 Alexander Purr <purr@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2 + */ +use fid\Hydrator\OrderMissingRecordHydrator; +use Zend\Filter\StringTrim; +use Zend\Form\Element\Text; +use Zend\Validator\StringLength; +use Zend\Validator\NotEmpty; + +$main_config = require 'fid-acquisition-digitization-form.php'; +unset($main_config['name'], $main_config['hydrator']); + +$additional_config = [ + 'name' => 'fid-acquisition-missing-record-form', + 'hydrator' => OrderMissingRecordHydrator::class, + 'elements' => [ + 'title' => [ + 'spec' => [ + 'name' => 'title', + 'type' => Text::class, + 'options' => [ + 'label' => 'acquisition_label_title', + ], + 'attributes' => [ + 'required' => 'required', + ], + ], + ], + 'responsible' => [ + 'spec' => [ + 'name' => 'responsible', + 'type' => Text::class, + 'options' => [ + 'label' => 'acquisition_label_responsible', + ], + ], + ], + 'year' => [ + 'spec' => [ + 'name' => 'year', + 'type' => Text::class, + 'options' => [ + 'label' => 'acquisition_label_year', + ], + ], + ], + 'language' => [ + 'spec' => [ + 'name' => 'language', + 'type' => Text::class, + 'options' => [ + 'label' => 'acquisition_label_language', + ], + ], + ], + 'input_filter' => [ + 'title' => [ + 'name' => 'title', + 'required' => true, + 'filters' => [ + StringTrim::class => [ + 'name' => StringTrim::class, + ], + ], + 'validators' => [ + NotEmpty::class => [ + 'name' => NotEmpty::class, + ], + StringLength::class => [ + 'name' => StringLength::class, + 'options' => [ + 'max' => 1000 + ], + ], + ], + ], + 'responsible' => [ + 'name' => 'responsible', + 'required' => false, + 'filters' => [ + StringTrim::class => [ + 'name' => StringTrim::class, + ], + ], + 'validators' => [ + StringLength::class => [ + 'name' => StringLength::class, + 'options' => [ + 'max' => 1000 + ], + ], + ], + ], + 'year' => [ + 'name' => 'year', + 'required' => false, + 'filters' => [ + StringTrim::class => [ + 'name' => StringTrim::class, + ], + ], + 'validators' => [ + StringLength::class => [ + 'name' => StringLength::class, + 'options' => [ + 'max' => 256 + ], + ], + ], + ], + 'language' => [ + 'name' => 'language', + 'required' => false, + 'filters' => [ + StringTrim::class => [ + 'name' => StringTrim::class, + ], + ], + 'validators' => [ + StringLength::class => [ + 'name' => StringLength::class, + 'options' => [ + 'max' => 256 + ], + ], + ], + ], + ], + ] +]; + +return array_merge_recursive($main_config, $additional_config); diff --git a/module/fid/config/module.config.php b/module/fid/config/module.config.php index bbddd14bde3704f6f28b3d15adfe0ab38af56726..74b728b9c8cd91cf378cf6c3b389dc022150af7a 100644 --- a/module/fid/config/module.config.php +++ b/module/fid/config/module.config.php @@ -30,6 +30,7 @@ use fid\Filter\PermissionsFilterFactory; use fid\FormModel\PasswordChangeModel; use fid\FormModel\PasswordResetModel; use fid\FormModel\UsernameChangeModel; +use fid\FormModel\UserDeleteModel; use fid\Helper\FormLabel; use fid\Helper\TranslatorDelegator; use fid\Hydrator\OrderHydrator; @@ -71,9 +72,11 @@ $config = [ 'fid-acquisition-form' => require 'fid-acquisition-form.php', 'fid-acquisition-subito-partial-copy-form' => require 'fid-acquisition-subito-partial-copy-form.php', 'fid-acquisition-digitization-form' => require 'fid-acquisition-digitization-form.php', + 'fid-acquisition-digitization-missing-record-form' => require 'fid-acquisition-digitization-missing-record-form.php', PasswordResetModel::class => require 'password-reset-form.php', PasswordChangeModel::class => require 'password-change-form.php', UsernameChangeModel::class => require 'username-change-form.php', + UserDeleteModel::class => require 'user-delete-form.php', ], 'filters' => [ 'factories' => [ @@ -84,6 +87,7 @@ $config = [ 'factories' => [ UserHydrator::class => InvokableFactory::class, OrderHydrator::class => InvokableFactory::class, + OrderMissingRecordHydrator::class => InvokableFactory::class, ], 'delegators' => [ UserHydrator::class => [ @@ -338,6 +342,16 @@ $config = [ ], ], ], + 'delete' => [ + 'type' => 'literal', + 'options' => [ + 'route' => '/delete', + 'defaults' => [ + 'controller' => UserController::class, + 'action' => 'delete', + ], + ], + ], ], ], 'admin' => [ @@ -424,6 +438,7 @@ $nonTabRecordActions = [ 'fidSubitoArticle', 'fidSubitoPartialCopy', 'fidDigitization', + 'fidDigitizationMissingRecord' ]; // Define record view routes -- route name => controller diff --git a/module/fid/config/user-delete-form.php b/module/fid/config/user-delete-form.php new file mode 100644 index 0000000000000000000000000000000000000000..c21ba9cd1cac4ac0a0d41a3a80a21568d8db7567 --- /dev/null +++ b/module/fid/config/user-delete-form.php @@ -0,0 +1,69 @@ +<?php +/** + * Copyright (C) 2021 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 + */ + use Zend\Filter\StringTrim; + use Zend\Form\Element\Password; + use Zend\Form\Element\Submit; + use Zend\Hydrator\ClassMethods; + use Zend\Validator\NotEmpty; + + return [ + 'hydrator' => ClassMethods::class, + 'elements' => [ + 'password' => [ + 'spec' => [ + 'name' => 'passwordConfirmation', + 'type' => Password::class, + 'options' => [ + 'label' => 'label_password', + ], + 'attributes' => [ + 'autocomplete' => 'current-password', + 'autofocus' => true, + 'title' => 'Password', + ], + ], + ], + 'submit' => [ + 'spec' => [ + 'name' => 'submit', + 'type' => Submit::class, + 'attributes' => [ + 'value' => 'label_submit', + ], + ], + ], + ], + 'input_filter' => [ + 'passwordConfirmation' => [ + 'name' => 'passwordConfirmation', + 'required' => true, + 'filters' => [ + StringTrim::class => [ + 'name' => StringTrim::class, + ], + ], + ], + 'submit' => [ + 'name' => 'submit', + 'required' => true, + ], + ], +]; diff --git a/module/fid/src/Controller/CustomTraits/FidAcquisitionTrait.php b/module/fid/src/Controller/CustomTraits/FidAcquisitionTrait.php index bc8fcd0b39a06a86f2fe925d91a06ed66f3f59b3..cd7fff820a0cbfb9beec148a608f9d2063831a67 100644 --- a/module/fid/src/Controller/CustomTraits/FidAcquisitionTrait.php +++ b/module/fid/src/Controller/CustomTraits/FidAcquisitionTrait.php @@ -33,6 +33,7 @@ use fid\Service\DataTransferObject\User; use fid\Validator\SubitoPartialCopyPageBounds; use fid\Validator\SubitoPartialCopyPageSelection; use finc\View\Helper\Root\Citation; +use VuFind\Controller\AbstractBase; use VuFind\Exception\Forbidden as ForbiddenException; use Zend\Form\Form; @@ -88,6 +89,13 @@ trait FidAcquisitionTrait return $this->runAcquisition(); } + public function fidDigitizationMissingRecordAction() + { + $this->type = self::DIGITIZATION; + $this->formConfig = ('fid-acquisition-digitization-missing-record-form'); + return $this->runDigitizationMissingRecord(); + } + protected function runAcquisition() { if (!($user = $this->getUser())) { @@ -172,7 +180,7 @@ trait FidAcquisitionTrait protected function getPermissionDeniedView() { - $view = $this->createViewModel(); + $view = AbstractBase::createViewModel(); $view->setVariables(['msg' => "fid::acquisition_permission_denied"]); $view->setTemplate('error/permissiondenied.phtml'); return $view; @@ -210,7 +218,14 @@ trait FidAcquisitionTrait $data += [ 'digitization' => [ 'format' => $form->getData()['format'], - 'comment' => $form->getData()['comment'] + 'comment' => $form->getData()['comment'], + 'library' => $form->getData()['library'], + 'signature' => $form->getData()['signature'], + 'external_url' => $form->getData()['external_url'], + 'title' => $form->getData()['title'] ?? '' , + 'responsible' => $form->getData()['responsible'] ?? '', + 'year' => $form->getData()['year']?? '', + 'language' => $form->getData()['language'] ?? '', ] ]; } @@ -220,4 +235,55 @@ trait FidAcquisitionTrait protected function handleOptionalErrorMessages($form) { } + + protected function runDigitizationMissingRecord() + { + if (!($user = $this->getUser())) { + return $this->forceLogin(); + } + + /** @var User $user */ + $user = $this->client->requestUserDetails(); + + try { + /* pass if permission is granted, else throw exception and switch to catch block */ + $this->permission()->check('fid.Acquisitions', 'exception'); + + /** @var Form $form */ + $form = $this->serviceLocator->get($this->formConfig); + + $this->addOptinalFormValidators($form); + + if ($this->formWasSubmitted()) { + $form->setData($this->getRequest()->getPost()); + if ($form->isValid()) { + $label = $form->getData()['title']; + $type = $this->type; + $hydratorData = compact('type', 'user', 'label'); + $hydratorData += $this->addTypeSpecificOrderInformation($form); + $form->getHydrator()->hydrate($hydratorData, $order = new Order()); + $this->client->requestOrderCreation($order); + $this->client->requestUserDetails(null, true); + $message = $this->translate('fid::acquisition_success'); + $messenger = $this->flashMessenger(); + $messenger->addSuccessMessage($message); + return $this->redirect()->toRoute('myresearch-home'); + } else { + $this->handleOptionalErrorMessages($form); + } + } + + $action = $this->url()->fromRoute("record-fiddigitizationmissingrecord", ['id' => 'none']); + $form->setAttribute('action', $action); + $form->prepare(); + + $view = AbstractBase::createViewModel(); + $view->setVariables(compact('form', 'user')); + $view->setTemplate("fid/record/acquisition-$this->type"); + } catch (ForbiddenException $ex) { + $view = $this->getPermissionDeniedView(); + } + + return $view; + } } diff --git a/module/fid/src/Controller/UserController.php b/module/fid/src/Controller/UserController.php index 99dc2db56ec1b7e2cd29da700314eeb03c9b7082..096fa3fa6ea61b32d68ff215eda737b90c8e0ed4 100644 --- a/module/fid/src/Controller/UserController.php +++ b/module/fid/src/Controller/UserController.php @@ -22,6 +22,7 @@ namespace fid\Controller; +use fid\FormModel\UserDeleteModel; use fid\FormModel\PasswordChangeModel; use fid\FormModel\PasswordResetModel; use fid\FormModel\UsernameChangeModel; @@ -426,6 +427,86 @@ class UserController extends AbstractBase return $this->redirect()->toRoute('myresearch-home'); } + /** + * @noinspection PhpUnused + * @return Response + */ + public function deleteAction() + { + if (!$this->getUser()) { + return $this->forceLogin(); + } + + /** @var User $user */ + $user = $this->client->requestUserDetails(null, true); + if ($user->getData()['deleted'] ?? false) { + $view = $this->createViewModel(); + $messages['html'] = true; + $messages['msg'] = $this->translate("fid::user_delete_error_account_blocked", [ + '%%fidname%%' => $this->translate("fid::acquisition_fid_name") + ]); + $this->flashMessenger()->addMessage($messages, 'error'); + $view->setTemplate('default/flash-message'); + return $view; + } + + /** @var Request $request */ + $request = $this->getRequest(); + /** @var Form $form */ + $form = $this->serviceLocator->get(UserDeleteModel::class); + $forwarded = $this->params()->fromRoute('forwarded', false); + + if ($submitted = $this->formWasSubmitted()) { + $form->setData($request->getPost()); + if (!$forwarded && $form->isValid()) { + return $this->deleteUser($form); + } + } + + $view = $this->createViewModel(); + $view->setVariables(compact('form')); + $view->setTemplate('fid/user/user-delete'); + + return $view; + } + + protected function deleteUser(Form $form) + { + $messenger = $this->getMessenger(); + /** @var UserDeleteModel $model */ + $model = $form->getHydrator()->hydrate($form->getData(), new UserDeleteModel()); + $error = []; + + try { + /** @var User $user */ + $user = $this->client->requestUserDetails(); + if ($this->client->checkCredentials($user->getUsername(), $model->getPasswordConfirmation())) { + $user->setDeleted(true); + $user->setDeletedAt(date('Y-m-d H:i:s', time())); + $user = $this->client->requestUserUpdate($user); + if (!$user->isDeleted()) { + $error['msg'] = $this->translate('fid::user_delete_error_unknown'); + } + } else { + $error['msg'] = $this->translate('fid::user_delete_error_wrong_password'); + } + } catch (ClientException $exception) { + $error['msg'] = $this->translate('fid::user_delete_error_unknown'); + } + + if(!empty($error)) { + $error['html'] = true; + $messenger->addErrorMessage($error); + return $this->redirect()->toRoute('fid/user/delete'); + } + + $this->client->logoff(); + $this->getAuthManager()->logout(""); + $view = $this->createViewModel(); + $view->setTemplate('myresearch/delete-success'); + return $view; + } + public function policyAction() { $viewModel = $this->createViewModel(); diff --git a/module/fid/src/FormModel/UserDeleteModel.php b/module/fid/src/FormModel/UserDeleteModel.php new file mode 100644 index 0000000000000000000000000000000000000000..8974fd938588674259152e5f9e1b1ad2b6df8261 --- /dev/null +++ b/module/fid/src/FormModel/UserDeleteModel.php @@ -0,0 +1,88 @@ +<?php +/** + * Copyright (C) 2020 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\FormModel; + +class UserDeleteModel +{ + /** + * @var string + */ + protected $id; + + /** + * @var string + */ + protected $passwordConfirmation; + + /** + * @var string + */ + protected $submit; + + /** + * @return string + */ + public function getPasswordConfirmation(): string + { + return $this->passwordConfirmation; + } + + /** + * @param string $password + */ + public function setPasswordConfirmation(string $password): void + { + $this->passwordConfirmation = $password; + } + + /** + * @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 getId(): string + { + return $this->id; + } + + /** + * @param string $id + */ + public function setId(string $id) + { + $this->id = $id; + } +} diff --git a/module/fid/src/Hydrator/OrderMissingRecordHydrator.php b/module/fid/src/Hydrator/OrderMissingRecordHydrator.php new file mode 100644 index 0000000000000000000000000000000000000000..87519536e79d6ce2f841389b2ba2a3a87c9169ce --- /dev/null +++ b/module/fid/src/Hydrator/OrderMissingRecordHydrator.php @@ -0,0 +1,34 @@ +<?php + +namespace fid\Hydrator; + +use fid\Service\DataTransferObject\Order; +use Zend\Hydrator\AbstractHydrator; + +class OrderMissingRecordHydrator extends AbstractHydrator { + + public function extract($object) + { + return; + // TODO: Implement extract() method. + } + + /** + * @param array $data + * @param Order|object $object + * @return Order|object|void + */ + public function hydrate(array $data, $object) + { + $object->setType($data['type']); + $object->setUser($data['user']); + + $digitization = array_key_exists('digitization', $data) ? $data['digitization'] : null; + $partialCopy = null; + $record = null; + + $object->setData(compact('record','partialCopy','digitization')); + $object->setLabel($data['label']); + return; + } +} \ No newline at end of file diff --git a/module/fid/src/Service/Client.php b/module/fid/src/Service/Client.php index 8d54127c89b38ad3be2eeb1e9ebd3956582317eb..531e760e3f96869f00cb708d3f68e14b0c67fdee 100644 --- a/module/fid/src/Service/Client.php +++ b/module/fid/src/Service/Client.php @@ -174,6 +174,27 @@ class Client } } + /** + * @param string $username + * @param string $password + * + * @return bool + */ + public function checkCredentials(string $username, string $password): bool + { + $body = json_encode(compact('username', 'password')); + $request = $this->buildRequest('post', 'logons', $body); + $response = $this->sendRequest($request); + + if ($response->getStatusCode() !== 201) { + return false; + } + + $logon = $this->parseLogon((string)$response->getBody()); + $this->storeLogon($logon); + return true; + } + /** * @throws ClientException */ diff --git a/module/fid/src/Service/DataTransferObject/User.php b/module/fid/src/Service/DataTransferObject/User.php index b2704cf9b31db72768096ea79f52f68098fee08d..7da55a719956b78bf8ff78e35c634d1d18a7c3c1 100644 --- a/module/fid/src/Service/DataTransferObject/User.php +++ b/module/fid/src/Service/DataTransferObject/User.php @@ -395,6 +395,34 @@ class User return $addresses[$addressIndex]; } + /** + * @return bool + */ + public function isDeleted(): bool + { + return ($this->data['deleted'] ?? false) === true; + } + + /** + * @return void + */ + public function setDeleted(bool $delete): void + { + if (empty($this->data)) { + $this->data = []; + } + $this->data['deleted'] = $delete; + } + + /** + * @param string $deletedAt + * @return void + */ + public function setDeletedAt(string $deletedAt): void + { + $this->data["deletedAt"] = $deletedAt; + } + /** * @return boolean */ diff --git a/module/fid/src/VuFind/Auth/Authenticator.php b/module/fid/src/VuFind/Auth/Authenticator.php index 5a2cd6130fe2f4dc329d9f1276fb76691a8e6756..bda67c1efad3cbebbd17eae04d4a2b431bc8134c 100644 --- a/module/fid/src/VuFind/Auth/Authenticator.php +++ b/module/fid/src/VuFind/Auth/Authenticator.php @@ -23,6 +23,7 @@ namespace fid\VuFind\Auth; use fid\Service\Client; use fid\Service\ClientException; +use fid\Service\DataTransferObject\User; use fid\VuFind\Db\Row\User as VuFindUser; use VuFind\Auth\AbstractBase; use VuFind\Db\Row\User as UserRow; @@ -40,6 +41,9 @@ class Authenticator extends AbstractBase protected const AUTH_ERROR_ACCOUNT_BLOCKED = 'fid::auth_error_account_blocked'; + protected const AUTH_ERROR_ACCOUNT_DELETED + = 'fid::auth_error_account_deleted'; + /** * @var Client */ @@ -92,6 +96,13 @@ class Authenticator extends AbstractBase throw new AuthException(self::AUTH_ERROR_ACCOUNT_BLOCKED); } + /** @var User $user */ + $user = $this->client->requestUserDetails(); + if ($user->isDeleted()) { + $this->client->logoff(); + throw new AuthException(self::AUTH_ERROR_ACCOUNT_DELETED); + } + if ($ownerId = $logon->getOwnerId()) { /** @var VuFindUser $userRow */ $userRow = $this->getUserTable()->getByUsername($ownerId); diff --git a/module/finc/src/finc/RecordTab/HierarchyTree.php b/module/finc/src/finc/RecordTab/HierarchyTree.php index cfc6a02c43cc86cde7eb86e3cc1a79e0bcab68a3..315b773894fe50aa0da87b36fdf6c63318eb1ae9 100644 --- a/module/finc/src/finc/RecordTab/HierarchyTree.php +++ b/module/finc/src/finc/RecordTab/HierarchyTree.php @@ -51,17 +51,20 @@ class HierarchyTree extends \VuFind\RecordTab\HierarchyTree else return 'hierarchy_tree'; } - /** - * {@inheritdoc} - * Returns different descriptions according to record type - * @return string - */ -/* public function isActive() + public function isActive() { - return ( - $this->getRecordDriver()->tryMethod('isSingleElementHierarchyRecord') - ? false : parent::isActive() - ); + $trees = $this->getTreeList(); + if (empty($trees)) { + return false; + } + foreach ($trees as $key => $value) { + if ($key !== $this->driver->getUniqueID()) { + return true; + } + } + if ($this->driver->getChildRecordCount() > 0) { + return true; + } + return false; } -*/ } diff --git a/themes/fid/languages/fid/de.ini b/themes/fid/languages/fid/de.ini index d5de9fd48920d13da0305d75ea0e78d4d9a66ed8..0a3fee6dac272d902870c7d7531427e88eedd530 100644 --- a/themes/fid/languages/fid/de.ini +++ b/themes/fid/languages/fid/de.ini @@ -1,6 +1,8 @@ auth_error_bad_credentials = Nutzername oder Passwort falsch. +auth_error_bad_password = Passwort falsch. auth_error_unknown_reason = Anmeldung derzeit nicht möglich. auth_error_account_blocked = Ihr Konto wurde aus Sicherheitsgründen gesperrt. Bitte kontaktieren Sie uns unter info@adlr.link, um eine Entsperrung vorzunehmen. +auth_error_account_deleted = Ihr Konto ist zur Löschung vorgemerkt und Ihre Daten werden beim nächsten Wartungslauf endgültig entfernt. user_init_form_title = "Registrierung" user_create_form_title = "Registrierung abschließen" @@ -105,6 +107,15 @@ username_update_error = "Es ist ein unerwarteter Fehler beim Aktualisieren Ihrer username_update_error_expired = "Ihr Verifikationslink ist bereits abgelaufen. Bitte starten Sie den Vorgang erneut." username_update_success = "Ihre E-Mail-Addresse wurde erfolgreich aktualisiert." +user_delete_link = "Konto löschen" +user_delete_info = "Sie können hier Ihr Konto zur Löschung anmelden. Wenn Sie fortfahren, wird der Zugang zu Ihrem Konto sofort gesperrt und das Konto beim nächsten Wartungslauf entfernt. +user_delete_hint = "Achtung! Sämtliche Daten in Ihrem Konto werden endgültig gelöscht und können nach der Löschung nicht wiedergestellt werden.<br /><br />Bitte geben Sie zur Bestätigung Ihr Passwort ein:" +user_delete_error_account_blocked = "Ihr Konto ist bereits gesperrt. Ihre Daten werden beim nächsten Wartungslauf endgültig entfernt. Vielen Dank für die Nutzung von %%fidname%%.<br /><br />Falls Sie zu einem späteren Zeitpunkt %%fidname%% wieder nutzen möchten, können Sie sich nach erfolgter Löschung jederzeit für ein neues Konto mit Ihrer E-Mail-Adresse registrieren." +user_delete_error_unknown = "Ein unerwarteter Fehler ist aufgetreten. Das Konto konnte nicht gesperrt werden." +user_delete_error_wrong_password = "Das angegebene Passwort ist falsch." +user_delete_success = "Ihr Konto ist nun gesperrt und Ihre Daten werden beim nächsten Wartungslauf endgültig entfernt. Vielen Dank für die Nutzung von %%fidname%%.<br /><br />Falls Sie zu einem späteren Zeitpunkt %%fidname%% wieder nutzen möchten, können Sie sich nach erfolgter Löschung jederzeit für ein neues Konto mit Ihrer E-Mail-Adresse registrieren." +user_delete_success_title = "Konto gesperrt und zur Löschung vorgemerkt." + Edit Account = "Profildaten ändern" @@ -117,6 +128,7 @@ read_user_list_not_allowed = "Sie haben keine Berechtigung die Nutzerliste einzu read_user_list_error = "Fehler beim Lesen der Nutzerliste" user_list_export = "CSV-Export" read_order_list_not_allowed = "Sie haben keine Berechtigung die Bestellliste einzusehen" +read_order_list_error = "Fehler beim Laden der Bestellliste" user_edit_form_title = "Nutzerdaten ändern für <em>%%username%%</em> (ID %%userid%%)" @@ -149,6 +161,13 @@ acquisition_label_pages = "Seitenzahlen (von-bis)" acquisition_label_comment = "Bemerkungen" acquisition_label_submit = "Bestellen" acquisition_label_format = "Format" +acquisition_label_title = "Titel" +acquisition_label_responsible = "Verantwortlich" +acquisition_label_year = "Jahr" +acquisition_label_language = "Sprache" +acquisition_label_library = "Besitzende Bibliothek in Deutschland" +acquisition_label_signature = "Signatur" +acquisition_label_external_url = "Link zu einem Katalogeintrag" acquisition_error_pages_too_short = "Ihre Eingabe hat zu wenige Zeichen. Bitte geben Sie mind. 3 Zeichen ein." acquisition_error_pages_too_long = "Ihre Eingabe hat zu viele Zeichen. Bitte geben Sie max. 13 Zeichen ein." acquisition_error_pages_pattern = "Falsches Format. Bitte geben Sie die gewünschten Seiten nur im Format VON-BIS ein, z. B. 23-30." @@ -158,8 +177,10 @@ acquisition_error_page_selection = "Der von Ihnen angegebene Seitenbereich über acquisition_subito_article_confirmation = "Möchten Sie den Artikel bestellen?" acquisition_subito_partial_copy_confirmation = "Möchten Sie die Teilkopie bestellen?" acquisition_pda_confirmation = "Möchten Sie das Buch bestellen?" -acquisition_pda_ordered = "Dieser Titel wurde bereits auf Nutzerwunsch durch adlr.link erworben und wird in Kürze verfügbar sein." +acquisition_pda_ordered = "Dieser Titel wurde bereits auf Nutzerwunsch durch %%fidname%% erworben und wird in Kürze verfügbar sein." acquisition_success = "Ihre Bestellung wurde entgegengenommen und wird nun von uns bearbeitet." acquisition_permission_denied = "Ihr Konto ist für Bestellungen zurzeit gesperrt." -number_of_pages = "Seiten" \ No newline at end of file +number_of_pages = "Seiten" + +FID_services = "FID Services" \ No newline at end of file diff --git a/themes/fid/languages/fid/en.ini b/themes/fid/languages/fid/en.ini index 473a3cd04ded671a639cffeb1d652c6914206b84..01cd367904a8b26b3886d97ca5cca59e5ed3696b 100644 --- a/themes/fid/languages/fid/en.ini +++ b/themes/fid/languages/fid/en.ini @@ -1,6 +1,8 @@ auth_error_bad_credentials = Invalid username or password. +auth_error_bad_password = Invalid password. auth_error_unknown_reason = Login currently impossible. auth_error_account_blocked = Your account has been disabled due to security reasons. Please contact us at info@adlr.link for more details. +auth_error_account_deleted = Your account is marked for deletion and your data will be permanently removed during the next maintenance run. user_init_form_title = "Registration" user_create_form_title = "Complete registration" @@ -104,6 +106,15 @@ username_update_error = "An unexpected error has occurred when updating your ema username_update_error_expired = "Your configmration link has already expired." username_update_success = "Your email address has successfully been updated." +user_delete_link = "Delete Account" +user_delete_info = "You can mark your account for deletion here. If you proceed, access to your account will be immediately blocked and the account will be removed during the next maintenance run." +user_delete_hint = " Attention. All data in your account will be permanently deleted and cannot be restored after deletion.<br /><br />Please enter your password to confirm:" +user_delete_error_account_blocked = "Your account is already disabled. Your data will be permanently removed during the next maintenance run. Thank you for using %%fidname%%.<br /><br />If you want to use %%fidname%% again at a later date, you can register for a new account with your email address at any time after it has been deleted." +user_delete_error_unknown = "An unexpected error occurred. Your account could not be disabled." +user_delete_error_wrong_password = "The password you typed is incorrect." +user_delete_success = "Your account is now disabled and your data will be permanently removed during the next maintenance run. Thank you for using %%fidname%%.<br /><br />If you would like to use %%fidname%% again at a later date, you can register for a new account with your email address at any time after deletion." +user_delete_success_title = "Account disabled and marked for deletion." + Edit Account = "Edit Account" requested_groups = "Membership requested" @@ -115,6 +126,7 @@ read_user_list_not_allowed = "You are not entitled to read the user list" read_user_list_error = "Error reading user list" user_list_export = "CSV-Export" read_order_list_not_allowed = "You are not entitled to read the order list" +read_order_list_error = "Error loading the order list" user_edit_form_title = "Edit user data of <em>%%username%%</em> (ID %%userid%%)" @@ -145,6 +157,13 @@ acquisition_info_requested_item = "Order item" acquisition_label_pages = "Pages (from-to)" acquisition_label_comment = "Remarks" acquisition_label_submit = "Order" +acquisition_label_title = "Title" +acquisition_label_responsible = "Authors and Corporations" +acquisition_label_year = "Year" +acquisition_label_language = "Language" +acquisition_label_library = "Possessing library in Germany" +acquisition_label_signature = "Signature" +acquisition_label_external_url = "Link to a catalog entry" acquisition_error_pages_too_short = "Your request has too few characters. Please enter at least 3 characters." acquisition_error_pages_too_long = "Your request has too many characters. Please enter a maximum of 13 characters." acquisition_error_pages_pattern = "Wrong format. Please enter the required pages only in the FROM-TO format, e.g. 23-30." @@ -154,8 +173,10 @@ acquisition_error_page_selection = "The page range you specify exceeds the 10 pe acquisition_subito_article_confirmation = "Do you like to order the article?" acquisition_subito_partial_copy_confirmation = "Do you like to order the partial copy?" acquisition_pda_confirmation = "Do you like to order the book?" -acquisition_pda_ordered = "This item has been acquired by adlr.link by request of a patron and will be available in a short time." +acquisition_pda_ordered = "This item has been acquired by %%fidname%% by request of a patron and will be available in a short time." acquisition_success = "Your order is received and will be processed now." acquisition_permission_denied = "Your account is currently blocked for orders." -number_of_pages = "Pages" \ No newline at end of file +number_of_pages = "Pages" + +FID_services = "FID Services" \ No newline at end of file diff --git a/themes/fid/templates/fid/record/acquisition-digitization-fields.phtml b/themes/fid/templates/fid/record/acquisition-digitization-fields.phtml new file mode 100644 index 0000000000000000000000000000000000000000..5fc013c898c672c4da51fac5501cca1e1a927a28 --- /dev/null +++ b/themes/fid/templates/fid/record/acquisition-digitization-fields.phtml @@ -0,0 +1,160 @@ +<!-- fid: fid - record - acquisition-digitization-fields --> +<?php +/** + * Copyright (C) 2021 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 Alexander Purr <purr@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\FormSelect; +use Zend\Form\View\Helper\FormSubmit; + +/** @var Form $form */ +?> + +<?php if (!isset($this->driver)): ?> + + <h2><?= $this->translate("fid::acquisition_info_requested_item") ?></h2> + + <? /* title */ ?> + <?php + /** @var Element\Text $elemTitle */ + $elemTitle = $form->get('title'); + $elemTitle->setLabelAttributes(['class' => 'control-label']); + $elemTitle->setAttributes(['class' => 'form-control']); + ?> + <div class="form-group"> + <?= $this->formElementErrors($elemTitle) ?> + <?= $this->formLabel($elemTitle) ?> + <?= $this->formElement($elemTitle) ?> + </div> + + <? /* responsible */ ?> + <?php + /** @var Element\Text $elemResponsible */ + $elemResponsible = $form->get('responsible'); + $elemResponsible->setLabelAttributes(['class' => 'control-label']); + $elemResponsible->setAttributes(['class' => 'form-control']); + ?> + <div class="form-group"> + <?= $this->formElementErrors($elemResponsible) ?> + <?= $this->formLabel($elemResponsible) ?> + <?= $this->formElement($elemResponsible) ?> + </div> + + <? /* year */ ?> + <?php + /** @var Element\Text $elemYear */ + $elemYear = $form->get('year'); + $elemYear->setLabelAttributes(['class' => 'control-label']); + $elemYear->setAttributes(['class' => 'form-control']); + ?> + <div class="form-group"> + <?= $this->formElementErrors($elemYear) ?> + <?= $this->formLabel($elemYear) ?> + <?= $this->formElement($elemYear) ?> + </div> + + <? /* language */ ?> + <?php + /** @var Element\Text $elemLanguage */ + $elemLanguage = $form->get('language'); + $elemLanguage->setLabelAttributes(['class' => 'control-label']); + $elemLanguage->setAttributes(['class' => 'form-control']); + ?> + <div class="form-group"> + <?= $this->formElementErrors($elemLanguage) ?> + <?= $this->formLabel($elemLanguage) ?> + <?= $this->formElement($elemLanguage) ?> + </div> + +<?php endif; ?> + +<? /* library */ ?> +<?php +/** @var Element\Text $elemFormat */ +$elemLibrary = $form->get('library'); +$elemLibrary->setLabelAttributes(['class' => 'control-label']); +$elemLibrary->setAttributes(['class' => 'form-control']); +?> + +<div class="form-group"> + <?= $this->formElementErrors($elemLibrary) ?> + <?= $this->formLabel($elemLibrary) ?> + <?= $this->formElement($elemLibrary) ?> +</div> + +<? /* signature */ ?> +<?php +/** @var Element\Text $elemSignature */ +$elemSignature = $form->get('signature'); +$elemSignature->setLabelAttributes(['class' => 'control-label']); +$elemSignature->setAttributes(['class' => 'form-control']); +?> + +<div class="form-group"> + <?= $this->formElementErrors($elemSignature) ?> + <?= $this->formLabel($elemSignature) ?> + <?= $this->formElement($elemSignature) ?> +</div> + +<? /* external_url */ ?> +<?php +/** @var Element\Url $elemExternalUrl */ +$elemExternalUrl = $form->get('external_url'); +$elemExternalUrl->setLabelAttributes(['class' => 'control-label']); +$elemExternalUrl->setAttributes(['class' => 'form-control']); +?> + +<div class="form-group"> + <?= $this->formElementErrors($elemExternalUrl) ?> + <?= $this->formLabel($elemExternalUrl) ?> + <?= $this->formElement($elemExternalUrl) ?> +</div> + +<? /* format */ ?> +<?php +/** @var Element\Select $elemFormat */ +$elemFormat = $form->get('format'); +$elemFormat->setLabelAttributes(['class' => 'control-label']); +$elemFormat->setAttributes(['class' => 'form-control']); +?> + +<div class="form-group"> + <?= $this->formElementErrors($elemFormat) ?> + <?= $this->formLabel($elemFormat) ?> + <?= $this->formElement($elemFormat) ?> +</div> + +<? /* comments */ ?> +<?php +/** @var Element\Textarea $elemComment */ +$elemComment = $form->get('comment'); +$elemComment->setLabelAttributes(['class' => 'control-label']); +$elemComment->setAttributes(['class' => 'form-control']); +?> + +<div class="form-group"> + <?= $this->formElementErrors($elemComment) ?> + <?= $this->formLabel($elemComment) ?> + <?= $this->formElement($elemComment) ?> +</div> +<!-- fid: fid - record - acquisition-digitization-fields - END --> diff --git a/themes/fid/templates/fid/record/acquisition-digitization.phtml b/themes/fid/templates/fid/record/acquisition-digitization.phtml index 7a33cba05b289428f40ee73b59715151a52923dd..1446734d34b8d255830de4f7b0be73067cb4f8cf 100644 --- a/themes/fid/templates/fid/record/acquisition-digitization.phtml +++ b/themes/fid/templates/fid/record/acquisition-digitization.phtml @@ -1,3 +1,4 @@ +<!-- fid: fid - record - acquisition-digitization --> <?php /** * Copyright (C) 2021 Leipzig University Library @@ -26,7 +27,6 @@ use Zend\Form\View\Helper\FormLabel; use Zend\Form\View\Helper\FormSelect; use Zend\Form\View\Helper\FormSubmit; -$driver = $this->driver; /** @var Form $form */ /** @var FormLabel $formLabel */ /** @var FormSubmit $formSubmit */ @@ -51,13 +51,17 @@ $form->setAttribute('class','fid-acquisition-form'); <div class="col col-md-6"> <?=$this->render('fid/record/acquisition-address-details'); ?> </div> - <div class="col col-md-6"> - <?php - $formatter = $this->recordDataFormatter(); - $this->coreFields = $formatter->getData($driver, $formatter->getDefaults('fid-acquisition-general')); + <?php if (isset($this->driver)): + $driver = $this->driver; ?> - <?=$this->render('fid/record/acquisition-record-details'); ?> - </div> + <div class="col col-md-6"> + <?php + $formatter = $this->recordDataFormatter(); + $this->coreFields = $formatter->getData($driver, $formatter->getDefaults('fid-acquisition-general')); + ?> + <?=$this->render('fid/record/acquisition-record-details'); ?> + </div> + <?php endif; ?> </div> <div class="row information"> @@ -68,44 +72,11 @@ $form->setAttribute('class','fid-acquisition-form'); </div> </div> -<? /* format */ ?> -<?php -/** @var Element\Select $elemFormat */ -$elemFormat = $form->get('format'); -$elemFormat->setLabelAttributes(['class' => 'control-label']); -$elemFormat->setAttributes(['class' => 'form-control']); -?> - -<? /* comments */ ?> -<?php -/** @var Element\Textarea $elemComment */ -$elemComment = $form->get('comment'); -$elemComment->setLabelAttributes(['class' => 'control-label']); -$elemComment->setAttributes(['class' => 'form-control']); -?> - - <div class="row pages"> - <?php if ( ! ( $this->formElementErrors($elemComment) == "" && $this->formElementErrors($elemFormat) == "" ) ): ?> - <div class="col col-xs-12"> - <div class="form-group"> - <?= $this->formElementErrors($elemFormat) ?> - <?= $this->formElementErrors($elemComment) ?> - </div> - </div> - <?php endif; ?> - <div class="col col-xs-12 col-md-6"> - <div class="form-group"> - <?= $this->formLabel($elemFormat) ?> - <?= $this->formElement($elemFormat) ?> - </div> - </div> - <div class="col col-xs-12 col-md-6"> - <div class="form-group"> - <?= $this->formLabel($elemComment) ?> - <?= $this->formElement($elemComment) ?> - </div> - </div> +<div class="row"> + <div class="col col-xs-12"> + <?=$this->render('fid/record/acquisition-digitization-fields'); ?> </div> +</div> <div class="row confirmation"> <div class="col col-xs-12"> @@ -122,3 +93,4 @@ $elemComment->setAttributes(['class' => 'form-control']); </div> <?= $this->form()->closeTag($form) ?> +<!-- fid: fid - record - acquisition-digitization-fields - END --> diff --git a/themes/fid/templates/fid/user/orders/additionals-data.phtml b/themes/fid/templates/fid/user/orders/additionals-data.phtml index 69b7f01f3ff584f6ed1eb2fc31bb78f07a082a9d..25c8c596c323569ea67cfecb855d3107cadbaba7 100644 --- a/themes/fid/templates/fid/user/orders/additionals-data.phtml +++ b/themes/fid/templates/fid/user/orders/additionals-data.phtml @@ -1,13 +1,34 @@ <!-- fid: fid - user - orders - data --> <td> <?php - $recordId = $this->order->getData()['record']['id']; + $recordId = $this->order->getData()['record']['id'] ?? null; $recordLabel = $this->order->getLabel(); - if ($recordLink = $this->recordLink()->getRecordLink($recordId, 'id')): + if ($recordId && $recordLink = $this->recordLink()->getRecordLink($recordId, 'id')): ?> <a onClick="$('#modal').modal('hide');" target="_self" href="<?=$recordLink?>"><?=$recordLabel?></a> <?php else: ?> - <?=$recordLabel?> + <?php + $externalUrl = $this->order->getData()['digitization']['external_url'] ?? null; + if($externalUrl) : ?> + <?= $this->externalLink($externalUrl, $recordLabel, ['data-lightbox-ignore' => '']) ?> + <?php else: ?> + <?=$recordLabel?> + <?php endif; ?> + <dl> + <?php // Template for use by the renderArray helper: + $arrTemplate = '<dt>%%LABEL%%:</dt><dd> %%VALUE%%</dd>'; + ?> + <?= $this->renderArray( + $arrTemplate, $this->order->getData()['digitization'], + [ + $this->transEsc('fid::acquisition_label_responsible') => 'responsible', + $this->transEsc('fid::acquisition_label_year') => 'year', + $this->transEsc('fid::acquisition_label_language') => 'language', + $this->transEsc('fid::acquisition_label_library') => 'library', + $this->transEsc('fid::acquisition_label_signature') => 'signature' + ] + ) ?> + </dl> <?php endif; ?> </td> <!-- fid: fid - user - orders - data - END --> diff --git a/themes/fid/templates/fid/user/user-delete.phtml b/themes/fid/templates/fid/user/user-delete.phtml new file mode 100644 index 0000000000000000000000000000000000000000..cc7e27eecbbbf6d49c12dc4158b0fab613616d98 --- /dev/null +++ b/themes/fid/templates/fid/user/user-delete.phtml @@ -0,0 +1,86 @@ +<?php + /** + * Copyright (C) 2021 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 + */ + 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/delete')); + $form->prepare(); + + $this->headTitle($this->translate("fid::delete_account_title")); +?> + +<h1><?= $this->translate("fid::user_delete_link") ?></h1> +<?= $this->flashmessages() ?> +<?= $this->translate("fid::user_delete_info") ?> +<br /><br /> +<?= $this->translate("fid::user_delete_hint") ?> +<?= $this->form()->openTag($form) ?> +<br/> +<?php /* username */ ?> +<?php + /** @var Element\Password $elemPassword */ + $elemPassword = $form->get('passwordConfirmation'); + $elemPassword->setLabelAttributes(['class' => 'control-label']); + $elemPassword->setAttributes(['class' => 'form-control']); +?> +<div> + <?= $this->formLabel($elemPassword) ?> + <?= $this->formElement($elemPassword) ?> + <?= $this->formElementErrors($elemPassword) ?> +</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> + <span class="decorate"><?=$this->transEsc('Back')?></span> + </a> + <?= $this->formElement($elemSubmit) ?> +</div> +<?= $this->form()->closeTag($form) ?> diff --git a/themes/fid/templates/myresearch/delete-success.phtml b/themes/fid/templates/myresearch/delete-success.phtml new file mode 100644 index 0000000000000000000000000000000000000000..de775c02dda8082ccbe6ae2dd0e991a5ffcd599b --- /dev/null +++ b/themes/fid/templates/myresearch/delete-success.phtml @@ -0,0 +1,16 @@ +<?php + $title = $this->translate('fid::user_delete_success_title'); + $this->headTitle($title); +?> +<br /> +<h1><?= $title ?></h1> +<br /> +<p><?= $this->translate("fid::user_delete_success", ['%%fidname%%' => $this->translate("fid::acquisition_fid_name")]); ?></p> +<br /> +<?php /* leave profile page after closing of modal; go to home page instead of login page */ ?> +<script> + //VuFind.lightbox.refreshOnClose = true + document.addEventListener('VuFind.lightbox.closed', function lightboxClosed(e) { + document.location.href = "<?=$this->url('search-home')?>"; + }, false); +</script> diff --git a/themes/finc/js/lightbox.js b/themes/finc/js/lightbox.js index 108712feda24df15a4e3a6fe1a104992589d21da..4d183e226b88d770ccea6bb32f1779abf431f7cd 100644 --- a/themes/finc/js/lightbox.js +++ b/themes/finc/js/lightbox.js @@ -1,4 +1,6 @@ -/*global grecaptcha, recaptchaOnLoad, resetCaptcha, VuFind, TEMPORARY BARF CK */ +/*global recaptchaOnLoad, resetCaptcha, VuFind, userIsLoggedIn:true */ +// TEMPORARY BARF CK +/*jshint strict: false */ VuFind.register('lightbox', function Lightbox() { // State var _originalUrl = false; @@ -15,7 +17,7 @@ VuFind.register('lightbox', function Lightbox() { function _html(content) { _modalBody.html(content); // Set or update title if we have one - var $h2 = _modalBody.find("h2:first-of-type"); + var $h2 = _modalBody.find('h2:first-of-type'); if (_lightboxTitle && $h2) { $h2.text(_lightboxTitle); } @@ -42,8 +44,8 @@ VuFind.register('lightbox', function Lightbox() { // Public: Present an alert function showAlert(message, _type) { var type = _type || 'info'; - _html('<div class="flash-message alert alert-' + type + '" role="alert">' + message + '</div>' - + '<button class="btn btn-default" data-dismiss="modal">' + VuFind.translate('close') + '</button>'); + _html('<div class="flash-message alert alert-' + type + '" role="alert">' + message + '</div>' + + '<button class="btn btn-default" data-dismiss="modal">' + VuFind.translate('close') + '</button>'); _modal.modal('show'); } function flashMessage(message, _type) { @@ -67,7 +69,7 @@ VuFind.register('lightbox', function Lightbox() { var _constrainLink; var _formSubmit; function render(content) { - if (typeof content !== "string") { + if (typeof content !== 'string') { return; } // Isolate successes @@ -128,9 +130,7 @@ VuFind.register('lightbox', function Lightbox() { // Add lightbox GET parameter if (!obj.url.match(/layout=lightbox/)) { var parts = obj.url.split('#'); - obj.url = parts[0].indexOf('?') < 0 - ? parts[0] + '?' - : parts[0] + '&'; + obj.url = parts[0].indexOf('?') < 0 ? parts[0] + '?' : parts[0] + '&'; obj.url += 'layout=lightbox'; if (_currentUrl) { obj.url += '&lbreferer=' + encodeURIComponent(_currentUrl); @@ -168,8 +168,7 @@ VuFind.register('lightbox', function Lightbox() { // - not a failed login if ( obj.method && ( - obj.url.match(/catalogLogin/) - || obj.url.match(/MyResearch\/(?!Bulk|Delete|Recover)/) + obj.url.match(/catalogLogin/) || obj.url.match(/MyResearch\/(?!Bulk|Delete|Recover)/) ) && flashMessages.length === 0 ) { @@ -182,7 +181,8 @@ VuFind.register('lightbox', function Lightbox() { VuFind.refreshPage(); } return false; - } else { + /* FINC-specific: avoid page reload after login if param is given - show account links by javascript */ + } else if (new URL(_originalUrl).searchParams.get('refreshOnClose') !== 'false' || !displayLogin()) { VuFind.lightbox.refreshOnClose = true; } _currentUrl = _originalUrl; // Now that we're logged in, where were we? @@ -202,6 +202,22 @@ VuFind.register('lightbox', function Lightbox() { ajax({ url: _currentUrl || _originalUrl }); } + /** + * Finc specific: Login without Page Reload + */ + function displayLogin() { + try { + if ($('#loginOptions').length && $('.logoutOptions').length) { + userIsLoggedIn = true; + $('#loginOptions').hide(); + $('.logoutOptions').removeClass('hidden'); + return true; + } + } catch (e) { /* Empty */ } + + return false; + } + /** * Evaluate a callback */ @@ -243,22 +259,23 @@ VuFind.register('lightbox', function Lightbox() { VuFind.lightbox.reset(); } var $link = $(this); - if (typeof $link.data("lightboxIgnore") != "undefined" - || typeof $link.attr("href") === "undefined" - || $link.attr("href").charAt(0) === "#" - || $link.attr("href").match(/^[a-zA-Z]+:[^/]/) // ignore resource identifiers (mailto:, tel:, etc.) - || (typeof $link.attr("target") !== "undefined" - && ( - $link.attr("target").toLowerCase() === "_new" - || $link.attr("target").toLowerCase() === "new" - )) + if (typeof $link.data('lightboxIgnore') !== 'undefined' || + typeof $link.attr('href') === 'undefined' || + $link.attr('href').charAt(0) === '#' || + $link.attr('href').match(/^[a-zA-Z]+:[^/]/) || // ignore resource identifiers (mailto:, tel:, etc.) + (typeof $link.attr('target') !== 'undefined' && + ( + $link.attr('target').toLowerCase() === '_new' || + $link.attr('target').toLowerCase() === 'new' + ) + ) ) { return true; } if (this.href.length > 1) { event.preventDefault(); var obj = {url: $(this).data('lightboxHref') || this.href}; - if ("string" === typeof $(this).data('lightboxPost')) { + if ('string' === typeof $(this).data('lightboxPost')) { obj.type = 'POST'; obj.data = $(this).data('lightboxPost'); } @@ -490,8 +507,9 @@ VuFind.register('lightbox', function Lightbox() { VuFind.lightbox.reset(); _emit('VuFind.lightbox.closed'); // set focus back on launching element - if (_origin != "undefined") + if (_origin !== null && _origin !== 'undefined') { _origin.focus(); + } }); _modal.on("shown.bs.modal", function lightboxShown() { bindFocus(); diff --git a/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml b/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml index 878760060d4bcac2728a7ac5cf914eb170648406..2d1425fa86e9d4d2a6bb2662c27d0722ce36cc4d 100644 --- a/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml +++ b/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml @@ -209,7 +209,7 @@ $i = 0; <?php if ($this->userlist()->getMode() !== 'disabled'): ?> <?php if ($this->permission()->allowDisplay('feature.Favorites')): ?> <?php /* Add to favorites; finc: keep Icon inside link - CK */ ?> - <a href="<?=$this->recordLink()->getActionUrl($this->driver, 'Save')?>" data-lightbox class="save-record result-link-label" data-id="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>" aria-label="<?=$this->transEsc('Add to favorites')?>"> + <a href="<?=$this->recordLink()->getActionUrl($this->driver, 'Save')?>?refreshOnClose=false" data-lightbox class="save-record result-link-label" data-id="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>" aria-label="<?=$this->transEsc('Add to favorites')?>"> <i class="fa fa-fw fa-star" aria-hidden="true"></i> <span><?=$this->transEsc('Add to favorites')?></span> </a><br/> <?php elseif ($block = $this->permission()->getAlternateContent('feature.Favorites')): ?> diff --git a/themes/finc/templates/RecordDriver/SolrAI/result-list.phtml b/themes/finc/templates/RecordDriver/SolrAI/result-list.phtml index 0b8dc222334495369c4a119078df6840174a8a3f..e21b80019c88987fa4b300e1455720c988b77584 100644 --- a/themes/finc/templates/RecordDriver/SolrAI/result-list.phtml +++ b/themes/finc/templates/RecordDriver/SolrAI/result-list.phtml @@ -219,7 +219,7 @@ if ($cover): <?php if ($this->userlist()->getMode() !== 'disabled'): ?> <?php /* if ($this->permission()->allowDisplay('feature.Favorites')): */ ?> <?php /* Add to favorites; finc: keep Icon inside link - CK */ ?> - <a href="<?=$this->recordLink()->getActionUrl($this->driver, 'Save')?>" data-lightbox class="save-record result-link-label" data-id="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>"> + <a href="<?=$this->recordLink()->getActionUrl($this->driver, 'Save')?>?refreshOnClose=false" data-lightbox class="save-record result-link-label" data-id="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>"> <i class="result-link-icon fa fa-fw fa-star" aria-hidden="true"></i> <?=$this->transEsc('Add to favorites')?> </a><br/> <?php elseif ($block = $this->permission()->getAlternateContent('feature.Favorites')): ?>