318 lines
10 KiB
PHP
318 lines
10 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Class: AjaxController
|
||
|
* The logic controlling AJAX requests.
|
||
|
*/
|
||
|
class AjaxController extends Controllers implements Controller {
|
||
|
# String: $base
|
||
|
# The base path for this controller.
|
||
|
public $base = "ajax";
|
||
|
|
||
|
# Boolean: $clean
|
||
|
# Does this controller support clean URLs?
|
||
|
public $clean_urls = false;
|
||
|
|
||
|
# Boolean: $feed
|
||
|
# Serve a syndication feed?
|
||
|
public $feed = false;
|
||
|
|
||
|
/**
|
||
|
* Function: parse
|
||
|
* Route constructor calls this to determine the action in the case of a POST request.
|
||
|
*/
|
||
|
public function parse($route): ?string {
|
||
|
if (
|
||
|
isset($_SERVER['HTTP_SEC_FETCH_SITE']) and
|
||
|
$_SERVER['HTTP_SEC_FETCH_SITE'] != "same-origin"
|
||
|
) {
|
||
|
show_403();
|
||
|
}
|
||
|
|
||
|
if (empty($route->action) and isset($_POST['action']))
|
||
|
return $route->action = $_POST['action'];
|
||
|
|
||
|
if (!isset($route->action))
|
||
|
error(
|
||
|
__("Error"),
|
||
|
__("Missing argument."),
|
||
|
code:400
|
||
|
);
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function: exempt
|
||
|
* Route constructor calls this to determine "view_site" exemptions.
|
||
|
*/
|
||
|
public function exempt($action): bool {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function: ajax_destroy_post
|
||
|
* Destroys a post.
|
||
|
*/
|
||
|
public function ajax_destroy_post(): void {
|
||
|
if (!isset($_POST['hash']) or !Session::check_token($_POST['hash']))
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("Invalid authentication token.")
|
||
|
);
|
||
|
|
||
|
if (empty($_POST['id']) or !is_numeric($_POST['id']))
|
||
|
error(
|
||
|
__("No ID Specified"),
|
||
|
__("An ID is required to delete a post."),
|
||
|
code:400
|
||
|
);
|
||
|
|
||
|
$post = new Post(
|
||
|
$_POST['id'], array("drafts" => true)
|
||
|
);
|
||
|
|
||
|
if ($post->no_results)
|
||
|
show_404(
|
||
|
__("Not Found"),
|
||
|
__("Post not found.")
|
||
|
);
|
||
|
|
||
|
if (!$post->deletable())
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("You do not have sufficient privileges to delete this post.")
|
||
|
);
|
||
|
|
||
|
Post::delete($post->id);
|
||
|
json_response(__("Post deleted."), true);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function: ajax_destroy_page
|
||
|
* Destroys a page.
|
||
|
*/
|
||
|
public function ajax_destroy_page(): void {
|
||
|
if (!Visitor::current()->group->can("delete_page"))
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("You do not have sufficient privileges to delete pages.")
|
||
|
);
|
||
|
|
||
|
if (!isset($_POST['hash']) or !Session::check_token($_POST['hash']))
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("Invalid authentication token.")
|
||
|
);
|
||
|
|
||
|
if (empty($_POST['id']) or !is_numeric($_POST['id']))
|
||
|
error(
|
||
|
__("No ID Specified"),
|
||
|
__("An ID is required to delete a page."),
|
||
|
code:400
|
||
|
);
|
||
|
|
||
|
$page = new Page($_POST['id']);
|
||
|
|
||
|
if ($page->no_results)
|
||
|
show_404(
|
||
|
__("Not Found"),
|
||
|
__("Page not found.")
|
||
|
);
|
||
|
|
||
|
Page::delete($page->id, true);
|
||
|
json_response(__("Page deleted."), true);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function: ajax_preview_post
|
||
|
* Previews a post.
|
||
|
*/
|
||
|
public function ajax_preview_post(): void {
|
||
|
if (!isset($_POST['hash']) or !Session::check_token($_POST['hash']))
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("Invalid authentication token.")
|
||
|
);
|
||
|
|
||
|
if (!Visitor::current()->group->can("add_post", "add_draft"))
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("You do not have sufficient privileges to add posts.")
|
||
|
);
|
||
|
|
||
|
$trigger = Trigger::current();
|
||
|
$main = MainController::current();
|
||
|
|
||
|
$class = camelize(fallback($_POST['safename'], "text"));
|
||
|
$field = fallback($_POST['field'], "body");
|
||
|
$content = fallback($_POST['content'], "");
|
||
|
|
||
|
# Custom filters.
|
||
|
if (isset(Feathers::$custom_filters[$class])) {
|
||
|
foreach (Feathers::$custom_filters[$class] as $custom_filter) {
|
||
|
if ($custom_filter["field"] == $field)
|
||
|
$content = call_user_func_array(
|
||
|
array(
|
||
|
Feathers::$instances[$_POST['safename']],
|
||
|
$custom_filter["name"]
|
||
|
),
|
||
|
array($content)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Trigger filters.
|
||
|
if (isset(Feathers::$filters[$class])) {
|
||
|
foreach (Feathers::$filters[$class] as $filter) {
|
||
|
if ($filter["field"] == $field and !empty($content))
|
||
|
$trigger->filter($content, $filter["name"]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
header("Cache-Control: no-cache, must-revalidate");
|
||
|
header("Expires: Mon, 03 Jun 1991 05:30:00 GMT");
|
||
|
|
||
|
$main->display(
|
||
|
"content".DIR."preview",
|
||
|
array("content" => $content),
|
||
|
__("Preview")
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function: ajax_preview_page
|
||
|
* Previews a page.
|
||
|
*/
|
||
|
public function ajax_preview_page(): void {
|
||
|
if (!isset($_POST['hash']) or !Session::check_token($_POST['hash']))
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("Invalid authentication token.")
|
||
|
);
|
||
|
|
||
|
if (!Visitor::current()->group->can("add_page"))
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("You do not have sufficient privileges to add pages.")
|
||
|
);
|
||
|
|
||
|
$trigger = Trigger::current();
|
||
|
$main = MainController::current();
|
||
|
|
||
|
$field = fallback($_POST['field'], "body");
|
||
|
$content = fallback($_POST['content'], "");
|
||
|
|
||
|
# Page title filters.
|
||
|
if ($field == "title")
|
||
|
$trigger->filter($content, array("markup_page_title", "markup_title"));
|
||
|
|
||
|
# Page body filters.
|
||
|
if ($field == "body")
|
||
|
$trigger->filter($content, array("markup_page_text", "markup_text"));
|
||
|
|
||
|
header("Cache-Control: no-cache, must-revalidate");
|
||
|
header("Expires: Mon, 03 Jun 1991 05:30:00 GMT");
|
||
|
|
||
|
$main->display(
|
||
|
"content".DIR."preview",
|
||
|
array("content" => $content),
|
||
|
__("Preview")
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function: ajax_file_upload
|
||
|
* Moves a file to the uploads directory.
|
||
|
*/
|
||
|
public function ajax_file_upload(): void {
|
||
|
if (!isset($_POST['hash']) or !Session::check_token($_POST['hash']))
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("Invalid authentication token.")
|
||
|
);
|
||
|
|
||
|
if (
|
||
|
!Visitor::current()->group->can(
|
||
|
"add_post",
|
||
|
"edit_post",
|
||
|
"add_draft",
|
||
|
"edit_draft",
|
||
|
"edit_own_post",
|
||
|
"edit_own_draft",
|
||
|
"add_page",
|
||
|
"edit_page"
|
||
|
)
|
||
|
)
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("You do not have sufficient privileges to upload files.")
|
||
|
);
|
||
|
|
||
|
if (!isset($_FILES['file']))
|
||
|
error(
|
||
|
__("Error"),
|
||
|
__("Missing argument."),
|
||
|
code:400
|
||
|
);
|
||
|
|
||
|
if (upload_tester($_FILES['file'])) {
|
||
|
$filename = upload($_FILES['file']);
|
||
|
$url = Config::current()->chyrp_url.
|
||
|
"/includes/thumbnail.php?file=".urlencode($filename);
|
||
|
|
||
|
$data = array("file" => $filename, "url" => $url);
|
||
|
json_response(__("File uploaded."), $data);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function ajax_uploads_modal(): void {
|
||
|
if (!isset($_POST['hash']) or !Session::check_token($_POST['hash']))
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("Invalid authentication token.")
|
||
|
);
|
||
|
|
||
|
if (!Visitor::current()->group->can("edit_post", "edit_page", true))
|
||
|
show_403(
|
||
|
__("Access Denied"),
|
||
|
__("You do not have sufficient privileges to manage uploads.")
|
||
|
);
|
||
|
|
||
|
$search = fallback($_POST['search'], "");
|
||
|
$filter = fallback($_POST['filter'], "");
|
||
|
$sort = fallback($_SESSION['uploads_sort'], "name");
|
||
|
|
||
|
$extensions = array();
|
||
|
$exploded = explode(",", $filter);
|
||
|
|
||
|
foreach ($exploded as $value) {
|
||
|
$value = trim($value, " .");
|
||
|
|
||
|
if ($value != "")
|
||
|
$extensions[] = $value;
|
||
|
}
|
||
|
|
||
|
$uploads = uploaded_search(
|
||
|
search:$search,
|
||
|
filter:$extensions,
|
||
|
sort:$sort
|
||
|
);
|
||
|
|
||
|
$admin = AdminController::current();
|
||
|
$admin->display(
|
||
|
"partials".DIR."uploads_modal",
|
||
|
array("uploads" => $uploads)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function: current
|
||
|
* Returns a singleton reference to the current class.
|
||
|
*/
|
||
|
public static function & current(): self {
|
||
|
static $instance = null;
|
||
|
$instance = (empty($instance)) ? new self() : $instance ;
|
||
|
return $instance;
|
||
|
}
|
||
|
}
|