Passed
Push — main ( c9076e...0f9b2d )
by Iain
04:41
created

SectionManager::getByEntity()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 1
dl 0
loc 15
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Copyright Iain Cambridge 2020-2023.
7
 *
8
 * Use of this software is governed by the Business Source License included in the LICENSE file and at https://getparthenon.com/docs/next/license.
9
 *
10
 * Change Date: TBD ( 3 years after 2.2.0 release )
11
 *
12
 * On the date above, in accordance with the Business Source License, use of this software will be governed by the open source license specified in the LICENSE file.
13
 */
14
15
namespace Parthenon\Athena;
16
17
use Parthenon\Athena\Controller\AthenaControllerInterface;
18
use Parthenon\Athena\Exception\NoSectionFoundException;
19
20
final class SectionManager implements SectionManagerInterface
21
{
22
    /**
23
     * @var SectionInterface[]
24
     */
25
    private array $sections = [];
26
    /**
27
     * @var AthenaControllerInterface[]
28
     */
29
    private array $controllers = [];
30
31
    public function __construct(private AccessRightsManagerInterface $accessRightsManager)
32
    {
33
    }
34
35
    public function addSection(SectionInterface $section): self
36
    {
37
        $this->sections[] = $section;
38
39
        return $this;
40
    }
41
42
    public function addController(AthenaControllerInterface $backofficeController): self
43
    {
44
        $this->controllers[] = $backofficeController;
45
46
        return $this;
47
    }
48
49
    /**
50
     * @return SectionInterface[]
51
     */
52
    public function getSections(): array
53
    {
54
        return $this->sections;
55
    }
56
57
    /**
58
     * @return AthenaControllerInterface[]
59
     */
60
    public function getControllers(): array
61
    {
62
        return $this->controllers;
63
    }
64
65
    /**
66
     * @throws NoSectionFoundException
67
     */
68
    public function getByUrlTag(string $urlTag): SectionInterface
69
    {
70
        foreach ($this->sections as $section) {
71
            if ($section->getUrlTag() === $urlTag) {
72
                return $section;
73
            }
74
        }
75
        throw new NoSectionFoundException(sprintf("No section found for url tag '%s'", $urlTag));
76
    }
77
78
    /**
79
     * @throws NoSectionFoundException
80
     */
81
    public function getByEntity(mixed $entity): SectionInterface
82
    {
83
        if (!is_object($entity)) {
84
            throw new \InvalidArgumentException('Expected object');
85
        }
86
87
        foreach ($this->sections as $section) {
88
            $rawEntity = $section->getEntity();
89
            $rawEntityClass = get_class($rawEntity);
90
            if (is_a($entity, $rawEntityClass)) {
91
                return $section;
92
            }
93
        }
94
95
        throw new NoSectionFoundException(sprintf('No section found for entity of class "%s"', get_class($entity)));
96
    }
97
98
    public function getMenu(): array
99
    {
100
        $output = [];
101
102
        foreach ($this->sections as $section) {
103
            $urlTag = $section->getUrlTag();
104
            $sectionName = $section->getMenuSection();
105
            $menuName = $section->getMenuName();
106
107
            if (!array_key_exists($sectionName, $output)) {
108
                $output[$sectionName] = [
109
                    'items' => [],
110
                    'roles' => [],
111
                ];
112
            }
113
            $sectionRights = $this->accessRightsManager->getAccessRights($section);
114
115
            $output[$sectionName]['items'][$menuName] = [
116
                'route' => 'parthenon_athena_crud_'.$urlTag.'_list',
117
                'required_role' => $sectionRights['view'] ?? 'USER_ROLE',
118
            ];
119
            $output[$sectionName]['roles'][] = $sectionRights['view'] ?? 'USER_ROLE';
120
        }
121
122
        foreach ($this->controllers as $controller) {
123
            foreach ($controller->getMenuOptions() as $sectionName => $menuOptions) {
124
                if (!array_key_exists($sectionName, $output)) {
125
                    $output[$sectionName] = [
126
                        'items' => [],
127
                        'roles' => [],
128
                    ];
129
                }
130
131
                foreach ($menuOptions as $menuName => $info) {
132
                    $output[$sectionName]['items'][$menuName] = [
133
                        'route' => $info['route'],
134
                        'required_role' => $info['role'] ?? 'ROLE_USER',
135
                    ];
136
                    $output[$sectionName]['roles'][] = $info['role'] ?? 'ROLE_USER';
137
                }
138
            }
139
        }
140
141
        foreach ($output as $key => $item) {
142
            $output[$key]['roles'] = array_unique($item['roles']);
143
        }
144
145
        return $output;
146
    }
147
}
148