From a0ffd0a9d761e32b3d3b3fd45c1b68642078c545 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Fri, 25 Aug 2023 13:10:39 +0300 Subject: [PATCH] Add API for notifications --- VKAPI/Handlers/Notifications.php | 83 +++++++++++ VKAPI/Handlers/Users.php | 25 +++- Web/Models/Entities/Club.php | 4 +- Web/Models/Entities/Comment.php | 13 ++ Web/Models/Entities/Note.php | 2 +- .../Entities/Notifications/Notification.php | 134 ++++++++++++++++++ Web/Models/Entities/Photo.php | 16 +++ Web/Models/Entities/Post.php | 17 +++ Web/Models/Entities/Video.php | 19 +++ 9 files changed, 309 insertions(+), 4 deletions(-) create mode 100644 VKAPI/Handlers/Notifications.php diff --git a/VKAPI/Handlers/Notifications.php b/VKAPI/Handlers/Notifications.php new file mode 100644 index 00000000..8a047f80 --- /dev/null +++ b/VKAPI/Handlers/Notifications.php @@ -0,0 +1,83 @@ +requireUser(); + + $res = (object)[ + "items" => [], + "profiles" => [], + "groups" => [], + "last_viewed" => $this->getUser()->getNotificationOffset() + ]; + + if($count > 100) + $this->fail(125, "Count is too big"); + + if(!eventdb()) + $this->fail(1289, "EventDB is disabled on this instance"); + + $notifs = array_slice(iterator_to_array((new Notifs)->getNotificationsByUser($this->getUser(), $this->getUser()->getNotificationOffset(), (bool)$archived, 1, $offset + $count)), $offset); + $tmpProfiles = []; + foreach($notifs as $notif) { + $sxModel = $notif->getModel(1); + + if(!method_exists($sxModel, "getAvatarUrl")) + $sxModel = $notif->getModel(0); + + + $tmpProfiles[] = $sxModel instanceof Club ? $sxModel->getId() * -1 : $sxModel->getId(); + $res->items[] = $notif->toVkApiStruct(); + } + + foreach(array_unique($tmpProfiles) as $id) { + if($id > 0) { + $sxModel = (new Users)->get($id); + $result = (object)[ + "uid" => $sxModel->getId(), + "first_name" => $sxModel->getFirstName(), + "last_name" => $sxModel->getLastName(), + "photo" => $sxModel->getAvatarUrl(), + "photo_medium_rec" => $sxModel->getAvatarUrl("tiny"), + "screen_name" => $sxModel->getShortCode() + ]; + + $res->profiles[] = $result; + } else { + $sxModel = (new Clubs)->get(abs($id)); + $result = $sxModel->toVkApiStruct($this->getUser()); + + $res->groups[] = $result; + } + } + + return $res; + } + + function markAsViewed() + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + try { + $this->getUser()->updateNotificationOffset(); + $this->getUser()->save(); + } catch(\Throwable $e) { + return 0; + } + + return 1; + } +} diff --git a/VKAPI/Handlers/Users.php b/VKAPI/Handlers/Users.php index a4298787..6d67ed39 100644 --- a/VKAPI/Handlers/Users.php +++ b/VKAPI/Handlers/Users.php @@ -1,7 +1,8 @@ $this->get(implode(',', $array), $nfilds, $offset, $count) ]; } + + function report(int $user_id, string $type = "spam", string $comment = "") + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + if($user_id == $this->getUser()->getId()) + $this->fail(12, "Can't report yourself."); + + if(sizeof(iterator_to_array((new Reports)->getDuplicates("user", $user_id, NULL, $this->getUser()->getId()))) > 0) + return 1; + + $report = new Report; + $report->setUser_id($this->getUser()->getId()); + $report->setTarget_id($user_id); + $report->setType("user"); + $report->setReason($comment); + $report->setCreated(time()); + $report->save(); + + return 1; + } } diff --git a/Web/Models/Entities/Club.php b/Web/Models/Entities/Club.php index 31485129..79ce08a4 100644 --- a/Web/Models/Entities/Club.php +++ b/Web/Models/Entities/Club.php @@ -374,7 +374,7 @@ class Club extends RowModel function toVkApiStruct(?User $user = NULL): object { - $res = []; + $res = (object) []; $res->id = $this->getId(); $res->name = $this->getName(); @@ -398,7 +398,7 @@ class Club extends RowModel $res->can_post = $this->canBeModifiedBy($user) ? 1 : ($this->canPost() ? 1 : 0); - return (object) $res; + return $res; } use Traits\TBackDrops; diff --git a/Web/Models/Entities/Comment.php b/Web/Models/Entities/Comment.php index d813d6be..229716de 100644 --- a/Web/Models/Entities/Comment.php +++ b/Web/Models/Entities/Comment.php @@ -90,4 +90,17 @@ class Comment extends Post { return "/wall" . $this->getTarget()->getPrettyId() . "#_comment" . $this->getId(); } + + function toNotifApiStruct() + { + $res = (object)[]; + + $res->id = $this->getId(); + $res->owner_id = $this->getOwner()->getId(); + $res->date = $this->getPublicationTime()->timestamp(); + $res->text = $this->getText(false); + $res->post = NULL; # todo + + return $res; + } } diff --git a/Web/Models/Entities/Note.php b/Web/Models/Entities/Note.php index 83082bf3..bdc34307 100644 --- a/Web/Models/Entities/Note.php +++ b/Web/Models/Entities/Note.php @@ -131,7 +131,7 @@ class Note extends Postable $res->date = $this->getPublicationTime()->timestamp(); $res->comments = $this->getCommentsCount(); $res->read_comments = $this->getCommentsCount(); - $res->view_url = "/note".$this->getOwner()->getId()."_".$this->getId(); + $res->view_url = "/note".$this->getOwner()->getId()."_".$this->getVirtualId(); $res->privacy_view = 1; $res->can_comment = 1; $res->text_wiki = "r"; diff --git a/Web/Models/Entities/Notifications/Notification.php b/Web/Models/Entities/Notifications/Notification.php index cad6e74b..8d7ab873 100644 --- a/Web/Models/Entities/Notifications/Notification.php +++ b/Web/Models/Entities/Notifications/Notification.php @@ -132,4 +132,138 @@ QUERY; return true; } + + function getVkApiInfo() + { + $origin_m = $this->encodeType($this->originModel); + $target_m = $this->encodeType($this->targetModel); + + $info = [ + "type" => "", + "parent" => NULL, + "feedback" => NULL, + ]; + + switch($this->getActionCode()) { + case 0: + $info["type"] = "like_post"; + $info["parent"] = $this->getModel(0)->toNotifApiStruct(); + $info["feedback"] = $this->getModel(1)->toVkApiStruct(); + break; + case 1: + $info["type"] = "copy_post"; + $info["parent"] = $this->getModel(0)->toNotifApiStruct(); + $info["feedback"] = NULL; # todo + break; + case 2: + switch($origin_m) { + case 19: + $info["type"] = "comment_video"; + $info["parent"] = $this->getModel(0)->toNotifApiStruct(); + $info["feedback"] = NULL; # айди коммента не сохраняется в бд( ну пиздец блять + break; + case 13: + $info["type"] = "comment_photo"; + $info["parent"] = $this->getModel(0)->toNotifApiStruct(); + $info["feedback"] = NULL; + break; + # unstandart (vk forgor about notes) + case 10: + $info["type"] = "comment_note"; + $info["parent"] = $this->getModel(0)->toVkApiStruct(); + $info["feedback"] = NULL; + break; + case 14: + $info["type"] = "comment_post"; + $info["parent"] = $this->getModel(0)->toNotifApiStruct(); + $info["feedback"] = NULL; + break; + # unused (users don't have topics bruh) + case 21: + $info["type"] = "comment_topic"; + $info["parent"] = $this->getModel(0)->toVkApiStruct(0, 90); + break; + default: + $info["type"] = "comment_unknown"; + break; + } + + break; + case 3: + $info["type"] = "wall"; + $info["feedback"] = $this->getModel(0)->toNotifApiStruct(); + break; + case 4: + switch($target_m) { + case 14: + $info["type"] = "mention"; + $info["feedback"] = $this->getModel(1)->toNotifApiStruct(); + break; + case 19: + $info["type"] = "mention_comment_video"; + $info["parent"] = $this->getModel(1)->toNotifApiStruct(); + break; + case 13: + $info["type"] = "mention_comment_photo"; + $info["parent"] = $this->getModel(1)->toNotifApiStruct(); + break; + # unstandart + case 10: + $info["type"] = "mention_comment_note"; + $info["parent"] = $this->getModel(1)->toVkApiStruct(); + break; + case 21: + $info["type"] = "mention_comments"; + break; + default: + $info["type"] = "mention_comment_unknown"; + break; + } + break; + case 5: + $info["type"] = "make_you_admin"; + $info["parent"] = $this->getModel(0)->toVkApiStruct($this->getModel(1)); + break; + # Нужно доделать после мержа #935 + case 6: + $info["type"] = "wall_publish"; + break; + # В вк не было такого уведомления, так что unstandart + case 7: + $info["type"] = "new_posts_in_club"; + break; + # В вк при передаче подарков приходит сообщение, а не уведомление, так что unstandart + case 9601: + $info["type"] = "sent_gift"; + $info["parent"] = $this->getModel(1)->toVkApiStruct($this->getModel(1)); + break; + case 9602: + $info["type"] = "voices_transfer"; + $info["parent"] = $this->getModel(1)->toVkApiStruct($this->getModel(1)); + break; + case 9603: + $info["type"] = "up_rating"; + $info["parent"] = $this->getModel(1)->toVkApiStruct($this->getModel(1)); + $info["parent"]->count = $this->getData(); + break; + default: + $info["type"] = NULL; + break; + } + + return $info; + } + + function toVkApiStruct() + { + $res = (object)[]; + + $info = $this->getVkApiInfo(); + $res->type = $info["type"]; + $res->date = $this->getDateTime()->timestamp(); + $res->parent = $info["parent"]; + $res->feedback = $info["feedback"]; + $res->reply = NULL; # Ответы на комментарии не реализованы + return $res; + } } diff --git a/Web/Models/Entities/Photo.php b/Web/Models/Entities/Photo.php index c1825b3a..72d371ad 100644 --- a/Web/Models/Entities/Photo.php +++ b/Web/Models/Entities/Photo.php @@ -347,4 +347,20 @@ class Photo extends Media return $photo; } + + function toNotifApiStruct() + { + $res = (object)[]; + + $res->id = $this->getVirtualId(); + $res->owner_id = $this->getOwner()->getId(); + $res->aid = 0; + $res->src = $this->getURLBySizeId("tiny"); + $res->src_big = $this->getURLBySizeId("normal"); + $res->src_small = $this->getURLBySizeId("miniscule"); + $res->text = $this->getDescription(); + $res->created = $this->getPublicationTime()->timestamp(); + + return $res; + } } diff --git a/Web/Models/Entities/Post.php b/Web/Models/Entities/Post.php index 42941901..fd6b7346 100644 --- a/Web/Models/Entities/Post.php +++ b/Web/Models/Entities/Post.php @@ -245,6 +245,23 @@ class Post extends Postable $this->unwire(); $this->save(); } + + function toNotifApiStruct() + { + $res = (object)[]; + + $res->id = $this->getVirtualId(); + $res->to_id = $this->getOwner() instanceof Club ? $this->getOwner()->getId() * -1 : $this->getOwner()->getId(); + $res->from_id = $res->to_id; + $res->date = $this->getPublicationTime()->timestamp(); + $res->text = $this->getText(false); + $res->attachments = []; # todo + + $res->copy_owner_id = NULL; # todo + $res->copy_post_id = NULL; # todo + + return $res; + } use Traits\TRichText; } diff --git a/Web/Models/Entities/Video.php b/Web/Models/Entities/Video.php index cef48e27..2e56414c 100644 --- a/Web/Models/Entities/Video.php +++ b/Web/Models/Entities/Video.php @@ -219,4 +219,23 @@ class Video extends Media return $video; } + + function toNotifApiStruct() + { + $fromYoutube = $this->getType() == Video::TYPE_EMBED; + $res = (object)[]; + + $res->id = $this->getVirtualId(); + $res->owner_id = $this->getOwner()->getId(); + $res->title = $this->getName(); + $res->description = $this->getDescription(); + $res->duration = "22"; + $res->link = "/video".$this->getOwner()->getId()."_".$this->getVirtualId(); + $res->image = $this->getThumbnailURL(); + $res->date = $this->getPublicationTime()->timestamp(); + $res->views = 0; + $res->player = !$fromYoutube ? $this->getURL() : $this->getVideoDriver()->getURL(); + + return $res; + } }