Passed
Push — develop ( c1c7b0...ceba44 )
by Nikolay
05:17
created

GeneralSettingsController::updateCodecs()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 14
rs 9.9332
c 0
b 0
f 0
cc 4
nc 5
nop 1
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\AdminCabinet\Controllers;
21
22
use MikoPBX\AdminCabinet\Forms\GeneralSettingsEditForm;
23
use MikoPBX\Common\Models\Codecs;
24
use MikoPBX\Common\Models\Extensions;
25
use MikoPBX\Common\Models\PbxSettings;
26
use MikoPBX\Common\Models\PbxSettingsConstants;
27
use MikoPBX\Core\System\Util;
28
29
/**
30
 * Class GeneralSettingsController
31
 *
32
 * This class handles general settings for the application.
33
 */
34
class GeneralSettingsController extends BaseController
35
{
36
    /**
37
     * Builds the general settings form.
38
     *
39
     * This action is responsible for preparing the data required to populate the general settings form.
40
     * It retrieves the audio and video codecs from the database, sorts them by priority, and assigns them to the view.
41
     * It also retrieves all PBX settings and creates an instance of the GeneralSettingsEditForm.
42
     *
43
     * @return void
44
     */
45
    public function modifyAction(): void
46
    {
47
        // Retrieve and sort audio codecs from database
48
        $audioCodecs = Codecs::find(['conditions' => 'type="audio"'])->toArray();
49
        usort($audioCodecs, [__CLASS__, 'sortArrayByPriority']);
50
        $this->view->audioCodecs = $audioCodecs;
51
52
        // Retrieve and sort video codecs from database
53
        $videoCodecs = Codecs::find(['conditions' => 'type="video"'])->toArray();
54
        usort($videoCodecs, [__CLASS__, 'sortArrayByPriority']);
55
        $this->view->videoCodecs = $videoCodecs;
56
57
        // Fetch all PBX settings
58
        $pbxSettings = PbxSettings::getAllPbxSettings();
59
60
        // Fetch and assign simple passwords for the view
61
        $this->view->simplePasswords = $this->getSimplePasswords($pbxSettings);
62
63
        // Create an instance of the GeneralSettingsEditForm and assign it to the view
64
        $this->view->form = new GeneralSettingsEditForm(null, $pbxSettings);
65
        $this->view->submitMode = null;
66
67
    }
68
69
    /**
70
     * Retrieves a list of simple passwords from the given data.
71
     *
72
     * This function checks if the SSHPassword and WebAdminPassword in the data array are simple passwords.
73
     * It also checks if the CloudInstanceId matches any of these passwords.
74
     * If a simple password or a matching CloudInstanceId is found, the corresponding password key is added to the list.
75
     *
76
     * @param array $data The data array containing the passwords and CloudInstanceId.
77
     * @return array The list of password keys that failed the simple password check.
78
     */
79
    private function getSimplePasswords(array $data): array
80
    {
81
        // Initialize an array to keep track of passwords that fail the check
82
        $passwordCheckFail = [];
83
84
        $cloudInstanceId = $data['CloudInstanceId'] ?? '';
85
        $checkPasswordFields = [PbxSettingsConstants::SSH_PASSWORD, 'WebAdminPassword'];
86
87
        // If SSH is disabled, remove the SSH_PASSWORD key
88
        if ($data[PbxSettingsConstants::SSH_DISABLE_SSH_PASSWORD] === 'on') {
89
            unset($checkPasswordFields[PbxSettingsConstants::SSH_PASSWORD]);
90
        }
91
92
        // Loop through and check passwords
93
        foreach ($checkPasswordFields as $value) {
94
            if (!isset($data[$value]) || $data[$value] === GeneralSettingsEditForm::HIDDEN_PASSWORD) {
95
                continue;
96
            }
97
            if ($cloudInstanceId === $data[$value] || Util::isSimplePassword($data[$value])) {
98
                $passwordCheckFail[] = $value;
99
            }
100
        }
101
        return $passwordCheckFail;
102
    }
103
104
    /**
105
     * Saves the general settings form data.
106
     *
107
     */
108
    public function saveAction(): void
109
    {
110
        if (!$this->request->isPost()) {
111
            return;
112
        }
113
        $data = $this->request->getPost();
114
115
        $passwordCheckFail = $this->getSimplePasswords($data);
116
        if (!empty($passwordCheckFail)) {
117
            foreach ($passwordCheckFail as $settingsKey) {
118
                $this->flash->error($this->translation->_('gs_SetPasswordError', ['password' => $data[$settingsKey]]));
119
            }
120
            $this->view->success = false;
121
            $this->view->passwordCheckFail = $passwordCheckFail;
122
            return;
123
        }
124
125
        $this->db->begin();
126
127
        list($result, $messages) = $this->updatePBXSettings($data);
128
        if (!$result) {
129
            $this->view->success = false;
130
            $this->view->messages = $messages;
131
            $this->db->rollback();
132
            return;
133
        }
134
135
        list($result, $messages) = $this->updateCodecs($data['codecs']);
136
        if (!$result) {
137
            $this->view->success = false;
138
            $this->view->messages = $messages;
139
            $this->db->rollback();
140
            return;
141
        }
142
143
        list($result, $messages) = $this->createParkingExtensions(
144
            $data[PbxSettingsConstants::PBX_CALL_PARKING_START_SLOT],
145
            $data[PbxSettingsConstants::PBX_CALL_PARKING_END_SLOT],
146
            $data[PbxSettingsConstants::PBX_CALL_PARKING_EXT],
147
        );
148
149
        if (!$result) {
150
            $this->view->success = false;
151
            $this->view->messages = $messages;
152
            $this->db->rollback();
153
            return;
154
        }
155
156
        $this->flash->success($this->translation->_('ms_SuccessfulSaved'));
157
        $this->view->success = true;
158
        $this->db->commit();
159
160
    }
161
162
163
    /**
164
     * Create parking extensions.
165
     *
166
     * @param int $startSlot
167
     * @param int $endSlot
168
     * @param int $reservedSlot
169
     *
170
     * @return array
171
     */
172
    private function createParkingExtensions(int $startSlot, int $endSlot, int $reservedSlot): array
173
    {
174
        $messages = [];
175
        // Delete all parking slots
176
        $currentSlots = Extensions::findByType(Extensions::TYPE_PARKING);
177
        foreach ($currentSlots as $currentSlot) {
178
            if (!$currentSlot->delete()) {
179
                $messages['error'][] = $currentSlot->getMessages();
180
            }
181
        }
182
183
        // Create an array of new numbers
184
        $numbers = range($startSlot, $endSlot);
185
        $numbers[] = $reservedSlot;
186
        foreach ($numbers as $number) {
187
            $record = new Extensions();
188
            $record->type = Extensions::TYPE_PARKING;
189
            $record->number = $number;
190
            if (!$record->create()) {
191
                $messages['error'][] = $record->getMessages();
192
            }
193
        }
194
195
        $result = count($messages) === 0;
196
        return [$result, $messages];
197
    }
198
199
    /**
200
     * Update codecs based on the provided data.
201
     *
202
     * @param string $codecsData The JSON-encoded data for codecs.
203
     *
204
     * @return array
205
     */
206
    private function updateCodecs(string $codecsData): array
207
    {
208
        $messages = [];
209
        $codecs = json_decode($codecsData, true);
210
        foreach ($codecs as $codec) {
211
            $record = Codecs::findFirstById($codec['codecId']);
212
            $record->priority = $codec['priority'];
213
            $record->disabled = $codec['disabled'] === true ? '1' : '0';
214
            if (!$record->update()) {
215
                $messages['error'][] = $record->getMessages();
216
            }
217
        }
218
        $result = count($messages) === 0;
219
        return [$result, $messages];
220
    }
221
222
    /**
223
     * Update PBX settings based on the provided data.
224
     *
225
     * @param array $data The data containing PBX settings.
226
     *
227
     * @return array
228
     */
229
    private function updatePBXSettings(array $data):array
230
    {
231
        $messages = [];
232
        $pbxSettings = PbxSettings::getDefaultArrayValues();
233
234
        // Process SSHPassword and set SSHPasswordHash accordingly
235
        if (isset($data[PbxSettingsConstants::SSH_PASSWORD])) {
236
            if ($data[PbxSettingsConstants::SSH_PASSWORD] === $pbxSettings[PbxSettingsConstants::SSH_PASSWORD]
237
                || $data[PbxSettingsConstants::SSH_PASSWORD] === GeneralSettingsEditForm::HIDDEN_PASSWORD) {
238
                $data[PbxSettingsConstants::SSH_PASSWORD_HASH_STRING] = md5($data['WebAdminPassword']);
239
            } else {
240
                $data[PbxSettingsConstants::SSH_PASSWORD_HASH_STRING] = md5($data[PbxSettingsConstants::SSH_PASSWORD]);
241
            }
242
        }
243
244
        // Update PBX settings
245
        foreach ($pbxSettings as $key => $value) {
246
            switch ($key) {
247
                case 'PBXRecordCalls':
248
                case 'PBXRecordCallsInner':
249
                case 'AJAMEnabled':
250
                case 'AMIEnabled':
251
                case 'RestartEveryNight':
252
                case 'RedirectToHttps':
253
                case 'PBXSplitAudioThread':
254
                case 'UseWebRTC':
255
                case PbxSettingsConstants::SSH_DISABLE_SSH_PASSWORD:
256
                case 'PBXAllowGuestCalls':
257
                case '***ALL CHECK BOXES ABOVE***':
258
                    $newValue = ($data[$key] === 'on') ? '1' : '0';
259
                    break;
260
                case PbxSettingsConstants::SSH_PASSWORD:
261
                    // Set newValue as WebAdminPassword if SSHPassword is the same as the default value
262
                    if ($data[$key] === $value) {
263
                        $newValue = $data['WebAdminPassword'];
264
                    } elseif ($data[$key] !== GeneralSettingsEditForm::HIDDEN_PASSWORD) {
265
                        $newValue = $data[$key];
266
                    } else {
267
                        continue 2;
268
                    }
269
                    break;
270
                case 'SendMetrics':
271
                    $newValue = ($data[$key] === 'on') ? '1' : '0';
272
                    $this->session->set('SendMetrics', $newValue);
273
                    break;
274
                case 'PBXFeatureTransferDigitTimeout':
275
                    $newValue = ceil((int)$data['PBXFeatureDigitTimeout'] / 1000);
276
                    break;
277
                case 'WebAdminPassword':
278
                    if ($data[$key] !== GeneralSettingsEditForm::HIDDEN_PASSWORD) {
279
                        $newValue = $this->security->hash($data[$key]);
280
                    } else {
281
                        continue 2;
282
                    }
283
                    break;
284
                default:
285
                    $newValue = $data[$key];
286
            }
287
288
            if (array_key_exists($key, $data)) {
289
                $record = PbxSettings::findFirstByKey($key);
290
                if ($record === null) {
291
                    $record = new PbxSettings();
292
                    $record->key = $key;
293
                } elseif ($record->key === $key
294
                    && $record->value === $newValue) {
295
                    continue;
296
                }
297
                $record->value = $newValue;
298
299
                if ($record->save() === false) {
300
                    $messages['error'][] = $record->getMessages();
301
                }
302
            }
303
        }
304
        $result = count($messages) === 0;
305
        return [$result, $messages];
306
    }
307
308
}