• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ICanBoogie / Module / 4245494566

pending completion
4245494566

push

github

Olivier Laviale
Resolve templates using Config instead of Collection

115 of 432 relevant lines covered (26.62%)

0.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

37.5
/lib/Module/ModuleCollection.php
1
<?php
2

3
/*
4
 * This file is part of the ICanBoogie package.
5
 *
6
 * (c) Olivier Laviale <olivier.laviale@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
namespace ICanBoogie\Module;
13

14
use ArrayAccess;
15
use BadMethodCallException;
16
use ICanBoogie\Binding\Module\Config;
17
use ICanBoogie\Module;
18
use IteratorAggregate;
19
use Traversable;
20

21
use function substr;
22

23
/**
24
 * @implements ArrayAccess<string, Module>
25
 * @implements IteratorAggregate<string, (callable(): Module)>
26
 */
27
class ModuleCollection implements ArrayAccess, IteratorAggregate
28
{
29
    /**
30
     * @var array<string, Descriptor>
31
     *     Where _key_ is a module identifier.
32
     */
33
    public readonly array $descriptors;
34

35
    public function __construct(
36
        private readonly Config $config,
37
        private readonly ModuleProvider $provider
38
    ) {
39
        $this->descriptors = $this->config->descriptors;
1✔
40
    }
41

42
    public function offsetExists(mixed $offset): bool
43
    {
44
        return isset($this->descriptors[$offset]);
×
45
    }
46

47
    public function offsetGet(mixed $offset): mixed
48
    {
49
        return $this->provider->module_for_id($offset);
×
50
    }
51

52
    public function offsetSet(mixed $offset, mixed $value): void
53
    {
54
        throw new BadMethodCallException();
×
55
    }
56

57
    public function offsetUnset(mixed $offset): void
58
    {
59
        throw new BadMethodCallException();
×
60
    }
61

62
    public function getIterator(): Traversable
63
    {
64
        return $this->provider->getIterator();
×
65
    }
66

67
    /**
68
     * @param (callable(Descriptor): bool) $filter
69
     *
70
     * @return array<string, Descriptor>
71
     */
72
    public function filter_descriptors(callable $filter): array
73
    {
74
        return array_filter($this->descriptors, $filter);
×
75
    }
76

77
    /**
78
     * @return array<string, Descriptor>
79
     */
80
    public function filter_descriptors_by_users(string $module_id): array
81
    {
82
        $users = [];
×
83
        $descriptors = $this->descriptors;
×
84

85
        foreach ($descriptors as $user_id => $descriptor) {
×
86
            if ($descriptor->parent == $module_id
×
87
                || in_array($module_id, $descriptor->required)) {
×
88
                $users[$user_id] = $descriptor;
×
89
            }
90
        }
91

92
        return $users;
×
93
    }
94

95
    /**
96
     * Returns the usage of a module by other modules.
97
     */
98
    public function usage(string $module_id): int
99
    {
100
        return count($this->filter_descriptors_by_users($module_id));
×
101
    }
102

103
    /**
104
     * Checks if a module inherits from another.
105
     *
106
     * @param string $module_id Module identifier.
107
     * @param string $parent_id Identifier of the parent module.
108
     */
109
    public function is_inheriting(string $module_id, string $parent_id): bool
110
    {
111
        while ($module_id) {
×
112
            if ($module_id === $parent_id) {
×
113
                return true;
×
114
            }
115

116
            $descriptor = $this->descriptors[$module_id];
×
117
            $module_id = $descriptor->parent;
×
118
        }
119

120
        return false;
×
121
    }
122

123
    /**
124
     * Resolves a class name using module inheritance.
125
     *
126
     * To resolve a given class name, the method checks in each module namespace—starting from the
127
     * specified module—if the class exists. If it does, it returns its fully qualified name.
128
     *
129
     * @param string[] $tried
130
     */
131
    public function resolve_classname(
132
        string $unqualified_classname,
133
        string $module_id,
134
        array &$tried = []
135
    ): string|false {
136
        while ($module_id) {
18✔
137
            $descriptor = $this->descriptors[$module_id];
18✔
138
            $class = $descriptor->class;
18✔
139
            $pos = strrpos($class, '\\');
18✔
140
            assert($pos !== false);
141
            $namespace = substr($class, 0, $pos);
18✔
142

143
            $fully_qualified_classname = $namespace . '\\' . $unqualified_classname;
18✔
144
            $tried[] = $fully_qualified_classname;
18✔
145

146
            if (class_exists($fully_qualified_classname)) {
18✔
147
                return $fully_qualified_classname;
12✔
148
            }
149

150
            $module_id = $descriptor->parent;
10✔
151
        }
152

153
        return false;
6✔
154
    }
155
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc