diff --git a/contrib/browser_search/main.php b/contrib/browser_search/main.php index fb0e5906..0b458a64 100755 --- a/contrib/browser_search/main.php +++ b/contrib/browser_search/main.php @@ -28,7 +28,7 @@ class BrowserSearch implements Extension { global $config; $search_title = $config->get_string('title'); $search_file_url = make_link('browser_search/please_dont_use_this_tag_as_it_would_break_stuff__search.xml'); - $page->add_header(""); + $page->add_html_header(""); } // The search.xml file that is generated on the fly diff --git a/contrib/danbooru_api/main.php b/contrib/danbooru_api/main.php index 4d11d655..b925d860 100644 --- a/contrib/danbooru_api/main.php +++ b/contrib/danbooru_api/main.php @@ -159,8 +159,8 @@ class DanbooruApi implements Extension { $fp = fopen($url, "r"); if(!$fp) { - header("HTTP/1.0 409 Conflict"); - header("X-Danbooru-Errors: fopen read error"); + $page->add_http_header("HTTP/1.0 409 Conflict"); + $page->add_http_header("X-Danbooru-Errors: fopen read error"); } $data = ""; @@ -193,8 +193,8 @@ class DanbooruApi implements Extension $filename = basename($url); } else { // Nothing was specified at all - header("HTTP/1.0 409 Conflict"); - header("X-Danbooru-Errors: no input files"); + $page->add_http_header("HTTP/1.0 409 Conflict"); + $page->add_http_header("X-Danbooru-Errors: no input files"); return; } @@ -206,8 +206,8 @@ class DanbooruApi implements Extension { if(strtolower($_REQUEST['md5']) != $hash) { - header("HTTP/1.0 409 Conflict"); - header("X-Danbooru-Errors: md5 mismatch"); + $page->add_http_header("HTTP/1.0 409 Conflict"); + $page->add_http_header("X-Danbooru-Errors: md5 mismatch"); return; } } @@ -217,11 +217,11 @@ class DanbooruApi implements Extension // Does it exist already? $existing = Image::by_hash($hash); if(!is_null($existing)) { - header("HTTP/1.0 409 Conflict"); - header("X-Danbooru-Errors: duplicate"); + $page->add_http_header("HTTP/1.0 409 Conflict"); + $page->add_http_header("X-Danbooru-Errors: duplicate"); $existinglink = make_link("post/view/" . $existing->id); if($danboorup_kludge) $existinglink=make_http($existinglink); - header("X-Danbooru-Location: $existinglink"); + $page->add_http_header("X-Danbooru-Location: $existinglink"); return; // wut! } @@ -246,21 +246,21 @@ class DanbooruApi implements Extension // Did we POST or GET this call? if($_SERVER['REQUEST_METHOD'] == 'POST') { - header("X-Danbooru-Location: $newid"); + $page->add_http_header("X-Danbooru-Location: $newid"); } else - header("Location: $newid"); + $page->add_http_header("Location: $newid"); } catch(UploadException $ex) { // Did something screw up? - header("HTTP/1.0 409 Conflict"); - header("X-Danbooru-Errors: exception - " . $ex->getMessage()); + $page->add_http_header("HTTP/1.0 409 Conflict"); + $page->add_http_header("X-Danbooru-Errors: exception - " . $ex->getMessage()); return; } } else { - header("HTTP/1.0 409 Conflict"); - header("X-Danbooru-Errors: authentication error"); + $page->add_http_header("HTTP/1.0 409 Conflict"); + $page->add_http_header("X-Danbooru-Errors: authentication error"); return; } } @@ -387,7 +387,7 @@ class DanbooruApi implements Extension if(($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'show')) { $fixedlocation = make_link("post/view/" . $event->get_arg(3)); - header("Location: $fixedlocation"); + $page->add_http_header("Location: $fixedlocation"); } } diff --git a/contrib/regen_thumb/theme.php b/contrib/regen_thumb/theme.php index 2d8b7d68..6f5720a7 100644 --- a/contrib/regen_thumb/theme.php +++ b/contrib/regen_thumb/theme.php @@ -19,7 +19,7 @@ class RegenThumbTheme extends Themelet { public function display_results(Page $page, Image $image) { $page->set_title("Thumbnail Regenerated"); $page->set_heading("Thumbnail Regenerated"); - $page->add_header(""); + $page->add_html_header(""); $page->add_block(new NavBlock()); $page->add_block(new Block("Thumbnail", $this->build_thumb_html($image))); } diff --git a/contrib/resize/main.php b/contrib/resize/main.php new file mode 100644 index 00000000..972fc891 --- /dev/null +++ b/contrib/resize/main.php @@ -0,0 +1,247 @@ + + * Description: Allows admins to resize images. + * License: GPLv2 + * Version: 0.1 + * Notice: + * The image resize and resample code is based off of the "smart_resize_image" + * function copyright 2008 Maxim Chernyak, released under a MIT-style license. + * Documentation: + * This extension allows admins to resize images. + */ + +/** + * This class is just a wrapper around SCoreException. + */ +class ImageResizeException extends SCoreException { + var $error; + + public function __construct($error) { + $this->error = $error; + } +} + +/** + * This class handles image resize requests. + */ +class ResizeImage extends SimpleExtension { + + public function onInitExt($event) { + global $config; + $config->set_default_bool('resize_enabled', true); + $config->set_default_int('resize_default_width', 0); + $config->set_default_int('resize_default_height', 0); + } + + public function onImageAdminBlockBuilding($event) { + global $user, $config; + if($user->is_admin() && $config->get_bool("resize_enabled")) { + /* Add a link to resize the image */ + $event->add_part($this->theme->get_resize_html($event->image->id)); + } + } + + public function onSetupBuilding($event) { + $sb = new SetupBlock("Image Resize"); + $sb->add_bool_option("resize_enabled", "Allow resizing images: "); + $sb->add_label("
Preset/Default Width: "); + $sb->add_int_option("resize_default_width"); + $sb->add_label(" px"); + $sb->add_label("
Preset/Default Height: "); + $sb->add_int_option("resize_default_height"); + $sb->add_label(" px"); + $sb->add_label("
(enter 0 for no default)"); + $event->panel->add_block($sb); + } + + public function onPageRequest($event) { + global $page, $user; + + if ( $event->page_matches("resize") && $user->is_admin() ) { + // Try to get the image ID + $image_id = int_escape($event->get_arg(0)); + if (empty($image_id)) { + $image_id = isset($_POST['image_id']) ? $_POST['image_id'] : null; + } + if (empty($image_id)) { + throw new ImageResizeException("Can not resize Image: No valid Image ID given."); + } + + $image = Image::by_id($image_id); + if(is_null($image)) { + $this->theme->display_error($page, "Image not found", "No image in the database has the ID #$image_id"); + } else { + + /* Check if options were given to resize an image. */ + if (isset($_POST['resize_width']) || isset($_POST['resize_height'])) { + + /* get options */ + + $width = $height = 0; + + if (isset($_POST['resize_width'])) { + $width = int_escape($_POST['resize_width']); + } + if (isset($_POST['resize_height'])) { + $height = int_escape($_POST['resize_height']); + } + + /* Attempt to resize the image */ + try { + $this->resize_image($image_id, $width, $height); + + //$this->theme->display_resize_page($page, $image_id); + + $page->set_mode("redirect"); + $page->set_redirect(make_link("post/view/".$image_id)); + + } catch (ImageResizeException $e) { + $this->theme->display_resize_error($page, "Error Resizing", $e->error); + } + } else { + /* Display options for resizing */ + $this->theme->display_resize_page($page, $image_id); + } + } + } + } + + + // Private functions + + /* + This function could be made much smaller by using the ImageReplaceEvent + ie: Pretend that we are replacing the image with a resized copy. + */ + private function resize_image($image_id, $width, $height) { + global $config; + global $user; + global $page; + global $database; + + if ( ($height <= 0) && ($width <= 0) ) { + throw new ImageResizeException("Invalid options for height and width. ($width x $height)"); + } + + $image_obj = Image::by_id($image_id); + $hash = $image_obj->hash; + if (is_null($hash)) { + throw new ImageResizeException("Image does not have a hash associated with it."); + } + + $image_filename = warehouse_path("images", $hash); + $info = getimagesize($image_filename); + /* Get the image file type */ + $pathinfo = pathinfo($image_obj->filename); + $filetype = strtolower($pathinfo['extension']); + + if (($image_obj->width != $info[0] ) || ($image_obj->height != $info[1])) { + throw new ImageResizeException("The image size does not match what is in the database! - Aborting Resize."); + } + + /* Check memory usage limits */ + $memory_use = (filesize($image_filename)*2) + ($width*$height*4) + (4*1024*1024); + $memory_limit = get_memory_limit(); + + if ($memory_use > $memory_limit) { + throw new ImageResizeException("The image is too large to resize given the memory limits. ($memory_use > $memory_limit)"); + } + + /* Calculate the new size of the image */ + if ( $height > 0 && $width > 0 ) { + $new_height = $height; + $new_width = $width; + } else { + // Scale the new image + if ($width == 0) $factor = $height/$image_obj->height; + elseif ($height == 0) $factor = $width/$image_obj->width; + else $factor = min( $width / $image_obj->width, $height / $image_obj->height ); + + $new_width = round( $image_obj->width * $factor ); + $new_height = round( $image_obj->height * $factor ); + } + + /* Attempt to load the image */ + switch ( $info[2] ) { + case IMAGETYPE_GIF: $image = imagecreatefromgif($image_filename); break; + case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($image_filename); break; + case IMAGETYPE_PNG: $image = imagecreatefrompng($image_filename); break; + default: + throw new ImageResizeException("Unsupported image type."); + } + + /* Resize and resample the image */ + $image_resized = imagecreatetruecolor( $new_width, $new_height ); + + if ( ($info[2] == IMAGETYPE_GIF) || ($info[2] == IMAGETYPE_PNG) ) { + $transparency = imagecolortransparent($image); + + if ($transparency >= 0) { + $transparent_color = imagecolorsforindex($image, $trnprt_indx); + $transparency = imagecolorallocate($image_resized, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']); + imagefill($image_resized, 0, 0, $transparency); + imagecolortransparent($image_resized, $transparency); + } + elseif ($info[2] == IMAGETYPE_PNG) { + imagealphablending($image_resized, false); + $color = imagecolorallocatealpha($image_resized, 0, 0, 0, 127); + imagefill($image_resized, 0, 0, $color); + imagesavealpha($image_resized, true); + } + } + imagecopyresampled($image_resized, $image, 0, 0, 0, 0, $new_width, $new_height, $image_obj->width, $image_obj->height); + + /* Temp storage while we resize */ + $tmp_filename = tempnam("/tmp", 'shimmie_resize'); + if (empty($tmp_filename)) { + throw new ImageResizeException("Unable to save temporary image file."); + } + + /* Output to the same format as the original image */ + switch ( $info[2] ) { + case IMAGETYPE_GIF: imagegif($image_resized, $tmp_filename); break; + case IMAGETYPE_JPEG: imagejpeg($image_resized, $tmp_filename); break; + case IMAGETYPE_PNG: imagepng($image_resized, $tmp_filename); break; + default: + throw new ImageResizeException("Unsupported image type."); + } + + /* Move the new image into the main storage location */ + $new_hash = md5_file($tmp_filename); + $new_size = filesize($tmp_filename); + $target = warehouse_path("images", $new_hash); + if(!file_exists(dirname($target))) mkdir(dirname($target), 0755, true); + if(!@copy($tmp_filename, $target)) { + throw new ImageResizeException("Failed to copy new image file from temporary location ({$tmp_filename}) to archive ($target)"); + } + $new_filename = 'resized-'.$image_obj->filename; + + /* Remove temporary file */ + @unlink($tmp_filename); + + /* Delete original image and thumbnail */ + log_debug("image", "Removing image with hash ".$hash); + $image_obj->remove_image_only(); + + /* Generate new thumbnail */ + send_event(new ThumbnailGenerationEvent($new_hash, $filetype)); + + /* Update the database */ + $database->Execute( + "UPDATE images SET + filename = :filename, filesize = :filesize, hash = :hash, width = :width, height = :height + WHERE + id = :id + ", + array( + "filename"=>$new_filename, "filesize"=>$new_size, "hash"=>$new_hash, + "width"=>$new_width, "height"=>$new_height, "id"=>$image_id + ) + ); + + log_info("resize", "Resized Image #{$image_id} - New hash: {$new_hash}"); + } +} +?> diff --git a/contrib/resize/style.css b/contrib/resize/style.css new file mode 100644 index 00000000..ccfc01c2 --- /dev/null +++ b/contrib/resize/style.css @@ -0,0 +1,5 @@ +form#form_resize { + float: left; + margin: 0; + width: 60%; +} diff --git a/contrib/resize/theme.php b/contrib/resize/theme.php new file mode 100644 index 00000000..ee920b81 --- /dev/null +++ b/contrib/resize/theme.php @@ -0,0 +1,60 @@ + + + + "; + + return $html; + } + + public function display_resize_error(Page $page, $title, $message) { + $page->set_title("Resize Image"); + $page->set_heading("Resize Image"); + $page->add_block(new NavBlock()); + $page->add_block(new Block($title, $message)); + } + + public function display_resize_page(Page $page, $image_id) { + global $config; + + $default_width = $config->get_int('resize_default_width'); + $default_height = $config->get_int('resize_default_height'); + + $image = Image::by_id($image_id); + $thumbnail = $this->build_thumb_html($image, null); + + $html = "
+

