В контроллер скопипастил модель... Исправление

This commit is contained in:
Arsen Mirzaev Tatyano-Muradovich 2021-04-11 04:08:09 +10:00
parent c169347687
commit b50049eb67
2 changed files with 177 additions and 408 deletions

View File

@ -2,469 +2,238 @@
declare(strict_types=1); declare(strict_types=1);
namespace app\models; namespace app\controllers;
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\traits\SearchByEdge; use app\models\Product;
use Exception;
use moonland\phpexcel\Excel;
/** class ProductController extends Controller
* Продукт (в ассортименте магазина)
*
* Представляет собой лот состоящий из предложений от поставщиков
*
* @see Supply Поставки для продуктов
*/
class Product extends Document
{ {
use SearchByEdge; public function actionIndex(string $catn): array|string|null
/**
* Сценарий импорта .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
{ {
return 'product'; if ($model = Product::searchByCatn($catn)) {
// Товар найден
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
* Свойства
*/
public function attributes(): array
{
return array_merge(
parent::attributes(),
[
'catn',
'name',
// В библеотеке есть баг на название DESC (неизвестно в моей или нет)
'dscr',
'prod',
'dmns',
'imgs',
'time'
]
);
}
/**
* Метки свойств
*/
public function attributeLabels(): array
{
return array_merge(
parent::attributeLabels(),
[
'catn' => 'Каталожный номер (catn)',
'name' => 'Название (name)',
'dscr' => 'Описание (dscr)',
'prod' => 'Производитель (prod)',
'dmns' => 'Габариты (dmns)',
'imgs' => 'Изображения (imgs)',
'time' => 'Срок доставки (time)',
'file_excel' => 'Документ (file_excel)',
'file_image' => 'Изображение (file_image)',
'group' => 'Группа (group)'
]
);
}
/**
* Правила
*/
public function rules(): array
{
return array_merge(
parent::rules(),
[
[
'catn',
'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
]
]
);
}
/**
* Запись пустого продукта
*/
public static function writeEmpty(string $catn): ?self
{ {
// Инициализация // Инициализация
$model = new self; $return = [
'_csrf' => yii::$app->request->getCsrfToken()
];
// Настройки if (is_null($catn)) {
$model->catn = $catn; // Не получен артикул
// Запись yii::$app->response->statusCode = 500;
return $model->save() ? $model : null;
}
/** goto end;
* Импорт изображений }
*
* @return int Количество сохранённых изображений
*/
public function importImages(): int
{
// Инициализация
$amount = 0;
if ($this->validate()) { if ($model = Product::searchByCatn($catn)) {
// Проверка пройдена // Товар найден
foreach ($this->file_image as $file) { // Инициализация
// Перебор обрабатываемых изображений $text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия';
if (!file_exists(YII_PATH_PUBLIC . $catalog = '/img/products/' . $this->_key)) { $model->name = $text;
// Директория для изображений продукта не найдена
if (!mkdir(YII_PATH_PUBLIC . $catalog, 0775, true)) { if ($model->save()) {
// Не удалось записать директорию // Товар обновлён
return false; $return['name'] = $text;
};
}
if (!file_exists(YII_PATH_PUBLIC . $catalog_h150 = '/img/products/' . $this->_key . '/h150')) {
// Директория для обложек изображений продукта не найдена
if (!mkdir(YII_PATH_PUBLIC . $catalog_h150, 0775, true)) {
// Не удалось записать директорию
return false;
};
}
// Запись на сервер
$file->saveAs(YII_PATH_PUBLIC . $catalog . '/' . $file->baseName . '.' . $file->extension . '.original');
// Конвертация изображения для сохранения полного изображения
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()) { /**
// Получены ошибки * Конец алгоритма
*/
end:
foreach ($this->getErrors() as $attribute => $errors) { if (yii::$app->request->isPost) {
// Перебор атрибутов // POST-запрос
foreach ($errors as $error) { yii::$app->response->format = Response::FORMAT_JSON;
// Перебор ошибок атрибутов
$label = $this->getAttributeLabel($attribute); return $return;
}
Notification::_write("$label: $error", type: Notification::TYPE_ERROR); if ($model = Product::searchByCatn($catn)) {
} return $this->render('index', compact('model'));
} else {
return $this->redirect('/');
}
}
public function actionEditCatn(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->catn = $text;
if ($model->save()) {
// Товар обновлён
$return['main'] = $this->renderPartial('index', compact('model'));
} }
} }
return $amount; /**
* Конец алгоритма
*/
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 actionEditDesc(string $catn): array|string|null
* Импорт товаров
*
* На данный момент обрабатывает только импорт из
* файлов с расширением .excel
*/
public function importExcel(): bool
{ {
// Инициализация // Инициализация
$data = []; $return = [
$amount = 0; '_csrf' => yii::$app->request->getCsrfToken()
];
if ($this->validate()) { if (is_null($catn)) {
foreach ($this->file_excel as $file) { // Не получен артикул
// Перебор файлов
// Инициализация yii::$app->response->statusCode = 500;
$dir = '../assets/import/' . date('Y_m_d#H-i', time()) . '/excel/';
// Сохранение на диск goto end;
if (!file_exists($dir)) { }
mkdir($dir, 0775, true);
}
$file->saveAs($path = $dir . $file->baseName . '.' . $file->extension);
$data[] = Excel::import($path, [ if ($product = Product::searchByCatn($catn)) {
'setFirstRecordAsKeys' => true, // Товар найден
'setIndexSheetByName' => true,
]); // Инициализация
$text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия';
$product->desc = $text;
if ($product->save()) {
// Товар обновлён
$return['description'] = $text;
} }
}
/**
* Конец алгоритма
*/
end:
foreach ($data as $data) { if (yii::$app->request->isPost) {
// Перебор конвертированных файлов // POST-запрос
if (count($data) < 1) { yii::$app->response->format = Response::FORMAT_JSON;
// Не найдены строки с товарами
$this->addError('erros', 'Не удалось найти данные товаров'); return $return;
} else { }
// Перебор найденных товаров
foreach ($data as $doc) { if ($model = Product::searchByCatn($catn)) {
// Перебор полученных документов return $this->render('index', compact('model'));
} else {
return $this->redirect('/');
}
}
// Сохранение в базе данных public function actionWriteImage(string $catn): array|string|null
$product = new static($doc); {
// Инициализация
$return = [
'_csrf' => yii::$app->request->getCsrfToken()
];
$product->scenario = $product::SCENARIO_WRITE; if (is_null($catn)) {
// Не получен артикул
if ($product->validate()) { yii::$app->response->statusCode = 500;
// Проверка пройдена
// Запись документа goto end;
$product->save(); }
// Постинкрементация счётчика if ($model = Product::searchByCatn($catn)) {
$amount++; // Товар найден
// Запись группы // Инициализация
// $group = static::class . 'Group'; $model->file_image = UploadedFile::getInstancesByName('images');
// (new $group())->writeMember($product, $this->group); $model->scenario = $model::SCENARIO_IMPORT_IMAGE;
} else {
// Проверка не пройдена if ($model->importImages() > 0) {
foreach ($product->errors as $attribute => $error) { // Товар обновлён
$this->addError($attribute, $error);
} $return['main'] = $this->renderPartial('index', compact('model'));
}
}
}
} }
// Деинициализация
$this->file_excel = '';
static::afterImportExcel($amount);
return true;
} }
$this->addError('erros', 'Неизвестная ошибка'); /**
* Конец алгоритма
*/
end:
static::afterImportExcel($amount); if (yii::$app->request->isPost) {
// POST-запрос
return false; yii::$app->response->format = Response::FORMAT_JSON;
}
/** return $return;
* Поиск по каталожному номеру
*
* Ищет продукт и возвращает его,
* либо выполняет поиск через представление
*
* @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() if ($model = Product::searchByCatn($catn)) {
->where(['catn' => $catn]) return $this->render('index', compact('model'));
->limit($limit) } else {
->select($select) return $this->redirect('/');
->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();
} }
} }

View File

@ -454,14 +454,14 @@ class Product extends Document
* *
* @param int $amount Количество * @param int $amount Количество
*/ */
public static function afterImportOnec(): bool public static function afterImport1c(): bool
{ {
// Инициализация // Инициализация
$model = new Notification; $model = new Notification;
$date = date('H:i d.m.Y', time()); $date = date('H:i d.m.Y', time());
// Настройка // Настройка
$model->text = yii::$app->controller->renderPartial('/notification/system/afterImportOnec', compact('amount', 'date')); $model->text = yii::$app->controller->renderPartial('/notification/system/afterImport1c', compact('amount', 'date'));
$model->type = $model::TYPE_NOTICE; $model->type = $model::TYPE_NOTICE;
// Отправка // Отправка