From 35705c1ddd0961e98cc3753e4030b3c843d58585 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] 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