Resize Image ID ".$image_id."
".$thumbnail."

+

Please note: You will have to refresh the image page, or empty your browser cache.

+

Enter the new size for the image, or leave blank to scale the image automatically.


" + .make_form(make_link('resize/'.$image_id), 'POST', $multipart=True,'form_resize')." + + + + + +
New Width
New Height
+ + "; + + $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 { File + "; if($tl_enabled) { $upload_list .= " + URL + "; } - $upload_list .= " - - "; $max_size = $config->get_int('upload_size'); $max_kb = to_shorthand_int($max_size); @@ -103,7 +103,9 @@ class UploadTheme extends Themelet { $image = Image::by_id($image_id); $thumbnail = $this->build_thumb_html($image, null); - $html = "

Replacing Image ID ".$image_id."
Please note: You will have to refresh the image page, or empty your browser cache.

" + $html = " +
+

Replacing Image ID ".$image_id."
Please note: You will have to refresh the image page, or empty your browser cache.

" .$thumbnail."
" .make_form(make_link("upload/replace/".$image_id), "POST", $multipart=True)." diff --git a/ext/view/theme.php b/ext/view/theme.php index 993243b3..b9cb5cf8 100644 --- a/ext/view/theme.php +++ b/ext/view/theme.php @@ -10,11 +10,11 @@ class ViewImageTheme extends Themelet { $metatags = str_replace(" ", ", ", html_escape($image->get_tag_list())); $page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list())); - $page->add_header(""); - $page->add_header(""); - $page->add_header(""); - $page->add_header("get_thumb_link())."\">"); - $page->add_header("id}"))."\">"); + $page->add_html_header(""); + $page->add_html_header(""); + $page->add_html_header(""); + $page->add_html_header("get_thumb_link())."\">"); + $page->add_html_header("id}"))."\">"); $page->set_heading(html_escape($image->get_tag_list())); $page->add_block(new Block("Navigation", $this->build_navigation($image), "left", 0)); $page->add_block(new Block(null, $this->build_info($image, $editor_parts), "main", 10)); diff --git a/themes/danbooru/layout.class.php b/themes/danbooru/layout.class.php index b49b52c2..5045adcc 100644 --- a/themes/danbooru/layout.class.php +++ b/themes/danbooru/layout.class.php @@ -53,8 +53,8 @@ class Layout { $header_html = ""; - ksort($page->headers); - foreach($page->headers as $line) { + ksort($page->html_headers); + foreach($page->html_headers as $line) { $header_html .= "\t\t$line\n"; } diff --git a/themes/danbooru/themelet.class.php b/themes/danbooru/themelet.class.php index 1c2d687c..2fa978a5 100644 --- a/themes/danbooru/themelet.class.php +++ b/themes/danbooru/themelet.class.php @@ -10,7 +10,7 @@ class Themelet { public function display_permission_denied(Page $page) { - header("HTTP/1.0 403 Permission Denied"); + $page->add_http_header("HTTP/1.0 403 Permission Denied"); $this->display_error($page, "Permission Denied", "You do not have permission to access this page"); } diff --git a/themes/default/layout.class.php b/themes/default/layout.class.php index 290d1a8c..3ee91b82 100644 --- a/themes/default/layout.class.php +++ b/themes/default/layout.class.php @@ -14,8 +14,8 @@ class Layout { $contact_link = $config->get_string('contact_link'); $header_html = ""; - ksort($page->headers); - foreach($page->headers as $line) { + ksort($page->html_headers); + foreach($page->html_headers as $line) { $header_html .= "\t\t$line\n"; } diff --git a/themes/default/themelet.class.php b/themes/default/themelet.class.php index de1f9b4e..159f8881 100644 --- a/themes/default/themelet.class.php +++ b/themes/default/themelet.class.php @@ -18,7 +18,7 @@ class Themelet { * A specific, common error message */ public function display_permission_denied(Page $page) { - header("HTTP/1.0 403 Permission Denied"); + $page->add_http_header("HTTP/1.0 403 Permission Denied"); $this->display_error($page, "Permission Denied", "You do not have permission to access this page"); } diff --git a/themes/flat/layout.class.php b/themes/flat/layout.class.php index d8fb4e0f..f0e9a95b 100644 --- a/themes/flat/layout.class.php +++ b/themes/flat/layout.class.php @@ -14,8 +14,8 @@ class Layout { $contact_link = $config->get_string('contact_link'); $header_html = ""; - ksort($page->headers); - foreach($page->headers as $line) { + ksort($page->html_headers); + foreach($page->html_headers as $line) { $header_html .= "\t\t$line\n"; } diff --git a/themes/flat/themelet.class.php b/themes/flat/themelet.class.php index 5cb25716..b79ccc73 100644 --- a/themes/flat/themelet.class.php +++ b/themes/flat/themelet.class.php @@ -18,7 +18,7 @@ class Themelet { * A specific, common error message */ public function display_permission_denied(Page $page) { - header("HTTP/1.0 403 Permission Denied"); + $page->add_http_header("HTTP/1.0 403 Permission Denied"); $this->display_error($page, "Permission Denied", "You do not have permission to access this page"); } diff --git a/themes/futaba/layout.class.php b/themes/futaba/layout.class.php index ed1568fd..51f76716 100644 --- a/themes/futaba/layout.class.php +++ b/themes/futaba/layout.class.php @@ -9,8 +9,8 @@ class Layout { $contact_link = $config->get_string('contact_link'); $header_html = ""; - ksort($page->headers); - foreach($page->headers as $line) { + ksort($page->html_headers); + foreach($page->html_headers as $line) { $header_html .= "\t\t$line\n"; } diff --git a/themes/lite/layout.class.php b/themes/lite/layout.class.php index 5e9bed77..c7273ab3 100644 --- a/themes/lite/layout.class.php +++ b/themes/lite/layout.class.php @@ -20,7 +20,7 @@ class Layout { $contact_link = $config->get_string('contact_link'); $header_html = ""; - foreach($page->headers as $line) { + foreach($page->html_headers as $line) { $header_html .= "\t\t$line\n"; } diff --git a/themes/lite/themelet.class.php b/themes/lite/themelet.class.php index 59b403e2..8d57b147 100644 --- a/themes/lite/themelet.class.php +++ b/themes/lite/themelet.class.php @@ -18,7 +18,7 @@ class Themelet { * A specific, common error message */ public function display_permission_denied(Page $page) { - header("HTTP/1.0 403 Permission Denied"); + $page->add_http_header("HTTP/1.0 403 Permission Denied"); $this->display_error($page, "Permission Denied", "You do not have permission to access this page"); } diff --git a/themes/old_default/layout.class.php b/themes/old_default/layout.class.php index 43931d5e..cb4e6952 100644 --- a/themes/old_default/layout.class.php +++ b/themes/old_default/layout.class.php @@ -9,8 +9,8 @@ class Layout { $contact_link = $config->get_string('contact_link'); $header_html = ""; - ksort($page->headers); - foreach($page->headers as $line) { + ksort($page->html_headers); + foreach($page->html_headers as $line) { $header_html .= "\t\t$line\n"; } diff --git a/themes/old_default/themelet.class.php b/themes/old_default/themelet.class.php index 09eb031e..41c5cf5e 100644 --- a/themes/old_default/themelet.class.php +++ b/themes/old_default/themelet.class.php @@ -16,7 +16,7 @@ class Themelet { * A specific, common error message */ public function display_permission_denied(Page $page) { - header("HTTP/1.0 403 Permission Denied"); + $page->add_http_header("HTTP/1.0 403 Permission Denied"); $this->display_error($page, "Permission Denied", "You do not have permission to access this page"); } diff --git a/themes/warm/layout.class.php b/themes/warm/layout.class.php index 3bd85755..3d6c2cb7 100644 --- a/themes/warm/layout.class.php +++ b/themes/warm/layout.class.php @@ -14,7 +14,7 @@ class Layout { $contact_link = $config->get_string('contact_link'); $header_html = ""; - foreach($page->headers as $line) { + foreach($page->html_headers as $line) { $header_html .= "\t\t$line\n"; } diff --git a/themes/warm/themelet.class.php b/themes/warm/themelet.class.php index ddbad7a8..89f4dcf8 100644 --- a/themes/warm/themelet.class.php +++ b/themes/warm/themelet.class.php @@ -18,7 +18,7 @@ class Themelet { * A specific, common error message */ public function display_permission_denied(Page $page) { - header("HTTP/1.0 403 Permission Denied"); + $page->add_http_header("HTTP/1.0 403 Permission Denied"); $this->display_error($page, "Permission Denied", "You do not have permission to access this page"); }