mirror of
https://github.com/openvk/openvk
synced 2025-03-15 05:55:29 +03:00
Новые поля для поиска etc.
This commit is contained in:
parent
544a16dff7
commit
c93fb477d5
8 changed files with 163 additions and 60 deletions
|
@ -131,5 +131,10 @@ abstract class DBEntity
|
||||||
$this->changes = [];
|
$this->changes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTableName(): string
|
||||||
|
{
|
||||||
|
return $this->getTable()->getName();
|
||||||
|
}
|
||||||
|
|
||||||
use \Nette\SmartObject;
|
use \Nette\SmartObject;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ class Logs
|
||||||
return $this->toLog($this->logs->get($id));
|
return $this->toLog($this->logs->get($id));
|
||||||
}
|
}
|
||||||
|
|
||||||
function create(int $user, string $table, string $model, int $type, $object, $changes): void
|
function create(int $user, string $table, string $model, int $type, $object, $changes, ?string $ip = NULL, ?string $useragent = NULL): void
|
||||||
{
|
{
|
||||||
if (OPENVK_ROOT_CONF["openvk"]["preferences"]["logs"] === true) {
|
if (OPENVK_ROOT_CONF["openvk"]["preferences"]["logs"] === true) {
|
||||||
$fobject = (is_array($object) ? $object : $object->unwrap());
|
$fobject = (is_array($object) ? $object : $object->unwrap());
|
||||||
|
@ -65,8 +65,8 @@ class Logs
|
||||||
$log->setXdiff_Old(json_encode($nobject));
|
$log->setXdiff_Old(json_encode($nobject));
|
||||||
$log->setXdiff_New(json_encode($_changes));
|
$log->setXdiff_New(json_encode($_changes));
|
||||||
$log->setTs(time());
|
$log->setTs(time());
|
||||||
$log->setIp(CurrentUser::i()->getIP());
|
$log->setIp($ip ?? CurrentUser::i()->getIP());
|
||||||
$log->setUserAgent(CurrentUser::i()->getUserAgent());
|
$log->setUserAgent($useragent ?? CurrentUser::i()->getUserAgent());
|
||||||
$log->save();
|
$log->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ final class AuthPresenter extends OpenVKPresenter
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->authenticator->authenticate($chUser->getId());
|
$this->authenticator->authenticate($chUser->getId());
|
||||||
(new Logs)->create($user->getId(), "profiles", "openvk\\Web\\Models\\Entities\\User", 0, $user, $user);
|
(new Logs)->create($user->getId(), "profiles", "openvk\\Web\\Models\\Entities\\User", 0, $user, $user, $_SERVER["REMOTE_ADDR"], $_SERVER["HTTP_USER_AGENT"]);
|
||||||
$this->redirect("/id" . $user->getId());
|
$this->redirect("/id" . $user->getId());
|
||||||
$user->save();
|
$user->save();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Presenters;
|
namespace openvk\Web\Presenters;
|
||||||
|
|
||||||
use Nette\Database\DriverException;
|
use Nette\Database\DriverException;
|
||||||
use Nette\Utils\Finder;
|
use Nette\Utils\Finder;
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use openvk\Web\Models\Entities\Club;
|
use openvk\Web\Models\Entities\Club;
|
||||||
use openvk\Web\Models\Entities\Comment;
|
use openvk\Web\Models\Entities\Comment;
|
||||||
|
use openvk\Web\Models\Entities\Log;
|
||||||
use openvk\Web\Models\Entities\NoSpamLog;
|
use openvk\Web\Models\Entities\NoSpamLog;
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
use openvk\Web\Models\Repositories\Logs;
|
||||||
use openvk\Web\Models\Repositories\NoSpamLogs;
|
use openvk\Web\Models\Repositories\NoSpamLogs;
|
||||||
|
|
||||||
final class NoSpamPresenter extends OpenVKPresenter
|
final class NoSpamPresenter extends OpenVKPresenter
|
||||||
|
@ -135,15 +139,53 @@ final class NoSpamPresenter extends OpenVKPresenter
|
||||||
$this->assertNoCSRF();
|
$this->assertNoCSRF();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
|
function searchByAdditionalParams(?string $table = NULL, ?string $where = NULL, ?string $ip = NULL, ?string $useragent = NULL, ?int $ts = NULL, ?int $te = NULL, ?int $user = NULL)
|
||||||
|
{
|
||||||
|
$db = DatabaseConnection::i()->getContext();
|
||||||
|
if ($table && ($ip || $useragent || $ts || $te || $user)) {
|
||||||
|
$conditions = [];
|
||||||
|
|
||||||
|
if ($ip) $conditions[] = "`ip` REGEXP '$ip'";
|
||||||
|
if ($useragent) $conditions[] = "`useragent` REGEXP '$useragent'";
|
||||||
|
if ($ts) $conditions[] = "`ts` < $ts";
|
||||||
|
if ($te) $conditions[] = "`ts` > $te";
|
||||||
|
if ($user) $conditions[] = "`user` = $user";
|
||||||
|
$logs = $db->query("SELECT * FROM `logs` WHERE (`object_table` = '$table') AND (" . implode(" AND ", $conditions) . ") GROUP BY `object_id`");
|
||||||
|
$response = [];
|
||||||
|
|
||||||
|
if (!$where) {
|
||||||
|
foreach ($logs as $log) {
|
||||||
|
$log = (new Logs)->get($log->id);
|
||||||
|
$response[] = $log->getObject()->unwrap();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($logs as $log) {
|
||||||
|
$log = (new Logs)->get($log->id);
|
||||||
|
$object = $log->getObject()->unwrap();
|
||||||
|
|
||||||
|
if (!$object) continue;
|
||||||
|
foreach ($db->query("SELECT * FROM `$table` WHERE $where")->fetchAll() as $o) {
|
||||||
|
if ($object->id === $o["id"]) {
|
||||||
|
$response[] = $object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$where = $this->postParam("where");
|
$where = $this->postParam("where");
|
||||||
$ip = $this->postParam("ip");
|
$ip = $this->postParam("ip");
|
||||||
$useragent = $this->postParam("useragent");
|
$useragent = $this->postParam("useragent");
|
||||||
$searchTerm = $this->postParam("q");
|
$searchTerm = $this->postParam("q");
|
||||||
$ts = $this->postParam("ts");
|
$ts = (int)$this->postParam("ts");
|
||||||
$te = $this->postParam("te");
|
$te = (int)$this->postParam("te");
|
||||||
|
$user = (int)$this->postParam("user");
|
||||||
|
|
||||||
if (!$ip && !$useragent && !$searchTerm && !$ts && !$te && !$where && !$searchTerm)
|
if (!$ip && !$useragent && !$searchTerm && !$ts && !$te && !$where && !$searchTerm && !$user)
|
||||||
$this->returnJson(["success" => false, "error" => "Нет запроса. Заполните поле \"подстрока\" или введите запрос \"WHERE\" в поле под ним."]);
|
$this->returnJson(["success" => false, "error" => "Нет запроса. Заполните поле \"подстрока\" или введите запрос \"WHERE\" в поле под ним."]);
|
||||||
|
|
||||||
$model_name = NoSpamPresenter::ENTITIES_NAMESPACE . "\\" . $this->postParam("model");
|
$model_name = NoSpamPresenter::ENTITIES_NAMESPACE . "\\" . $this->postParam("model");
|
||||||
|
@ -160,8 +202,7 @@ final class NoSpamPresenter extends OpenVKPresenter
|
||||||
$table = $model->getTableName();
|
$table = $model->getTableName();
|
||||||
$columns = $db->getStructure()->getColumns($table);
|
$columns = $db->getStructure()->getColumns($table);
|
||||||
|
|
||||||
$rows = [];
|
if ($searchTerm) {
|
||||||
if (!$where) {
|
|
||||||
$conditions = [];
|
$conditions = [];
|
||||||
$need_deleted = false;
|
$need_deleted = false;
|
||||||
foreach ($columns as $column) {
|
foreach ($columns as $column) {
|
||||||
|
@ -171,12 +212,19 @@ final class NoSpamPresenter extends OpenVKPresenter
|
||||||
$conditions[] = "`$column[name]` REGEXP '$searchTerm'";
|
$conditions[] = "`$column[name]` REGEXP '$searchTerm'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$conditions = implode(" OR ", $conditions);
|
||||||
|
|
||||||
$where = "(" . implode(" OR ", $conditions) . ")";
|
$where = ($where ? " AND ($conditions)" : $conditions);
|
||||||
if ($need_deleted) $where .= " AND `deleted` = 0";
|
if ($need_deleted) $where .= " AND `deleted` = 0";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$rows = [];
|
||||||
|
if ($ip || $useragent || $ts || $te || $user) {
|
||||||
|
$rows = searchByAdditionalParams($table, $where, $ip, $useragent, $ts, $te, $user);
|
||||||
|
}
|
||||||
|
|
||||||
$result = $db->query("SELECT * FROM `$table` WHERE $where");
|
$result = $db->query("SELECT * FROM `$table` WHERE $where");
|
||||||
|
if (count($rows) === 0)
|
||||||
$rows = $result->fetchAll();
|
$rows = $result->fetchAll();
|
||||||
|
|
||||||
if (!in_array((int)$this->postParam("ban"), [1, 2, 3])) {
|
if (!in_array((int)$this->postParam("ban"), [1, 2, 3])) {
|
||||||
|
|
|
@ -16,16 +16,15 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select name="model" id="model" style="margin-left: -2px;">
|
<select name="model" id="model" style="margin-left: -2px;">
|
||||||
<option selected>Не выбрано</option>
|
<option selected value="none">Не выбрано</option>
|
||||||
<option n:foreach="$models as $model" value="{$model}">
|
<option n:foreach="$models as $model" value="{$model}">{$model}</option>
|
||||||
{$model}
|
|
||||||
</option>
|
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div style="border-top: 1px solid #ECECEC; margin: 8px 0;"/>
|
<div style="border-top: 1px solid #ECECEC; margin: 8px 0;"/>
|
||||||
|
<div id="noSpam-fields" style="display: none;">
|
||||||
<table cellspacing="7" cellpadding="0" width="100%" border="0">
|
<table cellspacing="7" cellpadding="0" width="100%" border="0">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr style="width: 129px; border-top: 1px solid #ECECEC;">
|
<tr style="width: 129px; border-top: 1px solid #ECECEC;">
|
||||||
|
@ -36,13 +35,20 @@
|
||||||
<input type="text" name="regex" placeholder="Regex" id="regex">
|
<input type="text" name="regex" placeholder="Regex" id="regex">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{* "Это могли бы быть мы с тобой, но" в овк нет логов :( *}
|
<tr style="width: 129px; border-top: 1px solid #ECECEC;">
|
||||||
{*<tr style="width: 129px">
|
<td>
|
||||||
|
<span class="nobold">Пользователь:</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="user" placeholder="ID" id="user">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="width: 129px">
|
||||||
<td>
|
<td>
|
||||||
<span class="nobold">IP:</span>
|
<span class="nobold">IP:</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="ip" placeholder="или подсеть">
|
<input type="text" name="ip" id="ip" placeholder="или подсеть">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr style="width: 129px">
|
<tr style="width: 129px">
|
||||||
|
@ -50,7 +56,7 @@
|
||||||
<span class="nobold">Юзер-агент:</span>
|
<span class="nobold">Юзер-агент:</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="useragent" placeholder="Mozila 1.0 Blablabla/test">
|
<input type="text" name="useragent" id="useragent" placeholder="Mozila 1.0 Blablabla/test">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr style="width: 129px">
|
<tr style="width: 129px">
|
||||||
|
@ -58,7 +64,7 @@
|
||||||
<span class="nobold">Время раньше, чем:</span>
|
<span class="nobold">Время раньше, чем:</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="date" name="ds">
|
<input type="datetime-local" name="ts" id="ts">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr style="width: 129px">
|
<tr style="width: 129px">
|
||||||
|
@ -66,15 +72,14 @@
|
||||||
<span class="nobold">Время позже, чем:</span>
|
<span class="nobold">Время позже, чем:</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="date" name="de">
|
<input type="datetime-local" name="te" id="te">
|
||||||
</td>
|
</td>
|
||||||
</tr>*}
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<br />
|
<textarea style="resize: vertical; width: calc(100% - 6px)" placeholder='city = "Воскресенск" && id = 1'
|
||||||
<center><b>ИЛИ</b></center>
|
name="where" id="where"/>
|
||||||
<br />
|
<span style="color: grey; font-size: 8px;">WHERE для поиска по разделу</span>
|
||||||
<textarea style="resize: vertical; width: calc(100% - 6px)" placeholder='city = "Воскресенск" && id = 1' name="where" id="where" />
|
|
||||||
<div style="border-top: 1px solid #ECECEC; margin: 8px 0;"/>
|
<div style="border-top: 1px solid #ECECEC; margin: 8px 0;"/>
|
||||||
<table cellspacing="7" cellpadding="0" width="100%" border="0">
|
<table cellspacing="7" cellpadding="0" width="100%" border="0">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -103,13 +108,24 @@
|
||||||
</div>
|
</div>
|
||||||
</center>
|
</center>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="noSpam-model-not-selected">
|
||||||
|
<center id="noSpam-model-not-selected-text" style="padding: 71px 25px;">Выберите раздел для начала работы</center>
|
||||||
|
<center id="noSpam-model-not-selected-loader" style="display: none;">
|
||||||
|
<img src="/assets/packages/static/openvk/img/loading_mini.gif" style="width: 40px; margin: 125px 0;">
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div style="width: 50%;">
|
<div style="width: 50%;">
|
||||||
<center id="noSpam-results-loader" style="display: none;">
|
<center id="noSpam-results-loader" style="display: none;">
|
||||||
<img src="/assets/packages/static/openvk/img/loading_mini.gif" style="width: 40px; margin: 125px 0;">
|
<img src="/assets/packages/static/openvk/img/loading_mini.gif" style="width: 40px; margin: 125px 0;">
|
||||||
</center>
|
</center>
|
||||||
<center id="noSpam-results-text" style="margin: 125px 25px;">Здесь будут отображаться результаты поиска</center>
|
<center id="noSpam-results-text" style="margin: 125px 25px;">Здесь будут отображаться результаты поиска</center>
|
||||||
<div id="noSpam-results-block" style="display: none;">
|
<div id="noSpam-results-block" style="display: none;">
|
||||||
<h4 style="padding: 8px;">Результаты поиска (<span id="noSpam-results-count" style="color: inherit; font-weight: inherit;"></span> шт.)</h4>
|
<h4 style="padding: 8px;">Результаты поиска
|
||||||
|
<span style="color: #a2a2a2; font-weight: inherit">
|
||||||
|
(<span id="noSpam-results-count" style="color: #a2a2a2; font-weight: inherit;"></span> шт.)
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
<ul style="padding-inline-start:18px;" id="noSpam-results-list"></ul>
|
<ul style="padding-inline-start:18px;" id="noSpam-results-list"></ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -127,6 +143,11 @@
|
||||||
let model = $("#model").val();
|
let model = $("#model").val();
|
||||||
let regex = $("#regex").val();
|
let regex = $("#regex").val();
|
||||||
let where = $("#where").val();
|
let where = $("#where").val();
|
||||||
|
let ip = $("#ip").val();
|
||||||
|
let useragent = $("#useragent").val();
|
||||||
|
let ts = $("#ts").val() ? Math.floor(new Date($("#ts").val()).getTime() / 1000) : null;
|
||||||
|
let te = $("#te").val() ? Math.floor(new Date($("#te").val()).getTime() / 1000) : null;
|
||||||
|
let user = $("#user").val();
|
||||||
|
|
||||||
await $.ajax({
|
await $.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
|
@ -136,6 +157,11 @@
|
||||||
q: regex,
|
q: regex,
|
||||||
where: where,
|
where: where,
|
||||||
ban: ban,
|
ban: ban,
|
||||||
|
ip: ip,
|
||||||
|
useragent: useragent,
|
||||||
|
ts: ts,
|
||||||
|
te: te,
|
||||||
|
user: user,
|
||||||
hash: {=$csrfToken}
|
hash: {=$csrfToken}
|
||||||
},
|
},
|
||||||
success: (response) => {
|
success: (response) => {
|
||||||
|
@ -182,12 +208,33 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#search").on("click", () => { search(); });
|
$("#search").on("click", () => { search(); });
|
||||||
$("#regex, #where").keypress((e) => {
|
$("input, textarea").keypress((e) => {
|
||||||
if (e.which === 13 && !e.shiftKey) {
|
if (e.which === 13 && !e.shiftKey) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
search();
|
search();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$("#apply").on("click", () => { search(Number($("#noSpam-ban-type").val())); })
|
$("#apply").on("click", () => { search(Number($("#noSpam-ban-type").val())); })
|
||||||
|
$("#model").on("change", async (e) => {
|
||||||
|
if (e.target.value !== "none") {
|
||||||
|
$("#noSpam-fields").hide();
|
||||||
|
$("#noSpam-model-not-selected").show();
|
||||||
|
$("#noSpam-model-not-selected-text").hide();
|
||||||
|
$("#noSpam-model-not-selected-loader").show();
|
||||||
|
setTimeout(() => {
|
||||||
|
$("#noSpam-model-not-selected").hide();
|
||||||
|
$("#noSpam-fields").show();
|
||||||
|
$("#noSpam-model-not-selected-loader").hide();
|
||||||
|
}, 100)
|
||||||
|
} else {
|
||||||
|
$("#noSpam-fields").hide();
|
||||||
|
$("#noSpam-model-not-selected").show();
|
||||||
|
$("#noSpam-model-not-selected-loader").show();
|
||||||
|
setTimeout(() => {
|
||||||
|
$("#noSpam-model-not-selected-text").show();
|
||||||
|
$("#noSpam-model-not-selected-loader").hide();
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
{/block}
|
{/block}
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
<a n:attr="id => ($mode === 'form' ? 'act_tab_a' : 'ki')" href="/noSpam">Бан по шаблону</a>
|
<a n:attr="id => ($mode === 'form' ? 'act_tab_a' : 'ki')" href="/noSpam">Бан по шаблону</a>
|
||||||
</div>
|
</div>
|
||||||
<div n:attr="id => ($mode === 'templates' ? 'activetabs' : 'ki')" class="tab">
|
<div n:attr="id => ($mode === 'templates' ? 'activetabs' : 'ki')" class="tab">
|
||||||
<a n:attr="id => ($mode === 'templates' ? 'act_tab_a' : 'ki')" href="/noSpam?act=templates">Шаблоны</a>
|
<a n:attr="id => ($mode === 'templates' ? 'act_tab_a' : 'ki')" href="/noSpam?act=templates">Действующие шаблоны</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -89,8 +89,10 @@
|
||||||
// Full width block
|
// Full width block
|
||||||
$(".navigation").hide();
|
$(".navigation").hide();
|
||||||
$(".page_content").width("100%");
|
$(".page_content").width("100%");
|
||||||
$(".page_body").width("100%").css("margin-right", 0).css("margin-top", "-5px");
|
$(".page_body").width("100%").css("margin-right", 0).css("margin-top", "-2px");
|
||||||
$(".tabs").width("100%");
|
$(".tabs").width("100%");
|
||||||
|
$(".sidebar").css("margin", 0);
|
||||||
|
$(".page_header").css("position", "initial");
|
||||||
|
|
||||||
function openTableField(name, id) {
|
function openTableField(name, id) {
|
||||||
MessageBox(name, $(`#${ name}-${ id}`).text(), ["OK"], [Function.noop]);
|
MessageBox(name, $(`#${ name}-${ id}`).text(), ["OK"], [Function.noop]);
|
||||||
|
|
|
@ -671,6 +671,7 @@ input[type~="phone"],
|
||||||
input[type="search"],
|
input[type="search"],
|
||||||
input[type~="search"],
|
input[type~="search"],
|
||||||
input[type~="date"],
|
input[type~="date"],
|
||||||
|
input[type~="datetime-local"],
|
||||||
select {
|
select {
|
||||||
border: 1px solid #C0CAD5;
|
border: 1px solid #C0CAD5;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
|
|
Loading…
Reference in a new issue