Skip to content

Commit 4b8a619

Browse files
committed
ISSUE-345: admin attribute
1 parent 8c73e39 commit 4b8a619

14 files changed

+1035
-12
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Identity\Exception;
6+
7+
use RuntimeException;
8+
9+
class AdminAttributeCreationException extends RuntimeException
10+
{
11+
private int $statusCode;
12+
13+
public function __construct(string $message, int $statusCode)
14+
{
15+
parent::__construct($message);
16+
$this->statusCode = $statusCode;
17+
}
18+
19+
public function getStatusCode(): int
20+
{
21+
return $this->statusCode;
22+
}
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Identity\Exception;
6+
7+
use RuntimeException;
8+
9+
class AttributeDefinitionCreationException extends RuntimeException
10+
{
11+
private int $statusCode;
12+
13+
public function __construct(string $message, int $statusCode)
14+
{
15+
parent::__construct($message);
16+
$this->statusCode = $statusCode;
17+
}
18+
19+
public function getStatusCode(): int
20+
{
21+
return $this->statusCode;
22+
}
23+
}

src/Domain/Identity/Model/AdminAttributeValue.php

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,36 @@
1414
class AdminAttributeValue implements DomainModel
1515
{
1616
#[ORM\Id]
17-
#[ORM\Column(name: 'adminattributeid', type: 'integer', options: ['unsigned' => true])]
18-
private int $adminAttributeId;
17+
#[ORM\ManyToOne(targetEntity: AdminAttributeDefinition::class)]
18+
#[ORM\JoinColumn(name: 'adminattributeid', referencedColumnName: 'id', nullable: false)]
19+
private AdminAttributeDefinition $attributeDefinition;
1920

2021
#[ORM\Id]
21-
#[ORM\Column(name: 'adminid', type: 'integer', options: ['unsigned' => true])]
22-
private int $adminId;
22+
#[ORM\ManyToOne(targetEntity: Administrator::class)]
23+
#[ORM\JoinColumn(name: 'adminid', referencedColumnName: 'id', nullable: false)]
24+
private Administrator $administrator;
2325

2426
#[ORM\Column(name: 'value', type: 'string', length: 255, nullable: true)]
2527
private ?string $value;
2628

27-
public function __construct(int $adminAttributeId, int $adminId, ?string $value = null)
28-
{
29-
$this->adminAttributeId = $adminAttributeId;
30-
$this->adminId = $adminId;
29+
public function __construct(
30+
AdminAttributeDefinition $attributeDefinition,
31+
Administrator $administrator,
32+
?string $value = null
33+
) {
34+
$this->attributeDefinition = $attributeDefinition;
35+
$this->administrator = $administrator;
3136
$this->value = $value;
3237
}
3338

34-
public function getAdminAttributeId(): int
39+
public function getAttributeDefinition(): AdminAttributeDefinition
3540
{
36-
return $this->adminAttributeId;
41+
return $this->attributeDefinition;
3742
}
3843

39-
public function getAdminId(): int
44+
public function getAdministrator(): Administrator
4045
{
41-
return $this->adminId;
46+
return $this->administrator;
4247
}
4348

4449
public function getValue(): ?string
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Identity\Model\Dto;
6+
7+
class AdminAttributeDefinitionDto
8+
{
9+
/**
10+
* @SuppressWarnings("BooleanArgumentFlag")
11+
*/
12+
public function __construct(
13+
public readonly string $name,
14+
public readonly ?string $type = null,
15+
public readonly ?int $listOrder = null,
16+
public readonly ?string $defaultValue = null,
17+
public readonly ?bool $required = false,
18+
public readonly ?string $tableName = null,
19+
) {
20+
}
21+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Identity\Model\Filter;
6+
7+
use PhpList\Core\Domain\Common\Model\Filter\FilterRequestInterface;
8+
9+
class AdminAttributeValueFilter implements FilterRequestInterface
10+
{
11+
private ?int $adminId = null;
12+
13+
public function setAdminId(?int $adminId): self
14+
{
15+
$this->adminId = $adminId;
16+
return $this;
17+
}
18+
19+
public function getAdminId(): ?int
20+
{
21+
return $this->adminId;
22+
}
23+
}

src/Domain/Identity/Repository/AdminAttributeDefinitionRepository.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,14 @@
77
use PhpList\Core\Domain\Common\Repository\AbstractRepository;
88
use PhpList\Core\Domain\Common\Repository\CursorPaginationTrait;
99
use PhpList\Core\Domain\Common\Repository\Interfaces\PaginatableRepositoryInterface;
10+
use PhpList\Core\Domain\Identity\Model\AdminAttributeDefinition;
1011

1112
class AdminAttributeDefinitionRepository extends AbstractRepository implements PaginatableRepositoryInterface
1213
{
1314
use CursorPaginationTrait;
15+
16+
public function findOneByName(string $name): ?AdminAttributeDefinition
17+
{
18+
return $this->findOneBy(['name' => $name]);
19+
}
1420
}

src/Domain/Identity/Repository/AdminAttributeValueRepository.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,20 @@
55
namespace PhpList\Core\Domain\Identity\Repository;
66

77
use PhpList\Core\Domain\Common\Repository\AbstractRepository;
8+
use PhpList\Core\Domain\Identity\Model\AdminAttributeValue;
89

910
class AdminAttributeValueRepository extends AbstractRepository
1011
{
12+
public function findOneByAdminIdAndAttributeId(int $adminId, int $definitionId): ?AdminAttributeValue
13+
{
14+
return $this->createQueryBuilder('aav')
15+
->join('aav.administrator', 'admin')
16+
->join('aav.attributeDefinition', 'attr')
17+
->where('admin.id = :adminId')
18+
->andWhere('attr.id = :attributeId')
19+
->setParameter('adminId', $adminId)
20+
->setParameter('attributeId', $definitionId)
21+
->getQuery()
22+
->getOneOrNullResult();
23+
}
1124
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Identity\Service;
6+
7+
use PhpList\Core\Domain\Identity\Model\AdminAttributeDefinition;
8+
use PhpList\Core\Domain\Identity\Model\Dto\AdminAttributeDefinitionDto;
9+
use PhpList\Core\Domain\Identity\Repository\AdminAttributeDefinitionRepository;
10+
use PhpList\Core\Domain\Identity\Exception\AttributeDefinitionCreationException;
11+
12+
class AdminAttributeDefinitionManager
13+
{
14+
private AdminAttributeDefinitionRepository $definitionRepository;
15+
16+
public function __construct(AdminAttributeDefinitionRepository $definitionRepository)
17+
{
18+
$this->definitionRepository = $definitionRepository;
19+
}
20+
21+
public function create(AdminAttributeDefinitionDto $attributeDefinitionDto): AdminAttributeDefinition
22+
{
23+
$existingAttribute = $this->definitionRepository->findOneByName($attributeDefinitionDto->name);
24+
if ($existingAttribute) {
25+
throw new AttributeDefinitionCreationException('Attribute definition already exists', 409);
26+
}
27+
28+
$attributeDefinition = (new AdminAttributeDefinition($attributeDefinitionDto->name))
29+
->setType($attributeDefinitionDto->type)
30+
->setListOrder($attributeDefinitionDto->listOrder)
31+
->setRequired($attributeDefinitionDto->required)
32+
->setDefaultValue($attributeDefinitionDto->defaultValue)
33+
->setTableName($attributeDefinitionDto->tableName);
34+
35+
$this->definitionRepository->save($attributeDefinition);
36+
37+
return $attributeDefinition;
38+
}
39+
40+
public function update(
41+
AdminAttributeDefinition $attributeDefinition,
42+
AdminAttributeDefinitionDto $attributeDefinitionDto
43+
): AdminAttributeDefinition {
44+
$existingAttribute = $this->definitionRepository->findOneByName($attributeDefinitionDto->name);
45+
if ($existingAttribute && $existingAttribute->getId() !== $attributeDefinition->getId()) {
46+
throw new AttributeDefinitionCreationException('Another attribute with this name already exists.', 409);
47+
}
48+
49+
$attributeDefinition
50+
->setName($attributeDefinitionDto->name)
51+
->setType($attributeDefinitionDto->type)
52+
->setListOrder($attributeDefinitionDto->listOrder)
53+
->setRequired($attributeDefinitionDto->required)
54+
->setDefaultValue($attributeDefinitionDto->defaultValue)
55+
->setTableName($attributeDefinitionDto->tableName);
56+
57+
$this->definitionRepository->save($attributeDefinition);
58+
59+
return $attributeDefinition;
60+
}
61+
62+
public function delete(AdminAttributeDefinition $attributeDefinition): void
63+
{
64+
$this->definitionRepository->remove($attributeDefinition);
65+
}
66+
67+
public function getTotalCount(): int
68+
{
69+
return $this->definitionRepository->count();
70+
}
71+
72+
public function getAttributesAfterId(int $afterId, int $limit): array
73+
{
74+
return $this->definitionRepository->getAfterId($afterId, $limit);
75+
}
76+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Identity\Service;
6+
7+
use PhpList\Core\Domain\Identity\Model\AdminAttributeDefinition;
8+
use PhpList\Core\Domain\Identity\Model\AdminAttributeValue;
9+
use PhpList\Core\Domain\Identity\Model\Administrator;
10+
use PhpList\Core\Domain\Identity\Repository\AdminAttributeValueRepository;
11+
use PhpList\Core\Domain\Identity\Exception\AdminAttributeCreationException;
12+
13+
class AdminAttributeManager
14+
{
15+
private AdminAttributeValueRepository $attributeRepository;
16+
17+
public function __construct(AdminAttributeValueRepository $attributeRepository)
18+
{
19+
$this->attributeRepository = $attributeRepository;
20+
}
21+
22+
public function createOrUpdate(
23+
Administrator $admin,
24+
AdminAttributeDefinition $definition,
25+
?string $value = null
26+
): AdminAttributeValue {
27+
$adminAttribute = $this->attributeRepository->findOneByAdminIdAndAttributeId(
28+
adminId: $admin->getId(),
29+
definitionId: $definition->getId()
30+
);
31+
32+
if (!$adminAttribute) {
33+
$adminAttribute = new AdminAttributeValue(attributeDefinition: $definition, administrator: $admin);
34+
}
35+
36+
$value = $value ?? $definition->getDefaultValue();
37+
if ($value === null) {
38+
throw new AdminAttributeCreationException('Value is required', 400);
39+
}
40+
41+
$adminAttribute->setValue($value);
42+
$this->attributeRepository->save($adminAttribute);
43+
44+
return $adminAttribute;
45+
}
46+
47+
public function getAdminAttribute(int $adminId, int $attributeDefinitionId): ?AdminAttributeValue
48+
{
49+
return $this->attributeRepository->findOneByAdminIdAndAttributeId(
50+
adminId: $adminId,
51+
definitionId: $attributeDefinitionId
52+
);
53+
}
54+
55+
public function delete(AdminAttributeValue $attribute): void
56+
{
57+
$this->attributeRepository->remove($attribute);
58+
}
59+
}

0 commit comments

Comments
 (0)