Wall: Add an initial closing of the posts

This commit is contained in:
Ilya Prokopenko 2022-08-12 15:11:08 +07:00
parent bbdfb04c01
commit 2949ed8afb
No known key found for this signature in database
GPG key ID: 7736BBBB05F14A56
17 changed files with 146 additions and 19 deletions

View file

@ -415,6 +415,9 @@ final class Wall extends VKAPIRequestHandler
if(!$post || $post->isDeleted()) $this->fail(100, "One of the parameters specified was missing or invalid");
$comments = (new CommentsRepo)->getCommentsByTarget($post, $offset+1, $count, $sort == "desc" ? "DESC" : "ASC");
if(!$post->getPrivacyPermission('comments.read', $this->user->identity))
$this->fail(15, "Access denied");
$items = [];
$profiles = [];
@ -519,8 +522,11 @@ final class Wall extends VKAPIRequestHandler
$post = (new PostsRepo)->getPostById($owner_id, $post_id);
if(!$post || $post->isDeleted()) $this->fail(100, "One of the parameters specified was missing or invalid");
if($post->isClosed() || !$post->getPrivacyPermission('comments.write', $this->user->identity))
$this->fail(15, "Access denied");
if($post->getTargetWall() < 0)
$club = (new ClubsRepo)->get(abs($post->getTargetWall()));
$club = (new ClubsRepo)->get(abs($post->getTargetWall()));
$flags = 0;
if($from_group != 0 && !is_null($club) && $club->canBeModifiedBy($this->user))
@ -555,7 +561,7 @@ final class Wall extends VKAPIRequestHandler
$comment = (new CommentsRepo)->get($comment_id);
if(!$comment) $this->fail(100, "One of the parameters specified was missing or invalid");;
if(!$comment->canBeDeletedBy($this->user))
$this->fail(7, "Access denied");
$this->fail(15, "Access denied");
$comment->delete();

View file

@ -94,6 +94,11 @@ class Post extends Postable
{
return (bool) $this->getRecord()->nsfw;
}
function isClosed(): bool
{
return (bool) $this->getRecord()->closed;
}
function isDeleted(): bool
{
@ -125,6 +130,27 @@ class Post extends Postable
$this->stateChanges("pinned", false);
$this->save();
}
function close(): void
{
DB::i()
->getContext()
->table("posts")
->where([
"wall" => $this->getTargetWall(),
"closed" => true,
])
->update(["closed" => false]);
$this->stateChanges("closed", true);
$this->save();
}
function open(): void
{
$this->stateChanges("closed", false);
$this->save();
}
function canBePinnedBy(User $user): bool
{
@ -138,6 +164,11 @@ class Post extends Postable
{
return $this->getOwnerPost() === $user->getId() || $this->canBePinnedBy($user);
}
function canBeClosedBy(User $user): bool
{
return $this->canBeDeletedBy($user);
}
function setContent(string $content): void
{

View file

@ -427,6 +427,8 @@ class User extends RowModel
"friends.add",
"wall.write",
"messages.write",
"comments.read",
"comments.write",
],
])->get($id);
}
@ -869,6 +871,8 @@ class User extends RowModel
"friends.add",
"wall.write",
"messages.write",
"comments.read",
"comments.write",
],
])->set($id, $status)->toInteger());
}

View file

@ -1,6 +1,6 @@
<?php declare(strict_types=1);
namespace openvk\Web\Presenters;
use openvk\Web\Models\Entities\{Comment, Photo, Video, User, Topic, Post};
use openvk\Web\Models\Entities\{Comment, Photo, Video, User, Topic, Post, Wall};
use openvk\Web\Models\Entities\Notifications\CommentNotification;
use openvk\Web\Models\Repositories\{Comments, Clubs};
@ -42,6 +42,9 @@ final class CommentPresenter extends OpenVKPresenter
if($entity instanceof Topic && $entity->isClosed())
$this->notFound();
if($entity instanceof Post && !$entity->getOwner()->getPrivacyPermission('comments.write', $this->user->identity))
exit(header("HTTP/1.1 403 Forbidden"));
if($entity instanceof Post && $entity->getTargetWall() < 0)
$club = (new Clubs)->get(abs($entity->getTargetWall()));
else if($entity instanceof Topic)

View file

