Skip to content

Commit

Permalink
FIX Sort without specifying a table name
Browse files Browse the repository at this point in the history
Using a table name in sort() is not allowed in CMS 5. We could use
orderBy() here but member is the table it will sort on by default anyway
so there's no need.

Also added unit tests, which should have caught this ages ago.
  • Loading branch information
GuySartorelli committed Feb 1, 2023
1 parent 2274b3e commit 8df5141
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/ORM/DataList.php
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ public function distinct($value)
*
* @param string|array $args
* @example $list = $list->sort('Name'); // default ASC sorting
* @example $list = $list->sort('"Name"'); // field names can have double quotes around them
* @example $list = $list->sort('Name ASC, Age DESC');
* @example $list = $list->sort('Name', 'ASC');
* @example $list = $list->sort(['Name' => 'ASC', 'Age' => 'DESC']);
Expand Down
10 changes: 5 additions & 5 deletions src/Security/Member.php
Original file line number Diff line number Diff line change
Expand Up @@ -1188,15 +1188,15 @@ public static function map_in_groups($groups = null)
*
* If no groups are passed, all groups with CMS permissions will be used.
*
* @param array $groups Groups to consider or NULL to use all groups with
* @param SS_List|array|null $groups Groups to consider or NULL to use all groups with
* CMS permissions.
* @return Map Returns a map of all members in the groups given that
* have CMS permissions.
*/
public static function mapInCMSGroups($groups = null)
public static function mapInCMSGroups(SS_List|array|null $groups = null): Map
{
// non-countable $groups will issue a warning when using count() in PHP 7.2+
if (!$groups) {
if ($groups === null) {
$groups = [];
}

Expand All @@ -1205,7 +1205,7 @@ public static function mapInCMSGroups($groups = null)
return ArrayList::create()->map();
}

if (count($groups ?? []) == 0) {
if (count($groups) === 0) {
$perms = ['ADMIN', 'CMS_ACCESS_AssetAdmin'];

if (class_exists(CMSMain::class)) {
Expand Down Expand Up @@ -1246,7 +1246,7 @@ public static function mapInCMSGroups($groups = null)
]);
}

return $members->sort('"Member"."Surname", "Member"."FirstName"')->map();
return $members->sort('"Surname", "FirstName"')->map();
}


Expand Down
110 changes: 110 additions & 0 deletions tests/php/Security/MemberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace SilverStripe\Security\Tests;

use InvalidArgumentException;
use SilverStripe\Admin\LeftAndMain;
use SilverStripe\Control\Cookie;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Convert;
Expand All @@ -12,6 +14,7 @@
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DB;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\Map;
use SilverStripe\ORM\ValidationException;
use SilverStripe\ORM\ValidationResult;
use SilverStripe\Security\Group;
Expand Down Expand Up @@ -1618,4 +1621,111 @@ public function testChangePasswordToBlankIsValidated()
$result = $member->changePassword('');
$this->assertFalse($result->isValid());
}

public function testMapInCMSGroupsNoLeftAndMain()
{
if (class_exists(LeftAndMain::class)) {
$this->markTestSkipped('LeftAndMain must not exist for this test.');
}
$result = Member::mapInCMSGroups();
$this->assertInstanceOf(Map::class, $result);

$this->assertEmpty($result, 'Without LeftAndMain, no groups are CMS groups.');
}

/**
* @dataProvider provideMapInCMSGroups
*/
public function testMapInCMSGroups(array $groupFixtures, array $groupCodes, array $expectedValue)
{
if (!empty($groupFixtures) && !empty($groupCodes)) {
throw new InvalidArgumentException('Data provider is misconfigured for this test.');
}

if (!class_exists(LeftAndMain::class)) {
$this->markTestSkipped('LeftAndMain must exist for this test.');
}

$groups = [];

// Convert fixture names to IDs
if (!empty($groupFixtures)) {
foreach ($groupFixtures as $index => $groupFixtureName) {
$groups[$index] = $this->objFromFixture(Group::class, $groupFixtureName)->ID;
}
}

// Convert codes to DataList
if (!empty($groupCodes)) {
$groups = Group::get()->filter(['Code' => $groupCodes]);
}

$result = Member::mapInCMSGroups($groups);
$this->assertInstanceOf(Map::class, $result);

$this->assertSame($expectedValue, $result->values());
}

public function provideMapInCMSGroups()
{
// Note: "ADMIN User" is not from the fixtures, that user is created by $this->logInWithPermission('ADMIN')
return [
'defaults' => [
'groupFixtures' => [],
'groupCodes' => [],
'expectedValue' => [
'Admin ',
'OtherAdmin ',
'ADMIN User',
],
],
'single group in a list' => [
'groupFixtures' => [],
'groupCodes' => [
'staffgroup'
],
'expectedValue' => [
'Staff User',
],
],
'single group in IDs array' => [
'groups' => [
'staffgroup',
],
'groupCodes' => [],
'expectedValue' => [
'Staff User',
],
],
'multiple groups in a list' => [
'groupFixtures' => [],
'groupCodes' => [
'staffgroup',
'securityadminsgroup',
],
'expectedValue' => [
'Staff User',
'Test User',
],
],
'multiple groups in IDs array' => [
'groupFixtures' => [
'staffgroup',
'securityadminsgroup',
],
'groupCodes' => [],
'expectedValue' => [
'Staff User',
'Test User',
],
],
'group with no members' => [
'groupFixtures' => [],
'groupCodes' => [
'memberless',
],
'expectedValue' => [],
],
];
}
}
2 changes: 2 additions & 0 deletions tests/php/Security/MemberTest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
Email: [email protected]
Password: 1nitialPassword
staffmember:
FirstName: Staff
Surname: User
Email: [email protected]
Groups: '=>SilverStripe\Security\Group.staffgroup'
managementmember:
Expand Down

0 comments on commit 8df5141

Please sign in to comment.