Исправление контроллера ошибок и моделей продуктов
This commit is contained in:
parent
912b25bea2
commit
c169347687
|
@ -15,16 +15,16 @@ class ErrorController extends Controller
|
||||||
// Исключение не выброшено
|
// Исключение не выброшено
|
||||||
|
|
||||||
// Запись кода ошибки
|
// Запись кода ошибки
|
||||||
$statusCode = $exception->statusCode;
|
$statusCode = $exception->statusCode ?? $exception->getCode() ?? 0;
|
||||||
|
|
||||||
// Запись названия ошибки
|
// Запись названия ошибки
|
||||||
$name = match ($exception->statusCode) {
|
$name = match ($statusCode) {
|
||||||
404 => '404 (Не найдено)',
|
404 => '404 (Не найдено)',
|
||||||
default => $exception->getName()
|
default => $exception->getName()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Запись сообщения об ошибке
|
// Запись сообщения об ошибке
|
||||||
$message = match ($exception->statusCode) {
|
$message = match ($statusCode) {
|
||||||
404 => 'Страница не найдена',
|
404 => 'Страница не найдена',
|
||||||
default => $exception->getMessage()
|
default => $exception->getMessage()
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,415 +2,469 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\controllers;
|
namespace app\models;
|
||||||
|
|
||||||
use yii;
|
use yii;
|
||||||
use yii\filters\AccessControl;
|
|
||||||
use yii\web\Controller;
|
|
||||||
use yii\web\Response;
|
|
||||||
use yii\web\HttpException;
|
|
||||||
use yii\web\UploadedFile;
|
use yii\web\UploadedFile;
|
||||||
|
use yii\imagine\Image;
|
||||||
|
|
||||||
use app\models\Product;
|
use app\models\traits\SearchByEdge;
|
||||||
|
use Exception;
|
||||||
|
use moonland\phpexcel\Excel;
|
||||||
|
|
||||||
class ProductController extends Controller
|
/**
|
||||||
|
* Продукт (в ассортименте магазина)
|
||||||
|
*
|
||||||
|
* Представляет собой лот состоящий из предложений от поставщиков
|
||||||
|
*
|
||||||
|
* @see Supply Поставки для продуктов
|
||||||
|
*/
|
||||||
|
class Product extends Document
|
||||||
{
|
{
|
||||||
public function actionIndex(string $catn): array|string|null
|
use SearchByEdge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сценарий импорта .excel документа
|
||||||
|
*
|
||||||
|
* Использовать для обхода правил при загрузке файла
|
||||||
|
*/
|
||||||
|
const SCENARIO_IMPORT_EXCEL = 'import_excel';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сценарий импорта изображений
|
||||||
|
*
|
||||||
|
* Использовать для обхода правил при загрузке файла
|
||||||
|
*/
|
||||||
|
const SCENARIO_IMPORT_IMAGE = 'import_image';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сценарий записи товара
|
||||||
|
*/
|
||||||
|
const SCENARIO_WRITE = 'write';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Файл .excel для импорта товаров
|
||||||
|
*/
|
||||||
|
public Excel|string|array|null $file_excel = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Изображение для импорта
|
||||||
|
*/
|
||||||
|
public UploadedFile|string|array|null $file_image = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Группа в которой состоит товар
|
||||||
|
*/
|
||||||
|
public ProductGroup|null $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
|
public static function collectionName(): string
|
||||||
{
|
{
|
||||||
if ($model = Product::searchByCatn($catn)) {
|
return 'product';
|
||||||
// Товар найден
|
|
||||||
|
|
||||||
if (yii::$app->request->isAjax) {
|
|
||||||
// AJAX-POST-запрос
|
|
||||||
|
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'main' => $this->renderPartial('index', compact('model')),
|
|
||||||
'redirect' => '/product/' . $catn,
|
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('index', compact('model'));
|
|
||||||
} else {
|
|
||||||
throw new HttpException(404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function actionEditTitle(string $catn): array|string|null
|
|
||||||
{
|
|
||||||
// Инициализация
|
|
||||||
$return = [
|
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
|
||||||
];
|
|
||||||
|
|
||||||
if (is_null($catn)) {
|
|
||||||
// Не получен артикул
|
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($model = Product::searchByCatn($catn)) {
|
|
||||||
// Товар найден
|
|
||||||
|
|
||||||
// Инициализация
|
|
||||||
$text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия';
|
|
||||||
|
|
||||||
$model->name = $text;
|
|
||||||
|
|
||||||
if ($model->save()) {
|
|
||||||
// Товар обновлён
|
|
||||||
|
|
||||||
$return['name'] = $text;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Конец алгоритма
|
* Свойства
|
||||||
*/
|
*/
|
||||||
end:
|
public function attributes(): array
|
||||||
|
|
||||||
if (yii::$app->request->isPost) {
|
|
||||||
// POST-запрос
|
|
||||||
|
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
|
||||||
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($model = Product::searchByCatn($catn)) {
|
|
||||||
return $this->render('index', compact('model'));
|
|
||||||
} else {
|
|
||||||
return $this->redirect('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function actionEditCatn(string $catn): array|string|null
|
|
||||||
{
|
{
|
||||||
// Инициализация
|
return array_merge(
|
||||||
$return = [
|
parent::attributes(),
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
|
||||||
];
|
|
||||||
|
|
||||||
if (is_null($catn)) {
|
|
||||||
// Не получен артикул
|
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($model = Product::searchByCatn($catn)) {
|
|
||||||
// Товар найден
|
|
||||||
|
|
||||||
// Инициализация
|
|
||||||
$text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия';
|
|
||||||
|
|
||||||
$model->catn = $text;
|
|
||||||
|
|
||||||
if ($model->save()) {
|
|
||||||
// Товар обновлён
|
|
||||||
|
|
||||||
$return['main'] = $this->renderPartial('index', compact('model'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Конец алгоритма
|
|
||||||
*/
|
|
||||||
end:
|
|
||||||
|
|
||||||
if (yii::$app->request->isPost) {
|
|
||||||
// POST-запрос
|
|
||||||
|
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
|
||||||
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($model = Product::searchByCatn($catn)) {
|
|
||||||
return $this->render('index', compact('model'));
|
|
||||||
} else {
|
|
||||||
return $this->redirect('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function actionEditDscr(string $catn): array|string|null
|
|
||||||
{
|
|
||||||
// Инициализация
|
|
||||||
$return = [
|
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
|
||||||
];
|
|
||||||
|
|
||||||
if (is_null($catn)) {
|
|
||||||
// Не получен артикул
|
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($product = Product::searchByCatn($catn)) {
|
|
||||||
// Товар найден
|
|
||||||
|
|
||||||
// Инициализация
|
|
||||||
$text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия';
|
|
||||||
|
|
||||||
$product->dscr = $text;
|
|
||||||
|
|
||||||
if ($product->save()) {
|
|
||||||
// Товар обновлён
|
|
||||||
|
|
||||||
$return['description'] = $text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Конец алгоритма
|
|
||||||
*/
|
|
||||||
end:
|
|
||||||
|
|
||||||
if (yii::$app->request->isPost) {
|
|
||||||
// POST-запрос
|
|
||||||
|
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
|
||||||
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($model = Product::searchByCatn($catn)) {
|
|
||||||
return $this->render('index', compact('model'));
|
|
||||||
} else {
|
|
||||||
return $this->redirect('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function actionEditDmns(string $catn): array|string|null
|
|
||||||
{
|
|
||||||
// Инициализация
|
|
||||||
$return = [
|
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
|
||||||
];
|
|
||||||
|
|
||||||
if (is_null($catn)) {
|
|
||||||
// Не получен артикул
|
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($product = Product::searchByCatn($catn)) {
|
|
||||||
// Товар найден
|
|
||||||
|
|
||||||
// Инициализация
|
|
||||||
$text = yii::$app->request->post('text') ?? yii::$app->request->get('text') ?? '0';
|
|
||||||
$text or $text = '0';
|
|
||||||
$dimension = yii::$app->request->post('dimension') ?? yii::$app->request->get('dimension') ?? 'x';
|
|
||||||
|
|
||||||
$product->dmns = array_merge(
|
|
||||||
$product->dmns ?? [],
|
|
||||||
[
|
[
|
||||||
$dimension => $text
|
'catn',
|
||||||
|
'name',
|
||||||
|
// В библеотеке есть баг на название DESC (неизвестно в моей или нет)
|
||||||
|
'dscr',
|
||||||
|
'prod',
|
||||||
|
'dmns',
|
||||||
|
'imgs',
|
||||||
|
'time'
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($product->save()) {
|
|
||||||
// Товар обновлён
|
|
||||||
|
|
||||||
$return['dimension'] = $text;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Конец алгоритма
|
* Метки свойств
|
||||||
*/
|
*/
|
||||||
end:
|
public function attributeLabels(): array
|
||||||
|
|
||||||
if (yii::$app->request->isPost) {
|
|
||||||
// POST-запрос
|
|
||||||
|
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
|
||||||
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($model = Product::searchByCatn($catn)) {
|
|
||||||
return $this->render('index', compact('model'));
|
|
||||||
} else {
|
|
||||||
return $this->redirect('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function actionWriteImage(string $catn): array|string|null
|
|
||||||
{
|
{
|
||||||
// Инициализация
|
return array_merge(
|
||||||
$return = [
|
parent::attributeLabels(),
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
[
|
||||||
];
|
'catn' => 'Каталожный номер (catn)',
|
||||||
|
'name' => 'Название (name)',
|
||||||
if (is_null($catn)) {
|
'dscr' => 'Описание (dscr)',
|
||||||
// Не получен артикул
|
'prod' => 'Производитель (prod)',
|
||||||
|
'dmns' => 'Габариты (dmns)',
|
||||||
yii::$app->response->statusCode = 500;
|
'imgs' => 'Изображения (imgs)',
|
||||||
|
'time' => 'Срок доставки (time)',
|
||||||
goto end;
|
'file_excel' => 'Документ (file_excel)',
|
||||||
}
|
'file_image' => 'Изображение (file_image)',
|
||||||
|
'group' => 'Группа (group)'
|
||||||
if ($product = Product::searchByCatn($catn)) {
|
]
|
||||||
// Товар найден
|
);
|
||||||
|
|
||||||
// Инициализация
|
|
||||||
$product->file_image = UploadedFile::getInstancesByName('images');
|
|
||||||
$product->scenario = $product::SCENARIO_IMPORT_IMAGE;
|
|
||||||
|
|
||||||
if ($product->importImages() > 0) {
|
|
||||||
// Товар обновлён
|
|
||||||
|
|
||||||
$return['main'] = $this->renderPartial('index', ['model' => $product]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Конец алгоритма
|
* Правила
|
||||||
*/
|
*/
|
||||||
end:
|
public function rules(): array
|
||||||
|
{
|
||||||
if (yii::$app->request->isPost) {
|
return array_merge(
|
||||||
// POST-запрос
|
parent::rules(),
|
||||||
|
[
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
[
|
||||||
|
'catn',
|
||||||
return $return;
|
'required',
|
||||||
|
'message' => 'Заполните поля: {attribute}',
|
||||||
|
'on' => self::SCENARIO_WRITE,
|
||||||
|
'except' => [self::SCENARIO_IMPORT_EXCEL, self::SCENARIO_IMPORT_IMAGE]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'catn',
|
||||||
|
'string',
|
||||||
|
'message' => '{attribute} должен быть строкой'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'imgs',
|
||||||
|
'arrayValidator',
|
||||||
|
'message' => '{attribute} должен быть массивом'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'dmns',
|
||||||
|
'arrayWithNumbersValidator',
|
||||||
|
'message' => '{attribute} должен быть массивом и хранить циферные значения'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'file_excel',
|
||||||
|
'required',
|
||||||
|
'message' => 'Заполните поля: {attribute}',
|
||||||
|
'on' => self::SCENARIO_IMPORT_EXCEL
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'file_excel',
|
||||||
|
'file',
|
||||||
|
'skipOnEmpty' => false,
|
||||||
|
'extensions' => 'xlsx',
|
||||||
|
'checkExtensionByMimeType' => false,
|
||||||
|
'maxFiles' => 5,
|
||||||
|
'maxSize' => 1024 * 1024 * 30,
|
||||||
|
'wrongExtension' => 'Разрешены только документы в формате: ".xlsx"',
|
||||||
|
'message' => 'Проблема при чтении документа',
|
||||||
|
'on' => self::SCENARIO_IMPORT_EXCEL
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'file_image',
|
||||||
|
'required',
|
||||||
|
'message' => 'Загрузите изображение',
|
||||||
|
'on' => self::SCENARIO_IMPORT_IMAGE
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'file_image',
|
||||||
|
'file',
|
||||||
|
'skipOnEmpty' => false,
|
||||||
|
'extensions' => ['jpg', 'jpeg', 'png', 'gif', 'webp'],
|
||||||
|
'checkExtensionByMimeType' => true,
|
||||||
|
'maxFiles' => 10,
|
||||||
|
'maxSize' => 1024 * 1024 * 30,
|
||||||
|
'wrongExtension' => 'Разрешены только изображения в формате: ".jpg", ".jpeg", ".png", ".gif", ".webp"',
|
||||||
|
'message' => 'Проблема при загрузке изображения',
|
||||||
|
'on' => self::SCENARIO_IMPORT_IMAGE
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($model = Product::searchByCatn($catn)) {
|
/**
|
||||||
return $this->render('index', compact('model'));
|
* Запись пустого продукта
|
||||||
} else {
|
*/
|
||||||
return $this->redirect('/');
|
public static function writeEmpty(string $catn): ?self
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function actionDeleteImage(string $catn): array|string|null
|
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$return = [
|
$model = new self;
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
|
||||||
];
|
|
||||||
$index = yii::$app->request->post('index') ?? yii::$app->request->get('index');
|
|
||||||
|
|
||||||
if (is_null($catn) || is_null($index)) {
|
// Настройки
|
||||||
// Не получены обязательные параметры
|
$model->catn = $catn;
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($product = Product::searchByCatn($catn)) {
|
|
||||||
// Товар найден
|
|
||||||
|
|
||||||
// Инициализация (буфер нужен из-за кривых сеттеров)
|
|
||||||
$buffer = $product->imgs;
|
|
||||||
|
|
||||||
// Удаление
|
|
||||||
unset($buffer[$index]);
|
|
||||||
|
|
||||||
// Запись
|
// Запись
|
||||||
$product->imgs = $buffer;
|
return $model->save() ? $model : null;
|
||||||
|
|
||||||
if ($product->save()) {
|
|
||||||
// Товар обновлён
|
|
||||||
|
|
||||||
$return['main'] = $this->renderPartial('index', ['model' => $product]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Конец алгоритма
|
* Импорт изображений
|
||||||
|
*
|
||||||
|
* @return int Количество сохранённых изображений
|
||||||
*/
|
*/
|
||||||
end:
|
public function importImages(): int
|
||||||
|
|
||||||
if (yii::$app->request->isPost) {
|
|
||||||
// POST-запрос
|
|
||||||
|
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
|
||||||
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($model = Product::searchByCatn($catn)) {
|
|
||||||
return $this->render('index', compact('model'));
|
|
||||||
} else {
|
|
||||||
return $this->redirect('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function actionWriteCover(string $catn): array|string|null
|
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$return = [
|
$amount = 0;
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
|
||||||
];
|
|
||||||
$index = yii::$app->request->post('index') ?? yii::$app->request->get('index');
|
|
||||||
|
|
||||||
if (is_null($catn) || is_null($index)) {
|
if ($this->validate()) {
|
||||||
// Не получены обязательные параметры
|
// Проверка пройдена
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
foreach ($this->file_image as $file) {
|
||||||
|
// Перебор обрабатываемых изображений
|
||||||
|
|
||||||
goto end;
|
if (!file_exists(YII_PATH_PUBLIC . $catalog = '/img/products/' . $this->_key)) {
|
||||||
|
// Директория для изображений продукта не найдена
|
||||||
|
|
||||||
|
if (!mkdir(YII_PATH_PUBLIC . $catalog, 0775, true)) {
|
||||||
|
// Не удалось записать директорию
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($product = Product::searchByCatn($catn)) {
|
|
||||||
// Товар найден
|
|
||||||
|
|
||||||
// Инициализация (буфер нужен из-за кривых сеттеров)
|
if (!file_exists(YII_PATH_PUBLIC . $catalog_h150 = '/img/products/' . $this->_key . '/h150')) {
|
||||||
$buffer = $product->imgs;
|
// Директория для обложек изображений продукта не найдена
|
||||||
|
|
||||||
foreach($buffer as $image_index => &$image) {
|
if (!mkdir(YII_PATH_PUBLIC . $catalog_h150, 0775, true)) {
|
||||||
// Перебор изображений
|
// Не удалось записать директорию
|
||||||
|
|
||||||
if ($image_index === (int) $index) {
|
return false;
|
||||||
// Найдено запрашиваемое изображение
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Установка обложки
|
// Запись на сервер
|
||||||
$image['covr'] = true;
|
$file->saveAs(YII_PATH_PUBLIC . $catalog . '/' . $file->baseName . '.' . $file->extension . '.original');
|
||||||
} else {
|
|
||||||
$image['covr'] = false;
|
// Конвертация изображения для сохранения полного изображения
|
||||||
|
Image::resize(YII_PATH_PUBLIC . $catalog . '/' . $file->baseName . '.' . $file->extension . '.original', 800, 800)
|
||||||
|
->save(YII_PATH_PUBLIC . $catalog . '/' . $file->baseName . '.' . $file->extension, ['quality' => 80]);
|
||||||
|
|
||||||
|
// Конвертация изображения для сохранения обложки (150px)
|
||||||
|
Image::resize(YII_PATH_PUBLIC . $catalog . '/' . $file->baseName . '.' . $file->extension, 150, 150)
|
||||||
|
->save(YII_PATH_PUBLIC . $catalog_h150 . '/' . $file->baseName . '.' . $file->extension, ['quality' => 80]);
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$this->imgs ?? $this->imgs = [];
|
||||||
|
|
||||||
|
// Запись в базу данных
|
||||||
|
$this->imgs = array_merge(
|
||||||
|
$this->imgs,
|
||||||
|
[[
|
||||||
|
'covr' => count($this->imgs) === 0 ? true : false,
|
||||||
|
'orig' => $catalog . '/' . $file->baseName . '.' . $file->extension,
|
||||||
|
'h150' => $catalog_h150 . '/' . $file->baseName . '.' . $file->extension
|
||||||
|
]]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->scenario = self::SCENARIO_WRITE;
|
||||||
|
|
||||||
|
if ($this->save()) {
|
||||||
|
// Изменения сохранены в базе данных
|
||||||
|
|
||||||
|
// Постинкрементация счётчика
|
||||||
|
$amount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Запись
|
if ($this->hasErrors()) {
|
||||||
$product->imgs = $buffer;
|
// Получены ошибки
|
||||||
|
|
||||||
if ($product->save()) {
|
foreach ($this->getErrors() as $attribute => $errors) {
|
||||||
// Товар обновлён
|
// Перебор атрибутов
|
||||||
|
|
||||||
$return['main'] = $this->renderPartial('index', ['model' => $product]);
|
foreach ($errors as $error) {
|
||||||
|
// Перебор ошибок атрибутов
|
||||||
|
|
||||||
|
$label = $this->getAttributeLabel($attribute);
|
||||||
|
|
||||||
|
Notification::_write("$label: $error", type: Notification::TYPE_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $amount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Конец алгоритма
|
* Импорт товаров
|
||||||
|
*
|
||||||
|
* На данный момент обрабатывает только импорт из
|
||||||
|
* файлов с расширением .excel
|
||||||
*/
|
*/
|
||||||
end:
|
public function importExcel(): bool
|
||||||
|
{
|
||||||
|
// Инициализация
|
||||||
|
$data = [];
|
||||||
|
$amount = 0;
|
||||||
|
|
||||||
if (yii::$app->request->isPost) {
|
if ($this->validate()) {
|
||||||
// POST-запрос
|
foreach ($this->file_excel as $file) {
|
||||||
|
// Перебор файлов
|
||||||
|
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
// Инициализация
|
||||||
|
$dir = '../assets/import/' . date('Y_m_d#H-i', time()) . '/excel/';
|
||||||
|
|
||||||
return $return;
|
// Сохранение на диск
|
||||||
|
if (!file_exists($dir)) {
|
||||||
|
mkdir($dir, 0775, true);
|
||||||
|
}
|
||||||
|
$file->saveAs($path = $dir . $file->baseName . '.' . $file->extension);
|
||||||
|
|
||||||
|
$data[] = Excel::import($path, [
|
||||||
|
'setFirstRecordAsKeys' => true,
|
||||||
|
'setIndexSheetByName' => true,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($model = Product::searchByCatn($catn)) {
|
|
||||||
return $this->render('index', compact('model'));
|
foreach ($data as $data) {
|
||||||
|
// Перебор конвертированных файлов
|
||||||
|
|
||||||
|
if (count($data) < 1) {
|
||||||
|
// Не найдены строки с товарами
|
||||||
|
|
||||||
|
$this->addError('erros', 'Не удалось найти данные товаров');
|
||||||
} else {
|
} else {
|
||||||
return $this->redirect('/');
|
// Перебор найденных товаров
|
||||||
|
|
||||||
|
foreach ($data as $doc) {
|
||||||
|
// Перебор полученных документов
|
||||||
|
|
||||||
|
// Сохранение в базе данных
|
||||||
|
$product = new static($doc);
|
||||||
|
|
||||||
|
$product->scenario = $product::SCENARIO_WRITE;
|
||||||
|
|
||||||
|
if ($product->validate()) {
|
||||||
|
// Проверка пройдена
|
||||||
|
|
||||||
|
// Запись документа
|
||||||
|
$product->save();
|
||||||
|
|
||||||
|
// Постинкрементация счётчика
|
||||||
|
$amount++;
|
||||||
|
|
||||||
|
// Запись группы
|
||||||
|
// $group = static::class . 'Group';
|
||||||
|
// (new $group())->writeMember($product, $this->group);
|
||||||
|
} else {
|
||||||
|
// Проверка не пройдена
|
||||||
|
foreach ($product->errors as $attribute => $error) {
|
||||||
|
$this->addError($attribute, $error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Деинициализация
|
||||||
|
$this->file_excel = '';
|
||||||
|
|
||||||
|
static::afterImportExcel($amount);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addError('erros', 'Неизвестная ошибка');
|
||||||
|
|
||||||
|
static::afterImportExcel($amount);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Поиск по каталожному номеру
|
||||||
|
*
|
||||||
|
* Ищет продукт и возвращает его,
|
||||||
|
* либо выполняет поиск через представление
|
||||||
|
*
|
||||||
|
* @todo Переделать нормально
|
||||||
|
*/
|
||||||
|
public static function searchByCatn(string $catn, int $limit = 1, array $select = []): static|array|null
|
||||||
|
{
|
||||||
|
if ($limit <= 1) {
|
||||||
|
return static::findOne(['catn' => $catn]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = self::find()
|
||||||
|
->where(['catn' => $catn])
|
||||||
|
->limit($limit)
|
||||||
|
->select($select)
|
||||||
|
->createCommand()
|
||||||
|
->execute()
|
||||||
|
->getAll();
|
||||||
|
|
||||||
|
foreach ($query as &$attribute) {
|
||||||
|
// Приведение всех свойств в массив и очистка от лишних данных
|
||||||
|
|
||||||
|
$attribute = $attribute->getAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Поиск по каталожному номеру (через представления)
|
||||||
|
*
|
||||||
|
* Ищет продукт и возвращает его,
|
||||||
|
* либо выполняет поиск через представление
|
||||||
|
*
|
||||||
|
* @todo Переделать нормально
|
||||||
|
*/
|
||||||
|
public static function searchByPartialCatn(string $catn, int $limit = 1, array $select = []): static|array|null
|
||||||
|
{
|
||||||
|
$query = self::find()
|
||||||
|
->for('product')
|
||||||
|
->in('product_search')
|
||||||
|
->search(['catn' => $catn])
|
||||||
|
->limit($limit)
|
||||||
|
->select($select)
|
||||||
|
->createCommand()
|
||||||
|
->execute()
|
||||||
|
->getAll();
|
||||||
|
|
||||||
|
foreach ($query as &$attribute) {
|
||||||
|
// Приведение всех свойств в массив и очистка от лишних данных
|
||||||
|
|
||||||
|
$attribute = $attribute->getAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Вызывается после загрузки поставок из excel-документа
|
||||||
|
*
|
||||||
|
* @param int $amount Количество
|
||||||
|
*/
|
||||||
|
public static function afterImportExcel(int $amount = 0): bool
|
||||||
|
{
|
||||||
|
// Инициализация
|
||||||
|
$model = new Notification;
|
||||||
|
$date = date('H:i d.m.Y', time());
|
||||||
|
|
||||||
|
// Настройка
|
||||||
|
$model->text = yii::$app->controller->renderPartial('/notification/system/afterImportExcel', compact('amount', 'date'));
|
||||||
|
$model->type = $model::TYPE_NOTICE;
|
||||||
|
|
||||||
|
// Отправка
|
||||||
|
return (bool) $model->write();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Вызывается после загрузки поставок из 1С
|
||||||
|
*
|
||||||
|
* @param int $amount Количество
|
||||||
|
*/
|
||||||
|
public static function afterImport1c(): bool
|
||||||
|
{
|
||||||
|
// Инициализация
|
||||||
|
$model = new Notification;
|
||||||
|
$date = date('H:i d.m.Y', time());
|
||||||
|
|
||||||
|
// Настройка
|
||||||
|
$model->text = yii::$app->controller->renderPartial('/notification/system/afterImport1c', compact('amount', 'date'));
|
||||||
|
$model->type = $model::TYPE_NOTICE;
|
||||||
|
|
||||||
|
// Отправка
|
||||||
|
return (bool) $model->write();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@ class Supply extends Product implements ProductInterface
|
||||||
$models = self::searchByAccount($account->readId());
|
$models = self::searchByAccount($account->readId());
|
||||||
$properties = self::xml2array($properties->xml);
|
$properties = self::xml2array($properties->xml);
|
||||||
|
|
||||||
$account->on(ApiController::EVENT_AFTER_OFFER_SYNC, self::afterImport());
|
$account->on(ApiController::EVENT_AFTER_OFFER_SYNC, self::afterImport1c());
|
||||||
|
|
||||||
foreach ($models as $model) {
|
foreach ($models as $model) {
|
||||||
// Перебор записей
|
// Перебор записей
|
||||||
|
|
Reference in New Issue