Passed
Push — develop ( a56058...ddfce4 )
by Nikolay
04:39
created

DropdownsAction   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 176
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 21
eloc 77
c 0
b 0
f 0
dl 0
loc 176
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A sortExtensionsArray() 0 3 1
A getQueryParametersByType() 0 45 5
A processExtension() 0 25 6
A findModuleByExtensionNumber() 0 23 4
A getForSelect() 0 35 5
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
namespace MikoPBX\PBXCoreREST\Lib\Extensions;
21
22
use MikoPBX\Common\Models\Extensions;
23
use MikoPBX\Common\Models\PbxExtensionModules;
24
use MikoPBX\Core\System\Util;
25
use MikoPBX\PBXCoreREST\Lib\PBXApiResult;
26
use Phalcon\Text;
27
28
/**
29
 * Class Dropdowns
30
 * Provides methods to generate select lists of extensions for different purposes.
31
 *
32
 * @package MikoPBX\PBXCoreREST\Lib\Extensions
33
 */
34
class DropdownsAction extends \Phalcon\Di\Injectable
35
{
36
37
    /**
38
     * Generate a select list of extensions based on the given type.
39
     *
40
     * @param string $type {all, routing, phones, internal} - The type of extensions to fetch.
41
     * @return PBXApiResult The result containing the select list of extensions.
42
     */
43
    public static function getForSelect(string $type = 'all'): PBXApiResult
44
    {
45
        // Initialize the result object
46
        $res = new PBXApiResult();
47
        $res->processor = __METHOD__;
48
        $res->success = true;
49
50
        // Determine the query conditions based on the type
51
        $parameters = self::getQueryParametersByType($type);
52
53
        // Fetch extensions based on the query parameters
54
        $extensions = Extensions::find($parameters);
55
56
        // Process fetched extensions
57
        foreach ($extensions as $record) {
58
             $extensionData = self::processExtension($record);
59
             if ($extensionData!==[]){
60
                 $res->data[]=$extensionData;
61
             }
62
        }
63
64
        // Sort the results based on the sorter value
65
        usort(
66
            $res->data,
67
            [__CLASS__, 'sortExtensionsArray']
68
        );
69
70
        // Delete sorter column
71
        foreach ($res->data as &$subArray) {
72
            if (array_key_exists('sorter', $subArray)) {
73
                unset($subArray['sorter']);
74
            }
75
        }
76
77
        return $res;
78
    }
79
80
    /**
81
     * Generate query parameters based on the extension type.
82
     *
83
     * @param string $type - The type of extensions.
84
     * @return array - Query parameters.
85
     */
86
    private static function getQueryParametersByType(string $type): array
87
    {
88
        // Initialize default query conditions
89
        $parameters = [
90
            'conditions' => 'show_in_phonebook="1"',
91
        ];
92
93
        // Define specific query conditions based on the type
94
        switch ($type) {
95
            case 'all':
96
                $parameters['conditions'] .= ' AND number NOT IN ({exclude:array})';
97
                $parameters['bind'] = [
98
                    'exclude' => ['did2user'],
99
                ];
100
                break;
101
            case 'phones':
102
                $parameters['conditions'] .= ' AND type IN ({ids:array})';
103
                $parameters['bind']['ids'] = [
104
                    Extensions::TYPE_SIP,
105
                    Extensions::TYPE_EXTERNAL
106
                ];
107
                break;
108
            case 'internal':
109
                $parameters['conditions'] .= ' AND type IN ({ids:array})';
110
                $parameters['bind']['ids'] = [
111
                    Extensions::TYPE_SIP
112
                ];
113
                break;
114
            case 'routing':
115
                $parameters['conditions'] .= ' AND type IN ({ids:array})';
116
                $parameters['bind']['ids'] = [
117
                    Extensions::TYPE_SIP,
118
                    Extensions::TYPE_EXTERNAL,
119
                    Extensions::TYPE_MODULES,
120
                    Extensions::TYPE_CONFERENCE,
121
                    Extensions::TYPE_DIALPLAN_APPLICATION,
122
                    Extensions::TYPE_IVR_MENU,
123
                    Extensions::TYPE_QUEUE,
124
                    Extensions::TYPE_SYSTEM,
125
                    // Extensions::TYPE_PARKING,
126
                ];
127
                break;
128
        }
129
130
        return $parameters;
131
    }
132
133
    /**
134
     * Process a fetched extension record to generate result entry.
135
     *
136
     * @param Extensions $record - The extension record.
137
     * @return array - Result entry for the extension.
138
     */
139
    private static function processExtension(Extensions $record): array
140
    {
141
        $type = ($record->userid > 0) ? ' USER' : $record->type??'';
142
        $type = Text::underscore(strtoupper($type));
143
144
        if ($type === Extensions::TYPE_MODULES) {
145
            // Check if the extension belongs to a module and if the module is disabled
146
            $module = self::findModuleByExtensionNumber($record->number??'');
147
            if ($module === null || $module->disabled === '1') {
148
                return []; // Skip disabled modules
149
            }
150
        }
151
152
        $represent = $record->getRepresent();
153
        $clearedRepresent = strip_tags($represent);
154
155
        // Create a result entry for the extension
156
        return [
157
            'name' => $represent,
158
            'value' => $record->number,
159
            'type' => $type,
160
            'typeLocalized' => Util::translate("ex_dropdownCategory_{$type}"),
161
            'sorter' => ($record->userid > 0) ?
162
                "{$type}{$clearedRepresent}{$record->number}" :
163
                "{$type}{$clearedRepresent}",
164
        ];
165
    }
166
167
    /**
168
     * Tries to find a module by extension number.
169
     *
170
     * @param string $number - The extension number.
171
     *
172
     * @return mixed|null The module object if found, null otherwise.
173
     */
174
    private static function findModuleByExtensionNumber(string $number)
175
    {
176
        $result = null;
177
        $extension = Extensions::findFirst("number ='{$number}'");
178
        $relatedLinks = $extension->getRelatedLinks();
179
        $moduleUniqueID = false;
180
181
        // Iterate through the related links to find the module
182
        foreach ($relatedLinks as $relation) {
183
            $obj = $relation['object'];
184
185
            // Check if the related object belongs to a module
186
            if (strpos(get_class($obj), 'Modules\\') === 0) {
187
                $moduleUniqueID = explode('Models\\', get_class($obj))[1];
188
            }
189
        }
190
191
        // If a module unique ID is found, retrieve the corresponding module object
192
        if ($moduleUniqueID) {
193
            $result = PbxExtensionModules::findFirstByUniqid($moduleUniqueID);
194
        }
195
196
        return $result;
197
    }
198
199
    /**
200
     * Sorts the extensions array.
201
     *
202
     * @param array $a - The first element to compare.
203
     * @param array $b - The second element to compare.
204
     *
205
     * @return int - Returns a negative, zero, or positive integer based on the comparison result.
206
     */
207
    private static function sortExtensionsArray($a, $b): int
208
    {
209
        return strcmp($a['sorter'], $b['sorter']);
210
    }
211
212
}