+
+ ";
+
+ $page->set_title("Resize Image");
+ $page->set_heading("Resize Image");
+ $page->add_block(new NavBlock());
+ $page->add_block(new Block("Resize Image", $html, "main", 20));
+
+ }
+}
+?>
diff --git a/contrib/rss_comments/main.php b/contrib/rss_comments/main.php
index aa73d550..084ce836 100644
--- a/contrib/rss_comments/main.php
+++ b/contrib/rss_comments/main.php
@@ -11,7 +11,7 @@ class RSS_Comments extends SimpleExtension {
global $config, $page;
$title = $config->get_string('title');
- $page->add_header("add_html_header("");
}
diff --git a/contrib/rss_images/main.php b/contrib/rss_images/main.php
index 9c8c1f7c..101b0ac8 100644
--- a/contrib/rss_images/main.php
+++ b/contrib/rss_images/main.php
@@ -13,11 +13,11 @@ class RSS_Images extends SimpleExtension {
if(count($event->search_terms) > 0) {
$search = html_escape(implode(' ', $event->search_terms));
- $page->add_header("add_html_header("");
}
else {
- $page->add_header("add_html_header("");
}
}
diff --git a/contrib/site_description/main.php b/contrib/site_description/main.php
index faccde49..43ed38b1 100644
--- a/contrib/site_description/main.php
+++ b/contrib/site_description/main.php
@@ -14,11 +14,11 @@ class SiteDescription extends SimpleExtension {
global $config, $page;
if(strlen($config->get_string("site_description")) > 0) {
$description = $config->get_string("site_description");
- $page->add_header("");
+ $page->add_html_header("");
}
if(strlen($config->get_string("site_keywords")) > 0) {
$keywords = $config->get_string("site_keywords");
- $page->add_header("");
+ $page->add_html_header("");
}
}
diff --git a/contrib/tagger/theme.php b/contrib/tagger/theme.php
index f1edc566..062998d9 100644
--- a/contrib/tagger/theme.php
+++ b/contrib/tagger/theme.php
@@ -11,7 +11,7 @@ class taggerTheme extends Themelet {
// Initialization code
$base_href = $config->get_string('base_href');
// TODO: AJAX test and fallback.
- $page->add_header("");
+ $page->add_html_header("");
$page->add_block(new Block(null,
"","main",1000));
diff --git a/core/imageboard.pack.php b/core/imageboard.pack.php
index e467e2db..9ce34abe 100644
--- a/core/imageboard.pack.php
+++ b/core/imageboard.pack.php
@@ -463,8 +463,8 @@ class Image {
*/
public function remove_image_only() {
log_info("core-image", "Removed Image File ({$this->hash})");
- unlink($this->get_image_filename());
- unlink($this->get_thumb_filename());
+ @unlink($this->get_image_filename());
+ @unlink($this->get_thumb_filename());
}
/**
diff --git a/core/page.class.php b/core/page.class.php
index dc7ebf29..d3879853 100644
--- a/core/page.class.php
+++ b/core/page.class.php
@@ -108,7 +108,8 @@ class Page {
var $heading = "";
var $subheading = "";
var $quicknav = "";
- var $headers = array();
+ var $html_headers = array();
+ var $http_headers = array();
var $blocks = array();
/** @publicsection */
@@ -136,11 +137,19 @@ class Page {
/**
* Add a line to the HTML head section
*/
- public function add_header($line, $position=50) {
- while(isset($this->headers[$position])) $position++;
- $this->headers[$position] = $line;
+ public function add_html_header($line, $position=50) {
+ while(isset($this->html_headers[$position])) $position++;
+ $this->html_headers[$position] = $line;
}
-
+
+ /**
+ * Add a http header to be sent to the client.
+ */
+ public function add_http_header($line, $position=50) {
+ while(isset($this->http_headers[$position])) $position++;
+ $this->http_headers[$position] = $line;
+ }
+
/**
* Add a Block of data
*/
@@ -157,15 +166,21 @@ class Page {
*/
public function display() {
global $page;
+
+ $this->add_http_header("Content-type: {$this->type}", 1);
+ $this->add_http_header("X-Powered-By: SCore-".SCORE_VERSION, 2);
- header("Content-type: {$this->type}");
- header("X-Powered-By: SCore-".SCORE_VERSION);
+ if (!headers_sent()) {
+ foreach($this->http_headers as $head){ header($head); }
+ } else {
+ print "Error: Headers have already been sent to the client.";
+ }
switch($this->mode) {
case "page":
header("Cache-control: no-cache");
usort($this->blocks, "blockcmp");
- $this->add_auto_headers();
+ $this->add_auto_html_headers();
$layout = new Layout();
$layout->display_page($page);
break;
@@ -186,26 +201,26 @@ class Page {
}
}
- protected function add_auto_headers() {
+ protected function add_auto_html_headers() {
$data_href = get_base_href();
foreach(glob("lib/*.css") as $css) {
- $this->add_header("");
+ $this->add_html_header("");
}
$css_files = glob("ext/*/style.css");
if($css_files) {
foreach($css_files as $css_file) {
- $this->add_header("");
+ $this->add_html_header("");
}
}
foreach(glob("lib/*.js") as $js) {
- $this->add_header("");
+ $this->add_html_header("");
}
$js_files = glob("ext/*/script.js");
if($js_files) {
foreach($js_files as $js_file) {
- $this->add_header("");
+ $this->add_html_header("");
}
}
}
diff --git a/ext/handle_404/main.php b/ext/handle_404/main.php
index 3a9a2503..b7e80aa0 100644
--- a/ext/handle_404/main.php
+++ b/ext/handle_404/main.php
@@ -14,8 +14,9 @@ class Handle404 extends SimpleExtension {
// hax.
if($page->mode == "page" && (!isset($page->blocks) || $this->count_main($page->blocks) == 0)) {
$h_pagename = html_escape(implode('/', $event->args));
- header("HTTP/1.0 404 Page Not Found");
log_debug("handle_404", "Hit 404: $h_pagename");
+
+ $page->add_http_header("HTTP/1.0 404 Page Not Found",5);
$page->set_title("404");
$page->set_heading("404 - No Handler Found");
$page->add_block(new NavBlock());
diff --git a/ext/image/main.php b/ext/image/main.php
index 1908d6f5..a42c7916 100644
--- a/ext/image/main.php
+++ b/ext/image/main.php
@@ -1,21 +1,27 @@
+ * Modified by: jgen
* Description: Handle the image database
* Visibility: admin
*/
-/*
- * ImageAdditionEvent:
- * $user -- the user adding the image
- * $image -- the image being added
- *
- * An image is being added to the database
+ /**
+ * An image is being added to the database.
*/
class ImageAdditionEvent extends Event {
var $user, $image;
-
+
+ /**
+ * Inserts a new image into the database with its associated
+ * information. Also calls TagSetEvent to set the tags for
+ * this new image.
+ *
+ * @sa TagSetEvent
+ * @param $user The user adding the image
+ * @param $image The new image to add.
+ */
public function ImageAdditionEvent(User $user, Image $image) {
$this->image = $image;
$this->user = $user;
@@ -30,34 +36,41 @@ class ImageAdditionException extends SCoreException {
}
}
-/*
- * ImageDeletionEvent:
- * $image -- the image being deleted
- *
- * An image is being deleted. Used by things like tags
- * and comments handlers to clean out related rows in
- * their tables
+/**
+ * An image is being deleted.
*/
class ImageDeletionEvent extends Event {
var $image;
-
+
+ /**
+ * Deletes an image.
+ * Used by things like tags and comments handlers to
+ * clean out related rows in their tables.
+ *
+ * @param $image The image being deleted
+ */
public function ImageDeletionEvent(Image $image) {
$this->image = $image;
}
}
-/*
- * ImageReplaceEvent:
- * $id -- the ID of the image to replace
- * $image -- the image object of the new image to use
- *
- * This function replaces an image. Effectively it only
- * replaces the image file contents and leaves the tags
- * and such the same.
+/**
+ * An image is being replaced.
*/
class ImageReplaceEvent extends Event {
var $id, $image;
-
+
+ /**
+ * Replaces an image.
+ * Updates an existing ID in the database to use a new image
+ * file, leaving the tags and such unchanged. Also removes
+ * the old image file and thumbnail from the disk.
+ *
+ * @param $id
+ * The ID of the image to replace
+ * @param $image
+ * The image object of the new image to use
+ */
public function ImageReplaceEvent($id, Image $image) {
$this->id = $id;
$this->image = $image;
@@ -72,15 +85,18 @@ class ImageReplaceException extends SCoreException {
}
}
-
-/*
- * ThumbnailGenerationEvent:
- * Request a thumb be made for an image
+/**
+ * Request a thumbnail be made for an image object.
*/
class ThumbnailGenerationEvent extends Event {
- var $hash;
- var $type;
-
+ var $hash, $type;
+
+ /**
+ * Request a thumbnail be made for an image object
+ *
+ * @param $hash The unique hash of the image
+ * @param $type The type of the image
+ */
public function ThumbnailGenerationEvent($hash, $type) {
$this->hash = $hash;
$this->type = $type;
@@ -95,8 +111,7 @@ class ThumbnailGenerationEvent extends Event {
* $image -- the image who's link is being parsed
*/
class ParseLinkTemplateEvent extends Event {
- var $link, $original;
- var $image;
+ var $link, $original, $image;
public function ParseLinkTemplateEvent($link, Image $image) {
$this->link = $link;
@@ -110,9 +125,8 @@ class ParseLinkTemplateEvent extends Event {
}
-/*
- * A class to handle adding / getting / removing image
- * files from the disk
+/**
+ * A class to handle adding / getting / removing image files from the disk.
*/
class ImageIO extends SimpleExtension {
public function onInitExt($event) {
@@ -124,11 +138,12 @@ class ImageIO extends SimpleExtension {
$config->set_default_string('thumb_convert_path', 'convert.exe');
$config->set_default_bool('image_show_meta', false);
- $config->set_default_bool('jquery_confirm', true);
+ $config->set_default_bool('image_jquery_confirm', true);
$config->set_default_string('image_ilink', '');
$config->set_default_string('image_tlink', '');
$config->set_default_string('image_tip', '$tags // $size // $filesize');
$config->set_default_string('upload_collision_handler', 'error');
+ $config->set_default_int('image_expires', (60*60*24*365) ); // defaults to one year
}
public function onPageRequest($event) {
@@ -172,9 +187,15 @@ class ImageIO extends SimpleExtension {
public function onImageAdminBlockBuilding($event) {
global $user;
+ global $config;
+
if($user->is_admin()) {
$event->add_part($this->theme->get_deleter_html($event->image->id));
}
+ /* In the future, could perhaps allow users to replace images that they own as well... */
+ if ($user->is_admin() && $config->get_bool("upload_replace")) {
+ $event->add_part($this->theme->get_replace_html($event->image->id));
+ }
}
public function onImageAddition($event) {
@@ -200,6 +221,9 @@ class ImageIO extends SimpleExtension {
}
public function onUserPageBuilding($event) {
+ global $user;
+ global $config;
+
$u_id = url_escape($event->display_user->id);
$i_image_count = Image::count_images(array("user_id={$event->display_user->id}"));
$i_days_old = ((time() - strtotime($event->display_user->join_date)) / 86400) + 1;
@@ -219,7 +243,17 @@ class ImageIO extends SimpleExtension {
if(!in_array("OS", $_SERVER) || $_SERVER["OS"] != 'Windows_NT') {
$sb->add_bool_option("image_show_meta", " Show metadata: ");
}
- $sb->add_bool_option("jquery_confirm", " Confirm Delete with jQuery: ");
+ $sb->add_bool_option("image_jquery_confirm", " Confirm Delete with jQuery: ");
+
+ $expires = array();
+ $expires['1 Minute'] = 60;
+ $expires['1 Hour'] = 3600;
+ $expires['1 Day'] = 86400;
+ $expires['1 Month (31 days)'] = 2678400; //(60*60*24*31)
+ $expires['1 Year'] = 31536000; // 365 days (60*60*24*365)
+ $expires['Never'] = 3153600000; // 100 years..
+ $sb->add_choice_option("image_expires", $expires, " Image Expiration: ");
+
$event->panel->add_block($sb);
$thumbers = array();
@@ -344,13 +378,18 @@ class ImageIO extends SimpleExtension {
}
$gmdate_mod = gmdate('D, d M Y H:i:s', filemtime($file)) . ' GMT';
- // FIXME: should be $page->blah
if($if_modified_since == $gmdate_mod) {
- header("HTTP/1.0 304 Not Modified");
+ $page->add_http_header("HTTP/1.0 304 Not Modified",3);
}
else {
- header("Last-Modified: $gmdate_mod");
- header("Expires: Fri, 2 Sep 2101 12:42:42 GMT"); // War was beginning
+ $page->add_http_header("Last-Modified: $gmdate_mod");
+
+ if ( $config->get_int("image_expires") ) {
+ $expires = date(DATE_RFC1123, time() + $config->get_int("image_expires"));
+ } else {
+ $expires = 'Fri, 2 Sep 2101 12:42:42 GMT'; // War was beginning
+ }
+ $page->add_http_header('Expires: '.$expires);
}
}
else {
@@ -403,7 +442,7 @@ class ImageIO extends SimpleExtension {
id = :id
",
array(
- "filename"=>$image_new->filename, "filesize"=>$image->filesize, "hash"=>$image->hash,
+ "filename"=>$image->filename, "filesize"=>$image->filesize, "hash"=>$image->hash,
"ext"=>$image->ext, "width"=>$image->width, "height"=>$image->height, "source"=>$image->source,
"id"=>$id
)
diff --git a/ext/image/theme.php b/ext/image/theme.php
index 516a045d..8d0537a1 100644
--- a/ext/image/theme.php
+++ b/ext/image/theme.php
@@ -1,42 +1,46 @@
get_bool("jquery_confirm")) {
+ if($config->get_bool("image_jquery_confirm")) {
$html = "
".make_form(make_link("image_admin/delete"),'POST',false,'delete_image')."
-
+
";
} else {
$html = "
".make_form(make_link("image_admin/delete"))."
-
+
";
}
- if($config->get_bool("upload_replace") && $user->is_admin()) {
- $html .= "
- ".make_form(make_link("image_admin/replace"))."
-
-
-
- ";
- }
-
+ return $html;
+ }
+
+ /**
+ * Display link to replace the image
+ *
+ * @param $image_id The image to replace
+ */
+ public function get_replace_html($image_id) {
+
+ $html = "
+ ".make_form(make_link("image_admin/replace"))."
+
+
+ ";
+
return $html;
}
}
diff --git a/ext/upload/main.php b/ext/upload/main.php
index 890e10f8..167bce07 100644
--- a/ext/upload/main.php
+++ b/ext/upload/main.php
@@ -5,17 +5,19 @@
* Description: Allows people to upload files to the website
*/
-/*
- * DataUploadEvent:
- * $user -- the user uploading the data
- * $tmpname -- the temporary file used for upload
- * $metadata -- info about the file, should contain at least "filename", "extension", "tags" and "source"
- *
- * Some data is being uploaded. Should be caught by a file handler.
+/**
+ * Occurs when some data is being uploaded.
*/
class DataUploadEvent extends Event {
var $user, $tmpname, $metadata, $hash, $type, $image_id = -1;
+ /**
+ * Some data is being uploaded.
+ * This should be caught by a file handler.
+ * @param $user The user uploading the data.
+ * @param $tmpname The temporary file used for upload.
+ * @param $metadata Info about the file, should contain at least "filename", "extension", "tags" and "source".
+ */
public function DataUploadEvent(User $user, $tmpname, $metadata) {
assert(file_exists($tmpname));
@@ -34,6 +36,11 @@ class DataUploadEvent extends Event {
class UploadException extends SCoreException {}
+/**
+ * Main upload class.
+ * All files that are uploaded to the site are handled through this class.
+ * This also includes transloaded files as well.
+ */
class Upload implements Extension {
var $theme;
// event handling {{{
@@ -107,6 +114,9 @@ class Upload implements Extension {
throw new UploadException("Can not upload more than one image for replacing.");
}
+ $source = isset($_POST['source']) ? $_POST['source'] : null;
+ $tags = ''; // Tags aren't changed when uploading. Set to null to stop PHP warnings.
+
if (count($_FILES)) {
foreach($_FILES as $file) {
$ok = $this->try_upload($file, $tags, $source, $image_id);
@@ -273,7 +283,8 @@ class Upload implements Extension {
if($event->image_id == -1) {
throw new UploadException("File type not recognised");
}
- header("X-Shimmie-Image-ID: ".int_escape($event->image_id));
+ //header("X-Shimmie-Image-ID: ".int_escape($event->image_id));
+ $page->add_http_header("X-Shimmie-Image-ID: ".int_escape($event->image_id));
}
catch(UploadException $ex) {
$this->theme->display_upload_error($page, "Error with ".html_escape($file['name']),
diff --git a/ext/upload/theme.php b/ext/upload/theme.php
index df0e5868..f26905c0 100644
--- a/ext/upload/theme.php
+++ b/ext/upload/theme.php
@@ -86,16 +86,16 @@ class UploadTheme extends Themelet {