fix(photos api): fix stupid incompabilites

This commit is contained in:
mrilyew 2025-04-02 21:57:23 +03:00
parent c04361bcab
commit 836eab13d4
5 changed files with 145 additions and 254 deletions

View file

@ -248,7 +248,7 @@ final class Photos extends VKAPIRequestHandler
]; ];
} }
public function createAlbum(string $title, int $group_id = 0, string $description = "", int $privacy = 0) public function createAlbum(string $title, int $group_id = 0, string $description = "")
{ {
$this->requireUser(); $this->requireUser();
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
@ -257,7 +257,7 @@ final class Photos extends VKAPIRequestHandler
$club = (new Clubs())->get((int) $group_id); $club = (new Clubs())->get((int) $group_id);
if (!$club || !$club->canBeModifiedBy($this->getUser())) { if (!$club || !$club->canBeModifiedBy($this->getUser())) {
$this->fail(20, "Invalid club"); $this->fail(15, "Access denied");
} }
} }
@ -271,163 +271,125 @@ final class Photos extends VKAPIRequestHandler
return $album->toVkApiStruct($this->getUser()); return $album->toVkApiStruct($this->getUser());
} }
public function editAlbum(int $album_id, int $owner_id, string $title, string $description = "", int $privacy = 0) public function editAlbum(int $album_id, int $owner_id, string $title = null, string $description = null, int $privacy = 0)
{ {
$this->requireUser(); $this->requireUser();
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
$album = (new Albums())->getAlbumByOwnerAndId($owner_id, $album_id); $album = (new Albums())->getAlbumByOwnerAndId($owner_id, $album_id);
if (!$album || $album->isDeleted()) { if (!$album || $album->isDeleted() || $album->isCreatedBySystem())
$this->fail(2, "Invalid album"); $this->fail(114, "Invalid album id");
} if (!$album->canBeModifiedBy($this->getUser()))
$this->fail(15, "Access denied");
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");
}
if (!is_null($title) && !empty($title) && !ctype_space($content))
$album->setName($title); $album->setName($title);
if (!is_null($description))
$album->setDescription($description); $album->setDescription($description);
try {
$album->save(); $album->save();
} catch(\Throwable $e) {
return $album->toVkApiStruct($this->getUser()); return 1;
} }
public 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) return 1;
}
public function getAlbums(int $owner_id = null, string $album_ids = "", int $offset = 0, int $count = 100, bool $need_system = true, bool $need_covers = true, bool $photo_sizes = false)
{ {
$this->requireUser(); $this->requireUser();
$res = []; $res = [
"count" => 0,
"items" => [],
];
$albums_list = [];
if ($owner_id == null && empty($album_ids)) {
$owner_id = $this->getUser()->getId();
}
if (empty($album_ids)) { if (empty($album_ids)) {
$owner = get_entity_by_id($owner_id);
if (!$owner || !$owner->canBeViewedBy($this->getUser()))
$this->fail(15, "Access denied");
if ($owner_id > 0 && !$owner->getPrivacyPermission('photos.read', $this->getUser()))
$this->fail(15, "Access denied");
$albums_list = null;
if ($owner_id > 0) { if ($owner_id > 0) {
$user = (new UsersRepo())->get($owner_id); # TODO rewrite to offset
$albums_list = array_slice(iterator_to_array((new Albums())->getUserAlbums($owner, 1, $count + $offset)), $offset);
$res = [ $res["count"] = (new Albums())->getUserAlbumsCount($owner);
"count" => (new Albums())->getUserAlbumsCount($user), } else {
"items" => [], $albums_list = array_slice(iterator_to_array((new Albums())->getClubAlbums($owner, 1, $count + $offset)), $offset);
]; $res["count"] = (new Albums())->getClubAlbumsCount($owner);
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 { } else {
$club = (new Clubs())->get($owner_id * -1); $album_ids = explode(',', $album_ids);
foreach ($album_ids as $album_id) {
$res = [ $album = (new Albums())->getAlbumByOwnerAndId((int)$owner_id, (int)$album_id);
"count" => (new Albums())->getClubAlbumsCount($club), if (!$album || $album->isDeleted() || !$album->canBeViewedBy($this->getUser()))
"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; continue;
}
$res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes); $albums_list[] = $album;
} }
} }
} else { foreach ($albums_list as $album) {
$albums = explode(',', $album_ids); if (!$need_system && $album->isCreatedBySystem()) # TODO use queries
$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; continue;
}
$res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes); $res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes);
} }
}
}
return $res; return $res;
} }
public function getAlbumsCount(int $user_id = 0, int $group_id = 0) public function getAlbumsCount(int $user_id = null, int $group_id = null)
{ {
$this->requireUser(); $this->requireUser();
if ($user_id == 0 && $group_id == 0 || $user_id > 0 && $group_id > 0) { if (is_null($user_id) && is_null($group_id)) {
$this->fail(21, "Select user_id or group_id"); $user_id = $this->getUser()->getId();
} }
if ($user_id > 0) { if (!is_null($user_id)){
$us = (new UsersRepo())->get($user_id); $__user = (new UsersRepo())->get($user_id);
if (!$us || $us->isDeleted()) { if (!$__user || $__user->isDeleted() || !$__user->getPrivacyPermission('photos.read', $this->getUser())) {
$this->fail(21, "Invalid user"); $this->fail(15, "Access denied");
} }
if (!$us->getPrivacyPermission('photos.read', $this->getUser())) { return (new Albums())->getUserAlbumsCount($__user);
$this->fail(21, "This user chose to hide his albums."); }
if (!is_null($group_id)) {
$__club = (new Clubs())->get($group_id);
if (!$__club || !$__club->canBeViewedBy($this->getUser())) {
$this->fail(15, "Access denied");
} }
return (new Albums())->getUserAlbumsCount($us); return (new Albums())->getClubAlbumsCount($__club);
} }
if ($group_id > 0) { return 0;
$cl = (new Clubs())->get($group_id);
if (!$cl) {
$this->fail(21, "Invalid club");
}
return (new Albums())->getClubAlbumsCount($cl);
}
} }
public function getById(string $photos, bool $extended = false, bool $photo_sizes = false) public function getById(string $photos, bool $extended = false, bool $photo_sizes = false)
{ {
$this->requireUser(); $this->requireUser();
$phts = explode(",", $photos); $photos_splitted_list = explode(",", $photos);
$res = []; $res = [];
if (sizeof($photos_splitted_list) > 78) {
foreach ($phts as $phota) { $this->fail(-78, "Photos count must not exceed limit");
$ph = explode("_", $phota);
$photo = (new PhotosRepo())->getByOwnerAndVID((int) $ph[0], (int) $ph[1]);
if (!$photo || $photo->isDeleted()) {
$this->fail(21, "Invalid photo");
} }
if (!$photo->canBeViewedBy($this->getUser())) { foreach ($photos_splitted_list as $photo_id) {
$this->fail(15, "Access denied"); $photo_s_id = explode("_", $photo_id);
} $photo = (new PhotosRepo())->getByOwnerAndVID((int) $photo_s_id[0], (int) $photo_s_id[1]);
if(!$photo || $photo->isDeleted() || !$photo->canBeViewedBy($this->getUser()))
continue;
$res[] = $photo->toVkApiStruct($photo_sizes, $extended); $res[] = $photo->toVkApiStruct($photo_sizes, $extended);
} }
@ -443,12 +405,7 @@ final class Photos extends VKAPIRequestHandler
if (empty($photo_ids)) { if (empty($photo_ids)) {
$album = (new Albums())->getAlbumByOwnerAndId($owner_id, $album_id); $album = (new Albums())->getAlbumByOwnerAndId($owner_id, $album_id);
if (!$album || $album->isDeleted() || !$album->canBeViewedBy($this->getUser())) {
if (!$album || $album->isDeleted()) {
$this->fail(21, "Invalid album");
}
if (!$album->canBeViewedBy($this->getUser())) {
$this->fail(15, "Access denied"); $this->fail(15, "Access denied");
} }
@ -459,11 +416,15 @@ final class Photos extends VKAPIRequestHandler
if (!$photo || $photo->isDeleted()) { if (!$photo || $photo->isDeleted()) {
continue; continue;
} }
$res["items"][] = $photo->toVkApiStruct($photo_sizes, $extended); $res["items"][] = $photo->toVkApiStruct($photo_sizes, $extended);
} }
} else { } else {
$photos = explode(',', $photo_ids); $photos = array_unique(explode(',', $photo_ids));
if (sizeof($photos) > 78) {
$this->fail(-78, "Photos count must not exceed limit");
}
$res = [ $res = [
"count" => sizeof($photos), "count" => sizeof($photos),
@ -473,10 +434,11 @@ final class Photos extends VKAPIRequestHandler
foreach ($photos as $photo) { foreach ($photos as $photo) {
$id = explode("_", $photo); $id = explode("_", $photo);
$phot = (new PhotosRepo())->getByOwnerAndVID((int) $id[0], (int) $id[1]); $photo_entity = (new PhotosRepo())->getByOwnerAndVID((int) $id[0], (int) $id[1]);
if ($phot && !$phot->isDeleted() && $phot->canBeViewedBy($this->getUser())) { if (!$photo_entity || $photo_entity->isDeleted() || !$photo_entity->canBeViewedBy($this->getUser()))
$res["items"][] = $phot->toVkApiStruct($photo_sizes, $extended); continue;
}
$res["items"][] = $photo_entity->toVkApiStruct($photo_sizes, $extended);
} }
} }
@ -490,12 +452,8 @@ final class Photos extends VKAPIRequestHandler
$album = (new Albums())->get($album_id); $album = (new Albums())->get($album_id);
if (!$album || $album->canBeModifiedBy($this->getUser())) { if (!$album || $album->isDeleted() || $album->isCreatedBySystem() || !$album->canBeModifiedBy($this->getUser())) {
$this->fail(21, "Invalid album"); $this->fail(15, "Access denied");
}
if ($album->isDeleted()) {
$this->fail(22, "Album already deleted");
} }
$album->delete(); $album->delete();
@ -510,12 +468,8 @@ final class Photos extends VKAPIRequestHandler
$photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id); $photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id);
if (!$photo) { if (!$photo || $photo->isDeleted() || !$photo->canBeModifiedBy($this->getUser())) {
$this->fail(21, "Invalid photo"); $this->fail(21, "Access denied");
}
if ($photo->isDeleted()) {
$this->fail(21, "Photo is deleted");
} }
if (!empty($caption)) { if (!empty($caption)) {
@ -526,60 +480,46 @@ final class Photos extends VKAPIRequestHandler
return 1; return 1;
} }
public function delete(int $owner_id, int $photo_id, string $photos = "") public function delete(int $owner_id = null, int $photo_id = null, string $photos = null)
{ {
$this->requireUser(); $this->requireUser();
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
if (empty($photos)) { if(!$owner_id) {
$owner_id = $this->getUser()->getId();
}
if (is_null($photos)) {
if(is_null($photo_id))
return 0;
$photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id); $photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id);
if (!$photo || $photo->isDeleted() || !$photo->canBeModifiedBy($this->getUser())) {
if ($this->getUser()->getId() !== $photo->getOwner()->getId()) { return 1;
$this->fail(21, "You can't delete another's photo");
}
if (!$photo) {
$this->fail(21, "Invalid photo");
}
if ($photo->isDeleted()) {
$this->fail(21, "Photo is already deleted");
} }
$photo->delete(); $photo->delete();
} else { } else {
$photozs = explode(',', $photos); $photos_list = array_unique(explode(',', $photos));
if (sizeof($photos_list) > 10) {
foreach ($photozs as $photo) { $this->fail(-78, "Photos count must not exceed limit");
$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) { foreach ($photos_list as $photo_id) {
$this->fail(21, "Invalid photo"); $id = explode("_", $photo_id);
} $photo = (new PhotosRepo())->getByOwnerAndVID((int) $id[0], (int) $id[1]);
if (!$photo || $photo->isDeleted() || !$photo->canBeModifiedBy($this->getUser()))
continue;
if ($phot->isDeleted()) { $photo->delete();
$this->fail(21, "Photo already deleted");
}
$phot->delete();
} }
} }
return 1; return 1;
} }
public function getAllComments(int $owner_id, int $album_id, bool $need_likes = false, int $offset = 0, int $count = 100) # Поскольку комментарии едины, можно использовать метод "wall.deleteComment".
{ /*public function deleteComment(int $comment_id, int $owner_id = 0)
$this->fail(501, "Not implemented");
}
public function deleteComment(int $comment_id, int $owner_id = 0)
{ {
$this->requireUser(); $this->requireUser();
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
@ -596,9 +536,9 @@ final class Photos extends VKAPIRequestHandler
$comment->delete(); $comment->delete();
return 1; return 1;
} }*/
public function createComment(int $owner_id, int $photo_id, string $message = "", string $attachments = "", bool $from_group = false) public function createComment(int $owner_id, int $photo_id, string $message = "", bool $from_group = false)
{ {
$this->requireUser(); $this->requireUser();
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
@ -609,12 +549,8 @@ final class Photos extends VKAPIRequestHandler
$photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id); $photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id);
if (!$photo || $photo->isDeleted()) { if (!$photo || $photo->isDeleted() || !$photo->canBeViewedBy($this->getUser())) {
$this->fail(180, "Invalid photo"); $this->fail(15, "Access denied");
}
if (!$photo->canBeViewedBy($this->getUser())) {
$this->fail(15, "Access to photo denied");
} }
$comment = new Comment(); $comment = new Comment();
@ -625,55 +561,6 @@ final class Photos extends VKAPIRequestHandler
$comment->setCreated(time()); $comment->setCreated(time());
$comment->save(); $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(); return $comment->getId();
} }
@ -682,16 +569,12 @@ final class Photos extends VKAPIRequestHandler
$this->requireUser(); $this->requireUser();
if ($owner_id < 0) { if ($owner_id < 0) {
$this->fail(4, "This method doesn't works with clubs"); $this->fail(-413, "Clubs are not supported");
} }
$user = (new UsersRepo())->get($owner_id); $user = (new UsersRepo())->get($owner_id);
if (!$user) { if (!$user || !$user->getPrivacyPermission('photos.read', $this->getUser())) {
$this->fail(4, "Invalid user"); $this->fail(15, "Access denied");
}
if (!$user->getPrivacyPermission('photos.read', $this->getUser())) {
$this->fail(21, "This user chose to hide his albums.");
} }
$photos = (new PhotosRepo())->getEveryUserPhoto($user, $offset, $count); $photos = (new PhotosRepo())->getEveryUserPhoto($user, $offset, $count);
@ -717,12 +600,8 @@ final class Photos extends VKAPIRequestHandler
$photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id); $photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id);
$comms = array_slice(iterator_to_array($photo->getComments(1, $offset + $count)), $offset); $comms = array_slice(iterator_to_array($photo->getComments(1, $offset + $count)), $offset);
if (!$photo || $photo->isDeleted()) { if (!$photo || $photo->isDeleted() || !$photo->canBeViewedBy($this->getUser())) {
$this->fail(4, "Invalid photo"); $this->fail(15, "Access denied");
}
if (!$photo->canBeViewedBy($this->getUser())) {
$this->fail(21, "Access denied");
} }
$res = [ $res = [

View file

@ -26,7 +26,9 @@ class Album extends MediaCollection
{ {
$coverPhoto = $this->getCoverPhoto(); $coverPhoto = $this->getCoverPhoto();
if (!$coverPhoto) { if (!$coverPhoto) {
return "/assets/packages/static/openvk/img/camera_200.png"; $server_url = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
return $server_url . "/assets/packages/static/openvk/img/camera_200.png";
} }
return $coverPhoto->getURL(); return $coverPhoto->getURL();
@ -92,14 +94,13 @@ class Album extends MediaCollection
{ {
$res = (object) []; $res = (object) [];
$res->id = $this->getPrettyId(); $res->id = $this->getId();
$res->vid = $this->getId();
$res->thumb_id = !is_null($this->getCoverPhoto()) ? $this->getCoverPhoto()->getPrettyId() : 0; $res->thumb_id = !is_null($this->getCoverPhoto()) ? $this->getCoverPhoto()->getPrettyId() : 0;
$res->owner_id = $this->getOwner()->getId(); $res->owner_id = $this->getOwner()->getRealId();
$res->title = $this->getName(); $res->title = $this->getName();
$res->description = $this->getDescription(); $res->description = $this->getDescription();
$res->created = $this->getCreationTime()->timestamp(); $res->created = $this->getCreationTime()->timestamp();
$res->updated = $this->getEditTime() ? $this->getEditTime()->timestamp() : null; $res->updated = $this->getEditTime() ? $this->getEditTime()->timestamp() : $res->created;
$res->size = $this->size(); $res->size = $this->size();
$res->privacy_comment = 1; $res->privacy_comment = 1;
$res->upload_by_admins_only = 1; $res->upload_by_admins_only = 1;

View file

@ -349,7 +349,6 @@ class Photo extends Media
$res->width = $this->getDimensions()[0]; $res->width = $this->getDimensions()[0];
$res->height = $this->getDimensions()[1]; $res->height = $this->getDimensions()[1];
$res->date = $res->created = $this->getPublicationTime()->timestamp(); $res->date = $res->created = $this->getPublicationTime()->timestamp();
if ($photo_sizes) { if ($photo_sizes) {
$res->sizes = array_values($this->getVkApiSizes()); $res->sizes = array_values($this->getVkApiSizes());
$res->src_small = $res->photo_75 = $this->getURLBySizeId("miniscule"); $res->src_small = $res->photo_75 = $this->getURLBySizeId("miniscule");
@ -359,14 +358,19 @@ class Photo extends Media
$res->src_xxbig = $res->photo_1280 = $this->getURLBySizeId("larger"); $res->src_xxbig = $res->photo_1280 = $this->getURLBySizeId("larger");
$res->src_xxxbig = $res->photo_2560 = $this->getURLBySizeId("original"); $res->src_xxxbig = $res->photo_2560 = $this->getURLBySizeId("original");
$res->src_original = $res->url = $this->getURLBySizeId("UPLOADED_MAXRES"); $res->src_original = $res->url = $this->getURLBySizeId("UPLOADED_MAXRES");
$res->orig_photo = [
"height" => $res->height,
"width" => $res->width,
"type" => "base",
"url" => $this->getURL(),
];
} }
if ($extended) { if ($extended) {
$res->likes = $this->getLikesCount(); # их нету но пусть будут $res->likes = $this->getLikesCount();
$res->comments = $this->getCommentsCount(); $res->comments = $this->getCommentsCount();
$res->tags = 0;
$res->can_comment = 1; $res->can_comment = 1;
$res->can_repost = 0; $res->can_repost = 1;
} }
return $res; return $res;

View file

@ -51,6 +51,7 @@ class Photos
"deleted" => 0, "deleted" => 0,
"system" => 0, "system" => 0,
"private" => 0, "private" => 0,
"anonymous" => 0,
])->order("id DESC"); ])->order("id DESC");
foreach ($photos->limit($limit, $offset) as $photo) { foreach ($photos->limit($limit, $offset) as $photo) {
@ -65,6 +66,7 @@ class Photos
"deleted" => 0, "deleted" => 0,
"system" => 0, "system" => 0,
"private" => 0, "private" => 0,
"anonymous" => 0,
]); ]);
return sizeof($photos); return sizeof($photos);

View file

@ -665,3 +665,8 @@ ul {
background: #1e1a2b; background: #1e1a2b;
border: 1px solid #2c2640; border: 1px solid #2c2640;
} }
.insertedPhoto {
background: #1e1a2b;
border: 1px solid #403a56;
}