Merge branch 'master' into website-contact

This commit is contained in:
Maxim Leshchenko 2021-11-12 18:00:02 +02:00
commit 3a7ab3de11
14 changed files with 214 additions and 30 deletions

View file

@ -94,7 +94,17 @@ class Club extends RowModel
{ {
return is_null($this->getRecord()->owner_comment) ? "" : $this->getRecord()->owner_comment; return is_null($this->getRecord()->owner_comment) ? "" : $this->getRecord()->owner_comment;
} }
function isOwnerHidden(): bool
{
return (bool) $this->getRecord()->owner_hidden;
}
function isOwnerClubPinned(): bool
{
return (bool) $this->getRecord()->owner_club_pinned;
}
function getDescription(): ?string function getDescription(): ?string
{ {
return $this->getRecord()->about; return $this->getRecord()->about;
@ -269,9 +279,11 @@ class Club extends RowModel
} }
} }
function getManagers(int $page = 1): \Traversable function getManagers(int $page = 1, bool $ignoreHidden = false): \Traversable
{ {
$rels = $this->getRecord()->related("group_coadmins.club")->page($page, 6); $rels = $this->getRecord()->related("group_coadmins.club")->page($page, 6);
if($ignoreHidden)
$rels = $rels->where("hidden", false);
foreach($rels as $rel) { foreach($rels as $rel) {
$rel = (new Managers)->get($rel->id); $rel = (new Managers)->get($rel->id);
@ -281,13 +293,21 @@ class Club extends RowModel
} }
} }
function getManager(User $user): ?Manager function getManager(User $user, bool $ignoreHidden = false): ?Manager
{ {
return (new Managers)->getByUserAndClub($user->getId(), $this->getId()); $manager = (new Managers)->getByUserAndClub($user->getId(), $this->getId());
if ($ignoreHidden && $manager !== null && $manager->isHidden())
return null;
return $manager;
} }
function getManagersCount(): int function getManagersCount(bool $ignoreHidden = false): int
{ {
if($ignoreHidden)
return sizeof($this->getRecord()->related("group_coadmins.club")->where("hidden", false)) + (int) !$this->isOwnerHidden();
return sizeof($this->getRecord()->related("group_coadmins.club")) + 1; return sizeof($this->getRecord()->related("group_coadmins.club")) + 1;
} }

View file

@ -41,6 +41,16 @@ class Manager extends RowModel
{ {
return is_null($this->getRecord()->comment) ? "" : $this->getRecord()->comment; return is_null($this->getRecord()->comment) ? "" : $this->getRecord()->comment;
} }
function isHidden(): bool
{
return (bool) $this->getRecord()->hidden;
}
function isClubPinned(): bool
{
return (bool) $this->getRecord()->club_pinned;
}
use Traits\TSubscribable; use Traits\TSubscribable;
} }

View file

