From 0554b176853b9cd5f5b76e3df3a1d09138470f9c Mon Sep 17 00:00:00 2001 From: Alex Arnaud <alex.arnaud@biblibre.com> Date: Fri, 7 Mar 2025 10:16:16 +0100 Subject: [PATCH 1/5] [RTok] hotline#220612 : UserGroup form : fix getting search_id_site --- VERSIONS_HOTLINE/220612 | 1 + .../Controller/Plugin/Manager/UserGroup.php | 4 +- .../UserGroupControllerPostWithSiteTest.php | 48 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 VERSIONS_HOTLINE/220612 create mode 100644 tests/application/modules/admin/controllers/UserGroupControllerPostWithSiteTest.php diff --git a/VERSIONS_HOTLINE/220612 b/VERSIONS_HOTLINE/220612 new file mode 100644 index 00000000000..804988cf6e0 --- /dev/null +++ b/VERSIONS_HOTLINE/220612 @@ -0,0 +1 @@ +- correctif #220612 : corrige la récupération du site dans le formulaire des groupes dynamiques \ No newline at end of file diff --git a/library/ZendAfi/Controller/Plugin/Manager/UserGroup.php b/library/ZendAfi/Controller/Plugin/Manager/UserGroup.php index 980c0dd0f24..6dd1715b041 100644 --- a/library/ZendAfi/Controller/Plugin/Manager/UserGroup.php +++ b/library/ZendAfi/Controller/Plugin/Manager/UserGroup.php @@ -204,8 +204,8 @@ class ZendAfi_Controller_Plugin_Manager_UserGroup ZendAfi_Form_Admin_UserGroup::PERMISSION); $multi_lib_name = (new Class_User_SearchCriteriaMultiLibraries([]))->getName(); - if (isset($post[$multi_lib_name])) - $post[$multi_lib_name] |= 'all'; + if ( ! ($post[$multi_lib_name] ?? null)) + $post[$multi_lib_name] = 'all'; unset($post[ZendAfi_Form_Admin_UserGroup::RIGHTS_PERMISSIONS]); return $post; diff --git a/tests/application/modules/admin/controllers/UserGroupControllerPostWithSiteTest.php b/tests/application/modules/admin/controllers/UserGroupControllerPostWithSiteTest.php new file mode 100644 index 00000000000..57c2a56ce8b --- /dev/null +++ b/tests/application/modules/admin/controllers/UserGroupControllerPostWithSiteTest.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright (c) 2012-2024, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class UserGroupControllerPostSiteTest extends Admin_AbstractControllerTestCase +{ + public function setUp(): void + { + parent::setUp(); + $this->fixture(Class_UserGroup::class, + ['id' => 77, + 'protected' => false, + 'libelle' => 'Accés aux ressources numériques', + 'group_type' => Class_UserGroup::TYPE_DYNAMIC, + 'users' => [], + 'rights' => []]); + + $this->postDispatch('admin/usergroup/edit/id/77', + ['libelle' => 'Accés aux ressources numériques', + 'search_id_site' => '2']); + } + + + /** @test */ + public function searchIdSiteFilterShouldBeSavedAs2() + { + $this->assertEquals('2', json_decode(Class_UserGroup::find(77) + ->getFilters())->search_id_site); + } +} -- GitLab From 2cce7a06537bea6047fb4be1deead34c756efef2 Mon Sep 17 00:00:00 2001 From: Alex Arnaud <alex.arnaud@biblibre.com> Date: Thu, 13 Mar 2025 10:06:49 +0100 Subject: [PATCH 2/5] [RTOK] hotline#218050 : Session activity form : don't show queue message if total max is over 0 --- VERSIONS_HOTLINE/218050 | 1 + library/Class/SessionActivity.php | 1 + ...ActivitiesWithQueueAndZeroTotalMaxTest.php | 88 +++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 VERSIONS_HOTLINE/218050 create mode 100644 tests/scenarios/Activities/ActivitiesWithQueueAndZeroTotalMaxTest.php diff --git a/VERSIONS_HOTLINE/218050 b/VERSIONS_HOTLINE/218050 new file mode 100644 index 00000000000..021670660d8 --- /dev/null +++ b/VERSIONS_HOTLINE/218050 @@ -0,0 +1 @@ + - correctif #218050 : Formulaire d'inscritpion à une session : n'affiche pas le message de placement en attente si le total max est à 0. \ No newline at end of file diff --git a/library/Class/SessionActivity.php b/library/Class/SessionActivity.php index 088161eb624..9843734d635 100644 --- a/library/Class/SessionActivity.php +++ b/library/Class/SessionActivity.php @@ -763,6 +763,7 @@ class Class_SessionActivity extends Storm_Model_Abstract { public function acceptAttendeesOnlyInQueue(): bool { return $this->getQueueAttendees() + && $this->getEffectifTotalMax() > 0 && ($this->getTotalRegistered() >= $this->getEffectifTotalMax()); } diff --git a/tests/scenarios/Activities/ActivitiesWithQueueAndZeroTotalMaxTest.php b/tests/scenarios/Activities/ActivitiesWithQueueAndZeroTotalMaxTest.php new file mode 100644 index 00000000000..c35dfe881a2 --- /dev/null +++ b/tests/scenarios/Activities/ActivitiesWithQueueAndZeroTotalMaxTest.php @@ -0,0 +1,88 @@ +<?php +/** + * Copyright (c) 2012-2025, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class ActivitiesWithQueueAndZeroTotalMaxTest extends AbstractControllerTestCase +{ + public function setUp(): void + { + parent::setUp(); + $this->_buildTemplateProfil(['id' => 1]); + $time = new TimeSourceForTest('2024-04-01 14:00:00'); + + Class_Activity::setTimeSource($time); + Class_SessionActivity::setTimeSource($time); + Class_SessionActivityInscription::setTimeSource($time); + + Class_AdminVar::set('ACTIVITY', '1'); + Class_AdminVar::set('ACTIVITY_SESSION_QUOTAS', '1'); + + $groupe = $this->fixture(Class_UserGroup::class, + ['id' => 12, + 'libelle' => 'Stagiaires', + 'rights' => [Class_UserGroup::RIGHT_SUIVRE_ACTIVITY]]); + + $user = $this->fixture(Class_Users::class, + ['id' => 435, + 'prenom' => 'Chichi', + 'nom' => 'Ro', + 'login' => 'Chichiro', + 'password' => 'pwd', + 'mail' => 'chichi@ro.fr', + 'id_site' => 12, + 'user_groups' => [$groupe]]); + + ZendAfi_Auth::getInstance()->logUser($user); + + $this->fixture(Class_Activity::class, + ['id' => 33, + 'libelle' => 'Apprendre à nager']); + + $this->fixture(Class_SessionActivity::class, + ['id' => 35, + 'activity_id' => 33, + 'date_debut' => '2024-04-20', + 'date_fin' => '2024-04-20', + 'effectif_min' => 0, + 'effectif_max' => 3, + 'effectif_child_min' => 0, + 'effectif_child_max' => 0, + 'age_child_max' => 0, + 'effectif_inscription_max' => 2, + 'effectif_inscription_child_max' => 0, + 'effectif_total_min' => 0, + 'effectif_total_max' => 0, + 'duree'=> 2, + 'contenu' => 'Intro à la natation', + 'horaires' => '9h', + 'date_limite_inscription'=>'2024-04-19', + 'queue_attendees' => true + ]); + + $this->dispatch('/opac/abonne/inscrire-session/id/35'); + } + + /** @test */ + public function messageYouWillBePutInQueueShouldNotBeDisplayed() + { + $this->assertNotXpathContentContains('//div', 'Vous serez placé.e en liste d\'attente'); + } +} -- GitLab From 387afccdb05eb271d2acebde1b347197f221e6e0 Mon Sep 17 00:00:00 2001 From: Alex Arnaud <alex.arnaud@biblibre.com> Date: Thu, 13 Mar 2025 10:10:45 +0100 Subject: [PATCH 3/5] [RTOK] hotline#193156 : fix date format when typing manually in DTpickers --- VERSIONS_HOTLINE/193156 | 1 + .../jquery.simple-dtpicker.js | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 VERSIONS_HOTLINE/193156 diff --git a/VERSIONS_HOTLINE/193156 b/VERSIONS_HOTLINE/193156 new file mode 100644 index 00000000000..9b54897e47a --- /dev/null +++ b/VERSIONS_HOTLINE/193156 @@ -0,0 +1 @@ +- correctif #193156 : corrige la saisie manuelle dans les datetimepickers \ No newline at end of file diff --git a/public/opac/js/mugifly-jquery-simple-datetimepicker/jquery.simple-dtpicker.js b/public/opac/js/mugifly-jquery-simple-datetimepicker/jquery.simple-dtpicker.js index 8afcb2a83b8..b90f8c3bc29 100644 --- a/public/opac/js/mugifly-jquery-simple-datetimepicker/jquery.simple-dtpicker.js +++ b/public/opac/js/mugifly-jquery-simple-datetimepicker/jquery.simple-dtpicker.js @@ -856,7 +856,8 @@ $(this).addClass('active'); var $picker = getParentPickerObject($(this)); - var date = getPickedDate($picker); + var $inp = getPickersInputObject($picker); + date = formatDateString($picker, $inp.val()); var hour = $(this).data("hour"); var min = $(this).data("min"); draw($picker, { @@ -927,6 +928,17 @@ return obj !== undefined && obj !== null && clas === type; }; + var formatDateString = function($picker, date_string) { + var format = $picker.data('dateFormat'); + // Do we need to do that for each available formats ? + if (format.startsWith('DD/MM/YYYY')) { + parts = date_string.split(' ')[0].split('/'); + return new Date(parts[2], parts[1] -1, parts[0]); + } + + return getPickedDate($picker); + }; + var init = function($obj, opt) { /* Container */ var $picker = $('<div>'); -- GitLab From dd42394cc9d9a9299b74f380339480f342cfde28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?ANDRE=20s=C3=A9bastien?= <sandre@afi-sa.fr> Date: Thu, 13 Mar 2025 11:23:12 +0100 Subject: [PATCH 4/5] hotline_221141 : dont block save for rewrite url --- VERSIONS_HOTLINE/221141 | 1 + .../admin/controllers/BibController.php | 31 ++-- .../admin/controllers/ProfilController.php | 33 ++-- library/Class/Bib.php | 6 +- library/Class/Profil.php | 5 +- library/ZendAfi/Form/Admin/Library.php | 2 + .../ZendAfi/Form/Configuration/Profile.php | 13 +- .../Form/Configuration/Profile/Page.php | 13 +- library/ZendAfi/Validate/RewriteUrl.php | 150 ++---------------- .../Validate/RewriteUrl/LibraryStrategy.php | 37 +++-- .../Validate/RewriteUrl/NullStrategy.php | 86 +++++++++- .../Validate/RewriteUrl/ProfilStrategy.php | 114 ++----------- .../RewriteUrl/StringLibraryStrategy.php | 61 +++++++ .../RewriteUrl/StringProfilStrategy.php | 61 +++++++ .../Validate/RewriteUrl/StringStrategy.php | 68 -------- .../ProfilControllerRewriteUrlTest.php | 47 +++++- .../controllers/WidgetControllerTest.php | 29 ++-- tests/library/Class/ProfilTest.php | 34 ++-- 18 files changed, 389 insertions(+), 402 deletions(-) create mode 100644 VERSIONS_HOTLINE/221141 create mode 100644 library/ZendAfi/Validate/RewriteUrl/StringLibraryStrategy.php create mode 100644 library/ZendAfi/Validate/RewriteUrl/StringProfilStrategy.php delete mode 100644 library/ZendAfi/Validate/RewriteUrl/StringStrategy.php diff --git a/VERSIONS_HOTLINE/221141 b/VERSIONS_HOTLINE/221141 new file mode 100644 index 00000000000..564ac5968e7 --- /dev/null +++ b/VERSIONS_HOTLINE/221141 @@ -0,0 +1 @@ + - correctif #221141 : Profil : Modifier un profil qui a une url de redirection ne génère plus de message d'erreur de validation inadéquat. \ No newline at end of file diff --git a/application/modules/admin/controllers/BibController.php b/application/modules/admin/controllers/BibController.php index 762491fa12c..85fc7348236 100644 --- a/application/modules/admin/controllers/BibController.php +++ b/application/modules/admin/controllers/BibController.php @@ -355,38 +355,43 @@ class Admin_BibController extends ZendAfi_Controller_Action { } - public function updateLieuElementAction() { - if (!$library = Class_Bib::find($this->_getParam('id'))) + public function updateLieuElementAction() + { + if ( ! ($library = Class_Bib::find($this->_getParam('id')))) return $this->_renderUpdateLieuElement(fn() => $this->view->renderError('Bibliothèque non trouvée')); - $library->updateAttributes($this->getRequest()->getParams()); - if (!$location = $this->getOrCreateLocation($this->_getParam('id_lieu'), $library)) - return $this->_renderUpdateLieuElement(fn() => $this->view->renderError('Vous devez d\'abord définir le nom de la bibliothèque')); + if ( ! ($location = $this->getOrCreateLocation($this->_getParam('id_lieu'), $library))) + return $this->_renderUpdateLieuElement(fn() => $this->view->renderError('Vous devez d\'abord définir le nom de la bibliothèque'), $library); $this->_renderUpdateLieuElement(function($location_element) use ($location) - { - $location_element->setValue($location->getId()); + { + $location_element->setValue($location->getId()); + + return + $this->view->tagEditLocation($location, true) . + $this->view->renderLieu($location); + }, $library); - return - $this->view->tagEditLocation($location, true) . - $this->view->renderLieu($location); - }); return null; } - protected function _renderUpdateLieuElement($callback) { + protected function _renderUpdateLieuElement(Closure $callback): self + { $viewRenderer = $this->getHelper('ViewRenderer'); $viewRenderer->setNoRender(); - $location_element = (new ZendAfi_Form_Admin_Library())->newLocationElement(); + $location_element = (new ZendAfi_Form_Admin_Library) + ->newLocationElement(); $location_element->removeDecorator('HtmlTag'); $location_element->removeDecorator('Label'); $html = $callback($location_element); $this->getResponse()->setBody($location_element->render($this->view) . $html); + + return $this; } diff --git a/application/modules/admin/controllers/ProfilController.php b/application/modules/admin/controllers/ProfilController.php index 3423907fe6b..b3e1a1ea7c1 100644 --- a/application/modules/admin/controllers/ProfilController.php +++ b/application/modules/admin/controllers/ProfilController.php @@ -310,9 +310,11 @@ class Admin_ProfilController extends ZendAfi_Controller_Action { protected function getSearchAndLoginWidget($widgets_as_array) { $widget_by_type = array_filter($widgets_as_array, function($widget) - { $type = $widget['type_module']; - if($type == 'LOGIN' || $type == 'RECH_SIMPLE') - return true; }); + { + $type = $widget['type_module']; + if($type == 'LOGIN' || $type == 'RECH_SIMPLE') + return true; + }); $result = []; $uniq_type_widgets = []; foreach($widget_by_type as $id => $widget) { @@ -336,7 +338,8 @@ class Admin_ProfilController extends ZendAfi_Controller_Action { $this->_profil->getCfgSiteAsArray(), $this->_profil->getCfgAccueilAsArray()); - $this->view->form = ZendAfi_Form_Configuration_Profile_Page::newWith($params); + $this->view->form = ZendAfi_Form_Configuration_Profile_Page::newWith($params) + ->addValidatorsFor($this->_profil); $this->view->form->setAction($this->view->url()); if ( ! $this->_request->isPost() ) @@ -344,8 +347,8 @@ class Admin_ProfilController extends ZendAfi_Controller_Action { $this->_profil->setIntent($this->_getParam('intent', '')); - if( ! $this->view->form->isValidModelAndArray($this->_profil, - $this->_request->getPost())) + if ( ! $this->view->form->isValidModelAndArray($this->_profil, + $this->_request->getPost())) return null; return $this->updateAccueil($this->_profil); @@ -355,14 +358,14 @@ class Admin_ProfilController extends ZendAfi_Controller_Action { public function genresAction() { if ($this->_request->isPost() && $_POST !== []) + { + foreach($_POST as $id => $picto) { - foreach($_POST as $id => $picto) - { - $elems=explode("_",$id); - $id_genre=$elems[1]; - sqlExecute("update codif_genre set picto='$picto' where id_genre=$id_genre"); - } + $elems=explode("_",$id); + $id_genre=$elems[1]; + sqlExecute("update codif_genre set picto='$picto' where id_genre=$id_genre"); } + } // Entree en maj $this->view->genres=fetchAll("select * from codif_genre"); $this->view->titre = $this->_("Pictogrammes pour les genres"); @@ -379,7 +382,8 @@ class Admin_ProfilController extends ZendAfi_Controller_Action { $params['boite_recherche_simple_in_banniere'] = $profil->getBoiteRechercheSimpleInBanniere(); $params['boite_login_in_banniere'] = $profil->getBoiteLoginInBanniere(); - $this->view->form = ZendAfi_Form_Configuration_Profile::newWith($params); + $this->view->form = ZendAfi_Form_Configuration_Profile::newWith($params) + ->addValidatorsFor($this->_profil); $this->view->form->setAction($this->view->url()); @@ -427,7 +431,8 @@ class Admin_ProfilController extends ZendAfi_Controller_Action { $params['boite_recherche_simple_in_banniere'] = $profil->getBoiteRechercheSimpleInBanniere(); $params['boite_login_in_banniere'] = $profil->getBoiteLoginInBanniere(); - $this->view->form = ZendAfi_Form_Configuration_Profile::newWith($params); + $this->view->form = ZendAfi_Form_Configuration_Profile::newWith($params) + ->addValidatorsFor($this->_profil); $this->view->form->setAction($this->view->url()); $this->_postProfil($profil); diff --git a/library/Class/Bib.php b/library/Class/Bib.php index 36e2a69df93..3c490beb038 100644 --- a/library/Class/Bib.php +++ b/library/Class/Bib.php @@ -923,11 +923,7 @@ class Class_Bib extends Storm_Model_Abstract { !$this->getNotifyOnNewUser() || $this->getMail(), $this->_('Merci d\'indiquer un email dans l\'onglet Adresse')); - $validator = new ZendAfi_Validate_RewriteUrl; - $validator->isValid($this); - foreach($validator->getMessages() as $message) { - $this->checkAttribute('rewrite_url', false, $message); - } + (new ZendAfi_Validate_RewriteUrl_LibraryStrategy($this))->validateUrl(); } diff --git a/library/Class/Profil.php b/library/Class/Profil.php index fd613ecc59f..077d20f426e 100644 --- a/library/Class/Profil.php +++ b/library/Class/Profil.php @@ -1579,13 +1579,12 @@ class Class_Profil extends Storm_Model_Abstract { $this->_isCSSColorValid($this->getCouleurLienBandeau()), $this->_('La couleur des liens du bandeau doit être au format #001122')); - $validator = new ZendAfi_Validate_RewriteUrl; - $validator->isValid($this); + (new ZendAfi_Validate_RewriteUrl_ProfilStrategy($this))->validateUrl(); $intent_validator = new ZendAfi_Validate_ProfileIntent; $intent_validator->isValid($this); - foreach ($intent_validator->getMessages() + $validator->getMessages() as $message) + foreach ($intent_validator->getMessages() as $message) $this->check(false, $message); return $this; diff --git a/library/ZendAfi/Form/Admin/Library.php b/library/ZendAfi/Form/Admin/Library.php index d24733ab283..6608c51a423 100644 --- a/library/ZendAfi/Form/Admin/Library.php +++ b/library/ZendAfi/Form/Admin/Library.php @@ -76,6 +76,8 @@ class ZendAfi_Form_Admin_Library extends ZendAfi_Form { ->addElement('text', 'rewrite_url', ['label' => $this->_('URL de redirection'), + 'validators' => [(new ZendAfi_Validate_RewriteUrl) + ->initLibraryStrategy($this->_library)], 'size' => 50]) ->addElement('comboProfils', diff --git a/library/ZendAfi/Form/Configuration/Profile.php b/library/ZendAfi/Form/Configuration/Profile.php index 81366dbb826..b0c9753784d 100644 --- a/library/ZendAfi/Form/Configuration/Profile.php +++ b/library/ZendAfi/Form/Configuration/Profile.php @@ -72,8 +72,7 @@ class ZendAfi_Form_Configuration_Profile extends ZendAfi_Form ->addElement('text', 'rewrite_url', - ['label' => $this->_('URL du profil'), - 'validators' => [new ZendAfi_Validate_RewriteUrl]]) + ['label' => $this->_('URL du profil')]) ->addElement('userfile', 'header_img', @@ -425,4 +424,14 @@ class ZendAfi_Form_Configuration_Profile extends ZendAfi_Form return $this; } + + + public function addValidatorsFor(?Class_Profil $profil): self + { + if ($rewrite_url = $this->getElement('rewrite_url')) + $rewrite_url->setValidators([(new ZendAfi_Validate_RewriteUrl) + ->initProfilStrategy($profil)]); + + return $this; + } } diff --git a/library/ZendAfi/Form/Configuration/Profile/Page.php b/library/ZendAfi/Form/Configuration/Profile/Page.php index 14130ac8c3f..a49a3afa8d2 100644 --- a/library/ZendAfi/Form/Configuration/Profile/Page.php +++ b/library/ZendAfi/Form/Configuration/Profile/Page.php @@ -36,8 +36,7 @@ class ZendAfi_Form_Configuration_Profile_Page extends ZendAfi_Form ->addElement('text', 'rewrite_url', - ['label' => $this->_('URL de redirection'), - 'validators' => [new ZendAfi_Validate_RewriteUrl]]) + ['label' => $this->_('URL de redirection')]) ->addElement('checkbox', 'use_parent_css', @@ -96,4 +95,14 @@ class ZendAfi_Form_Configuration_Profile_Page extends ZendAfi_Form Class_Template::current()->customProfilePageForm($this); } + + + public function addValidatorsFor(?Class_Profil $profil): self + { + if ($rewrite_url = $this->getElement('rewrite_url')) + $rewrite_url->setValidators([(new ZendAfi_Validate_RewriteUrl) + ->initProfilStrategy($profil)]); + + return $this; + } } diff --git a/library/ZendAfi/Validate/RewriteUrl.php b/library/ZendAfi/Validate/RewriteUrl.php index 2187ba889b6..7650b598590 100644 --- a/library/ZendAfi/Validate/RewriteUrl.php +++ b/library/ZendAfi/Validate/RewriteUrl.php @@ -22,160 +22,40 @@ class ZendAfi_Validate_RewriteUrl extends Zend_Validate_Abstract { - use Trait_Translator; - const - INVALID_URL = 'invalidURL', - URL_ALREADY_EXISTS_IN_A_MODEL = 'urlAlreadyExistsInAModel', - URL_ALREADY_EXISTS_IN_A_PAGE = 'urlAlreadyExistsInAPage', - URL_ALREADY_EXISTS_IN_ANOTHER_MODEL = 'urlAlreadyExistsInAnOtherModel', - URL_FORBIDEN = 'url_forbiden'; + protected ?ZendAfi_Validate_RewriteUrl_NullStrategy $_strategy = null; - protected array $_messageTemplates = []; - protected bool $_validate_url = true; - - public function isValid($model): bool + public function isValid($url) { - if (is_string($model)) { - (new ZendAfi_Validate_RewriteUrl_StringStrategy($this, $model))->validateUrl(); - - return $this->getValidateUrl(); - } - - if ($model instanceof Class_Bib) { - (new ZendAfi_Validate_RewriteUrl_LibraryStrategy($this, $model))->validateUrl(); - - return $this->getValidateUrl(); - } - - if ($model instanceof Class_Profil) - (new ZendAfi_Validate_RewriteUrl_ProfilStrategy($this, $model))->validateUrl(); - - return $this->getValidateUrl(); + return $this->_strategy + ? $this->_strategy->addUrl($url)->validateUrl() + : true; } - protected function _initMessageTEmplates(): self + public function initProfilStrategy($model): self { - if ( ! $this->_messageTemplates) - $this->_messageTemplates = [static::INVALID_URL => '', - static::URL_ALREADY_EXISTS_IN_A_MODEL => '', - static::URL_ALREADY_EXISTS_IN_A_PAGE => '', - static::URL_ALREADY_EXISTS_IN_ANOTHER_MODEL => '', - static::URL_FORBIDEN => '']; + $this->_strategy = (new ZendAfi_Validate_RewriteUrl_StringProfilStrategy($model)) + ->addValidator($this); return $this; } - public function errorInvalideUrl(string $value): self - { - $this->_initMessageTEmplates(); - - $key = static::INVALID_URL; - - $this->_messageTemplates[$key] = $this->_("'%s' n'est pas une URL valide", - $value); - - return $this->_addError($key); - } - - - public function errorUrlForbiden(string $value): self - { - $this->_initMessageTEmplates(); - - $key = static::URL_FORBIDEN; - - $this->_messageTemplates[$key] = $this->_("L'Url '%s' est une url interdite", - $value); - - return $this->_addError($key); - } - - - public function errorAlreadyExistInProfil(string $value, string $label): self - { - $this->_initMessageTEmplates(); - - $key = static::URL_ALREADY_EXISTS_IN_A_MODEL; - - $this->_messageTemplates[$key] = $this->_("L'URL '%s' est déjà définie pour le profil: '%s'", - $value, - $label); - - return $this->_addError($key); - } - - - public function errorAlreadyExistInLibrary(string $value, string $label): self - { - $this->_initMessageTEmplates(); - - $key = static::URL_ALREADY_EXISTS_IN_A_MODEL; - - $this->_messageTemplates[$key] = $this->_("L'URL '%s' est déjà définie pour la bibliothèque: '%s'", - $value, - $label); - - return $this->_addError($key); - } - - - public function errorAlreadyExistsInPage(string $value, string $page): self - { - $this->_initMessageTEmplates(); - - $key = static::URL_ALREADY_EXISTS_IN_A_PAGE; - - $this->_messageTemplates[$key] = $this->_("L'URL '%s' est déjà définie pour la page '%s'", - $value, - $page); - - return $this->_addError($key); - } - - - public function errorAlreadyExistsInAnotherProfil(string $value, string $label): self - { - $this->_initMessageTEmplates(); - - $key = static::URL_ALREADY_EXISTS_IN_ANOTHER_MODEL; - - $this->_messageTemplates[$key] = $this->_("L'URL '%s' est déjà définie pour le profil: '%s'", - $value, - $label); - - return $this->_addError($key); - } - - - public function errorAlreadyExistsInAnotherLibrary(string $value, string $label): self + public function initLibraryStrategy($model): self { - $this->_initMessageTEmplates(); - - $key = static::URL_ALREADY_EXISTS_IN_ANOTHER_MODEL; + $this->_strategy = (new ZendAfi_Validate_RewriteUrl_StringLibraryStrategy($model)) + ->addValidator($this); - $this->_messageTemplates[$key] = $this->_("L'URL '%s' est déjà définie pour la bibliothèque: '%s'", - $value, - $label); - - return $this->_addError($key); + return $this; } - protected function _addError(string $key): self + public function addError(string $message): self { - $this->_validate_url = false; - - $this->_error($key); + $this->_messageTemplates['error_rewrite'] = $message; + $this->_error('error_rewrite'); return $this; } - - - public function getValidateUrl(): bool - { - return $this->_validate_url; - } } diff --git a/library/ZendAfi/Validate/RewriteUrl/LibraryStrategy.php b/library/ZendAfi/Validate/RewriteUrl/LibraryStrategy.php index fd139fee26a..0153574f0b4 100644 --- a/library/ZendAfi/Validate/RewriteUrl/LibraryStrategy.php +++ b/library/ZendAfi/Validate/RewriteUrl/LibraryStrategy.php @@ -23,28 +23,26 @@ class ZendAfi_Validate_RewriteUrl_LibraryStrategy extends ZendAfi_Validate_RewriteUrl_NullStrategy { - public function __construct(protected ZendAfi_Validate_RewriteUrl $_validator, - protected Class_Bib $_bib) - {} + protected string $_column = 'id_site'; - - public function validateUrl(): self + public function validateUrl(): bool { - return $this->_checkDefaultUrl((string) $this->_bib->getRewriteUrl()) - ->_checkBibWithSameUrlAsAnotherBib() - ->_checkOtherModelsUrl(); + $this->_initUrl() + ->_checkDefaultUrl() + ->_checkBibWithSameUrlAsAnotherBib() + ->_checkOtherModelsUrl(); + + return parent::validateUrl(); } protected function _checkOtherModelsUrl(): self { if ($this->_mustCheck() - && ($label = (Class_Profil::query() - ->select('libelle') - ->eq('rewrite_url', $this->_url) - ->fetchFirst() - ?->getLibelle() ?? ''))) - $this->_validator->errorAlreadyExistsInAnotherProfil($this->_url, $label); + && ($profil = Class_Profil::query() + ->eq('rewrite_url', $this->_url) + ->fetchFirst())) + $this->_errorAlreadyExistInProfil($profil); return $this; } @@ -53,11 +51,12 @@ class ZendAfi_Validate_RewriteUrl_LibraryStrategy extends ZendAfi_Validate_Rewri protected function _checkBibWithSameUrlAsAnotherBib(): self { if ($this->_mustCheck() - && ($other = Class_Bib::query() - ->eq('rewrite_url', $this->_url) - ->not_eq('id_site', $this->_bib->getId()) - ->fetchFirst())) - $this->_validator->errorAlreadyExistInLibrary($this->_url, $other->getLibelle()); + && ($label = ($this->_queryNotId(Class_Bib::query() + ->select('libelle') + ->eq('rewrite_url', $this->_url)) + ->fetchFirst() + ?->getLibelle() ?? ''))) + $this->_errorAlreadyExistInLibrary($label); return $this; } diff --git a/library/ZendAfi/Validate/RewriteUrl/NullStrategy.php b/library/ZendAfi/Validate/RewriteUrl/NullStrategy.php index 2c0cf0d31b3..41cc8f9b92e 100644 --- a/library/ZendAfi/Validate/RewriteUrl/NullStrategy.php +++ b/library/ZendAfi/Validate/RewriteUrl/NullStrategy.php @@ -22,26 +22,41 @@ class ZendAfi_Validate_RewriteUrl_NullStrategy { + use Trait_Translator; - protected string $_url = ''; + protected string $_url; + protected bool $_validate_url = true; + protected string $_column = ''; - public function validateUrl(): self + public function __construct(protected ?Storm_Model_Abstract $_model) + {} + + + public function validateUrl(): bool { - return $this; + return $this->_validate_url; } - protected function _checkDefaultUrl(string $url): self + protected function _initUrl(): self { - $this->_url = trim($url); + $this->_url = $this->_model + ? trim((string) $this->_model->getRewriteUrl()) + : ''; + + return $this; + } + + protected function _checkDefaultUrl(): self + { if ($this->_mustCheck() && ! preg_match("/^[a-zA-Z0-9\-_]*$/", $this->_url)) - $this->_validator->errorInvalideUrl($this->_url); + $this->_errorInvalideUrl(); if ($this->_mustCheck() && ($front_controller = Bokeh_Engine::getInstance()->getFrontController()) && $front_controller->getDispatcher()->isValidController($this->_url)) - $this->_validator->errorUrlForbiden($this->_url); + $this->_errorUrlForbiden(); return $this; } @@ -49,6 +64,61 @@ class ZendAfi_Validate_RewriteUrl_NullStrategy protected function _mustCheck(): bool { - return $this->_url && $this->_validator->getValidateUrl(); + return $this->_url && $this->_validate_url; + } + + + protected function _checkAttrib(string $message): self + { + if ($message && $this->_model) { + $this->_validate_url = false; + + $this->_model->checkAttribute('rewrite_url', false, $message); + } + + return $this; + } + + + protected function _queryNotId(Storm_Query $query) + { + if ($this->_column + && $this->_model + && ! $this->_model->isNew()) + $query->not_eq($this->_column, $this->_model->getId()); + + return $query; + } + + + protected function _errorInvalideUrl(): self + { + return $this->_checkAttrib($this->_("'%s' n'est pas une URL valide", $this->_url)); + } + + + protected function _errorUrlForbiden(): self + { + return $this->_checkAttrib($this->_("L'Url '%s' est une url interdite", $this->_url)); + } + + + protected function _errorAlreadyExistInLibrary(string $label): self + { + return $this->_checkAttrib($this->_("L'URL '%s' est déjà définie pour la bibliothèque: '%s'", + $this->_url, + $label)); + } + + + protected function _errorAlreadyExistInProfil(Class_Profil $profil): self + { + $prefix = ($parent_rewrite = ($profil->getParentProfil()?->getLibelle() ?? '')) + ? ($parent_rewrite . ' > ') + : ''; + + return $this->_checkAttrib($this->_("L'URL '%s' est déjà définie pour le profil: '%s'", + $this->_url, + $prefix . $profil->getLibelle())); } } diff --git a/library/ZendAfi/Validate/RewriteUrl/ProfilStrategy.php b/library/ZendAfi/Validate/RewriteUrl/ProfilStrategy.php index 2c303bbeeee..e7252cf626c 100644 --- a/library/ZendAfi/Validate/RewriteUrl/ProfilStrategy.php +++ b/library/ZendAfi/Validate/RewriteUrl/ProfilStrategy.php @@ -23,21 +23,16 @@ class ZendAfi_Validate_RewriteUrl_ProfilStrategy extends ZendAfi_Validate_RewriteUrl_NullStrategy { - protected ?string $_parent_rewrite_url = null; + protected string $_column = 'id_profil'; - public function __construct(protected ZendAfi_Validate_RewriteUrl $_validator, - protected Class_Profil $_profil) - {} - - - public function validateUrl(): self + public function validateUrl(): bool { - return $this->_checkDefaultUrl((string) $this->_profil->getRewriteUrl()) - ->_checkProfilWithSameUrlAsAnotherProfil() - ->_checkProfilWithSameUrlAsAPage() - ->_checkPageWithSameUrlAsAPageWithoutRewriteUrl() - ->_checkPageWithSameUrlAsAProfil() - ->_checkOtherModelsUrl(); + $this->_initUrl() + ->_checkDefaultUrl() + ->_checkProfilWithSameUrlAsAnotherProfil() + ->_checkOtherModelsUrl(); + + return parent::validateUrl(); } @@ -49,7 +44,7 @@ class ZendAfi_Validate_RewriteUrl_ProfilStrategy extends ZendAfi_Validate_Rewrit ->eq('rewrite_url', $this->_url) ->fetchFirst() ?->getLibelle() ?? ''))) - $this->_validator->errorAlreadyExistsInAnotherLibrary($this->_url, $label); + $this->_errorAlreadyExistInLibrary($label); return $this; } @@ -58,96 +53,11 @@ class ZendAfi_Validate_RewriteUrl_ProfilStrategy extends ZendAfi_Validate_Rewrit protected function _checkProfilWithSameUrlAsAnotherProfil(): self { if ($this->_mustCheck() - && $this->_parentRewriteUrl() - && ($other = Class_Profil::query() - ->eq('rewrite_url', $this->_url) - ->is_null('parent_id') - ->not_eq('id_profil', $this->_profil->getId()) + && ($profil = $this->_queryNotId(Class_Profil::query() + ->eq('rewrite_url', $this->_url)) ->fetchFirst())) - $this->_validator->errorAlreadyExistInProfil($this->_url, $other->getLibelle()); - - return $this; - } - - - protected function _checkProfilWithSameUrlAsAPage(): self - { - $profils = null; - - if ($this->_mustCheck() - && ! $this->_parentRewriteUrl()) { - $profils = Class_Profil::query() - ->eq('rewrite_url', $this->_url) - ->not_eq('id_profil', $this->_profil->getId()) - ->gt('parent_id', 0) - ->fetchAll(); - - $profils = array_filter($profils, - fn($model) => $model->hasParentProfil() - && ! $model->getParent()->getRewriteUrl()); - } - - if ($profils) - $this->_validator->errorAlreadyExistsInPage($this->_url, - $this->_messageErrorPage(array_shift($profils))); + $this->_errorAlreadyExistInProfil($profil); return $this; } - - - protected function _checkPageWithSameUrlAsAPageWithoutRewriteUrl(): self - { - $profils = null; - - if ($this->_mustCheck() - && ! $this->_parentRewriteUrl()) { - $profils = Class_Profil::query() - ->eq('rewrite_url', $this->_url) - ->not_eq('id_profil', $this->_profil->getId()) - ->gt('parent_id', 0) - ->fetchAll(); - - $profils = array_filter($profils, - fn($model) => $model->hasParentProfil() - && ($model->getParent()->getRewriteUrl() == $this->_parentRewriteUrl())); - } - - if ($profils) - $this->_validator->errorAlreadyExistsInPage($this->_url, - $this->_messageErrorPage(array_shift($profils))); - - return $this; - } - - - protected function _checkPageWithSameUrlAsAProfil(): self - { - if ($this->_mustCheck() - && ! $this->_parentRewriteUrl() - && ($other = Class_Profil::query() - ->eq('rewrite_url', $this->_url) - ->not_eq('id_profil', $this->_profil->getId()) - ->is_null('parent_id') - ->fetchFirst())) - $this->_validator->errorAlreadyExistInProfil($this->_url, $other->getLibelle()); - - return $this; - } - - - protected function _parentRewriteUrl(): string - { - return $this->_parent_rewrite_url ??= ($this->_profil->hasParentProfil() - ? ((string) $this->_profil->getParent() - ->getRewriteUrl()) - : ''); - } - - - protected function _messageErrorPage(?Class_Profil $profil): string - { - return $profil - ? $profil->getParentProfil()->getLibelle() . ' > ' . $profil->getLibelle() - : ''; - } } diff --git a/library/ZendAfi/Validate/RewriteUrl/StringLibraryStrategy.php b/library/ZendAfi/Validate/RewriteUrl/StringLibraryStrategy.php new file mode 100644 index 00000000000..06f6ffd16ac --- /dev/null +++ b/library/ZendAfi/Validate/RewriteUrl/StringLibraryStrategy.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright (c) 2012-2025, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class ZendAfi_Validate_RewriteUrl_StringLibraryStrategy + extends ZendAfi_Validate_RewriteUrl_LibraryStrategy +{ + + protected ZendAfi_Validate_RewriteUrl $_validator; + + public function addUrl(string $url): self + { + $this->_url = trim($url); + + return $this; + } + + + public function addValidator(ZendAfi_Validate_RewriteUrl $validator): self + { + $this->_validator = $validator; + + return $this; + } + + + protected function _initUrl(): self + { + return $this; + } + + + protected function _checkAttrib(string $message): self + { + if ($message) { + $this->_validate_url = false; + + $this->_validator->addError($message); + } + + return $this; + } +} diff --git a/library/ZendAfi/Validate/RewriteUrl/StringProfilStrategy.php b/library/ZendAfi/Validate/RewriteUrl/StringProfilStrategy.php new file mode 100644 index 00000000000..0574feb40ac --- /dev/null +++ b/library/ZendAfi/Validate/RewriteUrl/StringProfilStrategy.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright (c) 2012-2025, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class ZendAfi_Validate_RewriteUrl_StringProfilStrategy + extends ZendAfi_Validate_RewriteUrl_ProfilStrategy +{ + + protected ZendAfi_Validate_RewriteUrl $_validator; + + public function addUrl(string $url): self + { + $this->_url = trim($url); + + return $this; + } + + + public function addValidator(ZendAfi_Validate_RewriteUrl $validator): self + { + $this->_validator = $validator; + + return $this; + } + + + protected function _initUrl(): self + { + return $this; + } + + + protected function _checkAttrib(string $message): self + { + if ($message) { + $this->_validate_url = false; + + $this->_validator->addError($message); + } + + return $this; + } +} diff --git a/library/ZendAfi/Validate/RewriteUrl/StringStrategy.php b/library/ZendAfi/Validate/RewriteUrl/StringStrategy.php deleted file mode 100644 index 43fdc0aa0aa..00000000000 --- a/library/ZendAfi/Validate/RewriteUrl/StringStrategy.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php -/** - * Copyright (c) 2012-2025, Agence Française Informatique (AFI). All rights reserved. - * - * BOKEH is free software; you can redistribute it and/or modify - * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by - * the Free Software Foundation. - * - * There are special exceptions to the terms and conditions of the AGPL as it - * is applied to this software (see README file). - * - * BOKEH is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE - * along with BOKEH; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -class ZendAfi_Validate_RewriteUrl_StringStrategy extends ZendAfi_Validate_RewriteUrl_NullStrategy -{ - - public function __construct(ZendAfi_Validate_RewriteUrl $validator, - string $url) - { - $this->_validator = $validator; - $this->_url = $url; - } - - - public function validateUrl(): self - { - return $this->_checkDefaultUrl($this->_url) - ->_checkLibraryExists() - ->_checkProfilExists(); - } - - - protected function _checkLibraryExists(): self - { - if ($this->_mustCheck() - && ($label = (Class_Bib::query() - ->select('libelle') - ->eq('rewrite_url', $this->_url) - ->fetchFirst() - ?->getLibelle() ?? ''))) - $this->_validator->errorAlreadyExistsInAnotherLibrary($this->_url, $label); - - return $this; - } - - - protected function _checkProfilExists(): self - { - if ($this->_mustCheck() - && ($label = (Class_Profil::query() - ->select('libelle') - ->eq('rewrite_url', $this->_url) - ->fetchFirst() - ?->getLibelle() ?? ''))) - $this->_validator->errorAlreadyExistsInAnotherProfil($this->_url, $label); - - return $this; - } -} diff --git a/tests/application/modules/admin/controllers/ProfilControllerRewriteUrlTest.php b/tests/application/modules/admin/controllers/ProfilControllerRewriteUrlTest.php index 4d249cf1fce..a1cfda1516c 100644 --- a/tests/application/modules/admin/controllers/ProfilControllerRewriteUrlTest.php +++ b/tests/application/modules/admin/controllers/ProfilControllerRewriteUrlTest.php @@ -41,7 +41,7 @@ class ProfilControllerRewriteUrlTest extends Admin_AbstractControllerTestCase ['libelle' => 'Principal', 'rewrite_url' => 'agenda']); - $this->assertEquals('agenda', Class_Profil::getCurrentProfil()->getRewriteUrl()); + $this->assertEquals('agenda', Class_Profil::find(1)->getRewriteUrl()); } @@ -52,6 +52,49 @@ class ProfilControllerRewriteUrlTest extends Admin_AbstractControllerTestCase ['libelle' => 'Principal', 'rewrite_url' => 'profil-rewrite']); - $this->assertEquals('profil-rewrite', Class_Profil::getCurrentProfil()->getRewriteUrl()); + $this->assertEquals('profil-rewrite', Class_Profil::find(1)->getRewriteUrl()); + } + + + /** @test */ + public function rewriteUrlWithSameUrlAsCurrentShouldBeWithoutError() + { + Class_Profil::find(1) + ->setRewriteUrl('profil-rewrite') + ->assertSave(); + + $this->postDispatch('/admin/profil/accueil/id_profil/1', + ['libelle' => 'Principal', + 'rewrite_url' => 'profil-rewrite']); + + $this->assertEquals('profil-rewrite', Class_Profil::find(1)->getRewriteUrl()); + } + + + /** @test */ + public function rewriteUrlUniqOnNewProfilShouldBeWithoutError() + { + $this->postDispatch('/admin/profil/add', + ['libelle' => 'new profil added', + 'rewrite_url' => 'profil-rewrite']); + + $this->assertEquals('profil-rewrite', + Class_Profil::findFirstBy(['libelle' => 'new profil added']) + ->getRewriteUrl()); + } + + + /** @test */ + public function rewriteUrlAlreadyExistsOnNewProfilShouldBeWithError() + { + Class_Profil::find(1) + ->setRewriteUrl('profil-rewrite') + ->assertSave(); + + $this->postDispatch('/admin/profil/add', + ['libelle' => 'new profil added', + 'rewrite_url' => 'profil-rewrite']); + + $this->assertXpath('//ul[@class="errors"]/li[text()="L\'URL \'profil-rewrite\' est déjà définie pour le profil: \'portail\'"]'); } } diff --git a/tests/application/modules/admin/controllers/WidgetControllerTest.php b/tests/application/modules/admin/controllers/WidgetControllerTest.php index e6eafef037e..a9fade3e2bc 100644 --- a/tests/application/modules/admin/controllers/WidgetControllerTest.php +++ b/tests/application/modules/admin/controllers/WidgetControllerTest.php @@ -2395,34 +2395,39 @@ class WidgetControllerWidgetAddFromTemplateTest extends WidgetControllerWidgetCo -class WidgetControllerWidgetAddWidgetErrorFromTemplateTest extends WidgetControllerWidgetConfigurationTestCase { - protected - $_module_config; +class WidgetControllerWidgetAddWidgetErrorFromTemplateTest + extends WidgetControllerWidgetConfigurationTestCase +{ - public function setUp(): void { + protected $_module_config; + + public function setUp(): void + { parent::setUp(); - $profil = $this->fixture('Class_Profil', ['id' => 50, - 'parent_id' => 5 - ]); - $profil2 = $this->fixture('Class_Profil', ['id' => 51, - 'parent_id' => 5 ]); + + $profil = $this->fixture(Class_Profil::class, + ['id' => 50, + 'parent_id' => 5]); + $profil2 = $this->fixture(Class_Profil::class, + ['id' => 51, + 'parent_id' => 5 ]); $profil->setRewriteUrl('same')->save(); $profil2->setRewriteUrl('same')->saveWithoutValidation(); - $this->dispatch('admin/widget/add/template/articles/template_no/5/id_profil/50', true); + $this->dispatch('admin/widget/add/template/articles/template_no/5/id_profil/50'); $this->_module_config = $profil->getCfgAccueilAsArray()['modules'][1]; } /** @test */ public function responseShouldRenderEditPopup() { - $this->assertFlashMessengerContentContains("Echec de la sauvegarde de la configuration : Erreur de sauvegarde du profil : L'URL 'same' est déjà définie pour la page"); + $this->assertFlashMessengerContentContains("Echec de la sauvegarde de la configuration : Erreur de sauvegarde du profil : L'URL 'same' est déjà définie pour le profil: '** nouveau profil ** > ** nouveau profil **"); } - } + class WidgetControllerWidgetAddWidgetFromTemplateTest extends WidgetControllerWidgetConfigurationTestCase { protected $_module_config; diff --git a/tests/library/Class/ProfilTest.php b/tests/library/Class/ProfilTest.php index f1749845845..f5c8d1c10f1 100644 --- a/tests/library/Class/ProfilTest.php +++ b/tests/library/Class/ProfilTest.php @@ -944,14 +944,14 @@ class ProfilAdulteChatenayTest extends ProfilAdulteChatenayTestCase { $this->assertFalse($this->profil_nature->isValid()); - $this->assertEquals("L'URL 'nature' est déjà définie pour la page 'Portail > Nature'", + $this->assertEquals("L'URL 'nature' est déjà définie pour le profil: 'Portail > Nature'", implode(',', $this->profil_nature->getErrors())); } /** @test */ - public function withSameRewriteURLButNotSameParentProfilShouldBeValid() { + public function withSameRewriteURLButNotSameParentProfilShouldBeNotValid() { $this->profil->setRewriteUrl('adulte')->assertSave(); $this->page_histoire->setRewriteUrl('histoire')->assertSave(); @@ -959,13 +959,13 @@ class ProfilAdulteChatenayTest extends ProfilAdulteChatenayTestCase { ['id' => 345, 'libelle' => 'zork', 'rewrite_url' => 'zork']); - $other_histoire = $this->fixture(Class_Profil::class, - ['id' => 346, - 'parent_id' => 345, - 'libelle' => 'histoire', - 'rewrite_url' => 'histoire']); - $this->assertTrue($other_histoire->isValid(), - implode(',', $other_histoire->getErrors())); + $other_histoire = (new Class_Profil) + ->setId(346) + ->setParentId(345) + ->setLibelle('histoire') + ->setRewriteUrl('histoire'); + $this->assertFalse($other_histoire->isValid(), + implode(',', $other_histoire->getErrors())); } @@ -978,7 +978,7 @@ class ProfilAdulteChatenayTest extends ProfilAdulteChatenayTestCase { /** @test */ - public function savePageWithSameRewriteUrlAsAnotherPageWithoutParentShouldBeValid() { + public function savePageWithSameRewriteUrlAsAnotherPageWithoutParentShouldNotBeValid() { $this->fixture(Class_Profil::class, ['id' => 375, 'parent_id' => null, @@ -993,7 +993,7 @@ class ProfilAdulteChatenayTest extends ProfilAdulteChatenayTestCase { $this->profil->setRewriteUrl('adulte')->assertSave(); $this->page_histoire->setRewriteUrl('histoire'); - $this->assertTrue($this->page_histoire->isValid()); + $this->assertFalse($this->page_histoire->isValid()); } @@ -1008,12 +1008,12 @@ class ProfilAdulteChatenayTest extends ProfilAdulteChatenayTestCase { 'libelle' => 'jeunesse', 'rewrite_url' => '']); - $other_histoire = $this->fixture(Class_Profil::class, - ['id' => 346, - 'parent_id' => 345, - 'libelle' => 'histoire', - 'rewrite_url' => 'histoire']); - $this->assertTrue($other_histoire->isValid()); + $other_histoire = (new Class_Profil) + ->setId(346) + ->setParentId(345) + ->setLibelle('histoire') + ->setRewriteUrl('histoire'); + $this->assertFalse($other_histoire->isValid()); } -- GitLab From d87d7ee8300f3346114575a6b8a0abb2a57ff51d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?ANDRE=20s=C3=A9bastien?= <sandre@afi-sa.fr> Date: Fri, 14 Mar 2025 15:03:02 +0100 Subject: [PATCH 5/5] 9.0.2-Focale --- VERSIONS | 11 +++++++++++ VERSIONS_HOTLINE/193156 | 1 - VERSIONS_HOTLINE/218050 | 1 - VERSIONS_HOTLINE/220612 | 1 - VERSIONS_HOTLINE/221141 | 1 - library/startup.php | 2 +- 6 files changed, 12 insertions(+), 5 deletions(-) delete mode 100644 VERSIONS_HOTLINE/193156 delete mode 100644 VERSIONS_HOTLINE/218050 delete mode 100644 VERSIONS_HOTLINE/220612 delete mode 100644 VERSIONS_HOTLINE/221141 diff --git a/VERSIONS b/VERSIONS index e4bc124e57b..9c667abfc57 100644 --- a/VERSIONS +++ b/VERSIONS @@ -1,3 +1,14 @@ +17/03/2025 - 9.0.2-Focale + + - correctif #193156 : Administration : Corrige la saisie manuelle dans les datetimepickers. + + - correctif #218050 : Formulaire d'inscritpion à une session : n'affiche pas le message de placement en attente si le total max est à 0. + + - correctif #220612 : Administration : Groupe : Corrige la récupération du site dans le formulaire des groupes dynamiques. + + - correctif #221141 : Profil : Modifier un profil qui a une url de redirection ne génère plus de message d'erreur de validation inadéquat. + + 27/02/2025 - v9.0.1-Focale - fonctionnalité #215563 : RGAA : Les étiquettes de champs de sélection de tri et de nombre de page dans la liste de résultat (Magasin de thème) sont pertinentes. diff --git a/VERSIONS_HOTLINE/193156 b/VERSIONS_HOTLINE/193156 deleted file mode 100644 index 9b54897e47a..00000000000 --- a/VERSIONS_HOTLINE/193156 +++ /dev/null @@ -1 +0,0 @@ -- correctif #193156 : corrige la saisie manuelle dans les datetimepickers \ No newline at end of file diff --git a/VERSIONS_HOTLINE/218050 b/VERSIONS_HOTLINE/218050 deleted file mode 100644 index 021670660d8..00000000000 --- a/VERSIONS_HOTLINE/218050 +++ /dev/null @@ -1 +0,0 @@ - - correctif #218050 : Formulaire d'inscritpion à une session : n'affiche pas le message de placement en attente si le total max est à 0. \ No newline at end of file diff --git a/VERSIONS_HOTLINE/220612 b/VERSIONS_HOTLINE/220612 deleted file mode 100644 index 804988cf6e0..00000000000 --- a/VERSIONS_HOTLINE/220612 +++ /dev/null @@ -1 +0,0 @@ -- correctif #220612 : corrige la récupération du site dans le formulaire des groupes dynamiques \ No newline at end of file diff --git a/VERSIONS_HOTLINE/221141 b/VERSIONS_HOTLINE/221141 deleted file mode 100644 index 564ac5968e7..00000000000 --- a/VERSIONS_HOTLINE/221141 +++ /dev/null @@ -1 +0,0 @@ - - correctif #221141 : Profil : Modifier un profil qui a une url de redirection ne génère plus de message d'erreur de validation inadéquat. \ No newline at end of file diff --git a/library/startup.php b/library/startup.php index 2427857b9c8..e45f9360e86 100644 --- a/library/startup.php +++ b/library/startup.php @@ -144,7 +144,7 @@ class Bokeh_Engine { defineConstant('BOKEH_MAJOR_VERSION', 9); defineConstant('BOKEH_MINOR_VERSION', 0); - defineConstant('BOKEH_PATCH_VERSION', 1); + defineConstant('BOKEH_PATCH_VERSION', 2); defineConstant('BOKEH_NAMED_VERSION', 'Focale'); defineConstant('BOKEH_RELEASE_NUMBER', BOKEH_MAJOR_VERSION . '.' . BOKEH_MINOR_VERSION -- GitLab