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/link_image
ext/log_db
ext/mass_tagger
ext/news
ext/notes
ext/numeric_score
@ -62,6 +63,7 @@ ext/text_score
ext/tips
ext/twitter_soc
ext/upload_cmd
ext/update
ext/wiki
ext/word_filter
ext/zoom

View File

@ -35,16 +35,11 @@ class AdminBuildingEvent extends Event {
}
}
class AdminPage implements Extension {
var $theme;
class AdminPage extends SimpleExtension {
public function onPageRequest($event) {
global $page, $user;
public function get_priority() {return 50;}
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($event->page_matches("admin")) {
if(!$user->is_admin()) {
$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()) {
log_info("admin", "Util: {$_POST['action']}");
set_time_limit(0);
@ -91,18 +86,20 @@ class AdminPage implements Extension {
}
}
}
}
if($event instanceof AdminBuildingEvent) {
public function onAdminBuilding($event) {
global $page;
$this->theme->display_page($page);
$this->theme->display_form($page);
}
if($event instanceof UserBlockBuildingEvent) {
public function onUserBlockBuilding($event) {
global $user;
if($user->is_admin()) {
$event->add_link("Board Admin", make_link("admin"));
}
}
}
private function delete_by_query($query) {
global $page, $user;
@ -134,10 +131,8 @@ class AdminPage implements Extension {
}
private function dbdump($page) {
include "config.php";
$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];
$username = $matches[2];
$password = $matches[3];

View File

@ -915,7 +915,9 @@ class Artists implements Extension {
$artistID
));
for ($i = 0 ; $i < count($result) ; $i++)
$num = count($result);
for ($i = 0 ; $i < $num ; $i++)
{
$result[$i]["name"] = stripslashes($result[$i]["name"]);
}
@ -932,7 +934,9 @@ class Artists implements Extension {
$artistID
));
for ($i = 0 ; $i < count($result) ; $i++)
$num = count($result);
for ($i = 0 ; $i < $num ; $i++)
{
$result[$i]["url"] = stripslashes($result[$i]["url"]);
}
@ -1049,7 +1053,9 @@ class Artists implements Extension {
, $artistsPerPage
));
for ($i = 0 ; $i < count($listing) ; $i++)
$number_of_listings = count($listing);
for ($i = 0 ; $i < $number_of_listings ; $i++)
{
$listing[$i]["name"] = stripslashes($listing[$i]["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.
$table_rows = "";
for ($i = 0 ; $i < count($entries) ; $i++)
$num_entries = count($entries);
for ($i = 0 ; $i < $num_entries ; $i++)
{
/**
* Add table rows
@ -106,7 +107,8 @@ class BlotterTheme extends Themelet {
$html .= "<html><head><title>Blotter</title></head>
<body><pre>";
for ($i = 0 ; $i < count($entries) ; $i++)
$num_entries = count($entries);
for ($i = 0 ; $i < $num_entries ; $i++)
{
/**
* Blotter entries
@ -156,7 +158,8 @@ $(document).ready(function() {
});
//--></script>";
$entries_list = "";
for ($i = 0 ; $i < count($entries) ; $i++)
$num_entries = count($entries);
for ($i = 0 ; $i < $num_entries ; $i++)
{
/**
* Blotter entries
@ -175,8 +178,8 @@ $(document).ready(function() {
$in_text = "";
$pos_break = "";
$pos_align = "text-align: right; position: absolute; right: 0px;";
if($position == "left") { $pos_break = "<br />"; $pos_align = ""; }
if(count($entries) == 0) { $out_text = "No blotter entries yet."; $in_text = "Empty.";}
if($position === "left") { $pos_break = "<br />"; $pos_align = ""; }
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']));
$out_text = "Blotter updated: {$clean_date}";
$in_text = "<ul>$entries_list</ul>";

View File

@ -11,23 +11,19 @@
* message specified in the box.
*/
class Downtime implements Extension {
var $theme;
class Downtime extends SimpleExtension {
public function get_priority() {return 10;}
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 SetupBuildingEvent) {
public function onSetupBuilding($event) {
$sb = new SetupBlock("Downtime");
$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) {
public function onPageRequest($event) {
global $config, $page, $user;
if($config->get_bool("downtime")) {
if(!$user->is_admin() && !$this->is_safe_page($event)) {
$msg = $config->get_string("downtime_message");
@ -37,7 +33,6 @@ class Downtime implements Extension {
$this->theme->display_notification($page);
}
}
}
private function is_safe_page(PageRequestEvent $event) {
if($event->page_matches("user_admin/login")) return true;

View File

@ -6,7 +6,7 @@ class DowntimeTheme extends Themelet {
*/
public function display_notification(Page $page) {
$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>
<body>
<div id="downtime">
<h1>Down for Maintenance</h1>
<h1><center>Down for Maintenance</center></h1>
<div id="message">
$message
</div>

View File

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

View File

@ -5,7 +5,7 @@ class FeaturedTheme extends Themelet {
* Show $text on the $page
*/
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) {
@ -18,5 +18,25 @@ class FeaturedTheme extends Themelet {
</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) {
$binary = array();
for($j=0; $j<strlen($string); $j++) {
$length = strlen($string);
for($j=0; $j<$length; $j++) {
$c = ord($string[$j]);
for($i=7; $i>=0; $i--) {
$binary[] = ($c >> $i) & 0x01;

View File

@ -4,13 +4,14 @@ class MP3FileHandlerTheme extends Themelet {
public function display_image(Page $page, Image $image) {
$data_href = get_base_href();
$ilink = $image->get_image_link();
$fname = url_escape($image->filename); //Most of the time this will be the title/artist of the song.
$html = "
<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'
codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0'
width='400' height='15'>
<param name='movie' value='$data_href/ext/handle_mp3/xspf_player_slim.swf?song_url=$ilink'/>
<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'
width='400' height='15'
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]
[$base/comment/list|Comments]
[$base/tags|Tags]
[$base/wiki|Wiki]
[$base/wiki/more|&raquo;]');
[$base/ext_doc|&raquo;]');
}
public function onPageRequest(PageRequestEvent $event) {
@ -46,7 +45,8 @@ class Home extends SimpleExtension {
}
$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_choice_option("home_counter", $counters, "<br>Counter: ");
$event->panel->add_block($sb);
@ -67,13 +67,21 @@ class Home extends SimpleExtension {
$num_comma = number_format($total);
$counter_text = "";
for($n=0; $n<strlen($strtotal); $n++) {
$length = strlen($strtotal);
for($n=0; $n<$length; $n++) {
$cur = $strtotal[$n];
$counter_text .= " <img alt='$cur' src='$base_href/ext/home/counters/$counter_dir/$cur.gif' /> ";
}
// get the homelinks and process them
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 = preg_replace('#\[(.*?)\|(.*?)\]#', "<a href='\\1'>\\2</a>", $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>";
$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>";
$contact_link = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a> &ndash;";
$search_html = "
<div class='space' id='search'>
<form action='".make_link("post/list")."' method='GET'>
@ -47,7 +48,7 @@ EOD
$counter_html
<div class='space' id='foot'>
<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>
</small></small>
</div>

View File

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

View File

@ -34,24 +34,20 @@ class AddIPBanEvent extends Event {
}
// }}}
class IPBan implements Extension {
var $theme;
// event handler {{{
class IPBan extends SimpleExtension {
public function get_priority() {return 10;}
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 InitExtEvent) {
public function onInitExt($event) {
global $config;
if($config->get_int("ext_ipban_version") < 5) {
$this->install();
}
$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($event->get_arg(0) == "add" && $user->check_auth_token()) {
if(isset($_POST['ip']) && isset($_POST['reason']) && isset($_POST['end'])) {
@ -79,23 +75,26 @@ class IPBan implements Extension {
$this->theme->display_permission_denied($page);
}
}
}
if($event instanceof UserBlockBuildingEvent) {
public function onUserBlockBuilding($event) {
global $user;
if($user->is_admin()) {
$event->add_link("IP Bans", make_link("ip_ban/list"));
}
}
if($event instanceof AddIPBanEvent) {
public function onAddIPBan($event) {
global $user;
$this->add_ip_ban($event->ip, $event->reason, $event->end, $user);
}
if($event instanceof RemoveIPBanEvent) {
public function onRemoveIPBan($event) {
global $database;
$database->Execute("DELETE FROM bans WHERE id = :id", array("id"=>$event->id));
$database->cache->delete("ip_bans");
}
}
// }}}
// installer {{{
protected function install() {
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)";
$database->Execute($sql, array("ip"=>$ip, "reason"=>$reason, "end"=>strtotime($end), "admin_id"=>$user->id));
$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")) {
$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.
$sql = "SELECT * FROM images ";
$args = array();
//year
if(int_escape($event->get_arg(0)) == 0){
if(empty($_GET['year'])){
$year = date("Y");
}else{
$year = $event->get_arg(0);
$year = $_GET['year'];
}
//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");
}else{
$month = $event->get_arg(1);
$month = $_GET['month'];
}
//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");
}else{
$day = $event->get_arg(2);
$day = $_GET['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")){
$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 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")){
$sql .=
"WHERE EXTRACT(YEAR FROM posted) = :year
AND EXTRACT(MONTH FROM posted) = :month
"AND EXTRACT(MONTH FROM posted) = :month
AND NOT numeric_score=0
";
$sgra = array("month" => $month);
$args = array_merge($agrs, $sgra);
$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")){
$sql .=
"WHERE EXTRACT(YEAR FROM posted) = :year
AND NOT numeric_score=0
";
$dte = array($totaldate, $year, "Y", "year");
$sql .= "AND NOT numeric_score=0";
$dte = array($totaldate, $year, "\y\e\a\\r\=Y", "year");
$args = $agrs;
}
$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
$args = array(
"year" => $year,
"month" => $month,
"day" => $day,
"limit" => $t_images
);
$result = $database->get_all($sql, $args);
$images = array();
@ -185,7 +186,7 @@ class NumericScore implements Extension {
}
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) {
@ -206,8 +207,8 @@ class NumericScore implements Extension {
"Can't find the user named ".html_escape($matches[1]));
}
$event->add_querylet(new Querylet(
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=? AND score=1)",
array($duser->id)));
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=1)",
array("ns_user_id"=>$duser->id)));
}
if(preg_match("/^downvoted_by=(.*)$/", $event->term, $matches)) {
$duser = User::by_name($matches[1]);
@ -216,20 +217,20 @@ class NumericScore implements Extension {
"Can't find the user named ".html_escape($matches[1]));
}
$event->add_querylet(new Querylet(
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=? AND score=-1)",
array($duser->id)));
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=-1)",
array("ns_user_id"=>$duser->id)));
}
if(preg_match("/^upvoted_by_id=(\d+)$/", $event->term, $matches)) {
$iid = int_escape($matches[1]);
$event->add_querylet(new Querylet(
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=? AND score=1)",
array($iid)));
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=1)",
array("ns_user_id"=>$iid)));
}
if(preg_match("/^downvoted_by_id=(\d+)$/", $event->term, $matches)) {
$iid = int_escape($matches[1]);
$event->add_querylet(new Querylet(
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=? AND score=-1)",
array($iid)));
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=-1)",
array("ns_user_id"=>$iid)));
}
}
}
@ -239,8 +240,8 @@ class NumericScore implements Extension {
global $config;
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("CREATE INDEX images__numeric_score ON images(numeric_score)");
$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->create_table("numeric_score_votes", "
image_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);
}
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);
}
}
private function add_vote($image_id, $user_id, $score) {
global $database;
$database->Execute(
"DELETE FROM numeric_score_votes WHERE image_id=? AND user_id=?",
array($image_id, $user_id));
$database->execute(
"DELETE FROM numeric_score_votes WHERE image_id=:imageid AND user_id=:userid",
array("imageid" => $image_id, "userid" => $user_id));
if($score != 0) {
$database->Execute(
"INSERT INTO numeric_score_votes(image_id, user_id, score) VALUES(?, ?, ?)",
array($image_id, $user_id, $score));
$database->execute(
"INSERT INTO numeric_score_votes(image_id, user_id, score) VALUES(:imageid, :userid, :score)",
array("imageid" => $image_id, "userid" => $user_id, "score" => $score));
}
$database->Execute(
"UPDATE images SET numeric_score=(SELECT SUM(score) FROM numeric_score_votes WHERE image_id=?) WHERE id=?",
array($image_id, $image_id));
"UPDATE images SET numeric_score=(SELECT SUM(score) FROM numeric_score_votes WHERE image_id=:imageid) WHERE id=:id",
array("imageid" => $image_id, "id" => $image_id));
}
}
?>

