/** * Generate the necessary DataUploadEvent for a given image and tags. */ private function add_image($tmpname, $filename, $tags, $source, $rating, $thumbfile) { assert(file_exists($tmpname)); $pathinfo = pathinfo($filename); if (!array_key_exists('extension', $pathinfo)) { throw new UploadException("File has no extension"); } $metadata = array(); $metadata['filename'] = $pathinfo['basename']; $metadata['extension'] = $pathinfo['extension']; $metadata['tags'] = $tags; $metadata['source'] = $source; $event = new DataUploadEvent($tmpname, $metadata); send_event($event); if ($event->image_id == -1) { throw new UploadException("File type not recognised"); } else { if (class_exists("RatingSetEvent") && in_array($rating, array("s", "q", "e"))) { $ratingevent = new RatingSetEvent(Image::by_id($event->image_id), $rating); send_event($ratingevent); } if (file_exists($thumbfile)) { copy($thumbfile, warehouse_path("thumbs", $event->hash)); } } }
public function onPageRequest(PageRequestEvent $event) { global $page, $user; if ($event->page_matches("regen_thumb") && $user->can("delete_image") && isset($_POST['image_id'])) { $image = Image::by_id(int_escape($_POST['image_id'])); send_event(new ThumbnailGenerationEvent($image->hash, $image->ext, true)); $this->theme->display_results($page, $image); } }
public function onPageRequest($event) { global $config, $database, $page, $user; if ($event->page_matches("regen_thumb") && $user->is_admin() && isset($_POST['image_id'])) { $image = Image::by_id(int_escape($_POST['image_id'])); send_event(new ThumbnailGenerationEvent($image->hash, $image->ext)); $this->theme->display_results($page, $image); } }
public function onPageRequest(PageRequestEvent $event) { global $page, $user; if ($event->page_matches("api/shimmie")) { $page->set_mode("data"); $page->set_type("text/plain"); if ($event->page_matches("api/shimmie/get_tags")) { $tag = $event->get_arg(0); if (empty($tag) && isset($_GET['tag'])) { $tag = $_GET['tag']; } $res = $this->api_get_tags($tag); $page->set_data(json_encode($res)); } elseif ($event->page_matches("api/shimmie/get_image")) { $arg = $event->get_arg(0); if (empty($arg) && isset($_GET['id'])) { $arg = $_GET['id']; } $image = Image::by_id(int_escape($arg)); // FIXME: handle null image $image->get_tag_array(); // tag data isn't loaded into the object until necessary $safe_image = new _SafeImage($image); $page->set_data(json_encode($safe_image)); } elseif ($event->page_matches("api/shimmie/find_images")) { $search_terms = $event->get_search_terms(); $page_number = $event->get_page_number(); $page_size = $event->get_page_size(); $images = Image::find_images(($page_number - 1) * $page_size, $page_size, $search_terms); $safe_images = array(); foreach ($images as $image) { $image->get_tag_array(); $safe_images[] = new _SafeImage($image); } $page->set_data(json_encode($safe_images)); } elseif ($event->page_matches("api/shimmie/get_user")) { $query = $user->id; $type = "id"; if ($event->count_args() == 1) { $query = $event->get_arg(0); $type = "name"; } elseif (isset($_GET['id'])) { $query = $_GET['id']; } elseif (isset($_GET['name'])) { $query = $_GET['name']; $type = "name"; } $all = $this->api_get_user($type, $query); $page->set_data(json_encode($all)); } else { $page->set_mode("redirect"); $page->set_redirect(make_link("ext_doc/shimmie_api")); } } }
public function onPageRequest(PageRequestEvent $event) { global $config, $database, $page; if ($event->page_matches("get_svg")) { $id = int_escape($event->get_arg(0)); $image = Image::by_id($id); $hash = $image->hash; $page->set_type("image/svg+xml"); $page->set_mode("data"); $page->set_data(file_get_contents(warehouse_path("images", $hash))); } }
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 = "<div style='clear:both;'></div>\n\t\t\t\t<p>Resize Image ID " . $image_id . "<br>" . $thumbnail . "</p>\n\t\t\t\t<p>Please note: You will have to refresh the image page, or empty your browser cache.</p>\n\t\t\t\t<p>Enter the new size for the image, or leave blank to scale the image automatically.</p><br>" . make_form(make_link('resize/' . $image_id), 'POST', $multipart = True, 'form_resize') . "\n\t\t\t\t<input type='hidden' name='image_id' value='{$image_id}'>\n\t\t\t\t<table id='large_upload_form'>\n\t\t\t\t\t<tr><td>New Width</td><td colspan='3'><input id='resize_width' name='resize_width' type='text' value='" . $default_width . "'></td></tr>\n\t\t\t\t\t<tr><td>New Height</td><td colspan='3'><input id='resize_height' name='resize_height' type='text' value='" . $default_height . "'></td></tr>\n\t\t\t\t\t<tr><td colspan='4'><input id='resizebutton' type='submit' value='Resize'></td></tr>\n\t\t\t\t</table>\n\t\t\t</form>\n\t\t"; $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)); }
public function onPageRequest($event) { global $config, $database, $page; if ($event->page_matches("get_ico")) { $id = int_escape($event->get_arg(0)); $image = Image::by_id($id); $hash = $image->hash; $ha = substr($hash, 0, 2); $page->set_type("image/x-icon"); $page->set_mode("data"); $page->set_data(file_get_contents("images/{$ha}/{$hash}")); } }
public function onPageRequest(PageRequestEvent $event) { global $config, $database, $page, $user; if ($event->page_matches("image_hash_ban")) { if ($user->is_admin()) { if ($event->get_arg(0) == "dnp") { $image = Image::by_id(int_escape($event->get_arg(1))); if ($image) { send_event(new AddImageHashBanEvent($image->hash, "DNP")); send_event(new ImageDeletionEvent($image)); } $page->set_mode("redirect"); $page->set_redirect($_SERVER["HTTP_REFERER"]); } else { if ($event->get_arg(0) == "add") { if (isset($_POST['hash']) && isset($_POST['reason'])) { send_event(new AddImageHashBanEvent($_POST['hash'], $_POST['reason'])); $page->set_mode("redirect"); $page->set_redirect(make_link("image_hash_ban/list/1")); } if (isset($_POST['image_id'])) { $image = Image::by_id(int_escape($_POST['image_id'])); if ($image) { send_event(new ImageDeletionEvent($image)); $page->set_mode("redirect"); $page->set_redirect(make_link("post/list")); } } } else { if ($event->get_arg(0) == "remove") { if (isset($_POST['hash'])) { send_event(new RemoveImageHashBanEvent($_POST['hash'])); $page->set_mode("redirect"); $page->set_redirect(make_link("image_hash_ban/list/1")); } } else { if ($event->get_arg(0) == "list") { $page_num = 0; if ($event->count_args() == 2) { $page_num = int_escape($event->get_arg(1)); } $page_size = 100; $page_count = ceil($database->get_one("SELECT COUNT(id) FROM image_bans") / $page_size); $this->theme->display_Image_hash_Bans($page, $page_num, $page_count, $this->get_image_hash_bans($page_num, $page_size)); } } } } } } }
public function receive_event(Event $event) { if (is_null($this->theme)) { $this->theme = get_theme_object($this); } if ($event instanceof DataUploadEvent && $this->supported_ext($event->type) && $this->check_contents($event->tmpname)) { $hash = $event->hash; $ha = substr($hash, 0, 2); if (!move_upload_to_archive($event)) { return; } send_event(new ThumbnailGenerationEvent($event->hash, $event->type)); $image = $this->create_image_from_data(warehouse_path("images", $hash), $event->metadata); if (is_null($image)) { throw new UploadException("SVG handler failed to create image object from data"); } $iae = new ImageAdditionEvent($event->user, $image); send_event($iae); $event->image_id = $iae->image->id; } if ($event instanceof ThumbnailGenerationEvent && $this->supported_ext($event->type)) { $hash = $event->hash; $ha = substr($hash, 0, 2); global $config; // if($config->get_string("thumb_engine") == "convert") { // $w = $config->get_int("thumb_width"); // $h = $config->get_int("thumb_height"); // $q = $config->get_int("thumb_quality"); // $mem = $config->get_int("thumb_max_memory") / 1024 / 1024; // IM takes memory in MB // // exec("convert images/{$ha}/{$hash}[0] -geometry {$w}x{$h} -quality {$q} jpg:thumbs/{$ha}/{$hash}"); // } // else { copy("ext/handle_svg/thumb.jpg", warehouse_path("thumbs", $hash)); // } } if ($event instanceof DisplayingImageEvent && $this->supported_ext($event->image->ext)) { global $page; $this->theme->display_image($page, $event->image); } if ($event instanceof PageRequestEvent && $event->page_matches("get_svg")) { global $config, $database, $page; $id = int_escape($event->get_arg(0)); $image = Image::by_id($id); $hash = $image->hash; $page->set_type("image/svg+xml"); $page->set_mode("data"); $page->set_data(file_get_contents(warehouse_path("images", $hash))); } }
public function onPostListBuilding($event) { global $config, $page, $user; $fid = $config->get_int("featured_id"); if ($fid > 0) { $image = Image::by_id($fid); if (!is_null($image)) { if (class_exists("Ratings")) { if (strpos(Ratings::get_user_privs($user), $image->rating) === FALSE) { return; } } $this->theme->display_featured($page, $image); } } }
public function onPageRequest(PageRequestEvent $event) { global $config, $database, $page, $user; if ($event->page_matches("image_hash_ban")) { if ($user->can("ban_image")) { if ($event->get_arg(0) == "add") { $image = isset($_POST['image_id']) ? Image::by_id(int_escape($_POST['image_id'])) : null; $hash = isset($_POST["hash"]) ? $_POST["hash"] : $image->hash; $reason = isset($_POST['reason']) ? $_POST['reason'] : "DNP"; if ($hash) { send_event(new AddImageHashBanEvent($hash, $reason)); flash_message("Image ban added"); if ($image) { send_event(new ImageDeletionEvent($image)); flash_message("Image deleted"); } $page->set_mode("redirect"); $page->set_redirect($_SERVER['HTTP_REFERER']); } } else { if ($event->get_arg(0) == "remove") { if (isset($_POST['hash'])) { send_event(new RemoveImageHashBanEvent($_POST['hash'])); flash_message("Image ban removed"); $page->set_mode("redirect"); $page->set_redirect($_SERVER['HTTP_REFERER']); } } else { if ($event->get_arg(0) == "list") { $page_num = 0; if ($event->count_args() == 2) { $page_num = int_escape($event->get_arg(1)); } $page_size = 100; $page_count = ceil($database->get_one("SELECT COUNT(id) FROM image_bans") / $page_size); $this->theme->display_Image_hash_Bans($page, $page_num, $page_count, $this->get_image_hash_bans($page_num, $page_size)); } } } } } }
public function onPageRequest(PageRequestEvent $event) { global $database, $page; if ($event->page_matches("api/shimmie")) { $page->set_mode("data"); $page->set_type("text/plain"); if ($event->page_matches("api/shimmie/get_tags")) { if ($event->count_args() == 2) { $all = $database->get_all("SELECT tag FROM tags WHERE tag LIKE ?", array($event->get_arg(0) . "%")); } else { $all = $database->get_all("SELECT tag FROM tags"); } $res = array(); foreach ($all as $row) { $res[] = $row["tag"]; } $page->set_data(json_encode($res)); } if ($event->page_matches("api/shimmie/get_image")) { $image = Image::by_id(int_escape($event->get_arg(0))); $image->get_tag_array(); // tag data isn't loaded into the object until necessary $safe_image = new _SafeImage($image); $page->set_data(json_encode($safe_image)); } if ($event->page_matches("api/shimmie/find_images")) { $search_terms = $event->get_search_terms(); $page_number = $event->get_page_number(); $page_size = $event->get_page_size(); $images = Image::find_images(($page_number - 1) * $page_size, $page_size, $search_terms); $safe_images = array(); foreach ($images as $image) { $image->get_tag_array(); $safe_images[] = new _SafeImage($image); } $page->set_data(json_encode($safe_images)); } } }
public function onPostListBuilding(PostListBuildingEvent $event) { global $config, $database, $page, $user; $fid = $config->get_int("featured_id"); if ($fid > 0) { $image = $database->cache->get("featured_image_object:{$fid}"); if ($image === false) { $image = Image::by_id($fid); if ($image) { // make sure the object is fully populated before saving $image->get_tag_array(); } $database->cache->set("featured_image_object:{$fid}", $image, 600); } if (!is_null($image)) { if (class_exists("Ratings")) { if (strpos(Ratings::get_user_privs($user), $image->rating) === FALSE) { return; } } $this->theme->display_featured($page, $image); } } }
private function add_comment_wrapper($image_id, $user, $comment, $event) { global $database; global $config; // basic sanity checks if (!$config->get_bool('comment_anon') && $user->is_anonymous()) { throw new CommentPostingException("Anonymous posting has been disabled"); } else { if (is_null(Image::by_id($image_id))) { throw new CommentPostingException("The image does not exist"); } else { if (trim($comment) == "") { throw new CommentPostingException("Comments need text..."); } else { if (strlen($comment) > 9000) { throw new CommentPostingException("Comment too long~"); } else { if (strlen($comment) / strlen(gzcompress($comment)) > 10) { throw new CommentPostingException("Comment too repetitive~"); } else { if ($user->is_anonymous() && !$this->hash_match()) { throw new CommentPostingException("Comment submission form is out of date; refresh the " . "comment form to show you aren't a spammer~"); } else { if ($this->is_comment_limit_hit()) { throw new CommentPostingException("You've posted several comments recently; wait a minute and try again..."); } else { if ($this->is_dupe($image_id, $comment)) { throw new CommentPostingException("Someone already made that comment on that image -- try and be more original?"); } else { if ($config->get_bool('comment_captcha') && !captcha_check()) { throw new CommentPostingException("Error in captcha"); } else { if ($user->is_anonymous() && $this->is_spam_akismet($comment)) { throw new CommentPostingException("Akismet thinks that your comment is spam. Try rewriting the comment, or logging in."); } else { $database->Execute("INSERT INTO comments(image_id, owner_id, owner_ip, posted, comment) " . "VALUES(?, ?, ?, now(), ?)", array($image_id, $user->id, $_SERVER['REMOTE_ADDR'], $comment)); $cid = $database->db->Insert_ID(); log_info("comment", "Comment #{$cid} added to Image #{$image_id}"); } } } } } } } } } } }
public function onPageRequest(PageRequestEvent $event) { global $page, $user; if ($event->page_matches("upload/replace")) { // check if the user is an administrator and can upload files. if (!$user->can("replace_image")) { $this->theme->display_permission_denied(); } else { if ($this->is_full) { throw new UploadException("Can not replace Image: disk nearly full"); } // 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 UploadException("Can not replace Image: No valid Image ID given."); } $image_old = Image::by_id($image_id); if (is_null($image_old)) { $this->theme->display_error(404, "Image not found", "No image in the database has the ID #{$image_id}"); } if (count($_FILES) + count($_POST) > 0) { if (count($_FILES) > 1) { 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); break; // leave the foreach loop. } } else { foreach ($_POST as $name => $value) { if (substr($name, 0, 3) == "url" && strlen($value) > 0) { $ok = $this->try_transload($value, $tags, $source, $image_id); break; // leave the foreach loop. } } } $this->theme->display_upload_status($page, $ok); } else { if (!empty($_GET['url'])) { $url = $_GET['url']; $source = isset($_GET['source']) ? $_GET['source'] : $url; $ok = $this->try_transload($url, $tags, $source, $image_id); $this->theme->display_upload_status($page, $ok); } else { $this->theme->display_replace_page($page, $image_id); } } } } else { if ($event->page_matches("upload")) { if (!$user->can("create_image")) { $this->theme->display_permission_denied(); } else { /* Regular Upload Image */ if (count($_FILES) + count($_POST) > 0) { $ok = true; foreach ($_FILES as $name => $file) { $tags = $this->tags_for_upload_slot(int_escape(substr($name, 4))); $source = isset($_POST['source']) ? $_POST['source'] : null; $ok = $ok & $this->try_upload($file, $tags, $source); } foreach ($_POST as $name => $value) { if (substr($name, 0, 3) == "url" && strlen($value) > 0) { $tags = $this->tags_for_upload_slot(int_escape(substr($name, 3))); $source = isset($_POST['source']) ? $_POST['source'] : $value; $ok = $ok & $this->try_transload($value, $tags, $source); } } $this->theme->display_upload_status($page, $ok); } else { if (!empty($_GET['url'])) { $url = $_GET['url']; $source = isset($_GET['source']) ? $_GET['source'] : $url; $tags = array('tagme'); if (!empty($_GET['tags']) && $_GET['tags'] != "null") { $tags = Tag::explode($_GET['tags']); } $ok = $this->try_transload($url, $tags, $source); $this->theme->display_upload_status($page, $ok); } else { if ($this->is_full) { $this->theme->display_full($page); } else { $this->theme->display_page($page); } } } } } } }
/** * This function attempts to revert all changes by a given IP within an (optional) timeframe. * * @param string $name * @param string $ip * @param string $date */ public function process_revert_all_changes($name, $ip, $date) { global $database; $select_code = array(); $select_args = array(); if (!is_null($name)) { $duser = User::by_name($name); if (is_null($duser)) { $this->theme->add_status($name, "user not found"); return; } else { $select_code[] = 'user_id = ?'; $select_args[] = $duser->id; } } if (!is_null($date)) { $select_code[] = 'date_set >= ?'; $select_args[] = $date; } if (!is_null($ip)) { $select_code[] = 'user_ip = ?'; $select_args[] = $ip; } if (count($select_code) == 0) { log_error("source_history", "Tried to mass revert without any conditions"); return; } log_info("source_history", 'Attempting to revert edits where ' . implode(" and ", $select_code) . " (" . implode(" / ", $select_args) . ")"); // Get all the images that the given IP has changed source on (within the timeframe) that were last editied by the given IP $result = $database->get_col(' SELECT t1.image_id FROM source_histories t1 LEFT JOIN source_histories t2 ON (t1.image_id = t2.image_id AND t1.date_set < t2.date_set) WHERE t2.image_id IS NULL AND t1.image_id IN ( select image_id from source_histories where ' . implode(" AND ", $select_code) . ') ORDER BY t1.image_id ', $select_args); foreach ($result as $image_id) { // Get the first source history that was done before the given IP edit $row = $database->get_row(' SELECT id, source FROM source_histories WHERE image_id=' . $image_id . ' AND NOT (' . implode(" AND ", $select_code) . ') ORDER BY date_set DESC LIMIT 1 ', $select_args); if (empty($row)) { // we can not revert this image based on the date restriction. // Output a message perhaps? } else { $revert_id = $row['id']; $result = $this->get_source_history_from_revert($revert_id); if (empty($result)) { // there is no history entry with that id so either the image was deleted // while the user was viewing the history, or something messed up /* calling die() is probably not a good idea, we should throw an Exception */ die('Error: No source history with specified id (' . $revert_id . ') was found in the database.' . "\n\n" . 'Perhaps the image was deleted while processing this request.'); } // lets get the values out of the result $stored_result_id = $result['id']; $stored_image_id = $result['image_id']; $stored_source = $result['source']; log_debug("source_history", 'Reverting source of Image #' . $stored_image_id . ' to [' . $stored_source . ']'); $image = Image::by_id($stored_image_id); if (is_null($image)) { die('Error: No image with the id (' . $stored_image_id . ') was found. Perhaps the image was deleted while processing this request.'); } // all should be ok so we can revert by firing the SetSources event. send_event(new SourceSetEvent($image, $stored_source)); $this->theme->add_status('Reverted Change', 'Reverted Image #' . $image_id . ' to Source History #' . $stored_result_id . ' (' . $row['source'] . ')'); } } log_info("source_history", 'Reverted ' . count($result) . ' edits.'); }
/** * @param Page $page * @param bool $with_images * @param bool $with_comments */ private function delete_user(Page $page, $with_images = false, $with_comments = false) { global $user, $config, $database; $page->set_title("Error"); $page->set_heading("Error"); $page->add_block(new NavBlock()); if (!$user->can("delete_user")) { $page->add_block(new Block("Not Admin", "Only admins can delete accounts")); } else { if (!isset($_POST['id']) || !is_numeric($_POST['id'])) { $page->add_block(new Block("No ID Specified", "You need to specify the account number to edit")); } else { log_warning("user", "Deleting user #{$_POST['id']}"); if ($with_images) { log_warning("user", "Deleting user #{$_POST['id']}'s uploads"); $rows = $database->get_all("SELECT * FROM images WHERE owner_id = :owner_id", array("owner_id" => $_POST['id'])); foreach ($rows as $key => $value) { $image = Image::by_id($value['id']); if ($image) { send_event(new ImageDeletionEvent($image)); } } } else { $database->Execute("UPDATE images SET owner_id = :new_owner_id WHERE owner_id = :old_owner_id", array("new_owner_id" => $config->get_int('anon_id'), "old_owner_id" => $_POST['id'])); } if ($with_comments) { log_warning("user", "Deleting user #{$_POST['id']}'s comments"); $database->execute("DELETE FROM comments WHERE owner_id = :owner_id", array("owner_id" => $_POST['id'])); } else { $database->Execute("UPDATE comments SET owner_id = :new_owner_id WHERE owner_id = :old_owner_id", array("new_owner_id" => $config->get_int('anon_id'), "old_owner_id" => $_POST['id'])); } send_event(new UserDeletionEvent($_POST['id'])); $database->execute("DELETE FROM users WHERE id = :id", array("id" => $_POST['id'])); $page->set_mode("redirect"); $page->set_redirect(make_link("post/list")); } } }
public function receive_event(Event $event) { global $config, $database, $page, $user; if (is_null($this->theme)) { $this->theme = get_theme_object($this); } // f*****g PHP "security" measures -_-;;; $free_num = @disk_free_space(realpath("./images/")); if ($free_num === FALSE) { $is_full = false; } else { $is_full = $free_num < 100 * 1024 * 1024; } if ($event instanceof InitExtEvent) { $config->set_default_int('upload_count', 3); $config->set_default_int('upload_size', '1MB'); $config->set_default_bool('upload_anon', false); $config->set_default_bool('upload_replace', true); } if ($event instanceof PostListBuildingEvent) { if ($this->can_upload($user)) { if ($is_full) { $this->theme->display_full($page); } else { $this->theme->display_block($page); } } } if ($event instanceof PageRequestEvent) { if ($event->page_matches("upload/replace")) { /* Upload & Replace Image Request */ if (!$config->get_bool("upload_replace")) { throw new UploadException("Upload Replacing Images is not enabled."); } // check if the user is an administrator and can upload files. if (!$user->is_admin()) { $this->theme->display_permission_denied($page); } else { if ($is_full) { throw new UploadException("Can not replace Image: disk nearly full"); } // 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 UploadException("Can not replace Image: No valid Image ID given."); } $image_old = Image::by_id($image_id); if (is_null($image_old)) { $this->theme->display_error($page, "Image not found", "No image in the database has the ID #{$image_id}"); } if (count($_FILES) + count($_POST) > 0) { if (count($_FILES) > 1) { 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); break; // leave the foreach loop. } } else { foreach ($_POST as $name => $value) { if (substr($name, 0, 3) == "url" && strlen($value) > 0) { $ok = $this->try_transload($value, $tags, $source, $image_id); break; // leave the foreach loop. } } } $this->theme->display_upload_status($page, $ok); } else { if (!empty($_GET['url'])) { $url = $_GET['url']; $ok = $this->try_transload($url, $tags, $url, $image_id); $this->theme->display_upload_status($page, $ok); } else { $this->theme->display_replace_page($page, $image_id); } } } // END of if admin / can_upload } else { if ($event->page_matches("upload")) { if (!$this->can_upload($user)) { $this->theme->display_permission_denied($page); } else { /* Regular Upload Image */ if (count($_FILES) + count($_POST) > 0) { $tags = Tag::explode($_POST['tags']); $source = isset($_POST['source']) ? $_POST['source'] : null; $ok = true; foreach ($_FILES as $file) { $ok = $ok & $this->try_upload($file, $tags, $source); } foreach ($_POST as $name => $value) { if (substr($name, 0, 3) == "url" && strlen($value) > 0) { $ok = $ok & $this->try_transload($value, $tags, $source); } } $this->theme->display_upload_status($page, $ok); } else { if (!empty($_GET['url'])) { $url = $_GET['url']; $tags = array('tagme'); if (!empty($_GET['tags']) && $_GET['tags'] != "null") { $tags = Tag::explode($_GET['tags']); } $ok = $this->try_transload($url, $tags, $url); $this->theme->display_upload_status($page, $ok); } else { if (!$is_full) { $this->theme->display_page($page); } } } } // END of if can_upload } } } // END of if PageRequestEvent if ($event instanceof SetupBuildingEvent) { $tes = array(); $tes["Disabled"] = "none"; if (function_exists("curl_init")) { $tes["cURL"] = "curl"; } $tes["fopen"] = "fopen"; $tes["WGet"] = "wget"; $sb = new SetupBlock("Upload"); $sb->position = 10; // Output the limits from PHP so the user has an idea of what they can set. $sb->add_label("<i>PHP's Upload Limit = " . ini_get('max_file_uploads') . "</i><br/>"); $sb->add_int_option("upload_count", "Max uploads: "); $sb->add_label("<br/><i>PHP's Max Size Upload = " . ini_get('upload_max_filesize') . "</i><br/>"); $sb->add_shorthand_int_option("upload_size", "<br/>Max size per file: "); $sb->add_bool_option("upload_anon", "<br/>Allow anonymous uploads: "); $sb->add_bool_option("upload_replace", "<br/>Allow replacing images: "); $sb->add_choice_option("transload_engine", $tes, "<br/>Transload: "); $event->panel->add_block($sb); } if ($event instanceof DataUploadEvent) { if ($is_full) { throw new UploadException("Upload failed; disk nearly full"); } if (filesize($event->tmpname) > $config->get_int('upload_size')) { $size = to_shorthand_int(filesize($event->tmpname)); $limit = to_shorthand_int($config->get_int('upload_size')); throw new UploadException("File too large ({$size} > {$limit})"); } } }
/** * This function gets the current order of images from a given pool. * @param int $poolID * @return \Image[] Array of image objects. */ private function edit_posts($poolID) { global $database; $result = $database->Execute("SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", array("pid" => $poolID)); $images = array(); while ($row = $result->fetch()) { $image = Image::by_id($row["image_id"]); $images[] = array($image); } return $images; }
/** * This function could be made much smaller by using the ImageReplaceEvent * ie: Pretend that we are replacing the image with a rotated copy. * * @param int $image_id * @param int $deg * @throws ImageRotateException */ private function rotate_image($image_id, $deg) { global $config, $user, $page, $database; if ($deg <= -360 || $deg >= 360) { throw new ImageRotateException("Invalid options for rotation angle. ({$deg})"); } $image_obj = Image::by_id($image_id); $hash = $image_obj->hash; if (is_null($hash)) { throw new ImageRotateException("Image does not have a hash associated with it."); } $image_filename = warehouse_path("images", $hash); if (file_exists($image_filename) == false) { throw new ImageRotateException("{$image_filename} does not exist."); } $info = getimagesize($image_filename); /* Get the image file type */ $pathinfo = pathinfo($image_obj->filename); $filetype = strtolower($pathinfo['extension']); /* Check Memory usage limits Old check: $memory_use = (filesize($image_filename)*2) + ($width*$height*4) + (4*1024*1024); New check: memory_use = width * height * (bits per channel) * channels * 2.5 It didn't make sense to compute the memory usage based on the NEW size for the image. ($width*$height*4) We need to consider the size that we are GOING TO instead. The factor of 2.5 is simply a rough guideline. http://stackoverflow.com/questions/527532/reasonable-php-memory-limit-for-image-resize */ $memory_use = $info[0] * $info[1] * ($info['bits'] / 8) * $info['channels'] * 2.5 / 1024; $memory_limit = get_memory_limit(); if ($memory_use > $memory_limit) { throw new ImageRotateException("The image is too large to rotate given the memory limits. ({$memory_use} > {$memory_limit})"); } /* 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 ImageRotateException("Unsupported image type or "); } /* Rotate and resample the image */ /* $image_rotated = 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_rotated, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']); imagefill($image_rotated, 0, 0, $transparency); imagecolortransparent($image_rotated, $transparency); } elseif ($info[2] == IMAGETYPE_PNG) { imagealphablending($image_rotated, false); $color = imagecolorallocatealpha($image_rotated, 0, 0, 0, 127); imagefill($image_rotated, 0, 0, $color); imagesavealpha($image_rotated, true); } } */ $image_rotated = imagerotate($image, $deg, 0); /* Temp storage while we rotate */ $tmp_filename = tempnam(ini_get('upload_tmp_dir'), 'shimmie_rotate'); if (empty($tmp_filename)) { throw new ImageRotateException("Unable to save temporary image file."); } /* Output to the same format as the original image */ switch ($info[2]) { case IMAGETYPE_GIF: imagegif($image_rotated, $tmp_filename); break; case IMAGETYPE_JPEG: imagejpeg($image_rotated, $tmp_filename); break; case IMAGETYPE_PNG: imagepng($image_rotated, $tmp_filename); break; default: throw new ImageRotateException("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 (!@copy($tmp_filename, $target)) { throw new ImageRotateException("Failed to copy new image file from temporary location ({$tmp_filename}) to archive ({$target})"); } $new_filename = 'rotated-' . $image_obj->filename; list($new_width, $new_height) = getimagesize($target); /* 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 \n\t\t\t\t\tfilename = :filename, filesize = :filesize,\thash = :hash, width = :width, height = :height\n\t\t\t\tWHERE \n\t\t\t\t\tid = :id\n\t\t\t\t", array("filename" => $new_filename, "filesize" => $new_size, "hash" => $new_hash, "width" => $new_width, "height" => $new_height, "id" => $image_id)); log_info("rotate", "Rotated Image #{$image_id} - New hash: {$new_hash}"); }
/** * Only allows 1 file to be uploaded - for replacing another image file. * * @param Page $page * @param int $image_id */ public function display_replace_page(Page $page, $image_id) { global $config, $page; $tl_enabled = $config->get_string("transload_engine", "none") != "none"; $upload_list = "\n\t\t\t\t<tr>\n\t\t\t\t\t<td>File</td>\n\t\t\t\t\t<td><input name='data' type='file'></td>\n\t\t\t\t\t"; if ($tl_enabled) { $upload_list .= "\n\t\t\t<td>or URL</td>\n\t\t\t<td><input name='url' type='text'></td>\n\t\t\t"; } $upload_list .= "</tr>"; $max_size = $config->get_int('upload_size'); $max_kb = to_shorthand_int($max_size); $image = Image::by_id($image_id); $thumbnail = $this->build_thumb_html($image); $html = "\n\t\t\t\t<p>Replacing Image ID " . $image_id . "<br>Please note: You will have to refresh the image page, or empty your browser cache.</p>" . $thumbnail . "<br>" . make_form(make_link("upload/replace/" . $image_id), "POST", $multipart = True) . "\n\t\t\t\t<input type='hidden' name='image_id' value='{$image_id}'>\n\t\t\t\t<table id='large_upload_form' class='vert'>\n\t\t\t\t\t{$upload_list}\n\t\t\t\t\t<tr><td>Source</td><td colspan='3'><input name='source' type='text'></td></tr>\n\t\t\t\t\t<tr><td colspan='4'><input id='uploadbutton' type='submit' value='Post'></td></tr>\n\t\t\t\t</table>\n\t\t\t</form>\n\t\t\t<small>(Max file size is {$max_kb})</small>\n\t\t"; $page->set_title("Replace Image"); $page->set_heading("Replace Image"); $page->add_block(new NavBlock()); $page->add_block(new Block("Upload Replacement Image", $html, "main", 20)); }
/** * HERE WE GET ALL NOTE REQUESTS * @param PageRequestEvent $event */ private function get_notes_requests(PageRequestEvent $event) { global $config; $pageNumber = $event->get_arg(1); if (is_null($pageNumber) || !is_numeric($pageNumber)) { $pageNumber = 0; } else { if ($pageNumber <= 0) { $pageNumber = 0; } else { $pageNumber--; } } $requestsPerPage = $config->get_int('notesRequestsPerPage'); //$result = $database->get_all("SELECT * FROM pool_images WHERE pool_id=?", array($poolID)); global $database; $get_requests = "\n\t\t\tSELECT DISTINCT image_id " . "FROM note_request " . "ORDER BY date DESC LIMIT ?, ?"; $result = $database->Execute($get_requests, array($pageNumber * $requestsPerPage, $requestsPerPage)); $totalPages = ceil($database->get_one("SELECT COUNT(*) FROM note_request") / $requestsPerPage); $images = array(); while (!$result->EOF) { $image = Image::by_id($result->fields["image_id"]); $images[] = array($image); $result->MoveNext(); } $this->theme->display_note_requests($images, $pageNumber + 1, $totalPages); }
public function display_replace_page(Page $page, $image_id) { global $config; $tl_enabled = $config->get_string("transload_engine", "none") != "none"; $upload_list = ''; $upload_list .= "\n\t\t\t\t<tr>\n\t\t\t\t\t<td width='60'><form><input id='radio_buttona' type='radio' name='method' value='file' checked='checked' onclick='javascript:document.getElementById("url0").style.display = "none";document.getElementById("url0").value = "";document.getElementById("data0").style.display = ""' /> File<br>"; if ($tl_enabled) { $upload_list .= "\n\t\t\t\t\t<input id='radio_buttonb' type='radio' name='method' value='url' onclick='javascript:document.getElementById("data0").style.display = "none";document.getElementById("data0").value = "";document.getElementById("url0").style.display = ""' /> URL</ br></td></form>\n\t\t\t\t\t<td><input id='data0' name='data0' class='wid' type='file'><input id='url0' name='url0' class='wid' type='text' style='display:none'></td>\n\t\t\t\t\t"; } else { $upload_list .= "</form></td>\n\t\t\t\t\t"; } $max_size = $config->get_int('upload_size'); $max_kb = to_shorthand_int($max_size); $image = Image::by_id($image_id); $thumbnail = $this->build_thumb_html($image, null); $html = "\n\t\t\t\t<div style='clear:both;'></div>\n\t\t\t\t<p>Replacing Image ID " . $image_id . "<br>Please note: You will have to refresh the image page, or empty your browser cache.</p>" . $thumbnail . "<br>" . make_form(make_link("upload/replace/" . $image_id), "POST", $multipart = True) . "\n\t\t\t\t<input type='hidden' name='image_id' value='{$image_id}'>\n\t\t\t\t<table id='large_upload_form' class='vert'>\n\t\t\t\t\t{$upload_list}\n\t\t\t\t\t<tr><td>Source</td><td colspan='3'><input name='source' type='text'></td></tr>\n\t\t\t\t\t<tr><td colspan='4'><input id='uploadbutton' type='submit' value='Post'></td></tr>\n\t\t\t\t</table>\n\t\t\t</form>\n\t\t\t<small>(Max file size is {$max_kb})</small>\n\t\t"; $page->set_title("Replace Image"); $page->set_heading("Replace Image"); $page->add_block(new NavBlock()); $page->add_block(new Block("Upload Replacement Image", $html, "main", 20)); }
/** * Generate the necessary DataUploadEvent for a given image and tags. */ private function add_image($tmpname, $filename, $tags) { assert(file_exists($tmpname)); $pathinfo = pathinfo($filename); if (!array_key_exists('extension', $pathinfo)) { throw new UploadException("File has no extension"); } $metadata = array(); $metadata['filename'] = $pathinfo['basename']; $metadata['extension'] = $pathinfo['extension']; $metadata['tags'] = ""; // = $tags; doesn't work when not logged in here $metadata['source'] = null; $event = new DataUploadEvent($tmpname, $metadata); send_event($event); // Generate info message $infomsg = ""; // Will contain info message if ($event->image_id == -1) { $infomsg = "File type not recognised. Filename: {$filename}"; } else { $infomsg = "Image uploaded. ID: {$event->image_id} - Filename: {$filename} - Tags: {$tags}"; } $msgNumber = $this->add_upload_info($infomsg); // Set tags $img = Image::by_id($event->image_id); $img->set_tags($tags); }
/** * @param DataUploadEvent $event * @throws UploadException */ public function onDataUpload(DataUploadEvent $event) { $supported_ext = $this->supported_ext($event->type); $check_contents = $this->check_contents($event->tmpname); if ($supported_ext && $check_contents) { if (!move_upload_to_archive($event)) { return; } send_event(new ThumbnailGenerationEvent($event->hash, $event->type)); /* Check if we are replacing an image */ if (array_key_exists('replace', $event->metadata) && isset($event->metadata['replace'])) { /* hax: This seems like such a dirty way to do this.. */ /* Validate things */ $image_id = int_escape($event->metadata['replace']); /* Check to make sure the image exists. */ $existing = Image::by_id($image_id); if (is_null($existing)) { throw new UploadException("Image to replace does not exist!"); } if ($existing->hash === $event->metadata['hash']) { throw new UploadException("The uploaded image is the same as the one to replace."); } // even more hax.. $event->metadata['tags'] = $existing->get_tag_list(); $image = $this->create_image_from_data(warehouse_path("images", $event->metadata['hash']), $event->metadata); if (is_null($image)) { throw new UploadException("Data handler failed to create image object from data"); } $ire = new ImageReplaceEvent($image_id, $image); send_event($ire); $event->image_id = $image_id; } else { $image = $this->create_image_from_data(warehouse_path("images", $event->hash), $event->metadata); if (is_null($image)) { throw new UploadException("Data handler failed to create image object from data"); } $iae = new ImageAdditionEvent($image); send_event($iae); $event->image_id = $iae->image->id; // Rating Stuff. if (!empty($event->metadata['rating'])) { $rating = $event->metadata['rating']; send_event(new RatingSetEvent($image, $rating)); } // Locked Stuff. if (!empty($event->metadata['locked'])) { $locked = $event->metadata['locked']; send_event(new LockSetEvent($image, !empty($locked))); } } } elseif ($supported_ext && !$check_contents) { throw new UploadException("Invalid or corrupted file"); } }
public function receive_event(Event $event) { if (is_null($this->theme)) { $this->theme = get_theme_object($this); } if ($event instanceof DataUploadEvent && $this->supported_ext($event->type) && $this->check_contents($event->tmpname)) { if (!move_upload_to_archive($event)) { return; } send_event(new ThumbnailGenerationEvent($event->hash, $event->type)); /* Check if we are replacing an image */ if (array_key_exists('replace', $event->metadata) && isset($event->metadata['replace'])) { /* hax: This seems like such a dirty way to do this.. */ /* Validate things */ $image_id = int_escape($event->metadata['replace']); /* Check to make sure the image exists. */ $existing = Image::by_id($image_id); if (is_null($existing)) { throw new UploadException("Image to replace does not exist!"); } if ($existing->hash === $event->metadata['hash']) { throw new UploadException("The uploaded image is the same as the one to replace."); } // even more hax.. $event->metadata['tags'] = $existing->get_tag_list(); $image = $this->create_image_from_data(warehouse_path("images", $event->metadata['hash']), $event->metadata); if (is_null($image)) { throw new UploadException("Data handler failed to create image object from data"); } $ire = new ImageReplaceEvent($image_id, $image); send_event($ire); $event->image_id = $image_id; } else { $image = $this->create_image_from_data(warehouse_path("images", $event->hash), $event->metadata); if (is_null($image)) { throw new UploadException("Data handler failed to create image object from data"); } $iae = new ImageAdditionEvent($event->user, $image); send_event($iae); $event->image_id = $iae->image->id; // Rating Stuff. if (!empty($event->metadata['rating'])) { global $user; $rating = $event->metadata['rating']; send_event(new RatingSetEvent($image, $user, $rating)); } // Locked Stuff. if (!empty($event->metadata['locked'])) { $locked = $event->metadata['locked']; send_event(new LockSetEvent($image, !empty($locked))); } } } if ($event instanceof ThumbnailGenerationEvent && $this->supported_ext($event->type)) { $this->create_thumb($event->hash); } if ($event instanceof DisplayingImageEvent && $this->supported_ext($event->image->ext)) { global $page; $this->theme->display_image($page, $event->image); } if ($event instanceof SetupBuildingEvent) { $sb = $this->setup(); if ($sb) { $event->panel->add_block($sb); } } }
/** * Wrapper for getting a single post * @param int $id */ protected function postShow($id = null) { if (!is_null($id)) { $post = new _SafeOuroborosImage(Image::by_id($id)); $this->sendData('post', $post); } else { $this->sendResponse(424, 'ID is mandatory'); } }
public function onTagTermParse(TagTermParseEvent $event) { $matches = array(); if (preg_match("/^source[=|:](.*)\$/i", $event->term, $matches)) { $source = $matches[1] !== "none" ? $matches[1] : null; send_event(new SourceSetEvent(Image::by_id($event->id), $source)); } if (!empty($matches)) { $event->metatag = true; } }
/** * @return array */ public function get_reported_images() { global $database; $all_reports = $database->get_all("\n\t\t\tSELECT image_reports.*, users.name AS reporter_name\n\t\t\tFROM image_reports\n\t\t\tJOIN users ON reporter_id = users.id"); if (is_null($all_reports)) { $all_reports = array(); } $reports = array(); foreach ($all_reports as $report) { $image_id = int_escape($report['image_id']); $image = Image::by_id($image_id); if (is_null($image)) { send_event(new RemoveReportedImageEvent($report['id'])); continue; } $report['image'] = $image; $reports[] = $report; } return $reports; }
private function process_revert_request($revert_id) { global $page; // check for the nothing case if ($revert_id == "nothing") { // tried to set it too the same thing so ignore it (might be a bot) // go back to the index page with you $page->set_mode("redirect"); $page->set_redirect(make_link()); return; } $revert_id = int_escape($revert_id); // lets get this revert id assuming it exists $result = $this->get_tag_history_from_revert($revert_id); if ($result == null) { // there is no history entry with that id so either the image was deleted // while the user was viewing the history, someone is playing with form // variables or we have messed up in code somewhere. die("Error: No tag history with specified id was found."); } // lets get the values out of the result $stored_result_id = $result->fields['id']; $stored_image_id = $result->fields['image_id']; $stored_tags = $result->fields['tags']; log_debug("tag_history", "Reverting tags of {$stored_image_id} to [{$stored_tags}]"); // all should be ok so we can revert by firing the SetUserTags event. send_event(new TagSetEvent(Image::by_id($stored_image_id), $stored_tags)); // all should be done now so redirect the user back to the image $page->set_mode("redirect"); $page->set_redirect(make_link("post/view/{$stored_image_id}")); }