diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php index 31d3d4fe..85731811 100644 --- a/Web/Models/Entities/User.php +++ b/Web/Models/Entities/User.php @@ -558,6 +558,7 @@ class User extends RowModel "poster", "apps", "docs", + "fave", ], ])->get($id); } @@ -1195,6 +1196,7 @@ class User extends RowModel "poster", "apps", "docs", + "fave", ], ])->set($id, (int) $status)->toInteger(); diff --git a/Web/Models/Repositories/Faves.php b/Web/Models/Repositories/Faves.php new file mode 100644 index 00000000..d73b588b --- /dev/null +++ b/Web/Models/Repositories/Faves.php @@ -0,0 +1,48 @@ +context = DatabaseConnection::i()->getContext(); + $this->likes = $this->context->table("likes"); + } + + private function fetchLikes(User $user, string $class = 'Post') + { + $fetch = $this->likes->where([ + "model" => "openvk\\Web\\Models\\Entities\\".$class, + "origin" => $user->getRealId(), + ]); + + return $fetch; + } + + function fetchLikesSection(User $user, string $class = 'Post', int $page = 1, ?int $perPage = NULL): \Traversable + { + $perPage ??= OPENVK_DEFAULT_PER_PAGE; + $fetch = $this->fetchLikes($user, $class)->page($page, $perPage); + foreach($fetch as $like) { + $className = "openvk\\Web\\Models\\Repositories\\".$class."s"; + $repo = new $className; + if(!$repo) { + continue; + } + + $entity = $repo->get($like->target); + yield $entity; + } + } + + function fetchLikesSectionCount(User $user, string $class = 'Post') + { + return $this->fetchLikes($user, $class)->count(); + } +} diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php index 1aa14213..b3e27512 100644 --- a/Web/Presenters/GroupPresenter.php +++ b/Web/Presenters/GroupPresenter.php @@ -373,6 +373,7 @@ final class GroupPresenter extends OpenVKPresenter public function renderDeleteAvatar(int $id) { $this->assertUserLoggedIn(); + $this->assertNoCSRF(); $this->willExecuteWriteAction(); $club = $this->clubs->get($id); diff --git a/Web/Presenters/UserPresenter.php b/Web/Presenters/UserPresenter.php index 8770b4de..07d702cd 100644 --- a/Web/Presenters/UserPresenter.php +++ b/Web/Presenters/UserPresenter.php @@ -9,7 +9,7 @@ use openvk\Web\Util\Sms; use openvk\Web\Themes\Themepacks; use openvk\Web\Models\Entities\{Photo, Post, EmailChangeVerification}; use openvk\Web\Models\Entities\Notifications\{CoinsTransferNotification, RatingUpNotification}; -use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Videos, Notes, Vouchers, EmailChangeVerifications, Audios}; +use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Videos, Notes, Vouchers, EmailChangeVerifications, Audios, Faves}; use openvk\Web\Models\Exceptions\InvalidUserNameException; use openvk\Web\Util\Validator; use Chandler\Security\Authenticator; @@ -474,6 +474,7 @@ final class UserPresenter extends OpenVKPresenter public function renderDeleteAvatar() { $this->assertUserLoggedIn(); + $this->assertNoCSRF(); $this->willExecuteWriteAction(); $avatar = $this->user->identity->getAvatarPhoto(); @@ -666,6 +667,7 @@ final class UserPresenter extends OpenVKPresenter "menu_standardo" => "poster", "menu_aplikoj" => "apps", "menu_doxc" => "docs", + "menu_feva" => "fave", ]; foreach ($settings as $checkbox => $setting) { $user->setLeftMenuItemStatus($setting, $this->checkbox($checkbox)); @@ -942,4 +944,65 @@ final class UserPresenter extends OpenVKPresenter $this->redirect("/settings"); } } + + function renderFave(): void + { + $this->assertUserLoggedIn(); + + $page = (int)($this->queryParam("p") ?? 1); + $section = $this->queryParam("section") ?? "posts"; + $display_section = "posts"; + $data = NULL; + $count = 0; + + switch($section) { + default: + $this->notFound(); + break; + case 'wall': + case 'post': + case 'posts': + $data = (new Faves)->fetchLikesSection($this->user->identity, 'Post', $page); + $count = (new Faves)->fetchLikesSectionCount($this->user->identity, 'Post'); + $display_section = "posts"; + break; + case 'comment': + case 'comments': + $data = (new Faves)->fetchLikesSection($this->user->identity, 'Comment', $page); + $count = (new Faves)->fetchLikesSectionCount($this->user->identity, 'Comment'); + $display_section = "comments"; + break; + case 'photo': + case 'photos': + $data = (new Faves)->fetchLikesSection($this->user->identity, 'Photo', $page); + $count = (new Faves)->fetchLikesSectionCount($this->user->identity, 'Photo'); + $display_section = "photos"; + break; + case 'video': + case 'videos': + $data = (new Faves)->fetchLikesSection($this->user->identity, 'Video', $page); + $count = (new Faves)->fetchLikesSectionCount($this->user->identity, 'Video'); + $display_section = "videos"; + break; + } + + $this->template->data = iterator_to_array($data); + $this->template->count = $count; + $this->template->page = $page; + $this->template->perPage = OPENVK_DEFAULT_PER_PAGE; + $this->template->section = $display_section; + + $this->template->paginatorConf = (object) [ + "page" => $page, + "count" => $count, + "amount" => sizeof($this->template->data), + "perPage" => $this->template->perPage, + "atBottom" => false, + "tidy" => true, + 'pageCount' => ceil($count / $this->template->perPage), + ]; + $this->template->extendedPaginatorConf = clone $this->template->paginatorConf; + $this->template->extendedPaginatorConf->space = 11; + $this->template->paginatorConf->atTop = true; + } } diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index 2e8dc828..7a55a8b0 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -198,10 +198,11 @@ {_my_settings} - {if $thisUser->getLeftMenuItemStatus('docs') || $thisUser->getLeftMenuItemStatus('apps')} + {if $thisUser->getLeftMenuItemStatus('docs') || $thisUser->getLeftMenuItemStatus('apps') || $thisUser->getLeftMenuItemStatus('fave')} {_apps} {_my_documents} + {_bookmarks_tab} {/if} {var $canAccessAdminPanel = $thisUser->getChandlerUser()->can("access")->model("admin")->whichBelongsTo(NULL)} diff --git a/Web/Presenters/templates/User/Fave.xml b/Web/Presenters/templates/User/Fave.xml new file mode 100644 index 00000000..50ead41f --- /dev/null +++ b/Web/Presenters/templates/User/Fave.xml @@ -0,0 +1,80 @@ +{extends "../@layout.xml"} + +{block title}{_bookmarks_tab}{/block} + +{block header} + {_bookmarks_tab} +{/block} + +{block wrap} +
+
+
+
+
+ {tr("faves", $count)} {*tr("showing_x_y", $page, $count)*} +
+ + {include "../components/paginator.xml", conf => $paginatorConf} +
+ +
+
+ + {if $count > 0} + {foreach $data as $dat} + {if $section == "posts"} +
+ {include "../components/post.xml", post => $dat, commentSection => true} +
+ {elseif $section == "comments"} +
+ {include "../components/comment.xml", comment => $dat, correctLink => true, no_reply_button => true} +
+ {elseif $section == "photos"} +
+ + {$dat->getDescription()} + +
+ {elseif $section == "videos"} +
+ {include "../components/video.xml", video => $dat} +
+ {/if} + {/foreach} + {else} + {include "../components/content_error.xml", description => tr("faves_".$section."_empty_tip")} + {/if} +
+ +
+ +
+ {include "../components/paginator.xml", conf => $extendedPaginatorConf} +
+
+
+
+ +{/block} diff --git a/Web/Presenters/templates/User/Settings.xml b/Web/Presenters/templates/User/Settings.xml index 5ae6ee4b..f4cf0271 100644 --- a/Web/Presenters/templates/User/Settings.xml +++ b/Web/Presenters/templates/User/Settings.xml @@ -696,6 +696,17 @@ {_my_documents} + + + + + + {_bookmarks_tab} + + {_report} {/if}
+ {var $isLiked = $comment->hasLikeFrom($thisUser)} -
+
{if $likesCount > 0}{$likesCount}{/if}
diff --git a/Web/di.yml b/Web/di.yml index b9821fec..55ac4483 100644 --- a/Web/di.yml +++ b/Web/di.yml @@ -54,5 +54,6 @@ services: - openvk\Web\Models\Repositories\BannedLinks - openvk\Web\Models\Repositories\ChandlerGroups - openvk\Web\Models\Repositories\Documents + - openvk\Web\Models\Repositories\Faves - openvk\Web\Presenters\MaintenancePresenter - openvk\Web\Presenters\NoSpamPresenter diff --git a/Web/routes.yml b/Web/routes.yml index eac95801..8014b0ef 100644 --- a/Web/routes.yml +++ b/Web/routes.yml @@ -413,6 +413,8 @@ routes: handler: "InternalAPI->getPostTemplate" - url: "/tour" handler: "About->tour" + - url: "/fave" + handler: "User->fave" - url: "/{?shortCode}" handler: "UnknownTextRouteStrategy->delegate" placeholders: diff --git a/locales/en.strings b/locales/en.strings index ae2bc52d..b215497d 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -641,6 +641,8 @@ "my_feed" = "My Feed"; "my_feedback" = "My Feedback"; "my_settings" = "My Settings"; +"bookmarks" = "Bookmarks"; +"bookmarks_tab" = "Saved"; "bug_tracker" = "Bug Tracker"; "menu_settings" = "Settings"; @@ -2113,6 +2115,7 @@ "s_apps" = "Applications"; "s_posts" = "Posts"; "s_comments" = "Comments"; +"s_photos" = "Photos"; "s_videos" = "Videos"; "s_audios" = "Music"; "s_audios_playlists" = "Playlists"; @@ -2385,3 +2388,17 @@ "select_doc" = "Attach document"; "no_documents" = "No documents found"; "go_to_my_documents" = "Go to own documents"; + +/* Fave */ + +"faves" = "Bookmarks"; +"faves_empty_tip" = "There will be your liked content."; +"faves_posts_empty_tip" = "There will be posts liked by you."; +"faves_comments_empty_tip" = "There will be comments liked by you."; +"faves_photos_empty_tip" = "There will be photos liked by you."; +"faves_videos_empty_tip" = "There will be videos liked by you."; +"faves_zero" = "No bookmarks"; +"faves_one" = "One bookmark"; +"faves_few" = "$1 bookmarks"; +"faves_many" = "$1 bookmarks"; +"faves_other" = "$1 bookmarks"; diff --git a/locales/ru.strings b/locales/ru.strings index 14f6f624..21c2fcf1 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -624,6 +624,8 @@ "my_feed" = "Мои Новости"; "my_feedback" = "Мои Ответы"; "my_settings" = "Мои Настройки"; +"bookmarks" = "Закладки"; +"bookmarks_tab" = "Избранное"; "bug_tracker" = "Баг-трекер"; "menu_settings" = "Настройки"; @@ -2008,6 +2010,7 @@ "s_apps" = "Приложения"; "s_posts" = "Записи"; "s_comments" = "Комментарии"; +"s_photos" = "Фотографии"; "s_videos" = "Видео"; "s_audios" = "Аудио"; "s_audios_playlists" = "Плейлисты"; @@ -2280,3 +2283,17 @@ "select_doc" = "Выбор документа"; "no_documents" = "Документов нет"; "go_to_my_documents" = "Перейти к своим документам"; + +/* Fave */ + +"faves" = "Закладки"; +"faves_empty_tip" = "Здесь будет отображаться понравившийся Вам контент..."; +"faves_posts_empty_tip" = "Здесь будут отображаться понравившиеся Вам записи."; +"faves_comments_empty_tip" = "Здесь будут отображаться понравившиеся Вам комментарии."; +"faves_photos_empty_tip" = "Здесь будут отображаться понравившиеся Вам фотографии."; +"faves_videos_empty_tip" = "Здесь будут отображаться понравившиеся Вам видео."; +"faves_zero" = "Ни одной закладки"; /* на украинском можно как ни одной вподобайки */ +"faves_one" = "Одна закладка"; +"faves_few" = "$1 закладки"; +"faves_many" = "$1 закладок"; +"faves_other" = "$1 закладок";