Skip to content

Commit

Permalink
Optimalizace volání isInRole + přihlašovacího formuláře (#1385)
Browse files Browse the repository at this point in the history
* db optimization

* db optimization

* db optimization

* db optimization

* cache impr, application form caching

* address disabled
  • Loading branch information
jan-stanek authored Oct 11, 2024
1 parent 7f2bb8b commit e99631b
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 81 deletions.
8 changes: 6 additions & 2 deletions app/AdminModule/Presenters/UsersPresenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use App\Model\Enums\ApplicationState;
use App\Model\Enums\PaymentType;
use App\Model\User\Queries\UserAttendsProgramsQuery;
use App\Services\AclService;
use App\Services\ApplicationService;
use App\Services\ExcelExportService;
use JsonException;
Expand Down Expand Up @@ -56,6 +57,9 @@ class UsersPresenter extends AdminBasePresenter
#[Inject]
public CustomInputRepository $customInputRepository;

#[Inject]
public AclService $aclService;

#[Inject]
public ApplicationService $applicationService;

Expand Down Expand Up @@ -83,8 +87,8 @@ public function renderDetail(int $id): void
$this->template->customInputTypeCheckbox = CustomInput::CHECKBOX;
$this->template->customInputTypeFile = CustomInput::FILE;

$this->template->roleAdminName = $this->roleRepository->findBySystemName(Role::ADMIN)->getName();
$this->template->roleOrganizerName = $this->roleRepository->findBySystemName(Role::ORGANIZER)->getName();
$this->template->roleAdminName = $this->aclService->findRoleNameBySystemName(Role::ADMIN);
$this->template->roleOrganizerName = $this->aclService->findRoleNameBySystemName(Role::ORGANIZER);

$this->template->paymentMethodCash = PaymentType::CASH;
$this->template->paymentMethodBank = PaymentType::BANK;
Expand Down
8 changes: 8 additions & 0 deletions app/Model/User/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,14 @@ public function isInRole(Role $role): bool
return $this->roles->contains($role);
}

/**
* Je uživatel v roli podle systémového názvu?
*/
public function isInRoleWithSystemName(string $name): bool
{
return $this->roles->exists(static fn (int $key, Role $role) => $role->getSystemName() === $name);
}

/**
* Vrací, zda má uživatel nějakou roli, která nemá cenu podle podakcí.
*/
Expand Down
60 changes: 32 additions & 28 deletions app/Services/AclService.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class AclService

private Cache $roleNamesCache;

private Cache $roleNameBySystemNameCache;

private Cache $permissionNamesCache;

private Cache $resourceNamesCache;
Expand All @@ -39,9 +41,10 @@ public function __construct(
private readonly Translator $translator,
Storage $storage,
) {
$this->roleNamesCache = new Cache($storage, 'RoleNames');
$this->permissionNamesCache = new Cache($storage, 'PermissionNames');
$this->resourceNamesCache = new Cache($storage, 'ResourceNames');
$this->roleNamesCache = new Cache($storage, 'RoleNames');
$this->roleNameBySystemNameCache = new Cache($storage, 'RoleNamesBySystemName');
$this->permissionNamesCache = new Cache($storage, 'PermissionNames');
$this->resourceNamesCache = new Cache($storage, 'ResourceNames');
}

/**
Expand All @@ -53,17 +56,21 @@ public function __construct(
*/
public function findAllRoleNames(): array
{
$names = $this->roleNamesCache->load(null);
if ($names === null) {
return $this->roleNamesCache->load(null, function () {
$names = $this->roleRepository->createQueryBuilder('r')
->select('r.name')
->getQuery()
->getScalarResult();
$names = array_map('current', $names);
$this->roleNamesCache->save(null, $names);
}
->select('r.name')
->getQuery()
->getScalarResult();

return array_map('current', $names);
});
}

return $names;
public function findRoleNameBySystemName(string $systemName): string
{
return $this->roleNameBySystemNameCache->load($systemName, function () use ($systemName) {
return $this->roleRepository->findBySystemName($systemName)->getName();
});
}

