src/FlexApp/Service/AdsFilters/FilterAdsFilesDataService.php line 41

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace FlexApp\Service\AdsFilters;
  4. use Exception;
  5. use RuntimeException;
  6. use Symfony\Component\Yaml\Yaml;
  7. use WebBundle\Helper\ProxyHelper;
  8. /**
  9.  * Сервис для чтения файлов (локально или по SFTP), а также парсинга YAML-файлов с ссылками (Ads/Filters).
  10.  */
  11. class FilterAdsFilesDataService
  12. {
  13.     private const FILTERS_ADS_PATH_TEMPLATE 'var/filters_ads/links_%s.txt';
  14.     /**
  15.      * Универсальный метод чтения файла:
  16.      *  - Если !App::isGeneral(), то пытается прочитать файл локально.
  17.      *  - Если App::isGeneral(), то читает через SFTP, используя ProxyHelper::getConnection().
  18.      *
  19.      * @param string $relativePath Относительный путь к файлу, например:
  20.      *                             "var/sitemap/sitemap.da-dk_part1.xml"
  21.      *
  22.      * @return string Содержимое файла.
  23.      *
  24.      */
  25.     public function getFileContents(string $relativePath): string
  26.     {
  27.         $fullPath ProxyHelper::getFullPathByRelative($relativePath);
  28.         if (is_file($fullPath) && is_readable($fullPath)) {
  29.             $data = @file_get_contents($fullPath);
  30.             if ($data !== false) {
  31.                 return $data;
  32.             }
  33.         }
  34.         $conn ProxyHelper::getConnection(ProxyHelper::ADMIN_SERV_ID);
  35.         if (!is_resource($conn)) {
  36.             throw new RuntimeException(sprintf(
  37.                 'Файл [%s] не найден локально, и не удалось установить SSH-соединение (conn == null).',
  38.                 $fullPath
  39.             ));
  40.         }
  41.         $sftp = @ssh2_sftp($conn);
  42.         if (!is_resource($sftp)) {
  43.             throw new RuntimeException(sprintf(
  44.                 'Файл [%s] не найден локально, и SFTP-ресурс недоступен.',
  45.                 $fullPath
  46.             ));
  47.         }
  48.         $sftpPath sprintf('ssh2.sftp://%d/%s', (int) $sftpltrim($fullPath'/'));
  49.         $data = @file_get_contents($sftpPath);
  50.         if ($data === false) {
  51.             throw new RuntimeException(sprintf(
  52.                 'Не удалось прочитать файл [%s] ни локально, ни через SFTP.',
  53.                 $fullPath
  54.             ));
  55.         }
  56.         return $data;
  57.     }
  58.     /**
  59.      * Возвращает содержимое YAML-файла var/filters_ads/links_{locale}.txt
  60.      * (указанного в FILTERS_ADS_PATH_TEMPLATE) в виде массива.
  61.      *
  62.      * @param string $locale Код локали, например "ru".
  63.      *
  64.      * @return array Ассоциативный массив (распарсенные данные), либо [] если не удалось.
  65.      */
  66.     public function getFiltersAdsByLocale(string $locale): array
  67.     {
  68.         // Подставим локаль в шаблон пути
  69.         $relativePath sprintf(self::FILTERS_ADS_PATH_TEMPLATE$locale);
  70.         // Универсальное чтение (локально или через SFTP)
  71.         $content $this->getFileContents($relativePath);
  72.         try {
  73.             $parsed Yaml::parse($content);
  74.         } catch (Exception $e) {
  75.             throw new Exception(sprintf(
  76.                 'Ошибка парсинга YAML для локали "%s": %s',
  77.                 $locale,
  78.                 $e->getMessage()
  79.             ), 0$e);
  80.         }
  81.         if (!is_array($parsed)) {
  82.             return [];
  83.         }
  84.         return $parsed;
  85.     }
  86. }