From 53f6b3e12be9a191c48178fe4728a7fbeb69972e Mon Sep 17 00:00:00 2001
From: mrilyew <99399973+mrilyew@users.noreply.github.com>
Date: Fri, 25 Oct 2024 16:28:35 +0300
Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D1=8B=20=D0=B4?=
=?UTF-8?q?=D0=BB=D1=8F=20=D0=BF=D0=BB=D0=B5=D0=B9=D0=BB=D0=B8=D1=81=D1=82?=
=?UTF-8?q?=D0=BE=D0=B2=20=D0=B8=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA=D0=B0=20?=
=?UTF-8?q?(#1137)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* search: a bit refactor
* search: a bit refactor 2
* audios: a bit changes
* results highlight, midnight changes, player insear
* add audio download button, simplify css
* upload page changes, add playlist add menu
* -comments search, arrow keys on tips
* move $query var and optimize users/groups.search
го рофлить
* слегка проебался
---
ServiceAPI/Search.php | 76 --
VKAPI/Handlers/Audio.php | 13 +-
VKAPI/Handlers/Groups.php | 21 +-
VKAPI/Handlers/Users.php | 118 +--
VKAPI/Handlers/Video.php | 56 ++
Web/Models/Entities/Audio.php | 5 +
Web/Models/Entities/Club.php | 2 +-
Web/Models/Entities/Comment.php | 27 +
Web/Models/Entities/Playlist.php | 26 +
Web/Models/Entities/Traits/TRichText.php | 2 +-
Web/Models/Entities/User.php | 21 +-
Web/Models/Entities/Video.php | 4 +-
Web/Models/Repositories/Applications.php | 16 +-
Web/Models/Repositories/Audios.php | 82 ++-
Web/Models/Repositories/Clubs.php | 24 +-
Web/Models/Repositories/Comments.php | 43 +-
Web/Models/Repositories/Posts.php | 53 +-
Web/Models/Repositories/Users.php | 146 ++--
Web/Models/Repositories/Videos.php | 47 +-
Web/Presenters/AudioPresenter.php | 151 +++-
Web/Presenters/SearchPresenter.php | 148 ++--
Web/Presenters/templates/@layout.xml | 84 +--
.../templates/Audio/EditPlaylist.xml | 11 +-
Web/Presenters/templates/Audio/List.xml | 87 +--
.../templates/Audio/NewPlaylist.xml | 10 +-
Web/Presenters/templates/Audio/Playlist.xml | 32 +-
Web/Presenters/templates/Audio/Upload.xml | 82 ++-
Web/Presenters/templates/Audio/bigplayer.xml | 10 +-
Web/Presenters/templates/Audio/player.xml | 32 +-
.../templates/Audio/playlistListView.xml | 20 +
Web/Presenters/templates/Audio/tabs.xml | 42 +-
Web/Presenters/templates/Search/Index.xml | 697 +++++++++---------
Web/Presenters/templates/User/View.xml | 16 +-
Web/Presenters/templates/Videos/List.xml | 6 +-
.../templates/components/comment.xml | 37 +-
.../templates/components/content_error.xml | 6 +
.../templates/components/paginator.xml | 6 +-
Web/Presenters/templates/components/video.xml | 8 +-
Web/Util/Makima/Makima.php | 2 +-
Web/static/css/audios.css | 256 +++++--
Web/static/css/main.css | 507 ++++++++-----
Web/static/img/arrows.png | Bin 0 -> 219 bytes
Web/static/img/audios_controls.png | Bin 3706 -> 4259 bytes
Web/static/img/hide.png | Bin 184 -> 0 bytes
Web/static/img/show.png | Bin 169 -> 0 bytes
Web/static/js/al_music.js | 349 ++++++---
Web/static/js/al_navigation.js | 190 +++++
Web/static/js/al_wall.js | 59 +-
Web/static/js/openvk.cls.js | 132 +---
install/sqls/00047-unlisted-playlists.sql | 1 +
locales/en.strings | 44 +-
locales/ru.strings | 48 +-
locales/uk.strings | 4 -
themepacks/midnight/stylesheet.css | 64 +-
themepacks/openvk_modern/stylesheet.css | 84 +--
55 files changed, 2451 insertions(+), 1556 deletions(-)
delete mode 100644 ServiceAPI/Search.php
create mode 100644 Web/Presenters/templates/Audio/playlistListView.xml
create mode 100644 Web/Presenters/templates/components/content_error.xml
create mode 100644 Web/static/img/arrows.png
delete mode 100644 Web/static/img/hide.png
delete mode 100644 Web/static/img/show.png
create mode 100644 Web/static/js/al_navigation.js
create mode 100644 install/sqls/00047-unlisted-playlists.sql
diff --git a/ServiceAPI/Search.php b/ServiceAPI/Search.php
deleted file mode 100644
index de0f9d2c3..000000000
--- a/ServiceAPI/Search.php
+++ /dev/null
@@ -1,76 +0,0 @@
-user = $user;
- $this->users = new Users;
- $this->clubs = new Clubs;
- $this->videos = new Videos;
- }
-
- function fastSearch(string $query, string $type = "users", callable $resolve, callable $reject)
- {
- if($query == "" || strlen($query) < 3)
- $reject(12, "No input or input < 3");
-
- $repo;
- $sort;
-
- switch($type) {
- default:
- case "users":
- $repo = (new Users);
- $sort = "rating DESC";
-
- break;
- case "groups":
- $repo = (new Clubs);
- $sort = "id ASC";
-
- break;
- case "videos":
- $repo = (new Videos);
- $sort = "created ASC";
-
- break;
- }
-
- $res = $repo->find($query, ["doNotSearchMe" => $this->user->getId(), "doNotSearchPrivate" => true,], $sort);
-
- $results = array_slice(iterator_to_array($res), 0, 5);
-
- $count = sizeof($results);
-
- $arr = [
- "count" => $count,
- "items" => []
- ];
-
- if(sizeof($results) < 1) {
- $reject(2, "No results");
- }
-
- foreach($results as $res) {
- $arr["items"][] = [
- "id" => $res->getId(),
- "name" => $type == "users" ? $res->getCanonicalName() : $res->getName(),
- "avatar" => $type != "videos" ? $res->getAvatarUrl() : $res->getThumbnailURL(),
- "url" => $type != "videos" ? $res->getUrl() : "/video".$res->getPrettyId(),
- "description" => ovk_proc_strtr($res->getDescription() ?? "...", 40)
- ];
- }
-
- $resolve($arr);
- }
-}
diff --git a/VKAPI/Handlers/Audio.php b/VKAPI/Handlers/Audio.php
index 004daef49..e0991af92 100644
--- a/VKAPI/Handlers/Audio.php
+++ b/VKAPI/Handlers/Audio.php
@@ -581,13 +581,18 @@ function getAlbums(int $owner_id = 0, int $offset = 0, int $count = 50, int $dro
];
}
- function searchAlbums(string $query, int $offset = 0, int $limit = 25, int $drop_private = 0): object
+ function searchAlbums(string $query = '', int $offset = 0, int $limit = 25, int $drop_private = 0, int $order = 0, int $from_me = 0): object
{
$this->requireUser();
$playlists = [];
- $search = (new Audios)->searchPlaylists($query)->offsetLimit($offset, $limit);
- foreach($search as $playlist) {
+ $params = [];
+ $order_str = (['id', 'length', 'listens'][$order] ?? 'id');
+ if($from_me === 1)
+ $params['from_me'] = $this->getUser()->getId();
+
+ $search = (new Audios)->findPlaylists($query, $params, ['type' => $order_str, 'invert' => false]);
+ foreach($search->offsetLimit($offset, $limit) as $playlist) {
if(!$playlist->canBeViewedBy($this->getUser())) {
if($drop_private == 0)
$playlists[] = NULL;
@@ -599,7 +604,7 @@ function searchAlbums(string $query, int $offset = 0, int $limit = 25, int $drop
}
return (object) [
- "count" => sizeof($playlists),
+ "count" => $search->size(),
"items" => $playlists,
];
}
diff --git a/VKAPI/Handlers/Groups.php b/VKAPI/Handlers/Groups.php
index ca67e7b76..f87061911 100644
--- a/VKAPI/Handlers/Groups.php
+++ b/VKAPI/Handlers/Groups.php
@@ -252,23 +252,30 @@ function getById(string $group_ids = "", string $group_id = "", string $fields =
return $response;
}
- function search(string $q, int $offset = 0, int $count = 100)
+ function search(string $q, int $offset = 0, int $count = 100, string $fields = "screen_name,is_admin,is_member,is_advertiser,photo_50,photo_100,photo_200")
{
+ if($count > 100) {
+ $this->fail(100, "One of the parameters specified was missing or invalid: count should be less or equal to 100");
+ }
+
$clubs = new ClubsRepo;
$array = [];
$find = $clubs->find($q);
- foreach ($find as $group)
+ foreach ($find->offsetLimit($offset, $count) as $group)
$array[] = $group->getId();
+
+ if(!$array || sizeof($array) < 1) {
+ return (object) [
+ "count" => 0,
+ "items" => [],
+ ];
+ }
return (object) [
"count" => $find->size(),
- "items" => $this->getById(implode(',', $array), "", "is_admin,is_member,is_advertiser,photo_50,photo_100,photo_200", $offset, $count)
- /*
- * As there is no thing as "fields" by the original documentation
- * i'll just bake this param by the example shown here: https://dev.vk.com/method/groups.search
- */
+ "items" => $this->getById(implode(',', $array), "", $fields)
];
}
diff --git a/VKAPI/Handlers/Users.php b/VKAPI/Handlers/Users.php
index 132b62044..704823be8 100644
--- a/VKAPI/Handlers/Users.php
+++ b/VKAPI/Handlers/Users.php
@@ -263,6 +263,9 @@ function get(string $user_ids = "0", string $fields = "", int $offset = 0, int $
case 'is_dead':
$response[$i]->is_dead = $usr->isDead();
break;
+ case 'nickname':
+ $response[$i]->nickname = $usr->getPseudo();
+ break;
}
}
@@ -314,89 +317,90 @@ function search(string $q,
int $count = 100,
string $city = "",
string $hometown = "",
- int $sex = 2,
- int $status = 0, # это про marital status
+ int $sex = 3,
+ int $status = 0, # marital_status
bool $online = false,
- # дальше идут параметры которых нету в vkapi но есть на сайте
- string $profileStatus = "", # а это уже нормальный статус
+ # non standart params:
int $sort = 0,
- int $before = 0,
- int $politViews = 0,
- int $after = 0,
- string $interests = "",
+ int $polit_views = 0,
string $fav_music = "",
string $fav_films = "",
string $fav_shows = "",
- string $fav_books = "",
- string $fav_quotes = ""
+ string $fav_books = ""
)
{
- $users = new UsersRepo;
-
- $sortg = "id ASC";
+ if($count > 100) {
+ $this->fail(100, "One of the parameters specified was missing or invalid: count should be less or equal to 100");
+ }
- $nfilds = $fields;
+ $users = new UsersRepo;
+ $output_sort = ['type' => 'id', 'invert' => false];
+ $output_params = [
+ "ignore_private" => true,
+ ];
switch($sort) {
+ default:
case 0:
- $sortg = "id DESC";
+ $output_sort = ['type' => 'id', 'invert' => false];
break;
case 1:
- $sortg = "id ASC";
- break;
- case 2:
- $sortg = "first_name DESC";
- break;
- case 3:
- $sortg = "first_name ASC";
+ $output_sort = ['type' => 'id', 'invert' => true];
break;
case 4:
- $sortg = "rating DESC";
+ $output_sort = ['type' => 'rating', 'invert' => false];
+ break;
+ }
- if(!str_contains($nfilds, "rating")) {
- $nfilds .= "rating";
- }
+ if(!empty($city))
+ $output_params['city'] = $city;
- break;
- case 5:
- $sortg = "rating DESC";
+ if(!empty($hometown))
+ $output_params['hometown'] = $hometown;
- if(!str_contains($nfilds, "rating")) {
- $nfilds .= "rating";
- }
+ if($sex != 3)
+ $output_params['gender'] = $sex;
- break;
- }
+ if($status != 0)
+ $output_params['marital_status'] = $status;
+
+ if($polit_views != 0)
+ $output_params['polit_views'] = $polit_views;
- $array = [];
+ if(!empty($interests))
+ $output_params['interests'] = $interests;
- $parameters = [
- "city" => !empty($city) ? $city : NULL,
- "hometown" => !empty($hometown) ? $hometown : NULL,
- "gender" => $sex < 2 ? $sex : NULL,
- "maritalstatus" => (bool)$status ? $status : NULL,
- "politViews" => (bool)$politViews ? $politViews : NULL,
- "is_online" => $online ? 1 : NULL,
- "status" => !empty($profileStatus) ? $profileStatus : NULL,
- "before" => $before != 0 ? $before : NULL,
- "after" => $after != 0 ? $after : NULL,
- "interests" => !empty($interests) ? $interests : NULL,
- "fav_music" => !empty($fav_music) ? $fav_music : NULL,
- "fav_films" => !empty($fav_films) ? $fav_films : NULL,
- "fav_shows" => !empty($fav_shows) ? $fav_shows : NULL,
- "fav_books" => !empty($fav_books) ? $fav_books : NULL,
- "fav_quotes" => !empty($fav_quotes) ? $fav_quotes : NULL,
- "doNotSearchPrivate" => true,
- ];
+ if(!empty($fav_music))
+ $output_params['fav_music'] = $fav_music;
+
+ if(!empty($fav_films))
+ $output_params['fav_films'] = $fav_films;
- $find = $users->find($q, $parameters, $sortg);
+ if(!empty($fav_shows))
+ $output_params['fav_shows'] = $fav_shows;
+
+ if(!empty($fav_books))
+ $output_params['fav_books'] = $fav_books;
- foreach ($find as $user)
+ if($online)
+ $output_params['is_online'] = 1;
+
+ $array = [];
+ $find = $users->find($q, $output_params, $output_sort);
+
+ foreach ($find->offsetLimit($offset, $count) as $user)
$array[] = $user->getId();
+ if(!$array || sizeof($array) < 1) {
+ return (object) [
+ "count" => 0,
+ "items" => [],
+ ];
+ }
+
return (object) [
- "count" => $find->size(),
- "items" => $this->get(implode(',', $array), $nfilds, $offset, $count)
+ "count" => $find->size(),
+ "items" => $this->get(implode(',', $array), $fields)
];
}
diff --git a/VKAPI/Handlers/Video.php b/VKAPI/Handlers/Video.php
index f468686dc..d933f728e 100755
--- a/VKAPI/Handlers/Video.php
+++ b/VKAPI/Handlers/Video.php
@@ -60,4 +60,60 @@ function get(int $owner_id, string $videos = "", int $offset = 0, int $count = 3
];
}
}
+
+ function search(string $q = '', int $sort = 0, int $offset = 0, int $count = 10, bool $extended = false, string $fields = ''): object
+ {
+ $this->requireUser();
+
+ $params = [];
+ $db_sort = ['type' => 'id', 'invert' => false];
+ $videos = (new VideosRepo)->find($q, $params, $db_sort);
+ $items = iterator_to_array($videos->offsetLimit($offset, $count));
+ $count = $videos->size();
+
+ $return_items = [];
+ $profiles = [];
+ $groups = [];
+ foreach($items as $item)
+ $return_item = $item->getApiStructure($this->getUser());
+ $return_item = $return_item->video;
+ $return_items[] = $return_item;
+
+ if($return_item['owner_id']) {
+ if($return_item['owner_id'] > 0)
+ $profiles[] = $return_item['owner_id'];
+ else
+ $groups[] = abs($return_item['owner_id']);
+ }
+
+ if($extended) {
+ $profiles = array_unique($profiles);
+ $groups = array_unique($groups);
+
+ $profilesFormatted = [];
+ $groupsFormatted = [];
+
+ foreach($profiles as $prof) {
+ $profile = (new UsersRepo)->get($prof);
+ $profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields);
+ }
+
+ foreach($groups as $gr) {
+ $group = (new ClubsRepo)->get($gr);
+ $groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields);
+ }
+
+ return (object) [
+ "count" => $count,
+ "items" => $return_items,
+ "profiles" => $profilesFormatted,
+ "groups" => $groupsFormatted,
+ ];
+ }
+
+ return (object) [
+ "count" => $count,
+ "items" => $return_items,
+ ];
+ }
}
diff --git a/Web/Models/Entities/Audio.php b/Web/Models/Entities/Audio.php
index 6be207ddd..3b998f329 100644
--- a/Web/Models/Entities/Audio.php
+++ b/Web/Models/Entities/Audio.php
@@ -152,6 +152,11 @@ function getName(): string
return $this->getPerformer() . " — " . $this->getTitle();
}
+ function getDownloadName(): string
+ {
+ return preg_replace('/[\\/:*?"<>|]/', '_', str_replace(' ', '_', $this->getName()));
+ }
+
function getGenre(): ?string
{
return $this->getRecord()->genre;
diff --git a/Web/Models/Entities/Club.php b/Web/Models/Entities/Club.php
index dc1c356e7..c919b059b 100644
--- a/Web/Models/Entities/Club.php
+++ b/Web/Models/Entities/Club.php
@@ -437,7 +437,7 @@ function getAudiosCollectionSize()
return (new \openvk\Web\Models\Repositories\Audios)->getClubCollectionSize($this);
}
- function toVkApiStruct(?User $user = NULL): object
+ function toVkApiStruct(?User $user = NULL, string $fields = ''): object
{
$res = (object) [];
diff --git a/Web/Models/Entities/Comment.php b/Web/Models/Entities/Comment.php
index 200d7a168..fd32c0b8b 100644
--- a/Web/Models/Entities/Comment.php
+++ b/Web/Models/Entities/Comment.php
@@ -140,4 +140,31 @@ function canBeEditedBy(?User $user = NULL): bool
return $user->getId() == $this->getOwner(false)->getId();
}
+
+ function getTargetURL(): string
+ {
+ $target = $this->getTarget();
+ $target_name = 'wall';
+
+ if(!$target) {
+ return '/404';
+ }
+
+ switch(get_class($target)) {
+ case 'openvk\Web\Models\Entities\Note':
+ $target_name = 'note';
+ break;
+ case 'openvk\Web\Models\Entities\Photo':
+ $target_name = 'photo';
+ break;
+ case 'openvk\Web\Models\Entities\Video':
+ $target_name = 'video';
+ break;
+ case 'openvk\Web\Models\Entities\Topic':
+ $target_name = 'topic';
+ break;
+ }
+
+ return $target_name . $target->getPrettyId();
+ }
}
diff --git a/Web/Models/Entities/Playlist.php b/Web/Models/Entities/Playlist.php
index c027a0387..ac36b4f34 100644
--- a/Web/Models/Entities/Playlist.php
+++ b/Web/Models/Entities/Playlist.php
@@ -41,6 +41,21 @@ function getLength(): int
{
return $this->getRecord()->length;
}
+
+ function fetchClassic(int $offset = 0, ?int $limit = NULL): \Traversable
+ {
+ $related = $this->getRecord()->related("$this->relTableName.collection")
+ ->limit($limit ?? OPENVK_DEFAULT_PER_PAGE, $offset)
+ ->order("index ASC");
+
+ foreach($related as $rel) {
+ $media = $rel->ref($this->entityTableName, "media");
+ if(!$media)
+ continue;
+
+ yield new $this->entityClassName($media);
+ }
+ }
function getAudios(int $offset = 0, ?int $limit = NULL, ?int $shuffleSeed = NULL): \Traversable
{
@@ -162,6 +177,7 @@ function toVkApiStruct(?User $user = NULL): object
"bookmarked" => $this->isBookmarkedBy($user),
"listens" => $this->getListens(),
"cover_url" => $this->getCoverURL(),
+ "searchable" => !$this->isUnlisted(),
];
}
@@ -199,6 +215,11 @@ function getCoverPhotoId(): ?int
{
return $this->getRecord()->cover_photo_id;
}
+
+ function getCoverPhoto(): ?Photo
+ {
+ return (new Photos)->get((int) $this->getRecord()->cover_photo_id);
+ }
function canBeModifiedBy(User $user): bool
{
@@ -253,4 +274,9 @@ function getMetaDescription(): string
return implode(" • ", $props);
}
+
+ function isUnlisted(): bool
+ {
+ return (bool)$this->getRecord()->unlisted;
+ }
}
diff --git a/Web/Models/Entities/Traits/TRichText.php b/Web/Models/Entities/Traits/TRichText.php
index dc78a0345..0f02a8ab4 100644
--- a/Web/Models/Entities/Traits/TRichText.php
+++ b/Web/Models/Entities/Traits/TRichText.php
@@ -123,7 +123,7 @@ function getText(bool $html = true): string
$text = preg_replace_callback("%([\n\r\s]|^)(\#([\p{L}_0-9][\p{L}_0-9\(\)\-\']+[\p{L}_0-9\(\)]|[\p{L}_0-9]{1,2}))%Xu", function($m) {
$slug = rawurlencode($m[3]);
- return "$m[1]$m[2]";
+ return "$m[1]$m[2]";
}, $text);
$text = $this->formatEmojis($text);
diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php
index e8756550c..18d7fea9e 100644
--- a/Web/Models/Entities/User.php
+++ b/Web/Models/Entities/User.php
@@ -1321,17 +1321,22 @@ function canBeViewedBy(?User $user = NULL): bool
return true;
}
- function isClosed()
+ function isClosed(): bool
{
return (bool) $this->getProfileType();
}
+
+ function isHideFromGlobalFeedEnabled(): bool
+ {
+ return $this->isClosed();
+ }
function getRealId()
{
return $this->getId();
}
- function toVkApiStruct(?User $user = NULL): object
+ function toVkApiStruct(?User $user = NULL, string $fields = ''): object
{
$res = (object) [];
@@ -1349,8 +1354,16 @@ function toVkApiStruct(?User $user = NULL): object
if(!is_null($user))
$res->can_access_closed = (bool)$this->canBeViewedBy($user);
- if($user->isDead())
- $res->is_dead = 1;
+ if(!is_array($fields))
+ $fields = explode(',', $fields);
+
+ foreach($fields as $field) {
+ switch($field) {
+ case 'is_dead':
+ $res->is_dead = $user->isDead();
+ break;
+ }
+ }
return $res;
}
diff --git a/Web/Models/Entities/Video.php b/Web/Models/Entities/Video.php
index 2c1c0b051..a4d0b8987 100644
--- a/Web/Models/Entities/Video.php
+++ b/Web/Models/Entities/Video.php
@@ -181,8 +181,8 @@ function setLink(string $link): string
{
if(preg_match(file_get_contents(__DIR__ . "/../VideoDrivers/regex/youtube.txt"), $link, $matches)) {
$pointer = "YouTube:$matches[1]";
- } else if(preg_match(file_get_contents(__DIR__ . "/../VideoDrivers/regex/vimeo.txt"), $link, $matches)) {
- $pointer = "Vimeo:$matches[1]";
+ /*} else if(preg_match(file_get_contents(__DIR__ . "/../VideoDrivers/regex/vimeo.txt"), $link, $matches)) {
+ $pointer = "Vimeo:$matches[1]";*/
} else {
throw new ISE("Invalid link");
}
diff --git a/Web/Models/Repositories/Applications.php b/Web/Models/Repositories/Applications.php
index 0687856e6..c09060676 100644
--- a/Web/Models/Repositories/Applications.php
+++ b/Web/Models/Repositories/Applications.php
@@ -67,11 +67,21 @@ function getInstalledCount(User $user): int
return sizeof($this->appRels->where("user", $user->getId()));
}
- function find(string $query, array $pars = [], string $sort = "id"): Util\EntityStream
+ function find(string $query = "", array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream
{
- $query = "%$query%";
+ $query = "%$query%";
$result = $this->apps->where("CONCAT_WS(' ', name, description) LIKE ?", $query)->where("enabled", 1);
+ $order_str = 'id';
+
+ switch($order['type']) {
+ case 'id':
+ $order_str = 'id ' . ($order['invert'] ? 'ASC' : 'DESC');
+ break;
+ }
+
+ if($order_str)
+ $result->order($order_str);
- return new Util\EntityStream("Application", $result->order("$sort"));
+ return new Util\EntityStream("Application", $result);
}
}
\ No newline at end of file
diff --git a/Web/Models/Repositories/Audios.php b/Web/Models/Repositories/Audios.php
index 64457299f..73f5ac293 100644
--- a/Web/Models/Repositories/Audios.php
+++ b/Web/Models/Repositories/Audios.php
@@ -208,7 +208,7 @@ function search(string $query, int $sortMode = 0, bool $performerOnly = false, b
$search = $this->audios->where([
"unlisted" => 0,
"deleted" => 0,
- ])->where("MATCH ($columns) AGAINST (? WITH QUERY EXPANSION)", $query)->order($order);
+ ])->where("MATCH ($columns) AGAINST (? IN BOOLEAN MODE)", "%$query%")->order($order);
if($withLyrics)
$search = $search->where("lyrics IS NOT NULL");
@@ -219,6 +219,7 @@ function search(string $query, int $sortMode = 0, bool $performerOnly = false, b
function searchPlaylists(string $query): EntityStream
{
$search = $this->playlists->where([
+ "unlisted" => 0,
"deleted" => 0,
])->where("MATCH (`name`, `description`) AGAINST (? IN BOOLEAN MODE)", $query);
@@ -243,53 +244,72 @@ function isAdded(int $user_id, int $audio_id): bool
])->fetch());
}
- function find(string $query, array $pars = [], string $sort = "id DESC", int $page = 1, ?int $perPage = NULL): \Traversable
+ function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false], int $page = 1, ?int $perPage = NULL): \Traversable
{
- $query = "%$query%";
+ $query = "%$query%";
$result = $this->audios->where([
"unlisted" => 0,
"deleted" => 0,
]);
+ $order_str = (in_array($order['type'], ['id', 'length', 'listens']) ? $order['type'] : 'id') . ' ' . ($order['invert'] ? 'ASC' : 'DESC');;
- $notNullParams = [];
-
- foreach($pars as $paramName => $paramValue)
- if($paramName != "before" && $paramName != "after" && $paramName != "only_performers")
- $paramValue != NULL ? $notNullParams+=["$paramName" => "%$paramValue%"] : NULL;
- else
- $paramValue != NULL ? $notNullParams+=["$paramName" => "$paramValue"] : NULL;
-
- $nnparamsCount = sizeof($notNullParams);
-
- if($notNullParams["only_performers"] == "1") {
+ if($params["only_performers"] == "1") {
$result->where("performer LIKE ?", $query);
} else {
$result->where("name LIKE ? OR performer LIKE ?", $query, $query);
}
- if($nnparamsCount > 0) {
- foreach($notNullParams as $paramName => $paramValue) {
- switch($paramName) {
- case "before":
- $result->where("created < ?", $paramValue);
- break;
- case "after":
- $result->where("created > ?", $paramValue);
- break;
- case "with_lyrics":
- $result->where("lyrics IS NOT NULL");
- break;
- }
+ foreach($params as $paramName => $paramValue) {
+ if(is_null($paramValue) || $paramValue == '') continue;
+
+ switch($paramName) {
+ case "before":
+ $result->where("created < ?", $paramValue);
+ break;
+ case "after":
+ $result->where("created > ?", $paramValue);
+ break;
+ case "with_lyrics":
+ $result->where("lyrics IS NOT NULL");
+ break;
+ case 'genre':
+ if($paramValue == 'any') break;
+
+ $result->where("genre", $paramValue);
+ break;
}
}
- return new Util\EntityStream("Audio", $result->order($sort));
+ if($order_str)
+ $result->order($order_str);
+
+ return new Util\EntityStream("Audio", $result);
}
- function findPlaylists(string $query, int $page = 1, ?int $perPage = NULL): \Traversable
+ function findPlaylists(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false]): \Traversable
{
- $query = "%$query%";
- $result = $this->playlists->where("name LIKE ?", $query);
+ $query = "%$query%";
+ $result = $this->playlists->where([
+ "deleted" => 0,
+ ])->where("CONCAT_WS(' ', name, description) LIKE ?", $query);
+ $order_str = (in_array($order['type'], ['id', 'length', 'listens']) ? $order['type'] : 'id') . ' ' . ($order['invert'] ? 'ASC' : 'DESC');
+
+ if(is_null($params['from_me']) || empty($params['from_me']))
+ $result->where(["unlisted" => 0]);
+
+ foreach($params as $paramName => $paramValue) {
+ if(is_null($paramValue) || $paramValue == '') continue;
+
+ switch($paramName) {
+ # БУДЬ МАКСИМАЛЬНО АККУРАТЕН С ДАННЫМ ПАРАМЕТРОМ
+ case "from_me":
+ $result->where("owner", $paramValue);
+ break;
+ }
+ }
+
+ if($order_str)
+ $result->order($order_str);
return new Util\EntityStream("Playlist", $result);
}
diff --git a/Web/Models/Repositories/Clubs.php b/Web/Models/Repositories/Clubs.php
index d77eac638..b393952fe 100644
--- a/Web/Models/Repositories/Clubs.php
+++ b/Web/Models/Repositories/Clubs.php
@@ -42,13 +42,25 @@ function get(int $id): ?Club
{
return $this->toClub($this->clubs->get($id));
}
-
- function find(string $query, array $pars = [], string $sort = "id DESC", int $page = 1, ?int $perPage = NULL): \Traversable
+
+ function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false], int $page = 1, ?int $perPage = NULL): \Traversable
{
- $query = "%$query%";
- $result = $this->clubs->where("name LIKE ? OR about LIKE ?", $query, $query);
-
- return new Util\EntityStream("Club", $result->order($sort));
+ $query = "%$query%";
+ $result = $this->clubs;
+ $order_str = 'id';
+
+ switch($order['type']) {
+ case 'id':
+ $order_str = 'id ' . ($order['invert'] ? 'ASC' : 'DESC');
+ break;
+ }
+
+ $result = $result->where("name LIKE ? OR about LIKE ?", $query, $query);
+
+ if($order_str)
+ $result->order($order_str);
+
+ return new Util\EntityStream("Club", $result);
}
function getCount(): int
diff --git a/Web/Models/Repositories/Comments.php b/Web/Models/Repositories/Comments.php
index f4b8e5ace..811d1358c 100644
--- a/Web/Models/Repositories/Comments.php
+++ b/Web/Models/Repositories/Comments.php
@@ -60,34 +60,31 @@ function getCommentsCountByTarget(Postable $target): int
]));
}
- function find(string $query = "", array $pars = [], string $sort = "id"): Util\EntityStream
+ function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream
{
- $query = "%$query%";
+ $result = $this->comments->where("content LIKE ?", "%$query%")->where("deleted", 0);
+ $order_str = 'id';
- $notNullParams = [];
-
- foreach($pars as $paramName => $paramValue)
- if($paramName != "before" && $paramName != "after")
- $paramValue != NULL ? $notNullParams+=["$paramName" => "%$paramValue%"] : NULL;
- else
- $paramValue != NULL ? $notNullParams+=["$paramName" => "$paramValue"] : NULL;
-
- $result = $this->comments->where("content LIKE ?", $query)->where("deleted", 0);
- $nnparamsCount = sizeof($notNullParams);
+ switch($order['type']) {
+ case 'id':
+ $order_str = 'created ' . ($order['invert'] ? 'ASC' : 'DESC');
+ break;
+ }
- if($nnparamsCount > 0) {
- foreach($notNullParams as $paramName => $paramValue) {
- switch($paramName) {
- case "before":
- $result->where("created < ?", $paramValue);
- break;
- case "after":
- $result->where("created > ?", $paramValue);
- break;
- }
+ foreach($params as $paramName => $paramValue) {
+ switch($paramName) {
+ case "before":
+ $result->where("created < ?", $paramValue);
+ break;
+ case "after":
+ $result->where("created > ?", $paramValue);
+ break;
}
}
- return new Util\EntityStream("Comment", $result->order("$sort"));
+ if($order_str)
+ $result->order($order_str);
+
+ return new Util\EntityStream("Comment", $result);
}
}
diff --git a/Web/Models/Repositories/Posts.php b/Web/Models/Repositories/Posts.php
index fb32fe6e5..36082f245 100644
--- a/Web/Models/Repositories/Posts.php
+++ b/Web/Models/Repositories/Posts.php
@@ -154,36 +154,45 @@ function getPostById(int $wall, int $post, bool $forceSuggestion = false): ?Post
}
- function find(string $query = "", array $pars = [], string $sort = "id"): Util\EntityStream
+ function find(string $query = "", array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream
{
- $query = "%$query%";
+ $query = "%$query%";
+ $result = $this->posts->where("content LIKE ?", $query)->where("deleted", 0)->where("suggested", 0);
+ $order_str = 'id';
- $notNullParams = [];
+ switch($order['type']) {
+ case 'id':
+ $order_str = 'created ' . ($order['invert'] ? 'ASC' : 'DESC');
+ break;
+ }
- foreach($pars as $paramName => $paramValue)
- if($paramName != "before" && $paramName != "after")
- $paramValue != NULL ? $notNullParams+=["$paramName" => "%$paramValue%"] : NULL;
- else
- $paramValue != NULL ? $notNullParams+=["$paramName" => "$paramValue"] : NULL;
+ foreach($params as $paramName => $paramValue) {
+ if(is_null($paramValue) || $paramValue == '') continue;
- $result = $this->posts->where("content LIKE ?", $query)->where("deleted", 0)->where("suggested", 0);
- $nnparamsCount = sizeof($notNullParams);
-
- if($nnparamsCount > 0) {
- foreach($notNullParams as $paramName => $paramValue) {
- switch($paramName) {
- case "before":
- $result->where("created < ?", $paramValue);
- break;
- case "after":
- $result->where("created > ?", $paramValue);
- break;
- }
+ switch($paramName) {
+ case "before":
+ $result->where("created < ?", $paramValue);
+ break;
+ case "after":
+ $result->where("created > ?", $paramValue);
+ break;
+ /*case 'die_in_agony':
+ $result->where("nsfw", 1);
+ break;
+ case 'ads':
+ $result->where("ad", 1);
+ break;*/
+ # БУДЬ МАКСИМАЛЬНО АККУРАТЕН С ДАННЫМ ПАРАМЕТРОМ
+ case 'from_me':
+ $result->where("owner", $paramValue);
+ break;
}
}
+ if($order_str)
+ $result->order($order_str);
- return new Util\EntityStream("Post", $result->order("$sort"));
+ return new Util\EntityStream("Post", $result);
}
function getPostCountOnUserWall(int $user): int
diff --git a/Web/Models/Repositories/Users.php b/Web/Models/Repositories/Users.php
index e826f3b3c..cc75b50f0 100644
--- a/Web/Models/Repositories/Users.php
+++ b/Web/Models/Repositories/Users.php
@@ -54,94 +54,76 @@ function getByChandlerUser(?ChandlerUser $user): ?User
return $user ? $this->getByChandlerUserId($user->getId()) : NULL;
}
- function find(string $query, array $pars = [], string $sort = "id DESC"): Util\EntityStream
+ function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream
{
- $query = "%$query%";
+ $query = "%$query%";
$result = $this->users->where("CONCAT_WS(' ', first_name, last_name, pseudo, shortcode) LIKE ?", $query)->where("deleted", 0);
-
- $notNullParams = [];
- $nnparamsCount = 0;
-
- foreach($pars as $paramName => $paramValue)
- if($paramName != "before" && $paramName != "after" && $paramName != "gender" && $paramName != "maritalstatus" && $paramName != "politViews" && $paramName != "doNotSearchMe")
- $paramValue != NULL ? $notNullParams += ["$paramName" => "%$paramValue%"] : NULL;
- else
- $paramValue != NULL ? $notNullParams += ["$paramName" => "$paramValue"] : NULL;
-
- $nnparamsCount = sizeof($notNullParams);
-
- if($nnparamsCount > 0) {
- foreach($notNullParams as $paramName => $paramValue) {
- switch($paramName) {
- case "hometown":
- $result->where("hometown LIKE ?", $paramValue);
- break;
- case "city":
- $result->where("city LIKE ?", $paramValue);
- break;
- case "maritalstatus":
- $result->where("marital_status ?", $paramValue);
- break;
- case "status":
- $result->where("status LIKE ?", $paramValue);
- break;
- case "politViews":
- $result->where("polit_views ?", $paramValue);
- break;
- case "email":
- $result->where("email_contact LIKE ?", $paramValue);
- break;
- case "telegram":
- $result->where("telegram LIKE ?", $paramValue);
- break;
- case "site":
- $result->where("telegram LIKE ?", $paramValue);
- break;
- case "address":
- $result->where("address LIKE ?", $paramValue);
- break;
- case "is_online":
- $result->where("online >= ?", time() - 900);
- break;
- case "interests":
- $result->where("interests LIKE ?", $paramValue);
- break;
- case "fav_mus":
- $result->where("fav_music LIKE ?", $paramValue);
- break;
- case "fav_films":
- $result->where("fav_films LIKE ?", $paramValue);
- break;
- case "fav_shows":
- $result->where("fav_shows LIKE ?", $paramValue);
- break;
- case "fav_books":
- $result->where("fav_books LIKE ?", $paramValue);
- break;
- case "fav_quote":
- $result->where("fav_quote LIKE ?", $paramValue);
- break;
- case "before":
- $result->where("UNIX_TIMESTAMP(since) < ?", $paramValue);
- break;
- case "after":
- $result->where("UNIX_TIMESTAMP(since) > ?", $paramValue);
- break;
- case "gender":
- $result->where("sex ?", $paramValue);
- break;
- case "doNotSearchMe":
- $result->where("id !=", $paramValue);
- break;
- case "doNotSearchPrivate":
- $result->where("profile_type", 0);
- break;
- }
+ $order_str = 'id';
+
+ switch($order['type']) {
+ case 'id':
+ case 'reg_date':
+ $order_str = 'id ' . ($order['invert'] ? 'ASC' : 'DESC');
+ break;
+ case 'rating':
+ $order_str = 'rating DESC';
+ break;
+ }
+
+ foreach($params as $paramName => $paramValue) {
+ if(is_null($paramValue) || $paramValue == '') continue;
+
+ switch($paramName) {
+ case "hometown":
+ $result->where("hometown LIKE ?", "%$paramValue%");
+ break;
+ case "city":
+ $result->where("city LIKE ?", "%$paramValue%");
+ break;
+ case "marital_status":
+ $result->where("marital_status ?", $paramValue);
+ break;
+ case "polit_views":
+ $result->where("polit_views ?", $paramValue);
+ break;
+ case "is_online":
+ $result->where("online >= ?", time() - 900);
+ break;
+ case "fav_mus":
+ $result->where("fav_music LIKE ?", "%$paramValue%");
+ break;
+ case "fav_films":
+ $result->where("fav_films LIKE ?", "%$paramValue%");
+ break;
+ case "fav_shows":
+ $result->where("fav_shows LIKE ?", "%$paramValue%");
+ break;
+ case "fav_books":
+ $result->where("fav_books LIKE ?", "%$paramValue%");
+ break;
+ case "before":
+ $result->where("UNIX_TIMESTAMP(since) < ?", $paramValue);
+ break;
+ case "after":
+ $result->where("UNIX_TIMESTAMP(since) > ?", $paramValue);
+ break;
+ case "gender":
+ if((int) $paramValue == 3) break;
+ $result->where("sex ?", (int) $paramValue);
+ break;
+ case "ignore_id":
+ $result->where("id != ?", $paramValue);
+ break;
+ case "ignore_private":
+ $result->where("profile_type", 0);
+ break;
}
}
+ if($order_str)
+ $result->order($order_str);
- return new Util\EntityStream("User", $result->order($sort));
+ return new Util\EntityStream("User", $result);
}
function getStatistics(): object
diff --git a/Web/Models/Repositories/Videos.php b/Web/Models/Repositories/Videos.php
index 2d41c3f9a..e91c226d1 100644
--- a/Web/Models/Repositories/Videos.php
+++ b/Web/Models/Repositories/Videos.php
@@ -46,36 +46,37 @@ function getUserVideosCount(User $user): int
return sizeof($this->videos->where("owner", $user->getId())->where(["deleted" => 0, "unlisted" => 0]));
}
- function find(string $query = "", array $pars = [], string $sort = "id"): Util\EntityStream
+ function find(string $query = "", array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream
{
- $query = "%$query%";
-
- $notNullParams = [];
-
- foreach($pars as $paramName => $paramValue)
- if($paramName != "before" && $paramName != "after")
- $paramValue != NULL ? $notNullParams+=["$paramName" => "%$paramValue%"] : NULL;
- else
- $paramValue != NULL ? $notNullParams+=["$paramName" => "$paramValue"] : NULL;
-
+ $query = "%$query%";
$result = $this->videos->where("CONCAT_WS(' ', name, description) LIKE ?", $query)->where("deleted", 0);
- $nnparamsCount = sizeof($notNullParams);
+ $order_str = 'id';
+
+ switch($order['type']) {
+ case 'id':
+ $order_str = 'id ' . ($order['invert'] ? 'ASC' : 'DESC');
+ break;
+ }
- if($nnparamsCount > 0) {
- foreach($notNullParams as $paramName => $paramValue) {
- switch($paramName) {
- case "before":
- $result->where("created < ?", $paramValue);
- break;
- case "after":
- $result->where("created > ?", $paramValue);
- break;
- }
+ foreach($params as $paramName => $paramValue) {
+ switch($paramName) {
+ case "before":
+ $result->where("created < ?", $paramValue);
+ break;
+ case "after":
+ $result->where("created > ?", $paramValue);
+ break;
+ case 'only_youtube':
+ if((int) $paramValue != 1) break;
+ $result->where("link != ?", 'NULL');
+ break;
}
}
+ if($order_str)
+ $result->order($order_str);
- return new Util\EntityStream("Video", $result->order("$sort"));
+ return new Util\EntityStream("Video", $result);
}
function getLastVideo(User $user)
diff --git a/Web/Presenters/AudioPresenter.php b/Web/Presenters/AudioPresenter.php
index 8ec17012d..7e2825c13 100644
--- a/Web/Presenters/AudioPresenter.php
+++ b/Web/Presenters/AudioPresenter.php
@@ -75,7 +75,7 @@ function renderList(?int $owner = NULL, ?string $mode = "list"): void
if (!$entity || $entity->isBanned())
$this->redirect("/playlists" . $this->user->id);
- $playlists = $this->audios->getPlaylistsByClub($entity, $page, 10);
+ $playlists = $this->audios->getPlaylistsByClub($entity, $page, OPENVK_DEFAULT_PER_PAGE);
$playlistsCount = $this->audios->getClubPlaylistsCount($entity);
} else {
$entity = (new Users)->get($owner);
@@ -85,7 +85,7 @@ function renderList(?int $owner = NULL, ?string $mode = "list"): void
if(!$entity->getPrivacyPermission("audios.read", $this->user->identity))
$this->flashFail("err", tr("forbidden"), tr("forbidden_comment"));
- $playlists = $this->audios->getPlaylistsByUser($entity, $page, 9);
+ $playlists = $this->audios->getPlaylistsByUser($entity, $page, OPENVK_DEFAULT_PER_PAGE);
$playlistsCount = $this->audios->getUserPlaylistsCount($entity);
}
@@ -109,8 +109,8 @@ function renderList(?int $owner = NULL, ?string $mode = "list"): void
$this->template->mode = $mode;
$this->template->page = $page;
-
- if(in_array($mode, ["list", "new", "popular"]) && $this->user->identity)
+
+ if(in_array($mode, ["list", "new", "popular"]) && $this->user->identity && $page < 2)
$this->template->friendsAudios = $this->user->identity->getBroadcastList("all", true);
}
@@ -142,7 +142,13 @@ function renderUpload(): void
$this->assertUserLoggedIn();
$group = NULL;
+ $playlist = NULL;
$isAjax = $this->postParam("ajax", false) == 1;
+
+ if(!is_null($this->queryParam("gid")) && !is_null($this->queryParam("playlist"))) {
+ $this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax);
+ }
+
if(!is_null($this->queryParam("gid"))) {
$gid = (int) $this->queryParam("gid");
$group = (new Clubs)->get($gid);
@@ -153,6 +159,19 @@ function renderUpload(): void
$this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax);
}
+ if(!is_null($this->queryParam("playlist"))) {
+ $playlist_id = (int)$this->queryParam("playlist");
+ $playlist = (new Audios)->getPlaylist($playlist_id);
+ if(!$playlist || $playlist->isDeleted())
+ $this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax);
+
+ if(!$playlist->canBeModifiedBy($this->user->identity))
+ $this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax);
+
+ $this->template->playlist = $playlist;
+ $this->template->owner = $playlist->getOwner();
+ }
+
$this->template->group = $group;
if($_SERVER["REQUEST_METHOD"] !== "POST")
@@ -196,6 +215,8 @@ function renderUpload(): void
$lyrics = $this->postParam("lyrics");
$genre = empty($this->postParam("genre")) ? "Other" : $this->postParam("genre");
$nsfw = ($this->postParam("explicit") ?? "off") === "on";
+ $is_unlisted = ($this->postParam("unlisted") ?? "off") === "on";
+
if(empty($performer) || empty($name) || iconv_strlen($performer . $name) > 128) # FQN of audio must not be more than 128 chars
$this->flashFail("err", tr("error"), tr("error_insufficient_info"), null, $isAjax);
@@ -206,6 +227,7 @@ function renderUpload(): void
$audio->setLyrics(empty($lyrics) ? NULL : $lyrics);
$audio->setGenre($genre);
$audio->setExplicit($nsfw);
+ $audio->setUnlisted($is_unlisted);
try {
$audio->setFile($upload);
@@ -215,13 +237,18 @@ function renderUpload(): void
} catch(\RuntimeException $ex) {
$this->flashFail("err", tr("error"), tr("ffmpeg_timeout"), null, $isAjax);
} catch(\BadMethodCallException $ex) {
- $this->flashFail("err", tr("error"), "Загрузка аудио под Linux на данный момент не реализована. Следите за обновлениями: https://github.com/openvk/openvk/pull/512/commits", null, $isAjax);
+ $this->flashFail("err", tr("error"), "хз", null, $isAjax);
} catch(\Exception $ex) {
$this->flashFail("err", tr("error"), tr("ffmpeg_not_installed"), null, $isAjax);
}
$audio->save();
- $audio->add($group ?? $this->user->identity);
+
+ if($playlist) {
+ $playlist->add($audio);
+ } else {
+ $audio->add($group ?? $this->user->identity);
+ }
if(!$isAjax)
$this->redirect(is_null($group) ? "/audios" . $this->user->id : "/audios-" . $group->getId());
@@ -233,9 +260,9 @@ function renderUpload(): void
else
$redirectLink .= $this->user->id;
- $pagesCount = (int)ceil((new Audios)->getCollectionSizeByEntityId(isset($group) ? $group->getRealId() : $this->user->id) / 10);
- $redirectLink .= "?p=".$pagesCount;
-
+ if($playlist)
+ $redirectLink = "/playlist" . $playlist->getPrettyId();
+
$this->returnJson([
"success" => true,
"redirect_link" => $redirectLink,
@@ -279,7 +306,7 @@ function renderListen(int $id): void
function renderSearch(): void
{
- $this->redirect("/search?type=audios");
+ $this->redirect("/search?section=audios");
}
function renderNewPlaylist(): void
@@ -304,6 +331,8 @@ function renderNewPlaylist(): void
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$title = $this->postParam("title");
$description = $this->postParam("description");
+ $is_unlisted = (int)$this->postParam('is_unlisted');
+
$audios = !empty($this->postParam("audios")) ? array_slice(explode(",", $this->postParam("audios")), 0, 1000) : [];
if(empty($title) || iconv_strlen($title) < 1)
@@ -313,7 +342,9 @@ function renderNewPlaylist(): void
$playlist->setOwner($owner);
$playlist->setName(substr($title, 0, 125));
$playlist->setDescription(substr($description, 0, 2045));
-
+ if($is_unlisted == 1)
+ $playlist->setUnlisted(true);
+
if($_FILES["cover"]["error"] === UPLOAD_ERR_OK) {
if(!str_starts_with($_FILES["cover"]["type"], "image"))
$this->flashFail("err", tr("error"), tr("not_a_photo"));
@@ -427,6 +458,7 @@ function renderEditPlaylist(int $owner_id, int $virtual_id)
$title = $this->postParam("title");
$description = $this->postParam("description");
+ $is_unlisted = (int)$this->postParam('is_unlisted');
$new_audios = !empty($this->postParam("audios")) ? explode(",", rtrim($this->postParam("audios"), ",")) : [];
if(empty($title) || iconv_strlen($title) < 1)
@@ -436,6 +468,7 @@ function renderEditPlaylist(int $owner_id, int $virtual_id)
$playlist->setDescription(ovk_proc_strtr($description, 2045));
$playlist->setEdited(time());
$playlist->resetLength();
+ $playlist->setUnlisted((bool)$is_unlisted);
if($_FILES["new_cover"]["error"] === UPLOAD_ERR_OK) {
if(!str_starts_with($_FILES["new_cover"]["type"], "image"))
@@ -475,12 +508,15 @@ function renderPlaylist(int $owner_id, int $virtual_id): void
$this->template->playlist = $playlist;
$this->template->page = $page;
+ $this->template->cover = $playlist->getCoverPhoto();
+ $this->template->cover_url = $this->template->cover ? $this->template->cover->getURL() : "/assets/packages/static/openvk/img/song.jpg";
$this->template->audios = iterator_to_array($playlist->fetch($page, 10));
$this->template->ownerId = $owner_id;
$this->template->owner = $playlist->getOwner();
$this->template->isBookmarked = $this->user->identity && $playlist->isBookmarkedBy($this->user->identity);
$this->template->isMy = $this->user->identity && $playlist->getOwner()->getId() === $this->user->id;
- $this->template->canEdit = $this->user->identity && $playlist->canBeModifiedBy($this->user->identity);
+ $this->template->canEdit = $this->user->identity && $playlist->canBeModifiedBy($this->user->identity);
+ $this->template->count = $playlist->size();
}
function renderAction(int $audio_id): void
@@ -531,16 +567,65 @@ function renderAction(int $audio_id): void
break;
case "add_to_club":
- $club = (new Clubs)->get((int)$this->postParam("club"));
-
- if(!$club || !$club->canBeModifiedBy($this->user->identity))
- $this->flashFail("err", "error", tr("access_denied"), null, true);
-
- if(!$audio->isInLibraryOf($club))
- $audio->add($club);
- else
- $this->flashFail("err", "error", tr("group_has_audio"), null, true);
-
+ $detailed = [];
+ if($audio->isWithdrawn())
+ $this->flashFail("err", "error", tr("invalid_audio"), null, true);
+
+ if(empty($this->postParam("clubs")))
+ $this->flashFail("err", "error", 'clubs not passed', null, true);
+
+ $clubs_arr = explode(',', $this->postParam("clubs"));
+ $count = sizeof($clubs_arr);
+ if($count < 1 || $count > 10) {
+ $this->flashFail("err", "error", tr('too_many_or_to_lack'), null, true);
+ }
+
+ foreach($clubs_arr as $club_id) {
+ $club = (new Clubs)->get((int)$club_id);
+ if(!$club || !$club->canBeModifiedBy($this->user->identity))
+ continue;
+
+ if(!$audio->isInLibraryOf($club)) {
+ $detailed[$club_id] = true;
+ $audio->add($club);
+ } else {
+ $detailed[$club_id] = false;
+ continue;
+ }
+ }
+
+ $this->returnJson(["success" => true, 'detailed' => $detailed]);
+ break;
+ case "add_to_playlist":
+ $detailed = [];
+ if($audio->isWithdrawn())
+ $this->flashFail("err", "error", tr("invalid_audio"), null, true);
+
+ if(empty($this->postParam("playlists")))
+ $this->flashFail("err", "error", 'playlists not passed', null, true);
+
+ $playlists_arr = explode(',', $this->postParam("playlists"));
+ $count = sizeof($playlists_arr);
+ if($count < 1 || $count > 10) {
+ $this->flashFail("err", "error", tr('too_many_or_to_lack'), null, true);
+ }
+
+ foreach($playlists_arr as $playlist_id) {
+ $pid = explode('_', $playlist_id);
+ $playlist = (new Audios)->getPlaylistByOwnerAndVID((int)$pid[0], (int)$pid[1]);
+ if(!$playlist || !$playlist->canBeModifiedBy($this->user->identity))
+ continue;
+
+ if(!$playlist->hasAudio($audio)) {
+ $playlist->add($audio);
+ $detailed[$playlist_id] = true;
+ } else {
+ $detailed[$playlist_id] = false;
+ continue;
+ }
+ }
+
+ $this->returnJson(["success" => true, 'detailed' => $detailed]);
break;
case "delete":
if($audio->canBeModifiedBy($this->user->identity))
@@ -653,6 +738,28 @@ function renderApiGetContext()
$audios = $stream->page($page, 10);
$audiosCount = $stream->size();
break;
+ case "classic_search_context":
+ $data = json_decode($this->postParam("context_entity"), true);
+
+ $params = [];
+ $order = [
+ "type" => $data['order'] ?? 'id',
+ "invert" => (int)$data['invert'] == 1 ? true : false
+ ];
+
+ if($data['genre'] && $data['genre'] != 'any')
+ $params['genre'] = $data['genre'];
+
+ if($data['only_performers'] && (int)$data['only_performers'] == 1)
+ $params['only_performers'] = '1';
+
+ if($data['with_lyrics'] && (int)$data['with_lyrics'] == 1)
+ $params['with_lyrics'] = '1';
+
+ $stream = $this->audios->find($data['query'], $params, $order);
+ $audios = $stream->page($page, 10);
+ $audiosCount = $stream->size();
+ break;
}
$pagesCount = ceil($audiosCount / $perPage);
diff --git a/Web/Presenters/SearchPresenter.php b/Web/Presenters/SearchPresenter.php
index 023945035..72c34e895 100644
--- a/Web/Presenters/SearchPresenter.php
+++ b/Web/Presenters/SearchPresenter.php
@@ -1,7 +1,7 @@
users = $users;
- $this->clubs = $clubs;
+ $this->users = new Users;
+ $this->clubs = new Clubs;
$this->posts = new Posts;
- $this->comments = new Comments;
$this->videos = new Videos;
$this->apps = new Applications;
- $this->notes = new Notes;
$this->audios = new Audios;
parent::__construct();
@@ -33,85 +29,101 @@ function renderIndex(): void
{
$this->assertUserLoggedIn();
- $query = $this->queryParam("query") ?? "";
- $type = $this->queryParam("type") ?? "users";
- $sorter = $this->queryParam("sort") ?? "id";
- $invert = $this->queryParam("invert") == 1 ? "ASC" : "DESC";
- $page = (int) ($this->queryParam("p") ?? 1);
-
+ $query = $this->queryParam("q") ?? "";
+ $section = $this->queryParam("section") ?? "users";
+ $order = $this->queryParam("order") ?? "id";
+ $invert = (int) ($this->queryParam("invert") ?? 0) == 1;
+ $page = (int) ($this->queryParam("p") ?? 1);
+
# https://youtu.be/pSAWM5YuXx8
+ # https://youtu.be/FfNZRhIn2Vk
$repos = [
"groups" => "clubs",
"users" => "users",
"posts" => "posts",
- "comments" => "comments",
"videos" => "videos",
"audios" => "audios",
"apps" => "apps",
- "notes" => "notes"
+ "audios_playlists" => "audios"
];
+ $parameters = [
+ "ignore_private" => true,
+ ];
+
+ foreach($_REQUEST as $param_name => $param_value) {
+ if(is_null($param_value)) continue;
+
+ switch($param_name) {
+ default:
+ $parameters[$param_name] = $param_value;
+ break;
+ case 'marital_status':
+ case 'polit_views':
+ if((int) $param_value == 0) continue;
+ $parameters[$param_name] = $param_value;
+
+ break;
+ case 'is_online':
+ if((int) $param_value == 1)
+ $parameters['is_online'] = 1;
+
+ break;
+ case 'only_performers':
+ if((int) $param_value == 1 || $param_value == 'on')
+ $parameters['only_performers'] = true;
+
+ break;
+ case 'with_lyrics':
+ if($param_value == 'on' || $param_value == '1')
+ $parameters['with_lyrics'] = true;
+
+ break;
+ # дай бог работал этот case
+ case 'from_me':
+ if((int) $param_value != 1) continue;
+ $parameters['from_me'] = $this->user->id;
+
+ break;
+ }
+ }
- switch($sorter) {
+ $repo = $repos[$section] or $this->throwError(400, "Bad Request", "Invalid search entity $section.");
+
+ $results = NULL;
+ switch($section) {
default:
- case "id":
- $sort = "id " . $invert;
- break;
- case "name":
- $sort = "first_name " . $invert;
- break;
- case "rating":
- $sort = "rating " . $invert;
+ $results = $this->{$repo}->find($query, $parameters, ['type' => $order, 'invert' => $invert]);
break;
- case "length":
- if($type != "audios") break;
-
- $sort = "length " . $invert;
+ case 'audios_playlists':
+ $results = $this->{$repo}->findPlaylists($query, $parameters, ['type' => $order, 'invert' => $invert]);
break;
- case "listens":
- if($type != "audios") break;
-
- $sort = "listens " . $invert;
- break;
}
-
- $parameters = [
- "type" => $this->queryParam("type"),
- "city" => $this->queryParam("city") != "" ? $this->queryParam("city") : NULL,
- "maritalstatus" => $this->queryParam("maritalstatus") != 0 ? $this->queryParam("maritalstatus") : NULL,
- "with_photo" => $this->queryParam("with_photo"),
- "status" => $this->queryParam("status") != "" ? $this->queryParam("status") : NULL,
- "politViews" => $this->queryParam("politViews") != 0 ? $this->queryParam("politViews") : NULL,
- "email" => $this->queryParam("email"),
- "telegram" => $this->queryParam("telegram"),
- "site" => $this->queryParam("site") != "" ? "https://".$this->queryParam("site") : NULL,
- "address" => $this->queryParam("address"),
- "is_online" => $this->queryParam("is_online") == 1 ? 1 : NULL,
- "interests" => $this->queryParam("interests") != "" ? $this->queryParam("interests") : NULL,
- "fav_mus" => $this->queryParam("fav_mus") != "" ? $this->queryParam("fav_mus") : NULL,
- "fav_films" => $this->queryParam("fav_films") != "" ? $this->queryParam("fav_films") : NULL,
- "fav_shows" => $this->queryParam("fav_shows") != "" ? $this->queryParam("fav_shows") : NULL,
- "fav_books" => $this->queryParam("fav_books") != "" ? $this->queryParam("fav_books") : NULL,
- "fav_quote" => $this->queryParam("fav_quote") != "" ? $this->queryParam("fav_quote") : NULL,
- "hometown" => $this->queryParam("hometown") != "" ? $this->queryParam("hometown") : NULL,
- "before" => $this->queryParam("datebefore") != "" ? strtotime($this->queryParam("datebefore")) : NULL,
- "after" => $this->queryParam("dateafter") != "" ? strtotime($this->queryParam("dateafter")) : NULL,
- "gender" => $this->queryParam("gender") != "" && $this->queryParam("gender") != 2 ? $this->queryParam("gender") : NULL,
- "doNotSearchPrivate" => true,
- "only_performers" => $this->queryParam("only_performers") == "on" ? "1" : NULL,
- "with_lyrics" => $this->queryParam("with_lyrics") == "on" ? true : NULL,
- ];
-
- $repo = $repos[$type] or $this->throwError(400, "Bad Request", "Invalid search entity $type.");
- $results = $this->{$repo}->find($query, $parameters, $sort);
- $iterator = $results->page($page, 14);
+ $iterator = $results->page($page, OPENVK_DEFAULT_PER_PAGE);
$count = $results->size();
- $this->template->iterator = iterator_to_array($iterator);
+ $this->template->order = $order;
+ $this->template->invert = $invert;
+ $this->template->data = $this->template->iterator = iterator_to_array($iterator);
$this->template->count = $count;
- $this->template->type = $type;
+ $this->template->section = $section;
$this->template->page = $page;
- $this->template->perPage = 14;
+ $this->template->perPage = OPENVK_DEFAULT_PER_PAGE;
+ $this->template->query = $query;
+ $this->template->atSearch = true;
+
+ $this->template->paginatorConf = (object) [
+ "page" => $page,
+ "count" => $count,
+ "amount" => sizeof($this->template->data),
+ "perPage" => $this->template->perPage,
+ "atBottom" => false,
+ "tidy" => true,
+ "space" => 6,
+ 'pageCount' => ceil($count / $this->template->perPage),
+ ];
+ $this->template->extendedPaginatorConf = clone $this->template->paginatorConf;
+ $this->template->extendedPaginatorConf->space = 12;
}
}
diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml
index 803ebdd0d..b54ef44c7 100644
--- a/Web/Presenters/templates/@layout.xml
+++ b/Web/Presenters/templates/@layout.xml
@@ -87,7 +87,7 @@