diff --git a/VERSIONS_HOTLINE/144782 b/VERSIONS_HOTLINE/144782 new file mode 100644 index 0000000000000000000000000000000000000000..86f073db6548439c10a2724b9558f7fa24f50897 --- /dev/null +++ b/VERSIONS_HOTLINE/144782 @@ -0,0 +1,2 @@ + - correctif #144782 : Magasin de thèmes : Dans le compte lecteur, les actions des sélections vide sont désactivées. + En complément, un résultat de recherche vers un panier sans document n'affiche maintenant pas de document. \ No newline at end of file diff --git a/library/Class/CriteresRecherche.php b/library/Class/CriteresRecherche.php index 7dc8ae880152a915950072eac3ac20d9f4e8a886..efde52779d72a32a3e5adefba53c3b4ee6105175 100644 --- a/library/Class/CriteresRecherche.php +++ b/library/Class/CriteresRecherche.php @@ -416,6 +416,12 @@ class Class_CriteresRecherche extends Class_CriteresRecherche_Abstract { } + public function isEmptyPanier() : bool { + return ($selection = $this->getPanier()) + && $selection->isEmpty(); + } + + public function isRechercheCatalogueOuPanierOuSelection() { return $this->isRechercheCatalogue() || $this->isRecherchePanier() @@ -1040,6 +1046,9 @@ class Class_CriteresRecherche extends Class_CriteresRecherche_Abstract { if ($this->isEmptySelection()) return $this->_('La sélection courante est vide'); + if ($this->isEmptyPanier()) + return $this->_('La sélection est vide'); + return parent::getStateError(); } diff --git a/library/Class/Date.php b/library/Class/Date.php index d86cc7d562b8514ef930a791b8a23b7ddf9d4b43..a146944c3047e3471ab68421877908d5bdd28841 100644 --- a/library/Class/Date.php +++ b/library/Class/Date.php @@ -119,6 +119,7 @@ class Class_Date { } + /* Zend_Date is deprecated. Use Class_Date::human() */ public static function humanDate($datestr, $format='d MMMM yyyy HH:mm:ss') { try { $date = new Zend_Date($datestr, null, Zend_Registry::get('locale')); @@ -126,7 +127,6 @@ class Class_Date { return ''; } return $date->toString($format); - } @@ -149,4 +149,16 @@ class Class_Date { : $day_of_week; } + + public static function human(string $sql_date, string $format = '%d/%m/%Y') : string { + $sql_date = trim($sql_date); + $format = trim($format); + + if ( ! $sql_date || ! $format) + return ''; + + return '0000-00-00' === $sql_date + ? '' + : strftime($format, strtotime($sql_date)); + } } \ No newline at end of file diff --git a/library/Class/PanierNotice.php b/library/Class/PanierNotice.php index 98b1c5007e76bf6d397347be2f02869452b615ad..3f0fa9fa735869f70265be19fad8eb4066c078f5 100644 --- a/library/Class/PanierNotice.php +++ b/library/Class/PanierNotice.php @@ -572,4 +572,14 @@ class Class_PanierNotice extends Storm_Model_Abstract { public function numberOfDomains() { return count($this->getDomainIdsAsArray()); } + + + public function getHumanDateMaj() : string { + return Class_Date::human($this->getDateMaj()); + } + + + public function isEmpty() : bool { + return ! $this->getClesNotices(); + } } \ No newline at end of file diff --git a/library/templates/Intonation/Library/Settings.php b/library/templates/Intonation/Library/Settings.php index b2449764654d39b59c9aa9c25d9ab9abe7bc14fb..be387452798ff8fa908d95f857cc40683f7b1a54 100644 --- a/library/templates/Intonation/Library/Settings.php +++ b/library/templates/Intonation/Library/Settings.php @@ -325,6 +325,8 @@ class Intonation_Library_Settings extends Intonation_System_Abstract { 'span class highlight' => 'font-weight-bold text_decoration_underline', 'span class more_description_data_title' => 'font-italic', 'span class facet_title' => 'font-weight-bold', + 'span class selection_date_maj' => 'badge-warning', + 'span class selection_count_records' => 'badge-info' ], 'icons_map_doc_types' => [], diff --git a/library/templates/Intonation/Library/View/Wrapper/Selection.php b/library/templates/Intonation/Library/View/Wrapper/Selection.php index 2b851c1b6371a3b66155431681dc94a057f675f4..58cbe8a58a5b507463cb542b4053e34002a11e3d 100644 --- a/library/templates/Intonation/Library/View/Wrapper/Selection.php +++ b/library/templates/Intonation/Library/View/Wrapper/Selection.php @@ -21,9 +21,13 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_Wrapper_Abstract { + use Trait_InspectorGadget; + protected $_count_records_cache; + + public function getMainTitle() { return $this->_model->getLibelle(); } @@ -94,14 +98,17 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_ public function getMainLink() { - return (new Intonation_Library_Link) - ->setUrl($this->_view->url(['controller' => 'recherche', - 'action' => 'simple', - 'id_panier' => $this->getId()], - null, true)) - ->setImage($this->getIco('search_more', 'library')) - ->setText($this->_('Voir')) - ->setTitle($this->_('Voir la sélection dans la recherche')); + return $this->_countRecords() + ?((new Intonation_Library_Link) + ->setUrl($this->_view->url(['controller' => 'recherche', + 'action' => 'simple', + 'id_panier' => $this->getId()], + null, true)) + ->setImage($this->getIco('search_more', 'library')) + ->setText($this->_('Voir')) + ->setClass($this->_countRecords() ? '' : 'disabled') + ->setTitle($this->_('Voir la sélection dans la recherche'))) + : $this->_addRecordToSelectionLink(); } @@ -126,27 +133,26 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_ public function getBadges() { - $date = ($date_maj = $this->_model->getDateMaj()) + $date = ($date_maj = $this->_model->getHumanDateMaj()) ? $this->_('date : %s', $this->_view->tag('span', - ((new DateTime($date_maj)) - ->format($this->_('d/m/Y'))), + $date_maj, ['class' => 'badge badge-light fs_1em'])) : ''; $badges = [ ((new Intonation_Library_Badge) ->setTag('span') - ->setClass('badge-info') + ->setClass('selection_count_records') ->setText($this->_('nombre : %s', $this->_view->tag('span', - $this->_model->numberOfNotices(), + $this->_countRecords(), ['class' => 'badge badge-light fs_1em']))) ->setTitle($this->_('Le nombre de documents dans la sélection %s', $this->_model->getLibelle()))), ((new Intonation_Library_Badge) ->setTag('span') - ->setClass('badge-warning') + ->setClass('selection_date_maj') ->setText($date) ->setTitle($this->_('La date de dernière mise à jour de la sélection %s', $this->_model->getLibelle())))]; @@ -168,7 +174,9 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_ public function getActions() { - $actions = $this->_getActions(); + if ( ! $actions = $this->_getActions()) + return []; + $button = (new Intonation_Library_Link) ->setImage($this->getIco('more', 'utils')) ->setText($this->_('Plus')) @@ -180,27 +188,25 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_ protected function _getActions() { - $actions = [(new Intonation_Library_Link) - ->setUrl($this->_view->url(['controller' => 'abonne', - 'action' => 'exporter-la-selection', - 'selection_id' => $this->_model->getId()])) - ->setImage($this->getIco('export', 'utils')) - ->setText($this->_('Exporter')) - ->setTitle($this->_('Exporter la sélection %s', $this->_model->getLibelle())) - ->setScreenReaderText($this->_('la sélection %s', $this->_model->getLibelle())) - ->setPopup(true)]; - - if ($this->_model->canBeEditedByMe()) { - $actions[] = (new Intonation_Library_Link) + $actions = []; + + if ( $this->_countRecords()) + $actions []=(new Intonation_Library_Link) ->setUrl($this->_view->url(['controller' => 'abonne', - 'action' => 'ajouter-a-la-selection', + 'action' => 'exporter-la-selection', 'selection_id' => $this->_model->getId()])) - ->setImage($this->getIco('add', 'utils')) - ->setText($this->_('Ajouter')) - ->setTitle($this->_('Ajouter un document à la sélection %s', $this->_model->getLibelle())) - ->setScreenReaderText($this->_('le document %s à la sélection', $this->_model->getLibelle())); + ->setImage($this->getIco('export', 'utils')) + ->setText($this->_('Exporter')) + ->setTitle($this->_('Exporter la sélection %s', $this->_model->getLibelle())) + ->setScreenReaderText($this->_('la sélection %s', $this->_model->getLibelle())) + ->setPopup(true); + + if ( ! $this->_model->canBeEditedByMe()) + return $actions; - $actions[] = (new Intonation_Library_Link) + if ( $this->_countRecords()) { + $actions [] = $this->_addRecordToSelectionLink(); + $actions [] = (new Intonation_Library_Link) ->setUrl($this->_view->url(['controller' => 'abonne', 'action' => 'selection', 'selection_id' => $this->_model->getId()])) @@ -210,8 +216,7 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_ ->setAriaLabel($this->_('Gérer votre sélection de documents')); } - if ((new Intonation_Library_UserPatcher)->isSelectionDefault($this->_model) - || !$this->_model->canBeEditedByMe()) + if ((new Intonation_Library_UserPatcher)->isSelectionDefault($this->_model)) return $actions; $actions[] = (new Intonation_Library_Link) @@ -222,8 +227,7 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_ ->setText($this->_('Renommer')) ->setTitle($this->_('Renommer la sélection %s', $this->_model->getLibelle())) ->setAriaLabel($this->_('Renommer la sélection %s', $this->_model->getLibelle())) - ->setPopup('true') - ; + ->setPopup('true'); $actions[] = (new Intonation_Library_Link) ->setUrl($this->_view->url(['controller' => 'panier', @@ -233,8 +237,7 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_ ->setText($this->_('Domaines liés')) ->setTitle($this->_('Lier la sélection %s à un domaine', $this->_model->getLibelle())) ->setAriaLabel($this->_('Lier la sélection %s à un domaine', $this->_model->getLibelle())) - ->setPopup('true') - ; + ->setPopup('true'); $actions[] = (new Intonation_Library_Link) ->setUrl($this->_view->url(['controller' => 'abonne', @@ -245,8 +248,7 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_ ->setTitle($this->_('Supprimer la sélection %s', $this->_model->getLibelle())) ->setAriaLabel($this->_('Supprimer la sélection %s', $this->_model->getLibelle())) ->setClass('text-danger') - ->setPopup('true') - ; + ->setPopup('true'); return $actions; } @@ -270,4 +272,26 @@ class Intonation_Library_View_Wrapper_Selection extends Intonation_Library_View_ public function getTimelineEventsDates() : Intonation_Library_TimelineEventsDates { return new Intonation_Library_TimelineEventsDates($this->_model->getDateMaj()); } + + + protected function _countRecords() : int { + if ( $this->_count_records_cache) + return $this->_count_records_cache; + + return $this->_count_records_cache = (int) $this->_model->numberOfNotices(); + } + + + protected function _addRecordToSelectionLink() : ?Intonation_Library_Link { + return $this->_model->canBeEditedByMe() + ? ((new Intonation_Library_Link) + ->setUrl($this->_view->url(['controller' => 'abonne', + 'action' => 'ajouter-a-la-selection', + 'selection_id' => $this->_model->getId()])) + ->setImage($this->getIco('add', 'utils')) + ->setText($this->_('Ajouter')) + ->setTitle($this->_('Ajouter un document à la sélection %s', $this->_model->getLibelle())) + ->setScreenReaderText($this->_('le document %s à la sélection', $this->_model->getLibelle()))) + : null; + } } diff --git a/library/templates/Intonation/Library/View/Wrapper/User/RichContent/Selection.php b/library/templates/Intonation/Library/View/Wrapper/User/RichContent/Selection.php index aecc2d3002c243e83fafd8e28c4a24d48eba8966..6fc106508387df88a4261bafdc2bfbd141838fc9 100644 --- a/library/templates/Intonation/Library/View/Wrapper/User/RichContent/Selection.php +++ b/library/templates/Intonation/Library/View/Wrapper/User/RichContent/Selection.php @@ -37,20 +37,21 @@ class Intonation_Library_View_Wrapper_User_RichContent_Selection extends Intonat $wrapper->getBadges()), $this->_view->div(['class' => 'col-12 col-sm-3 pt-3 pl-3 order-sm-3'], - $this->_view->renderActions($wrapper->getActions())), + $this->_view->renderActions(array_merge([$wrapper->getMainLink()], + $wrapper->getActions()))), $this->_view->div(['class' => 'col-12 col-sm-9'], - $this->_view->renderList(new Storm_Collection($this->_model->getNoticesAsArray()), - function($record) - { - return - $this->_view - ->cardifyHorizontal( - (new Intonation_Library_View_Wrapper_RecordInSelection) - ->setSelection($this->_model) - ->setModel($record) - ->setView($this->_view)); - }))]; + $this->_view->renderList(new Storm_Collection($this->_model->getNoticesAsArray()), + function($record) + { + return + $this->_view + ->cardifyHorizontal( + (new Intonation_Library_View_Wrapper_RecordInSelection) + ->setSelection($this->_model) + ->setModel($record) + ->setView($this->_view)); + }))]; return $this->_view->grid(implode($html)); } diff --git a/tests/application/modules/opac/controllers/RechercheControllerTest.php b/tests/application/modules/opac/controllers/RechercheControllerTest.php index d6634db50b236b7d60fdd62723b4437d7abb23bb..eedf2233f68ec7ffaf43a782e8dcda0aa7dc0039 100644 --- a/tests/application/modules/opac/controllers/RechercheControllerTest.php +++ b/tests/application/modules/opac/controllers/RechercheControllerTest.php @@ -3896,3 +3896,33 @@ class RechercheControllerSimpleAccentsSpeciauxTest extends AbstractControllerTes $this->assertXPathContentContains('//a[contains(@href,"viewnotice/id/1")]', 'Symphony'); } } + + + + +class RechercheControllerWithEmptyPanierTest extends AbstractControllerTestCase { + protected $_storm_default_to_volatile = true; + + + public function setUp() { + parent::setUp(); + + $this->_buildTemplateProfil(['id' => 789]); + + $this->fixture(Class_PanierNotice::class, + ['id' => 289, + 'libelle' => 'panier vide']); + + $sql = $this->mock()->beStrict(); + + Zend_Registry::set('sql', $sql); + + $this->dispatch('/recherche/simple/id_panier/289'); + } + + + /** @test */ + public function shouldRenderNoResult() { + $this->assertXPathContentContains('//p', 'Aucun résultat'); + } +} \ No newline at end of file diff --git a/tests/scenarios/Templates/TemplatesAbonneSelectionsTest.php b/tests/scenarios/Templates/TemplatesAbonneSelectionsTest.php index cf2b01dfbe1343e35e6664e15e6ac79623a7ec40..d991a9e316f68a7b9cdc6a01d7edc48508646653 100644 --- a/tests/scenarios/Templates/TemplatesAbonneSelectionsTest.php +++ b/tests/scenarios/Templates/TemplatesAbonneSelectionsTest.php @@ -85,19 +85,22 @@ abstract class TemplatesAbonneSelectionsTestCase extends TemplatesIntonationTest class TemplatesAbonneShowUserCartAsAdminTest extends Admin_AbstractControllerTestCase { - protected $_storm_default_to_volatile = true; - - public function setUp() { parent::setUp(); $this->_buildTemplateProfil(['id' => 2]); - $admin = Class_Users::newInstanceWithId('123456',['nom'=>'Zozor'])->beAdminPortail(); + $admin = Class_Users::newInstanceWithId('123456', + ['nom'=>'Zozor'])->beAdminPortail(); + + $this->fixture(Class_Notice::class, + ['id' => 123, + 'clef_alpha' => 'BLACKSAD']); $this->fixture(Class_PanierNotice::class, ['id' => 67, 'libelle' => 'Zozor sélection', + 'notices' => 'BLACKSAD', 'id_user' => 123456]); $this->dispatch('/opac/panier/viewauteur/id/123456'); @@ -106,7 +109,8 @@ class TemplatesAbonneShowUserCartAsAdminTest extends Admin_AbstractControllerTes /** @test */ public function shouldRenderZozorSelection() { - $this->assertXPathContentContains('//body[contains(@class, "template_INTONATION")]//div[contains(@class,"card-title")]//a[contains(@href, "id_panier/67")]', 'Zozor sélection'); + $this->assertXPathContentContains('//body[contains(@class, "template_INTONATION")]//div[contains(@class,"card-title")]//a[contains(@href, "id_panier/67")]', + 'Zozor sélection'); } } @@ -203,19 +207,32 @@ class TemplatesAbonneSelectionsAsAbonneTest extends TemplatesAbonneSelectionsTes /** @test */ - public function dateMajShouldBe2011() { + public function dateMajShouldBe14Slash02Slash2022() { $this->assertXPathContentContains('//div//span[contains(@class, "badge_text")]//span[contains(@class, "badge-light fs_1em")]', '14/02/2022'); } } + class TemplatesAbonneSelectionsViewSelectionTest extends TemplatesAbonneSelectionsTestCase { + + + public function setUp() { + parent::setUp(); + $this->dispatch('/opac/abonne/selection/selection_id/2/id_profil/72'); + } + /** @test */ public function exporterSelection2LinkShouldBePresent() { - $this->dispatch('/opac/abonne/selection/selection_id/2/id_profil/72'); $this->assertXPathContentContains('//a[contains(@href, "/abonne/exporter-la-selection/selection_id/2")]', 'Exporter'); } + + + /** @test */ + public function dateMajShouldBePresent() { + $this->assertXPathContentContains('//span[@class= "badge_tag selection_date_maj text-left badge badge-warning"]', '14/02/2022'); + } } @@ -549,6 +566,14 @@ abstract class TemplatesAbonneSelectionsOthersAsAdminTestCase parent::setUp(); $this->_buildTemplateProfil(['id' => 72]); + $this->fixture(Class_Notice::class, + ['id' => 123, + 'clef_alpha' => 'COMBAT ORDINAIRE']); + + $this->fixture(Class_Notice::class, + ['id' => 123, + 'clef_alpha' => 'BLACKSAD']); + $this->_mes_bd = $this->fixture(Class_PanierNotice::class, ['id' => 2, 'libelle' => 'Mes BD', @@ -673,8 +698,6 @@ class TemplatesAbonneSelectionsInDomainsAsAdminTest class TemplatesAbonneSelectionsInDomainsAsAdminWithInspectorGadgetTest extends AbstractControllerTestCase { - protected $_storm_default_to_volatile = true; - public function setUp() { parent::setUp(); @@ -684,8 +707,8 @@ class TemplatesAbonneSelectionsInDomainsAsAdminWithInspectorGadgetTest $user = $this->fixture(Class_Users::class, ['id' => 89, 'login' => 'log', - 'password' => 'pass' - ]); + 'disable_newsletter' => 1, + 'password' => 'pass']); ZendAfi_Auth::getInstance()->logUser($user); @@ -931,4 +954,71 @@ class TemplatesAbonneSelectionsWithManySelectionsTest extends TemplatesAbonneSel public function scriptTruncateListToolsShouldBeLoaded() { $this->assertXPath('//script[contains(@src, "/library/templates/Intonation/Assets/js/truncate_list_tools.js")]'); } +} + + + + +class TemplatesAbonneSelectionEmptyTest extends TemplatesAbonneSelectionsTestCase { + + + public function setUp() { + parent::setUp(); + + $this->_buildTemplateProfil(['id' => 7898789]); + + Class_PanierNotice::find(2) + ->setNotices('') + ->setDateMaj('0000-00-00'); + + $this->dispatch('/opac/abonne/selection/selection_id/2'); + } + + + /** @test */ + public function linkAddToSelectionShouldBePresent() { + $this->assertXPathContentContains('//a[contains(@href, "/abonne/ajouter-a-la-selection/selection_id/2")]', 'Ajouter'); + } + + + /** @test */ + public function linkDeleteSelectionShouldBePresent() { + $this->assertXPathContentContains('//a[contains(@href, "/abonne/supprimer-la-selection/selection_id/2")]', 'Supprimer'); + } + + + /** @test */ + public function linkExporterSelection2ShouldNotBePresent() { + $this->assertNotXPathContentContains('//a[contains(@href, "/abonne/exporter-la-selection/selection_id/2")]', 'Exporter'); + } + + + /** @test */ + public function linkVoirsSelection2ShouldNotBePresent() { + $this->assertNotXPathContentContains('//a[contains(@href, "/recherche/simple/id_panier/2")]', 'Voir'); + } + + + /** @test */ + public function linkManageSelection2ShouldNotBePresent() { + $this->assertNotXPathContentContains('//a[contains(@href, "/abonne/selection/selection_id/2")]', 'Gérer'); + } + + + /** @test */ + public function buttonPlusShouldBePresent() { + $this->assertXPathContentContains('//div[contains(@class, "wrapper_user_selections wrapper_active")]//div[contains(@class, "card")]//button', 'Plus'); + } + + + /** @test */ + public function dateMajShouldNotBePresent() { + $this->assertNotXPath('//span[@class= "badge_tag selection_date_maj text-left badge badge-warning"]'); + } + + + /** @test */ + public function numberOfRecordsShouldBeZero() { + $this->assertXPath('//span[@class= "badge_tag selection_count_records text-left badge badge-info"]//span[text()="0"]'); + } } \ No newline at end of file