Skip to content

Commit e99631b

Browse files
authored
Optimalizace volání isInRole + přihlašovacího formuláře (#1385)
* db optimization * db optimization * db optimization * db optimization * cache impr, application form caching * address disabled
1 parent 7f2bb8b commit e99631b

14 files changed

+146
-81
lines changed

app/AdminModule/Presenters/UsersPresenter.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use App\Model\Enums\ApplicationState;
2020
use App\Model\Enums\PaymentType;
2121
use App\Model\User\Queries\UserAttendsProgramsQuery;
22+
use App\Services\AclService;
2223
use App\Services\ApplicationService;
2324
use App\Services\ExcelExportService;
2425
use JsonException;
@@ -56,6 +57,9 @@ class UsersPresenter extends AdminBasePresenter
5657
#[Inject]
5758
public CustomInputRepository $customInputRepository;
5859

60+
#[Inject]
61+
public AclService $aclService;
62+
5963
#[Inject]
6064
public ApplicationService $applicationService;
6165

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

86-
$this->template->roleAdminName = $this->roleRepository->findBySystemName(Role::ADMIN)->getName();
87-
$this->template->roleOrganizerName = $this->roleRepository->findBySystemName(Role::ORGANIZER)->getName();
90+
$this->template->roleAdminName = $this->aclService->findRoleNameBySystemName(Role::ADMIN);
91+
$this->template->roleOrganizerName = $this->aclService->findRoleNameBySystemName(Role::ORGANIZER);
8892

8993
$this->template->paymentMethodCash = PaymentType::CASH;
9094
$this->template->paymentMethodBank = PaymentType::BANK;

app/Model/User/User.php

+8
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,14 @@ public function isInRole(Role $role): bool
669669
return $this->roles->contains($role);
670670
}
671671

672+
/**
673+
* Je uživatel v roli podle systémového názvu?
674+
*/
675+
public function isInRoleWithSystemName(string $name): bool
676+
{
677+
return $this->roles->exists(static fn (int $key, Role $role) => $role->getSystemName() === $name);
678+
}
679+
672680
/**
673681
* Vrací, zda má uživatel nějakou roli, která nemá cenu podle podakcí.
674682
*/

app/Services/AclService.php

+32-28
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class AclService
2828

2929
private Cache $roleNamesCache;
3030

31+
private Cache $roleNameBySystemNameCache;
32+
3133
private Cache $permissionNamesCache;
3234

3335
private Cache $resourceNamesCache;
@@ -39,9 +41,10 @@ public function __construct(
3941
private readonly Translator $translator,
4042
Storage $storage,
4143
) {
42-
$this->roleNamesCache = new Cache($storage, 'RoleNames');
43-
$this->permissionNamesCache = new Cache($storage, 'PermissionNames');
44-
$this->resourceNamesCache = new Cache($storage, 'ResourceNames');
44+
$this->roleNamesCache = new Cache($storage, 'RoleNames');
45+
$this->roleNameBySystemNameCache = new Cache($storage, 'RoleNamesBySystemName');
46+
$this->permissionNamesCache = new Cache($storage, 'PermissionNames');
47+
$this->resourceNamesCache = new Cache($storage, 'ResourceNames');
4548
}
4649

4750
/**
@@ -53,17 +56,21 @@ public function __construct(
5356
*/
5457
public function findAllRoleNames(): array
5558
{
56-
$names = $this->roleNamesCache->load(null);
57-
if ($names === null) {
59+
return $this->roleNamesCache->load(null, function () {
5860
$names = $this->roleRepository->createQueryBuilder('r')
59-
->select('r.name')
60-
->getQuery()
61-
->getScalarResult();
62-
$names = array_map('current', $names);
63-
$this->roleNamesCache->save(null, $names);
64-
}
61+
->select('r.name')
62+
->getQuery()
63+
->getScalarResult();
64+
65+
return array_map('current', $names);
66+
});
67+
}
6568