@ -386,6 +386,8 @@ final class UserPresenter extends OpenVKPresenter
"friends.add",
"wall.write",
"messages.write",
"comments.read",
"comments.write",
];
foreach($settings as $setting) {
$input = $this->postParam(str_replace(".", "_", $setting));

View file

@ -409,4 +409,26 @@ final class WallPresenter extends OpenVKPresenter
# TODO localize message based on language and ?act=(un)pin
$this->flashFail("succ", tr("information_-1"), tr("changes_saved_comment"));
}
function renderOpen(int $wall, int $post_id): void
{
$this->assertUserLoggedIn();
$this->willExecuteWriteAction();
$post = $this->posts->getPostById($wall, $post_id);
if(!$post)
$this->notFound();
if(!$post->canBeClosedBy($this->user->identity))
$this->flashFail("err", tr("not_enough_permissions"), tr("not_enough_permissions_comment"));
if(($this->queryParam("act") ?? "open") === "open") {
$post->open();
} else {
$post->close();
}
# TODO localize message based on language and ?act=(open|close)
$this->flashFail("succ", tr("information_-1"), tr("changes_saved_comment"));
}
}

View file

@ -77,6 +77,7 @@
page => $cPage,
model => "notes",
parent => $note,
showTitle => false}
showTitle => false,
wallOwner => $author}
</div>
{/block}

View file

@ -356,6 +356,31 @@
</select>
</td>
</tr>
<tr>
<td width="120" valign="top">
<span class="nobold">{_privacy_setting_see_comments}</span>
</td>
<td>
<select name="comments.read" style="width: 164px;">
<option value="3" {if $user->getPrivacySetting('comments.read') == 3}selected{/if}>{_privacy_value_anybody_dative}</option>
<option value="2" {if $user->getPrivacySetting('comments.read') == 2}selected{/if}>{_privacy_value_users}</option>
<option value="1" {if $user->getPrivacySetting('comments.read') == 1}selected{/if}>{_privacy_value_friends_dative}</option>
<option value="0" {if $user->getPrivacySetting('comments.read') == 0}selected{/if}>{_privacy_value_only_me_dative}</option>
</select>
</td>
</tr>
<tr>
<td width="120" valign="top">
<span class="nobold">{_privacy_setting_write_comments}</span>
</td>
<td>
<select name="comments.write", style="width: 164px;">
<option value="2" {if $user->getPrivacySetting('comments.write') == 2}selected{/if}>{_privacy_value_anybody}</option>
<option value="1" {if $user->getPrivacySetting('comments.write') == 1}selected{/if}>{_privacy_value_friends}</option>
<option value="0" {if $user->getPrivacySetting('comments.write') == 0}selected{/if}>{_privacy_value_nobody}</option>
</select>
</td>
</tr>
<tr>
<td>

View file

@ -14,22 +14,39 @@
{/block}
{block content}
{include "../components/post.xml", post => $post, forceNoCommentsLink => TRUE, forceNoDeleteLink => TRUE}
{include "../components/post.xml", post => $post, forceNoCommentsLink => TRUE, forceNoPinLink => TRUE, forceNoDeleteLink => TRUE}
<hr/>
<div style="float: left; min-height: 100px; width: 68%;">
<div n:if="$wallOwner->getPrivacyPermission('comments.read', $thisUser)" style="float: left; min-height: 100px; width: 68%;">
{include "../components/comments.xml",
comments => $comments,
count => $cCount,
page => $cPage,
model => "posts",
parent => $post }
parent => $post,
readOnly => (!$wallOwner->getPrivacyPermission('comments.write', $thisUser) XOR $post->isClosed()) }
</div>
<div style="float: left; min-height: 100px; width: 32%;">
<div style="float: right; min-height: 100px; width: 32%;">
<h4>{_actions}</h4>
{if isset($thisUser)}
{var $canPin = $post->canBePinnedBy($thisUser)}
{var $canClose = $post->canBeClosedBy($thisUser)}
{var $canDelete = $post->canBeDeletedBy($thisUser)}
{/if}
{if $canPin}
{if $post->isPinned()}
<a class="profile_link" style="display:block;width:96%;" href="/wall{$post->getPrettyId()}/pin?act=unpin&hash={rawurlencode($csrfToken)}">{_unpin}</a>
{else}
<a class="profile_link" style="display:block;width:96%;" href="/wall{$post->getPrettyId()}/pin?act=pin&hash={rawurlencode($csrfToken)}">{_pin}</a>
{/if}
{/if}
{if $canClose}
{if $post->isClosed()}
<a class="profile_link" style="display:block;width:96%;" href="/wall{$post->getPrettyId()}/open?act=open&hash={rawurlencode($csrfToken)}">{_enable_comments}</a>
{else}
<a class="profile_link" style="display:block;width:96%;" href="/wall{$post->getPrettyId()}/open?act=close&hash={rawurlencode($csrfToken)}">{_disable_comments}</a>
{/if}
{/if}
<a n:if="$canDelete ?? false" class="profile_link" style="display:block;width:96%;" href="/wall{$post->getPrettyId()}/delete">{_delete}</a>
</div>
{/block}

