diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php
index 467d59fe..f8d9fca2 100644
--- a/ServiceAPI/Wall.php
+++ b/ServiceAPI/Wall.php
@@ -2,8 +2,6 @@
namespace openvk\ServiceAPI;
use openvk\Web\Models\Entities\Post;
use openvk\Web\Models\Entities\User;
-use openvk\Web\Models\Entities\Notifications\PostAcceptedNotification;
-use openvk\Web\Models\Repositories\{Posts, Notes};
use openvk\Web\Models\Repositories\{Posts, Notes, Videos};
class Wall implements Handler
@@ -101,67 +99,7 @@ class Wall implements Handler
$resolve($arr);
}
-
- function declinePost(int $id, callable $resolve, callable $reject)
- {
- $post = $this->posts->get($id);
- if(!$post || $post->isDeleted())
- $reject(11, "No post with id=$id");
-
- if($post->getSuggestionType() == 0)
- $reject(19, "Post is not suggested");
-
- if($post->getSuggestionType() == 2)
- $reject(10, "Post is already declined");
-
- if(!$post->canBePinnedBy($this->user))
- $reject(22, "Access to post denied");
-
- $post->setSuggested(2);
- $post->setDeleted(1);
- $post->save();
-
- $resolve($this->posts->getSuggestedPostsCount($post->getWallOwner()->getId()));
- }
-
- function acceptPost(int $id, bool $sign, string $content, callable $resolve, callable $reject)
- {
- $post = $this->posts->get($id);
- if(!$post || $post->isDeleted())
- $reject(11, "No post with id=$id");
-
- if($post->getSuggestionType() == 0)
- $reject(19, "Post is not suggested");
-
- if($post->getSuggestionType() == 2)
- $reject(10, "Post is declined");
-
- if(!$post->canBePinnedBy($this->user))
- $reject(22, "Access to post denied");
-
- $author = $post->getOwner();
- $flags = 0;
- $flags |= 0b10000000;
-
- if($sign)
- $flags |= 0b01000000;
-
- $post->setSuggested(0);
- $post->setCreated(time());
- $post->setApi_Source_Name(NULL);
- $post->setFlags($flags);
-
- if(mb_strlen($content) > 0)
- $post->setContent($content);
-
- $post->save();
-
- if($author->getId() != $this->user->getId())
- (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit();
- $resolve(["id" => $post->getPrettyId(), "new_count" => $this->posts->getSuggestedPostsCount($post->getWallOwner()->getId())]);
- }
-
function getVideos(int $page = 1, callable $resolve, callable $reject)
{
$videos = $this->videos->getByUser($this->user, $page, 8);
diff --git a/Web/Models/Entities/Post.php b/Web/Models/Entities/Post.php
index a43a8b47..a53ede22 100644
--- a/Web/Models/Entities/Post.php
+++ b/Web/Models/Entities/Post.php
@@ -264,6 +264,12 @@ class Post extends Postable
if($this->getTargetWall() > 0)
return $this->getPublicationTime()->timestamp() + WEEK > time() && $user->getId() == $this->getOwner(false)->getId();
+ else {
+ if($this->isPostedOnBehalfOfGroup())
+ return $this->getWallOwner()->canBeModifiedBy($user);
+ else
+ return $user->getId() == $this->getOwner(false)->getId();
+ }
return $user->getId() == $this->getOwner(false)->getId();
}
diff --git a/Web/Presenters/InternalAPIPresenter.php b/Web/Presenters/InternalAPIPresenter.php
index e2e6b50e..dca5db04 100644
--- a/Web/Presenters/InternalAPIPresenter.php
+++ b/Web/Presenters/InternalAPIPresenter.php
@@ -104,7 +104,7 @@ final class InternalAPIPresenter extends OpenVKPresenter
}
if($this->postParam("parentType", false) == "post") {
- $post = (new Posts)->getPostById($owner_id, $post_id);
+ $post = (new Posts)->getPostById($owner_id, $post_id, true);
} else {
$post = (new Comments)->get($post_id);
}
diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php
index 39bc86a3..9c7bfaa4 100644
--- a/Web/Presenters/WallPresenter.php
+++ b/Web/Presenters/WallPresenter.php
@@ -2,7 +2,7 @@
namespace openvk\Web\Presenters;
use openvk\Web\Models\Exceptions\TooMuchOptionsException;
use openvk\Web\Models\Entities\{Poll, Post, Photo, Video, Club, User};
-use openvk\Web\Models\Entities\Notifications\{MentionNotification, NewSuggestedPostsNotification, RepostNotification, WallPostNotification};
+use openvk\Web\Models\Entities\Notifications\{MentionNotification, NewSuggestedPostsNotification, RepostNotification, WallPostNotification, PostAcceptedNotification};
use openvk\Web\Models\Repositories\{Posts, Users, Clubs, Albums, Notes, Videos, Comments, Photos};
use Chandler\Database\DatabaseConnection;
use Nette\InvalidStateException as ISE;
@@ -624,4 +624,93 @@ final class WallPresenter extends OpenVKPresenter
"avatar" => $post->getOwner()->getAvatarUrl()
]]);
}
+
+ function renderAccept() {
+ $this->assertUserLoggedIn();
+ $this->willExecuteWriteAction(true);
+
+ if($_SERVER["REQUEST_METHOD"] !== "POST") {
+ header("HTTP/1.1 405 Method Not Allowed");
+ exit("Ты дебил, это точка апи.");
+ }
+
+ $id = $this->postParam("id");
+ $sign = $this->postParam("sign") == 1;
+ $content = $this->postParam("new_content");
+
+ $post = (new Posts)->get((int)$id);
+
+ if(!$post || $post->isDeleted())
+ $this->flashFail("err", "Error", tr("error_accepting_invalid_post"), NULL, true);
+
+ if($post->getSuggestionType() == 0)
+ $this->flashFail("err", "Error", tr("error_accepting_not_suggested_post"), NULL, true);
+
+ if($post->getSuggestionType() == 2)
+ $this->flashFail("err", "Error", tr("error_accepting_declined_post"), NULL, true);
+
+ if(!$post->canBePinnedBy($this->user->identity))
+ $this->flashFail("err", "Error", "Can't accept this post.", NULL, true);
+
+ $author = $post->getOwner();
+
+ $flags = 0;
+ $flags |= 0b10000000;
+
+ if($sign)
+ $flags |= 0b01000000;
+
+ $post->setSuggested(0);
+ $post->setCreated(time());
+ $post->setApi_Source_Name(NULL);
+ $post->setFlags($flags);
+
+ if(mb_strlen($content) > 0)
+ $post->setContent($content);
+
+ $post->save();
+
+ if($author->getId() != $this->user->id)
+ (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit();
+
+ $this->returnJson([
+ "success" => true,
+ "id" => $post->getPrettyId(),
+ "new_count" => (new Posts)->getSuggestedPostsCount($post->getWallOwner()->getId())
+ ]);
+ }
+
+ function renderDecline() {
+ $this->assertUserLoggedIn();
+ $this->willExecuteWriteAction(true);
+
+ if($_SERVER["REQUEST_METHOD"] !== "POST") {
+ header("HTTP/1.1 405 Method Not Allowed");
+ exit("Ты дебил, это метод апи.");
+ }
+
+ $id = $this->postParam("id");
+ $post = (new Posts)->get((int)$id);
+
+ if(!$post || $post->isDeleted())
+ $this->flashFail("err", "Error", tr("error_declining_invalid_post"), NULL, true);
+
+ if($post->getSuggestionType() == 0)
+ $this->flashFail("err", "Error", tr("error_declining_not_suggested_post"), NULL, true);
+
+ if($post->getSuggestionType() == 2)
+ $this->flashFail("err", "Error", tr("error_declining_declined_post"), NULL, true);
+
+ if(!$post->canBePinnedBy($this->user->identity))
+ $this->flashFail("err", "Error", "Can't decline this post.", NULL, true);
+
+ $post->setSuggested(2);
+ $post->setDeleted(1);
+ $post->save();
+
+ $this->returnJson([
+ "success" => true,
+ "new_count" => (new Posts)->getSuggestedPostsCount($post->getWallOwner()->getId())
+ ]);
+ }
}
diff --git a/Web/routes.yml b/Web/routes.yml
index 5703fd28..755ec2f3 100644
--- a/Web/routes.yml
+++ b/Web/routes.yml
@@ -141,6 +141,10 @@ routes:
handler: "Wall->delete"
- url: "/wall{num}_{num}/pin"
handler: "Wall->pin"
+ - url: "/wall/accept"
+ handler: "Wall->accept"
+ - url: "/wall/decline"
+ handler: "Wall->decline"
- url: "/blob_{text}/{?path}.{text}"
handler: "Blob->file"
placeholders:
diff --git a/Web/static/js/al_suggestions.js b/Web/static/js/al_suggestions.js
index 4b702cb5..1c3da3e8 100644
--- a/Web/static/js/al_suggestions.js
+++ b/Web/static/js/al_suggestions.js
@@ -1,3 +1,32 @@
+function endSuggestAction(new_count, post_node) {
+ if(document.getElementById("cound") != null)
+ document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", new_count)
+ else
+ document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", new_count)
+
+ if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) {
+ document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = new_count
+
+ if(new_count < 1) {
+ u("object a[href='"+location.pathname+"']").remove()
+ }
+ }
+
+ if(new_count < 1 && document.querySelector(".sugglist") != null) {
+ $(".sugglist a").click()
+ $(".sugglist").remove()
+ }
+
+ post_node.style.transition = "opacity 300ms ease-in-out";
+ post_node.style.opacity = "0";
+ post_node.classList.remove("post")
+
+ setTimeout(() => {post_node.outerHTML = ""}, 300)
+
+ if(document.querySelectorAll("#postz .post").length < 1 && new_count > 0 && document.querySelector(".paginator") != null)
+ loadMoreSuggestedPosts()
+}
+
// "Опубликовать запись"
$(document).on("click", "#publish_post", async (e) => {
let id = Number(e.currentTarget.dataset.id)
@@ -11,178 +40,122 @@ $(document).on("click", "#publish_post", async (e) => {
let id = Number(e.currentTarget.dataset.id)
let post;
- try {
- e.currentTarget.classList.add("loaded")
- e.currentTarget.setAttribute("value", "")
- e.currentTarget.setAttribute("id", "")
- post = await API.Wall.acceptPost(id, document.getElementById("signatr").checked, document.getElementById("pooblish").value)
- } catch(ex) {
- switch(ex.code) {
- case 11:
- MessageBox(tr("error"), tr("error_accepting_invalid_post"), [tr("ok")], [Function.noop]);
- break;
- case 19:
- MessageBox(tr("error"), tr("error_accepting_not_suggested_post"), [tr("ok")], [Function.noop]);
- break;
- case 10:
- MessageBox(tr("error"), tr("error_accepting_declined_post"), [tr("ok")], [Function.noop]);
- break;
- case 22:
- MessageBox(tr("error"), "Access denied", [tr("ok")], [Function.noop]);
- break;
- default:
- MessageBox(tr("error"), "Unknown error "+ex.code+": "+ex.message, [tr("ok")], [Function.noop]);
- break;
- }
+ let formData = new FormData()
+ formData.append("id", id)
+ formData.append("sign", document.getElementById("signatr").checked ? 1 : 0)
+ formData.append("new_content", document.getElementById("pooblish").value)
+ formData.append("hash", u("meta[name=csrf]").attr("value"))
- e.currentTarget.setAttribute("value", tr("publish_suggested"))
- e.currentTarget.classList.remove("loaded")
- e.currentTarget.setAttribute("id", "publish_post")
- return 0;
- }
+ ky.post("/wall/accept", {
+ hooks: {
+ beforeRequest: [
+ (_request) => {
+ e.currentTarget.classList.add("loaded")
+ e.currentTarget.setAttribute("value", "")
+ e.currentTarget.setAttribute("id", "")
+ }
+ ],
+ afterResponse: [
+ async (_request, _options, response) => {
+ json = await response.json()
- NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + post.id)});
-
- if(document.getElementById("cound") != null)
- document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post.new_count)
- else
- document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post.new_count)
+ if(json.success) {
+ NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + json.id)});
+ endSuggestAction(json.new_count, e.currentTarget.closest("table"))
+ } else {
+ MessageBox(tr("error"), json.flash.message, [tr("ok")], [Function.noop]);
+ }
- if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) {
- document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post.new_count
-
- if(post.new_count < 1) {
- u("object a[href='"+location.pathname+"']").remove()
- }
- }
-
- if(post.new_count < 1 && document.querySelector(".sugglist") != null) {
- $(".sugglist a").click()
- $(".sugglist").remove()
- }
-
- let post_node = e.currentTarget.closest("table")
- post_node.style.transition = "opacity 300ms ease-in-out";
- post_node.style.opacity = "0";
- post_node.classList.remove("post")
-
- setTimeout(() => {post_node.outerHTML = ""}, 300)
-
- if(document.querySelectorAll("#postz .post").length < 1 && post.new_count > 0 && document.querySelector(".paginator") != null)
- loadMoreSuggestedPosts()
+ e.currentTarget.setAttribute("value", tr("publish_suggested"))
+ e.currentTarget.classList.remove("loaded")
+ e.currentTarget.setAttribute("id", "publish_post")
+ }
+ ]
+ },
+ body: formData
+ })
}), Function.noop]);
- document.getElementById("pooblish").innerHTML = e.currentTarget.closest("table").querySelector(".really_text").innerHTML.replace(/(<([^>]+)>)/gi, '')
+ document.getElementById("pooblish").innerHTML = e.currentTarget.closest("table").querySelector(".really_text").dataset.text
document.querySelector(".ovk-diag-body").style.padding = "9px";
})
// "Отклонить"
$(document).on("click", "#decline_post", async (e) => {
let id = Number(e.currentTarget.dataset.id)
- let post;
- try {
- e.currentTarget.classList.add("loaded")
- e.currentTarget.setAttribute("value", "")
- e.currentTarget.setAttribute("id", "")
- post = await API.Wall.declinePost(id)
- } catch(ex) {
- switch(ex.code) {
- case 11:
- MessageBox(tr("error"), tr("error_declining_invalid_post"), [tr("ok")], [Function.noop]);
- break;
- case 19:
- MessageBox(tr("error"), tr("error_declining_not_suggested_post"), [tr("ok")], [Function.noop]);
- break;
- case 10:
- MessageBox(tr("error"), tr("error_declining_declined_post"), [tr("ok")], [Function.noop]);
- break;
- case 22:
- MessageBox(tr("error"), "Access denied", [tr("ok")], [Function.noop]);
- break;
- default:
- MessageBox(tr("error"), "Unknown error "+ex.code+": "+ex.message, [tr("ok")], [Function.noop]);
- break;
- }
+ let formData = new FormData()
+ formData.append("id", id)
+ formData.append("hash", u("meta[name=csrf]").attr("value"))
- e.currentTarget.setAttribute("value", tr("decline_suggested"))
- e.currentTarget.setAttribute("id", "decline_post")
- e.currentTarget.classList.remove("loaded")
- return 0;
- }
-
- //NewNotification(tr("suggestion_succefully_declined"), "", null);
+ ky.post("/wall/decline", {
+ hooks: {
+ beforeRequest: [
+ (_request) => {
+ e.currentTarget.classList.add("loaded")
+ e.currentTarget.setAttribute("value", "")
+ e.currentTarget.setAttribute("id", "")
+ }
+ ],
+ afterResponse: [
+ async (_request, _options, response) => {
+ json = await response.json()
- let post_node = e.currentTarget.closest("table")
- post_node.style.transition = "opacity 300ms ease-in-out";
- post_node.style.opacity = "0";
- post_node.classList.remove("post")
+ if(json.success) {
+ endSuggestAction(json.new_count, e.currentTarget.closest("table"))
+ } else {
+ MessageBox(tr("error"), json.flash.message, [tr("ok")], [Function.noop]);
+ }
- setTimeout(() => {post_node.outerHTML = ""}, 300)
-
- if(document.getElementById("cound") != null)
- document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post)
- else
- document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post)
-
- if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) {
- document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post
-
- if(post < 1) {
- u("object a[href='"+location.pathname+"']").remove()
- }
- }
-
- if(post < 1 && document.querySelector(".sugglist") != null) {
- $(".sugglist a").click()
- $(".sugglist").remove()
- }
-
- if(document.querySelectorAll("#postz .post").length < 1 && post > 0 && document.querySelector(".paginator") != null)
- loadMoreSuggestedPosts()
+ e.currentTarget.setAttribute("value", tr("decline_suggested"))
+ e.currentTarget.setAttribute("id", "decline_post")
+ e.currentTarget.classList.remove("loaded")
+ }
+ ]
+ },
+ body: formData
+ })
})
-function loadMoreSuggestedPosts()
-{
- let xhr = new XMLHttpRequest
+function loadMoreSuggestedPosts() {
let link = location.href
if(!link.includes("/suggested")) {
link += "/suggested"
}
- xhr.open("GET", link)
+ ky.get(link, {
+ hooks: {
+ beforeRequest: [
+ (_request) => {
+ document.getElementById("postz").innerHTML = `
`
+ }
+ ],
+ afterResponse: [
+ async (_request, _options, response) => {
+ let text = await response.text()
+ let parser = new DOMParser()
+ let body = parser.parseFromString(text, "text/html")
- xhr.onloadstart = () => {
- document.getElementById("postz").innerHTML = `
`
- }
+ if(body.querySelectorAll(".post").length < 1) {
+ let url = new URL(location.href)
+ url.searchParams.set("p", url.searchParams.get("p") - 1)
+
+ if(url.searchParams.get("p") < 1) {
+ return 0;
+ }
- xhr.onload = () => {
- let parser = new DOMParser()
- let body = parser.parseFromString(xhr.responseText, "text/html").getElementById("postz")
+ history.pushState({}, "", url)
+
+ loadMoreSuggestedPosts()
+ }
- if(body.querySelectorAll(".post").length < 1) {
- let url = new URL(location.href)
- url.searchParams.set("p", url.searchParams.get("p") - 1)
-
- if(url.searchParams.get("p") < 1) {
- return 0;
- }
-
- // OVK AJAX ROUTING ??????????
- history.pushState({}, "", url)
-
- loadMoreSuggestedPosts()
+ body.querySelectorAll(".bsdn").forEach(bsdnInitElement)
+ document.getElementById("postz").innerHTML = body.getElementById("postz").innerHTML
+ }
+ ]
}
-
- document.getElementById("postz").innerHTML = body.innerHTML
- }
-
- xhr.onerror = () => {
- document.getElementById("postz").innerHTML = tr("error_loading_suggest")
- }
-
- xhr.send()
+ })
}
// нажатие на "x предложенных записей"
@@ -198,29 +171,24 @@ $(document).on("click", ".sugglist a", (e) => {
// если ещё ничего не подгружалось
if(document.querySelector(".insertThere").innerHTML == "") {
- let xhr = new XMLHttpRequest
- xhr.open("GET", e.currentTarget.href)
-
- xhr.onloadstart = () => {
- // лоадер
- document.querySelector(".insertThere").insertAdjacentHTML("afterbegin", `
`)
- }
-
- xhr.onload = () => {
- let parser = new DOMParser
- let result = parser.parseFromString(xhr.responseText, 'text/html').querySelector(".infContainer")
- // парсинг результата и вставка постов
- document.querySelector(".insertThere").innerHTML = result.innerHTML
- }
-
- function errorl() {
- document.getElementById("postz").innerHTML = tr("error_loading_suggest")
- }
-
- xhr.onerror = () => {errorl()}
- xhr.ontimeout = () => {errorl()}
-
- xhr.send()
+ ky(e.currentTarget.href, {
+ hooks: {
+ beforeRequest: [
+ (_request) => {
+ document.querySelector(".insertThere").insertAdjacentHTML("afterbegin", `
`)
+ }
+ ],
+ afterResponse: [
+ async (_request, _options, response) => {
+ let parser = new DOMParser
+ let result = parser.parseFromString(await response.text(), 'text/html').querySelector(".infContainer")
+
+ result.querySelectorAll(".bsdn").forEach(bsdnInitElement)
+ document.querySelector(".insertThere").innerHTML = result.innerHTML
+ }
+ ]
+ }
+ })
}
} else {
// переключение на нормальную стену
@@ -232,37 +200,32 @@ $(document).on("click", ".sugglist a", (e) => {
}
})
-// нажатие на пагинатор у постов пъедложки
+// нажатие на пагинатор у постов предложки
$(document).on("click", "#postz .paginator a", (e) => {
e.preventDefault()
- let xhr = new XMLHttpRequest
- xhr.open("GET", e.currentTarget.href)
-
- xhr.onloadstart = () => {
- if(document.querySelector(".sugglist") != null) {
- document.querySelector(".sugglist").scrollIntoView({behavior: "smooth"})
- } else {
- document.querySelector(".infContainer").scrollIntoView({behavior: "smooth"})
+ ky(e.currentTarget.href, {
+ hooks: {
+ beforeRequest: [
+ (_request) => {
+ if(document.querySelector(".sugglist") != null) {
+ document.querySelector(".sugglist").scrollIntoView({behavior: "smooth"})
+ } else {
+ document.querySelector(".infContainer").scrollIntoView({behavior: "smooth"})
+ }
+
+ setTimeout(() => {document.getElementById("postz").innerHTML = `
`}, 500)
+ }
+ ],
+ afterResponse: [
+ async (_request, _options, response) => {
+ let result = (new DOMParser).parseFromString(await response.text(), "text/html").querySelector(".infContainer")
+ result.querySelectorAll(".bsdn").forEach(bsdnInitElement)
+
+ document.getElementById("postz").innerHTML = result.innerHTML
+ history.pushState({}, "", e.currentTarget.href)
+ }
+ ]
}
- // после того как долистали наверх, добавляем лоадер
- setTimeout(() => {document.getElementById("postz").innerHTML = `
`}, 500)
- }
-
- xhr.onload = () => {
- // опять парс
- let result = (new DOMParser).parseFromString(xhr.responseText, "text/html").querySelector(".infContainer")
- // опять вставка
- document.getElementById("postz").innerHTML = result.innerHTML
- history.pushState({}, "", e.currentTarget.href)
- }
-
- function errorl() {
- document.getElementById("postz").innerHTML = tr("error_loading_suggest")
- }
-
- xhr.onerror = () => {errorl()}
- xhr.ontimeout = () => {errorl()}
-
- xhr.send()
+ })
})