save_uploaded_file() read, and prune_images() deleted, any path in the "uploaded" POST field. Uploads now go to UPLOAD_DIR under a random name that only the session knows.
262 lines
7.7 KiB
PHP
262 lines
7.7 KiB
PHP
<?php
|
|
require_once('../open_db.lib.php');
|
|
require_once('../get_data.lib.php');
|
|
|
|
function save_data($id = NULL) {
|
|
global $db, $is_admin, $queue, $action;
|
|
$image_file = FALSE;
|
|
$queue_id = NULL;
|
|
|
|
// extract POST variables
|
|
$result = get_post_data(TRUE);
|
|
// assign their keys and values to the symbol table
|
|
extract($result[0], EXTR_OVERWRITE);
|
|
|
|
// Visitors can only add a new story to the queue. They cannot pick the
|
|
// table, overwrite an existing story, or set editor-only fields.
|
|
if (!$is_admin) {
|
|
$action = 'submit';
|
|
$id = NULL;
|
|
$date = NULL;
|
|
$hidden = NULL;
|
|
$comments = NULL;
|
|
$editor = 'original author';
|
|
}
|
|
$id = is_numeric($id) ? (int)$id : NULL;
|
|
|
|
$queue = get_queue();
|
|
// Are we posting a story from the queue?
|
|
if ($is_admin && $queue && $action == 'post')
|
|
$move = TRUE;
|
|
else
|
|
$move = FALSE;
|
|
$table = which_table($move, $action);
|
|
|
|
// Process data...
|
|
$story = sanitise($story);
|
|
// Add the date if it's not got one
|
|
if (!$date)
|
|
$date = gmdate("Y-m-d H:i:s");
|
|
// Verify image
|
|
if ($move && isset($id) && isset($uploaded) && $uploaded === (string)$id) {
|
|
// Special case - transfer image from queue table
|
|
if ($getimg = $db->execute_query("SELECT img, mime FROM queue WHERE id = ?", array($id))) {
|
|
$row = $getimg->fetch_assoc();
|
|
$img = $row['img'];
|
|
$mime = $row['mime'];
|
|
$getimg->close();
|
|
} else {
|
|
die("Error in query: $db->error");
|
|
}
|
|
} else {
|
|
$image_file = save_uploaded_file();
|
|
if ($image_file) {
|
|
$img = fread(fopen($image_file, "r"), filesize($image_file));
|
|
$mime = get_mimetype($image_file);
|
|
}
|
|
}
|
|
|
|
// Column => value; the values are bound as query parameters
|
|
$fields = array(
|
|
'title' => $title,
|
|
'author' => $author,
|
|
'email' => $email,
|
|
'editor' => $editor,
|
|
);
|
|
if ($is_admin && isset($comments)) {
|
|
$fields['comments'] = $comments;
|
|
}
|
|
$fields['hidden'] = $hidden ? 1 : 0;
|
|
if ($remove_img && $story) {
|
|
$fields['story'] = $story;
|
|
$fields['mime'] = NULL;
|
|
$fields['img'] = NULL;
|
|
} else if (isset($img)) {
|
|
$fields['mime'] = $mime;
|
|
$fields['img'] = $img;
|
|
$fields['story'] = '';
|
|
} else {
|
|
$fields['story'] = $story;
|
|
}
|
|
if (!is_numeric($id) || $move)
|
|
$fields['date'] = $date;
|
|
|
|
$set = implode(', ', array_map(function ($column) { return "`$column` = ?"; }, array_keys($fields)));
|
|
$params = array_values($fields);
|
|
if (is_numeric($id) && !$move) {
|
|
$query = "UPDATE $table SET $set WHERE `id` = ? LIMIT 1";
|
|
$params[] = $id;
|
|
} else {
|
|
$query = "INSERT INTO $table SET $set";
|
|
}
|
|
|
|
//echo $query;
|
|
$result = $db->execute_query($query, $params) or die("Query failed: ".$db->error);
|
|
|
|
if (is_numeric($id) && $move) {
|
|
$queue_id = $id;
|
|
}
|
|
|
|
// Get the (new) ID if we don't already have it.
|
|
if (!is_numeric($id) || $move) {
|
|
$query = "SELECT LAST_INSERT_ID();";
|
|
$getid = $db->query($query) or die("Query failed: ".$db->error);
|
|
$row = $getid->fetch_row();
|
|
$id = $row[0];
|
|
}
|
|
|
|
// Delete the article in the queue if pushing live
|
|
if ($move && $queue_id) {
|
|
delete_story($queue_id, $move);
|
|
$queue = FALSE;
|
|
}
|
|
|
|
// Allow unprivileged user to view image on queue
|
|
if (!$is_admin && $action == 'submit')
|
|
$_SESSION['allow_queue_image'] = $id;
|
|
|
|
// Prune filesystem
|
|
if ($image_file)
|
|
prune_images($image_file);
|
|
|
|
// email admin if added to the queue
|
|
if ($action == 'submit')
|
|
send_email($title, $author, $story);
|
|
|
|
return $id;
|
|
}
|
|
|
|
function delete_story($id, $move = FALSE) {
|
|
global $db, $is_admin, $queue;
|
|
// Only editors can delete stories
|
|
if (!$is_admin)
|
|
return '';
|
|
$queue = get_queue();
|
|
$table = which_table($move, 'delete');
|
|
|
|
$query = "DELETE FROM $table WHERE `id` = ? LIMIT 1";
|
|
//echo $query;
|
|
$result = $db->execute_query($query, array((int)$id)) or die("Query failed : ".$db->error);
|
|
|
|
$message = '';
|
|
if (!$move)
|
|
$message = 'Article has been deleted.';
|
|
|
|
return $message;
|
|
}
|
|
|
|
function get_mimetype($image_file) {
|
|
$upload = getimagesize($image_file);
|
|
$mimetype = $upload ? $upload['mime'] : NULL;
|
|
return $mimetype;
|
|
}
|
|
|
|
function save_uploaded_file() {
|
|
// A new upload in this request
|
|
if (is_uploaded_file($_FILES['upload']['tmp_name'] ?? '')) {
|
|
return store_upload($_FILES['upload']['tmp_name']);
|
|
}
|
|
// An image uploaded at the preview step; the session knows which one
|
|
if (($_POST['uploaded'] ?? '') === 'pending') {
|
|
return pending_upload();
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
function prune_images($image_file) {
|
|
// Delete the saved image, and anything older than $age.
|
|
// Only ever touch upload files inside the upload directory.
|
|
$age = 86400; // a day old
|
|
$dir = upload_dir();
|
|
if (dirname($image_file) === $dir && is_upload_name(basename($image_file))) {
|
|
@unlink($image_file);
|
|
}
|
|
unset($_SESSION['pending_upload']);
|
|
|
|
foreach (glob($dir . '/*') as $cleanup_file) {
|
|
if (is_upload_name(basename($cleanup_file)) &&
|
|
@filemtime($cleanup_file) < (time() - $age)) {
|
|
@unlink($cleanup_file);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Validate data
|
|
*
|
|
* Updates the global $validate array, with the key as the element name, and the value set to the error message.
|
|
*
|
|
*/
|
|
$validate = array();
|
|
function validate_data() {
|
|
global $validate;
|
|
// extract POST variables
|
|
$result = get_post_data(TRUE);
|
|
// assign their keys and values to the symbol table
|
|
extract($result[0], EXTR_OVERWRITE);
|
|
$upload_error = $_FILES['upload']['error'] ?? UPLOAD_ERR_NO_FILE;
|
|
$upload_tmp = $_FILES['upload']['tmp_name'] ?? '';
|
|
|
|
|
|
if (!$author) {
|
|
$validate['author'] = "You have not submitted an author.";
|
|
}
|
|
|
|
if (!$title) {
|
|
$validate['title'] = "You have not submitted a title.";
|
|
}
|
|
|
|
if ($remove_img && !$story) {
|
|
$validate['story'] = "You've tried to remove an image without replacing it with text.";
|
|
}
|
|
|
|
// 0 == no error; 4 == no file; all others are errors.
|
|
if ($upload_error > 0 &&
|
|
$upload_error !== 4) {
|
|
$validate['upload'] = 'There was an error uploading the file ('.$upload_error.')';
|
|
} else if ($upload_tmp) {
|
|
$upload = getimagesize($upload_tmp);
|
|
if (!$upload)
|
|
$validate['upload'] = htmlspecialchars($_FILES['upload']['name']) .
|
|
" wasn't an image file. Please go back.";
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
function sanitise($story) {
|
|
if ($story) {
|
|
// No Javascript please!
|
|
$story = preg_replace("#<script[^>]*?>.*?</script>#si", "", $story);
|
|
// No comments please!
|
|
$story = preg_replace("#<!--.*?-->#si", "", $story);
|
|
// Replace number ranges with n-dashes
|
|
$stort = preg_replace("#(\d)-+(\d)#si", "$1–$2", $story);
|
|
// Replace " -- " and "--" with m-dashes
|
|
$story = preg_replace("#(\s?)--(\s?)#si", "$1—$2", $story);
|
|
// Replace ellipses
|
|
$story = preg_replace("#(\w|\p{P}|>)\. ?\. ?\.(\s|\p{P})#si", "$1…$2", $story);
|
|
|
|
// External processing
|
|
include_once('../lib/smartypants.inc.php');
|
|
$story = SmartyPants($story);
|
|
#include_once('../lib/convert_entities.inc.php');
|
|
#$story = html_entity_decode_full($story); // Convert named entities to numeric entities
|
|
// Won't worry about HTML Purifier yet
|
|
}
|
|
return $story;
|
|
}
|
|
|
|
function send_email($title, $author, $story) {
|
|
include_once('../lib/convert_entities.inc.php');
|
|
$to = 'editor@xxx.org.za';
|
|
$subject = "New submission: $title";
|
|
$headers = 'From: x.x.x Queue <editor@xxx.org.za>'."\r\n";
|
|
$message = "Please review the queue. $author has sent the following new submission:\n\n";
|
|
if ($story)
|
|
$message .= wordwrap(preg_replace("#(<br.?/?>|</p>)#", "\n", strip_tags(html_entity_decode_full($story))));
|
|
else
|
|
$message .= "<Submission is an image. Review on the site.>";
|
|
$message .= "\n\nhttp://xxx.org.za/publish/edit";
|
|
mb_send_mail($to, $subject, $message, $headers);
|
|
}
|