Passed
Push — develop ( 92210f...e51e97 )
by Nikolay
05:11
created

PBXConfModulesProvider::hookModulesMethod()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 28
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 28
rs 9.0111
c 0
b 0
f 0
cc 6
nc 6
nop 2
1
<?php
2
/*
3
 * MikoPBX - free phone system for small business
4
 * Copyright © 2017-2023 Alexey Portnov and Nikolay Beketov
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with this program.
17
 * If not, see <https://www.gnu.org/licenses/>.
18
 */
19
20
declare(strict_types=1);
21
22
namespace MikoPBX\Common\Providers;
23
24
use MikoPBX\Common\Models\PbxExtensionModules;
25
use MikoPBX\Common\Models\PbxSettings;
26
use MikoPBX\Core\System\Util;
27
use MikoPBX\Modules\Config\ConfigClass;
28
use Phalcon\Di;
29
use Phalcon\Di\DiInterface;
30
use Phalcon\Di\ServiceProviderInterface;
31
32
/**
33
 * Registers pbxConfModules service provider and provides methods to interact with additional modules.
34
 *
35
 * @package MikoPBX\Common\Providers
36
 */
37
class PBXConfModulesProvider implements ServiceProviderInterface
38
{
39
    public const SERVICE_NAME = 'pbxConfModules';
40
41
    public const VERSION_HASH = 'versionHash';
42
43
    /**
44
     * Registers pbxConfModules service provider.
45
     * Creates an array of external installed modules.
46
     *
47
     * @param DiInterface $di The DI container.
48
     */
49
    public function register(DiInterface $di): void
50
    {
51
        $di->setShared(
52
            self::SERVICE_NAME,
53
            function (string $methodName=''){
54
                $additionalModules = [];
55
                $modules = PbxExtensionModules::getEnabledModulesArray();
56
                foreach ($modules as $value) {
57
                    $className      = str_replace('Module', '', $value['uniqid']);
58
                    $fullClassName = "\\Modules\\{$value['uniqid']}\\Lib\\{$className}Conf";
59
                    if (class_exists($fullClassName)) {
60
                        $object = new $fullClassName();
61
                        if ($object instanceof ConfigClass){
62
                            $additionalModules[] = $object;
63
                        }
64
                    }
65
                }
66
67
                // Sort the array based on the priority value for $methodName
68
                usort($additionalModules, function($a, $b) use ($methodName) {
69
                    return $a->getMethodPriority($methodName) - $b->getMethodPriority($methodName);
70
                });
71
                return  $additionalModules;
72
            }
73
        );
74
    }
75
76
    /**
77
     * Recreates modules service after enable or disable them
78
     */
79
    public static function recreateModulesProvider(): void
80
    {
81
        $di = Di::getDefault();
82
        $di->remove(self::SERVICE_NAME);
83
        $di->register(new self());
84
    }
85
86
    /**
87
     * Calls additional module method by name and returns an array of results.
88
     *
89
     * @param string $methodName The method name to call.
90
     * @param array  $arguments  The arguments to pass to the method.
91
     *
92
     * @return array The array of results.
93
     */
94
    public static function hookModulesMethod(string $methodName, array $arguments = []): array
95
    {
96
        $result            = [];
97
        $di = Di::getDefault();
98
        $additionalModules = $di->getShared(PBXConfModulesProvider::SERVICE_NAME, ['methodName'=>$methodName]);
99
100
        foreach ($additionalModules as $configClassObj) {
101
            if ( ! method_exists($configClassObj, $methodName)) {
102
                continue;
103
            }
104
            try {
105
                $moduleMethodResponse = call_user_func_array([$configClassObj, $methodName], $arguments);
106
            } catch (\Throwable $e) {
107
                global $errorLogger;
108
                $errorLogger->captureException($e);
109
                Util::sysLogMsg(__METHOD__, $e->getMessage(), LOG_ERR);
110
                continue;
111
            }
112
            if ( ! empty($moduleMethodResponse)) {
113
                if (is_a($configClassObj, ConfigClass::class)) {
114
                    $result[$configClassObj->moduleUniqueId] = $moduleMethodResponse;
115
                } else {
116
                    $result[] = $moduleMethodResponse;
117
                }
118
            }
119
        }
120
121
        return $result;
122
    }
123
124
    /**
125
     * Calculated PBX version + all installed modules versions hash
126
     *
127
     * @return string calculated hash
128
     */
129
    public static function getVersionsHash(bool $recreate=false): string
130
    {
131
        $di = Di::getDefault();
132
        $cache = $di->get(ManagedCacheProvider::SERVICE_NAME);
133
        $version = $cache->get(PBXConfModulesProvider::VERSION_HASH) ?? '';
134
        if (empty($version) or $recreate){
135
            $result = PbxSettings::getValueByKey('PBXVersion');
136
            $modulesVersions = PbxExtensionModules::getEnabledModulesArray();
137
            foreach ($modulesVersions as $module) {
138
                $result .= "{$module['id']}{$module['version']}";
139
            }
140
            $version = md5($result);
141
            $cache->set(PBXConfModulesProvider::VERSION_HASH, $version, 3600);
142
        }
143
        return $version;
144
    }
145
146
}