Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
FilesystemProfileRegistry
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
4 / 4
9
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
3
 has
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 all
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\Profile\Infrastructure\Repository;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Core\Profile\Domain\Model\Profile;
12use App\Core\Profile\Domain\Repository\ProfileRegistryInterface;
13
14/**
15 * Filesystem Profile Registry.
16 *
17 * Discovers and builds profile metadata from the root `profiles/` directory structure.
18 *
19 * @package App\Core\Profile\Infrastructure\Repository
20 */
21final readonly class FilesystemProfileRegistry implements ProfileRegistryInterface
22{
23    /**
24     * FilesystemProfileRegistry constructor.
25     *
26     * @param string $appBasePath Absolute path to application root directory.
27     */
28    public function __construct(
29        private string $appBasePath
30    ) {
31    }
32
33    public function get(string $name): ?Profile
34    {
35        $sanitized = preg_replace('/[^a-zA-Z0-9_-]/', '', $name);
36        if ($sanitized === '') {
37            return null;
38        }
39
40        $profileDir = $this->appBasePath . '/profiles/' . $sanitized;
41        if (!is_dir($profileDir)) {
42            return null;
43        }
44
45        $label = ucfirst($sanitized);
46        return new Profile(
47            name: $sanitized,
48            label: $label,
49            basePath: $profileDir,
50            sqlPath: $profileDir . '/sql',
51            configPath: $profileDir . '/config',
52            viewsPath: $profileDir . '/resources/views',
53            srcPath: $profileDir . '/src'
54        );
55    }
56
57    public function has(string $name): bool
58    {
59        return $this->get($name) !== null;
60    }
61
62    /**
63     * @return array<string, Profile>
64     */
65    public function all(): array
66    {
67        $profilesDir = $this->appBasePath . '/profiles';
68        if (!is_dir($profilesDir)) {
69            return [];
70        }
71
72        $dirs = \Yiisoft\Files\FileHelper::findDirectories($profilesDir, ['recursive' => false]);
73        $profiles = [];
74        foreach ($dirs as $dirPath) {
75            $entry = basename($dirPath);
76            $profile = $this->get($entry);
77            if ($profile !== null) {
78                $profiles[$entry] = $profile;
79            }
80        }
81
82        return $profiles;
83    }
84}