Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix user roles #101

Merged
merged 8 commits into from
Feb 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ parameters:
count: 1
path: src/DB.php

-
message: "#^Plugin definitions cannot be altered\\.$#"
count: 1
path: src/Entity/EntityTypeManager.php

-
message: "#^Method Retrofit\\\\Drupal\\\\Entity\\\\WrappedConfigEntity\\:\\:__get\\(\\) has no return type specified\\.$#"
count: 1
Expand Down Expand Up @@ -520,11 +525,6 @@ parameters:
count: 1
path: src/Theme/HookPreprocess.php

-
message: "#^Method Retrofit\\\\Drupal\\\\User\\\\GlobalUser\\:\\:__get\\(\\) has no return type specified\\.$#"
count: 1
path: src/User/GlobalUser.php

-
message: "#^Method Retrofit\\\\Drupal\\\\User\\\\GlobalUser\\:\\:__set\\(\\) has parameter \\$value with no type specified\\.$#"
count: 1
Expand Down
21 changes: 21 additions & 0 deletions src/Entity/EntityTypeManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Retrofit\Drupal\Entity;

use Drupal\Core\Entity\EntityTypeInterface;

class EntityTypeManager extends \Drupal\Core\Entity\EntityTypeManager
{
/**
* @param EntityTypeInterface[] $definitions
*/
protected function alterDefinitions(&$definitions): void
{
if (isset($definitions['user_role'])) {
$definitions['user_role']->setClass(Role::class);
}
parent::alterDefinitions($definitions);
}
}
41 changes: 41 additions & 0 deletions src/Entity/Role.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace Retrofit\Drupal\Entity;

use Drupal\user\Entity\Role as CoreRole;

class Role extends CoreRole
{
public function __toString()
{
return $this->label;
}

public function __set(string $name, string $value): void
{
match ($name) {
'rid' => $this->id = $value,
'name' => $this->label = $value,
default => null
};
}

public function __get(string $name): mixed
{
return match ($name) {
'rid' => $this->id,
'name' => $this->label,
default => null
};
}

public function __isset(string $name): bool
{
return match ($name) {
'rid', 'name' => true,
default => false
};
}
darrenoh marked this conversation as resolved.
Show resolved Hide resolved
}
7 changes: 7 additions & 0 deletions src/Provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Retrofit\Drupal\Asset\RetrofitJsCollectionRenderer;
use Retrofit\Drupal\Asset\RetrofitLibraryDiscovery;
use Retrofit\Drupal\Controller\RetrofitTitleResolver;
use Retrofit\Drupal\Entity\EntityTypeManager;
use Retrofit\Drupal\Field\FieldTypePluginManager;
use Retrofit\Drupal\Form\FormBuilder;
use Retrofit\Drupal\Language\GlobalLanguageSetter;
Expand Down Expand Up @@ -151,6 +152,12 @@ public function register(ContainerBuilder $container)
(new ChildDefinition('path.current'))
->setDecoratedService('path.current')
);

$container->setDefinition(
EntityTypeManager::class,
(new ChildDefinition('entity_type.manager'))
->setDecoratedService('entity_type.manager')
);
}

public function alter(ContainerBuilder $container)
Expand Down
26 changes: 14 additions & 12 deletions src/User/GlobalUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Retrofit\Drupal\User;

use Drupal\Core\Session\AccountInterface;
use Retrofit\Drupal\Entity\Role;

final class GlobalUser implements AccountInterface
{
Expand All @@ -20,16 +21,7 @@ public function id()

public function getRoles($exclude_locked_roles = false)
{
$roles = $this->inner->getRoles($exclude_locked_roles);
// Drupal 7 appended `user` to locked roles, so we need to do the same.
if (!$exclude_locked_roles) {
if ($this->isAuthenticated()) {
$roles[] = 'authenticated user';
} else {
$roles[] = 'anonymous user';
}
}
return $roles;
return $this->inner->getRoles($exclude_locked_roles);
}

public function hasPermission($permission)
Expand Down Expand Up @@ -82,10 +74,20 @@ public function getLastAccessedTime()
return $this->inner->getLastAccessedTime();
}

public function __get(string $name)
public function __get(string $name): mixed
{
return match ($name) {
'roles' => $this->getRoles(),
'roles' => array_map(
fn($role) => match ($role->id()) {
'anonymous',
'authenticated' => strtolower((string) $role->label()),
default => (string) $role->label(),
},
array_filter(array_map(
[Role::class, 'load'],
array_combine($this->getRoles(), $this->getRoles())
))
),
'name' => $this->getAccountName(),
default => null,
};
Expand Down
12 changes: 12 additions & 0 deletions src/functions/user.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
declare(strict_types=1);

use Drupal\Core\Session\AccountInterface;
use Drupal\user\RoleInterface;
use Retrofit\Drupal\Entity\Role;

function user_access(string $string, ?AccountInterface $account = null): bool
{
Expand All @@ -21,3 +23,13 @@ function user_is_logged_in(): bool
{
return \Drupal::currentUser()->isAuthenticated();
}

function user_role_load(string $rid): ?RoleInterface
{
return Role::load($rid);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use long-form \Drupal::entityTypeManager()->getStorage('user_role')->load($rid);

Copy link
Contributor Author

@darrenoh darrenoh Nov 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could. I actually like the simplicity of letting this static method do it for us. Every entity class has a static load method.
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21EntityInterface.php/function/EntityInterface%3A%3Aload/10

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clarity I changed this to use our extended Role class.

}

function user_role_load_by_name(string $role_name): RoleInterface|false
{
return Role::load($role_name) ?? false;
}
1 change: 1 addition & 0 deletions tests/src/Integration/Routing/HookMenuRoutesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public function register(ContainerBuilder $container): void
protected function setUp(): void
{
parent::setUp();
$this->installConfig(['user']);
$this->config('system.site')
->set('name', 'Drupal')
->save();
Expand Down
Loading