Создание связей, удаление связей и удаление товаров
This commit is contained in:
parent
7e63c8be97
commit
43272d051e
|
@ -99,6 +99,7 @@ $config = [
|
||||||
'<_key:[0-9]+>/files/<file:[^/]+>' => 'account/file',
|
'<_key:[0-9]+>/files/<file:[^/]+>' => 'account/file',
|
||||||
'<_key:[0-9]+>/<action:(accept|decline)>' => 'account/<action>',
|
'<_key:[0-9]+>/<action:(accept|decline)>' => 'account/<action>',
|
||||||
'product/<catn:[^/]+>' => 'product/index',
|
'product/<catn:[^/]+>' => 'product/index',
|
||||||
|
'product/<catn:[^/]+>/<action:(connect|disconnect|delete)>' => 'product/<action>',
|
||||||
'<section:(product|cart)>/<catn:[^/]+>/<action:(read|write|edit|delete)>/<target:(title|catn|dscr|dmns|wght|image|cover|comm)>' => '<section>/<action>-<target>',
|
'<section:(product|cart)>/<catn:[^/]+>/<action:(read|write|edit|delete)>/<target:(title|catn|dscr|dmns|wght|image|cover|comm)>' => '<section>/<action>-<target>',
|
||||||
'profile/geolocation/<action:(init|write)>' => 'profile/geolocation-<action>',
|
'profile/geolocation/<action:(init|write)>' => 'profile/geolocation-<action>',
|
||||||
'profile/panel/<panel:(suppliers)>/<block:(requests)>/<action:(search)>' => 'profile/panel-<panel>-<block>-<action>',
|
'profile/panel/<panel:(suppliers)>/<block:(requests)>/<action:(search)>' => 'profile/panel-<panel>-<block>-<action>',
|
||||||
|
|
|
@ -12,9 +12,32 @@ use yii\web\HttpException;
|
||||||
use yii\web\UploadedFile;
|
use yii\web\UploadedFile;
|
||||||
|
|
||||||
use app\models\Product;
|
use app\models\Product;
|
||||||
|
use app\models\ProductEdgeProduct;
|
||||||
|
|
||||||
class ProductController extends Controller
|
class ProductController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function actionIndex(string $catn): array|string|null
|
public function actionIndex(string $catn): array|string|null
|
||||||
{
|
{
|
||||||
if ($model = Product::searchByCatn($catn)) {
|
if ($model = Product::searchByCatn($catn)) {
|
||||||
|
@ -38,6 +61,321 @@ class ProductController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Подключение аналога
|
||||||
|
*
|
||||||
|
* @param string $catn Артикул
|
||||||
|
*/
|
||||||
|
public function actionConnect(string $catn): array|string|null
|
||||||
|
{
|
||||||
|
// Инициализация буфера ответа
|
||||||
|
$return = [
|
||||||
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
|
];
|
||||||
|
|
||||||
|
if (empty($catn)) {
|
||||||
|
// Не получен артикул
|
||||||
|
|
||||||
|
// Запись кода ответа
|
||||||
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
||||||
|
// Переход в конец алгоритма
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($from = Product::searchByCatn($catn)) {
|
||||||
|
// Товар найден
|
||||||
|
|
||||||
|
if ($target = yii::$app->request->post('catn') ?? yii::$app->request->get('catn')) {
|
||||||
|
// Инициализирован артикул товара для связи
|
||||||
|
|
||||||
|
if ($to = Product::searchByCatn($target)) {
|
||||||
|
// Существует товар к которому планируется соединение
|
||||||
|
} else {
|
||||||
|
// Не существует товар к которому планируется соединение
|
||||||
|
|
||||||
|
// Инициализация товара
|
||||||
|
$to = new Product();
|
||||||
|
|
||||||
|
// Запись артикула
|
||||||
|
$to->catn = (string) $target;
|
||||||
|
|
||||||
|
if ($to->save()) {
|
||||||
|
// Удалось записать товар
|
||||||
|
} else {
|
||||||
|
// Не удалось записать товар
|
||||||
|
|
||||||
|
// Запись кода ответа
|
||||||
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
||||||
|
// Запись в буфер возврата
|
||||||
|
$return['alert'] = "Не удалось записать новый товар: $target";
|
||||||
|
|
||||||
|
// Переход в конец алгоритма
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запись ребра
|
||||||
|
if ($edge = ProductEdgeProduct::writeSafe(Product::collectionName() . "/$from->_key", Product::collectionName() . "/$to->_key", data: ['type' => 'analogue'])) {
|
||||||
|
// Ребро сохранено
|
||||||
|
|
||||||
|
// Запись в журнал о соединении
|
||||||
|
$from->journal('connect', [
|
||||||
|
'to' => Product::collectionName() . "/$to->_key"
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Запись в журнал о соединении
|
||||||
|
$to->journal('connect', [
|
||||||
|
'from' => Product::collectionName() . "/$from->_key"
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Запись в буфер возврата
|
||||||
|
$return['alert'] = "Продукты успешно соединены ребром: $edge->_key";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Запись кода ответа
|
||||||
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
||||||
|
// Запись в буфер возврата
|
||||||
|
$return['alert'] = "Не удалось найти товар к которому требуется соединение: $catn";
|
||||||
|
|
||||||
|
// Переход в конец алгоритма
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Конец алгоритма
|
||||||
|
*/
|
||||||
|
end:
|
||||||
|
|
||||||
|
if (yii::$app->request->isPost) {
|
||||||
|
// POST-запрос
|
||||||
|
|
||||||
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Product::searchByCatn($catn)) {
|
||||||
|
// Старый товар ещё существует (подразумевается, что произошла ошибка)
|
||||||
|
|
||||||
|
// Возврат на страницу товара
|
||||||
|
return $this->redirect("/product/$catn");
|
||||||
|
} else {
|
||||||
|
// Обрабатываемый товар не существует (подразумевается, что произошла ошибка)
|
||||||
|
|
||||||
|
// Переадресация на главную страницу
|
||||||
|
return $this->redirect("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Отключение аналога
|
||||||
|
*
|
||||||
|
* @param string $catn Артикул
|
||||||
|
*/
|
||||||
|
public function actionDisconnect(string $catn): array|string|null
|
||||||
|
{
|
||||||
|
// Инициализация буфера ответа
|
||||||
|
$return = [
|
||||||
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
|
];
|
||||||
|
|
||||||
|
if (empty($catn)) {
|
||||||
|
// Не получен артикул
|
||||||
|
|
||||||
|
// Запись кода ответа
|
||||||
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
||||||
|
// Переход в конец алгоритма
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($from = Product::searchByCatn($catn)) {
|
||||||
|
// Товар найден
|
||||||
|
|
||||||
|
if ($target = yii::$app->request->post('catn') ?? yii::$app->request->get('catn')) {
|
||||||
|
// Инициализирован артикул товара для связи
|
||||||
|
|
||||||
|
if ($to = Product::searchByCatn($target)) {
|
||||||
|
// Существует товар который нужно отсоединить
|
||||||
|
|
||||||
|
// Поиск ребра
|
||||||
|
if ($edge = @ProductEdgeProduct::searchByVertex(Product::collectionName() . "/$from->_key", Product::collectionName() . "/$to->_key", type: 'analogue')[0]) {
|
||||||
|
// Найдено ребро (from: $from, to: $to)
|
||||||
|
} else if ($edge = @ProductEdgeProduct::searchByVertex(Product::collectionName() . "/$to->_key", Product::collectionName() . "/$from->_key", type: 'analogue')[0]) {
|
||||||
|
// Найдено ребро (from: $to, to: $from)
|
||||||
|
} else {
|
||||||
|
// Не найдены ребра
|
||||||
|
|
||||||
|
// Запись кода ответа
|
||||||
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
||||||
|
// Запись в буфер возврата
|
||||||
|
$return['alert'] = "Не удалось найти связь с этим товаром: $target";
|
||||||
|
|
||||||
|
// Переход в конец алгоритма
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($edge->delete() > 0) {
|
||||||
|
// Удалось удалить ребро (связь)
|
||||||
|
|
||||||
|
// Запись в журнал о разъединении
|
||||||
|
$from->journal('disconnect', [
|
||||||
|
'to' => Product::collectionName() . "/$to->_key"
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Запись в журнал о соединении
|
||||||
|
$to->journal('disconnect', [
|
||||||
|
'from' => Product::collectionName() . "/$from->_key"
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Запись в буфер возврата
|
||||||
|
$return['alert'] = "Продукты успешно отсоединены";
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Не удалось удалить ребро (связь)
|
||||||
|
|
||||||
|
// Запись кода ответа
|
||||||
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
||||||
|
// Запись в буфер возврата
|
||||||
|
$return['alert'] = "Не удалось удалить ребро между $catn и $target";
|
||||||
|
|
||||||
|
// Переход в конец алгоритма
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Не существует товар который нужно отсоединить
|
||||||
|
|
||||||
|
// Запись кода ответа
|
||||||
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
||||||
|
// Запись в буфер возврата
|
||||||
|
$return['alert'] = "Не удалось найти товар который нужно отсоединить: $catn";
|
||||||
|
|
||||||
|
// Переход в конец алгоритма
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Запись кода ответа
|
||||||
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
||||||
|
// Запись в буфер возврата
|
||||||
|
$return['alert'] = "Не удалось найти товар от когорого требуется отсоединение: $catn";
|
||||||
|
|
||||||
|
// Переход в конец алгоритма
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Конец алгоритма
|
||||||
|
*/
|
||||||
|
end:
|
||||||
|
|
||||||
|
if (yii::$app->request->isPost) {
|
||||||
|
// POST-запрос
|
||||||
|
|
||||||
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Product::searchByCatn($catn)) {
|
||||||
|
// Обрабатываемый товар ещё существует (подразумевается, что произошла ошибка)
|
||||||
|
|
||||||
|
// Возврат на страницу товара
|
||||||
|
return $this->redirect("/product/$catn");
|
||||||
|
} else {
|
||||||
|
// Обрабатываемый товар не существует (подразумевается, что произошла ошибка)
|
||||||
|
|
||||||
|
// Переадресация на главную страницу
|
||||||
|
return $this->redirect("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Отключение аналога
|
||||||
|
*
|
||||||
|
* @param string $catn Артикул
|
||||||
|
*/
|
||||||
|
public function actionDelete(string $catn): array|string|null
|
||||||
|
{
|
||||||
|
// Инициализация буфера ответа
|
||||||
|
$return = [
|
||||||
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
|
];
|
||||||
|
|
||||||
|
if (empty($catn)) {
|
||||||
|
// Не получен артикул
|
||||||
|
|
||||||
|
// Запись кода ответа
|
||||||
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
||||||
|
// Переход в конец алгоритма
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($product = Product::searchByCatn($catn)) {
|
||||||
|
// Товар найден
|
||||||
|
|
||||||
|
if ($product->delete() > 0) {
|
||||||
|
// Удалось удалить
|
||||||
|
|
||||||
|
// Запись в буфер возврата
|
||||||
|
$return['alert'] = "Товар удалён: $catn";
|
||||||
|
$return['location'] = '/';
|
||||||
|
} else {
|
||||||
|
// Запись кода ответа
|
||||||
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
||||||
|
// Запись в буфер возврата
|
||||||
|
$return['alert'] = "Не удалось удалить товар: $catn";
|
||||||
|
|
||||||
|
// Переход в конец алгоритма
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Запись кода ответа
|
||||||
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
||||||
|
// Запись в буфер возврата
|
||||||
|
$return['alert'] = "Не удалось найти товар: $catn";
|
||||||
|
|
||||||
|
// Переход в конец алгоритма
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Конец алгоритма
|
||||||
|
*/
|
||||||
|
end:
|
||||||
|
|
||||||
|
if (yii::$app->request->isPost) {
|
||||||
|
// POST-запрос
|
||||||
|
|
||||||
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Product::searchByCatn($catn)) {
|
||||||
|
// Обрабатываемый товар ещё существует (подразумевается, что произошла ошибка)
|
||||||
|
|
||||||
|
// Возврат на страницу товара
|
||||||
|
return $this->redirect("/product/$catn");
|
||||||
|
} else {
|
||||||
|
// Обрабатываемый товар не существует (подразумевается, что он успешно удалён)
|
||||||
|
|
||||||
|
// Переадресация на главную страницу
|
||||||
|
return $this->redirect("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function actionEditTitle(string $catn): array|string|null
|
public function actionEditTitle(string $catn): array|string|null
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация
|
||||||
|
@ -45,7 +383,7 @@ class ProductController extends Controller
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
|
|
||||||
if (is_null($catn)) {
|
if (empty($catn)) {
|
||||||
// Не получен артикул
|
// Не получен артикул
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
yii::$app->response->statusCode = 500;
|
||||||
|
@ -95,7 +433,7 @@ class ProductController extends Controller
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
|
|
||||||
if (is_null($catn)) {
|
if (empty($catn)) {
|
||||||
// Не получен артикул
|
// Не получен артикул
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
yii::$app->response->statusCode = 500;
|
||||||
|
@ -152,7 +490,7 @@ class ProductController extends Controller
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
|
|
||||||
if (is_null($catn)) {
|
if (empty($catn)) {
|
||||||
// Не получен артикул
|
// Не получен артикул
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
yii::$app->response->statusCode = 500;
|
||||||
|
@ -202,7 +540,7 @@ class ProductController extends Controller
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
|
|
||||||
if (is_null($catn)) {
|
if (empty($catn)) {
|
||||||
// Не получен артикул
|
// Не получен артикул
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
yii::$app->response->statusCode = 500;
|
||||||
|
@ -258,7 +596,7 @@ class ProductController extends Controller
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
|
|
||||||
if (is_null($catn)) {
|
if (empty($catn)) {
|
||||||
// Не получен артикул
|
// Не получен артикул
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
yii::$app->response->statusCode = 500;
|
||||||
|
@ -308,7 +646,7 @@ class ProductController extends Controller
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
|
|
||||||
if (is_null($catn)) {
|
if (empty($catn)) {
|
||||||
// Не получен артикул
|
// Не получен артикул
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
yii::$app->response->statusCode = 500;
|
||||||
|
@ -358,7 +696,7 @@ class ProductController extends Controller
|
||||||
];
|
];
|
||||||
$index = yii::$app->request->post('index') ?? yii::$app->request->get('index');
|
$index = yii::$app->request->post('index') ?? yii::$app->request->get('index');
|
||||||
|
|
||||||
if (is_null($catn) || is_null($index)) {
|
if (empty($catn) || empty($index)) {
|
||||||
// Не получены обязательные параметры
|
// Не получены обязательные параметры
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
yii::$app->response->statusCode = 500;
|
||||||
|
@ -413,7 +751,7 @@ class ProductController extends Controller
|
||||||
];
|
];
|
||||||
$index = yii::$app->request->post('index') ?? yii::$app->request->get('index');
|
$index = yii::$app->request->post('index') ?? yii::$app->request->get('index');
|
||||||
|
|
||||||
if (is_null($catn) || is_null($index)) {
|
if (empty($catn) || empty($index)) {
|
||||||
// Не получены обязательные параметры
|
// Не получены обязательные параметры
|
||||||
|
|
||||||
yii::$app->response->statusCode = 500;
|
yii::$app->response->statusCode = 500;
|
||||||
|
|
|
@ -15,12 +15,26 @@ use app\models\Search;
|
||||||
|
|
||||||
use app\models\connection\Dellin;
|
use app\models\connection\Dellin;
|
||||||
use app\models\Settings;
|
use app\models\Settings;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
class SearchController extends Controller
|
class SearchController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @todo Сессию привязать к аккаунту и проверку по нему делать, иначе её можно просто сбрасывать
|
* @todo
|
||||||
|
* 1. Сессию привязать к аккаунту и проверку по нему делать, иначе её можно просто сбрасывать
|
||||||
|
* 2. Пагинация
|
||||||
*/
|
*/
|
||||||
public function actionIndex(): array|string
|
public function actionIndex(): array|string
|
||||||
{
|
{
|
||||||
|
|
|
@ -81,6 +81,14 @@ abstract class Edge extends Document
|
||||||
* Записать (с проверкой на существование)
|
* Записать (с проверкой на существование)
|
||||||
*
|
*
|
||||||
* Создаст ребро только в том случае, если его аналога не существует
|
* Создаст ребро только в том случае, если его аналога не существует
|
||||||
|
*
|
||||||
|
* @param string $_from Идентификатор отправителя (_id)
|
||||||
|
* @param string $_from Идентификатор получетеля (_id)
|
||||||
|
* @param string $type Дополнительное поле - тип взаимосвязи
|
||||||
|
* @param string $data Дополнительные данные
|
||||||
|
*
|
||||||
|
* @todo
|
||||||
|
* 1. Удалить $type и оставить только $data
|
||||||
*/
|
*/
|
||||||
public static function writeSafe(string $_from, string $_to, string $type = '', array $data = []): ?static
|
public static function writeSafe(string $_from, string $_to, string $type = '', array $data = []): ?static
|
||||||
{
|
{
|
||||||
|
@ -95,6 +103,14 @@ abstract class Edge extends Document
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Записать
|
* Записать
|
||||||
|
*
|
||||||
|
* @param string $_from Идентификатор отправителя (_id)
|
||||||
|
* @param string $_from Идентификатор получетеля (_id)
|
||||||
|
* @param string $type Дополнительное поле - тип взаимосвязи
|
||||||
|
* @param string $data Дополнительные данные
|
||||||
|
*
|
||||||
|
* @todo
|
||||||
|
* 1. Удалить $type и оставить только $data
|
||||||
*/
|
*/
|
||||||
public static function write(string $_from, string $_to, string $type, array $data = []): ?static
|
public static function write(string $_from, string $_to, string $type, array $data = []): ?static
|
||||||
{
|
{
|
||||||
|
|
|
@ -585,4 +585,21 @@ class Product extends Document
|
||||||
select: 'supply_edge_product[0]'
|
select: 'supply_edge_product[0]'
|
||||||
)[0];
|
)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Найти все аналоги
|
||||||
|
*
|
||||||
|
* @param string $catn Идентификатор товара
|
||||||
|
* @param int $limit Ограничение по количеству
|
||||||
|
*
|
||||||
|
* @return array|null Найденные аналоги
|
||||||
|
*/
|
||||||
|
public static function searchAnalogs(string $catn, int $limit = 30): ?array
|
||||||
|
{
|
||||||
|
// Поиск ключей аналогов
|
||||||
|
$analogs = ProductEdgeProduct::searchConnections(self::searchByCatn($catn)->_key, $limit);
|
||||||
|
|
||||||
|
|
||||||
|
return ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,4 +10,49 @@ class ProductEdgeProduct extends Edge
|
||||||
{
|
{
|
||||||
return 'product_edge_product';
|
return 'product_edge_product';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Найти все соединения
|
||||||
|
*
|
||||||
|
* @param string $_key Ключ товара
|
||||||
|
* @param int $limit Ограничение по количеству
|
||||||
|
*
|
||||||
|
* @return array|null Найденные соединения (массив с ключами - "_key")
|
||||||
|
*/
|
||||||
|
public static function searchConnections(string $_key, int $limit = 30): ?array
|
||||||
|
{
|
||||||
|
// Инициализация буфера возврата
|
||||||
|
$return = [];
|
||||||
|
|
||||||
|
// Поиск аналогов
|
||||||
|
$edges = self::find()->where(['_from' => Product::collectionName() . "/$_key"])->limit($limit)->all();
|
||||||
|
|
||||||
|
foreach ($edges as $edge) {
|
||||||
|
// Перебор найденных рёбер
|
||||||
|
|
||||||
|
// Извлечение ключа
|
||||||
|
preg_match_all('/\w+\/([0-9]+)/', $edge->_to, $matches);
|
||||||
|
|
||||||
|
// Запись артикула в буфер вывода
|
||||||
|
$return[] = $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Перерасчет ограничения по количеству
|
||||||
|
$limit -= count($edges);
|
||||||
|
|
||||||
|
// Поиск аналогов (с обратной привязкой)
|
||||||
|
$edges = self::find()->where(['_to' => Product::collectionName() . "/$_key"])->limit($limit)->all();
|
||||||
|
|
||||||
|
foreach ($edges as $edge) {
|
||||||
|
// Перебор найденных рёбер
|
||||||
|
|
||||||
|
// Извлечение ключа
|
||||||
|
preg_match_all('/\w+\/([0-9]+)/', $edge->_to, $matches);
|
||||||
|
|
||||||
|
// Запись артикула в буфер вывода
|
||||||
|
$return[] = $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
use yii\bootstrap\ActiveForm;
|
use yii\bootstrap\ActiveForm;
|
||||||
use yii\helpers\Html;
|
|
||||||
|
|
||||||
use app\models\Product;
|
use app\models\Product;
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ use app\models\Product;
|
||||||
</label>
|
</label>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="product_slider_image">
|
<div class="col product_slider_image">
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация
|
||||||
|
@ -93,7 +94,7 @@ use app\models\Product;
|
||||||
<div class="col p-0 unselectable">
|
<div class="col p-0 unselectable">
|
||||||
<img class="mb-3 img-fluid w-100 rounded" src="$orig"/>
|
<img class="mb-3 img-fluid w-100 rounded" src="$orig"/>
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<button class="flex-grow-1 mr-3 btn button_blue button_clean" onclick="return product_panel_images_cover_write('$catn', '$key');">Сделать основной обложкой</button>
|
<button class="flex-grow-1 mr-3 btn button_blue button_clean" onclick="return product_panel_images_cover_write('$catn', '$key');">Сделать обложкой</button>
|
||||||
<button class="btn button_red button_clean" onclick="return product_panel_images_delete('$catn', '$key');">Удалить</button>
|
<button class="btn button_red button_clean" onclick="return product_panel_images_delete('$catn', '$key');">Удалить</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -112,14 +113,29 @@ use app\models\Product;
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col ml-4 d-flex flex-column">
|
<div class="ml-4 px-3 d-flex flex-column w-50"> <?php if (
|
||||||
<div class="row mb-1">
|
!yii::$app->user->isGuest
|
||||||
|
&& yii::$app->user->identity->type === 'administrator'
|
||||||
|
) : ?>
|
||||||
|
<nav class="row my-2 py-2 px-3 rounded product_admin_menu">
|
||||||
|
<a id="product_info_admin_connect" class="mr-2 h-100 text-dark d-flex" title="Подключить аналог" role="button" onclick="return product_panel_connect('<?= $model['catn'] ?>');">
|
||||||
|
<i class="fas fa-plus-square my-auto"></i>
|
||||||
|
</a>
|
||||||
|
<a id="product_info_admin_connect" class="mr-2 h-100 text-dark d-flex" title="Отключить аналог" role="button" onclick="return product_panel_disconnect('<?= $model['catn'] ?>');">
|
||||||
|
<i class="fas fa-minus-square my-auto"></i>
|
||||||
|
</a>
|
||||||
|
<a id="product_info_admin_connect" class="ml-auto h-100 text-dark d-flex" title="Удалить" role="button" onclick="return product_panel_delete('<?= $model['catn'] ?>');">
|
||||||
|
<i class="fas fa-trash-alt my-auto"></i>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<?php endif ?>
|
||||||
|
<div class="row mb-2">
|
||||||
<?php if (
|
<?php if (
|
||||||
!yii::$app->user->isGuest
|
!yii::$app->user->isGuest
|
||||||
&& (yii::$app->user->identity->type === 'administrator'
|
&& (yii::$app->user->identity->type === 'administrator'
|
||||||
|| yii::$app->user->identity->type === 'moderator')
|
|| yii::$app->user->identity->type === 'moderator')
|
||||||
) : ?>
|
) : ?>
|
||||||
<h3 id="title_<?= $model['catn'] ?>" class="my-auto pointer-event" role="button" onclick="return product_panel_title_edit('<?= $model['catn'] ?>', this);"><?= $model['name'] ?? 'Без названия' ?></h3>
|
<h3 id="title_<?= $model['catn'] ?>" class="my-auto pointer-event product_title" role="button" onclick="return product_panel_title_edit('<?= $model['catn'] ?>', this);"><?= $model['name'] ?? 'Без названия' ?></h3>
|
||||||
<?php else : ?>
|
<?php else : ?>
|
||||||
<h3 id="title_<?= $model['catn'] ?>" class="my-auto"><?= $model['name'] ?? 'Без названия' ?></h3>
|
<h3 id="title_<?= $model['catn'] ?>" class="my-auto"><?= $model['name'] ?? 'Без названия' ?></h3>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
@ -131,16 +147,8 @@ use app\models\Product;
|
||||||
&& (yii::$app->user->identity->type === 'administrator'
|
&& (yii::$app->user->identity->type === 'administrator'
|
||||||
|| yii::$app->user->identity->type === 'moderator')
|
|| yii::$app->user->identity->type === 'moderator')
|
||||||
) : ?>
|
) : ?>
|
||||||
<h6 id="catn_<?= $model['catn'] ?>" class="mr-auto my-auto pointer-event" role="button" onclick="return product_panel_catn_edit('<?= $model['catn'] ?>', this, true);">
|
<h6 id="catn_<?= $model['catn'] ?>" class="mr-auto my-auto pointer-event product_title" role="button" onclick="return product_panel_catn_edit('<?= $model['catn'] ?>', this, true);">
|
||||||
<?= $model['catn'] ?? '' ?>
|
<?= $model['catn'] ?? '' ?>
|
||||||
<!-- <small class="d-flex">
|
|
||||||
<a class="text-dark my-auto ml-3" title="Редактировать" role="button" onclick="return product_panel_edit('<?= $model['catn'] ?>');">
|
|
||||||
<i class="fas fa-edit"></i>
|
|
||||||
</a>
|
|
||||||
<a class="text-dark my-auto ml-2" title="Удалить" role="button" onclick="return product_panel_delete('<?= $model['catn'] ?>');">
|
|
||||||
<i class="fas fa-trash-alt"></i>
|
|
||||||
</a>
|
|
||||||
</small> -->
|
|
||||||
</h6>
|
</h6>
|
||||||
<h6 id="prod_<?= $model['catn'] ?>" class="my-0">
|
<h6 id="prod_<?= $model['catn'] ?>" class="my-0">
|
||||||
<?= $model['prod'] ?? 'Неизвестно' ?>
|
<?= $model['prod'] ?? 'Неизвестно' ?>
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use app\models\Product;
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
<link href="/css/pages/search.css" rel="stylesheet">
|
<link href="/css/pages/search.css" rel="stylesheet">
|
||||||
|
|
||||||
<div id="page_search" class="container flex-grow-1 d-flex">
|
<div id="page_search" class="container flex-grow-1 d-flex">
|
||||||
|
@ -75,6 +83,9 @@
|
||||||
|
|
||||||
// Инициализация указателя номера цикла
|
// Инициализация указателя номера цикла
|
||||||
$supply_iterator = 1;
|
$supply_iterator = 1;
|
||||||
|
|
||||||
|
// Инициализация реестра пустышек (товаров без поставок или с ошибками)
|
||||||
|
$empties = [];
|
||||||
?>
|
?>
|
||||||
<?php foreach (empty($row['supplies']) || count($row['supplies']) === 0 ? [null] : $row['supplies'] as $supply) : ?>
|
<?php foreach (empty($row['supplies']) || count($row['supplies']) === 0 ? [null] : $row['supplies'] as $supply) : ?>
|
||||||
<?php
|
<?php
|
||||||
|
@ -134,6 +145,9 @@
|
||||||
</div>
|
</div>
|
||||||
HTML;
|
HTML;
|
||||||
|
|
||||||
|
// Запись в список ненайденных
|
||||||
|
$empties[] = $catn;
|
||||||
|
|
||||||
// Запись блокировщика
|
// Запись блокировщика
|
||||||
$empty_block = true;
|
$empty_block = true;
|
||||||
|
|
||||||
|
@ -212,7 +226,13 @@
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
|
<?php foreach ($empties as $catn) : ?>
|
||||||
|
<?php foreach (Product::searchAnalogs($catn) as $product) : ?>
|
||||||
|
<?php
|
||||||
|
var_dump($product);
|
||||||
|
?>
|
||||||
|
<?php endforeach ?>
|
||||||
|
<?php endforeach ?>
|
||||||
<div class="col pb-2">
|
<div class="col pb-2">
|
||||||
<div class="row p-2 rounded">
|
<div class="row p-2 rounded">
|
||||||
<img class="ml-0 h-100 img-fluid rounded" src="<?= $covr ?>" />
|
<img class="ml-0 h-100 img-fluid rounded" src="<?= $covr ?>" />
|
||||||
|
@ -229,6 +249,7 @@
|
||||||
</div> -->
|
</div> -->
|
||||||
<div class="col ml-3 p-0 d-flex flex-column">
|
<div class="col ml-3 p-0 d-flex flex-column">
|
||||||
<?= $supplies_html ?>
|
<?= $supplies_html ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -74,3 +74,13 @@
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#page_product article .product_title {
|
||||||
|
word-wrap: anywhere;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#page_product article .product_admin_menu {
|
||||||
|
background-color: #f4f4f6;
|
||||||
|
}
|
||||||
|
|
|
@ -26,13 +26,27 @@ function main_response(data, status, xhr) {
|
||||||
document.title = data.title;
|
document.title = data.title;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Перенаправление
|
// Перенаправление (только запись в историю)
|
||||||
if (data.redirect !== undefined) {
|
if (data.redirect !== undefined) {
|
||||||
|
|
||||||
// Перенаправление
|
// Запись в историю
|
||||||
history.pushState({}, document.title, data.redirect);
|
history.pushState({}, document.title, data.redirect);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Перенаправление
|
||||||
|
if (data.location !== undefined) {
|
||||||
|
|
||||||
|
// Перенаправление
|
||||||
|
location = data.location;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Системное уведомление
|
||||||
|
if (data.alert !== undefined) {
|
||||||
|
|
||||||
|
// Отображение
|
||||||
|
alert(data.alert);
|
||||||
|
};
|
||||||
|
|
||||||
// CSRF-токен
|
// CSRF-токен
|
||||||
if (data._csrf !== undefined) {
|
if (data._csrf !== undefined) {
|
||||||
|
|
||||||
|
|
|
@ -300,6 +300,65 @@ function product_panel_description_save(catn, element) {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function product_panel_connect(catn) {
|
||||||
|
if (catn !== null && catn !== undefined) {
|
||||||
|
$.ajax({
|
||||||
|
url: '/product/' + catn + '/connect',
|
||||||
|
type: 'post',
|
||||||
|
dataType: 'json',
|
||||||
|
data: {
|
||||||
|
'_csrf': yii.getCsrfToken(),
|
||||||
|
'catn': prompt('Подключить аналог')
|
||||||
|
},
|
||||||
|
success: product_response_success,
|
||||||
|
error: product_response_error
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function product_panel_disconnect(catn) {
|
||||||
|
if (catn !== null && catn !== undefined) {
|
||||||
|
$.ajax({
|
||||||
|
url: '/product/' + catn + '/disconnect',
|
||||||
|
type: 'post',
|
||||||
|
dataType: 'json',
|
||||||
|
data: {
|
||||||
|
'_csrf': yii.getCsrfToken(),
|
||||||
|
'catn': prompt('Отключить аналог')
|
||||||
|
},
|
||||||
|
success: product_response_success,
|
||||||
|
error: product_response_error
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function product_panel_delete(catn) {
|
||||||
|
if (catn !== null && catn !== undefined) {
|
||||||
|
$.ajax({
|
||||||
|
url: '/product/' + catn + '/delete',
|
||||||
|
type: 'post',
|
||||||
|
dataType: 'json',
|
||||||
|
data: {
|
||||||
|
'_csrf': yii.getCsrfToken()
|
||||||
|
},
|
||||||
|
success: product_response_success,
|
||||||
|
error: product_response_error
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function product_panel_images_write(catn, element) {
|
function product_panel_images_write(catn, element) {
|
||||||
if (catn !== null && catn !== undefined && element !== null && element !== undefined) {
|
if (catn !== null && catn !== undefined && element !== null && element !== undefined) {
|
||||||
// Инициализация
|
// Инициализация
|
||||||
|
|
Reference in New Issue