/
mikopbx
/
ModuleBeelinePbx
Обзор
Документация
Войти
/
mikopbx
/
ModuleBeelinePbx
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
master
Lib/RestAPI/GetController.php
109 строк
5 KB
boffart
Инициализация модуля ModuleBeelinePbx
08 июл 2026, 17:11
08 июл 2026, 17:11
1cc4e1a
Код
Авторство
О чём код?
<?php /* * MikoPBX - free phone system for small business * Copyright © 2017-2024 Alexey Portnov and Nikolay Beketov * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program. * If not, see <https://www.gnu.org/licenses/>. */ namespace Modules\ModuleBeelinePbx\Lib\RestAPI; use DateTime; use MikoPBX\PBXCoreREST\Controllers\BaseController; use Modules\ModuleBeelinePbx\Lib\BeelineCdrHelper; use Modules\ModuleBeelinePbx\Models\CallHistory; class GetController extends BaseController { /** * Максимальное число строк, отдаваемых за один запрос. */ public const MAX_LIMIT = 5000; /** * Последовательная выгрузка импортированной истории звонков в XML для внешних потребителей (1С). * * curl 'http://127.0.0.1:80/pbxcore/beeline-pbx/cdr?offset=619640'; */ public function getDataAction(): void { $offset = (int)$this->request->get('offset'); // Учитываем запрошенный размер пачки (1С шлёт limit=450). Без этого контроллер // отдавал бы до MAX_LIMIT строк за раз, и 1С «зависала» на обработке огромного пакета. // Значение вне диапазона (0/пусто/слишком большое) ограничиваем MAX_LIMIT. $limit = (int)$this->request->get('limit'); if ($limit <= 0 || $limit > self::MAX_LIMIT) { $limit = self::MAX_LIMIT; } $maxOffset = 0; $filter = [ 'id>:id: OR start>=:start:', 'bind' => ['id' => $offset], 'order' => 'id', 'limit' => $limit, ]; try { $dt = new DateTime(); $dt->setTime(0, 0, 0); $filter['bind']['start'] = $dt->format('Y-m-d H:i:s'); $arrData = CallHistory::find($filter)->toArray(); } catch (\Throwable $e) { $arrData = []; } usort($arrData, static function ($a, $b) { return strtotime($a['start']) <=> strtotime($b['start']); }); $xmlOutput = '<history>' . PHP_EOL; foreach ($arrData as $data) { $maxOffset = max($maxOffset, (int)$data['id']); // strpos===0 вместо str_starts_with (PHP 8+) для совместимости с PHP 7.4. if (strpos((string)$data['linkedid'], BeelineCdrHelper::UNIQUEID_PREFIX) !== 0) { continue; } $xmlOutput .= "<history_record no=\"$data[linkedid]\" entire_id=\"$data[linkedid]\" line=\"$data[did]\">"; $detailAttr = [ 'call_id' => $data['linkedid'], 'status' => $data['disposition'] === 'ANSWERED' ? 'ANSWER' : 'CANCEL', 'call_flow' => '', 'queue' => '', 'start' => $data['start'], 'started' => (new DateTime($data['start']))->format('c'), 'answered' => empty($data['answer']) ? '' : (new DateTime($data['answer']))->format('c'), 'finished' => (new DateTime($data['endtime']))->format('c'), 'duration' => $data['duration'], 'conversation' => $data['billsec'], 'record_file' => $data['recordingfile'], 'finish_cause' => 'Normal Clearing', ]; $attributesDetail = ''; foreach ($detailAttr as $key => $val) { $attributesDetail .= sprintf('%s="%s" ', $key, $val); } $xmlOutput .= "<details $attributesDetail />"; $xmlOutput .= "<from ext=\"\" number=\"$data[src_num]\"></from>"; $xmlOutput .= "<to ext=\"\" number=\"$data[dst_num]\"></to>"; $xmlOutput .= '</history_record>' . PHP_EOL; } $xmlOutput .= '</history>' . PHP_EOL; $this->response->setContent($xmlOutput); $this->response->setHeader('X-MIN-OFFSET', $offset); $this->response->setHeader('X-MAX-OFFSET', max($maxOffset, $offset)); $this->response->sendRaw(); } }