Simplefai ze kod

This commit is contained in:
lalka2018 2023-10-10 18:16:48 +03:00
parent a0e895824c
commit 029d21c7ee
6 changed files with 261 additions and 261 deletions

View file

@ -2,8 +2,6 @@
namespace openvk\ServiceAPI; namespace openvk\ServiceAPI;
use openvk\Web\Models\Entities\Post; use openvk\Web\Models\Entities\Post;
use openvk\Web\Models\Entities\User; 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}; use openvk\Web\Models\Repositories\{Posts, Notes, Videos};
class Wall implements Handler class Wall implements Handler
@ -102,66 +100,6 @@ class Wall implements Handler
$resolve($arr); $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) function getVideos(int $page = 1, callable $resolve, callable $reject)
{ {
$videos = $this->videos->getByUser($this->user, $page, 8); $videos = $this->videos->getByUser($this->user, $page, 8);

View file

@ -264,6 +264,12 @@ class Post extends Postable
if($this->getTargetWall() > 0) if($this->getTargetWall() > 0)
return $this->getPublicationTime()->timestamp() + WEEK > time() && $user->getId() == $this->getOwner(false)->getId(); 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(); return $user->getId() == $this->getOwner(false)->getId();
} }

View file

@ -104,7 +104,7 @@ final class InternalAPIPresenter extends OpenVKPresenter
} }
if($this->postParam("parentType", false) == "post") { if($this->postParam("parentType", false) == "post") {
$post = (new Posts)->getPostById($owner_id, $post_id); $post = (new Posts)->getPostById($owner_id, $post_id, true);
} else { } else {
$post = (new Comments)->get($post_id); $post = (new Comments)->get($post_id);
} }

View file

@ -2,7 +2,7 @@
namespace openvk\Web\Presenters; namespace openvk\Web\Presenters;
use openvk\Web\Models\Exceptions\TooMuchOptionsException; use openvk\Web\Models\Exceptions\TooMuchOptionsException;
use openvk\Web\Models\Entities\{Poll, Post, Photo, Video, Club, User}; 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 openvk\Web\Models\Repositories\{Posts, Users, Clubs, Albums, Notes, Videos, Comments, Photos};
use Chandler\Database\DatabaseConnection; use Chandler\Database\DatabaseConnection;
use Nette\InvalidStateException as ISE; use Nette\InvalidStateException as ISE;
@ -624,4 +624,93 @@ final class WallPresenter extends OpenVKPresenter
"avatar" => $post->getOwner()->getAvatarUrl() "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())
]);
}
} }

View file

@ -141,6 +141,10 @@ routes:
handler: "Wall->delete" handler: "Wall->delete"
- url: "/wall{num}_{num}/pin" - url: "/wall{num}_{num}/pin"
handler: "Wall->pin" handler: "Wall->pin"
- url: "/wall/accept"
handler: "Wall->accept"
- url: "/wall/decline"
handler: "Wall->decline"
- url: "/blob_{text}/{?path}.{text}" - url: "/blob_{text}/{?path}.{text}"
handler: "Blob->file" handler: "Blob->file"
placeholders: placeholders:

View file

