From dde2be7f191e2252a2ff2738dd486818fb8a45c2 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Wed, 4 Sep 2024 14:33:53 +0300 Subject: [PATCH 01/66] Fix some missing UserEntityInterface references. (#3901) --- module/VuFind/src/VuFind/OAuth2/Entity/UserEntity.php | 2 +- themes/bootstrap3/templates/myresearch/schedulesearch.phtml | 4 ++-- themes/bootstrap3/templates/record/comments-list.phtml | 2 +- themes/bootstrap5/templates/myresearch/schedulesearch.phtml | 4 ++-- themes/bootstrap5/templates/record/comments-list.phtml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/module/VuFind/src/VuFind/OAuth2/Entity/UserEntity.php b/module/VuFind/src/VuFind/OAuth2/Entity/UserEntity.php index a2e95049440..7fe6461d130 100644 --- a/module/VuFind/src/VuFind/OAuth2/Entity/UserEntity.php +++ b/module/VuFind/src/VuFind/OAuth2/Entity/UserEntity.php @@ -82,7 +82,7 @@ public function __construct( } if ($userIdentifier === null) { throw new \VuFind\Exception\BadConfig( - "$userIdentifierField empty for user {$user->id}." + "$userIdentifierField empty for user {$user->getId()}." . ' The configured user identifier field has to be required.' ); } diff --git a/themes/bootstrap3/templates/myresearch/schedulesearch.phtml b/themes/bootstrap3/templates/myresearch/schedulesearch.phtml index a77d5d44afa..49927003e5d 100644 --- a/themes/bootstrap3/templates/myresearch/schedulesearch.phtml +++ b/themes/bootstrap3/templates/myresearch/schedulesearch.phtml @@ -12,9 +12,9 @@ component('show-account-menu-button')?>
- email)): ?> + getEmail())): ?>
- transEsc('alert_email_address') . ': ' . $this->escapeHtml($user->email) ?> + transEsc('alert_email_address') . ': ' . $this->escapeHtml($user->getEmail()) ?> auth()->getManager()->supportsEmailChange()): ?> (transEsc('edit');?>) diff --git a/themes/bootstrap3/templates/record/comments-list.phtml b/themes/bootstrap3/templates/record/comments-list.phtml index b889ce49ddc..bd2aa36b31a 100644 --- a/themes/bootstrap3/templates/record/comments-list.phtml +++ b/themes/bootstrap3/templates/record/comments-list.phtml @@ -8,7 +8,7 @@ getUser()->getId() ? $this->transEsc('comment_anonymous_user') : $this->escapeHtml(trim($comment->getUser()->getFirstName() . ' ' . $comment->getUser()->getLastName()))?>
escapeHtml($comment->getCreated()->format('Y-m-d H:i:s'))?> - auth()->getUserObject()) && $comment->getUser()->getId() == $user->id): ?> + auth()->getUserObject()) && $comment->getUser()->getId() == $user->getId()): ?> transEsc('Delete')?> diff --git a/themes/bootstrap5/templates/myresearch/schedulesearch.phtml b/themes/bootstrap5/templates/myresearch/schedulesearch.phtml index a77d5d44afa..49927003e5d 100644 --- a/themes/bootstrap5/templates/myresearch/schedulesearch.phtml +++ b/themes/bootstrap5/templates/myresearch/schedulesearch.phtml @@ -12,9 +12,9 @@ component('show-account-menu-button')?>
- email)): ?> + getEmail())): ?>
- transEsc('alert_email_address') . ': ' . $this->escapeHtml($user->email) ?> + transEsc('alert_email_address') . ': ' . $this->escapeHtml($user->getEmail()) ?> auth()->getManager()->supportsEmailChange()): ?> (transEsc('edit');?>) diff --git a/themes/bootstrap5/templates/record/comments-list.phtml b/themes/bootstrap5/templates/record/comments-list.phtml index b889ce49ddc..bd2aa36b31a 100644 --- a/themes/bootstrap5/templates/record/comments-list.phtml +++ b/themes/bootstrap5/templates/record/comments-list.phtml @@ -8,7 +8,7 @@ getUser()->getId() ? $this->transEsc('comment_anonymous_user') : $this->escapeHtml(trim($comment->getUser()->getFirstName() . ' ' . $comment->getUser()->getLastName()))?>
escapeHtml($comment->getCreated()->format('Y-m-d H:i:s'))?> - auth()->getUserObject()) && $comment->getUser()->getId() == $user->id): ?> + auth()->getUserObject()) && $comment->getUser()->getId() == $user->getId()): ?> transEsc('Delete')?> From 1b93d5a84b7672c33854f7793011b8dead4f7420 Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Wed, 4 Sep 2024 07:37:11 -0400 Subject: [PATCH 02/66] ConfigManager.java: add default local dir support; modernize comments. (#3904) - Thanks to Abid Fakhre Alam for valuable input. --- .../src/org/vufind/index/ConfigManager.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/import/index_java/src/org/vufind/index/ConfigManager.java b/import/index_java/src/org/vufind/index/ConfigManager.java index 3a6c783b203..aaf637688ab 100644 --- a/import/index_java/src/org/vufind/index/ConfigManager.java +++ b/import/index_java/src/org/vufind/index/ConfigManager.java @@ -70,25 +70,28 @@ public static ConfigManager instance() private File findConfigFile(String filename) throws IllegalStateException { // Find VuFind's home directory in the environment; if it's not available, - // try using a relative path on the assumption that we are currently in - // VuFind's import subdirectory: + // we cannot proceed: String vufindHome = System.getenv("VUFIND_HOME"); if (vufindHome == null) { // this shouldn't happen since import-marc.sh and .bat always set VUFIND_HOME throw new IllegalStateException("VUFIND_HOME must be set"); } - // Check for VuFind 2.0's local directory environment variable: + // Check for VuFind's local directory environment variable: String vufindLocal = System.getenv("VUFIND_LOCAL_DIR"); - // Get the relative VuFind path from the properties file, defaulting to - // the 2.0-style config/vufind if necessary. + // If VUFIND_LOCAL_DIR is not set, issue a warning and try to derive it from VUFIND_HOME + if (vufindLocal == null || vufindLocal.length() == 0) { + vufindLocal = vufindHome + "/local"; + logger.warn("The VUFIND_LOCAL_DIR environment variable is missing. Defaulting to " + vufindLocal); + } + + // Get the relative VuFind path from the properties file, defaulting to config/vufind if necessary. String relativeConfigPath = PropertyUtils.getProperty( vuFindConfigs, "vufind.config.relative_path", "config/vufind" ); - // Try several different locations for the file -- VuFind 2 local dir, - // VuFind 2 base dir, VuFind 1 base dir. + // Try several different locations for the file -- VuFind local dir, VuFind base dir, legacy base dir. File file; if (vufindLocal != null) { file = new File(vufindLocal + "/" + relativeConfigPath + "/" + filename); @@ -100,7 +103,7 @@ private File findConfigFile(String filename) throws IllegalStateException if (file.exists()) { return file; } - file = new File(vufindHome + "/web/conf/" + filename); + file = new File(vufindHome + "/web/conf/" + filename); // legacy from VuFind 1.x return file; } From 60aef1a942c383803b1e284c157ba5b087d83345 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Wed, 4 Sep 2024 14:39:13 +0300 Subject: [PATCH 03/66] Use correct id in scheduled search list. (#3903) --- module/VuFind/src/VuFind/Search/History.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/VuFind/src/VuFind/Search/History.php b/module/VuFind/src/VuFind/Search/History.php index 59737403c65..6289d6e076c 100644 --- a/module/VuFind/src/VuFind/Search/History.php +++ b/module/VuFind/src/VuFind/Search/History.php @@ -99,7 +99,7 @@ public function getSearchHistory($userId = null) $unsaved[] = $search; } if ($search->getOptions()->supportsScheduledSearch()) { - $schedule[$search->getSearchId()] = $current->getNotificationFrequency(); + $schedule[$current->getId()] = $current->getNotificationFrequency(); } } From 6b0db20e2f37dfee659e6df3370ba8cc9b7c55e5 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Wed, 4 Sep 2024 14:57:34 +0300 Subject: [PATCH 04/66] SImplify formatting of DateTime for display. (#3900) --- .../src/VuFind/View/Helper/Root/Config.php | 54 +++++++++++++++++++ .../templates/admin/feedback/home.phtml | 4 +- .../templates/record/comments-list.phtml | 2 +- .../templates/admin/feedback/home.phtml | 4 +- .../templates/record/comments-list.phtml | 2 +- 5 files changed, 60 insertions(+), 6 deletions(-) diff --git a/module/VuFind/src/VuFind/View/Helper/Root/Config.php b/module/VuFind/src/VuFind/View/Helper/Root/Config.php index a1961129d05..07f0d84a9d0 100644 --- a/module/VuFind/src/VuFind/View/Helper/Root/Config.php +++ b/module/VuFind/src/VuFind/View/Helper/Root/Config.php @@ -49,6 +49,20 @@ class Config extends \Laminas\View\Helper\AbstractHelper */ protected $configLoader; + /** + * Display date format + * + * @var ?string + */ + protected $displayDateFormat = null; + + /** + * Display time format + * + * @var ?string + */ + protected $displayTimeFormat = null; + /** * Config constructor. * @@ -140,4 +154,44 @@ public function offcanvasSide(): ?string ? 'left' : 'right'; } + + /** + * Get date display format + * + * @return string + */ + public function dateFormat(): string + { + if (null === $this->displayDateFormat) { + $config = $this->get('config'); + $this->displayDateFormat = $config->Site->displayDateFormat ?? 'm-d-Y'; + } + return $this->displayDateFormat; + } + + /** + * Get time display format + * + * @return string + */ + public function timeFormat(): string + { + if (null === $this->displayTimeFormat) { + $config = $this->get('config'); + $this->displayTimeFormat = $config->Site->displayTimeFormat ?? 'H:i'; + } + return $this->displayTimeFormat; + } + + /** + * Get date+time display format + * + * @param string $separator String between date and time + * + * @return string + */ + public function dateTimeFormat($separator = ' '): string + { + return $this->dateFormat() . $separator . $this->timeFormat(); + } } diff --git a/themes/bootstrap3/templates/admin/feedback/home.phtml b/themes/bootstrap3/templates/admin/feedback/home.phtml index 543b664bac2..3ed2ae7c7e9 100644 --- a/themes/bootstrap3/templates/admin/feedback/home.phtml +++ b/themes/bootstrap3/templates/admin/feedback/home.phtml @@ -110,11 +110,11 @@ $this->headTitle($this->translate('VuFind Administration - Feedback Management') escapeHtml($key)?>: escapeHtml($value)?>
transEsc('Created')?>: - escapeHtml($this->dateTime()->convertToDisplayDateAndTime('Y-m-d H:i:s', $feedbackEntity->getCreated()->format('Y-m-d H:i:s')))?> + escapeHtml($feedbackEntity->getCreated()->format($this->config()->dateTimeFormat()))?> transEsc('by') . ' ' . $this->escapeHtml($feedbackItem['user_name']) . ' (' . $feedbackEntity->getUser()->getId() . ')') : ''?>
transEsc('Updated')?>: - escapeHtml($this->dateTime()->convertToDisplayDateAndTime('Y-m-d H:i:s', $feedbackEntity->getUpdated()->format('Y-m-d H:i:s')))?> + escapeHtml($feedbackEntity->getUpdated()->format($this->config()->dateTimeFormat()))?> transEsc('by') . ' ' . $this->escapeHtml($feedbackItem['manager_name']) . ' (' . $feedbackEntity->getUpdatedBy() . ')') : ''?>
diff --git a/themes/bootstrap3/templates/record/comments-list.phtml b/themes/bootstrap3/templates/record/comments-list.phtml index bd2aa36b31a..be86c8fa886 100644 --- a/themes/bootstrap3/templates/record/comments-list.phtml +++ b/themes/bootstrap3/templates/record/comments-list.phtml @@ -7,7 +7,7 @@
getUser()->getId() ? $this->transEsc('comment_anonymous_user') : $this->escapeHtml(trim($comment->getUser()->getFirstName() . ' ' . $comment->getUser()->getLastName()))?>
- escapeHtml($comment->getCreated()->format('Y-m-d H:i:s'))?> + escapeHtml($comment->getCreated()->format($this->config()->dateTimeFormat()))?> auth()->getUserObject()) && $comment->getUser()->getId() == $user->getId()): ?> transEsc('Delete')?> diff --git a/themes/bootstrap5/templates/admin/feedback/home.phtml b/themes/bootstrap5/templates/admin/feedback/home.phtml index 19d3b9e2a46..fed6e4b72e7 100644 --- a/themes/bootstrap5/templates/admin/feedback/home.phtml +++ b/themes/bootstrap5/templates/admin/feedback/home.phtml @@ -110,11 +110,11 @@ $this->headTitle($this->translate('VuFind Administration - Feedback Management') escapeHtml($key)?>: escapeHtml($value)?>
transEsc('Created')?>: - escapeHtml($this->dateTime()->convertToDisplayDateAndTime('Y-m-d H:i:s', $feedbackEntity->getCreated()->format('Y-m-d H:i:s')))?> + escapeHtml($feedbackEntity->getCreated()->format($this->config()->dateTimeFormat()))?> transEsc('by') . ' ' . $this->escapeHtml($feedbackItem['user_name']) . ' (' . $feedbackEntity->getUser()->getId() . ')') : ''?>
transEsc('Updated')?>: - escapeHtml($this->dateTime()->convertToDisplayDateAndTime('Y-m-d H:i:s', $feedbackEntity->getUpdated()->format('Y-m-d H:i:s')))?> + escapeHtml($feedbackEntity->getUpdated()->format($this->config()->dateTimeFormat()))?> transEsc('by') . ' ' . $this->escapeHtml($feedbackItem['manager_name']) . ' (' . $feedbackEntity->getUpdatedBy() . ')') : ''?>
diff --git a/themes/bootstrap5/templates/record/comments-list.phtml b/themes/bootstrap5/templates/record/comments-list.phtml index bd2aa36b31a..be86c8fa886 100644 --- a/themes/bootstrap5/templates/record/comments-list.phtml +++ b/themes/bootstrap5/templates/record/comments-list.phtml @@ -7,7 +7,7 @@
getUser()->getId() ? $this->transEsc('comment_anonymous_user') : $this->escapeHtml(trim($comment->getUser()->getFirstName() . ' ' . $comment->getUser()->getLastName()))?>
- escapeHtml($comment->getCreated()->format('Y-m-d H:i:s'))?> + escapeHtml($comment->getCreated()->format($this->config()->dateTimeFormat()))?> auth()->getUserObject()) && $comment->getUser()->getId() == $user->getId()): ?> transEsc('Delete')?> From 83789bdcf9a27c7d067d4d248f5832bd0829b75b Mon Sep 17 00:00:00 2001 From: Milo Ivir <43657314+milotype@users.noreply.github.com> Date: Wed, 4 Sep 2024 08:04:40 -0400 Subject: [PATCH 05/66] Translation progress (via Lokalise) --- languages/CreatorRoles/hr.ini | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/languages/CreatorRoles/hr.ini b/languages/CreatorRoles/hr.ini index eaf868c2a65..f1400896f95 100644 --- a/languages/CreatorRoles/hr.ini +++ b/languages/CreatorRoles/hr.ini @@ -48,9 +48,9 @@ bdd = "Dizajner uveza" bearb = "Urednik" begr = "Osnivač" Beiträger = "Pridonositelj" -beiträger = "Književni pridonositelj" -beiträger k = "Umjetnički pridonositelj" -beiträger m = "Glazbeni pridonositelj" +beiträger = "Književni doprinositelj" +beiträger k = "Umjetnički doprinositelj" +beiträger m = "Doprinositelj glazbe" bjd = "Dizajner omota" bkd = "Dizajner knjiga" bkp = "Proizvođač knjiga" @@ -125,7 +125,7 @@ drm = "Tehnički crtač" drt = "Redatelj" dsr = "Dizajner" dst = "Distributor" -dtc = "Davatelj podataka" +dtc = "Doprinositelj podataka" dte = "Posvećenik" dtm = "Upravitelj podataka" dto = "Posvećuje" From 62fc567a76d39362d9037d02d0f94e14961ec772 Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Wed, 4 Sep 2024 08:06:28 -0400 Subject: [PATCH 06/66] =?UTF-8?q?Updated=20translations=20courtesy=20of=20?= =?UTF-8?q?Agn=C3=A8s=20Manneheut.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- languages/fr.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/languages/fr.ini b/languages/fr.ini index 90ecf5f93a2..91bc6329131 100644 --- a/languages/fr.ini +++ b/languages/fr.ini @@ -400,6 +400,7 @@ epf_recommendations = "Résultats dans les publications" epf_recommendations_more = "Plus de résultats dans les publications" ePub Full Text = "Texte intégral au format ePub" Era = "Période" +error_creating_marc_xml = "Une erreur s'est produite lors du formatage en MARC." error_inconsistent_parameters = "Hélas une erreur est survenue. De mauvais paramètres ont été détectés." error_page_parameter_list_heading = "Paramètres de la requête" Exception = "Exception" @@ -946,6 +947,7 @@ od_info_unavail = "Cette information n'est pas disponible pour le moment." od_is_checkedout = "Vous avez emprunté ce titre. Il doit être retourné pour le %%due_date%%." od_is_on_hold = "Vous avez fait une demande pour ce titre." od_loans = "Emprunts OverDrive" +od_mag_issue_ischeckedout = "emprunté" od_mycontent_help = 'Pour trouver des informations et une aide pour le téléchargement de ces titres, veuillez consulter l\'aide OverDrive.' od_none_found = "Aucun titre n'a été trouvé." od_return_failure = "Ce titre ne peut pas être retourné." @@ -1123,6 +1125,7 @@ relais_success_message = "La demande numéro #%%id%% a été créée. Vous recev Related Author = "Auteurs similaires" Related Items = "Documents similaires" Related Subjects = "Sujets similaires" +Relevance = "Pertinence" Remove filter = "Enlever le filtre" Remove Filters = "Enlever les filtres" Remove from Book Bag = "Retirer du panier" From 0cbe1d804f941ac399958990e50bdfae0b69e77a Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Wed, 4 Sep 2024 08:06:55 -0400 Subject: [PATCH 07/66] Fix whitespace in language file. --- languages/ISO639-3/de.ini | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/languages/ISO639-3/de.ini b/languages/ISO639-3/de.ini index 55a1a362e0c..f61cbd10509 100644 --- a/languages/ISO639-3/de.ini +++ b/languages/ISO639-3/de.ini @@ -1482,7 +1482,7 @@ ctn = "Chhintange" cto = "Emberá-Catío" ctp = "Chatino, Western Highland" cts = "Bikol, Northern Catanduanes" -ctt = "Wayanad Chetti " +ctt = "Wayanad Chetti" ctu = "Chol-Sprache" ctz = "Chatino, Zacatepec" cua = "Cua" @@ -3907,7 +3907,7 @@ maw = "Mampruli" max = "Malay, North Moluccan" maz = "Zentral-Mazahua" mba = "Higaonon" -mbb = "West-Bukidnon-Manobo " +mbb = "West-Bukidnon-Manobo" mbc = "Macushi" mbd = "Dibabawon Manobo" mbe = "Molale" @@ -4314,7 +4314,7 @@ mrd = "Magar, Western" mre = "Martha’s Vineyards Gebärdensprache" mrf = "Elseng" mrg = "Mising" -mrh = "Mara Chin " +mrh = "Mara Chin" mri = "Maori" mrj = "West-Mari" mrk = "Hmwaveke" @@ -6233,7 +6233,7 @@ suy = "Suyá" suz = "Sunwar" sva = "Swanische Sprache" svb = "Ulau-Suain" -svc = "Vincentisches Kreol " +svc = "Vincentisches Kreol" sve = "Serili" svk = "Slowakische Gebärdensprache" svm = "Moliseslawisch" @@ -6697,7 +6697,7 @@ tsl = "Ts'ün-Lao" tsm = "Türkische Gebärdensprache" tsn = "Setswana" tso = "Tsonga" -tsp = "Nord-Tusya " +tsp = "Nord-Tusya" tsq = "Thai-Gebärdensprache" tsr = "Akei" tss = "Taiwanesische Gebärdensprache" @@ -6965,7 +6965,7 @@ vaa = "Vaagri Booli" vae = "Vale" vaf = "Vafsi" vag = "Vagla" -vah = "Varhadi-Nagpuri " +vah = "Varhadi-Nagpuri" vai = "Vai" vaj = "Vasekela Bushman" val = "Vehes" From 39aaae6a64cf38539564c95e62290d846f2235fc Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Wed, 4 Sep 2024 08:08:34 -0400 Subject: [PATCH 08/66] Updated translations courtesy of Craig Murdoch (loaded via Lokalise). --- languages/mi.ini | 457 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 451 insertions(+), 6 deletions(-) diff --git a/languages/mi.ini b/languages/mi.ini index c4185ae3580..fca3faec169 100644 --- a/languages/mi.ini +++ b/languages/mi.ini @@ -1,4 +1,4 @@ -; Translations courtesy of Craig Murdoch. +; Translations by Ian Cormack, Taumatua Māori Language Services, sponsored by Te Mātāpuna Auckland University of Technology Library. Abstract = "Whakarāpopotonga" Access = "Urunga" Access URL = "URL Uru" @@ -6,7 +6,13 @@ access_denied = "Kua aukatia te urunga." Accession Number = "Tau Tāpiringa" Account = "Pūkete" account_block_options_missing = "Kua tangohia ētahi kōwhiringa nā tētahi āraitanga ki tō pūkete. Ngā taipitopito: %%details%%" +account_checkouts_due = "Ngā tūemi me whakahoki ākuanei" +account_checkouts_overdue = "Ngā tūemi tōmuri" +account_has_alerts = "He matohi ō tō pūkete" +account_normal_checkouts = "Ngā tūemi me whakahoki ā muri ake" account_requests_available = "E wātea ana kia tīkina atu" +account_requests_in_transit = "Kei Te Whakawhiti" +account_requests_other = "Tūnga Kē Atu" Add a Library Card = "Tāpirihia he Kāri Whare Pukapuka" Add a Library Card using login = "Tāpiritia he Kāri Whare Pukapuka mā te Takiuru Pūtahitanga" Add a Note = "Tāpirihia he Tuhipoka" @@ -20,9 +26,12 @@ add_comment_fail_blank = "Kaua te kōrero e pātea" add_comment_success = "I tāpiritia te kōrero" add_favorite_fail = "Hapa: Kāore te mauhanga i tiakina" add_list_fail = "Hapa: Kāore te rārangi i waihangatia" +add_other_libraries = "Whakaurua tuhinga i ētahi atu whare pukapuka" add_search = "Tāpiri āpure rapu" add_search_group = "Tāpiri rōpū rapu" +add_tag_error = "Hapa: Tē Taea Te Tiaki Tūtohu" add_tag_note = "Mā ngā mokowā e wehewehe i ngā ripa. Whakamahi tohukī mō ngā tūtohu kupu-maha." +add_tag_success = "Ngā Tūtohu Kua Tiakina" add_to_favorites_html = "Tāpiri %%title%% ki ngā makau" Additional data = "Ngā raraunga tāpiri" Address = "Wāhinoho" @@ -45,12 +54,16 @@ Advanced Search = "Rapu Whatutoto" advSearchError_noRights = "Ka aroha noa, engari kāore ō whakaaetanga ki te takatā i tērā rapu. Kua mōnehu pea tō wātū pūtirotiro?" advSearchError_notAdvanced = "Ehara te rapu i tono koe ki te takatā i te rapu whatutoto." advSearchError_notFound = "Kāore i kitea te rapu i tono koe." +ajax_load_interrupted = "I whakararua te utanga" ajaxview_label_information = "Mōhiohio" +ajaxview_label_tools = "Ngā utauta" +alert_email_address = "Ka tukuna ngā hua matohi whakahōtaka ki te wāhitau īmēra" All = "Katoa" All Fields = "Ngā āpure katoa" All Pages Loaded = "Kua utaina ngā whārangi katoa" All Text = "Ngā kuputuhi katoa" alphabrowse_matches = "Ngā hua" +alphabrowselink_html = 'Tirotiro tūrunga mā te %%index%% e tīmata ana i te %%from%%.' Always ask me = "Pātai mai i ngā wā katoa" An error has occurred = "Kua puta mai tētahi hapa" An error occurred during execution; please try again later. = "Kua hapa te whakahaere; me ngana anō ā muri ake." @@ -67,21 +80,44 @@ Ask a Librarian = "Tonoa he kaitiaki pukapuka" Associated country = "Whenua pātahi" Audience = "Whakaminenga" Audio = "Ororongo" +authentication_error_admin = "Kāore e āhei mātou te takiuru i a koe i tēnei wā. Whakapā ki tō kaiwhakahaere pūnaha mō te āwhina." +authentication_error_blank = "Tē whakaaetia kia noho wātea te mōhiohio takiuru." +authentication_error_creation_blocked = "Kāore i a koe te mana ki te waihanga i tētahi pūkete." +authentication_error_denied = "Kāore i te ōrite ngā taipitopito tuakiri! Kua aukatia te urunga." +authentication_error_email_not_verified_html = 'Kāore anō kia manatokona tō wāhitau īmēra. Tirohia tō tātari pāme mō te karere manatoko. Ki te hiahiatia, ka taea e mātou te Tuku anō i te Īmēra Manatoko.' +authentication_error_expired = "Kua mōnehu te tono whakamotuhēhē." +authentication_error_in_progress = "Kei te tukatuka kētia te tono whakamotuhēhē. Me ngana anō ā muri ake mēnā me tīmata anō." +authentication_error_invalid = "Takiuru muhu -- me ngana anō." +authentication_error_loggedout = "Kua takiputa koe." +authentication_error_session_ip_mismatch = "I tīmataria te tono whakamotuhēhē ki tētahi wāhitau wātū, kawa ipurangi e rerekē ana. Kua aukatia te urunga." +authentication_error_technical = "Kāore e āhei mātou te takiuru i a koe i tēnei wā. Me ngana anō ā muri ake." Author = "Kaituhi" +Author Browse = "Tirotiro Kaituhi" +Author Notes = "Ngā Tuhipoka Kaituhi" Author Results for = "Ngā rapu kaituhi mō" Author Search Results = "Ngā hua rapu kaituhi" +Authority File = "Kōnae Whakamana" Authors = "Ngā kaituhi" +Authors Related to Your Search = "Ngā Kaituhi e Pā ana ki Tō Rapu" +Auto configuration is currently disabled = "Kua monokia te whirihora aunoa i tēnei wā" +auto_configure_description = "Mēnā te tāutanga hou tēnei, ka taea pea te hapa te whakatika mā te utauta Whirihora Aunoa o VuFind." +auto_configure_disabled = "Kua monokia te whirihora aunoa." +auto_configure_title = "Whirihora Aunoa" Availability = "Wāteatanga" Available = "Wātea" Available Functionality = "Taumahinga Wātea" Awards = "Ngā whakawhiwhinga" Back to Record = "Hoki ki te Pūkete" Back to Search Results = "Hoki ki ngā Hua Rapu" +Backtrace = "Rapu whakamuri" Bag = "Pēke pukapuka" Balance = "Taurite" Barcode = "Waeherepae" +Be the first to leave a comment = "Me noho koe te mea tuatahi ki te waiho tākupu" +Be the first to tag this record = "Me noho koe te mea tuatahi ki te tūtohu i tēnei pūkete" Bibliographic Details = "Ngā taipitopito rārangi puna kōrero" Bibliography = "Rārangi puna kōrero" +blender_backend_error_message = "%%error%% -- %%label%%" Blu-ray Disc = "Ngā kōpae Hihi-ōrangi" Book = "Pukapuka" Book Bag = "Pēke pukapuka" @@ -90,16 +126,27 @@ Book Cover = "Uhi pukapuka" bookbag_confirm_empty = "Me whakangita tō Pēke Pukapuka?" bookbag_delete = "Mukua ngā makau kua tīpakotia" bookbag_delete_selected = "Mukua ngā mea tīpako" +bookbag_full = "Katoa" +bookbag_full_msg = "Kua Kī Tō Pēke Pukapuka" Bookmark = "Tohuwāhi" bookplate_label = "Tapanga %%title%%" Books = "Ngā pukapuka" Borrowing Location = "Tauwāhi Mino" -Braille = "Tuhi matapō " +Braille = "Tuhi matapō" +Breadcrumbs = "Ngā maramara parāoa" Brief View = "Tirohanga poto" +Browse = "Tirotiro" +Browse Alphabetically = "Tirotiro ā-Arapū" +Browse for Authors = "Tirotiro mō ngā Kaituhi" +Browse Home = "Tirotiro Kāinga" +Browse the Catalog = "Tirotirohia te Putumōhio Tūemi" +Browse the Collection = "Tirotirohia te Kohinga" +Browse the Collection Alphabetically = "Tirotirohia ā-Arapū te Kohinga" browse_author = "Kaituhi" browse_dewey = "Tau karanga (Dewey)" browse_format = "Hōputu" browse_lcc = "Tau karanga (LC)" +browse_title = "Taitara" bulk_email = "Kua tīpakona te īmērā" bulk_email_success = "I īmēratia t/ō tūemi" bulk_email_title = "Ngā tūemi Putumōhio Whare Pukapuka AUT" @@ -109,6 +156,7 @@ bulk_export_not_supported = "Kāore te/ngā pūkete kua tīpako koe i te tautoko bulk_fail = "Ka aroha, kua puta tētahi hapa. Mahia anō." bulk_noitems_advice = "Kāore tētahi tūemi i tīpakohia. Me pāwhiri ki tētahi pouakataki i te taha o tētahi tūemi, ka ngana anō." bulk_print = "Tāngia ngā mea kua tīpakona" +bulk_save = "Tiakina Ngā Mea Tiaki" bulk_save_error = 'E ngaro ana ētahi raraunga. "Kāore i tiakina ō tūemi.' bulk_save_success = "I oti pai te tiaki i ō tūemi" By = "Mā" @@ -130,28 +178,52 @@ Call Number = "Tau karanga" callnumber_abbrev = "Tau karanga" Cannot find record = "Tē kitea te pūkete" Cannot find similar records = "Tē kitea he pūkete ōrite" +cannot set = "Tē taea te tautuhi" +captcha_label_input = "Tāurua tāu e kite ana" +captcha_label_multiple = "Tīpakona tō CAPTCHA makau:" captcha_label_single = "CAPTCHA:" captcha_not_passed = "Kāore i hipa te CAPTCHA" +captcha_technical_difficulties = "I rahua te CAPTCHA nā ngā raru hangarau" Cassette = "Rīpene" +cat_establish_account = "Hei whakapūmau i tō kōtaha pūkete, tāurua ēnei mōhiohio:" +cat_password_abbrev = "Kupuhipa Putumōhio Whare Pukapuka" +cat_username_abbrev = "Ingoa Kaiwhakamahi Putumōhio" +Catalog Login = "Takiuru Putumōhio" +Catalog Results = "Ngā Hua Putumōhio" +catalog_login_desc = "Tāura ō taipitopito tuakiri putumōhio whare pukapuka." CD = "CD" +Change Email Address = "Huri Wāhitau Īmēra" Change Password = "Huri Kupuhipa" +change_email_disabled = "Tē whakaaetia kia huri koe i tō wāhitau īmēra i tēnei wā" +change_email_verification_reminder = "Mā te tāpae i tēnei puka ka takuna he īmēra ki te wāhitau hōu; me pāwhiri i tētahi hono i te īmēra i mua i te whakamanatanga o te huringa." change_notification_email_message = "Kātahi tonu ka taea tētahi tono ki te huri i tō wāhitau īmēra i te %%library%%. Ki te kore koe taua tono i mahi, me takiuru pea koe ki te %%url%% kei takahia tō pūkete. Me tono tautoko i %%email%% mēnā he pātai, he āwangawanga ōu." change_notification_email_subject = "Whakamōhiotanga Panoni Īmēra Pūkete" channel_add_more = "Tāpirihia kia nui ake ngā hongere pēnei" +channel_browse = "Tirotirohia ngā pūkete atu anō" +channel_expand = "Tūhuratia ngā hongere pātahi" +channel_explore = "Tūhurahura Hongere" +channel_search = "Whakaatu tūemi hei hua rapu" +channel_searchbox_label = "Rapua ētahi atu hongere:" Check Hold = "Tiro puringa" Check Recall = "Tiro tono whakahoki" +check_profile = "Tirohia ngā mōhiohio kaiwhakamahi." Checked Out = "Kua tākina atu" Checked Out Items = "Ngā tūemi kua tākina atu" Checkedout = "Kua tākina atu" Checkout Date = "Rā taki atu" Chicago Citation = "Tohutoru Kātū Chicago" +Chicago Edition Citation = "Tohutoru Kātū Chicago (17th ed.)" child_record_count = "%%count%% pūkete" child_records = "Ngā ihirangi/ngā wāhanga" +Choose a Category to Begin Browsing = "Kōwhiria he Kāwai e Tīmata ai te Tirotiro" +Choose a Column to Begin Browsing = "Kōwhiria he Tīwae e Tīmata ai te Tirotiro" Choose a List = "Kōwhiria he rārangi" +choose_login_method = "Me kōwhiri he tikanga takiuru:" citation_issue_abbrev = "tau" citation_multipage_abbrev = "wh." citation_singlepage_abbrev = "wh." citation_volume_abbrev = "Huānga." +Citations = "Kupu Hautoa" Cite this = "Kīia tēnei" City = "Tāone" Clear = "Ūkui" @@ -160,11 +232,23 @@ clear_tag_filter = "Ūkui tātari" close = "kati" Code = "Waehere" Collection = "Kohinga" +Collection Browse = "Tirotiro Kohinga" +Collection Items = "Ngā Tūemi Kohinga" +collection_disambiguation = "I Kitea Ngā Kohinga Ōrite Maha" +collection_empty = "Kāore he tūemi hei whakaatu." +collection_view_record = "Tiro pūkete" +Collections = "Ngā Kohinga" comment_anonymous_user = "Tautangata" +comment_error_load = "Hapa: Tē taea Te Rārangi Tākupu Te Tātuhi Anō" +comment_error_save = "Hapa: Tē Taea Te Tākupu Te Tiaki" +Comments = "Ngā Tākupu" Company/Entity = "Kamupene/Hinonga" +Conference Proceeding = "Mauhanga Hui" Configuration = "Whirihoranga" confirm_delete = "Me muku tēnei?" confirm_delete_brief = "Muku tūemi?" +confirm_delete_feedback = "Muku Whakahokinga Kōrero" +confirm_delete_library_card_brief = "Me Muku Te Kāri Whare Pukapuka?" confirm_delete_library_card_text = "Me āta muku tēnei kāri whare pukapuka?" confirm_delete_list_brief = "Muku Rārangi?" confirm_delete_list_text = "Me muku tēnei rārangi?" @@ -175,22 +259,38 @@ confirm_hold_cancel_all_text = "Me whakakore ō puringa katoa o nāianei?" confirm_hold_cancel_selected_text = "Me whakakore ō puringa katoa kua tīpakona?" confirm_ill_request_cancel_all_text = "Me whakakore ō tono hoatu taurewa whakawhiti whare pukapuka katoa o nāianei?" confirm_ill_request_cancel_selected_text = "Me whakakore ō tono hoatu taurewa whakawhiti whare pukapuka kua tīpakona?" +confirm_new_password = "Whakaū Kupuhipa Hou" +confirm_renew_all_text = "Me whakahou ō tūemi katoa?" +confirm_renew_selected_text = "Me whakahou ngā tūemi kua tīpakohia?" +confirm_storage_retrieval_request_cancel_all_text = "Me whakakore ō tono tiki rokiroki katoa o nāianei?" +confirm_storage_retrieval_request_cancel_selected_text = "Me whakakore ō tono tiki rokiroki tīpako?" +Connecting of library cards is not supported = "Tē tautokona te tūhono kāri whare pukapuka" Contents = "Ngā ihirangi" Contributing Source = "Puna takoha" Contributors = "Ngā kaitāpae" +Cookie Settings = "Ngā Tautuhinga Pihikete" Coordinates = "Ngā taunga" Copies = "Ngā tārua" Copy = "Tārua" +copy_to_clipboard_button_label = "Tārua ki te papatopenga" +copy_to_clipboard_failure_message = "Kua rahua te tārua ki te papatopenga" +copy_to_clipboard_success_message = "I tāruatia paitia ki te papatopenga" Copyright = "Manatārua" Corporate Author = "Kaituhi rangatōpū" Corporate Authors = "Ngā kaituhi rangatōpū" +could_not_process_feedback = "Tē taea ō whakahokinga kōrero te tukatuka. Me ngana anō ā muri ake." Country = "Whenua" Course = "Akoranga" Course Reserves = "Ngā Tāpuitanga Akoranga" course_reserves_empty_list = "Kāore i kitea he Tāpuitanga Akoranga ōrite." Cover Image = "Ata uhi" +cover_source_label = "Uhi nō" Create a List = "Hanga rārangi" +Create New Account = "Hanga Pūkete Hōu" +Create New Password = "Hanga kupuhipa Hōu" Created = "I hangaia" +csrf_validation_failed = "Tē taea te tono te tukatuka. Me ngana anō." +Data Set = "Huinga Raraunga" Database = "Pātengi raraunga" Date = "Rā" Date of birth = "Rā whānau" @@ -200,10 +300,16 @@ date_from = "Mai" date_month_placeholder = "Marama" date_to = "Ki" date_year_placeholder = "Tau" +Debug Information = "Patuiro Mōhiohio" +deep_paging_failure = "Kāore e wātea ana i tēnei wā te whārangi hua rapu i tono koe; kua tahurikētia koe ki te whārangi %%page%%." default_list_title = "Ngā makau" del_search = "Tango rōpū rapu" Delete = "Muku" delete_account_confirm = "Me āta muku tō pūkete?" +delete_account_description_html = "Ka mukua ngā rapu i tiakina me ngā rārangi tūemi Ka taea te whakatū i te pūkete hōu ā muri ake ki te hiahia." +delete_account_failure = "I rahua te muku i te pūkete." +delete_account_success_message = "Kua mukua tō pūkete. E takiputa ana..." +delete_account_title = "Muku Pūkete" delete_all = "Muku katoa" delete_comment_failure = "Kāore i taea te muku tākupu." delete_comment_success = "I mukua te tākupu." @@ -216,27 +322,37 @@ delete_tags = "Mukua ngā tūtohu" delete_tags_by = "Muku tūtohu nā" Department = "Tari" Description = "Whakaahuatanga" +Desired Username = "Ingoa Kaiwhakamahi Ka Hiahiatia" Detailed View = "Tirohanga taipitopito" Details = "Tirohanga kaimahi" Displaying the top = "E whakaatu ana i ngā mea o runga" +Document Inspector = "Pūtirotiro Tuhinga" Document Type = "Momo tuhinga" DOI = "DOI" doi_detected_html = 'Te āhua nei he DOI tuku kei tō rapu. Pāwhiri ki konei kia tirohia te wātea o te rauemi: %%doi%%' +Draw Search Box = "Tātuhi Pouaka Rapu" +draw_searchbox_end = "Wetekina te kiore ki te whakamutu i te tātuhi." +draw_searchbox_start = "Pāwhiri ka tō ki te tīpako wāhanga." Due = "Rā whakahoki" Due Date = "Rā whakahoki" DVD = "DVD" eBook = "īPukapuka" Edit = "Takatā" edit = "takatā" +Edit Library Card = "Takatā Kāri Whare Pukapuka" Edit this Advanced Search = "Takatāngia tēnei rapu whatutoto" edit_list = "Takatā rārangi" edit_list_fail = "Ka aroha, kāore koe e whakaaetia ki te takatā i tēnei rārangi" edit_list_success = "I pai te whakahou i te rārangi." Edition = "Putanga" +EDS Results = "Ngā Hua EDS" eds_expander_fulltext = "Rapua hoki ngā kuputuhi katoa o ngā tuhinga" eds_expander_relatedsubjects = "Hoatu marau ōrite" eds_expander_thesaurus = "Hoatu kupu whai pānga" +eds_limiter_FC = "Putumōhio Anake" +eds_limiter_FC1 = "Pūrokiroki Pūtahitanga Anake" eds_limiter_FM6 = "Ka Wātea Te Ororongo" +eds_limiter_FR = "E Wātea Ana He Tohutoro" eds_limiter_FT = "Kuputuhi katoa" eds_limiter_FT1 = "E wātea ana i te kohinga whare pukapuka" eds_limiter_RV = "Kua arotake aropātia" @@ -254,6 +370,11 @@ Email this = "Īmēratia tēnei" Email this Search = "Īmēratia tēnei rapu" email_failure = "Hapa - Tē taea te karere te tuku" email_link = "Hononga" +email_login_desc = "Whakamahia tēnei hono ki te takiuru. Ki te kore koe e tono takiuru, me waiho tēnei karere. Me mōhio ka noho mana te hono mō tētahi wā whāiti anake, ā, mā te pūrere anake nāu i whakamahi ki te tāuru i te wāhitau īmēra." +email_login_link = "Hono hei takiuru: <%%url%%>" +email_login_link_sent = "Kua tukuna he hono takiuru ki tō wāhitau īmēra. Ka pau pea ētahi meneti i mua i te taenga o te waehere. Ki te kore e whiwhi wawe i te hono, tirohia tō tātari pāme." +email_login_requested = "Kua tonoa he takiuru mā tō wāhitau īmēra i te %%title%%." +email_login_subject = "Takiuru ki %%title%%" email_maximum_recipients_note = "E %%max%% te mōrahi kaiwhiwhi e whakaaetia ana." email_multiple_recipients_note = "Ka taea te tautuhi kaiwhiwhi maha me te wehewehe ki te piko." email_selected_favorites = "Ngā makau īmēra kua tīpakona" @@ -261,8 +382,12 @@ email_sending = "E tuku karere ana…" email_subject = "Marau" email_success = "Kua tukuna te karere" Empty = "Kua hema" +Empty Book Bag = "Whakangita Pāhi Pukapuka" empty_search_disallowed = "Tē taea he uiui hema i te ūnga rapu" +Enable Auto Config = "Whakahohe Whirihora Aunoa" End Page = "Whārangi mutunga" +eol_ellipsis = "..." +ePub Full Text = "Kuputuhi Katoa ePub" Era = "Wā" error_inconsistent_parameters = "Ka aroha, kua puta tētahi hapa. I kitea he tawhā maiorooro." error_page_parameter_list_heading = "Tono tawhā" @@ -287,12 +412,32 @@ export_send = "Tuku ki %%service%%" export_success = "Kua rite te kaweake" export_to = "Kaweake ki %%target%%" export_unsupported_format = "Hōputu kaweake tē tautokona" +external_auth_access_heading = "Tono Urunga" external_auth_access_login_message = "Kei te tono urunga tētahi taupānga o waho ki ō raraunga. Me takiuru ki te arotake me te whakamana i te tono." external_auth_allow_access = "Tuku Urunga" +external_auth_deny_access = "Whakakore Urunga" external_auth_heading = "Urunga ki ngā rauemi whai raihana" +external_auth_ils_prompt = "Ka tikina atu ētahi o ngā mōhiohio kua tonoa i tō kīwhaiaro putumōhio whare pukapuka." external_auth_login_message = "Takiuru kia uru atu ki ngā rauemi whai raihana" +external_auth_prompt_html = "kei te tono i ēnei motika uru:" +external_auth_scope_address = "Pānuitia tō wāhinoho" +external_auth_scope_age = "Pānuitia tō pakeke" +external_auth_scope_birthdate = "Pānuitia tō rā whānau" +external_auth_scope_block_status = "Tirohia mēnā he aukati kei tō pūkete" +external_auth_scope_email = "Pānuitia tō wāhitau īmēra" +external_auth_scope_library_user_id = "Pānuitia tētahi hāhe ahurei ko tō pūtautuhi kaiwhakamahi whare pukapuka te pūtake" +external_auth_scope_locale = "Pānuitia tō reo hohe" +external_auth_scope_name = "Pānuitia tō ingoa" +external_auth_scope_openid = "Pānuitia tō pūtautuhi kaiwhakamahi" +external_auth_scope_phone = "Pānuitia tō tau waea" +external_auth_scope_profile = "Pānuitia ō mōhiohio kīwhaiaro taketake (ingoa, reo, rā whānau)" +external_auth_scope_unique_id = "Pānuitia tō pūtautuhi ahurei" +external_auth_scopes_none = "kore" external_auth_unauthorized = "Kāore koe e whakaaetia ana kia uru atu ki ngā rauemi whai raihana" external_auth_unauthorized_desc = 'Kāore tō tikanga takiuru e whakarite urunga ki ngā rauemi whai raihana." Me takiputa, ka takiuru anō mā te tikanga rerekē.' +facet_list_empty = "Kāore he raraunga wātea" +facet_list_for = "Rārangi taha mō te %%field%%" +FAQs = "Ngā pātai auau" fav_delete = "Mukua ngā makau kua tīpakotia" fav_delete_deleting = "E mukua ana tō (ō) makau." fav_delete_fail = "Ka aroha, kua puta tētahi hapa. Kāore tō (ō) makau i mukua." @@ -308,29 +453,49 @@ fav_list_delete_cancel = "Kāore te rārangi i mukua." fav_list_delete_fail = 'Ka aroha, kua puta tētahi hapa. "Kāore tō rārangi i mukua.' Fee = "Utu" Feedback = "Urupare" +Feedback Management = "Whakahaere Whakahokinga Kōrero" +feedback_delete_failure = "I rahua te muku whakahokinga kōrero" +feedback_delete_filter = "E whakamahi ana koe i tēnei tātari - Ingoa puka: %%formname%%, URL pae %%siteurl%%, Tūnga %%status%%" feedback_delete_success = "%%count%% whakautu whakahokinga whakaaro kua mukua." +feedback_delete_warning = "Kia tūpato! Kua tata koe te muku i te %%count%% karere whakahokinga kōrero" feedback_email = "Īmēra" +feedback_filter_empty = "Kāore e wātea ana he whakahokinga kōrero mō tēnei tātari" feedback_help_label = "Ka hia āwhina koe?" feedback_name = "Ingoa" feedback_response = "Tēnā koe mō tō urupare." feedback_status_answered = "Kua whakautua" +feedback_status_closed = "Kati" +feedback_status_in progress = "Kei Te Haere Tonu" +feedback_status_open = "Huaki" +feedback_status_pending = "Tārewa ana" +feedback_status_update_failure = "I rahua te whakahou i te tūnga whakahokinga kōrero" +feedback_status_update_success = "I oti pai te whakahou i te tūnga whakahokinga kōrero" feedback_title = "Tukua mai tō urupare" Field of activity = "Momo mahi" File Description = "Whakaahuatanga kōnae" Filter = "Tātari" +Filter Collection = "Kohinga tātari" +filter_tags = "Ngā Tūtohu Tātari" filter_toggle_entries = "%%count%% tātari" filter_wildcard = "Tētahi" Find = "Kimi" +Find New Items = "Kimihia ngā tūemi hou" find_more_ellipsis = "Kimihia ētahi atu…" Fine = "Whaina" +Fine Date = "Kimi Āwhina" +Fine Description = "Whakaaturanga" fine_limit_patron = "Kua hipa i a koe tō tepe whaina, ā, kāore e taea te whakahou tūemi" Fines = "Ngā whaina" First = "Tuatahi" First Name = "Ingoa tuatahi" +First Search Result = "Hua Rapu Tuatahi" +fix_metadata = "Āe, whakatikahia te raraungameta; māku e tatari" footer_header_find_more = "Kimihia ētahi atu" footer_header_need_help = "Ka hia āwhina koe?" footer_header_search_options = "Ngā kōwhiringa rapu" for search = "mō te rapu" +Forgot Password = "Kua Wareware Te Kupuhipa" +Form name = "Ingoa puka" Format = "Hōputu" From = "Mai" Full description = "Whakaahuatanga katoa" @@ -342,10 +507,14 @@ Geographic Search = "Rapu matawhenua" Geographic Terms = "Ngā kupu matawhenua" Geography = "Mātai Matawhenua" Get full text = "Whiwhi kuputuhi katoa" +Get more information = "Whiwhi mōhiohio anō" Globe = "Ao mahere" Go = "Haere" Go to Standard View = "Haere ki te tirohanga noa" go_to_list = "Haere ki te rārangi" +google_map_cluster = "Rāpoi" +google_map_cluster_points = "Ngā Wāhi Rāpoi" +Government Document = "Tuhinga Kāwanatanga" Grid = "Mātiti" Group = "Rōpū" group_AND = "Ngā rōpū KATOA" @@ -355,11 +524,19 @@ Help = "Āwhina" Help with Advanced Search = "Āwhina me te rapu whatutoto" Help with Search Operators = "Āwhina me ngā paheko rapu" help_page_missing = "Kāore i reira te whārangi kua tonoa." +hierarchy_hide_tree = "Huna Paparanga Katoa" +hierarchy_show_tree = "Whakaaturia Te Paparanga Katoa" +hierarchy_tree = "Horopaki" +hierarchy_tree_error = "Ka aroha noa, tē taea te uru te rākau paparanga" +hierarchy_view_context = "Tiro Horopaki" +highlight_snippet_html = "“…%%snippet%%…”" History = "Hītori" history_delete = "Muku" history_delete_link = "Muku" history_empty_search = "Tēahi mea ake (rapu hema)" history_limits = "Ngā tepe" +history_login_html = 'Me takiuru kia kitea ai ō rapu tiaki.' +history_no_saved_searches = "Kāore anō koe kia whai rapu kua tiakina." history_no_searches = "Kāore he rapu i tō hītori." history_purge = "Ūkuia ngā rapu kāore i tiakina" history_recent_searches = "Ngā rapu o nā tata nei" @@ -381,13 +558,31 @@ hold_cancel_success = "I pai te whakakore i tō tono" hold_cancel_success_items = 'I pai te whakakore i te "%%count%% tono' hold_date_invalid = "Tāurua he rā whaimana" hold_date_past = "Tāurua he rā āmuri atu" +hold_edit_conflicting_pickup_locations = "He rerekē ngā kōwhiringa tauwāhi tiki atu mō ngā puringa tīpako. Whakatikahia tētahi puringa hei huri i tana tauwāhi tiki atu." +hold_edit_failed_items = "I rahua te whakahou mō te %%count%% puringa" +hold_edit_frozen = "Tūnga Whakatio" +hold_edit_frozen_set = "Whakatio (whakatārewa rangitahi)" +hold_edit_frozen_through = "Kua Whakatiohia" +hold_edit_frozen_unset = "Wete (haere tonu)" +hold_edit_no_change = "Kāore he rerekētanga" +hold_edit_selected = "Takatā Puringa Tīpako" hold_edit_success_items = "%%count%% puringa kua whakahoutia" +hold_edit_title = "Huri Mōhiohio Puringa" hold_empty_selection = "Kāore he puringa i tīpakohia" hold_error_age_restricted = "Tē taea tētahi puringa te whakarite nā te whakatiki taipakeke kua utaina ki runga i ngā kiko." hold_error_blocked = "Kāore i a koe te mana tika hei whakarite puringa ki tēnei tūemi" hold_error_fail = "I rahua tō tono. Tono āwhina anō i tētahi kaitiaki pukapuka" +hold_error_item_not_holdable = "Kāore i taea tēnei tuemi te tono." +hold_error_not_holdable = "Kāore i taea tēnei rauemi te tono." +hold_error_on_shelf_blocked = "Tē watea ngā puringa whata" hold_error_too_many_holds = "Tē taea te whakarite puringa nā te mea kua hipa kē te mōrahi o ngā puringa." +hold_error_update_blocked_status = "Kei te tūnga te puringa e āraitia ai ētahi, te katoa rānei o ngā huringa." +hold_error_update_failed = "Tē taea te puringa te whakahōu." hold_expires = "Ka mōnehu" +hold_frozen = "Kua whakatiohia (kua whakatārewa rangitahitia)" +hold_frozen_through = "Kua whakatiohia (kua whakatārewa rangitahitia) tae noa ki te %%date%%" +hold_frozen_through_date_invalid = "Tāurutia he rā whai mana e whakatio ai te puringa tae noa ki taua wā" +hold_in_process = "Kei te tukatukatia" hold_invalid_pickup = "Kua tāurua he wāhi tiki muhu. Me whakamātau anō" hold_invalid_request_group = "Kua tāurua he rōpū tono puringa muhu. Me whakamātau anō" hold_items_available = "Tē taea te whakarite puringa nā te korenga e wātea o ētahi tūemi." @@ -395,12 +590,19 @@ hold_login = "Takiuru mō te puringa me ngā mōhiohio tono whakahoki" hold_place = "Tāpae tono" hold_place_fail_missing = "I rahua tō tono. E ngaro ana ētahi raraunga. Tono āwhina anō i tētahi kaitiaki pukapuka" hold_place_success_html = 'I oti pai tō tono. Ō puringa me ngā tono kia whakahoki.' -hold_queue_position = "Tūnga ā-tira %%position%%" +hold_profile_html = 'Mō ngā mōhiohio puringa me te tono whakahoki, me whakaū tō Kōtaha Putumōhio Whare Pukapuka.' +hold_proxied_by = "Kua Tonoa E" +hold_proxied_for = "Kua Tonoa Mā" +hold_queue_position = "Tūnga ā-tira" hold_record_already_on_loan = "E mino kētia ana e koe te rekoata" hold_request_group = "He tono mai i" hold_requested_group = "I tonoa mai i" hold_required_by = "Kua kore e hiahiatia ā muri i te" +hold_required_by_date_before_start_date = "Me tāuru he rā tutuki kei muri atu i te rā tīmata" +hold_required_by_date_invalid = "Tāurua he rā 'tutuki' whai mana" hold_required_by_optional = "Kua kore e hiahiatia ā muri i te" +hold_start_date = "Rā tīmata" +hold_start_date_invalid = "Tāurua tētahi rā tīmata whai mana" hold_success = "I oti pai tō tono" Holdings = "Ngā puringa" Holdings at Other Libraries = "Ngā puringa i ētahi atu whare pukapuka" @@ -438,8 +640,10 @@ ill_request_place_success = "I oti pai tō tono" ill_request_place_success_html = 'I oti pai tō tono. Ngā tono hoatu taurewa whakawhiti whare pukapuka.' ill_request_place_text = "Tāpaetia he tono hoatu taurewa whakawhiti whare pukapuka" ill_request_processed = "Kua tukatukatia" +ill_request_profile_html = 'Mō ngā mōhiohio tono hoatu taurewa whakawhiti whare pukapuka, me whakaū tō Kōtaha Rārangi Tūemi Whare Pukapuka.' ill_request_submit_text = "Tāpae tono" Illustrated = "Whai whakaahua" +ils_account_create_error = "Tē taea tō pūkete te hanga i tā mātou pūnaha whakahaere whare pukapuka. Ki te haere tonu te raru, whakapā ki tō whare pukapuka." ils_action_unavailable = "Kāore te taumahi i tonoa e wātea ana mā te kāri whare pukapuka hohe." ils_connection_failed = "I rahua te tūhononga ki te pūnaha whakahaere whare pukapuka. Kāore e taea te whakaatu mōhiohio e pā ana ki tō pūkete whare pukapuka. Ki te haere tonu te raru, whakapā ki tō whare pukapuka." ils_offline_holdings_message = "Kāore e wātea ana i tēnei wā ngā mōhiohio puringa me te wāteatanga. E tuku whakapāha ana mātou mēnā ka rarua koe e tēnei, ā, whakapā mai ki te tono āwhina anō:" @@ -448,6 +652,7 @@ ils_offline_login_message = "Tē wātea ō taipitopito pūkete i roto i tēnei w ils_offline_status = "E whakatikahia ana tā mātou Pūnaha Whakahaere Whare Pukapuka i tēnei wā." ils_offline_title = "E whakatikahia ana te pūnaha" ils_transaction_history_disabled = "Kāore e hohe ana te hītori mino mō te kāri whare pukapuka hohe." +Image = "Atahanga" Import Record = "Mauhanga Kawemai" in = "i" In This Collection = "I roto i tēnei kohinga" @@ -462,6 +667,8 @@ institutional_login_desc = "Tāurua tō ingoa kaiwhakamahi me tō kupuhipa AUT." Instructor = "Kaitohutohu" Interlibrary Loan Requests = "Ngā tono hoatu taurewa whakawhiti whare pukapuka" Internet = "Ipurangi" +interval_captcha_not_passed = "Ka taea anake tēnei mahi te mahi i muri i te %%delay%% hēkona." +Invalid Patron Login = "Takiuru Kiritaki Muhu" Invalid phone number. = "Tau waea muhu." Invalid Recipient Email Address = "Wāhitau kaiwhiwhi īmēra muhu" Invalid Sender Email Address = "Wāhitau kaituku īmēra muhu" @@ -492,6 +699,7 @@ large = "Rahi" Last = "Whakamutunga" Last Modified = "Whakakētanga tōmua" Last Name = "Ingoa whānau" +Last Search Result = "Hua Rapu Tōmua" less = "iti iho" less_ellipsis = "iti iho…" libphonenumber_invalid = "Tau waea muhu" @@ -502,20 +710,35 @@ libphonenumber_toolong = "He roa rawa te aho i whakaratohia mai mō tō te tau w libphonenumber_tooshort = "He poto rawa te aho i whakaratohia mai mō tō te tau waea" libphonenumber_tooshortidd = "He poto rawa te tau waea i muri i te IDD" Library = "Whare pukapuka" +Library Card = "Kāri Whare Pukapuka" +Library Card Deleted = "Kua Mukua Te Kāri Whare Pukapuka" +Library Card Name = "Ingoa Kāri Whare Pukapuka" +Library Cards = "Ngā Kāri Whare Pukapuka" +Library Cards Disabled = "Kua Monokia Ngā Kāri Whare Pukapuka" +Library Catalog Password = "Kupuhipa Putumōhio" Library Catalog Profile = "Kīwhaiaro putumōhio whare pukapuka" Library Catalog Record = "Mauhanga putumōhio whare pukapuka" Library Catalog Search = "Rapu putumōhio whare pukapuka" Library Catalog Search Result = "Hua rapu putumōhio whare pukapuka" +Library Catalog Username = "Ingoa kaiwhakamahi Putumōhio Whare Pukapuka" Library Web Search = "Rapu tukutuku whare pukapuka" +library_card_edit_password_placeholder = "Kupuhipa Hōu" lightbox_error = "Hapa: tē taea te pouaka putarere te tāuta" Limit To = "Here ki" +Link to full results = "Hono atu ki ngā hua katoa" link_text_need_help = "Ka hia āwhina koe?" +Linked Full Text = "Kuputuhi Katoa Whai Hono" List = "Rārangi" +List Tags = "Whakarārangi Tūtohu" list_access_denied = "Kāore koe e whakaaetia kia tiro i tēnei rārangi." list_edit_name_required = "Ka hiahiatia te ingoa rārangi." -Loading = "E uta an" +load_tag_error = "Hapa: Tē Taea Te Uta Tūtohu" +Loading = "E uta ana" +loading_ellipsis = "E uta ana..." Loan History = "Hītori mino" loan_history_empty = "Kāore ō mino i roto i te hītori mino." +Local Login = "Takiuru Paetata" +local_login_desc = "Tāurua te ingoa kaiwhakamahi me te kupuhipa i hanga nā koe mō tēnei pae." Located = "Tauwāhi" Location = "Tauwāhi" Log Out = "Takiputa" @@ -527,6 +750,8 @@ Logout = "Takiputa" Main Author = "Kaituhi matua" Main Authors = "Ngā kaituhi matua" Major Categories = "Ngā kāwai matua" +Manage Scheduled Alerts = "Whakahaere Matohi Whakahōtaka" +Manage Tags = "Whakahaere Tūtohu" Manuscript = "Tuhinga taketake" Map = "Mahere whenua" Map View = "Tiro Mahere Whenua" @@ -540,12 +765,15 @@ Message From Sender = "Karere mai i te kaituku" Metadata Prefix = "Kūmua raraungameta" Microfilm = "Kiriata mōkito" MLA Citation = "Tohutoro MLA" +MLA Edition Citation = "Tohutoro MLA (9th ed.)" Mobile Number = "Tau pūkoro" mobile_link = "Te āhua nei, e whakamahi ana koe i te pūrere pūkoro; me whakawhiti ki te tirohanga pūkoro?" Monograph Title = "Taitara tuhinga whāiti" more = "ētahi atu" More catalog results = "Ētahi atu hua putumōhio" +More EDS results = "Ētahi anō hua EDS…" More options = "Ētahi kōwhiringa anō" +More Summon results = "Ētahi anō hua Summon…" More Topics = "Ētahi kaupapa anō" more_authors_abbrev = "me ētahi atu." more_ellipsis = "ētahi atu…" @@ -562,19 +790,35 @@ My Profile = "Kīwhaiaro" Narrow Search = "Rapu whāiti" navigate_back = "Hoki" nearby_items = 'Ngā tūemi tata ki "%%title%%"' +New Item Feed = "Whāngai Tūemi Hōu" +New Item Search = "Rapu Tūemi Hōu" +New Item Search Results = "Ngā Hua Rapu Tūemi Hōu" New Items = "Ngā tūemi hou" +New results found for search = "Kua kitea he hua hōu mō te rapu" New Title = "Taitara hou" +new_email_success = "Kua angitu te huri i tō wāhitau īmēra" +new_password = "Kupuhipa Hōu" +new_password_success = "Kua oti tō kupuhipa i te huri" new_results_heading = "%%count%% hua hou rawa" +new_user_welcome_subject = "Tō pūkete hōu i te %%library%%" +new_user_welcome_text = "Nau mai ki %%library%%. Kua huakina he pūkete hōu mā %%firstname%% %%lastname%%. Ko tō ingoa kaiwhakamahi ko %%username%%. Me tautuhi he kupuhipa i tēnei whārangi: %%url%%" Newspaper = "Nūpepa" Next = "Panuku" +Next Search Result = "Hua Rapu Whai Ake" No citations are available for this record = "Kāore e wātea ana he kupu hautoa mō tēnei pūkete" No Cover Image = "Kāore he ata uhi" No dependency problems found = "Kāore i kitea he raru whakamauru" No excerpts were found for this record. = "Kāore i kitea he tangohanga mō tēnei pūkete." +No library account = "Kāore he pūkete whare pukapuka" No new item information is currently available. = "Kāore he mōhiohio tūemi hou e wātea ana." +No pickup locations available = "Kāore ētahi tauwāhi tiki atu i te wātea" No Preference = "Kāore he manako" +No reviews were found for this record = "Kāore i kitea he arotake mō tēnei pūkete" +No Tags = "Kāore He Tūtohu" no_description = "Kāore he whakaahuatanga e wātea ana." +no_email_address = "Kei te ngaro te wāhitau īmēra." no_items_selected = "Kāore tētahi tūemi i tīpakohia" +no_proxied_user = "Kāore he kaiwhakamahi takawaenga (he tono māu anō)" nohit_active_filters = "Kua hoatu tētahi neke atu ngā tātari aronga ki tēnei rapu. Ki te tango tātari koe, ka tīkina atu pea he hua atu anō." nohit_change_tab = 'Erapu ana koe i rōto i te tūtohu "%%activeTab%%". Ka kitea pea tētahi mea i tētahi o ērā atu tūtohu:' nohit_filters = "Ngā tātari kua hoatu ki tēnei rapu:" @@ -623,15 +867,69 @@ Notes = "Ngā tuhipoka" Number = "Tau" number_decimal_point = "." number_thousands_separator = "," +OAI Server = "Tūmau OAI" Occupation = "Mahi" +od_account_noaccess = "Kāore tētahi kāri whare pukapuka e whai urunga ki ngā ihirangi i Overdrive" +od_account_problem = "Kei te rarua tō pūkete. %%message%%" +od_admin_menu = "OverDrive API" +od_audiobook-mp3 = "Pukapuka ororongo MP3" +od_audiobook-overdrive = "Pukapuka Overdrive Listen" od_avail_avail = "Wātea:" od_avail_holds = "Ngā puringa:" +od_avail_total = "Tapeke Tānga:" od_but_cancel_hold = "Whakakore puringa" +od_but_checkout = "Taki Atu Mā Overdrive" +od_but_checkout_s = "Taki atu" +od_but_gettitle = "Tīkina ake ēnei ihirangi" od_but_gettitle_s = "Tikiake" +od_but_hold = "Whakaritea He Puringa Mā Overdrive" od_but_hold_s = "Whakarite puringa" +od_but_return = "Whakahokia tēnei taitara" +od_cancel_hold = "Whakakorea te Puringa Overdrive" +od_checkout = "Takiatu Overdrive" +od_code_connection_failed = "Kua rahua te Tūhono ki Overdrive. Ki te haere tonu te raru, whakapā ki tō whare pukapuka." +od_code_contentnotavail = "He kore wātea tēnei ihirangi i tō rohe." +od_code_login_for_avail = "Takiuru mō te wāteatanga" +od_code_resource_not_found = "Kāore te taitara i kitea" +od_content = "Ihirangi Overdrive" +od_dl_formats = "Ngā Hōputu Tikiake Ka Tautokotia" +od_docheckout_failure = "Kāore i taea tēnei taitara te taki atu" +od_docheckout_success = "Kua takina atu tēnei taitara ki a koe. Ka mōnehu ā te %%expireDate%%" +od_early_return = "Whakahokinga Tōmua Overdrive" od_ebook-epub-adobe = "Adobe EPUB eBook" +od_ebook-epub-open = "īPukapuka Open EPUB" +od_ebook-kindle = "Pukapuka Kindle" +od_ebook-mediado = "īPukapuka MediaDo Reader" +od_ebook-overdrive = "īPukapuka Overdrive Read" od_ebook-pdf-adobe = "Adobe PDF eBook" +od_ebook-pdf-open = "īPukapuka Open PDF" +od_expires_on = "Ka mōnehu tēnei taitara ā te %%due_date%%." +od_get_title = "Tikiake Overdrive" +od_gettitle_failure = "Kāore i taea tēnei taitara te tikiake." +od_help_linktext = "Āwhina Overdrive" +od_history = "Hītori Overdrive" +od_hold = "Puringa Overdrive" +od_hold_cancel_failure = "Kua rahua te tono whakakore puringa." +od_hold_cancel_success = "Kua whakakore paitia te puringa." +od_hold_email = "Ngā wāhitau īmēra mō te whakamōhio puringa: %%holdEmailAddress%%." +od_hold_now_avail = "Kei te wātea tēnei puringa mō te taki atu. Ka mōnehu te taki atu i te %%expireDate%%." +od_hold_place_failure = "Kua rahua te tono puringa." +od_hold_place_success = "Kua whakaritea tēnei taitara hei puringa. Ko tō tūnga puriunga ko te %%holdListPosition%%" +od_hold_placed_on = "I whakaritea te puringa i te %%holdPlacedDate%%." +od_hold_queue = "Tūnga %%holdPosition%% o te %%numberOfHolds%% puringa i te tūtira." +od_hold_queue_s = "Tūnga %%holdPosition%% / %%numberOfHolds%%" +od_holds = "Ngā Puringa Overdrive" +od_info_unavail = "He kore wātea tēnei mōhiohio i tēnei wā." +od_is_checkedout = "Kua takina atu e koe tēnei taitara. Ko te rā whakahoki te %%due_date%%." +od_is_on_hold = "Kua whakaritea he puringa mō tēnei taitara." +od_loans = "Ngā Hoatu Taurewa Overdrive" +od_mycontent_help = 'Mō ngā mōhiohio me te āwhina e pā ana ki te tikiake i ēnei taitara, tirohia Āwhina Overdrive.' +od_none_found = "Kāore i kitea he taitara." +od_return_failure = "Kāore i taea tēnei taitara te whakahoki." +od_return_success = "Kua whakahoki tēnei taitara" +od_video-streaming = "kōnae ataata e pāho ana" of_num_results = "#%%position%% o ngā hua %%total%%" +old_password = "Kupuhipa Tawhito" On Reserve = "Kua tāpuitia" On Reserve - Ask at Circulation Desk = "Kua tāpuitia - tonoa he kaitiaki pukapuka" on_reserve = "Ngā tāpuitanga" @@ -649,14 +947,42 @@ Other Authors = "Ētahi atu kaituhi" Other Editions = "Ētahi atu putanga" Other Libraries = "Ētahi atu whare pukapuka" Other Sources = "Ētahi atu puna" +other_versions_link = "Whakaatu ērā atu putanga (%%count%%)" +other_versions_search_link = "Whakaatu putanga katoa (%%count%%)" +other_versions_title = "Ētahi Atu Putanga (%%count%%)" Page not found. = "Tē kitea te whārangi." +page_first = "Haere ki te Whārangi Tuatahi" +page_last = "Haere ki te Whārangi Whakamutunga" +page_next = "Haere ki te Whārangi Whai Ake" page_num = "Whārangi %%page%%" +page_prev = "Haere ki te Whārangi Tōmua" +page_reload_on_deselect_hint = "Ka uta anō te whārangi ina tangohia he tātari." +page_reload_on_select_hint = "Ka uta anō te whārangi ina tīpakohia, ina ākiritia he tātari." +pagination_label = "Whakawhārangitanga" Password = "Kupuhipa" +Password Again = "Kupuhipa Anō" +Password cannot be blank = "Tē taea te kupuhipa te noho wātea" +password_error_auth_old = "He muhu te kupuhipa i whakamahi tōmuatia" +password_error_invalid = "He muhu te kupuhipa hou (hei tauira, he pūāhua muhu kei roto)" +password_error_not_unique = "Kāore te kupuhipa i hurihia" +password_maximum_length = "Ko te roa mōrahi mō te kupuhipa he %%maxlength%% pūāhua" +password_minimum_length = "Ko te roa mōkito mō te kupuhipa he %% minLength%% pūāhua" +password_only_alphanumeric = "Ngā tau me ngā pū A-Z anake" +password_only_numeric = "Ngā tau anake" +Passwords do not match = "Kāore e ōrite ana ngā kupuhipa" past_days = "{range, plural, =1 {Inanahi} other {Ngā # Rā kua hipa}}" patron_account_expires = "Ka mōnehu" +patron_status_address_missing = "Kei te ngaro tō wāhinoho." +patron_status_card_blocked = "Kua aukatia te mino ki tēnei kāri whare pukapuka" +patron_status_card_expired = "Kua mōnehu tō kāri whare pukapuka." +patron_status_debarred_overdue = "He tūemi tōmuri āu kāore anō kia whakahokia." +patron_status_debt_limit_reached = "Kei a koe te %%blockCount%% hei whaina, hei utunga hoki. He %%blockLimit%% te tepe mō te mino." +patron_status_guarantees_debt_limit_reached = "Kei ō kī taurangi te %%blockCount%% hei whaina, hei utunga hoki. He %%blockLimit%% te tepe aukati mō te mino." +patron_status_maximum_requests = "Ka taea te mōrahi (%%blockCount%%) o ngā tono hohe." PDF Full Text = "Kuputuhi katoa PDF" peer_reviewed = "Kua arotake aropātia" peer_reviewed_limit = "Whakawhāiti ki ngā tuhinga mai i ngā hautaka kua arotake aropātia" +permanent_link = "Hono pūmau" permission_denied = "Kua tonoa he whārangi, hohenga rānei, engari i a koe te whakaaetanga e hiahiatia ana." permission_denied_title = "Kua aukatihia te whakaaetanga" Phone Number = "Tau Waea" @@ -669,14 +995,19 @@ Place of birth = "Wāhi whānautanga" Place of death = "Wāhi mate" Playing Time = "Wā purei" Please check back soon = "Me tiro anō ākuanei" +Please contact the Library Reference Department for assistance = "Tono āwhina i te Tari Tohutoro Whare Pukapuka" Please enable JavaScript. = "Me whakahohe i JavaScript." Please upgrade your browser. = "Whakamohoatia tō pūtirotiro." +Postcard = "Kāripōhi" +Poster = "Pānui whakaahua" Preferences = "Ngā manakohanga" Preferred Library = "Whare pukapuka manako" +preferred_library_default = "Te kōwhiringa tino pai rawa e wātea ana" Prev = "Tōmua" prev_ellipsis = "Tōmua..." Preview = "Arokite" Preview from = "Arokite mai i" +Previous Search Result = "Hua Rapu Tōmua" Previous Title = "Taitara tōmua" Print = "Tā" Private = "Tūmataiti" @@ -685,7 +1016,10 @@ Profile = "Kīwhaiaro" profile_update = "I whakahoutia tō kīwhaiaro e ai ki te tono" pronounced = "i whakahuatia" Provider = "i whakahuatia" +proxied_user = "Whakaritea he tono mō te kaiwhakamahi takawaenga" +proxy_hold_place_success_html = 'Kua oti pai tō tono takawaenga. Ō Puringa me Ō Tono Whakahoki.' Public = "Tūmatanui" +public_list_indicator = "Rārangi Tūmatanui" Publication = "Whakaputanga" Publication Date = "Rā whakaputa" Publication Frequency = "Auau whakaputa" @@ -699,6 +1033,7 @@ Publisher = "Kaiwhakaputa" Publisher Information = "Mōhiohio kaiwhakaputa" Publisher Permissions = "Ngā whakaaetanga whakaputa" QR Code = "QR Code" +query time = "wā uiui" random_recommendation_title = "Ētahi tūemi matapōkere i ō hua" Range = "Awhe" Range slider = "Pūreti awhe" @@ -713,21 +1048,45 @@ rating_70 = "3½ whetū" rating_80 = "4 whetū" rating_90 = "4½ whetū" rating_add_or_update = "Tāpiritia, ka whakahou rānei i te Whakatauranga" +rating_add_success = "Whakatauranga Tiaki" +rating_breakdown_group_title = "mai i te%%from%% ki te %%to%%" +rating_breakdown_percentage = "%%percentage%%%" +rating_disabled = "Kua monokia te whakatauranga" +rating_none = "Kāore anō kia whakatauria" +rating_prompt = "Tō Whakatauranga" +rating_remove = "Tango Whakatauranga" rating_summary = "%%count%% whakatauranga" rating_summary_single = "1 whakatauranga" rating_summary_unrated = "Tāpirihia te whakatauranga tuatahi" Read the full review online... = "Pānui tuihonotia te arotake katoa…" Recall This = "Tonoa kia whakahokia tēnei" recently_returned_channel_title = "I whakahokia i nā noa nei" +recommend_links_text = "Ka āhei hoki te ngana:" Record Citations = "Ngā kupu hautoa kōpae" Record Count = "Tapeke kōpae" +Record in the Search Index = "Pūkete kei te Kuputohu Rapu" Record Type = "Momo kōpae" +Recover Account = "Whakaora Pūkete" +recovery_by_email = "Whakaora mā te īmēra" +recovery_by_username = "Whakaora mā te ingoa kaiwhakamahi" +recovery_disabled = "Kāore anō te whakaora kupuhipa kia whakahohea" recovery_email_notification = "Ka tae mai he tono ki te whakaora anō i te kupuhipa mō tō pūkete i te %%library%%." +recovery_email_sent = "Kua tukuna ngā tohutohu whakaora kupuhipa ki te wāhitau kua rēhita ki tēnei pūkete." +recovery_email_subject = "Whakaora Pūkete VuFind" +recovery_email_url_pretext = "Ka taea te tautuhi anō tō kupuhipa i tēnei URL: %%url%%" +recovery_expired_hash = "Kua mōnehu tēnei hono whakaora" +recovery_invalid_hash = "Kāore i tautohua te hono whakaora" +recovery_new_disabled = "Tē whakaaetia kia huri koe i tō kupuhipa īmēra i tēnei wā" +recovery_title = "Whakaora Kupuhipa Anō" +recovery_too_soon = "Kua maha rawa ngā tono puringa i mahi, me ngana anō ā muri ake." +recovery_user_not_found = "Kāore i kitea tō pūkete" +rectangle_center_message = "Koinei te pūwāhi pokapū mō te tapawhā kua miramiratia" +Reference Material = "Rauemi Tohutoro" Refine Results = "Whakamahine hua" Region = "Rohe" relais_available = "E wātea ana tēnei tūemi mā te hoatu taurewa whakawhiti whare pukapuka. Me tono?" relais_checking = "E taki ana te wāteatanga…" -relais_error_html = 'Kua rarua tēnei tono. Pāwhiri ki konei ki te tono i tēnei tūemi mā te paetukutuku hoatu taurewa whakawhiti whare pukapuka.' +relais_error_html = 'Kua rarua tēnei tono. Pāwhiri ki konei ki te tono i tēnei tūemi mā te paetukutuku hoatu taurewa whakawhiti whare pukapuka.' relais_request = "Tono hoatu taurewa whakawhiti whare pukapuka" relais_requesting = "E tono ana…" relais_search = "Rapu hoatu taurewa whakawhiti whare pukapuka" @@ -736,8 +1095,10 @@ relais_success_message = 'Kua hangaia te tau tuakiri #%%id%%. "Ka whiwhi koe i t Related Author = "Kaituhi whai pānga" Related Items = "Ngā tūemi whai pānga" Related Subjects = "Ngā marau whai pānga" +Relevance = "Hāngaitanga" Remove filter = "Tango tātari" Remove Filters = "Tango tātari" +Remove from Book Bag = "Tangohia i te Pēke Pukapuka" renew_all = "Whakahoutia ngā tūemi katoa" renew_determine_fail = "Tē taea te mōhio mēnā ka taea tō tūemi te whakahou. Whakapā ki tētahi kaitiaki pukapuka." renew_empty_selection = "Kāore tētahi tūemi i tīpakohia" @@ -748,6 +1109,7 @@ renew_item_due = "Me whakahoki te tūemi i roto i te 24 haora e tū mai nei" renew_item_limit = "Kua taea tēnei tūemi ki te tepe whakahou" renew_item_no = "Kāore e taea tēnei tūemi te whakahou" renew_item_overdue = "Tūemi tōmuri" +renew_item_overdue_tooltip = "Nga Tūemi tōmuri" renew_item_requested = "Kua tonoa tēnei tūemi e tētahi atu kaiwhakamahi" renew_select_box = "Whakahou tūemi" renew_selected = "Whakahoutia ngā tūemi kua tīpakona" @@ -759,6 +1121,9 @@ request_place_text = "Tāpaetia he tono" request_submit_text = "Tāpae tono" Requests = "Ngā tono" Reserves = "Ngā tāpuitanga" +Reserves Search = "Rapu Tāpuitanga" +Reserves Search Results = "Ngā Hua Rapu Tāpuitanga" +reset_filters_button = "Tautuhi Tātari Anō" result_checkbox_label = "Tīpakona te hua me te tau %%number%%" result_count = "%%count%% hua" Results = "Ngā hua" @@ -775,10 +1140,16 @@ save_search = "Tiaki rapu" save_search_remove = "Tangohia te rapu kua tiakina" Saved in = "I tiakina i" saved_items = "Ngā tūemi i tiakina" +schedule_daily = "Ia rā" +schedule_explanation = "Whiwhi matohi īmēra mō ngā hua hōu mō te rapu." +schedule_none = "Kore" +schedule_weekly = "Ia wiki" +Scheduled Alert Results = "Ngā hua matohi whakahōtaka" scholarly_limit = "Whakawhāiti ki ngā tuhinga mai i ngā hautaka pūmātauranga" Scroll to Load More = "Panuku ki te uta i ētahi atu anō" Search = "Rapu" Search For = "Rapu mō" +Search For Items on Reserve = "Rapua Tūemi kua Tāpuitia" Search History = "Hītori rapu" Search Home = "Rapu kāinga" Search Mode = "Aratau rapu" @@ -788,6 +1159,7 @@ Search Tips = "Ngā aki rapu" Search Tools = "Ngā utauta rapu" Search Type = "Momo rapu" search_AND = "Ngā kupu KATOA" +search_backend_partial_failure = "E whakaatu ana i ngā hua wāhi noa. I rahua te rapu i tēnei, ēnei ūnga: %%sources%%" search_groups = "Rapu rōpū" search_match = "Ōrite" search_NOT = "KĀORE he kupu" @@ -797,6 +1169,7 @@ search_unsave_success = "Kua angitu te tango i te rapu kua tiakina." seconds_abbrev = "s" see all = "tirohia te katoa" See also = "Tirohia hoki" +see_all_ellipsis = "tirohia te katoa..." Select this record = "Tīpakona tēnei pūkete" Select your carrier = "Tīpakona tō kaikawe" select_pickup_location = "Tīpako tauwāhi tiki atu" @@ -809,8 +1182,11 @@ Sensor Image = "Ata pūoko" Serial = "Raupapa" Series = "Rangatū" Set = "Huinga" +shortlink_redirect = "Ka tahurikētia koe ā te %%delay%% hēkona..." +Show = "Whakaatu" +show_filters_html = "Whakaatu tātari (%%count%%)" showing_items_html = "E whakaatu ana i te %%start%% - %%end%% tūemi" -showing_items_of_html = "E whakaatu ana i te %%start%% - %%end%% tūemi katoa" +showing_items_of_html = "E whakaatu ana i te %%start%% - %%end%% of %%total%% tūemi" showing_results_for_html = "E whakaatu ana i te %%start%% - %%end%% hua mō te rapu '%%lookfor%%'" showing_results_html = "E whakaatu ana i te %%start%% - %%end%% hua" showing_results_of_for_html = "E whakaatu ana i te %%start%% - %%end%% hua o te %%total%% mō te rapu '%%lookfor%%'" @@ -818,16 +1194,19 @@ showing_results_of_html = "E whakaatu ana i te %%start%% - %%end%%Library Catalog Profile.\'' +storage_retrieval_request_reference = "Tohutoro" storage_retrieval_request_submit_text = "Tāpaetia he tono" storage_retrieval_request_year = "Tau" Subcollection = "Kohinga-iti" @@ -880,6 +1273,7 @@ Summary = "Whakarāpopototanga" Summon Results = "Tono hua" summon_database_recommendations = "Ka kitea pea he rauemi tāpiri i konei:" Supplements = "Ngā tāpiritanga" +Supplied by Amazon = "He mea whakarato e Amazon" switch_view = "Whakawhiti tirohanga ki te %%view%%" switchquery_fuzzy = "Mā te whakahaere i te rapu makaro e tīkina atu ai pea ngā kupu he ōrite te takikupu" switchquery_intro = "Ka taea pea ētahi hua anō mā te whakakē i tō uiui rapu." @@ -888,15 +1282,28 @@ switchquery_truncatechar = "Whakapotoa tō uiui rapu hei whakawhānui atu i ō h switchquery_unwantedbools = "Kā taea pea e ngā kupu AND, OR me NOT tō rapu te whakapōraru; tāpiritia he tohukī" switchquery_unwantedquotes = "Mā te tango tohukī e tukua ai pea he rapu whānui ake" switchquery_wildcard = "Mā te tāpiri tohu kārimākā e tikia atu ai pea ngā rerekētanga ā-rohe" +Synonym = "Kupu taurite" System Unavailable = "Tē wātea te pūnaha" Table of Contents = "Rārangi ihirangi" Table of Contents unavailable = "Tē wātea te rārangi ihirangi" +Tag = "Tūtohu" +Tag Management = "Whakahaere Tūtohu" +tag_delete_filter = "E whakamahi ana koe i tēnei tātari - Ingoa kaiwhakamahi: %username%, Tūtohu %tag%, Rauemi %resource%" +tag_delete_warning = "Kia tūpato! Kua tata koe te muku i te %count% tūtohu rauemi" +tag_filter_empty = "Kāore e wātea ana he tūtohu mō tēnei tātari" +Tags = "Ngā Tūtohu" tags_deleted = "%count% tūtohu kua mukua" +test_fail = "Kua rahua" +test_fix = "Whakatika" +test_ok = "ĀE" Text this = "Pātuhitia tēnei" +That email address is already used = "Kua whakamahia kētia tēnei wāhitau īmēra." +That username is already taken = "Kua tango kētia taua ingoa kaiwhakamahi." The record you selected is not part of any of your lists. = "Kāore te pūkete i tīpako koe nō tētahi o ō rārangi." The record you selected is not part of the selected list. = "Kāore te pūkete i tīpako koe nō te rārangi kua tīpakona." The system is currently unavailable due to system maintenance = "Kāore te pūnaha i te wātea ko te whakatika pūnaha te pūtake" Theme = "Tāhuhu" +Thesis = "Tuhinga whakapae" This email was sent from = "He mea tuku tēnei īmēra i" This field is required = "E hiahiatia ana tēnei āpure" This item is already part of the following list/lists = "He wāhanga kē tēnei tūemi o ēnei rārangi" @@ -919,45 +1326,83 @@ total_comments = "Ngā tākupu katoa" total_lists = "Ngā rārangi katoa" total_resources = "Ngā rauemi katoa" total_saved_items = "Ngā tūemi katoa i tiakina" +total_tags = "Tapeke Tūtohu" total_users = "Ngā kaiwhakamahi katoa" Transliterated Title = "Taitara kupu mino" +tree_search_limit_reached_html = "I puta i tō rapu ngā hua tino maha rawa i te rākau. Kei te whakaatu i ngā tūemi tuatahi %%limit%%." trending_items_channel_title = "Ngā tūemi e kaingākautia ana" +unique_tags = "Ngā Tūtohu Ahurei" University Library = "Whare Pukapuka o te Whare Wānanga" Unknown = "Tē mōhiotia" unrecognized_facet_label = "Tētahi atu" +unsubscribe_confirmation = "Me whakakore te ohaurunga īmēra?" +unsubscribe_description = "Kāore i te hiahia whiwhi i tēnei karere ā muri ake? Whakakorea te ohaurunga mā tēnei hono" +unsubscribe_successful = "Kua whakakorea te ohauru" +Updated = "I whakahoutia" +upgrade_description = "Mēnā kei te whakahōu koe i tētahi putanga VuFind o mua, ka taea ō tautuhinga tawhito te uta mā tēnei utauta." URL = "URL" Use for = "Whakamahi mō" Use instead = "Whakamahi kē" User Account = "Pūkete kaiwhakamahi" +User Agent = "Māngai Kaiwhakamahi:" +Username = "Ingoa kaiwhakamahi" +Username cannot be blank = "Tē taea te ingoa kaiwhakamahi te wātea" +Username is already in use in another library card = "Kei te whakamahi kētia te ingoa kaiwhakamahi i tētahi atu kāri whare pukapuka" +username_error_invalid = "He muhu te ingoa kaiwhakamahi (hei tauira, he pūāhua muhu kei roto)" +username_maximum_length = "Ko te roa mōrahi mō te ingoa kaiwhakamahi he %%maxlength%% pūāhua" +username_minimum_length = "Ko te roa mōkito mō te ingoa kaiwhakamahi he %% minLength%% pūāhua" +username_only_alphanumeric = "Ngā tau me ngā pū A-Z anake" +username_only_letters_numbers_and_basic_punctuation = "Ngā pūāhua, tau me ngā tohu kārawara noa anake" +username_only_numeric = "Ngā tau anake" +verification_done = "Kua oti tō wāhitau īmēra te manatoko." +verification_email_change_sent = "Kua tukuna ngā tohutohu manatoko wāhitau īmēra ki te wāhitau īmēra hou. Me manatoko i te wāhitau i mua i te whakamanatanga o te panoni." verification_email_notification = "Kātahi tonu ka taea tētahi tono ki te manatoko i tō wāhitau īmēra i te %%library%%." +verification_email_sent = "Kua tukuna ngā tohutohu manatoko wāhitau īmēra ki te wāhitau kua rēhita ki tēnei pūkete." +verification_email_subject = "Manatoko Īmēra" +verification_email_url_pretext = "Ka taea te tautuhi anō tō kupuhipa i tēnei URL: %%url%%" +verification_too_soon = "Me whai manatokonga tō īmēra. Kua tukuna i nā noa nei he īmēra ki tō wāhitau īmēra rēhita. Ki te kore koe i whiwhi, tāria ētahi meneti ka ngana anō." +verification_user_not_found = "Kāore i kitea tō pūkete" +Versions = "Ngā putanga" VHS = "VHS" Video = "Ataata" Video Clips = "Ngā topenga ataata" +Video Game = "Kēmu Ataata" Videos = "Ngā ataata" View Book Bag = "Tiro pēke pukapuka" +View Complete Issue = "Tiro Putanga Katoa" +View Full Collection = "Tiro Kohinga Katoa" View Full Record = "Tiro pūkete katoa" View in EDS = "Tirohia i EDS" +View online: Full view Book Preview from the Hathi Trust = "Tiro tuihonotia: Tiro Takamua Pukapuka tirohanga katoa nā te Hathi Trust" View Record = "Tiro pūkete" View Records = "Tirohia ngā pūkete" +View Retraction Notice = "Tirohia Te Pānuitanga Kounutanga" View this record in EBSCOhost = "Tīrohia tēnei i te EBSCOhost" view_already_selected = "Kua tīapakona kētia te tirohanga %%current%%" visual_facet_parent = "Nō" Volume = "Huānga" Volume Holdings = "Ngā puringa huānga" +VuFind Administration - Feedback Management = "Mahi Whakarite VuFind - Whakahaere Whakahokinga Kōrero" +VuFind Configuration = "Whirihora VuFind" +vufind_upgrade_fail = "Tē taea a VuFind te whakahōu i tēnei wā" Warning: These citations may not always be 100% accurate = "Kia tūpato: Kāore pea ēnei kupu hautoa i te ōrite pū 100%" wcterms_broader = "Ngā marau whānui ake" wcterms_exact = "Ngā marau whai pānga" wcterms_narrower = "Ngā marau whāiti ake" Web = "Tukutuku" +Website = "Paetukutuku" What am I looking at = "E kite ana au i te aha?" widen_prefix = "Me whakawhānui atu pea i tō rapu ki teto" +wiki_link = "He mea whakarato e Wikipedia" with filters = "me ngā tātari" Year of Publication = "Tau whakaputa" You do not have any fines = "Kāore ō whaina" You do not have any holds or recalls placed = "Kāore ō puringa, ō tono kia whakahoki rānei" You do not have any interlibrary loan requests placed = "Kāore ō tono hoatu taurewa whakawhiti whare pukapuka" You do not have any items checked out = "Kāore ō tūemi kua tākina atu" +You do not have any library cards = "Kāore ō kāri whare pukapuka" You do not have any saved resources = "Kāore ō rauemi kua tiakina. Whakahaeretia he rapu, ka whakamahi i te pātene Tāpiri ki ngā Makau hei tiaki tūemi." +You do not have any storage retrieval requests placed = "Kāore anō koe kia whakatakoto i tētahi tono tiki rokiroki" You must be logged in first = "Me takiuru i te tuatahi" Your Account = "Tō pūkete" Your book bag is empty = "Kua hema tō pēke pukapuka" From 9ae34895f2f0230503d2afe0595da33b38356164 Mon Sep 17 00:00:00 2001 From: Milo Ivir <43657314+milotype@users.noreply.github.com> Date: Wed, 4 Sep 2024 08:09:50 -0400 Subject: [PATCH 09/66] Translation progress (via Lokalise) --- languages/hr.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/languages/hr.ini b/languages/hr.ini index caa90a190f1..868c49c9ce9 100644 --- a/languages/hr.ini +++ b/languages/hr.ini @@ -430,6 +430,7 @@ explain_coord = "* %%coord%% (prilagodi broj podudaranja u usporedbi s pretragom explain_difference_score = "razlika u odnosu na najbolji rezultat" explain_disabled = "Objašnjenje je deaktivirano za %%searchClassId%%" explain_for_search = "Obrazloženje za pretragu" +explain_function_query_label = "Funkcija" explain_modified_value = "Proizvod od %%relevanceValue%% (vrijednost relevantnosti)" explain_modifier = "s modifikatorom od %%modifier%%" explain_record_score = "ocjena zapisa" @@ -1345,6 +1346,7 @@ sort_due_date_desc = "Datum roka posudbe (najprije najnovije)" sort_relevance = "Relevantnost" sort_return_date_asc = "Datum vraćanja posudbe (najprije najstarije)" sort_return_date_desc = "Datum vraćanja posudbe (najprije najnovije)" +sort_saved = "Datum spremanja (najprije najnovija)" sort_title = "Naslov" sort_year = "Datum uzlazno" sort_year_asc = "Datum silazno" @@ -1353,6 +1355,7 @@ Source Title = "Naslov izvora" spell_expand_alt = "Proširi pretragu" spell_suggest = "Alternative za pretragu" Staff View = "Prikaz za djelatnike knjižnice" +standalone_record_link = "Samostalni zapis" Start a new Advanced Search = "Započni novu naprednu pretragu" Start a new Basic Search = "Započni novu osnovnu pretragu" Start Page = "Početna stranica" From ae50ed3bb029c750937183b29dda69b83f1479f2 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Wed, 4 Sep 2024 15:25:09 +0300 Subject: [PATCH 10/66] [FINNA-2477] Simplify date/time formatting. --- themes/finna2/templates/Helpers/userlist.phtml | 2 +- themes/finna2/templates/list/list.phtml | 2 +- themes/finna2/templates/myresearch/fines.phtml | 4 ++-- themes/finna2/templates/myresearch/profile.phtml | 4 ++-- themes/finna2/templates/record/comments-list.phtml | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/themes/finna2/templates/Helpers/userlist.phtml b/themes/finna2/templates/Helpers/userlist.phtml index 8532dc92862..8226cf73eb4 100644 --- a/themes/finna2/templates/Helpers/userlist.phtml +++ b/themes/finna2/templates/Helpers/userlist.phtml @@ -12,7 +12,7 @@ date): ?>
-
transEsc('modified'); ?>: dateTime()->convertToDisplayDate('U', $this->date->getTimestamp()); ?>
+
transEsc('modified'); ?>: date->format($this->config()->dateFormat()); ?>
diff --git a/themes/finna2/templates/list/list.phtml b/themes/finna2/templates/list/list.phtml index cc090413756..b044bbdd61a 100644 --- a/themes/finna2/templates/list/list.phtml +++ b/themes/finna2/templates/list/list.phtml @@ -31,7 +31,7 @@ $this->headScript()->prependScript("var listId = {$list->getId()}; var publicLis
-
transEsc('modified'); ?>: dateTime()->convertToDisplayDate('U', $list->getFinnaUpdated()?->getTimestamp() ?: $list->getCreated()->getTimestamp()); ?>
+
transEsc('modified'); ?>: getFinnaUpdated() ?? $list->getCreated())->format($this->config()->dateFormat()); ?>
diff --git a/themes/finna2/templates/myresearch/fines.phtml b/themes/finna2/templates/myresearch/fines.phtml index c46c8c5a327..443d4df3854 100644 --- a/themes/finna2/templates/myresearch/fines.phtml +++ b/themes/finna2/templates/myresearch/fines.phtml @@ -128,7 +128,7 @@
transEsc('Payment::Last Paid')?>: safeMoneyFormat($this->lastTransaction->getAmount() / 100.00)?> - dateTime()->convertToDisplayDateAndTime('U', $this->lastTransaction->getPaidDate()->getTimestamp())?> + lastTransaction->getPaidDate()->format($this->config()->dateTimeFormat())?>
profile)): ?> @@ -328,7 +328,7 @@ $token): ?> transEsc($token->platform)?> / transEsc($token->browser)?> - dateTime()->convertToDisplayDateAndTime('Y-m-d H:i:s', $token->last_login)?> + getLastLogin()->format($this->config()->dateTimeFormat())?>
diff --git a/themes/finna2/templates/record/comments-list.phtml b/themes/finna2/templates/record/comments-list.phtml index a767e0034a3..10402086707 100644 --- a/themes/finna2/templates/record/comments-list.phtml +++ b/themes/finna2/templates/record/comments-list.phtml @@ -29,11 +29,11 @@
getUser() ? $this->transEsc('comment_anonymous_user') : $this->escapeHtml(trim($this->userPublicName($comment->getUser())))?> - escapeHtml($this->dateTime()->convertToDisplayDateAndTime('U', $comment->getCreated()->getTimestamp()))?> + escapeHtml($comment->getCreated()->format($this->config()->dateTimeFormat()))?> getFinnaUpdated()): ?>
transEsc('modified')?> - escapeHtml($this->dateTime()->convertToDisplayDateAndTime('U', $comment->getFinnaUpdated()->getTimestamp()))?> + escapeHtml($comment->getFinnaUpdated()->format($this->config()->dateTimeFormat()))?>
From 3f28641bf016ab273dc75fe9084924e5f3bcb4c6 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Wed, 4 Sep 2024 22:10:18 +0300 Subject: [PATCH 11/66] Simplify formatting of last login dates in profile page. (#3906) --- themes/bootstrap3/templates/myresearch/profile.phtml | 2 +- themes/bootstrap5/templates/myresearch/profile.phtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/themes/bootstrap3/templates/myresearch/profile.phtml b/themes/bootstrap3/templates/myresearch/profile.phtml index a1ed5fd56ba..f988175431f 100644 --- a/themes/bootstrap3/templates/myresearch/profile.phtml +++ b/themes/bootstrap3/templates/myresearch/profile.phtml @@ -104,7 +104,7 @@ $token): ?> transEsc($token->getPlatform())?> / transEsc($token->getBrowser())?> - dateTime()->convertToDisplayDateAndTime('U', $token->getLastLogin()->getTimestamp())?> + getLastLogin()->format($this->config()->dateTimeFormat())?> diff --git a/themes/bootstrap5/templates/myresearch/profile.phtml b/themes/bootstrap5/templates/myresearch/profile.phtml index a1ed5fd56ba..f988175431f 100644 --- a/themes/bootstrap5/templates/myresearch/profile.phtml +++ b/themes/bootstrap5/templates/myresearch/profile.phtml @@ -104,7 +104,7 @@ $token): ?> transEsc($token->getPlatform())?> / transEsc($token->getBrowser())?> - dateTime()->convertToDisplayDateAndTime('U', $token->getLastLogin()->getTimestamp())?> + getLastLogin()->format($this->config()->dateTimeFormat())?> From 323746b35717c5c6a519e38cec24cc48796f269c Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Wed, 4 Sep 2024 22:11:35 +0300 Subject: [PATCH 12/66] Fix holds Mink test (#3909) The test was using cover image to go to record page, which isn't working anymore. --- .../tests/integration-tests/src/VuFindTest/Mink/HoldsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/HoldsTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/HoldsTest.php index 05afa21e315..e63eb10b141 100644 --- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/HoldsTest.php +++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/HoldsTest.php @@ -107,7 +107,7 @@ protected function gotoRecordWithSearch( . urlencode("id:($id)") ); $page = $session->getPage(); - $this->clickCss($page, '#result0 a.record-cover-link'); + $this->clickCss($page, '#result0 a.getFull'); $this->waitForPageLoad($page); return $page; } From 43d9da7b1cf8d9cce878bfd4844e24c670751463 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Thu, 5 Sep 2024 10:00:37 +0300 Subject: [PATCH 13/66] [FINNA-2549] Fix hierarchy tree lightbox heading. --- .../RecordTab/collectionhierarchytree.phtml | 24 +++++++++++++++++++ .../templates/RecordTab/hierarchytree.phtml | 7 +++--- 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 themes/finna2/templates/RecordTab/collectionhierarchytree.phtml diff --git a/themes/finna2/templates/RecordTab/collectionhierarchytree.phtml b/themes/finna2/templates/RecordTab/collectionhierarchytree.phtml new file mode 100644 index 00000000000..514ab6e96f2 --- /dev/null +++ b/themes/finna2/templates/RecordTab/collectionhierarchytree.phtml @@ -0,0 +1,24 @@ +treeContext = 'Collection'; + $this->treePreviewElement = '#tree-preview'; +?> + +inLightbox): ?> + +

transEsc($this->tab->getDescription())?>

+ slot('hierarchy-tree-heading')->set(''); ?> + +
+
+ render('RecordTab/hierarchytree.phtml')?> +
+
+ tab->getActiveRecord()) !== false): ?> + + render('collection/collection-record-error.phtml')?> + + record($collectionRecord)->getCollectionBriefRecord()?> + + +
+
diff --git a/themes/finna2/templates/RecordTab/hierarchytree.phtml b/themes/finna2/templates/RecordTab/hierarchytree.phtml index cc425ab1d43..119d6c62f78 100644 --- a/themes/finna2/templates/RecordTab/hierarchytree.phtml +++ b/themes/finna2/templates/RecordTab/hierarchytree.phtml @@ -4,10 +4,11 @@ $hierarchyTreeList = $this->tab->getTreeList(); $activeTree = $this->tab->getActiveTree(); ?> +inLightbox && $heading = $this->slot('hierarchy-tree-heading')->get($this->tab->getDescription())): ?> + +

