Files
CRM-IKZ/app/Controllers/AdminBoardSourceController.php
T
2026-07-14 08:19:56 +04:00

259 lines
8.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Controllers;
use App\Core\Auth;
use App\Core\DB;
use App\Core\View;
class AdminBoardSourceController
{
private function requireAdmin(): void
{
if (!Auth::check()) {
header('Location: /login');
exit;
}
$user = Auth::user();
if ((int)($user['is_admin'] ?? 0) !== 1) {
http_response_code(403);
echo 'Доступ запрещен';
exit;
}
}
private function extractSpreadsheetId(string $url): string
{
if (preg_match('~/spreadsheets/d/([a-zA-Z0-9-_]+)~', $url, $matches)) {
return $matches[1];
}
return trim($url);
}
public function edit(): void
{
$this->requireAdmin();
$boardId = (int)($_GET['id'] ?? 0);
$pdo = DB::connection();
$stmt = $pdo->prepare("SELECT id, name, code FROM boards WHERE id = ? LIMIT 1");
$stmt->execute([$boardId]);
$board = $stmt->fetch();
if (!$board) {
http_response_code(404);
echo 'Доска не найдена';
return;
}
$stmt = $pdo->prepare("
SELECT *
FROM board_sources
WHERE board_id = ?
AND source_type = 'google_sheet'
LIMIT 1
");
$stmt->execute([$boardId]);
$source = $stmt->fetch();
$stmt = $pdo->prepare("
SELECT id, code, name
FROM board_fields
WHERE board_id = ?
AND is_active = 1
ORDER BY sort_order ASC, id ASC
");
$stmt->execute([$boardId]);
$customFields = $stmt->fetchAll();
$mappings = [];
if ($source) {
$stmt = $pdo->prepare("
SELECT target_type, target_key, source_column_name
FROM board_source_mappings
WHERE board_source_id = ?
AND is_active = 1
");
$stmt->execute([$source['id']]);
foreach ($stmt->fetchAll() as $row) {
$mappings[$row['target_type'] . ':' . $row['target_key']] = $row['source_column_name'];
}
}
$baseFields = [
['key' => 'creator_name', 'name' => 'Постановщик'],
['key' => 'assignee_name', 'name' => 'Ответственный'],
['key' => 'name', 'name' => 'Наименование'],
['key' => 'description', 'name' => 'Описание задачи'],
['key' => 'status', 'name' => 'Статус'],
['key' => 'priority', 'name' => 'Приоритет'],
['key' => 'crm_id', 'name' => 'CRM ID'],
['key' => 'completed_flag', 'name' => 'Выполнено'],
['key' => 'task_created_at', 'name' => 'Дата постановки'],
['key' => 'planned_at', 'name' => 'Дата план'],
['key' => 'completed_at', 'name' => 'Дата факт'],
];
View::render('admin/boards/source/edit', [
'board' => $board,
'source' => $source,
'baseFields' => $baseFields,
'customFields' => $customFields,
'mappings' => $mappings,
'user' => Auth::user(),
]);
}
public function save(): void
{
$this->requireAdmin();
$boardId = (int)($_POST['board_id'] ?? 0);
$spreadsheetUrl = trim((string)($_POST['spreadsheet_url'] ?? ''));
$sheetName = trim((string)($_POST['sheet_name'] ?? ''));
$syncMode = trim((string)($_POST['sync_mode'] ?? 'import_export'));
$isActive = isset($_POST['is_active']) ? 1 : 0;
if ($boardId <= 0 || $spreadsheetUrl === '' || $sheetName === '') {
$_SESSION['error'] = 'Заполни ссылку и имя вкладки';
header('Location: /admin/boards/source?id=' . $boardId);
exit;
}
$spreadsheetId = $this->extractSpreadsheetId($spreadsheetUrl);
if ($spreadsheetId === '') {
$_SESSION['error'] = 'Не удалось определить Spreadsheet ID';
header('Location: /admin/boards/source?id=' . $boardId);
exit;
}
$pdo = DB::connection();
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("
SELECT id
FROM board_sources
WHERE board_id = ?
AND source_type = 'google_sheet'
LIMIT 1
");
$stmt->execute([$boardId]);
$sourceId = (int)$stmt->fetchColumn();
if ($sourceId > 0) {
$stmt = $pdo->prepare("
UPDATE board_sources
SET
spreadsheet_url = ?,
source_key = ?,
sheet_name = ?,
sync_mode = ?,
is_active = ?,
updated_at = NOW()
WHERE id = ?
");
$stmt->execute([
$spreadsheetUrl,
$spreadsheetId,
$sheetName,
$syncMode,
$isActive,
$sourceId,
]);
} else {
$stmt = $pdo->prepare("
INSERT INTO board_sources (
board_id,
source_type,
spreadsheet_url,
source_key,
sheet_name,
sync_mode,
is_active,
created_at,
updated_at
) VALUES (?, 'google_sheet', ?, ?, ?, ?, ?, NOW(), NOW())
");
$stmt->execute([
$boardId,
$spreadsheetUrl,
$spreadsheetId,
$sheetName,
$syncMode,
$isActive,
]);
$sourceId = (int)$pdo->lastInsertId();
}
$stmt = $pdo->prepare("DELETE FROM board_source_mappings WHERE board_source_id = ?");
$stmt->execute([$sourceId]);
$baseMappings = $_POST['mapping_base'] ?? [];
if (is_array($baseMappings)) {
$stmt = $pdo->prepare("
INSERT INTO board_source_mappings (
board_source_id,
target_type,
target_key,
source_column_name,
is_active,
created_at,
updated_at
) VALUES (?, 'base', ?, ?, 1, NOW(), NOW())
");
foreach ($baseMappings as $key => $columnName) {
$columnName = trim((string)$columnName);
if ($columnName === '') {
continue;
}
$stmt->execute([$sourceId, $key, $columnName]);
}
}
$customMappings = $_POST['mapping_custom'] ?? [];
if (is_array($customMappings)) {
$stmt = $pdo->prepare("
INSERT INTO board_source_mappings (
board_source_id,
target_type,
target_key,
source_column_name,
is_active,
created_at,
updated_at
) VALUES (?, 'custom', ?, ?, 1, NOW(), NOW())
");
foreach ($customMappings as $key => $columnName) {
$columnName = trim((string)$columnName);
if ($columnName === '') {
continue;
}
$stmt->execute([$sourceId, $key, $columnName]);
}
}
$pdo->commit();
$_SESSION['success'] = 'Интеграция Google Sheets сохранена';
} catch (\Throwable $e) {
$pdo->rollBack();
$_SESSION['error'] = 'Ошибка сохранения интеграции: ' . $e->getMessage();
}
header('Location: /admin/boards/source?id=' . $boardId);
exit;
}
}