use yii\base\DynamicModel;
use yii\helpers\Json;
use yii\web\UploadedFile;
+use yii_app\records\Files;
use yii_app\records\Images;
use yii_app\records\MatrixErp;
use yii_app\records\MatrixErpMedia;
$res['status'] = 'error';
$res['errors'][] = "Не удалось сохранить свойства для GUID {$matrix->guid}.";
}
+
}
} catch (\Throwable $e) {
$res['status'] = 'error';
return false;
}
+ $seen = [];
+ $adminId = Yii::$app->user->id ?? null;
+
+ if (!empty($matrixProduct['image_urls']) && is_array($matrixProduct['image_urls'])) {
+ $imageUrls = $matrixProduct['image_urls'];
+ foreach ($imageUrls as $imgUrl) {
+ $imgUrl = trim((string)$imgUrl);
+ if ($imgUrl === '' || isset($seen[$imgUrl])) {
+ continue;
+ }
+ $seen[$imgUrl] = true;
+
+ try {
+ $info = FileService::saveFromUrlToUploads($imgUrl, $adminId);
+ if (!empty($info) && $info['fileType'] === 'image') {
+ $this->saveMatrixMediaForMatrixProperty($info, 'foto', $matrixProductProperty, $adminId);
+ } elseif (!empty($info)) {
+ // На случай, если по ссылке оказался не image — можно пропустить или тоже сохранять как 'foto'
+ Yii::warning("Ожидали image, но получили {$info['fileType']} для {$imgUrl}");
+ }
+ } catch (\Throwable $e) {
+ Yii::error("Ошибка сохранения изображения {$imgUrl}: " . $e->getMessage());
+ }
+ }
+ }
+
+
+ if (!empty($matrixProduct['video_url'])) {
+ $videoUrl = trim((string)$matrixProduct['video_url']);
+ if ($videoUrl !== '' && !isset($seen[$videoUrl])) {
+ $seen[$videoUrl] = true;
+
+ try {
+ $info = FileService::saveFromUrlToUploads($videoUrl, $adminId);
+ if (!empty($info)) {
+ $name = ($info['fileType'] === 'video') ? 'video' : 'video';
+ $this->saveMatrixMediaForMatrixProperty($info, $name, $matrixProductProperty, $adminId);
+ }
+ } catch (\Throwable $e) {
+ Yii::error("Ошибка сохранения видео {$videoUrl}: " . $e->getMessage());
+ }
+ }
+ }
+
$matrixProductProperty->display_name = $matrixProduct['name'];
$matrixProductProperty->description = $matrixProduct['description'];
return $matrixProductProperty->save();
}
+
+ private function saveMatrixMediaForMatrixProperty(array $info, string $name, $matrixProp, $adminId) {
+ // Files
+ $file = new Files();
+ $file->created_at = date("Y-m-d H:i:s");
+ $file->entity_id = $matrixProp->id;
+ $file->entity = "matrix_media";
+ $file->file_type = $info['fileType']; // 'image' или 'video'
+ $file->url = $info['target_base_file'];
+ if(!$file->save()) {
+ Yii::error("Ошибка сохранения в файлы " . json_encode($file->getErrors(), JSON_UNESCAPED_UNICODE));
+ }
+
+ // MatrixErpMedia
+ $mm = new MatrixErpMedia();
+ $mm->guid = $matrixProp->guid;
+ $mm->created_admin_id = $adminId;
+ $mm->date = date("Y-m-d H:i:s");
+ $mm->created_at = date("Y-m-d H:i:s");
+ $mm->file_id = $file->id;
+ $mm->name = $name; // 'foto' или 'video'
+
+ if(!$mm->save()) {
+ Yii::error("Ошибка сохранения в медиа " . json_encode($mm->getErrors(), JSON_UNESCAPED_UNICODE));
+ }
+ }
}
\ No newline at end of file
namespace yii_app\services;
use GuzzleHttp\Client;
+use GuzzleHttp\Exception\GuzzleException;
use Yii;
use yii\helpers\ArrayHelper;
use yii\helpers\FileHelper;
return $uploaded;
}
+ public static function saveFromUrlToUploads(string $url, int $adminId): ?array
+ {
+ if (!filter_var($url, FILTER_VALIDATE_URL)) {
+ Yii::error("Недопустимый URL: {$url}");
+ return null;
+ }
+
+ $client = new Client([
+ 'headers' => [
+ 'User-Agent' => 'Mozilla/5.0 (compatible; ERP24 Downloader)',
+ 'Accept' => '*/*',
+ ],
+ 'allow_redirects' => ['max' => 5],
+ 'connect_timeout' => 10,
+ 'timeout' => 30,
+ 'http_errors' => false,
+ 'verify' => true, // лучше включить SSL
+ ]);
+
+ $tmp = tempnam(sys_get_temp_dir(), 'dl_');
+ if ($tmp === false) {
+ Yii::error("Не удалось создать временный файл для {$url}");
+ return null;
+ }
+
+ try {
+ $response = $client->request('GET', $url, ['sink' => $tmp]);
+ } catch (GuzzleException $e) {
+ @unlink($tmp);
+ Yii::error("Ошибка сети при загрузке {$url}: " . $e->getMessage());
+ return null;
+ }
+
+ $status = $response->getStatusCode();
+ if ($status >= 400) {
+ @unlink($tmp);
+ Yii::error("Ошибка загрузки {$url}: HTTP {$status}");
+ return null;
+ }
+
+ // Заголовки
+ $contentType = trim(explode(';', $response->getHeaderLine('Content-Type'))[0] ?? '');
+
+ $mimeMap = [
+ 'image/jpeg' => 'jpg',
+ 'image/png' => 'png',
+ 'image/webp' => 'webp',
+ 'image/gif' => 'gif',
+ 'video/mp4' => 'mp4',
+ 'video/webm' => 'webm',
+ 'video/quicktime' => 'mov',
+ 'video/x-msvideo' => 'avi',
+ 'video/mpeg' => 'mpeg',
+ ];
+
+ $pathExt = strtolower(pathinfo(parse_url($url, PHP_URL_PATH) ?? '', PATHINFO_EXTENSION));
+ $ext = $mimeMap[$contentType] ?? ($pathExt ?: 'bin');
+
+ $fileType = str_starts_with($contentType, 'image/') ? 'image'
+ : (str_starts_with($contentType, 'video/') ? 'video' : $ext);
+
+ $basename = basename(parse_url($url, PHP_URL_PATH) ?? '') ?: 'file';
+ $basename = preg_replace('/[^\pL\pN._-]+/u', '_', $basename) ?: 'file';
+
+ // Папки
+ $uploadDir = \Yii::getAlias('@uploads');
+ $targetDir = $uploadDir . "/{$adminId}/" . date("Y/m/d") . "/";
+ $targetBaseDir = "/uploads/{$adminId}/" . date("Y/m/d") . "/";
+
+ if (!is_dir($targetDir) && !mkdir($targetDir, 0777, true) && !is_dir($targetDir)) {
+ @unlink($tmp);
+ Yii::error("Не удалось создать директорию {$targetDir}");
+ return null;
+ }
+
+ if ($pathExt && str_ends_with(strtolower($basename), '.' . $pathExt)) {
+ $basename = substr($basename, 0, -(strlen($pathExt) + 1));
+ }
+
+ if (strlen($basename) > 100) {
+ $basename = substr($basename, 0, 100);
+ }
+
+ $filename = date("His") . '_' . substr(md5($url . microtime(true)), 0, 8) . '_' . $basename . '.' . $ext;
+ $targetFile = $targetDir . $filename;
+ $targetBaseFile = $targetBaseDir . $filename;
+
+ if (!@rename($tmp, $targetFile)) {
+ if (!@copy($tmp, $targetFile)) {
+ @unlink($tmp);
+ Yii::error("Не удалось сохранить файл {$url} в {$targetFile}");
+ return null;
+ }
+ @unlink($tmp);
+ }
+
+ return [
+ 'fileType' => $fileType,
+ 'target_file' => $targetFile,
+ 'target_base_dir' => $targetBaseDir,
+ 'target_base_file' => $targetBaseFile,
+ 'mime' => $contentType,
+ 'ext' => $ext,
+ 'source_url' => $url,
+ ];
+ }
+
}
$result[] = [
'id' => $product->id,
'name' => $properties['displayName'],
- 'pictures' => [$properties['imageUrl']],
+ 'pictures' => $properties['imageUrls'],
'price' => $price,
'oldprice' => MarketplaceService::getProductOldPrice($product->id),
'description' => MarketplaceService::getProductDescription($product->id),
'productUrl' => $product->product_url ?? self::getProductLinkByGuid($product->guid),
'flowwowCategory' => $product->flowwow_category,
'flowwowSubcategory' => $product->flowwow_subcategory,
+ 'imageUrls' => self::getProductImageUrls($product->guid),
];
}
return null;
}
+ public static function getProductImageUrls($guid)
+ {
+ $urls = [];
+ $data = MatrixErpMedia::find()
+ ->where(['guid' => $guid])
+ ->all();
+ foreach ($data as $media) {
+ if (!empty($data->file)) {
+ $resultData = FileService::getFile($data->file);
+ if (File::src($resultData, 'images') != null) {
+ $fileName = File::src($resultData, 'images');
+ $urls[] = 'https://media.erp-flowers.ru/media/view-url?url=' . $fileName;
+ }
+ }
+ }
+ return $urls;
+ }
+
public static function getProductLinkByGuid($guid)
{
return 'https://media.erp-flowers.ru/media/view-card?guid=' . urlencode($guid);
return null;
}
- return $product->lenghth ?? 20;
+ return $product->lenghth ?? null;
}
private static function getProductParams($productId)
{
- return [
+
+ $params = [
'Ширина, См' => self::getProductWidth($productId),
'Высота, См' => self::getProductHeight($productId),
- 'Длина, См' => self::getProductLength($productId),
+
];
+ if (self::getProductLength($productId)) {
+ array_push($params, ['Длина, См' => self::getProductLength($productId)]);
+ }
+
+ return $params;
}
/**
* Получает данные о заказах для указанных кампаний с учетом фильтров.