requireUser(); $posts = new PostsRepo; $items = []; $profiles = []; $groups = []; $cnt = 0; if ($owner_id > 0) $wallOnwer = (new UsersRepo)->get($owner_id); else $wallOnwer = (new ClubsRepo)->get($owner_id * -1); if ($owner_id > 0) if(!$wallOnwer || $wallOnwer->isDeleted()) $this->fail(18, "User was deleted or banned"); if(!$wallOnwer->canBeViewedBy($this->getUser())) $this->fail(15, "Access denied"); else if(!$wallOnwer) $this->fail(15, "Access denied: wall is disabled"); // Don't search for logic here pls $iteratorv; switch($filter) { case "all": $iteratorv = $posts->getPostsFromUsersWall($owner_id, 1, $count, $offset); $cnt = $posts->getPostCountOnUserWall($owner_id); break; case "owner": $iteratorv = $posts->getOwnersPostsFromWall($owner_id, 1, $count, $offset); $cnt = $posts->getOwnersCountOnUserWall($owner_id); break; case "others": $iteratorv = $posts->getOthersPostsFromWall($owner_id, 1, $count, $offset); $cnt = $posts->getOthersCountOnUserWall($owner_id); break; case "postponed": $this->fail(42, "Postponed posts are not implemented."); break; case "suggests": if($owner_id < 0) { if($wallOnwer->getWallType() != 2) $this->fail(125, "Group's wall type is open or closed"); if($wallOnwer->canBeModifiedBy($this->getUser())) { $iteratorv = $posts->getSuggestedPosts($owner_id * -1, 1, $count, $offset); $cnt = $posts->getSuggestedPostsCount($owner_id * -1); } else { $iteratorv = $posts->getSuggestedPostsByUser($owner_id * -1, $this->getUser()->getId(), 1, $count, $offset); $cnt = $posts->getSuggestedPostsCountByUser($owner_id * -1, $this->getUser()->getId()); } } else { $this->fail(528, "Suggested posts avaiable only at groups"); } break; default: $this->fail(254, "Invalid filter"); break; } foreach($iteratorv as $post) { $from_id = get_class($post->getOwner()) == "openvk\Web\Models\Entities\Club" ? $post->getOwner()->getId() * (-1) : $post->getOwner()->getId(); $attachments = []; $repost = []; foreach($post->getChildren() as $attachment) { if($attachment instanceof \openvk\Web\Models\Entities\Photo) { if($attachment->isDeleted()) continue; $attachments[] = $this->getApiPhoto($attachment); } else if($attachment instanceof \openvk\Web\Models\Entities\Poll) { $attachments[] = $this->getApiPoll($attachment, $this->getUser()); } else if ($attachment instanceof \openvk\Web\Models\Entities\Video) { $attachments[] = $attachment->getApiStructure($this->getUser()); } else if ($attachment instanceof \openvk\Web\Models\Entities\Note) { if(VKAPI_DECL_VER === '4.100') { $attachments[] = $attachment->toVkApiStruct(); } else { $attachments[] = [ 'type' => 'note', 'note' => $attachment->toVkApiStruct() ]; } } else if ($attachment instanceof \openvk\Web\Models\Entities\Audio) { $attachments[] = [ "type" => "audio", "audio" => $attachment->toVkApiStruct($this->getUser()), ]; } else if ($attachment instanceof \openvk\Web\Models\Entities\Post) { $repostAttachments = []; foreach($attachment->getChildren() as $repostAttachment) { if($repostAttachment instanceof \openvk\Web\Models\Entities\Photo) { if($repostAttachment->isDeleted()) continue; $repostAttachments[] = $this->getApiPhoto($repostAttachment); /* Рекурсии, сука! Заказывали? */ } } if ($attachment->isPostedOnBehalfOfGroup()) $groups[] = $attachment->getOwner()->getId(); else $profiles[] = $attachment->getOwner()->getId(); $repost[] = [ "id" => $attachment->getVirtualId(), "owner_id" => $attachment->isPostedOnBehalfOfGroup() ? $attachment->getOwner()->getId() * -1 : $attachment->getOwner()->getId(), "from_id" => $attachment->isPostedOnBehalfOfGroup() ? $attachment->getOwner()->getId() * -1 : $attachment->getOwner()->getId(), "date" => $attachment->getPublicationTime()->timestamp(), "post_type" => $attachment->getVkApiType(), "text" => $attachment->getText(false), "attachments" => $repostAttachments, "post_source" => $attachment->getPostSourceInfo(), ]; if ($attachment->getTargetWall() > 0) $profiles[] = $attachment->getTargetWall(); else $groups[] = abs($attachment->getTargetWall()); if($post->isSigned()) $profiles[] = $attachment->getOwner()->getId(); } } $signerId = NULL; if($post->isSigned()) { $actualAuthor = $post->getOwner(false); $signerId = $actualAuthor->getId(); } # TODO "can_pin", "copy_history" и прочее не должны возвращаться, если равны null или false # Ну и ещё всё надо перенести в toVkApiStruct, а то слишком много дублированного кода $post_temp_obj = (object)[ "id" => $post->getVirtualId(), "from_id" => $from_id, "owner_id" => $post->getTargetWall(), "date" => $post->getPublicationTime()->timestamp(), "post_type" => $post->getVkApiType(), "text" => $post->getText(false), "copy_history" => $repost, "can_edit" => $post->canBeEditedBy($this->getUser()), "can_delete" => $post->canBeDeletedBy($this->getUser()), "can_pin" => $post->canBePinnedBy($this->getUser()), "can_archive" => false, # TODO MAYBE "is_archived" => false, "is_pinned" => $post->isPinned(), "is_explicit" => $post->isExplicit(), "attachments" => $attachments, "post_source" => $post->getPostSourceInfo(), "comments" => (object)[ "count" => $post->getCommentsCount(), "can_post" => 1 ], "likes" => (object)[ "count" => $post->getLikesCount(), "user_likes" => (int) $post->hasLikeFrom($this->getUser()), "can_like" => 1, "can_publish" => 1, ], "reposts" => (object)[ "count" => $post->getRepostCount(), "user_reposted" => 0 ] ]; if($post->hasSource()) $post_temp_obj->copyright = $post->getVkApiCopyright(); if($signerId) $post_temp_obj->signer_id = $signerId; if($post->isDeactivationMessage()) $post_temp_obj->final_post = 1; $items[] = $post_temp_obj; if ($from_id > 0) $profiles[] = $from_id; else $groups[] = $from_id * -1; if($post->isSigned()) $profiles[] = $post->getOwner(false)->getId(); $attachments = NULL; # free attachments so it will not clone everythingg } if($extended == 1) { $profiles = array_unique($profiles); $groups = array_unique($groups); $profilesFormatted = []; $groupsFormatted = []; foreach($profiles as $prof) { $user = (new UsersRepo)->get($prof); $profilesFormatted[] = (object)[ "first_name" => $user->getFirstName(), "id" => $user->getId(), "last_name" => $user->getLastName(), "can_access_closed" => (bool)$user->canBeViewedBy($this->getUser()), "is_closed" => $user->isClosed(), "sex" => $user->isFemale() ? 1 : ($user->isNeutral() ? 0 : 2), "screen_name" => $user->getShortCode(), "photo_50" => $user->getAvatarUrl(), "photo_100" => $user->getAvatarUrl(), "online" => $user->isOnline(), "verified" => $user->isVerified() ]; } foreach($groups as $g) { $group = (new ClubsRepo)->get($g); $groupsFormatted[] = (object)[ "id" => $group->getId(), "name" => $group->getName(), "screen_name" => $group->getShortCode(), "is_closed" => 0, "type" => "group", "photo_50" => $group->getAvatarUrl(), "photo_100" => $group->getAvatarUrl(), "photo_200" => $group->getAvatarUrl(), "verified" => $group->isVerified() ]; } return (object) [ "count" => $cnt, "items" => $items, "profiles" => $profilesFormatted, "groups" => $groupsFormatted ]; } else return (object) [ "count" => $cnt, "items" => $items ]; } function getById(string $posts, int $extended = 0, string $fields = "", User $user = NULL) { if($user == NULL) { $this->requireUser(); $user = $this->getUser(); # костыли костыли крылышки } $items = []; $profiles = []; $groups = []; $psts = explode(',', $posts); foreach($psts as $pst) { $id = explode("_", $pst); $post = (new PostsRepo)->getPostById(intval($id[0]), intval($id[1])); if($post && !$post->isDeleted()) { if(!$post->canBeViewedBy($this->getUser())) continue; $from_id = get_class($post->getOwner()) == "openvk\Web\Models\Entities\Club" ? $post->getOwner()->getId() * (-1) : $post->getOwner()->getId(); $attachments = []; $repost = []; // чел высрал семь сигарет 😳 помянем 🕯 foreach($post->getChildren() as $attachment) { if($attachment instanceof \openvk\Web\Models\Entities\Photo) { $attachments[] = $this->getApiPhoto($attachment); } else if($attachment instanceof \openvk\Web\Models\Entities\Poll) { $attachments[] = $this->getApiPoll($attachment, $user); } else if ($attachment instanceof \openvk\Web\Models\Entities\Video) { $attachments[] = $attachment->getApiStructure($this->getUser()); } else if ($attachment instanceof \openvk\Web\Models\Entities\Note) { if(VKAPI_DECL_VER === '4.100') { $attachments[] = $attachment->toVkApiStruct(); } else { $attachments[] = [ 'type' => 'note', 'note' => $attachment->toVkApiStruct() ]; } } else if ($attachment instanceof \openvk\Web\Models\Entities\Audio) { $attachments[] = [ "type" => "audio", "audio" => $attachment->toVkApiStruct($this->getUser()) ]; } else if ($attachment instanceof \openvk\Web\Models\Entities\Post) { $repostAttachments = []; foreach($attachment->getChildren() as $repostAttachment) { if($repostAttachment instanceof \openvk\Web\Models\Entities\Photo) { if($attachment->isDeleted()) continue; $repostAttachments[] = $this->getApiPhoto($repostAttachment); /* Рекурсии, сука! Заказывали? */ } } if ($attachment->isPostedOnBehalfOfGroup()) $groups[] = $attachment->getOwner()->getId(); else $profiles[] = $attachment->getOwner()->getId(); $repost[] = [ "id" => $attachment->getVirtualId(), "owner_id" => $attachment->isPostedOnBehalfOfGroup() ? $attachment->getOwner()->getId() * -1 : $attachment->getOwner()->getId(), "from_id" => $attachment->isPostedOnBehalfOfGroup() ? $attachment->getOwner()->getId() * -1 : $attachment->getOwner()->getId(), "date" => $attachment->getPublicationTime()->timestamp(), "post_type" => "post", "text" => $attachment->getText(false), "attachments" => $repostAttachments, "post_source" => $attachment->getPostSourceInfo(), ]; if ($attachment->getTargetWall() > 0) $profiles[] = $attachment->getTargetWall(); else $groups[] = abs($attachment->getTargetWall()); if($post->isSigned()) $profiles[] = $attachment->getOwner()->getId(); } } if($post->isSigned()) { $actualAuthor = $post->getOwner(false); $signerId = $actualAuthor->getId(); } $post_temp_obj = (object)[ "id" => $post->getVirtualId(), "from_id" => $from_id, "owner_id" => $post->getTargetWall(), "date" => $post->getPublicationTime()->timestamp(), "post_type" => $post->getVkApiType(), "text" => $post->getText(false), "copy_history" => $repost, "can_edit" => $post->canBeEditedBy($this->getUser()), "can_delete" => $post->canBeDeletedBy($user), "can_pin" => $post->canBePinnedBy($user), "can_archive" => false, # TODO MAYBE "is_archived" => false, "is_pinned" => $post->isPinned(), "is_explicit" => $post->isExplicit(), "post_source" => $post->getPostSourceInfo(), "attachments" => $attachments, "comments" => (object)[ "count" => $post->getCommentsCount(), "can_post" => 1 ], "likes" => (object)[ "count" => $post->getLikesCount(), "user_likes" => (int) $post->hasLikeFrom($user), "can_like" => 1, "can_publish" => 1, ], "reposts" => (object)[ "count" => $post->getRepostCount(), "user_reposted" => 0 ] ]; if($post->hasSource()) $post_temp_obj->copyright = $post->getVkApiCopyright(); if($signerId) $post_temp_obj->signer_id = $signerId; if($post->isDeactivationMessage()) $post_temp_obj->final_post = 1; $items[] = $post_temp_obj; if ($from_id > 0) $profiles[] = $from_id; else $groups[] = $from_id * -1; if($post->isSigned()) $profiles[] = $post->getOwner(false)->getId(); $attachments = NULL; # free attachments so it will not clone everything $repost = NULL; # same } } if($extended == 1) { $profiles = array_unique($profiles); $groups = array_unique($groups); $profilesFormatted = []; $groupsFormatted = []; foreach($profiles as $prof) { $user = (new UsersRepo)->get($prof); if($user) { $profilesFormatted[] = (object)[ "first_name" => $user->getFirstName(), "id" => $user->getId(), "last_name" => $user->getLastName(), "can_access_closed" => (bool)$user->canBeViewedBy($this->getUser()), "is_closed" => $user->isClosed(), "sex" => $user->isFemale() ? 1 : 2, "screen_name" => $user->getShortCode(), "photo_50" => $user->getAvatarUrl(), "photo_100" => $user->getAvatarUrl(), "online" => $user->isOnline(), "verified" => $user->isVerified() ]; } else { $profilesFormatted[] = (object)[ "id" => (int) $prof, "first_name" => "DELETED", "last_name" => "", "deactivated" => "deleted" ]; } } foreach($groups as $g) { $group = (new ClubsRepo)->get($g); $groupsFormatted[] = (object)[ "id" => $group->getId(), "name" => $group->getName(), "screen_name" => $group->getShortCode(), "is_closed" => 0, "type" => "group", "photo_50" => $group->getAvatarUrl(), "photo_100" => $group->getAvatarUrl(), "photo_200" => $group->getAvatarUrl(), "verified" => $group->isVerified() ]; } return (object) [ "items" => (array)$items, "profiles" => (array)$profilesFormatted, "groups" => (array)$groupsFormatted ]; } else return (object) [ "items" => (array)$items ]; } function post(string $owner_id, string $message = "", string $copyright = "", int $from_group = 0, int $signed = 0, string $attachments = "", int $post_id = 0): object { $this->requireUser(); $this->willExecuteWriteAction(); $owner_id = intval($owner_id); $wallOwner = ($owner_id > 0 ? (new UsersRepo)->get($owner_id) : (new ClubsRepo)->get($owner_id * -1)) ?? $this->fail(18, "User was deleted or banned"); if($owner_id > 0) $canPost = $wallOwner->getPrivacyPermission("wall.write", $this->getUser()) && $wallOwner->canBeViewedBy($this->getUser()); else if($owner_id < 0) if($wallOwner->canBeModifiedBy($this->getUser())) $canPost = true; else $canPost = $wallOwner->canPost(); else $canPost = false; if($canPost == false) $this->fail(15, "Access denied"); if($post_id > 0) { if($owner_id > 0) $this->fail(62, "Suggested posts available only at groups"); $post = (new PostsRepo)->getPostById($owner_id, $post_id, true); if(!$post || $post->isDeleted()) $this->fail(32, "Invald post"); if($post->getSuggestionType() == 0) $this->fail(20, "Post is not suggested"); if($post->getSuggestionType() == 2) $this->fail(16, "Post is declined"); if(!$post->canBePinnedBy($this->getUser())) $this->fail(51, "Access denied"); $author = $post->getOwner(); $flags = 0; $flags |= 0b10000000; if($signed == 1) $flags |= 0b01000000; $post->setSuggested(0); $post->setCreated(time()); $post->setFlags($flags); if(!empty($message) && iconv_strlen($message) > 0) $post->setContent($message); $post->save(); if($author->getId() != $this->getUser()->getId()) (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); return (object)["post_id" => $post->getVirtualId()]; } $anon = OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"]; if($wallOwner instanceof Club && $from_group == 1 && $signed != 1 && $anon) { $manager = $wallOwner->getManager($this->getUser()); if($manager) $anon = $manager->isHidden(); elseif($this->getUser()->getId() === $wallOwner->getOwner()->getId()) $anon = $wallOwner->isOwnerHidden(); } else { $anon = false; } $flags = 0; if($from_group == 1 && $wallOwner instanceof Club && $wallOwner->canBeModifiedBy($this->getUser())) $flags |= 0b10000000; if($signed == 1) $flags |= 0b01000000; $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'poll', 'audio']); $final_attachments = []; $should_be_suggested = $owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2; foreach($parsed_attachments as $attachment) { if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) { $final_attachments[] = $attachment; } } if((empty($message) && (empty($attachments) || sizeof($final_attachments) < 1))) $this->fail(100, "Required parameter 'message' missing."); try { $post = new Post; $post->setOwner($this->getUser()->getId()); $post->setWall($owner_id); $post->setCreated(time()); $post->setContent($message); $post->setFlags($flags); $post->setApi_Source_Name($this->getPlatform()); if(!is_null($copyright) && !empty($copyright)) { try { $post->setSource($copyright); } catch(\Throwable) {} } if($should_be_suggested) $post->setSuggested(1); $post->save(); } catch(\LogicException $ex) { $this->fail(100, "One of the parameters specified was missing or invalid"); } foreach($final_attachments as $attachment) { $post->attach($attachment); } if($wall > 0 && $wall !== $this->user->identity->getId()) (new WallPostNotification($wallOwner, $post, $this->user->identity))->emit(); if($should_be_suggested) { return (object)["post_id" => "on_view"]; } return (object)["post_id" => $post->getVirtualId()]; } function repost(string $object, string $message = "", string $attachments = "", int $group_id = 0, int $as_group = 0, int $signed = 0) { $this->requireUser(); $this->willExecuteWriteAction(); $postArray; if(preg_match('/(wall|video|photo)((?:-?)[0-9]+)_([0-9]+)/', $object, $postArray) == 0) $this->fail(100, "One of the parameters specified was missing or invalid: object is incorrect"); $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio']); $final_attachments = []; foreach($parsed_attachments as $attachment) { if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) { $final_attachments[] = $attachment; } } $repost_entity = NULL; $repost_type = $postArray[1]; switch($repost_type) { default: case 'wall': $repost_entity = (new PostsRepo)->getPostById((int) $postArray[2], (int) $postArray[3]); break; case 'photo': $repost_entity = (new PhotosRepo)->getByOwnerAndVID((int) $postArray[2], (int) $postArray[3]); break; case 'video': $repost_entity = (new VideosRepo)->getByOwnerAndVID((int) $postArray[2], (int) $postArray[3]); break; } if(!$repost_entity || $repost_entity->isDeleted() || !$repost_entity->canBeViewedBy($this->getUser())) $this->fail(100, "One of the parameters specified was missing or invalid"); $nPost = new Post; $nPost->setOwner($this->user->getId()); if($group_id > 0) { $club = (new ClubsRepo)->get($group_id); if(!$club) $this->fail(42, "Invalid group"); if(!$club->canBeModifiedBy($this->user)) $this->fail(16, "Access to group denied"); $nPost->setWall($club->getRealId()); $flags = 0; if($as_group === 1 || $signed === 1) $flags |= 0b10000000; if($signed === 1) $flags |= 0b01000000; $nPost->setFlags($flags); } else { $nPost->setWall($this->user->getId()); } $nPost->setContent($message); $nPost->setApi_Source_Name($this->getPlatform()); $nPost->save(); $nPost->attach($repost_entity); foreach($parsed_attachments as $attachment) { $nPost->attach($attachment); } if($repost_type == 'wall' && $repost_entity->getOwner(false)->getId() !== $this->user->getId() && !($repost_entity->getOwner() instanceof Club)) (new RepostNotification($repost_entity->getOwner(false), $repost_entity, $this->user))->emit(); $repost_count = 1; if($repost_type == 'wall') { $repost_count = $repost_entity->getRepostCount(); } return (object) [ "success" => 1, // 👍 "post_id" => $nPost->getVirtualId(), "pretty_id" => $nPost->getPrettyId(), "reposts_count" => $repost_count, "likes_count" => $repost_entity->getLikesCount() ]; } function getComments(int $owner_id, int $post_id, bool $need_likes = true, int $offset = 0, int $count = 10, string $fields = "sex,screen_name,photo_50,photo_100,online_info,online", string $sort = "asc", bool $extended = false) { $this->requireUser(); $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->canBeViewedBy($this->getUser())) $this->fail(15, "Access denied"); $comments = (new CommentsRepo)->getCommentsByTarget($post, $offset+1, $count, $sort == "desc" ? "DESC" : "ASC"); $items = []; $profiles = []; foreach($comments as $comment) { $owner = $comment->getOwner(); $oid = $owner->getId(); if($owner instanceof Club) $oid *= -1; $attachments = []; foreach($comment->getChildren() as $attachment) { if($attachment instanceof \openvk\Web\Models\Entities\Photo) { $attachments[] = $this->getApiPhoto($attachment); } elseif($attachment instanceof \openvk\Web\Models\Entities\Note) { $attachments[] = $attachment->toVkApiStruct(); } elseif($attachment instanceof \openvk\Web\Models\Entities\Audio) { $attachments[] = [ "type" => "audio", "audio" => $attachment->toVkApiStruct($this->getUser()), ]; } } $item = [ "id" => $comment->getId(), "from_id" => $oid, "date" => $comment->getPublicationTime()->timestamp(), "text" => $comment->getText(false), "post_id" => $post->getVirtualId(), "owner_id" => $post->isPostedOnBehalfOfGroup() ? $post->getOwner()->getId() * -1 : $post->getOwner()->getId(), "parents_stack" => [], "attachments" => $attachments, "thread" => [ "count" => 0, "items" => [], "can_post" => false, "show_reply_button" => true, "groups_can_post" => false, ] ]; if($comment->isFromPostAuthor($post)) $item['is_from_post_author'] = true; if($need_likes == true) $item['likes'] = [ "can_like" => 1, "count" => $comment->getLikesCount(), "user_likes" => (int) $comment->hasLikeFrom($this->getUser()), "can_publish" => 1 ]; $items[] = $item; if($extended == true) $profiles[] = $comment->getOwner()->getId(); $attachments = null; // Reset $attachments to not duplicate prikols } $response = [ "count" => (new CommentsRepo)->getCommentsCountByTarget($post), "items" => $items, "current_level_count" => (new CommentsRepo)->getCommentsCountByTarget($post), "can_post" => true, "show_reply_button" => true, "groups_can_post" => false ]; if($extended == true) { $profiles = array_unique($profiles); $response['profiles'] = (!empty($profiles) ? (new Users)->get(implode(',', $profiles), $fields) : []); } return (object) $response; } function getComment(int $owner_id, int $comment_id, bool $extended = false, string $fields = "sex,screen_name,photo_50,photo_100,online_info,online") { $this->requireUser(); $comment = (new CommentsRepo)->get($comment_id); # один хуй айди всех комментов общий if(!$comment || $comment->isDeleted()) $this->fail(100, "Invalid comment"); if(!$comment->canBeViewedBy($this->getUser())) $this->fail(15, "Access denied"); $profiles = []; $attachments = []; foreach($comment->getChildren() as $attachment) { if($attachment instanceof \openvk\Web\Models\Entities\Photo) { $attachments[] = $this->getApiPhoto($attachment); } elseif($attachment instanceof \openvk\Web\Models\Entities\Video) { $attachments[] = $attachment->getApiStructure(); } elseif($attachment instanceof \openvk\Web\Models\Entities\Note) { $attachments[] = [ 'type' => 'note', 'note' => $attachment->toVkApiStruct() ]; } elseif($attachment instanceof \openvk\Web\Models\Entities\Audio) { $attachments[] = [ "type" => "audio", "audio" => $attachment->toVkApiStruct($this->getUser()), ]; } } $item = [ "id" => $comment->getId(), "from_id" => $comment->getOwner()->getId(), "date" => $comment->getPublicationTime()->timestamp(), "text" => $comment->getText(false), "post_id" => $comment->getTarget()->getVirtualId(), "owner_id" => $comment->getTarget()->isPostedOnBehalfOfGroup() ? $comment->getTarget()->getOwner()->getId() * -1 : $comment->getTarget()->getOwner()->getId(), "parents_stack" => [], "attachments" => $attachments, "likes" => [ "can_like" => 1, "count" => $comment->getLikesCount(), "user_likes" => (int) $comment->hasLikeFrom($this->getUser()), "can_publish" => 1 ], "thread" => [ "count" => 0, "items" => [], "can_post" => false, "show_reply_button" => true, "groups_can_post" => false, ] ]; if($comment->isFromPostAuthor()) $item['is_from_post_author'] = true; if($extended == true) $profiles[] = $comment->getOwner()->getId(); $response = [ "items" => [$item], "can_post" => true, "show_reply_button" => true, "groups_can_post" => false ]; if($extended == true) { $profiles = array_unique($profiles); $response['profiles'] = (!empty($profiles) ? (new Users)->get(implode(',', $profiles), $fields) : []); } return $response; } function createComment(int $owner_id, int $post_id, string $message = "", int $from_group = 0, string $attachments = "") { $this->requireUser(); $this->willExecuteWriteAction(); $post = (new PostsRepo)->getPostById($owner_id, $post_id); if(!$post || $post->isDeleted()) $this->fail(100, "Invalid post"); if(!$post->canBeViewedBy($this->getUser())) $this->fail(15, "Access denied"); if($post->getTargetWall() < 0) $club = (new ClubsRepo)->get(abs($post->getTargetWall())); $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio']); $final_attachments = []; foreach($parsed_attachments as $attachment) { if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) { $final_attachments[] = $attachment; } } if((empty($message) && (empty($attachments) || sizeof($final_attachments) < 1))) { $this->fail(100, "Required parameter 'message' missing."); } $flags = 0; if($from_group != 0 && !is_null($club) && $club->canBeModifiedBy($this->user)) $flags |= 0b10000000; try { $comment = new Comment; $comment->setOwner($this->user->getId()); $comment->setModel(get_class($post)); $comment->setTarget($post->getId()); $comment->setContent($message); $comment->setCreated(time()); $comment->setFlags($flags); $comment->save(); } catch (\LengthException $ex) { $this->fail(1, "ошибка про то что коммент большой слишком"); } foreach($final_attachments as $attachment) { $comment->attach($attachment); } if($post->getOwner()->getId() !== $this->user->getId()) if(($owner = $post->getOwner()) instanceof User) (new CommentNotification($owner, $comment, $post, $this->user))->emit(); return (object) [ "comment_id" => $comment->getId(), "parents_stack" => [] ]; } function deleteComment(int $comment_id) { $this->requireUser(); $this->willExecuteWriteAction(); $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"); $comment->delete(); return 1; } function delete(int $owner_id, int $post_id) { $this->requireUser(); $this->willExecuteWriteAction(); $post = (new PostsRepo)->getPostById($owner_id, $post_id, true); if(!$post || $post->isDeleted()) $this->fail(583, "Invalid post"); $wallOwner = $post->getWallOwner(); if($post->getTargetWall() < 0 && !$post->getWallOwner()->canBeModifiedBy($this->getUser()) && $post->getWallOwner()->getWallType() != 1 && $post->getSuggestionType() == 0) $this->fail(12, "Access denied: you can't delete your accepted post."); if($post->getOwnerPost() == $this->getUser()->getId() || $post->getTargetWall() == $this->getUser()->getId() || $owner_id < 0 && $wallOwner->canBeModifiedBy($this->getUser())) { $post->unwire(); $post->delete(); return 1; } else { $this->fail(15, "Access denied"); } } function edit(int $owner_id, int $post_id, string $message = "", string $attachments = "", string $copyright = NULL, int $explicit = -1, int $from_group = 0, int $signed = 0) { $this->requireUser(); $this->willExecuteWriteAction(); $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio']); $final_attachments = []; foreach($parsed_attachments as $attachment) { if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) { $final_attachments[] = $attachment; } } if(empty($message) && sizeof($final_attachments) < 1) { $this->fail(-66, "Post will be empty, don't saving."); } $post = (new PostsRepo)->getPostById($owner_id, $post_id); if(!$post || $post->isDeleted()) $this->fail(102, "Invalid post"); if(!$post->canBeEditedBy($this->getUser())) $this->fail(7, "Access to editing denied"); if(!empty($message) || (empty($message) && sizeof($final_attachments) > 0)) $post->setContent($message); $post->setEdited(time()); if(!is_null($copyright) && !empty($copyright)) { if($copyright == 'remove') { $post->resetSource(); } else { try { $post->setSource($copyright); } catch(\Throwable) {} } } if($explicit != -1) { $post->setNsfw($explicit == 1); } $wallOwner = ($owner_id > 0 ? (new UsersRepo)->get($owner_id) : (new ClubsRepo)->get($owner_id * -1)); $flags = 0; if($from_group == 1 && $wallOwner instanceof Club && $wallOwner->canBeModifiedBy($this->getUser())) $flags |= 0b10000000; /*if($signed == 1) $flags |= 0b01000000;*/ $post->setFlags($flags); $post->save(true); if($attachments == 'remove' || sizeof($final_attachments) > 0) { $post->unwire(); foreach($final_attachments as $attachment) { $post->attach($attachment); } } return ["post_id" => $post->getVirtualId()]; } function editComment(int $comment_id, int $owner_id = 0, string $message = "", string $attachments = "") { $this->requireUser(); $this->willExecuteWriteAction(); $comment = (new CommentsRepo)->get($comment_id); $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio']); $final_attachments = []; foreach($parsed_attachments as $attachment) { if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) { $final_attachments[] = $attachment; } } if(empty($message) && sizeof($final_attachments) < 1) $this->fail(100, "Required parameter 'message' missing."); if(!$comment || $comment->isDeleted()) $this->fail(102, "Invalid comment"); if(!$comment->canBeEditedBy($this->getUser())) $this->fail(15, "Access to editing comment denied"); if(!empty($message) || (empty($message) && sizeof($final_attachments) > 0)) $comment->setContent($message); $comment->setEdited(time()); $comment->save(true); if(sizeof($final_attachments) > 0) { $comment->unwire(); foreach($final_attachments as $attachment) { $comment->attach($attachment); } } return 1; } function checkCopyrightLink(string $link): int { $this->requireUser(); try { $result = check_copyright_link($link); } catch(\InvalidArgumentException $e) { $this->fail(3102, "Specified link is incorrect (can't find source)"); } catch(\LengthException $e) { $this->fail(3103, "Specified link is incorrect (too long)"); } catch(\LogicException $e) { $this->fail(3104, "Link is suspicious"); } catch(\Throwable $e) { $this->fail(3102, "Specified link is incorrect"); } return 1; } function pin(int $owner_id, int $post_id) { $this->requireUser(); $this->willExecuteWriteAction(); $post = (new PostsRepo)->getPostById($owner_id, $post_id); if(!$post || $post->isDeleted()) $this->fail(100, "One of the parameters specified was missing or invalid: post_id is undefined"); if(!$post->canBePinnedBy($this->getUser())) return 0; if($post->isPinned()) return 1; $post->pin(); return 1; } function unpin(int $owner_id, int $post_id) { $this->requireUser(); $this->willExecuteWriteAction(); $post = (new PostsRepo)->getPostById($owner_id, $post_id); if(!$post || $post->isDeleted()) $this->fail(100, "One of the parameters specified was missing or invalid: post_id is undefined"); if(!$post->canBePinnedBy($this->getUser())) return 0; if(!$post->isPinned()) return 1; $post->unpin(); return 1; } private function getApiPhoto($attachment) { return [ "type" => "photo", "photo" => [ "album_id" => $attachment->getAlbum() ? $attachment->getAlbum()->getId() : 0, "date" => $attachment->getPublicationTime()->timestamp(), "id" => $attachment->getVirtualId(), "owner_id" => $attachment->getOwner()->getId(), "sizes" => !is_null($attachment->getVkApiSizes()) ? array_values($attachment->getVkApiSizes()) : NULL, "text" => "", "has_tags" => false ] ]; } private function getApiPoll($attachment, $user) { $answers = array(); foreach($attachment->getResults()->options as $answer) { $answers[] = (object)[ "id" => $answer->id, "rate" => $answer->pct, "text" => $answer->name, "votes" => $answer->votes ]; } $userVote = array(); foreach($attachment->getUserVote($user) as $vote) $userVote[] = $vote[0]; return [ "type" => "poll", "poll" => [ "multiple" => $attachment->isMultipleChoice(), "end_date" => $attachment->endsAt() == NULL ? 0 : $attachment->endsAt()->timestamp(), "closed" => $attachment->hasEnded(), "is_board" => false, "can_edit" => false, "can_vote" => $attachment->canVote($user), "can_report" => false, "can_share" => true, "created" => 0, "id" => $attachment->getId(), "owner_id" => $attachment->getOwner()->getId(), "question" => $attachment->getTitle(), "votes" => $attachment->getVoterCount(), "disable_unvote" => $attachment->isRevotable(), "anonymous" => $attachment->isAnonymous(), "answer_ids" => $userVote, "answers" => $answers, "author_id" => $attachment->getOwner()->getId(), ] ]; } }