merge type hints

This commit is contained in:
Shish 2012-02-02 14:16:14 +00:00
commit dab85e5f26
65 changed files with 1318 additions and 722 deletions

2
.gitignore vendored
View File

@ -35,6 +35,7 @@ ext/image_hash_ban
ext/ipban ext/ipban
ext/link_image ext/link_image
ext/log_db ext/log_db
ext/mass_tagger
ext/news ext/news
ext/notes ext/notes
ext/numeric_score ext/numeric_score
@ -62,6 +63,7 @@ ext/text_score
ext/tips ext/tips
ext/twitter_soc ext/twitter_soc
ext/upload_cmd ext/upload_cmd
ext/update
ext/wiki ext/wiki
ext/word_filter ext/word_filter
ext/zoom ext/zoom

View File

@ -35,16 +35,11 @@ class AdminBuildingEvent extends Event {
} }
} }
class AdminPage implements Extension { class AdminPage extends SimpleExtension {
var $theme; public function onPageRequest($event) {
global $page, $user;
public function get_priority() {return 50;} if($event->page_matches("admin")) {
public function receive_event(Event $event) {
global $config, $database, $page, $user;
if(is_null($this->theme)) $this->theme = get_theme_object($this);
if(($event instanceof PageRequestEvent) && $event->page_matches("admin")) {
if(!$user->is_admin()) { if(!$user->is_admin()) {
$this->theme->display_permission_denied($page); $this->theme->display_permission_denied($page);
} }
@ -53,7 +48,7 @@ class AdminPage implements Extension {
} }
} }
if(($event instanceof PageRequestEvent) && $event->page_matches("admin_utils")) { if($event->page_matches("admin_utils")) {
if($user->is_admin() && $user->check_auth_token()) { if($user->is_admin() && $user->check_auth_token()) {
log_info("admin", "Util: {$_POST['action']}"); log_info("admin", "Util: {$_POST['action']}");
set_time_limit(0); set_time_limit(0);
@ -91,16 +86,18 @@ class AdminPage implements Extension {
} }
} }
} }
}
if($event instanceof AdminBuildingEvent) { public function onAdminBuilding($event) {
$this->theme->display_page($page); global $page;
$this->theme->display_form($page); $this->theme->display_page($page);
} $this->theme->display_form($page);
}
if($event instanceof UserBlockBuildingEvent) { public function onUserBlockBuilding($event) {
if($user->is_admin()) { global $user;
$event->add_link("Board Admin", make_link("admin")); if($user->is_admin()) {
} $event->add_link("Board Admin", make_link("admin"));
} }
} }
@ -134,10 +131,8 @@ class AdminPage implements Extension {
} }
private function dbdump($page) { private function dbdump($page) {
include "config.php";
$matches = array(); $matches = array();
preg_match("#(\w+)://(\w+):(\w+)@([\w\.\-]+)/([\w_]+)(\?.*)?#", $database_dsn, $matches); preg_match("#(\w+)://(\w+):(\w+)@([\w\.\-]+)/([\w_]+)(\?.*)?#", DATABASE_DSN, $matches);
$software = $matches[1]; $software = $matches[1];
$username = $matches[2]; $username = $matches[2];
$password = $matches[3]; $password = $matches[3];

View File

@ -914,8 +914,10 @@ class Artists implements Extension {
, array( , array(
$artistID $artistID
)); ));
for ($i = 0 ; $i < count($result) ; $i++) $num = count($result);
for ($i = 0 ; $i < $num ; $i++)
{ {
$result[$i]["name"] = stripslashes($result[$i]["name"]); $result[$i]["name"] = stripslashes($result[$i]["name"]);
} }
@ -931,8 +933,10 @@ class Artists implements Extension {
, array( , array(
$artistID $artistID
)); ));
$num = count($result);
for ($i = 0 ; $i < count($result) ; $i++) for ($i = 0 ; $i < $num ; $i++)
{ {
$result[$i]["url"] = stripslashes($result[$i]["url"]); $result[$i]["url"] = stripslashes($result[$i]["url"]);
} }
@ -1048,8 +1052,10 @@ class Artists implements Extension {
$pageNumber * $artistsPerPage $pageNumber * $artistsPerPage
, $artistsPerPage , $artistsPerPage
)); ));
$number_of_listings = count($listing);
for ($i = 0 ; $i < count($listing) ; $i++) for ($i = 0 ; $i < $number_of_listings ; $i++)
{ {
$listing[$i]["name"] = stripslashes($listing[$i]["name"]); $listing[$i]["name"] = stripslashes($listing[$i]["name"]);
$listing[$i]["user_name"] = stripslashes($listing[$i]["user_name"]); $listing[$i]["user_name"] = stripslashes($listing[$i]["user_name"]);

View File

@ -55,7 +55,8 @@ class BlotterTheme extends Themelet {
// Now, time for entries list. // Now, time for entries list.
$table_rows = ""; $table_rows = "";
for ($i = 0 ; $i < count($entries) ; $i++) $num_entries = count($entries);
for ($i = 0 ; $i < $num_entries ; $i++)
{ {
/** /**
* Add table rows * Add table rows
@ -106,7 +107,8 @@ class BlotterTheme extends Themelet {
$html .= "<html><head><title>Blotter</title></head> $html .= "<html><head><title>Blotter</title></head>
<body><pre>"; <body><pre>";
for ($i = 0 ; $i < count($entries) ; $i++) $num_entries = count($entries);
for ($i = 0 ; $i < $num_entries ; $i++)
{ {
/** /**
* Blotter entries * Blotter entries
@ -156,7 +158,8 @@ $(document).ready(function() {
}); });
//--></script>"; //--></script>";
$entries_list = ""; $entries_list = "";
for ($i = 0 ; $i < count($entries) ; $i++) $num_entries = count($entries);
for ($i = 0 ; $i < $num_entries ; $i++)
{ {
/** /**
* Blotter entries * Blotter entries
@ -175,8 +178,8 @@ $(document).ready(function() {
$in_text = ""; $in_text = "";
$pos_break = ""; $pos_break = "";
$pos_align = "text-align: right; position: absolute; right: 0px;"; $pos_align = "text-align: right; position: absolute; right: 0px;";
if($position == "left") { $pos_break = "<br />"; $pos_align = ""; } if($position === "left") { $pos_break = "<br />"; $pos_align = ""; }
if(count($entries) == 0) { $out_text = "No blotter entries yet."; $in_text = "Empty.";} if(count($entries) === 0) { $out_text = "No blotter entries yet."; $in_text = "Empty.";}
else { $clean_date = date("m/d/y",strtotime($entries[0]['entry_date'])); else { $clean_date = date("m/d/y",strtotime($entries[0]['entry_date']));
$out_text = "Blotter updated: {$clean_date}"; $out_text = "Blotter updated: {$clean_date}";
$in_text = "<ul>$entries_list</ul>"; $in_text = "<ul>$entries_list</ul>";

View File

@ -11,31 +11,26 @@
* message specified in the box. * message specified in the box.
*/ */
class Downtime implements Extension { class Downtime extends SimpleExtension {
var $theme;
public function get_priority() {return 10;} public function get_priority() {return 10;}
public function receive_event(Event $event) { public function onSetupBuilding($event) {
global $config, $database, $page, $user; $sb = new SetupBlock("Downtime");
if(is_null($this->theme)) $this->theme = get_theme_object($this); $sb->add_bool_option("downtime", "Disable non-admin access: ");
$sb->add_longtext_option("downtime_message", "<br>");
$event->panel->add_block($sb);
}
if($event instanceof SetupBuildingEvent) { public function onPageRequest($event) {
$sb = new SetupBlock("Downtime"); global $config, $page, $user;
$sb->add_bool_option("downtime", "Disable non-admin access: ");
$sb->add_longtext_option("downtime_message", "<br>");
$event->panel->add_block($sb);
}
if($event instanceof PageRequestEvent) { if($config->get_bool("downtime")) {
if($config->get_bool("downtime")) { if(!$user->is_admin() && !$this->is_safe_page($event)) {
if(!$user->is_admin() && !$this->is_safe_page($event)) { $msg = $config->get_string("downtime_message");
$msg = $config->get_string("downtime_message"); $this->theme->display_message($msg);
$this->theme->display_message($msg); exit;
exit;
}
$this->theme->display_notification($page);
} }
$this->theme->display_notification($page);
} }
} }

View File

@ -6,7 +6,7 @@ class DowntimeTheme extends Themelet {
*/ */
public function display_notification(Page $page) { public function display_notification(Page $page) {
$page->add_block(new Block("Downtime", $page->add_block(new Block("Downtime",
"<span style='font-size: 1.5em'><b>DOWNTIME MODE IS ON!</b></span>", "left", 0)); "<span style='font-size: 1.5em'><b><center>DOWNTIME MODE IS ON!</center></b></span>", "left", 0));
} }
/** /**
@ -28,7 +28,7 @@ class DowntimeTheme extends Themelet {
</head> </head>
<body> <body>
<div id="downtime"> <div id="downtime">
<h1>Down for Maintenance</h1> <h1><center>Down for Maintenance</center></h1>
<div id="message"> <div id="message">
$message $message
</div> </div>

View File

@ -23,7 +23,6 @@ class Emoticons extends FormatterExtension {
return $text; return $text;
} }
} }
add_event_listener(new Emoticons());
class EmoticonList extends SimpleExtension { class EmoticonList extends SimpleExtension {
public function onPageRequest($event) { public function onPageRequest($event) {

View File

@ -5,7 +5,7 @@ class FeaturedTheme extends Themelet {
* Show $text on the $page * Show $text on the $page
*/ */
public function display_featured(Page $page, Image $image) { public function display_featured(Page $page, Image $image) {
$page->add_block(new Block("Featured Image", $this->build_thumb_html($image), "left", 3)); $page->add_block(new Block("Featured Image", $this->build_featured_html($image), "left", 3));
} }
public function get_buttons_html($image_id) { public function get_buttons_html($image_id) {
@ -18,5 +18,25 @@ class FeaturedTheme extends Themelet {
</form> </form>
"; ";
} }
public function build_featured_html(Image $image, $query=null) {
global $config;
$i_id = int_escape($image->id);
$h_view_link = make_link("post/view/$i_id", $query);
$h_thumb_link = $image->get_thumb_link();
$h_tip = html_escape($image->get_tooltip());
$tsize = get_thumbnail_size($image->width, $image->height);
return "
<center><div>
<a href='$h_view_link' style='position: relative; height: {$tsize[1]}px; width: {$tsize[0]}px;'>
<img id='thumb_$i_id' title='$h_tip' alt='$h_tip' class='highlighted' style='height: {$tsize[1]}px; width: {$tsize[0]}px;' src='$h_thumb_link'>
</a>
</div></center>
";
}
} }
?> ?>

View File

@ -56,7 +56,8 @@ class FlashFileHandler extends DataHandlerExtension {
private function str_to_binarray($string) { private function str_to_binarray($string) {
$binary = array(); $binary = array();
for($j=0; $j<strlen($string); $j++) { $length = strlen($string);
for($j=0; $j<$length; $j++) {
$c = ord($string[$j]); $c = ord($string[$j]);
for($i=7; $i>=0; $i--) { for($i=7; $i>=0; $i--) {
$binary[] = ($c >> $i) & 0x01; $binary[] = ($c >> $i) & 0x01;

View File

@ -4,13 +4,14 @@ class MP3FileHandlerTheme extends Themelet {
public function display_image(Page $page, Image $image) { public function display_image(Page $page, Image $image) {
$data_href = get_base_href(); $data_href = get_base_href();
$ilink = $image->get_image_link(); $ilink = $image->get_image_link();
$fname = url_escape($image->filename); //Most of the time this will be the title/artist of the song.
$html = " $html = "
<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' <object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'
codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0'
width='400' height='15'> width='400' height='15'>
<param name='movie' value='$data_href/ext/handle_mp3/xspf_player_slim.swf?song_url=$ilink'/> <param name='movie' value='$data_href/ext/handle_mp3/xspf_player_slim.swf?song_url=$ilink'/>
<param name='quality' value='high' /> <param name='quality' value='high' />
<embed src='$data_href/ext/handle_mp3/xspf_player_slim.swf?song_url=$ilink' quality='high' <embed src='$data_href/ext/handle_mp3/xspf_player_slim.swf?song_url=$ilink&song_title=$fname' quality='high'
pluginspage='http://www.macromedia.com/go/getflashplayer' pluginspage='http://www.macromedia.com/go/getflashplayer'
width='400' height='15' width='400' height='15'
type='application/x-shockwave-flash'></embed> type='application/x-shockwave-flash'></embed>

View File

@ -21,8 +21,7 @@ class Home extends SimpleExtension {
$config->set_default_string("home_links", '[$base/post/list|Posts] $config->set_default_string("home_links", '[$base/post/list|Posts]
[$base/comment/list|Comments] [$base/comment/list|Comments]
[$base/tags|Tags] [$base/tags|Tags]
[$base/wiki|Wiki] [$base/ext_doc|&raquo;]');
[$base/wiki/more|&raquo;]');
} }
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event) {
@ -46,7 +45,8 @@ class Home extends SimpleExtension {
} }
$sb = new SetupBlock("Home Page"); $sb = new SetupBlock("Home Page");
$sb->add_longtext_option("home_links", 'Page Links - Example: [/post/list|Posts]<br>'); $sb->add_bool_option("home_choice", "Use custom page links: ");
$sb->add_longtext_option("home_links", '<br>Page Links - Example: [/post/list|Posts]<br>');
$sb->add_longtext_option("home_text", "<br>Page Text:<br>"); $sb->add_longtext_option("home_text", "<br>Page Text:<br>");
$sb->add_choice_option("home_counter", $counters, "<br>Counter: "); $sb->add_choice_option("home_counter", $counters, "<br>Counter: ");
$event->panel->add_block($sb); $event->panel->add_block($sb);
@ -67,13 +67,21 @@ class Home extends SimpleExtension {
$num_comma = number_format($total); $num_comma = number_format($total);
$counter_text = ""; $counter_text = "";
for($n=0; $n<strlen($strtotal); $n++) { $length = strlen($strtotal);
for($n=0; $n<$length; $n++) {
$cur = $strtotal[$n]; $cur = $strtotal[$n];
$counter_text .= " <img alt='$cur' src='$base_href/ext/home/counters/$counter_dir/$cur.gif' /> "; $counter_text .= " <img alt='$cur' src='$base_href/ext/home/counters/$counter_dir/$cur.gif' /> ";
} }
// get the homelinks and process them // get the homelinks and process them
$main_links = $config->get_string('home_links'); if($config->get_bool('home_choice')){
$main_links = $config->get_string('home_links');
}else{
$main_links = '[$base/post/list|Posts] [$base/comment/list|Comments] [$base/tags|Tags]';
if(file_exists("ext/pools")){$main_links .= ' [$base/pools|Pools]';}
if(file_exists("ext/wiki")){$main_links .= ' [$base/wiki|Wiki]';}
$main_links .= ' [$base/ext_doc|&raquo;]';
}
$main_links = str_replace('$base', $base_href, $main_links); $main_links = str_replace('$base', $base_href, $main_links);
$main_links = preg_replace('#\[(.*?)\|(.*?)\]#', "<a href='\\1'>\\2</a>", $main_links); $main_links = preg_replace('#\[(.*?)\|(.*?)\]#', "<a href='\\1'>\\2</a>", $main_links);
$main_links = str_replace('//', "/", $main_links); $main_links = str_replace('//', "/", $main_links);

View File

@ -29,6 +29,7 @@ EOD
$main_links_html = empty($main_links) ? "" : "<div class='space' id='links'>$main_links</div>"; $main_links_html = empty($main_links) ? "" : "<div class='space' id='links'>$main_links</div>";
$message_html = empty($main_text) ? "" : "<div class='space' id='message'>$main_text</div>"; $message_html = empty($main_text) ? "" : "<div class='space' id='message'>$main_text</div>";
$counter_html = empty($counter_text) ? "" : "<div class='space' id='counter'>$counter_text</div>"; $counter_html = empty($counter_text) ? "" : "<div class='space' id='counter'>$counter_text</div>";
$contact_link = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a> &ndash;";
$search_html = " $search_html = "
<div class='space' id='search'> <div class='space' id='search'>
<form action='".make_link("post/list")."' method='GET'> <form action='".make_link("post/list")."' method='GET'>
@ -47,7 +48,7 @@ EOD
$counter_html $counter_html
<div class='space' id='foot'> <div class='space' id='foot'>
<small><small> <small><small>
<a href='mailto:$contact_link'>Contact</a> &ndash; Serving $num_comma posts &ndash; $contact_link Serving $num_comma posts &ndash;
Running <a href='http://code.shishnet.org/shimmie2/'>Shimmie</a> Running <a href='http://code.shishnet.org/shimmie2/'>Shimmie</a>
</small></small> </small></small>
</div> </div>

View File

@ -161,6 +161,7 @@ class ImageBan extends SimpleExtension {
$database->Execute( $database->Execute(
"INSERT INTO image_bans (hash, reason, date) VALUES (?, ?, now())", "INSERT INTO image_bans (hash, reason, date) VALUES (?, ?, now())",
array($hash, $reason)); array($hash, $reason));
log_info("image_hash_ban", "Banned hash: ($hash) because '$reason'");
} }
public function remove_image_hash_ban($hash) { public function remove_image_hash_ban($hash) {

View File

@ -34,24 +34,20 @@ class AddIPBanEvent extends Event {
} }
// }}} // }}}
class IPBan implements Extension { class IPBan extends SimpleExtension {
var $theme;
// event handler {{{
public function get_priority() {return 10;} public function get_priority() {return 10;}
public function receive_event(Event $event) { public function onInitExt($event) {
global $config, $database, $page, $user; global $config;
if(is_null($this->theme)) $this->theme = get_theme_object($this); if($config->get_int("ext_ipban_version") < 5) {
$this->install();
if($event instanceof InitExtEvent) {
if($config->get_int("ext_ipban_version") < 5) {
$this->install();
}
$this->check_ip_ban();
} }
$this->check_ip_ban();
}
if(($event instanceof PageRequestEvent) && $event->page_matches("ip_ban")) { public function onPageRequest($event) {
if($event->page_matches("ip_ban")) {
global $config, $database, $page, $user;
if($user->is_admin()) { if($user->is_admin()) {
if($event->get_arg(0) == "add" && $user->check_auth_token()) { if($event->get_arg(0) == "add" && $user->check_auth_token()) {
if(isset($_POST['ip']) && isset($_POST['reason']) && isset($_POST['end'])) { if(isset($_POST['ip']) && isset($_POST['reason']) && isset($_POST['end'])) {
@ -79,23 +75,26 @@ class IPBan implements Extension {
$this->theme->display_permission_denied($page); $this->theme->display_permission_denied($page);
} }
} }
}
if($event instanceof UserBlockBuildingEvent) { public function onUserBlockBuilding($event) {
if($user->is_admin()) { global $user;
$event->add_link("IP Bans", make_link("ip_ban/list")); if($user->is_admin()) {
} $event->add_link("IP Bans", make_link("ip_ban/list"));
}
if($event instanceof AddIPBanEvent) {
$this->add_ip_ban($event->ip, $event->reason, $event->end, $user);
}
if($event instanceof RemoveIPBanEvent) {
$database->Execute("DELETE FROM bans WHERE id = :id", array("id"=>$event->id));
$database->cache->delete("ip_bans");
} }
} }
// }}}
public function onAddIPBan($event) {
global $user;
$this->add_ip_ban($event->ip, $event->reason, $event->end, $user);
}
public function onRemoveIPBan($event) {
global $database;
$database->Execute("DELETE FROM bans WHERE id = :id", array("id"=>$event->id));
$database->cache->delete("ip_bans");
}
// installer {{{ // installer {{{
protected function install() { protected function install() {
global $database; global $database;
@ -263,6 +262,7 @@ class IPBan implements Extension {
$sql = "INSERT INTO bans (ip, reason, end_timestamp, banner_id) VALUES (:ip, :reason, :end, :admin_id)"; $sql = "INSERT INTO bans (ip, reason, end_timestamp, banner_id) VALUES (:ip, :reason, :end, :admin_id)";
$database->Execute($sql, array("ip"=>$ip, "reason"=>$reason, "end"=>strtotime($end), "admin_id"=>$user->id)); $database->Execute($sql, array("ip"=>$ip, "reason"=>$reason, "end"=>strtotime($end), "admin_id"=>$user->id));
$database->cache->delete("ip_bans"); $database->cache->delete("ip_bans");
log_info("ipban", "'$user->name' has banned '$ip' because '$reason' until '$end'");
} }
// }}} // }}}
} }

View File

@ -0,0 +1,53 @@
<?php
/*
* Name: Mass Tagger
* Author: Christian Walde <walde.christian@googlemail.com>
* License: WTFPL
* Description: Tag a bunch of images at once
* Documentation:
* Once enabled, a new "Mass Tagger" box will appear on the left hand side of
* post listings, with a button to enable the mass tagger. Once clicked JS will
* add buttons to each image to mark them for tagging, and a field for
* inputting tags will appear. Once the "Tag" button is clicked, the tags in
* the text field will be added to marked images.
*
* As of now only compatible with the lite theme.
*/
class MassTagger extends SimpleExtension {
public function onPostListBuilding($event) {
global $config, $page, $user;
if( !$user->is_admin() ) return;
$this->theme->display_mass_tagger( $page, $event, $config );
}
public function onPageRequest($event) {
global $config, $page, $user;
if( !$event->page_matches("mass_tagger") ) return;
if( !$user->is_admin() ) return;
if($event->get_arg(0) == "tag") $this->_apply_mass_tags( $config, $page, $user, $event );
}
private function _apply_mass_tags( $config, $page, $user, $event ) {
if( !isset($_POST['ids']) or !isset($_POST['tag']) ) return;
$tag = $_POST['tag'];
$ids = explode( ':', $_POST['ids'] );
$ids = array_filter ( $ids , 'is_numeric' );
$ids = array_map( "Image::by_id", $ids );
$func = function( $image ) use ( $tag ) {
$tag .= " " . $image->get_tag_list();
$image->set_tags( $tag );
};
array_walk( $ids, $func );
$page->set_mode("redirect");
$page->set_redirect(make_link("post/list"));
}
}
?>

View File

@ -0,0 +1,68 @@
function toggle_tag( button, id ) {
id += ":";
var list = $('#mass_tagger_ids');
var string = list.val();
if( string.indexOf( id ) > -1 ) return remove_mass_tag_id( button, list, id, string );
return add_mass_tag_id( button, list, id, string );
}
function add_mass_tag_id( button, list, id, string ) {
$(button).attr( 'style', 'display:block;border: 3px solid blue;' );
string += id;
list.val( string );
return false;
}
function remove_mass_tag_id( button, list, id, string ) {
$(button).attr( 'style', '' );
string = string.replace( id, '' );
list.val( string );
return false;
}
function activate_mass_tagger ( image_link ) {
find_thumb_link_containers().each(
function ( index, block ) {
add_mass_tag_button( block, image_link );
}
);
$('#mass_tagger_controls').attr( 'style', 'display:block' );
$('#mass_tagger_activate').attr( 'style', 'display:none' );
return false;
}
function add_mass_tag_button ( block, image_link ) {
var id = get_image_id( block );
var button = create_mass_tag_button( id, image_link );
$(block).append( button );
return;
}
function get_image_id ( block ) {
var link = $(block).children(":first").attr('href');
var id = link.split('/').pop();
return id;
}
function create_mass_tag_button ( id, image_link ) {
var img = $('<img />');
img.attr( "src", image_link+'/ext/mass_tagger/toggle.gif' );
var link = $('<a />');
link.attr("class",'zoom');
link.attr("onclick",'return toggle_tag( this, "'+id+'")');
link.attr("href",'#');
link.append( img );
return link;
}

View File

@ -0,0 +1,8 @@
.zoom{ position:absolute;display:none;margin:-110px 27px; }
.thumbblock:hover .zoom{ display:block; }
.zoom:hover{ border: 3px solid blue; }
/*.zoom img:hover{ background:url(/contrib/simpletest/data/pbx_screenshot.jpg) no-repeat;}*/
.zoom img { width: 100px; height: 100px; }
#mass_tagger_controls { display:none; }

View File

@ -0,0 +1,26 @@
<?php
class MassTaggerTheme extends Themelet {
/*
* Show $text on the $page
*/
public function display_mass_tagger( Page $page, Event $event, $config ) {
$data_href = get_base_href();
$body = "
<form action='".make_link("mass_tagger/tag")."' method='POST'>
<input id='mass_tagger_activate' type='button' onclick='activate_mass_tagger(\"$data_href\");' value='Activate'/>
<div id='mass_tagger_controls'>
Click on images to mark them. Use the 'Index Options' in the Board Config to increase the amount of shown images.
<br />
<input type='hidden' name='ids' id='mass_tagger_ids' />
<label>Tags: <input type='text' name='tag' /></label>
<input type='submit' value='Tag Marked Images' />
</div>
</form>
";
$block = new Block("Mass Tagger", $body, "left", 50);
$page->add_block( $block );
}
}
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

95
contrib/numeric_score/main.php Normal file → Executable file
View File

@ -109,66 +109,67 @@ class NumericScore implements Extension {
if($event->page_matches("popular_by_day") || $event->page_matches("popular_by_month") || $event->page_matches("popular_by_year")) { if($event->page_matches("popular_by_day") || $event->page_matches("popular_by_month") || $event->page_matches("popular_by_year")) {
$t_images = $config->get_int("index_height") * $config->get_int("index_width"); $t_images = $config->get_int("index_height") * $config->get_int("index_width");
//TODO: Somehow make popular_by_#/2012/12/31 > popular_by_#?day=31&month=12&year=2012 (So no problems with date formats)
//TODO: Add Popular_by_week. //TODO: Add Popular_by_week.
$sql = "SELECT * FROM images ";
$args = array();
//year //year
if(int_escape($event->get_arg(0)) == 0){ if(empty($_GET['year'])){
$year = date("Y"); $year = date("Y");
}else{ }else{
$year = $event->get_arg(0); $year = $_GET['year'];
} }
//month //month
if(int_escape($event->get_arg(1)) == 0 || int_escape($event->get_arg(1)) > 12){ if(empty($_GET['month']) || int_escape($_GET['month']) > 12){
$month = date("m"); $month = date("m");
}else{ }else{
$month = $event->get_arg(1); $month = $_GET['month'];
} }
//day //day
if(int_escape($event->get_arg(2)) == 0 || int_escape($event->get_arg(2)) > 31){ if(empty($_GET['day']) || int_escape($_GET['day']) > 31){
$day = date("d"); $day = date("d");
}else{ }else{
$day = $event->get_arg(2); $day = $_GET['day'];
} }
$totaldate = $year."/".$month."/".$day; $totaldate = $year."/".$month."/".$day;
$sql =
"SELECT * FROM images
WHERE EXTRACT(YEAR FROM posted) = :year
";
$agrs = array("limit" => $t_images, "year" => $year);
if($event->page_matches("popular_by_day")){ if($event->page_matches("popular_by_day")){
$sql .= $sql .=
"WHERE EXTRACT(YEAR FROM posted) = :year "AND EXTRACT(MONTH FROM posted) = :month
AND EXTRACT(MONTH FROM posted) = :month
AND EXTRACT(DAY FROM posted) = :day AND EXTRACT(DAY FROM posted) = :day
AND NOT numeric_score=0 AND NOT numeric_score=0
"; ";
$dte = array($totaldate, date("F jS, Y", (strtotime($totaldate))), "Y/m/d", "day"); //array_push doesn't seem to like using double arrows
//this requires us to instead create two arrays and merge
$sgra = array("month" => $month, "day" => $day);
$args = array_merge($agrs, $sgra);
$dte = array($totaldate, date("F jS, Y", (strtotime($totaldate))), "\\y\\e\\a\\r\\=Y\\&\\m\\o\\n\\t\\h\\=m\\&\\d\\a\\y\\=d", "day");
} }
if($event->page_matches("popular_by_month")){ if($event->page_matches("popular_by_month")){
$sql .= $sql .=
"WHERE EXTRACT(YEAR FROM posted) = :year "AND EXTRACT(MONTH FROM posted) = :month
AND EXTRACT(MONTH FROM posted) = :month
AND NOT numeric_score=0 AND NOT numeric_score=0
"; ";
$sgra = array("month" => $month);
$args = array_merge($agrs, $sgra);
$title = date("F Y", (strtotime($totaldate))); $title = date("F Y", (strtotime($totaldate)));
$dte = array($totaldate, $title, "Y/m", "month"); $dte = array($totaldate, $title, "\\y\\e\\a\\r\\=Y\\&\\m\\o\\n\\t\\h\\=m", "month");
} }
if($event->page_matches("popular_by_year")){ if($event->page_matches("popular_by_year")){
$sql .= $sql .= "AND NOT numeric_score=0";
"WHERE EXTRACT(YEAR FROM posted) = :year $dte = array($totaldate, $year, "\y\e\a\\r\=Y", "year");
AND NOT numeric_score=0 $args = $agrs;
";
$dte = array($totaldate, $year, "Y", "year");
} }
$sql .= " ORDER BY numeric_score DESC LIMIT :limit OFFSET 0"; $sql .= " ORDER BY numeric_score DESC LIMIT :limit OFFSET 0";
//filter images by year/score != 0 > limit to max images on one page > order from highest to lowest score //filter images by year/score != 0 > limit to max images on one page > order from highest to lowest score
$args = array(
"year" => $year,
"month" => $month,
"day" => $day,
"limit" => $t_images
);
$result = $database->get_all($sql, $args); $result = $database->get_all($sql, $args);
$images = array(); $images = array();
@ -185,7 +186,7 @@ class NumericScore implements Extension {
} }
if($event instanceof ImageDeletionEvent) { if($event instanceof ImageDeletionEvent) {
$database->execute("DELETE FROM numeric_score_votes WHERE image_id=?", array($event->image->id)); $database->execute("DELETE FROM numeric_score_votes WHERE image_id=:id", array("id" => $event->image->id));
} }
if($event instanceof ParseLinkTemplateEvent) { if($event instanceof ParseLinkTemplateEvent) {
@ -206,8 +207,8 @@ class NumericScore implements Extension {
"Can't find the user named ".html_escape($matches[1])); "Can't find the user named ".html_escape($matches[1]));
} }
$event->add_querylet(new Querylet( $event->add_querylet(new Querylet(
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=? AND score=1)", "images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=1)",
array($duser->id))); array("ns_user_id"=>$duser->id)));
} }
if(preg_match("/^downvoted_by=(.*)$/", $event->term, $matches)) { if(preg_match("/^downvoted_by=(.*)$/", $event->term, $matches)) {
$duser = User::by_name($matches[1]); $duser = User::by_name($matches[1]);
@ -216,20 +217,20 @@ class NumericScore implements Extension {
"Can't find the user named ".html_escape($matches[1])); "Can't find the user named ".html_escape($matches[1]));
} }
$event->add_querylet(new Querylet( $event->add_querylet(new Querylet(
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=? AND score=-1)", "images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=-1)",
array($duser->id))); array("ns_user_id"=>$duser->id)));
} }
if(preg_match("/^upvoted_by_id=(\d+)$/", $event->term, $matches)) { if(preg_match("/^upvoted_by_id=(\d+)$/", $event->term, $matches)) {
$iid = int_escape($matches[1]); $iid = int_escape($matches[1]);
$event->add_querylet(new Querylet( $event->add_querylet(new Querylet(
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=? AND score=1)", "images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=1)",
array($iid))); array("ns_user_id"=>$iid)));
} }
if(preg_match("/^downvoted_by_id=(\d+)$/", $event->term, $matches)) { if(preg_match("/^downvoted_by_id=(\d+)$/", $event->term, $matches)) {
$iid = int_escape($matches[1]); $iid = int_escape($matches[1]);
$event->add_querylet(new Querylet( $event->add_querylet(new Querylet(
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=? AND score=-1)", "images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=-1)",
array($iid))); array("ns_user_id"=>$iid)));
} }
} }
} }
@ -239,8 +240,8 @@ class NumericScore implements Extension {
global $config; global $config;
if($config->get_int("ext_numeric_score_version") < 1) { if($config->get_int("ext_numeric_score_version") < 1) {
$database->Execute("ALTER TABLE images ADD COLUMN numeric_score INTEGER NOT NULL DEFAULT 0"); $database->execute("ALTER TABLE images ADD COLUMN numeric_score INTEGER NOT NULL DEFAULT 0");
$database->Execute("CREATE INDEX images__numeric_score ON images(numeric_score)"); $database->execute("CREATE INDEX images__numeric_score ON images(numeric_score)");
$database->create_table("numeric_score_votes", " $database->create_table("numeric_score_votes", "
image_id INTEGER NOT NULL, image_id INTEGER NOT NULL,
user_id INTEGER NOT NULL, user_id INTEGER NOT NULL,
@ -253,24 +254,24 @@ class NumericScore implements Extension {
$config->set_int("ext_numeric_score_version", 1); $config->set_int("ext_numeric_score_version", 1);
} }
if($config->get_int("ext_numeric_score_version") < 2) { if($config->get_int("ext_numeric_score_version") < 2) {
$database->Execute("CREATE INDEX numeric_score_votes__user_votes ON numeric_score_votes(user_id, score)"); $database->execute("CREATE INDEX numeric_score_votes__user_votes ON numeric_score_votes(user_id, score)");
$config->set_int("ext_numeric_score_version", 2); $config->set_int("ext_numeric_score_version", 2);
} }
} }
private function add_vote($image_id, $user_id, $score) { private function add_vote($image_id, $user_id, $score) {
global $database; global $database;
$database->Execute( $database->execute(
"DELETE FROM numeric_score_votes WHERE image_id=? AND user_id=?", "DELETE FROM numeric_score_votes WHERE image_id=:imageid AND user_id=:userid",
array($image_id, $user_id)); array("imageid" => $image_id, "userid" => $user_id));
if($score != 0) { if($score != 0) {
$database->Execute( $database->execute(
"INSERT INTO numeric_score_votes(image_id, user_id, score) VALUES(?, ?, ?)", "INSERT INTO numeric_score_votes(image_id, user_id, score) VALUES(:imageid, :userid, :score)",
array($image_id, $user_id, $score)); array("imageid" => $image_id, "userid" => $user_id, "score" => $score));
} }
$database->Execute( $database->Execute(
"UPDATE images SET numeric_score=(SELECT SUM(score) FROM numeric_score_votes WHERE image_id=?) WHERE id=?", "UPDATE images SET numeric_score=(SELECT SUM(score) FROM numeric_score_votes WHERE image_id=:imageid) WHERE id=:id",
array($image_id, $image_id)); array("imageid" => $image_id, "id" => $image_id));
} }
} }
?> ?>

View File

@ -67,8 +67,8 @@ class NumericScoreTheme extends Themelet {
'</span>'; '</span>';
} }
$b_dte = make_link("popular_by_".$dte[3]."/".date($dte[2], (strtotime('-1 '.$dte[3], strtotime($dte[0]))))); $b_dte = make_link("popular_by_".$dte[3]."?".date($dte[2], (strtotime('-1 '.$dte[3], strtotime($dte[0])))));
$f_dte = make_link("popular_by_".$dte[3]."/".date($dte[2], (strtotime('+1 '.$dte[3], strtotime($dte[0]))))); $f_dte = make_link("popular_by_".$dte[3]."?".date($dte[2], (strtotime('+1 '.$dte[3], strtotime($dte[0])))));
$html = '<center><h3><a href="'.$b_dte.'">&laquo;</a> '.$dte[1] $html = '<center><h3><a href="'.$b_dte.'">&laquo;</a> '.$dte[1]
.' <a href="'.$f_dte.'">&raquo;</a>' .' <a href="'.$f_dte.'">&raquo;</a>'

24
contrib/pm/main.php Normal file → Executable file
View File

@ -93,13 +93,13 @@ class PrivMsg extends SimpleExtension {
switch($event->get_arg(0)) { switch($event->get_arg(0)) {
case "read": case "read":
$pm_id = int_escape($event->get_arg(1)); $pm_id = int_escape($event->get_arg(1));
$pm = $database->get_row("SELECT * FROM private_message WHERE id = ?", array($pm_id)); $pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", array("id" => $pm_id));
if(is_null($pm)) { if(is_null($pm)) {
$this->theme->display_error($page, "No such PM", "There is no PM #$pm_id"); $this->theme->display_error($page, "No such PM", "There is no PM #$pm_id");
} }
else if(($pm["to_id"] == $user->id) || $user->is_admin()) { else if(($pm["to_id"] == $user->id) || $user->is_admin()) {
$from_user = User::by_id(int_escape($pm["from_id"])); $from_user = User::by_id(int_escape($pm["from_id"]));
$database->get_row("UPDATE private_message SET is_read='Y' WHERE id = ?", array($pm_id)); $database->get_row("UPDATE private_message SET is_read='Y' WHERE id = :id", array("id" => $pm_id));
$this->theme->display_message($page, $from_user, $user, new PM($pm)); $this->theme->display_message($page, $from_user, $user, new PM($pm));
} }
else { else {
@ -109,12 +109,12 @@ class PrivMsg extends SimpleExtension {
case "delete": case "delete":
if($user->check_auth_token()) { if($user->check_auth_token()) {
$pm_id = int_escape($_POST["pm_id"]); $pm_id = int_escape($_POST["pm_id"]);
$pm = $database->get_row("SELECT * FROM private_message WHERE id = ?", array($pm_id)); $pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", array("id" => $pm_id));
if(is_null($pm)) { if(is_null($pm)) {
$this->theme->display_error($page, "No such PM", "There is no PM #$pm_id"); $this->theme->display_error($page, "No such PM", "There is no PM #$pm_id");
} }
else if(($pm["to_id"] == $user->id) || $user->is_admin()) { else if(($pm["to_id"] == $user->id) || $user->is_admin()) {
$database->execute("DELETE FROM private_message WHERE id = ?", array($pm_id)); $database->execute("DELETE FROM private_message WHERE id = :id", array("id" => $pm_id));
log_info("pm", "Deleted PM #$pm_id"); log_info("pm", "Deleted PM #$pm_id");
$page->set_mode("redirect"); $page->set_mode("redirect");
$page->set_redirect($_SERVER["HTTP_REFERER"]); $page->set_redirect($_SERVER["HTTP_REFERER"]);
@ -146,9 +146,9 @@ class PrivMsg extends SimpleExtension {
INSERT INTO private_message( INSERT INTO private_message(
from_id, from_ip, to_id, from_id, from_ip, to_id,
sent_date, subject, message) sent_date, subject, message)
VALUES(?, ?, ?, now(), ?, ?)", VALUES(:fromid, :fromip, :toid, now(), :subject, :message)",
array($event->pm->from_id, $event->pm->from_ip, array("fromid" => $event->pm->from_id, "fromip" => $event->pm->from_ip,
$event->pm->to_id, $event->pm->subject, $event->pm->message) "toid" => $event->pm->to_id, "subject" => $event->pm->subject, "message" => $event->pm->message)
); );
log_info("pm", "Sent PM to User #{$event->pm->to_id}"); log_info("pm", "Sent PM to User #{$event->pm->to_id}");
} }
@ -158,11 +158,11 @@ class PrivMsg extends SimpleExtension {
global $database; global $database;
$arr = $database->get_all(" $arr = $database->get_all("
SELECT private_message.*,user_from.name AS from_name SELECT private_message.*,user_from.name AS from_name
FROM private_message FROM private_message
JOIN users AS user_from ON user_from.id=from_id JOIN users AS user_from ON user_from.id=from_id
WHERE to_id = ? WHERE to_id = :toid",
", array($user->id)); array("toid" => $user->id));
$pms = array(); $pms = array();
foreach($arr as $pm) { foreach($arr as $pm) {
$pms[] = new PM($pm); $pms[] = new PM($pm);

View File

@ -2,7 +2,26 @@
class RandomImageTheme extends Themelet { class RandomImageTheme extends Themelet {
public function display_random(Page $page, Image $image) { public function display_random(Page $page, Image $image) {
$page->add_block(new Block("Random Image", $this->build_thumb_html($image), "left", 8)); $page->add_block(new Block("Random Image", $this->build_random_html($image), "left", 8));
}
public function build_random_html(Image $image, $query=null) {
global $config;
$i_id = int_escape($image->id);
$h_view_link = make_link("post/view/$i_id", $query);
$h_thumb_link = $image->get_thumb_link();
$h_tip = html_escape($image->get_tooltip());
$tsize = get_thumbnail_size($image->width, $image->height);
return "
<center><div>
<a href='$h_view_link' style='position: relative; height: {$tsize[1]}px; width: {$tsize[0]}px;'>
<img id='thumb_$i_id' title='$h_tip' alt='$h_tip' class='highlighted' style='height: {$tsize[1]}px; width: {$tsize[0]}px;' src='$h_thumb_link'>
</a>
</div></center>
";
} }
} }
?> ?>

View File

@ -114,7 +114,8 @@ class Ratings implements Extension {
if(preg_match("/^rating=([sqeu]+)$/", $event->term, $matches)) { if(preg_match("/^rating=([sqeu]+)$/", $event->term, $matches)) {
$sqes = $matches[1]; $sqes = $matches[1];
$arr = array(); $arr = array();
for($i=0; $i<strlen($sqes); $i++) { $length = strlen($sqes);
for($i=0; $i<$length; $i++) {
$arr[] = "'" . $sqes[$i] . "'"; $arr[] = "'" . $sqes[$i] . "'";
} }
$set = join(', ', $arr); $set = join(', ', $arr);
@ -157,7 +158,8 @@ class Ratings implements Extension {
public static function privs_to_sql($sqes) { public static function privs_to_sql($sqes) {
$arr = array(); $arr = array();
for($i=0; $i<strlen($sqes); $i++) { $length = strlen($sqes);
for($i=0; $i<$length; $i++) {
$arr[] = "'" . $sqes[$i] . "'"; $arr[] = "'" . $sqes[$i] . "'";
} }
$set = join(', ', $arr); $set = join(', ', $arr);

View File

@ -106,7 +106,7 @@ class SimpleUrl {
} }
if (preg_match('/^([^\/]*)@(.*)/', $url, $matches)) { if (preg_match('/^([^\/]*)@(.*)/', $url, $matches)) {
$url = $prefix . $matches[2]; $url = $prefix . $matches[2];
$parts = split(":", $matches[1]); $parts = explode(":", $matches[1]);
return array( return array(
urldecode($parts[0]), urldecode($parts[0]),
isset($parts[1]) ? urldecode($parts[1]) : false); isset($parts[1]) ? urldecode($parts[1]) : false);

View File

@ -190,7 +190,7 @@ class HttpHeaderExpectation extends SimpleExpectation {
* @access protected * @access protected
*/ */
function _findHeader($compare) { function _findHeader($compare) {
$lines = split("\r\n", $compare); $lines = explode("\r\n", $compare);
foreach ($lines as $line) { foreach ($lines as $line) {
if ($this->_testHeaderLine($line)) { if ($this->_testHeaderLine($line)) {
return $line; return $line;
@ -206,7 +206,7 @@ class HttpHeaderExpectation extends SimpleExpectation {
* @access private * @access private
*/ */
function _testHeaderLine($line) { function _testHeaderLine($line) {
if (count($parsed = split(':', $line, 2)) < 2) { if (count($parsed = explode(':', $line, 2)) < 2) {
return false; return false;
} }
list($header, $value) = $parsed; list($header, $value) = $parsed;
@ -1538,4 +1538,4 @@ class WebTestCase extends SimpleTestCase {
return $trace->traceMethod(); return $trace->traceMethod();
} }
} }
?> ?>

View File

@ -5,72 +5,69 @@
* Description: Keep a record of tag changes, and allows you to revert changes. * Description: Keep a record of tag changes, and allows you to revert changes.
*/ */
class Tag_History implements Extension { class Tag_History extends SimpleExtension {
var $theme;
// in before tags are actually set, so that "get current tags" works // in before tags are actually set, so that "get current tags" works
public function get_priority() {return 40;} public function get_priority() {return 40;}
public function receive_event(Event $event) { public function onInitExtEvent($event) {
global $config, $database, $page, $user; global $config;
if(is_null($this->theme)) $this->theme = get_theme_object($this); $config->set_default_int("history_limit", -1);
if(($event instanceof InitExtEvent)) { // shimmie is being installed so call install to create the table.
$config->set_default_int("history_limit", -1); if($config->get_int("ext_tag_history_version") < 3) {
$this->install();
// shimmie is being installed so call install to create the table.
if($config->get_int("ext_tag_history_version") < 3) {
$this->install();
}
} }
}
if(($event instanceof AdminBuildingEvent))
{ public function onAdminBuildingEvent($event) {
if(isset($_POST['revert_ip']) && $user->is_admin() && $user->check_auth_token()) global $user;
{
$revert_ip = filter_var($_POST['revert_ip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE); if(isset($_POST['revert_ip']) && $user->is_admin() && $user->check_auth_token()) {
$revert_ip = filter_var($_POST['revert_ip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE);
if ($revert_ip === false) {
// invalid ip given. if ($revert_ip === false) {
$this->theme->display_admin_block('Invalid IP'); // invalid ip given.
$this->theme->display_admin_block('Invalid IP');
return;
}
if (isset($_POST['revert_date']) && !empty($_POST['revert_date'])) {
if (isValidDate($_POST['revert_date'])){
$revert_date = addslashes($_POST['revert_date']); // addslashes is really unnecessary since we just checked if valid, but better safe.
} else {
$this->theme->display_admin_block('Invalid Date');
return; return;
} }
if (isset($_POST['revert_date']) && !empty($_POST['revert_date'])) {
if (isValidDate($_POST['revert_date'])){
$revert_date = addslashes($_POST['revert_date']); // addslashes is really unnecessary since we just checked if valid, but better safe.
} else {
$this->theme->display_admin_block('Invalid Date');
return;
}
} else {
$revert_date = null;
}
set_time_limit(0); // reverting changes can take a long time, disable php's timelimit if possible.
// Call the revert function.
$this->process_revert_all_changes_by_ip($revert_ip, $revert_date);
// output results
$this->theme->display_revert_ip_results();
} }
else else {
{ $revert_date = null;
$this->theme->display_admin_block(); // add a block to the admin panel
} }
set_time_limit(0); // reverting changes can take a long time, disable php's timelimit if possible.
// Call the revert function.
$this->process_revert_all_changes_by_ip($revert_ip, $revert_date);
// output results
$this->theme->display_revert_ip_results();
} }
else {
$this->theme->display_admin_block(); // add a block to the admin panel
}
}
if (($event instanceof PageRequestEvent) && ($event->page_matches("tag_history"))) public function onPageRequest($event) {
{ global $config, $page, $user;
if($event->get_arg(0) == "revert")
{ if ($event->page_matches("tag_history")) {
if($event->get_arg(0) == "revert") {
// this is a request to revert to a previous version of the tags // this is a request to revert to a previous version of the tags
if($config->get_bool("tag_edit_anon") || !$user->is_anonymous()) { if($config->get_bool("tag_edit_anon") || !$user->is_anonymous()) {
$this->process_revert_request($_POST['revert']); if(isset($_POST['revert'])) {
$this->process_revert_request($_POST['revert']);
}
} }
} }
else if($event->count_args() == 1) else if($event->count_args() == 1) {
{
// must be an attempt to view a tag history // must be an attempt to view a tag history
$image_id = int_escape($event->get_arg(0)); $image_id = int_escape($event->get_arg(0));
$this->theme->display_history_page($page, $image_id, $this->get_tag_history_from_id($image_id)); $this->theme->display_history_page($page, $image_id, $this->get_tag_history_from_id($image_id));
@ -79,32 +76,36 @@ class Tag_History implements Extension {
$this->theme->display_global_page($page, $this->get_global_tag_history()); $this->theme->display_global_page($page, $this->get_global_tag_history());
} }
} }
}
if(($event instanceof DisplayingImageEvent))
{ public function onDisplayingImage($event) {
// handle displaying a link on the view page global $page;
$this->theme->display_history_link($page, $event->image->id); // handle displaying a link on the view page
} $this->theme->display_history_link($page, $event->image->id);
if(($event instanceof ImageDeletionEvent)) }
{
// handle removing of history when an image is deleted public function onImageDeletion($event) {
$this->delete_all_tag_history($event->image->id); // handle removing of history when an image is deleted
} $this->delete_all_tag_history($event->image->id);
if(($event instanceof SetupBuildingEvent)) { }
$sb = new SetupBlock("Tag History");
$sb->add_label("Limit to "); public function onSetupBuilding($event) {
$sb->add_int_option("history_limit"); $sb = new SetupBlock("Tag History");
$sb->add_label(" entires per image"); $sb->add_label("Limit to ");
$sb->add_label("<br>(-1 for unlimited)"); $sb->add_int_option("history_limit");
$event->panel->add_block($sb); $sb->add_label(" entires per image");
} $sb->add_label("<br>(-1 for unlimited)");
if(($event instanceof TagSetEvent)) { $event->panel->add_block($sb);
$this->add_tag_history($event->image, $event->tags); }
}
if($event instanceof UserBlockBuildingEvent) { public function onTagSetEvent($event) {
if($user->is_admin()) { $this->add_tag_history($event->image, $event->tags);
$event->add_link("Tag Changes", make_link("tag_history")); }
}
public function onUserBlockBuilding($event) {
global $user;
if($user->is_admin()) {
$event->add_link("Tag Changes", make_link("tag_history"));
} }
} }
@ -250,6 +251,18 @@ class Tag_History implements Extension {
return ($row ? $row : array()); return ($row ? $row : array());
} }
/* This doesn't actually get _ALL_ IPs as it limits to 1000. */
public function get_all_user_ips()
{
global $database;
$row = $database->get_all("
SELECT DISTINCT user_ip
FROM tag_histories
ORDER BY tag_histories.user_ip DESC
LIMIT 1000");
return ($row ? $row : array());
}
/* /*
* This function attempts to revert all changes by a given IP within an (optional) timeframe. * This function attempts to revert all changes by a given IP within an (optional) timeframe.
*/ */

178
contrib/update/main.php Normal file
View File

@ -0,0 +1,178 @@
<?php
/**
* Name: Update
* Author: DakuTree <dakutree@codeanimu.net>
* Link: http://www.codeanimu.net
* License: GPLv2
* Description: Shimmie updater!
*/
class Update extends SimpleExtension {
public function onInitExt(Event $event) {
global $config;
$config->set_default_string("update_url", "http://nodeload.github.com/shish/shimmie2/zipball/master"); //best to avoid using https
$config->set_default_string("commit_hash", "");
}
public function onSetupBuilding($event) {
global $config;
//Would prefer to use the admin panel for this.
//But since the admin panel is optional...kind of stuck to using this.
$sb = new SetupBlock("Update");
$sb->position = 75;
$sb->add_label("Current Commit: ".$config->get_string('commit_hash'));
$sb->add_text_option("update_url", "<br>Update URL: ");
$sb->add_label("<br><a href='".make_link('update')."'>Update</a>");
$event->panel->add_block($sb);
}
public function onPageRequest(Event $event) {
global $config, $user;
if($event->page_matches("update") && $user->is_admin()) {
$ok = $this->update_shimmie();
}
}
private function update_shimmie() {
global $config, $page;
//This is a REALLY ugly function. (Damn my limited PHP knowledge >_<)
$html = "";
$url = $config->get_string("update_url");
$mfile = "master.zip";
if(glob("*-shimmie2*")){ //#3
$dir = glob("*-shimmie2*");
preg_match('@^([a-zA-Z0-9]+\-[0-9a-z]+\-)([^/]+)@i', $dir[0], $matches);
if(!empty($matches[2])){
$html .= "commit: ".$matches[2];
$commit = $matches[2];
mkdir("./backup");
$html .= "<br>backup folder created!";
$d_dir = "data/cache";
//This should empty the /data/cache/ folder.
if (is_dir($d_dir)) {
$objects = scandir($d_dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($d_dir."/".$object) == "dir") rmdir($d_dir."/".$object); else unlink($d_dir."/".$object);
}
}
reset($objects);
$html .= "<br>data folder emptied!";
}
copy ("./config.php", "./backup/config.php");//Although this stays the same, will keep backup just incase.
//FIXME: Somehow get rid of this massive rename list.
rename ("./core", "./backup/core");
rename ("./".$matches[0]."/core", "./core");
rename ("./lib", "./backup/lib");
rename ("./".$matches[0]."/lib", "./lib");
rename ("./themes", "./backup/themes");
rename ("./".$matches[0]."/themes", "./themes");
rename ("./.htaccess", "./backup/.htaccess");
rename ("./".$matches[0]."/.htaccess", "./.htaccess");
rename ("./doxygen.conf", "./backup/doxygen.conf");
rename ("./".$matches[0]."/doxygen.conf", "./doxygen.conf");
rename ("./index.php", "./backup/index.php");
rename ("./".$matches[0]."/index.php", "./index.php");
rename ("./install.php", "./backup/install.php");
rename ("./".$matches[0]."/install.php", "./install.php");
rename ("./ext", "./backup/ext");
rename ("./".$matches[0]."/ext", "./ext");
rename ("./contrib", "./backup/contrib");
rename ("./".$matches[0]."/contrib", "./contrib");
$html .= "<br>old shimmie setup has been moved to /backup/ (excluding images/thumbs)!";
if (is_dir($matches[0])) {
$objects = scandir($matches[0]);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($matches[0]."/".$object) == "dir") rmdir($matches[0]."/".$object); else unlink($matches[0]."/".$object);
}
}
reset($objects);
rmdir($matches[0]);
$html .= "<br>".$matches[0]." deleted!";
}
$html .= "<br>shimmie updated (although you may have gotten errors, it should have worked!";
$html .= "<br>due to the way shimmie loads extensions, all optional extensions have been disabled";
$config->set_string("commit_hash", $commit);
$html .= "<br>new commit_hash has been set!";
}else{
$html .= "Error! Folder does not exist!?"; //Although this should be impossible, shall have it anyway.
}
}elseif (file_exists($mfile)){ //#2
$zip = new ZipArchive;
if ($zip->open($mfile) === TRUE) {
$zip->extractTo('./');
$zip->close();
$html .= "extracted!";
$html .= "<br><a href='javascript:history.go(0)'>refresh</a> the page to continue!";
unlink($mfile); //Deletes master.zip
} else {
$html .= "failed!";
}
}else{ //#1
//Taken from the upload ext.
if($config->get_string("transload_engine") == "curl" && function_exists("curl_init")) {
$ch = curl_init($url);
$fp = fopen($mfile, "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_USERAGENT, "Shimmie-".VERSION);
curl_exec($ch);
curl_close($ch);
fclose($fp);
if(file_exists($mfile)){
$html .= "downloaded!";
$html .= "<br><a href='javascript:history.go(0)'>refresh</a> the page to continue!";
}else{
$html .= "download failed!";
$html .= "<br><a href='javascript:history.go(0)'>refresh</a> to try again!";
$html .= "<br>if you keep having this problem, you may have a problem with your transload engine!";
}
}elseif($config->get_string("transload_engine") == "wget") {
//this doesn't work?
$s_url = escapeshellarg($url);
system("wget $s_url --output-document=$mfile");
if(file_exists($mfile)){
$html .= "downloaded!";
$html .= "<br><a href='javascript:history.go(0)'>refresh</a> the page to continue!";
}else{
$html .= "download failed!";
$html .= "<br><a href='javascript:history.go(0)'>refresh</a> to try again!";
$html .= "<br>if you keep having this problem, you may have a problem with your transload engine!";
}
}elseif($config->get_string("transload_engine") == "fopen") {
$fp = @fopen($url, "r");
if(!$fp) {
return false;
}
$data = "";
$length = 0;
while(!feof($fp) && $length <= $config->get_int('upload_size')) {
$data .= fread($fp, 8192);
$length = strlen($data);
}
fclose($fp);
$fp = fopen($mfile, "w");
fwrite($fp, $data);
fclose($fp);
if(file_exists($mfile)){
$html .= "downloaded!";
$html .= "<br><a href='javascript:history.go(0)'>refresh</a> the page to continue!";
}else{
$html .= "download failed!";
$html .= "<br><a href='javascript:history.go(0)'>refresh</a> to try again!";
$html .= "<br>if you keep having this problem, you may have a problem with your transload engine!";
}
}elseif($config->get_string("transload_engine") == "none"){
$html .= "no transload engine set!";
}
}
$page->add_block(new Block("Update", $html));
}
}
?>

View File

@ -6,21 +6,20 @@
* Description: Simple search and replace * Description: Simple search and replace
*/ */
class WordFilter implements Extension { class WordFilter extends SimpleExtension {
// before emoticon filter // before emoticon filter
public function get_priority() {return 40;} public function get_priority() {return 40;}
public function receive_event(Event $event) { public function onTextFormatting($event) {
if($event instanceof TextFormattingEvent) { $event->formatted = $this->filter($event->formatted);
$event->formatted = $this->filter($event->formatted); $event->stripped = $this->filter($event->stripped);
$event->stripped = $this->filter($event->stripped); }
}
if(($event instanceof SetupBuildingEvent)) { public function onSetupBuilding($event) {
$sb = new SetupBlock("Word Filter"); $sb = new SetupBlock("Word Filter");
$sb->add_longtext_option("word_filter"); $sb->add_longtext_option("word_filter");
$sb->add_label("<br>(each line should be search term and replace term, separated by a comma)"); $sb->add_label("<br>(each line should be search term and replace term, separated by a comma)");
$event->panel->add_block($sb); $event->panel->add_block($sb);
}
} }
private function filter($text) { private function filter($text) {

View File

@ -1,95 +0,0 @@
<?php
/**
* Functions which are only in some versions of PHP,
* or only implemented on some platforms
*
* \privatesection
*/
# (PHP 5 >= 5.2.1)
# Based on http://www.phpit.net/
# article/creating-zip-tar-archives-dynamically-php/2/
if(!function_exists('sys_get_temp_dir')) {
function sys_get_temp_dir() {
// Try to get from environment variable
if(!empty($_ENV['TMP'])) {
return realpath($_ENV['TMP']);
}
else if(!empty($_ENV['TMPDIR'])) {
return realpath($_ENV['TMPDIR']);
}
else if(!empty($_ENV['TEMP'])) {
return realpath($_ENV['TEMP']);
}
// Detect by creating a temporary file
else {
// Try to use system's temporary directory
// as random name shouldn't exist
$temp_file = tempnam(md5(uniqid(rand(), TRUE)), '');
if($temp_file) {
$temp_dir = realpath(dirname($temp_file));
unlink($temp_file);
return $temp_dir;
}
else {
return FALSE;
}
}
}
}
# (PHP >= 5.1)
# from http://www.php.net/inet_pton
if(!function_exists('inet_pton')) {
function inet_pton($ip) {
# ipv4
if(strpos($ip, '.') !== FALSE) {
$ip = pack('N',ip2long($ip));
}
# ipv6
else if(strpos($ip, ':') !== FALSE) {
$ip = explode(':', $ip);
$res = str_pad('', (4*(8-count($ip))), '0000', STR_PAD_LEFT);
foreach($ip as $seg) {
$res .= str_pad($seg, 4, '0', STR_PAD_LEFT);
}
$ip = pack('H'.strlen($res), $res);
}
return $ip;
}
}
# (PHP >= 5.1)
# from http://www.php.net/inet_ntop
if(!function_exists('inet_ntop')) {
function inet_ntop($ip) {
if (strlen($ip)==4) {
// ipv4
list(,$ip)=unpack('N',$ip);
$ip=long2ip($ip);
} elseif(strlen($ip)==16) {
// ipv6
$ip=bin2hex($ip);
$ip=substr(chunk_split($ip,4,':'),0,-1);
$ip=explode(':',$ip);
$res='';
foreach($ip as $seg) {
while($seg{0}=='0') $seg=substr($seg,1);
if ($seg!='') {
$res.=($res==''?'':':').$seg;
} else {
if (strpos($res,'::')===false) {
if (substr($res,-1)==':') continue;
$res.=':';
continue;
}
$res.=($res==''?'':':').'0';
}
}
$ip=$res;
}
return $ip;
}
}
?>

View File

@ -1,6 +1,4 @@
<?php <?php
require_once "compat.inc.php";
/** @privatesection */ /** @privatesection */
// Querylet {{{ // Querylet {{{
class Querylet { class Querylet {
@ -56,7 +54,7 @@ class DBEngine {
} }
public function create_table_sql($name, $data) { public function create_table_sql($name, $data) {
return "CREATE TABLE $name ($data)"; return 'CREATE TABLE '.$name.' ('.$data.')';
} }
} }
class MySQL extends DBEngine { class MySQL extends DBEngine {
@ -82,12 +80,16 @@ class MySQL extends DBEngine {
public function create_table_sql($name, $data) { public function create_table_sql($name, $data) {
$data = $this->scoreql_to_sql($data); $data = $this->scoreql_to_sql($data);
$ctes = "ENGINE=InnoDB DEFAULT CHARSET='utf8'"; $ctes = "ENGINE=InnoDB DEFAULT CHARSET='utf8'";
return "CREATE TABLE $name ($data) $ctes"; return 'CREATE TABLE '.$name.' ('.$data.') '.$ctes;
} }
} }
class PostgreSQL extends DBEngine { class PostgreSQL extends DBEngine {
var $name = "pgsql"; var $name = "pgsql";
public function init($db) {
$db->query("SET application_name TO 'shimmie [{$_SERVER['REMOTE_ADDR']}]';");
}
public function scoreql_to_sql($data) { public function scoreql_to_sql($data) {
$data = str_replace("SCORE_AIPK", "SERIAL PRIMARY KEY", $data); $data = str_replace("SCORE_AIPK", "SERIAL PRIMARY KEY", $data);
$data = str_replace("SCORE_INET", "INET", $data); $data = str_replace("SCORE_INET", "INET", $data);
@ -103,7 +105,7 @@ class PostgreSQL extends DBEngine {
public function create_table_sql($name, $data) { public function create_table_sql($name, $data) {
$data = $this->scoreql_to_sql($data); $data = $this->scoreql_to_sql($data);
return "CREATE TABLE $name ($data)"; return 'CREATE TABLE '.$name.' ('.$data.')';
} }
} }
@ -151,14 +153,14 @@ class SQLite extends DBEngine {
$matches = array(); $matches = array();
if(preg_match("/INDEX\s*\((.*)\)/", $bit, $matches)) { if(preg_match("/INDEX\s*\((.*)\)/", $bit, $matches)) {
$col = $matches[1]; $col = $matches[1];
$extras .= "CREATE INDEX {$name}_{$col} on $name($col);"; $extras .= 'CREATE INDEX '.$name.'_'.$col.' on '.$name($col).';';
} }
else { else {
$cols[] = $bit; $cols[] = $bit;
} }
} }
$cols_redone = implode(", ", $cols); $cols_redone = implode(", ", $cols);
return "CREATE TABLE $name ($cols_redone); $extras"; return 'CREATE TABLE '.$name.' ('.$cols_redone.'); '.$extras;
} }
} }
// }}} // }}}
@ -183,7 +185,7 @@ class MemcacheCache implements CacheEngine {
var $memcache=null, $hits=0, $misses=0; var $memcache=null, $hits=0, $misses=0;
public function __construct($args) { public function __construct($args) {
$hp = split(":", $args); $hp = explode(":", $args);
if(class_exists("Memcache")) { if(class_exists("Memcache")) {
$this->memcache = new Memcache; $this->memcache = new Memcache;
@$this->memcache->pconnect($hp[0], $hp[1]); @$this->memcache->pconnect($hp[0], $hp[1]);
@ -286,23 +288,25 @@ class Database {
if(preg_match("/user=([^;]*)/", DATABASE_DSN, $matches)) $db_user=$matches[1]; if(preg_match("/user=([^;]*)/", DATABASE_DSN, $matches)) $db_user=$matches[1];
if(preg_match("/password=([^;]*)/", DATABASE_DSN, $matches)) $db_pass=$matches[1]; if(preg_match("/password=([^;]*)/", DATABASE_DSN, $matches)) $db_pass=$matches[1];
$this->db = new PDO(DATABASE_DSN, $db_user, $db_pass, array( $db_params = array(
PDO::ATTR_PERSISTENT => true, PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
)); );
if(defined("HIPHOP")) $this->db = new PDO(DATABASE_DSN, $db_user, $db_pass);
else $this->db = new PDO(DATABASE_DSN, $db_user, $db_pass, $db_params);
$db_proto = $this->db->getAttribute(PDO::ATTR_DRIVER_NAME); $db_proto = $this->db->getAttribute(PDO::ATTR_DRIVER_NAME);
if($db_proto == "mysql") { if($db_proto === "mysql") {
$this->engine = new MySQL(); $this->engine = new MySQL();
} }
else if($db_proto == "pgsql") { else if($db_proto === "pgsql") {
$this->engine = new PostgreSQL(); $this->engine = new PostgreSQL();
} }
else if($db_proto == "sqlite") { else if($db_proto === "sqlite") {
$this->engine = new SQLite(); $this->engine = new SQLite();
} }
else { else {
die("Unknown PDO driver: $db_proto"); die('Unknown PDO driver: '.$db_proto);
} }
$matches = array(); $matches = array();
@ -326,14 +330,15 @@ class Database {
*/ */
public function execute($query, $args=array()) { public function execute($query, $args=array()) {
try { try {
_count_execs($this->db, $query, $args);
$stmt = $this->db->prepare($query); $stmt = $this->db->prepare($query);
if (!array_key_exists(0, $args)) { if (!array_key_exists(0, $args)) {
foreach($args as $name=>$value) { foreach($args as $name=>$value) {
if(is_numeric($value)) { if(is_numeric($value)) {
$stmt->bindValue(":$name", $value, PDO::PARAM_INT); $stmt->bindValue(':'.$name, $value, PDO::PARAM_INT);
} }
else { else {
$stmt->bindValue(":$name", $value, PDO::PARAM_STR); $stmt->bindValue(':'.$name, $value, PDO::PARAM_STR);
} }
} }
$stmt->execute(); $stmt->execute();
@ -344,8 +349,8 @@ class Database {
return $stmt; return $stmt;
} }
catch(PDOException $pdoe) { catch(PDOException $pdoe) {
print "Message: ".$pdoe->getMessage(); print 'Message: '.$pdoe->getMessage();
print "<p>Error: $query"; print '<p>Error: '.$query;
exit; exit;
} }
} }

View File

@ -0,0 +1,21 @@
<?php
// to change these system-level settings, do define("FOO", 123); in config.php
function _d($name, $value) {if(!defined($name)) define($name, $value);}
_d("DATABASE_DSN", null); // string PDO database connection details
_d("CACHE_DSN", null); // string cache connection details
_d("DEBUG", false); // boolean print various debugging details
_d("DEBUG_SQL", false); // boolean dump SQL queries to data/sql.log
_d("COVERAGE", false); // boolean activate xdebug coverage monitor
_d("CONTEXT", null); // string file to log performance data into
_d("CACHE_MEMCACHE", false); // boolean store complete rendered pages in memcache
_d("CACHE_DIR", false); // boolean store complete rendered pages on disk
_d("CACHE_HTTP", false); // boolean output explicit HTTP caching headers
_d("COOKIE_PREFIX", 'shm'); // string if you run multiple galleries with non-shared logins, give them different prefixes
_d("SPEED_HAX", false); // boolean do some questionable things in the name of performance
_d("COMPILE_ELS", false); // boolean pre-build the list of event listeners
_d("NICE_URLS", false); // boolean force niceurl mode
_d("WH_SPLITS", 1); // int how many levels of subfolders to put in the warehouse
_d("VERSION", 'trunk'); // string shimmie version
_d("SCORE_VERSION", 's2hack/'.VERSION); // string SCore version
_d("TIMEZONE", null); // string timezone
?>

119
core/email.class.php Normal file
View File

@ -0,0 +1,119 @@
<?php
class Email {
/**
* A generic email.
*/
var $to;
var $subject;
var $header;
var $style;
var $header_img;
var $sitename;
var $sitedomain;
var $siteemail;
var $date;
var $body;
var $footer;
public function __construct($to, $subject, $header, $body) {
global $config;
$this->to = $to;
$sub_prefix = $config->get_string("mail_sub");
if(!isset($sub_prefix)){
$this->subject = $subject;
}
else{
$this->subject = $sub_prefix." ".$subject;
}
$this->style = $config->get_string("mail_style");
$this->header = html_escape($header);
$this->header_img = $config->get_string("mail_img");
$this->sitename = $config->get_string("site_title");
$this->sitedomain = make_http(make_link(""));
$this->siteemail = $config->get_string("site_email");
$this->date = date("F j, Y");
$this->body = $body;
$this->footer = $config->get_string("mail_fot");
}
public function send() {
$headers = "From: ".$this->sitename." <".$this->siteemail.">\r\n";
$headers .= "Reply-To: ".$this->siteemail."\r\n";
$headers .= "X-Mailer: PHP/" . phpversion(). "\r\n";
$headers .= "errors-to: ".$this->siteemail."\r\n";
$headers .= "Date: " . date(DATE_RFC2822);
$headers .= 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$message = '
<html>
<head>
<link rel="stylesheet" href="'.$this->style.'" type="text/css">
</head>
<body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0" bgcolor="#EEEEEE" >
<table width="100%" cellpadding="10" cellspacing="0" class="backgroundTable" bgcolor="#EEEEEE" >
<tr>
<td valign="top" align="center">
<table width="550" cellpadding="0" cellspacing="0">
<tr>
<td style="background-color:#FFFFFF;border-top:0px solid #333333;border-bottom:10px solid #FFFFFF;"><center><a href="'.$this->sitedomain.'"><IMG SRC="'.$this->header_img.'" alt="'.$this->sitename.'" name="Header" BORDER="0" align="center" title="'.$this->sitename.'"></a>
</center></td>
</tr>
</table>
<table width="550" cellpadding="20" cellspacing="0" bgcolor="#FFFFFF">
<tr>
<td bgcolor="#FFFFFF" valign="top" style="font-size:12px;color:#000000;line-height:150%;font-family:trebuchet ms;">
<p>
<span style="font-size:20px; font-weight:bold; color:#3399FF; font-family:arial; line-height:110%;">'.$this->header.'</span><br>
<span style="font-size:11px;font-weight:normal;color:#666666;font-style:italic;font-family:arial;">'.$this->date.'</span><br>
</p>
<p>'.$this->body.'</p>
<p>'.$this->footer.'</p>
</td>
</tr>
<tr>
<td style="background-color:#FFFFCC;border-top:10px solid #FFFFFF;" valign="top">
<span style="font-size:10px;color:#996600;line-height:100%;font-family:verdana;">
This email was sent to you since you are a member of <a href="'.$this->sitedomain.'">'.$this->sitename.'</a>. To change your email preferences, visit your <a href="'.make_http(make_link("preferences")).'">Account preferences</a>.<br />
<br />
Contact us:<br />
<a href="'.$this->siteemail.'">'.$this->siteemail.'</a><br /><br />
Copyright (C) <a href="'.$this->sitedomain.'">'.$this->sitename.'</a><br />
</span></td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
';
$sent = mail($this->to, $this->subject, $message, $headers);
if($sent){
log_info("mail", "Sent message '$this->subject' to '$this->to'");
}
else{
log_info("mail", "Error sending message '$this->subject' to '$this->to'");
}
return $sent;
}
}
?>

View File

@ -68,7 +68,7 @@ class PageRequestEvent extends Event {
} }
public function count_args() { public function count_args() {
return $this->arg_count - $this->part_count; return (int)($this->arg_count - $this->part_count);
} }
/* /*
@ -76,20 +76,20 @@ class PageRequestEvent extends Event {
*/ */
public function get_search_terms() { public function get_search_terms() {
$search_terms = array(); $search_terms = array();
if($this->count_args() == 2) { if($this->count_args() === 2) {
$search_terms = explode(' ', $this->get_arg(0)); $search_terms = explode(' ', $this->get_arg(0));
} }
return $search_terms; return $search_terms;
} }
public function get_page_number() { public function get_page_number() {
$page_number = 1; $page_number = 1;
if($this->count_args() == 1) { if($this->count_args() === 1) {
$page_number = int_escape($this->get_arg(0)); $page_number = int_escape($this->get_arg(0));
} }
else if($this->count_args() == 2) { else if($this->count_args() === 2) {
$page_number = int_escape($this->get_arg(1)); $page_number = int_escape($this->get_arg(1));
} }
if($page_number == 0) $page_number = 1; // invalid -> 0 if($page_number === 0) $page_number = 1; // invalid -> 0
return $page_number; return $page_number;
} }
public function get_page_size() { public function get_page_size() {

View File

@ -92,6 +92,9 @@ abstract class SimpleExtension implements Extension {
var $theme; var $theme;
var $_child; var $_child;
// in PHP5.3, late static bindings can take care of this; __CLASS__
// used here will refer to the subclass
// http://php.net/manual/en/language.oop5.late-static-bindings.php
public function i_am(Extension $child) { public function i_am(Extension $child) {
$this->_child = $child; $this->_child = $child;
if(is_null($this->theme)) $this->theme = get_theme_object($child, false); if(is_null($this->theme)) $this->theme = get_theme_object($child, false);

View File

@ -27,6 +27,8 @@ $tag_n = 0; // temp hack
$_flexihash = null; $_flexihash = null;
$_fh_last_opts = null; $_fh_last_opts = null;
require_once "lib/flexihash.php";
/** /**
* An object representing an entry in the images table. As of 2.2, this no * An object representing an entry in the images table. As of 2.2, this no
* longer necessarily represents an image per se, but could be a video, * longer necessarily represents an image per se, but could be a video,
@ -196,12 +198,12 @@ class Image {
} }
if(count($tags) == 0) { if(count($tags) == 0) {
$row = $database->get_row("SELECT images.* FROM images WHERE images.id $gtlt {$this->id} ORDER BY images.id $dir LIMIT 1"); $row = $database->get_row('SELECT images.* FROM images WHERE images.id '.$gtlt.' '.$this->id.' ORDER BY images.id '.$dir.' LIMIT 1');
} }
else { else {
$tags[] = "id$gtlt{$this->id}"; $tags[] = 'id'. $gtlt . $this->id;
$querylet = Image::build_search_querylet($tags); $querylet = Image::build_search_querylet($tags);
$querylet->append_sql(" ORDER BY images.id $dir LIMIT 1"); $querylet->append_sql(' ORDER BY images.id '.$dir.' LIMIT 1');
$row = $database->get_row($querylet->sql, $querylet->variables); $row = $database->get_row($querylet->sql, $querylet->variables);
} }
@ -251,8 +253,14 @@ class Image {
*/ */
public function get_image_link() { public function get_image_link() {
global $config; global $config;
if(strlen($config->get_string('image_ilink')) > 0) {
return $this->parse_link_template($config->get_string('image_ilink')); $image_ilink = $config->get_string('image_ilink'); // store a copy for speed.
if( !empty($image_ilink) ) { /* empty is faster than strlen */
if(!startsWith($image_ilink, "http://") && !startsWith($image_ilink, "/")) {
$image_ilink = make_link($image_ilink);
}
return $this->parse_link_template($image_ilink);
} }
else if($config->get_bool('nice_urls', false)) { else if($config->get_bool('nice_urls', false)) {
return $this->parse_link_template(make_link('_images/$hash/$id - $tags.$ext')); return $this->parse_link_template(make_link('_images/$hash/$id - $tags.$ext'));
@ -280,8 +288,14 @@ class Image {
*/ */
public function get_thumb_link() { public function get_thumb_link() {
global $config; global $config;
if(strlen($config->get_string('image_tlink')) > 0) {
return $this->parse_link_template($config->get_string('image_tlink')); $image_tlink = $config->get_string('image_tlink'); // store a copy for speed.
if( !empty($image_tlink) ) { /* empty is faster than strlen */
if(!startsWith($image_tlink, "http://") && !startsWith($image_tlink, "/")) {
$image_tlink = make_link($image_tlink);
}
return $this->parse_link_template($image_tlink);
} }
else if($config->get_bool('nice_urls', false)) { else if($config->get_bool('nice_urls', false)) {
return $this->parse_link_template(make_link('_thumbs/$hash/thumb.jpg')); return $this->parse_link_template(make_link('_thumbs/$hash/thumb.jpg'));
@ -338,8 +352,8 @@ class Image {
*/ */
public function get_mime_type() { public function get_mime_type() {
$type = strtolower($this->ext); $type = strtolower($this->ext);
if($type == "jpg") $type = "jpeg"; if($type === "jpg") $type = "jpeg";
return "image/$type"; return 'image/'.$type;
} }
/** /**
@ -379,7 +393,7 @@ class Image {
public function set_locked($tf) { public function set_locked($tf) {
global $database; global $database;
$ln = $tf ? "Y" : "N"; $ln = $tf ? "Y" : "N";
$sln = $database->engine->scoreql_to_sql("SCORE_BOOL_$ln"); $sln = $database->engine->scoreql_to_sql('SCORE_BOOL_'.$ln);
$sln = str_replace("'", "", $sln); $sln = str_replace("'", "", $sln);
$sln = str_replace('"', "", $sln); $sln = str_replace('"', "", $sln);
if($sln != $this->locked) { if($sln != $this->locked) {
@ -458,7 +472,7 @@ class Image {
global $database; global $database;
$this->delete_tags_from_image(); $this->delete_tags_from_image();
$database->execute("DELETE FROM images WHERE id=:id", array("id"=>$this->id)); $database->execute("DELETE FROM images WHERE id=:id", array("id"=>$this->id));
log_info("core-image", "Deleted Image #{$this->id} ({$this->hash})"); log_info("core-image", 'Deleted Image #'.$this->id.' ('.$this->hash.')');
unlink($this->get_image_filename()); unlink($this->get_image_filename());
unlink($this->get_thumb_filename()); unlink($this->get_thumb_filename());
@ -469,7 +483,7 @@ class Image {
* It DOES NOT remove anything from the database. * It DOES NOT remove anything from the database.
*/ */
public function remove_image_only() { public function remove_image_only() {
log_info("core-image", "Removed Image File ({$this->hash})"); log_info("core-image", 'Removed Image File ('.$this->hash.')');
@unlink($this->get_image_filename()); @unlink($this->get_image_filename());
@unlink($this->get_thumb_filename()); @unlink($this->get_thumb_filename());
} }
@ -522,7 +536,6 @@ class Image {
if($opts != $_fh_last_opts) { if($opts != $_fh_last_opts) {
$_fh_last_opts = $opts; $_fh_last_opts = $opts;
require_once("lib/flexihash.php");
$_flexihash = new Flexihash(); $_flexihash = new Flexihash();
foreach(explode(",", $opts) as $opt) { foreach(explode(",", $opts) as $opt) {
$parts = explode("=", $opt); $parts = explode("=", $opt);
@ -550,7 +563,7 @@ class Image {
private static function build_search_querylet($terms) { private static function build_search_querylet($terms) {
assert(is_array($terms)); assert(is_array($terms));
global $database; global $database;
if($database->engine->name == "mysql") if($database->engine->name === "mysql")
return Image::build_ugly_search_querylet($terms); return Image::build_ugly_search_querylet($terms);
else else
return Image::build_accurate_search_querylet($terms); return Image::build_accurate_search_querylet($terms);
@ -593,7 +606,7 @@ class Image {
// various types of querylet // various types of querylet
foreach($terms as $term) { foreach($terms as $term) {
$positive = true; $positive = true;
if(strlen($term) > 0 && $term[0] == '-') { if(is_string($term) && !empty($term) && ($term[0] == '-')) {
$positive = false; $positive = false;
$term = substr($term, 1); $term = substr($term, 1);
} }
@ -641,7 +654,7 @@ class Image {
if(count($tag_querylets) == 0) { if(count($tag_querylets) == 0) {
$query = new Querylet("SELECT images.* FROM images "); $query = new Querylet("SELECT images.* FROM images ");
if(strlen($img_search->sql) > 0) { if(!empty($img_search->sql)) {
$query->append_sql(" WHERE "); $query->append_sql(" WHERE ");
$query->append($img_search); $query->append($img_search);
} }
@ -658,7 +671,7 @@ class Image {
) )
"), array("tag"=>$tag_querylets[0]->tag)); "), array("tag"=>$tag_querylets[0]->tag));
if(strlen($img_search->sql) > 0) { if(!empty($img_search->sql)) {
$query->append_sql(" AND "); $query->append_sql(" AND ");
$query->append($img_search); $query->append($img_search);
} }
@ -760,7 +773,7 @@ class Image {
// turn each term into a specific type of querylet // turn each term into a specific type of querylet
foreach($terms as $term) { foreach($terms as $term) {
$negative = false; $negative = false;
if((strlen($term) > 0) && ($term[0] == '-')) { if( !empty($term) && ($term[0] == '-')) {
$negative = true; $negative = true;
$term = substr($term, 1); $term = substr($term, 1);
} }
@ -789,11 +802,13 @@ class Image {
foreach($tag_querylets as $tq) { foreach($tag_querylets as $tq) {
global $tag_n; global $tag_n;
$sign = $tq->positive ? "+" : "-"; $sign = $tq->positive ? "+" : "-";
$sql .= " $sign (tag LIKE :tag$tag_n)"; //$sql .= " $sign (tag LIKE :tag$tag_n)";
$terms["tag$tag_n"] = $tq->tag; $sql .= ' '.$sign.' (tag LIKE :tag'.$tag_n.')';
//$terms["tag$tag_n"] = $tq->tag;
$terms['tag'.$tag_n] = $tq->tag;
$tag_n++; $tag_n++;
if($sign == "+") $positive_tag_count++; if($sign === "+") $positive_tag_count++;
else $negative_tag_count++; else $negative_tag_count++;
} }
$tag_search = new Querylet($sql, $terms); $tag_search = new Querylet($sql, $terms);
@ -815,14 +830,14 @@ class Image {
if($positive_tag_count + $negative_tag_count == 0) { if($positive_tag_count + $negative_tag_count == 0) {
$query = new Querylet("SELECT images.*,UNIX_TIMESTAMP(posted) AS posted_timestamp FROM images "); $query = new Querylet("SELECT images.*,UNIX_TIMESTAMP(posted) AS posted_timestamp FROM images ");
if(strlen($img_search->sql) > 0) { if(!empty($img_search->sql)) {
$query->append_sql(" WHERE "); $query->append_sql(" WHERE ");
$query->append($img_search); $query->append($img_search);
} }
} }
// one positive tag (a common case), do an optimised search // one positive tag (a common case), do an optimised search
else if($positive_tag_count == 1 && $negative_tag_count == 0) { else if($positive_tag_count === 1 && $negative_tag_count === 0) {
$query = new Querylet( $query = new Querylet(
// MySQL is braindead, and does a full table scan on images, running the subquery once for each row -_- // MySQL is braindead, and does a full table scan on images, running the subquery once for each row -_-
// "{$this->get_images} WHERE images.id IN (SELECT image_id FROM tags WHERE tag LIKE ?) ", // "{$this->get_images} WHERE images.id IN (SELECT image_id FROM tags WHERE tag LIKE ?) ",
@ -836,7 +851,7 @@ class Image {
", ",
$tag_search->variables); $tag_search->variables);
if(strlen($img_search->sql) > 0) { if(!empty($img_search->sql)) {
$query->append_sql(" AND "); $query->append_sql(" AND ");
$query->append($img_search); $query->append($img_search);
} }
@ -858,24 +873,24 @@ class Image {
if($tags_ok) { if($tags_ok) {
$tag_id_list = join(', ', $tag_id_array); $tag_id_list = join(', ', $tag_id_array);
$subquery = new Querylet(" $subquery = new Querylet('
SELECT images.*, SUM({$tag_search->sql}) AS score SELECT images.*, SUM('.$tag_search->sql.') AS score
FROM images FROM images
LEFT JOIN image_tags ON image_tags.image_id = images.id LEFT JOIN image_tags ON image_tags.image_id = images.id
JOIN tags ON image_tags.tag_id = tags.id JOIN tags ON image_tags.tag_id = tags.id
WHERE tags.id IN ({$tag_id_list}) WHERE tags.id IN ('.$tag_id_list.')
GROUP BY images.id GROUP BY images.id
HAVING score = :score", HAVING score = :score',
array_merge( array_merge(
$tag_search->variables, $tag_search->variables,
array("score"=>$positive_tag_count) array("score"=>$positive_tag_count)
) )
); );
$query = new Querylet(" $query = new Querylet('
SELECT *, UNIX_TIMESTAMP(posted) AS posted_timestamp SELECT *, UNIX_TIMESTAMP(posted) AS posted_timestamp
FROM ({$subquery->sql}) AS images ", $subquery->variables); FROM ('.$subquery->sql.') AS images ', $subquery->variables);
if(strlen($img_search->sql) > 0) { if(!empty($img_search->sql)) {
$query->append_sql(" WHERE "); $query->append_sql(" WHERE ");
$query->append($img_search); $query->append($img_search);
} }
@ -921,15 +936,15 @@ class Tag {
if(is_string($tags)) { if(is_string($tags)) {
$tags = explode(' ', $tags); $tags = explode(' ', $tags);
} }
else if(is_array($tags)) { //else if(is_array($tags)) {
// do nothing // do nothing
} //}
$tags = array_map("trim", $tags); $tags = array_map("trim", $tags);
$tag_array = array(); $tag_array = array();
foreach($tags as $tag) { foreach($tags as $tag) {
if(is_string($tag) && strlen($tag) > 0) { if(is_string($tag) && !empty($tag)) {
$tag_array[] = $tag; $tag_array[] = $tag;
} }
} }
@ -946,13 +961,13 @@ class Tag {
public static function implode($tags) { public static function implode($tags) {
assert(is_string($tags) || is_array($tags)); assert(is_string($tags) || is_array($tags));
if(is_string($tags)) { if(is_array($tags)) {
// do nothing
}
else if(is_array($tags)) {
sort($tags); sort($tags);
$tags = implode(' ', $tags); $tags = implode(' ', $tags);
} }
//else if(is_string($tags)) {
// do nothing
//}
return $tags; return $tags;
} }

View File

@ -225,8 +225,8 @@ class Page {
print $this->data; print $this->data;
break; break;
case "redirect": case "redirect":
header("Location: {$this->redirect}"); header('Location: '.$this->redirect);
print "You should be redirected to <a href='{$this->redirect}'>{$this->redirect}</a>"; print 'You should be redirected to <a href="'.$this->redirect.'">'.$this->redirect.'</a>';
break; break;
default: default:
print "Invalid page mode"; print "Invalid page mode";
@ -242,22 +242,22 @@ class Page {
// caching failed, add all files to html_headers. // caching failed, add all files to html_headers.
foreach(glob("lib/*.css") as $css) { foreach(glob("lib/*.css") as $css) {
$this->add_html_header("<link rel='stylesheet' href='$data_href/$css' type='text/css'>"); $this->add_html_header('<link rel="stylesheet" href="'.$data_href.'/'.$css.'" type="text/css">');
} }
$css_files = glob("ext/*/style.css"); $css_files = glob("ext/*/style.css");
if($css_files) { if($css_files) {
foreach($css_files as $css_file) { foreach($css_files as $css_file) {
$this->add_html_header("<link rel='stylesheet' href='$data_href/$css_file' type='text/css'>"); $this->add_html_header('<link rel="stylesheet" href="'.$data_href.'/'.$css_file.'" type="text/css">');
} }
} }
foreach(glob("lib/*.js") as $js) { foreach(glob("lib/*.js") as $js) {
$this->add_html_header("<script src='$data_href/$js' type='text/javascript'></script>"); $this->add_html_header('<script src="'.$data_href.'/'.$js.'" type="text/javascript"></script>');
} }
$js_files = glob("ext/*/script.js"); $js_files = glob("ext/*/script.js");
if($js_files) { if($js_files) {
foreach($js_files as $js_file) { foreach($js_files as $js_file) {
$this->add_html_header("<script src='$data_href/$js_file' type='text/javascript'></script>"); $this->add_html_header('<script src="'.$data_href.'/'.$js_file.'" type="text/javascript"></script>');
} }
} }
} }
@ -358,16 +358,16 @@ class Page {
} }
} }
// tell the client where to get the css cache file // tell the client where to get the css cache file
$this->add_html_header('<link rel="stylesheet" href="'.$data_href.'/'.$cache_location.$md5sum.'.css'.'" type="text/css">'); $this->add_html_header('<link rel="stylesheet" href="'.$data_href.'/'.$cache_location.$md5sum.'.css" type="text/css">');
} else { } else {
// Caching of CSS disabled. // Caching of CSS disabled.
foreach(glob("lib/*.css") as $css) { foreach(glob("lib/*.css") as $css) {
$this->add_html_header("<link rel='stylesheet' href='$data_href/$css' type='text/css'>"); $this->add_html_header('<link rel="stylesheet" href="'.$data_href.'/'.$css.'" type="text/css">');
} }
$css_files = glob("ext/*/style.css"); $css_files = glob("ext/*/style.css");
if($css_files) { if($css_files) {
foreach($css_files as $css_file) { foreach($css_files as $css_file) {
$this->add_html_header("<link rel='stylesheet' href='$data_href/$css_file' type='text/css'>"); $this->add_html_header('<link rel="stylesheet" href="'.$data_href.'/'.$css_file.'" type="text/css">');
} }
} }
} }
@ -408,16 +408,16 @@ class Page {
} }
} }
// tell the client where to get the js cache file // tell the client where to get the js cache file
$this->add_html_header('<script src="'.$data_href.'/'.$cache_location.$md5sum.'.js'.'" type="text/javascript"></script>'); $this->add_html_header('<script src="'.$data_href.'/'.$cache_location.$md5sum.'.js" type="text/javascript"></script>');
} else { } else {
// Caching of Javascript disabled. // Caching of Javascript disabled.
foreach(glob("lib/*.js") as $js) { foreach(glob("lib/*.js") as $js) {
$this->add_html_header("<script src='$data_href/$js' type='text/javascript'></script>"); $this->add_html_header('<script src="'.$data_href.'/'.$js.'" type="text/javascript"></script>');
} }
$js_files = glob("ext/*/script.js"); $js_files = glob("ext/*/script.js");
if($js_files) { if($js_files) {
foreach($js_files as $js_file) { foreach($js_files as $js_file) {
$this->add_html_header("<script src='$data_href/$js_file' type='text/javascript'></script>"); $this->add_html_header('<script src="'.$data_href.'/'.$js_file.'" type="text/javascript"></script>');
} }
} }
} }

View File

@ -40,7 +40,7 @@ class User {
public static function by_session(/*string*/ $name, /*string*/ $session) { public static function by_session(/*string*/ $name, /*string*/ $session) {
global $config, $database; global $config, $database;
if($database->engine->name == "mysql") { if($database->engine->name === "mysql") {
$query = "SELECT * FROM users WHERE name = :name AND md5(concat(pass, :ip)) = :sess"; $query = "SELECT * FROM users WHERE name = :name AND md5(concat(pass, :ip)) = :sess";
} }
else { else {
@ -53,12 +53,12 @@ class User {
public static function by_id(/*int*/ $id) { public static function by_id(/*int*/ $id) {
assert(is_numeric($id)); assert(is_numeric($id));
global $database; global $database;
if($id == 1) { if($id === 1) {
$cached = $database->cache->get("user-id:$id"); $cached = $database->cache->get('user-id:'.$id);
if($cached) return new User($cached); if($cached) return new User($cached);
} }
$row = $database->get_row("SELECT * FROM users WHERE id = :id", array("id"=>$id)); $row = $database->get_row("SELECT * FROM users WHERE id = :id", array("id"=>$id));
if($id == 1) $database->cache->set("user-id:$id", $row, 300); if($id === 1) $database->cache->set('user-id:'.$id, $row, 300);
return is_null($row) ? null : new User($row); return is_null($row) ? null : new User($row);
} }
@ -98,7 +98,7 @@ class User {
*/ */
public function is_anonymous() { public function is_anonymous() {
global $config; global $config;
return ($this->id == $config->get_int('anon_id')); return ($this->id === $config->get_int('anon_id'));
} }
/** /**
@ -108,7 +108,7 @@ class User {
*/ */
public function is_logged_in() { public function is_logged_in() {
global $config; global $config;
return ($this->id != $config->get_int('anon_id')); return ($this->id !== $config->get_int('anon_id'));
} }
/** /**
@ -125,20 +125,20 @@ class User {
global $database; global $database;
$yn = $admin ? 'Y' : 'N'; $yn = $admin ? 'Y' : 'N';
$database->Execute("UPDATE users SET admin=:yn WHERE id=:id", array("yn"=>$yn, "id"=>$this->id)); $database->Execute("UPDATE users SET admin=:yn WHERE id=:id", array("yn"=>$yn, "id"=>$this->id));
log_info("core-user", "Made {$this->name} admin=$yn"); log_info("core-user", 'Made '.$this->name.' admin='.$yn);
} }
public function set_password(/*string*/ $password) { public function set_password(/*string*/ $password) {
global $database; global $database;
$hash = md5(strtolower($this->name) . $password); $hash = md5(strtolower($this->name) . $password);
$database->Execute("UPDATE users SET pass=:hash WHERE id=:id", array("hash"=>$hash, "id"=>$this->id)); $database->Execute("UPDATE users SET pass=:hash WHERE id=:id", array("hash"=>$hash, "id"=>$this->id));
log_info("core-user", "Set password for {$this->name}"); log_info("core-user", 'Set password for '.$this->name);
} }
public function set_email(/*string*/ $address) { public function set_email(/*string*/ $address) {
global $database; global $database;
$database->Execute("UPDATE users SET email=:email WHERE id=:id", array("email"=>$address, "id"=>$this->id)); $database->Execute("UPDATE users SET email=:email WHERE id=:id", array("email"=>$address, "id"=>$this->id));
log_info("core-user", "Set email for {$this->name}"); log_info("core-user", 'Set email for '.$this->name);
} }
/** /**
@ -148,7 +148,7 @@ class User {
public function get_avatar_html() { public function get_avatar_html() {
// FIXME: configurable // FIXME: configurable
global $config; global $config;
if($config->get_string("avatar_host") == "gravatar") { if($config->get_string("avatar_host") === "gravatar") {
if(!empty($this->email)) { if(!empty($this->email)) {
$hash = md5(strtolower($this->email)); $hash = md5(strtolower($this->email));
$s = $config->get_string("avatar_gravatar_size"); $s = $config->get_string("avatar_gravatar_size");
@ -173,14 +173,14 @@ class User {
*/ */
public function get_auth_token() { public function get_auth_token() {
global $config; global $config;
$salt = file_get_contents("config.php"); $salt = DATABASE_DSN;
$addr = get_session_ip($config); $addr = get_session_ip($config);
return md5(md5($this->passhash . $addr) . "salty-csrf-" . $salt); return md5(md5($this->passhash . $addr) . "salty-csrf-" . $salt);
} }
public function get_auth_html() { public function get_auth_html() {
$at = $this->get_auth_token(); $at = $this->get_auth_token();
return "<input type='hidden' name='auth_token' value='$at'>"; return '<input type="hidden" name="auth_token" value="'.$at.'">';
} }
public function check_auth_token() { public function check_auth_token() {

View File

@ -21,6 +21,10 @@ function html_escape($input) {
* @retval int * @retval int
*/ */
function int_escape($input) { function int_escape($input) {
/*
Side note, Casting to an integer is FASTER than using intval.
http://hakre.wordpress.com/2010/05/13/php-casting-vs-intval/
*/
return (int)$input; return (int)$input;
} }
@ -56,13 +60,13 @@ function sql_escape($input) {
function bool_escape($input) { function bool_escape($input) {
$input = strtolower($input); $input = strtolower($input);
return ( return (
$input == "y" || $input === "y" ||
$input == "yes" || $input === "yes" ||
$input == "t" || $input === "t" ||
$input == "true" || $input === "true" ||
$input == "on" || $input === "on" ||
$input == 1 || $input === 1 ||
$input == true $input === true
); );
} }
@ -86,7 +90,7 @@ function parse_shorthand_int($limit) {
return (int)$limit; return (int)$limit;
} }
if(preg_match('/^([\d\.]+)([gmk])?b?$/i', "$limit", $m)) { if(preg_match('/^([\d\.]+)([gmk])?b?$/i', (string)$limit, $m)) {
$value = $m[1]; $value = $m[1];
if (isset($m[2])) { if (isset($m[2])) {
switch(strtolower($m[2])) { switch(strtolower($m[2])) {
@ -118,7 +122,7 @@ function to_shorthand_int($int) {
return sprintf("%.1fKB", $int / 1024); return sprintf("%.1fKB", $int / 1024);
} }
else { else {
return "$int"; return (string)$int;
} }
} }
@ -186,6 +190,17 @@ function undb_bool($val) {
if($val === false || $val == 'N' || $val == 'n' || $val == 'F' || $val == 'f' || $val === 0) return false; if($val === false || $val == 'N' || $val == 'n' || $val == 'F' || $val == 'f' || $val === 0) return false;
} }
function startsWith($haystack, $needle) {
$length = strlen($needle);
return (substr($haystack, 0, $length) === $needle);
}
function endsWith($haystack, $needle) {
$length = strlen($needle);
$start = $length * -1; //negative
return (substr($haystack, $start) === $needle);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* HTML Generation * * HTML Generation *
@ -207,24 +222,24 @@ function make_link($page=null, $query=null) {
if(NICE_URLS || $config->get_bool('nice_urls', false)) { if(NICE_URLS || $config->get_bool('nice_urls', false)) {
#$full = "http://" . $_SERVER["SERVER_NAME"] . $_SERVER["PHP_SELF"]; #$full = "http://" . $_SERVER["SERVER_NAME"] . $_SERVER["PHP_SELF"];
$full = $_SERVER["PHP_SELF"]; $full = $_SERVER["PHP_SELF"];
$base = str_replace("/index.php", "", $full); $base = str_replace("/".basename($_SERVER["SCRIPT_FILENAME"]), "", $full);
} }
else { else {
$base = "./index.php?q="; $base = "./".basename($_SERVER["SCRIPT_FILENAME"])."?q=";
} }
if(is_null($query)) { if(is_null($query)) {
return str_replace("//", "/", "$base/$page"); return str_replace("//", "/", $base.'/'.$page );
} }
else { else {
if(strpos($base, "?")) { if(strpos($base, "?")) {
return "$base/$page&$query"; return $base .'/'. $page .'&'. $query;
} }
else if(strpos($query, "#") === 0) { else if(strpos($query, "#") === 0) {
return "$base/$page$query"; return $base .'/'. $page . $query;
} }
else { else {
return "$base/$page?$query"; return $base .'/'. $page .'?'. $query;
} }
} }
} }
@ -293,14 +308,14 @@ function make_http(/*string*/ $link) {
function make_form($target, $method="POST", $multipart=False, $form_id="", $onsubmit="") { function make_form($target, $method="POST", $multipart=False, $form_id="", $onsubmit="") {
global $user; global $user;
$auth = $user->get_auth_html(); $auth = $user->get_auth_html();
$extra = empty($form_id) ? '' : " id='$form_id'"; $extra = empty($form_id) ? '' : 'id="'. $form_id .'"';
if($multipart) { if($multipart) {
$extra .= " enctype='multipart/form-data'"; $extra .= " enctype='multipart/form-data'";
} }
if($onsubmit) { if($onsubmit) {
$extra .= " onsubmit='$onsubmit'"; $extra .= ' onsubmit="'.$onsubmit.'"';
} }
return "<form action='$target' method='$method'$extra>$auth"; return '<form action="'.$target.'" method="'.$method.'" '.$extra.'>'.$auth;
} }
/** /**
@ -310,7 +325,7 @@ function make_form($target, $method="POST", $multipart=False, $form_id="", $onsu
function theme_file($filepath) { function theme_file($filepath) {
global $config; global $config;
$theme = $config->get_string("theme","default"); $theme = $config->get_string("theme","default");
return make_link("themes/$theme/$filepath"); return make_link('themes/'.$theme.'/'.$filepath);
} }
@ -381,11 +396,11 @@ function captcha_check() {
* @private * @private
*/ */
function _version_check() { function _version_check() {
if(version_compare(PHP_VERSION, "5.0.0") == -1) { if(version_compare(PHP_VERSION, "5.2.6") == -1) {
print " print "
Currently SCore Engine doesn't support versions of PHP lower than 5.0.0 -- Currently SCore Engine doesn't support versions of PHP lower than 5.2.6 --
PHP4 and earlier are officially dead according to their creators, if your web host is running an older version, they are dangerously out of
please tell your host to upgrade. date and you should plan on moving elsewhere.
"; ";
exit; exit;
} }
@ -409,10 +424,10 @@ function check_cli() {
*/ */
function _count_execs($db, $sql, $inputarray) { function _count_execs($db, $sql, $inputarray) {
global $_execs; global $_execs;
if(DEBUG) { if((DEBUG_SQL === true) || (is_null(DEBUG_SQL) && @$_GET['DEBUG_SQL'])) {
$fp = @fopen("data/sql.log", "a"); $fp = @fopen("data/sql.log", "a");
if($fp) { if($fp) {
if(is_array($inputarray)) { if(isset($inputarray) && is_array($inputarray)) {
fwrite($fp, preg_replace('/\s+/msi', ' ', $sql)." -- ".join(", ", $inputarray)."\n"); fwrite($fp, preg_replace('/\s+/msi', ' ', $sql)." -- ".join(", ", $inputarray)."\n");
} }
else { else {
@ -443,12 +458,12 @@ function _count_execs($db, $sql, $inputarray) {
*/ */
function get_theme_object(Extension $class, $fatal=true) { function get_theme_object(Extension $class, $fatal=true) {
$base = get_class($class); $base = get_class($class);
if(class_exists("Custom{$base}Theme")) { if(class_exists('Custom'.$base.'Theme')) {
$class = "Custom{$base}Theme"; $class = 'Custom'.$base.'Theme';
return new $class(); return new $class();
} }
elseif ($fatal || class_exists("{$base}Theme")) { elseif ($fatal || class_exists($base.'Theme')) {
$class = "{$base}Theme"; $class = $base.'Theme';
return new $class(); return new $class();
} else { } else {
return false; return false;
@ -552,14 +567,14 @@ function get_base_href() {
$possible_vars = array('SCRIPT_NAME', 'PHP_SELF', 'PATH_INFO', 'ORIG_PATH_INFO'); $possible_vars = array('SCRIPT_NAME', 'PHP_SELF', 'PATH_INFO', 'ORIG_PATH_INFO');
$ok_var = null; $ok_var = null;
foreach($possible_vars as $var) { foreach($possible_vars as $var) {
if(substr($_SERVER[$var], -4) == '.php') { if(substr($_SERVER[$var], -4) === '.php') {
$ok_var = $_SERVER[$var]; $ok_var = $_SERVER[$var];
break; break;
} }
} }
assert(!empty($ok_var)); assert(!empty($ok_var));
$dir = dirname($ok_var); $dir = dirname($ok_var);
if($dir == "/" || $dir == "\\") $dir = ""; if($dir === "/" || $dir === "\\") $dir = "";
return $dir; return $dir;
} }
@ -579,10 +594,10 @@ function warehouse_path(/*string*/ $base, /*string*/ $hash, /*bool*/ $create=tru
$ab = substr($hash, 0, 2); $ab = substr($hash, 0, 2);
$cd = substr($hash, 2, 2); $cd = substr($hash, 2, 2);
if(WH_SPLITS == 2) { if(WH_SPLITS == 2) {
$pa = "$base/$ab/$cd/$hash"; $pa = $base.'/'.$ab.'/'.$cd.'/'.$hash;
} }
else { else {
$pa = "$base/$ab/$hash"; $pa = $base.'/'.$ab.'/'.$hash;
} }
if($create && !file_exists(dirname($pa))) mkdir(dirname($pa), 0755, true); if($create && !file_exists(dirname($pa))) mkdir(dirname($pa), 0755, true);
return $pa; return $pa;
@ -841,6 +856,12 @@ function get_debug_info() {
else { else {
$i_mem = "???"; $i_mem = "???";
} }
if($config->get_string("commit_hash") == ""){
$commit = "";
}else{
$commit = " (".$config->get_string("commit_hash").")";
}
$time = sprintf("%5.2f", microtime(true) - $_load_start); $time = sprintf("%5.2f", microtime(true) - $_load_start);
$i_files = count(get_included_files()); $i_files = count(get_included_files());
$hits = $database->cache->get_hits(); $hits = $database->cache->get_hits();
@ -850,7 +871,7 @@ function get_debug_info() {
$debug .= "; Used $i_files files and $_execs queries"; $debug .= "; Used $i_files files and $_execs queries";
$debug .= "; Sent $_event_count events"; $debug .= "; Sent $_event_count events";
$debug .= "; $hits cache hits and $miss misses"; $debug .= "; $hits cache hits and $miss misses";
$debug .= "; Shimmie version ". VERSION; // .", SCore Version ". SCORE_VERSION; $debug .= "; Shimmie version ". VERSION . $commit; // .", SCore Version ". SCORE_VERSION;
return $debug; return $debug;
} }
@ -914,6 +935,10 @@ function _stripslashes_r($arr) {
} }
function _sanitise_environment() { function _sanitise_environment() {
if(TIMEZONE) {
date_default_timezone_set(TIMEZONE);
}
if(DEBUG) { if(DEBUG) {
error_reporting(E_ALL); error_reporting(E_ALL);
} }
@ -930,6 +955,120 @@ function _sanitise_environment() {
} }
} }
function _get_themelet_files($_theme) {
$themelets = array();
if(file_exists('themes/'.$_theme.'/custompage.class.php')) $themelets[] = 'themes/'.$_theme.'/custompage.class.php';
$themelets[] = 'themes/'.$_theme.'/layout.class.php';
$themelets[] = 'themes/'.$_theme.'/themelet.class.php';
$themelet_files = glob("ext/*/theme.php");
foreach($themelet_files as $filename) {
$themelets[] = $filename;
}
$custom_themelets = glob('themes/'.$_theme.'/*.theme.php');
if($custom_themelets) {
$m = array();
foreach($custom_themelets as $filename) {
if(preg_match('/themes\/'.$_theme.'\/(.*)\.theme\.php/',$filename,$m)
&& in_array('ext/'.$m[1].'/theme.php', $themelets)) {
$themelets[] = $filename;
}
}
}
return $themelets;
}
function _load_extensions() {
global $_event_listeners;
ctx_log_start("Loading extensions");
if(COMPILE_ELS && file_exists("data/event_listeners.php")) {
require_once("data/event_listeners.php");
}
else {
$all_events = array();
foreach(get_declared_classes() as $class) {
if(is_subclass_of($class, "Event")) {
$all_events[] = $class;
}
}
foreach(get_declared_classes() as $class) {
$rclass = new ReflectionClass($class);
if($rclass->isAbstract()) {
// don't do anything
}
elseif(is_subclass_of($class, "SimpleExtension")) {
$c = new $class();
$c->i_am($c);
$my_events = array();
foreach(get_class_methods($c) as $method) {
if(substr($method, 0, 2) == "on") {
$my_events[] = substr($method, 2) . "Event";
}
}
add_event_listener($c, $c->get_priority(), $my_events);
}
elseif(is_subclass_of($class, "Extension")) {
$c = new $class();
add_event_listener($c, $c->get_priority(), $all_events);
}
}
if(COMPILE_ELS) {
$p = "<"."?php\n";
foreach(get_declared_classes() as $class) {
$rclass = new ReflectionClass($class);
if($rclass->isAbstract()) {}
elseif(is_subclass_of($class, "SimpleExtension")) {
$p .= "\$$class = new $class(); ";
$p .= "\${$class}->i_am(\$$class);\n";
}
elseif(is_subclass_of($class, "Extension")) {
$p .= "\$$class = new $class();\n";
}
}
$p .= "\$_event_listeners = array(\n";
foreach($_event_listeners as $event => $listeners) {
$p .= "\t'$event' => array(\n";
foreach($listeners as $id => $listener) {
$p .= "\t\t$id => \$".get_class($listener).",\n";
}
$p .= "\t),\n";
}
$p .= ");\n";
$p .= "?".">";
file_put_contents("data/event_listeners.php", $p);
}
}
ctx_log_endok();
}
function _fatal_error(Exception $e) {
$version = VERSION;
$message = $e->getMessage();
//$trace = var_dump($e->getTrace());
header("HTTP/1.0 500 Internal Error");
echo '
<html>
<head>
<title>Internal error - SCore-'.$version.'</title>
</head>
<body>
<h1>Internal Error</h1>
<p>'.$message.'
</body>
</html>
';
}
/** /**
* Turn ^^ into ^ and ^s into / * Turn ^^ into ^ and ^s into /
* *
@ -938,7 +1077,8 @@ function _sanitise_environment() {
*/ */
function _decaret($str) { function _decaret($str) {
$out = ""; $out = "";
for($i=0; $i<strlen($str); $i++) { $length = strlen($str);
for($i=0; $i<$length; $i++) {
if($str[$i] == "^") { if($str[$i] == "^") {
$i++; $i++;
if($str[$i] == "^") $out .= "^"; if($str[$i] == "^") $out .= "^";
@ -985,7 +1125,7 @@ function _get_page_request() {
global $config; global $config;
$args = _get_query_parts(); $args = _get_query_parts();
if(count($args) == 0 || strlen($args[0]) == 0) { if(empty($args) || strlen($args[0]) === 0) {
$args = explode('/', $config->get_string('front_page')); $args = explode('/', $config->get_string('front_page'));
} }
@ -1074,7 +1214,7 @@ function _start_cache() {
} }
else { else {
header("Content-type: text/html"); header("Content-type: text/html");
header("Last-Modified: $gmdate_mod"); header('Last-Modified: '.$gmdate_mod);
$zdata = @file_get_contents($_cache_filename); $zdata = @file_get_contents($_cache_filename);
if(CACHE_MEMCACHE) { if(CACHE_MEMCACHE) {
$_cache_memcache->set($_cache_hash, $zdata, 0, 600); $_cache_memcache->set($_cache_hash, $zdata, 0, 600);
@ -1119,11 +1259,14 @@ function _start_coverage() {
function _end_coverage() { function _end_coverage() {
if(function_exists("xdebug_get_code_coverage")) { if(function_exists("xdebug_get_code_coverage")) {
if(!file_exists("data/coverage")) mkdir("data/coverage"); // Absolute path is necessary because working directory
// inside register_shutdown_function is unpredictable.
$absolute_path = dirname(dirname(__FILE__)) . "/data/coverage";
if(!file_exists($absolute_path)) mkdir($absolute_path);
$n = 0; $n = 0;
$t = time(); $t = time();
while(file_exists("data/coverage/$t.$n.log")) $n++; while(file_exists("$absolute_path/$t.$n.log")) $n++;
file_put_contents("data/coverage/$t.$n.log", serialize(xdebug_get_code_coverage())); file_put_contents("$absolute_path/$t.$n.log", serialize(xdebug_get_code_coverage()));
} }
} }
?> ?>

10
ext/alias_editor/main.php Normal file → Executable file
View File

@ -45,7 +45,7 @@ class AliasEditor extends SimpleExtension {
else if($event->get_arg(0) == "remove") { else if($event->get_arg(0) == "remove") {
if($user->is_admin()) { if($user->is_admin()) {
if(isset($_POST['oldtag'])) { if(isset($_POST['oldtag'])) {
$database->Execute("DELETE FROM aliases WHERE oldtag=?", array($_POST['oldtag'])); $database->execute("DELETE FROM aliases WHERE oldtag=:oldtag", array("oldtag" => $_POST['oldtag']));
log_info("alias_editor", "Deleted alias for ".$_POST['oldtag']); log_info("alias_editor", "Deleted alias for ".$_POST['oldtag']);
$page->set_mode("redirect"); $page->set_mode("redirect");
@ -103,12 +103,12 @@ class AliasEditor extends SimpleExtension {
public function onAddAlias(AddAliasEvent $event) { public function onAddAlias(AddAliasEvent $event) {
global $database; global $database;
$pair = array($event->oldtag, $event->newtag); $pair = array("oldtag" => $event->oldtag, "newtag" => $event->newtag);
if($database->get_row("SELECT * FROM aliases WHERE oldtag=? AND lower(newtag)=lower(?)", $pair)) { if($database->get_row("SELECT * FROM aliases WHERE oldtag=:oldtag AND lower(newtag)=lower(:newtag)", $pair)) {
throw new AddAliasException("That alias already exists"); throw new AddAliasException("That alias already exists");
} }
else { else {
$database->Execute("INSERT INTO aliases(oldtag, newtag) VALUES(?, ?)", $pair); $database->execute("INSERT INTO aliases(oldtag, newtag) VALUES(:oldtag, :newtag)", $pair);
log_info("alias_editor", "Added alias for {$event->oldtag} -> {$event->newtag}"); log_info("alias_editor", "Added alias for {$event->oldtag} -> {$event->newtag}");
} }
} }
@ -134,7 +134,7 @@ class AliasEditor extends SimpleExtension {
foreach(explode("\n", $csv) as $line) { foreach(explode("\n", $csv) as $line) {
$parts = explode(",", $line); $parts = explode(",", $line);
if(count($parts) == 2) { if(count($parts) == 2) {
$database->execute("INSERT INTO aliases(oldtag, newtag) VALUES(?, ?)", $parts); $database->execute("INSERT INTO aliases(oldtag, newtag) VALUES(:oldtag, :newtag)", array("oldtag" => $parts[0], "newtag" => $parts[1]));
} }
} }
} }

View File

@ -142,7 +142,7 @@ class BBCode extends FormatterExtension {
$start = strpos($text, "[code]"); $start = strpos($text, "[code]");
if($start === false) break; if($start === false) break;
$end = strpos($text, "[/code]"); $end = strpos($text, "[/code]", $start);
if($end === false) break; if($end === false) break;
$beginning = substr($text, 0, $start); $beginning = substr($text, 0, $start);
@ -173,5 +173,4 @@ class BBCode extends FormatterExtension {
return $text; return $text;
} }
} }
add_event_listener(new BBCode());
?> ?>

View File

@ -61,7 +61,7 @@ class Comment {
} }
class CommentList extends SimpleExtension { class CommentList extends SimpleExtension {
public function onInitExt($event) { public function onInitExt(InitExtEvent $event) {
global $config, $database; global $config, $database;
$config->set_default_bool('comment_anon', true); $config->set_default_bool('comment_anon', true);
$config->set_default_int('comment_window', 5); $config->set_default_int('comment_window', 5);
@ -114,7 +114,7 @@ class CommentList extends SimpleExtension {
public function onPageRequest(PageRequestEvent $event) { public function onPageRequest(PageRequestEvent $event) {
global $page, $user; global $page, $user;
if($event->page_matches("comment")) { if($event->page_matches("comment")) {
if($event->get_arg(0) == "add") { if($event->get_arg(0) === "add") {
if(isset($_POST['image_id']) && isset($_POST['comment'])) { if(isset($_POST['image_id']) && isset($_POST['comment'])) {
try { try {
$cpe = new CommentPostingEvent($_POST['image_id'], $user, $_POST['comment']); $cpe = new CommentPostingEvent($_POST['image_id'], $user, $_POST['comment']);
@ -127,10 +127,10 @@ class CommentList extends SimpleExtension {
} }
} }
} }
else if($event->get_arg(0) == "delete") { else if($event->get_arg(0) === "delete") {
if($user->is_admin()) { if($user->is_admin()) {
// FIXME: post, not args // FIXME: post, not args
if($event->count_args() == 3) { if($event->count_args() === 3) {
send_event(new CommentDeletionEvent($event->get_arg(1))); send_event(new CommentDeletionEvent($event->get_arg(1)));
$page->set_mode("redirect"); $page->set_mode("redirect");
if(!empty($_SERVER['HTTP_REFERER'])) { if(!empty($_SERVER['HTTP_REFERER'])) {
@ -145,7 +145,7 @@ class CommentList extends SimpleExtension {
$this->theme->display_permission_denied($page); $this->theme->display_permission_denied($page);
} }
} }
else if($event->get_arg(0) == "list") { else if($event->get_arg(0) === "list") {
$page_num = int_escape($event->get_arg(1)); $page_num = int_escape($event->get_arg(1));
$this->build_page($page_num); $this->build_page($page_num);
} }
@ -297,7 +297,7 @@ class CommentList extends SimpleExtension {
} }
// }}} // }}}
// get comments {{{ // get comments {{{
private function get_recent_comments() { private function get_recent_comments($count) {
global $config; global $config;
global $database; global $database;
$rows = $database->get_all(" $rows = $database->get_all("
@ -310,7 +310,7 @@ class CommentList extends SimpleExtension {
LEFT JOIN users ON comments.owner_id=users.id LEFT JOIN users ON comments.owner_id=users.id
ORDER BY comments.id DESC ORDER BY comments.id DESC
LIMIT :limit LIMIT :limit
", array("limit"=>$config->get_int('comment_count'))); ", array("limit"=>$count));
$comments = array(); $comments = array();
foreach($rows as $row) { foreach($rows as $row) {
$comments[] = new Comment($row); $comments[] = new Comment($row);
@ -369,14 +369,17 @@ class CommentList extends SimpleExtension {
global $database; global $database;
// sqlite fails at intervals // sqlite fails at intervals
if($database->engine->name == "sqlite") return false; if($database->engine->name === "sqlite") return false;
$window = int_escape($config->get_int('comment_window')); $window = int_escape($config->get_int('comment_window'));
$max = int_escape($config->get_int('comment_limit')); $max = int_escape($config->get_int('comment_limit'));
if($database->engine->name == "mysql") $window_sql = "interval $window minute";
else $window_sql = "interval '$window minute'";
// window doesn't work as an SQL param because it's inside quotes >_< // window doesn't work as an SQL param because it's inside quotes >_<
$result = $database->get_all("SELECT * FROM comments WHERE owner_ip = :remote_ip ". $result = $database->get_all("SELECT * FROM comments WHERE owner_ip = :remote_ip ".
"AND posted > now() - interval '$window minute'", "AND posted > now() - $window_sql",
Array("remote_ip"=>$_SERVER['REMOTE_ADDR'])); Array("remote_ip"=>$_SERVER['REMOTE_ADDR']));
return (count($result) >= $max); return (count($result) >= $max);

View File

@ -21,12 +21,12 @@ class CommentListTheme extends Themelet {
$next = $page_number + 1; $next = $page_number + 1;
$h_prev = ($page_number <= 1) ? "Prev" : $h_prev = ($page_number <= 1) ? "Prev" :
"<a href='".make_link("comment/list/$prev")."'>Prev</a>"; '<a href="'.make_link('comment/list/'.$prev).'">Prev</a>';
$h_index = "<a href='".make_link()."'>Index</a>"; $h_index = "<a href='".make_link()."'>Index</a>";
$h_next = ($page_number >= $total_pages) ? "Next" : $h_next = ($page_number >= $total_pages) ? "Next" :
"<a href='".make_link("comment/list/$next")."'>Next</a>"; '<a href="'.make_link('comment/list/'.$next).'">Next</a>';
$nav = "$h_prev | $h_index | $h_next"; $nav = $h_prev.' | '.$h_index.' | '.$h_next;
$page->set_title("Comments"); $page->set_title("Comments");
$page->set_heading("Comments"); $page->set_heading("Comments");
@ -46,7 +46,7 @@ class CommentListTheme extends Themelet {
$comment_count = count($comments); $comment_count = count($comments);
if($comment_limit > 0 && $comment_count > $comment_limit) { if($comment_limit > 0 && $comment_count > $comment_limit) {
$hidden = $comment_count - $comment_limit; $hidden = $comment_count - $comment_limit;
$comment_html .= "<p>showing $comment_limit of $comment_count comments</p>"; $comment_html .= '<p>showing '.$comment_limit.' of '.$comment_count.' comments</p>';
$comments = array_slice($comments, -$comment_limit); $comments = array_slice($comments, -$comment_limit);
} }
$this->anon_id = 1; $this->anon_id = 1;
@ -68,14 +68,14 @@ class CommentListTheme extends Themelet {
} }
} }
$html = " $html = '
<table class='comment_list_table'><tr> <table class="comment_list_table"><tr>
<td>$thumb_html</td> <td>'.$thumb_html.'</td>
<td>$comment_html</td> <td>'.$comment_html.'</td>
</tr></table> </tr></table>
"; ';
$page->add_block(new Block("{$image->id}: ".($image->get_tag_list()), $html, "main", $position++)); $page->add_block(new Block( $image->id.': '.$image->get_tag_list(), $html, "main", $position++));
} }
} }
@ -134,15 +134,7 @@ class CommentListTheme extends Themelet {
global $user; global $user;
$tfe = new TextFormattingEvent($comment->comment); $tfe = new TextFormattingEvent($comment->comment);
send_event($tfe);
// sending this event to all ~50 exts has a lot of overhead
if(SPEED_HAX) {
$bb = new BBCode();
$bb->receive_event($tfe);
}
else {
send_event($tfe);
}
$i_uid = int_escape($comment->owner_id); $i_uid = int_escape($comment->owner_id);
$h_name = html_escape($comment->owner_name); $h_name = html_escape($comment->owner_name);
@ -154,23 +146,23 @@ class CommentListTheme extends Themelet {
$anoncode = ""; $anoncode = "";
if($h_name == "Anonymous" && $this->anon_id >= 0) { if($h_name == "Anonymous" && $this->anon_id >= 0) {
$anoncode = "<sup>{$this->anon_id}</sup>"; $anoncode = '<sup>'.$this->anon_id.'</sup>';
$this->anon_id++; $this->anon_id++;
} }
$h_userlink = "<a href='".make_link("user/$h_name")."'>$h_name</a>$anoncode"; $h_userlink = '<a href="'.make_link('user/'.$h_name).'">'.$h_name.'</a>'.$anoncode;
$stripped_nonl = str_replace("\n", "\\n", substr($tfe->stripped, 0, 50)); $stripped_nonl = str_replace("\n", "\\n", substr($tfe->stripped, 0, 50));
$stripped_nonl = str_replace("\r", "\\r", $stripped_nonl); $stripped_nonl = str_replace("\r", "\\r", $stripped_nonl);
$h_dellink = $user->is_admin() ? $h_dellink = $user->is_admin() ?
"<br>($h_poster_ip, $h_timestamp, <a ". '<br>('.$h_poster_ip.', '.$h_timestamp.', <a '.
"onclick=\"return confirm('Delete comment by $h_name:\\n$stripped_nonl');\" ". 'onclick="return confirm(\'Delete comment by '.$h_name.':\\n'.$stripped_nonl.'\');" '.
"href='".make_link("comment/delete/$i_comment_id/$i_image_id")."'>Del</a>)" : ""; 'href="'.make_link('comment/delete/'.$i_comment_id.'/'.$i_image_id).'">Del</a>)' : '';
if($trim) { if($trim) {
return " return '
$h_userlink: $h_comment '.$h_userlink.': '.$h_comment.'
<a href='".make_link("post/view/$i_image_id")."'>&gt;&gt;&gt;</a> <a href="'.make_link('post/view/'.$i_image_id).'">&gt;&gt;&gt;</a>
$h_dellink '.$h_dellink.'
"; ';
} }
else { else {
//$avatar = ""; //$avatar = "";
@ -179,14 +171,14 @@ class CommentListTheme extends Themelet {
// $avatar = "<img src=\"http://www.gravatar.com/avatar/$hash.jpg\"><br>"; // $avatar = "<img src=\"http://www.gravatar.com/avatar/$hash.jpg\"><br>";
//} //}
$oe = ($this->comments_shown++ % 2 == 0) ? "even" : "odd"; $oe = ($this->comments_shown++ % 2 == 0) ? "even" : "odd";
return " return '
<a name='$i_comment_id'></a> <a name="'.$i_comment_id.'"></a>
<div class='$oe comment'> <div class="'.$oe.' comment">
<!--<span class='timeago' style='float: right;'>$h_timestamp</span>--> <!--<span class="timeago" style="float: right;">'.$h_timestamp.'</span>-->
$h_userlink: $h_comment '.$h_userlink.': '.$h_comment.'
$h_dellink '.$h_dellink.'
</div> </div>
"; ';
} }
} }
@ -197,15 +189,15 @@ class CommentListTheme extends Themelet {
$hash = CommentList::get_hash(); $hash = CommentList::get_hash();
$captcha = $config->get_bool("comment_captcha") ? captcha_get_html() : ""; $captcha = $config->get_bool("comment_captcha") ? captcha_get_html() : "";
return " return '
".make_form(make_link("comment/add"))." '.make_form(make_link("comment/add")).'
<input type='hidden' name='image_id' value='$i_image_id' /> <input type="hidden" name="image_id" value="'.$i_image_id.'" />
<input type='hidden' name='hash' value='$hash' /> <input type="hidden" name="hash" value="'.$hash.'" />
<textarea name='comment' rows='5' cols='50'></textarea> <textarea name="comment" rows="5" cols="50"></textarea>
$captcha '.$captcha.'
<br><input type='submit' value='Post Comment' /> <br><input type="submit" value="Post Comment" />
</form> </form>
"; ';
} }
} }
?> ?>

View File

@ -25,12 +25,13 @@ class ExtensionInfo {
function ExtensionInfo($main) { function ExtensionInfo($main) {
$matches = array(); $matches = array();
$lines = file($main); $lines = file($main);
$number_of_lines = count($lines);
preg_match("#(ext|contrib)/(.*)/main.php#", $main, $matches); preg_match("#(ext|contrib)/(.*)/main.php#", $main, $matches);
$this->ext_name = $matches[2]; $this->ext_name = $matches[2];
$this->name = $this->ext_name; $this->name = $this->ext_name;
$this->enabled = $this->is_enabled($this->ext_name); $this->enabled = $this->is_enabled($this->ext_name);
for($i=0; $i<count($lines); $i++) { for($i=0; $i<$number_of_lines; $i++) {
$line = $lines[$i]; $line = $lines[$i];
if(preg_match("/Name: (.*)/", $line, $matches)) { if(preg_match("/Name: (.*)/", $line, $matches)) {
$this->name = $matches[1]; $this->name = $matches[1];

View File

@ -176,5 +176,4 @@ class PixelFileHandler extends DataHandlerExtension {
} }
// }}} // }}}
} }
add_event_listener(new PixelFileHandler());
?> ?>

View File

@ -130,7 +130,7 @@ 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 { class ImageIO extends SimpleExtension {
public function onInitExt($event) { public function onInitExt(InitExtEvent $event) {
global $config; global $config;
$config->set_default_int('thumb_width', 192); $config->set_default_int('thumb_width', 192);
$config->set_default_int('thumb_height', 192); $config->set_default_int('thumb_height', 192);
@ -147,7 +147,7 @@ class ImageIO extends SimpleExtension {
$config->set_default_int('image_expires', (60*60*24*365) ); // defaults to one year $config->set_default_int('image_expires', (60*60*24*365) ); // defaults to one year
} }
public function onPageRequest($event) { public function onPageRequest(PageRequestEvent $event) {
$num = $event->get_arg(0); $num = $event->get_arg(0);
$matches = array(); $matches = array();
if(!is_null($num) && preg_match("/(\d+)/", $num, $matches)) { if(!is_null($num) && preg_match("/(\d+)/", $num, $matches)) {
@ -186,7 +186,7 @@ class ImageIO extends SimpleExtension {
} }
} }
public function onImageAdminBlockBuilding($event) { public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) {
global $user; global $user;
global $config; global $config;
@ -199,7 +199,7 @@ class ImageIO extends SimpleExtension {
} }
} }
public function onImageAddition($event) { public function onImageAddition(ImageAdditionEvent $event) {
try { try {
$this->add_image($event->image); $this->add_image($event->image);
} }
@ -208,11 +208,11 @@ class ImageIO extends SimpleExtension {
} }
} }
public function onImageDeletion($event) { public function onImageDeletion(ImageDeletionEvent $event) {
$event->image->delete(); $event->image->delete();
} }
public function onImageReplace($event) { public function onImageReplace(ImageReplaceEvent $event) {
try { try {
$this->replace_image($event->id, $event->image); $this->replace_image($event->id, $event->image);
} }
@ -221,7 +221,7 @@ class ImageIO extends SimpleExtension {
} }
} }
public function onUserPageBuilding($event) { public function onUserPageBuilding(UserPageBuildingEvent $event) {
global $user; global $user;
global $config; global $config;
@ -233,7 +233,7 @@ class ImageIO extends SimpleExtension {
$event->add_stats("<a href='$images_link'>Images uploaded</a>: $i_image_count, $h_image_rate per day"); $event->add_stats("<a href='$images_link'>Images uploaded</a>: $i_image_count, $h_image_rate per day");
} }
public function onSetupBuilding($event) { public function onSetupBuilding(SetupBuildingEvent $event) {
$sb = new SetupBlock("Image Options"); $sb = new SetupBlock("Image Options");
$sb->position = 30; $sb->position = 30;
// advanced only // advanced only

View File

@ -129,14 +129,14 @@ class PostListBuildingEvent extends Event {
} }
class Index extends SimpleExtension { class Index extends SimpleExtension {
public function onInitExt($event) { public function onInitExt(InitExtEvent $event) {
global $config; global $config;
$config->set_default_int("index_width", 3); $config->set_default_int("index_width", 3);
$config->set_default_int("index_height", 4); $config->set_default_int("index_height", 4);
$config->set_default_bool("index_tips", true); $config->set_default_bool("index_tips", true);
} }
public function onPageRequest($event) { public function onPageRequest(PageRequestEvent $event) {
global $config, $database, $page, $user; global $config, $database, $page, $user;
if($event->page_matches("post/list")) { if($event->page_matches("post/list")) {
if(isset($_GET['search'])) { if(isset($_GET['search'])) {
@ -147,7 +147,7 @@ class Index extends SimpleExtension {
} }
else { else {
$page->set_mode("redirect"); $page->set_mode("redirect");
$page->set_redirect(make_link("post/list/$search/1")); $page->set_redirect(make_link('post/list/'.$search.'/1'));
} }
return; return;
} }
@ -171,7 +171,7 @@ class Index extends SimpleExtension {
} }
else if(count($search_terms) > 0 && count($images) == 1 && $page_number == 1) { else if(count($search_terms) > 0 && count($images) == 1 && $page_number == 1) {
$page->set_mode("redirect"); $page->set_mode("redirect");
$page->set_redirect(make_link("post/view/{$images[0]->id}")); $page->set_redirect(make_link('post/view/'.$images[0]->id));
} }
else { else {
send_event(new PostListBuildingEvent($search_terms)); send_event(new PostListBuildingEvent($search_terms));
@ -182,7 +182,7 @@ class Index extends SimpleExtension {
} }
} }
public function onSetupBuilding($event) { public function onSetupBuilding(SetupBuildingEvent $event) {
$sb = new SetupBlock("Index Options"); $sb = new SetupBlock("Index Options");
$sb->position = 20; $sb->position = 20;
@ -195,17 +195,18 @@ class Index extends SimpleExtension {
$event->panel->add_block($sb); $event->panel->add_block($sb);
} }
public function onSearchTermParse($event) { public function onSearchTermParse(SearchTermParseEvent $event) {
$matches = array(); $matches = array();
if(preg_match("/^size(<|>|<=|>=|=)(\d+)x(\d+)$/", $event->term, $matches)) { // check for tags first as tag based searches are more common.
if(preg_match("/tags(<|>|<=|>=|=)(\d+)/", $event->term, $matches)) {
$cmp = $matches[1]; $cmp = $matches[1];
$args = array("width"=>int_escape($matches[2]), "height"=>int_escape($matches[3])); $tags = $matches[2];
$event->add_querylet(new Querylet("width $cmp :width AND height $cmp :height", $args)); $event->add_querylet(new Querylet('images.id IN (SELECT DISTINCT image_id FROM image_tags GROUP BY image_id HAVING count(image_id) '.$cmp.' '.$tags.')'));
} }
else if(preg_match("/^ratio(<|>|<=|>=|=)(\d+):(\d+)$/", $event->term, $matches)) { else if(preg_match("/^ratio(<|>|<=|>=|=)(\d+):(\d+)$/", $event->term, $matches)) {
$cmp = $matches[1]; $cmp = $matches[1];
$args = array("width"=>int_escape($matches[2]), "height"=>int_escape($matches[3])); $args = array("width"=>int_escape($matches[2]), "height"=>int_escape($matches[3]));
$event->add_querylet(new Querylet("width / height $cmp :width / :height", $args)); $event->add_querylet(new Querylet('width / height '.$cmp.' :width / :height', $args));
} }
else if(preg_match("/^(filesize|id)(<|>|<=|>=|=)(\d+[kmg]?b?)$/i", $event->term, $matches)) { else if(preg_match("/^(filesize|id)(<|>|<=|>=|=)(\d+[kmg]?b?)$/i", $event->term, $matches)) {
$col = $matches[1]; $col = $matches[1];
@ -215,24 +216,24 @@ class Index extends SimpleExtension {
} }
else if(preg_match("/^(hash|md5)=([0-9a-fA-F]*)$/i", $event->term, $matches)) { else if(preg_match("/^(hash|md5)=([0-9a-fA-F]*)$/i", $event->term, $matches)) {
$hash = strtolower($matches[2]); $hash = strtolower($matches[2]);
$event->add_querylet(new Querylet("images.hash = '$hash'")); $event->add_querylet(new Querylet('images.hash = "'.$hash.'"'));
} }
else if(preg_match("/^(filetype|ext)=([a-zA-Z0-9]*)$/i", $event->term, $matches)) { else if(preg_match("/^(filetype|ext)=([a-zA-Z0-9]*)$/i", $event->term, $matches)) {
$ext = strtolower($matches[2]); $ext = strtolower($matches[2]);
$event->add_querylet(new Querylet("images.ext = '$ext'")); $event->add_querylet(new Querylet('images.ext = "'.$ext.'"'));
} }
else if(preg_match("/^(filename|name)=([a-zA-Z0-9]*)$/i", $event->term, $matches)) { else if(preg_match("/^(filename|name)=([a-zA-Z0-9]*)$/i", $event->term, $matches)) {
$filename = strtolower($matches[2]); $filename = strtolower($matches[2]);
$event->add_querylet(new Querylet("images.filename LIKE '%$filename%'")); $event->add_querylet(new Querylet('images.filename LIKE "%'.$filename.'%"'));
} }
else if(preg_match("/^posted=(([0-9\*]*)?(-[0-9\*]*)?(-[0-9\*]*)?)$/", $event->term, $matches)) { else if(preg_match("/^posted=(([0-9\*]*)?(-[0-9\*]*)?(-[0-9\*]*)?)$/", $event->term, $matches)) {
$val = str_replace("*", "%", $matches[1]); $val = str_replace("*", "%", $matches[1]);
$event->add_querylet(new Querylet("images.posted LIKE '%$val%'")); $event->add_querylet(new Querylet('images.posted LIKE "%'.$val.'%"'));
} }
else if(preg_match("/tags(<|>|<=|>=|=)(\d+)/", $event->term, $matches)) { else if(preg_match("/^size(<|>|<=|>=|=)(\d+)x(\d+)$/", $event->term, $matches)) {
$cmp = $matches[1]; $cmp = $matches[1];
$tags = $matches[2]; $args = array("width"=>int_escape($matches[2]), "height"=>int_escape($matches[3]));
$event->add_querylet(new Querylet("images.id IN (SELECT DISTINCT image_id FROM image_tags GROUP BY image_id HAVING count(image_id) $cmp $tags)")); $event->add_querylet(new Querylet('width '.$cmp.' :width AND height '.$cmp.' :height', $args));
} }
} }
} }

View File

@ -8,8 +8,8 @@ class IndexTheme extends Themelet {
} }
public function display_intro(Page $page) { public function display_intro(Page $page) {
$text = <<<EOD $text = "
<div style="text-align: left;"> <div style='text-align: left;'>
<p>The first thing you'll probably want to do is create a new account; note <p>The first thing you'll probably want to do is create a new account; note
that the first account you create will by default be marked as the board's that the first account you create will by default be marked as the board's
administrator, and any further accounts will be regular users. administrator, and any further accounts will be regular users.
@ -19,7 +19,7 @@ and of course start organising your images :-)
<p>This message will go away once your first image is uploaded~ <p>This message will go away once your first image is uploaded~
</div> </div>
EOD; ";
$page->set_title("Welcome to Shimmie ".VERSION); $page->set_title("Welcome to Shimmie ".VERSION);
$page->set_heading("Welcome to Shimmie"); $page->set_heading("Welcome to Shimmie");
$page->add_block(new Block("Installation Succeeded!", $text, "main", 0)); $page->add_block(new Block("Installation Succeeded!", $text, "main", 0));
@ -69,12 +69,12 @@ EOD;
$next = $page_number + 1; $next = $page_number + 1;
$u_tags = url_escape(implode(" ", $search_terms)); $u_tags = url_escape(implode(" ", $search_terms));
$query = empty($u_tags) ? "" : "/$u_tags"; $query = empty($u_tags) ? "" : '/'.$u_tags;
$h_prev = ($page_number <= 1) ? "Prev" : "<a href='".make_link("post/list$query/$prev")."'>Prev</a>"; $h_prev = ($page_number <= 1) ? "Prev" : '<a href="'.make_link('post/list'.$query.'/'.$prev).'">Prev</a>';
$h_index = "<a href='".make_link()."'>Index</a>"; $h_index = "<a href='".make_link()."'>Index</a>";
$h_next = ($page_number >= $total_pages) ? "Next" : "<a href='".make_link("post/list$query/$next")."'>Next</a>"; $h_next = ($page_number >= $total_pages) ? "Next" : '<a href="'.make_link('post/list'.$query.'/'.$next).'">Next</a>';
$h_search_string = html_escape(implode(" ", $search_terms)); $h_search_string = html_escape(implode(" ", $search_terms));
$h_search_link = make_link(); $h_search_link = make_link();
@ -102,7 +102,7 @@ EOD;
</form> </form>
<div id='search_completions'></div>"; <div id='search_completions'></div>";
return "$h_prev | $h_index | $h_next<br>$h_search"; return $h_prev.' | '.$h_index.' | '.$h_next.'<br>'.$h_search;
} }
protected function build_table($images, $query) { protected function build_table($images, $query) {

BIN
ext/mail/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

9
ext/mail/mail.css Normal file
View File

@ -0,0 +1,9 @@
.headerTop { background-color:#FFCC66; border-top:0px solid #000000; border-bottom:1px solid #FFFFFF; text-align:center; }
.adminText { font-size:10px; color:#996600; line-height:200%; font-family:verdana; text-decoration:none; }
.headerBar { background-color:#FFFFFF; border-top:0px solid #333333; border-bottom:10px solid #FFFFFF; }
.title { font-size:20px; font-weight:bold; color:#CC6600; font-family:arial; line-height:110%; }
.subTitle { font-size:11px; font-weight:normal; color:#666666; font-style:italic; font-family:arial; }
.defaultText { font-size:12px; color:#000000; line-height:150%; font-family:trebuchet ms; }
.footerRow { background-color:#FFFFCC; border-top:10px solid #FFFFFF; }
.footerText { font-size:10px; color:#996600; line-height:100%; font-family:verdana; }
a { color:#FF6600; color:#FF6600; color:#FF6600; }

45
ext/mail/main.php Normal file
View File

@ -0,0 +1,45 @@
<?php
/**
* Name: Mail System
* Author: Zach Hall <zach@sosguy.net>
* Link: http://seemslegit.com
* License: GPLv2
* Description: Provides an interface for sending and receiving mail.
*/
class Mail extends SimpleExtension {
public function onSetupBuilding(SetupBuildingEvent $event) {
$sb = new SetupBlock("Mailing Options");
$sb->add_text_option("mail_sub", "<br>Subject prefix: ");
$sb->add_text_option("mail_img", "<br>Banner Image URL: ");
$sb->add_text_option("mail_style", "<br>Style URL: ");
$sb->add_longtext_option("mail_fot", "<br>Footer (Use HTML)");
$sb->add_label("<br><i>Should measure 550x110px. Use an absolute URL</i>");
$event->panel->add_block($sb);
}
public function onInitExt(InitExtEvent $event) {
global $config;
$config->set_default_string("mail_sub", $config->get_string("site_title")." - ");
$config->set_default_string("mail_img", make_http("ext/mail/banner.png"));
$config->set_default_string("mail_style", make_http("ext/mail/mail.css"));
$config->set_default_string("mail_fot", "<a href='".make_http(make_link())."'>".$config->get_string("site_title")."</a>");
}
}
class MailTest extends SimpleExtension {
public function onPageRequest(PageRequestEvent $event) {
if($event->page_matches("mail/test")) {
global $page;
$page->set_mode("data");
echo "Alert: uncomment this page's code on /ext/mail/main.php starting on line 33, and change the email address. Make sure you're using a server with a domain, not localhost.";
/*
echo "Preparing to send message:<br>";
echo "created new mail object. sending now... ";
$email = new Email("example@localhost.com", "hello", "hello world", "this is a test message.");
$email->send();
echo "sent.";
*/
}
}
}
?>

View File

@ -162,7 +162,7 @@ class SetupBlock extends Block {
// }}} // }}}
class Setup extends SimpleExtension { class Setup extends SimpleExtension {
public function onInitExt($event) { public function onInitExt(InitExtEvent $event) {
global $config; global $config;
$config->set_default_string("title", "Shimmie"); $config->set_default_string("title", "Shimmie");
$config->set_default_string("front_page", "post/list"); $config->set_default_string("front_page", "post/list");
@ -178,7 +178,7 @@ class Setup extends SimpleExtension {
$config->set_default_bool("autocache_min_js", false); $config->set_default_bool("autocache_min_js", false);
} }
public function onPageRequest($event) { public function onPageRequest(PageRequestEvent $event) {
global $config, $page, $user; global $config, $page, $user;
if($event->page_matches("nicetest")) { if($event->page_matches("nicetest")) {
@ -210,7 +210,7 @@ class Setup extends SimpleExtension {
} }
} }
public function onSetupBuilding($event) { public function onSetupBuilding(SetupBuildingEvent $event) {
$themes = array(); $themes = array();
foreach(glob("themes/*") as $theme_dirname) { foreach(glob("themes/*") as $theme_dirname) {
$name = str_replace("themes/", "", $theme_dirname); $name = str_replace("themes/", "", $theme_dirname);
@ -309,7 +309,7 @@ class Setup extends SimpleExtension {
$event->panel->add_block($sb); $event->panel->add_block($sb);
} }
public function onConfigSave($event) { public function onConfigSave(ConfigSaveEvent $event) {
global $config; global $config;
foreach($_POST as $_name => $junk) { foreach($_POST as $_name => $junk) {
if(substr($_name, 0, 6) == "_type_") { if(substr($_name, 0, 6) == "_type_") {
@ -327,7 +327,7 @@ class Setup extends SimpleExtension {
log_warning("setup", "Configuration updated"); log_warning("setup", "Configuration updated");
} }
public function onUserBlockBuilding($event) { public function onUserBlockBuilding(UserBlockBuildingEvent $event) {
global $user; global $user;
if($user->is_admin()) { if($user->is_admin()) {
$event->add_link("Board Config", make_link("setup")); $event->add_link("Board Config", make_link("setup"));

View File

@ -56,7 +56,7 @@ class LockSetEvent extends Event {
} }
class TagEdit extends SimpleExtension { class TagEdit extends SimpleExtension {
public function onPageRequest($event) { public function onPageRequest(PageRequestEvent $event) {
global $user, $page; global $user, $page;
if($event->page_matches("tag_edit")) { if($event->page_matches("tag_edit")) {
if($event->get_arg(0) == "replace") { if($event->get_arg(0) == "replace") {
@ -71,8 +71,8 @@ class TagEdit extends SimpleExtension {
} }
} }
public function onImageInfoSet($event) { public function onImageInfoSet(ImageInfoSetEvent $event) {
global $user; global $user, $page;
if($this->can_tag($event->image)) { if($this->can_tag($event->image)) {
send_event(new TagSetEvent($event->image, $_POST['tag_edit__tags'])); send_event(new TagSetEvent($event->image, $_POST['tag_edit__tags']));
if($this->can_source($event->image)) { if($this->can_source($event->image)) {
@ -88,41 +88,41 @@ class TagEdit extends SimpleExtension {
} }
} }
public function onTagSet($event) { public function onTagSet(TagSetEvent $event) {
global $user; global $user;
if($user->is_admin() || !$event->image->is_locked()) { if($user->is_admin() || !$event->image->is_locked()) {
$event->image->set_tags($event->tags); $event->image->set_tags($event->tags);
} }
} }
public function onSourceSet($event) { public function onSourceSet(SourceSetEvent $event) {
global $user; global $user;
if($user->is_admin() || !$event->image->is_locked()) { if($user->is_admin() || !$event->image->is_locked()) {
$event->image->set_source($event->source); $event->image->set_source($event->source);
} }
} }
public function onLockSet($event) { public function onLockSet(LockSetEvent $event) {
global $user; global $user;
if($user->is_admin()) { if($user->is_admin()) {
$event->image->set_locked($event->locked); $event->image->set_locked($event->locked);
} }
} }
public function onImageDeletion($event) { public function onImageDeletion(ImageDeletionEvent $event) {
$event->image->delete_tags_from_image(); $event->image->delete_tags_from_image();
} }
public function onAdminBuilding($event) { public function onAdminBuilding(AdminBuildingEvent $event) {
$this->theme->display_mass_editor(); $this->theme->display_mass_editor();
} }
// When an alias is added, oldtag becomes inaccessable // When an alias is added, oldtag becomes inaccessable
public function onAddAlias($event) { public function onAddAlias(AddAliasEvent $event) {
$this->mass_tag_edit($event->oldtag, $event->newtag); $this->mass_tag_edit($event->oldtag, $event->newtag);
} }
public function onImageInfoBoxBuilding($event) { public function onImageInfoBoxBuilding(ImageInfoBoxBuildingEvent $event) {
global $user; global $user;
if($this->can_tag($event->image)) { if($this->can_tag($event->image)) {
$event->add_part($this->theme->get_tag_editor_html($event->image), 40); $event->add_part($this->theme->get_tag_editor_html($event->image), 40);
@ -135,7 +135,7 @@ class TagEdit extends SimpleExtension {
} }
} }
public function onSetupBuilding($event) { public function onSetupBuilding(SetupBuildingEvent $event) {
$sb = new SetupBlock("Tag Editing"); $sb = new SetupBlock("Tag Editing");
$sb->add_bool_option("tag_edit_anon", "Allow anonymous tag editing: "); $sb->add_bool_option("tag_edit_anon", "Allow anonymous tag editing: ");
$sb->add_bool_option("source_edit_anon", "<br>Allow anonymous source editing: "); $sb->add_bool_option("source_edit_anon", "<br>Allow anonymous source editing: ");

View File

@ -6,7 +6,7 @@
*/ */
class TagList extends SimpleExtension { class TagList extends SimpleExtension {
public function onInitExt($event) { public function onInitExt(InitExtEvent $event) {
global $config; global $config;
$config->set_default_int("tag_list_length", 15); $config->set_default_int("tag_list_length", 15);
$config->set_default_int("popular_tag_list_length", 15); $config->set_default_int("popular_tag_list_length", 15);
@ -16,7 +16,7 @@ class TagList extends SimpleExtension {
$config->set_default_bool("tag_list_pages", false); $config->set_default_bool("tag_list_pages", false);
} }
public function onPageRequest($event) { public function onPageRequest(PageRequestEvent $event) {
global $page, $database; global $page, $database;
if($event->page_matches("tags")) { if($event->page_matches("tags")) {
@ -59,7 +59,7 @@ class TagList extends SimpleExtension {
} }
} }
public function onPostListBuilding($event) { public function onPostListBuilding(PostListBuildingEvent $event) {
global $config, $page; global $config, $page;
if($config->get_int('tag_list_length') > 0) { if($config->get_int('tag_list_length') > 0) {
if(!empty($event->search_terms)) { if(!empty($event->search_terms)) {
@ -71,7 +71,7 @@ class TagList extends SimpleExtension {
} }
} }
public function onDisplayingImage($event) { public function onDisplayingImage(DisplayingImageEvent $event) {
global $config, $page; global $config, $page;
if($config->get_int('tag_list_length') > 0) { if($config->get_int('tag_list_length') > 0) {
if($config->get_string('tag_list_image_type') == 'related') { if($config->get_string('tag_list_image_type') == 'related') {
@ -83,7 +83,7 @@ class TagList extends SimpleExtension {
} }
} }
public function onSetupBuilding($event) { public function onSetupBuilding(SetupBuildingEvent $event) {
$sb = new SetupBlock("Tag Map Options"); $sb = new SetupBlock("Tag Map Options");
$sb->add_int_option("tags_min", "Only show tags used at least "); $sb->add_label(" times"); $sb->add_int_option("tags_min", "Only show tags used at least "); $sb->add_label(" times");
$sb->add_bool_option("tag_list_pages", "<br>Paged tag lists: "); $sb->add_bool_option("tag_list_pages", "<br>Paged tag lists: ");

View File

@ -45,7 +45,7 @@ class Upload extends SimpleExtension {
// early, so it can stop the DataUploadEvent before any data handlers see it // early, so it can stop the DataUploadEvent before any data handlers see it
public function get_priority() {return 40;} public function get_priority() {return 40;}
public function onInitExt($event) { public function onInitExt(InitExtEvent $event) {
global $config; global $config;
$config->set_default_int('upload_count', 3); $config->set_default_int('upload_count', 3);
$config->set_default_int('upload_size', '1MB'); $config->set_default_int('upload_size', '1MB');
@ -63,7 +63,7 @@ class Upload extends SimpleExtension {
} }
public function onPostListBuilding($event) { public function onPostListBuilding(PostListBuildingEvent $event) {
global $user, $page; global $user, $page;
if($this->can_upload($user)) { if($this->can_upload($user)) {
if($this->is_full) { if($this->is_full) {
@ -75,7 +75,7 @@ class Upload extends SimpleExtension {
} }
} }
public function onSetupBuilding($event) { public function onSetupBuilding(SetupBuildingEvent $event) {
$tes = array(); $tes = array();
$tes["Disabled"] = "none"; $tes["Disabled"] = "none";
if(function_exists("curl_init")) { if(function_exists("curl_init")) {
@ -97,7 +97,7 @@ class Upload extends SimpleExtension {
$event->panel->add_block($sb); $event->panel->add_block($sb);
} }
public function onDataUpload($event) { public function onDataUpload(DataUploadEvent $event) {
global $config; global $config;
if($this->is_full) { if($this->is_full) {
throw new UploadException("Upload failed; disk nearly full"); throw new UploadException("Upload failed; disk nearly full");

View File

@ -16,7 +16,9 @@ class UploadTheme extends Themelet {
$tl_enabled = ($config->get_string("transload_engine", "none") != "none"); $tl_enabled = ($config->get_string("transload_engine", "none") != "none");
// Uploader 2.0! // Uploader 2.0!
$upload_list = ""; $upload_list = "";
for($i=0; $i<$config->get_int('upload_count'); $i++) $upload_count = $config->get_int('upload_count');
for($i=0; $i<$upload_count; $i++)
{ {
$a=$i+1; $a=$i+1;
$s=$i-1; $s=$i-1;
@ -243,7 +245,9 @@ class UploadTheme extends Themelet {
global $config; global $config;
$upload_list = ""; $upload_list = "";
for($i=0; $i<$config->get_int('upload_count'); $i++) { $upload_count = $config->get_int('upload_count');
for($i=0; $i<$upload_count; $i++) {
if($i == 0) $style = ""; // "style='display:visible'"; if($i == 0) $style = ""; // "style='display:visible'";
else $style = "style='display:none'"; else $style = "style='display:none'";
$upload_list .= "<input size='10' ". $upload_list .= "<input size='10' ".

View File

@ -43,7 +43,7 @@ class UserCreationEvent extends Event {
class UserCreationException extends SCoreException {} class UserCreationException extends SCoreException {}
class UserPage extends SimpleExtension { class UserPage extends SimpleExtension {
public function onInitExt(Event $event) { public function onInitExt(InitExtEvent $event) {
global $config; global $config;
$config->set_default_bool("login_signup_enabled", true); $config->set_default_bool("login_signup_enabled", true);
$config->set_default_int("login_memory", 365); $config->set_default_int("login_memory", 365);
@ -54,7 +54,7 @@ class UserPage extends SimpleExtension {
$config->set_default_bool("login_tac_bbcode", true); $config->set_default_bool("login_tac_bbcode", true);
} }
public function onPageRequest(Event $event) { public function onPageRequest(PageRequestEvent $event) {
global $config, $database, $page, $user; global $config, $database, $page, $user;
// user info is shown on all pages // user info is shown on all pages
@ -152,7 +152,7 @@ class UserPage extends SimpleExtension {
} }
} }
if(($event instanceof PageRequestEvent) && $event->page_matches("user")) { if($event->page_matches("user")) {
$display_user = ($event->count_args() == 0) ? $user : User::by_name($event->get_arg(0)); $display_user = ($event->count_args() == 0) ? $user : User::by_name($event->get_arg(0));
if($event->count_args() == 0 && $user->is_anonymous()) { if($event->count_args() == 0 && $user->is_anonymous()) {
$this->theme->display_error($page, "Not Logged In", $this->theme->display_error($page, "Not Logged In",
@ -169,7 +169,7 @@ class UserPage extends SimpleExtension {
} }
} }
public function onUserPageBuilding(Event $event) { public function onUserPageBuilding(UserPageBuildingEvent $event) {
global $page, $user, $config; global $page, $user, $config;
$h_join_date = autodate($event->display_user->join_date); $h_join_date = autodate($event->display_user->join_date);
@ -197,7 +197,7 @@ class UserPage extends SimpleExtension {
} }
} }
public function onSetupBuilding(Event $event) { public function onSetupBuilding(SetupBuildingEvent $event) {
global $config; global $config;
$hosts = array( $hosts = array(
@ -228,17 +228,17 @@ class UserPage extends SimpleExtension {
$event->panel->add_block($sb); $event->panel->add_block($sb);
} }
public function onUserBlockBuilding(Event $event) { public function onUserBlockBuilding(UserBlockBuildingEvent $event) {
$event->add_link("My Profile", make_link("user")); $event->add_link("My Profile", make_link("user"));
$event->add_link("Log Out", make_link("user_admin/logout"), 99); $event->add_link("Log Out", make_link("user_admin/logout"), 99);
} }
public function onUserCreation(Event $event) { public function onUserCreation(UserCreationEvent $event) {
$this->check_user_creation($event); $this->check_user_creation($event);
$this->create_user($event); $this->create_user($event);
} }
public function onSearchTermParse(Event $event) { public function onSearchTermParse(SearchTermParseEvent $event) {
global $user; global $user;
$matches = array(); $matches = array();
@ -537,5 +537,4 @@ class UserPage extends SimpleExtension {
// }}} // }}}
} }
add_event_listener(new UserPage());
?> ?>

View File

@ -30,9 +30,9 @@ class UserPageTheme extends Themelet {
public function display_user_block(Page $page, User $user, $parts) { public function display_user_block(Page $page, User $user, $parts) {
$h_name = html_escape($user->name); $h_name = html_escape($user->name);
$html = "Logged in as $h_name"; $html = 'Logged in as '.$h_name;
foreach($parts as $part) { foreach($parts as $part) {
$html .= "<br><a href='{$part["link"]}'>{$part["name"]}</a>"; $html .= '<br><a href="'.$part["link"].'">'.$part["name"].'</a>';
} }
$page->add_block(new Block("User Links", $html, "left", 90)); $page->add_block(new Block("User Links", $html, "left", 90));
} }
@ -48,12 +48,12 @@ class UserPageTheme extends Themelet {
} }
if(empty($tac)) {$html = "";} if(empty($tac)) {$html = "";}
else {$html = "<p>$tac</p>";} else {$html = '<p>'.$tac.'</p>';}
$reca = "<tr><td colspan='2'>".captcha_get_html()."</td></tr>"; $reca = "<tr><td colspan='2'>".captcha_get_html()."</td></tr>";
$html .= " $html .= '
".make_form(make_link("user_admin/create"))." '.make_form(make_link("user_admin/create"))."
<table style='width: 300px;'> <table style='width: 300px;'>
<tr><td>Name</td><td><input type='text' name='name'></td></tr> <tr><td>Name</td><td><input type='text' name='name'></td></tr>
<tr><td>Password</td><td><input type='password' name='pass1'></td></tr> <tr><td>Password</td><td><input type='password' name='pass1'></td></tr>
@ -81,8 +81,8 @@ class UserPageTheme extends Themelet {
public function display_login_block(Page $page) { public function display_login_block(Page $page) {
global $config; global $config;
$html = " $html = '
".make_form(make_link("user_admin/login"))." '.make_form(make_link("user_admin/login"))."
<table summary='Login Form'> <table summary='Login Form'>
<tr> <tr>
<td width='70'><label for='user'>Name</label></td> <td width='70'><label for='user'>Name</label></td>
@ -107,7 +107,7 @@ class UserPageTheme extends Themelet {
$html .= "<tr><td>Uploaded from: "; $html .= "<tr><td>Uploaded from: ";
$n = 0; $n = 0;
foreach($uploads as $ip => $count) { foreach($uploads as $ip => $count) {
$html .= "<br>$ip ($count)"; $html .= '<br>'.$ip.' ('.$count.')';
if(++$n >= 20) { if(++$n >= 20) {
$html .= "<br>..."; $html .= "<br>...";
break; break;
@ -117,7 +117,7 @@ class UserPageTheme extends Themelet {
$html .= "</td><td>Commented from:"; $html .= "</td><td>Commented from:";
$n = 0; $n = 0;
foreach($comments as $ip => $count) { foreach($comments as $ip => $count) {
$html .= "<br>$ip ($count)"; $html .= '<br>'.$ip.' ('.$count.')';
if(++$n >= 20) { if(++$n >= 20) {
$html .= "<br>..."; $html .= "<br>...";
break; break;
@ -133,10 +133,10 @@ class UserPageTheme extends Themelet {
public function display_user_page(User $duser, $stats) { public function display_user_page(User $duser, $stats) {
global $page, $user; global $page, $user;
assert(is_array($stats)); assert(is_array($stats));
$stats[] = "User ID: {$duser->id}"; $stats[] = 'User ID: '.$duser->id;
$page->set_title("{$duser->name}'s Page"); $page->set_title($duser->name."'s Page");
$page->set_heading("{$duser->name}'s Page"); $page->set_heading($duser->name."'s Page");
$page->add_block(new NavBlock()); $page->add_block(new NavBlock());
$page->add_block(new Block("Stats", join("<br>", $stats), "main", 0)); $page->add_block(new Block("Stats", join("<br>", $stats), "main", 0));

View File

@ -55,30 +55,11 @@ if(empty($database_dsn) && !file_exists("config.php")) {
exit; exit;
} }
require_once "config.php"; require_once "config.php";
require_once "core/default_config.inc.php";
// to change these system-level settings, do define("FOO", 123); in config.php
function _d($name, $value) {if(!defined($name)) define($name, $value);}
_d("DATABASE_DSN", null); // string PDO database connection details
_d("CACHE_DSN", null); // string cache connection details
_d("DEBUG", false); // boolean print various debugging details
_d("COVERAGE", false); // boolean activate xdebug coverage monitor
_d("CONTEXT", null); // string file to log performance data into
_d("CACHE_MEMCACHE", false); // boolean store complete rendered pages in memcache
_d("CACHE_DIR", false); // boolean store complete rendered pages on disk
_d("CACHE_HTTP", false); // boolean output explicit HTTP caching headers
_d("COOKIE_PREFIX", 'shm'); // string if you run multiple galleries with non-shared logins, give them different prefixes
_d("SPEED_HAX", false); // boolean do some questionable things in the name of performance
_d("NICE_URLS", false); // boolean force niceurl mode
_d("WH_SPLITS", 1); // int how many levels of subfolders to put in the warehouse
_d("VERSION", 'trunk'); // string shimmie version
_d("SCORE_VERSION", 's2hack/'.VERSION); // string SCore version
_d("TIMEZONE", 'UTC'); // string timezone
// set up and purify the environment
date_default_timezone_set(TIMEZONE);
require_once "core/util.inc.php"; require_once "core/util.inc.php";
require_once "lib/context.php"; require_once "lib/context.php";
// set up and purify the environment
if(CONTEXT) { if(CONTEXT) {
ctx_set_log(CONTEXT); ctx_set_log(CONTEXT);
} }
@ -101,77 +82,29 @@ try {
} }
ctx_log_endok(); ctx_log_endok();
ctx_log_start("Connecting to DB"); ctx_log_start("Connecting to DB");
// connect to the database // connect to the database
$database = new Database(); $database = new Database();
//$database->db->fnExecute = '_count_execs'; // FIXME: PDO equivalent
$database->db->beginTransaction(); $database->db->beginTransaction();
$config = new DatabaseConfig($database); $config = new DatabaseConfig($database);
ctx_log_endok(); ctx_log_endok();
ctx_log_start("Loading themelets");
// load the theme parts // load the theme parts
ctx_log_start("Loading themelets");
$_theme = $config->get_string("theme", "default"); $_theme = $config->get_string("theme", "default");
if(!file_exists("themes/$_theme")) $_theme = "default"; if(!file_exists("themes/$_theme")) $_theme = "default";
if(file_exists("themes/$_theme/custompage.class.php")) require_once "themes/$_theme/custompage.class.php"; foreach(_get_themelet_files($_theme) as $themelet) {
require_once "themes/$_theme/layout.class.php"; require_once $themelet;
require_once "themes/$_theme/themelet.class.php";
$themelets = glob("ext/*/theme.php");
foreach($themelets as $filename) {
require_once $filename;
}
$custom_themelets = glob("themes/$_theme/*.theme.php");
if($custom_themelets) {
$m = array();
foreach($custom_themelets as $filename) {
if(preg_match("/themes\/$_theme\/(.*)\.theme\.php/",$filename,$m)
&& in_array("ext/{$m[1]}/theme.php", $themelets)) {
require_once $filename;
}
}
} }
ctx_log_endok(); ctx_log_endok();
_load_extensions();
// initialise the extensions
$all_events = array();
foreach(get_declared_classes() as $class) {
if(is_subclass_of($class, "Event")) {
$all_events[] = $class;
}
}
foreach(get_declared_classes() as $class) {
$rclass = new ReflectionClass($class);
if($rclass->isAbstract()) {
// don't do anything
}
elseif(is_subclass_of($class, "SimpleExtension")) {
$c = new $class();
$c->i_am($c);
$my_events = array();
foreach(get_class_methods($c) as $method) {
if(substr($method, 0, 2) == "on") {
$my_events[] = substr($method, 2) . "Event";
}
}
add_event_listener($c, $c->get_priority(), $my_events);
}
elseif(is_subclass_of($class, "Extension")) {
$c = new $class();
add_event_listener($c, $c->get_priority(), $all_events);
}
}
ctx_log_endok("Initialisation"); ctx_log_endok("Initialisation");
ctx_log_start("Page generation"); ctx_log_start("Page generation");
// start the page generation waterfall // start the page generation waterfall
$page = class_exists("CustomPage") ? new CustomPage() : new Page(); $page = class_exists("CustomPage") ? new CustomPage() : new Page();
$user = _get_user($config, $database); $user = _get_user();
send_event(new InitExtEvent()); send_event(new InitExtEvent());
send_event(_get_page_request()); send_event(_get_page_request());
$page->display(); $page->display();
@ -182,22 +115,8 @@ try {
ctx_log_endok(); ctx_log_endok();
} }
catch(Exception $e) { catch(Exception $e) {
$version = VERSION;
$message = $e->getMessage();
//$trace = var_dump($e->getTrace());
header("HTTP/1.0 500 Internal Error");
print <<<EOD
<html>
<head>
<title>Internal error - SCore-$version</title>
</head>
<body>
<h1>Internal Error</h1>
<p>$message
</body>
</html>
EOD;
if($database && $database->db) $database->db->rollback(); if($database && $database->db) $database->db->rollback();
_fatal_error($e);
ctx_log_ender(); ctx_log_ender();
} }
?> ?>

View File

@ -119,6 +119,7 @@ if(is_readable("config.php")) {
exit; exit;
} }
require_once "core/compat.inc.php"; require_once "core/compat.inc.php";
require_once "core/util.inc.php";
require_once "core/database.class.php"; require_once "core/database.class.php";
do_install(); do_install();
@ -160,6 +161,7 @@ function do_install() { // {{{
if(isset($_POST['database_type']) && isset($_POST['database_host']) && isset($_POST['database_user']) && isset($_POST['database_name'])) { if(isset($_POST['database_type']) && isset($_POST['database_host']) && isset($_POST['database_user']) && isset($_POST['database_name'])) {
global $database_dsn; global $database_dsn;
$database_dsn = "{$_POST['database_type']}:user={$_POST['database_user']};password={$_POST['database_password']};host={$_POST['database_host']};dbname={$_POST['database_name']}"; $database_dsn = "{$_POST['database_type']}:user={$_POST['database_user']};password={$_POST['database_password']};host={$_POST['database_host']};dbname={$_POST['database_name']}";
define('DATABASE_DSN', $database_dsn);
install_process(); install_process();
} }
else if(file_exists("auto_install.conf")) { else if(file_exists("auto_install.conf")) {
@ -362,9 +364,10 @@ function build_dirs() { // {{{
} // }}} } // }}}
function write_config() { // {{{ function write_config() { // {{{
global $database_dsn; global $database_dsn;
$file_content = "<"+"?php\n"+
"define('DATABASE_DSN', '$database_dsn');\n"+ $file_content = '<' . '?php' . "\n" .
"?"+">"; "define('DATABASE_DSN', '$database_dsn');\n" .
'?' . '>';
if(is_writable("./") && file_put_contents("config.php", $file_content)) { if(is_writable("./") && file_put_contents("config.php", $file_content)) {
assert(file_exists("config.php")); assert(file_exists("config.php"));

9
lib/helpers.js Normal file
View File

@ -0,0 +1,9 @@
function find_thumb_link_containers () {
var post_link = "a[href*='/post/view/']";
var has_thumb_img = ":has(img[src*='/thumb/'])";
var list = $( post_link + has_thumb_img ).parent();
return list;
}

View File

@ -904,7 +904,9 @@ class Securimage {
} }
$out_data = ''; $out_data = '';
for($i = 0; $i < sizeof($files); ++$i) { $file_size = sizeof($files);
for($i = 0; $i < $file_size; ++$i) {
if ($i == 0) { // output header if ($i == 0) { // output header
$out_data .= pack('C4VC8', ord('R'), ord('I'), ord('F'), ord('F'), $data_len + 36, ord('W'), ord('A'), ord('V'), ord('E'), ord('f'), ord('m'), ord('t'), ord(' ')); $out_data .= pack('C4VC8', ord('R'), ord('I'), ord('F'), ord('F'), $data_len + 36, ord('W'), ord('A'), ord('V'), ord('E'), ord('f'), ord('m'), ord('t'), ord(' '));

View File

@ -142,7 +142,8 @@ class Layout {
case "upload": case "upload":
if(file_exists("ext/numeric_score")){ $custom_sublinks .= "<li><b>Popular by </b><a href='".make_link('popular_by_day')."'>Day</a>/<a href='".make_link('popular_by_month')."'>Month</a>/<a href='".make_link('popular_by_year')."'>Year</a></li>";} if(file_exists("ext/numeric_score")){ $custom_sublinks .= "<li><b>Popular by </b><a href='".make_link('popular_by_day')."'>Day</a>/<a href='".make_link('popular_by_month')."'>Month</a>/<a href='".make_link('popular_by_year')."'>Year</a></li>";}
$custom_sublinks .= "<li><a href='".make_link('post/list')."'>All</a></li>"; $custom_sublinks .= "<li><a href='".make_link('post/list')."'>All</a></li>";
$custom_sublinks .= "<li><a href='".make_link("post/list/favorited_by=$username/1")."'>My Favorites</a></li>"; if(file_exists("ext/favorites")){ $custom_sublinks .= "<li><a href='".make_link("post/list/favorited_by=$username/1")."'>My Favorites</a></li>";}
if(file_exists("ext/rss_images")){ $custom_sublinks .= "<li><a href='".make_link('rss/images')."'>Feed</a></li>";}
if(file_exists("ext/random_image")){ $custom_sublinks .= "<li><a href='".make_link("random_image/view")."'>Random Image</a></li>";} if(file_exists("ext/random_image")){ $custom_sublinks .= "<li><a href='".make_link("random_image/view")."'>Random Image</a></li>";}
if($hw){ $custom_sublinks .= "<li><a href='".make_link("wiki/posts")."'>Help</a></li>"; if($hw){ $custom_sublinks .= "<li><a href='".make_link("wiki/posts")."'>Help</a></li>";
}else{ $custom_sublinks .= "<li><a href='".make_link("ext_doc/index")."'>Help</a></li>";} }else{ $custom_sublinks .= "<li><a href='".make_link("ext_doc/index")."'>Help</a></li>";}

View File

@ -29,13 +29,13 @@ class Themelet {
*/ */
public function build_thumb_html(Image $image, $query=null) { public function build_thumb_html(Image $image, $query=null) {
global $config; global $config;
$i_id = int_escape($image->id); $i_id = (int) $image->id;
$h_view_link = make_link("post/view/$i_id", $query); $h_view_link = make_link('post/view/'.$i_id, $query);
$h_thumb_link = $image->get_thumb_link(); $h_thumb_link = $image->get_thumb_link();
// Removes the size tag if the file is an mp3 // Removes the size tag if the file is an mp3
if($image->ext == 'mp3'){ if($image->ext === 'mp3'){
$iitip = $image->get_tooltip(); $iitip = $image->get_tooltip();
$mp3tip = array("0x0"); $mp3tip = array("0x0");
$h_tip = str_replace($mp3tip, " ", $iitip); $h_tip = str_replace($mp3tip, " ", $iitip);
@ -45,29 +45,29 @@ class Themelet {
if(strstr($h_tip, " ")){ if(strstr($h_tip, " ")){
$h_tip = html_escape(str_replace($justincase, "", $h_tip)); $h_tip = html_escape(str_replace($justincase, "", $h_tip));
}else{ }else{
$h_tip = html_escape($h_tip); $h_tip = html_escape($h_tip);
} }
}else{ }else{
$h_tip = html_escape($image->get_tooltip()); $h_tip = html_escape($image->get_tooltip());
} }
// If file is flash or svg then sets thumbnail to max size. // If file is flash or svg then sets thumbnail to max size.
if($image->ext == 'swf' || $image->ext == 'svg'){ if($image->ext === 'swf' || $image->ext === 'svg'){
$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); } $tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
else{ else{
$tsize = get_thumbnail_size($image->width, $image->height); } $tsize = get_thumbnail_size($image->width, $image->height); }
return " return '
<!-- cancel border --> <!-- cancel border -->
<div class='thumbblock'> <div class="thumbblock">
<div class='thumb'> <div class="thumb">
<a href='$h_view_link' style='position: relative; display: block; height: {$tsize[1]}px; width: {$tsize[0]}px;'> <a href="'.$h_view_link.'" style="position: relative; display: block; height: '.$tsize[1].'px; width: '.$tsize[0].'px;">
<img id='thumb_$i_id' title='$h_tip' alt='$h_tip' height='{$tsize[1]}' width='{$tsize[0]}' src='$h_thumb_link'> <img id="thumb_'.$i_id.'" title="'.$h_tip.'" alt="'.$h_tip.'" height="'.$tsize[1].'" width="'.$tsize[0].'" src="'.$h_thumb_link.'">
</a> </a>
</div> </div>
</div> </div>
"; ';
} }
@ -81,8 +81,8 @@ class Themelet {
} }
private function gen_page_link($base_url, $query, $page, $name) { private function gen_page_link($base_url, $query, $page, $name) {
$link = make_link("$base_url/$page", $query); $link = make_link($base_url.'/'.$page, $query);
return "<a href='$link'>$name</a>"; return '<a href="'.$link.'">'.$name.'</a>';
} }
private function gen_page_link_block($base_url, $query, $page, $current_page, $name) { private function gen_page_link_block($base_url, $query, $page, $current_page, $name) {
@ -116,8 +116,8 @@ class Themelet {
} }
$pages_html = implode(" | ", $pages); $pages_html = implode(" | ", $pages);
return "<p class='paginator'>$first_html | $prev_html | $random_html | $next_html | $last_html". return '<p class="paginator">'.$first_html.' | '.$prev_html.' | '.$random_html.' | '.$next_html.' | '.$last_html
"<br>&lt;&lt; $pages_html &gt;&gt;</p><!-- cancel border -->"; .'<br>&lt;&lt; '.$pages_html.' &gt;&gt;</p><!-- cancel border -->';
} }
} }
?> ?>

View File

@ -96,8 +96,8 @@ class Layout {
case "post": case "post":
if(file_exists("ext/numeric_score")){ $cs .= "<b>Popular by </b><a href='".make_link('popular_by_day')."'>Day</a><b>/</b><a href='".make_link('popular_by_month')."'>Month</a><b>/</b><a href='".make_link('popular_by_year')."'>Year</a> ";} if(file_exists("ext/numeric_score")){ $cs .= "<b>Popular by </b><a href='".make_link('popular_by_day')."'>Day</a><b>/</b><a href='".make_link('popular_by_month')."'>Month</a><b>/</b><a href='".make_link('popular_by_year')."'>Year</a> ";}
$cs .= "<a class='tab' href='".make_link('post/list')."'>All</a>"; $cs .= "<a class='tab' href='".make_link('post/list')."'>All</a>";
$cs .= "<a class='tab' href='".make_link("post/list/favorited_by=$username/1")."'>My Favorites</a>"; if(file_exists("ext/favorites")){ $cs .= "<a class='tab' href='".make_link("post/list/favorited_by=$username/1")."'>My Favorites</a>";}
$cs .= "<a class='tab' href='".make_link('rss/images')."'>Feed</a>"; if(file_exists("ext/rss_images")){ $cs .= "<a class='tab' href='".make_link('rss/images')."'>Feed</a>";}
if(file_exists("ext/random_image")){ $cs .= "<a class='tab' href='".make_link("random_image/view")."'>Random Image</a>";} if(file_exists("ext/random_image")){ $cs .= "<a class='tab' href='".make_link("random_image/view")."'>Random Image</a>";}
if($hw){ $cs .= "<a class='tab' href='".make_link("wiki/posts")."'>Help</a>"; if($hw){ $cs .= "<a class='tab' href='".make_link("wiki/posts")."'>Help</a>";
}else{ $cs .= "<a class='tab' href='".make_link("ext_doc/index")."'>Help</a>";} }else{ $cs .= "<a class='tab' href='".make_link("ext_doc/index")."'>Help</a>";}