Merge branch 'develop' of https://github.com/shish/shimmie2 into develop
This commit is contained in:
		
						commit
						445687111e
					
				| @ -191,7 +191,13 @@ class Image { | |||||||
| 			return null; | 			return null; | ||||||
| 		} | 		} | ||||||
| 		fwrite($fp, json_encode($req)); | 		fwrite($fp, json_encode($req)); | ||||||
| 		$data = fgets($fp, 1024); | 		$data = ""; | ||||||
|  | 		while (($buffer = fgets($fp, 4096)) !== false) { | ||||||
|  | 			$data .= $buffer; | ||||||
|  | 		} | ||||||
|  | 		if (!feof($fp)) { | ||||||
|  | 			die("Error: unexpected fgets() fail in query_accelerator($req)\n"); | ||||||
|  | 		} | ||||||
| 		fclose($fp); | 		fclose($fp); | ||||||
| 		return json_decode($data); | 		return json_decode($data); | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -41,6 +41,7 @@ _d("CORE_EXTS", "bbcode,user,mail,upload,image,view,handle_pixel,ext_manager,set | |||||||
| _d("EXTRA_EXTS", "");        // string   optional extra extensions
 | _d("EXTRA_EXTS", "");        // string   optional extra extensions
 | ||||||
| _d("BASE_URL", null);        // string   force a specific base URL (default is auto-detect)
 | _d("BASE_URL", null);        // string   force a specific base URL (default is auto-detect)
 | ||||||
| _d("MIN_PHP_VERSION", '7.0');// string   minimum supported PHP version
 | _d("MIN_PHP_VERSION", '7.0');// string   minimum supported PHP version
 | ||||||
|  | _d("SLOW_PAGES", null);      // float    log pages which take more time than this
 | ||||||
| _d("ENABLED_MODS", "imageboard"); | _d("ENABLED_MODS", "imageboard"); | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|  | |||||||
| @ -105,11 +105,19 @@ class User { | |||||||
| 		$user = User::by_name($name); | 		$user = User::by_name($name); | ||||||
| 		if($user) { | 		if($user) { | ||||||
| 			if($user->passhash == md5(strtolower($name) . $pass)) { | 			if($user->passhash == md5(strtolower($name) . $pass)) { | ||||||
|  | 				log_info("core-user", "Migrating from md5 to bcrypt for ".html_escape($name)); | ||||||
| 				$user->set_password($pass); | 				$user->set_password($pass); | ||||||
| 			} | 			} | ||||||
| 			if(password_verify($pass, $user->passhash)) { | 			if(password_verify($pass, $user->passhash)) { | ||||||
|  | 				log_info("core-user", "Logged in as ".html_escape($name)." ({$user->class->name})"); | ||||||
| 				return $user; | 				return $user; | ||||||
| 			} | 			} | ||||||
|  | 			else { | ||||||
|  | 				log_warning("core-user", "Failed to log in as ".html_escape($name)." (Invalid password)"); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			log_warning("core-user", "Failed to log in as ".html_escape($name)." (Invalid username)"); | ||||||
| 		} | 		} | ||||||
| 		return null; | 		return null; | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -350,6 +350,18 @@ function get_debug_info(): string { | |||||||
| 	return $debug; | 	return $debug; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function log_slow() { | ||||||
|  | 	global $_shm_load_start; | ||||||
|  | 	if(!is_null(SLOW_PAGES)) { | ||||||
|  | 		$_time = microtime(true) - $_shm_load_start; | ||||||
|  | 		if($_time > SLOW_PAGES) { | ||||||
|  | 			$_query = _get_query(); | ||||||
|  | 			$_dbg = get_debug_info(); | ||||||
|  | 			file_put_contents("data/slow-pages.log", "$_time $_query $_dbg\n", FILE_APPEND | LOCK_EX); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function score_assert_handler($file, $line, $code, $desc = null) { | function score_assert_handler($file, $line, $code, $desc = null) { | ||||||
| 	$file = basename($file); | 	$file = basename($file); | ||||||
| 	print("Assertion failed at $file:$line: $code ($desc)"); | 	print("Assertion failed at $file:$line: $code ($desc)"); | ||||||
| @ -389,7 +401,7 @@ function _sanitise_environment() { | |||||||
| 		date_default_timezone_set(TIMEZONE); | 		date_default_timezone_set(TIMEZONE); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ini_set('zend.assertions', 1);  // generate assertions
 | 	# ini_set('zend.assertions', 1);  // generate assertions
 | ||||||
| 	ini_set('assert.exception', 1);  // throw exceptions when failed
 | 	ini_set('assert.exception', 1);  // throw exceptions when failed
 | ||||||
| 	if(DEBUG) { | 	if(DEBUG) { | ||||||
| 		error_reporting(E_ALL); | 		error_reporting(E_ALL); | ||||||
|  | |||||||
| @ -130,16 +130,15 @@ class AdminPage extends Extension { | |||||||
| 		$reason = @$_POST['reason']; | 		$reason = @$_POST['reason']; | ||||||
| 		assert(strlen($query) > 1); | 		assert(strlen($query) > 1); | ||||||
| 
 | 
 | ||||||
| 		log_warning("admin", "Mass deleting: $query"); | 		$images = Image::find_images(0, 1000000, Tag::explode($query)); | ||||||
| 		$count = 0; | 		$count = count($images); | ||||||
| 		foreach(Image::find_images(0, 1000000, Tag::explode($query)) as $image) { | 		log_warning("admin", "Mass-deleting $count images from $query", true); | ||||||
|  | 		foreach($images as $image) { | ||||||
| 			if($reason && class_exists("ImageBan")) { | 			if($reason && class_exists("ImageBan")) { | ||||||
| 				send_event(new AddImageHashBanEvent($image->hash, $reason)); | 				send_event(new AddImageHashBanEvent($image->hash, $reason)); | ||||||
| 			} | 			} | ||||||
| 			send_event(new ImageDeletionEvent($image)); | 			send_event(new ImageDeletionEvent($image)); | ||||||
| 			$count++; |  | ||||||
| 		} | 		} | ||||||
| 		log_debug("admin", "Deleted $count images", true); |  | ||||||
| 
 | 
 | ||||||
| 		$page->set_mode("redirect"); | 		$page->set_mode("redirect"); | ||||||
| 		$page->set_redirect(make_link("post/list")); | 		$page->set_redirect(make_link("post/list")); | ||||||
|  | |||||||
| @ -14,10 +14,24 @@ class AutoComplete extends Extension { | |||||||
| 		if($event->page_matches("api/internal/autocomplete")) { | 		if($event->page_matches("api/internal/autocomplete")) { | ||||||
| 			if(!isset($_GET["s"])) return; | 			if(!isset($_GET["s"])) return; | ||||||
| 
 | 
 | ||||||
|  | 			$page->set_mode("data"); | ||||||
|  | 			$page->set_type("application/json"); | ||||||
|  | 
 | ||||||
|  | 			$s = strtolower($_GET["s"]); | ||||||
|  | 			if( | ||||||
|  | 				$s == '' || | ||||||
|  | 				$s[0] == '_' || | ||||||
|  | 				$s[0] == '%' || | ||||||
|  | 				strlen($s) > 32 | ||||||
|  | 			) { | ||||||
|  | 				$page->set_data("{}"); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			//$limit = 0;
 | 			//$limit = 0;
 | ||||||
| 			$cache_key = "autocomplete-" . strtolower($_GET["s"]); | 			$cache_key = "autocomplete-$s"; | ||||||
| 			$limitSQL = ""; | 			$limitSQL = ""; | ||||||
| 			$SQLarr = array("search"=>$_GET["s"]."%"); | 			$SQLarr = array("search"=>"$s%"); | ||||||
| 			if(isset($_GET["limit"]) && $_GET["limit"] !== 0){ | 			if(isset($_GET["limit"]) && $_GET["limit"] !== 0){ | ||||||
| 				$limitSQL = "LIMIT :limit"; | 				$limitSQL = "LIMIT :limit"; | ||||||
| 				$SQLarr['limit'] = $_GET["limit"]; | 				$SQLarr['limit'] = $_GET["limit"]; | ||||||
| @ -37,8 +51,6 @@ class AutoComplete extends Extension { | |||||||
| 				$database->cache->set($cache_key, $res, 600); | 				$database->cache->set($cache_key, $res, 600); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			$page->set_mode("data"); |  | ||||||
| 			$page->set_type("application/json"); |  | ||||||
| 			$page->set_data(json_encode($res)); | 			$page->set_data(json_encode($res)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -64,7 +64,7 @@ class VideoFileHandler extends DataHandlerExtension { | |||||||
| 
 | 
 | ||||||
| 		$orig_size = $this->video_size($inname); | 		$orig_size = $this->video_size($inname); | ||||||
| 		$scaled_size = get_thumbnail_size($orig_size[0], $orig_size[1]); | 		$scaled_size = get_thumbnail_size($orig_size[0], $orig_size[1]); | ||||||
| 		$cmd = escapeshellcmd(Tag::implode([ | 		$cmd = escapeshellcmd(implode(" ", [ | ||||||
| 			escapeshellarg($ffmpeg), | 			escapeshellarg($ffmpeg), | ||||||
| 			"-y", "-i", escapeshellarg($inname), | 			"-y", "-i", escapeshellarg($inname), | ||||||
| 			"-vf", "scale={$scaled_size[0]}:{$scaled_size[1]}", | 			"-vf", "scale={$scaled_size[0]}:{$scaled_size[1]}", | ||||||
| @ -76,12 +76,13 @@ class VideoFileHandler extends DataHandlerExtension { | |||||||
| 
 | 
 | ||||||
| 		exec($cmd, $output, $ret); | 		exec($cmd, $output, $ret); | ||||||
| 
 | 
 | ||||||
| 		if ((int)$ret == (int)1) { | 		if ((int)$ret == (int)0) { | ||||||
| 			$ok = true; | 			$ok = true; | ||||||
|  | 			log_error('handle_video', "Generating thumbnail with command `$cmd`, returns $ret"); | ||||||
| 		} | 		} | ||||||
| 
 | 		else { | ||||||
| 		// error_log("Generating thumbnail with command `$cmd`, returns $ret");
 |  | ||||||
| 			log_debug('handle_video', "Generating thumbnail with command `$cmd`, returns $ret"); | 			log_debug('handle_video', "Generating thumbnail with command `$cmd`, returns $ret"); | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		return $ok; | 		return $ok; | ||||||
| 	} | 	} | ||||||
| @ -89,7 +90,7 @@ class VideoFileHandler extends DataHandlerExtension { | |||||||
| 	protected function video_size(string $filename) { | 	protected function video_size(string $filename) { | ||||||
| 		global $config; | 		global $config; | ||||||
| 		$ffmpeg = $config->get_string("thumb_ffmpeg_path"); | 		$ffmpeg = $config->get_string("thumb_ffmpeg_path"); | ||||||
| 		$cmd = escapeshellcmd(Tag::implode([ | 		$cmd = escapeshellcmd(implode(" ", [ | ||||||
| 			escapeshellarg($ffmpeg), | 			escapeshellarg($ffmpeg), | ||||||
| 			"-y", "-i", escapeshellarg($filename), | 			"-y", "-i", escapeshellarg($filename), | ||||||
| 			"-vstats" | 			"-vstats" | ||||||
| @ -100,15 +101,17 @@ class VideoFileHandler extends DataHandlerExtension { | |||||||
| 		$regex_sizes = "/Video: .* ([0-9]{1,4})x([0-9]{1,4})/"; | 		$regex_sizes = "/Video: .* ([0-9]{1,4})x([0-9]{1,4})/"; | ||||||
| 		if (preg_match($regex_sizes, $output, $regs)) { | 		if (preg_match($regex_sizes, $output, $regs)) { | ||||||
| 			if (preg_match("/displaymatrix: rotation of (90|270).00 degrees/", $output)) { | 			if (preg_match("/displaymatrix: rotation of (90|270).00 degrees/", $output)) { | ||||||
| 				return [$regs[2], $regs[1]]; | 				$size = [$regs[2], $regs[1]]; | ||||||
| 			} | 			} | ||||||
| 			else { | 			else { | ||||||
| 				return [$regs[1], $regs[2]]; | 				$size = [$regs[1], $regs[2]]; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			return [1, 1]; | 			$size = [1, 1]; | ||||||
| 		} | 		} | ||||||
|  | 		log_debug('handle_video', "Getting video size with `$cmd`, returns $output -- $size[0], $size[1]"); | ||||||
|  | 		return $size; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
|  | |||||||
| @ -43,7 +43,11 @@ class IPBan extends Extension { | |||||||
| 		if($config->get_int("ext_ipban_version") < 8) { | 		if($config->get_int("ext_ipban_version") < 8) { | ||||||
| 			$this->install(); | 			$this->install(); | ||||||
| 		} | 		} | ||||||
| 		$config->set_default_string("ipban_message", "If you couldn't possibly be guilty of what you're banned for, the person we banned probably had a dynamic IP address and so do you. See <a href='http://whatismyipaddress.com/dynamic-static'>http://whatismyipaddress.com/dynamic-static</a> for more information.\n"); | 		$config->set_default_string("ipban_message", | ||||||
|  | '<p>IP <b>$IP</b> has been banned until <b>$DATE</b> by <b>$ADMIN</b> because of <b>$REASON</b> | ||||||
|  | <p>If you couldn\'t possibly be guilty of what you\'re banned for, the person we banned probably had a dynamic IP address and so do you. | ||||||
|  | <p>See <a href="http://whatismyipaddress.com/dynamic-static">http://whatismyipaddress.com/dynamic-static</a> for more information. | ||||||
|  | <p>$CONTACT'); | ||||||
| 		$this->check_ip_ban(); | 		$this->check_ip_ban(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -84,7 +88,7 @@ class IPBan extends Extension { | |||||||
| 
 | 
 | ||||||
| 	public function onSetupBuilding(SetupBuildingEvent $event) { | 	public function onSetupBuilding(SetupBuildingEvent $event) { | ||||||
| 		$sb = new SetupBlock("IP Ban"); | 		$sb = new SetupBlock("IP Ban"); | ||||||
| 		$sb->add_longtext_option("ipban_message", 'Message to show to banned users:'); | 		$sb->add_longtext_option("ipban_message", 'Message to show to banned users:<br>(with $IP, $DATE, $ADMIN, $REASON, and $CONTACT)'); | ||||||
| 		$event->panel->add_block($sb); | 		$event->panel->add_block($sb); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -226,14 +230,20 @@ class IPBan extends Extension { | |||||||
| 				$admin = User::by_id($row[$prefix.'banner_id']); | 				$admin = User::by_id($row[$prefix.'banner_id']); | ||||||
| 				$date = date("Y-m-d", $row[$prefix.'end_timestamp']); | 				$date = date("Y-m-d", $row[$prefix.'end_timestamp']); | ||||||
| 				$msg = $config->get_string("ipban_message"); | 				$msg = $config->get_string("ipban_message"); | ||||||
| 				header("HTTP/1.0 403 Forbidden"); | 				$msg = str_replace('$IP', $ip, $msg); | ||||||
| 				print "IP <b>$ip</b> has been banned until <b>$date</b> by <b>{$admin->name}</b> because of <b>$reason</b>\n"; | 				$msg = str_replace('$DATE', $date, $msg); | ||||||
| 				print "<p>$msg"; | 				$msg = str_replace('$ADMIN', $admin->name, $msg); | ||||||
| 
 | 				$msg = str_replace('$REASON', $reason, $msg); | ||||||
| 				$contact_link = contact_link(); | 				$contact_link = contact_link(); | ||||||
| 				if(!empty($contact_link)) { | 				if(!empty($contact_link)) { | ||||||
| 					print "<p><a href='$contact_link'>Contact the staff (be sure to include this message)</a>"; | 					$msg = str_replace('$CONTACT', "<a href='$contact_link'>Contact the staff (be sure to include this message)</a>", $msg); | ||||||
| 				} | 				} | ||||||
|  | 				else { | ||||||
|  | 					$msg = str_replace('$CONTACT', "", $msg); | ||||||
|  | 				} | ||||||
|  | 				header("HTTP/1.0 403 Forbidden"); | ||||||
|  | 				print "$msg"; | ||||||
|  | 
 | ||||||
| 				exit; | 				exit; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -91,13 +91,13 @@ class RSS_Images extends Extension { | |||||||
| 
 | 
 | ||||||
| 		$link = make_http(make_link("post/view/{$image->id}")); | 		$link = make_http(make_link("post/view/{$image->id}")); | ||||||
| 		$tags = html_escape($image->get_tag_list()); | 		$tags = html_escape($image->get_tag_list()); | ||||||
| 		$owner = $image->get_owner(); |  | ||||||
| 		$thumb_url = $image->get_thumb_link(); | 		$thumb_url = $image->get_thumb_link(); | ||||||
| 		$image_url = $image->get_image_link(); | 		$image_url = $image->get_image_link(); | ||||||
| 		$posted = date(DATE_RSS, strtotime($image->posted)); | 		$posted = date(DATE_RSS, strtotime($image->posted)); | ||||||
| 		$content = html_escape( | 		$content = html_escape( | ||||||
|  | 			"<div>" . | ||||||
| 			"<p>" . $this->theme->build_thumb_html($image) . "</p>" . | 			"<p>" . $this->theme->build_thumb_html($image) . "</p>" . | ||||||
| 			"<p>Uploaded by " . html_escape($owner->name) . "</p>" | 			"</div>" | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		$data = " | 		$data = " | ||||||
|  | |||||||
| @ -1,16 +1,25 @@ | |||||||
| $(function() { | $(function() { | ||||||
| 	if(Cookies.get("ui-tnc-agreed") !== "true") { | 	if(Cookies.get("ui-tnc-agreed") !== "true") { | ||||||
| 		$("BODY").html(""+ | 		$("BODY").addClass("censored"); | ||||||
| 			"<div align='center' style='font-size: 2em; position: absolute; z-index: 99999999999999999999999999;'>"+ | 		$("BODY").append("<div class='tnc_bg'></div>"); | ||||||
|  | 		$("BODY").append(""+ | ||||||
|  | 			"<div class='tnc'>"+ | ||||||
| 			"<p>For legal reasons, we need to point out that:"+ | 			"<p>For legal reasons, we need to point out that:"+ | ||||||
| 			"<p>A) this site contains material not suitable for minors"+ | 			"<p>A) this site contains material not suitable for minors"+ | ||||||
| 			"<br>B) cookies may be used"+ | 			"<br>B) cookies may be used"+ | ||||||
| 			"<p><a href='/tnc_agreed'>Click here if you're an adult, and you're ok with that</a>"+ | 			"<p><a onclick='tnc_agree();'>Click here if you're an adult, and you're ok with that</a>"+ | ||||||
| 			"</div>"+ | 			"</div>"+ | ||||||
| 		""); | 		""); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | function tnc_agree() { | ||||||
|  | 	Cookies.set("ui-tnc-agreed", "true", {path: '/', expires: 365}); | ||||||
|  | 	$("BODY").removeClass("censored"); | ||||||
|  | 	$(".tnc_bg").hide(); | ||||||
|  | 	$(".tnc").hide(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function image_hash_ban(id) { | function image_hash_ban(id) { | ||||||
| 	var reason = prompt("WHY?", "DNP"); | 	var reason = prompt("WHY?", "DNP"); | ||||||
| 	if(reason) { | 	if(reason) { | ||||||
|  | |||||||
							
								
								
									
										35
									
								
								ext/rule34/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ext/rule34/style.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | BODY.censored #header, | ||||||
|  | BODY.censored NAV, | ||||||
|  | BODY.censored ARTICLE, | ||||||
|  | BODY.censored FOOTER { | ||||||
|  | 	filter: blur(10px); | ||||||
|  | } | ||||||
|  | .tnc_bg { | ||||||
|  | 	position: fixed; | ||||||
|  | 	top: 0px; | ||||||
|  | 	left: 0px; | ||||||
|  | 	right: 0px; | ||||||
|  | 	bottom: 0px; | ||||||
|  | 	background: #ACE4A3; | ||||||
|  | 	opacity: 0.75; | ||||||
|  | 	z-index: 999999999999999999999; | ||||||
|  | } | ||||||
|  | .tnc { | ||||||
|  | 	position: fixed; | ||||||
|  | 	top: 20%; | ||||||
|  | 	left: 20%; | ||||||
|  | 	right: 20%; | ||||||
|  | 	text-align: center; | ||||||
|  | 	font-size: 2em; | ||||||
|  | 	background: #ACE4A3; | ||||||
|  | 	border: 1px solid #7EB977; | ||||||
|  | 	z-index: 9999999999999999999999; | ||||||
|  | } | ||||||
|  | @media (max-width: 1024px) { | ||||||
|  | 	.tnc { | ||||||
|  | 		top: 5%; | ||||||
|  | 		left: 5%; | ||||||
|  | 		right: 5%; | ||||||
|  | 		font-size: 3vw; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -66,19 +66,19 @@ class StatsDInterface extends Extension { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public function onUserCreation(UserCreationEvent $event) { | 	public function onUserCreation(UserCreationEvent $event) { | ||||||
| 		StatsDInterface::$stats["shimmie.events.user_creations"] = "1|c"; | 		StatsDInterface::$stats["shimmie_events.user_creations"] = "1|c"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public function onDataUpload(DataUploadEvent $event) { | 	public function onDataUpload(DataUploadEvent $event) { | ||||||
| 		StatsDInterface::$stats["shimmie.events.uploads"] = "1|c"; | 		StatsDInterface::$stats["shimmie_events.uploads"] = "1|c"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public function onCommentPosting(CommentPostingEvent $event) { | 	public function onCommentPosting(CommentPostingEvent $event) { | ||||||
| 		StatsDInterface::$stats["shimmie.events.comments"] = "1|c"; | 		StatsDInterface::$stats["shimmie_events.comments"] = "1|c"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public function onImageInfoSet(ImageInfoSetEvent $event) { | 	public function onImageInfoSet(ImageInfoSetEvent $event) { | ||||||
| 		StatsDInterface::$stats["shimmie.events.info-sets"] = "1|c"; | 		StatsDInterface::$stats["shimmie_events.info-sets"] = "1|c"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
|  | |||||||
| @ -497,6 +497,8 @@ class TagList extends Extension { | |||||||
| 	private function add_refine_block(Page $page, array $search) { | 	private function add_refine_block(Page $page, array $search) { | ||||||
| 		global $database, $config; | 		global $database, $config; | ||||||
| 
 | 
 | ||||||
|  | 		if(count($search) > 5) return; | ||||||
|  | 
 | ||||||
| 		$wild_tags = $search; | 		$wild_tags = $search; | ||||||
| 		$str_search = Tag::implode($search); | 		$str_search = Tag::implode($search); | ||||||
| 		$related_tags = $database->cache->get("related_tags:$str_search"); | 		$related_tags = $database->cache->get("related_tags:$str_search"); | ||||||
| @ -509,7 +511,7 @@ class TagList extends Extension { | |||||||
| 			foreach($wild_tags as $tag) { | 			foreach($wild_tags as $tag) { | ||||||
| 				$tag = str_replace("*", "%", $tag); | 				$tag = str_replace("*", "%", $tag); | ||||||
| 				$tag = str_replace("?", "_", $tag); | 				$tag = str_replace("?", "_", $tag); | ||||||
| 				$tag_ids = $database->get_col("SELECT id FROM tags WHERE tag LIKE :tag", array("tag"=>$tag)); | 				$tag_ids = $database->get_col("SELECT id FROM tags WHERE tag LIKE :tag AND count < 25000", array("tag"=>$tag)); | ||||||
| 				// $search_tags = array_merge($search_tags,
 | 				// $search_tags = array_merge($search_tags,
 | ||||||
| 				//                  $database->get_col("SELECT tag FROM tags WHERE tag LIKE :tag", array("tag"=>$tag)));
 | 				//                  $database->get_col("SELECT tag FROM tags WHERE tag LIKE :tag", array("tag"=>$tag)));
 | ||||||
| 				$tag_id_array = array_merge($tag_id_array, $tag_ids); | 				$tag_id_array = array_merge($tag_id_array, $tag_ids); | ||||||
| @ -518,6 +520,8 @@ class TagList extends Extension { | |||||||
| 			} | 			} | ||||||
| 			$tag_id_list = join(', ', $tag_id_array); | 			$tag_id_list = join(', ', $tag_id_array); | ||||||
| 
 | 
 | ||||||
|  | 			if(count($tag_id_array) > 5) return; | ||||||
|  | 
 | ||||||
| 			if($tags_ok) { | 			if($tags_ok) { | ||||||
| 				$query = " | 				$query = " | ||||||
| 					SELECT t2.tag AS tag, COUNT(it2.image_id) AS calc_count | 					SELECT t2.tag AS tag, COUNT(it2.image_id) AS calc_count | ||||||
|  | |||||||
| @ -82,18 +82,6 @@ class Upload extends Extension { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public function onPostListBuilding(PostListBuildingEvent $event) { |  | ||||||
| 		global $user, $page; |  | ||||||
| 		if($user->can("create_image")) { |  | ||||||
| 			if($this->is_full) { |  | ||||||
| 				$this->theme->display_full($page); |  | ||||||
| 			} |  | ||||||
| 			else { |  | ||||||
| 				$this->theme->display_block($page); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public function onSetupBuilding(SetupBuildingEvent $event) { | 	public function onSetupBuilding(SetupBuildingEvent $event) { | ||||||
| 		$tes = array(); | 		$tes = array(); | ||||||
| 		$tes["Disabled"] = "none"; | 		$tes["Disabled"] = "none"; | ||||||
| @ -130,6 +118,15 @@ class Upload extends Extension { | |||||||
| 	public function onPageRequest(PageRequestEvent $event) { | 	public function onPageRequest(PageRequestEvent $event) { | ||||||
| 		global $database, $page, $user; | 		global $database, $page, $user; | ||||||
| 
 | 
 | ||||||
|  | 		if($user->can("create_image")) { | ||||||
|  | 			if($this->is_full) { | ||||||
|  | 				$this->theme->display_full($page); | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				$this->theme->display_block($page); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		if($event->page_matches("upload/replace")) { | 		if($event->page_matches("upload/replace")) { | ||||||
| 			// check if the user is an administrator and can upload files.
 | 			// check if the user is an administrator and can upload files.
 | ||||||
| 			if(!$user->can("replace_image")) { | 			if(!$user->can("replace_image")) { | ||||||
|  | |||||||
| @ -19,9 +19,9 @@ class UploadTheme extends Themelet { | |||||||
| 		$html = " | 		$html = " | ||||||
| 			".make_form(make_link("upload"), "POST", $multipart=True, 'file_upload')." | 			".make_form(make_link("upload"), "POST", $multipart=True, 'file_upload')." | ||||||
| 				<table id='large_upload_form' class='vert'> | 				<table id='large_upload_form' class='vert'> | ||||||
|  | 					<tr><td width='20'>Common Tags<td colspan='5'><input name='tags' type='text' placeholder='tagme' class='autocomplete_tags' autocomplete='off'></td></tr> | ||||||
|  | 					<tr><td>Common Source</td><td colspan='5'><input name='source' type='text'></td></tr> | ||||||
| 					$upload_list | 					$upload_list | ||||||
| 					<tr><td width='20'>Tags<td colspan='5'><input name='tags' type='text' placeholder='tagme' class='autocomplete_tags' autocomplete='off'></td></tr> |  | ||||||
| 					<tr><td>Source</td><td colspan='5'><input name='source' type='text'></td></tr> |  | ||||||
| 					<tr><td colspan='6'><input id='uploadbutton' type='submit' value='Post'></td></tr> | 					<tr><td colspan='6'><input id='uploadbutton' type='submit' value='Post'></td></tr> | ||||||
| 				</table> | 				</table> | ||||||
| 			</form> | 			</form> | ||||||
|  | |||||||
| @ -240,7 +240,9 @@ class UserPage extends Extension { | |||||||
| 			$this->theme->display_ip_list( | 			$this->theme->display_ip_list( | ||||||
| 				$page, | 				$page, | ||||||
| 				$this->count_upload_ips($event->display_user), | 				$this->count_upload_ips($event->display_user), | ||||||
| 				$this->count_comment_ips($event->display_user)); | 				$this->count_comment_ips($event->display_user), | ||||||
|  | 				$this->count_log_ips($event->display_user) | ||||||
|  | 			); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -344,7 +346,6 @@ class UserPage extends Extension { | |||||||
| 		if(!is_null($duser)) { | 		if(!is_null($duser)) { | ||||||
| 			$user = $duser; | 			$user = $duser; | ||||||
| 			$this->set_login_cookie($duser->name, $pass); | 			$this->set_login_cookie($duser->name, $pass); | ||||||
| 			log_info("user", "{$user->class->name} logged in"); |  | ||||||
| 			$page->set_mode("redirect"); | 			$page->set_mode("redirect"); | ||||||
| 
 | 
 | ||||||
| 			// Try returning to previous page
 | 			// Try returning to previous page
 | ||||||
| @ -358,7 +359,6 @@ class UserPage extends Extension { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			log_warning("user", "Failed to log in as ".html_escape($name)); |  | ||||||
| 			$this->theme->display_error(401, "Error", "No user with those details was found"); | 			$this->theme->display_error(401, "Error", "No user with those details was found"); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -587,6 +587,21 @@ class UserPage extends Extension { | |||||||
| 		return $rows; | 		return $rows; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	private function count_log_ips(User $duser): array { | ||||||
|  | 		if(!class_exists('LogDatabase')) return array(); | ||||||
|  | 		global $database; | ||||||
|  | 		$rows = $database->get_pairs(" | ||||||
|  | 				SELECT | ||||||
|  | 					address, | ||||||
|  | 					COUNT(id) AS count, | ||||||
|  | 					MAX(date_sent) AS most_recent | ||||||
|  | 				FROM score_log | ||||||
|  | 				WHERE username=:username | ||||||
|  | 				GROUP BY address | ||||||
|  | 				ORDER BY most_recent DESC", array("username"=>$duser->name));
 | ||||||
|  | 		return $rows; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	private function delete_user(Page $page, bool $with_images=false, bool $with_comments=false) { | 	private function delete_user(Page $page, bool $with_images=false, bool $with_comments=false) { | ||||||
| 		global $user, $config, $database; | 		global $user, $config, $database; | ||||||
| 		 | 		 | ||||||
|  | |||||||
| @ -168,7 +168,7 @@ class UserPageTheme extends Themelet { | |||||||
| 		$page->add_block(new Block("Login", $html, "left", 90)); | 		$page->add_block(new Block("Login", $html, "left", 90)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public function display_ip_list(Page $page, array $uploads, array $comments) { | 	public function display_ip_list(Page $page, array $uploads, array $comments, array $events) { | ||||||
| 		$html = "<table id='ip-history'>"; | 		$html = "<table id='ip-history'>"; | ||||||
| 		$html .= "<tr><td>Uploaded from: "; | 		$html .= "<tr><td>Uploaded from: "; | ||||||
| 		$n = 0; | 		$n = 0; | ||||||
| @ -190,8 +190,18 @@ class UserPageTheme extends Themelet { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		$html .= "</td><td>Logged Events:"; | ||||||
|  | 		$n = 0; | ||||||
|  | 		foreach($events as $ip => $count) { | ||||||
|  | 			$html .= '<br>'.$ip.' ('.$count.')'; | ||||||
|  | 			if(++$n >= 20) { | ||||||
|  | 				$html .= "<br>..."; | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		$html .= "</td></tr>"; | 		$html .= "</td></tr>"; | ||||||
| 		$html .= "<tr><td colspan='2'>(Most recent at top)</td></tr></table>"; | 		$html .= "<tr><td colspan='3'>(Most recent at top)</td></tr></table>"; | ||||||
| 
 | 
 | ||||||
| 		$page->add_block(new Block("IPs", $html, "main", 70)); | 		$page->add_block(new Block("IPs", $html, "main", 70)); | ||||||
| 	} | 	} | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user