From c5c480edef82ab6cc0514331f135ffc5c7bb2215 Mon Sep 17 00:00:00 2001 From: Nicolas Roudaire Date: Sat, 4 Jan 2025 15:55:02 +0100 Subject: [PATCH] PHP Enums for Image and User privacy level --- admin/theme/template/users_list.html.twig | 650 +++++++++--------- .../Admin/AdminBatchManagerController.php | 5 +- src/Controller/Admin/AdminPhotoController.php | 3 +- src/Controller/Admin/AdminUsersController.php | 7 +- src/Controller/AlbumController.php | 8 +- src/DataMapper/AlbumMapper.php | 5 +- src/Entity/Image.php | 9 +- src/Entity/UserInfos.php | 14 +- src/Enum/UserPrivacyLevelType.php | 29 + src/Form/Model/UserInfosModel.php | 7 +- src/Form/UserInfosType.php | 13 +- src/Repository/AlbumRepository.php | 3 +- src/Repository/ImageRepository.php | 7 +- src/Utils/UserManager.php | 3 +- tests/DataMapper/AlbumMapperTest.php | 5 +- themes/treflez/template/_albums.html.twig | 1 - .../template/_picture_info_cards.html.twig | 2 +- .../template/_picture_info_sidebar.html.twig | 2 +- .../template/_picture_info_tabs.html.twig | 2 +- translations/messages+intl-icu.en_GB.php | 9 + 20 files changed, 411 insertions(+), 373 deletions(-) create mode 100644 src/Enum/UserPrivacyLevelType.php diff --git a/admin/theme/template/users_list.html.twig b/admin/theme/template/users_list.html.twig index bb9c23f3a..c514359f5 100644 --- a/admin/theme/template/users_list.html.twig +++ b/admin/theme/template/users_list.html.twig @@ -161,332 +161,336 @@ {{user.getUserInfos().getStatusValue}} {{user.getMailAddress()}} {{user.getGroups() | json_encode }} - {{user.getUserInfos().getLevel()}} + {{user.getUserInfos().getLevel()|trans}} {{user.getUserInfos().getRegistrationDate() | date}} {% endfor %} -

> - -
- {{'No user selected, no action possible.'|trans}} -
-
-

- -

- -
-

- - -

-
- -
-

- -

-
- -
-

- -

-
- -
-

- -

-
- -
-

- - -

-

- - -

-
- -
-

- -

-
- -
-

- - -

-
- -
-

- -

-
- -
-

- -

-
- -
-

- - -

-
- -
-

- - -

-

- - -

-
- -
-

- - -

-

- - -

-
- -
-

- - -

-

- - -

-
- -

- - -

-
-

- - - - {% endblock %} +
+

{{'New username'|trans}}

+

+ +

+

+ + {{'Cancel'|trans}} +

+
+ <% } %> + + +
<%- user.registeredOn_string %>
<%- user.lastVisit_string %>
+ + +
+

{{'Properties'|trans}}

+
+ +
+ +
+ +
+ +
+ +
+ +
+ checked="checked" <% } %>> +
+ +
+ +
+ +

{{'Preferences'|trans}}

+ +
+

+ + +

+
+ +
+ +
+ +
+ +
+ +
+

+ + +

+
+ +
+ checked="checked" <% }%>> + +
+ +
+ checked="checked" <% }%>> + +
+ +
+ checked="checked" <% }%>> + +
+ +

+ +