@ -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) => { $(document).on("click", "#publish_post", async (e) => {
let id = Number(e.currentTarget.dataset.id) 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 id = Number(e.currentTarget.dataset.id)
let post; let post;
try { let formData = new FormData()
e.currentTarget.classList.add("loaded") formData.append("id", id)
e.currentTarget.setAttribute("value", "") formData.append("sign", document.getElementById("signatr").checked ? 1 : 0)
e.currentTarget.setAttribute("id", "") formData.append("new_content", document.getElementById("pooblish").value)
post = await API.Wall.acceptPost(id, document.getElementById("signatr").checked, document.getElementById("pooblish").value) formData.append("hash", u("meta[name=csrf]").attr("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;
}
e.currentTarget.setAttribute("value", tr("publish_suggested")) ky.post("/wall/accept", {
e.currentTarget.classList.remove("loaded") hooks: {
e.currentTarget.setAttribute("id", "publish_post") beforeRequest: [
return 0; (_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(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.getElementById("cound") != null) e.currentTarget.setAttribute("value", tr("publish_suggested"))
document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post.new_count) e.currentTarget.classList.remove("loaded")
else e.currentTarget.setAttribute("id", "publish_post")
document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post.new_count) }
]
if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { },
document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post.new_count body: formData
})
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()
}), Function.noop]); }), 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.querySelector(".ovk-diag-body").style.padding = "9px";
}) })
// "Отклонить" // "Отклонить"
$(document).on("click", "#decline_post", async (e) => { $(document).on("click", "#decline_post", async (e) => {
let id = Number(e.currentTarget.dataset.id) let id = Number(e.currentTarget.dataset.id)
let post;
try { let formData = new FormData()
e.currentTarget.classList.add("loaded") formData.append("id", id)
e.currentTarget.setAttribute("value", "") formData.append("hash", u("meta[name=csrf]").attr("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;
}
e.currentTarget.setAttribute("value", tr("decline_suggested")) ky.post("/wall/decline", {
e.currentTarget.setAttribute("id", "decline_post") hooks: {
e.currentTarget.classList.remove("loaded") beforeRequest: [
return 0; (_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_declined"), "", null); if(json.success) {
endSuggestAction(json.new_count, e.currentTarget.closest("table"))
} else {
MessageBox(tr("error"), json.flash.message, [tr("ok")], [Function.noop]);
}
let post_node = e.currentTarget.closest("table") e.currentTarget.setAttribute("value", tr("decline_suggested"))
post_node.style.transition = "opacity 300ms ease-in-out"; e.currentTarget.setAttribute("id", "decline_post")
post_node.style.opacity = "0"; e.currentTarget.classList.remove("loaded")
post_node.classList.remove("post") }
]
setTimeout(() => {post_node.outerHTML = ""}, 300) },
body: formData
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()
}) })
function loadMoreSuggestedPosts() function loadMoreSuggestedPosts() {
{
let xhr = new XMLHttpRequest
let link = location.href let link = location.href
if(!link.includes("/suggested")) { if(!link.includes("/suggested")) {
link += "/suggested" link += "/suggested"
} }
xhr.open("GET", link) ky.get(link, {
hooks: {
beforeRequest: [
(_request) => {
document.getElementById("postz").innerHTML = `<img src="/assets/packages/static/openvk/img/loading_mini.gif">`
}
],
afterResponse: [
async (_request, _options, response) => {
let text = await response.text()
let parser = new DOMParser()
let body = parser.parseFromString(text, "text/html")
xhr.onloadstart = () => { if(body.querySelectorAll(".post").length < 1) {
document.getElementById("postz").innerHTML = `<img src="/assets/packages/static/openvk/img/loading_mini.gif">` let url = new URL(location.href)
} url.searchParams.set("p", url.searchParams.get("p") - 1)
xhr.onload = () => { if(url.searchParams.get("p") < 1) {
let parser = new DOMParser() return 0;
let body = parser.parseFromString(xhr.responseText, "text/html").getElementById("postz") }
if(body.querySelectorAll(".post").length < 1) { history.pushState({}, "", url)
let url = new URL(location.href)
url.searchParams.set("p", url.searchParams.get("p") - 1)
if(url.searchParams.get("p") < 1) { loadMoreSuggestedPosts()
return 0; }
}
// OVK AJAX ROUTING ?????????? body.querySelectorAll(".bsdn").forEach(bsdnInitElement)
history.pushState({}, "", url) document.getElementById("postz").innerHTML = body.getElementById("postz").innerHTML
}
loadMoreSuggestedPosts() ]
} }
})
document.getElementById("postz").innerHTML = body.innerHTML
}
xhr.onerror = () => {
document.getElementById("postz").innerHTML = tr("error_loading_suggest")
}
xhr.send()
} }
// нажатие на "x предложенных записей" // нажатие на "x предложенных записей"
@ -198,29 +171,24 @@ $(document).on("click", ".sugglist a", (e) => {
// если ещё ничего не подгружалось // если ещё ничего не подгружалось
if(document.querySelector(".insertThere").innerHTML == "") { if(document.querySelector(".insertThere").innerHTML == "") {
let xhr = new XMLHttpRequest ky(e.currentTarget.href, {
xhr.open("GET", e.currentTarget.href) hooks: {
beforeRequest: [
(_request) => {
document.querySelector(".insertThere").insertAdjacentHTML("afterbegin", `<img src="/assets/packages/static/openvk/img/loading_mini.gif">`)
}
],
afterResponse: [
async (_request, _options, response) => {
let parser = new DOMParser
let result = parser.parseFromString(await response.text(), 'text/html').querySelector(".infContainer")
xhr.onloadstart = () => { result.querySelectorAll(".bsdn").forEach(bsdnInitElement)
// лоадер document.querySelector(".insertThere").innerHTML = result.innerHTML
document.querySelector(".insertThere").insertAdjacentHTML("afterbegin", `<img src="/assets/packages/static/openvk/img/loading_mini.gif">`) }
} ]
}
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()
} }
} else { } else {
// переключение на нормальную стену // переключение на нормальную стену
@ -232,37 +200,32 @@ $(document).on("click", ".sugglist a", (e) => {
} }
}) })
// нажатие на пагинатор у постов пъедложки // нажатие на пагинатор у постов предложки
$(document).on("click", "#postz .paginator a", (e) => { $(document).on("click", "#postz .paginator a", (e) => {
e.preventDefault() e.preventDefault()
let xhr = new XMLHttpRequest ky(e.currentTarget.href, {
xhr.open("GET", e.currentTarget.href) hooks: {
beforeRequest: [
(_request) => {
if(document.querySelector(".sugglist") != null) {
document.querySelector(".sugglist").scrollIntoView({behavior: "smooth"})
} else {
document.querySelector(".infContainer").scrollIntoView({behavior: "smooth"})
}
xhr.onloadstart = () => { setTimeout(() => {document.getElementById("postz").innerHTML = `<img src="/assets/packages/static/openvk/img/loading_mini.gif">`}, 500)
if(document.querySelector(".sugglist") != null) { }
document.querySelector(".sugglist").scrollIntoView({behavior: "smooth"}) ],
} else { afterResponse: [
document.querySelector(".infContainer").scrollIntoView({behavior: "smooth"}) 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 = `<img src="/assets/packages/static/openvk/img/loading_mini.gif">`}, 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()
}) })