@ -473,6 +473,38 @@ class User extends RowModel
return sizeof($sel); return sizeof($sel);
} }
function getPinnedClubs(): \Traversable
{
foreach($this->getRecord()->related("groups.owner")->where("owner_club_pinned", true) as $target) {
$target = (new Clubs)->get($target->id);
if(!$target) continue;
yield $target;
}
foreach($this->getRecord()->related("group_coadmins.user")->where("club_pinned", true) as $target) {
$target = (new Clubs)->get($target->club);
if(!$target) continue;
yield $target;
}
}
function getPinnedClubCount(): int
{
return sizeof($this->getRecord()->related("groups.owner")->where("owner_club_pinned", true)) + sizeof($this->getRecord()->related("group_coadmins.user")->where("club_pinned", true));
}
function isClubPinned(Club $club): bool
{
if($club->getOwner()->getId() === $this->getId())
return $club->isOwnerClubPinned();
$manager = $club->getManager($this);
if(!is_null($manager))
return $manager->isClubPinned();
}
function getMeetings(int $page = 1): \Traversable function getMeetings(int $page = 1): \Traversable
{ {
$sel = $this->getRecord()->related("event_turnouts.user")->page($page, OPENVK_DEFAULT_PER_PAGE); $sel = $this->getRecord()->related("event_turnouts.user")->page($page, OPENVK_DEFAULT_PER_PAGE);

View file

@ -83,15 +83,30 @@ final class GroupPresenter extends OpenVKPresenter
{ {
$this->assertUserLoggedIn(); $this->assertUserLoggedIn();
$this->template->club = $this->clubs->get($id);
$this->template->followers = $this->template->club->getFollowers((int) ($this->queryParam("p") ?? 1));
$this->template->count = $this->template->club->getFollowersCount();
$this->template->paginatorConf = (object) [ $this->template->paginatorConf = (object) [
"count" => $this->template->count, "count" => $this->template->count,
"page" => $this->queryParam("p") ?? 1, "page" => $this->queryParam("p") ?? 1,
"amount" => NULL, "amount" => NULL,
"perPage" => OPENVK_DEFAULT_PER_PAGE, "perPage" => OPENVK_DEFAULT_PER_PAGE,
]; ];
$this->template->club = $this->clubs->get($id);
$this->template->onlyShowManagers = $this->queryParam("onlyAdmins") == "1";
if($this->template->onlyShowManagers) {
$this->template->followers = null;
$this->template->managers = $this->template->club->getManagers((int) ($this->queryParam("p") ?? 1), !$this->template->club->canBeModifiedBy($this->user->identity));
if($this->template->club->canBeModifiedBy($this->user->identity) || !$this->template->club->isOwnerHidden()) {
$this->template->managers = array_merge([$this->template->club->getOwner()], iterator_to_array($this->template->managers));
}
$this->template->count = $this->template->club->getManagersCount();
return;
}
$this->template->followers = $this->template->club->getFollowers((int) ($this->queryParam("p") ?? 1));
$this->template->managers = null;
$this->template->count = $this->template->club->getFollowersCount();
} }
function renderModifyAdmin(int $id): void function renderModifyAdmin(int $id): void
@ -99,6 +114,7 @@ final class GroupPresenter extends OpenVKPresenter
$user = is_null($this->queryParam("user")) ? $this->postParam("user") : $this->queryParam("user"); $user = is_null($this->queryParam("user")) ? $this->postParam("user") : $this->queryParam("user");
$comment = $this->postParam("comment"); $comment = $this->postParam("comment");
$removeComment = $this->postParam("removeComment") === "1"; $removeComment = $this->postParam("removeComment") === "1";
$hidden = ["0" => false, "1" => true][$this->queryParam("hidden")] ?? null;
//$index = $this->queryParam("index"); //$index = $this->queryParam("index");
if(!$user) if(!$user)
$this->badRequest(); $this->badRequest();
@ -108,10 +124,30 @@ final class GroupPresenter extends OpenVKPresenter
if(!$user || !$club) if(!$user || !$club)
$this->notFound(); $this->notFound();
if(!$club->canBeModifiedBy($this->user->identity ?? NULL) && $club->getOwner()->getId() !== $user->getId()) if(!$club->canBeModifiedBy($this->user->identity ?? NULL))
$this->flashFail("err", "Ошибка доступа", "У вас недостаточно прав, чтобы изменять этот ресурс."); $this->flashFail("err", "Ошибка доступа", "У вас недостаточно прав, чтобы изменять этот ресурс.");
if($removeComment) { if(!is_null($hidden)) {
if($club->getOwner()->getId() == $user->getId()) {
$club->setOwner_Hidden($hidden);
$club->save();
} else {
$manager = (new Managers)->getByUserAndClub($user->getId(), $club->getId());
$manager->setHidden($hidden);
$manager->save();
}
if($club->getManagersCount(true) == 0) {
$club->setAdministrators_List_Display(2);
$club->save();
}
if($hidden) {
$this->flashFail("succ", "Операция успешна", "Теперь " . $user->getCanonicalName() . " будет показываться как обычный подписчик всем кроме других администраторов");
} else {
$this->flashFail("succ", "Операция успешна", "Теперь все будут знать про то что " . $user->getCanonicalName() . " - администратор");
}
} elseif($removeComment) {
if($club->getOwner()->getId() == $user->getId()) { if($club->getOwner()->getId() == $user->getId()) {
$club->setOwner_Comment(null); $club->setOwner_Comment(null);
$club->save(); $club->save();

View file

@ -4,6 +4,7 @@ use openvk\Web\Util\Sms;
use openvk\Web\Themes\Themepacks; use openvk\Web\Themes\Themepacks;
use openvk\Web\Models\Entities\Photo; use openvk\Web\Models\Entities\Photo;
use openvk\Web\Models\Repositories\Users; use openvk\Web\Models\Repositories\Users;
use openvk\Web\Models\Repositories\Clubs;
use openvk\Web\Models\Repositories\Albums; use openvk\Web\Models\Repositories\Albums;
use openvk\Web\Models\Repositories\Videos; use openvk\Web\Models\Repositories\Videos;
use openvk\Web\Models\Repositories\Notes; use openvk\Web\Models\Repositories\Notes;
@ -80,6 +81,38 @@ final class UserPresenter extends OpenVKPresenter
$this->template->page = $this->queryParam("p") ?? 1; $this->template->page = $this->queryParam("p") ?? 1;
} }
} }
function renderPinClub(): void
{
$this->assertUserLoggedIn();
$club = (new Clubs)->get((int) $this->queryParam("club"));
if(!$club)
$this->notFound();
if(!$club->canBeModifiedBy($this->user->identity ?? NULL))
$this->flashFail("err", "Ошибка доступа", "У вас недостаточно прав, чтобы изменять этот ресурс.");
$isClubPinned = $this->user->identity->isClubPinned($club);
if(!$isClubPinned && $this->user->identity->getPinnedClubCount() > 10)
$this->flashFail("err", "Ошибка", "Находится в левом меню могут максимум 10 групп");
if($club->getOwner()->getId() === $this->user->identity->getId()) {
$club->setOwner_Club_Pinned(!$isClubPinned);
$club->save();
} else {
$manager = $club->getManager($this->user->identity);
if(!is_null($manager)) {
$manager->setClub_Pinned(!$isClubPinned);
$manager->save();
}
}
if($isClubPinned)
$this->flashFail("succ", "Операция успешна", "Группа " . $club->getName() . " была успешно удалена из левого меню");
else
$this->flashFail("succ", "Операция успешна", "Группа " . $club->getName() . " была успешно добавлена в левое меню");
}
function renderEdit(): void function renderEdit(): void
{ {

View file

@ -169,6 +169,12 @@
href="{$menuItem['url']}" href="{$menuItem['url']}"
target="_blank" target="_blank"
class="link">{$menuItem["name"]}</a> class="link">{$menuItem["name"]}</a>
<div n:if="$thisUser->getPinnedClubCount() > 0" style="height: 1px;background: #CCC;margin: 4px 0 2px;"></div>
<a
n:foreach="$thisUser->getPinnedClubs() as $club"
href="{$club->getURL()}"
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
class="link">{$club->getName()}</a>
<a <a
n:if="OPENVK_ROOT_CONF['openvk']['preferences']['adPoster']['enable']" n:if="OPENVK_ROOT_CONF['openvk']['preferences']['adPoster']['enable']"

View file

@ -82,9 +82,10 @@
<span class="nobold">{_group_administrators_list}: </span> <span class="nobold">{_group_administrators_list}: </span>
</td> </td>
<td> <td>
<input type="radio" name="administrators_list_display" value="0" {if $club->getAdministratorsListDisplay() == 0}checked{/if}/> {_group_display_only_creator}<br> {var areAllAdminsHidden = $club->getManagersCount(true) == 0}
<input type="radio" name="administrators_list_display" value="1" {if $club->getAdministratorsListDisplay() == 1}checked{/if}/> {_group_display_all_administrators}<br> <input type="radio" name="administrators_list_display" value="0" n:attr="checked => $club->getAdministratorsListDisplay() == 0, disabled => $areAllAdminsHidden" /> {_group_display_only_creator}<br>
<input type="radio" name="administrators_list_display" value="2" {if $club->getAdministratorsListDisplay() == 2}checked{/if}/> {_group_dont_display_administrators_list}<br> <input type="radio" name="administrators_list_display" value="1" n:attr="checked => $club->getAdministratorsListDisplay() == 1, disabled => $areAllAdminsHidden" /> {_group_display_all_administrators}<br>
<input type="radio" name="administrators_list_display" value="2" n:attr="checked => $club->getAdministratorsListDisplay() == 2, disabled => $areAllAdminsHidden" /> {_group_dont_display_administrators_list}<br>
</td> </td>
</tr> </tr>

View file

@ -1,5 +1,6 @@
{extends "../@listView.xml"} {extends "../@listView.xml"}
{var iterator = $followers} {var $Manager = openvk\Web\Models\Entities\Manager::class}
{var iterator = $onlyShowManagers ? $managers : $followers}
{var count = $paginatorConf->count} {var count = $paginatorConf->count}
{var page = $paginatorConf->page} {var page = $paginatorConf->page}
{var perPage = 6} {var perPage = 6}
@ -9,6 +10,8 @@
{block header} {block header}
<a href="{$club->getURL()}">{$club->getCanonicalName()}</a> <a href="{$club->getURL()}">{$club->getCanonicalName()}</a>
» {_followers} » {_followers}
<a n:if="!$onlyShowManagers" href="/club{$club->getId()}/followers?onlyAdmins=1" style="float: right;">{_all_followers}</a>
<a n:if="$onlyShowManagers" href="/club{$club->getId()}/followers" style="float: right;">{_only_administrators}</a>
{/block} {/block}
{block actions} {block actions}
@ -38,49 +41,50 @@
{/block} {/block}
{block link|strip|stripHtml} {block link|strip|stripHtml}
/id{$x->getId()} /id{$x instanceof $Manager ? $x->getUserId() : $x->getId()}
{/block} {/block}
{block preview} {block preview}
<img src="{$x->getAvatarURL()}" alt="{$x->getCanonicalName()}" width=75 /> <img src="{$x instanceof $Manager ? $x->getUser()->getAvatarURL() : $x->getAvatarURL()}" alt="{$x instanceof $Manager ? $x->getUser()->getCanonicalName() : $x->getCanonicalName()}" width=75 />
{/block} {/block}
{block name} {block name}
{$x->getCanonicalName()} {$x instanceof $Manager ? $x->getUser()->getCanonicalName() : $x->getCanonicalName()}
{/block} {/block}
{block description} {block description}
{var user = $x instanceof $Manager ? $x->getUser() : $x}
{var manager = $x instanceof $Manager ? $x : $club->getManager($user, !$club->canBeModifiedBy($thisUser))}
<table> <table>
<tbody> <tbody>
<tr> <tr>
<td width="120" valign="top"><span class="nobold">{_"gender"}: </span></td> <td width="120" valign="top"><span class="nobold">{_"gender"}: </span></td>
<td>{$x->isFemale() ? "женский" : "мужской"}</td> <td>{$user->isFemale() ? "женский" : "мужской"}</td>
</tr> </tr>
<tr> <tr>
<td width="120" valign="top"><span class="nobold">{_"registration_date"}: </span></td> <td width="120" valign="top"><span class="nobold">{_"registration_date"}: </span></td>
<td>{$x->getRegistrationTime()}</td> <td>{$user->getRegistrationTime()}</td>
</tr> </tr>
<tr> <tr>
<td width="120" valign="top"><span class="nobold">{_role}: </span></td> <td width="120" valign="top"><span class="nobold">{_role}: </span></td>
<td> <td>
{$club->canBeModifiedBy($x) ? tr("administrator") : tr("follower")} {$club->getOwner()->getId() == $user->getId() ? !$club->isOwnerHidden() || $club->canBeModifiedBy($thisUser) : !is_null($manager) ? tr("administrator") : tr("follower")}
</td> </td>
</tr> </tr>
{var manager = $club->getManager($x)} <tr n:if="$manager && !empty($manager->getComment()) || $club->getOwner()->getId() === $user->getId() && !empty($club->getOwnerComment()) && (!$club->isOwnerHidden() || $club->canBeModifiedBy($thisUser))">
<tr n:if="$manager && !empty($manager->getComment()) || $club->getOwner()->getId() === $x->getId() && !empty($club->getOwnerComment())">
<td width="120" valign="top"><span class="nobold">{_comment}: </span></td> <td width="120" valign="top"><span class="nobold">{_comment}: </span></td>
<td> <td>
{if $club->getOwner()->getId() === $x->getId()} {if $club->getOwner()->getId() === $user->getId()}
{$club->getOwnerComment()} {$club->getOwnerComment()}
{else} {else}
{$manager->getComment()} {$manager->getComment()}
{/if} {/if}
</td> </td>
</tr> </tr>
<tr n:if="$club->canBeModifiedBy($thisUser ?? NULL) && $club->getOwner()->getId() !== $x->getId() || $club->getOwner()->getId() == $x->getId()"> <tr n:if="$club->canBeModifiedBy($thisUser ?? NULL)">
<td width="120" valign="top"><span class="nobold">{_actions}: </span></td> <td width="120" valign="top"><span class="nobold">{_actions}: </span></td>
<td> <td>
<a href="/club{$club->getId()}/setAdmin.jsp?user={$x->getId()}&hash={rawurlencode($csrfToken)}" n:if="$club->getOwner()->getId() !== $x->getId()"> <a href="/club{$club->getId()}/setAdmin.jsp?user={$user->getId()}&hash={rawurlencode($csrfToken)}" n:if="$club->getOwner()->getId() !== $user->getId()">
{if $manager} {if $manager}
{_devote} {_devote}
{else} {else}
@ -93,9 +97,21 @@
{_set_comment} {_set_comment}
</a> </a>
{/if} {/if}
<a n:if="$club->getOwner()->getId() === $x->getId()" href="javascript:setClubAdminComment('{$club->getId()}', '{$club->getOwner()->getId()}', '{rawurlencode($csrfToken)}')"> <a n:if="$club->getOwner()->getId() === $user->getId()" href="javascript:setClubAdminComment('{$club->getId()}', '{$club->getOwner()->getId()}', '{rawurlencode($csrfToken)}')">
{_set_comment} {_set_comment}
</a> </a>
{if $manager}
|
<a href="/club{$club->getId()}/setAdmin.jsp?user={$user->getId()}&hidden={(int) !$manager->isHidden()}&hash={rawurlencode($csrfToken)}">
{if $manager->isHidden()}{_hidden_yes}{else}{_hidden_no}{/if}
</a>
{/if}
{if $club->getOwner()->getId() == $user->getId()}
|
<a href="/club{$club->getId()}/setAdmin.jsp?user={$user->getId()}&hidden={(int) !$club->isOwnerHidden()}&hash={rawurlencode($csrfToken)}">
{if $club->isOwnerHidden()}{_hidden_yes}{else}{_hidden_no}{/if}
</a>
{/if}
</td> </td>
</tr> </tr>
</tbody> </tbody>

View file

@ -124,7 +124,8 @@
<img class="ava" src="{$author->getAvatarUrl()}" /> <img class="ava" src="{$author->getAvatarUrl()}" />
</a> </a>
</div> </div>
<div class="info info-without-subtitle-centered" n:if="empty($club->getOwnerComment())"> {* Это наверное костыль, ну да ладно *}
<div n:class="info, strlen($author->getCanonicalName()) < 22 ? info-centered" n:if="empty($club->getOwnerComment())">
<a href="{$author->getURL()}" class="title">{$author->getCanonicalName()}</a> <a href="{$author->getURL()}" class="title">{$author->getCanonicalName()}</a>
</div> </div>
<div class="info" n:if="!empty($club->getOwnerComment())"> <div class="info" n:if="!empty($club->getOwnerComment())">
@ -139,10 +140,13 @@
</div> </div>
<div> <div>
<div class="content_subtitle"> <div class="content_subtitle">
{tr("administrators", $club->getManagersCount() + 1)} {tr("administrators", $club->getManagersCount(true))}
<div style="float: right;">
<a href="/club{$club->getId()}/followers?onlyAdmins=1">{_"all_title"}</a>
</div>
</div> </div>
<div class="avatar-list"> <div class="avatar-list">
<div class="avatar-list-item"> <div class="avatar-list-item" n:if="!$club->isOwnerHidden()">
{var author = $club->getOwner()} {var author = $club->getOwner()}
<div class="avatar"> <div class="avatar">
<a href="{$author->getURL()}"> <a href="{$author->getURL()}">
@ -154,7 +158,7 @@
<div class="subtitle" n:if="!empty($club->getOwnerComment())">{$club->getOwnerComment()}</div> <div class="subtitle" n:if="!empty($club->getOwnerComment())">{$club->getOwnerComment()}</div>
</div> </div>
</div> </div>
<div class="avatar-list-item" n:foreach="$club->getManagers(1) as $manager"> <div class="avatar-list-item" n:foreach="$club->getManagers(1, true) as $manager">
{var user = $manager->getUser()} {var user = $manager->getUser()}
<div class="avatar"> <div class="avatar">
<a href="{$user->getURL()}"> <a href="{$user->getURL()}">

View file

@ -40,4 +40,23 @@
{block description} {block description}
{$x->getDescription()} {$x->getDescription()}
{if $x->canBeModifiedBy($thisUser ?? NULL)}
{var clubPinned = $thisUser->isClubPinned($x)}
<table n:if="$clubPinned || $thisUser->getPinnedClubCount() <= 10">
<tbody>
<tr>
<td width="120" valign="top"><span class="nobold">{_actions}: </span></td>
<td>
<a href="/groups_pin?club={$x->getId()}&hash={rawurlencode($csrfToken)}">
{if $clubPinned}
{_remove_from_left_menu}
{else}
{_add_to_left_menu}
{/if}
</a>
</td>
</tr>
</tbody>
</table>
{/if}
{/block} {/block}

View file

@ -151,6 +151,8 @@ routes:
handler: "Group->modifyAdmin" handler: "Group->modifyAdmin"
- url: "/groups{num}" - url: "/groups{num}"
handler: "User->groups" handler: "User->groups"
- url: "/groups_pin"
handler: "User->pinClub"
- url: "/groups_create" - url: "/groups_create"
handler: "Group->create" handler: "Group->create"
- url: "/audios{num}" - url: "/audios{num}"

View file

@ -1480,9 +1480,10 @@ body.scrolled .toTop:hover {
.avatar-list-item .info { .avatar-list-item .info {
float: left; float: left;
padding-left: 8px; padding-left: 8px;
width: 134px;
} }
.avatar-list-item .info-without-subtitle-centered { .avatar-list-item .info-centered {
padding-top: 8px; padding-top: 8px;
} }

View file

@ -0,0 +1,2 @@
ALTER TABLE `group_coadmins` ADD COLUMN `hidden` BOOLEAN NOT NULL DEFAULT FALSE;
ALTER TABLE `groups` ADD COLUMN `owner_hidden` BOOLEAN NOT NULL DEFAULT FALSE AFTER `owner_comment`;

View file

@ -0,0 +1,2 @@
ALTER TABLE `groups` ADD COLUMN `owner_club_pinned` BOOLEAN NOT NULL DEFAULT FALSE AFTER `owner_hidden`;
ALTER TABLE `group_coadmins` ADD COLUMN `club_pinned` BOOLEAN DEFAULT FALSE NOT NULL;