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

ICanBoogie / Module / 4270677071

pending completion
4270677071

push

github

Olivier Laviale
Tidy

2 of 2 new or added lines in 2 files covered. (100.0%)

73 of 415 relevant lines covered (17.59%)

0.68 hits per line

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

38.71
/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 || in_array($module_id, $descriptor->required)) {
×
87
                $users[$user_id] = $descriptor;
×
88
            }
89
        }
90

91
        return $users;
×
92
    }
93

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

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

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

119
        return false;
×
120
    }
121

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

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

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

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

152
        return false;
6✔
153
    }
154
}
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