66-
return $names;
69+
public function findRoleNameBySystemName(string $systemName): string
70+
{
71+
return $this->roleNameBySystemNameCache->load($systemName, function () use ($systemName) {
72+
return $this->roleRepository->findBySystemName($systemName)->getName();
73+
});
6774
}
6875

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

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

8897
/**
@@ -250,16 +259,14 @@ public function getRolesOptionsWithCapacity(bool $registerableNowOnly, bool $inc
250259
*/
251260
public function findAllPermissionNames(): Collection
252261
{
253-
$names = $this->permissionNamesCache->load(null);
254-
if ($names === null) {
255-
$names = $this->permissionRepository->createQueryBuilder('p')
256-
->select('p.name')
257-
->addSelect('role.name AS roleName')->join('p.roles', 'role')
258-
->addSelect('resource.name AS resourceName')->join('p.resource', 'resource')
259-
->getQuery()
260-
->getResult();
261-
$this->permissionNamesCache->save(null, $names);
262-
}
262+
$names = $this->permissionNamesCache->load(null, function () {
263+
return $this->permissionRepository->createQueryBuilder('p')
264+
->select('p.name')
265+
->addSelect('role.name AS roleName')->join('p.roles', 'role')
266+
->addSelect('resource.name AS resourceName')->join('p.resource', 'resource')
267+
->getQuery()
268+
->getResult();
269+
});
263270

264271
return new ArrayCollection($names);
265272
}
@@ -273,16 +280,13 @@ public function findAllPermissionNames(): Collection
273280
*/
274281
public function findAllResourceNames(): array
275282
{
276-
$names = $this->resourceNamesCache->load(null);
277-
if ($names === null) {
283+
return $this->resourceNamesCache->load(null, function () {
278284
$names = $this->resourceRepository->createQueryBuilder('r')
279285
->select('r.name')
280286
->getQuery()
281287
->getScalarResult();
282-
$names = array_map('current', $names);
283-
$this->resourceNamesCache->save(null, $names);
284-
}
285288

286-
return $names;
289+
return array_map('current', $names);
290+
});
287291
}
288292
}

app/Services/ApplicationService.php

