From a1ec1ca24134a6ffd441159d902ee730a44017e9 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sat, 27 May 2023 22:15:16 +0300 Subject: [PATCH] VKAPI: Some methods for topics and photos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлены методы для обсуждений (addTopic, closeTopic(), createComment(), deleteComment(), deleteTopic(), editTopic(), fixTopic(), getComments(), getTopics(), openTopic(), unfixTopic()) и для фотографий (createAlbum(), editAlbum(), getAlbums(), getAlbumsCount(), getById(), get(), deleteAlbum(), edit(), delete(), deleteComment(), createComment(), getAll(), getComments()) --- VKAPI/Handlers/Board.php | 422 ++++++++++++++++++++++++ VKAPI/Handlers/Notes.php | 6 +- VKAPI/Handlers/Photos.php | 501 ++++++++++++++++++++++++++++- Web/Models/Entities/Album.php | 27 ++ Web/Models/Entities/Comment.php | 26 ++ Web/Models/Entities/Photo.php | 30 +- Web/Models/Entities/User.php | 17 + Web/Models/Repositories/Albums.php | 10 + Web/Models/Repositories/Photos.php | 13 +- 9 files changed, 1038 insertions(+), 14 deletions(-) create mode 100644 VKAPI/Handlers/Board.php diff --git a/VKAPI/Handlers/Board.php b/VKAPI/Handlers/Board.php new file mode 100644 index 00000000..5bd72d45 --- /dev/null +++ b/VKAPI/Handlers/Board.php @@ -0,0 +1,422 @@ +requireUser(); + $this->willExecuteWriteAction(); + + $club = (new ClubsRepo)->get($group_id); + + if(!$club) { + $this->fail(403, "Invalid club"); + } + + if(!$club->canBeModifiedBy($this->getUser())) { + $this->fail(403, "Access to club denied"); + } + + $flags = 0; + + if($from_group == true && $club->canBeModifiedBy($this->getUser())) + $flags |= 0b10000000; + + $topic = new Topic; + $topic->setGroup($club->getId()); + $topic->setOwner($this->getUser()->getId()); + $topic->setTitle(ovk_proc_strtr($title, 127)); + $topic->setCreated(time()); + $topic->setFlags($flags); + $topic->save(); + + if(!empty($text)) { + $comment = new Comment; + $comment->setOwner($this->getUser()->getId()); + $comment->setModel(get_class($topic)); + $comment->setTarget($topic->getId()); + $comment->setContent($text); + $comment->setCreated(time()); + $comment->setFlags($flags); + $comment->save(); + + if(!empty($attachments)) { + $attachmentsArr = explode(",", $attachments); + # блин а мне это везде копировать типа + + if(sizeof($attachmentsArr) > 10) + $this->fail(50, "Error: too many attachments"); + + foreach($attachmentsArr as $attac) { + $attachmentType = NULL; + + if(str_contains($attac, "photo")) + $attachmentType = "photo"; + elseif(str_contains($attac, "video")) + $attachmentType = "video"; + else + $this->fail(205, "Unknown attachment type"); + + $attachment = str_replace($attachmentType, "", $attac); + + $attachmentOwner = (int)explode("_", $attachment)[0]; + $attachmentId = (int)end(explode("_", $attachment)); + + $attacc = NULL; + + if($attachmentType == "photo") { + $attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); + if(!$attacc || $attacc->isDeleted()) + $this->fail(100, "Photo does not exists"); + if($attacc->getOwner()->getId() != $this->getUser()->getId()) + $this->fail(43, "You do not have access to this photo"); + + $comment->attach($attacc); + } elseif($attachmentType == "video") { + $attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); + if(!$attacc || $attacc->isDeleted()) + $this->fail(100, "Video does not exists"); + if($attacc->getOwner()->getId() != $this->getUser()->getId()) + $this->fail(43, "You do not have access to this video"); + + $comment->attach($attacc); + } + + } + + } + + } + + return $topic->getId(); + } + + function closeTopic(int $group_id, int $topic_id) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $topic = (new TopicsRepo)->getTopicById($group_id, $topic_id); + + if(!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) { + return 0; + } + + $topic->setClosed(1); + + $topic->save(); + + return 1; + } + + function createComment(int $group_id, int $topic_id, string $message = "", string $attachments = "", bool $from_group = true) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + if(empty($message) && empty($attachments)) { + $this->fail(100, "Required parameter 'message' missing."); + } + + $topic = (new TopicsRepo)->getTopicById($group_id, $topic_id); + + if(!$topic || $topic->isDeleted() || $topic->isClosed()) { + $this->fail(100, "Topic is deleted, closed or invalid."); + } + + $flags = 0; + + if($from_group != 0 && !is_null($topic->getClub()) && $topic->getClub()->canBeModifiedBy($this->user)) + $flags |= 0b10000000; + + if(strlen($message) > 300) { + $this->fail(20, "Comment is too long."); + } + + $comment = new Comment; + $comment->setOwner($this->getUser()->getId()); + $comment->setModel(get_class($topic)); + $comment->setTarget($topic->getId()); + $comment->setContent($message); + $comment->setCreated(time()); + $comment->setFlags($flags); + $comment->save(); + + if(!empty($attachments)) { + $attachmentsArr = explode(",", $attachments); + + if(sizeof($attachmentsArr) > 10) + $this->fail(50, "Error: too many attachments"); + + foreach($attachmentsArr as $attac) { + $attachmentType = NULL; + + if(str_contains($attac, "photo")) + $attachmentType = "photo"; + elseif(str_contains($attac, "video")) + $attachmentType = "video"; + else + $this->fail(205, "Unknown attachment type"); + + $attachment = str_replace($attachmentType, "", $attac); + + $attachmentOwner = (int)explode("_", $attachment)[0]; + $attachmentId = (int)end(explode("_", $attachment)); + + $attacc = NULL; + + if($attachmentType == "photo") { + $attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); + if(!$attacc || $attacc->isDeleted()) + $this->fail(100, "Photo does not exists"); + if($attacc->getOwner()->getId() != $this->getUser()->getId()) + $this->fail(43, "You do not have access to this photo"); + + $comment->attach($attacc); + } elseif($attachmentType == "video") { + $attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); + if(!$attacc || $attacc->isDeleted()) + $this->fail(100, "Video does not exists"); + if($attacc->getOwner()->getId() != $this->getUser()->getId()) + $this->fail(43, "You do not have access to this video"); + + $comment->attach($attacc); + } + } + } + + return $comment->getId(); + } + + function deleteComment(int $comment_id, int $group_id = 0, int $topic_id = 0) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $comment = (new CommentsRepo)->get($comment_id); + + if($comment->isDeleted() || !$comment || !$comment->canBeDeletedBy($this->getUser())) + $this->fail(403, "Access to comment denied"); + + $comment->delete(); + + return 1; + } + + function deleteTopic(int $group_id, int $topic_id) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $topic = (new TopicsRepo)->getTopicById($group_id, $topic_id); + + if(!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) { + return 0; + } + + $topic->deleteTopic(); + + return 1; + } + + function editComment(int $comment_id, int $group_id = 0, int $topic_id = 0, string $message, string $attachments) + { + /* + $this->requireUser(); + $this->willExecuteWriteAction(); + + $comment = (new CommentsRepo)->get($comment_id); + + if($comment->getOwner() != $this->getUser()->getId()) + $this->fail(15, "Access to comment denied"); + + $comment->setContent($message); + $comment->setEdited(time()); + $comment->save(); + */ + return 1; + } + + function editTopic(int $group_id, int $topic_id, string $title) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $topic = (new TopicsRepo)->getTopicById($group_id, $topic_id); + + if(!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) { + return 0; + } + + $topic->setTitle(ovk_proc_strtr($title, 127)); + + $topic->save(); + + return 1; + } + + function fixTopic(int $group_id, int $topic_id) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $topic = (new TopicsRepo)->getTopicById($group_id, $topic_id); + + if(!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) { + return 0; + } + + $topic->setPinned(1); + + $topic->save(); + + return 1; + } + + function getComments(int $group_id, int $topic_id, bool $need_likes = false, int $start_comment_id = 0, int $offset = 0, int $count = 40, bool $extended = false, string $sort = "asc") + { + # start_comment_id ne robit + $this->requireUser(); + $this->willExecuteWriteAction(); + + $topic = (new TopicsRepo)->getTopicById($group_id, $topic_id); + + if(!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) { + $this->fail(5, "Invalid topic"); + } + + $arr = [ + "items" => [] + ]; + $comms = array_slice(iterator_to_array($topic->getComments(1, $count + $offset)), $offset); + foreach($comms as $comm) { + $arr["items"][] = $this->getApiBoardComment($comm, $need_likes); + + if($extended) { + if($comm->getOwner() instanceof \openvk\Web\Models\Entities\User) { + $arr["profiles"][] = $comm->getOwner()->toVkApiStruct(); + } + } + } + + return $arr; + } + + function getTopics(int $group_id, string $topic_ids = "", int $order = 1, int $offset = 0, int $count = 40, bool $extended = false, int $preview = 0, int $preview_length = 90) + { + # order и extended ничё не делают + $this->requireUser(); + $this->willExecuteWriteAction(); + + $arr = []; + $club = (new ClubsRepo)->get($group_id); + $topics = array_slice(iterator_to_array((new TopicsRepo)->getClubTopics($club, 1, $count + $offset)), $offset); + $arr["count"] = (new TopicsRepo)->getClubTopicsCount($club); + $arr["items"] = []; + $arr["default_order"] = $order; + $arr["can_add_topics"] = $club->canBeModifiedBy($this->getUser()) ? true : $club->isEveryoneCanCreateTopics() ? true : false; + $arr["profiles"] = []; + + if(empty($topic_ids)) { + foreach($topics as $topic) { + if($topic->isDeleted()) continue; + $arr["items"][] = $topic->toVkApiStruct($preview, $preview_length); + } + } else { + $topics = explode(',', $topic_ids); + + foreach($topics as $topic) + { + $id = explode("_", $topic); + $topicy = (new TopicsRepo)->getTopicById((int)$id[0], (int)$id[1]); + if($topicy) { + $arr["items"] = $topicy->toVkApiStruct(); + } + } + } + + return $arr; + } + + function openTopic(int $group_id, int $topic_id) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $topic = (new TopicsRepo)->getTopicById($group_id, $topic_id); + + if(!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) { + return 0; + } + + $topic->setClosed(0); + + $topic->save(); + + return 1; + } + + function restoreComment(int $group_id, int $topic_id, int $comment_id) + { + $this->fail(4, "Not implemented"); + } + + function unfixTopic(int $group_id, int $topic_id) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $topic = (new TopicsRepo)->getTopicById($group_id, $topic_id); + + if(!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) { + return 0; + } + + $topic->setPinned(0); + + $topic->save(); + + return 1; + } + + private function getApiBoardComment($comment, bool $need_likes = false) + { + $res = (object) []; + + $res->id = $comment->getId(); + $res->from_id = $comment->getOwner()->getId(); + $res->date = $comment->getPublicationTime()->timestamp(); + $res->text = $comment->getText(); + $res->attachments = []; + $res->likes = []; + if($need_likes) { + $res->likes = [ + "count" => $comment->getLikesCount(), + "user_likes" => (int) $comment->hasLikeFrom($this->getUser()), + "can_like" => 1 # а чё типо не может ахахаххахах + ]; + } + + foreach($comment->getChildren() as $attachment) { + if($attachment instanceof \openvk\Web\Models\Entities\Photo) { + if($attachment->isDeleted()) + continue; + + $res->attachments[] = $attachment->toVkApiStruct(); + } else if($$attachment instanceof \openvk\Web\Models\Entities\Video) { + $res->attachments[] = $attachment->getApiStructure(); + } + } + + return $res; + } +} \ No newline at end of file diff --git a/VKAPI/Handlers/Notes.php b/VKAPI/Handlers/Notes.php index 266ec99b..5635e39b 100644 --- a/VKAPI/Handlers/Notes.php +++ b/VKAPI/Handlers/Notes.php @@ -104,6 +104,7 @@ final class Notes extends VKAPIRequestHandler function editComment(int $comment_id, string $message, int $owner_id = NULL) { + /* $this->requireUser(); $this->willExecuteWriteAction(); @@ -115,7 +116,8 @@ final class Notes extends VKAPIRequestHandler $comment->setContent($message); $comment->setEdited(time()); $comment->save(); - + */ + return 1; } @@ -128,7 +130,7 @@ final class Notes extends VKAPIRequestHandler $this->fail(15, "Invalid user"); if(empty($note_ids)) { - $notes = array_slice(iterator_to_array((new NotesRepo)->getUserNotes($user, 1, $count, $sort == 0 ? "ASC" : "DESC")), $offset); + $notes = array_slice(iterator_to_array((new NotesRepo)->getUserNotes($user, 1, $count + $offset, $sort == 0 ? "ASC" : "DESC")), $offset); $nodez = (object) [ "count" => (new NotesRepo)->getUserNotesCount((new UsersRepo)->get($user_id)), "notes" => [] diff --git a/VKAPI/Handlers/Photos.php b/VKAPI/Handlers/Photos.php index 9a02dd8c..f46f9157 100644 --- a/VKAPI/Handlers/Photos.php +++ b/VKAPI/Handlers/Photos.php @@ -3,9 +3,12 @@ namespace openvk\VKAPI\Handlers; use Nette\InvalidStateException; use Nette\Utils\ImageException; -use openvk\Web\Models\Entities\Photo; +use openvk\Web\Models\Entities\{Photo, Album, Comment}; use openvk\Web\Models\Repositories\Albums; +use openvk\Web\Models\Repositories\Photos as PhotosRepo; use openvk\Web\Models\Repositories\Clubs; +use openvk\Web\Models\Repositories\Users as UsersRepo; +use openvk\Web\Models\Repositories\Comments as CommentsRepo; final class Photos extends VKAPIRequestHandler { @@ -227,4 +230,500 @@ final class Photos extends VKAPIRequestHandler "items" => $images, ]; } + + function createAlbum(string $title, int $group_id = 0, string $description = "", int $privacy = 0) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + if($group_id != 0) { + $club = (new Clubs)->get((int) $group_id); + + if(!$club || !$club->canBeModifiedBy($this->getUser())) { + $this->fail(20, "Invalid club"); + } + } + + $album = new Album; + $album->setOwner(isset($club) ? $club->getId() * -1 : $this->getUser()->getId()); + $album->setName($title); + $album->setDescription($description); + $album->setCreated(time()); + $album->save(); + + return $album->toVkApiStruct($this->getUser()); + } + + function editAlbum(int $album_id, int $owner_id, string $title, string $description = "", int $privacy = 0) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $album = (new Albums)->getAlbumByOwnerAndId($owner_id, $album_id); + + if(!$album || $album->isDeleted()) { + $this->fail(2, "Invalid album"); + } + + if(empty($title)) { + $this->fail(25, "Title is empty"); + } + + if($album->isCreatedBySystem()) { + $this->fail(40, "You can't change system album"); + } + + if(!$album->canBeModifiedBy($this->getUser())) { + $this->fail(2, "Access to album denied"); + } + + $album->setName($title); + $album->setDescription($description); + + $album->save(); + + return $album->toVkApiStruct($this->getUser()); + } + + function getAlbums(int $owner_id, string $album_ids = "", int $offset = 0, int $count = 100, bool $need_system = true, bool $need_covers = true, bool $photo_sizes = false) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $res = []; + + if(empty($album_ids)) { + if($owner_id > 0) { + $user = (new UsersRepo)->get($owner_id); + + $res = [ + "count" => (new Albums)->getUserAlbumsCount($user), + "items" => [] + ]; + + if(!$user || $user->isDeleted()) + $this->fail(2, "Invalid user"); + + + if(!$user->getPrivacyPermission('photos.read', $this->getUser())) + $this->fail(21, "This user chose to hide his albums."); + + $albums = array_slice(iterator_to_array((new Albums)->getUserAlbums($user, 1, $count + $offset)), $offset); + + foreach($albums as $album) { + if(!$need_system && $album->isCreatedBySystem()) continue; + $res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes); + } + } + + else { + $club = (new Clubs)->get($owner_id * -1); + + $res = [ + "count" => (new Albums)->getClubAlbumsCount($club), + "items" => [] + ]; + + if(!$club) + $this->fail(2, "Invalid club"); + + $albums = array_slice(iterator_to_array((new Albums)->getClubAlbums($club, 1, $count + $offset)), $offset); + + foreach($albums as $album) { + if(!$need_system && $album->isCreatedBySystem()) continue; + $res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes); + } + } + + } else { + $albums = explode(',', $album_ids); + + $res = [ + "count" => sizeof($albums), + "items" => [] + ]; + + foreach($albums as $album) + { + $id = explode("_", $album); + + $album = (new Albums)->getAlbumByOwnerAndId((int)$id[0], (int)$id[1]); + if($album && !$album->isDeleted()) { + if(!$need_system && $album->isCreatedBySystem()) continue; + $res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes); + } + } + } + + return $res; + } + + function getAlbumsCount(int $user_id = 0, int $group_id = 0) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + if($user_id == 0 && $group_id == 0 || $user_id > 0 && $group_id > 0) { + $this->fail(21, "Select user_id or group_id"); + } + + if($user_id > 0) { + + $us = (new UsersRepo)->get($user_id); + if(!$us || $us->isDeleted()) { + $this->fail(21, "Invalid user"); + } + + if(!$us->getPrivacyPermission('photos.read', $this->getUser())) { + $this->fail(21, "This user chose to hide his albums."); + } + + return (new Albums)->getUserAlbumsCount($us); + } + + if($group_id > 0) + { + $cl = (new Clubs)->get($group_id); + if(!$cl) { + $this->fail(21, "Invalid club"); + } + + return (new Albums)->getClubAlbumsCount($cl); + } + } + + function getById(string $photos, bool $extended = false, bool $photo_sizes = false) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $phts = explode(",", $photos); + $res = []; + + foreach($phts as $phota) { + $ph = explode("_", $phota); + $photo = (new PhotosRepo)->getByOwnerAndVID((int)$ph[0], (int)$ph[1]); + + if(!$photo || $photo->isDeleted()) { + $this->fail(21, "Invalid photo"); + } + + if(!$photo->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) { + $this->fail(21, "This user chose to hide his photos."); + } + + $res[] = $photo->toVkApiStruct($photo_sizes, $extended); + } + + return $res; + } + + function get(int $owner_id, int $album_id, string $photo_ids = "", bool $extended = false, bool $photo_sizes = false, int $offset = 0, int $count = 10) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $res = []; + + if(empty($photo_ids)) { + $album = (new Albums)->getAlbumByOwnerAndId($owner_id, $album_id); + + if(!$album->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) { + $this->fail(21, "This user chose to hide his albums."); + } + + if(!$album || $album->isDeleted()) { + $this->fail(21, "Invalid album"); + } + + $photos = array_slice(iterator_to_array($album->getPhotos(1, $count + $offset)), $offset); + $res["count"] = sizeof($photos); + + foreach($photos as $photo) { + if(!$photo || $photo->isDeleted()) continue; + $res["items"][] = $photo->toVkApiStruct($photo_sizes, $extended); + } + + } else { + $photos = explode(',', $photo_ids); + + $res = [ + "count" => sizeof($photos), + "items" => [] + ]; + + foreach($photos as $photo) + { + $id = explode("_", $photo); + + $phot = (new PhotosRepo)->getByOwnerAndVID((int)$id[0], (int)$id[1]); + if($phot && !$phot->isDeleted()) { + $res["items"][] = $phot->toVkApiStruct($photo_sizes, $extended); + } + } + } + + return $res; + } + + function deleteAlbum(int $album_id, int $group_id = 0) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $album = (new Albums)->get($album_id); + + if(!$album || $album->canBeModifiedBy($this->getUser())) { + $this->fail(21, "Invalid album"); + } + + if($album->isDeleted()) { + $this->fail(22, "Album already deleted"); + } + + $album->delete(); + + return 1; + } + + function edit(int $owner_id, int $photo_id, string $caption = "") + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); + + if(!$photo) { + $this->fail(21, "Invalid photo"); + } + + if($photo->isDeleted()) { + $this->fail(21, "Photo is deleted"); + } + + if(!empty($caption)) { + $photo->setDescription($caption); + $photo->save(); + } + + return 1; + } + + function delete(int $owner_id, int $photo_id, string $photos = "") + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + if(empty($photos)) { + $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); + + if($this->getUser()->getId() !== $photo->getOwner()->getId()) { + $this->fail(21, "You can't delete another's photo"); + } + + if(!$photo) { + $this->fail(21, "Invalid photo"); + } + + if($photo->isDeleted()) { + $this->fail(21, "Photo already deleted"); + } + + $photo->delete(); + } else { + $photozs = explode(',', $photos); + + foreach($photozs as $photo) + { + $id = explode("_", $photo); + + $phot = (new PhotosRepo)->getByOwnerAndVID((int)$id[0], (int)$id[1]); + + if($this->getUser()->getId() !== $phot->getOwner()->getId()) { + $this->fail(21, "You can't delete another's photo"); + } + + if(!$phot) { + $this->fail(21, "Invalid photo"); + } + + if($phot->isDeleted()) { + $this->fail(21, "Photo already deleted"); + } + + $phot->delete(); + } + } + + return 1; + } + + function getAllComments(int $owner_id, int $album_id, bool $need_likes = false, int $offset = 0, int $count = 100) + { + $this->fail(10, "Not implemented :D"); + } + + function deleteComment(int $comment_id, int $owner_id = 0) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $comment = (new CommentsRepo)->get($comment_id); + if(!$comment) { + $this->fail(21, "Invalid comment"); + } + + if(!$comment->canBeModifiedBy($this->getUser())) { + $this->fail(21, "Forbidden"); + } + + if($comment->isDeleted()) { + $this->fail(4, "Comment already deleted"); + } + + $comment->delete(); + + return 1; + } + + function createComment(int $owner_id, int $photo_id, string $message = "", string $attachments = "", bool $from_group = false) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + if(empty($message) && empty($attachments)) { + $this->fail(100, "Required parameter 'message' missing."); + } + + $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); + + if(!$photo->getAlbum()->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) { + $this->fail(21, "This user chose to hide his albums."); + } + + if(!$photo) + $this->fail(180, "Photo not found"); + if($photo->isDeleted()) + $this->fail(189, "Photo is deleted"); + + $comment = new Comment; + $comment->setOwner($this->getUser()->getId()); + $comment->setModel(get_class($photo)); + $comment->setTarget($photo->getId()); + $comment->setContent($message); + $comment->setCreated(time()); + $comment->save(); + + if(!empty($attachments)) { + $attachmentsArr = explode(",", $attachments); + + if(sizeof($attachmentsArr) > 10) + $this->fail(50, "Error: too many attachments"); + + foreach($attachmentsArr as $attac) { + $attachmentType = NULL; + + if(str_contains($attac, "photo")) + $attachmentType = "photo"; + elseif(str_contains($attac, "video")) + $attachmentType = "video"; + else + $this->fail(205, "Unknown attachment type"); + + $attachment = str_replace($attachmentType, "", $attac); + + $attachmentOwner = (int)explode("_", $attachment)[0]; + $attachmentId = (int)end(explode("_", $attachment)); + + $attacc = NULL; + + if($attachmentType == "photo") { + $attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); + if(!$attacc || $attacc->isDeleted()) + $this->fail(100, "Photo does not exists"); + if($attacc->getOwner()->getId() != $this->getUser()->getId()) + $this->fail(43, "You do not have access to this photo"); + + $comment->attach($attacc); + } elseif($attachmentType == "video") { + $attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); + if(!$attacc || $attacc->isDeleted()) + $this->fail(100, "Video does not exists"); + if($attacc->getOwner()->getId() != $this->getUser()->getId()) + $this->fail(43, "You do not have access to this video"); + + $comment->attach($attacc); + } + } + } + + return $comment->getId(); + } + + function getAll(int $owner_id, bool $extended = false, int $offset = 0, int $count = 100, bool $photo_sizes = false) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + if($owner_id < 0) { + $this->fail(4, "This method doesn't works with clubs"); + } + + $user = (new UsersRepo)->get($owner_id); + + if(!$user) { + $this->fail(4, "Invalid user"); + } + + if(!$user->getPrivacyPermission('photos.read', $this->getUser())) { + $this->fail(21, "This user chose to hide his albums."); + } + + $photos = array_slice(iterator_to_array((new PhotosRepo)->getEveryUserPhoto($user, 1, $count + $offset)), $offset); + $res = []; + + foreach($photos as $photo) { + if(!$photo || $photo->isDeleted()) continue; + $res["items"][] = $photo->toVkApiStruct($photo_sizes, $extended); + } + + return $res; + } + + function getComments(int $owner_id, int $photo_id, bool $need_likes = false, int $offset = 0, int $count = 100, bool $extended = false, string $fields = "") + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); + $comms = array_slice(iterator_to_array($photo->getComments(1, $offset + $count)), $offset); + + if(!$photo) { + $this->fail(4, "Invalid photo"); + } + + if(!$photo->getAlbum()->getOwner()->getPrivacyPermission('photos.read', $this->getUser())) { + $this->fail(21, "This user chose to hide his photos."); + } + + if($photo->isDeleted()) { + $this->fail(4, "Photo is deleted"); + } + + $res = [ + "count" => sizeof($comms), + "items" => [] + ]; + + foreach($comms as $comment) { + $res["items"][] = $comment->toVkApiStruct($this->getUser(), $need_likes, $extended); + if($extended) { + if($comment->getOwner() instanceof \openvk\Web\Models\Entities\User) { + $res["profiles"][] = $comment->getOwner()->toVkApiStruct(); + } + } + } + + return $res; + } } \ No newline at end of file diff --git a/Web/Models/Entities/Album.php b/Web/Models/Entities/Album.php index b20f0388..150cc625 100644 --- a/Web/Models/Entities/Album.php +++ b/Web/Models/Entities/Album.php @@ -66,4 +66,31 @@ class Album extends MediaCollection { return $this->has($photo); } + + function toVkApiStruct(?User $user = NULL, bool $need_covers = false, bool $photo_sizes = false): object + { + $res = (object) []; + + $res->id = $this->getPrettyId(); + $res->thumb_id = !is_null($this->getCoverPhoto()) ? $this->getCoverPhoto()->getPrettyId() : 0; + $res->owner_id = $this->getOwner()->getId(); + $res->title = $this->getName(); + $res->description = $this->getDescription(); + $res->created = $this->getCreationTime()->timestamp(); + $res->updated = $this->getEditTime() ? $this->getEditTime()->timestamp() : NULL; + $res->size = $this->size(); + $res->privacy_comment = 1; + $res->upload_by_admins_only = 1; + $res->comments_disabled = 0; + $res->can_upload = $this->canBeModifiedBy($user); # thisUser недоступен в entities + if($need_covers) { + $res->thumb_src = $this->getCoverURL(); + + if($photo_sizes) { + $res->sizes = !is_null($this->getCoverPhoto()) ? $this->getCoverPhoto()->getVkApiSizes() : NULL; + } + } + + return $res; + } } diff --git a/Web/Models/Entities/Comment.php b/Web/Models/Entities/Comment.php index 9115ad3e..ddcffc53 100644 --- a/Web/Models/Entities/Comment.php +++ b/Web/Models/Entities/Comment.php @@ -52,4 +52,30 @@ class Comment extends Post $this->getTarget() instanceof Post && $this->getTarget()->getTargetWall() < 0 && (new Clubs)->get(abs($this->getTarget()->getTargetWall()))->canBeModifiedBy($user) || $this->getTarget() instanceof Topic && $this->getTarget()->canBeModifiedBy($user); } + + function toVkApiStruct(?User $user = NULL, bool $need_likes = false, bool $extended = false): object + { + $res = (object) []; + + $res->id = $this->getId(); + $res->from_id = $this->getOwner()->getId(); + $res->date = $this->getPublicationTime()->timestamp(); + $res->text = $this->getText(); + $res->attachments = []; + $res->parents_stack = []; + + foreach($this->getChildren() as $attachment) { + if($attachment->isDeleted()) + continue; + + $res->attachments[] = $attachment->toVkApiStruct(); + } + + if($need_likes) { + $res->count = $this->getLikesCount(); + $res->user_likes = (int)$this->hasLikeFrom($user); + $res->can_like = 1; + } + return $res; + } } diff --git a/Web/Models/Entities/Photo.php b/Web/Models/Entities/Photo.php index 3c4db886..29526daa 100644 --- a/Web/Models/Entities/Photo.php +++ b/Web/Models/Entities/Photo.php @@ -296,25 +296,35 @@ class Photo extends Media return (new Albums)->getAlbumByPhotoId($this); } - function toVkApiStruct(): object + function toVkApiStruct(bool $photo_sizes = true, bool $extended = false): object { $res = (object) []; $res->id = $res->pid = $this->getId(); - $res->owner_id = $res->user_id = $this->getOwner()->getId()->getId(); + $res->owner_id = $res->user_id = $this->getOwner()->getId(); $res->aid = $res->album_id = NULL; $res->width = $this->getDimensions()[0]; $res->height = $this->getDimensions()[1]; $res->date = $res->created = $this->getPublicationTime()->timestamp(); - $res->sizes = $this->getVkApiSizes(); - $res->src_small = $res->photo_75 = $this->getURLBySizeId("miniscule"); - $res->src = $res->photo_130 = $this->getURLBySizeId("tiny"); - $res->src_big = $res->photo_604 = $this->getURLBySizeId("normal"); - $res->src_xbig = $res->photo_807 = $this->getURLBySizeId("large"); - $res->src_xxbig = $res->photo_1280 = $this->getURLBySizeId("larger"); - $res->src_xxxbig = $res->photo_2560 = $this->getURLBySizeId("original"); - $res->src_original = $res->url = $this->getURLBySizeId("UPLOADED_MAXRES"); + if($photo_sizes) { + $res->sizes = $this->getVkApiSizes(); + $res->src_small = $res->photo_75 = $this->getURLBySizeId("miniscule"); + $res->src = $res->photo_130 = $this->getURLBySizeId("tiny"); + $res->src_big = $res->photo_604 = $this->getURLBySizeId("normal"); + $res->src_xbig = $res->photo_807 = $this->getURLBySizeId("large"); + $res->src_xxbig = $res->photo_1280 = $this->getURLBySizeId("larger"); + $res->src_xxxbig = $res->photo_2560 = $this->getURLBySizeId("original"); + $res->src_original = $res->url = $this->getURLBySizeId("UPLOADED_MAXRES"); + } + + if($extended) { + $res->likes = $this->getLikesCount(); # их нету но пусть будут + $res->comments = $this->getCommentsCount(); + $res->tags = 0; + $res->can_comment = 1; + $res->can_repost = 0; + } return $res; } diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php index ed1e3e60..348631e4 100644 --- a/Web/Models/Entities/User.php +++ b/Web/Models/Entities/User.php @@ -1109,6 +1109,23 @@ class User extends RowModel return true; } + + function toVkApiStruct(): object + { + $res = (object) []; + + $res->id = $this->getId(); + $res->first_name = $this->getFirstName(); + $res->last_name = $this->getLastName(); + $res->deactivated = $this->isDeactivated(); + $res->photo_50 = $this->getAvatarURL(); + $res->photo_100 = $this->getAvatarURL("tiny"); + $res->photo_200 = $this->getAvatarURL("normal"); + $res->photo_id = !is_null($this->getAvatarPhoto()) ? $this->getAvatarPhoto()->getPrettyId() : NULL; + # TODO: Perenesti syuda vsyo ostalnoyie + + return $res; + } use Traits\TBackDrops; use Traits\TSubscribable; diff --git a/Web/Models/Repositories/Albums.php b/Web/Models/Repositories/Albums.php index 99c6c732..b38ee462 100644 --- a/Web/Models/Repositories/Albums.php +++ b/Web/Models/Repositories/Albums.php @@ -123,4 +123,14 @@ class Albums return $dbalbum->collection ? $this->get($dbalbum->collection) : null; } + + function getAlbumByOwnerAndId(int $owner, int $id) + { + $album = $this->albums->where([ + "owner" => $owner, + "id" => $id + ])->fetch(); + + return new Album($album); + } } diff --git a/Web/Models/Repositories/Photos.php b/Web/Models/Repositories/Photos.php index 4ff8a1b9..88c7e804 100644 --- a/Web/Models/Repositories/Photos.php +++ b/Web/Models/Repositories/Photos.php @@ -1,6 +1,6 @@ photos->where([ + "owner" => $user->getId() + ]); + + foreach($photos as $photo) { + yield new Photo($photo); + } + } }