mirror of
https://github.com/openvk/openvk
synced 2024-11-15 03:31:18 +03:00
Group [Very WIP]: Add early implementation of group's contacts
This commit is contained in:
parent
cb8038590c
commit
594d025ab8
12 changed files with 313 additions and 6 deletions
|
@ -3,7 +3,7 @@ namespace openvk\Web\Models\Entities;
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Entities\{User, Manager};
|
use openvk\Web\Models\Entities\{User, Manager};
|
||||||
use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Managers};
|
use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Managers, Contacts};
|
||||||
use Nette\Database\Table\{ActiveRow, GroupedSelection};
|
use Nette\Database\Table\{ActiveRow, GroupedSelection};
|
||||||
use Chandler\Database\DatabaseConnection as DB;
|
use Chandler\Database\DatabaseConnection as DB;
|
||||||
use Chandler\Security\User as ChandlerUser;
|
use Chandler\Security\User as ChandlerUser;
|
||||||
|
@ -302,6 +302,11 @@ class Club extends RowModel
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getContacts(): \Traversable
|
||||||
|
{
|
||||||
|
return (new Contacts)->getByClub($this->getId());
|
||||||
|
}
|
||||||
|
|
||||||
function removeManager(User $user): void
|
function removeManager(User $user): void
|
||||||
{
|
{
|
||||||
DB::i()->getContext()->table("group_coadmins")->where([
|
DB::i()->getContext()->table("group_coadmins")->where([
|
||||||
|
|
36
Web/Models/Entities/Contact.php
Normal file
36
Web/Models/Entities/Contact.php
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
namespace openvk\Web\Models\Entities;
|
||||||
|
use Chandler\Database\DatabaseConnection;
|
||||||
|
use openvk\Web\Models\RowModel;
|
||||||
|
use openvk\Web\Models\Repositories\Contacts;
|
||||||
|
use openvk\Web\Models\Repositories\{Users, Clubs};
|
||||||
|
|
||||||
|
class Contact extends RowModel
|
||||||
|
{
|
||||||
|
protected $tableName = "group_contacts";
|
||||||
|
|
||||||
|
function getId(): int
|
||||||
|
{
|
||||||
|
return $this->getRecord()->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUser(): ?User
|
||||||
|
{
|
||||||
|
return (new Users)->get($this->getRecord()->user);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGroup(): ?Club
|
||||||
|
{
|
||||||
|
return (new Clubs)->get($this->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDescription(): string
|
||||||
|
{
|
||||||
|
return ovk_proc_strtr($this->getRecord()->content, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEmail(): string
|
||||||
|
{
|
||||||
|
return $this->getRecord()->email;
|
||||||
|
}
|
||||||
|
}
|
35
Web/Models/Repositories/Contacts.php
Normal file
35
Web/Models/Repositories/Contacts.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
namespace openvk\Web\Models\Repositories;
|
||||||
|
use openvk\Web\Models\Entities\Contact;
|
||||||
|
use Nette\Database\Table\ActiveRow;
|
||||||
|
use Chandler\Database\DatabaseConnection;
|
||||||
|
|
||||||
|
class Contacts
|
||||||
|
{
|
||||||
|
private $context;
|
||||||
|
private $contacts;
|
||||||
|
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
$this->context = DatabaseConnection::i()->getContext();
|
||||||
|
$this->contacts = $this->context->table("group_contacts");
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(int $id): ?Contact
|
||||||
|
{
|
||||||
|
$ar = $this->clubs->get($id);
|
||||||
|
return is_null($ar) ? NULL : new Contact($ar);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getByClub(int $id): \Traversable
|
||||||
|
{
|
||||||
|
$contacts = $this->contacts->where("group", $id)->where("deleted", 0);
|
||||||
|
return new Util\EntityStream("Contact", $contacts);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getByClubAndUser(int $club, int $user): ?Contact
|
||||||
|
{
|
||||||
|
$contact = $this->contacts->where("group", $club)->where("user", $user)->fetch();
|
||||||
|
return $this->get($contact);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
namespace openvk\Web\Presenters;
|
namespace openvk\Web\Presenters;
|
||||||
use openvk\Web\Models\Entities\{Club, Photo};
|
use openvk\Web\Models\Entities\{Club, Photo, Contact};
|
||||||
use openvk\Web\Models\Entities\Notifications\ClubModeratorNotification;
|
use openvk\Web\Models\Entities\Notifications\ClubModeratorNotification;
|
||||||
use openvk\Web\Models\Repositories\{Clubs, Users, Albums, Managers};
|
use openvk\Web\Models\Repositories\{Clubs, Users, Albums, Managers, Contacts};
|
||||||
|
|
||||||
final class GroupPresenter extends OpenVKPresenter
|
final class GroupPresenter extends OpenVKPresenter
|
||||||
{
|
{
|
||||||
|
@ -131,7 +131,6 @@ final class GroupPresenter extends OpenVKPresenter
|
||||||
$this->flashFail("succ", "Операция успешна", $user->getCanonicalName() . " назначен(а) администратором.");
|
$this->flashFail("succ", "Операция успешна", $user->getCanonicalName() . " назначен(а) администратором.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderEdit(int $id): void
|
function renderEdit(int $id): void
|
||||||
|
@ -197,6 +196,62 @@ final class GroupPresenter extends OpenVKPresenter
|
||||||
$this->template->views = $club->getPostViewStats(false);
|
$this->template->views = $club->getPostViewStats(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderContacts(int $id): void
|
||||||
|
{
|
||||||
|
$this->assertUserLoggedIn();
|
||||||
|
|
||||||
|
$club = $this->clubs->get($id);
|
||||||
|
$this->template->club = $club;
|
||||||
|
$this->template->contacts = $club->getContacts()->page($this->queryParam("p") ?? 1);
|
||||||
|
$this->template->count = $club->getContacts()->size();
|
||||||
|
$this->template->paginatorConf = (object) [
|
||||||
|
"count" => $this->template->count,
|
||||||
|
"page" => $this->queryParam("p") ?? 1,
|
||||||
|
"amount" => NULL,
|
||||||
|
"perPage" => OPENVK_DEFAULT_PER_PAGE,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderActionContact(): void
|
||||||
|
{
|
||||||
|
$contact;
|
||||||
|
$id = $this->queryParam("id");
|
||||||
|
|
||||||
|
if($this->queryParam("type") == 'delete' || $this->queryParam("type") == 'edit') {
|
||||||
|
if(!$id)
|
||||||
|
exit(json_encode([ "error" => tr("error_segmentation") ]));
|
||||||
|
|
||||||
|
$contact = (new Contacts)->get($id);
|
||||||
|
|
||||||
|
if(!$contact)
|
||||||
|
exit(json_encode([ "error" => "Contact does not exist" ]));
|
||||||
|
|
||||||
|
if(!$contact->getClub()->canBeModifiedBy($this->user->identity ?? NULL) && $contact->getClub()->getOwner()->getId() !== $user->getId())
|
||||||
|
exit(json_encode([ "error" => "You have no permissions to modify this contact" ]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->queryParam("type") == 'delete') {
|
||||||
|
$contact->setDeleted(1);
|
||||||
|
$contact->save();
|
||||||
|
exit(json_encode([ "status" => 'ok' ]));
|
||||||
|
} else if ($this->queryParam("type") == 'edit') {
|
||||||
|
if(!empty($this->queryParam("desc"))) {
|
||||||
|
$contact->setContent($this->queryParam("desc"));
|
||||||
|
$contact->save();
|
||||||
|
exit(json_encode([ "status" => 'ok' ]));
|
||||||
|
} else
|
||||||
|
exit(json_encode([ "error" => "Description cannot be empty" ]));
|
||||||
|
|
||||||
|
} else if ($this->queryParam("type") == 'create') {
|
||||||
|
/* ну тут мне впринципе дальше лень делать
|
||||||
|
|
||||||
|
$contact = new Contact;
|
||||||
|
$contact->setGroup();
|
||||||
|
$contact->save(); */
|
||||||
|
exit(json_encode([ "error" => "Not implemented yet" ]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function renderAdmin(int $clb, int $id): void
|
function renderAdmin(int $clb, int $id): void
|
||||||
{
|
{
|
||||||
$this->assertUserLoggedIn();
|
$this->assertUserLoggedIn();
|
||||||
|
|
89
Web/Presenters/templates/Group/Contacts.xml
Normal file
89
Web/Presenters/templates/Group/Contacts.xml
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
{extends "../@listView.xml"}
|
||||||
|
{var iterator = $contacts}
|
||||||
|
{var count = $paginatorConf->count}
|
||||||
|
{var page = $paginatorConf->page}
|
||||||
|
{var perPage = 6}
|
||||||
|
|
||||||
|
{block title}{_contacts} {$club->getCanonicalName()}{/block}
|
||||||
|
|
||||||
|
{block header}
|
||||||
|
<a href="{$club->getURL()}">{$club->getCanonicalName()}</a>
|
||||||
|
» {_contacts}
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block actions}
|
||||||
|
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{* BEGIN ELEMENTS DESCRIPTION *}
|
||||||
|
|
||||||
|
{block tabs}
|
||||||
|
{if $club->canBeModifiedBy($thisUser)}
|
||||||
|
<div class="tab">
|
||||||
|
<a href="javascript:void(0)">
|
||||||
|
{_main}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="tab">
|
||||||
|
<a href="/club{$club->getId()}/followers">
|
||||||
|
{_followers}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div id="activetabs" class="tab">
|
||||||
|
<a id="act_tab_a" href="/club{$club->getId()}/contacts">
|
||||||
|
{_contacts}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="tab">
|
||||||
|
<a href="/club{$club->getId()}/stats">
|
||||||
|
{_statistics}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block link|strip|stripHtml}
|
||||||
|
/id{$x->getId()}
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block preview}
|
||||||
|
<img src="{$x->getUser()->getAvatarURL()}" alt="{$x->getUser()->getCanonicalName()}" width=75 />
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block name}
|
||||||
|
{$x->getUser()->getCanonicalName()}
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block description}
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td width="120" valign="top"><span class="nobold">{_"gender"}: </span></td>
|
||||||
|
<td>{$x->getUser()->isFemale() ? "женский" : "мужской"}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="120" valign="top"><span class="nobold">{_description}: </span></td>
|
||||||
|
<td>
|
||||||
|
{$x->getDescription()}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="120" valign="top"><span class="nobold">{_role}: </span></td>
|
||||||
|
<td>
|
||||||
|
{$club->canBeModifiedBy($x->getUser()) ? tr("administrator") : tr("follower")}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr n:if="$club->canBeModifiedBy($thisUser ?? NULL) && $club->getOwner()->getId() !== $x->getUser()->getId()">
|
||||||
|
<td width="120" valign="top"><span class="nobold">{_actions}: </span></td>
|
||||||
|
<td>
|
||||||
|
<a href="javascript:contactEdit({$x->getUser()->getId()}, {rawurlencode($csrfToken)})">
|
||||||
|
{_edit}
|
||||||
|
</a>,
|
||||||
|
<a href="javascript:contactDelete({$x->getUser()->getId()}, {rawurlencode($csrfToken)})">
|
||||||
|
{_delete}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{/block}
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
{block content}
|
{block content}
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
<div id="activetabs" class="tab">
|
<div class="tab">
|
||||||
<a id="act_tab_a" href="javascript:void(0)">
|
<a id="act_tab_a" href="javascript:void(0)">
|
||||||
{_main}
|
{_main}
|
||||||
</a>
|
</a>
|
||||||
|
@ -17,6 +17,11 @@
|
||||||
{_followers}
|
{_followers}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="tab">
|
||||||
|
<a href="/club{$club->getId()}/contacts">
|
||||||
|
{_contacts}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<div class="tab">
|
<div class="tab">
|
||||||
<a href="/club{$club->getId()}/stats">
|
<a href="/club{$club->getId()}/stats">
|
||||||
{_statistics}
|
{_statistics}
|
||||||
|
|
|
@ -17,6 +17,31 @@
|
||||||
|
|
||||||
{* BEGIN ELEMENTS DESCRIPTION *}
|
{* BEGIN ELEMENTS DESCRIPTION *}
|
||||||
|
|
||||||
|
{block tabs}
|
||||||
|
{if $club->canBeModifiedBy($thisUser)}
|
||||||
|
<div class="tab">
|
||||||
|
<a href="javascript:void(0)">
|
||||||
|
{_main}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div id="activetabs" class="tab">
|
||||||
|
<a id="act_tab_a" href="/club{$club->getId()}/followers">
|
||||||
|
{_followers}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="tab">
|
||||||
|
<a href="/club{$club->getId()}/contacts">
|
||||||
|
{_contacts}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="tab">
|
||||||
|
<a href="/club{$club->getId()}/stats">
|
||||||
|
{_statistics}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/block}
|
||||||
|
|
||||||
{block link|strip|stripHtml}
|
{block link|strip|stripHtml}
|
||||||
/id{$x->getId()}
|
/id{$x->getId()}
|
||||||
{/block}
|
{/block}
|
||||||
|
|
|
@ -104,6 +104,29 @@
|
||||||
<div style="padding:4px">
|
<div style="padding:4px">
|
||||||
{_"group_type_open"}
|
{_"group_type_open"}
|
||||||
</div>
|
</div>
|
||||||
|
</div><div>
|
||||||
|
<div class="content_title_expanded" onclick="hidePanel(this);">
|
||||||
|
Контакты
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{var contacts = $club->getContacts()}
|
||||||
|
<div class="content_subtitle">
|
||||||
|
{$contacts->size()}
|
||||||
|
<div style="float:right;">
|
||||||
|
<a href="/club{$club->getId()}/contacts">{_"all_title"}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="group_contact" n:foreach="$contacts->page(1, 5) as $contact">
|
||||||
|
<avatar>
|
||||||
|
<img src="{$contact->getUser()->getAvatarUrl()}" style="image-rendering: -webkit-optimize-contrast;" />
|
||||||
|
</avatar>
|
||||||
|
<description>
|
||||||
|
<a href="{$contact->getUser()->getURL()}"><b>{$contact->getUser()->getFullName()}</b></a><br>
|
||||||
|
{$contact->getDescription()}
|
||||||
|
</description>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="content_title_expanded" onclick="hidePanel(this);">
|
<div class="content_title_expanded" onclick="hidePanel(this);">
|
||||||
|
|
|
@ -37,3 +37,4 @@ services:
|
||||||
- openvk\Web\Models\Repositories\Vouchers
|
- openvk\Web\Models\Repositories\Vouchers
|
||||||
- openvk\Web\Models\Repositories\Gifts
|
- openvk\Web\Models\Repositories\Gifts
|
||||||
- openvk\Web\Models\Repositories\ContentSearchRepository
|
- openvk\Web\Models\Repositories\ContentSearchRepository
|
||||||
|
- openvk\Web\Models\Repositories\Contacts
|
||||||
|
|
|
@ -145,6 +145,10 @@ routes:
|
||||||
handler: "Group->statistics"
|
handler: "Group->statistics"
|
||||||
- url: "/club{num}/followers"
|
- url: "/club{num}/followers"
|
||||||
handler: "Group->followers"
|
handler: "Group->followers"
|
||||||
|
- url: "/club{num}/contacts"
|
||||||
|
handler: "Group->contacts"
|
||||||
|
- url: "/club{num}/contacts/action"
|
||||||
|
handler: "Group->actionContact"
|
||||||
- url: "/club{num}/followers/{num}"
|
- url: "/club{num}/followers/{num}"
|
||||||
handler: "Group->admin"
|
handler: "Group->admin"
|
||||||
- url: "/club{num}/setAdmin.jsp"
|
- url: "/club{num}/setAdmin.jsp"
|
||||||
|
|
|
@ -1425,3 +1425,18 @@ body.scrolled .toTop:hover {
|
||||||
#ovkDraw .literally .lc-picker .toolbar-button:hover:not(.disabled), #ovkDraw .literally .horz-toolbar .square-toolbar-button:hover:not(.disabled) {
|
#ovkDraw .literally .lc-picker .toolbar-button:hover:not(.disabled), #ovkDraw .literally .horz-toolbar .square-toolbar-button:hover:not(.disabled) {
|
||||||
border-color: #cdcdcd;
|
border-color: #cdcdcd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.group_contact {
|
||||||
|
font-size: 10px;
|
||||||
|
display: flex;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group_contact avatar {
|
||||||
|
width: 30px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group_contact avatar img {
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
14
install/sqls/00003-contact-groups.sql
Normal file
14
install/sqls/00003-contact-groups.sql
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
DROP TABLE IF EXISTS `group_contacts`;
|
||||||
|
CREATE TABLE `group_contacts` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`group` bigint(20) unsigned NOT NULL,
|
||||||
|
`user` bigint(20) unsigned NOT NULL,
|
||||||
|
`content` varchar(64) COLLATE utf8mb4_general_nopad_ci NOT NULL,
|
||||||
|
`email` varchar(64) COLLATE utf8mb4_general_nopad_ci DEFAULT NULL,
|
||||||
|
`deleted` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `group` (`group`),
|
||||||
|
KEY `user` (`user`),
|
||||||
|
CONSTRAINT `group_contacts_ibfk_1` FOREIGN KEY (`group`) REFERENCES `groups` (`id`),
|
||||||
|
CONSTRAINT `group_contacts_ibfk_2` FOREIGN KEY (`user`) REFERENCES `profiles` (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_nopad_ci;
|
Loading…
Reference in a new issue