diff --git a/src/Controllers/TelegramController.php b/src/Controllers/TelegramController.php index c4674b1..f92527d 100644 --- a/src/Controllers/TelegramController.php +++ b/src/Controllers/TelegramController.php @@ -20,7 +20,7 @@ class TelegramController { use ViewResponseTrait; - + private TelegramService $telegramService; private Telegram $module; private TelegramConfigService $telegramConfigService; @@ -49,7 +49,7 @@ public function configsIndex(ServerRequestInterface $request): array $configs = $this->telegramConfigService->getAllConfigs(); $users = $this->telegramConfigService->getAvailableUsers(); $trees = $this->telegramConfigService->getAvailableTrees(); - + return [ 'configs' => $configs, 'users' => $users, @@ -72,7 +72,7 @@ public function configAdd(ServerRequestInterface $request): array $events = \Tywed\Webtrees\Module\Telegram\CustomOnThisDayModule::getAllEvents(); $defaultEvents = \Tywed\Webtrees\Module\Telegram\CustomOnThisDayModule::getDefaultEvents(); $eventLabels = \Tywed\Webtrees\Module\Telegram\CustomOnThisDayModule::getEventLabels(); - + return [ 'config' => null, 'users' => $users, @@ -101,13 +101,13 @@ public function configEdit(ServerRequestInterface $request, string $id): array FlashMessages::addMessage(I18N::translate('Configuration not found'), 'danger'); return []; } - + $users = $this->telegramConfigService->getAvailableUsers(); $trees = $this->telegramConfigService->getAvailableTrees(); $events = \Tywed\Webtrees\Module\Telegram\CustomOnThisDayModule::getAllEvents(); $defaultEvents = \Tywed\Webtrees\Module\Telegram\CustomOnThisDayModule::getDefaultEvents(); $eventLabels = \Tywed\Webtrees\Module\Telegram\CustomOnThisDayModule::getEventLabels(); - + return [ 'config' => $config, 'users' => $users, @@ -131,19 +131,19 @@ public function configEdit(ServerRequestInterface $request, string $id): array public function configStore(ServerRequestInterface $request): ResponseInterface { $data = Validator::parsedBody($request); - + $name = $data->string('name', ''); $bot_token = $data->string('bot_token', ''); $chat_id = $data->string('chat_id', ''); $user_id = $data->string('user_id', ''); $tree_id = $data->string('tree_id', ''); - + // Validate required fields if (empty($name) || empty($bot_token) || empty($chat_id) || empty($user_id) || empty($tree_id)) { FlashMessages::addMessage(I18N::translate('Please fill in all required fields'), 'danger'); return redirect(route('module', ['module' => $this->module->name(), 'action' => 'ConfigAdd'])); } - + $config = [ 'id' => uniqid(), 'name' => $name, @@ -159,10 +159,10 @@ public function configStore(ServerRequestInterface $request): ResponseInterface 'start_message' => $data->string('start_message', ''), 'end_message' => $data->string('end_message', ''), ]; - + $this->telegramConfigService->saveConfig($config); FlashMessages::addMessage(I18N::translate('Configuration added successfully'), 'success'); - + return redirect(route('module', ['module' => $this->module->name(), 'action' => 'Admin'])); } @@ -176,19 +176,19 @@ public function configStore(ServerRequestInterface $request): ResponseInterface public function configUpdate(ServerRequestInterface $request, string $id): ResponseInterface { $data = Validator::parsedBody($request); - + $name = $data->string('name', ''); $bot_token = $data->string('bot_token', ''); $chat_id = $data->string('chat_id', ''); $user_id = $data->string('user_id', ''); $tree_id = $data->string('tree_id', ''); - + // Validate required fields if (empty($name) || empty($bot_token) || empty($chat_id) || empty($user_id) || empty($tree_id)) { FlashMessages::addMessage(I18N::translate('Please fill in all required fields'), 'danger'); return redirect(route('module', ['module' => $this->module->name(), 'action' => 'ConfigEdit', 'id' => $id])); } - + $config = [ 'id' => $id, 'name' => $name, @@ -204,10 +204,10 @@ public function configUpdate(ServerRequestInterface $request, string $id): Respo 'start_message' => $data->string('start_message', ''), 'end_message' => $data->string('end_message', ''), ]; - + $this->telegramConfigService->saveConfig($config, $id); FlashMessages::addMessage(I18N::translate('Configuration updated successfully'), 'success'); - + return redirect(route('module', ['module' => $this->module->name(), 'action' => 'Admin'])); } @@ -222,7 +222,7 @@ public function configDelete(ServerRequestInterface $request, string $id): Respo { $this->telegramConfigService->deleteConfig($id); FlashMessages::addMessage(I18N::translate('Configuration deleted successfully'), 'success'); - + return redirect(route('module', ['module' => $this->module->name(), 'action' => 'Admin'])); } diff --git a/src/CustomOnThisDayModule.php b/src/CustomOnThisDayModule.php index 7d99424..3596ce9 100644 --- a/src/CustomOnThisDayModule.php +++ b/src/CustomOnThisDayModule.php @@ -37,4 +37,4 @@ public static function getEventLabels(): array return $all_events; } -} \ No newline at end of file +} diff --git a/src/Helpers/AppHelper.php b/src/Helpers/AppHelper.php index 54537ac..7bdee5c 100644 --- a/src/Helpers/AppHelper.php +++ b/src/Helpers/AppHelper.php @@ -26,4 +26,4 @@ public static function get(string $class) throw new Exception('Can not find container resolver'); } -} \ No newline at end of file +} diff --git a/src/RequestHandlers/TelegramChangesCronJob.php b/src/RequestHandlers/TelegramChangesCronJob.php index 832417d..db6e30b 100644 --- a/src/RequestHandlers/TelegramChangesCronJob.php +++ b/src/RequestHandlers/TelegramChangesCronJob.php @@ -68,7 +68,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface ]; continue; } - + // Daily guard for changes $lastChangesLaunchJd = $config['last_changes_launch_jd'] ?? null; if ($lastChangesLaunchJd === $startJd) { @@ -78,7 +78,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface ]; continue; } - + // Prepare context (user, language, tree) via service $context = $this->telegramService->prepareCronContext( $config, @@ -140,5 +140,3 @@ function (string $message) use (&$results, $configId): void { ]); } } - - diff --git a/src/RequestHandlers/TelegramCronJob.php b/src/RequestHandlers/TelegramCronJob.php index 1bd7836..596ddbb 100644 --- a/src/RequestHandlers/TelegramCronJob.php +++ b/src/RequestHandlers/TelegramCronJob.php @@ -113,10 +113,10 @@ function (string $message) use (&$results, $configId): void { $events = $config['events'] ?? CustomOnThisDayModule::getDefaultEvents(); $event_array = is_array($events) ? $events : (is_string($events) ? explode(',', $events) : []); - + // Normalize event types: trim whitespace and filter empty values $event_array = array_filter(array_map('trim', $event_array), fn($e) => $e !== ''); - + $filter = $config['filter'] ?? true; $factList = $this->telegramService->getTodayFacts($event_array, $startJd, $startJd, $tree, $filter); @@ -140,7 +140,7 @@ function (string $message) use (&$results, $configId): void { } Auth::logout(); - + // Update last launch markers for this configuration (successful run) $config['last_launch'] = $currentTimestamp; // keep timestamp for UI display $config['last_launch_jd'] = $startJd; // use JD for daily guard @@ -149,20 +149,20 @@ function (string $message) use (&$results, $configId): void { } catch (\Exception $e) { Auth::logout(); // Ensure logout even on error - + // Check if this is a Telegram API error (not a general error) - $isTelegramError = strpos($e->getMessage(), 'Telegram') !== false || + $isTelegramError = strpos($e->getMessage(), 'Telegram') !== false || strpos($e->getMessage(), 'bot') !== false || strpos($e->getMessage(), 'chat') !== false || strpos($e->getMessage(), 'token') !== false; - + if ($isTelegramError) { // Update last_error for Telegram-related errors $config['last_error'] = $e->getMessage(); $config['last_error_date'] = $currentTimestamp; $this->telegramConfigService->saveConfig($config, $configId); } - + $results[$configId] = [ 'success' => false, 'message' => "Configuration \"{$configName}\": Error - " . $e->getMessage(), @@ -175,4 +175,4 @@ function (string $message) use (&$results, $configId): void { 'results' => $results, ]); } -} \ No newline at end of file +} diff --git a/src/Services/TelegramConfigService.php b/src/Services/TelegramConfigService.php index 306f341..e0bdc16 100644 --- a/src/Services/TelegramConfigService.php +++ b/src/Services/TelegramConfigService.php @@ -33,7 +33,7 @@ public function __construct(Telegram $module, UserService $userService, TreeServ public function getAllConfigs(): array { $configs = json_decode($this->module->getPreference(Telegram::CUSTOM_MODULE_CONFIGS, '[]'), true); - + // Ensure configs is always an array if (!is_array($configs)) { $configs = []; @@ -41,11 +41,11 @@ public function getAllConfigs(): array // Check if migration has already been done $migrationDone = $this->module->getPreference('telegram_migration_done', '0') === '1'; - + if (!$migrationDone) { // Migrate existing configs to new structure if needed $configs = $this->migrateConfigs($configs); - + // Mark migration as done $this->module->setPreference('telegram_migration_done', '1'); } @@ -112,12 +112,12 @@ public function getAllConfigs(): array private function migrateConfigs(array $configs): array { $migrated = false; - + foreach ($configs as $key => $config) { // Check if config needs migration (has old field names) if (isset($config['telegram_token']) || isset($config['telegram_id']) || isset($config['user']) || isset($config['tree'])) { $newConfig = $config; - + // Migrate field names if (isset($config['telegram_token'])) { $newConfig['bot_token'] = $config['telegram_token']; @@ -135,7 +135,7 @@ private function migrateConfigs(array $configs): array $newConfig['tree_id'] = $config['tree']; unset($newConfig['tree']); } - + // Add missing fields if (!isset($newConfig['enabled'])) { $newConfig['enabled'] = true; @@ -167,17 +167,17 @@ private function migrateConfigs(array $configs): array if (!isset($newConfig['last_error_date'])) { $newConfig['last_error_date'] = null; } - + $configs[$key] = $newConfig; $migrated = true; } } - + // Save migrated configs if any changes were made if ($migrated) { $this->saveAllConfigs($configs); } - + return $configs; } @@ -200,7 +200,7 @@ private function saveAllConfigs(array $configs): void public function getConfigById(string $id): ?array { $configs = $this->getAllConfigs(); - + foreach ($configs as $config) { if ($config['id'] === $id) { return $config; @@ -236,7 +236,7 @@ public function saveConfig(array $configData, ?string $id = null): array if (!isset($configData['id'])) { $configData['id'] = uniqid(); } - + // Check if ID already exists foreach ($configs as $config) { if ($config['id'] === $configData['id']) { @@ -245,7 +245,7 @@ public function saveConfig(array $configData, ?string $id = null): array break; } } - + $configs[] = $configData; $this->saveAllConfigs($configs); return $configData; diff --git a/src/Services/TelegramService.php b/src/Services/TelegramService.php index 73d2441..cc111c1 100644 --- a/src/Services/TelegramService.php +++ b/src/Services/TelegramService.php @@ -172,7 +172,7 @@ public function generateTelegramMessage(Collection $factList, array $config = nu if ($factType === '' || !isset($types[$factType])) { continue; } - + if (!isset($messages[$factType])) { $messages[$factType] = "🔸 {$types[$factType]}:\n"; } @@ -220,7 +220,7 @@ public function generateTelegramMessage(Collection $factList, array $config = nu $eventOrder = is_array($events) ? $events : (is_string($events) ? explode(',', $events) : []); - + // Normalize event types: trim whitespace and filter empty values $eventOrder = array_filter(array_map('trim', $eventOrder), fn($e) => $e !== ''); @@ -399,4 +399,4 @@ public function sendTelegramMessage(string $telegramToken, string $telegramId, s throw $e; } } -} \ No newline at end of file +} diff --git a/src/Telegram.php b/src/Telegram.php index 6e7d130..ece54c7 100644 --- a/src/Telegram.php +++ b/src/Telegram.php @@ -32,7 +32,7 @@ /** * Telegram Module - * + * * A module that sends Telegram notifications about significant family events */ class Telegram extends AbstractModule implements ModuleCustomInterface, ModuleGlobalInterface, ModuleConfigInterface, MiddlewareInterface @@ -61,7 +61,7 @@ public function __construct() { $userService = AppHelper::get(UserService::class); $treeService = AppHelper::get(TreeService::class); - + $this->telegramService = new TelegramService($this, $userService, $treeService); $this->telegramConfigService = new TelegramConfigService($this, $userService, $treeService); $this->telegramController = new TelegramController($this->telegramService, $this, $this->telegramConfigService); @@ -143,7 +143,7 @@ public function getChangesCronAction(ServerRequestInterface $request): ResponseI /** * HTTP request processing - * + * * @param ServerRequestInterface $request * @param RequestHandlerInterface $handler * @return ResponseInterface @@ -155,7 +155,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface /** * Path to module resources - * + * * @return string */ public function resourcesFolder(): string @@ -165,7 +165,7 @@ public function resourcesFolder(): string /** * Load translations - * + * * @param string $language * @return array */ @@ -187,7 +187,7 @@ public function customTranslations(string $language): array public function getAdminAction(ServerRequestInterface $request): ResponseInterface { $this->layout = 'layouts/administration'; - + $params = $this->telegramController->configsIndex($request); return $this->viewResponse($this->name() . '::configs-list', $params); } @@ -201,7 +201,7 @@ public function getAdminAction(ServerRequestInterface $request): ResponseInterfa public function postAdminAction(ServerRequestInterface $request): ResponseInterface { $action = Validator::parsedBody($request)->string('action', ''); - + switch ($action) { case 'delete': $id = Validator::parsedBody($request)->string('id', ''); @@ -227,7 +227,7 @@ public function postAdminAction(ServerRequestInterface $request): ResponseInterf public function getConfigAddAction(ServerRequestInterface $request): ResponseInterface { $this->layout = 'layouts/administration'; - + $params = $this->telegramController->configAdd($request); return $this->viewResponse($this->name() . '::config-form', $params); } @@ -252,22 +252,22 @@ public function postConfigAddAction(ServerRequestInterface $request): ResponseIn public function getConfigEditAction(ServerRequestInterface $request, string $id = ''): ResponseInterface { $this->layout = 'layouts/administration'; - + // If ID not provided as parameter, try to get from query parameters (for backward compatibility) if (empty($id)) { $id = Validator::queryParams($request)->string('id', ''); } - + if (empty($id)) { FlashMessages::addMessage(I18N::translate('Configuration ID not provided'), 'danger'); return redirect(route('module', ['module' => $this->name(), 'action' => 'Admin'])); } - + $params = $this->telegramController->configEdit($request, $id); if (empty($params)) { return redirect(route('module', ['module' => $this->name(), 'action' => 'Admin'])); } - + return $this->viewResponse($this->name() . '::config-form', $params); } @@ -283,4 +283,4 @@ public function postConfigEditAction(ServerRequestInterface $request): ResponseI return $this->telegramController->configUpdate($request, $id); } -} \ No newline at end of file +}