Modules.php 5.62 KB
Newer Older
1
<?php
Tino Goratsch's avatar
Tino Goratsch committed
2

3
/**
4
 * Copyright (c) by the ACP3 Developers.
Tino Goratsch's avatar
Tino Goratsch committed
5
 * See the LICENSE file at the top-level module directory for licensing details.
6 7
 */

8 9
namespace ACP3\Core;

10
use ACP3\Core\Environment\ApplicationPath;
11
use ACP3\Core\Modules\Helper\ControllerActionExists;
12
use ACP3\Core\Modules\ModuleInfoCache;
13
use ACP3\Core\Modules\Vendor;
14
use MJS\TopSort\Implementations\StringSort;
15 16 17

class Modules
{
18 19 20 21
    /**
     * @var \ACP3\Core\Environment\ApplicationPath
     */
    protected $appPath;
22 23 24 25
    /**
     * @var \ACP3\Core\Modules\Helper\ControllerActionExists
     */
    protected $controllerActionExists;
26
    /**
27
     * @var \ACP3\Core\Modules\ModuleInfoCache
28
     */
29
    protected $moduleInfoCache;
30
    /**
31
     * @var \ACP3\Core\Modules\Vendor
32
     */
33
    protected $vendors;
34 35 36
    /**
     * @var array
     */
37
    private $modulesInfo = [];
38 39 40
    /**
     * @var array
     */
41
    private $allModules = [];
42 43

    /**
44 45 46 47
     * @param \ACP3\Core\Environment\ApplicationPath           $appPath
     * @param \ACP3\Core\Modules\Helper\ControllerActionExists $controllerActionExists
     * @param \ACP3\Core\Modules\ModuleInfoCache               $moduleInfoCache
     * @param \ACP3\Core\Modules\Vendor                        $vendors
48 49
     */
    public function __construct(
50
        ApplicationPath $appPath,
51
        ControllerActionExists $controllerActionExists,
52
        ModuleInfoCache $moduleInfoCache,
53
        Vendor $vendors
Tino Goratsch's avatar
Tino Goratsch committed
54
    ) {
55
        $this->appPath = $appPath;
56
        $this->controllerActionExists = $controllerActionExists;
57
        $this->moduleInfoCache = $moduleInfoCache;
58
        $this->vendors = $vendors;
59 60 61
    }

    /**
62
     * Returns, whether the given module controller action exists.
63 64 65
     *
     * @param string $path
     *
66
     * @return bool
67
     */
68
    public function controllerActionExists(string $path)
69
    {
70
        return $this->controllerActionExists->controllerActionExists($path);
71 72 73
    }

    /**
74
     * Returns, whether a module is active or not.
75
     *
76
     * @param string $moduleName
77
     *
78
     * @return bool
79
     */
80
    public function isActive(string $moduleName)
81
    {
82
        $info = $this->getModuleInfo($moduleName);
Tino Goratsch's avatar
Tino Goratsch committed
83

84 85 86 87
        return !empty($info) && $info['active'] === true;
    }

    /**
88
     * Returns the available information about the given module.
89
     *
90
     * @param string $moduleName
91 92 93
     *
     * @return array
     */
94
    public function getModuleInfo(string $moduleName)
95
    {
96
        $moduleName = \strtolower($moduleName);
97 98
        if (empty($this->modulesInfo)) {
            $this->modulesInfo = $this->moduleInfoCache->getModulesInfoCache();
99
        }
Tino Goratsch's avatar
Tino Goratsch committed
100

101
        return !empty($this->modulesInfo[$moduleName]) ? $this->modulesInfo[$moduleName] : [];
102 103 104
    }

    /**
105
     * @param string $moduleName
106
     *
107
     * @return int
108
     */
109
    public function getModuleId(string $moduleName)
110
    {
111
        $info = $this->getModuleInfo($moduleName);
Tino Goratsch's avatar
Tino Goratsch committed
112

113 114 115 116
        return !empty($info) ? $info['id'] : 0;
    }

    /**
117
     * Checks, whether a module is currently installed or not.
118 119 120
     *
     * @param string $moduleName
     *
121
     * @return bool
122
     */
123
    public function isInstalled(string $moduleName)
124 125
    {
        $info = $this->getModuleInfo($moduleName);
Tino Goratsch's avatar
Tino Goratsch committed
126

127
        return !empty($info) && $info['installed'] === true || $info['installable'] === false;
128 129 130
    }

    /**
Tino Goratsch's avatar
Tino Goratsch committed
131
     * Returns all currently installed AND active modules.
132 133 134
     *
     * @return array
     */
135
    public function getActiveModules(): array
136
    {
137
        $modules = $this->getAllModulesAlphabeticallySorted();
138

139
        foreach ($modules as $key => $values) {
140 141 142 143 144 145 146 147 148
            if ($values['active'] === false) {
                unset($modules[$key]);
            }
        }

        return $modules;
    }

    /**
Tino Goratsch's avatar
Tino Goratsch committed
149
     * Returns all currently installed modules.
150
     *
151
     * @return array
152
     */
153
    public function getInstalledModules(): array
154
    {
155
        $modules = $this->getAllModulesAlphabeticallySorted();
156

157
        foreach ($modules as $key => $values) {
158 159 160 161 162 163 164 165 166
            if ($values['installed'] === false) {
                unset($modules[$key]);
            }
        }

        return $modules;
    }

    /**
Tino Goratsch's avatar
Tino Goratsch committed
167
     * Returns an alphabetically sorted array of all found ACP3 modules.
168
     *
169
     * @return array
170
     */
171 172 173 174 175 176 177
    public function getAllModulesAlphabeticallySorted(): array
    {
        $allModulesAlphabeticallySorted = [];
        foreach ($this->getAllModules() as $info) {
            $allModulesAlphabeticallySorted[$info['name']] = $info;
        }

Tino Goratsch's avatar
Tino Goratsch committed
178
        \ksort($allModulesAlphabeticallySorted);
179 180 181 182 183

        return $allModulesAlphabeticallySorted;
    }

    private function getAllModules(): array
184 185
    {
        if (empty($this->allModules)) {
186
            foreach ($this->vendors->getVendors() as $vendor) {
187
                foreach (Filesystem::scandir($this->appPath->getModulesDir() . $vendor . '/') as $module) {
188 189
                    $info = $this->getModuleInfo($module);
                    if (!empty($info)) {
190
                        $info['vendor'] = $vendor;
Tino Goratsch's avatar
Tino Goratsch committed
191
                        $this->allModules[\strtolower($module)] = $info;
192 193 194 195 196 197 198
                    }
                }
            }
        }

        return $this->allModules;
    }
199 200

    /**
Tino Goratsch's avatar
Tino Goratsch committed
201
     * Returns an array with all modules which is sorted topologically.
202 203 204 205 206 207 208 209 210
     *
     * @return array
     */
    public function getAllModulesTopSorted(): array
    {
        $topSort = new StringSort();

        $modules = $this->getAllModules();
        foreach ($modules as $module) {
Tino Goratsch's avatar
Tino Goratsch committed
211
            $topSort->add(\strtolower($module['dir']), $module['dependencies']);
212 213 214 215 216 217 218 219 220
        }

        $topSortedModules = [];
        foreach ($topSort->sort() as $module) {
            $topSortedModules[$module] = $modules[$module];
        }

        return $topSortedModules;
    }
Tino Goratsch's avatar
Tino Goratsch committed
221
}