+3-5
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ public function getStateText(Application $application): string
726726
*/
727727
public function isAllowedEditRegistration(User $user): bool
728728
{
729-
return ! $user->isInRole($this->roleRepository->findBySystemName(Role::NONREGISTERED))
729+
return ! $user->isInRoleWithSystemName(Role::NONREGISTERED)
730730
&& ! $user->hasPaidAnyApplication()
731731
&& $this->queryBus->handle(
732732
new SettingDateValueQuery(Settings::EDIT_REGISTRATION_TO),
@@ -757,9 +757,7 @@ public function isAllowedEditApplication(Application $application): bool
757757
*/
758758
public function isAllowedAddApplication(User $user): bool
759759
{
760-
return ! $user->isInRole(
761-
$this->roleRepository->findBySystemName(Role::NONREGISTERED),
762-
)
760+
return ! $user->isInRoleWithSystemName(Role::NONREGISTERED)
763761
&& $user->hasPaidEveryApplication()
764762
&& $this->queryBus->handle(
765763
new SettingBoolValueQuery(Settings::IS_ALLOWED_ADD_SUBEVENTS_AFTER_PAYMENT),
@@ -793,7 +791,7 @@ public function isAllowedEditCustomInputs(): bool
793791
*/
794792
private function createRolesApplication(User $user, Collection $roles, User $createdBy, bool $approve = false): RolesApplication
795793
{
796-
if (! $user->isInRole($this->roleRepository->findBySystemName(Role::NONREGISTERED))) {
794+
if (! $user->isInRoleWithSystemName(Role::NONREGISTERED)) {
797795
throw new InvalidArgumentException('User is already registered.');
798796
}
799797

app/WebModule/Components/ApplicationContentControl.php

+11-9
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use App\Model\Settings\Queries\SettingStringValueQuery;
1313
use App\Model\Settings\Settings;
1414
use App\Model\Structure\Repositories\SubeventRepository;
15+
use App\Services\AclService;
1516
use App\Services\Authenticator;
1617
use App\Services\QueryBus;
1718
use App\WebModule\Forms\ApplicationFormFactory;
@@ -32,6 +33,7 @@ public function __construct(
3233
private readonly QueryBus $queryBus,
3334
private readonly ApplicationFormFactory $applicationFormFactory,
3435
private readonly Authenticator $authenticator,
36+
private readonly AclService $aclService,
3537
private readonly RoleRepository $roleRepository,
3638
private readonly SubeventRepository $subeventRepository,
3739
public IApplicationsGridControlFactory $applicationsGridControlFactory,
@@ -58,7 +60,7 @@ public function render(ContentDto|null $content = null): void
5860
$template->backlink = $presenter->getHttpRequest()->getUrl()->getPath();
5961

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

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

70-
$template->unapprovedRole = $user->isInRole($this->roleRepository->findBySystemName(Role::UNAPPROVED)->getName());
71-
$template->nonregisteredRole = $user->isInRole($this->roleRepository->findBySystemName(Role::NONREGISTERED)->getName());
72-
$template->noRegisterableRole = $this->roleRepository->findFilteredRoles(true, false, false)->isEmpty();
73-
$template->registrationStart = $this->roleRepository->getRegistrationStart();
74-
$template->registrationEnd = $this->roleRepository->getRegistrationEnd();
75-
$template->bankAccount = $this->queryBus->handle(new SettingStringValueQuery(Settings::ACCOUNT_NUMBER));
76-
$template->dbUser = $dbUser;
77-
$template->userHasFixedFeeRole = $userHasFixedFeeRole;
72+
$template->isInUnapprovedRole = $user->isInRole($this->aclService->findRoleNameBySystemName(Role::UNAPPROVED));
73+
$template->isInNonregisteredRole = $user->isInRole($this->aclService->findRoleNameBySystemName(Role::NONREGISTERED));
74+
$template->noRegisterableRole = $this->roleRepository->findFilteredRoles(true, false, false)->isEmpty();
75+
$template->registrationStart = $this->roleRepository->getRegistrationStart();
76+
$template->registrationEnd = $this->roleRepository->getRegistrationEnd();
77+
$template->bankAccount = $this->queryBus->handle(new SettingStringValueQuery(Settings::ACCOUNT_NUMBER));
78+
$template->dbUser = $dbUser;
79+
$template->userHasFixedFeeRole = $userHasFixedFeeRole;
7880

7981
$template->usersApplications = $explicitSubeventsExists && $userHasFixedFeeRole
8082
? $dbUser->getNotCanceledApplications()

app/WebModule/Components/ContactFormContentControl.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
namespace App\WebModule\Components;
66

7-
use App\Model\Acl\Repositories\RoleRepository;
87
use App\Model\Acl\Role;
98
use App\Model\Cms\Dto\ContentDto;
109
use App\Model\Settings\Queries\SettingBoolValueQuery;
1110
use App\Model\Settings\Settings;
11+
use App\Services\AclService;
1212
use App\Services\QueryBus;
1313
use App\WebModule\Forms\ContactForm;
1414
use App\WebModule\Forms\IContactFormFactory;
@@ -22,7 +22,7 @@ class ContactFormContentControl extends BaseContentControl
2222
public function __construct(
2323
private readonly QueryBus $queryBus,
2424
private readonly IContactFormFactory $contactFormFactory,
25-
private readonly RoleRepository $roleRepository,
25+
private readonly AclService $aclService,
2626
) {
2727
}
2828

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

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

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

4242
$template->render();

app/WebModule/Components/FaqContentControl.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
namespace App\WebModule\Components;
66

7-
use App\Model\Acl\Repositories\RoleRepository;
87
use App\Model\Acl\Role;
98
use App\Model\Cms\Dto\ContentDto;
109
use App\Model\Cms\Repositories\FaqRepository;
10+
use App\Services\AclService;
1111
use App\WebModule\Forms\FaqFormFactory;
1212
use App\WebModule\Presenters\WebBasePresenter;
1313
use Nette\Application\UI\Form;
@@ -23,7 +23,7 @@ class FaqContentControl extends BaseContentControl
2323
public function __construct(
2424
private readonly FaqFormFactory $faqFormFactory,
2525
private readonly FaqRepository $faqRepository,
26-
private readonly RoleRepository $roleRepository,
26+
private readonly AclService $aclService,
2727
) {
2828
}
2929

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

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

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

4242
$template->render();
4343
}

app/WebModule/Components/ProgramsContentControl.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace App\WebModule\Components;
66

7-
use App\Model\Acl\Repositories\RoleRepository;
87
use App\Model\Acl\Role;
98
use App\Model\Cms\Dto\ContentDto;
109
use App\Model\Enums\ProgramRegistrationType;
@@ -13,6 +12,7 @@
1312
use App\Model\Settings\Queries\SettingDateTimeValueQuery;
1413
use App\Model\Settings\Queries\SettingStringValueQuery;
1514
use App\Model\Settings\Settings;
15+
use App\Services\AclService;
1616
use App\Services\QueryBus;
1717
use App\WebModule\Presenters\WebBasePresenter;
1818
use Throwable;
@@ -26,7 +26,7 @@ class ProgramsContentControl extends BaseContentControl
2626
{
2727
public function __construct(
2828
private readonly QueryBus $queryBus,
29-
private readonly RoleRepository $roleRepository,
29+
private readonly AclService $aclService,
3030
) {
3131
}
3232

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

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

5454
if ($presenter->getUser()->isLoggedIn()) {
5555
$template->userWaitingForPayment = ! $this->queryBus->handle(new SettingBoolValueQuery(Settings::IS_ALLOWED_REGISTER_PROGRAMS_BEFORE_PAYMENT))

app/WebModule/Components/TicketContentControl.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44

55
namespace App\WebModule\Components;
66

7-
use App\Model\Acl\Repositories\RoleRepository;
87
use App\Model\Acl\Role;
98
use App\Model\Cms\Dto\ContentDto;
9+
use App\Services\AclService;
1010

1111
/**
1212
* Komponenta obsahu se vstupenkou.
1313
*/
1414
class TicketContentControl extends BaseContentControl
1515
{
1616
public function __construct(
17-
private readonly RoleRepository $roleRepository,
17+
private readonly AclService $aclService,
1818
private readonly ITicketControlFactory $ticketControlFactory,
1919
) {
2020
}
@@ -30,7 +30,7 @@ public function render(ContentDto $content): void
3030

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

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

3535
$template->render();
3636
}

app/WebModule/Components/TicketControl.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
namespace App\WebModule\Components;
66

7-
use App\Model\Acl\Repositories\RoleRepository;
87
use App\Model\Acl\Role;
98
use App\Model\Settings\Queries\SettingDateTimeValueQuery;
109
use App\Model\Settings\Settings;
10+
use App\Services\AclService;
1111
use App\Services\QueryBus;
1212
use App\WebModule\Presenters\WebBasePresenter;
1313
use DateTimeImmutable;
@@ -24,7 +24,7 @@
2424
*/
2525
class TicketControl extends Control
2626
{
27-
public function __construct(private readonly QueryBus $queryBus, private readonly RoleRepository $roleRepository)
27+
public function __construct(private readonly QueryBus $queryBus, private readonly AclService $aclService)
2828
{
2929
}
3030

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

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

5151
$template->qr = $this->generateQr($this->presenter->getUser()->getId());

0 commit comments

Comments
 (0)