Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
7.69% covered (danger)
7.69%
4 / 52
20.00% covered (danger)
20.00%
2 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
StatusAbstract
7.69% covered (danger)
7.69%
4 / 52
20.00% covered (danger)
20.00%
2 / 10
1113.76
0.00% covered (danger)
0.00%
0 / 1
 activate
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 activateRoutes
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 installRoutesHooks
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
30
 activateHooks
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 activateRoutesHooks
15.38% covered (danger)
15.38%
2 / 13
0.00% covered (danger)
0.00%
0 / 1
84.30
 deactivate
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 deactivateRoutes
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 deactivateRoutesHooks
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
132
 uninstallRoutesHooks
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 deactivateHooks
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS\Module
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace phpOMS\Module;
16
17use phpOMS\Application\ApplicationAbstract;
18use phpOMS\Application\ApplicationInfo;
19use phpOMS\System\File\Local\Directory;
20use phpOMS\System\File\Local\File;
21use phpOMS\System\File\PathException;
22use phpOMS\System\File\PermissionException;
23use phpOMS\Utils\ArrayUtils;
24use phpOMS\Utils\Parser\Php\ArrayParser;
25
26/**
27 * Status abstract class.
28 *
29 * This abstraction can be used by modules in order to manipulate their basic status/state.
30 *
31 * @package phpOMS\Module
32 * @license OMS License 2.0
33 * @link    https://jingga.app
34 * @since   1.0.0
35 */
36abstract class StatusAbstract
37{
38    /**
39     * Path of the file
40     *
41     * @var string
42     * @since 1.0.0
43     */
44    public const PATH = '';
45
46    /**
47     * Deactivate module.
48     *
49     * @param ApplicationAbstract $app  Application
50     * @param ModuleInfo          $info Module info
51     *
52     * @return void
53     *
54     * @since 1.0.0
55     */
56    public static function activate(ApplicationAbstract $app, ModuleInfo $info) : void
57    {
58        self::activateRoutes($info);
59        self::activateHooks($info);
60    }
61
62    /**
63     * Init routes.
64     *
65     * @param ModuleInfo           $info    Module info
66     * @param null|ApplicationInfo $appInfo Application info
67     *
68     * @return void
69     *
70     * @since 1.0.0
71     */
72    public static function activateRoutes(ModuleInfo $info, ApplicationInfo $appInfo = null) : void
73    {
74        self::activateRoutesHooks($info, $appInfo, 'Routes');
75    }
76
77    /**
78     * Install routes.
79     *
80     * @param string $destRoutePath Destination route path
81     * @param string $srcRoutePath  Source route path
82     *
83     * @return void
84     *
85     * @throws PathException
86     * @throws PermissionException
87     *
88     * @since 1.0.0
89     */
90    protected static function installRoutesHooks(string $destRoutePath, string $srcRoutePath) : void
91    {
92        if (!\is_file($srcRoutePath)) {
93            return;
94        }
95
96        if (!\is_file($destRoutePath)) {
97            \file_put_contents($destRoutePath, '<?php return [];');
98        }
99
100        if (!\is_file($destRoutePath)) {
101            throw new PathException($destRoutePath); // @codeCoverageIgnore
102        }
103
104        if (!\is_writable($destRoutePath)) {
105            throw new PermissionException($destRoutePath); // @codeCoverageIgnore
106        }
107
108        /** @noinspection PhpIncludeInspection */
109        $appRoutes = include $destRoutePath;
110        /** @noinspection PhpIncludeInspection */
111        $moduleRoutes = include $srcRoutePath;
112
113        $appRoutes = \array_merge_recursive($appRoutes, $moduleRoutes);
114
115        \file_put_contents($destRoutePath, '<?php return ' . ArrayParser::serializeArray($appRoutes) . ';', \LOCK_EX);
116    }
117
118    /**
119     * Init hooks.
120     *
121     * @param ModuleInfo           $info    Module info
122     * @param null|ApplicationInfo $appInfo Application info
123     *
124     * @return void
125     *
126     * @since 1.0.0
127     */
128    public static function activateHooks(ModuleInfo $info, ApplicationInfo $appInfo = null) : void
129    {
130        self::activateRoutesHooks($info, $appInfo, 'Hooks');
131    }
132
133    /**
134     * Init routes and hooks.
135     *
136     * @param ModuleInfo           $info    Module info
137     * @param null|ApplicationInfo $appInfo Application info
138     *
139     * @return void
140     *
141     * @since 1.0.0
142     */
143    public static function activateRoutesHooks(ModuleInfo $info, ApplicationInfo $appInfo = null, string $type) : void
144    {
145        $directories = new Directory(static::PATH . '/' . $type);
146
147        /** @var Directory|File $child */
148        foreach ($directories as $child) {
149            if ($child instanceof Directory) {
150                /** @var File $file */
151                foreach ($child as $file) {
152                    if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php'))
153                        || ($appInfo !== null && \basename($file->getName(), '.php') !== $appInfo->getInternalName())
154                    ) {
155                        continue;
156                    }
157
158                    self::installRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/' . $type . '.php', $file->getPath());
159                }
160            } elseif ($child instanceof File) {
161                if (!\is_dir(__DIR__ . '/../../' . $child->getName())
162                    || ($appInfo !== null && \basename($child->getName(), '.php') !== $appInfo->getInternalName())
163                ) {
164                    continue;
165                }
166
167                self::installRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/' . $type . '.php', $child->getPath());
168            }
169        }
170    }
171
172    /**
173     * Deactivate module.
174     *
175     * @param ApplicationAbstract $app  Application
176     * @param ModuleInfo          $info Module info
177     *
178     * @return void
179     *
180     * @since 1.0.0
181     */
182    public static function deactivate(ApplicationAbstract $app, ModuleInfo $info) : void
183    {
184        self::deactivateRoutes($info);
185        self::deactivateHooks($info);
186    }
187
188    /**
189     * Deactivate routes.
190     *
191     * @param ModuleInfo           $info    Module info
192     * @param null|ApplicationInfo $appInfo Application info
193     *
194     * @return void
195     *
196     * @since 1.0.0
197     */
198    public static function deactivateRoutes(ModuleInfo $info, ApplicationInfo $appInfo = null) : void
199    {
200        self::deactivateRoutesHooks($info, $appInfo, 'Routes');
201    }
202
203    /**
204     * Deactivate routes and hooks.
205     *
206     * @param ModuleInfo           $info    Module info
207     * @param null|ApplicationInfo $appInfo Application info
208     *
209     * @return void
210     *
211     * @since 1.0.0
212     */
213    public static function deactivateRoutesHooks(ModuleInfo $info, ApplicationInfo $appInfo = null, string $type) : void
214    {
215        $directories = new Directory(static::PATH . '/'. $type);
216
217        /** @var Directory|File $child */
218        foreach ($directories as $child) {
219            if ($child instanceof Directory) {
220                /** @var File $file */
221                foreach ($child as $file) {
222                    if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php'))
223                        || ($appInfo !== null && \basename($file->getName(), '.php') !== $appInfo->getInternalName())
224                    ) {
225                        continue;
226                    }
227
228                    self::uninstallRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/'. $type . '.php', $file->getPath());
229                }
230            } elseif ($child instanceof File) {
231                if (!\is_dir(__DIR__ . '/../../' . $child->getName())
232                    || ($appInfo !== null && \basename($child->getName(), '.php') !== $appInfo->getInternalName())
233                ) {
234                    continue;
235                }
236
237                self::uninstallRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/'. $type . '.php', $child->getPath());
238            }
239        }
240    }
241
242    /**
243     * Uninstall routes.
244     *
245     * @param string $destRoutePath Destination route path
246     * @param string $srcRoutePath  Source route path
247     *
248     * @return void
249     *
250     * @throws PermissionException
251     *
252     * @since 1.0.0
253     */
254    protected static function uninstallRoutesHooks(string $destRoutePath, string $srcRoutePath) : void
255    {
256        if (!\is_file($destRoutePath)
257            || !\is_file($srcRoutePath)
258        ) {
259            return;
260        }
261
262        if (!\is_writable($destRoutePath)) {
263            throw new PermissionException($destRoutePath); // @codeCoverageIgnore
264        }
265
266        /** @noinspection PhpIncludeInspection */
267        $appRoutes = include $destRoutePath;
268        /** @noinspection PhpIncludeInspection */
269        $moduleRoutes = include $srcRoutePath;
270
271        $appRoutes = ArrayUtils::array_diff_assoc_recursive($appRoutes, $moduleRoutes);
272
273        \file_put_contents($destRoutePath, '<?php return ' . ArrayParser::serializeArray($appRoutes) . ';', \LOCK_EX);
274    }
275
276    /**
277     * Deactivate hooks.
278     *
279     * @param ModuleInfo           $info    Module info
280     * @param null|ApplicationInfo $appInfo Application info
281     *
282     * @return void
283     *
284     * @since 1.0.0
285     */
286    public static function deactivateHooks(ModuleInfo $info, ApplicationInfo $appInfo = null) : void
287    {
288        self::deactivateRoutesHooks($info, $appInfo, 'Hooks');
289    }
290}