<?php
declare(strict_types=1);
namespace FlexApp\Service\AdsFilters;
use Exception;
use RuntimeException;
use Symfony\Component\Yaml\Yaml;
use WebBundle\Helper\ProxyHelper;
/**
* Сервис для чтения файлов (локально или по SFTP), а также парсинга YAML-файлов с ссылками (Ads/Filters).
*/
class FilterAdsFilesDataService
{
private const FILTERS_ADS_PATH_TEMPLATE = 'var/filters_ads/links_%s.txt';
/**
* Универсальный метод чтения файла:
* - Если !App::isGeneral(), то пытается прочитать файл локально.
* - Если App::isGeneral(), то читает через SFTP, используя ProxyHelper::getConnection().
*
* @param string $relativePath Относительный путь к файлу, например:
* "var/sitemap/sitemap.da-dk_part1.xml"
*
* @return string Содержимое файла.
*
*/
public function getFileContents(string $relativePath): string
{
$fullPath = ProxyHelper::getFullPathByRelative($relativePath);
if (is_file($fullPath) && is_readable($fullPath)) {
$data = @file_get_contents($fullPath);
if ($data !== false) {
return $data;
}
}
$conn = ProxyHelper::getConnection(ProxyHelper::ADMIN_SERV_ID);
if (!is_resource($conn)) {
throw new RuntimeException(sprintf(
'Файл [%s] не найден локально, и не удалось установить SSH-соединение (conn == null).',
$fullPath
));
}
$sftp = @ssh2_sftp($conn);
if (!is_resource($sftp)) {
throw new RuntimeException(sprintf(
'Файл [%s] не найден локально, и SFTP-ресурс недоступен.',
$fullPath
));
}
$sftpPath = sprintf('ssh2.sftp://%d/%s', (int) $sftp, ltrim($fullPath, '/'));
$data = @file_get_contents($sftpPath);
if ($data === false) {
throw new RuntimeException(sprintf(
'Не удалось прочитать файл [%s] ни локально, ни через SFTP.',
$fullPath
));
}
return $data;
}
/**
* Возвращает содержимое YAML-файла var/filters_ads/links_{locale}.txt
* (указанного в FILTERS_ADS_PATH_TEMPLATE) в виде массива.
*
* @param string $locale Код локали, например "ru".
*
* @return array Ассоциативный массив (распарсенные данные), либо [] если не удалось.
*/
public function getFiltersAdsByLocale(string $locale): array
{
// Подставим локаль в шаблон пути
$relativePath = sprintf(self::FILTERS_ADS_PATH_TEMPLATE, $locale);
// Универсальное чтение (локально или через SFTP)
$content = $this->getFileContents($relativePath);
try {
$parsed = Yaml::parse($content);
} catch (Exception $e) {
throw new Exception(sprintf(
'Ошибка парсинга YAML для локали "%s": %s',
$locale,
$e->getMessage()
), 0, $e);
}
if (!is_array($parsed)) {
return [];
}
return $parsed;
}
}