Skip to content

Commit 5475e2c

Browse files
committed
Fix namespace extraction in ClassesInDirectories
- Fix extractNamespace() to properly skip non-T_NAMESPACE tokens - Handle both T_NAME_QUALIFIED and T_STRING tokens for namespace parsing - Filter ClassesInDirectories::list() to return only interfaces - Update README and demo to use MediaQuerySqlModule The bug was that extractNamespace() was processing non-array tokens like '(' from declare(strict_types=1), causing it to extract 'strict_types' instead of the actual namespace. Fixed by changing the condition to explicitly require T_NAMESPACE tokens.
1 parent f7dfff9 commit 5475e2c

File tree

3 files changed

+49
-22
lines changed

3 files changed

+49
-22
lines changed

README.md

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,23 +49,36 @@ MediaQueryModule binds the execution of SQL to an interface by setting `DbQueryC
4949

5050
```php
5151
use Ray\AuraSqlModule\AuraSqlModule;
52-
use Ray\MediaQuery\DbQueryConfig;
53-
use Ray\MediaQuery\MediaQueryModule;
54-
use Ray\MediaQuery\Queries;
52+
use Ray\MediaQuery\MediaQuerySqlModule;
5553

5654
protected function configure(): void
5755
{
58-
$this->install(
59-
new MediaQueryModule(
60-
Queries::fromDir('/path/to/queryInterface'),
61-
new DbQueryConfig('/path/to/sql')
62-
),
63-
);
56+
$this->install(new MediaQuerySqlModule(
57+
interfaceDir: '/path/to/queryInterface',
58+
sqlDir: '/path/to/sql'
59+
));
6460
$this->install(new AuraSqlModule('mysql:host=localhost;dbname=test', 'username', 'password'));
6561
}
6662
```
6763

68-
Note: MediaQueryModule requires AuraSqlModule to be installed.
64+
Note: MediaQuerySqlModule requires AuraSqlModule to be installed.
65+
66+
For advanced use cases requiring explicit query class selection, create a custom module:
67+
68+
```php
69+
use Ray\MediaQuery\MediaQueryBaseModule;
70+
use Ray\MediaQuery\MediaQueryDbModule;
71+
use Ray\MediaQuery\DbQueryConfig;
72+
use Ray\MediaQuery\Queries;
73+
74+
class MyQueryModule extends AbstractModule {
75+
protected function configure(): void {
76+
$queries = Queries::fromClasses([UserInterface::class, OrderInterface::class]);
77+
$this->install(new MediaQueryBaseModule($queries));
78+
$this->install(new MediaQueryDbModule(new DbQueryConfig('/path/to/sql')));
79+
}
80+
}
81+
```
6982

7083
### Request object injection
7184

demo/run.php

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,22 @@
1111
use Ray\AuraSqlModule\AuraSqlModule;
1212
use Ray\Di\AbstractModule;
1313
use Ray\Di\Injector;
14-
use Ray\MediaQuery\DbQueryConfig;
15-
use Ray\MediaQuery\MediaQueryModule;
16-
use Ray\MediaQuery\Queries;
14+
use Ray\MediaQuery\MediaQuerySqlModule;
1715

1816
$sqlDir = __DIR__ . '/sql';
17+
$interfaceDir = __DIR__ . '/src';
1918
$dsn = 'sqlite::memory:';
20-
$injector = new Injector(new class($sqlDir, $dsn) extends AbstractModule {
19+
$injector = new Injector(new class($interfaceDir, $sqlDir, $dsn) extends AbstractModule {
2120

2221
public function __construct(
22+
private string $interfaceDir,
2323
private string $sqlDir,
2424
private string $dsn
2525
){}
2626

2727
protected function configure()
2828
{
29-
$queries = Queries::fromClasses([
30-
UserAddInterface::class,
31-
UserItemInterface::class
32-
]);
33-
$this->install(new MediaQueryModule($queries, [new DbQueryConfig($this->sqlDir)]));
29+
$this->install(new MediaQuerySqlModule($this->interfaceDir, $this->sqlDir));
3430
$this->install(new AuraSqlModule($this->dsn));
3531
}
3632
});

src/ClassesInDirectories.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use RecursiveIteratorIterator;
1010
use SplFileInfo;
1111

12-
use function class_exists;
1312
use function count;
1413
use function file_get_contents;
1514
use function interface_exists;
@@ -44,7 +43,7 @@ public static function list(string ...$directories): Generator
4443

4544
$className = self::getClassFromFile($file->getRealPath());
4645

47-
if ($className === null || (! class_exists($className) && ! interface_exists($className))) {
46+
if ($className === null || ! interface_exists($className)) {
4847
continue;
4948
}
5049

@@ -82,14 +81,33 @@ private static function extractNamespace(array $tokens): string|null
8281
{
8382
/** @psalm-suppress MixedAssignment */
8483
foreach ($tokens as $index => $token) {
85-
if (is_array($token) && $token[0] !== T_NAMESPACE) {
84+
if (! is_array($token) || $token[0] !== T_NAMESPACE) {
8685
continue;
8786
}
8887

88+
$namespace = '';
8989
for ($j = $index + 1, $count = count($tokens); $j < $count; $j++) {
90+
// T_NAME_QUALIFIED for namespaces like Foo\Bar\Baz
9091
if (isset($tokens[$j][0]) && $tokens[$j][0] === T_NAME_QUALIFIED) {
9192
return $tokens[$j][1];
9293
}
94+
95+
// T_STRING for simple namespaces like Demo or parts of namespace
96+
if (is_array($tokens[$j]) && $tokens[$j][0] === T_STRING) {
97+
$namespace .= $tokens[$j][1];
98+
continue;
99+
}
100+
101+
// Handle namespace separator
102+
if ($tokens[$j] === '\\') {
103+
$namespace .= '\\';
104+
continue;
105+
}
106+
107+
// Stop at semicolon or opening brace
108+
if ($tokens[$j] === ';' || $tokens[$j] === '{') {
109+
return $namespace !== '' ? $namespace : null;
110+
}
93111
}
94112
}
95113

0 commit comments

Comments
 (0)