Разработка сессий, переработка под браузеры, уведомления приходят только получателю

This commit is contained in:
Arsen Mirzaev Tatyano-Muradovich 2021-03-22 05:03:37 +10:00
parent 8cbe77e354
commit 722bf6c378
23 changed files with 176 additions and 221 deletions

View File

@ -24,7 +24,8 @@
"triagens/arangodb": "^3.6", "triagens/arangodb": "^3.6",
"moonlandsoft/yii2-phpexcel": ">=2.0", "moonlandsoft/yii2-phpexcel": ">=2.0",
"carono/yii2-1c-exchange": "^0.3.1", "carono/yii2-1c-exchange": "^0.3.1",
"mirzaev/yii2-arangodb": "~2.1.x-dev" "mirzaev/yii2-arangodb": "~2.1.x-dev",
"mirzaev/yii2-arangodb-sessions": "~1.0.0"
}, },
"require-dev": { "require-dev": {
"codeception/codeception": ">=4.1", "codeception/codeception": ">=4.1",

82
composer.lock generated
View File

@ -4,14 +4,14 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "f259164a4251a4ef37262d42fbeb40d6", "content-hash": "116946ecdb84687a081d5633fd8505f6",
"packages": [ "packages": [
{ {
"name": "bower-asset/bootstrap", "name": "bower-asset/bootstrap",
"version": "v3.4.1", "version": "v3.4.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/twbs/bootstrap.git", "url": "git@github.com:twbs/bootstrap.git",
"reference": "68b0d231a13201eb14acd3dc84e51543d16e5f7e" "reference": "68b0d231a13201eb14acd3dc84e51543d16e5f7e"
}, },
"dist": { "dist": {
@ -715,56 +715,6 @@
}, },
"time": "2021-01-23T16:37:31+00:00" "time": "2021-01-23T16:37:31+00:00"
}, },
{
"name": "mirzaev/yii2-arangodb",
"version": "2.1.x-dev",
"source": {
"type": "git",
"url": "https://git.hood.su/mirzaev/yii2/arangodb",
"reference": "1592238e5f8495dd7385848e8d65300ba7940b46"
},
"require": {
"php": "^8.0.0",
"triagens/arangodb": "~3.2",
"yiisoft/yii2": "2.*"
},
"require-dev": {
"yiisoft/yii2-debug": "*"
},
"type": "yii2-extension",
"autoload": {
"psr-4": {
"mirzaev\\yii2\\arangodb\\": "mirzaev/yii2-arangodb"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"AGPL-3.0-or-later"
],
"authors": [
{
"name": "Arsen Mirzaev Tatyano-Muradovich",
"email": "red@hood.su",
"homepage": "https://hood.su/mirzaev",
"role": "Developer"
},
{
"name": "Ilya Rumyantsev",
"email": "explosivebit@gmail.com"
},
{
"name": "Alvian Burhanuddin",
"email": "alvianthelfarqy@gmail.com"
}
],
"description": "Library for connecting ArangoDB-PHP to Yii2",
"homepage": "https://git.hood.su/mirzaev/yii2/arangodb",
"keywords": [
"ArangoDb",
"yii2"
],
"time": "2021-03-15T16:41:18+00:00"
},
{ {
"name": "moonlandsoft/yii2-phpexcel", "name": "moonlandsoft/yii2-phpexcel",
"version": "2.0.0", "version": "2.0.0",
@ -3554,16 +3504,16 @@
}, },
{ {
"name": "phpspec/prophecy", "name": "phpspec/prophecy",
"version": "1.12.2", "version": "1.13.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpspec/prophecy.git", "url": "https://github.com/phpspec/prophecy.git",
"reference": "245710e971a030f42e08f4912863805570f23d39" "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea",
"reference": "245710e971a030f42e08f4912863805570f23d39", "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3615,9 +3565,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/phpspec/prophecy/issues", "issues": "https://github.com/phpspec/prophecy/issues",
"source": "https://github.com/phpspec/prophecy/tree/1.12.2" "source": "https://github.com/phpspec/prophecy/tree/1.13.0"
}, },
"time": "2020-12-19T10:15:11+00:00" "time": "2021-03-17T13:42:18+00:00"
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
@ -3939,16 +3889,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "9.5.2", "version": "9.5.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "f661659747f2f87f9e72095bb207bceb0f151cb4" "reference": "27241ac75fc37ecf862b6e002bf713b6566cbe41"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f661659747f2f87f9e72095bb207bceb0f151cb4", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/27241ac75fc37ecf862b6e002bf713b6566cbe41",
"reference": "f661659747f2f87f9e72095bb207bceb0f151cb4", "reference": "27241ac75fc37ecf862b6e002bf713b6566cbe41",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4026,7 +3976,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.2" "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.3"
}, },
"funding": [ "funding": [
{ {
@ -4038,7 +3988,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2021-02-02T14:45:58+00:00" "time": "2021-03-17T07:30:34+00:00"
}, },
{ {
"name": "psr/container", "name": "psr/container",
@ -6721,9 +6671,7 @@
], ],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": { "stability-flags": [],
"mirzaev/yii2-arangodb": 20
},
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {

View File

@ -47,6 +47,9 @@ class AuthenticationController extends Controller
if (!Yii::$app->user->isGuest || $model->authentication()) { if (!Yii::$app->user->isGuest || $model->authentication()) {
// Аккаунт аутентифицирован // Аккаунт аутентифицирован
// Создание сессии
yii::$app->session->open();
// Инициализация // Инициализация
$notifications_button = $this->renderPartial('/notification/button'); $notifications_button = $this->renderPartial('/notification/button');
$notifications_panel_full = true; $notifications_panel_full = true;

View File

@ -34,11 +34,15 @@ class DeauthenticationController extends Controller
public function actionIndex() public function actionIndex()
{ {
// Инициализация
yii::$app->response->format = Response::FORMAT_JSON; yii::$app->response->format = Response::FORMAT_JSON;
// Выход из аккаунта // Выход из аккаунта
yii::$app->user->logout(); yii::$app->user->logout();
// Удаление сессии
yii::$app->session->destroy();
// Инициализация // Инициализация
$model = new AccountForm(yii::$app->request->post('AccountForm') ?? yii::$app->request->get('AccountForm') ?? null); $model = new AccountForm(yii::$app->request->post('AccountForm') ?? yii::$app->request->get('AccountForm') ?? null);

View File

@ -35,12 +35,15 @@ class NotificationController extends Controller
*/ */
public function actionIndex() public function actionIndex()
{ {
var_dump(yii::$app->session->id);
if (yii::$app->request->isPost) { if (yii::$app->request->isPost) {
// POST-запрос // POST-запрос
// Инициализация // Инициализация
$model = new Notification(yii::$app->request->post('Notification')); $model = new Notification(yii::$app->request->post('Notification'));
$preload = (bool) (int) yii::$app->request->post('preload'); $preload = (bool) (int) yii::$app->request->post('preload');
$account = yii::$app->user->identity;
yii::$app->response->format = Response::FORMAT_JSON; yii::$app->response->format = Response::FORMAT_JSON;
@ -67,7 +70,7 @@ class NotificationController extends Controller
->for(['account', $model::collectionName() . '_edge_account']) ->for(['account', $model::collectionName() . '_edge_account'])
->traversal($model::collectionName(), 'OUTBOUND') ->traversal($model::collectionName(), 'OUTBOUND')
->in('account_edge_' . $model::collectionName()) ->in('account_edge_' . $model::collectionName())
->where(['account._id' => yii::$app->user->id]) ->where(['account._id == "' . $account->readId() . '" && notification_edge_account._from != account_edge_notification[0]._to'])
->select($model::collectionName() . '_edge_account'); ->select($model::collectionName() . '_edge_account');
if (yii::$app->request->post('last')) { if (yii::$app->request->post('last')) {
@ -90,8 +93,8 @@ class NotificationController extends Controller
* *
* @param bool $new Активация проверки на то, что уведомление не получено * @param bool $new Активация проверки на то, что уведомление не получено
* @param bool $count Посчитать * @param bool $count Посчитать
*/ */
$search = function (bool $new = false, bool $count = false) use ($model, $type, $let, $limit): array|int { $search = function (bool $new = false, bool $count = false) use ($model, $account, $type, $let, $limit): array|int {
if ($count) { if ($count) {
// Запрошен подсчёт непрочитанных уведомлений // Запрошен подсчёт непрочитанных уведомлений
@ -106,7 +109,7 @@ class NotificationController extends Controller
params: $new ? $let->getBindVars() : [], params: $new ? $let->getBindVars() : [],
subquery_where: [ subquery_where: [
[ [
'account._id' => yii::$app->user->id 'account._id' => $account->readId()
], ],
[ [
[ [
@ -122,8 +125,11 @@ class NotificationController extends Controller
'notification_edge_account', 'notification_edge_account',
'(' . (string) $let . ')' '(' . (string) $let . ')'
], ],
foreach: [
'edge' => 'notification_edge_account'
],
where: $new ? [ where: $new ? [
'account_edge_notification[0]._to' => null 'edge != null'
] : [], ] : [],
limit: $limit, limit: $limit,
sort: ['DESC'], sort: ['DESC'],
@ -131,7 +137,7 @@ class NotificationController extends Controller
handle: $count ? function ($request) { handle: $count ? function ($request) {
// Посчитать рёбра (информация о количестве непрочитанных уведомлений) // Посчитать рёбра (информация о количестве непрочитанных уведомлений)
return $request->count(); return $request->count();
}: null } : null
); );
}; };

View File

@ -248,13 +248,13 @@ class ProfileController extends Controller
foreach: ['edge' => 'account_edge_search'], foreach: ['edge' => 'account_edge_search'],
where: 'edge._to == search._id', where: 'edge._to == search._id',
limit: $rows_amount, limit: $rows_amount,
offset: ((int) $page_search_history ?? 0) * $rows_amount offset: $offset = ((int) $page_search_history ?? 0) * $rows_amount
); );
// Проверка результатов // Проверка результатов
monitoring_result_check: monitoring_result_check:
if (count($search_history) === 0) { if (count($search_history) === 0 && $offset !== 0) {
// Вышли за границу поиска после последней страницы // Вышли за границу поиска после последней страницы
// Реинициализация (вычитание для идентичного конечного результата) // Реинициализация (вычитание для идентичного конечного результата)
@ -271,7 +271,7 @@ class ProfileController extends Controller
foreach: ['edge' => 'account_edge_search'], foreach: ['edge' => 'account_edge_search'],
where: 'edge._to == search._id', where: 'edge._to == search._id',
limit: $rows_amount, limit: $rows_amount,
offset: ((int) $page_search_history ?? 0) * $rows_amount offset: $offset = ((int) $page_search_history ?? 0) * $rows_amount
); );
// Повторная проверка // Повторная проверка

View File

@ -13,30 +13,30 @@ use app\models\AccountForm;
class RegistrationController extends Controller class RegistrationController extends Controller
{ {
public function behaviors() // public function behaviors()
{ // {
return [ // return [
'access' => [ // 'access' => [
'class' => AccessControl::class, // 'class' => AccessControl::class,
'rules' => [ // 'rules' => [
[ // [
'allow' => true, // 'allow' => true,
'roles' => ['?'], // 'roles' => ['?'],
] // ]
], // ],
] // ]
]; // ];
} // }
public function actionIndex() public function actionIndex()
{ {
// Инициализация
$model = new AccountForm(yii::$app->request->post('AccountForm') ?? yii::$app->request->get('AccountForm'));
$model->scenario = $model::SCENARIO_REGISTRATION;
if (yii::$app->request->isPost) { if (yii::$app->request->isPost) {
// POST-запрос // POST-запрос
// Инициализация
$model = new AccountForm(yii::$app->request->post('AccountForm'));
$model->scenario = $model::SCENARIO_REGISTRATION;
yii::$app->response->format = Response::FORMAT_JSON; yii::$app->response->format = Response::FORMAT_JSON;
if (!yii::$app->user->isGuest || $model->registration()) { if (!yii::$app->user->isGuest || $model->registration()) {
@ -46,9 +46,17 @@ class RegistrationController extends Controller
$model->scenario = $model::SCENARIO_AUTHENTICATION; $model->scenario = $model::SCENARIO_AUTHENTICATION;
$model->authentication(); $model->authentication();
// Инициализация
$notifications_button = $this->renderPartial('/notification/button');
$notifications_panel_full = true;
$notifications_panel = $this->renderPartial('/notification/panel', compact('notifications_panel_full'));
// Запись ответа // Запись ответа
$return = [ $return = [
'menu' => $this->renderPartial('/account/panel/authenticated'), 'menu' => $this->renderPartial('/account/panel/authenticated', compact(
'notifications_button',
'notifications_panel'
)),
'_csrf' => yii::$app->request->getCsrfToken() '_csrf' => yii::$app->request->getCsrfToken()
]; ];
@ -80,7 +88,7 @@ class RegistrationController extends Controller
yii::$app->response->statusCode = 400; yii::$app->response->statusCode = 400;
return [ return [
'main' => $this->renderPartial('/account', compact('model')), 'main' => $this->renderPartial('/account/index', compact('model')),
'redirect' => '/registration', 'redirect' => '/registration',
'_csrf' => yii::$app->request->getCsrfToken() '_csrf' => yii::$app->request->getCsrfToken()
]; ];
@ -90,7 +98,7 @@ class RegistrationController extends Controller
if (!yii::$app->user->isGuest) { if (!yii::$app->user->isGuest) {
yii::$app->response->redirect('/'); yii::$app->response->redirect('/');
} else { } else {
return $this->render('/account', compact('model')); return $this->render('/account/index', compact('model'));
} }
} }
} }

View File

@ -165,7 +165,7 @@ class Account extends Document implements IdentityInterface, PartnerInterface
* @todo Подождать обновление Yii2 и добавить * @todo Подождать обновление Yii2 и добавить
* проверку типов передаваемых параметров * проверку типов передаваемых параметров
*/ */
public static function findByMail($mail): self public static function findByMail($mail): ?self
{ {
return static::findOne(['mail' => $mail]); return static::findOne(['mail' => $mail]);
} }

View File

@ -16,6 +16,8 @@ use Exception;
* Поиск * Поиск
* *
* @see Product Поиск по товарам * @see Product Поиск по товарам
*
* @todo Нет смысла каждый раз возвращать кнопку, надо написать проверки
*/ */
class Notification extends Document class Notification extends Document
{ {
@ -43,13 +45,18 @@ class Notification extends Document
* *
* @see SCENARIO_TRUSTED_CREATE * @see SCENARIO_TRUSTED_CREATE
*/ */
public Account|string|array|null $account; public string $account;
/** /**
* Текст уведомления * Текст уведомления
*/ */
public string $text; public string $text;
/**
* Разделитель получателей уведомлений
*/
public static string $delimiter = ',';
/** /**
* Типы уведомлений * Типы уведомлений
*/ */
@ -119,13 +126,10 @@ class Notification extends Document
/** /**
* Запись * Запись
*
* @param bool|string $html Содержимое уведомления (HTML или текст)
* @param Account|array|string|null $account Получатель уведомления
*/ */
public function write(Account|array|string|null $account = null): self|array|null public function write(): self|array|null
{ {
return $this::_write($this->text, $this->html, $account, $this->type); return $this::_write($this->text, $this->html, $this->account, $this->type);
} }
/** /**
@ -133,14 +137,14 @@ class Notification extends Document
* *
* @param string $html Содержимое уведомления (HTML или текст) * @param string $html Содержимое уведомления (HTML или текст)
* @param bool|string|null $html Содержимое уведомления (HTML или текст) * @param bool|string|null $html Содержимое уведомления (HTML или текст)
* @param Account|array|string|null $account Получатель уведомления * @param string $account Получатель уведомления
* @param string $type Тип уведомления * @param string $type Тип уведомления
*/ */
public static function _write(string $text, bool|string|null $html = false, Account|array|string|null $account = null, string $type = self::TYPE_NOTICE): self|array|null public static function _write(string $text, bool|string|null $html = false, string $account = null, string $type = self::TYPE_NOTICE): self|array|null
{ {
// Инициализация // Инициализация
$model = new self; $model = new self;
$account ?? $account = yii::$app->user->identity ?? throw new Exception('Не удалось инициализировать получателя'); $account or $account = yii::$app->user->identity->_key ?? throw new Exception('Не удалось инициализировать получателя');
if ((bool) (int) $html) { if ((bool) (int) $html) {
// Получен текст в формете HTML-кода // Получен текст в формете HTML-кода
@ -160,79 +164,56 @@ class Notification extends Document
// Уведомление записано // Уведомление записано
// Инициализация получателей и создание ребра // Инициализация получателей и создание ребра
if (empty($account)) { self::searchReceiverAndConnect($model, $account, $type);
// Получатель не передан
goto test;
} else if (is_string($account)) {
// Передана необработанная строка
// Инициализация
$delimiter = ',';
// Конвертация
$account = array_map('trim', explode($delimiter, $account));
if (in_array('@all', $account, true)) {
// Найден флаг обозначающий отправку всем пользователям
// Инициализация
$return = [];
foreach (Account::readAll() as $account) {
// Перебор всех аккаунтов
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
$return[] = AccountEdgeNotification::writeSafe($model->readId(), $account->readId(), $type) ? $model : null;
}
return $return ? $return : null;
}
if (in_array('@test', $account, true)) {
// Найден флаг обозначающий тестирование (отправка самому себе)
test:
return AccountEdgeNotification::writeSafe($model->readId(), yii::$app->user->id, $type) ? $model : null;
}
}
if (is_array($account)) {
// Несколько получателей
// Инициализация
$return = [];
foreach ($account as $account) {
// Перебор получателей
if ($account instanceof Account) {
// Один получатель
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
return AccountEdgeNotification::writeSafe($model->readId(), $account->readId(), $type) ? $model : null;
}
if ($account = Account::searchById(Account::collectionName() . '/' . $account)) {
// Аккаунт найден
echo ($account->readId()) . "\n";
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
$return[] = AccountEdgeNotification::writeSafe($model->readId(), $account->readId(), $type) ? $model : null;
}
}
return $return ? $return : null;
} else if ($account instanceof Account) {
// Один получатель
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
return AccountEdgeNotification::writeSafe($model->readId(), $account->readId(), $type) ? $model : null;
}
} }
return null; return null;
} }
/**
* Поиск получателя
*
* @param self $model Уведомление
* @param string $text Необработанный текст
* @param string $type Тип уведомления
*/
protected static function searchReceiverAndConnect(self $model, string $text, string $type = self::TYPE_NOTICE): AccountEdgeNotification|array|null
{
// Инициализация
$return = [];
// Конвертация
$accounts = array_map('trim', explode(self::$delimiter, $text));
foreach ($accounts as $account) {
if (in_array('@all', $accounts, true)) {
// Найден флаг обозначающий отправку всем пользователям
// Инициализация
$return = [];
foreach (Account::readAll() as $account) {
// Перебор всех аккаунтов
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
$return[] = AccountEdgeNotification::writeSafe($model->readId(), $account->readId(), $type);
}
} else if (in_array('@test', $accounts, true)) {
// Найден флаг обозначающий тестирование (отправка самому себе)
$return[] = AccountEdgeNotification::writeSafe($model->readId(), yii::$app->user->id, $type);
} else {
// Найден идентификатор (подразумевается)
if ($account = Account::searchById(Account::collectionName() . '/' . $account)) {
// Аккаунт найден
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
$return[] = AccountEdgeNotification::writeSafe($model->readId(), $account->readId(), $type);
}
}
}
return $return ? $return : null;
}
} }

View File

@ -9,8 +9,8 @@ use app\models\AccountForm;
?> ?>
<div class="container d-flex flex-column h-100"> <div class="container">
<div class="row my-auto"> <div class="row">
<div class="mx-auto"> <div class="mx-auto">
<?php <?php
$form = ActiveForm::begin([ $form = ActiveForm::begin([

View File

@ -1,6 +1,6 @@
<link href="/css/pages/cart.css" rel="stylesheet"> <link href="/css/pages/cart.css" rel="stylesheet">
<div id="page_cart" class="container py-3"> <div id="page_cart" class="container mb-auto py-3">
<article class="py-3 px-4 rounded"> <article class="py-3 px-4 rounded">
<h4 class="ml-4 mt-2 mb-4"><i class="fas fa-shopping-cart mr-2"></i>Корзина</h4> <h4 class="ml-4 mt-2 mb-4"><i class="fas fa-shopping-cart mr-2"></i>Корзина</h4>
<div class="col mb-4 list rounded overflow-hidden"> <div class="col mb-4 list rounded overflow-hidden">

View File

@ -5,12 +5,13 @@ declare(strict_types=1);
$this->title = 'SkillParts'; $this->title = 'SkillParts';
?> ?>
<link href="/css/ticker.css" rel="stylesheet"> <link href="/css/ticker.css" rel="stylesheet">
<div id="page_index"> <div id="page_index" class="mb-auto">
<div class="info_panel mb-4"> <section class="info_panel mb-4">
<div class="container h-100 d-flex flex-column justify-content-center"> <div class="container h-100 d-flex flex-column justify-content-center">
<p class="mb-4 ml-0 gilroy">Проблема с подбором запчастей?</p> <h1 class="mb-4 ml-0 gilroy">Проблема с подбором запчастей?</h1>
<p class="ml-0 d-flex"> <p class="ml-0 d-flex">
<span class="p-2 px-3 button_call_icon d-flex"><i class="fas fa-phone-alt my-auto text-white"></i></span> <span class="p-2 px-3 button_call_icon d-flex"><i class="fas fa-phone-alt my-auto text-white"></i></span>
<a class="btn text-white button_clean button_blue button_call" href="/call" role="button">Связаться с менеджером</a> <a class="btn text-white button_clean button_blue button_call" href="/call" role="button">Связаться с менеджером</a>
@ -19,9 +20,9 @@ $this->title = 'SkillParts';
<div class="h-100 d-flex flex-column justify-content-end"> <div class="h-100 d-flex flex-column justify-content-end">
<img class="img-fluid" src="/img/photos/compressed/963K_cutted.webp" alt="Связаться с менеджером"> <img class="img-fluid" src="/img/photos/compressed/963K_cutted.webp" alt="Связаться с менеджером">
</div> </div>
</div> </section>
<div class="h-100 d-flex ticker"> <section class="h-100 d-flex ticker">
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/cummins.png" alt="Cummins"> <img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/cummins.png" alt="Cummins">
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/iveco.png" alt="Iveco"> <img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/iveco.png" alt="Iveco">
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/komatsu.png" alt="Komatsu"> <img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/komatsu.png" alt="Komatsu">
@ -37,9 +38,9 @@ $this->title = 'SkillParts';
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/shehwa.png" alt="SHEHWA"> <img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/shehwa.png" alt="SHEHWA">
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/bomag.png" alt="BOMAG"> <img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/bomag.png" alt="BOMAG">
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/hitachi.png" alt="Hitachi"> <img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/hitachi.png" alt="Hitachi">
</div> </section>
<div class="container mb-4"> <section class="container mb-4">
<!-- <div class="row mb-3"> <!-- <div class="row mb-3">
<h4 class="col gilroy categories_blocks_panel_title">Сопутствующие товары</h4> <h4 class="col gilroy categories_blocks_panel_title">Сопутствующие товары</h4>
</div> --> </div> -->
@ -80,7 +81,7 @@ $this->title = 'SkillParts';
</div> </div>
</div> </div>
</div> </div>
</div> </section>
</div> </div>
<script src="/js/ticker.js" defer></script> <script src="/js/ticker.js" defer></script>

View File

@ -29,7 +29,7 @@ AppAsset::register($this);
<link rel="apple-touch-icon" sizes="144x144" href="/favicons/apple-icon-144x144.png"> <link rel="apple-touch-icon" sizes="144x144" href="/favicons/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/favicons/apple-icon-152x152.png"> <link rel="apple-touch-icon" sizes="152x152" href="/favicons/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-icon-180x180.png"> <link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="/favicons/android-icon-192x192.png"> <link rel="icon" type="image/png" sizes="192x192" href="/favicons/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/favicons/favicon-96x96.png"> <link rel="icon" type="image/png" sizes="96x96" href="/favicons/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png"> <link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png">
@ -50,9 +50,11 @@ AppAsset::register($this);
<header class="container pt-2 mt-1 mb-2 mb-sm-4"> <header class="container pt-2 mt-1 mb-2 mb-sm-4">
<div class="row h-100"> <div class="row h-100">
<a id="logo" class="col-3 col-md-4 h-100 py-2" title="SkillParts" href="/" role="button" onclick="return page_main();"> <div id="logo" class="col-3 col-md-4 h-100">
<img class="h-100" src="/img/logos/skillparts.svg" alt="SkillParts"> <a class="py-2 h-100 d-inline-flex" title="SkillParts" href="/" role="button" onclick="return page_main();">
</a> <img class="h-100" src="/img/logos/skillparts.svg" alt="SkillParts">
</a>
</div>
<div class="col px-0 mt-auto d-flex h-title"> <div class="col px-0 mt-auto d-flex h-title">
<div class="ml-auto p-0 h-divider-title-left"></div> <div class="ml-auto p-0 h-divider-title-left"></div>
<div class="px-4 d-flex flex-column justify-content-center h-divider-title"> <div class="px-4 d-flex flex-column justify-content-center h-divider-title">
@ -90,20 +92,20 @@ AppAsset::register($this);
<div class="position-relative col-sm-8 col-lg-10 px-0"> <div class="position-relative col-sm-8 col-lg-10 px-0">
<input id="search_line" type="text" class="form-control col-12 catalog_search_line button_clean" placeholder="Введите номер запчасти, например: 45223503481" oninput="$('#search_line').dropdown('hide'); product_search(this.value);" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" autocomplete="off"> <input id="search_line" type="text" class="form-control col-12 catalog_search_line button_clean" placeholder="Введите номер запчасти, например: 45223503481" oninput="$('#search_line').dropdown('hide'); product_search(this.value);" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" autocomplete="off">
<?php <?php
// Сделать системные настройки и по ним работать // Сделать системные настройки и по ним работать
$search_panel = yii::$app->controller->renderPartial('/search/panel', ['history' => true]); $search_panel = yii::$app->controller->renderPartial('/search/panel', ['history' => true]);
// if (!yii::$app->user->isGuest && $search_panel = $search_panel ?? yii::$app->controller->renderPartial('/search/panel', ['history' => true])) { // if (!yii::$app->user->isGuest && $search_panel = $search_panel ?? yii::$app->controller->renderPartial('/search/panel', ['history' => true])) {
echo <<<HTML echo <<<HTML
<div id="search_line_window" class="dropdown-menu w-100" aria-labelledby="search_line"> <div id="search_line_window" class="dropdown-menu w-100" aria-labelledby="search_line">
$search_panel $search_panel
</div> </div>
HTML; HTML;
// } else { // } else {
// echo <<<HTML // echo <<<HTML
// <div id="search_line_window" class="dropdown-menu w-100" style="display: none" aria-labelledby="search_line"></div> // <div id="search_line_window" class="dropdown-menu w-100" style="display: none" aria-labelledby="search_line"></div>
// HTML; // HTML;
// } // }
?> ?>
</div> </div>
<button type="submit" class="col btn button_clean catalog_search_button" onclick="product_search(this.parentElement.getElementsByTagName('input')[0].value, 1)">ПОИСК</button> <button type="submit" class="col btn button_clean catalog_search_button" onclick="product_search(this.parentElement.getElementsByTagName('input')[0].value, 1)">ПОИСК</button>
@ -112,7 +114,7 @@ AppAsset::register($this);
</div> </div>
</aside> </aside>
<main class="col p-0"> <main class="col p-0 d-flex flex-column justify-content-center">
<?= $content ?> <?= $content ?>
</main> </main>

View File

@ -1,6 +1,6 @@
<link href="/css/pages/orders.css" rel="stylesheet"> <link href="/css/pages/orders.css" rel="stylesheet">
<div id="page_orders" class="container py-3"> <div id="page_orders" class="container mb-auto py-3">
<article class="py-3 px-4 rounded"> <article class="py-3 px-4 rounded">
<h4 class="ml-4 mt-2 mb-4"><i class="fas fa-list mr-2"></i>Заказы</h4> <h4 class="ml-4 mt-2 mb-4"><i class="fas fa-list mr-2"></i>Заказы</h4>
<div class="col mb-4 list rounded overflow-hidden"> <div class="col mb-4 list rounded overflow-hidden">
@ -24,7 +24,8 @@
// Инициализация // Инициализация
extract($order); extract($order);
$date = date('d.m.Y', $order['date']); // Инициализация
$date = empty($jrnl) ? '' : date('H:i d.m.Y', end($jrnl)['date']);
echo <<<HTML echo <<<HTML
<div class="row py-2 cart_list_target"> <div class="row py-2 cart_list_target">

View File

@ -8,10 +8,10 @@ use app\models\Product;
?> ?>
<link href="/css/pages/product.css" rel="stylesheet"> <link href="/css/pages/product.css" rel="stylesheet">
<div id="page_product" class="container h-100"> <div id="page_product" class="container mb-auto">
<div class="row h-100 py-3"> <div class="row py-3">
<article class="col-12"> <article class="col-12">
<div class="h-100 p-3 d-flex flex-column rounded"> <div class="p-3 d-flex flex-column rounded">
<div id="product_slider" class="row px-3 profile_panel"> <div id="product_slider" class="row px-3 profile_panel">
<div class="col-1 product_slider_preview p-0 pr-3 mb-3"> <div class="col-1 product_slider_preview p-0 pr-3 mb-3">
<?php <?php

View File

@ -11,7 +11,7 @@ $panel ?? $panel = 'profile_panel_settings_import';
?> ?>
<link href="/css/pages/profile.css" rel="stylesheet"> <link href="/css/pages/profile.css" rel="stylesheet">
<div id="page_profile" class="container h-100"> <div id="page_profile" class="container mb-auto">
<div class="row h-100 py-3"> <div class="row h-100 py-3">
<nav class="col-3"> <nav class="col-3">
<?= $sidebar ?? yii::$app->controller->renderPartial('/profile/sidebar') ?> <?= $sidebar ?? yii::$app->controller->renderPartial('/profile/sidebar') ?>

View File

@ -8,7 +8,7 @@ $panel ?? $panel = 'profile_panel_monitoring_input_search_history';
?> ?>
<link href="/css/pages/profile.css" rel="stylesheet"> <link href="/css/pages/profile.css" rel="stylesheet">
<div id="page_profile" class="container h-100"> <div id="page_profile" class="container mb-auto">
<div class="row h-100 py-3"> <div class="row h-100 py-3">
<nav class="col-3"> <nav class="col-3">
<?= $sidebar ?? Yii::$app->controller->renderPartial('/profile/sidebar') ?> <?= $sidebar ?? Yii::$app->controller->renderPartial('/profile/sidebar') ?>
@ -36,7 +36,7 @@ $panel ?? $panel = 'profile_panel_monitoring_input_search_history';
<div class="col">Время</div> <div class="col">Время</div>
</div> </div>
<?php <?php
foreach ($search_history as $row) { foreach ($search_history ?? [] as $row) {
// Инициализация // Инициализация
$time = $row->jrnl; $time = $row->jrnl;
$date = empty($row->jrnl) ? '' : date('H:i d.m.Y', end($time)['date']); $date = empty($row->jrnl) ? '' : date('H:i d.m.Y', end($time)['date']);

View File

@ -44,8 +44,8 @@ use app\models\SupplyEdgeProduct;
<dt> <dt>
<?php <?php
if ( if (
'/' . yii::$app->request->pathInfo === '/profile/supplies' '/' . yii::$app->request->pathInfo === $targetUrl = '/profile/supplies'
|| '/' . yii::$app->request->pathInfo === '/profile/import' || '/' . yii::$app->request->pathInfo === $targetUrl = '/profile/import'
) { ) {
// Запрошена та же страница от которой послан запрос (текущая) // Запрошена та же страница от которой послан запрос (текущая)

View File

@ -12,7 +12,7 @@ $panel ?? $panel = 'profile_panel_supplies_input_import';
<link href="/css/pages/profile.css" rel="stylesheet"> <link href="/css/pages/profile.css" rel="stylesheet">
<div id="page_profile" class="container h-100"> <div id="page_profile" class="container mb-auto">
<div class="row h-100 py-3"> <div class="row h-100 py-3">
<nav class="col-3"> <nav class="col-3">
<?= $sidebar ?? yii::$app->controller->renderPartial('/profile/sidebar') ?> <?= $sidebar ?? yii::$app->controller->renderPartial('/profile/sidebar') ?>

View File

@ -15,7 +15,7 @@ $panel ?? $panel = 'profile_panel_trusted_input_notifications';
<link href="/css/pages/profile.css" rel="stylesheet"> <link href="/css/pages/profile.css" rel="stylesheet">
<div id="page_profile" class="container h-100"> <div id="page_profile" class="container mb-auto">
<div class="row h-100 py-3"> <div class="row h-100 py-3">
<nav class="col-3"> <nav class="col-3">
<?= $sidebar ?? yii::$app->controller->renderPartial('/profile/sidebar') ?> <?= $sidebar ?? yii::$app->controller->renderPartial('/profile/sidebar') ?>

View File

@ -2,7 +2,7 @@
<div id="page_search" class="container h-100"> <div id="page_search" class="container h-100">
<div class="row py-3"> <div class="row py-3">
<article class="col"> <section class="col">
<?php <?php
if (isset($timer) && $timer > 0) { if (isset($timer) && $timer > 0) {
echo <<<HTML echo <<<HTML
@ -143,7 +143,7 @@
} }
} }
?> ?>
</article> </section>
</div> </div>
</div> </div>

View File

@ -25,7 +25,7 @@ if (isset($history) && $history) {
foreach ($rows as $row) { foreach ($rows as $row) {
// Инициализация // Инициализация
$time = $row->jrnl; $time = $row->jrnl;
$date = empty($row->jrnl) ? '' : date('H:i d.m.Y', end($time)['date']); $date = empty($time) ? '' : date('H:i d.m.Y', end($time)['date']);
echo <<<HTML echo <<<HTML
<a class="dropdown-item d-flex button_white text-dark" href="/search?type=product&q=$row->text">$row->text<span class="ml-auto">$date</span></a> <a class="dropdown-item d-flex button_white text-dark" href="/search?type=product&q=$row->text">$row->text<span class="ml-auto">$date</span></a>

View File

@ -1,12 +1,12 @@
#page_search nav>div, #page_search nav>div,
#page_search article>div>div { #page_search section>div>div {
height : 65px; height : 65px;
background-color: #fff; background-color: #fff;
border-right : 0 solid #fff; border-right : 0 solid #fff;
transition : 100ms ease-in; transition : 100ms ease-in;
} }
/* #page_search nav > div, #page_search article > div:hover > div { /* #page_search nav > div, #page_search section > div:hover > div {
height: 68px; height: 68px;
border-right: 6px solid #e1e1ea; border-right: 6px solid #e1e1ea;
border-radius: .25rem 0 0 .25rem !important; border-radius: .25rem 0 0 .25rem !important;