View File

@ -67,8 +67,8 @@ class NumericScoreTheme extends Themelet {
'</span>';
}
$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])))));
$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])))));
$html = '<center><h3><a href="'.$b_dte.'">&laquo;</a> '.$dte[1]
.' <a href="'.$f_dte.'">&raquo;</a>'

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

@ -93,13 +93,13 @@ class PrivMsg extends SimpleExtension {
switch($event->get_arg(0)) {
case "read":
$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)) {
$this->theme->display_error($page, "No such PM", "There is no PM #$pm_id");
}
else if(($pm["to_id"] == $user->id) || $user->is_admin()) {
$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));
}
else {
@ -109,12 +109,12 @@ class PrivMsg extends SimpleExtension {
case "delete":
if($user->check_auth_token()) {
$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)) {
$this->theme->display_error($page, "No such PM", "There is no PM #$pm_id");
}
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");
$page->set_mode("redirect");
$page->set_redirect($_SERVER["HTTP_REFERER"]);
@ -146,9 +146,9 @@ class PrivMsg extends SimpleExtension {
INSERT INTO private_message(
from_id, from_ip, to_id,
sent_date, subject, message)
VALUES(?, ?, ?, now(), ?, ?)",
array($event->pm->from_id, $event->pm->from_ip,
$event->pm->to_id, $event->pm->subject, $event->pm->message)
VALUES(:fromid, :fromip, :toid, now(), :subject, :message)",
array("fromid" => $event->pm->from_id, "fromip" => $event->pm->from_ip,
"toid" => $event->pm->to_id, "subject" => $event->pm->subject, "message" => $event->pm->message)
);
log_info("pm", "Sent PM to User #{$event->pm->to_id}");
}
@ -161,8 +161,8 @@ class PrivMsg extends SimpleExtension {
SELECT private_message.*,user_from.name AS from_name
FROM private_message
JOIN users AS user_from ON user_from.id=from_id
WHERE to_id = ?
", array($user->id));
WHERE to_id = :toid",
array("toid" => $user->id));
$pms = array();
foreach($arr as $pm) {
$pms[] = new PM($pm);

View File

@ -2,7 +2,26 @@
class RandomImageTheme extends Themelet {
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)) {
$sqes = $matches[1];
$arr = array();
for($i=0; $i<strlen($sqes); $i++) {
$length = strlen($sqes);
for($i=0; $i<$length; $i++) {
$arr[] = "'" . $sqes[$i] . "'";
}
$set = join(', ', $arr);
@ -157,7 +158,8 @@ class Ratings implements Extension {
public static function privs_to_sql($sqes) {
$arr = array();
for($i=0; $i<strlen($sqes); $i++) {
$length = strlen($sqes);
for($i=0; $i<$length; $i++) {
$arr[] = "'" . $sqes[$i] . "'";
}
$set = join(', ', $arr);

View File

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

View File

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

View File

@ -5,17 +5,12 @@
* Description: Keep a record of tag changes, and allows you to revert changes.
*/
class Tag_History implements Extension {
var $theme;
class Tag_History extends SimpleExtension {
// in before tags are actually set, so that "get current tags" works
public function get_priority() {return 40;}
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 InitExtEvent)) {
public function onInitExtEvent($event) {
global $config;
$config->set_default_int("history_limit", -1);
// shimmie is being installed so call install to create the table.
@ -24,10 +19,10 @@ class Tag_History implements Extension {
}
}
if(($event instanceof AdminBuildingEvent))
{
if(isset($_POST['revert_ip']) && $user->is_admin() && $user->check_auth_token())
{
public function onAdminBuildingEvent($event) {
global $user;
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) {
@ -43,7 +38,8 @@ class Tag_History implements Extension {
$this->theme->display_admin_block('Invalid Date');
return;
}
} else {
}
else {
$revert_date = null;
}
@ -54,23 +50,24 @@ class Tag_History implements Extension {
// output results
$this->theme->display_revert_ip_results();
}
else
{
else {
$this->theme->display_admin_block(); // add a block to the admin panel
}
}
if (($event instanceof PageRequestEvent) && ($event->page_matches("tag_history")))
{
if($event->get_arg(0) == "revert")
{
public function onPageRequest($event) {
global $config, $page, $user;
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
if($config->get_bool("tag_edit_anon") || !$user->is_anonymous()) {
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
$image_id = int_escape($event->get_arg(0));
$this->theme->display_history_page($page, $image_id, $this->get_tag_history_from_id($image_id));
@ -79,18 +76,20 @@ class Tag_History implements Extension {
$this->theme->display_global_page($page, $this->get_global_tag_history());
}
}
}
if(($event instanceof DisplayingImageEvent))
{
public function onDisplayingImage($event) {
global $page;
// handle displaying a link on the view page
$this->theme->display_history_link($page, $event->image->id);
}
if(($event instanceof ImageDeletionEvent))
{
public function onImageDeletion($event) {
// handle removing of history when an image is deleted
$this->delete_all_tag_history($event->image->id);
}
if(($event instanceof SetupBuildingEvent)) {
public function onSetupBuilding($event) {
$sb = new SetupBlock("Tag History");
$sb->add_label("Limit to ");
$sb->add_int_option("history_limit");
@ -98,15 +97,17 @@ class Tag_History implements Extension {
$sb->add_label("<br>(-1 for unlimited)");
$event->panel->add_block($sb);
}
if(($event instanceof TagSetEvent)) {
public function onTagSetEvent($event) {
$this->add_tag_history($event->image, $event->tags);
}
if($event instanceof UserBlockBuildingEvent) {
public function onUserBlockBuilding($event) {
global $user;
if($user->is_admin()) {
$event->add_link("Tag Changes", make_link("tag_history"));
}
}
}
protected function install()
{
@ -250,6 +251,18 @@ class Tag_History implements Extension {
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.
*/

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,22 +6,21 @@
* Description: Simple search and replace
*/
class WordFilter implements Extension {
class WordFilter extends SimpleExtension {
// before emoticon filter
public function get_priority() {return 40;}
public function receive_event(Event $event) {
if($event instanceof TextFormattingEvent) {
public function onTextFormatting($event) {
$event->formatted = $this->filter($event->formatted);
$event->stripped = $this->filter($event->stripped);
}
if(($event instanceof SetupBuildingEvent)) {
public function onSetupBuilding($event) {
$sb = new SetupBlock("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)");
$event->panel->add_block($sb);
}
}
private function filter($text) {
$map = $this->get_map();

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
require_once "compat.inc.php";
/** @privatesection */
// Querylet {{{
class Querylet {
@ -56,7 +54,7 @@ class DBEngine {
}
public function create_table_sql($name, $data) {
return "CREATE TABLE $name ($data)";
return 'CREATE TABLE '.$name.' ('.$data.')';
}
}
class MySQL extends DBEngine {
@ -82,12 +80,16 @@ class MySQL extends DBEngine {
public function create_table_sql($name, $data) {
$data = $this->scoreql_to_sql($data);
$ctes = "ENGINE=InnoDB DEFAULT CHARSET='utf8'";
return "CREATE TABLE $name ($data) $ctes";
return 'CREATE TABLE '.$name.' ('.$data.') '.$ctes;
}
}
class PostgreSQL extends DBEngine {
var $name = "pgsql";
public function init($db) {
$db->query("SET application_name TO 'shimmie [{$_SERVER['REMOTE_ADDR']}]';");
}
public function scoreql_to_sql($data) {
$data = str_replace("SCORE_AIPK", "SERIAL PRIMARY KEY", $data);
$data = str_replace("SCORE_INET", "INET", $data);
@ -103,7 +105,7 @@ class PostgreSQL extends DBEngine {
public function create_table_sql($name, $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();
if(preg_match("/INDEX\s*\((.*)\)/", $bit, $matches)) {
$col = $matches[1];
$extras .= "CREATE INDEX {$name}_{$col} on $name($col);";
$extras .= 'CREATE INDEX '.$name.'_'.$col.' on '.$name($col).';';
}
else {
$cols[] = $bit;
}
}
$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;
public function __construct($args) {
$hp = split(":", $args);
$hp = explode(":", $args);
if(class_exists("Memcache")) {
$this->memcache = new Memcache;
@$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("/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_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);
if($db_proto == "mysql") {
if($db_proto === "mysql") {
$this->engine = new MySQL();
}
else if($db_proto == "pgsql") {
else if($db_proto === "pgsql") {
$this->engine = new PostgreSQL();
}
else if($db_proto == "sqlite") {
else if($db_proto === "sqlite") {
$this->engine = new SQLite();
}
else {
die("Unknown PDO driver: $db_proto");
die('Unknown PDO driver: '.$db_proto);
}
$matches = array();
@ -326,14 +330,15 @@ class Database {
*/
public function execute($query, $args=array()) {
try {
_count_execs($this->db, $query, $args);
$stmt = $this->db->prepare($query);
if (!array_key_exists(0, $args)) {
foreach($args as $name=>$value) {
if(is_numeric($value)) {
$stmt->bindValue(":$name", $value, PDO::PARAM_INT);
$stmt->bindValue(':'.$name, $value, PDO::PARAM_INT);
}
else {
$stmt->bindValue(":$name", $value, PDO::PARAM_STR);
$stmt->bindValue(':'.$name, $value, PDO::PARAM_STR);
}
}
$stmt->execute();
@ -344,8 +349,8 @@ class Database {
return $stmt;
}
catch(PDOException $pdoe) {
print "Message: ".$pdoe->getMessage();
print "<p>Error: $query";
print 'Message: '.$pdoe->getMessage();
print '<p>Error: '.$query;
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() {
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() {
$search_terms = array();
if($this->count_args() == 2) {
if($this->count_args() === 2) {
$search_terms = explode(' ', $this->get_arg(0));
}
return $search_terms;
}
public function get_page_number() {
$page_number = 1;
if($this->count_args() == 1) {
if($this->count_args() === 1) {
$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));
}
if($page_number == 0) $page_number = 1; // invalid -> 0
if($page_number === 0) $page_number = 1; // invalid -> 0
return $page_number;
}
public function get_page_size() {

View File

@ -92,6 +92,9 @@ abstract class SimpleExtension implements Extension {
var $theme;
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) {
$this->_child = $child;
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;
$_fh_last_opts = null;
require_once "lib/flexihash.php";
/**
* 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,
@ -196,12 +198,12 @@ class Image {
}
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 {
$tags[] = "id$gtlt{$this->id}";
$tags[] = 'id'. $gtlt . $this->id;
$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);
}
@ -251,8 +253,14 @@ class Image {
*/
public function get_image_link() {
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)) {
return $this->parse_link_template(make_link('_images/$hash/$id - $tags.$ext'));
@ -280,8 +288,14 @@ class Image {
*/
public function get_thumb_link() {
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)) {
return $this->parse_link_template(make_link('_thumbs/$hash/thumb.jpg'));
@ -338,8 +352,8 @@ class Image {
*/
public function get_mime_type() {
$type = strtolower($this->ext);
if($type == "jpg") $type = "jpeg";
return "image/$type";
if($type === "jpg") $type = "jpeg";
return 'image/'.$type;
}
/**
@ -379,7 +393,7 @@ class Image {
public function set_locked($tf) {
global $database;
$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);
if($sln != $this->locked) {
@ -458,7 +472,7 @@ class Image {
global $database;
$this->delete_tags_from_image();
$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_thumb_filename());
@ -469,7 +483,7 @@ class Image {
* It DOES NOT remove anything from the database.
*/
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_thumb_filename());
}
@ -522,7 +536,6 @@ class Image {
if($opts != $_fh_last_opts) {
$_fh_last_opts = $opts;
require_once("lib/flexihash.php");
$_flexihash = new Flexihash();
foreach(explode(",", $opts) as $opt) {
$parts = explode("=", $opt);
@ -550,7 +563,7 @@ class Image {
private static function build_search_querylet($terms) {
assert(is_array($terms));
global $database;
if($database->engine->name == "mysql")
if($database->engine->name === "mysql")
return Image::build_ugly_search_querylet($terms);
else
return Image::build_accurate_search_querylet($terms);
@ -593,7 +606,7 @@ class Image {
// various types of querylet
foreach($terms as $term) {
$positive = true;
if(strlen($term) > 0 && $term[0] == '-') {
if(is_string($term) && !empty($term) && ($term[0] == '-')) {
$positive = false;
$term = substr($term, 1);
}
@ -641,7 +654,7 @@ class Image {
if(count($tag_querylets) == 0) {
$query = new Querylet("SELECT images.* FROM images ");
if(strlen($img_search->sql) > 0) {
if(!empty($img_search->sql)) {
$query->append_sql(" WHERE ");
$query->append($img_search);
}
@ -658,7 +671,7 @@ class Image {
)
"), array("tag"=>$tag_querylets[0]->tag));
if(strlen($img_search->sql) > 0) {
if(!empty($img_search->sql)) {
$query->append_sql(" AND ");
$query->append($img_search);
}
@ -760,7 +773,7 @@ class Image {
// turn each term into a specific type of querylet
foreach($terms as $term) {
$negative = false;
if((strlen($term) > 0) && ($term[0] == '-')) {
if( !empty($term) && ($term[0] == '-')) {
$negative = true;
$term = substr($term, 1);
}
@ -789,11 +802,13 @@ class Image {
foreach($tag_querylets as $tq) {
global $tag_n;
$sign = $tq->positive ? "+" : "-";
$sql .= " $sign (tag LIKE :tag$tag_n)";
$terms["tag$tag_n"] = $tq->tag;
//$sql .= " $sign (tag LIKE :tag$tag_n)";
$sql .= ' '.$sign.' (tag LIKE :tag'.$tag_n.')';
//$terms["tag$tag_n"] = $tq->tag;
$terms['tag'.$tag_n] = $tq->tag;
$tag_n++;
if($sign == "+") $positive_tag_count++;
if($sign === "+") $positive_tag_count++;
else $negative_tag_count++;
}
$tag_search = new Querylet($sql, $terms);
@ -815,14 +830,14 @@ class Image {
if($positive_tag_count + $negative_tag_count == 0) {
$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($img_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(
// 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 ?) ",
@ -836,7 +851,7 @@ class Image {
",
$tag_search->variables);
if(strlen($img_search->sql) > 0) {
if(!empty($img_search->sql)) {
$query->append_sql(" AND ");
$query->append($img_search);
}
@ -858,24 +873,24 @@ class Image {
if($tags_ok) {
$tag_id_list = join(', ', $tag_id_array);
$subquery = new Querylet("
SELECT images.*, SUM({$tag_search->sql}) AS score
$subquery = new Querylet('
SELECT images.*, SUM('.$tag_search->sql.') AS score
FROM images
LEFT JOIN image_tags ON image_tags.image_id = images.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
HAVING score = :score",
HAVING score = :score',
array_merge(
$tag_search->variables,
array("score"=>$positive_tag_count)
)
);
$query = new Querylet("
$query = new Querylet('
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($img_search);
}
@ -921,15 +936,15 @@ class Tag {
if(is_string($tags)) {
$tags = explode(' ', $tags);
}
else if(is_array($tags)) {
//else if(is_array($tags)) {
// do nothing
}
//}
$tags = array_map("trim", $tags);
$tag_array = array();
foreach($tags as $tag) {
if(is_string($tag) && strlen($tag) > 0) {
if(is_string($tag) && !empty($tag)) {
$tag_array[] = $tag;
}
}
@ -946,13 +961,13 @@ class Tag {
public static function implode($tags) {
assert(is_string($tags) || is_array($tags));
if(is_string($tags)) {
// do nothing
}
else if(is_array($tags)) {
if(is_array($tags)) {
sort($tags);
$tags = implode(' ', $tags);
}
//else if(is_string($tags)) {
// do nothing
//}
return $tags;
}

View File

@ -225,8 +225,8 @@ class Page {
print $this->data;
break;
case "redirect":
header("Location: {$this->redirect}");
print "You should be redirected to <a href='{$this->redirect}'>{$this->redirect}</a>";
header('Location: '.$this->redirect);
print 'You should be redirected to <a href="'.$this->redirect.'">'.$this->redirect.'</a>';
break;
default:
print "Invalid page mode";
@ -242,22 +242,22 @@ class Page {
// caching failed, add all files to html_headers.
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");
if($css_files) {
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) {
$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");
if($js_files) {
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
$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 {
// Caching of CSS disabled.
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");
if($css_files) {
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
$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 {
// Caching of Javascript disabled.
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");
if($js_files) {
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) {
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";
}
else {
@ -53,12 +53,12 @@ class User {
public static function by_id(/*int*/ $id) {
assert(is_numeric($id));
global $database;
if($id == 1) {
$cached = $database->cache->get("user-id:$id");
if($id === 1) {
$cached = $database->cache->get('user-id:'.$id);
if($cached) return new User($cached);
}
$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);
}
@ -98,7 +98,7 @@ class User {
*/
public function is_anonymous() {
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() {
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;
$yn = $admin ? 'Y' : 'N';
$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) {
global $database;
$hash = md5(strtolower($this->name) . $password);
$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) {
global $database;
$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() {
// FIXME: configurable
global $config;
if($config->get_string("avatar_host") == "gravatar") {
if($config->get_string("avatar_host") === "gravatar") {
if(!empty($this->email)) {
$hash = md5(strtolower($this->email));
$s = $config->get_string("avatar_gravatar_size");
@ -173,14 +173,14 @@ class User {
*/
public function get_auth_token() {
global $config;
$salt = file_get_contents("config.php");
$salt = DATABASE_DSN;
$addr = get_session_ip($config);
return md5(md5($this->passhash . $addr) . "salty-csrf-" . $salt);
}
public function get_auth_html() {
$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() {

View File

@ -21,6 +21,10 @@ function html_escape($input) {
* @retval int
*/
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;
}
@ -56,13 +60,13 @@ function sql_escape($input) {
function bool_escape($input) {
$input = strtolower($input);
return (
$input == "y" ||
$input == "yes" ||
$input == "t" ||
$input == "true" ||
$input == "on" ||
$input == 1 ||
$input == true
$input === "y" ||
$input === "yes" ||
$input === "t" ||
$input === "true" ||
$input === "on" ||
$input === 1 ||
$input === true
);
}
@ -86,7 +90,7 @@ function parse_shorthand_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];
if (isset($m[2])) {
switch(strtolower($m[2])) {
@ -118,7 +122,7 @@ function to_shorthand_int($int) {
return sprintf("%.1fKB", $int / 1024);
}
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;
}
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 *
@ -207,24 +222,24 @@ function make_link($page=null, $query=null) {
if(NICE_URLS || $config->get_bool('nice_urls', false)) {
#$full = "http://" . $_SERVER["SERVER_NAME"] . $_SERVER["PHP_SELF"];
$full = $_SERVER["PHP_SELF"];
$base = str_replace("/index.php", "", $full);
$base = str_replace("/".basename($_SERVER["SCRIPT_FILENAME"]), "", $full);
}
else {
$base = "./index.php?q=";
$base = "./".basename($_SERVER["SCRIPT_FILENAME"])."?q=";
}
if(is_null($query)) {
return str_replace("//", "/", "$base/$page");
return str_replace("//", "/", $base.'/'.$page );
}
else {
if(strpos($base, "?")) {
return "$base/$page&$query";
return $base .'/'. $page .'&'. $query;
}
else if(strpos($query, "#") === 0) {
return "$base/$page$query";
return $base .'/'. $page . $query;
}
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="") {
global $user;
$auth = $user->get_auth_html();
$extra = empty($form_id) ? '' : " id='$form_id'";
$extra = empty($form_id) ? '' : 'id="'. $form_id .'"';
if($multipart) {
$extra .= " enctype='multipart/form-data'";
}
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) {
global $config;
$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
*/
function _version_check() {
if(version_compare(PHP_VERSION, "5.0.0") == -1) {
if(version_compare(PHP_VERSION, "5.2.6") == -1) {
print "
Currently SCore Engine doesn't support versions of PHP lower than 5.0.0 --
PHP4 and earlier are officially dead according to their creators,
please tell your host to upgrade.
Currently SCore Engine doesn't support versions of PHP lower than 5.2.6 --
if your web host is running an older version, they are dangerously out of
date and you should plan on moving elsewhere.
";
exit;
}
@ -409,10 +424,10 @@ function check_cli() {
*/
function _count_execs($db, $sql, $inputarray) {
global $_execs;
if(DEBUG) {
if((DEBUG_SQL === true) || (is_null(DEBUG_SQL) && @$_GET['DEBUG_SQL'])) {
$fp = @fopen("data/sql.log", "a");
if($fp) {
if(is_array($inputarray)) {
if(isset($inputarray) && is_array($inputarray)) {
fwrite($fp, preg_replace('/\s+/msi', ' ', $sql)." -- ".join(", ", $inputarray)."\n");
}
else {
@ -443,12 +458,12 @@ function _count_execs($db, $sql, $inputarray) {
*/
function get_theme_object(Extension $class, $fatal=true) {
$base = get_class($class);
if(class_exists("Custom{$base}Theme")) {
$class = "Custom{$base}Theme";
if(class_exists('Custom'.$base.'Theme')) {
$class = 'Custom'.$base.'Theme';
return new $class();
}
elseif ($fatal || class_exists("{$base}Theme")) {
$class = "{$base}Theme";
elseif ($fatal || class_exists($base.'Theme')) {
$class = $base.'Theme';
return new $class();
} else {
return false;
@ -552,14 +567,14 @@ function get_base_href() {
$possible_vars = array('SCRIPT_NAME', 'PHP_SELF', 'PATH_INFO', 'ORIG_PATH_INFO');
$ok_var = null;
foreach($possible_vars as $var) {
if(substr($_SERVER[$var], -4) == '.php') {
if(substr($_SERVER[$var], -4) === '.php') {
$ok_var = $_SERVER[$var];
break;
}
}
assert(!empty($ok_var));
$dir = dirname($ok_var);
if($dir == "/" || $dir == "\\") $dir = "";
if($dir === "/" || $dir === "\\") $dir = "";
return $dir;
}
@ -579,10 +594,10 @@ function warehouse_path(/*string*/ $base, /*string*/ $hash, /*bool*/ $create=tru
$ab = substr($hash, 0, 2);
$cd = substr($hash, 2, 2);
if(WH_SPLITS == 2) {
$pa = "$base/$ab/$cd/$hash";
$pa = $base.'/'.$ab.'/'.$cd.'/'.$hash;
}
else {
$pa = "$base/$ab/$hash";
$pa = $base.'/'.$ab.'/'.$hash;
}
if($create && !file_exists(dirname($pa))) mkdir(dirname($pa), 0755, true);
return $pa;
@ -841,6 +856,12 @@ function get_debug_info() {
else {
$i_mem = "???";
}
if($config->get_string("commit_hash") == ""){
$commit = "";
}else{
$commit = " (".$config->get_string("commit_hash").")";
}
$time = sprintf("%5.2f", microtime(true) - $_load_start);
$i_files = count(get_included_files());
$hits = $database->cache->get_hits();
@ -850,7 +871,7 @@ function get_debug_info() {
$debug .= "; Used $i_files files and $_execs queries";
$debug .= "; Sent $_event_count events";
$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;
}
@ -914,6 +935,10 @@ function _stripslashes_r($arr) {
}
function _sanitise_environment() {
if(TIMEZONE) {
date_default_timezone_set(TIMEZONE);
}
if(DEBUG) {
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 /
*
@ -938,7 +1077,8 @@ function _sanitise_environment() {
*/
function _decaret($str) {
$out = "";
for($i=0; $i<strlen($str); $i++) {
$length = strlen($str);
for($i=0; $i<$length; $i++) {
if($str[$i] == "^") {
$i++;
if($str[$i] == "^") $out .= "^";
@ -985,7 +1125,7 @@ function _get_page_request() {
global $config;
$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'));
}
@ -1074,7 +1214,7 @@ function _start_cache() {
}
else {
header("Content-type: text/html");
header("Last-Modified: $gmdate_mod");
header('Last-Modified: '.$gmdate_mod);
$zdata = @file_get_contents($_cache_filename);
if(CACHE_MEMCACHE) {
$_cache_memcache->set($_cache_hash, $zdata, 0, 600);
@ -1119,11 +1259,14 @@ function _start_coverage() {
function _end_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;
$t = time();
while(file_exists("data/coverage/$t.$n.log")) $n++;
file_put_contents("data/coverage/$t.$n.log", serialize(xdebug_get_code_coverage()));
while(file_exists("$absolute_path/$t.$n.log")) $n++;
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") {
if($user->is_admin()) {
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']);
$page->set_mode("redirect");
@ -103,12 +103,12 @@ class AliasEditor extends SimpleExtension {
public function onAddAlias(AddAliasEvent $event) {
global $database;
$pair = array($event->oldtag, $event->newtag);
if($database->get_row("SELECT * FROM aliases WHERE oldtag=? AND lower(newtag)=lower(?)", $pair)) {
$pair = array("oldtag" => $event->oldtag, "newtag" => $event->newtag);
if($database->get_row("SELECT * FROM aliases WHERE oldtag=:oldtag AND lower(newtag)=lower(:newtag)", $pair)) {
throw new AddAliasException("That alias already exists");
}
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}");
}
}
@ -134,7 +134,7 @@ class AliasEditor extends SimpleExtension {
foreach(explode("\n", $csv) as $line) {
$parts = explode(",", $line);
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]");
if($start === false) break;
$end = strpos($text, "[/code]");
$end = strpos($text, "[/code]", $start);
if($end === false) break;
$beginning = substr($text, 0, $start);
@ -173,5 +173,4 @@ class BBCode extends FormatterExtension {
return $text;
}
}
add_event_listener(new BBCode());
?>

View File

@ -61,7 +61,7 @@ class Comment {
}
class CommentList extends SimpleExtension {
public function onInitExt($event) {
public function onInitExt(InitExtEvent $event) {
global $config, $database;
$config->set_default_bool('comment_anon', true);
$config->set_default_int('comment_window', 5);
@ -114,7 +114,7 @@ class CommentList extends SimpleExtension {
public function onPageRequest(PageRequestEvent $event) {
global $page, $user;
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'])) {
try {
$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()) {
// FIXME: post, not args
if($event->count_args() == 3) {
if($event->count_args() === 3) {
send_event(new CommentDeletionEvent($event->get_arg(1)));
$page->set_mode("redirect");
if(!empty($_SERVER['HTTP_REFERER'])) {
@ -145,7 +145,7 @@ class CommentList extends SimpleExtension {
$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));
$this->build_page($page_num);
}
@ -297,7 +297,7 @@ class CommentList extends SimpleExtension {
}
// }}}
// get comments {{{
private function get_recent_comments() {
private function get_recent_comments($count) {
global $config;
global $database;
$rows = $database->get_all("
@ -310,7 +310,7 @@ class CommentList extends SimpleExtension {
LEFT JOIN users ON comments.owner_id=users.id
ORDER BY comments.id DESC
LIMIT :limit
", array("limit"=>$config->get_int('comment_count')));
", array("limit"=>$count));
$comments = array();
foreach($rows as $row) {
$comments[] = new Comment($row);
@ -369,14 +369,17 @@ class CommentList extends SimpleExtension {
global $database;
// 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'));
$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 >_<
$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']));
return (count($result) >= $max);

View File

@ -21,12 +21,12 @@ class CommentListTheme extends Themelet {
$next = $page_number + 1;
$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_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_heading("Comments");
@ -46,7 +46,7 @@ class CommentListTheme extends Themelet {
$comment_count = count($comments);
if($comment_limit > 0 && $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);
}
$this->anon_id = 1;
@ -68,14 +68,14 @@ class CommentListTheme extends Themelet {
}
}
$html = "
<table class='comment_list_table'><tr>
<td>$thumb_html</td>
<td>$comment_html</td>
$html = '
<table class="comment_list_table"><tr>
<td>'.$thumb_html.'</td>
<td>'.$comment_html.'</td>
</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;
$tfe = new TextFormattingEvent($comment->comment);
// 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);
$h_name = html_escape($comment->owner_name);
@ -154,23 +146,23 @@ class CommentListTheme extends Themelet {
$anoncode = "";
if($h_name == "Anonymous" && $this->anon_id >= 0) {
$anoncode = "<sup>{$this->anon_id}</sup>";
$anoncode = '<sup>'.$this->anon_id.'</sup>';
$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("\r", "\\r", $stripped_nonl);
$h_dellink = $user->is_admin() ?
"<br>($h_poster_ip, $h_timestamp, <a ".
"onclick=\"return confirm('Delete comment by $h_name:\\n$stripped_nonl');\" ".
"href='".make_link("comment/delete/$i_comment_id/$i_image_id")."'>Del</a>)" : "";
'<br>('.$h_poster_ip.', '.$h_timestamp.', <a '.
'onclick="return confirm(\'Delete comment by '.$h_name.':\\n'.$stripped_nonl.'\');" '.
'href="'.make_link('comment/delete/'.$i_comment_id.'/'.$i_image_id).'">Del</a>)' : '';
if($trim) {
return "
$h_userlink: $h_comment
<a href='".make_link("post/view/$i_image_id")."'>&gt;&gt;&gt;</a>
$h_dellink
";
return '
'.$h_userlink.': '.$h_comment.'
<a href="'.make_link('post/view/'.$i_image_id).'">&gt;&gt;&gt;</a>
'.$h_dellink.'
';
}
else {
//$avatar = "";
@ -179,14 +171,14 @@ class CommentListTheme extends Themelet {
// $avatar = "<img src=\"http://www.gravatar.com/avatar/$hash.jpg\"><br>";
//}
$oe = ($this->comments_shown++ % 2 == 0) ? "even" : "odd";
return "
<a name='$i_comment_id'></a>
<div class='$oe comment'>
<!--<span class='timeago' style='float: right;'>$h_timestamp</span>-->
$h_userlink: $h_comment
$h_dellink
return '
<a name="'.$i_comment_id.'"></a>
<div class="'.$oe.' comment">
<!--<span class="timeago" style="float: right;">'.$h_timestamp.'</span>-->
'.$h_userlink.': '.$h_comment.'
'.$h_dellink.'
</div>
";
';
}
}
@ -197,15 +189,15 @@ class CommentListTheme extends Themelet {
$hash = CommentList::get_hash();
$captcha = $config->get_bool("comment_captcha") ? captcha_get_html() : "";
return "
".make_form(make_link("comment/add"))."
<input type='hidden' name='image_id' value='$i_image_id' />
<input type='hidden' name='hash' value='$hash' />
<textarea name='comment' rows='5' cols='50'></textarea>
$captcha
<br><input type='submit' value='Post Comment' />
return '
'.make_form(make_link("comment/add")).'
<input type="hidden" name="image_id" value="'.$i_image_id.'" />
<input type="hidden" name="hash" value="'.$hash.'" />
<textarea name="comment" rows="5" cols="50"></textarea>
'.$captcha.'
<br><input type="submit" value="Post Comment" />
</form>
";
';
}
}
?>

View File

@ -25,12 +25,13 @@ class ExtensionInfo {
function ExtensionInfo($main) {
$matches = array();
$lines = file($main);
$number_of_lines = count($lines);
preg_match("#(ext|contrib)/(.*)/main.php#", $main, $matches);
$this->ext_name = $matches[2];
$this->name = $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];
if(preg_match("/Name: (.*)/", $line, $matches)) {
$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.
*/
class ImageIO extends SimpleExtension {
public function onInitExt($event) {
public function onInitExt(InitExtEvent $event) {
global $config;
$config->set_default_int('thumb_width', 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
}
public function onPageRequest($event) {
public function onPageRequest(PageRequestEvent $event) {
$num = $event->get_arg(0);
$matches = array();
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 $config;
@ -199,7 +199,7 @@ class ImageIO extends SimpleExtension {
}
}
public function onImageAddition($event) {
public function onImageAddition(ImageAdditionEvent $event) {
try {
$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();
}
public function onImageReplace($event) {
public function onImageReplace(ImageReplaceEvent $event) {
try {
$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 $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");
}
public function onSetupBuilding($event) {
public function onSetupBuilding(SetupBuildingEvent $event) {
$sb = new SetupBlock("Image Options");
$sb->position = 30;
// advanced only

View File

@ -129,14 +129,14 @@ class PostListBuildingEvent extends Event {
}
class Index extends SimpleExtension {
public function onInitExt($event) {
public function onInitExt(InitExtEvent $event) {
global $config;
$config->set_default_int("index_width", 3);
$config->set_default_int("index_height", 4);
$config->set_default_bool("index_tips", true);
}
public function onPageRequest($event) {
public function onPageRequest(PageRequestEvent $event) {
global $config, $database, $page, $user;
if($event->page_matches("post/list")) {
if(isset($_GET['search'])) {
@ -147,7 +147,7 @@ class Index extends SimpleExtension {
}
else {
$page->set_mode("redirect");
$page->set_redirect(make_link("post/list/$search/1"));
$page->set_redirect(make_link('post/list/'.$search.'/1'));
}
return;
}
@ -171,7 +171,7 @@ class Index extends SimpleExtension {
}
else if(count($search_terms) > 0 && count($images) == 1 && $page_number == 1) {
$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 {
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->position = 20;
@ -195,17 +195,18 @@ class Index extends SimpleExtension {
$event->panel->add_block($sb);
}
public function onSearchTermParse($event) {
public function onSearchTermParse(SearchTermParseEvent $event) {
$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];
$args = array("width"=>int_escape($matches[2]), "height"=>int_escape($matches[3]));
$event->add_querylet(new Querylet("width $cmp :width AND height $cmp :height", $args));
$tags = $matches[2];
$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)) {
$cmp = $matches[1];
$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)) {
$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)) {
$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)) {
$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)) {
$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)) {
$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];
$tags = $matches[2];
$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)"));
$args = array("width"=>int_escape($matches[2]), "height"=>int_escape($matches[3]));
$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) {
$text = <<<EOD
<div style="text-align: left;">
$text = "
<div style='text-align: left;'>
<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
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~
</div>
EOD;
";
$page->set_title("Welcome to Shimmie ".VERSION);
$page->set_heading("Welcome to Shimmie");
$page->add_block(new Block("Installation Succeeded!", $text, "main", 0));
@ -69,12 +69,12 @@ EOD;
$next = $page_number + 1;
$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_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_link = make_link();
@ -102,7 +102,7 @@ EOD;
</form>
<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) {

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

View File

@ -56,7 +56,7 @@ class LockSetEvent extends Event {
}
class TagEdit extends SimpleExtension {
public function onPageRequest($event) {
public function onPageRequest(PageRequestEvent $event) {
global $user, $page;
if($event->page_matches("tag_edit")) {
if($event->get_arg(0) == "replace") {
@ -71,8 +71,8 @@ class TagEdit extends SimpleExtension {
}
}
public function onImageInfoSet($event) {
global $user;
public function onImageInfoSet(ImageInfoSetEvent $event) {
global $user, $page;
if($this->can_tag($event->image)) {
send_event(new TagSetEvent($event->image, $_POST['tag_edit__tags']));
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;
if($user->is_admin() || !$event->image->is_locked()) {
$event->image->set_tags($event->tags);
}
}
public function onSourceSet($event) {
public function onSourceSet(SourceSetEvent $event) {
global $user;
if($user->is_admin() || !$event->image->is_locked()) {
$event->image->set_source($event->source);
}
}
public function onLockSet($event) {
public function onLockSet(LockSetEvent $event) {
global $user;
if($user->is_admin()) {
$event->image->set_locked($event->locked);
}
}
public function onImageDeletion($event) {
public function onImageDeletion(ImageDeletionEvent $event) {
$event->image->delete_tags_from_image();
}
public function onAdminBuilding($event) {
public function onAdminBuilding(AdminBuildingEvent $event) {
$this->theme->display_mass_editor();
}
// 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);
}
public function onImageInfoBoxBuilding($event) {
public function onImageInfoBoxBuilding(ImageInfoBoxBuildingEvent $event) {
global $user;
if($this->can_tag($event->image)) {
$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->add_bool_option("tag_edit_anon", "Allow anonymous tag editing: ");
$sb->add_bool_option("source_edit_anon", "<br>Allow anonymous source editing: ");

View File

@ -6,7 +6,7 @@
*/
class TagList extends SimpleExtension {
public function onInitExt($event) {
public function onInitExt(InitExtEvent $event) {
global $config;
$config->set_default_int("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);
}
public function onPageRequest($event) {
public function onPageRequest(PageRequestEvent $event) {
global $page, $database;
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;
if($config->get_int('tag_list_length') > 0) {
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;
if($config->get_int('tag_list_length') > 0) {
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->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: ");

View File

@ -45,7 +45,7 @@ class Upload extends SimpleExtension {
// early, so it can stop the DataUploadEvent before any data handlers see it
public function get_priority() {return 40;}
public function onInitExt($event) {
public function onInitExt(InitExtEvent $event) {
global $config;
$config->set_default_int('upload_count', 3);
$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;
if($this->can_upload($user)) {
if($this->is_full) {
@ -75,7 +75,7 @@ class Upload extends SimpleExtension {
}
}
public function onSetupBuilding($event) {
public function onSetupBuilding(SetupBuildingEvent $event) {
$tes = array();
$tes["Disabled"] = "none";
if(function_exists("curl_init")) {
@ -97,7 +97,7 @@ class Upload extends SimpleExtension {
$event->panel->add_block($sb);
}
public function onDataUpload($event) {
public function onDataUpload(DataUploadEvent $event) {
global $config;
if($this->is_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");
// Uploader 2.0!
$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;
$s=$i-1;
@ -243,7 +245,9 @@ class UploadTheme extends Themelet {
global $config;
$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'";
else $style = "style='display:none'";
$upload_list .= "<input size='10' ".

View File

@ -43,7 +43,7 @@ class UserCreationEvent extends Event {
class UserCreationException extends SCoreException {}
class UserPage extends SimpleExtension {
public function onInitExt(Event $event) {
public function onInitExt(InitExtEvent $event) {
global $config;
$config->set_default_bool("login_signup_enabled", true);
$config->set_default_int("login_memory", 365);
@ -54,7 +54,7 @@ class UserPage extends SimpleExtension {
$config->set_default_bool("login_tac_bbcode", true);
}
public function onPageRequest(Event $event) {
public function onPageRequest(PageRequestEvent $event) {
global $config, $database, $page, $user;
// 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));
if($event->count_args() == 0 && $user->is_anonymous()) {
$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;
$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;
$hosts = array(
@ -228,17 +228,17 @@ class UserPage extends SimpleExtension {
$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("Log Out", make_link("user_admin/logout"), 99);
}
public function onUserCreation(Event $event) {
public function onUserCreation(UserCreationEvent $event) {
$this->check_user_creation($event);
$this->create_user($event);
}
public function onSearchTermParse(Event $event) {
public function onSearchTermParse(SearchTermParseEvent $event) {
global $user;
$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) {
$h_name = html_escape($user->name);
$html = "Logged in as $h_name";
$html = 'Logged in as '.$h_name;
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));
}
@ -48,12 +48,12 @@ class UserPageTheme extends Themelet {
}
if(empty($tac)) {$html = "";}
else {$html = "<p>$tac</p>";}
else {$html = '<p>'.$tac.'</p>';}
$reca = "<tr><td colspan='2'>".captcha_get_html()."</td></tr>";
$html .= "
".make_form(make_link("user_admin/create"))."
$html .= '
'.make_form(make_link("user_admin/create"))."
<table style='width: 300px;'>
<tr><td>Name</td><td><input type='text' name='name'></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) {
global $config;
$html = "
".make_form(make_link("user_admin/login"))."
$html = '
'.make_form(make_link("user_admin/login"))."
<table summary='Login Form'>
<tr>
<td width='70'><label for='user'>Name</label></td>
@ -107,7 +107,7 @@ class UserPageTheme extends Themelet {
$html .= "<tr><td>Uploaded from: ";
$n = 0;
foreach($uploads as $ip => $count) {
$html .= "<br>$ip ($count)";
$html .= '<br>'.$ip.' ('.$count.')';
if(++$n >= 20) {
$html .= "<br>...";
break;
@ -117,7 +117,7 @@ class UserPageTheme extends Themelet {
$html .= "</td><td>Commented from:";
$n = 0;
foreach($comments as $ip => $count) {
$html .= "<br>$ip ($count)";
$html .= '<br>'.$ip.' ('.$count.')';
if(++$n >= 20) {
$html .= "<br>...";
break;
@ -133,10 +133,10 @@ class UserPageTheme extends Themelet {
public function display_user_page(User $duser, $stats) {
global $page, $user;
assert(is_array($stats));
$stats[] = "User ID: {$duser->id}";
$stats[] = 'User ID: '.$duser->id;
$page->set_title("{$duser->name}'s Page");
$page->set_heading("{$duser->name}'s Page");
$page->set_title($duser->name."'s Page");
$page->set_heading($duser->name."'s Page");
$page->add_block(new NavBlock());
$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;
}
require_once "config.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/default_config.inc.php";
require_once "core/util.inc.php";
require_once "lib/context.php";
// set up and purify the environment
if(CONTEXT) {
ctx_set_log(CONTEXT);
}
@ -101,77 +82,29 @@ try {
}
ctx_log_endok();
ctx_log_start("Connecting to DB");
// connect to the database
$database = new Database();
//$database->db->fnExecute = '_count_execs'; // FIXME: PDO equivalent
$database->db->beginTransaction();
$config = new DatabaseConfig($database);
ctx_log_endok();
ctx_log_start("Loading themelets");
// load the theme parts
ctx_log_start("Loading themelets");
$_theme = $config->get_string("theme", "default");
if(!file_exists("themes/$_theme")) $_theme = "default";
if(file_exists("themes/$_theme/custompage.class.php")) require_once "themes/$_theme/custompage.class.php";
require_once "themes/$_theme/layout.class.php";
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;
}
}
foreach(_get_themelet_files($_theme) as $themelet) {
require_once $themelet;
}
ctx_log_endok();
// 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);
}
}
_load_extensions();
ctx_log_endok("Initialisation");
ctx_log_start("Page generation");
// start the page generation waterfall
$page = class_exists("CustomPage") ? new CustomPage() : new Page();
$user = _get_user($config, $database);
$user = _get_user();
send_event(new InitExtEvent());
send_event(_get_page_request());
$page->display();
@ -182,22 +115,8 @@ try {
ctx_log_endok();
}
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();
_fatal_error($e);
ctx_log_ender();
}
?>

View File

@ -119,6 +119,7 @@ if(is_readable("config.php")) {
exit;
}
require_once "core/compat.inc.php";
require_once "core/util.inc.php";
require_once "core/database.class.php";
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'])) {
global $database_dsn;
$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();
}
else if(file_exists("auto_install.conf")) {
@ -362,9 +364,10 @@ function build_dirs() { // {{{
} // }}}
function write_config() { // {{{
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)) {
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 = '';
for($i = 0; $i < sizeof($files); ++$i) {
$file_size = sizeof($files);
for($i = 0; $i < $file_size; ++$i) {
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(' '));

View File

@ -142,7 +142,8 @@ class Layout {
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>";}
$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($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>";}

View File

@ -29,13 +29,13 @@ class Themelet {
*/
public function build_thumb_html(Image $image, $query=null) {
global $config;
$i_id = int_escape($image->id);
$h_view_link = make_link("post/view/$i_id", $query);
$i_id = (int) $image->id;
$h_view_link = make_link('post/view/'.$i_id, $query);
$h_thumb_link = $image->get_thumb_link();
// Removes the size tag if the file is an mp3
if($image->ext == 'mp3'){
if($image->ext === 'mp3'){
$iitip = $image->get_tooltip();
$mp3tip = array("0x0");
$h_tip = str_replace($mp3tip, " ", $iitip);
@ -53,21 +53,21 @@ class Themelet {
// 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')); }
else{
$tsize = get_thumbnail_size($image->width, $image->height); }
return "
return '
<!-- cancel border -->
<div class='thumbblock'>
<div class='thumb'>
<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'>
<div class="thumbblock">
<div class="thumb">
<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.'">
</a>
</div>
</div>
";
';
}
@ -81,8 +81,8 @@ class Themelet {
}
private function gen_page_link($base_url, $query, $page, $name) {
$link = make_link("$base_url/$page", $query);
return "<a href='$link'>$name</a>";
$link = make_link($base_url.'/'.$page, $query);
return '<a href="'.$link.'">'.$name.'</a>';
}
private function gen_page_link_block($base_url, $query, $page, $current_page, $name) {
@ -116,8 +116,8 @@ class Themelet {
}
$pages_html = implode(" | ", $pages);
return "<p class='paginator'>$first_html | $prev_html | $random_html | $next_html | $last_html".
"<br>&lt;&lt; $pages_html &gt;&gt;</p><!-- cancel border -->";
return '<p class="paginator">'.$first_html.' | '.$prev_html.' | '.$random_html.' | '.$next_html.' | '.$last_html
.'<br>&lt;&lt; '.$pages_html.' &gt;&gt;</p><!-- cancel border -->';
}
}
?>

View File

@ -96,8 +96,8 @@ class Layout {
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> ";}
$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>";
$cs .= "<a class='tab' href='".make_link('rss/images')."'>Feed</a>";
if(file_exists("ext/favorites")){ $cs .= "<a class='tab' href='".make_link("post/list/favorited_by=$username/1")."'>My Favorites</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($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>";}