diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 306baf60..e01446e6 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -206,6 +206,9 @@ final class Wall extends VKAPIRequestHandler if($post->isDeactivationMessage()) $post_temp_obj->final_post = 1; + if($post->getGeo()) + $post_temp_obj->geo = $post->getVkApiGeo(); + $items[] = $post_temp_obj; if ($from_id > 0) @@ -321,14 +324,10 @@ final class Wall extends VKAPIRequestHandler } else if ($attachment instanceof \openvk\Web\Models\Entities\Video) { $attachments[] = $attachment->getApiStructure($this->getUser()); } else if ($attachment instanceof \openvk\Web\Models\Entities\Note) { - if(VKAPI_DECL_VER === '4.100') { - $attachments[] = $attachment->toVkApiStruct(); - } else { - $attachments[] = [ - 'type' => 'note', - 'note' => $attachment->toVkApiStruct() - ]; - } + $attachments[] = [ + 'type' => 'note', + 'note' => $attachment->toVkApiStruct() + ]; } else if ($attachment instanceof \openvk\Web\Models\Entities\Audio) { $attachments[] = [ "type" => "audio", @@ -419,6 +418,9 @@ final class Wall extends VKAPIRequestHandler if($post->isDeactivationMessage()) $post_temp_obj->final_post = 1; + if($post->getGeo()) + $post_temp_obj->geo = $post->getVkApiGeo(); + $items[] = $post_temp_obj; if ($from_id > 0) @@ -493,7 +495,11 @@ final class Wall extends VKAPIRequestHandler ]; } - function post(string $owner_id, string $message = "", string $copyright = "", int $from_group = 0, int $signed = 0, string $attachments = "", int $post_id = 0): object + function post(string $owner_id, string $message = "", string $copyright = "", int $from_group = 0, int $signed = 0, string $attachments = "", int $post_id = 0, + float $lat = NULL, + float $long = NULL, + string $place_name = '' + ): object { $this->requireUser(); $this->willExecuteWriteAction(); @@ -584,44 +590,6 @@ final class Wall extends VKAPIRequestHandler if((empty($message) && (empty($attachments) || sizeof($final_attachments) < 1))) $this->fail(100, "Required parameter 'message' missing."); - $geo = NULL; - - if ($latitude && $longitude) { - $latitude = number_format($latitude, 8, ".", ''); - $longitude = number_format($longitude, 8, ".", ''); - - if ((!$latitude || !$longitude) || ($latitude > 90 || $latitude < -90 || $longitude > 180 || $longitude < -180)) { - $this->fail(100, "Invalid latitude or longitude"); - } - - $geo = array( - "name" => null, - "lat" => $latitude, - "lng" => $longitude, - ); - - if (strlen(trim($geo_name))) { - $geo["name"] = $geo_name; - } else { - $info = file_get_contents("https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2", false, stream_context_create([ - 'http' => [ - 'method' => 'GET', - 'header' => implode("\r\n", [ - 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/22.0.1216.0 Safari/537.2', - "Referer: https://$_SERVER[SERVER_NAME]/" - ]) - ] - ])); - - if ($info) { - $info = json_decode($info, true, JSON_UNESCAPED_UNICODE); - if (key_exists("place_id", $info)) { - $geo["name"] = $info["name"] ?? $info["display_name"]; - } - } - } - } - try { $post = new Post; $post->setOwner($this->getUser()->getId()); @@ -637,6 +605,45 @@ final class Wall extends VKAPIRequestHandler } catch(\Throwable) {} } + /*$info = file_get_contents("https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2", false, stream_context_create([ + 'http' => [ + 'method' => 'GET', + 'header' => implode("\r\n", [ + 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/22.0.1216.0 Safari/537.2', + "Referer: https://$_SERVER[SERVER_NAME]/" + ]) + ] + ])); + + if ($info) { + $info = json_decode($info, true, JSON_UNESCAPED_UNICODE); + if (key_exists("place_id", $info)) { + $geo["name"] = $info["name"] ?? $info["display_name"]; + } + }*/ + if($lat && $long) { + if(($lat > 90 || $lat < -90) || ($long > 180 || $long < -180)) { + $this->fail(-785, 'Invalid geo info'); + } + + $latitude = number_format((float) $lat, 8, ".", ''); + $longitude = number_format((float) $long, 8, ".", ''); + + $res = [ + 'lat' => $latitude, + 'lng' => $longitude + ]; + if($place_name && mb_strlen($place_name) > 0) { + $res['name'] = $place_name; + } else { + $res['name'] = 'Geopoint'; + } + + $post->setGeo(json_encode($res)); + $post->setGeo_Lat($latitude); + $post->setGeo_Lon($longitude); + } + if($should_be_suggested) $post->setSuggested(1); @@ -1167,6 +1174,52 @@ final class Wall extends VKAPIRequestHandler return 1; } + function getNearby(int $owner_id, int $post_id) + { + $this->requireUser(); + + $post = (new PostsRepo)->getPostById($owner_id, $post_id); + if(!$post || $post->isDeleted()) + $this->fail(100, "One of the parameters specified was missing or invalid: post_id is undefined"); + + if(!$post->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); + + $lat = $post->getLat(); + $lon = $post->getLon(); + + if(!$lat || !$lon) + $this->fail(-97, "Post doesn't contains geo"); + + $query = file_get_contents(__DIR__ . "/../../Web/Models/sql/get-nearest-posts.tsql"); + $_posts = \Chandler\Database\DatabaseConnection::i()->getContext()->query($query, $lat, $lon, $post->getId())->fetchAll(); + $posts = []; + + foreach($_posts as $post) { + $distance = $post["distance"]; + $post = (new PostsRepo)->get($post["id"]); + if (!$post || $post->isDeleted() || !$post->canBeViewedBy($this->getUser())) continue; + + $owner = $post->getOwner(); + $preview = mb_substr($post->getText(), 0, 50) . (strlen($post->getText()) > 50 ? "..." : ""); + $posts[] = [ + "message" => strlen($preview) > 0 ? $preview : "(нет текста)", + "url" => "/wall" . $post->getPrettyId(), + "created" => $post->getPublicationTime()->html(), + "owner" => [ + "domain" => $owner->getURL(), + "photo_50" => $owner->getAvatarURL(), + "name" => $owner->getCanonicalName(), + "verified" => $owner->isVerified(), + ], + "geo" => $post->getGeo(), + "distance" => $distance + ]; + } + + return $posts; + } + private function getApiPhoto($attachment) { return [ "type" => "photo", diff --git a/Web/Models/Entities/Post.php b/Web/Models/Entities/Post.php index 9b207023..f3f8e1f7 100644 --- a/Web/Models/Entities/Post.php +++ b/Web/Models/Entities/Post.php @@ -472,6 +472,14 @@ class Post extends Postable { return (float) $this->getRecord()->geo_lon ?? NULL; } + + function getVkApiGeo(): object + { + return (object) [ + 'type' => 'point', + 'coordinates' => $this->getLat() . ',' . $this->getLon(), + ]; + } use Traits\TRichText; } diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index ca3dba89..3790e5a3 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -309,37 +309,20 @@ final class WallPresenter extends OpenVKPresenter $this->flashFail("err", tr("failed_to_publish_post"), "Poll format invalid"); } - if(empty($this->postParam("text")) && sizeof($horizontal_attachments) < 1 && sizeof($vertical_attachments) < 1 && !$poll) - $note = NULL; - - if(!is_null($this->postParam("note")) && $this->postParam("note") != "none") { - $note = (new Notes)->get((int)$this->postParam("note")); - - if(!$note || $note->isDeleted() || $note->getOwner()->getId() != $this->user->id) { - $this->flashFail("err", tr("error"), tr("error_attaching_note")); - } - - if($note->getOwner()->getPrivacySetting("notes.read") < 1) { - $this->flashFail("err", " "); - } - } - $geo = NULL; - if (!is_null($this->postParam("geo")) && $this->postParam("geo") != "none") { + if (!is_null($this->postParam("geo")) && $this->postParam("geo") != "") { $geo = json_decode($this->postParam("geo"), true, JSON_UNESCAPED_UNICODE); - if (!$geo["lat"] || !$geo["lng"] || !$geo["name"]) { - $this->flashFail("err", tr("error"), tr("error_geolocation")); - } - - $latitude = number_format((float) $geo["lat"], 8, ".", ''); - $longitude = number_format((float) $geo["lng"], 8, ".", ''); - if ($latitude > 90 || $latitude < -90 || $longitude > 180 || $longitude < -180) { - $this->flashFail("err", tr("error"), "Invalid latitude or longitude"); + if($geo["lat"] && $geo["lng"] && $geo["name"]) { + $latitude = number_format((float) $geo["lat"], 8, ".", ''); + $longitude = number_format((float) $geo["lng"], 8, ".", ''); + if($latitude > 90 || $latitude < -90 || $longitude > 180 || $longitude < -180) { + $this->flashFail("err", tr("error"), "Invalid latitude or longitude"); + } } } - if(empty($this->postParam("text")) && !$photo && !$video && !$poll && !$note && !$geo) + if(empty($this->postParam("text")) && sizeof($horizontal_attachments) < 1 && sizeof($vertical_attachments) < 1 && !$poll) $this->flashFail("err", tr("failed_to_publish_post"), tr("post_is_empty_or_too_big")); $should_be_suggested = $wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2; @@ -712,49 +695,4 @@ final class WallPresenter extends OpenVKPresenter $this->template->page = $page; $this->template->perPage = OPENVK_DEFAULT_PER_PAGE; } - - function renderNearest(int $wall, int $post_id): void - { - if ($_SERVER["REQUEST_METHOD"] !== "POST") $this->notFound(); - $this->assertUserLoggedIn(); - - $post = $this->posts->getPostById($wall, $post_id); - if(!$post) - $this->notFound(); - - $lat = $post->getLat(); - $lon = $post->getLon(); - - if (!$lat || !$lon) - $this->returnJson(["success" => false, "error" => tr("error_no_geotag")]); - - $query = file_get_contents(__DIR__ . "/../Models/sql/get-nearest-posts.tsql"); - $_posts = DatabaseConnection::i()->getContext()->query($query, $lat, $lon, $post->getId())->fetchAll(); - $posts = []; - foreach ($_posts as $post) { - $distance = $post["distance"]; - $post = (new Posts)->get($post["id"]); - if (!$post || $post->isDeleted()) continue; - - $owner = $post->getOwner(); - - $preview = mb_substr($post->getText(), 0, 50) . (strlen($post->getText()) > 50 ? "..." : ""); - $posts[] = [ - "preview" => strlen($preview) > 0 ? $preview : "(нет текста)", - "url" => "/wall" . $post->getPrettyId(), - "time" => $post->getPublicationTime()->html(), - "owner" => [ - "url" => $owner->getURL(), - "avatar_url" => $owner->getAvatarURL(), - "name" => $owner->getCanonicalName(), - "verified" => $owner->isVerified(), - "writes" => ($owner instanceof User) ? ($owner->isFemale() ? tr("post_writes_f") : tr("post_writes_m")) : tr("post_writes_m") - ], - "geo" => $post->getGeo(), - "distance" => $distance - ]; - } - - $this->returnJson(["success" => true, "posts" => $posts, "need_count" => count($posts) === 25]); - } } diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index b7d84b96..811548cd 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -404,6 +404,11 @@ {script "js/al_feed.js"} {/ifset} + {script "js/node_modules/leaflet/dist/leaflet.js"} + {script "js/node_modules/leaflet-control-geocoder/dist/Control.Geocoder.js"} + {css "js/node_modules/leaflet/dist/leaflet.css"} + {css "js/node_modules/leaflet-control-geocoder/dist/Control.Geocoder.css"} + diff --git a/Web/Presenters/templates/components/post/microblogpost.xml b/Web/Presenters/templates/components/post/microblogpost.xml index ba4a8667..b39b8239 100644 --- a/Web/Presenters/templates/components/post/microblogpost.xml +++ b/Web/Presenters/templates/components/post/microblogpost.xml @@ -92,10 +92,12 @@ -
-- - + + |
-
- ${post.preview}
+
+
+ ${escapeHtml(post.message)}
-
${tr("geotag")}: ${post.geo.name ?? tr("admin_open")}
+
+ ${tplMapIcon}
+ ${escapeHtml(post.geo.name)}
+
|
@@ -2745,14 +2775,14 @@ function getPostPopup(post) {
}
function openNearPosts(posts) {
- if (posts.posts.length > 0) {
+ if (posts.length > 0) {
let MsgTxt = "";
- MsgTxt += "
-