/**
Expand All @@ -73,6 +80,7 @@ public function saveRole(Role $role): void
{
$this->roleRepository->save($role);
$this->roleNamesCache->clean([Cache::Namespaces => ['RoleNames']]);
$this->roleNameBySystemNameCache->clean([Cache::Namespaces => ['RoleNamesBySystemName']]);
$this->permissionNamesCache->clean([Cache::Namespaces => ['PermissionNames']]);
}

Expand All @@ -83,6 +91,7 @@ public function removeRole(Role $role): void
{
$this->roleRepository->remove($role);
$this->roleNamesCache->clean([Cache::Namespaces => ['RoleNames']]);
$this->roleNameBySystemNameCache->clean([Cache::Namespaces => ['RoleNamesBySystemName']]);
}

/**
Expand Down Expand Up @@ -250,16 +259,14 @@ public function getRolesOptionsWithCapacity(bool $registerableNowOnly, bool $inc
*/
public function findAllPermissionNames(): Collection
{
$names = $this->permissionNamesCache->load(null);
if ($names === null) {
$names = $this->permissionRepository->createQueryBuilder('p')
->select('p.name')
->addSelect('role.name AS roleName')->join('p.roles', 'role')
->addSelect('resource.name AS resourceName')->join('p.resource', 'resource')
->getQuery()
->getResult();
$this->permissionNamesCache->save(null, $names);
}
$names = $this->permissionNamesCache->load(null, function () {
return $this->permissionRepository->createQueryBuilder('p')
->select('p.name')
->addSelect('role.name AS roleName')->join('p.roles', 'role')
->addSelect('resource.name AS resourceName')->join('p.resource', 'resource')
->getQuery()
->getResult();
});

return new ArrayCollection($names);
}
Expand All @@ -273,16 +280,13 @@ public function findAllPermissionNames(): Collection
*/
public function findAllResourceNames(): array
{
$names = $this->resourceNamesCache->load(null);
if ($names === null) {
return $this->resourceNamesCache->load(null, function () {
$names = $this->resourceRepository->createQueryBuilder('r')
->select('r.name')
->getQuery()
->getScalarResult();
$names = array_map('current', $names);
$this->resourceNamesCache->save(null, $names);
}

return $names;
return array_map('current', $names);
});
}
}
8 changes: 3 additions & 5 deletions app/Services/ApplicationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ public function getStateText(Application $application): string
*/
public function isAllowedEditRegistration(User $user): bool
{
return ! $user->isInRole($this->roleRepository->findBySystemName(Role::NONREGISTERED))
return ! $user->isInRoleWithSystemName(Role::NONREGISTERED)
&& ! $user->hasPaidAnyApplication()
&& $this->queryBus->handle(
new SettingDateValueQuery(Settings::EDIT_REGISTRATION_TO),
Expand Down Expand Up @@ -757,9 +757,7 @@ public function isAllowedEditApplication(Application $application): bool
*/
public function isAllowedAddApplication(User $user): bool
{
return ! $user->isInRole(
$this->roleRepository->findBySystemName(Role::NONREGISTERED),
)
return ! $user->isInRoleWithSystemName(Role::NONREGISTERED)
&& $user->hasPaidEveryApplication()
&& $this->queryBus->handle(
new SettingBoolValueQuery(Settings::IS_ALLOWED_ADD_SUBEVENTS_AFTER_PAYMENT),
Expand Down Expand Up @@ -793,7 +791,7 @@ public function isAllowedEditCustomInputs(): bool
*/
private function createRolesApplication(User $user, Collection $roles, User $createdBy, bool $approve = false): RolesApplication
{
if (! $user->isInRole($this->roleRepository->findBySystemName(Role::NONREGISTERED))) {
if (! $user->isInRoleWithSystemName(Role::NONREGISTERED)) {
throw new InvalidArgumentException('User is already registered.');
}

Expand Down
20 changes: 11 additions & 9 deletions app/WebModule/Components/ApplicationContentControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use App\Model\Settings\Queries\SettingStringValueQuery;
use App\Model\Settings\Settings;
use App\Model\Structure\Repositories\SubeventRepository;
use App\Services\AclService;
use App\Services\Authenticator;
use App\Services\QueryBus;
use App\WebModule\Forms\ApplicationFormFactory;
Expand All @@ -32,6 +33,7 @@ public function __construct(
private readonly QueryBus $queryBus,
private readonly ApplicationFormFactory $applicationFormFactory,
private readonly Authenticator $authenticator,
private readonly AclService $aclService,
private readonly RoleRepository $roleRepository,
private readonly SubeventRepository $subeventRepository,
public IApplicationsGridControlFactory $applicationsGridControlFactory,
Expand All @@ -58,7 +60,7 @@ public function render(ContentDto|null $content = null): void
$template->backlink = $presenter->getHttpRequest()->getUrl()->getPath();

$user = $presenter->getUser();
$template->guestRole = $user->isInRole($this->roleRepository->findBySystemName(Role::GUEST)->getName());
$template->guestRole = $user->isInRole($this->aclService->findRoleNameBySystemName(Role::GUEST));
$template->testRole = Role::TEST;

$explicitSubeventsExists = $this->subeventRepository->explicitSubeventsExists();
Expand All @@ -67,14 +69,14 @@ public function render(ContentDto|null $content = null): void
$dbUser = $presenter->getDbUser();
$userHasFixedFeeRole = $dbUser->hasFixedFeeRole();

$template->unapprovedRole = $user->isInRole($this->roleRepository->findBySystemName(Role::UNAPPROVED)->getName());
$template->nonregisteredRole = $user->isInRole($this->roleRepository->findBySystemName(Role::NONREGISTERED)->getName());
$template->noRegisterableRole = $this->roleRepository->findFilteredRoles(true, false, false)->isEmpty();
$template->registrationStart = $this->roleRepository->getRegistrationStart();
$template->registrationEnd = $this->roleRepository->getRegistrationEnd();
$template->bankAccount = $this->queryBus->handle(new SettingStringValueQuery(Settings::ACCOUNT_NUMBER));
$template->dbUser = $dbUser;
$template->userHasFixedFeeRole = $userHasFixedFeeRole;
$template->isInUnapprovedRole = $user->isInRole($this->aclService->findRoleNameBySystemName(Role::UNAPPROVED));
$template->isInNonregisteredRole = $user->isInRole($this->aclService->findRoleNameBySystemName(Role::NONREGISTERED));
$template->noRegisterableRole = $this->roleRepository->findFilteredRoles(true, false, false)->isEmpty();
$template->registrationStart = $this->roleRepository->getRegistrationStart();
$template->registrationEnd = $this->roleRepository->getRegistrationEnd();
$template->bankAccount = $this->queryBus->handle(new SettingStringValueQuery(Settings::ACCOUNT_NUMBER));
$template->dbUser = $dbUser;
$template->userHasFixedFeeRole = $userHasFixedFeeRole;

$template->usersApplications = $explicitSubeventsExists && $userHasFixedFeeRole
? $dbUser->getNotCanceledApplications()
Expand Down
6 changes: 3 additions & 3 deletions app/WebModule/Components/ContactFormContentControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

namespace App\WebModule\Components;

use App\Model\Acl\Repositories\RoleRepository;
use App\Model\Acl\Role;
use App\Model\Cms\Dto\ContentDto;
use App\Model\Settings\Queries\SettingBoolValueQuery;
use App\Model\Settings\Settings;
use App\Services\AclService;
use App\Services\QueryBus;
use App\WebModule\Forms\ContactForm;
use App\WebModule\Forms\IContactFormFactory;
Expand All @@ -22,7 +22,7 @@ class ContactFormContentControl extends BaseContentControl
public function __construct(
private readonly QueryBus $queryBus,
private readonly IContactFormFactory $contactFormFactory,
private readonly RoleRepository $roleRepository,
private readonly AclService $aclService,
) {
}

Expand All @@ -36,7 +36,7 @@ public function render(ContentDto $content): void

$template->backlink = $this->getPresenter()->getHttpRequest()->getUrl()->getPath();

$template->guestRole = $this->getPresenter()->getUser()->isInRole($this->roleRepository->findBySystemName(Role::GUEST)->getName());
$template->guestRole = $this->getPresenter()->getUser()->isInRole($this->aclService->findRoleNameBySystemName(Role::GUEST));
$template->guestsAllowed = $this->queryBus->handle(new SettingBoolValueQuery(Settings::CONTACT_FORM_GUESTS_ALLOWED));

$template->render();
Expand Down
6 changes: 3 additions & 3 deletions app/WebModule/Components/FaqContentControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

namespace App\WebModule\Components;

use App\Model\Acl\Repositories\RoleRepository;
use App\Model\Acl\Role;
use App\Model\Cms\Dto\ContentDto;
use App\Model\Cms\Repositories\FaqRepository;
use App\Services\AclService;
use App\WebModule\Forms\FaqFormFactory;
use App\WebModule\Presenters\WebBasePresenter;
use Nette\Application\UI\Form;
Expand All @@ -23,7 +23,7 @@ class FaqContentControl extends BaseContentControl
public function __construct(
private readonly FaqFormFactory $faqFormFactory,
private readonly FaqRepository $faqRepository,
private readonly RoleRepository $roleRepository,
private readonly AclService $aclService,
) {
}

Expand All @@ -37,7 +37,7 @@ public function render(ContentDto $content): void

$template->backlink = $this->getPresenter()->getHttpRequest()->getUrl()->getPath();

$template->guestRole = $this->getPresenter()->getUser()->isInRole($this->roleRepository->findBySystemName(Role::GUEST)->getName());
$template->guestRole = $this->getPresenter()->getUser()->isInRole($this->aclService->findRoleNameBySystemName(Role::GUEST));

$template->render();
}
Expand Down
6 changes: 3 additions & 3 deletions app/WebModule/Components/ProgramsContentControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace App\WebModule\Components;

use App\Model\Acl\Repositories\RoleRepository;
use App\Model\Acl\Role;
use App\Model\Cms\Dto\ContentDto;
use App\Model\Enums\ProgramRegistrationType;
Expand All @@ -13,6 +12,7 @@
use App\Model\Settings\Queries\SettingDateTimeValueQuery;
use App\Model\Settings\Queries\SettingStringValueQuery;
use App\Model\Settings\Settings;
use App\Services\AclService;
use App\Services\QueryBus;
use App\WebModule\Presenters\WebBasePresenter;
use Throwable;
Expand All @@ -26,7 +26,7 @@ class ProgramsContentControl extends BaseContentControl
{
public function __construct(
private readonly QueryBus $queryBus,
private readonly RoleRepository $roleRepository,
private readonly AclService $aclService,
) {
}

Expand All @@ -49,7 +49,7 @@ public function render(ContentDto $content): void
$presenter = $this->getPresenter();
assert($presenter instanceof WebBasePresenter);

$template->guestRole = $presenter->getUser()->isInRole($this->roleRepository->findBySystemName(Role::GUEST)->getName());
$template->guestRole = $presenter->getUser()->isInRole($this->aclService->findRoleNameBySystemName(Role::GUEST));

if ($presenter->getUser()->isLoggedIn()) {
$template->userWaitingForPayment = ! $this->queryBus->handle(new SettingBoolValueQuery(Settings::IS_ALLOWED_REGISTER_PROGRAMS_BEFORE_PAYMENT))
Expand Down
6 changes: 3 additions & 3 deletions app/WebModule/Components/TicketContentControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

namespace App\WebModule\Components;

use App\Model\Acl\Repositories\RoleRepository;
use App\Model\Acl\Role;
use App\Model\Cms\Dto\ContentDto;
use App\Services\AclService;

/**
* Komponenta obsahu se vstupenkou.
*/
class TicketContentControl extends BaseContentControl
{
public function __construct(
private readonly RoleRepository $roleRepository,
private readonly AclService $aclService,
private readonly ITicketControlFactory $ticketControlFactory,
) {
}
Expand All @@ -30,7 +30,7 @@ public function render(ContentDto $content): void

$template->backlink = $presenter->getHttpRequest()->getUrl()->getPath();

$template->guestRole = $presenter->getUser()->isInRole($this->roleRepository->findBySystemName(Role::GUEST)->getName());
$template->guestRole = $presenter->getUser()->isInRole($this->aclService->findRoleNameBySystemName(Role::GUEST));

$template->render();
}
Expand Down
8 changes: 4 additions & 4 deletions app/WebModule/Components/TicketControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

namespace App\WebModule\Components;

use App\Model\Acl\Repositories\RoleRepository;
use App\Model\Acl\Role;
use App\Model\Settings\Queries\SettingDateTimeValueQuery;
use App\Model\Settings\Settings;
use App\Services\AclService;
use App\Services\QueryBus;
use App\WebModule\Presenters\WebBasePresenter;
use DateTimeImmutable;
Expand All @@ -24,7 +24,7 @@
*/
class TicketControl extends Control
{
public function __construct(private readonly QueryBus $queryBus, private readonly RoleRepository $roleRepository)
public function __construct(private readonly QueryBus $queryBus, private readonly AclService $aclService)
{
}

Expand All @@ -44,8 +44,8 @@ public function render(): void
$ticketDownloadFrom = $this->queryBus->handle(new SettingDateTimeValueQuery(Settings::TICKETS_FROM));
$template->ticketsAvailable = $ticketDownloadFrom !== null && $ticketDownloadFrom <= new DateTimeImmutable();

$template->registeredAndPaid = ! $user->isInRole($this->roleRepository->findBySystemName(Role::UNAPPROVED)->getName())
&& ! $user->isInRole($this->roleRepository->findBySystemName(Role::NONREGISTERED)->getName())
$template->registeredAndPaid = ! $user->isInRole($this->aclService->findRoleNameBySystemName(Role::UNAPPROVED))
&& ! $user->isInRole($this->aclService->findRoleNameBySystemName(Role::NONREGISTERED))
&& $presenter->getDbUser()->hasPaidEveryApplication();

$template->qr = $this->generateQr($this->presenter->getUser()->getId());
Expand Down
Loading

0 comments on commit e99631b

Please sign in to comment.