'."\n"; $page .= '

No articles found.

Try searching again, or return to the main page. The search is case-insensitive, and searches the title, author, date, and the text of each article.

'."\n"; $page .= ''."\n"; } else { $page .= '
'."\n"; $page .= '

No articles found.

'; $page .= '
'."\n"; } $page .= ''."\n"; return $page; } $page .= ''."\n"; if (count($result) > 1) $page .= get_pager(); return $page; } /* * Return number of entries matching our request */ function get_count() { global $db, $is_admin; $search = get_search_args(); $queue = get_queue(); $table = which_table(); $params = array(); // if search= is defined, search.... if ($search) { $count_query = "SELECT COUNT(*) FROM $table WHERE". " (title LIKE ? OR author LIKE ? OR date LIKE ? OR story LIKE ?)"; $params = array_fill(0, 4, "%$search%"); // Otherwise, fall back to default view } else { $count_query = "SELECT COUNT(*) FROM ".$table." WHERE 1"; } if (!$is_admin) $count_query .= " AND hidden IS NOT TRUE"; //echo $count_query."
"; $row_count = NULL; if ($count_query) { if ($result = $db->execute_query($count_query, $params)) { $row_count = $result->fetch_row(); $result->close(); } else { db_fail(); } } return $row_count[0]; } /* * Return array of results, correctly keyed to column names. */ function get_query($id = NULL) { global $db, $is_admin; $search = get_search_args(); $sort = get_sort_arg(); $order = get_order(); $start = get_start_num(); $show = get_show_num(); $queue = get_queue(); $table = which_table(); $results = array(); $params = array(); $limit = " LIMIT ".(int)$start." , ".(int)$show; // If id= is defined, show the corresponding application only if (is_numeric($id)) { if (!$is_admin) $query = "SELECT * FROM $table WHERE 1 AND hidden IS NOT TRUE AND id = ".(int)$id." LIMIT 0, 1"; else $query = "SELECT * FROM $table WHERE 1 AND id = ".(int)$id." LIMIT 0, 1"; // if search= is defined, search.... } else if ($search) { $query = "SELECT * FROM $table WHERE". " (title LIKE ? OR author LIKE ? OR date LIKE ? OR story LIKE ?)"; $params = array_fill(0, 4, "%$search%"); if (!$is_admin) $query .= " AND hidden IS NOT TRUE"; $query .= " ORDER BY ".$sort." ".$order.$limit; // Otherwise, fall back to default view } else { $query = "SELECT * FROM ".$table." WHERE 1"; if (!$is_admin) $query .= " AND hidden IS NOT TRUE"; $query .= " ORDER BY ".$sort." ".$order.$limit; } //echo $query; if ($result = $db->execute_query($query, $params)) { while ($row = $result->fetch_assoc()) { $row['queue_url'] = $queue ? 1 : 0; $results[] = $row; } $result->close(); } else { db_fail(); } return $results; } /* * Return array of the POST variables we may care about * (safer than extract($_POST)) * * If $stripslashes is non-null, turn every value into a string: * NULL (or an array) becomes string(""), int(0) becomes string("0"). * (It used to run stripslashes, but magic_quotes_gpc no longer exists.) * * If $html is non-null, run the output through htmlspecialchars, * to translate HTML-unsafe characters. This should only be needed * if you're outputting back to an HTML form. */ function get_post_data($stripslashes = NULL, $html = NULL) { $queue = get_queue(); $results = array(); $entry['id'] = isset($_POST['id']) ? $_POST['id'] : NULL; $entry['title'] = isset($_POST['title']) ? $_POST['title'] : NULL; $entry['author'] = isset($_POST['author']) ? $_POST['author'] : NULL; $entry['email'] = isset($_POST['email']) ? $_POST['email'] : NULL; $entry['upload'] = isset($_POST['upload']) ? $_POST['upload'] : NULL; $entry['story'] = isset($_POST['story']) ? $_POST['story'] : NULL; $entry['comments'] = isset($_POST['comments']) ? $_POST['comments'] : NULL; $entry['date'] = isset($_POST['date']) ? $_POST['date'] : NULL; $entry['hidden'] = isset($_POST['hidden']) ? $_POST['hidden'] : NULL; $entry['uploaded'] = isset($_POST['uploaded']) ? $_POST['uploaded'] : NULL; $entry['editor'] = isset($_POST['editor']) ? $_POST['editor'] : NULL; $entry['remove_img'] = isset($_POST['remove_img']) ? ($_POST['remove_img'] ? 1 : 0) : NULL; $entry['queue_url'] = $queue ? 1 : 0; if ($stripslashes) { $entry = array_map('map_string', $entry); } if ($html) { $entry = array_map('map_html', $entry); } $results[] = $entry; return $results; } function map_string($value) { return is_scalar($value) ? (string)$value : ''; } function map_html($string) { return htmlspecialchars(map_string($string), ENT_QUOTES, 'UTF-8', FALSE); } function unmap_html($string) { return htmlspecialchars_decode($string, ENT_QUOTES); } /* * Utility functions to sanitise data */ function get_id() { global $db, $id; if (is_numeric($id)) { return $id; } else if (isset($_REQUEST['id']) && is_numeric($_REQUEST['id'])) { $id = $db->real_escape_string($_REQUEST['id']); return $id; } else { return NULL; } } function get_search_args() { global $db; if (isset($_GET['search']) && is_string($_GET['search'])) { return $_GET['search']; } } function get_order() { global $db; $order = NULL; if (isset($_GET['order']) && is_string($_GET['order'])) { $order = $db->real_escape_string($_GET['order']); } // Sort ascending by default if ($order != "ASC" && $order != "DESC" && $order != "asc" && $order != "desc") if (get_sort_arg() == "date") { $order = "desc"; } else $order = "asc"; return $order; } function get_sort_arg() { global $db; $sort = NULL; if (isset($_GET['sort']) && is_string($_GET['sort'])) { $sort = $db->real_escape_string($_GET['sort']); } if ($sort != "author" && $sort != "date" && $sort != "title") $sort = "date"; return $sort; } // The most stories that one page can show define('MAX_SHOW', 50); // Return a whole number from the query string, limited to $min..$max, // or NULL if the value is missing or is not a whole number function get_int_arg($name, $min, $max = PHP_INT_MAX) { if (!isset($_GET[$name]) || !is_string($_GET[$name])) return NULL; $value = filter_var(trim($_GET[$name]), FILTER_VALIDATE_INT); if ($value === FALSE) return NULL; return max($min, min($max, $value)); } function get_show_num() { global $num_stories; $show = get_int_arg('show', 1, MAX_SHOW); if ($show !== NULL) return $show; else if ($num_stories) return (int)$num_stories; else // provide fallback return 1; } function get_start_num() { $start = get_int_arg('start', 0); return $start === NULL ? 0 : $start; } /* * Return the queue */ function get_queue() { global $action, $queue; if ($action == 'save' || $action == 'submit') $queue = TRUE; else if (isset($_REQUEST['queue'])) $queue = ($_REQUEST['queue'] === '1') ? TRUE : FALSE; else if (!is_bool($queue)) $queue = FALSE; return $queue; } /* * Returns the table name */ function which_table($move = FALSE, $action = 'read') { global $is_admin; $queue = get_queue(); // Editing: a visitor can never write to the live table if (!$is_admin && in_array($action, array('post', 'save', 'submit', 'delete'))) { return 'queue'; } else if ($action == 'delete' && $move && $is_admin) { return 'queue'; } else if ($action == 'post' && $is_admin) { return 'xxx'; } else if ($action == 'save' || $action == 'submit') { return 'queue'; // Viewing } else if ($queue && $is_admin) { return 'queue'; } else { return 'xxx'; } } /* * Uploaded images wait in a directory outside the web root until the * story is saved. The session holds the random file name, so the client * never sends a file path. */ function upload_dir() { $dir = rtrim(config('UPLOAD_DIR') ?: sys_get_temp_dir() . '/xxx-uploads', '/'); if (!is_dir($dir)) mkdir($dir, 0700, TRUE); return $dir; } function is_upload_name($name) { return is_string($name) && preg_match('/^[0-9a-f]{32}$/', $name); } /* * Move a file from $_FILES into the upload directory, and remember it * in the session. Returns the new path, or FALSE. */ function store_upload($tmp_file) { $name = bin2hex(random_bytes(16)); $file = upload_dir() . '/' . $name; if (!move_uploaded_file($tmp_file, $file)) return FALSE; $_SESSION['pending_upload'] = $name; return $file; } /* * Return the path of the image this session uploaded earlier, or FALSE. */ function pending_upload() { $name = $_SESSION['pending_upload'] ?? NULL; if (!is_upload_name($name)) return FALSE; $file = upload_dir() . '/' . $name; return is_file($file) ? $file : FALSE; } /* * URL that shows the pending image; the name part stops browsers from * showing an older upload from their cache. */ function pending_upload_url() { return '/display?pending=' . substr($_SESSION['pending_upload'] ?? '', 0, 8); }