transEsc($heading)?>

+
- + record($this->driver)->renderTemplate( 'core-fields.phtml', @@ -89,7 +89,7 @@ ] ); ?> - + userlist()->getMode() !== 'disabled'): ?> diff --git a/themes/finna2/templates/RecordDriver/SolrAipa/core.phtml b/themes/finna2/templates/RecordDriver/SolrAipa/core.phtml index 170f91f565c..dadcfc20000 100644 --- a/themes/finna2/templates/RecordDriver/SolrAipa/core.phtml +++ b/themes/finna2/templates/RecordDriver/SolrAipa/core.phtml @@ -185,7 +185,7 @@
- inLightbox): ?> -

transEsc($this->tab->getDescription())?>

- 1): ?>
$hierarchyTitle): ?> From b164e9848154fb8b96dd4d9a923a87a905a0bf73 Mon Sep 17 00:00:00 2001 From: siiriylonen <117457514+siiriylonen@users.noreply.github.com> Date: Thu, 5 Sep 2024 10:07:11 +0300 Subject: [PATCH 14/66] [FINNA-2408] LIDO: Display download-only videos as links (#3002) --- module/Finna/src/Finna/RecordDriver/SolrLido.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/module/Finna/src/Finna/RecordDriver/SolrLido.php b/module/Finna/src/Finna/RecordDriver/SolrLido.php index 097b02c4a04..4694f4897f3 100644 --- a/module/Finna/src/Finna/RecordDriver/SolrLido.php +++ b/module/Finna/src/Finna/RecordDriver/SolrLido.php @@ -155,6 +155,7 @@ class SolrLido extends \VuFind\RecordDriver\SolrDefault implements \Laminas\Log\ 'preview_audio' => 'displayLink', 'preview_text' => 'displayLink', 'provided_text' => 'displayLink', + 'provided_video' => 'displayLink', ]; /** @@ -226,6 +227,13 @@ class SolrLido extends \VuFind\RecordDriver\SolrDefault implements \Laminas\Log\ */ protected $displayExternalLinks = ['provided_3D']; + /** + * Array of types displayed as download links with documents + * + * @var array + */ + protected $displayDownloadLinks = ['provided_video']; + /** * Events used for author information. * @@ -572,7 +580,11 @@ protected function getRepresentations(string $language): array } // Representation is a document or wanted to be displayed also as an document $displayAsLink = in_array($type, $this->displayExternalLinks); - if (in_array($type, $documentTypeKeys) || $displayAsLink) { + if ( + in_array($type, $documentTypeKeys) + || in_array($type, $this->displayDownloadLinks) + || $displayAsLink + ) { $documentDesc = $description; $linkType = $displayAsLink ? 'external-link' : 'proxy-link'; if ($displayAsLink && !$documentDesc) { From 6f3e84b579adad75f01bc396ee0bd54b26594358 Mon Sep 17 00:00:00 2001 From: Pasi Tiisanoja Date: Thu, 5 Sep 2024 10:16:36 +0300 Subject: [PATCH 15/66] [FINNA-2529] Fix heading levels and image alt tag on terms page. (#3008) --- themes/finna2/templates/content/terms_en-gb.phtml | 4 ++-- themes/finna2/templates/content/terms_fi.phtml | 4 ++-- themes/finna2/templates/content/terms_sv.phtml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/themes/finna2/templates/content/terms_en-gb.phtml b/themes/finna2/templates/content/terms_en-gb.phtml index 5c8d919de19..d51a0423546 100644 --- a/themes/finna2/templates/content/terms_en-gb.phtml +++ b/themes/finna2/templates/content/terms_en-gb.phtml @@ -3,11 +3,11 @@ $this->content()->setHeading($this->translate('Terms')); ?>
-

Terms governing the use of materials

+

Terms governing the use of materials

diff --git a/themes/bootstrap5/templates/devtools/language.phtml b/themes/bootstrap5/templates/devtools/language.phtml index 531372d8e67..38486a93b12 100644 --- a/themes/bootstrap5/templates/devtools/language.phtml +++ b/themes/bootstrap5/templates/devtools/language.phtml @@ -2,6 +2,9 @@ $pageTitle = 'Comparing Languages Against ' . $mainName; $this->headTitle($pageTitle); + $this->layout()->breadcrumbs = '
  • Development Tools' + . '
  • ' . $this->escapeHtml($pageTitle) . '
  • '; + $uLangs = []; foreach ($this->layout()->allLangs ?? [] as $c => $n) { $uLangs[] = $c; diff --git a/themes/bootstrap5/templates/devtools/permissions.phtml b/themes/bootstrap5/templates/devtools/permissions.phtml new file mode 100644 index 00000000000..075868cd700 --- /dev/null +++ b/themes/bootstrap5/templates/devtools/permissions.phtml @@ -0,0 +1,15 @@ +translate('Permissions'); + $titleEsc = $this->escapeHtml($title); + $this->headTitle($title); + $this->layout()->breadcrumbs = '
  • Development Tools' + . '
  • ' . $titleEsc . '
  • '; +?> +

    + + + + $status): ?> + + +
    PermissionGranted?
    escapeHtml($permission)?>
    From 49bb6d58cb37c886fd594ed28021a5a48f80cfaa Mon Sep 17 00:00:00 2001 From: siiriylonen <117457514+siiriylonen@users.noreply.github.com> Date: Thu, 5 Sep 2024 11:08:25 +0300 Subject: [PATCH 23/66] [FINNA-2388] Fix SR link text for favorites import button. (#3013) --- themes/finna2/templates/list/list.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/finna2/templates/list/list.phtml b/themes/finna2/templates/list/list.phtml index b044bbdd61a..d27cade56e3 100644 --- a/themes/finna2/templates/list/list.phtml +++ b/themes/finna2/templates/list/list.phtml @@ -40,7 +40,7 @@ $this->headScript()->prependScript("var listId = {$list->getId()}; var publicLis paginationControl($this->results->getPaginator(), 'Sliding', 'search/pagination_simple.phtml', ['results' => $this->results]) ?>
    render('search/controls/sort.phtml')?> From 0f93d38f16fb24a4fec834eeb8d98f156782e62e Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Thu, 5 Sep 2024 12:06:23 +0300 Subject: [PATCH 24/66] Fix displaying of summary in image popup. --- .../DefaultRecord/record-image-popup-information.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/finna2/templates/RecordDriver/DefaultRecord/record-image-popup-information.phtml b/themes/finna2/templates/RecordDriver/DefaultRecord/record-image-popup-information.phtml index 2226956e7d9..59654a20c80 100644 --- a/themes/finna2/templates/RecordDriver/DefaultRecord/record-image-popup-information.phtml +++ b/themes/finna2/templates/RecordDriver/DefaultRecord/record-image-popup-information.phtml @@ -79,7 +79,7 @@ if ($otherTitles):?>
    -

    cleanHtml($summary)?>

    +

    cleanHtml($summary)?>

    From d3560295fd542f15b8f06de72ee3ce43b8407b99 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Thu, 5 Sep 2024 12:06:50 +0300 Subject: [PATCH 25/66] Fix remaining short PHP open tags. --- .../templates/RecordDriver/DefaultRecord/core.phtml | 4 ++-- .../RecordDriver/DefaultRecord/data-series.phtml | 2 +- themes/finna2/templates/RecordDriver/EDS/core.phtml | 4 ++-- themes/finna2/templates/RecordDriver/Primo/core.phtml | 4 ++-- .../finna2/templates/RecordDriver/SolrAipa/core.phtml | 4 ++-- .../templates/RecordDriver/SolrAuthDefault/core.phtml | 6 +++--- .../finna2/templates/RecordDriver/SolrEad/core.phtml | 4 ++-- .../templates/RecordDriver/SolrForward/core.phtml | 4 ++-- .../finna2/templates/RecordDriver/SolrLido/core.phtml | 4 ++-- .../finna2/templates/RecordDriver/SolrLrmi/core.phtml | 4 ++-- .../finna2/templates/RecordDriver/SolrQdc/core.phtml | 4 ++-- .../RecordDriver/SolrQdc/result-condensed.phtml | 4 ++-- themes/finna2/templates/collection/view.phtml | 4 ++-- themes/finna2/templates/search/logosection.phtml | 10 +++++----- 14 files changed, 31 insertions(+), 31 deletions(-) diff --git a/themes/finna2/templates/RecordDriver/DefaultRecord/core.phtml b/themes/finna2/templates/RecordDriver/DefaultRecord/core.phtml index b832506d038..bfe0836f445 100644 --- a/themes/finna2/templates/RecordDriver/DefaultRecord/core.phtml +++ b/themes/finna2/templates/RecordDriver/DefaultRecord/core.phtml @@ -271,7 +271,7 @@
    - + record($this->driver)->renderTemplate( 'core-fields.phtml', @@ -280,7 +280,7 @@ ] ); ?> - + content()->findTemplateForLng('content/Additions/record-post-metadata')): ?>
    diff --git a/themes/finna2/templates/RecordDriver/DefaultRecord/data-series.phtml b/themes/finna2/templates/RecordDriver/DefaultRecord/data-series.phtml index e1e5364a5c5..0cc6a3597a2 100644 --- a/themes/finna2/templates/RecordDriver/DefaultRecord/data-series.phtml +++ b/themes/finna2/templates/RecordDriver/DefaultRecord/data-series.phtml @@ -14,7 +14,7 @@ } $lookfor = implode(', ', $terms); ?> - diff --git a/themes/finna2/templates/RecordDriver/EDS/core.phtml b/themes/finna2/templates/RecordDriver/EDS/core.phtml index f7bc0ac1af3..1a858884430 100644 --- a/themes/finna2/templates/RecordDriver/EDS/core.phtml +++ b/themes/finna2/templates/RecordDriver/EDS/core.phtml @@ -85,7 +85,7 @@
    - + record($this->driver)->renderTemplate( 'core-fields.phtml', @@ -97,7 +97,7 @@ ] ); ?> - + userlist()->getMode() !== 'disabled'): ?> diff --git a/themes/finna2/templates/RecordDriver/Primo/core.phtml b/themes/finna2/templates/RecordDriver/Primo/core.phtml index 21c005dfa3b..b8a960d0a4f 100644 --- a/themes/finna2/templates/RecordDriver/Primo/core.phtml +++ b/themes/finna2/templates/RecordDriver/Primo/core.phtml @@ -80,7 +80,7 @@
    - + record($this->driver)->renderTemplate( 'core-fields.phtml', @@ -194,7 +194,7 @@ ] ); ?> - + 1): ?>
    diff --git a/themes/finna2/templates/RecordDriver/SolrAuthDefault/core.phtml b/themes/finna2/templates/RecordDriver/SolrAuthDefault/core.phtml index b2b964e84a4..a4b41a5ebb3 100644 --- a/themes/finna2/templates/RecordDriver/SolrAuthDefault/core.phtml +++ b/themes/finna2/templates/RecordDriver/SolrAuthDefault/core.phtml @@ -49,7 +49,7 @@ driver->getCorporateType()): ?>
    - + record($this->driver)->getAuthoritySummary(true)): ?>
    @@ -74,7 +74,7 @@
    - + record($this->driver)->renderTemplate( 'core-fields.phtml', @@ -83,7 +83,7 @@ ] ); ?> - + content()->findTemplateForLng('content/Additions/record-post-metadata')): ?>
    diff --git a/themes/finna2/templates/RecordDriver/SolrEad/core.phtml b/themes/finna2/templates/RecordDriver/SolrEad/core.phtml index aacce0d0513..6ee70a2d686 100644 --- a/themes/finna2/templates/RecordDriver/SolrEad/core.phtml +++ b/themes/finna2/templates/RecordDriver/SolrEad/core.phtml @@ -120,7 +120,7 @@
    - + record($this->driver)->renderTemplate( 'core-fields.phtml', @@ -129,7 +129,7 @@ ] ); ?> - + content()->findTemplateForLng('content/Additions/record-post-metadata')): ?>
    diff --git a/themes/finna2/templates/RecordDriver/SolrForward/core.phtml b/themes/finna2/templates/RecordDriver/SolrForward/core.phtml index 1b078d6a1bf..d1256535ad7 100644 --- a/themes/finna2/templates/RecordDriver/SolrForward/core.phtml +++ b/themes/finna2/templates/RecordDriver/SolrForward/core.phtml @@ -238,7 +238,7 @@
    - + record($this->driver)->renderTemplate( 'core-fields.phtml', @@ -247,7 +247,7 @@ ] ); ?> - + content()->findTemplateForLng('content/Additions/record-post-metadata')): ?>
    diff --git a/themes/finna2/templates/RecordDriver/SolrLido/core.phtml b/themes/finna2/templates/RecordDriver/SolrLido/core.phtml index 4306d01d27f..1f72a51a7a5 100644 --- a/themes/finna2/templates/RecordDriver/SolrLido/core.phtml +++ b/themes/finna2/templates/RecordDriver/SolrLido/core.phtml @@ -125,7 +125,7 @@
    - + record($this->driver)->renderTemplate( 'core-fields.phtml', @@ -134,7 +134,7 @@ ] ); ?> - + content()->findTemplateForLng('content/Additions/record-post-metadata')): ?>
    diff --git a/themes/finna2/templates/RecordDriver/SolrLrmi/core.phtml b/themes/finna2/templates/RecordDriver/SolrLrmi/core.phtml index c00eaa6fd12..ca0b327bc14 100644 --- a/themes/finna2/templates/RecordDriver/SolrLrmi/core.phtml +++ b/themes/finna2/templates/RecordDriver/SolrLrmi/core.phtml @@ -95,7 +95,7 @@ ', array_map([$this, 'escapeHtml'], $summary)) ?>
    - + record($this->driver)->renderTemplate( 'core-fields.phtml', @@ -105,7 +105,7 @@ ] ); ?> - +
    userlist()->getMode() !== 'disabled'): ?> diff --git a/themes/finna2/templates/RecordDriver/SolrQdc/core.phtml b/themes/finna2/templates/RecordDriver/SolrQdc/core.phtml index 46c16bb3ee7..9a091e1b327 100644 --- a/themes/finna2/templates/RecordDriver/SolrQdc/core.phtml +++ b/themes/finna2/templates/RecordDriver/SolrQdc/core.phtml @@ -188,7 +188,7 @@ - + record($this->driver)->renderTemplate( 'core-fields.phtml', @@ -197,7 +197,7 @@ ] ); ?> - + content()->findTemplateForLng('content/Additions/record-post-metadata')): ?>
    diff --git a/themes/finna2/templates/RecordDriver/SolrQdc/result-condensed.phtml b/themes/finna2/templates/RecordDriver/SolrQdc/result-condensed.phtml index 19953b50722..a29135413bc 100644 --- a/themes/finna2/templates/RecordDriver/SolrQdc/result-condensed.phtml +++ b/themes/finna2/templates/RecordDriver/SolrQdc/result-condensed.phtml @@ -101,11 +101,11 @@ record($this->driver)->getOnlineUrls('results')?> record($this->driver)->getPreviews()?> + icon('authorize') ?> - + ***/ ?>
    diff --git a/themes/finna2/templates/collection/view.phtml b/themes/finna2/templates/collection/view.phtml index f90064a3ba0..6a2a8111070 100644 --- a/themes/finna2/templates/collection/view.phtml +++ b/themes/finna2/templates/collection/view.phtml @@ -96,7 +96,7 @@
    - + recordDataFormatter($driver); $coreFields = $formatter->getDefaults(); @@ -123,7 +123,7 @@ record($this->driver)->renderTemplate('core-field-groups.phtml', ['data' => $coreFieldGroups]);?> - + diff --git a/themes/finna2/templates/search/logosection.phtml b/themes/finna2/templates/search/logosection.phtml index 25a11e442e9..057044ee368 100644 --- a/themes/finna2/templates/search/logosection.phtml +++ b/themes/finna2/templates/search/logosection.phtml @@ -1,14 +1,14 @@ imageSrc()->getSourceAddress('finna-logo.' . $this->layout()->userLang)) || ($srcUrl = $this->imageSrc()->getSourceAddress('finna-logo'))): ?> +imageSrc()->getSourceAddress('finna-logo.' . $this->layout()->userLang)) || ($srcUrl = $this->imageSrc()->getSourceAddress('finna-logo'))): ?> transEsc('Home');?> Logo - + - -layout()->templateName === 'home' && $this->layout()->templateDir == 'search') : ?> + +layout()->templateName === 'home' && $this->layout()->templateDir == 'search') : ?>
    - + */ ?> From 397db785de1584af0c4c60ab08654ee2ddd947d4 Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Thu, 5 Sep 2024 12:22:35 +0300 Subject: [PATCH 26/66] [FINNA-2477] Fix initLightboxLogin check to match event object (#3017) Also fixes one of the regex matches in the URL checks. --- themes/finna2/js/finna-layout.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/themes/finna2/js/finna-layout.js b/themes/finna2/js/finna-layout.js index eba5c3ff020..4cbddb40ed6 100644 --- a/themes/finna2/js/finna-layout.js +++ b/themes/finna2/js/finna-layout.js @@ -467,8 +467,9 @@ finna.layout = (function finnaLayout() { if (!document.addEventListener) { return; } + // Lightbox passes an object as an event containing keys: {formUrl, originalUrl} VuFind.listen('lightbox.login', function onLightboxLogin(e) { - if ($('body').hasClass('template-name-home') && !e.detail.formUrl.match(/catalogLogin/) && !e.detail.formUrl.match(/\Save/) && !e.detail.formUrl.match(/%2[fF]Save/)) { + if ($('body').hasClass('template-name-home') && !e.formUrl.match(/catalogLogin/) && !e.formUrl.match(/\/Save/) && !e.formUrl.match(/%2[fF]Save/)) { window.location.href = VuFind.path + '/MyResearch/Home'; e.preventDefault(); } From 728cdab3271b9b7a6c7f04c5d21133586845cb03 Mon Sep 17 00:00:00 2001 From: rajaro Date: Thu, 5 Sep 2024 12:35:47 +0300 Subject: [PATCH 27/66] [FINNA-2349] Add screen reader only heading to organisation widget (#3005) --- .../organisationinfo/elements/location/widget-details.phtml | 1 + 1 file changed, 1 insertion(+) diff --git a/themes/finna2/templates/organisationinfo/elements/location/widget-details.phtml b/themes/finna2/templates/organisationinfo/elements/location/widget-details.phtml index bdab07a97c4..fe674511925 100644 --- a/themes/finna2/templates/organisationinfo/elements/location/widget-details.phtml +++ b/themes/finna2/templates/organisationinfo/elements/location/widget-details.phtml @@ -1,4 +1,5 @@
    matomoTracking('Location Widget', $id . '/' . $orgInfo['name'])?>> +

    transEsc('organisation_info_contact')?>

    From f92cbf3f2a71a65fdf8a39091f6b156524682741 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Thu, 5 Sep 2024 13:22:04 +0300 Subject: [PATCH 28/66] Fix response returned from export action. --- module/Finna/src/Finna/Controller/MyResearchController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/Finna/src/Finna/Controller/MyResearchController.php b/module/Finna/src/Finna/Controller/MyResearchController.php index 9e485949d66..9626f04b5d5 100644 --- a/module/Finna/src/Finna/Controller/MyResearchController.php +++ b/module/Finna/src/Finna/Controller/MyResearchController.php @@ -1308,7 +1308,7 @@ public function exportAction() 'lists' => $this->exportUserLists($user), ]; $json = json_encode($exportData); - $timestamp = (new \DateTime('now'))->format('Y-m-d-H-i'); + $timestamp = (new \DateTime())->format('Y-m-d-H-i'); $filename = "finna-export-$timestamp.json"; $response = $this->getResponse(); $response->setContent($json); @@ -1320,7 +1320,7 @@ public function exportAction() ) ->addHeaderLine('Content-Length', strlen($json)); - return $this->response; + return $response; } /** From 09e49a033c45faf024a89893031803f2b4a54afe Mon Sep 17 00:00:00 2001 From: Aleksi Peebles Date: Thu, 5 Sep 2024 13:50:54 +0300 Subject: [PATCH 29/66] Add an option to use a separate admin theme (#3910) --- config/vufind/config.ini | 3 +++ module/VuFindAdmin/config/module.config.php | 1 + .../VuFindTheme/src/VuFindTheme/Initializer.php | 15 +++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/config/vufind/config.ini b/config/vufind/config.ini index dada5c60678..d76ba2ebd73 100644 --- a/config/vufind/config.ini +++ b/config/vufind/config.ini @@ -52,6 +52,9 @@ theme = sandal ; standard themes since they support responsive design. ;mobile_theme = mobile +; Uncomment the following line to use a different theme for Admin module. +;admin_theme = sandal + ; Automatic asset minification and concatenation setting. When active, HeadScript ; and HeadLink will concatenate and minify all viable files to reduce requests and ; load times. This setting is off by default. diff --git a/module/VuFindAdmin/config/module.config.php b/module/VuFindAdmin/config/module.config.php index 9188ef6306e..4bdb9bf1a5b 100644 --- a/module/VuFindAdmin/config/module.config.php +++ b/module/VuFindAdmin/config/module.config.php @@ -33,6 +33,7 @@ 'defaults' => [ 'controller' => 'Admin', 'action' => 'Home', + 'admin_route' => true, ], ], 'may_terminate' => true, diff --git a/module/VuFindTheme/src/VuFindTheme/Initializer.php b/module/VuFindTheme/src/VuFindTheme/Initializer.php index d90ca0524bb..202f7d8adeb 100644 --- a/module/VuFindTheme/src/VuFindTheme/Initializer.php +++ b/module/VuFindTheme/src/VuFindTheme/Initializer.php @@ -201,6 +201,21 @@ public function init() */ protected function pickTheme(?Request $request) { + // The admin theme should always be picked if + // - the Admin module is enabled AND + // - an admin theme is set AND + // - an admin route is requested (route configuration has an + // 'admin_route' => true default parameter). + if ( + isset($this->event) + && ($routeMatch = $this->event->getRouteMatch()) + && $routeMatch->getParam('admin_route') + && ($this->config->admin_enabled ?? false) + && ($adminTheme = ($this->config->admin_theme ?? false)) + ) { + return $adminTheme; + } + // Load standard configuration options: $standardTheme = $this->config->theme; if (PHP_SAPI == 'cli') { From 0d99804abc3af2e8195fd9f1bcbf24ae797eaac3 Mon Sep 17 00:00:00 2001 From: Aleisha Date: Fri, 6 Sep 2024 02:07:38 +1200 Subject: [PATCH 30/66] KohaRest: add option to include recalls in patron holds page (#3421) NOTE: This depends on Bug 36075 to be pushed to Koha https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=36075 Co-authored-by: Danyon Sewell --- config/vufind/KohaRest.ini | 11 +++- .../VuFind/src/VuFind/ILS/Driver/KohaRest.php | 60 +++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/config/vufind/KohaRest.ini b/config/vufind/KohaRest.ini index 872d7cc31a7..fe853d7ae7d 100644 --- a/config/vufind/KohaRest.ini +++ b/config/vufind/KohaRest.ini @@ -47,6 +47,8 @@ host = "http://koha-server/api" ; - updatecharges ; - payout ; - remaining_permissions +; - recalls +; - manage_recalls ; ; Add an API key to the user and copy the values for Client ID and Secret below. ; To add an API key in Koha, go to the patron screen and click More -> Manage API @@ -125,6 +127,11 @@ updateFields = frozen:frozenThrough:pickUpLocation ; is false. ;allowCancelInTransit = false +; Uncomment the following line to enable recalls (disabled by default). Requires a +; Koha version that includes +; https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=36075 +;enableRecalls = true + ; This section controls article request behavior. To enable, uncomment (at minimum) ; the HMACKeys and extraFields settings below. [StorageRetrievalRequests] @@ -160,10 +167,10 @@ extraFields = item-issue:acceptTerms:pickUpLocation ; false. Requires Koha REST DI plugin version 23.11.06 or later (earlier versions ; included suspended holds by default). ;includeSuspendedHoldsInQueueLength = false -; This section allows libraries to define different custom itemLimit rules for +; This section allows libraries to define different custom itemLimit rules for ; different biblio-level item types. ; In Koha the biblio-level item type is defined in the 942$c subfield. -; Set 'itemLimit' to set a fallback value that will be used for any item types not given a more +; Set 'itemLimit' to set a fallback value that will be used for any item types not given a more ; specific setting. ; Set 'itemLimitByType' followed by a [] containing a string for the Koha biblio-level item type. ; The string after the equal sign is the number of items to display in the holdings tab. diff --git a/module/VuFind/src/VuFind/ILS/Driver/KohaRest.php b/module/VuFind/src/VuFind/ILS/Driver/KohaRest.php index 98654a13236..b8f1871bca4 100644 --- a/module/VuFind/src/VuFind/ILS/Driver/KohaRest.php +++ b/module/VuFind/src/VuFind/ILS/Driver/KohaRest.php @@ -902,6 +902,7 @@ public function getMyHolds($patron) $entry['pickup_library_id'] ?? null ), 'create' => $this->convertDate($entry['hold_date'] ?? null), + '__create' => $entry['hold_date'] ?? null, 'expire' => $available ? null : $expirationDate, 'position' => $entry['priority'], 'available' => $available, @@ -921,6 +922,65 @@ public function getMyHolds($patron) ]; } + if ($this->config['Holds']['enableRecalls'] ?? false) { + $result = $this->makeRequest( + [ + 'path' => 'v1/recalls', + 'query' => [ + 'patron_id' => $patron['id'], + 'completed' => 'false', + '_match' => 'exact', + '_per_page' => -1, + ], + ] + ); + + foreach ($result['data'] as $entry) { + $biblio = $this->getBiblio($entry['biblio_id']); + $volume = ''; + if ($entry['item_id'] ?? null) { + $item = $this->getItem($entry['item_id']); + $volume = $item['serial_issue_number']; + } + $available = !empty($entry['waiting_date']); + $inTransit = !empty($entry['status']) && $entry['status'] == 'in_transit'; + $requestId = $entry['recall_id']; + $cancelDetails = ''; + $updateDetails = ($available || $inTransit) ? '' : $requestId; + // Note: Expiration date is the last interest date until the hold becomes + // available for pickup. Then it becomes the last pickup date. + $expirationDate = $this->convertDate($entry['expiration_date']); + $holds[] = [ + 'id' => $entry['biblio_id'], + 'item_id' => $entry['recall_id'], + 'reqnum' => $requestId, + 'location' => $this->getLibraryName( + $entry['pickup_library_id'] ?? null + ), + 'create' => $this->convertDate($entry['hold_date'] ?? null), + '__create' => $entry['hold_date'] ?? null, + 'expire' => $available ? null : $expirationDate, + 'position' => $entry['priority'], + 'available' => $available, + 'last_pickup_date' => $available ? $expirationDate : null, + 'in_transit' => $inTransit, + 'title' => $this->getBiblioTitle($biblio), + 'isbn' => $biblio['isbn'] ?? '', + 'issn' => $biblio['issn'] ?? '', + 'publication_year' => $biblio['copyright_date'] + ?? $biblio['publication_year'] ?? '', + 'volume' => $volume, + 'cancel_details' => $cancelDetails, + 'updateDetails' => $updateDetails, + ]; + } + } + $callback = function ($a, $b) { + return $a['__create'] === $b['__create'] + ? $a['item_id'] <=> $b['item_id'] + : $a['__create'] <=> $b['__create']; + }; + usort($holds, $callback); return $holds; } From 8ee49d3f7cd31e0139b8fe11356457c4b8f51951 Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Thu, 5 Sep 2024 13:04:55 -0400 Subject: [PATCH 31/66] FOLIO: only pull due dates from open loans. (#3907) --- module/VuFind/src/VuFind/ILS/Driver/Folio.php | 2 +- .../tests/fixtures/folio/responses/get-holding-checkedout.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/VuFind/src/VuFind/ILS/Driver/Folio.php b/module/VuFind/src/VuFind/ILS/Driver/Folio.php index 53f340c24cd..097f0bf2f35 100644 --- a/module/VuFind/src/VuFind/ILS/Driver/Folio.php +++ b/module/VuFind/src/VuFind/ILS/Driver/Folio.php @@ -889,7 +889,7 @@ protected function getDateTimeFromString(string $str): DateTime */ protected function getDueDate($itemId, $showTime) { - $query = 'itemId==' . $itemId; + $query = 'itemId==' . $itemId . ' AND status.name==Open'; foreach ( $this->getPagedResults( 'loans', diff --git a/module/VuFind/tests/fixtures/folio/responses/get-holding-checkedout.json b/module/VuFind/tests/fixtures/folio/responses/get-holding-checkedout.json index cfdf1259c7a..926be5dd59b 100644 --- a/module/VuFind/tests/fixtures/folio/responses/get-holding-checkedout.json +++ b/module/VuFind/tests/fixtures/folio/responses/get-holding-checkedout.json @@ -188,7 +188,7 @@ "expectedMethod": "GET", "expectedPath": "\/circulation\/loans", "expectedParams": { - "query": "itemId==itemid", + "query": "itemId==itemid AND status.name==Open", "offset": 0, "limit": 1000 }, From 73e5cdec162a53b8a7d2f91d0ec3a350cacde00e Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Thu, 5 Sep 2024 14:56:06 -0400 Subject: [PATCH 32/66] Related record module: more by author (#3908) --- config/vufind/config.ini | 3 + languages/en.ini | 1 + .../src/VuFind/Related/MoreByAuthorSolr.php | 124 ++++++++++++++++++ .../src/VuFind/Related/PluginManager.php | 2 + .../Related/MoreByAuthorSolrTest.php | 86 ++++++++++++ .../src/VuFindTest/Related/SimilarTest.php | 18 ++- .../templates/Related/MoreByAuthorSolr.phtml | 9 ++ .../templates/Related/Similar.phtml | 28 +--- .../templates/Related/Similar/item.phtml | 25 ++++ .../templates/Related/MoreByAuthorSolr.phtml | 9 ++ .../templates/Related/Similar.phtml | 28 +--- .../templates/Related/Similar/item.phtml | 25 ++++ 12 files changed, 294 insertions(+), 64 deletions(-) create mode 100644 module/VuFind/src/VuFind/Related/MoreByAuthorSolr.php create mode 100644 module/VuFind/tests/unit-tests/src/VuFindTest/Related/MoreByAuthorSolrTest.php create mode 100644 themes/bootstrap3/templates/Related/MoreByAuthorSolr.phtml create mode 100644 themes/bootstrap3/templates/Related/Similar/item.phtml create mode 100644 themes/bootstrap5/templates/Related/MoreByAuthorSolr.phtml create mode 100644 themes/bootstrap5/templates/Related/Similar/item.phtml diff --git a/config/vufind/config.ini b/config/vufind/config.ini index d76ba2ebd73..55856f6046f 100644 --- a/config/vufind/config.ini +++ b/config/vufind/config.ini @@ -2059,9 +2059,12 @@ hide_holdings[] = "World Wide Web" ; Available options: ; Channels - Display links to channels of content related to record ; Bookplate - Display a bookplate image or something similar +; MoreByAuthorSolr - Display books from the Solr index matching the current +; record's primary author. ; Similar - Similarity based on Solr lookup ; WorldCatSimilar - Similarity based on WorldCat lookup related[] = "Similar" +;related[] = "MoreByAuthorSolr" ; The following settings are for the related Bookplate module. They can be ; enabled here by uncommenting below or from another config file of your choice. diff --git a/languages/en.ini b/languages/en.ini index 9fc9f5b7d8c..56ec648c798 100644 --- a/languages/en.ini +++ b/languages/en.ini @@ -842,6 +842,7 @@ More options = "More options" More Summon results = "More Summon results…" More Topics = "More Topics" more_authors_abbrev = "et al." +more_by_author = "Also by %%name%%" more_ellipsis = "more…" more_info_toggle = "Show/hide more info." more_options_ellipsis = "More options…" diff --git a/module/VuFind/src/VuFind/Related/MoreByAuthorSolr.php b/module/VuFind/src/VuFind/Related/MoreByAuthorSolr.php new file mode 100644 index 00000000000..84bafdba8c7 --- /dev/null +++ b/module/VuFind/src/VuFind/Related/MoreByAuthorSolr.php @@ -0,0 +1,124 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:related_records_modules Wiki + */ + +namespace VuFind\Related; + +use VuFindSearch\Command\SearchCommand; +use VuFindSearch\Query\Query; + +use function count; + +/** + * Related Records: Solr-based "more by author" + * + * @category VuFind + * @package Related_Records + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:related_records_modules Wiki + */ +class MoreByAuthorSolr implements RelatedInterface +{ + /** + * Similar records + * + * @var array + */ + protected array $results = []; + + /** + * Author being searched + * + * @var string + */ + protected string $author = ''; + + /** + * Maximum number of titles to suggest + * + * @var int + */ + protected int $maxRecommendations = 5; + + /** + * Constructor + * + * @param \VuFindSearch\Service $searchService Search service + */ + public function __construct(protected \VuFindSearch\Service $searchService) + { + } + + /** + * Establishes base settings for making recommendations. + * + * @param string $settings Settings from config.ini + * @param \VuFind\RecordDriver\AbstractBase $driver Record driver object + * + * @return void + */ + public function init($settings, $driver) + { + $this->results = []; + if ($this->author = $driver->tryMethod('getPrimaryAuthor')) { + $queryStr = '"' . addcslashes($this->author, '"') . '"'; + $query = new Query($queryStr, 'Author'); + $command = new SearchCommand(DEFAULT_SEARCH_BACKEND, $query, 0, $this->maxRecommendations + 1); + foreach ($this->searchService->invoke($command)->getResult() as $result) { + if (count($this->results) >= $this->maxRecommendations) { + break; + } + if ($result->getUniqueID() != $driver->getUniqueID()) { + $this->results[] = $result; + } + } + } + } + + /** + * Get name of author being searched for. + * + * @return string + */ + public function getName(): string + { + return $this->author; + } + + /** + * Get an array of Record Driver objects representing items similar to the one + * passed to the constructor. + * + * @return array + */ + public function getResults(): array + { + return $this->results; + } +} diff --git a/module/VuFind/src/VuFind/Related/PluginManager.php b/module/VuFind/src/VuFind/Related/PluginManager.php index 6f320158433..a1bcb44a024 100644 --- a/module/VuFind/src/VuFind/Related/PluginManager.php +++ b/module/VuFind/src/VuFind/Related/PluginManager.php @@ -51,6 +51,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager 'channels' => Channels::class, 'bookplate' => Bookplate::class, 'editions' => Deprecated::class, + 'morebyauthorsolr' => MoreByAuthorSolr::class, 'similar' => Similar::class, 'worldcateditions' => Deprecated::class, 'worldcatsimilar' => WorldCatSimilar::class, @@ -65,6 +66,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager Channels::class => InvokableFactory::class, Bookplate::class => BookplateFactory::class, Deprecated::class => InvokableFactory::class, + MoreByAuthorSolr::class => SimilarFactory::class, Similar::class => SimilarFactory::class, WorldCatSimilar::class => SimilarFactory::class, ]; diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Related/MoreByAuthorSolrTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Related/MoreByAuthorSolrTest.php new file mode 100644 index 00000000000..aabab328af2 --- /dev/null +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Related/MoreByAuthorSolrTest.php @@ -0,0 +1,86 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:testing:unit_tests Wiki + */ + +namespace VuFindTest\Related; + +use VuFind\Related\MoreByAuthorSolr; +use VuFindSearch\Query\Query; + +/** + * MoreByAuthorSolr Related Items Test Class + * + * @category VuFind + * @package Tests + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:testing:unit_tests Wiki + */ +class MoreByAuthorSolrTest extends \PHPUnit\Framework\TestCase +{ + /** + * Test results. + * + * @return void + */ + public function testGetResults() + { + // Similar is really just a thin wrapper around the search service; make + // sure it does its job properly with the help of some mocks. + $driver = $this->getMockBuilder(\VuFind\RecordDriver\SolrDefault::class) + ->onlyMethods(['getPrimaryAuthor', 'getUniqueId']) + ->getMock(); + $driver->method('getUniqueId')->willReturn('fakeid'); + $driver->method('getPrimaryAuthor')->willReturn('Smith, John'); + + $driver2 = $this->getMockBuilder(\VuFind\RecordDriver\SolrDefault::class) + ->onlyMethods(['getPrimaryAuthor', 'getUniqueId']) + ->getMock(); + $driver2->method('getUniqueId')->willReturn('fakeid2'); + $driver2->method('getPrimaryAuthor')->willReturn('Smith, John'); + + $commandObj = $this->createMock(\VuFindSearch\Command\AbstractBase::class); + $commandObj->expects($this->once())->method('getResult')->willReturn([$driver, $driver2]); + $checkCommand = function ($command) { + $this->assertEquals(\VuFindSearch\Command\SearchCommand::class, $command::class); + $this->assertEquals('Solr', $command->getTargetIdentifier()); + $expectedQuery = new Query('"Smith, John"', 'Author'); + $this->assertEquals($expectedQuery, $command->getArguments()[0]); + return true; + }; + $service = $this->getMockBuilder(\VuFindSearch\Service::class) + ->getMock(); + $service->expects($this->once())->method('invoke') + ->with($this->callback($checkCommand)) + ->willReturn($commandObj); + $related = new MoreByAuthorSolr($service); + $related->init('', $driver); + $this->assertEquals('Smith, John', $related->getName()); + $this->assertEquals([$driver2], $related->getResults()); + } +} diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Related/SimilarTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Related/SimilarTest.php index 5252acb239e..c1840aadbe5 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/Related/SimilarTest.php +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Related/SimilarTest.php @@ -54,25 +54,23 @@ public function testGetResults() $driver = $this->getMockBuilder(\VuFind\RecordDriver\SolrDefault::class) ->onlyMethods(['getUniqueId']) ->getMock(); - $driver->expects($this->once()) - ->method('getUniqueId') - ->will($this->returnValue('fakeid')); + $driver->expects($this->once())->method('getUniqueId')->willReturn('fakeid'); $commandObj = $this->getMockBuilder(\VuFindSearch\Command\AbstractBase::class) ->disableOriginalConstructor() ->getMock(); $commandObj->expects($this->once())->method('getResult') - ->will($this->returnValue(['fakeresponse'])); + ->willReturn(['fakeresponse']); $checkCommand = function ($command) { - return $command::class === \VuFindSearch\Command\SimilarCommand::class - && $command->getTargetIdentifier() === 'Solr' - && $command->getArguments()[0] === 'fakeid'; + $this->assertEquals(\VuFindSearch\Command\SimilarCommand::class, $command::class); + $this->assertEquals('Solr', $command->getTargetIdentifier()); + $this->assertEquals('fakeid', $command->getArguments()[0]); + return true; }; - $service = $this->getMockBuilder(\VuFindSearch\Service::class) - ->getMock(); + $service = $this->createMock(\VuFindSearch\Service::class); $service->expects($this->once())->method('invoke') ->with($this->callback($checkCommand)) - ->will($this->returnValue($commandObj)); + ->willReturn($commandObj); $similar = new Similar($service); $similar->init('', $driver); $this->assertEquals(['fakeresponse'], $similar->getResults()); diff --git a/themes/bootstrap3/templates/Related/MoreByAuthorSolr.phtml b/themes/bootstrap3/templates/Related/MoreByAuthorSolr.phtml new file mode 100644 index 00000000000..80678288d9b --- /dev/null +++ b/themes/bootstrap3/templates/Related/MoreByAuthorSolr.phtml @@ -0,0 +1,9 @@ +related->getResults(); ?> + +

    transEsc('more_by_author', ['%%name%%' => $this->related->getName()])?>

    +
      + +
    • render('Related/Similar/item.phtml', compact('data'))?>
    • + +
    + diff --git a/themes/bootstrap3/templates/Related/Similar.phtml b/themes/bootstrap3/templates/Related/Similar.phtml index a30d6354628..7d1773ccb7d 100644 --- a/themes/bootstrap3/templates/Related/Similar.phtml +++ b/themes/bootstrap3/templates/Related/Similar.phtml @@ -3,33 +3,7 @@
      -
    • - 'related__icon']; - - $formats = $data->getFormats(); - $format = $formats[0] ?? null; - $icon = $format - ? preg_replace('/[^a-z0-9]/', '', strtolower($format)) - : 'default'; - - if ($format) { - $attrs['title'] = $format; - } - ?> - - icon('format-' . $icon, $attrs) ?> - escapeHtml($data->getTitle())?> - - getPrimaryAuthors(); ?> - -
      transEsc('by')?>: escapeHtml($authors[0]);?> 1): ?>, transEsc('more_authors_abbrev')?> - - getPublicationDates(); ?> - -
      transEsc('Published')?>: (escapeHtml($pubDates[0])?>) - -
    • +
    • render('Related/Similar/item.phtml', compact('data'))?>
    diff --git a/themes/bootstrap3/templates/Related/Similar/item.phtml b/themes/bootstrap3/templates/Related/Similar/item.phtml new file mode 100644 index 00000000000..9bc365e6585 --- /dev/null +++ b/themes/bootstrap3/templates/Related/Similar/item.phtml @@ -0,0 +1,25 @@ + 'related__icon']; + + $formats = $data->getFormats(); + $format = $formats[0] ?? null; + $icon = $format + ? preg_replace('/[^a-z0-9]/', '', strtolower($format)) + : 'default'; + + if ($format) { + $attrs['title'] = $format; + } +?> + + icon('format-' . $icon, $attrs) ?> + escapeHtml($data->getTitle())?> + +getPrimaryAuthors(); ?> + +
    transEsc('by')?>: escapeHtml($authors[0]);?> 1): ?>, transEsc('more_authors_abbrev')?> + +getPublicationDates(); ?> + +
    transEsc('Published')?>: (escapeHtml($pubDates[0])?>) + diff --git a/themes/bootstrap5/templates/Related/MoreByAuthorSolr.phtml b/themes/bootstrap5/templates/Related/MoreByAuthorSolr.phtml new file mode 100644 index 00000000000..80678288d9b --- /dev/null +++ b/themes/bootstrap5/templates/Related/MoreByAuthorSolr.phtml @@ -0,0 +1,9 @@ +related->getResults(); ?> + +

    transEsc('more_by_author', ['%%name%%' => $this->related->getName()])?>

    +
      + +
    • render('Related/Similar/item.phtml', compact('data'))?>
    • + +
    + diff --git a/themes/bootstrap5/templates/Related/Similar.phtml b/themes/bootstrap5/templates/Related/Similar.phtml index a30d6354628..7d1773ccb7d 100644 --- a/themes/bootstrap5/templates/Related/Similar.phtml +++ b/themes/bootstrap5/templates/Related/Similar.phtml @@ -3,33 +3,7 @@
      -
    • - 'related__icon']; - - $formats = $data->getFormats(); - $format = $formats[0] ?? null; - $icon = $format - ? preg_replace('/[^a-z0-9]/', '', strtolower($format)) - : 'default'; - - if ($format) { - $attrs['title'] = $format; - } - ?> - - icon('format-' . $icon, $attrs) ?> - escapeHtml($data->getTitle())?> - - getPrimaryAuthors(); ?> - -
      transEsc('by')?>: escapeHtml($authors[0]);?> 1): ?>, transEsc('more_authors_abbrev')?> - - getPublicationDates(); ?> - -
      transEsc('Published')?>: (escapeHtml($pubDates[0])?>) - -
    • +
    • render('Related/Similar/item.phtml', compact('data'))?>
    diff --git a/themes/bootstrap5/templates/Related/Similar/item.phtml b/themes/bootstrap5/templates/Related/Similar/item.phtml new file mode 100644 index 00000000000..9bc365e6585 --- /dev/null +++ b/themes/bootstrap5/templates/Related/Similar/item.phtml @@ -0,0 +1,25 @@ + 'related__icon']; + + $formats = $data->getFormats(); + $format = $formats[0] ?? null; + $icon = $format + ? preg_replace('/[^a-z0-9]/', '', strtolower($format)) + : 'default'; + + if ($format) { + $attrs['title'] = $format; + } +?> + + icon('format-' . $icon, $attrs) ?> + escapeHtml($data->getTitle())?> + +getPrimaryAuthors(); ?> + +
    transEsc('by')?>: escapeHtml($authors[0]);?> 1): ?>, transEsc('more_authors_abbrev')?> + +getPublicationDates(); ?> + +
    transEsc('Published')?>: (escapeHtml($pubDates[0])?>) + From fc8a5d3355b9da7881199bb77396d6f34d998ab6 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Fri, 6 Sep 2024 09:49:29 +0300 Subject: [PATCH 33/66] Fix Shibboleth authenticator constructor params. --- module/Finna/src/Finna/Auth/Shibboleth.php | 16 +++++----------- .../Finna/src/Finna/Auth/ShibbolethFactory.php | 1 + 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/module/Finna/src/Finna/Auth/Shibboleth.php b/module/Finna/src/Finna/Auth/Shibboleth.php index 3e3ac898111..bdf119e18c7 100644 --- a/module/Finna/src/Finna/Auth/Shibboleth.php +++ b/module/Finna/src/Finna/Auth/Shibboleth.php @@ -33,6 +33,7 @@ namespace Finna\Auth; use Laminas\Http\PhpEnvironment\Request; +use VuFind\Auth\ILSAuthenticator; use VuFind\Auth\Shibboleth\ConfigurationLoaderInterface; use VuFind\Db\Entity\UserEntityInterface; use VuFind\Exception\Auth as AuthException; @@ -50,30 +51,23 @@ */ class Shibboleth extends \VuFind\Auth\Shibboleth { - /** - * ILS connection - * - * @var \Finna\ILS\Connection - */ - protected $ils; - /** * Constructor * * @param \Laminas\Session\ManagerInterface $sessionManager Session manager * @param ConfigurationLoaderInterface $configurationLoader Configuration loader * @param Request $request Http request object + * @param ILSAuthenticator $ilsAuthenticator ILS authenticator * @param \Finna\ILS\Connection $ils ILS connection */ public function __construct( \Laminas\Session\ManagerInterface $sessionManager, ConfigurationLoaderInterface $configurationLoader, Request $request, - \Finna\ILS\Connection $ils + ILSAuthenticator $ilsAuthenticator, + protected \Finna\ILS\Connection $ils ) { - $this->sessionManager = $sessionManager; - $this->configurationLoader = $configurationLoader; - $this->request = $request; + parent::__construct($sessionManager, $configurationLoader, $request, $ilsAuthenticator); $this->ils = $ils; } diff --git a/module/Finna/src/Finna/Auth/ShibbolethFactory.php b/module/Finna/src/Finna/Auth/ShibbolethFactory.php index cd2fc05a1bd..1f21a5abc8b 100644 --- a/module/Finna/src/Finna/Auth/ShibbolethFactory.php +++ b/module/Finna/src/Finna/Auth/ShibbolethFactory.php @@ -77,6 +77,7 @@ public function __invoke( $container->get(\Laminas\Session\SessionManager::class), $loader, $request, + $container->get(\VuFind\Auth\ILSAuthenticator::class), $container->get(\VuFind\ILS\Connection::class) ); } From f6526b14b3e9b4cd7449ba41df047a1a5c7394c5 Mon Sep 17 00:00:00 2001 From: Pasi Tiisanoja Date: Fri, 6 Sep 2024 10:05:13 +0300 Subject: [PATCH 34/66] [FINNA-2264] Show format field in RSS carousel, add title truncation configuration. (#2999) --- local/config/vufind/rss.ini.sample | 3 + module/Finna/src/Finna/Feed/Feed.php | 27 ++- module/Finna/src/Finna/Feed/FeedFactory.php | 4 +- .../Reader/Extension/DublinCore/Entry.php | 64 +++++++ themes/finna2/js/finna-feed-element.js | 6 +- themes/finna2/less/finna/feed.less | 33 +++- themes/finna2/less/global/icons.less | 172 ++++++++++++------ themes/finna2/less/global/variables.less | 2 +- .../templates/ajax/feed-carousel-item.phtml | 12 +- 9 files changed, 257 insertions(+), 66 deletions(-) create mode 100644 module/Finna/src/Finna/Feed/Reader/Extension/DublinCore/Entry.php diff --git a/local/config/vufind/rss.ini.sample b/local/config/vufind/rss.ini.sample index bd491c24c51..56d078152ee 100644 --- a/local/config/vufind/rss.ini.sample +++ b/local/config/vufind/rss.ini.sample @@ -90,9 +90,11 @@ ;; Optional carousel settings: ; titlePosition = "bottom" Display item title below image. +; titleTruncateSize = [size] // Title truncation size (default: 70). ; height = [pixels] Carousel height ; autoplay = [false|milliseconds] Autoplay slide change interval (autoplay is off by default). ; dots = [0|1] Display current slide indicator (default 1). +; displayFormatHeader = [true|false] Determines whether to display the format in the carousel item's header (default: false). ;; Optional slider settings: @@ -123,6 +125,7 @@ ; content[image] = 0 ; content[date] = 0 ; content[description] = 0 +; content[format] = 0 [carousel] type = "carousel" diff --git a/module/Finna/src/Finna/Feed/Feed.php b/module/Finna/src/Finna/Feed/Feed.php index 15307fe1bf1..c70c2861f27 100644 --- a/module/Finna/src/Finna/Feed/Feed.php +++ b/module/Finna/src/Finna/Feed/Feed.php @@ -38,6 +38,7 @@ use Laminas\Feed\Reader\Reader; use Laminas\Mvc\Controller\Plugin\Url; use Laminas\View\Helper\ServerUrl; +use Psr\Container\ContainerInterface; use VuFind\Cache\Manager as CacheManager; use VuFindTheme\View\Helper\ImageLink; @@ -450,6 +451,8 @@ public function parseFeed($channel, $config, $id = null) $contentDateFormat = $config->contentDateFormat ?? 'j.n.Y'; $fullDateFormat = $config->fullDateFormat ?? 'j.n.Y'; $cleanContent = $config->cleanContent ?? true; + $titleTruncateSize = (int)($config->titleTruncateSize ?? 70); + $displayFormatHeader = $config->displayFormatHeader ?? false; $contentNavigation = $config->feedcontentNavigation ?? true; $nextArticles = $config->feedcontentNextArticles ?? false; @@ -465,6 +468,7 @@ public function parseFeed($channel, $config, $id = null) 'title' => 'getTitle', 'text' => 'getContent', 'description' => 'getDescription', + 'format' => 'getFormat', 'image' => 'getEnclosure', 'link' => 'getLink', 'date' => 'getDateCreated', @@ -501,6 +505,8 @@ public function parseFeed($channel, $config, $id = null) } $data = []; $data['modal'] = $modal; + $data['titleTruncateSize'] = $titleTruncateSize; + $data['displayFormatHeader'] = $displayFormatHeader; foreach ($content as $setting => $method) { if ( !isset($elements[$setting]) @@ -684,10 +690,29 @@ public function parseFeed($channel, $config, $id = null) 'allowedImages', 'contentNavigation', 'nextArticles', - 'additionalHtml' + 'additionalHtml', + 'titleTruncateSize' ); } + /** + * Set up custom extensions + * + * @param ContainerInterface $container Service container + * + * @return void + */ + public function registerExtensions(ContainerInterface $container) + { + $manager = new \Laminas\Feed\Reader\ExtensionPluginManager($container); + $manager->setInvokableClass( + 'DublinCore\Entry', + \Finna\Feed\Reader\Extension\DublinCore\Entry::class + ); + Reader::setExtensionManager($manager); + Reader::registerExtension('DublinCore'); + } + /** * Process item content * diff --git a/module/Finna/src/Finna/Feed/FeedFactory.php b/module/Finna/src/Finna/Feed/FeedFactory.php index 53b3dbb700d..1b0078bf6dd 100644 --- a/module/Finna/src/Finna/Feed/FeedFactory.php +++ b/module/Finna/src/Finna/Feed/FeedFactory.php @@ -73,7 +73,7 @@ public function __invoke( } $config = $container->get(\VuFind\Config\PluginManager::class); $renderer = $container->get('ViewRenderer'); - return new $requestedName( + $feed = new $requestedName( $config->get('config'), $config->get('rss'), $config->get('rss-organisation-page'), @@ -84,5 +84,7 @@ public function __invoke( $renderer->plugin('cleanHtml'), $container->get(\Finna\OrganisationInfo\OrganisationInfo::class) ); + $feed->registerExtensions($container); + return $feed; } } diff --git a/module/Finna/src/Finna/Feed/Reader/Extension/DublinCore/Entry.php b/module/Finna/src/Finna/Feed/Reader/Extension/DublinCore/Entry.php new file mode 100644 index 00000000000..7fa644a1d86 --- /dev/null +++ b/module/Finna/src/Finna/Feed/Reader/Extension/DublinCore/Entry.php @@ -0,0 +1,64 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ + +namespace Finna\Feed\Reader\Extension\DublinCore; + +use Laminas\Feed\Reader\Extension\DublinCore\Entry as ParentEntry; + +use function array_key_exists; + +/** + * Laminas\Feed\Entry extension for Dublin Core + * + * @category VuFind + * @package Feed_Plugins + * @author Pasi Tiisanoja + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ + +class Entry extends ParentEntry +{ + /** + * Get a Dublin Core format. + * + * @return string + */ + public function getFormat() + { + if (array_key_exists('format', $this->data)) { + return $this->data['format']; + } + + $format = (string)$this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc11:format)') + ?: (string)$this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc10:format)'); + + return $this->data['format'] = $format ?: null; + } +} diff --git a/themes/finna2/js/finna-feed-element.js b/themes/finna2/js/finna-feed-element.js index df64e5cb5cb..2387f7639fb 100644 --- a/themes/finna2/js/finna-feed-element.js +++ b/themes/finna2/js/finna-feed-element.js @@ -60,11 +60,11 @@ class FinnaFeedElement extends HTMLElement { // Move title field below image let maxH = 0; this.querySelectorAll('.carousel-slide-header p').forEach(el => { - maxH = Math.max(maxH, el.getBoundingClientRect().height + 10); el.classList.add('title-bottom'); - el.parentNode.classList.add('title-bottom'); + maxH = Math.max(maxH, el.getBoundingClientRect().height); + }); - this.querySelectorAll('.carousel-slide-header, .carousel-slide-header p').forEach(el => { + this.querySelectorAll('.carousel-slide-header p').forEach(el => { el.style.minHeight = el.style.height = `${maxH}px`; }); this.querySelectorAll('.carousel-feed .carousel-text').forEach(el => { diff --git a/themes/finna2/less/finna/feed.less b/themes/finna2/less/finna/feed.less index 03539f0bb3c..f707c00140e 100644 --- a/themes/finna2/less/finna/feed.less +++ b/themes/finna2/less/finna/feed.less @@ -731,9 +731,10 @@ finna-feed.carousel.splide--ltr { .carousel-text { &:not(.no-text) { opacity: 1; + z-index: 1; } } - .carousel-slide-header:not(.title-bottom) { + .carousel-slide-header p:not(.title-bottom) { opacity: 0; } .carousel-text.scrollable { @@ -754,7 +755,7 @@ finna-feed.carousel.splide--ltr { .carousel-text:not(.no-text) { opacity: 1; } - .carousel-slide-header:not(.title-bottom) { + .carousel-slide-header p:not(.title-bottom) { opacity: 0; } .carousel-text.scrollable { @@ -769,15 +770,33 @@ finna-feed.carousel.splide--ltr { } } } + .carousel-header-format { + display: inline-block; + font-weight: normal; + font-size: 10px; + border: 1px solid #fff; + margin-top: 2px; + margin-bottom: 2px; + padding: 2px 6px 2px 6px; + border-radius: 10px; + text-shadow: none; + } .feed-link { flex-flow: column; } .wrapper { flex: 1 1 100%; width: 100%; + &.iconlabel::before { + color: white; + mix-blend-mode: difference; + position: absolute; + font-size: 39px; + } img { max-width: none; max-height: 100%; + position: relative; } } .carousel-text { @@ -809,10 +828,18 @@ finna-feed.carousel.splide--ltr { flex-direction: column; position: relative; p { + .carousel-header-title { + display: block; + } &.title-bottom { position: initial; height: 100%; width: 100%; + padding-bottom: 10px; + .carousel-header-title { + display: inline-block; + width: 100%; + } } position: absolute; bottom: 0; @@ -926,7 +953,7 @@ finna-feed.carousel-slider.splide--ltr { finna-feed.carousel-slider.splide--ltr { .slider-text-part { .slider-title { - font-size: @font-size-h2; + font-size: @font-size-h2; } } &.image-right .feed-link { diff --git a/themes/finna2/less/global/icons.less b/themes/finna2/less/global/icons.less index f1979c10d2c..43698f65be2 100644 --- a/themes/finna2/less/global/icons.less +++ b/themes/finna2/less/global/icons.less @@ -44,109 +44,175 @@ table .iconlabel { letter-spacing: 0px; font-size: 1em; } -.iconlabel.format-0aipa:before { - content: "\e8cc"; -} -.iconlabel.format-unknownname:before, -.iconlabel.format-personalname:before { - font-family: finnaicons; +.iconlabel[class*="unknownname"]:before, +.iconlabel[class*="personalname"]:before { content: "\e922"; } -.iconlabel.format-corporatename-alt:before { - font-family: finnaicons; +.iconlabel[class*="corporatename-alt"]:before { content: "\e921"; } -.iconlabel.format-corporatename:before { - font-family: finnaicons; +.iconlabel[class*="corporatename"]:before { content: "\e923"; } -.iconlabel.format-familyname:before { - font-family: finnaicons; +.iconlabel[class*="familyname"]:before { content: "\e8ba"; } -.iconlabel.format-1bookebook:before, .iconlabel.format-1bookebooksection:before, .iconlabel.format-1otherelectronic:before, .iconlabel.format-ebook:before { +.iconlabel[class*="format-1other"]:before, +.iconlabel[class*="format-feed-other"]:before { + content: "\e00d"; +} +.iconlabel[class*="format-1othermicrofilm"]:before, +.iconlabel[class*="format-feed-othermicrofilm"]:before { + font-family: FontAwesome; + content: @fa-var-film; +} +.iconlabel[class*="format-1otherinterview"]:before, +.iconlabel[class*="format-feed-otherinterview"]:before { + font-family: FontAwesome; + content: @fa-var-microphone; +} +.iconlabel.format-book:before, +.iconlabel[class*="format-1book"]:before, +.iconlabel[class*="format-feed-book"]:before { + content: "\e616"; +} +.iconlabel[class*="format-1bookebook"]:before, +.iconlabel[class*="format-1bookebooksection"]:before, +.iconlabel.format-1bookotherelectronic:before, +.iconlabel[class*="format-feed-bookebook"]:before, +.iconlabel[class*="format-feed-bookbooksection"]:before, +.iconlabel.format-feed-bookotherelectronic:before { content: "\e617"; } -.iconlabel[class*="format-2bookaudiobook"]:before { +.iconlabel[class*="format-1bookaudiobook"]:before, +.iconlabel[class*="format-2bookaudiobook"]:before, +.iconlabel[class*="format-feed-bookaudiobook"]:before { content: "\e8c4"; } -.iconlabel.format-2bookaudiobookdaisy:before { +.iconlabel.format-bookaudiobookdaisy:before, +.iconlabel.format-feed-bookaudiobookdaisy:before { content: "\e807"; } -.iconlabel.format-kirja:before, .iconlabel.format-book:before, .iconlabel.format-1bookbook:before, .iconlabel.kirja:before, .iconlabel.format-1bookbooksection:before, .iconlabel.format-1bookbraille:before { - content: "\e616"; -} -.iconlabel.format-1journalarticle:before, .iconlabel.format-1journaljournal:before, .iconlabel.format-1journalserial:before, .iconlabel.format-1journalnewspaper:before, .iconlabel.format-1journalappendix:before, .iconlabel.format-1journalnewspaperarticle:before, .iconlabel.format-journal:before, .iconlabel.format-newspaper:before, .iconlabel.format-news:before, .iconlabel.format-report:before, .iconlabel.format-review:before, .iconlabel.format-academicjournal:before, .iconlabel.format-1othertextephemera:before { +.iconlabel.format-newspaper:before, +.iconlabel.format-journal:before, +.iconlabel[class*="format-1journal"]:before, +.iconlabel[class*="format-feed-journal"]:before, +.iconlabel.format-1othertextephemera:before { content: "\e001"; } -.iconlabel.format-1journaleserial:before, .iconlabel.format-1journalearticle:before, .iconlabel.format-1journalejournal:before, .iconlabel.format-1journalenewspaper:before { +.iconlabel[class*="format-1journaleserial"]:before, +.iconlabel[class*="format-1journalearticle"]:before, +.iconlabel[class*="format-1journalejournal"]:before, +.iconlabel[class*="format-1journalenewspaper"]:before, +.iconlabel[class*="format-feed-journaleserial"]:before, +.iconlabel[class*="format-feed-journalearticle"]:before, +.iconlabel[class*="format-feed-journalejournal"]:before, +.iconlabel[class*="format-feed-journalenewspaper"]:before { content: "\e60d"; } -.iconlabel.format-1placebuilding:before, .iconlabel.format-1placeplace:before, .iconlabel.format-1placearchaeologicalsite:before { +.iconlabel[class*="format-1place"]:before, +.iconlabel[class*="format-feed-place"]:before { content: "\e901"; } -.iconlabel.format-1otherother:before, .iconlabel.format-1othercollection:before, .iconlabel.format-1othersubunit:before, .iconlabel.format-1otherkit:before, .iconlabel.format-1othermanuscript:before, .iconlabel.format-1othertext:before, .iconlabel.format-1othercdrom:before { - content: "\e00d"; -} -.iconlabel.format-1othermicrofilm:before { - font-family: FontAwesome; - content: @fa-var-film; -} -.iconlabel.format-1otherinterview:before { - font-family: FontAwesome; - content: @fa-var-microphone; -} -.iconlabel.format-manuscript:before, .iconlabel.format-1thesisother:before, .iconlabel.format-1thesisgradu:before, .iconlabel.format-1thesisthesis:before, .iconlabel.format-1thesislaudatur:before, .iconlabel.format-1thesismasters:before, .iconlabel.format-1thesisbachelorspolytechnic:before, .iconlabel.format-1thesisbachelors:before, .iconlabel.format-1thesismasterspolytechnic:before, .iconlabel.yamk:before, .iconlabel.format-1thesislicentiate:before, .iconlabel.format-1otherresearchdata:before { +.iconlabel.format-manuscript:before, +.iconlabel[class*="format-1othertextmanuscript"]:before, +.iconlabel[class*="format-1otherresearchdata"]:before, +.iconlabel[class*="format-1thesis"]:before, +.iconlabel[class*="format-feed-othertextmanuscript"]:before, +.iconlabel[class*="format-feed-otherresearchdata"]:before, +.iconlabel[class*="format-feed-thesis"]:before { content: "\e00c"; } -.iconlabel.format-0workofart:before, .iconlabel[class*="format-1workofart"]:before { +.iconlabel.format-0workofart:before, +.iconlabel[class*="format-1workofart"]:before, +.iconlabel[class*="format-feed-workofart"]:before { content: "\e00b"; } -.iconlabel[class*="format-1video"]:before { +.iconlabel.format-video:before, +.iconlabel[class*="format-1video"]:before, +.iconlabel[class*="format-feed-video"]:before { content: "\e00a"; } -.iconlabel[class*="format-1sound"]:before { +.iconlabel[class*="format-1sound"]:before, +.iconlabel[class*="format-feed-sound"]:before { content: "\e009"; } - .iconlabel.format-1soundcd:before, .iconlabel.format-1soundsounddisc:before, .iconlabel.format-1soundnonmusicalcd:before, .iconlabel.format-1soundnonmusicaldisc:before { + .iconlabel.format-1soundcd:before, + .iconlabel.format-1soundsounddisc:before, + .iconlabel.format-1soundnonmusicalcd:before, + .iconlabel.format-1soundnonmusicaldisc:before, + .iconlabel.format-feed-soundcd:before, + .iconlabel.format-feed-sounddisc:before, + .iconlabel.format-feed-soundnonmusicalcd:before, + .iconlabel.format-feed-soundnonmusicaldisc:before { content: "\e802"; } -.iconlabel.format-1soundsoundcassette:before, .iconlabel.format-1soundnonmusicalcassette:before, .iconlabel.format-1othertapecassette:before, .iconlabel.format-1otherdisccartridge:before { +.iconlabel.format-1soundsoundcassette:before, +.iconlabel.format-1soundnonmusicalcassette:before, +.iconlabel.format-1othertapecassette:before, +.iconlabel.format-1otherdisccartridge:before, +.iconlabel.format-feed-soundsoundcassette:before, +.iconlabel.format-feed-soundnonmusicalcassette:before, +.iconlabel.format-feed-othertapecassette:before, +.iconlabel.format-feed-otherdisccartridge:before { content: "\e8ad"; } -.iconlabel[class*="format-1image"]:before { +.iconlabel.format-photo:before, +.iconlabel[class*="format-1image"]:before, +.iconlabel[class*="format-feed-image"]:before { content: "\e008"; } -.iconlabel-smallpress:before, .iconlabel.format-1otherprint:before { - content: "\e007"; -} -.fa.fa-TOC:before, .iconlabel.format-1document:before, .iconlabel.format-1documentother:before, .iconlabel.format-1documentdigitizedarchiveitem:before, .iconlabel.format-1othertexttext:before, .iconlabel.format-1othertextdiary:before, .iconlabel.format-1othertextconferenceproceeding:before, .iconlabel.format-1othertextmanuscript:before, .iconlabel.format-1othertextresearchreport:before, .iconlabel.format-1othertextletter:before, .iconlabel.format-0manuscript:before { - font-family: finnaicons; +.iconlabel[class*="format-1document"]:before, +.iconlabel[class*="format-1othertext"]:before, +.iconlabel.format-0manuscript:before, +.iconlabel[class*="format-feed-document"]:before, +.iconlabel[class*="format-feed-othertext"]:before, +.iconlabel.format-feed-manuscript:before { content: "\e006"; } -.iconlabel[class*="format-1documentarchive"]:before, .iconlabel[class*="format-1documentdigitizedarchive"]:before, .iconlabel[class*="format-1documentseries"]:before, .iconlabel.format-1documentothercollection:before, .iconlabel.format-1documentcollection:before { - font-family: finnaicons; +.iconlabel[class*="format-1documentarchive"]:before, +.iconlabel[class*="format-1documentdigitizedarchive"]:before, +.iconlabel[class*="format-1documentseries"]:before, +.iconlabel.format-1documentothercollection:before, +.iconlabel.format-1documentcollection:before { content: "\e8cb"; } -.iconlabel.format-0note:before, .iconlabel.format-0musicalscore:before, .iconlabel[class*="format-1musicalscore"]:before { +.iconlabel.format-0note:before, +.iconlabel.format-0musicalscore:before, +.iconlabel[class*="format-1musicalscore"]:before, +.iconlabel.format-note:before, +.iconlabel.format-musicalscore:before { content: "\e005"; } -.iconlabel.format-0database:before { +.iconlabel.format-0database:before, +.iconlabel.format-feed-database:before { content: "\e004"; } -.iconlabel.esine:before, .iconlabel.format-1physicalobjectother:before, .iconlabel.format-1physicalobjectculturehistoricalobject:before, .iconlabel.format-0physicalobject:before { +.iconlabel[class*="format-0physicalobject"]:before, +.iconlabel[class*="format-1physicalobject"]:before, +.iconlabel[class*="format-feed-physicalobject"]:before { content: "\e003"; } -.iconlabel[class*="format-1map"]:before, .iconlabel.karttapallo:before { +.iconlabel[class*="format-1map"]:before, +.iconlabel[class*="format-feed-map"]:before +{ content: "\e002"; } -.iconlabel.format-0learningmaterial:before { +.iconlabel.format-0aipa:before, +.iconlabel.format-feed-aipa:before { + content: "\e8cc"; +} +.iconlabel.format-0learningmaterial:before, +.iconlabel.format-feed-learningmaterial:before { content: "\e971"; } -.iconlabel[class*="format-1gameboardgame"]:before { +.iconlabel[class*="format-1gameboardgame"]:before, +.iconlabel[class*="format-1gameboardgame"]:before +{ content: "\e8c2"; } -.iconlabel[class*="format-1gamevideogame"]:before, .iconlabel[class*="format-2gamevideogame"]:before { +.iconlabel[class*="format-1gamevideogame"]:before, +.iconlabel[class*="format-2gamevideogame"]:before { font-family: FontAwesome; content: @fa-var-gamepad; } diff --git a/themes/finna2/less/global/variables.less b/themes/finna2/less/global/variables.less index 1c761f3a819..aec8847e4dd 100644 --- a/themes/finna2/less/global/variables.less +++ b/themes/finna2/less/global/variables.less @@ -125,7 +125,7 @@ //== Generated horizontal carousel styles //== Carousel images background-color -@carousel-slider-background: #000; +@carousel-slider-background: @gray; //== Styling the header of carousel @carousel-header-background: transparent; @carousel-header-color: @gray; diff --git a/themes/finna2/templates/ajax/feed-carousel-item.phtml b/themes/finna2/templates/ajax/feed-carousel-item.phtml index f593105dd36..59d95baca0d 100644 --- a/themes/finna2/templates/ajax/feed-carousel-item.phtml +++ b/themes/finna2/templates/ajax/feed-carousel-item.phtml @@ -5,6 +5,7 @@ $hasIcon = !empty($item['icon']['name']); $hasImg = !empty($item['image']['url']); $noText = empty($item['text']); + $displayFormatHeader = $item['displayFormatHeader']; ?> partial('Helpers/feed-icon.phtml', ['icon' => $item['icon'], 'wrapper' => true]);?> @@ -14,7 +15,7 @@ @@ -44,8 +45,8 @@
    - - icon('status-unavailable');?> transEsc('status_' . $status, null, $this->translate($status))?> + icon('status-unavailable');?> transEsc('status_' . $status, $statusDescriptionTokens, $this->translate($status, $statusDescriptionTokens))?> escapeHtml($row['returnDate'])?> – transEsc('Due')?>: escapeHtml($row['duedate'])?> diff --git a/themes/finna2/templates/RecordTab/holdingsils.phtml b/themes/finna2/templates/RecordTab/holdingsils.phtml index 3f1d50c0561..a62e4b329a0 100644 --- a/themes/finna2/templates/RecordTab/holdingsils.phtml +++ b/themes/finna2/templates/RecordTab/holdingsils.phtml @@ -256,7 +256,8 @@ } } $statusDesc = $row['availability']->getStatusDescription(); - $statuses[$this->translate("status_$statusDesc", null, $this->translate($statusDesc))] = 1; + $statusDescriptionTokens = $row['availability']->getStatusDescriptionTokens(); + $statuses[$this->translate("status_$statusDesc", $statusDescriptionTokens, $this->translate($statusDesc, $statusDescriptionTokens))] = 1; if (!isset($row['branch'])) { if (isset($row['requests_placed']) && $row['requests_placed'] > $requests) { $requests = $row['requests_placed']; diff --git a/themes/finna2/templates/RecordTab/holdingsils/electronic.phtml b/themes/finna2/templates/RecordTab/holdingsils/electronic.phtml index bd3c5b17ab5..b7a94409561 100644 --- a/themes/finna2/templates/RecordTab/holdingsils/electronic.phtml +++ b/themes/finna2/templates/RecordTab/holdingsils/electronic.phtml @@ -21,15 +21,16 @@
    + getStatusDescriptionTokens(); ?> is(\VuFind\ILS\Logic\AvailabilityStatusInterface::STATUS_UNKNOWN)): ?> transEsc('status_unknown_message')?> is(\VuFind\ILS\Logic\AvailabilityStatusInterface::STATUS_UNAVAILABLE)): ?> - transEsc($item['availability']->getStatusDescription())?> + transEsc($item['availability']->getStatusDescription(), $statusDescriptionTokens)?> is(\VuFind\ILS\Logic\AvailabilityStatusInterface::STATUS_UNCERTAIN)): ?> - transEsc($item['availability']->getStatusDescription())?> + transEsc($item['availability']->getStatusDescription(), $statusDescriptionTokens)?> - transEsc($item['availability']->getStatusDescription())?> + transEsc($item['availability']->getStatusDescription(), $statusDescriptionTokens)?> diff --git a/themes/finna2/templates/ajax/status-full.phtml b/themes/finna2/templates/ajax/status-full.phtml index 4dcaa4070f1..d9e5707fbb9 100644 --- a/themes/finna2/templates/ajax/status-full.phtml +++ b/themes/finna2/templates/ajax/status-full.phtml @@ -85,7 +85,7 @@ if ($groupBranches) { // Check if availability is better while taking into account non-boolean // statuses as well (anything is better than unavailable, available better than // uncertain): - if ($item['availability']->compareTo($statusItemsFiltered[$location]['availability']) == 1) { + if ($item['availability']->compareTo($statusItemsFiltered[$location]['availability']) == -1) { // Copy keys one by one so as to not overwrite callnumbers or any other existing field foreach (array_keys($item) as $key) { $statusItemsFiltered[$location][$key] = $item[$key]; @@ -204,7 +204,8 @@ foreach ($this->statusItems as $item): (transEsc('closest_due_date')); ?>) getStatusDescription(); ?> - (transEscWithPrefix('status_', $statusDesc, null, $this->translate($statusDesc))?>) + getStatusDescriptionTokens(); ?> + (transEscWithPrefix('status_', $statusDesc, $statusDescriptionTokens, $this->translate($statusDesc, $statusDescriptionTokens))?>) From 4dc8b2cf6ed2136aa478d5cf6a05ed244f6eee30 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Fri, 6 Sep 2024 11:10:24 +0300 Subject: [PATCH 36/66] [FINNA-2477] KohaRest: Fix extra status information handling. --- module/Finna/src/Finna/ILS/Driver/KohaRest.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/module/Finna/src/Finna/ILS/Driver/KohaRest.php b/module/Finna/src/Finna/ILS/Driver/KohaRest.php index a15e5eb3e52..622020bfe8c 100644 --- a/module/Finna/src/Finna/ILS/Driver/KohaRest.php +++ b/module/Finna/src/Finna/ILS/Driver/KohaRest.php @@ -32,6 +32,7 @@ use VuFind\Exception\ILS as ILSException; use VuFind\I18n\TranslatableString; +use VuFind\ILS\Logic\AvailabilityStatus; use VuFind\Marc\MarcReader; use function array_key_exists; @@ -1123,11 +1124,24 @@ protected function getItemStatusesForBiblio($id, $patron = null, $brief = false) } $requestsTotal = max($requestsTotal, $requests); + $extraStatusInformation = []; + if ($transit = $avail['unavailabilities']['Item::Transfer'] ?? null) { + if (null !== ($toLibrary = $transit['to_library'] ?? null)) { + $extraStatusInformation['location'] = $this->getLibraryName($toLibrary); + if ($status == 'HoldingStatus::transit_to_date') { + $extraStatusInformation['date'] = $this->convertDate( + $transit['datesent'], + true + ); + } + } + } + $entry = [ 'id' => $id, 'item_id' => $item['item_id'], 'location' => $location, - 'availability' => $available, + 'availability' => new AvailabilityStatus($available, $status, $extraStatusInformation), 'status' => $status, 'status_array' => $statusCodes, 'reserve' => 'N', From 73d5375948b904ccb2feb25a57fec6ce96d1a833 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Fri, 6 Sep 2024 11:29:44 +0300 Subject: [PATCH 37/66] [FINNA-2511] Restore a skeleton R2 view helper for back-compatibility. --- .../Finna/src/Finna/View/Helper/Root/R2.php | 114 ++++++++++++++++++ themes/finna2/theme.config.php | 2 + 2 files changed, 116 insertions(+) create mode 100644 module/Finna/src/Finna/View/Helper/Root/R2.php diff --git a/module/Finna/src/Finna/View/Helper/Root/R2.php b/module/Finna/src/Finna/View/Helper/Root/R2.php new file mode 100644 index 00000000000..bde12e51ae8 --- /dev/null +++ b/module/Finna/src/Finna/View/Helper/Root/R2.php @@ -0,0 +1,114 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:developer_manual Wiki + */ + +namespace Finna\View\Helper\Root; + +/** + * Helper class for restricted Solr R2 search. + * + * @category VuFind + * @package View_Helpers + * @author Ere Maijala + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:developer_manual Wiki + * + * @deprecated This only exists for backward compatibility with existing templates. + */ +class R2 extends \Laminas\View\Helper\AbstractHelper +{ + /** + * Check if R2 is available + * + * @return bool + */ + public function isAvailable() + { + return false; + } + + /** + * Check if user is authenticated to use R2. + * + * @return bool + */ + public function isAuthenticated() + { + return false; + } + + /** + * Check if user is registered to REMS during this session. + * + * @param bool $checkEntitlements Also check entitlements? + * + * @return bool + */ + public function isRegistered($checkEntitlements = false) + { + return false; + } + + /** + * Check if user is has access to R2 + * + * @param bool $ignoreCache Ignore cache? + * + * @return bool + */ + public function hasUserAccess($ignoreCache = true) + { + return false; + } + + /** + * Render R2 registration info. Returns HTML. + * + * @param AbstractBase $driver Record driver + * @param array $params Parameters + * + * @return null|string + */ + public function registeredInfo($driver, $params = null) + { + return null; + } + + /** + * Render R2 registration prompt. Returns HTML. + * + * @param AbstractBase $driver Record driver + * @param array $params Parameters + * + * @return string|null + */ + public function register($driver, $params = null) + { + return null; + } +} diff --git a/themes/finna2/theme.config.php b/themes/finna2/theme.config.php index 9c6bf98e694..bd9968b8661 100644 --- a/themes/finna2/theme.config.php +++ b/themes/finna2/theme.config.php @@ -50,6 +50,7 @@ 'Finna\View\Helper\Root\Piwik' => 'VuFind\View\Helper\Root\PiwikFactory', 'Finna\View\Helper\Root\Primo' => 'Finna\View\Helper\Root\PrimoFactory', 'Finna\View\Helper\Root\ProxyUrl' => 'Finna\View\Helper\Root\ProxyUrlFactory', + 'Finna\View\Helper\Root\R2' => 'Laminas\ServiceManager\Factory\InvokableFactory', 'Finna\View\Helper\Root\Record' => 'Finna\View\Helper\Root\RecordFactory', 'Finna\View\Helper\Root\RecordDataFormatter' => 'Finna\View\Helper\Root\RecordDataFormatterFactory', 'Finna\View\Helper\Root\RecordFieldMarkdown' => 'Finna\View\Helper\Root\RecordFieldMarkdownFactory', @@ -120,6 +121,7 @@ 'organisationsList' => 'Finna\View\Helper\Root\OrganisationsList', 'personaAuth' => 'Finna\View\Helper\Root\PersonaAuth', 'primo' => 'Finna\View\Helper\Root\Primo', + 'R2' => 'Finna\View\Helper\Root\R2', 'recordFieldMarkdown' => 'Finna\View\Helper\Root\RecordFieldMarkdown', 'recordImage' => 'Finna\View\Helper\Root\RecordImage', 'recordLink' => 'Finna\View\Helper\Root\RecordLink', From d79ebf89b26bce18b3787189524d814312700ca9 Mon Sep 17 00:00:00 2001 From: sagajac Date: Fri, 6 Sep 2024 13:25:18 +0300 Subject: [PATCH 38/66] [FINNA-1300] Add Northern Sami translations to the record page of curated materials (#3012) --- local/languages/finna/Aipa/se.ini | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/local/languages/finna/Aipa/se.ini b/local/languages/finna/Aipa/se.ini index aaae2bb3a39..03031b4cb08 100644 --- a/local/languages/finna/Aipa/se.ini +++ b/local/languages/finna/Aipa/se.ini @@ -1,10 +1,18 @@ +basicEducationGrades1-2 = "Jahkeluohkát 1-2" +basicEducationGrades3-4 = "Jahkeluohkát 3-4" +basicEducationGrades5-6 = "Jahkeluohkát 5-6" +basicEducationGrades7-9 = "Jahkeluohkát 7-9" Curated By = "Čohkken" earlyChildhoodEducation = "Árrabajásgeassin" +educational_data = "Skuvlendieđut" educationalModules = "Modulat" +educationalSubjects = "Oahppoávdnasat" +educationalSyllabuses = "Oahppomearit" learningAreas = "Oahppama oasit" lowerSecondarySchool = "Badjeskuvla" lrmi_assignment_ideas = "Bargobihtáid ideat" lrmi_objectives = "Ulbmil ja sisdoallu" +lrmi_study_objectives = "Ulbmil" More Information = "Lassidieđut" primarySchool = "Vuolleskuvla" questions_feedback = "Jearaldagat dahje máhcahat materiálapáhkas?" @@ -14,6 +22,8 @@ studyContents = "Sisdoalut" studyObjectives = "Ulbmilat" transversalCompetences = "Viiddis máhttin" upperSecondarySchool = "Logahat" +vocationalCommonUnits = "Ámmátlaš skuvlejumi oktasaš dutkosa oasit" +vocationalCommonUnitSubjects = "Ámmátlaš skuvlejumi oktasaš dutkosa osiid oassesuorggit" vocationalEducation = "Ámmátlaš skuvlejupmi" vocationalUnits = "Ámmátlaš skuvlejumi dutkosa oasit" -vocationalCommonUnits = "Ámmátlaš skuvlejumi oktasaš dutkosa oasit" +vocationalQualifications = "Ámmátdutkosat" From 56d75dd06f4199020dce0be6289c4359c76b8574 Mon Sep 17 00:00:00 2001 From: Alex Buckley <37675958+alexklbuckley@users.noreply.github.com> Date: Sat, 7 Sep 2024 02:51:55 +1200 Subject: [PATCH 39/66] Add session key permission provider (#3882) - Includes refactoring to make permission provider plugin manager a stand-alone service. - Includes development tool to demonstrate use of the provider. Sponsored-by: Auckland University of Technology, New Zealand Co-authored-by: Demian Katz --- config/vufind/permissions.ini | 15 ++- module/VuFind/config/module.config.php | 3 +- .../Role/DynamicRoleProviderFactory.php | 42 ++----- .../Role/PermissionProvider/PluginManager.php | 2 + .../PluginManagerFactory.php | 76 +++++++++++++ .../Role/PermissionProvider/SessionKey.php | 104 ++++++++++++++++++ .../PermissionProvider/SessionKeyFactory.php | 79 +++++++++++++ .../Controller/DevtoolsController.php | 13 +++ .../templates/devtools/permissions.phtml | 21 ++++ .../templates/devtools/permissions.phtml | 21 ++++ 10 files changed, 341 insertions(+), 35 deletions(-) create mode 100644 module/VuFind/src/VuFind/Role/PermissionProvider/PluginManagerFactory.php create mode 100644 module/VuFind/src/VuFind/Role/PermissionProvider/SessionKey.php create mode 100644 module/VuFind/src/VuFind/Role/PermissionProvider/SessionKeyFactory.php diff --git a/config/vufind/permissions.ini b/config/vufind/permissions.ini index 35da3ecd413..66a780efb33 100644 --- a/config/vufind/permissions.ini +++ b/config/vufind/permissions.ini @@ -21,9 +21,11 @@ ; insecureCookie - Grant the permissions to users who have the named cookie(s) set in ; their browser. This can be easily spoofed by an end user, so it ; should not be used to protect secure features; however, it may be -; useful for setting flags to control unprotected behavior. If you use -; the cookie consent option, also be sure to add any custom cookies you -; create to CookieConsent.yaml so they are properly documented. +; useful for setting flags to control unprotected behavior. +; The sessionKey permission provider is a more secure alternative to the +; insecureCookie permission provider. +; If you use the cookie consent option, also be sure to add any custom cookies +; you create to CookieConsent.yaml so they are properly documented. ; ipRange - Grant the permission to the single IP address or to the range. ; Accepts a single IP address or a range with a minus character without ; blanks as separator. Also partial addresses can be used (e.g. 192.168 @@ -43,6 +45,12 @@ ; with optional modifier ~ (match instead of string comparison, values ; are treated as regular expressions), ! (not) or !~ (no match). Only ; one of the values must match (OR). +; sessionKey - Grant the permissions to users who have the named key(s) stored in +; the permission provider's session container. Keys can be set using +; the provider's setSessionValue() method. For an example of this, see +; \VuFindDevTools\Controller\DevtoolsController::permissionsAction(). +; A demo is available in the development tools; for details, see: +; https://vufind.org/wiki/development:devtools ; shibboleth - Same as serverParam with support for Shibboleth multi-valued ; attributes (values separated by semicolons). The IdP entityId can be ; referenced with idpentityid. Please note that only checking the IdP @@ -67,6 +75,7 @@ ; ipRange[] = "1.2.3.7-1.2.5.254" ; insecureCookie = "VUFIND_CUSTOM_COOKIE_NAME" ; permission = sample.permission +; sessionKey = "VUFIND_SESSION_KEY_NAME" ; Example configuration (grants the "sample.permission" permission to users ; who are from myCollege or who is a studentmajor (.*studentmajor.*): diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index 9a74716244e..9f09b72181c 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -494,8 +494,9 @@ 'VuFind\RecordTab\TabManager' => 'VuFind\RecordTab\TabManagerFactory', 'VuFind\Related\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', 'VuFind\Resolver\Driver\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', - 'VuFind\Role\PermissionManager' => 'VuFind\Role\PermissionManagerFactory', 'VuFind\Role\PermissionDeniedManager' => 'VuFind\Role\PermissionDeniedManagerFactory', + 'VuFind\Role\PermissionManager' => 'VuFind\Role\PermissionManagerFactory', + 'VuFind\Role\PermissionProvider\PluginManager' => 'VuFind\Role\PermissionProvider\PluginManagerFactory', 'VuFind\Search\BackendManager' => 'VuFind\Search\BackendManagerFactory', 'VuFind\Search\Explanation\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', 'VuFind\Search\FacetCache\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', diff --git a/module/VuFind/src/VuFind/Role/DynamicRoleProviderFactory.php b/module/VuFind/src/VuFind/Role/DynamicRoleProviderFactory.php index 1ac98e92ff8..569be4cfeb7 100644 --- a/module/VuFind/src/VuFind/Role/DynamicRoleProviderFactory.php +++ b/module/VuFind/src/VuFind/Role/DynamicRoleProviderFactory.php @@ -49,60 +49,40 @@ class DynamicRoleProviderFactory implements FactoryInterface /** * Create service * - * @param ContainerInterface $sm Service manager - * @param string $name Requested service name (unused) - * @param array $options Extra options (unused) + * @param ContainerInterface $container Service container + * @param string $name Requested service name (unused) + * @param array $options Extra options (unused) * * @return object * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function __invoke(ContainerInterface $sm, $name, array $options = null) + public function __invoke(ContainerInterface $container, $name, array $options = null) { - $config = $sm->get('config'); - $rbacConfig = $config['lmc_rbac']; + $config = $container->get('config'); return new $name( - $this->getPermissionProviderPluginManager($sm, $rbacConfig), - $this->getPermissionConfiguration($sm, $rbacConfig) + $container->get(PermissionProvider\PluginManager::class), + $this->getPermissionConfiguration($container, $config['lmc_rbac']) ); } - /** - * Create the supporting plugin manager. - * - * @param ContainerInterface $serviceLocator Service locator - * @param array $rbacConfig LmcRbacMvc configuration - * - * @return PermissionProviderPluginManager - */ - protected function getPermissionProviderPluginManager( - ContainerInterface $serviceLocator, - array $rbacConfig - ) { - $pm = new PermissionProvider\PluginManager( - $serviceLocator, - $rbacConfig['vufind_permission_provider_manager'] - ); - return $pm; - } - /** * Get a configuration array. * - * @param ContainerInterface $serviceLocator Service locator - * @param array $rbacConfig LmcRbacMvc configuration + * @param ContainerInterface $container Service container + * @param array $rbacConfig LmcRbacMvc configuration * * @return array */ protected function getPermissionConfiguration( - ContainerInterface $serviceLocator, + ContainerInterface $container, array $rbacConfig ) { // Get role provider settings from the LmcRbacMvc configuration: $config = $rbacConfig['role_provider']['VuFind\Role\DynamicRoleProvider']; // Load the permissions: - $configLoader = $serviceLocator->get(\VuFind\Config\PluginManager::class); + $configLoader = $container->get(\VuFind\Config\PluginManager::class); $permissions = $configLoader->get('permissions')->toArray(); // If we're configured to map legacy settings, do so now: diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/PluginManager.php b/module/VuFind/src/VuFind/Role/PermissionProvider/PluginManager.php index 4f852d7d432..697c56a58ca 100644 --- a/module/VuFind/src/VuFind/Role/PermissionProvider/PluginManager.php +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/PluginManager.php @@ -51,6 +51,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager 'ipRegEx' => IpRegEx::class, 'role' => Role::class, 'serverParam' => ServerParam::class, + 'sessionKey' => SessionKey::class, 'shibboleth' => Shibboleth::class, 'user' => User::class, 'username' => Username::class, @@ -67,6 +68,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager IpRegEx::class => IpRegExFactory::class, Role::class => \Laminas\ServiceManager\Factory\InvokableFactory::class, ServerParam::class => InjectRequestFactory::class, + SessionKey::class => SessionKeyFactory::class, Shibboleth::class => ShibbolethFactory::class, User::class => InjectAuthorizationServiceFactory::class, Username::class => InjectAuthorizationServiceFactory::class, diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/PluginManagerFactory.php b/module/VuFind/src/VuFind/Role/PermissionProvider/PluginManagerFactory.php new file mode 100644 index 00000000000..837970414d8 --- /dev/null +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/PluginManagerFactory.php @@ -0,0 +1,76 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ + +namespace VuFind\Role\PermissionProvider; + +use Laminas\ServiceManager\Exception\ServiceNotCreatedException; +use Laminas\ServiceManager\Exception\ServiceNotFoundException; +use Psr\Container\ContainerExceptionInterface as ContainerException; +use Psr\Container\ContainerInterface; + +/** + * Factory for instantiating permission provider plugin manager. + * + * @category VuFind + * @package Authorization + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class PluginManagerFactory implements \Laminas\ServiceManager\Factory\FactoryInterface +{ + /** + * Create an object + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException&\Throwable if any other error occurs + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function __invoke( + ContainerInterface $container, + $requestedName, + array $options = null + ) { + if (!empty($options)) { + throw new \Exception('Unexpected options passed to factory.'); + } + $config = $container->get('config'); + $providerConfig = $config['lmc_rbac']['vufind_permission_provider_manager'] ?? []; + return new $requestedName($container, $providerConfig); + } +} diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/SessionKey.php b/module/VuFind/src/VuFind/Role/PermissionProvider/SessionKey.php new file mode 100644 index 00000000000..2df17a24b1f --- /dev/null +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/SessionKey.php @@ -0,0 +1,104 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://www.vufind.org Main Page + */ + +namespace VuFind\Role\PermissionProvider; + +use Laminas\Session\Container; + +/** + * Session key permission provider. + * + * @category VuFind + * @package Authorization + * @author Alex Buckley + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ + +class SessionKey implements PermissionProviderInterface +{ + use \VuFind\Log\LoggerAwareTrait; + + /** + * Constructor + * + * @param $session Session container + */ + public function __construct( + protected Container $session + ) { + } + + /** + * Return an array of roles which may be granted the permission based on + * the options. + * + * @param mixed $options Options (sessionKeys) provided from configuration. + * + * @return array + */ + public function getPermissions($options) + { + foreach ((array)$options as $sessionKey) { + $this->debug("getPermissions: option sessionKey '{$sessionKey}'"); + if (!($this->session->$sessionKey ?? false)) { + $this->debug('getPermissions: result = false'); + return []; + } + $this->debug('getPermissions: result = true'); + } + return ['guest', 'loggedin']; + } + + /** + * Activate a key in the Session container. + * + * @param string $sessionKey - Set a boolean true value for this session key. + * + * @return void + */ + public function setSessionValue(string $sessionKey): void + { + // Store boolean true value for the sessionKey + $this->session->$sessionKey = true; + } + + /** + * Deactivate a key in the Session container. + * + * @param string $sessionKey - Set a boolean true value for this session key. + * + * @return void + */ + public function unsetSessionValue(string $sessionKey): void + { + // Store null value for the sessionKey + $this->session->$sessionKey = null; + } +} diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/SessionKeyFactory.php b/module/VuFind/src/VuFind/Role/PermissionProvider/SessionKeyFactory.php new file mode 100644 index 00000000000..fc0369965f8 --- /dev/null +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/SessionKeyFactory.php @@ -0,0 +1,79 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ + +namespace VuFind\Role\PermissionProvider; + +use Laminas\ServiceManager\Exception\ServiceNotCreatedException; +use Laminas\ServiceManager\Exception\ServiceNotFoundException; +use Psr\Container\ContainerExceptionInterface as ContainerException; +use Psr\Container\ContainerInterface; + +/** + * Factory for instantiating SessionKey permission provider. + * + * @category VuFind + * @package Authorization + * @author Alex Buckley + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class SessionKeyFactory implements \Laminas\ServiceManager\Factory\FactoryInterface +{ + /** + * Create an object + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException&\Throwable if any other error occurs + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function __invoke( + ContainerInterface $container, + $requestedName, + array $options = null + ) { + if (!empty($options)) { + throw new \Exception('Unexpected options passed to factory.'); + } + return new $requestedName( + new \Laminas\Session\Container( + 'SessionKey', + $container->get(\Laminas\Session\SessionManager::class) + ) + ); + } +} diff --git a/module/VuFindDevTools/src/VuFindDevTools/Controller/DevtoolsController.php b/module/VuFindDevTools/src/VuFindDevTools/Controller/DevtoolsController.php index 2d470a0bb44..df40a2cc257 100644 --- a/module/VuFindDevTools/src/VuFindDevTools/Controller/DevtoolsController.php +++ b/module/VuFindDevTools/src/VuFindDevTools/Controller/DevtoolsController.php @@ -33,6 +33,8 @@ use VuFind\I18n\Locale\LocaleSettings; use VuFind\I18n\Translator\Loader\ExtendedIni; use VuFind\Role\PermissionManager; +use VuFind\Role\PermissionProvider\PluginManager as PermissionProviderPluginManager; +use VuFind\Role\PermissionProvider\SessionKey; use VuFind\Search\Results\PluginManager as ResultsManager; use VuFindDevTools\LanguageHelper; @@ -149,6 +151,17 @@ public function languageAction() */ public function permissionsAction() { + // Handle demo session key setting/unsetting: + $set = $this->params()->fromQuery('setSessionKey'); + $unset = $this->params()->fromQuery('unsetSessionKey'); + if ($set || $unset) { + $provider = $this->getService(PermissionProviderPluginManager::class)->get(SessionKey::class); + $method = $set ? 'setSessionValue' : 'unsetSessionValue'; + $provider->$method('demo_key'); + return $this->redirect()->toRoute('devtools-permissions'); + } + + // Retrieve full permission list: $manager = $this->getService(PermissionManager::class); $permissions = []; foreach ($manager->getAllConfiguredPermissions() as $permission) { diff --git a/themes/bootstrap3/templates/devtools/permissions.phtml b/themes/bootstrap3/templates/devtools/permissions.phtml index 075868cd700..05214ed7540 100644 --- a/themes/bootstrap3/templates/devtools/permissions.phtml +++ b/themes/bootstrap3/templates/devtools/permissions.phtml @@ -7,9 +7,30 @@ ?>

    +

    Configured Permissions

    +

    This section shows all permissions currently configured in permissions.ini and whether they are granted to the current +active user (or logged-out guest).

    $status): ?>
    PermissionGranted?
    escapeHtml($permission)?>
    + +

    Session Key Testing

    +

    If you want to activate or deactivate user permissions in a custom controller action (e.g. to apply permissions based +on custom logic), you can use the "session key" permission provider. You can test out the mechanism by adding something like this +to your permissions.ini file:

    + +
    +[SessionBasedPermission]
    +permission = session.based.permission
    +sessionKey = demo_key
    +
    + +

    You can use the following links to set or unset the "demo_key" session key.

    + +

    See \VuFindDevTools\Controller\DevtoolsController::permissionsAction() for example code showing how to set and unset keys.

    + +

    Note: this demo is only capabile of setting the "demo_key" session key. General-purpose key setting has not been implemented +for security reasons.

    diff --git a/themes/bootstrap5/templates/devtools/permissions.phtml b/themes/bootstrap5/templates/devtools/permissions.phtml index 075868cd700..05214ed7540 100644 --- a/themes/bootstrap5/templates/devtools/permissions.phtml +++ b/themes/bootstrap5/templates/devtools/permissions.phtml @@ -7,9 +7,30 @@ ?>

    +

    Configured Permissions

    +

    This section shows all permissions currently configured in permissions.ini and whether they are granted to the current +active user (or logged-out guest).

    $status): ?>
    PermissionGranted?
    escapeHtml($permission)?>
    + +

    Session Key Testing

    +

    If you want to activate or deactivate user permissions in a custom controller action (e.g. to apply permissions based +on custom logic), you can use the "session key" permission provider. You can test out the mechanism by adding something like this +to your permissions.ini file:

    + +
    +[SessionBasedPermission]
    +permission = session.based.permission
    +sessionKey = demo_key
    +
    + +

    You can use the following links to set or unset the "demo_key" session key.

    + +

    See \VuFindDevTools\Controller\DevtoolsController::permissionsAction() for example code showing how to set and unset keys.

    + +

    Note: this demo is only capabile of setting the "demo_key" session key. General-purpose key setting has not been implemented +for security reasons.

    From be7e781c4fc0f14d46da0894c15ded4b43fb5ef2 Mon Sep 17 00:00:00 2001 From: Maccabee Levine <31278545+maccabeelevine@users.noreply.github.com> Date: Fri, 6 Sep 2024 11:26:20 -0400 Subject: [PATCH 40/66] Add file extensions to BibTeX and RIS exports (#3913) --- config/vufind/export.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/vufind/export.ini b/config/vufind/export.ini index 2f323cd03e5..e4f8cd38ff1 100644 --- a/config/vufind/export.ini +++ b/config/vufind/export.ini @@ -86,8 +86,10 @@ headers[] = "Content-type: application/rdf+xml" requiredMethods[] = getTitle ;limit = 100 headers[] = "Content-type: application/x-bibtex; charset=utf-8" +headers[] = "Content-Disposition: attachment; filename=\"VuFindExport.bibtex\";" [RIS] requiredMethods[] = getTitle ;limit = 100 headers[] = "Content-type: application/x-research-info-systems; charset=utf-8" +headers[] = "Content-Disposition: attachment; filename=\"VuFindExport.ris\";" From 0c721c16f9aab3366b3b351ef8084dbe0d9526fb Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Fri, 6 Sep 2024 13:41:05 -0400 Subject: [PATCH 41/66] Fix incorrect comment. --- config/vufind/config.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/vufind/config.ini b/config/vufind/config.ini index 442ee4a35f1..b54dd773259 100644 --- a/config/vufind/config.ini +++ b/config/vufind/config.ini @@ -1464,7 +1464,7 @@ show_in_holdings = false ; include in holdings tab of record view ; If set to true, this setting will attempt to embed results from the link ; resolver directly in search results instead of opening a new window or page. ; This will override the window_settings option if set! Embedding is currently -; unsupported when the resolver setting above is set to "other". +; unsupported when the resolver setting above is set to "generic". embed = false ; When embed is true and this is set to true results from the link resolver will From 7c7c9d00eedf3598ce151897f4934c6cdc4849c5 Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Fri, 6 Sep 2024 14:58:41 -0400 Subject: [PATCH 42/66] Fix message/types in findCssAndCallMethod(). --- .../src/VuFindTest/Integration/MinkTestCase.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/module/VuFind/src/VuFindTest/Integration/MinkTestCase.php b/module/VuFind/src/VuFindTest/Integration/MinkTestCase.php index 9b915e8d137..feed36ea694 100644 --- a/module/VuFind/src/VuFindTest/Integration/MinkTestCase.php +++ b/module/VuFind/src/VuFindTest/Integration/MinkTestCase.php @@ -738,12 +738,12 @@ protected function findCssAndGetHtml( /** * Return value of a method of an element selected via CSS; retry if it fails due to DOM change. * - * @param Element $page Page element - * @param string $selector CSS selector - * @param callable $method Method to call - * @param int $timeout Wait timeout for CSS selection (in ms) - * @param int $index Index of the element (0-based) - * @param int $retries Retry count for set loop + * @param Element $page Page element + * @param string $selector CSS selector + * @param string $method Method to call + * @param int $timeout Wait timeout for CSS selection (in ms) + * @param int $index Index of the element (0-based) + * @param int $retries Retry count for set loop * * @return string */ @@ -771,7 +771,7 @@ protected function findCssAndCallMethod( $this->snooze(); } - throw new \Exception('Failed to get text after ' . $retries . ' attempts.'); + throw new \Exception("Failed to call $method on '$selector' after $retries attempts."); } /** From bdc47879e488a1671abd4874f48c796ffff80499 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Mon, 9 Sep 2024 08:33:11 +0300 Subject: [PATCH 43/66] [FINNA-2477] Fix availability statuses with Aurora and Quria. --- .../Finna/src/Finna/ILS/Driver/AxiellWebServices.php | 12 +++++------- .../Finna/ILS/Driver/AxiellWebServicesFactory.php | 1 - module/Finna/src/Finna/ILS/Driver/Quria.php | 3 ++- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/module/Finna/src/Finna/ILS/Driver/AxiellWebServices.php b/module/Finna/src/Finna/ILS/Driver/AxiellWebServices.php index 37f9d991744..c9f8fef8297 100644 --- a/module/Finna/src/Finna/ILS/Driver/AxiellWebServices.php +++ b/module/Finna/src/Finna/ILS/Driver/AxiellWebServices.php @@ -37,7 +37,7 @@ use VuFind\Date\DateException; use VuFind\Exception\ILS as ILSException; use VuFind\I18n\Translator\TranslatorAwareInterface as TranslatorAwareInterface; -use VuFind\ILS\Logic\AvailabilityStatusManager; +use VuFind\ILS\Logic\AvailabilityStatus; use function count; use function in_array; @@ -307,14 +307,12 @@ class AxiellWebServices extends \VuFind\ILS\Driver\AbstractBase implements /** * Constructor * - * @param \VuFind\Date\Converter $dateConverter Date converter object - * @param \VuFind\Config\PathResolver $pathResolver Config file path resolver - * @param AvailabilityStatusManager $availabilityStatusManager Availability status manager + * @param \VuFind\Date\Converter $dateConverter Date converter object + * @param \VuFind\Config\PathResolver $pathResolver Config file path resolver */ public function __construct( \VuFind\Date\Converter $dateConverter, - \VuFind\Config\PathResolver $pathResolver, - protected AvailabilityStatusManager $availabilityStatusManager + \VuFind\Config\PathResolver $pathResolver ) { $this->dateFormat = $dateConverter; $this->pathResolver = $pathResolver; @@ -1245,7 +1243,7 @@ protected function parseHoldings($organisationHoldings, $id, $journalInfo = null 'barcode' => $id, 'item_id' => $reservableId, 'holdings_id' => $group, - 'availability' => $this->availabilityStatusManager->createAvailabilityStatus($available), + 'availability' => new AvailabilityStatus($available, $status), 'availabilityInfo' => $availabilityInfo, 'status' => $status, 'location' => $group, diff --git a/module/Finna/src/Finna/ILS/Driver/AxiellWebServicesFactory.php b/module/Finna/src/Finna/ILS/Driver/AxiellWebServicesFactory.php index 6ef3a32d92f..c40420868b5 100644 --- a/module/Finna/src/Finna/ILS/Driver/AxiellWebServicesFactory.php +++ b/module/Finna/src/Finna/ILS/Driver/AxiellWebServicesFactory.php @@ -72,7 +72,6 @@ public function __invoke( $requestedName, [ $container->get(\VuFind\Config\PathResolver::class), - $container->get(\VuFind\ILS\Logic\AvailabilityStatusManager::class), ] ); } diff --git a/module/Finna/src/Finna/ILS/Driver/Quria.php b/module/Finna/src/Finna/ILS/Driver/Quria.php index 22bdc60d99c..5ff742920df 100644 --- a/module/Finna/src/Finna/ILS/Driver/Quria.php +++ b/module/Finna/src/Finna/ILS/Driver/Quria.php @@ -36,6 +36,7 @@ use VuFind\Date\DateException; use VuFind\Exception\ILS as ILSException; +use VuFind\ILS\Logic\AvailabilityStatus; use function in_array; use function is_callable; @@ -443,7 +444,7 @@ protected function parseHoldings($organisationHoldings, $id, $journalInfo = null 'barcode' => $id, 'item_id' => $reservableId, 'holdings_id' => $group ?? '', - 'availability' => $this->availabilityStatusManager->createAvailabilityStatus($available), + 'availability' => new AvailabilityStatus($available, $status), 'availabilityInfo' => $availabilityInfo, 'status' => $status, 'location' => $group ?? $branchName, From 1841dcbd3bab44b4877f865ee9b67faa2bcbf483 Mon Sep 17 00:00:00 2001 From: Pasi Tiisanoja Date: Mon, 9 Sep 2024 10:20:59 +0300 Subject: [PATCH 44/66] Fix calculation of slide header height. (#3018) --- themes/finna2/js/finna-feed-element.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/themes/finna2/js/finna-feed-element.js b/themes/finna2/js/finna-feed-element.js index 2387f7639fb..df64e5cb5cb 100644 --- a/themes/finna2/js/finna-feed-element.js +++ b/themes/finna2/js/finna-feed-element.js @@ -60,11 +60,11 @@ class FinnaFeedElement extends HTMLElement { // Move title field below image let maxH = 0; this.querySelectorAll('.carousel-slide-header p').forEach(el => { + maxH = Math.max(maxH, el.getBoundingClientRect().height + 10); el.classList.add('title-bottom'); - maxH = Math.max(maxH, el.getBoundingClientRect().height); - + el.parentNode.classList.add('title-bottom'); }); - this.querySelectorAll('.carousel-slide-header p').forEach(el => { + this.querySelectorAll('.carousel-slide-header, .carousel-slide-header p').forEach(el => { el.style.minHeight = el.style.height = `${maxH}px`; }); this.querySelectorAll('.carousel-feed .carousel-text').forEach(el => { From ba25ef5e739d3057c34ab7344c5a4f1316cca783 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Mon, 9 Sep 2024 14:16:17 +0300 Subject: [PATCH 45/66] Increase admin API cache clear max execution time. --- .../src/FinnaApi/Controller/AdminApiController.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/module/FinnaApi/src/FinnaApi/Controller/AdminApiController.php b/module/FinnaApi/src/FinnaApi/Controller/AdminApiController.php index b0ab91179fd..87cedda3973 100644 --- a/module/FinnaApi/src/FinnaApi/Controller/AdminApiController.php +++ b/module/FinnaApi/src/FinnaApi/Controller/AdminApiController.php @@ -32,6 +32,8 @@ use VuFind\Service\Feature\RetryTrait; +use function ini_get; + /** * Provides web api for different admin tasks. * @@ -60,6 +62,11 @@ public function clearCacheAction() return $result; } + // Check time limit; increase if necessary: + if (ini_get('max_execution_time') < 3600) { + ini_set('max_execution_time', '3600'); + } + try { $cacheList = $this->getRequest()->getQuery()->get('id') ?: $this->getDefaultCachesToClear(); From a3710ff541e39b6c44babd113db9b8e715f77b6b Mon Sep 17 00:00:00 2001 From: Alex Buckley <37675958+alexklbuckley@users.noreply.github.com> Date: Tue, 10 Sep 2024 00:28:23 +1200 Subject: [PATCH 46/66] Introduce option to display shorter author data on EDS item detail page (#3881) - Add DetailPageFormat config to EDS.ini - Add short author display to EDS core.phtml files Sponsored-By: Auckland University of Technology, New Zealand --- config/vufind/EDS.ini | 19 ++++++---- themes/bootstrap3/css/EDS.css | 8 ++-- .../templates/RecordDriver/EDS/core.phtml | 38 +++++++++++++++++-- themes/bootstrap5/css/EDS.css | 8 ++-- .../templates/RecordDriver/EDS/core.phtml | 38 +++++++++++++++++-- 5 files changed, 88 insertions(+), 23 deletions(-) diff --git a/config/vufind/EDS.ini b/config/vufind/EDS.ini index 924efe1180b..67fce1d8477 100644 --- a/config/vufind/EDS.ini +++ b/config/vufind/EDS.ini @@ -406,16 +406,21 @@ AU = None ; This section controls how the authors of EDS records are displayed. [AuthorDisplay] -; Control which data is used to display author information in search results. -; - 'Short' (the default) is fetched from the RecordInfo section of a record (the +; The following two settings control which data is used to display author +; information in search results (ResultListFormat) and item detail pages +; (DetailPageFormat). Both settings support two options: +; - 'Short' (the default for ResultListFormat) is fetched from the RecordInfo section of a record (the ; 'BibRecord/BibRelationships/HasContributorRelationships/*PersonEntity/Name/NameFull' data). -; Also, when you set 'ResultListFormat' to 'Short' you can change the default delimiter "; " between +; This format also suppresses the display of 'AuInfo' group data on the detail page +; when activated there. +; In this display mode, you can change the default delimiter "; " between ; the author names by overriding the styles defined in the EDS.css file ; under: 'Author name delimiters'. -; - 'Long' is fetched from the item 'Au' group data. +; - 'Long' (the default for DetailPageFormat) is fetched from the item 'Au' group data. ResultListFormat = 'Short' -; This setting controls how many author names to display when ResultListFormat is -; set to 'Short'. It is ignored if the setting is 'Long'. If a record has more author names -; than you define in AuthorNameLimit, then VuFind will display the more_authors_abbrev text. +DetailPageFormat = 'Long' +; This setting controls how many author names to display when ResultListFormat or DetailPageFormat +; are set to 'Short'. It is ignored if the setting is 'Long'. If a record has more author names +; than you define in ShortAuthorLimit, then VuFind will display the more_authors_abbrev text. ; If undefined, the default value is 3. ;ShortAuthorLimit = 3 diff --git a/themes/bootstrap3/css/EDS.css b/themes/bootstrap3/css/EDS.css index 112c665a55f..8fdcd2f29a9 100644 --- a/themes/bootstrap3/css/EDS.css +++ b/themes/bootstrap3/css/EDS.css @@ -89,10 +89,10 @@ /* Author name delimiters */ /* On EDS search result page */ -.search-results-eds .result .author:not(:last-of-type):after { - content: '; '; -} +.search-results-eds .result .author:not(:last-of-type):after, /* On combined result page */ -#combined_EDS .record-list .author:not(:last-of-type):after { +#combined_EDS .record-list .author:not(:last-of-type):after, +/* On EDS item detail page */ +.record__biblio-value .author:not(:last-of-type):after { content: '; '; } diff --git a/themes/bootstrap3/templates/RecordDriver/EDS/core.phtml b/themes/bootstrap3/templates/RecordDriver/EDS/core.phtml index 7c080d66d28..212c97c3d36 100644 --- a/themes/bootstrap3/templates/RecordDriver/EDS/core.phtml +++ b/themes/bootstrap3/templates/RecordDriver/EDS/core.phtml @@ -7,6 +7,8 @@ $restrictedView = empty($accessLevel) ? false : true; $coverDetails = $this->record($this->driver)->getCoverDetails('core', 'medium'); $cover = $coverDetails['html']; + $edsConfig = $this->config()->get('EDS'); + $authorDisplay = strtolower($edsConfig->AuthorDisplay->DetailPageFormat ?? 'Long'); ?>
    schemaOrg()->getAttributes(['vocab' => 'http://schema.org/', 'resource' => '#record', 'typeof' => $this->schemaOrg()->getRecordTypes($this->driver)])?>>
    @@ -77,10 +79,38 @@ transEsc('Bibliographic Details')?> $item): ?> - - transEsc($item['Label']) . ':'?> - driver->linkUrls($item['Data'])?> - + + + transEsc($item['Label']) . ':'?> + getPrimaryAuthorsWithHighlighting(); + $authorCount = count($authors); + $authorNameLimit = $edsConfig->AuthorDisplay->ShortAuthorLimit ?? 3; + ?> + 1): ?> + + $author): ?> + highlight($author)?>= $authorNameLimit) { + echo ' ' . $this->transEsc('more_authors_abbrev'); + break; + } + ?> + + + driver->linkUrls($item['Data'])?> + + + + + + + transEsc($item['Label']) . ':'?> + driver->linkUrls($item['Data'])?> + + diff --git a/themes/bootstrap5/css/EDS.css b/themes/bootstrap5/css/EDS.css index 112c665a55f..8fdcd2f29a9 100644 --- a/themes/bootstrap5/css/EDS.css +++ b/themes/bootstrap5/css/EDS.css @@ -89,10 +89,10 @@ /* Author name delimiters */ /* On EDS search result page */ -.search-results-eds .result .author:not(:last-of-type):after { - content: '; '; -} +.search-results-eds .result .author:not(:last-of-type):after, /* On combined result page */ -#combined_EDS .record-list .author:not(:last-of-type):after { +#combined_EDS .record-list .author:not(:last-of-type):after, +/* On EDS item detail page */ +.record__biblio-value .author:not(:last-of-type):after { content: '; '; } diff --git a/themes/bootstrap5/templates/RecordDriver/EDS/core.phtml b/themes/bootstrap5/templates/RecordDriver/EDS/core.phtml index 7c080d66d28..212c97c3d36 100644 --- a/themes/bootstrap5/templates/RecordDriver/EDS/core.phtml +++ b/themes/bootstrap5/templates/RecordDriver/EDS/core.phtml @@ -7,6 +7,8 @@ $restrictedView = empty($accessLevel) ? false : true; $coverDetails = $this->record($this->driver)->getCoverDetails('core', 'medium'); $cover = $coverDetails['html']; + $edsConfig = $this->config()->get('EDS'); + $authorDisplay = strtolower($edsConfig->AuthorDisplay->DetailPageFormat ?? 'Long'); ?>
    schemaOrg()->getAttributes(['vocab' => 'http://schema.org/', 'resource' => '#record', 'typeof' => $this->schemaOrg()->getRecordTypes($this->driver)])?>>
    @@ -77,10 +79,38 @@ transEsc('Bibliographic Details')?> $item): ?> - - transEsc($item['Label']) . ':'?> - driver->linkUrls($item['Data'])?> - + + + transEsc($item['Label']) . ':'?> + getPrimaryAuthorsWithHighlighting(); + $authorCount = count($authors); + $authorNameLimit = $edsConfig->AuthorDisplay->ShortAuthorLimit ?? 3; + ?> + 1): ?> + + $author): ?> + highlight($author)?>= $authorNameLimit) { + echo ' ' . $this->transEsc('more_authors_abbrev'); + break; + } + ?> + + + driver->linkUrls($item['Data'])?> + + + + + + + transEsc($item['Label']) . ':'?> + driver->linkUrls($item['Data'])?> + + From d1563dba2bef7da16252b068a563cbbf82293071 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Mon, 9 Sep 2024 15:30:58 +0300 Subject: [PATCH 47/66] Add scopes to OIDC well-known configuration. (#3915) --- module/VuFind/src/VuFind/Controller/OAuth2Controller.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/module/VuFind/src/VuFind/Controller/OAuth2Controller.php b/module/VuFind/src/VuFind/Controller/OAuth2Controller.php index 74adef490ea..2a8e2a95b2a 100644 --- a/module/VuFind/src/VuFind/Controller/OAuth2Controller.php +++ b/module/VuFind/src/VuFind/Controller/OAuth2Controller.php @@ -366,6 +366,9 @@ public function wellKnownConfigurationAction() if ($url = $this->oauth2Config['Server']['documentationUrl'] ?? null) { $configuration['service_documentation'] = $url; } + if ($scopes = $this->oauth2Config['Scopes'] ?? []) { + $configuration['scopes_supported'] = array_keys($scopes); + } return $this->getJsonResponse($configuration); } From a2e634cc11dab00aed4fc2dd8f70545811ad7194 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Mon, 9 Sep 2024 15:34:08 +0300 Subject: [PATCH 48/66] KohaRest: Fix getConfig for holdings. (#3916) There was a mistake that dropped everything else but itemLimit from the Holdings configuration. --- module/VuFind/src/VuFind/ILS/Driver/KohaRest.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/module/VuFind/src/VuFind/ILS/Driver/KohaRest.php b/module/VuFind/src/VuFind/ILS/Driver/KohaRest.php index b8f1871bca4..db53614740a 100644 --- a/module/VuFind/src/VuFind/ILS/Driver/KohaRest.php +++ b/module/VuFind/src/VuFind/ILS/Driver/KohaRest.php @@ -1807,17 +1807,15 @@ public function getConfig($function, $params = []) 'default_sort' => '+due_date', ]; } elseif ('Holdings' === $function) { - $limitByType = $this->config['Holdings']['itemLimitByType'] ?? []; - $type = ''; - if ($limitByType) { + $config = $this->config['Holdings'] ?? []; + if ($limitByType = $this->config['Holdings']['itemLimitByType'] ?? null) { $biblio = $this->getBiblio($params['id']); $type = $biblio['item_type']; + if ($typeLimit = $limitByType[$type] ?? null) { + $config['itemLimit'] = $typeLimit; + } } - return [ - 'itemLimit' => $limitByType[$type] - ?? $this->config['Holdings']['itemLimit'] - ?? null, - ]; + return $config; } return $this->config[$function] ?? false; From 9e312d8a125b118d7c7f1f214dfe6f6e7c5eb547 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Mon, 9 Sep 2024 15:35:03 +0300 Subject: [PATCH 49/66] Add a couple of Finnish and Swedish holding status translations. (#3917) --- languages/HoldingStatus/fi.ini | 2 ++ languages/HoldingStatus/sv.ini | 2 ++ 2 files changed, 4 insertions(+) diff --git a/languages/HoldingStatus/fi.ini b/languages/HoldingStatus/fi.ini index c4010e0e18f..0f41aed2a6c 100644 --- a/languages/HoldingStatus/fi.ini +++ b/languages/HoldingStatus/fi.ini @@ -5,3 +5,5 @@ service_available_presentation = "Käyttö vain kirjastossa" service_loan = "Lainaus" service_presentation = "Käyttö kirjastossa" services_available_html = "Käytettävissä toiminnoille: %%list%%" +transit_to = "Matkalla kohteeseen %%location%%" +transit_to_date = "Matkalla kohteeseen %%location%%, lähtenyt %%date%%" diff --git a/languages/HoldingStatus/sv.ini b/languages/HoldingStatus/sv.ini index 0cf907e4e0c..10cb640960c 100644 --- a/languages/HoldingStatus/sv.ini +++ b/languages/HoldingStatus/sv.ini @@ -5,3 +5,5 @@ service_available_presentation = "Endast i biblioteksbruk" service_loan = "Lån" service_presentation = "I biblioteksbruk" services_available_html = "Tillgänglig för %%list%%" +transit_to = "På väg till %%location%%" +transit_to_date = "På väg till %%location%%, skickad %%date%%" From 6119d51c494d948905119983a5903071a51c4bdd Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Mon, 9 Sep 2024 16:03:26 +0300 Subject: [PATCH 50/66] [FINNA-2477] Add short author support to EDS core template. --- .../RecordDriver/EDS/core-fields.phtml | 48 +++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/themes/finna2/templates/RecordDriver/EDS/core-fields.phtml b/themes/finna2/templates/RecordDriver/EDS/core-fields.phtml index 4acf8df6825..93dc06f756b 100644 --- a/themes/finna2/templates/RecordDriver/EDS/core-fields.phtml +++ b/themes/finna2/templates/RecordDriver/EDS/core-fields.phtml @@ -1,16 +1,48 @@ +config()->get('EDS'); + $authorDisplay = strtolower($edsConfig->AuthorDisplay->DetailPageFormat ?? 'Long'); +?>
    driver->getItems($this->defaults) as $key => $item): ?> ignoreDetailsFields ?? [])): ?> - - - - + + + + getPrimaryAuthorsWithHighlighting(); + $authorCount = count($authors); + $authorNameLimit = $edsConfig->AuthorDisplay->ShortAuthorLimit ?? 3; + ?> + 1): ?> + + + driver->linkUrls($item['Data'])?> + + + + + + + + + + From 8155e55ef48341c1b6eb9fcd66a6ad2abf6bcdd7 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Mon, 9 Sep 2024 17:17:56 +0300 Subject: [PATCH 51/66] [FINNA-2564] Fix SolrAuth autocomplete suggestions --- module/Finna/config/module.config.php | 2 + module/Finna/src/Finna/Autocomplete/Solr.php | 11 +-- .../Finna/src/Finna/Autocomplete/SolrAuth.php | 64 ++++++++++++++ .../Finna/Autocomplete/SolrAuthFactory.php | 83 +++++++++++++++++++ 4 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 module/Finna/src/Finna/Autocomplete/SolrAuth.php create mode 100644 module/Finna/src/Finna/Autocomplete/SolrAuthFactory.php diff --git a/module/Finna/config/module.config.php b/module/Finna/config/module.config.php index 124fdbd9d0f..7a2a15897f4 100644 --- a/module/Finna/config/module.config.php +++ b/module/Finna/config/module.config.php @@ -554,10 +554,12 @@ 'autocomplete' => [ 'factories' => [ 'Finna\Autocomplete\Solr' => 'Finna\Autocomplete\SolrFactory', + \Finna\Autocomplete\SolrAuth::class => \Finna\Autocomplete\SolrAuthFactory::class, 'Finna\Autocomplete\L1' => 'Finna\Autocomplete\SolrFactory', ], 'aliases' => [ 'VuFind\Autocomplete\Solr' => 'Finna\Autocomplete\Solr', + \VuFind\Autocomplete\SolrAuth::class => \Finna\Autocomplete\SolrAuth::class, ], ], 'content_description' => [], diff --git a/module/Finna/src/Finna/Autocomplete/Solr.php b/module/Finna/src/Finna/Autocomplete/Solr.php index 08f290787d7..2a0327ae459 100644 --- a/module/Finna/src/Finna/Autocomplete/Solr.php +++ b/module/Finna/src/Finna/Autocomplete/Solr.php @@ -158,18 +158,15 @@ public function __construct( $this->facetConfig = $facetConfig; $this->searchConfig = $searchConfig; $this->facetSettings = $settings; - $this->facetTranslations = $facetConfig->Results->toArray(); - foreach ($facetConfig->CheckboxFacets->toArray() as $field => $val) { + $this->facetTranslations = $facetConfig?->Results?->toArray() ?? []; + foreach ($facetConfig?->CheckboxFacets?->toArray() ?? [] as $field => $val) { [$field, ] = explode(':', $field); $this->facetTranslations[$field] = $val; } $this->orFacets = []; - if (isset($this->facetConfig->Results_Settings->orFacets)) { - $this->orFacets = array_map( - 'trim', - explode(',', $this->facetConfig->Results_Settings->orFacets) - ); + if (null !== ($orFacets = $this->facetConfig->Results_Settings->orFacets ?? null)) { + $this->orFacets = array_map('trim', explode(',', $orFacets)); } parent::__construct($results); } diff --git a/module/Finna/src/Finna/Autocomplete/SolrAuth.php b/module/Finna/src/Finna/Autocomplete/SolrAuth.php new file mode 100644 index 00000000000..76d1ff981e6 --- /dev/null +++ b/module/Finna/src/Finna/Autocomplete/SolrAuth.php @@ -0,0 +1,64 @@ + + * @author Chris Hallberg + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:autosuggesters Wiki + */ + +namespace Finna\Autocomplete; + +/** + * Solr Authority Autocomplete Module + * + * This class provides suggestions by using the local Solr authority index. + * + * @category VuFind + * @package Autocomplete + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:autosuggesters Wiki + */ +class SolrAuth extends Solr +{ + /** + * Constructor + * + * @param PluginManager $results Results plugin manager + * @param \Laminas\Config\Config $facetConfig Facet configuration + * @param \Laminas\Config\Config $searchConfig Search configuration + * @param Url $urlHelper Url helper + */ + public function __construct( + \VuFind\Search\Results\PluginManager $results, + $facetConfig, + $searchConfig, + $urlHelper + ) { + parent::__construct($results, $facetConfig, $searchConfig, $urlHelper); + $this->defaultDisplayField = 'heading'; + $this->searchClassId = 'SolrAuth'; + } +} diff --git a/module/Finna/src/Finna/Autocomplete/SolrAuthFactory.php b/module/Finna/src/Finna/Autocomplete/SolrAuthFactory.php new file mode 100644 index 00000000000..6821df398b9 --- /dev/null +++ b/module/Finna/src/Finna/Autocomplete/SolrAuthFactory.php @@ -0,0 +1,83 @@ + + * @author Ere Maijala + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ + +namespace Finna\Autocomplete; + +use Laminas\ServiceManager\Exception\ServiceNotCreatedException; +use Laminas\ServiceManager\Exception\ServiceNotFoundException; +use Psr\Container\ContainerExceptionInterface as ContainerException; +use Psr\Container\ContainerInterface; + +/** + * Factory for Solr-driven autocomplete plugins. Works for \VuFind\Autocomplete\Solr + * and all of its subclasses. + * + * @category VuFind + * @package Autocomplete + * @author Demian Katz + * @author Ere Maijala + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class SolrAuthFactory implements \Laminas\ServiceManager\Factory\FactoryInterface +{ + /** + * Create an object + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException if any other error occurs + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function __invoke( + ContainerInterface $container, + $requestedName, + array $options = null + ) { + $configManager = $container->get(\VuFind\Config\PluginManager::class); + $config = $configManager->get('authority'); + return new $requestedName( + $container->get(\VuFind\Search\Results\PluginManager::class), + $config, + $config, + $container->get('ViewHelperManager')->get('url'), + ); + } +} From 35395b1c1627785262c672f2ce9b120ddcb306c3 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Tue, 10 Sep 2024 09:38:43 +0300 Subject: [PATCH 52/66] [FINNA-2563] Replace deprecated mb_convert_encoding call in Feed loader --- module/Finna/src/Finna/Feed/Feed.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/Finna/src/Finna/Feed/Feed.php b/module/Finna/src/Finna/Feed/Feed.php index c70c2861f27..245de9b2b11 100644 --- a/module/Finna/src/Finna/Feed/Feed.php +++ b/module/Finna/src/Finna/Feed/Feed.php @@ -738,7 +738,7 @@ protected function processItemContent( // attributes in div & p elements $dom = new \DOMDocument(); $saveErrors = libxml_use_internal_errors(true); - $dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8')); + $dom->loadHTML(htmlspecialchars_decode(htmlentities($content, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'))); $domx = new \DOMXPath($dom); // Process style attributes: From 7362a32960464b47d7e0189388401110ff472f64 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Tue, 10 Sep 2024 09:53:56 +0300 Subject: [PATCH 53/66] Revert "Fix calculation of slide header height. (#3018)" This reverts commit 1841dcbd3bab44b4877f865ee9b67faa2bcbf483. --- themes/finna2/js/finna-feed-element.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/themes/finna2/js/finna-feed-element.js b/themes/finna2/js/finna-feed-element.js index df64e5cb5cb..2387f7639fb 100644 --- a/themes/finna2/js/finna-feed-element.js +++ b/themes/finna2/js/finna-feed-element.js @@ -60,11 +60,11 @@ class FinnaFeedElement extends HTMLElement { // Move title field below image let maxH = 0; this.querySelectorAll('.carousel-slide-header p').forEach(el => { - maxH = Math.max(maxH, el.getBoundingClientRect().height + 10); el.classList.add('title-bottom'); - el.parentNode.classList.add('title-bottom'); + maxH = Math.max(maxH, el.getBoundingClientRect().height); + }); - this.querySelectorAll('.carousel-slide-header, .carousel-slide-header p').forEach(el => { + this.querySelectorAll('.carousel-slide-header p').forEach(el => { el.style.minHeight = el.style.height = `${maxH}px`; }); this.querySelectorAll('.carousel-feed .carousel-text').forEach(el => { From 16eacd32fa6005565f1ea86743c25abe9007022f Mon Sep 17 00:00:00 2001 From: Juha Luoma <33253757+LuomaJuha@users.noreply.github.com> Date: Tue, 10 Sep 2024 10:48:01 +0300 Subject: [PATCH 54/66] [FINNA-2478] LIDO: Add support for displaying video/quicktime videos (#2985) --- module/Finna/src/Finna/RecordDriver/SolrLido.php | 1 + 1 file changed, 1 insertion(+) diff --git a/module/Finna/src/Finna/RecordDriver/SolrLido.php b/module/Finna/src/Finna/RecordDriver/SolrLido.php index 493392ab066..22377cfaef0 100644 --- a/module/Finna/src/Finna/RecordDriver/SolrLido.php +++ b/module/Finna/src/Finna/RecordDriver/SolrLido.php @@ -143,6 +143,7 @@ class SolrLido extends \VuFind\RecordDriver\SolrDefault implements \Laminas\Log\ */ protected $supportedVideoFormats = [ 'mp4' => 'video/mp4', + 'mov' => 'video/quicktime', ]; /** From 223fed0dab1bde658849b2e0d45acdf46103c659 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Tue, 10 Sep 2024 11:07:40 +0300 Subject: [PATCH 55/66] [FINNA-2264] Fix feed title height calculation. --- themes/finna2/less/finna/feed.less | 2 ++ 1 file changed, 2 insertions(+) diff --git a/themes/finna2/less/finna/feed.less b/themes/finna2/less/finna/feed.less index f707c00140e..a6679360551 100644 --- a/themes/finna2/less/finna/feed.less +++ b/themes/finna2/less/finna/feed.less @@ -794,6 +794,8 @@ finna-feed.carousel.splide--ltr { font-size: 39px; } img { + // FIXME: min-width is required for proper title height calculation + min-width: 50px; max-width: none; max-height: 100%; position: relative; From 01cef7555722626bc1d4be95c72aa406bd8e0695 Mon Sep 17 00:00:00 2001 From: Pasi Tiisanoja Date: Wed, 11 Sep 2024 08:58:20 +0300 Subject: [PATCH 56/66] [FINNA-2264] Fix carousel title height calculation. (#3020) --- themes/finna2/less/finna/feed.less | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/themes/finna2/less/finna/feed.less b/themes/finna2/less/finna/feed.less index a6679360551..9cecc50a68d 100644 --- a/themes/finna2/less/finna/feed.less +++ b/themes/finna2/less/finna/feed.less @@ -759,6 +759,7 @@ finna-feed.carousel.splide--ltr { opacity: 0; } .carousel-text.scrollable { + z-index: 1; padding-bottom: 0; .carousel-text-shadow { position: sticky; @@ -794,8 +795,6 @@ finna-feed.carousel.splide--ltr { font-size: 39px; } img { - // FIXME: min-width is required for proper title height calculation - min-width: 50px; max-width: none; max-height: 100%; position: relative; @@ -843,7 +842,7 @@ finna-feed.carousel.splide--ltr { width: 100%; } } - position: absolute; + position: relative; bottom: 0; width: 100%; min-height: 30px; From f978d63d26c2da499a91525fab4e1a2420f9024f Mon Sep 17 00:00:00 2001 From: siiriylonen <117457514+siiriylonen@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:14:09 +0300 Subject: [PATCH 57/66] [FINNA-2119] Improve clarity of button functions in my account (#2994) --- local/languages/finna/en-gb.ini | 1 + local/languages/finna/fi.ini | 1 + local/languages/finna/sv.ini | 1 + themes/finna2/less/finna/myresearch.less | 72 +++++++++++++++---- .../finna2/templates/checkouts/history.phtml | 13 ++-- themes/finna2/templates/holds/list.phtml | 31 ++++---- .../templates/myresearch/checkedout.phtml | 13 ++-- .../templates/myresearch/illrequests.phtml | 22 +++--- .../myresearch/storageretrievalrequests.phtml | 22 +++--- 9 files changed, 118 insertions(+), 58 deletions(-) diff --git a/local/languages/finna/en-gb.ini b/local/languages/finna/en-gb.ini index f9a8b3d27c8..b3903223ea4 100644 --- a/local/languages/finna/en-gb.ini +++ b/local/languages/finna/en-gb.ini @@ -174,6 +174,7 @@ Call Slips = "Requests" Calling Name = "Calling Name" cannot cancel = "Cannot cancel" cannot cancel any interlibrary loan requests = "Cannot cancel any Interlibrary Loan Requests" +Cannot cancel any Retrieval Requests = "Cannot cancel any Retrieval Requests" Cannot renew yet = "Cannot renew yet" cannot renew = "Cannot renew" cannot renew any checked out items = "No items to renew" diff --git a/local/languages/finna/fi.ini b/local/languages/finna/fi.ini index 9837f584642..bf76a6269ee 100644 --- a/local/languages/finna/fi.ini +++ b/local/languages/finna/fi.ini @@ -168,6 +168,7 @@ Call Slips = "Tilaukset" Calling Name = "Kutsumanimi" cannot cancel = "Ei voi perua" cannot cancel any interlibrary loan requests = "Yhtään kaukolainatilausta ei voi perua" +Cannot cancel any Retrieval Requests = "Yhtään varastotilausta ei voi perua" Cannot renew yet = "Ei voida uusia vielä" cannot renew = "Ei voi uusia" cannot renew any checked out items = "Ei uusittavia lainoja" diff --git a/local/languages/finna/sv.ini b/local/languages/finna/sv.ini index 9dc17b400d1..ae0545209c0 100644 --- a/local/languages/finna/sv.ini +++ b/local/languages/finna/sv.ini @@ -168,6 +168,7 @@ Call Slips = "Beställningar" Calling Name = "Tilltalsnamn" cannot cancel = "Kan inte återkalla" cannot cancel any interlibrary loan requests = "Kan inte återkalla inga fjärrlånebeställningar" +Cannot cancel any Retrieval Requests = "Kan inte återkalla inga lagerbeställningar" Cannot renew yet = "Kan ännu inte förnyas" cannot renew = "Kan inte förnya" cannot renew any checked out items = "Inga förnyande lån" diff --git a/themes/finna2/less/finna/myresearch.less b/themes/finna2/less/finna/myresearch.less index f28c3f3ba97..ceaec2d4ebf 100644 --- a/themes/finna2/less/finna/myresearch.less +++ b/themes/finna2/less/finna/myresearch.less @@ -78,7 +78,7 @@ } } -.loan-history-purge-all { +.loan-history-purge-all, .button-bottom { margin-top: 10px; } .loan-history-buttons-bottom { @@ -98,16 +98,21 @@ .toolbar { display: flex; flex-direction: row; - align-items: baseline; + align-items: center; &.no-list-functions { + justify-content: space-between; + align-items: baseline; + @media(max-width: @screen-xs-max) { + flex-direction: column-reverse; + align-items: flex-start; + } .myresearch-notification { height: fit-content; - align-self: center; } } .btn-finna-toolbar { margin: 3px 0px; - @media (max-width: @screen-md) { + @media (max-width: @screen-sm-max) { font-size: 0.9em; } } @@ -122,6 +127,9 @@ &:last-child { margin-right: 0; } + @media(max-width: @screen-xs-max) { + margin-right: 10px; + } } .checkbox-col { display: flex; @@ -135,6 +143,9 @@ align-items: baseline; justify-content: space-between; } + @media(max-width: @screen-xs-max) { + align-items: baseline; + } } .sort-button ul.dropdown-menu li a { font-size: 1em; @@ -203,14 +214,34 @@ margin-right: 5px; } } - .sort-col a.dropdown-toggle { - margin-bottom: 0; - height: 30px; - font-size: 0.9em; - @media (max-width: @screen-md) { - margin-top: 6px; + .sort-col { + a.dropdown-toggle { + margin-bottom: 0; + height: 30px; + font-size: 0.9em; + @media (max-width: @screen-md) { + margin-top: 6px; + } + @media (max-width: @screen-sm) { + span { + max-width: 200px; + } + } + } + @media (max-width: @screen-sm) { + .dropdown-menu > li > a { + max-width: 270px; + } + .dropdown-toggle span:not('.icon'), .dropdown-menu > li > a { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + vertical-align: bottom; + } } } + } .list-description, .public-list-desc, @@ -289,8 +320,13 @@ width: 100%; border-radius: @border-radius-base; @media (max-width: @screen-sm) { - .select-card-wrapper .select-card .library_card li > a { - white-space: normal; + .select-card-wrapper .select-card .library_card { + right: auto; + left: 0; + max-width: 250px; + & li > a { + white-space: normal; + } } } } @@ -425,7 +461,7 @@ } .toolbar .list-functions .sort-col { - @media(max-width: @screen-sm) { + @media(max-width: @screen-xs-max) { display: none; } } @@ -550,7 +586,7 @@ margin-top: 5px; border-bottom: 1px solid @gray-lighter; padding: 3px 0; - @media(max-width: @screen-md) { + @media(max-width: @screen-sm-max) { margin-top: 0; } .status-text { @@ -573,6 +609,14 @@ } } +form#renewals, form#update_holds, form#purge_history { + .toolbar { + @media (max-width: @screen-xs) { + flex-direction: column-reverse; + } + } +} + .online-payment-data { font-size: 1.2em; margin-bottom: 40px; diff --git a/themes/finna2/templates/checkouts/history.phtml b/themes/finna2/templates/checkouts/history.phtml index 1c745a61ed7..a2f555a316d 100644 --- a/themes/finna2/templates/checkouts/history.phtml +++ b/themes/finna2/templates/checkouts/history.phtml @@ -38,12 +38,12 @@ content()->findTemplateForLng('content/Additions/historic-loans-pre-list')): ?>
    render($template)?>
    -
    + transactions)): ?> - context($this)->renderInContext('myresearch/controls/sort.phtml', ['sortList' => $sortList]); ?> +
    + context($this)->renderInContext('myresearch/controls/sort.phtml', ['sortList' => $sortList]); ?> +
    -
    - transactions)): ?>
    paginationControl($paginator, 'Sliding', 'Helpers/pagination-simple.phtml', ['params' => $params]) ?> @@ -65,7 +65,8 @@
    @@ -87,7 +88,7 @@ transactions)): ?>
    - cancelForm): ?> -
    - - -
    -
    @@ -96,6 +85,11 @@
    transEsc('Cannot update any of the holds')?>
    + recordList)): ?> + +
    @@ -246,7 +240,18 @@
    - cancelForm): ?>
    + cancelForm): ?> + + +
    + content()->findTemplateForLng('content/Additions/holds-post-list')): ?>
    render($template)?>
    diff --git a/themes/finna2/templates/myresearch/checkedout.phtml b/themes/finna2/templates/myresearch/checkedout.phtml index 1ce01c6a999..96b170ba359 100644 --- a/themes/finna2/templates/myresearch/checkedout.phtml +++ b/themes/finna2/templates/myresearch/checkedout.phtml @@ -67,7 +67,8 @@
    @@ -107,12 +108,10 @@
    transEsc('cannot renew any checked out items')?>
    -
    -
    - - context($this)->renderInContext('myresearch/controls/sort.phtml', ['sortList' => $sortList]); ?> - -
    +
    + + context($this)->renderInContext('myresearch/controls/sort.phtml', ['sortList' => $sortList]); ?> +
    diff --git a/themes/finna2/templates/myresearch/illrequests.phtml b/themes/finna2/templates/myresearch/illrequests.phtml index 6a074761e11..4b02116d4c5 100644 --- a/themes/finna2/templates/myresearch/illrequests.phtml +++ b/themes/finna2/templates/myresearch/illrequests.phtml @@ -47,6 +47,7 @@
    @@ -66,14 +67,6 @@
  • transEsc('confirm_dialog_no')?>
  • -
    - - -
    @@ -186,7 +179,18 @@ - cancelForm): ?>
    + cancelForm): ?> + + +
    + content()->findTemplateForLng('content/Additions/illrequests-post-list')): ?>
    render($template)?>
    diff --git a/themes/finna2/templates/myresearch/storageretrievalrequests.phtml b/themes/finna2/templates/myresearch/storageretrievalrequests.phtml index ecda175b006..41393c2c472 100644 --- a/themes/finna2/templates/myresearch/storageretrievalrequests.phtml +++ b/themes/finna2/templates/myresearch/storageretrievalrequests.phtml @@ -46,6 +46,7 @@
    @@ -65,14 +66,6 @@
  • transEsc('confirm_dialog_no')?>
  • -
    - - -
    @@ -182,7 +175,18 @@ - cancelForm): ?> + cancelForm): ?> + + + + content()->findTemplateForLng('content/Additions/storageretrievalrequests-post-list')): ?>
    render($template)?>
    From adb4cc8fc2f938c83fc05b27abdb8f345c7e74ef Mon Sep 17 00:00:00 2001 From: Pasi Tiisanoja Date: Wed, 11 Sep 2024 13:19:08 +0300 Subject: [PATCH 58/66] [FINNA-2334] Make mobile menu focus visible. (#2984) --- themes/finna2/less/global/navbar-bootstrap.less | 4 ++++ themes/finna2/templates/navibar.phtml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/themes/finna2/less/global/navbar-bootstrap.less b/themes/finna2/less/global/navbar-bootstrap.less index e6b57dc6e8c..e767fd292da 100644 --- a/themes/finna2/less/global/navbar-bootstrap.less +++ b/themes/finna2/less/global/navbar-bootstrap.less @@ -74,6 +74,10 @@ background-color: @brand-primary; padding: 0; border-radius: 0; + &:focus { + background: darken(@brand-primary, 10%); + outline: 5px auto -webkit-focus-ring-color; + } .mobilemenu-bars, .mobilemenu-close { font-size: 24px; cursor: pointer; diff --git a/themes/finna2/templates/navibar.phtml b/themes/finna2/templates/navibar.phtml index ed27652024d..6cf7f622f90 100644 --- a/themes/finna2/templates/navibar.phtml +++ b/themes/finna2/templates/navibar.phtml @@ -9,11 +9,11 @@ ?>