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

tempestphp / tempest-framework / 11714560237

06 Nov 2024 06:46PM UTC coverage: 82.608% (+0.003%) from 82.605%
11714560237

push

github

web-flow
feat(container): support injecting properties using `#[Inject]` (#690)

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

95 existing lines in 9 files now uncovered.

7210 of 8728 relevant lines covered (82.61%)

49.34 hits per line

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

92.98
/src/Tempest/Core/src/Kernel/LoadDiscoveryClasses.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Tempest\Core\Kernel;
6

7
use Error;
8
use FilesystemIterator;
9
use RecursiveDirectoryIterator;
10
use RecursiveIteratorIterator;
11
use ReflectionException;
12
use SplFileInfo;
13
use Tempest\Container\Container;
14
use Tempest\Core\DiscoversPath;
15
use Tempest\Core\Discovery;
16
use Tempest\Core\DiscoveryCache;
17
use Tempest\Core\DoNotDiscover;
18
use Tempest\Core\Kernel;
19
use Tempest\Reflection\ClassReflector;
20
use Throwable;
21

22
/** @internal */
23
final readonly class LoadDiscoveryClasses
24
{
25
    public function __construct(
340✔
26
        private Kernel $kernel,
27
        private DiscoveryCache $discoveryCache,
28
        private Container $container,
29
    ) {
30
    }
340✔
31

32
    public function __invoke(): void
340✔
33
    {
34
        reset($this->kernel->discoveryClasses);
340✔
35

36
        while ($discoveryClass = current($this->kernel->discoveryClasses)) {
340✔
37
            /** @var Discovery $discovery */
38
            $discovery = $this->container->get($discoveryClass);
340✔
39

40
            try {
41
                $cachedPayload = $this->discoveryCache->get($discoveryClass);
340✔
42

43
                if ($cachedPayload) {
340✔
44
                    $discovery->restoreCachePayload($this->container, $cachedPayload);
337✔
45
                    next($this->kernel->discoveryClasses);
337✔
46

47
                    continue;
340✔
48
                }
UNCOV
49
            } catch (ReflectionException) {
×
50
                // Invalid cache
51
            }
52

53
            foreach ($this->kernel->discoveryLocations as $discoveryLocation) {
3✔
54
                $directories = new RecursiveDirectoryIterator($discoveryLocation->path, FilesystemIterator::UNIX_PATHS | FilesystemIterator::SKIP_DOTS);
3✔
55
                $files = new RecursiveIteratorIterator($directories);
3✔
56

57
                /** @var SplFileInfo $file */
58
                foreach ($files as $file) {
3✔
59
                    $fileName = $file->getFilename();
3✔
60

61
                    if ($fileName === '') {
3✔
UNCOV
62
                        continue;
×
63
                    }
64

65
                    if ($fileName === '.') {
3✔
UNCOV
66
                        continue;
×
67
                    }
68

69
                    if ($fileName === '..') {
3✔
UNCOV
70
                        continue;
×
71
                    }
72

73
                    $input = $file->getPathname();
3✔
74

75
                    if (ucfirst($fileName) === $fileName) {
3✔
76
                        // Trim ending slashing from path
77
                        $pathWithoutSlashes = rtrim($discoveryLocation->path, '\\/');
3✔
78

79
                        // Try to create a PSR-compliant class name from the path
80
                        $className = str_replace(
3✔
81
                            [
3✔
82
                                $pathWithoutSlashes,
3✔
83
                                '/',
3✔
84
                                '\\\\',
3✔
85
                                '.php',
3✔
86
                            ],
3✔
87
                            [
3✔
88
                                $discoveryLocation->namespace,
3✔
89
                                '\\',
3✔
90
                                '\\',
3✔
91
                                '',
3✔
92
                            ],
3✔
93
                            $file->getPathname(),
3✔
94
                        );
3✔
95

96
                        // Discovery errors (syntax errors, missing imports, etc.)
97
                        // are ignored when they happen in vendor files,
98
                        // but they are allowed to be thrown in project code
99
                        if ($discoveryLocation->isVendor()) {
3✔
100
                            try {
101
                                $input = new ClassReflector($className);
3✔
102
                            } catch (Throwable|Error) {
3✔
103
                            }
104
                        } elseif (class_exists($className)) {
3✔
105
                            $input = new ClassReflector($className);
3✔
106
                        }
107
                    }
108

109
                    if ($input instanceof ClassReflector) {
3✔
110
                        if ($this->shouldDiscover($discovery, $input)) {
3✔
111
                            $discovery->discover($input);
3✔
112
                        }
113
                    } elseif ($discovery instanceof DiscoversPath) {
3✔
114
                        $discovery->discoverPath($input);
3✔
115
                    }
116
                }
117
            }
118

119
            next($this->kernel->discoveryClasses);
3✔
120

121
            $this->discoveryCache->put($discoveryClass, $discovery->createCachePayload());
3✔
122
        }
123
    }
124

125
    private function shouldDiscover(Discovery $discovery, ClassReflector $input): bool
3✔
126
    {
127
        if (is_null($attribute = $input->getAttribute(DoNotDiscover::class))) {
3✔
128
            return true;
3✔
129
        }
130

131
        return in_array($discovery::class, $attribute->except, strict: true);
3✔
132
    }
133
}
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

© 2026 Coveralls, Inc