View file

@ -1,6 +1,7 @@
{var $author = $comment->getOwner()}
{var $Club = openvk\Web\Models\Entities\Club::class}
{var $Club = openvk\Web\Models\Entities\Club::class}
{var $postId = $comment->getTarget() instanceof \openvk\Web\Models\Entities\Post ? $comment->getTarget()->getId() : NULL}
{var $post = $comment->getTarget() instanceof \openvk\Web\Models\Entities\Post ? (new \openvk\Web\Models\Repositories\Posts)->get($postId) : NULL}
<a name="cid={$comment->getId()}"></a>
<table border="0" style="font-size: 11px;" class="post comment" id="_comment{$comment->getId()}" data-comment-id="{$comment->getId()}" data-owner-id="{$author->getId()}" data-from-group="{$comment->getOwner() instanceof $Club}" n:attr="data-post-id => $postId">
@ -29,11 +30,13 @@
</div>
</div>
<div n:if="isset($thisUser) &&! ($compact ?? false)" class="post-menu">
<a href="#_comment{$comment->getId()}" class="date">{$comment->getPublicationTime()}</a>&nbsp;|
<a href="#_comment{$comment->getId()}" class="date">{$comment->getPublicationTime()}</a>
{if $comment->canBeDeletedBy($thisUser)}
<a href="/comment{$comment->getId()}/delete">{_delete}</a>&nbsp;|
|&nbsp;<a href="/comment{$comment->getId()}/delete">{_delete}</a>
{/if}
{if $post->getOwner()->getPrivacyPermission('comments.write', $thisUser) && !$post->isClosed()}
|&nbsp;<a class="comment-reply">{_reply}</a>
{/if}
<a class="comment-reply">{_reply}</a>
<div style="float: right; font-size: .7rem;">
<a class="post-like-button" href="/comment{$comment->getId()}/like?hash={rawurlencode($csrfToken)}">
<div class="heart" style="{if $comment->hasLikeFrom($thisUser)}opacity: 1;{else}opacity: 0.4;{/if}"></div>

View file

@ -16,7 +16,9 @@
{include "paginator.xml", conf => (object) ["page" => $page, "count" => $count, "amount" => sizeof($comments), "perPage" => 10]}
</div>
{else}
{_comments_tip}
{if $wallOwner->getPrivacyPermission('comments.write', $thisUser)}
{_comments_tip}
{/if}
{/if}
{script "js/al_comments.js"}

View file

