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

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",
"moonlandsoft/yii2-phpexcel": ">=2.0",
"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": {
"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",
"This file is @generated automatically"
],
"content-hash": "f259164a4251a4ef37262d42fbeb40d6",
"content-hash": "116946ecdb84687a081d5633fd8505f6",
"packages": [
{
"name": "bower-asset/bootstrap",
"version": "v3.4.1",
"source": {
"type": "git",
"url": "https://github.com/twbs/bootstrap.git",
"url": "git@github.com:twbs/bootstrap.git",
"reference": "68b0d231a13201eb14acd3dc84e51543d16e5f7e"
},
"dist": {
@ -715,56 +715,6 @@
},
"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",
"version": "2.0.0",
@ -3554,16 +3504,16 @@
},
{
"name": "phpspec/prophecy",
"version": "1.12.2",
"version": "1.13.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "245710e971a030f42e08f4912863805570f23d39"
"reference": "be1996ed8adc35c3fd795488a653f4b518be70ea"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39",
"reference": "245710e971a030f42e08f4912863805570f23d39",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea",
"reference": "be1996ed8adc35c3fd795488a653f4b518be70ea",
"shasum": ""
},
"require": {
@ -3615,9 +3565,9 @@
],
"support": {
"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",
@ -3939,16 +3889,16 @@
},
{
"name": "phpunit/phpunit",
"version": "9.5.2",
"version": "9.5.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "f661659747f2f87f9e72095bb207bceb0f151cb4"
"reference": "27241ac75fc37ecf862b6e002bf713b6566cbe41"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f661659747f2f87f9e72095bb207bceb0f151cb4",
"reference": "f661659747f2f87f9e72095bb207bceb0f151cb4",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/27241ac75fc37ecf862b6e002bf713b6566cbe41",
"reference": "27241ac75fc37ecf862b6e002bf713b6566cbe41",
"shasum": ""
},
"require": {
@ -4026,7 +3976,7 @@
],
"support": {
"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": [
{
@ -4038,7 +3988,7 @@
"type": "github"
}
],
"time": "2021-02-02T14:45:58+00:00"
"time": "2021-03-17T07:30:34+00:00"
},
{
"name": "psr/container",
@ -6721,9 +6671,7 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"mirzaev/yii2-arangodb": 20
},
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {

View File

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

View File

@ -34,11 +34,15 @@ class DeauthenticationController extends Controller
public function actionIndex()
{
// Инициализация
yii::$app->response->format = Response::FORMAT_JSON;
// Выход из аккаунта
yii::$app->user->logout();
// Удаление сессии
yii::$app->session->destroy();
// Инициализация
$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()
{
var_dump(yii::$app->session->id);
if (yii::$app->request->isPost) {
// POST-запрос
// Инициализация
$model = new Notification(yii::$app->request->post('Notification'));
$preload = (bool) (int) yii::$app->request->post('preload');
$account = yii::$app->user->identity;
yii::$app->response->format = Response::FORMAT_JSON;
@ -67,7 +70,7 @@ class NotificationController extends Controller
->for(['account', $model::collectionName() . '_edge_account'])
->traversal($model::collectionName(), 'OUTBOUND')
->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');
if (yii::$app->request->post('last')) {
@ -91,7 +94,7 @@ class NotificationController extends Controller
* @param bool $new Активация проверки на то, что уведомление не получено
* @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) {
// Запрошен подсчёт непрочитанных уведомлений
@ -106,7 +109,7 @@ class NotificationController extends Controller
params: $new ? $let->getBindVars() : [],
subquery_where: [
[
'account._id' => yii::$app->user->id
'account._id' => $account->readId()
],
[
[
@ -122,8 +125,11 @@ class NotificationController extends Controller
'notification_edge_account',
'(' . (string) $let . ')'
],
foreach: [
'edge' => 'notification_edge_account'
],
where: $new ? [
'account_edge_notification[0]._to' => null
'edge != null'
] : [],
limit: $limit,
sort: ['DESC'],

View File

@ -248,13 +248,13 @@ class ProfileController extends Controller
foreach: ['edge' => 'account_edge_search'],
where: 'edge._to == search._id',
limit: $rows_amount,
offset: ((int) $page_search_history ?? 0) * $rows_amount
offset: $offset = ((int) $page_search_history ?? 0) * $rows_amount
);
// Проверка результатов
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'],
where: 'edge._to == search._id',
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
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'allow' => true,
'roles' => ['?'],
]
],
]
];
}
// public function behaviors()
// {
// return [
// 'access' => [
// 'class' => AccessControl::class,
// 'rules' => [
// [
// 'allow' => true,
// 'roles' => ['?'],
// ]
// ],
// ]
// ];
// }
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) {
// POST-запрос
// Инициализация
$model = new AccountForm(yii::$app->request->post('AccountForm'));
$model->scenario = $model::SCENARIO_REGISTRATION;
yii::$app->response->format = Response::FORMAT_JSON;
if (!yii::$app->user->isGuest || $model->registration()) {
@ -46,9 +46,17 @@ class RegistrationController extends Controller
$model->scenario = $model::SCENARIO_AUTHENTICATION;
$model->authentication();
// Инициализация
$notifications_button = $this->renderPartial('/notification/button');
$notifications_panel_full = true;
$notifications_panel = $this->renderPartial('/notification/panel', compact('notifications_panel_full'));
// Запись ответа
$return = [
'menu' => $this->renderPartial('/account/panel/authenticated'),
'menu' => $this->renderPartial('/account/panel/authenticated', compact(
'notifications_button',
'notifications_panel'
)),
'_csrf' => yii::$app->request->getCsrfToken()
];
@ -80,7 +88,7 @@ class RegistrationController extends Controller
yii::$app->response->statusCode = 400;
return [
'main' => $this->renderPartial('/account', compact('model')),
'main' => $this->renderPartial('/account/index', compact('model')),
'redirect' => '/registration',
'_csrf' => yii::$app->request->getCsrfToken()
];
@ -90,7 +98,7 @@ class RegistrationController extends Controller
if (!yii::$app->user->isGuest) {
yii::$app->response->redirect('/');
} 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 и добавить
* проверку типов передаваемых параметров
*/
public static function findByMail($mail): self
public static function findByMail($mail): ?self
{
return static::findOne(['mail' => $mail]);
}

View File

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

View File

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

View File

@ -1,6 +1,6 @@
<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">
<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">

View File

@ -5,12 +5,13 @@ declare(strict_types=1);
$this->title = 'SkillParts';
?>
<link href="/css/ticker.css" rel="stylesheet">
<div id="page_index">
<div class="info_panel mb-4">
<div id="page_index" class="mb-auto">
<section class="info_panel mb-4">
<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">
<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>
@ -19,9 +20,9 @@ $this->title = 'SkillParts';
<div class="h-100 d-flex flex-column justify-content-end">
<img class="img-fluid" src="/img/photos/compressed/963K_cutted.webp" alt="Связаться с менеджером">
</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/iveco.png" alt="Iveco">
<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/bomag.png" alt="BOMAG">
<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">
<h4 class="col gilroy categories_blocks_panel_title">Сопутствующие товары</h4>
</div> -->
@ -80,7 +81,7 @@ $this->title = 'SkillParts';
</div>
</div>
</div>
</div>
</section>
</div>
<script src="/js/ticker.js" defer></script>

View File

@ -50,9 +50,11 @@ AppAsset::register($this);
<header class="container pt-2 mt-1 mb-2 mb-sm-4">
<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">
<a class="py-2 h-100 d-inline-flex" title="SkillParts" href="/" role="button" onclick="return page_main();">
<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="ml-auto p-0 h-divider-title-left"></div>
<div class="px-4 d-flex flex-column justify-content-center h-divider-title">
@ -112,7 +114,7 @@ AppAsset::register($this);
</div>
</aside>
<main class="col p-0">
<main class="col p-0 d-flex flex-column justify-content-center">
<?= $content ?>
</main>

View File

@ -1,6 +1,6 @@
<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">
<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">
@ -24,7 +24,8 @@
// Инициализация
extract($order);
$date = date('d.m.Y', $order['date']);
// Инициализация
$date = empty($jrnl) ? '' : date('H:i d.m.Y', end($jrnl)['date']);
echo <<<HTML
<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">
<div id="page_product" class="container h-100">
<div class="row h-100 py-3">
<div id="page_product" class="container mb-auto">
<div class="row py-3">
<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 class="col-1 product_slider_preview p-0 pr-3 mb-3">
<?php

View File

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

View File

@ -44,8 +44,8 @@ use app\models\SupplyEdgeProduct;
<dt>
<?php
if (
'/' . yii::$app->request->pathInfo === '/profile/supplies'
|| '/' . yii::$app->request->pathInfo === '/profile/import'
'/' . yii::$app->request->pathInfo === $targetUrl = '/profile/supplies'
|| '/' . 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">
<div id="page_profile" class="container h-100">
<div id="page_profile" class="container mb-auto">
<div class="row h-100 py-3">
<nav class="col-3">
<?= $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">
<div id="page_profile" class="container h-100">
<div id="page_profile" class="container mb-auto">
<div class="row h-100 py-3">
<nav class="col-3">
<?= $sidebar ?? yii::$app->controller->renderPartial('/profile/sidebar') ?>

View File

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

View File

@ -25,7 +25,7 @@ if (isset($history) && $history) {
foreach ($rows as $row) {
// Инициализация
$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
<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 article>div>div {
#page_search section>div>div {
height : 65px;
background-color: #fff;
border-right : 0 solid #fff;
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;
border-right: 6px solid #e1e1ea;
border-radius: .25rem 0 0 .25rem !important;