Passed
Push — develop ( 578d35...1edb03 )
by Nikolay
13:40 queued 12s
created

Dropdowns   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 20
eloc 61
c 1
b 0
f 0
dl 0
loc 156
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A processExtension() 0 25 6
A findModuleByExtensionNumber() 0 23 4
A getForSelect() 0 35 5
A sortExtensionsArray() 0 3 1
A getQueryParametersByType() 0 25 4
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 Dropdowns 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'] = [Extensions::TYPE_SIP, Extensions::TYPE_EXTERNAL];
104
                break;
105
            case 'internal':
106
                $parameters['conditions'] .= ' AND type = "' . Extensions::TYPE_SIP . '"';
107
                break;
108
        }
109
110
        return $parameters;
111
    }
112
113
    /**
114
     * Process a fetched extension record to generate result entry.
115
     *
116
     * @param Extensions $record - The extension record.
117
     * @return array - Result entry for the extension.
118
     */
119
    private static function processExtension(Extensions $record): array
120
    {
121
        $type = ($record->userid > 0) ? ' USER' : $record->type;
122
        $type = Text::underscore(strtoupper($type));
0 ignored issues
show
Bug introduced by
It seems like $type can also be of type null; however, parameter $string of strtoupper() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

122
        $type = Text::underscore(strtoupper(/** @scrutinizer ignore-type */ $type));
Loading history...
123
124
        if ($type === Extensions::TYPE_MODULES) {
125
            // Check if the extension belongs to a module and if the module is disabled
126
            $module = self::findModuleByExtensionNumber($record->number);
0 ignored issues
show
Bug introduced by
It seems like $record->number can also be of type null; however, parameter $number of MikoPBX\PBXCoreREST\Lib\...duleByExtensionNumber() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

126
            $module = self::findModuleByExtensionNumber(/** @scrutinizer ignore-type */ $record->number);
Loading history...
127
            if ($module === null || $module->disabled === '1') {
128
                return []; // Skip disabled modules
129
            }
130
        }
131
132
        $represent = $record->getRepresent();
133
        $clearedRepresent = strip_tags($represent);
134
135
        // Create a result entry for the extension
136
        return [
137
            'name' => $represent,
138
            'value' => $record->number,
139
            'type' => $type,
140
            'typeLocalized' => Util::translate("ex_dropdownCategory_{$type}"),
141
            'sorter' => ($record->userid > 0) ?
142
                "{$type}{$clearedRepresent}{$record->number}" :
143
                "{$type}{$clearedRepresent}",
144
        ];
145
    }
146
147
    /**
148
     * Tries to find a module by extension number.
149
     *
150
     * @param string $number - The extension number.
151
     *
152
     * @return mixed|null The module object if found, null otherwise.
153
     */
154
    private static function findModuleByExtensionNumber(string $number)
155
    {
156
        $result = null;
157
        $extension = Extensions::findFirst("number ='{$number}'");
158
        $relatedLinks = $extension->getRelatedLinks();
159
        $moduleUniqueID = false;
160
161
        // Iterate through the related links to find the module
162
        foreach ($relatedLinks as $relation) {
163
            $obj = $relation['object'];
164
165
            // Check if the related object belongs to a module
166
            if (strpos(get_class($obj), 'Modules\\') === 0) {
167
                $moduleUniqueID = explode('Models\\', get_class($obj))[1];
168
            }
169
        }
170
171
        // If a module unique ID is found, retrieve the corresponding module object
172
        if ($moduleUniqueID) {
173
            $result = PbxExtensionModules::findFirstByUniqid($moduleUniqueID);
174
        }
175
176
        return $result;
177
    }
178
179
    /**
180
     * Sorts the extensions array.
181
     *
182
     * @param array $a - The first element to compare.
183
     * @param array $b - The second element to compare.
184
     *
185
     * @return int - Returns a negative, zero, or positive integer based on the comparison result.
186
     */
187
    private static function sortExtensionsArray($a, $b): int
188
    {
189
        return strcmp($a['sorter'], $b['sorter']);
190
    }
191
192
}