+
+ + +{% endblock %} diff --git a/src/Controller/Admin/AdminBatchManagerController.php b/src/Controller/Admin/AdminBatchManagerController.php index ad5e14c8f..9ae009834 100644 --- a/src/Controller/Admin/AdminBatchManagerController.php +++ b/src/Controller/Admin/AdminBatchManagerController.php @@ -21,6 +21,7 @@ use App\Entity\Caddie; use App\Entity\User; use App\Enum\ImageSizeType; +use App\Enum\UserPrivacyLevelType; use App\ImageLibraryGuesser; use App\Repository\AlbumRepository; use App\Repository\CaddieRepository; @@ -79,7 +80,7 @@ protected function appendFilter(SessionInterface $session, array $filter = []): } /** - * @return array|array> + * @return array|array> */ protected function getFilter(SessionInterface $session): array { @@ -983,7 +984,7 @@ public function unit( foreach ($imageMapper->getRepository()->findBy(['id' => $collection]) as $image) { $image->setName($request->request->get('name-' . $image->getId())); $image->setAuthor($request->request->get('author-' . $image->getId())); - $image->setLevel($request->request->get('level-' . $image->getId())); + $image->setLevel(UserPrivacyLevelType::from($request->request->get('level-' . $image->getId()))); if ($conf['allow_html_descriptions']) { $image->setComment($request->request->get('description-' . $image->getId()) ?? ''); diff --git a/src/Controller/Admin/AdminPhotoController.php b/src/Controller/Admin/AdminPhotoController.php index 6b77cc82b..2be24909f 100644 --- a/src/Controller/Admin/AdminPhotoController.php +++ b/src/Controller/Admin/AdminPhotoController.php @@ -17,6 +17,7 @@ use App\DataMapper\TagMapper; use App\DataMapper\UserMapper; use App\Enum\ImageSizeType; +use App\Enum\UserPrivacyLevelType; use App\ImageLibraryGuesser; use App\Repository\ImageAlbumRepository; use App\Repository\ImageRepository; @@ -85,7 +86,7 @@ public function edit( if ($request->isMethod('POST')) { $image->setName($request->request->get('name')); $image->setAuthor($request->request->get('author')); - $image->setLevel($request->request->get('level')); + $image->setLevel(UserPrivacyLevelType::from($request->request->get('level'))); if ($conf['allow_html_descriptions']) { $image->setComment($request->request->get('description')); diff --git a/src/Controller/Admin/AdminUsersController.php b/src/Controller/Admin/AdminUsersController.php index 25a34e7f7..fd2183e4d 100644 --- a/src/Controller/Admin/AdminUsersController.php +++ b/src/Controller/Admin/AdminUsersController.php @@ -14,6 +14,7 @@ use App\DataMapper\AlbumMapper; use App\DataMapper\UserMapper; use App\Entity\User; +use App\Enum\UserPrivacyLevelType; use App\Enum\UserStatusType; use App\Form\Model\UserProfileModel; use App\Form\UserCreationType; @@ -142,11 +143,11 @@ public function list( // user level options $level_options = []; - foreach ($conf['available_permission_levels'] as $level) { - $level_options[$level] = $translator->trans(sprintf('Level %d', $level), [], 'admin'); + foreach (UserPrivacyLevelType::cases() as $level) { + $level_options[$level->value] = $translator->trans(sprintf('Level %d', $level->value), [], 'admin'); } $tpl_params['level_options'] = $level_options; - $tpl_params['level_selected'] = $guestUser->getUserInfos()->getLevel(); + $tpl_params['level_selected'] = $guestUser->getUserInfos()->getLevel()->value; $tpl_params['ws'] = $this->generateUrl('ws'); $tpl_params['csrf_token'] = $csrfTokenManager->getToken('authenticate'); diff --git a/src/Controller/AlbumController.php b/src/Controller/AlbumController.php index 8244527f1..a431c875f 100644 --- a/src/Controller/AlbumController.php +++ b/src/Controller/AlbumController.php @@ -375,13 +375,11 @@ public function albums( if (count($albums) > 0) { $tpl_thumbnails_var = []; foreach ($albums as $album) { + $userCacheAlbum = $album->getUserCacheAlbum(); $name = $albumMapper->getAlbumsDisplayNameCache($album->getUppercats()); - $representative_infos = null; - if (isset($infos_of_images[$album->getRepresentativePictureId()])) { - $representative_infos = $infos_of_images[$album->getRepresentativePictureId()]; - } - $userCacheAlbum = $album->getUserCacheAlbum(); + $representative_infos = $infos_of_images[$album->getRepresentativePictureId()]; + $tpl_var = array_merge( $album->toArray(), [ diff --git a/src/DataMapper/AlbumMapper.php b/src/DataMapper/AlbumMapper.php index 863a2d7ca..810a72319 100644 --- a/src/DataMapper/AlbumMapper.php +++ b/src/DataMapper/AlbumMapper.php @@ -17,6 +17,7 @@ use App\Entity\Album; use App\Entity\ImageAlbum; use App\Entity\User; +use App\Enum\UserPrivacyLevelType; use App\Repository\AlbumRepository; use App\Repository\ImageAlbumRepository; use App\Repository\ImageRepository; @@ -146,7 +147,7 @@ protected function getAlbumsMenu(User $user, array $selected_album = []): array * * @return array> */ - public function getComputedAlbums(int $level, array $forbidden_categories = []): array + public function getComputedAlbums(UserPrivacyLevelType $level, array $forbidden_categories = []): array { $albums = []; $last_photo_date = null; @@ -1125,7 +1126,7 @@ public function getInfosOfImages(User $user, array $albums, array $image_ids, Im $bad_level_ids = []; foreach ($imageMapper->getRepository()->findBy(['id' => $image_ids]) as $image) { - if ($image->getLevel() <= $user->getUserInfos()->getLevel()) { + if ($image->getLevel()->value <= $user->getUserInfos()->getLevel()->value) { $infos_of_images[$image->getId()] = [$image->toArray(), 'image' => $image]; } else { $bad_level_ids[] = $image->getId(); diff --git a/src/Entity/Image.php b/src/Entity/Image.php index 732e1b7ea..cadc0575d 100644 --- a/src/Entity/Image.php +++ b/src/Entity/Image.php @@ -11,6 +11,7 @@ namespace App\Entity; +use App\Enum\UserPrivacyLevelType; use Doctrine\DBAL\Types\Types; use App\Repository\ImageRepository; use DateTimeInterface; @@ -75,8 +76,8 @@ class Image #[ORM\Column(type: Types::INTEGER, nullable: true)] private ?int $storage_category_id = null; - #[ORM\Column(type: Types::INTEGER, nullable: true)] - private ?int $level = 0; + #[ORM\Column(type: Types::INTEGER, nullable: true, enumType: UserPrivacyLevelType::class)] + private ?UserPrivacyLevelType $level = UserPrivacyLevelType::DEFAULT; #[ORM\Column(type: Types::STRING, length: 32, nullable: true)] private ?string $md5sum = null; @@ -325,12 +326,12 @@ public function setStorageCategoryId(?int $storage_category_id): self return $this; } - public function getLevel(): ?int + public function getLevel(): UserPrivacyLevelType { return $this->level; } - public function setLevel(int $level): self + public function setLevel(UserPrivacyLevelType $level): self { $this->level = $level; diff --git a/src/Entity/UserInfos.php b/src/Entity/UserInfos.php index 1ad12b682..5797cd399 100644 --- a/src/Entity/UserInfos.php +++ b/src/Entity/UserInfos.php @@ -11,6 +11,7 @@ namespace App\Entity; +use App\Enum\UserPrivacyLevelType; use App\Enum\UserStatusType; use Doctrine\DBAL\Types\Types; use DateTimeInterface; @@ -20,14 +21,13 @@ /** * * @phpstan-type UserInfosArray array{nb_image_page: int, language: ?string, expand: bool, show_nb_comments: bool, show_nb_hits: bool, - * recent_period: int, theme: ?string, enabled_high: bool, level: int} + * recent_period: int, theme: ?string, enabled_high: bool, level: UserPrivacyLevelType} */ #[ORM\Table(name: 'user_infos')] #[ORM\Entity(repositoryClass: UserInfosRepository::class)] class UserInfos { final public const DEFAULT_NB_IMAGE_PAGE = 15; - final public const DEFAULT_LEVEL = 0; final public const DEFAULT_RECENT_PERIOD = 7; final public const DEFAULT_SHOW_NB_COMMENTS = false; final public const DEFAULT_SHOW_NB_HITS = false; @@ -65,8 +65,8 @@ class UserInfos #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)] private ?DateTimeInterface $registration_date = null; - #[ORM\Column(type: Types::INTEGER, nullable: true)] - private ?int $level = self::DEFAULT_LEVEL; + #[ORM\Column(type: Types::INTEGER, nullable: true, enumType: UserPrivacyLevelType::class)] + private ?UserPrivacyLevelType $level = UserPrivacyLevelType::DEFAULT; #[ORM\Column(type: Types::INTEGER)] private int $recent_period = self::DEFAULT_RECENT_PERIOD; @@ -169,12 +169,12 @@ public function setRegistrationDate(?DateTimeInterface $registration_date): self return $this; } - public function getLevel(): int + public function getLevel(): UserPrivacyLevelType { - return $this->level ?? self::DEFAULT_LEVEL; + return $this->level; } - public function setLevel(int $level = self::DEFAULT_LEVEL): self + public function setLevel(UserPrivacyLevelType $level = UserPrivacyLevelType::DEFAULT): self { $this->level = $level; diff --git a/src/Enum/UserPrivacyLevelType.php b/src/Enum/UserPrivacyLevelType.php new file mode 100644 index 000000000..b0be59af6 --- /dev/null +++ b/src/Enum/UserPrivacyLevelType.php @@ -0,0 +1,29 @@ +trans(sprintf('Level %d', $this->value), locale: $locale); + } +} diff --git a/src/Form/Model/UserInfosModel.php b/src/Form/Model/UserInfosModel.php index e67e73145..d8b18a654 100644 --- a/src/Form/Model/UserInfosModel.php +++ b/src/Form/Model/UserInfosModel.php @@ -13,6 +13,7 @@ use App\Entity\Language; use App\Entity\Theme; +use App\Enum\UserPrivacyLevelType; use App\Enum\UserStatusType; class UserInfosModel @@ -23,7 +24,7 @@ class UserInfosModel private ?Language $language = null; private ?Theme $theme = null; private UserStatusType $status; - private int $level = 0; + private UserPrivacyLevelType $level = UserPrivacyLevelType::DEFAULT; private ?bool $show_nb_comments = null; private ?bool $show_nb_hits = null; private ?bool $expand = null; @@ -100,14 +101,14 @@ public function getStatus(): UserStatusType return $this->status; } - public function setLevel(int $Level): self + public function setLevel(UserPrivacyLevelType $Level): self { $this->level = $Level; return $this; } - public function getLevel(): int + public function getLevel(): UserPrivacyLevelType { return $this->level; } diff --git a/src/Form/UserInfosType.php b/src/Form/UserInfosType.php index 11823bacd..23dbda4c1 100644 --- a/src/Form/UserInfosType.php +++ b/src/Form/UserInfosType.php @@ -13,13 +13,13 @@ use App\Entity\Language; use App\Entity\Theme; +use App\Enum\UserPrivacyLevelType; use App\Enum\UserStatusType; use App\Form\Model\UserInfosModel; use App\Form\Transformer\UserToUserInfosTransformer; use App\Repository\LanguageRepository; use App\Repository\ThemeRepository; use App\Repository\UserRepository; -use Phyxo\Conf; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -29,7 +29,6 @@ use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Contracts\Translation\TranslatorInterface; class UserInfosType extends AbstractType { @@ -42,8 +41,6 @@ public function __construct( private readonly LanguageRepository $languageRepository, private readonly ThemeRepository $themeRepository, private readonly UserRepository $userRepository, - private readonly TranslatorInterface $translator, - private Conf $conf, ) { } @@ -86,13 +83,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void if ($options[self::IN_ADMIN_OPTION]) { $fields->add('status', EnumType::class, ['label' => 'Status', 'class' => UserStatusType::class, 'expanded' => false]); - - $levels = []; - foreach ($this->conf['available_permission_levels'] as $level) { - $levels[$level] = $this->translator->trans(sprintf('Level %d', $level)); - } - - $fields->add('level', ChoiceType::class, ['label' => 'Privacy level', 'choices' => array_flip($levels), 'expanded' => false]); + $fields->add('level', EnumType::class, ['label' => 'Privacy level', 'class' => UserPrivacyLevelType::class, 'expanded' => false]); } $fields->add( diff --git a/src/Repository/AlbumRepository.php b/src/Repository/AlbumRepository.php index de0aa4b1b..4a2e15970 100644 --- a/src/Repository/AlbumRepository.php +++ b/src/Repository/AlbumRepository.php @@ -13,6 +13,7 @@ use Doctrine\ORM\Query\Expr\Join; use App\Entity\Album; +use App\Enum\UserPrivacyLevelType; use DateTimeInterface; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\QueryBuilder; @@ -362,7 +363,7 @@ public function findPrivateWithGroupAccess(int $group_id) * * @return array */ - public function getComputedAlbums(int $level, array $forbidden_albums = []) + public function getComputedAlbums(UserPrivacyLevelType $level, array $forbidden_albums = []) { $qb = $this->createQueryBuilder('a'); $qb->select('a.id AS album_id, IDENTITY(a.parent) AS id_uppercat, MAX(i.date_available) as date_last, COUNT(i.id) AS nb_images'); diff --git a/src/Repository/ImageRepository.php b/src/Repository/ImageRepository.php index 21c922b26..1683b6955 100644 --- a/src/Repository/ImageRepository.php +++ b/src/Repository/ImageRepository.php @@ -16,6 +16,7 @@ use DateInterval; use App\Entity\Album; use App\Entity\Image; +use App\Enum\UserPrivacyLevelType; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\Query\ResultSetMappingBuilder; use Doctrine\Persistence\ManagerRegistry; @@ -66,7 +67,7 @@ public function updateFieldForImages(array $ids, string $field, string|DateTimeI $qb->getQuery()->getResult(); } - public function updateLevel(int $image_id, int $level = 0): void + public function updateLevel(int $image_id, UserPrivacyLevelType $level = UserPrivacyLevelType::DEFAULT): void { $qb = $this->createQueryBuilder('i'); $qb->update(); @@ -114,7 +115,7 @@ public function findWithNoStorageOrStorageForAlbums(array $album_ids = []) * * @return Image[] */ - public function getForbiddenImages(array $forbidden_albums = [], int $level = 0) + public function getForbiddenImages(array $forbidden_albums = [], UserPrivacyLevelType $level = UserPrivacyLevelType::DEFAULT) { $qb = $this->createQueryBuilder('i'); $qb->leftJoin('i.imageAlbums', 'ia'); @@ -962,7 +963,7 @@ public function findDuplicates(array $fields) /** * @return Image[] */ - public function filterByLevel(int $level, string $operator = '=') + public function filterByLevel(UserPrivacyLevelType $level, string $operator = '=') { $qb = $this->createQueryBuilder('i'); $qb->where('i.level ' . $operator . ' :level'); diff --git a/src/Utils/UserManager.php b/src/Utils/UserManager.php index 8fc8d2cde..3b28053b2 100644 --- a/src/Utils/UserManager.php +++ b/src/Utils/UserManager.php @@ -16,6 +16,7 @@ use App\Repository\GroupRepository; use App\Entity\User; use App\Entity\UserInfos; +use App\Enum\UserPrivacyLevelType; use App\Enum\UserStatusType; use App\Repository\UserInfosRepository; @@ -45,7 +46,7 @@ public function register(User $user): User $userInfos->setRegistrationDate(new DateTime()); $userInfos->setLastModified(new DateTime()); if (in_array('ROLE_WEBMASTER', $user->getRoles())) { - $userInfos->setLevel(10); // @FIX: find a way to only inject that param instead of conf ; max($this->conf['available_permission_levels']); + $userInfos->setLevel(UserPrivacyLevelType::ADMINS); } $userInfos->setStatus($user->getStatusFromRoles()); $user->setUserInfos($userInfos); diff --git a/tests/DataMapper/AlbumMapperTest.php b/tests/DataMapper/AlbumMapperTest.php index 89e39158d..aee81efc4 100644 --- a/tests/DataMapper/AlbumMapperTest.php +++ b/tests/DataMapper/AlbumMapperTest.php @@ -12,6 +12,7 @@ namespace App\Tests\DataMapper; use App\DataMapper\AlbumMapper; +use App\Enum\UserPrivacyLevelType; use App\Repository\AlbumRepository; use App\Repository\ImageAlbumRepository; use App\Repository\ImageRepository; @@ -75,11 +76,10 @@ public function testComputedAlbum(): void ], ]; - $albumRepository = $this->prophesize(AlbumRepository::class); $albumRepository->getComputedAlbums(Argument::any(), Argument::type('array'))->willReturn($albums); - $level = 0; + $level = UserPrivacyLevelType::DEFAULT; $forbidden_albums = []; $albumMapper = new AlbumMapper( $this->prophesize(Conf::class)->reveal(), @@ -165,7 +165,6 @@ public function testComputedAlbum(): void ], ]; - $computedAlbums = $albumMapper->getComputedAlbums($level, $forbidden_albums); $this->assertEquals($computedAlbums, $expectedComputedAlbums); diff --git a/themes/treflez/template/_albums.html.twig b/themes/treflez/template/_albums.html.twig index afbeaf3c4..5a84c085d 100644 --- a/themes/treflez/template/_albums.html.twig +++ b/themes/treflez/template/_albums.html.twig @@ -11,7 +11,6 @@ {% if theme_config.category_wells == 'never' %} {% set album_derivative = derivative_from_image(image: cat.representative.image, params: album_derivative_params) %} - {# this needs a fixed size else it messes up the grid on tablets #}
diff --git a/themes/treflez/template/_picture_info_cards.html.twig b/themes/treflez/template/_picture_info_cards.html.twig index 6d8cd4533..30c91c3b6 100644 --- a/themes/treflez/template/_picture_info_cards.html.twig +++ b/themes/treflez/template/_picture_info_cards.html.twig @@ -145,7 +145,7 @@