Поиск по нескольким разделам

This commit is contained in:
n1rwana 2023-08-09 12:35:37 +03:00
parent 02a393b79f
commit 6f9cbdfa84
No known key found for this signature in database
GPG key ID: 184A60085ABF17D8
3 changed files with 239 additions and 133 deletions

View file

@ -152,7 +152,13 @@ final class NoSpamPresenter extends OpenVKPresenter
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`");
$whereStart = "WHERE `object_table` = '$table'";
if ($table === "profiles") {
$whereStart .= "AND `type` = 0";
}
$logs = $db->query("SELECT * FROM `logs` $whereStart AND (" . implode(" AND ", $conditions) . ") GROUP BY `object_id`");
$response = [];
if (!$where) {
@ -166,6 +172,11 @@ final class NoSpamPresenter extends OpenVKPresenter
$object = $log->getObject()->unwrap();
if (!$object) continue;
//exit(var_dump(substr_replace($where, "", 0, strlen(" AND"))));
if (str_starts_with($where, " AND")) {
$where = substr_replace($where, "", 0, strlen(" AND"));
}
foreach ($db->query("SELECT * FROM `$table` WHERE $where")->fetchAll() as $o) {
if ($object->id === $o["id"]) {
$response[] = $object;
@ -179,6 +190,9 @@ final class NoSpamPresenter extends OpenVKPresenter
}
try {
$response = [];
$processed = 0;
$where = $this->postParam("where");
$ip = $this->postParam("ip");
$useragent = $this->postParam("useragent");
@ -190,135 +204,152 @@ final class NoSpamPresenter extends OpenVKPresenter
if (!$ip && !$useragent && !$searchTerm && !$ts && !$te && !$where && !$searchTerm && !$user)
$this->returnJson(["success" => false, "error" => "Нет запроса. Заполните поле \"подстрока\" или введите запрос \"WHERE\" в поле под ним."]);
$model_name = NoSpamPresenter::ENTITIES_NAMESPACE . "\\" . $this->postParam("model");
if (!class_exists($model_name))
$this->returnJson(["success" => false, "error" => "Модель не найдена"]);
$models = explode(",", $this->postParam("models"));
$model = new $model_name;
$c = new \ReflectionClass($model_name);
if ($c->isAbstract() || $c->getName() == NoSpamPresenter::ENTITIES_NAMESPACE . "\\Correspondence")
$this->returnJson(["success" => false, "error" => "No."]);
$db = DatabaseConnection::i()->getContext();
$table = $model->getTableName();
$columns = $db->getStructure()->getColumns($table);
if ($searchTerm) {
$conditions = [];
$need_deleted = false;
foreach ($columns as $column) {
if ($column["name"] == "deleted") {
$need_deleted = true;
} else {
$conditions[] = "`$column[name]` REGEXP '$searchTerm'";
}
}
$conditions = implode(" OR ", $conditions);
$where = ($where ? " AND ($conditions)" : $conditions);
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");
if (count($rows) === 0)
$rows = $result->fetchAll();
if (!in_array((int)$this->postParam("ban"), [1, 2, 3])) {
$response = [];
foreach ($rows as $key => $object) {
$object = (array)$object;
$_obj = [];
foreach ($object as $key => $value) {
foreach ($columns as $column) {
if ($column["name"] === $key && in_array(strtoupper($column["nativetype"]), ["BLOB", "BINARY", "VARBINARY", "TINYBLOB", "MEDIUMBLOB", "LONGBLOB"])) {
$value = "[BINARY]";
break;
}
}
$_obj[$key] = $value;
}
$response[] = $_obj;
foreach ($models as $_model) {
$model_name = NoSpamPresenter::ENTITIES_NAMESPACE . "\\" . $_model;
if (!class_exists($model_name)) {
continue;
}
$this->returnJson(["success" => true, "count" => count($response), "list" => $response]);
} else {
$ids = [];
$model = new $model_name;
foreach ($rows as $object) {
$object = new $model_name($db->table($table)->get($object->id));
if (!$object) continue;
$ids[] = $object->getId();
$c = new \ReflectionClass($model_name);
if ($c->isAbstract() || $c->getName() == NoSpamPresenter::ENTITIES_NAMESPACE . "\\Correspondence") {
continue;
}
$log = new NoSpamLog;
$log->setUser($this->user->id);
$log->setModel($this->postParam("model"));
$db = DatabaseConnection::i()->getContext();
$table = $model->getTableName();
$columns = $db->getStructure()->getColumns($table);
if ($searchTerm) {
$log->setRegex($searchTerm);
} else {
$log->setRequest($where);
}
$log->setBan_Type((int)$this->postParam("ban"));
$log->setCount(count($rows));
$log->setTime(time());
$log->setItems(implode(",", $ids));
$log->save();
$banned_ids = [];
foreach ($rows as $object) {
$object = new $model_name($db->table($table)->get($object->id));
if (!$object) continue;
$owner = NULL;
$methods = ["getOwner", "getUser", "getRecipient", "getInitiator"];
if (method_exists($object, "ban")) {
$owner = $object;
} else {
foreach ($methods as $method) {
if (method_exists($object, $method)) {
$owner = $object->$method();
break;
}
}
}
if ($owner instanceof User && $owner->getId() === $this->user->id) {
if (count($rows) === 1) {
$this->returnJson(["success" => false, "error" => "\"Производственная травма\" — Вы не можете блокировать или удалять свой же контент"]);
$conditions = [];
$need_deleted = false;
foreach ($columns as $column) {
if ($column["name"] == "deleted") {
$need_deleted = true;
} else {
continue;
$conditions[] = "`$column[name]` REGEXP '$searchTerm'";
}
}
$conditions = implode(" OR ", $conditions);
if (in_array((int)$this->postParam("ban"), [2, 3])) {
if ($owner) {
$_id = ($owner instanceof Club ? $owner->getId() * -1 : $owner->getId());
if (!in_array($_id, $banned_ids)) {
if ($owner instanceof User) {
$owner->ban("**content-noSpamTemplate-" . $log->getId() . "**", false, time() + $owner->getNewBanTime(), $this->user->id);
} else {
$owner->ban("Подозрительная активность");
}
$banned_ids[] = $_id;
}
}
}
if (in_array((int)$this->postParam("ban"), [1, 3]))
$object->delete();
$where = ($this->postParam("where") ? " AND ($conditions)" : "($conditions)");
if ($need_deleted) $where .= " AND (`deleted` = 0)";
}
$this->returnJson(["success" => true]);
$rows = [];
if ($ip || $useragent || $ts || $te || $user) {
$rows = searchByAdditionalParams($table, $where, $ip, $useragent, $ts, $te, $user);
}
if (count($rows) === 0) {
if (!$searchTerm) {
if (str_starts_with($where, " AND")) {
if ($searchTerm && !$this->postParam("where")) {
$where = substr_replace($where, "", 0, strlen(" AND"));
} else {
$where = "(" . $this->postParam("where") . ")" . $where;
}
}
$result = $db->query("SELECT * FROM `$table` WHERE $where");
$rows = $result->fetchAll();
}
}
if (!in_array((int)$this->postParam("ban"), [1, 2, 3])) {
foreach ($rows as $key => $object) {
$object = (array)$object;
$_obj = [];
foreach ($object as $key => $value) {
foreach ($columns as $column) {
if ($column["name"] === $key && in_array(strtoupper($column["nativetype"]), ["BLOB", "BINARY", "VARBINARY", "TINYBLOB", "MEDIUMBLOB", "LONGBLOB"])) {
$value = "[BINARY]";
break;
}
}
$_obj[$key] = $value;
$_obj["__model_name"] = $_model;
}
$response[] = $_obj;
}
} else {
$ids = [];
foreach ($rows as $object) {
$object = new $model_name($db->table($table)->get($object->id));
if (!$object) continue;
$ids[] = $object->getId();
}
$log = new NoSpamLog;
$log->setUser($this->user->id);
$log->setModel($_model);
if ($searchTerm) {
$log->setRegex($searchTerm);
} else {
$log->setRequest($where);
}
$log->setBan_Type((int)$this->postParam("ban"));
$log->setCount(count($rows));
$log->setTime(time());
$log->setItems(implode(",", $ids));
$log->save();
$banned_ids = [];
foreach ($rows as $object) {
$object = new $model_name($db->table($table)->get($object->id));
if (!$object) continue;
$owner = NULL;
$methods = ["getOwner", "getUser", "getRecipient", "getInitiator"];
if (method_exists($object, "ban")) {
$owner = $object;
} else {
foreach ($methods as $method) {
if (method_exists($object, $method)) {
$owner = $object->$method();
break;
}
}
}
if ($owner instanceof User && $owner->getId() === $this->user->id) {
if (count($rows) === 1) {
$this->returnJson(["success" => false, "error" => "\"Производственная травма\" — Вы не можете блокировать или удалять свой же контент"]);
} else {
continue;
}
}
if (in_array((int)$this->postParam("ban"), [2, 3])) {
if ($owner) {
$_id = ($owner instanceof Club ? $owner->getId() * -1 : $owner->getId());
if (!in_array($_id, $banned_ids)) {
if ($owner instanceof User) {
$owner->ban("**content-noSpamTemplate-" . $log->getId() . "**", false, time() + $owner->getNewBanTime(), $this->user->id);
} else {
$owner->ban("Подозрительная активность");
}
$banned_ids[] = $_id;
}
}
}
if (in_array((int)$this->postParam("ban"), [1, 3]))
$object->delete();
}
$processed++;
}
}
$this->returnJson(["success" => true, "processed" => $processed, "count" => count($response), "list" => $response]);
} catch (\Throwable $e) {
$this->returnJson(["success" => false, "error" => $e->getMessage()]);
}

View file

@ -4,21 +4,39 @@
{block header}{include title}{/block}
{block content}
<style>
.noSpamIcon {
width: 20px;
height: 20px;
background: url("/assets/packages/static/openvk/img/supp_icons.png");
}
.noSpamIcon-Add {
background-position: 0 0;
}
.noSpamIcon-Delete {
background-position: 0 -21px;
}
</style>
<div class="tabs">{include "Tabs.xml", mode => "form"}</div>
<br/>
<div style="display: flex; border: 1px solid #ECECEC; padding: 8px;">
<div id="noSpam-form" style="width: 50%; border-right: 1px solid #ECECEC;">
<table cellspacing="7" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<tbody id="models-list">
<tr id="0-model">
<td width="83px">
<span class="nobold">Раздел:</span>
</td>
<td>
<select name="model" id="model" style="margin-left: -2px;">
<option selected value="none">Не выбрано</option>
<option n:foreach="$models as $model" value="{$model}">{$model}</option>
</select>
<div style="display: flex; gap: 8px; justify-content: space-between;">
<div id="add-model" class="noSpamIcon noSpamIcon-Add" style="display: none;" />
<select name="model" id="model" class="model initialModel" style="margin-left: -2px;">
<option selected value="none">Не выбрано</option>
<option n:foreach="$models as $model" value="{$model}">{$model}</option>
</select>
</div>
</td>
</tr>
</tbody>
@ -140,6 +158,18 @@
$("#noSpam-results-loader").show();
$("#noSpam-loader").show();
let models = [];
$(".model").each(function (i) {
let name = $(this).val();
if (!models.includes(name)) {
if (name.length > 0 && name !== "none") {
models.push(name);
}
}
});
models = models.join(",");
let model = $("#model").val();
let regex = $("#regex").val();
let where = $("#where").val();
@ -153,6 +183,7 @@
type: "POST",
url: "/al_abuse/search",
data: {
models: models,
model: model,
q: regex,
where: where,
@ -178,10 +209,10 @@
});
$("#noSpam-results-list").append(`<li>
<a style="display: block;" onClick="$('#noSpam-result-fields-${ model}-${ item.id}').toggle()">
<h4 style="display: inherit; padding: 8px;">${ model} #${ item.id}</h4>
<a style="display: block;" onClick="$('#noSpam-result-fields-${ item.__model_name}-${ item.id}').toggle()">
<h4 style="display: inherit; padding: 8px;">${ item.__model_name} #${ item.id}</h4>
</a>
<div style="display: none;" id="noSpam-result-fields-${ model}-${ item.id}">${ fields}</div>
<div style="display: none;" id="noSpam-result-fields-${ item.__model_name}-${ item.id}">${ fields}</div>
</li>`);
});
$("#noSpam-results-block").show();
@ -215,8 +246,10 @@
}
});
$("#apply").on("click", () => { search(Number($("#noSpam-ban-type").val())); })
$("#model").on("change", async (e) => {
if (e.target.value !== "none") {
async function selectChange(value) {
console.log(value);
if (value !== "none") {
$("#noSpam-fields").hide();
$("#noSpam-model-not-selected").show();
$("#noSpam-model-not-selected-text").hide();
@ -224,17 +257,59 @@
setTimeout(() => {
$("#noSpam-model-not-selected").hide();
$("#noSpam-fields").show();
$("#add-model").show();
$("#noSpam-model-not-selected-loader").hide();
}, 100)
} else {
if ($(".model").not(".initialModel").length === 0) {
$("#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)
}
}
}
$(".model").change(async (e) => {
selectChange(e.target.value);
})
$("#add-model").on("click", () => {
console.log($(".model").length);
$("#models-list").append(`
<tr id="${ $('.model').length}-model">
<td width="83px">
</td>
<td>
<div style="display: flex; gap: 8px; justify-content: space-between;">
<div class="noSpamIcon noSpamIcon-Delete" onClick="deleteModelSelect(${ $('.model').length});"></div>
<select name="model" class="model" style="margin-left: -2px;" onChange="selectChange($(this).val())">
<option selected value="none">Не выбрано</option>
{foreach $models as $model}
<option value={$model}>{$model|noescape}</option>
{/foreach}
</select>
</div>
</td>
</tr>`);
});
function deleteModelSelect(id) {
$(`#${ id}-model`).remove();
if ($(".model").length === 0) {
console.log("BLYAT", $(".model"));
$("#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();
$("#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>
{/block}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB