diff --git a/Web/Models/Repositories/ChandlerUsers.php b/Web/Models/Repositories/ChandlerUsers.php index a827afac..510e5860 100644 --- a/Web/Models/Repositories/ChandlerUsers.php +++ b/Web/Models/Repositories/ChandlerUsers.php @@ -28,7 +28,8 @@ class ChandlerUsers function getById(string $UUID): ?ChandlerUser { - return new ChandlerUser($this->users->where("id", $UUID)->fetch()); + $user = $this->users->where("id", $UUID)->fetch(); + return $user ? new ChandlerUser($user) : NULL; } function getList(int $page = 1): \Traversable diff --git a/Web/Models/Repositories/Users.php b/Web/Models/Repositories/Users.php index 6c165aa3..de0d341d 100644 --- a/Web/Models/Repositories/Users.php +++ b/Web/Models/Repositories/Users.php @@ -44,9 +44,9 @@ class Users return $alias->getUser(); } - function getByChandlerUser(ChandlerUser $user): ?User + function getByChandlerUser(?ChandlerUser $user): ?User { - return $this->toUser($this->users->where("user", $user->getId())->fetch()); + return $user ? $this->toUser($this->users->where("user", $user->getId())->fetch()) : NULL; } function find(string $query, array $pars = [], string $sort = "id DESC"): Util\EntityStream diff --git a/Web/Presenters/AdminPresenter.php b/Web/Presenters/AdminPresenter.php index 8d2dd477..de7e4d91 100644 --- a/Web/Presenters/AdminPresenter.php +++ b/Web/Presenters/AdminPresenter.php @@ -3,7 +3,7 @@ namespace openvk\Web\Presenters; use Chandler\Database\Log; use Chandler\Database\Logs; use openvk\Web\Models\Entities\{Voucher, Gift, GiftCategory, User, BannedLink}; -use openvk\Web\Models\Repositories\{Bans, ChandlerGroups, ChandlerUsers, Photos, Posts, Users, Clubs, Videos, Vouchers, Gifts, BannedLinks, Logs}; +use openvk\Web\Models\Repositories\{Bans, ChandlerGroups, ChandlerUsers, Photos, Posts, Users, Clubs, Videos, Vouchers, Gifts, BannedLinks}; use Chandler\Database\DatabaseConnection; final class AdminPresenter extends OpenVKPresenter diff --git a/Web/Presenters/NoSpamPresenter.php b/Web/Presenters/NoSpamPresenter.php index f2c6fad3..1560ba63 100644 --- a/Web/Presenters/NoSpamPresenter.php +++ b/Web/Presenters/NoSpamPresenter.php @@ -7,11 +7,13 @@ use Nette\Utils\Finder; use Chandler\Database\DatabaseConnection; use openvk\Web\Models\Entities\Club; use openvk\Web\Models\Entities\Comment; -use openvk\Web\Models\Entities\Log; +use Chandler\Database\Log; use openvk\Web\Models\Entities\NoSpamLog; use openvk\Web\Models\Entities\User; -use openvk\Web\Models\Repositories\Logs; +use openvk\Web\Models\Repositories\ChandlerUsers; +use Chandler\Database\Logs; use openvk\Web\Models\Repositories\NoSpamLogs; +use openvk\Web\Models\Repositories\Users; final class NoSpamPresenter extends OpenVKPresenter { @@ -141,7 +143,7 @@ final class NoSpamPresenter extends OpenVKPresenter $this->assertNoCSRF(); $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) + function searchByAdditionalParams(?string $table = NULL, ?string $where = NULL, ?string $ip = NULL, ?string $useragent = NULL, ?int $ts = NULL, ?int $te = NULL, $user = NULL) { $db = DatabaseConnection::i()->getContext(); if ($table && ($ip || $useragent || $ts || $te || $user)) { @@ -151,35 +153,49 @@ final class NoSpamPresenter extends OpenVKPresenter if ($useragent) $conditions[] = "`useragent` REGEXP '$useragent'"; if ($ts) $conditions[] = "`ts` < $ts"; if ($te) $conditions[] = "`ts` > $te"; - if ($user) $conditions[] = "`user` = $user"; + if ($user) { + $users = new Users; + + $_user = $users->getByChandlerUser((new ChandlerUsers)->getById($user)) + ?? $users->get((int)$user) + ?? $users->getByAddress($user) + ?? NULL; + + if ($_user) { + $conditions[] = "`user` = '" . $_user->getChandlerGUID() . "'"; + } + } $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`"); + $conditions = count($conditions) > 0 ? "AND (" . implode(" AND ", $conditions) . ")" : ""; $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 ($conditions) { + $logs = $db->query("SELECT * FROM `ChandlerLogs` $whereStart $conditions GROUP BY `object_id`, `object_model`"); - 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")); + 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(); - foreach ($db->query("SELECT * FROM `$table` WHERE $where")->fetchAll() as $o) { - if ($object->id === $o["id"]) { - $response[] = $object; + if (!$object) continue; + 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; + } } } } @@ -190,166 +206,170 @@ final class NoSpamPresenter extends OpenVKPresenter } try { - $response = []; - $processed = 0; + $response = []; + $processed = 0; - $where = $this->postParam("where"); - $ip = $this->postParam("ip"); - $useragent = $this->postParam("useragent"); - $searchTerm = $this->postParam("q"); - $ts = (int)$this->postParam("ts"); - $te = (int)$this->postParam("te"); - $user = (int)$this->postParam("user"); + $where = $this->postParam("where"); + $ip = $this->postParam("ip"); + $useragent = $this->postParam("useragent"); + $searchTerm = $this->postParam("q"); + $ts = (int)$this->postParam("ts"); + $te = (int)$this->postParam("te"); + $user = $this->postParam("user"); - if (!$ip && !$useragent && !$searchTerm && !$ts && !$te && !$where && !$searchTerm && !$user) - $this->returnJson(["success" => false, "error" => "Нет запроса. Заполните поле \"подстрока\" или введите запрос \"WHERE\" в поле под ним."]); + if (!$ip && !$useragent && !$searchTerm && !$ts && !$te && !$where && !$searchTerm && !$user) + $this->returnJson(["success" => false, "error" => "Нет запроса. Заполните поле \"подстрока\" или введите запрос \"WHERE\" в поле под ним."]); - $models = explode(",", $this->postParam("models")); + $models = explode(",", $this->postParam("models")); - foreach ($models as $_model) { - $model_name = NoSpamPresenter::ENTITIES_NAMESPACE . "\\" . $_model; - if (!class_exists($model_name)) { - continue; + foreach ($models as $_model) { + $model_name = NoSpamPresenter::ENTITIES_NAMESPACE . "\\" . $_model; + if (!class_exists($model_name)) { + continue; + } + + $model = new $model_name; + + $c = new \ReflectionClass($model_name); + if ($c->isAbstract() || $c->getName() == NoSpamPresenter::ENTITIES_NAMESPACE . "\\Correspondence") { + continue; + } + + $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); - $model = new $model_name; + $where = ($this->postParam("where") ? " AND ($conditions)" : "($conditions)"); + if ($need_deleted) $where .= " AND (`deleted` = 0)"; + } - $c = new \ReflectionClass($model_name); - if ($c->isAbstract() || $c->getName() == NoSpamPresenter::ENTITIES_NAMESPACE . "\\Correspondence") { - continue; - } + $rows = []; + if ($ip || $useragent || $ts || $te || $user) { + $rows = searchByAdditionalParams($table, $where, $ip, $useragent, $ts, $te, $user); + } - $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; + 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 { - $conditions[] = "`$column[name]` REGEXP '$searchTerm'"; + $where = "(" . $this->postParam("where") . ")" . $where; } } - $conditions = implode(" OR ", $conditions); - - $where = ($this->postParam("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); - } - - 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; - } - } + if (!$where) { + $rows = []; + } else { $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]); + 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()]); } diff --git a/Web/Presenters/templates/NoSpam/Index.xml b/Web/Presenters/templates/NoSpam/Index.xml index f2afe4b4..746f86d5 100644 --- a/Web/Presenters/templates/NoSpam/Index.xml +++ b/Web/Presenters/templates/NoSpam/Index.xml @@ -58,7 +58,7 @@ Пользователь: - +