Passed
Push — main ( f153c1...dae74f )
by Thierry
04:42
created

StorageManager::make()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 9
rs 10
1
<?php
2
3
/**
4
 * StorageManager.php
5
 *
6
 * File storage manager.
7
 *
8
 * @package jaxon-storage
9
 * @author Thierry Feuzeu <[email protected]>
10
 * @copyright 2025 Thierry Feuzeu <[email protected]>
11
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
12
 * @link https://github.com/jaxon-php/jaxon-core
13
 */
14
15
namespace Jaxon\Storage;
16
17
use Jaxon\App\Config\ConfigManager;
18
use Jaxon\App\I18n\Translator;
19
use Jaxon\Exception\RequestException;
20
use League\Flysystem\Filesystem;
21
use League\Flysystem\Local\LocalFilesystemAdapter;
22
use Psr\Log\LoggerInterface;
23
use Closure;
24
25
use function is_array;
26
use function is_callable;
27
use function is_string;
28
29
class StorageManager
30
{
31
    /**
32
     * @var array<string, Closure>
33
     */
34
    protected $aAdapters = [];
35
36
    /**
37
     * The constructor
38
     *
39
     * @param ConfigManager $xConfigManager
40
     * @param Translator $xTranslator
41
     * @param LoggerInterface $logger
42
     */
43
    public function __construct(protected ConfigManager $xConfigManager,
44
        protected Translator $xTranslator, protected LoggerInterface $logger)
45
    {
46
        $this->registerDefaults();
47
    }
48
49
    /**
50
     * @param string $sAdapter
51
     * @param Closure $cFactory
52
     *
53
     * @return void
54
     */
55
    public function register(string $sAdapter, Closure $cFactory)
56
    {
57
        $this->aAdapters[$sAdapter] = $cFactory;
58
    }
59
60
    /**
61
     * Register the file storage adapters
62
     *
63
     * @return void
64
     */
65
    private function registerDefaults()
66
    {
67
        // Local file system adapter
68
        $this->register('local', function(string $sRootDir, $xOptions) {
69
            return empty($xOptions) ? new LocalFilesystemAdapter($sRootDir) :
70
                new LocalFilesystemAdapter($sRootDir, $xOptions);
71
        });
72
    }
73
74
    /**
75
     * @param string $sAdapter
76
     * @param string $sRootDir
77
     * @param array $aOptions
78
     *
79
     * @return Filesystem
80
     * @throws RequestException
81
     */
82
    public function make(string $sAdapter, string $sRootDir, array $aOptions = []): Filesystem
83
    {
84
        if(!isset($this->aAdapters[$sAdapter]) || !is_callable($this->aAdapters[$sAdapter]))
85
        {
86
            $this->logger->error("Jaxon Storage: adapter '$sAdapter' not configured.");
87
            throw new RequestException($this->xTranslator->trans('errors.storage.adapter'));
88
        }
89
90
        return new Filesystem(($this->aAdapters[$sAdapter])($sRootDir, $aOptions));
91
    }
92
93
    /**
94
     * @param string $sOptionName
95
     *
96
     * @return Filesystem
97
     * @throws RequestException
98
     */
99
    public function get(string $sOptionName): Filesystem
100
    {
101
        $sConfigKey = "storage.$sOptionName";
102
        if(!$this->xConfigManager->hasAppOption($sConfigKey))
103
        {
104
            $this->logger->error("Jaxon Storage: No '$sConfigKey' in options.");
105
            throw new RequestException($this->xTranslator->trans('errors.storage.options'));
106
        }
107
108
        $sAdapter = $this->xConfigManager->getAppOption("$sConfigKey.adapter");
109
        $sRootDir = $this->xConfigManager->getAppOption("$sConfigKey.dir");
110
        $aOptions = $this->xConfigManager->getAppOption("$sConfigKey.options", []);
111
        if(!is_string($sAdapter) || !is_string($sRootDir) || !is_array($aOptions))
112
        {
113
            $this->logger->error("Jaxon Storage: incorrect values in '$sConfigKey' options.");
114
            throw new RequestException($this->xTranslator->trans('errors.storage.options'));
115
        }
116
117
        return $this->make($sAdapter, $sRootDir, $aOptions);
118
    }
119
}
120