DialogManager::getLibraries()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * DialogManager.php
5
 *
6
 * Manage dialog library list and defaults.
7
 *
8
 * @author Thierry Feuzeu <[email protected]>
9
 * @copyright 2019 Thierry Feuzeu <[email protected]>
10
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
11
 * @link https://github.com/jaxon-php/jaxon-core
12
 */
13
14
namespace Jaxon\Plugin\Response\Dialog;
15
16
use Jaxon\App\Config\ConfigListenerInterface;
17
use Jaxon\App\Config\ConfigManager;
18
use Jaxon\App\I18n\Translator;
19
use Jaxon\Di\Container;
20
use Jaxon\Exception\SetupException;
21
use Jaxon\Plugin\Response\Dialog\Library\QuestionInterface;
22
use Jaxon\Plugin\Response\Dialog\Library\LibraryInterface;
23
use Jaxon\Plugin\Response\Dialog\Library\MessageInterface;
24
use Jaxon\Plugin\Response\Dialog\Library\ModalInterface;
25
use Jaxon\Utils\Config\Config;
26
27
use function array_map;
28
use function array_keys;
29
use function class_implements;
30
use function in_array;
31
use function substr;
32
33
class DialogManager implements ConfigListenerInterface
34
{
35
    /**
36
     * @var Container
37
     */
38
    private $di;
39
40
    /**
41
     * @var array
42
     */
43
    protected $aLibraries = [];
44
45
    /**
46
     * The QuestionInterface class name
47
     *
48
     * @var string
49
     */
50
    private $sQuestionLibrary = '';
51
52
    /**
53
     * The MessageInterface class name
54
     *
55
     * @var string
56
     */
57
    private $sMessageLibrary = '';
58
59
    /**
60
     * The ModalInterface class name
61
     *
62
     * @var string
63
     */
64
    private $sModalLibrary = '';
65
66
    /**
67
     * The name of the library to use for the next call.
68
     * This is used to override the default library.
69
     *
70
     * @var string
71
     */
72
    protected $sNextLibrary = '';
73
74
    /**
75
     * @var ConfigManager
76
     */
77
    protected $xConfigManager;
78
79
    /**
80
     * @var Translator
81
     */
82
    private $xTranslator;
83
84
    /**
85
     * The constructor
86
     *
87
     * @param Container $di
88
     * @param ConfigManager $xConfigManager
89
     * @param Translator $xTranslator
90
     */
91
    public function __construct(Container $di, ConfigManager $xConfigManager, Translator $xTranslator)
92
    {
93
        $this->di = $di;
94
        $this->xConfigManager = $xConfigManager;
95
        $this->xTranslator = $xTranslator;
96
    }
97
98
    /**
99
     * Register a javascript dialog library adapter.
100
     *
101
     * @param string $sClassName
102
     * @param string $sLibraryName
103
     *
104
     * @return void
105
     * @throws SetupException
106
     */
107
    public function registerLibrary(string $sClassName, string $sLibraryName)
108
    {
109
        if(isset($this->aLibraries[$sLibraryName]))
110
        {
111
            return;
112
        }
113
        if(!($aInterfaces = class_implements($sClassName)))
114
        {
115
            // The class is invalid.
116
            $sMessage = $this->xTranslator->trans('errors.register.invalid', ['name' => $sClassName]);
117
            throw new SetupException($sMessage);
118
        }
119
120
        $bIsQuestion = in_array(QuestionInterface::class, $aInterfaces);
121
        $bIsMessage = in_array(MessageInterface::class, $aInterfaces);
122
        $bIsModal = in_array(ModalInterface::class, $aInterfaces);
123
        if(!$bIsQuestion && !$bIsMessage && !$bIsModal)
124
        {
125
            // The class is invalid.
126
            $sMessage = $this->xTranslator->trans('errors.register.invalid', ['name' => $sClassName]);
127
            throw new SetupException($sMessage);
128
        }
129
130
        // Save the library
131
        $this->aLibraries[$sLibraryName] = [
132
            'question' => $bIsQuestion,
133
            'message' => $bIsMessage,
134
            'modal' => $bIsModal,
135
            'used' => false,
136
        ];
137
        // Register the library class in the container
138
        $this->di->registerDialogLibrary($sClassName, $sLibraryName);
139
    }
140
141
    /**
142
     * Set the QuestionInterface library
143
     *
144
     * @param string $sLibraryName The QuestionInterface library name
145
     *
146
     * @return void
147
     * @throws SetupException
148
     */
149
    public function setQuestionLibrary(string $sLibraryName)
150
    {
151
        if(!isset($this->aLibraries[$sLibraryName]) || !$this->aLibraries[$sLibraryName]['question'])
152
        {
153
            $sMessage = $this->xTranslator->trans('errors.dialog.library',
154
                ['type' => 'question', 'name' => $sLibraryName]);
155
            throw new SetupException($sMessage);
156
        }
157
        $this->sQuestionLibrary = $sLibraryName;
158
    }
159
160
    /**
161
     * Get the QuestionInterface library
162
     *
163
     * @return QuestionInterface
164
     */
165
    public function getQuestionLibrary(): QuestionInterface
166
    {
167
        return $this->di->getQuestionLibrary($this->sNextLibrary ?: $this->sQuestionLibrary);
168
    }
169
170
    /**
171
     * Set MessageInterface library
172
     *
173
     * @param string $sLibraryName The MessageInterface library name
174
     *
175
     * @return void
176
     * @throws SetupException
177
     */
178
    public function setMessageLibrary(string $sLibraryName)
179
    {
180
        if(!isset($this->aLibraries[$sLibraryName]) || !$this->aLibraries[$sLibraryName]['message'])
181
        {
182
            $sMessage = $this->xTranslator->trans('errors.dialog.library',
183
                ['type' => 'message', 'name' => $sLibraryName]);
184
            throw new SetupException($sMessage);
185
        }
186
        $this->sMessageLibrary = $sLibraryName;
187
    }
188
189
    /**
190
     * Get the MessageInterface library
191
     *
192
     * @return MessageInterface
193
     */
194
    public function getMessageLibrary(): MessageInterface
195
    {
196
        return $this->di->getMessageLibrary($this->sNextLibrary ?: $this->sMessageLibrary);
197
    }
198
199
    /**
200
     * Set the ModalInterface library
201
     *
202
     * @param string $sLibraryName The ModalInterface library name
203
     *
204
     * @return void
205
     * @throws SetupException
206
     */
207
    public function setModalLibrary(string $sLibraryName)
208
    {
209
        if(!isset($this->aLibraries[$sLibraryName]) || !$this->aLibraries[$sLibraryName]['modal'])
210
        {
211
            $sMessage = $this->xTranslator->trans('errors.dialog.library',
212
                ['type' => 'modal', 'name' => $sLibraryName]);
213
            throw new SetupException($sMessage);
214
        }
215
        $this->sModalLibrary = $sLibraryName;
216
    }
217
218
    /**
219
     * Get the ModalInterface library
220
     *
221
     * @return ModalInterface|null
222
     */
223
    public function getModalLibrary(): ?ModalInterface
224
    {
225
        return $this->di->getModalLibrary($this->sNextLibrary ?: $this->sModalLibrary);
226
    }
227
228
    /**
229
     * Set the name of the library to use for the next call
230
     *
231
     * @param string $sNextLibrary
232
     *
233
     * @return void
234
     */
235
    public function setNextLibrary(string $sNextLibrary): void
236
    {
237
        $this->sNextLibrary = $sNextLibrary;
238
    }
239
240
    /**
241
     * Register the javascript dialog libraries from config options.
242
     *
243
     * @return void
244
     * @throws SetupException
245
     */
246
    protected function registerLibraries()
247
    {
248
        $aLibraries = $this->xConfigManager->getOption('dialogs.lib.ext', []);
249
        foreach($aLibraries as $sLibraryName => $sClassName)
250
        {
251
            $this->registerLibrary($sClassName, $sLibraryName);
252
        }
253
    }
254
255
    /**
256
     * Set the default library for each dialog feature.
257
     *
258
     * @return void
259
     * @throws SetupException
260
     */
261
    protected function setDefaultLibraries()
262
    {
263
        // Set the default modal library
264
        if(($sLibraryName = $this->xConfigManager->getOption('dialogs.default.modal', '')))
265
        {
266
            $this->setModalLibrary($sLibraryName);
267
            $this->aLibraries[$sLibraryName]['used'] = true;
268
        }
269
        // Set the default message library
270
        if(($sLibraryName = $this->xConfigManager->getOption('dialogs.default.message', '')))
271
        {
272
            $this->setMessageLibrary($sLibraryName);
273
            $this->aLibraries[$sLibraryName]['used'] = true;
274
        }
275
        // Set the default question library
276
        if(($sLibraryName = $this->xConfigManager->getOption('dialogs.default.question', '')))
277
        {
278
            $this->setQuestionLibrary($sLibraryName);
279
            $this->aLibraries[$sLibraryName]['used'] = true;
280
        }
281
    }
282
283
    /**
284
     * Set the libraries in use.
285
     *
286
     * @return void
287
     */
288
    protected function setUsedLibraries()
289
    {
290
        // Set the other libraries in use
291
        $aLibraries = $this->xConfigManager->getOption('dialogs.lib.use', []);
292
        foreach($aLibraries as $sLibraryName)
293
        {
294
            if(isset($this->aLibraries[$sLibraryName])) // Make sure the library exists
295
            {
296
                $this->aLibraries[$sLibraryName]['used'] = true;
297
            }
298
        }
299
    }
300
301
    /**
302
     * Get the dialog libraries class instances
303
     *
304
     * @return LibraryInterface[]
305
     */
306
    public function getLibraries(): array
307
    {
308
        // Only return the libraries that are used.
309
        $aLibraries = array_filter($this->aLibraries, function($aLibrary) {
310
            return $aLibrary['used'];
311
        });
312
        return array_map(function($sLibraryName) {
313
            return $this->di->getDialogLibrary($sLibraryName);
314
        }, array_keys($aLibraries));
315
    }
316
317
    /**
318
     * @inheritDoc
319
     * @throws SetupException
320
     */
321
    public function onChange(Config $xConfig, string $sName)
322
    {
323
        if($sName === '')
324
        {
325
            // Reset the default libraries any time the config is changed.
326
            $this->registerLibraries();
327
            $this->setDefaultLibraries();
328
            $this->setUsedLibraries();
329
            return;
330
        }
331
        $sPrefix = substr($sName, 0, 15);
332
        switch($sPrefix)
333
        {
334
        case 'dialogs.default':
335
            $this->setDefaultLibraries();
336
            return;
337
        case 'dialogs.lib.ext':
338
            $this->registerLibraries();
339
            return;
340
        case 'dialogs.lib.use':
341
            $this->setUsedLibraries();
342
            return;
343
        default:
344
        }
345
    }
346
}
347