When you like a repost, put likes on the entire hierarchy of repost posts recursively

If you like a repost, all posts from the hierarchy will be liked. If you remove a like from a post, likes will be removed from all posts from the hierarchy. I don’t know what the load will be in the case of large hierarchies (for example, 20 posts), but with small hierarchies (5 posts) everything works fine. Fixes #159
This commit is contained in:
Maxim Leshchenko 2021-11-11 12:05:07 +02:00
parent 202c203b80
commit e44cfa5bc4
3 changed files with 59 additions and 7 deletions

View file

@ -3,6 +3,7 @@ namespace openvk\Web\Models\Entities;
use Chandler\Database\DatabaseConnection as DB; use Chandler\Database\DatabaseConnection as DB;
use openvk\Web\Models\Repositories\Clubs; use openvk\Web\Models\Repositories\Clubs;
use openvk\Web\Models\RowModel; use openvk\Web\Models\RowModel;
use openvk\Web\Models\Entities\Notifications\LikeNotification;
class Post extends Postable class Post extends Postable
{ {
@ -122,6 +123,42 @@ class Post extends Postable
$this->stateChanges("content", $content); $this->stateChanges("content", $content);
} }
function toggleLike(User $user): bool
{
$liked = parent::toggleLike($user);
if($this->getOwner(false)->getId() !== $user->getId() && !($this->getOwner() instanceof Club))
(new LikeNotification($this->getOwner(false), $this, $user))->emit();
foreach($this->getChildren() as $attachment) {
if($attachment instanceof Post)
$attachment->setLike($liked, $user);
}
return $liked;
}
function setLike(bool $liked, User $user): void
{
$searchData = [
"origin" => $user->getId(),
"model" => static::class,
"target" => $this->getRecord()->id,
];
if((sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0) !== $liked) {
if($this->getOwner(false)->getId() !== $user->getId() && !($this->getOwner() instanceof Club))
(new LikeNotification($this->getOwner(false), $this, $user))->emit();
parent::setLike($liked, $user);
}
foreach($this->getChildren() as $attachment) {
if($attachment instanceof Post)
$attachment->setLike($liked, $user);
}
}
function deletePost(): void function deletePost(): void
{ {
$this->setDeleted(1); $this->setDeleted(1);

View file

@ -96,17 +96,35 @@ abstract class Postable extends Attachable
yield (new Users)->get($like->origin); yield (new Users)->get($like->origin);
} }
function toggleLike(User $user): void function toggleLike(User $user): bool
{ {
$searchData = [ $searchData = [
"origin" => $user->getId(), "origin" => $user->getId(),
"model" => static::class, "model" => static::class,
"target" => $this->getRecord()->id, "target" => $this->getRecord()->id,
]; ];
if(sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0)
if(sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0) {
DB::i()->getContext()->table("likes")->where($searchData)->delete(); DB::i()->getContext()->table("likes")->where($searchData)->delete();
else return false;
}
DB::i()->getContext()->table("likes")->insert($searchData);
return true;
}
function setLike(bool $liked, User $user): void
{
$searchData = [
"origin" => $user->getId(),
"model" => static::class,
"target" => $this->getRecord()->id,
];
if($liked)
DB::i()->getContext()->table("likes")->insert($searchData); DB::i()->getContext()->table("likes")->insert($searchData);
else
DB::i()->getContext()->table("likes")->where($searchData)->delete();
} }
function hasLikeFrom(User $user): bool function hasLikeFrom(User $user): bool

View file

@ -1,7 +1,7 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace openvk\Web\Presenters; namespace openvk\Web\Presenters;
use openvk\Web\Models\Entities\{Post, Photo, Video, Club, User}; use openvk\Web\Models\Entities\{Post, Photo, Video, Club, User};
use openvk\Web\Models\Entities\Notifications\{LikeNotification, RepostNotification, WallPostNotification}; use openvk\Web\Models\Entities\Notifications\{RepostNotification, WallPostNotification};
use openvk\Web\Models\Repositories\{Posts, Users, Clubs, Albums}; use openvk\Web\Models\Repositories\{Posts, Users, Clubs, Albums};
use Chandler\Database\DatabaseConnection; use Chandler\Database\DatabaseConnection;
use Nette\InvalidStateException as ISE; use Nette\InvalidStateException as ISE;
@ -278,9 +278,6 @@ final class WallPresenter extends OpenVKPresenter
if(!is_null($this->user)) { if(!is_null($this->user)) {
$post->toggleLike($this->user->identity); $post->toggleLike($this->user->identity);
if($post->getOwner(false)->getId() !== $this->user->identity->getId() && !($post->getOwner() instanceof Club))
(new LikeNotification($post->getOwner(false), $post, $this->user->identity))->emit();
} }
$this->redirect( $this->redirect(