From 0aecc299cf42c692bb4963d5741832570fc02efb Mon Sep 17 00:00:00 2001 From: mrilyew <99399973+mrilyew@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:34:29 +0300 Subject: [PATCH] feat(profile): fav games & custom fields (#1193) * add fav games * add additional fields * add gui 4 dis * add maxlength --- VKAPI/Handlers/Account.php | 47 ++++++++- VKAPI/Handlers/Users.php | 26 ++++- Web/Models/Entities/User.php | 37 ++++++++ .../UserInfoEntities/AdditionalField.php | 95 +++++++++++++++++++ Web/Presenters/UserPresenter.php | 56 +++++++++-- Web/Presenters/templates/@layout.xml | 1 + Web/Presenters/templates/User/Edit.xml | 63 ++++++++++++ Web/Presenters/templates/User/View.xml | 16 ++++ Web/static/css/main.css | 22 +++++ Web/static/js/al_wall.js | 61 +++++++++++- install/sqls/00053-new-fields.sql | 10 ++ locales/en.strings | 16 ++++ locales/ru.strings | 16 ++++ quirks.yml | 3 +- 14 files changed, 456 insertions(+), 13 deletions(-) create mode 100644 Web/Models/Entities/UserInfoEntities/AdditionalField.php create mode 100644 install/sqls/00053-new-fields.sql diff --git a/VKAPI/Handlers/Account.php b/VKAPI/Handlers/Account.php index c1f3ef23..d4144b90 100644 --- a/VKAPI/Handlers/Account.php +++ b/VKAPI/Handlers/Account.php @@ -269,7 +269,7 @@ final class Account extends VKAPIRequestHandler return 1; $entity = get_entity_by_id($owner_id); - if(!$entity || $entity->isDeleted()) + if(!$entity) return 0; if(!$entity->isBlacklistedBy($this->getUser())) @@ -296,4 +296,49 @@ final class Account extends VKAPIRequestHandler return $result; } + + function saveInterestsInfo( + string $interests = NULL, + string $fav_music = NULL, + string $fav_films = NULL, + string $fav_shows = NULL, + string $fav_books = NULL, + string $fav_quote = NULL, + string $fav_games = NULL, + string $about = NULL, + ) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $user = $this->getUser(); + $changes = 0; + $changes_array = [ + "interests" => $interests, + "fav_music" => $fav_music, + "fav_films" => $fav_films, + "fav_books" => $fav_books, + "fav_shows" => $fav_shows, + "fav_quote" => $fav_quote, + "fav_games" => $fav_games, + "about" => $about, + ]; + + foreach($changes_array as $change_name => $change_value) { + $set_name = "set".ucfirst($change_name); + $get_name = "get".str_replace("Fav", "Favorite", str_replace("_", "", ucfirst($change_name))); + if(!is_null($change_value) && $change_value !== $user->$get_name()) { + $user->$set_name(ovk_proc_strtr($change_value, 1000)); + $changes += 1; + } + } + + if($changes > 0) { + $user->save(); + } + + return (object) [ + "changed" => (int)($changes > 0), + ]; + } } diff --git a/VKAPI/Handlers/Users.php b/VKAPI/Handlers/Users.php index 7dc68f3b..c47acb8e 100644 --- a/VKAPI/Handlers/Users.php +++ b/VKAPI/Handlers/Users.php @@ -12,8 +12,14 @@ final class Users extends VKAPIRequestHandler if($authuser == NULL) $authuser = $this->getUser(); $users = new UsersRepo; - if($user_ids == "0") + if($user_ids == "0") { + if(!$authuser) { + return []; + } + $user_ids = (string) $authuser->getId(); + } + $usrs = explode(',', $user_ids); $response = array(); @@ -198,6 +204,13 @@ final class Users extends VKAPIRequestHandler $response[$i]->quotes = $usr->getFavoriteQuote(); break; + case "games": + if(!$canView) { + break; + } + + $response[$i]->games = $usr->getFavoriteGames(); + break; case "email": if(!$canView) { break; @@ -280,6 +293,17 @@ final class Users extends VKAPIRequestHandler $response[$i]->blacklisted = (int)$this->getUser()->isBlacklistedBy($usr); break; + case "custom_fields": + if(sizeof($usrs) > 1) + break; + + $c_fields = \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField::getByOwner($usr->getId()); + $append_array = []; + foreach($c_fields as $c_field) + $append_array[] = $c_field->toVkApiStruct(); + + $response[$i]->custom_fields = $append_array; + break; } } diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php index 61ea120b..a1f650ec 100644 --- a/Web/Models/Entities/User.php +++ b/Web/Models/Entities/User.php @@ -228,6 +228,11 @@ class User extends RowModel return $this->getRecord()->about; } + function getAbout(): ?string + { + return $this->getRecord()->about; + } + function getStatus(): ?string { return $this->getRecord()->status; @@ -415,6 +420,11 @@ class User extends RowModel return $this->getRecord()->fav_quote; } + function getFavoriteGames(): ?string + { + return $this->getRecord()->fav_games; + } + function getCity(): ?string { return $this->getRecord()->city; @@ -425,6 +435,30 @@ class User extends RowModel return $this->getRecord()->address; } + function getAdditionalFields(bool $split = false): array + { + $all = \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField::getByOwner($this->getId()); + $result = [ + "interests" => [], + "contacts" => [], + ]; + + if($split) { + foreach($all as $field) { + if($field->getPlace() == "contact") + $result["contacts"][] = $field; + else if($field->getPlace() == "interest") + $result["interests"][] = $field; + } + } else { + $result = []; + foreach($all as $field) + $result[] = $field; + } + + return $result; + } + function getNotificationOffset(): int { return $this->getRecord()->notification_offset; @@ -1432,6 +1466,9 @@ class User extends RowModel $res->blacklisted = (int)$user->isBlacklistedBy($this); break; + case "games": + $res->games = $this->getFavoriteGames(); + break; } } diff --git a/Web/Models/Entities/UserInfoEntities/AdditionalField.php b/Web/Models/Entities/UserInfoEntities/AdditionalField.php new file mode 100644 index 00000000..47c69de3 --- /dev/null +++ b/Web/Models/Entities/UserInfoEntities/AdditionalField.php @@ -0,0 +1,95 @@ +getRecord()->owner; + } + + function getName(bool $tr = true): string + { + $orig_name = $this->getRecord()->name; + $name = $orig_name; + if($tr && $name[0] === "_") + $name = tr("custom_field_" . substr($name, 1)); + + if(str_contains($name, "custom_field")) + return $orig_name; + + return $name; + } + + function getContent(): string + { + return $this->getRecord()->text; + } + + function getPlace(): string + { + switch($this->getRecord()->place) { + case AdditionalField::PLACE_CONTACTS: + return "contact"; + case AdditionalField::PLACE_INTERESTS: + return "interest"; + } + + return "contact"; + } + + function isContact(): bool + { + return $this->getRecord()->place == AdditionalField::PLACE_CONTACTS; + } + + function toVkApiStruct(): object + { + return (object) [ + "type" => $this->getRecord()->place, + "name" => $this->getName(), + "text" => $this->getContent() + ]; + } + + static function getById(int $id) + { + $ctx = DatabaseConnection::i()->getContext(); + $entry = $ctx->table("additional_fields")->where("id", $id)->fetch(); + + if(!$entry) + return NULL; + + return new AdditionalField($entry); + } + + static function getByOwner(int $owner): \Traversable + { + $ctx = DatabaseConnection::i()->getContext(); + $entries = $ctx->table("additional_fields")->where("owner", $owner); + + foreach($entries as $entry) { + yield new AdditionalField($entry); + } + } + + static function getCountByOwner(int $owner): \Traversable + { + return DatabaseConnection::i()->getContext()->table("additional_fields")->where("owner", $owner)->count(); + } + + static function resetByOwner(int $owner): bool + { + DatabaseConnection::i()->getContext()->table("additional_fields")->where("owner", $owner)->delete(); + + return true; + } +} diff --git a/Web/Presenters/UserPresenter.php b/Web/Presenters/UserPresenter.php index f238e381..dc8fb02c 100644 --- a/Web/Presenters/UserPresenter.php +++ b/Web/Presenters/UserPresenter.php @@ -64,6 +64,7 @@ final class UserPresenter extends OpenVKPresenter $this->template->audios = (new Audios)->getRandomThreeAudiosByEntityId($user->getId()); $this->template->audiosCount = (new Audios)->getUserCollectionSize($user); $this->template->audioStatus = $user->getCurrentAudioStatus(); + $this->template->additionalFields = $user->getAdditionalFields(true); $this->template->user = $user; @@ -251,13 +252,14 @@ final class UserPresenter extends OpenVKPresenter else $user->setWebsite((!parse_url($website, PHP_URL_SCHEME) ? "https://" : "") . $website); } elseif($_GET['act'] === "interests") { - $user->setInterests(empty($this->postParam("interests")) ? NULL : ovk_proc_strtr($this->postParam("interests"), 300)); - $user->setFav_Music(empty($this->postParam("fav_music")) ? NULL : ovk_proc_strtr($this->postParam("fav_music"), 300)); - $user->setFav_Films(empty($this->postParam("fav_films")) ? NULL : ovk_proc_strtr($this->postParam("fav_films"), 300)); - $user->setFav_Shows(empty($this->postParam("fav_shows")) ? NULL : ovk_proc_strtr($this->postParam("fav_shows"), 300)); - $user->setFav_Books(empty($this->postParam("fav_books")) ? NULL : ovk_proc_strtr($this->postParam("fav_books"), 300)); - $user->setFav_Quote(empty($this->postParam("fav_quote")) ? NULL : ovk_proc_strtr($this->postParam("fav_quote"), 300)); - $user->setAbout(empty($this->postParam("about")) ? NULL : ovk_proc_strtr($this->postParam("about"), 300)); + $user->setInterests(empty($this->postParam("interests")) ? NULL : ovk_proc_strtr($this->postParam("interests"), 1000)); + $user->setFav_Music(empty($this->postParam("fav_music")) ? NULL : ovk_proc_strtr($this->postParam("fav_music"), 1000)); + $user->setFav_Films(empty($this->postParam("fav_films")) ? NULL : ovk_proc_strtr($this->postParam("fav_films"), 1000)); + $user->setFav_Shows(empty($this->postParam("fav_shows")) ? NULL : ovk_proc_strtr($this->postParam("fav_shows"), 1000)); + $user->setFav_Books(empty($this->postParam("fav_books")) ? NULL : ovk_proc_strtr($this->postParam("fav_books"), 1000)); + $user->setFav_Quote(empty($this->postParam("fav_quote")) ? NULL : ovk_proc_strtr($this->postParam("fav_quote"), 1000)); + $user->setFav_Games(empty($this->postParam("fav_games")) ? NULL : ovk_proc_strtr($this->postParam("fav_games"), 1000)); + $user->setAbout(empty($this->postParam("about")) ? NULL : ovk_proc_strtr($this->postParam("about"), 1000)); } elseif($_GET["act"] === "backdrop") { if($this->postParam("subact") === "remove") { $user->unsetBackDropPictures(); @@ -295,10 +297,46 @@ final class UserPresenter extends OpenVKPresenter $this->returnJson([ "success" => true ]); + } elseif($_GET['act'] === "additional") { + $maxAddFields = ovkGetQuirk("users.max-fields"); + $items = []; + + for($i = 0; $i < $maxAddFields; $i++) { + if(!$this->postParam("name_".$i)) { + continue; + } + + $items[] = [ + "name" => $this->postParam("name_".$i), + "text" => $this->postParam("text_".$i), + "place" => $this->postParam("place_".$i), + ]; + } + + \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField::resetByOwner($this->user->id); + foreach($items as $new_field_info) { + $name = ovk_proc_strtr($new_field_info["name"], 50); + $text = ovk_proc_strtr($new_field_info["text"], 1000); + if(ctype_space($name) || ctype_space($text)) { + continue; + } + + $place = (int)($new_field_info["place"]); + + $new_field = new \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField; + $new_field->setOwner($this->user->id); + $new_field->setName($name); + $new_field->setText($text); + $new_field->setPlace([0, 1][$place] ? $place : 0); + + $new_field->save(); + } } try { - $user->save(); + if($_GET['act'] !== "additional") { + $user->save(); + } } catch(\PDOException $ex) { if($ex->getCode() == 23000) $this->flashFail("err", tr("error"), tr("error_shorturl")); @@ -310,7 +348,7 @@ final class UserPresenter extends OpenVKPresenter } $this->template->mode = in_array($this->queryParam("act"), [ - "main", "contacts", "interests", "avatar", "backdrop" + "main", "contacts", "interests", "avatar", "backdrop", "additional" ]) ? $this->queryParam("act") : "main"; diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index 34e033dc..245ccfb0 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -460,6 +460,7 @@ "max_filesize_mb": 5, "current_id": {$thisUser ? $thisUser->getId() : 0}, "disable_ajax": {$disable_ajax ? $disable_ajax : 0}, + "max_add_fields": {ovkGetQuirk("users.max-fields")}, } diff --git a/Web/Presenters/templates/User/Edit.xml b/Web/Presenters/templates/User/Edit.xml index 8bea7f0c..0cc70a63 100644 --- a/Web/Presenters/templates/User/Edit.xml +++ b/Web/Presenters/templates/User/Edit.xml @@ -13,6 +13,7 @@ {var $isMain = $mode === 'main'} {var $isContacts = $mode === 'contacts'} {var $isInterests = $mode === 'interests'} + {var $isAdditional = $mode === 'additional'} {var $isAvatar = $mode === 'avatar'} {var $isBackDrop = $mode === 'backdrop'} @@ -31,6 +32,9 @@
+{tr("additional_fields_description", ovkGetQuirk("users.max-fields"))}
+ {/if} diff --git a/Web/Presenters/templates/User/View.xml b/Web/Presenters/templates/User/View.xml index cbcb1f1f..9c013dd1 100644 --- a/Web/Presenters/templates/User/View.xml +++ b/Web/Presenters/templates/User/View.xml @@ -506,6 +506,12 @@${tr("additional_field_name")} | ++ | + |
${tr("additional_field_text")} | ++ | |
${tr("additional_field_place")} | ++ + | + |