diff --git a/VERSIONS_HOTLINE/190858 b/VERSIONS_HOTLINE/190858 new file mode 100644 index 0000000000000000000000000000000000000000..778cb519ea92fbffef88036b96ac938e69d5e8eb --- /dev/null +++ b/VERSIONS_HOTLINE/190858 @@ -0,0 +1 @@ + - correctif #190858 : Admin : Newsletter, rendre l'affichage des compteurs du nombre d'inscrits plus cohérents. \ No newline at end of file diff --git a/library/Class/Newsletter.php b/library/Class/Newsletter.php index e1b21a281a01cf1fc629b1a51b2d9b358678a59b..bded130189a5e893db0cd2d6b1e027fcdd563a7b 100644 --- a/library/Class/Newsletter.php +++ b/library/Class/Newsletter.php @@ -196,18 +196,21 @@ class Class_Newsletter extends Storm_Model_Abstract { } - public function getNumberOfUsers() { + public function getNumberOfUsers(): string + { return sprintf('%05d', count($this->getRecipientsUsersIds())); } - public function getRecipientsUsersIds() { + public function getRecipientsUsersIds(): array + { $ids = []; - foreach($this->getRecipientsGroups() as $group) - foreach($group->getUsersIdsOptimized() as $id) - $ids[] = $id; - return array_unique($ids); + foreach ($this->getRecipientsGroups() as $group) + foreach ($group->getUsersIdsOptimized() as $id) + $ids [] = $id; + + return array_unique(array_filter($ids)); } diff --git a/library/Class/UserGroup.php b/library/Class/UserGroup.php index 7b81f423d30462b47e4044faff875511176e7efe..10213abfa2c814d970ea001b033e5ebcbdcca4ad 100644 --- a/library/Class/UserGroup.php +++ b/library/Class/UserGroup.php @@ -23,7 +23,7 @@ class UserGroupLoader extends Storm_Model_Loader { use Trait_MemoryCleaner; protected $_dynamics_of_user_cache = []; - + protected array $_user_ids_optimized = []; public function getOrCreate(Class_UserGroupCategorie $category, string $label, @@ -64,17 +64,25 @@ class UserGroupLoader extends Storm_Model_Loader { } - public function getUsersIdsOptimizedOf(Class_UserGroup $group) : array { - return $group->isManual() - ? $this->_getManualUserIdsOf($group) - : $this->_getDynamicUserIdsOf($group); + public function getUsersIdsOptimizedOf(Class_UserGroup $group): array + { + if ($ids = ($this->_user_ids_optimized[$group->getId()] ?? [])) + return $ids; + + return $this->_user_ids_optimized[$group->getId()] = + ($group->isManual() + ? $this->_getManualUserIdsOf($group) + : $this->_getDynamicUserIdsOf($group)); } - protected function _getManualUserIdsOf(Class_UserGroup $group) : array { - return array_map(fn($row) => $row->getId(), - Class_UserGroupMembership::query() - ->select(['id' => 'user_id']) + protected function _getManualUserIdsOf(Class_UserGroup $group): array + { + return array_map(fn($row) => $row->getUserId(), + Class_UserGroupMembership::join('group') + ->select('user_id') + ->inner(Class_Users::inner('user') + ->on_eq('user_id', 'id_user')) ->eq('user_group_id', $group->getId()) ->fetchAll()); } @@ -351,9 +359,10 @@ class Class_UserGroup extends Storm_Model_Abstract { } - public function numberOfUsers() : int{ + public function numberOfUsers(): int + { return $this->isManual() - ? parent::_numberOf('users') + ? count($this->getUsersIdsOptimized()) : $this->numberOfDynamicUsers(); } @@ -551,7 +560,9 @@ class Class_UserGroup extends Storm_Model_Abstract { return $this->getLibelle(); } - public function formatedCount() { + + public function formatedCount(): string + { return sprintf('%05d', $this->numberOfUsers()); } @@ -578,22 +589,30 @@ class Class_UserGroup extends Storm_Model_Abstract { } - public function getUsersIdsOptimized() { + public function getUsersIdsOptimized(): array + { return $this->getLoader()->getUsersIdsOptimizedOf($this); } - public function getUsersPage(int $page, int $items_by_page) : ?array{ + public function getUsersPage(int $page, int $items_by_page): array + { if ($this->isDynamic()) return $this->getDynamicUsersPage($page, $items_by_page); - $users=[]; - $members = Class_UserGroupMembership::findAllBy(['user_group_id' => $this->getId(), - 'limitPage' => [$page, $items_by_page]]); - foreach ($members as $member) { - $users[]=$member->getUser(); - } - return array_filter($users); + $id_users = Class_Users::join('user') + ->select('id_user') + ->inner(Class_UserGroupMembership::inner('group') + ->on_eq('id_user', 'user_id') + ->eq('user_group_id', $this->getId())) + ->limit_page($page, $items_by_page) + ->fetchAll(); + + return $id_users + ? (Class_Users::query() + ->in('id_user', array_map(fn($id) => $id->getIdUser(), $id_users)) + ->fetchAll()) + : []; } diff --git a/tests/application/modules/admin/controllers/NewsletterControllerTest.php b/tests/application/modules/admin/controllers/NewsletterControllerTest.php index 845bc088ec9b463ff2839135ce2301b4a7f4f781..5b4e7d7eaab01b211d0eb5bf21e3450c2da89f5b 100644 --- a/tests/application/modules/admin/controllers/NewsletterControllerTest.php +++ b/tests/application/modules/admin/controllers/NewsletterControllerTest.php @@ -1526,7 +1526,7 @@ abstract class Admin_NewsletterControllerEditSubcsribersTestCase parent::setUp(); Class_Newsletter::setTimeSource(new TimeSourceForTest('2005-03-27 12:30:00')); - Class_UserGroup::setMemoryCleaner(function(){}); + Class_UserGroup::setMemoryCleaner(function() {}); $this->_nl_nouveautes = $this->fixture(Class_Newsletter::class, ['id' => 1, @@ -1538,64 +1538,119 @@ abstract class Admin_NewsletterControllerEditSubcsribersTestCase 'libelle' => 'My Group']) ]]); } + + + public function tearDown() + { + Class_Newsletter::setTimeSource(null); + return parent::tearDown(); + } } class Admin_NewsletterControllerEditSubcsribersTest - extends Admin_NewsletterControllerEditSubcsribersTestCase { + extends Admin_NewsletterControllerEditSubcsribersTestCase +{ - public function setUp() { + public function setUp() + { parent::setUp(); + $user_1 = $this->fixture(Class_Users::class, + ['id' => 1, + 'nom' => 'user 1', + 'login' => 'login 1', + 'last_login' => '', + 'disable_newsletter' => 0, + 'password' => '123']); + + $this->fixture(Class_UserGroupMembership::class, + ['id' => 1, + 'user' => $user_1, + 'user_group_id' => 23]); + + $user_2 = $this->fixture(Class_Users::class, + ['id' => 2, + 'nom' => 'user 2', + 'login' => 'login 2', + 'last_login' => '', + 'disable_newsletter' => 0, + 'password' => '123']); + + $this->fixture(Class_UserGroupMembership::class, + ['id' => 2, + 'user' => $user_2, + 'user_group_id' => 23]); + + $this->fixture(Class_UserGroupMembership::class, + ['id' => 3, + 'user_id' => 999, + 'user_group_id' => 23]); + $this->dispatch('/admin/newsletter/edit-subscribers/id/1'); } /** @test */ - public function titleShouldBeAbonnesALaLettre() { + public function titleShouldBeAbonnesALaLettre() + { $this->assertXPathContentContains('//h1', 'Destinataires de la lettre : Nouveautés'); } /** @test */ - public function myGroupShouldBeDisplay() { + public function myGroupShouldBeDisplay() + { $this->assertXPathContentContains('//td', 'My Group'); } /** @test */ - public function myGroupMembershipLinkShouldBeDisplay() { - $this->assertXPath('//a[contains(@href, "/usergroup/editmembers/newsletter_id/1/id/23")]'); + public function myGroupMembershipLinkShouldBeDisplay() + { + $this->assertXPathContentContains('//a[contains(@href, "/usergroup/editmembers/newsletter_id/1/id/23")]', '00002'); + } + + + /** @test */ + public function headerActionsShouldHaveUrlNewsLetterWithCountUser() + { + $this->assertXPathContentContains('//div[@class="header_actions"]//a[contains(@href, "/admin/newsletter/edit-subscribers/id/1")]', '00002'); } /** @test */ - public function removeMyGroupLinkShouldBePresent() { + public function removeMyGroupLinkShouldBePresent() + { $this->assertXPath('//a[contains(@href, "/newsletter/remove-group/newsletter_id/1/id/23")]'); } /** @test */ - public function dedicatedGroupShouldBePresent() { - $this - ->assertXPathContentContains('//td', - 'Groupe manuel pour la lettre "Nouveautés"'); + public function dedicatedGroupShouldBePresent() + { + $this->assertXPathContentContains('//td', + 'Groupe manuel pour la lettre "Nouveautés"'); } /** @test */ - public function dedicatedGroupMembershipLinkShouldBePresent() { + public function dedicatedGroupMembershipLinkShouldBePresent() + { $group = Class_Newsletter::find(1)->getDedicatedGroup(); - $this->assertXPath('//a[contains(@href, "/usergroup/editmembers/newsletter_id/1/id/'. $group->getId() .'")]'); + $this->assertXPath('//a[contains(@href, "/usergroup/editmembers/newsletter_id/1/id/' + . $group->getId() .'")]'); } /** @test */ - public function removeDedicatedGroupLinkShouldNotBePresent() { + public function removeDedicatedGroupLinkShouldNotBePresent() + { $group = Class_Newsletter::find(1)->getDedicatedGroup(); - $this->assertNotXPath('//a[contains(@href, "/newsletter/remove-group/newsletter_id/1/id/' . $group->getId() . '")]'); + $this->assertNotXPath('//a[contains(@href, "/newsletter/remove-group/newsletter_id/1/id/' + . $group->getId() . '")]'); } } diff --git a/tests/application/modules/admin/controllers/UserGroupControllerTest.php b/tests/application/modules/admin/controllers/UserGroupControllerTest.php index e4413c477a8e476b5fc391fec1f14eb44285cc4e..5278619e6ccdf024fcda4b3886c67cf15c64159a 100644 --- a/tests/application/modules/admin/controllers/UserGroupControllerTest.php +++ b/tests/application/modules/admin/controllers/UserGroupControllerTest.php @@ -2147,3 +2147,75 @@ class Admin_UserGroupControllerEditPostDateFinWithMembershipTest $this->assertFalse($this->_group->hasUser(Class_Users::find($userid))); } } + + + + +/* @see : hotline : https://forge.afi-sa.net/issues/190858 */ +class Admin_UserGroupControllerEditMembersGroupUnexistsFromNewsletterTest + extends Admin_AbstractControllerTestCase +{ + + public function setUp() + { + parent::setUp(); + + Class_UserGroup::setMemoryCleaner(function() {}); + + $this->fixture(Class_Newsletter::class, + ['id' => 1, + 'titre' => 'Nouveautés', + 'mail_subject' => 'nouveautés', + 'last_distribution_date' => '2013-09-23', + 'user_groups' => [$this->fixture(Class_UserGroup::class, + ['id' => 23, + 'protected' => false, + 'libelle' => 'My Group']) + ]]); + + foreach (range(1, 10) as $id) { + $user = $this->fixture(Class_Users::class, + ['id' => $id, + 'nom' => 'user ' . $id, + 'login' => 'login ' . $id, + 'last_login' => '', + 'disable_newsletter' => 0, + 'password' => '123']); + + $this->fixture(Class_UserGroupMembership::class, + ['id' => $id, + 'user' => $user, + 'user_group_id' => 23]); + } + + foreach (range(30, 35) as $id) + $this->fixture(Class_UserGroupMembership::class, + ['id' => $id, + 'user_id' => 900 + $id, + 'user_group_id' => 23]); + + foreach (range(41, 49) as $id) { + $user = $this->fixture(Class_Users::class, + ['id' => $id, + 'nom' => 'user ' . $id, + 'login' => 'login ' . $id, + 'last_login' => '', + 'disable_newsletter' => 0, + 'password' => '123']); + + $this->fixture(Class_UserGroupMembership::class, + ['id' => $id, + 'user' => $user, + 'user_group_id' => 23]); + } + + $this->dispatch('admin/usergroup/editmembers/newsletter_id/1/id/23'); + } + + + /** @test */ + public function tableSubscribersShouldContain_19_Lines() + { + $this->assertXPathCount('//table[contains(@class, "subscribers")]/tbody/tr', 19); + } +}