@ -88,7 +88,7 @@
{if isset($thisUser)}
&nbsp;
<a n:if="!($forceNoCommentsLink ?? false) && $commentsCount == 0" href="javascript:expand_comment_textarea({$commentTextAreaId})">{_comment}</a>
<a n:if="!($forceNoCommentsLink ?? false) && $author->getPrivacyPermission('comments.read', $thisUser) && $commentsCount == 0" href="javascript:expand_comment_textarea({$commentTextAreaId})">{_comment}</a>
<div class="like_wrap">
<a n:if="!($forceNoShareLink ?? false)" class="post-share-button" href="javascript:repostPost('{$post->getPrettyId()}', '{rawurlencode($csrfToken)}')">
@ -106,12 +106,12 @@
</div>
{/if}
</div>
<div n:if="!($forceNoCommentsLink ?? false) && $commentSection == true && $compact == false" class="post-menu-s">
<div n:if="!($forceNoCommentsLink ?? false) && $author->getPrivacyPermission('comments.read', $thisUser) && $commentSection == true && $compact == false" class="post-menu-s">
<a n:if="$commentsCount > 3" href="/wall{$post->getPrettyId()}" class="expand_button">{_view_other_comments}</a>
{foreach $comments as $comment}
{include "../comment.xml", comment => $comment, $compact => true}
{/foreach}
<div n:ifset="$thisUser" id="commentTextArea{$commentTextAreaId}" n:attr="style => ($commentsCount == 0 ? 'display: none;')" class="commentsTextFieldWrap">
<div n:ifset="$thisUser" n:if="$author->getPrivacyPermission('comments.write', $thisUser) && !$post->isClosed()" id="commentTextArea{$commentTextAreaId}" n:attr="style => ($commentsCount == 0 ? 'display: none;')" class="commentsTextFieldWrap">
{var $commentsURL = "/al_comments/create/posts/" . $post->getId()}
{var $club = is_null($club) ? ($post->getTargetWall() < 0 ? (new openvk\Web\Models\Repositories\Clubs)->get(abs($post->getTargetWall())) : NULL) : $club}
{include "../textArea.xml", route => $commentsURL, postOpts => false, graffiti => (bool) ovkGetQuirk("comments.allow-graffiti"), post => $post, club => $club}

View file

@ -83,14 +83,14 @@
&nbsp;|&nbsp;
{/if}
<a n:if="!($forceNoCommentsLink ?? false)" href="/wall{$post->getPrettyId()}#comments">
<a n:if="!($forceNoCommentsLink ?? false) && $author->getPrivacyPermission('comments.read', $thisUser)" href="/wall{$post->getPrettyId()}#comments">
{_comments}
{if $post->getCommentsCount() > 0}
(<b>{$post->getCommentsCount()}</b>)
{/if}
</a>
{if !($forceNoCommentsLink ?? false) && !($forceNoShareLink ?? false)}
{if (!($forceNoCommentsLink ?? false) && $author->getPrivacyPermission('comments.read', $thisUser)) && !($forceNoShareLink ?? false)}
&nbsp;|&nbsp;
{/if}

View file

@ -129,6 +129,8 @@ routes:
handler: "Wall->delete"
- url: "/wall{num}_{num}/pin"
handler: "Wall->pin"
- url: "/wall{num}_{num}/open"
handler: "Wall->open"
- url: "/blob_{text}/{?path}.{text}"
handler: "Blob->file"
placeholders:

View file

@ -0,0 +1 @@
ALTER TABLE `posts` ADD `closed` tinyint(1) NOT NULL DEFAULT '0' AFTER `anonymous`;

View file

@ -165,6 +165,8 @@
"pinned" = "pinned";
"comments_tip" = "Be first, who leaves a comment at this post!";
"your_comment" = "Your comment";
"enable_comments" = "Enable comments";
"disable_comments" = "Disable comments";
"shown" = "Shown";
"x_out_of" = "$1 of";
"wall_zero" = "no posts";
@ -452,6 +454,8 @@
"privacy_setting_add_to_friends" = "Who can add me to friends";
"privacy_setting_write_wall" = "Who can publish post on my wall";
"privacy_setting_write_messages" = "Who can write messages to me";
"privacy_setting_see_comments" = "Who can see comments on my posts";
"privacy_setting_write_comments" = "Who can write comment on my posts";
"privacy_value_anybody" = "Anybody";
"privacy_value_anybody_dative" = "Anybody";
"privacy_value_users" = "OpenVK users";

View file

@ -171,6 +171,8 @@
"pinned" = "закреплено";
"comments_tip" = "Будьте первым, кто оставит комментарий!";
"your_comment" = "Ваш комментарий";
"enable_comments" = "Включить комментарии";
"disable_comments" = "Выключить комментарии";
"shown" = "Показано";
"x_out_of" = "$1 из";
"wall_zero" = "нет записей";
@ -488,6 +490,8 @@
"privacy_setting_add_to_friends" = "Кто может называть меня другом";
"privacy_setting_write_wall" = "Кто может писать у меня на стене";
"privacy_setting_write_messages" = "Кто может писать мне сообщения";
"privacy_setting_see_comments" = "Кому видно комментарии к моим записям";
"privacy_setting_write_comments" = "Кто может комментировать мои записи";
"privacy_value_anybody" = "Все желающие";
"privacy_value_anybody_dative" = "Всем желающим";
"privacy_value_users" = "Пользователям OpenVK";