true, 'cache_ttl' => 7200, 'sitemap_cache_ttl' => 86400, ]; /** * 마이그레이션 식별자 (로그용). * * @return string 식별자 */ public function name(): string { return 'NullifyUntouchedSeoCacheOverrides'; } /** * 옛 기본값 그대로인 SEO 캐시 키를 null(미설정)로 비웁니다. * * @param UpgradeContext $context 업그레이드 컨텍스트 */ public function run(UpgradeContext $context): void { try { $this->runInternal($context); } catch (\Throwable $e) { // 업그레이드 중단 금지 — 설정 정리 실패가 업그레이드 전체를 막지 않는다. $context->logger->warning(sprintf( '[7.0.6] NullifyUntouchedSeoCacheOverrides 실패 (seo.json 보존, 계속 진행): %s', $e->getMessage(), )); Log::warning('7.0.6 NullifyUntouchedSeoCacheOverrides 실패', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); } } /** * 실제 이행 로직. * * @param UpgradeContext $context 업그레이드 컨텍스트 */ private function runInternal(UpgradeContext $context): void { $settings = $this->readSeoSettings($context); if ($settings === null) { return; } $cleared = []; $kept = []; foreach (self::LEGACY_DEFAULTS as $key => $legacyDefault) { if (! array_key_exists($key, $settings) || $settings[$key] === null) { continue; } // 옛 기본값과 완전히 같을 때만 "안 건드림" 으로 본다 (타입까지 일치 요구) if ($settings[$key] === $legacyDefault) { $settings[$key] = null; $cleared[] = $key; continue; } $kept[$key] = $settings[$key]; } foreach ($kept as $key => $value) { $context->logger->info(sprintf( '[7.0.6] seo.%s = %s 는 옛 기본값과 달라 오버라이드로 보존 — 이제부터 실제 적용됩니다', $key, var_export($value, true), )); } if ($cleared === []) { $context->logger->info('[7.0.6] SEO 캐시 설정 — 비울 대상 없음 (이미 이행 완료이거나 전부 오버라이드)'); return; } $this->writeSeoSettings($settings); $context->logger->info('[7.0.6] SEO 캐시 설정 — 미설정(null)으로 비운 키: '.implode(', ', $cleared)); } /** * seo 설정 카테고리를 읽습니다. * * @param UpgradeContext $context 업그레이드 컨텍스트 * @return array|null 설정 배열 (파일 부재/손상 시 null) */ private function readSeoSettings(UpgradeContext $context): ?array { if (! Storage::disk('settings')->exists(self::SEO_SETTINGS_FILE)) { $context->logger->info('[7.0.6] seo.json 부재 — 정리 대상 없음, skip'); return null; } $decoded = json_decode((string) Storage::disk('settings')->get(self::SEO_SETTINGS_FILE), true); if (! is_array($decoded)) { // 손상 파일을 덮어쓰지 않는다 (파괴 금지) $context->logger->warning('[7.0.6] seo.json 파싱 실패 — 파일 보존하고 skip'); return null; } return $decoded; } /** * seo 설정 카테고리를 저장합니다. * * @param array $settings 저장할 설정 배열 */ private function writeSeoSettings(array $settings): void { Storage::disk('settings')->put( self::SEO_SETTINGS_FILE, json_encode($settings, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), ); } }