diff --git a/Web/Models/Entities/Name.php b/Web/Models/Entities/Name.php
new file mode 100644
index 000000000..d30c20f64
--- /dev/null
+++ b/Web/Models/Entities/Name.php
@@ -0,0 +1,43 @@
+getRecord()->id;
+ }
+
+ function getCreationDate(): DateTime
+ {
+ return new DateTime($this->getRecord()->created);
+ }
+
+ function getFirstName(): ?string
+ {
+ return $this->getRecord()->new_fn;
+ }
+
+ function getLastName(): ?string
+ {
+ return $this->getRecord()->new_ln;
+ }
+
+ function getUser(): ?User
+ {
+ return (new Users)->get($this->getRecord()->author);
+ }
+
+ function getStatus(): int
+ {
+ return $this->getRecord()->state;
+ }
+}
diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php
index f1045f624..91639518f 100644
--- a/Web/Models/Entities/User.php
+++ b/Web/Models/Entities/User.php
@@ -5,7 +5,7 @@
use openvk\Web\Util\DateTime;
use openvk\Web\Models\RowModel;
use openvk\Web\Models\Entities\{Photo, Message, Correspondence, Gift};
-use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Gifts, Notifications};
+use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Gifts, Notifications, Names};
use openvk\Web\Models\Exceptions\InvalidUserNameException;
use Nette\Database\Table\ActiveRow;
use Chandler\Database\DatabaseConnection;
@@ -1038,6 +1038,16 @@ function canUnbanThemself(): bool
return true;
}
+
+ function getNamesRequests(int $status = 0, ?bool $actual = false): \Traversable
+ {
+ return (new Names)->getByUser($this->getId(), $status, $actual);
+ }
+
+ function hasNamesRequests(int $status = 0, ?bool $actual = false): bool
+ {
+ return sizeof(iterator_to_array($this->getNamesRequests($status, $actual))) > 0;
+ }
use Traits\TSubscribable;
}
diff --git a/Web/Models/Repositories/Names.php b/Web/Models/Repositories/Names.php
new file mode 100644
index 000000000..570f5d720
--- /dev/null
+++ b/Web/Models/Repositories/Names.php
@@ -0,0 +1,50 @@
+context = DB::i()->getContext();
+ $this->names = $this->context->table("names");
+ $this->users = $this->context->table("profiles");
+ }
+
+ private function toName(?ActiveRow $ar): ?Name
+ {
+ return is_null($ar) ? NULL : new Name($ar);
+ }
+
+ function get(int $id): ?Name
+ {
+ return $this->toName($this->names->get($id));
+ }
+
+ function getCount(int $status = 0): int
+ {
+ return sizeof(DB::i()->getContext()->table("names")->where("state", $status));
+ }
+
+ function getList(int $page = 1, int $status = 0): \Traversable
+ {
+ foreach($this->names->where("state", $status)->order("created ASC")->page($page, 5) as $name)
+ yield $this->toName($name);
+ }
+
+ function getByUser(int $uid, int $status = 0, ?bool $actual = true): \Traversable
+ {
+ $filter = ["author" => $uid, "state" => $status];
+ $actual && $filter[] = "created >= " . (time() - 259200);
+
+ foreach($this->names->where($filter) as $name)
+ yield $this->toName($name);
+ }
+}
diff --git a/Web/Presenters/NamesPresenter.php b/Web/Presenters/NamesPresenter.php
new file mode 100644
index 000000000..f5c39fddf
--- /dev/null
+++ b/Web/Presenters/NamesPresenter.php
@@ -0,0 +1,73 @@
+names = $names;
+ }
+
+ function renderList(): void
+ {
+ $this->assertUserLoggedIn();
+ $this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0);
+
+ $this->template->mode = $this->queryParam("act") ?? "new";
+ $this->template->mode_status = 0;
+
+ if ($this->template->mode == "accepted")
+ $this->template->mode_status = 1;
+ else if ($this->template->mode == "rejected")
+ $this->template->mode_status = 2;
+
+ $this->template->page = (int) $this->queryParam("p") ?: 1;
+
+ $this->template->iterator = $this->names->getList($this->template->page, $this->template->mode_status);
+ $this->template->names = iterator_to_array($this->template->iterator);
+
+ $this->template->count = (clone $this->names)->getCount($this->template->mode_status);
+ }
+
+ function renderAction(int $id): void
+ {
+ $this->assertUserLoggedIn();
+ $this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0);
+
+ $act = $this->queryParam("act");
+
+ if(!$act)
+ $this->flashFail("err", tr("error"), tr("forbidden"));
+
+ $name = $this->names->get($id);
+
+ if(!$name)
+ $this->flashFail("err", tr("error"), "Заявка #$id не найдена.");
+
+ $user = $name->getUser();
+
+ if($act == "accept") {
+ $user->setFirst_name($name->getFirstName());
+ $user->setLast_name($name->getLastName());
+ $user->save();
+
+ $name->setState(1);
+ $name->save();
+
+ $this->flashFail("success", "Успех", "Заявка #$id была принята.");
+ } elseif($act == "reject") {
+ $name->setState(2);
+ $name->save();
+
+ $this->flashFail("success", "Успех", "Заявка #$id была отклонена.");
+ }
+
+ $this->flashFail("err", tr("error"), tr("forbidden"));
+ }
+}
diff --git a/Web/Presenters/OpenVKPresenter.php b/Web/Presenters/OpenVKPresenter.php
index 5b7908a8a..6567ad797 100755
--- a/Web/Presenters/OpenVKPresenter.php
+++ b/Web/Presenters/OpenVKPresenter.php
@@ -7,7 +7,7 @@
use Latte\Engine as TemplatingEngine;
use openvk\Web\Models\Entities\IP;
use openvk\Web\Themes\Themepacks;
-use openvk\Web\Models\Repositories\{IPs, Users, APITokens, Tickets};
+use openvk\Web\Models\Repositories\{IPs, Users, APITokens, Tickets, Names};
use WhichBrowser;
abstract class OpenVKPresenter extends SimplePresenter
@@ -258,8 +258,10 @@ function onStartup(): void
}
$this->template->ticketAnsweredCount = (new Tickets)->getTicketsCountByUserId($this->user->id, 1);
- if($user->can("write")->model("openvk\Web\Models\Entities\TicketReply")->whichBelongsTo(0))
+ if($user->can("write")->model("openvk\Web\Models\Entities\TicketReply")->whichBelongsTo(0)) {
$this->template->helpdeskTicketNotAnsweredCount = (new Tickets)->getTicketCount(0);
+ $this->template->namesNotModeratedCount = (new Names)->getCount(0);
+ }
}
header("X-OpenVK-User-Validated: $userValidated");
diff --git a/Web/Presenters/UserPresenter.php b/Web/Presenters/UserPresenter.php
index 48ebb660f..2f6cb09cd 100644
--- a/Web/Presenters/UserPresenter.php
+++ b/Web/Presenters/UserPresenter.php
@@ -2,7 +2,7 @@
namespace openvk\Web\Presenters;
use openvk\Web\Util\Sms;
use openvk\Web\Themes\Themepacks;
-use openvk\Web\Models\Entities\{Photo, Post, EmailChangeVerification};
+use openvk\Web\Models\Entities\{Photo, Post, EmailChangeVerification, Name};
use openvk\Web\Models\Entities\Notifications\{CoinsTransferNotification, RatingUpNotification};
use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Videos, Notes, Vouchers, EmailChangeVerifications};
use openvk\Web\Models\Exceptions\InvalidUserNameException;
@@ -142,8 +142,19 @@ function renderEdit(): void
if($_GET['act'] === "main" || $_GET['act'] == NULL) {
try {
- $user->setFirst_Name(empty($this->postParam("first_name")) ? $user->getFirstName() : $this->postParam("first_name"));
- $user->setLast_Name(empty($this->postParam("last_name")) ? "" : $this->postParam("last_name"));
+ if(!OPENVK_ROOT_CONF["openvk"]["preferences"]["namesModeration"]) {
+ $user->setFirst_Name(empty($this->postParam("first_name")) ? $user->getFirstName() : $this->postParam("first_name"));
+ $user->setLast_Name(empty($this->postParam("last_name")) ? "" : $this->postParam("last_name"));
+ } else {
+ if(!$user->hasNamesRequests(0, true) AND !$user->hasNamesRequests(2, true)) {
+ $name = new Name;
+ $name->setNew_fn(empty($this->postParam("first_name")) ? $user->getFirstName() : $this->postParam("first_name"));
+ $name->setNew_ln(empty($this->postParam("last_name")) ? $user->getFirstName() : $this->postParam("last_name"));
+ $name->setAuthor($user->getId());
+ $name->setCreated(time());
+ $name->save();
+ }
+ }
} catch(InvalidUserNameException $ex) {
$this->flashFail("err", tr("error"), tr("invalid_real_name"));
}
diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml
index e717acfea..b4ecc1ca1 100644
--- a/Web/Presenters/templates/@layout.xml
+++ b/Web/Presenters/templates/@layout.xml
@@ -186,6 +186,11 @@
({$helpdeskTicketNotAnsweredCount})
{/if}
+ Имена
+ {if $namesNotModeratedCount > 0}
+ ({$namesNotModeratedCount})
+ {/if}
+
{strpos($menuItem["name"], "@") === 0 ? tr(substr($menuItem["name"], 1)) : $menuItem["name"]}
diff --git a/Web/Presenters/templates/Names/List.xml b/Web/Presenters/templates/Names/List.xml
new file mode 100644
index 000000000..2551b03a1
--- /dev/null
+++ b/Web/Presenters/templates/Names/List.xml
@@ -0,0 +1,121 @@
+{extends "../@layout.xml"}
+
+{block header}
+ Администрирование
+{/block}
+
+{block content}
+ {var $isNew = $mode === 'new'}
+ {var $isAccepted = $mode === 'accepted'}
+ {var $isRejected = $mode === 'rejected'}
+
+ {var $amount = sizeof($names)}
+
+
+
+
+ {presenter "openvk!Support->knowledgeBaseArticle", "names"}
+
+
+ {if $count < 1}
+ {include "../components/nothing.xml"}
+ {else}
+ {tr("names_showed", $amount, $count)}
+
+
+
+
+
+
+
+
+
+ {$name->getCreationDate()}
+ |
+
+
+
+ {_city}: {$name->getUser()->getCity() ?? "Не указан"}
+
+
+
+
+ {_approved}
+
+
+ {_rejected}
+
+
+ |
+
+
+
+
+
+
+ {include "../components/paginator.xml", conf => (object) [
+ "page" => $page,
+ "count" => $count,
+ "amount" => $amount,
+ "perPage" => 5,
+ "atBottom" => true,
+ ]}
+
+ {/if}
+{/block}
diff --git a/Web/Presenters/templates/User/Edit.xml b/Web/Presenters/templates/User/Edit.xml
index 96152132e..d711bbe5f 100644
--- a/Web/Presenters/templates/User/Edit.xml
+++ b/Web/Presenters/templates/User/Edit.xml
@@ -33,8 +33,17 @@
{if $isMain}
-
+
{_main_information}
+
+ {_name_change_request}
+ {_name_change_request_pending}
+
+
+ {_name_change_request}
+ {_name_change_request_rejected}
+
+