DelegateStrategy::loadAll()   D
last analyzed

Complexity

Conditions 9
Paths 16

Size

Total Lines 30
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 9

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 30
ccs 19
cts 19
cp 1
rs 4.909
cc 9
eloc 20
nc 16
nop 3
crap 9
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Caridea
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
 * use this file except in compliance with the License. You may obtain a copy of
8
 * the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
 * License for the specific language governing permissions and limitations under
16
 * the License.
17
 *
18
 * @copyright 2015-2018 LibreWorks contributors
19
 * @license   Apache-2.0
20
 */
21
namespace Caridea\Acl;
22
23
/**
24
 * Delegates ACL retrieval to Loaders.
25
 *
26
 * @copyright 2015-2018 LibreWorks contributors
27
 * @license   Apache-2.0
28
 */
29
class DelegateStrategy implements MultiStrategy
30
{
31
    /**
32
     * @var SplFixedArray<\Caridea\Acl\Loader> The loaders to consult
33
     */
34
    private $loaders;
35
36
    /**
37
     * Creates a new DelegateStrategy.
38
     *
39
     * @param \Caridea\Acl\Loader[] $loaders An array of Loaders to use
40
     * @throws \InvalidArgumentException if an entry in `loaders` isn't a `Loader`
41
     */
42 6
    public function __construct(array $loaders)
43
    {
44 6
        foreach ($loaders as $loader) {
45 5
            if (!($loader instanceof Loader)) {
46 5
                throw new \InvalidArgumentException("Only instances of Loader are permitted in the loaders argument");
47
            }
48
        }
49
        // HHVM appears to use max() inside of FixedArray which bails when empty
50 5
        $this->loaders = empty($loaders) ?
51 5
            new \SplFixedArray() : \SplFixedArray::fromArray($loaders);
52 5
    }
53
54
    /**
55
     * Loads the ACL for a Target.
56
     *
57
     * @param \Caridea\Acl\Target $target The `Target` whose ACL will be loaded
58
     * @param \Caridea\Acl\Subject[] $subjects An array of `Subject`s
59
     * @param \Caridea\Acl\Service $service The calling service (to load parent ACLs)
60
     * @return \Caridea\Acl\Acl The loaded ACL
61
     * @throws \Caridea\Acl\Exception\Unloadable If the target provided is invalid
62
     */
63 2
    public function load(Target $target, array $subjects, Service $service): Acl
64
    {
65 2
        foreach ($this->loaders as $loader) {
66 2
            if ($loader->supports($target)) {
67 2
                return $loader->load($target, $subjects, $service);
68
            }
69
        }
70 1
        return new DenyAcl($target);
71
    }
72
73
    /**
74
     * Loads the ACLs for several Targets.
75
     *
76
     * @since 2.1.0
77
     * @param \Caridea\Acl\Target[] $targets The `Target` whose ACL will be loaded
78
     * @param \Caridea\Acl\Subject[] $subjects An array of `Subject`s
79
     * @param \Caridea\Acl\Service $service The ACL service (to load parent ACLs)
80
     * @return array<string,\Caridea\Acl\Acl> The loaded ACLs
81
     * @throws \Caridea\Acl\Exception\Unloadable If the target provided is invalid
82
     * @throws \InvalidArgumentException If the `subjects` argument contains invalid values
83
     */
84 3
    public function loadAll(array $targets, array $subjects, Service $service): array
85
    {
86 3
        $byType = [];
87 3
        foreach ($targets as $target) {
88 3
            if (!($target instanceof Target)) {
89 1
                throw new \InvalidArgumentException("Only instances of Target are permitted in the targets argument");
90
            }
91 2
            $type = $target->getType();
92 2
            if (!isset($byType[$type])) {
93 2
                $byType[$type] = [];
94
            }
95 2
            $byType[$type][] = $target;
96
        }
97 2
        $acls = [];
98 2
        foreach ($byType as $type => $ttargets) {
99 2
            foreach ($this->loaders as $loader) {
100 2
                if ($loader->supports($ttargets[0])) {
101 2
                    if ($loader instanceof MultiStrategy) {
102 1
                        $acls = array_merge($acls, $loader->loadAll($ttargets, $subjects, $service));
103
                    } else {
104 1
                        foreach ($ttargets as $target) {
105 1
                            $acls[(string)$target] = $loader->load($target, $subjects, $service);
106
                        }
107
                    }
108 2
                    break;
109
                }
110
            }
111
        }
112 2
        return $acls;
113
    }
114
}
115