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

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'));
* Свойства
*/
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;
// Настройки
$model->catn = $catn;
// Запись
return $model->save() ? $model : null;
}
/**
* Импорт изображений
*
* @return int Количество сохранённых изображений
*/
public function importImages(): int
{
// Инициализация
$amount = 0;
if ($this->validate()) {
// Проверка пройдена
foreach ($this->file_image as $file) {
// Перебор обрабатываемых изображений
if (!file_exists(YII_PATH_PUBLIC . $catalog = '/img/products/' . $this->_key)) {
// Директория для изображений продукта не найдена
if (!mkdir(YII_PATH_PUBLIC . $catalog, 0775, true)) {
// Не удалось записать директорию
return false;
};
}
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()) {
// Получены ошибки
foreach ($this->getErrors() as $attribute => $errors) {
// Перебор атрибутов
foreach ($errors as $error) {
// Перебор ошибок атрибутов
$label = $this->getAttributeLabel($attribute);
Notification::_write("$label: $error", type: Notification::TYPE_ERROR);
}
}
}
return $amount;
}
/**
* Импорт товаров
*
* На данный момент обрабатывает только импорт из
* файлов с расширением .excel
*/
public function importExcel(): bool
{
// Инициализация
$data = [];
$amount = 0;
if ($this->validate()) {
foreach ($this->file_excel as $file) {
// Перебор файлов
// Инициализация
$dir = '../assets/import/' . date('Y_m_d#H-i', time()) . '/excel/';
// Сохранение на диск
if (!file_exists($dir)) {
mkdir($dir, 0775, true);
}
$file->saveAs($path = $dir . $file->baseName . '.' . $file->extension);
$data[] = Excel::import($path, [
'setFirstRecordAsKeys' => true,
'setIndexSheetByName' => true,
]);
}
foreach ($data as $data) {
// Перебор конвертированных файлов
if (count($data) < 1) {
// Не найдены строки с товарами
$this->addError('erros', 'Не удалось найти данные товаров');
} else { } else {
// Перебор найденных товаров throw new HttpException(404);
}
}
foreach ($data as $doc) { public function actionEditTitle(string $catn): array|string|null
// Перебор полученных документов {
// Инициализация
$return = [
'_csrf' => yii::$app->request->getCsrfToken()
];
// Сохранение в базе данных if (is_null($catn)) {
$product = new static($doc); // Не получен артикул
$product->scenario = $product::SCENARIO_WRITE; yii::$app->response->statusCode = 500;
if ($product->validate()) { goto end;
// Проверка пройдена }
// Запись документа if ($model = Product::searchByCatn($catn)) {
$product->save(); // Товар найден
// Постинкрементация счётчика // Инициализация
$amount++; $text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия';
// Запись группы $model->name = $text;
// $group = static::class . 'Group';
// (new $group())->writeMember($product, $this->group); if ($model->save()) {
// Товар обновлён
$return['name'] = $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 { } else {
// Проверка не пройдена return $this->redirect('/');
foreach ($product->errors as $attribute => $error) {
$this->addError($attribute, $error);
}
}
}
} }
} }
// Деинициализация public function actionEditCatn(string $catn): array|string|null
$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; $return = [
$date = date('H:i d.m.Y', time()); '_csrf' => yii::$app->request->getCsrfToken()
];
// Настройка if (is_null($catn)) {
$model->text = yii::$app->controller->renderPartial('/notification/system/afterImportExcel', compact('amount', 'date')); // Не получен артикул
$model->type = $model::TYPE_NOTICE;
// Отправка yii::$app->response->statusCode = 500;
return (bool) $model->write();
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'));
}
} }
/** /**
* Вызывается после загрузки поставок из 1С * Конец алгоритма
*
* @param int $amount Количество
*/ */
public static function afterImport1c(): bool 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
{ {
// Инициализация // Инициализация
$model = new Notification; $return = [
$date = date('H:i d.m.Y', time()); '_csrf' => yii::$app->request->getCsrfToken()
];
// Настройка if (is_null($catn)) {
$model->text = yii::$app->controller->renderPartial('/notification/system/afterImport1c', compact('amount', 'date')); // Не получен артикул
$model->type = $model::TYPE_NOTICE;
// Отправка yii::$app->response->statusCode = 500;
return (bool) $model->write();
goto end;
}
if ($product = Product::searchByCatn($catn)) {
// Товар найден
// Инициализация
$text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия';
$product->desc = $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 actionWriteImage(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)) {
// Товар найден
// Инициализация
$model->file_image = UploadedFile::getInstancesByName('images');
$model->scenario = $model::SCENARIO_IMPORT_IMAGE;
if ($model->importImages() > 0) {
// Товар обновлён
$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('/');
}
} }
} }

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;
// Отправка // Отправка