SleepIsDeath/documentation/html/seedBlogs.php

4821 lines
144 KiB
PHP
Raw Permalink Normal View History

<?php
/*
* Modification History
*
* 2005-April-18 Jason Rohrer
* Created.
*
* 2005-July-26 Jason Rohrer
* Moved settings into a separate file.
*
* 2005-September-1 Jason Rohrer
* Added support for toggling permalinks.
*
* 2005-September-8 Jason Rohrer
* Improved some parameter names.
* Added fix for IE cookie clearing bug.
*
* 2005-September-18 Jason Rohrer
* Fixed several undefined variable notices.
*
* 2005-September-20 Jason Rohrer
* Added text formatting and pubDate fields to RSS feeds.
*
* 2005-November-14 Jason Rohrer
* Added version action.
* Changed behavior of story block formatting for headline-only lists.
* Fixed redirect behavior after login and register.
*
* 2005-November-21 Jason Rohrer
* Added [centerblock] tags for centering a left-aligned block of text.
*
* 2006-March-16 Jason Rohrer
* Removed check for existing session ID when resetting password.
* Added optional email notices to admins about pending items.
*
* 2006-August-10 Jason Rohrer
* Added sb_ prefix to all internal functions to prevent conflicts with other
* packages.
*
* 2006-September-21 Jason Rohrer
* Changed image alignment HTML.
*
* 2006-October-9 Jason Rohrer
* Fixed typo in admin letter. Added list of all pending posts.
* Added an Approve link when admin views a pending post.
* Fixed a bug in URL detection for link-only posts.
* Changed to support ordering by oldest-first, and switched comment ordering.
*
* 2007-May-29 Jason Rohrer
* Fixed warning generated by post queue.
*/
global $seedBlogs_version;
$seedBlogs_version = "0.2_in_progress";
// edit settings.php to change seedBlogs' settings
include( "sbSettings.php" );
// no end-user settings below this point
// enable verbose error reporting to detect uninitialized variables
error_reporting( E_ALL );
// page layout for web-based setup
$setup_header = "
<HTML>
<HEAD><TITLE>seedBlogs Web-based setup</TITLE></HEAD>
<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#0000FF VLINK=#FF0000>
<CENTER>
<TABLE WIDTH=75% BORDER=0 CELLSPACING=0 CELLPADDING=1>
<TR><TD BGCOLOR=#000000>
<TABLE WIDTH=100% BORDER=0 CELLSPACING=0 CELLPADDING=10>
<TR><TD BGCOLOR=#EEEEEE>";
$setup_footer = "
</TD></TR></TABLE>
</TD></TR></TABLE>
</CENTER>
</BODY></HTML>";
// set to 1 to force magic_quote behavior on all user-submitted data
// set to 0 to disable magic_quote behavior
// WARNING: setting $use_magic_quotes to 0 will make user-submitted
// data (for example, web form data) unsafe to pass directly
// into a MySQL database query.
$use_magic_quotes = 1;
if( get_magic_quotes_gpc() && !$use_magic_quotes ) {
// force magic quotes to be removed
$_GET = array_map( 'sb_stripslashes_deep', $_GET );
$_POST = array_map( 'sb_stripslashes_deep', $_POST );
$_REQUEST = array_map( 'sb_stripslashes_deep', $_REQUEST );
$_COOKIE = array_map( 'sb_stripslashes_deep', $_COOKIE );
}
else if( !get_magic_quotes_gpc() && $use_magic_quotes ) {
// force magic quotes to be added
$_GET = array_map( 'sb_addslashes_deep', $_GET );
$_POST = array_map( 'sb_addslashes_deep', $_POST );
$_REQUEST = array_map( 'sb_addslashes_deep', $_REQUEST );
$_COOKIE = array_map( 'sb_addslashes_deep', $_COOKIE );
}
// set to NULL so we can detect when we have set it on purpose
global $return_url;
$return_url = NULL;
// deal with cookies for logins
// ignore cookies if $loggedInID already set by another part of the script
global $loggedInID;
// set by the logout script to tell us to ignore cookies
global $justLoggedOut;
$cookieName = $tableNamePrefix . "cookie";
$cookie_user_id = "";
if( isset( $_COOKIE[ $cookieName ."_user_id" ] ) ) {
$cookie_user_id = $_COOKIE[ $cookieName ."_user_id" ];
}
$cookie_session_id = "";
if( isset( $_COOKIE[ $cookieName ."_session_id" ] ) ) {
$cookie_session_id = $_COOKIE[ $cookieName ."_session_id" ];
}
if( ! $justLoggedOut &&
strcmp( $loggedInID, "" ) == 0 ) { // $loggedInID not already set
$loggedInID = sb_getLoggedInUser();
if( strcmp( $loggedInID, "" ) != 0 ) {
// push the cookie expiration forward
sb_refreshCookie( $cookie_user_id, $cookie_session_id );
}
}
/**
* Displays either a login form or information about the currently logged-in
* user (along with a logout link).
*/
function seedBlogs_showLoginBox() {
global $loggedInID, $justLoggedOut, $tableNamePrefix;
// don't use global $return_url here
$return_url = sb_getReturnURL();
if( sb_getUserCount() == 0 ) {
// no registered users
// show link to register form
// use main site URL as return URL here
// This avoid redirecting the user back to sb_setup
global $mainSiteURL;
$encoded_return_url= urlencode( $mainSiteURL );
echo "[<A HREF=\"seedBlogs.php?action=show_register_form&".
"return_url=$encoded_return_url\">".
"Create Admin Account</A>]";
}
else if( $justLoggedOut || strcmp( $loggedInID, "" ) == 0 ) {
$encoded_return_url= urlencode( $return_url );
// show the login form
?>
<FORM ACTION="seedBlogs.php" METHOD="post">
<INPUT TYPE="hidden" NAME="action" VALUE="login">
<INPUT TYPE="hidden" NAME="return_url" VALUE="<?php echo $return_url;?>">
<TABLE BORDER=0>
<TR><TD>User ID:</TD>
<TD><INPUT TYPE="text" MAXLENGTH=20 SIZE=10 NAME="user_id"></TD></TR>
<TR><TD>Password:</TD>
<TD><INPUT TYPE="password" MAXLENGTH=20 SIZE=10 NAME="password"></TD></TR>
<TR><TD VALIGN=TOP>
[<A HREF="seedBlogs.php?action=show_register_form&return_url=<?php
echo $encoded_return_url; ?>">New Account</A>]</TD>
<TD ALIGN=RIGHT VALIGN=TOP><INPUT TYPE="Submit" VALUE="Log In"></TD><TR>
<TR><TD COLSPAN=2 VALIGN=TOP>
[<A HREF="seedBlogs.php?action=show_password_help_form">Forgot Password?</A>]</TD></TR>
</TABLE>
</FORM>
<?php
}
else {
$return_url = urlencode( $return_url );
// indicate which user is logged in
echo "Logged in as <B>" . sb_stripMagicQuotes( $loggedInID ) .
"</B><BR>\n";
echo "[<A HREF=\"seedBlogs.php?action=logout\">Log Out</A>] ";
echo "[<A HREF=\"seedBlogs.php?action=show_register_form&".
"return_url=$return_url\">".
"Edit Account</A>]\n";
if( sb_isAdministrator() ) {
// show a link to pending account queue, if any are pending
sb_connectToDatabase();
$query =
"SELECT COUNT(*) FROM $tableNamePrefix"."users ".
"WHERE approved = '0';";
$result = sb_queryDatabase( $query );
$pendingCount = mysql_result( $result, 0, 0 );
sb_closeDatabase();
if( $pendingCount > 0 ) {
$countString = "<B>$pendingCount</B> account requests";
if( $pendingCount == 1 ) {
$countString = "<B>$pendingCount</B> account request";
}
echo "<BR>[<A HREF=\"seedBlogs.php?action=show_account_queue".
"&return_url=$return_url\">" .
"$countString waiting</A>]";
}
// show a link to pending post queue, if any are waiting
sb_connectToDatabase();
$query =
"SELECT COUNT(*) FROM $tableNamePrefix"."posts ".
"WHERE approved = '0' AND removed = '0';";
$result = sb_queryDatabase( $query );
$pendingCount = mysql_result( $result, 0, 0 );
sb_closeDatabase();
if( $pendingCount > 0 ) {
$countString = "<B>$pendingCount</B> posts";
if( $pendingCount == 1 ) {
$countString = "<B>$pendingCount</B> post";
}
echo "<BR>[<A HREF=\"seedBlogs.php?action=show_post_queue".
"&blog_name=*&return_url=$return_url\">" .
"$countString pending approval</A>]";
}
echo "<BR>[<A HREF=\"seedBlogs.php?action=show_account_list".
"&return_url=$return_url\">" .
"Manage Accounts</A>]<BR>";
}
}
}
/**
* Displays the search box (used to search all seedBlogs).
*
* @param $inFieldWidth the width of the field, in characters.
* Defaults to 15.
* @param $inShowButton true to show the "Search" button, or false
* to hide it.
* Defaults to true.
*/
function seedBlogs_showSearchBox( $inFieldWidth = 15, $inShowButton = true ) {
// redisplay key words if they are present as POSTed variables
$key_words = "";
if( isset( $_REQUEST[ "key_words" ] ) ) {
$key_words =
sb_stripMagicQuotes(
sb_getRequestVariableRaw( "key_words" ) );
}
?>
<FORM ACTION="seedBlogs.php" METHOD="post">
<INPUT TYPE="hidden" NAME="action" VALUE="search">
<INPUT TYPE="text" MAXLENGTH=20 SIZE=<?php echo $inFieldWidth;?>
NAME="key_words"
VALUE="<?php echo htmlspecialchars( $key_words ); ?>">
<?php
if( $inShowButton ) {
echo "<INPUT TYPE=\"Submit\" VALUE=\"Search\">";
}
echo "</FORM>";
}
/**
* Displays a seed blog with default formatting options
*
* @param $inBlogName the name of the blog in the database. Should not
* contain spaces or special characters.
* @param $inShowIntroText 1 to show intro text under headlines, or 0 to
* show only headlines.
* @param $inShowAuthors (only applies if $inShowIntroText is 1) 1 to show
* the author of each post, or 0 to hide the authors.
* Defaults to 1.
* @param $inShowDates (only applies if $inShowIntroText is 1) 1 to show
* the creation date for each post, or 0 to hide the dates.
* Defaults to 1.
* @param $inOrder 1 to order by creation date with newest posts first,
* -1 to order by creation date with oldest posts first,
* 0 to order by expiration date with oldest posts first, or
* 2 to allow the administrators to tweak the ordering (up/down widgets
* will be displayed to allow admins to move posts up and down in the list).
* Defaults to 1.
* @param $inMaxNumber the maximum number of entries to show. -1 specifies
* no limit.
* Defaults to 10.
* @param $inNumToSkip the number of posts to skip, starting at the top
* of the list. Specifying 0 shows $inMaxNumber posts starting with the
* top post. Defaults to 0.
* @param $inShowArchive 1 to show the archive link, or 0 to hide it.
* Defaults to 1.
* @param $inShowSubmitLinkToPublic 1 to show a link for the public to submit
* posts, or 0 to hide the link.
* Defaults to 1.
*/
function seedBlog( $inBlogName,
$inShowIntroText,
$inShowAuthors = 1,
$inShowDates = 1,
$inOrder = 1,
$inMaxNumber = 10,
$inNumToSkip = 0,
$inShowArchive = 1,
$inShowSubmitLinkToPublic = 1 ) {
global $storyBlockFormatOpen, $storyBlockFormatClose,
$headlineFormatOpen, $headlineFormatClose, $textBlockFormatOpen,
$textBlockFormatClose, $storySeparator,
$linkStoryBlockFormatOpen, $linkStoryBlockFormatClose,
$linkHeadlineFormatOpen, $linkHeadlineFormatClose, $linkStorySeparator;
// pick from defaults depending on whether intro text is shown or not
$local_storyBlockFormatOpen = $linkStoryBlockFormatOpen;
$local_storyBlockFormatClose = $linkStoryBlockFormatClose;
$local_headlineFormatOpen = $linkHeadlineFormatOpen;
$local_headlineFormatClose = $linkHeadlineFormatClose;
$local_storySeparator = $linkStorySeparator;
if( $inShowIntroText ) {
$local_storyBlockFormatOpen = $storyBlockFormatOpen;
$local_storyBlockFormatClose = $storyBlockFormatClose;
$local_headlineFormatOpen = $headlineFormatOpen;
$local_headlineFormatClose = $headlineFormatClose;
$local_storySeparator = $storySeparator;
}
seedBlogFormatted( $inBlogName,
$inShowIntroText,
$inShowAuthors,
$inShowDates,
$inOrder,
$inMaxNumber,
$inNumToSkip,
$inShowArchive,
$inShowSubmitLinkToPublic,
$local_storyBlockFormatOpen,
$local_storyBlockFormatClose,
$local_headlineFormatOpen,
$local_headlineFormatClose,
$textBlockFormatOpen,
$textBlockFormatClose,
$local_storySeparator );
}
/**
* Displays a seed blog with customized formatting options.
*
* Parameters are the same as for the simpler call above, except:
* @param $inStoryBlockFormatOpen opening HTML used to format each story block.
* @param $inStoryBlockFormatClose closing HTML used to format each story
* block.
* @param $inHeadlineFormatOpen opening HTML used to format headlines.
* @param $inHeadlineFormatClose closing HTML used to format headlines.
* @param $inTextBlockFormatOpen opening HTML used to format the text of a
* post under the headline. Ignored if $inShowIntroText = 0.
* @param $inTextBlockFormatClose closing HTML used to format the text of a
* post under the headline. Ignored if $inShowIntroText = 0.
* @param $inStorySeparator HTML to insert between each story block in a story
* list.
*/
function seedBlogFormatted( $inBlogName,
$inShowIntroText,
$inShowAuthors,
$inShowDates,
$inOrder,
$inMaxNumber,
$inNumToSkip,
$inShowArchive,
$inShowSubmitLinkToPublic,
// formatting options:
$inStoryBlockFormatOpen,
$inStoryBlockFormatClose,
$inHeadlineFormatOpen,
$inHeadlineFormatClose,
$inTextBlockFormatOpen,
$inTextBlockFormatClose,
$inStorySeparator ) {
global $return_url;
if( $return_url == NULL ) {
$return_url = sb_getReturnURL();
$return_url = urlencode( $return_url );
}
// display link for posting new item
$postLinkName = "Submit";
$postLinkHint = "Submit a post into the approval queue";
$isCommentBlog = false;
if( preg_match( "/_comments/", $inBlogName ) ) {
$isCommentBlog = true;
$postLinkName = "Submit Comment";
$postLinkHint = "Submit a comment into the approval queue";
}
$allowPost = false;
global $loggedInID, $autoApprovePosts, $allowSubmissionsFromPublic;
global $tableNamePrefix;
if( strcmp( $loggedInID, "" ) != 0 ) {
if( $autoApprovePosts ||
sb_getUserDatabaseField( $loggedInID,
"administrator" ) == 1 ) {
// post, don't submit
$postLinkName = "New Post";
$postLinkHint = "Add a new post";
if( $isCommentBlog ) {
$postLinkName = "Post Comment";
$postLinkHint = "Add a new comment";
}
}
$allowPost = true;
}
else {
// no one logged in
if( $inShowSubmitLinkToPublic && $allowSubmissionsFromPublic ||
$isCommentBlog ) {
$allowPost = true;
}
}
if( $allowPost ) {
echo "[<A HREF=\"seedBlogs.php?action=edit_post&blog_name=$inBlogName".
"&return_url=$return_url\" TITLE=\"$postLinkHint\">" .
"$postLinkName</A>]<BR>";
}
if( sb_isAdministrator() ) {
// show link to queue, if there are posts wating
sb_connectToDatabase();
$query =
"SELECT COUNT(*) FROM $tableNamePrefix"."posts ".
"WHERE approved = \"0\" AND removed = \"0\" AND ".
"blog_name = \"$inBlogName\";";
$result = sb_queryDatabase( $query );
$pendingCount = mysql_result( $result, 0, 0 );
sb_closeDatabase();
if( $pendingCount > 0 ) {
$countString = "<B>$pendingCount</B> posts";
if( $pendingCount == 1 ) {
$countString = "<B>$pendingCount</B> post";
}
echo "[<A HREF=\"seedBlogs.php?action=show_post_queue".
"&blog_name=$inBlogName".
"&return_url=$return_url\">" .
"$countString in queue</A>]<BR>";
}
}
if( $inShowIntroText ) {
// extra space
//echo "<BR>";
}
// get blog posts from the database
$orderClause = "ORDER BY creation_date DESC";
if( $inOrder == 0 ) {
$orderClause = "ORDER BY expiration_date ASC";
}
if( $inOrder == -1 ) {
$orderClause = "ORDER BY creation_date ASC";
}
$limitNumber = $inMaxNumber;
if( $inMaxNumber == -1 ) {
// use a large number, as suggested in the MySQL docs, to cause
// limit to be ignored
$limitNumber = 99999;
}
// LIMIT is only supported by MySQL
$query =
"SELECT * " .
"FROM $tableNamePrefix"."posts " .
"WHERE approved = '1' AND removed = '0' ".
"AND blog_name = '$inBlogName' ".
"AND ( expiration_date > CURRENT_TIMESTAMP OR " .
"expiration_date IS NULL ) " .
"$orderClause LIMIT $inNumToSkip, $limitNumber;";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$numRows = mysql_numrows( $result );
if( $numRows == 0 ) {
echo "[no posts]<BR>";
}
$mapArray = NULL;
if( $inOrder == 2 ) {
// use map and ignore the above query
$mapQuery = "SELECT map FROM $tableNamePrefix"."order_map ".
"WHERE blog_name = '$inBlogName';";
sb_connectToDatabase();
$result = sb_queryDatabase( $mapQuery );
$mapRaw = "";
if( mysql_numrows( $result ) == 0 ) {
// no order_map entry yet for this blog
// insert a new map containing an empty string
$mapQuery = "INSERT INTO $tableNamePrefix"."order_map ".
"VALUES ( " .
"'$inBlogName', '' );";
sb_queryDatabase( $mapQuery );
}
else {
$mapRaw = mysql_result( $result, 0, 0 );
}
sb_closeDatabase();
$mapArrayRaw = preg_split( "/\s+/", $mapRaw );
// filter the map array to remove unapproved, removed, or expired
// post_ids
$map = "";
sb_connectToDatabase();
for( $i=0; $i<count( $mapArrayRaw ); $i++ ) {
$post_id = $mapArrayRaw[ $i ];
if( sb_isPostVisible( $post_id ) ) {
// post in map is visible
// add ID to our filtered map
if( strcmp( $map, "" ) == 0 ) {
$map = $post_id;
}
else {
$map = $map . "\n" . $post_id;
}
}
}
sb_closeDatabase();
// now split the filtered map to get our final array
$mapArray = preg_split( "/\s+/", $map );
if( strcmp( $map, "" ) == 0 ) {
// force an empty array;
$mapArray = array();
}
// reset numRows based on the size of our mapArray
$numRows = count( $mapArray ) - $inNumToSkip;
if( $inMaxNumber != -1 &&
$numRows > $inMaxNumber ) {
$numRows = $inMaxNumber;
}
}
// finally, display the posts, using either the query results or the
// map
for( $i=0; $i<$numRows; $i++ ) {
$subject_line = "";
$post_id = "";
$intro_text = "";
$body_text = "";
$user_id = "";
$date = "";
$allow_comments = "";
$show_permalink = "";
if( $mapArray == NULL ) {
// use the query results
$subject_line = mysql_result( $result, $i, "subject_line" );
$post_id = mysql_result( $result, $i, "post_id" );
$intro_text = mysql_result( $result, $i, "intro_text" );
$body_text = mysql_result( $result, $i, "body_text" );
$user_id = mysql_result( $result, $i, "user_id" );
$date = mysql_result( $result, $i, "creation_date" );
$allow_comments = mysql_result( $result, $i, "allow_comments" );
$show_permalink = mysql_result( $result, $i, "show_permalink" );
}
else {
// ignore query results
// re-query database according to map
$post_id = $mapArray[ $i + $inNumToSkip ];
$query =
"SELECT * " .
"FROM $tableNamePrefix"."posts " .
"WHERE post_id = '$post_id';";
sb_connectToDatabase();
$singleResult = sb_queryDatabase( $query );
sb_closeDatabase();
$subject_line = mysql_result( $singleResult, 0, "subject_line" );
$post_id = mysql_result( $singleResult, 0, "post_id" );
$intro_text = mysql_result( $singleResult, 0, "intro_text" );
$body_text = mysql_result( $singleResult, 0, "body_text" );
$user_id = mysql_result( $singleResult, 0, "user_id" );
$date = mysql_result( $singleResult, 0, "creation_date" );
$allow_comments =
mysql_result( $singleResult, 0, "allow_comments" );
$show_permalink =
mysql_result( $singleResult, 0, "show_permalink" );
}
// trim leading/trailing whitespace
$subject_line = trim( $subject_line );
$intro_text = trim( $intro_text );
$body_text = trim( $body_text );
if( $inShowIntroText ) {
$author = NULL;
if( $inShowAuthors ) {
$author = $user_id;
}
$dateString = NULL;
if( $inShowDates ) {
$dateString = $date;
}
$showUpDownWidgets =
( $inOrder == 2 && sb_isAdministrator() );
$index = $i + $inNumToSkip;
// show up widget if we are down from the top
$showUpWidget =
( $index > 0 ) &&
$showUpDownWidgets;
// show down widget if we are up from the bottom
$showDownWidget =
( $index < count( $mapArray ) - 1 ) &&
$showUpDownWidgets;
sb_generateStoryBlock( $inBlogName,
$post_id,
$subject_line,
$author,
$dateString,
$showUpWidget,
$showDownWidget,
$intro_text,
$body_text,
0, // show link to body text
$allow_comments,
$show_permalink,
$return_url,
// formatting options:
$inStoryBlockFormatOpen,
$inStoryBlockFormatClose,
$inHeadlineFormatOpen,
$inHeadlineFormatClose,
$inTextBlockFormatOpen,
$inTextBlockFormatClose );
}
else {
$linkTarget = "seedBlogs.php?action=display_post&".
"post_id=$post_id".
"&show_author=$inShowAuthors&show_date=$inShowDates";
$directURLTarget = false;
if( $intro_text != NULL && $body_text == NULL ) {
// we just have intro text and no body.
// check if the intro text contains just a URL
// intro text has already been trimmed of leading/trailing
// whitespace above
if( strstr( $intro_text, "http://" ) != false &&
strpos( $intro_text, "http://" ) == 0 &&
strstr( $intro_text, " " ) == false ) {
// intro text starts with URL and contains nothing else
// make a direct link
$linkTarget = trim( $intro_text );
$directURLTarget = true;
}
}
// open a story block for the headline
echo "$inStoryBlockFormatOpen";
// link around subject, with formatting inside link tags
echo "<A HREF=\"$linkTarget\">$inHeadlineFormatOpen".
"$subject_line".
"$inHeadlineFormatClose</A>";
if( $directURLTarget && sb_canEdit( $post_id ) ) {
// problem: clicking a direct URL link takes you to the URL
// and not the display page, so there is no
// way to edit the post.
// add a special edit link to these posts
echo " [<A HREF=\"seedBlogs.php?action=edit_post".
"&blog_name=$inBlogName".
"&post_id=$post_id&return_url=$return_url".
"&show_author=$inShowAuthors&show_date=$inShowDates\">" .
"Edit</A>]";
}
if( $inOrder == 2 && sb_isAdministrator() ) {
// show up/down widgets
$index = $i + $inNumToSkip;
$upShown = false;
if( $index > 0 ) {
echo " [<A HREF=\"seedBlogs.php?action=move_up".
"&blog_name=$inBlogName".
"&post_id=$post_id&return_url=$return_url\">" .
"Up</A>]";
$upShown = true;
}
if( $index < count( $mapArray ) - 1 ) {
if( ! $upShown ) {
// insert space to separate down widget from headline
echo " ";
}
echo "[<A HREF=\"seedBlogs.php?action=move_down".
"&blog_name=$inBlogName".
"&post_id=$post_id&return_url=$return_url\">" .
"Down</A>]";
}
}
echo "$inStoryBlockFormatClose";
}
if( $i < $numRows - 1 ) {
// separate from next story
echo "$inStorySeparator";
}
}
if( $inShowArchive ) {
// count total number of posts to see if we need the archive link
$postCount = 0;
if( $mapArray == NULL ) {
sb_connectToDatabase();
$query =
"SELECT COUNT(*) FROM $tableNamePrefix"."posts ".
"WHERE approved = '1' ".
"AND removed = '0' AND blog_name = '$inBlogName' " .
"AND ( expiration_date > CURRENT_TIMESTAMP OR " .
"expiration_date IS NULL );";
$result = sb_queryDatabase( $query );
$postCount = mysql_result( $result, 0, 0 );
sb_closeDatabase();
}
else {
$postCount = count( $mapArray );
}
$numOlderPosts = $postCount - ( $inNumToSkip + $numRows );
if( $numOlderPosts > 0 ) {
// there are more posts in the archive
if( $inShowIntroText ) {
// extra space
echo "<BR><BR>";
}
// archive pages have 10 posts each
// show link to archive
$offset = $inNumToSkip + $numRows;
echo "[<A HREF=\"seedBlogs.php?action=show_archive" .
"&blog_name=$inBlogName&order=$inOrder&count=10&".
"show_authors=$inShowAuthors&show_dates=$inShowDates&".
"offset=$offset".
"&show_intro=$inShowIntroText".
"&show_submit_link_to_public=$inShowSubmitLinkToPublic".
"\" TITLE=\"View the post archive\">$numOlderPosts ".
"in Archive</A>]<BR>";
}
}
}
/**
* Generates a URL to the RSS 2.0 feed for a given seedBlog.
* GETing this URL will return RSS XML.
*
* Order of RSS feed is fixed to "order by creation date", with
* newest posts listed first.
*
* @param $inBlogName the name of the blog in the database. Should not
* contain spaces or special characters.
* @param $inChannelTitle the name of the RSS channel.
* @param $inChannelDescription the description of the RSS channel.
* @param $inMaxNumber the maximum number of items to include in the feed.
* -1 specifies no limit.
* Defaults to 10.
* @param $inShowAuthors 1 to show authors, or 0 to hide them. Defaults to 1.
* @param $inShowDates 1 to show dates, or 0 to hide them. Defaults to 1.
*/
function seedBlogRSSLink( $inBlogName,
$inChannelTitle,
$inChannelDescription,
$inMaxNumber = 10,
$inShowAuthors = 1,
$inShowDates = 1 ) {
$encodedTitle = urlencode( $inChannelTitle );
$encodedDescription = urlencode( $inChannelDescription );
$urlParams =
"?action=rss_feed&".
"blog_name=$inBlogName&".
"channel_title=$encodedTitle&" .
"channel_description=$encodedDescription&".
"max_number=$inMaxNumber&show_authors=$inShowAuthors&".
"show_dates=$inShowDates";
global $fullSeedBlogsURL;
return $fullSeedBlogsURL . $urlParams;
}
/**
* Just like seedBlogRSSLink, but generates full HTML for an RSS button.
*
* Call this wherever you want an RSS button to appear on your page.
*/
function seedBlogRSSButton( $inBlogName,
$inChannelTitle,
$inChannelDescription,
$inMaxNumber = 10,
$inShowAuthors = 1,
$inShowDates = 1 ) {
$rss_url = seedBlogRSSLink( $inBlogName,
$inChannelTitle,
$inChannelDescription,
$inMaxNumber,
$inShowAuthors,
$inShowDates );
echo "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=1>".
"<TR><TD BGCOLOR=#898E79>".
"<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=1>".
"<TR><TD BGCOLOR=#FFFFFF>".
"<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2>".
"<TR><TD BGCOLOR=#FF6600>".
"<A HREF=\"$rss_url\"><FONT COLOR=#FFFFFF><B>RSS 2.0</B></FONT></A>".
"</TD></TR></TABLE></TD></TR></TABLE></TD></TR></TABLE>";
}
// end of functions that might be called externally by end-users
// general processing whenver seedBlogs.php is accessed directly
// grab POST/GET variables
$action = "";
if( isset( $_REQUEST[ "action" ] ) ) {
$action = sb_getRequestVariableSafe( "action" );
}
$post_id = "";
if( isset( $_REQUEST[ "post_id" ] ) ) {
$post_id = sb_getRequestVariableSafe( "post_id" );
}
$blog_name = "";
if( isset( $_REQUEST[ "blog_name" ] ) ) {
$blog_name = sb_getRequestVariableSafe( "blog_name" );
}
global $return_url;
$return_url = "";
if( isset( $_REQUEST[ "return_url" ] ) ) {
$return_url = sb_getRequestVariableSafe( "return_url" );
}
if( strcmp( $post_id, "" ) == 0 ) {
$post_id = NULL;
}
if( strcmp( $action, "version" ) == 0 ) {
global $seedBlogs_version;
echo "$seedBlogs_version";
}
else if( strcmp( $action, "login" ) == 0 ) {
sb_login();
}
else if( strcmp( $action, "logout" ) == 0 ) {
sb_logout();
}
else if( strcmp( $action, "show_register_form" ) == 0 ) {
sb_showRegisterForm( "" );
}
else if( strcmp( $action, "show_password_help_form" ) == 0 ) {
sb_showPasswordHelpForm( "" );
}
else if( strcmp( $action, "send_password_email" ) == 0 ) {
sb_sendPasswordEmail( "" );
}
else if( strcmp( $action, "register" ) == 0 ) {
sb_register();
}
else if( strcmp( $action, "setup_database" ) == 0 ) {
sb_setupDatabase();
}
else if( strcmp( $action, "edit_post" ) == 0 ) {
sb_showEditor( $blog_name, $post_id );
}
else if( strcmp( $action, "update_post" ) == 0 ) {
sb_updatePost( $blog_name, $post_id );
}
else if( strcmp( $action, "move_up" ) == 0 ) {
sb_moveUp( $blog_name, $post_id );
}
else if( strcmp( $action, "move_down" ) == 0 ) {
sb_moveDown( $blog_name, $post_id );
}
else if( strcmp( $action, "display_post" ) == 0 ) {
sb_displayPost( $post_id );
}
else if( strcmp( $action, "show_archive" ) == 0 ) {
sb_showArchive( $blog_name );
}
else if( strcmp( $action, "approve_post" ) == 0 ) {
sb_approvePost( $post_id );
}
else if( strcmp( $action, "approve_account" ) == 0 ) {
sb_approveAccount();
}
else if( strcmp( $action, "change_admin_status" ) == 0 ) {
sb_changeAdminStatus();
}
else if( strcmp( $action, "remove_account" ) == 0 ) {
sb_removeAccount();
}
else if( strcmp( $action, "show_post_queue" ) == 0 ) {
sb_showPostQueue( $blog_name );
}
else if( strcmp( $action, "show_account_queue" ) == 0 ) {
sb_showAccountQueue();
}
else if( strcmp( $action, "show_account_list" ) == 0 ) {
sb_showAccountList();
}
else if( strcmp( $action, "search" ) == 0 ) {
sb_search();
}
else if( strcmp( $action, "rss_feed" ) == 0 ) {
sb_rssFeed();
}
else if( strcmp( $action, "sb_setup" ) == 0 ) {
global $header, $footer;
//include_once( $header );
global $setup_header, $setup_footer;
echo $setup_header;
echo "<H2>seedBlogs Web-based Setup</H2>";
echo "Creating tables:<BR>";
echo "<CENTER><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=1>
<TR><TD BGCOLOR=#000000>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=5>
<TR><TD BGCOLOR=#FFFFFF>";
sb_setupDatabase();
echo "</TD></TR></TABLE></TD></TR></TABLE></CENTER><BR><BR>";
echo "After you create an admin account, the setup process will be ".
"complete.<BR><BR>";
echo "Step 2: ";
echo "<CENTER>";
seedBlogs_showLoginBox();
echo "</CENTER>";
echo $setup_footer;
//include_once( $footer );
}
else if( preg_match( "/seedBlogs\.php/", $_SERVER[ "SCRIPT_NAME" ] ) ) {
// seedBlogs.php has been called without an action parameter
// the preg_match ensures that seedBlogs.php was called directly and
// not just included by another script
// quick (and incomplete) test to see if we should show ins
global $tableNamePrefix;
// check if our "posts" table exists
$tableName = $tableNamePrefix . "posts";
sb_connectToDatabase();
$exists = sb_doesTableExist( $tableName );
sb_closeDatabase();
if( $exists ) {
// show main page
global $mainSiteURL;
// redirect
header( "Location: $mainSiteURL" );
}
else {
// start the setup procedure
global $header, $footer;
//include_once( $header );
global $setup_header, $setup_footer;
echo $setup_header;
echo "<H2>seedBlogs Web-based Setup</H2>";
echo "seedBlogs will walk you through a brief setup process.<BR><BR>";
echo "Step 1: ".
"<A HREF=\"seedBlogs.php?action=sb_setup\">".
"create the database tables</A>";
echo $setup_footer;
//include_once( $footer );
}
}
/**
* Creates the database tables needed by seedBlogs.
*/
function sb_setupDatabase() {
global $tableNamePrefix;
// make sure our "posts" table exists
$tableName = $tableNamePrefix . "posts";
sb_connectToDatabase();
if( ! sb_doesTableExist( $tableName ) ) {
// this table contains all the information for each post
$query =
"CREATE TABLE $tableName(" .
"post_id VARCHAR(255) NOT NULL PRIMARY KEY," .
"blog_name VARCHAR(255) NOT NULL," .
"user_id VARCHAR(20) NOT NULL," .
"creation_date DATETIME NOT NULL," .
"change_date DATETIME NOT NULL," .
"expiration_date DATETIME," .
"allow_comments TINYINT NOT NULL," .
"show_permalink TINYINT NOT NULL," .
"approved TINYINT NOT NULL," .
"removed TINYINT NOT NULL," .
"subject_line VARCHAR(60) NOT NULL," .
"intro_text LONGTEXT," .
"body_text LONGTEXT );";
$result = sb_queryDatabase( $query );
echo "<B>$tableName</B> table created<BR>";
}
else {
echo "<B>$tableName</B> table already exists<BR>";
}
$tableName = $tableNamePrefix . "users";
if( ! sb_doesTableExist( $tableName ) ) {
// this table contains information for each user
$query =
"CREATE TABLE $tableName(" .
"user_id VARCHAR(20) NOT NULL PRIMARY KEY," .
"password_md5 CHAR(32) NOT NULL,".
"email VARCHAR(255),".
"session_id CHAR(32) NULL,".
"approved TINYINT NOT NULL," .
"administrator TINYINT NOT NULL );";
$result = sb_queryDatabase( $query );
echo "<B>$tableName</B> table created<BR>";
}
else {
echo "<B>$tableName</B> table already exists<BR>";
}
$tableName = $tableNamePrefix . "order_map";
if( ! sb_doesTableExist( $tableName ) ) {
// this table contains order information for each blog
$query =
"CREATE TABLE $tableName(" .
"blog_name VARCHAR(255) NOT NULL PRIMARY KEY," .
"map LONGTEXT NOT NULL );";
// each map field contains a list of post_ids separated by whitespace
$result = sb_queryDatabase( $query );
echo "<B>$tableName</B> table created<BR>";
}
else {
echo "<B>$tableName</B> table already exists<BR>";
}
sb_closeDatabase();
}
/**
* Logs a user in (setting the global $loggedInID) according to
* the POSTED variables.
*/
function sb_login() {
// the body of this function was largely copied from the NCN project
// grab posted variables
$user_id = sb_getRequestVariableSafe( "user_id" );
// never used in database query, so strip once here
$password = sb_stripMagicQuotes( sb_getRequestVariableRaw( "password" ) );
if( sb_doesUserExist( $user_id ) ) {
if( sb_getUserDatabaseField( $user_id, "approved" ) == 0 ) {
// display failure page
sb_messagePage( "User ID <B>" .
sb_stripMagicQuotes( $user_id ) .
"</B> has no been approved yet." );
}
else {
$passwordMD5 = sb_computePasswordHash( sb_stripMagicQuotes( $user_id ),
$password );
$truePasswordMD5 = sb_getUserDatabaseField( $user_id,
"password_md5" );
if( strcmp( $truePasswordMD5, $passwordMD5 ) == 0 ) {
$session_id = sb_computeSessionID( sb_stripMagicQuotes( $user_id ),
$password );
sb_setUserDatabaseField( $user_id, "session_id", $session_id );
// set cookies with the user_id and session_id
sb_refreshCookie( $user_id, $session_id );
// set global
global $loggedInID;
$loggedInID = $user_id;
// show page user logged in from
// redirect
global $return_url;
header( "Location: $return_url" );
}
else {
// display failure page
sb_messagePage( "Log in failed." );
}
}
}
else {
// display failure page
sb_messagePage( "User ID <B>" .
sb_stripMagicQuotes( $user_id ) .
"</B> does not exist." );
}
}
/**
* Logs the current user out and clears cookies.
*/
function sb_logout() {
// clear cookie in user's browser
sb_clearCookie();
global $justLoggedOut, $loggedInID;
// clear the session id in the database
sb_setUserDatabaseField( $loggedInID, "session_id", NULL );
// tell other parts of script to ignore set cookies
$justLoggedOut = 1;
// drop the ID that we have read from the cookies so that
// the messagePage can reflect the fact that the user has logged out
$loggedInID = "";
sb_messagePage( "You have successfully logged out." );
}
/**
* Shows the user registration form, or shows the account editing form
* if a user is already logged in.
*
* @param inMessage the message to display.
*/
function sb_showRegisterForm( $inMessage ) {
global $header, $footer;
include_once( $header );
echo "<B>$inMessage</B>";
global $loggedInID, $tableNamePrefix;
$emailValue = "";
$editExisting = false;
$buttonName = "Register";
if( strcmp( $loggedInID, "" ) != 0 ) {
// user is already logged in
// query to get the current email address
$query = "SELECT * FROM $tableNamePrefix"."users ".
"WHERE user_id = '$loggedInID';";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$emailValue = mysql_result( $result, 0, "email" );
$editExisting = true;
$buttonName = "Update";
}
?>
<FORM ACTION="seedBlogs.php" METHOD="post">
<INPUT TYPE="hidden" NAME="action" VALUE="register">
<?php
global $return_url;
echo "<INPUT TYPE=\"hidden\" NAME=\"return_url\" VALUE=\"$return_url\">";
if( $editExisting ) {
echo "<INPUT TYPE=\"hidden\" ".
"NAME=\"user_id\" VALUE=\"$loggedInID\">";
}
echo "<TABLE BORDER=0>";
if( !$editExisting ) {
?>
<TR><TD>User ID:</TD>
<TD><INPUT TYPE="text" MAXLENGTH=20 SIZE=20 NAME="user_id"></TD></TR>
<?php
}
else {
echo "<TR><TD COLSPAN=2>Leave blank to keep old password</TD></TR>";
}
?>
<TR><TD><?php if( $editExisting ) echo "New ";?>Password:</TD>
<TD><INPUT TYPE="password" MAXLENGTH=20 SIZE=20 NAME="password"></TD></TR>
<TR><TD>Re-type Password:</TD>
<TD><INPUT TYPE="password" MAXLENGTH=20 SIZE=20
NAME="password_b"></TD></TR>
<TR><TD>Email:</TD>
<TD><INPUT TYPE="text" MAXLENGTH=255 SIZE=20 NAME="email"
VALUE="<?php echo $emailValue;?>"></TD></TR>
<TR><TD ALIGN=RIGHT COLSPAN=2>
<INPUT TYPE="Submit" VALUE="<?php echo $buttonName;?>"></TD><TR>
</TABLE>
</FORM>
<?php
include_once( $footer );
}
/**
* Shows a form the user can fill out for help with forgotton passwords.
*
* @param inMessage the message to display.
*/
function sb_showPasswordHelpForm( $inMessage ) {
global $header, $footer;
include_once( $header );
echo "<B>$inMessage</B><BR>";
echo "Enter <EM>either</EM> your user ID or your email address:"
?>
<FORM ACTION="seedBlogs.php" METHOD="post">
<INPUT TYPE="hidden" NAME="action" VALUE="send_password_email">
<TABLE BORDER=0>
<TR><TD>User ID:</TD>
<TD><INPUT TYPE="text" MAXLENGTH=255 SIZE=20 NAME="user_id"
VALUE=""></TD></TR>
<TR><TD>Email:</TD>
<TD><INPUT TYPE="text" MAXLENGTH=255 SIZE=20 NAME="email"
VALUE=""></TD></TR>
<TR><TD ALIGN=RIGHT COLSPAN=2>
<INPUT TYPE="Submit" VALUE="Send New Password by Email"></TD><TR>
</TABLE>
</FORM>
<?php
include_once( $footer );
}
/**
* Send a notice to the admins.
*
* @param inMessage the email message to send.
*/
function sb_sendAdminNotice( $inMessage ) {
// first, pull all admins from database
$query = "";
global $tableNamePrefix;
$query = "SELECT * FROM $tableNamePrefix"."users ".
"WHERE administrator = '1';";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$numRows = mysql_numrows( $result );
if( $numRows < 1 ) {
// no admins
return;
}
$emailList = mysql_result( $result, 0, "email" );
$userIDList = mysql_result( $result, 0, "user_id" );
for( $i=1; $i<$numRows; $i++ ) {
$user_id = mysql_result( $result, $i, "user_id" );
$email = mysql_result( $result, $i, "email" );
if( $i == $numRows - 1 ) {
// last user, insert and before name in list
$userIDList = $userIDList . ", and " . $user_id;
}
else {
// middle of list, just comma and space
$userIDList = $userIDList . ", " . $user_id;
}
$emailList = $emailList . ", " . $email;
}
$adminListNotice = "";
if( $numRows > 1 ) {
// more than one admin
// remind them of this fact to avoid confusion
$adminListNotice =
"\nNote that these admins were all notified ".
"about this issue:\n".
"$userIDList\n";
}
global $siteName, $mainSiteURL, $siteEmailAddress;
$mailHeaders = "From: $siteEmailAddress";
$result = mail( $emailList, "$siteName admin action needed",
"The following action is pending ".
"administrator approval:\n\n".
"$inMessage\n".
"$adminListNotice",
$mailHeaders );
}
/**
* Sends out a password email using the POSTed variables.
*/
function sb_sendPasswordEmail() {
global $header, $footer;
$user_id = sb_getRequestVariableSafe( "user_id" );
$email = sb_getRequestVariableSafe( "email" );
$error = 0;
// first, make sure the required fields are provided
if( strcmp( $user_id, "" ) == 0 && strcmp( $email, "" ) == 0 ) {
$error = 1;
sb_showPasswordHelpForm( "You must provide some account information." );
}
if( ! $error ) {
// query to either find user with this ID
// or find all users with this email
$query = "";
global $tableNamePrefix;
if( strcmp( $user_id, "" ) != 0 ) {
$query = "SELECT * FROM $tableNamePrefix"."users ".
"WHERE user_id = '$user_id';";
}
else {
$query = "SELECT * FROM $tableNamePrefix"."users ".
"WHERE email = '$email';";
}
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$numRows = mysql_numrows( $result );
if( $numRows == 0 ) {
sb_showPasswordHelpForm(
"The information you entered does not match any account." );
}
else if( $numRows > 1 ) {
sb_showPasswordHelpForm(
"More than one account uses this email address.<BR>".
"You must provide a User ID." );
}
else {
$user_id = mysql_result( $result, 0, "user_id" );
$email = mysql_result( $result, 0, "email" );
$password_md5 = mysql_result( $result, 0, "password_md5" );
// compute a new, temporary password
// however, we need to generate a password that
// cannot be guessed by attackers
// we can use the password MD5 sum (which we know) as a seed
$temp_session_id = sb_computeSessionID( $user_id, $password_md5 );
// temp passwords are 10 hex digits long
// there are roughly 10^12 possible temp passwords
$temp_password = substr( $temp_session_id, 0, 10 );
$temp_password_md5 =
sb_computePasswordHash( sb_stripMagicQuotes( $user_id ),
$temp_password );
sb_setUserDatabaseField( $user_id,
"password_md5", $temp_password_md5 );
global $siteName, $mainSiteURL, $siteEmailAddress;
$mailHeaders = "From: $siteEmailAddress";
$result = mail( $email, "$siteName temporary password",
"Your password at $mainSiteURL has been ".
"reset.\n\n".
"Here is your temporary account information:\n\n".
"User ID: $user_id\n".
"Password: $temp_password\n",
$mailHeaders );
sb_messagePage(
"A temporary password has been sent to you by email." );
}
}
}
/**
* Processes the variables posted by the register form.
*/
function sb_register() {
global $tableNamePrefix, $loggedInID, $autoApproveUsers;
$updateExisting = false;
if( strcmp( $loggedInID, "" ) != 0 ) {
$updateExisting = true;
}
// grab posted variables
$user_id = sb_getRequestVariableSafe( "user_id" );
// never used in database query, so strip once here
$password = sb_stripMagicQuotes( sb_getRequestVariableRaw( "password" ) );
$password_b = sb_stripMagicQuotes( sb_getRequestVariableRaw( "password_b" ) );
$email = sb_getRequestVariableSafe( "email" );
$error = 0;
// first, make sure the required fields are provided
if( !$updateExisting && strcmp( $user_id, "" ) == 0 ) {
$error = 1;
sb_showRegisterForm( "\"User ID\" is a required field." );
}
else if( !$updateExisting && strcmp( $password, "" ) == 0 ) {
$error = 1;
sb_showRegisterForm( "You must enter a password." );
}
else if( strcmp( $email, "" ) == 0 ) {
$error = 1;
sb_showRegisterForm( "You must enter an email address." );
}
else if( strcmp( $password, $password_b ) != 0 ) {
$error = 1;
sb_showRegisterForm( "Your re-typed password does not match." );
}
if( ! $error ) {
if( !$updateExisting && sb_doesUserExist( $user_id ) ) {
sb_showRegisterForm( "User id <B>$user_id</B> already exists." );
}
else if( !$updateExisting && strcmp( $user_id, "Anonymous" ) == 0 ) {
sb_showRegisterForm( "User id <B>Anonymous</B> is reserved." );
}
else if( !$updateExisting ) {
$password_md5 = sb_computePasswordHash( sb_stripMagicQuotes( $user_id ),
$password );
$approved = 0;
$administrator = 0;
if( sb_getUserCount() == 0 ) {
// auto admin and approve
$approved = 1;
$administrator = 1;
}
if( $autoApproveUsers ) {
$approved = 1;
}
$query = "INSERT INTO $tableNamePrefix". "users VALUES ( " .
"'$user_id', '$password_md5', '$email', NULL, ".
"'$approved', '$administrator' );";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
sb_closeDatabase();
if( $approved ) {
// log the user in using same POST variables
sb_login();
}
else {
// tell the user that their account registration is pending
// display failure page
sb_messagePage( "Your account request has been sent to the ".
"administrators for approval.<BR>".
"You will receive an email with further ".
"information." );
global $fullSeedBlogsURL, $emailAdminsAboutPendingItems;
if( $emailAdminsAboutPendingItems ) {
sb_sendAdminNotice(
"The following new account is waiting for approval:\n".
"$user_id\n\n".
"After you log in, check the following link for ".
"details:\n".
"$fullSeedBlogsURL?action=show_account_queue" );
}
}
$approvalMessage = "";
if( $approved ) {
$approvalMessage =
"Your account request has been auto-approved.";
}
else {
$approvalMessage =
"Your account is awaiting approval from the ".
"administrators. You will receive an email when your ".
"account is approved.";
}
// send an email with account information
global $siteName, $mainSiteURL, $siteEmailAddress;
$mailHeaders = "From: $siteEmailAddress";
$result = mail( $email, "$siteName account requested",
"Your account request at $mainSiteURL has been ".
"received.\n\n".
"$approvalMessage\n\n".
"Here is your account information:\n\n".
"User ID: $user_id\n".
"Email: $email\n",
$mailHeaders );
}
else {
// updating an existing account
$passwordUpdate = "";
if( strcmp( $password, "" ) != 0 ) {
// new password (already checked that $password_b matches)
$password_md5 = sb_computePasswordHash(
sb_stripMagicQuotes( $loggedInID ), $password );
$passwordUpdate = "password_md5 = '$password_md5', ";
}
$query = "UPDATE $tableNamePrefix". "users SET " .
"$passwordUpdate email = '$email' ".
"WHERE user_id = '$loggedInID';";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$passwordMessage = "";
if( strcmp( $password, "" ) != 0 ) {
// log the user in using same POST variables
// need to do this to reset the cookie
sb_login();
$passwordMessage = "(new password set)\n";
}
else {
sb_messagePage( "Your account information has been updated.<BR> ".
"You will receive an email with your new ".
"information." );
}
// send an email with the updated account information
global $siteName, $mainSiteURL, $siteEmailAddress;
$mailHeaders = "From: $siteEmailAddress";
$result = mail( $email, "$siteName account information updated",
"Your account information at $mainSiteURL has ".
"been updated.\n\n".
"Here is your new account information:\n\n".
"User ID: $user_id\n".
"$passwordMessage".
"Email: $email\n",
$mailHeaders );
}
}
}
/**
* Shows the editor form.
*
* @param $inBlogName the name of the blog to edit.
* @param $inPostID the postID to fill the form with, or NULL to
* show a blank form.
*/
function sb_showEditor( $inBlogName, $inPostID ) {
global $tableNamePrefix, $autoApprovePosts;
$show_author = sb_getRequestVariableSafe( "show_author" );
$show_date = sb_getRequestVariableSafe( "show_date" );
$blog_name = $inBlogName;
$author_name = "";
$subject_line = "";
$intro_text = "";
$body_text = "";
$expiration_date = NULL;
$allow_comments = 0;
// default to showing permalink
$show_permalink = 1;
$approved = 0;
$isExistingPost = false;
// populate form fields from database
if( $inPostID != NULL ) {
$query =
"SELECT * " .
"FROM $tableNamePrefix"."posts " .
"WHERE post_id = '$inPostID';";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
if( mysql_numrows( $result ) != 1 ) {
sb_closeDatabase();
sb_fatalError( "Post $inPostID does not exist in database." );
}
$row = mysql_fetch_array( $result, MYSQL_ASSOC );
$blog_name = $row[ "blog_name" ];
$author_name = $row[ "user_id" ];
$subject_line = $row[ "subject_line" ];
$intro_text = $row[ "intro_text" ];
$body_text = $row[ "body_text" ];
$expiration_date = $row[ "expiration_date" ];
$allow_comments = $row[ "allow_comments" ];
$show_permalink = $row[ "show_permalink" ];
$approved = $row[ "approved" ];
sb_closeDatabase();
$isExistingPost = true;
}
$buttonName = "Submit for Approval";
if( $isExistingPost ) {
$buttonName = "Update";
}
else {
if( sb_isAdministrator() ||
( $autoApprovePosts && strcmp( $loggedInID, "" ) != 0 ) ) {
// this is a direct post
$buttonName = "Post";
}
}
// include the header before generating a page
global $header, $footer;
include_once( $header );
global $return_url;
?>
<FORM ACTION="seedBlogs.php" METHOD="post">
<INPUT TYPE="hidden" NAME="action"
VALUE="update_post">
<INPUT TYPE="hidden" NAME="return_url"
VALUE="<?php echo $return_url; ?>">
<INPUT TYPE="hidden" NAME="show_author"
VALUE="<?php echo $show_author; ?>">
<INPUT TYPE="hidden" NAME="show_date"
VALUE="<?php echo $show_date; ?>">
<INPUT TYPE="hidden" NAME="blog_name"
VALUE="<?php echo $blog_name; ?>">
<?php
if( $inPostID != NULL ) {
?>
<INPUT TYPE="hidden" NAME="post_id"
VALUE="<?php echo $inPostID; ?>">
<?php
}
?>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=1><TR><TD BGCOLOR=#777777>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=10>
<?php
// alternating background colors for blocks in form
$bgColor = "#CCCCCC";
$altColor = "#EEEEEE";
global $loggedInID;
if( strcmp( $loggedInID, "" ) == 0 ) {
// no one logged in, allow them to provide a name
?>
<TR><TD ALIGN=LEFT BGCOLOR=<?php echo $bgColor;?>>
Your Name:
</TD>
<TD ALIGN=RIGHT BGCOLOR=<?php echo $bgColor;?>>
<INPUT TYPE="text" MAXLENGTH=60 SIZE=30 NAME="author_name"
VALUE="<?php echo $author_name; ?>">
</TD>
</TR>
<?php
$tempColor = $bgColor;
$bgColor = $altColor;
$altColor = $tempColor;
}
?>
<TR><TD ALIGN=LEFT BGCOLOR=<?php echo $bgColor;?>>
Headline:
</TD>
<TD ALIGN=RIGHT BGCOLOR=<?php echo $bgColor;?>>
<INPUT TYPE="text" MAXLENGTH=60 SIZE=30 NAME="subject_line"
VALUE="<?php echo $subject_line; ?>">
</TD>
</TR>
<?php
$tempColor = $bgColor;
$bgColor = $altColor;
$altColor = $tempColor;
$introTextName = "Intro Text:";
if( preg_match( "/_comments/", $blog_name ) ) {
// only one block of text for comments
$introTextName = "Text:";
}
?>
<TR><TD COLSPAN=2 BGCOLOR=<?php echo $bgColor;?>>
<?php echo $introTextName; ?><BR>
<TEXTAREA NAME="intro_text" COLS=50 ROWS=10><?php echo htmlspecialchars( $intro_text ); ?></TEXTAREA>
</TD></TR>
<?php
$tempColor = $bgColor;
$bgColor = $altColor;
$altColor = $tempColor;
// hide body text block for comments
if( ! preg_match( "/_comments/", $blog_name ) ) {
?>
<TR><TD COLSPAN=2 BGCOLOR=<?php echo $bgColor;?>>
Body Text:<BR>
<TEXTAREA NAME="body_text" COLS=50 ROWS=10><?php echo htmlspecialchars( $body_text ); ?></TEXTAREA>
</TD></TR>
<?php
$tempColor = $bgColor;
$bgColor = $altColor;
$altColor = $tempColor;
}
else {
// force blank body text
echo '<INPUT TYPE="hidden" NAME="body_text" VALUE="">';
}
if( ! preg_match( "/_comments/", $blog_name ) ) {
// no expiration dates allowed on comments
?>
<TR>
<TD ALIGN=LEFT BGCOLOR=<?php echo $bgColor;?>>
Expires:
</TD>
<TD ALIGN=LEFT BGCOLOR=<?php echo $bgColor;?>>
<?php
$fillWithCurrentTime = 0;
// unchecked
$neverExpiresCheckedState = "";
if( $expiration_date == NULL ) {
$fillWithCurrentTime = 1;
$neverExpiresCheckedState = "CHECKED";
}
sb_printDateTimeFormFromTimestamp( "expire_",
$fillWithCurrentTime, $expiration_date );
?>
<INPUT TYPE="checkbox" NAME="never_expires" VALUE=1
<?php echo $neverExpiresCheckedState;?> > Never Expires
</TD>
</TR>
<?php
$tempColor = $bgColor;
$bgColor = $altColor;
$altColor = $tempColor;
}
// should we show comment-enabling widgets?
// no comments allowed on comments
if( ! preg_match( "/_comments/", $blog_name ) ) {
$allowCommentsCheckedState = "";
if( $allow_comments ) {
$allowCommentsCheckedState = "CHECKED";
}
?>
<TR><TD BGCOLOR=<?php echo $bgColor;?>></TD>
<TD BGCOLOR=<?php echo $bgColor;?>>
<INPUT TYPE="checkbox" NAME="allow_comments" VALUE=1
<?php echo $allowCommentsCheckedState;?> > Allow Comments
</TD>
</TR>
<?php
$tempColor = $bgColor;
$bgColor = $altColor;
$altColor = $tempColor;
}
// only give permalink option for non-comments
if( ! preg_match( "/_comments/", $blog_name ) ) {
// permalink-enabling widget
$showPermalinkCheckedState = "";
if( $show_permalink ) {
$showPermalinkCheckedState = "CHECKED";
}
?>
<TR><TD BGCOLOR=<?php echo $bgColor;?>></TD>
<TD BGCOLOR=<?php echo $bgColor;?>>
<INPUT TYPE="checkbox" NAME="show_permalink" VALUE=1
<?php echo $showPermalinkCheckedState;?> > Show Permanent Link
</TD>
</TR>
<?php
$tempColor = $bgColor;
$bgColor = $altColor;
$altColor = $tempColor;
}
// should we show approval widgets?
if( $isExistingPost &&
sb_isAdministrator() &&
$approved == 0 ) {
?>
<TR><TD BGCOLOR=<?php echo $bgColor;?>></TD>
<TD BGCOLOR=<?php echo $bgColor;?>>
<INPUT TYPE="checkbox" NAME="approve" VALUE=1> Approve Post
</TD>
</TR>
<?php
$tempColor = $bgColor;
$bgColor = $altColor;
$altColor = $tempColor;
}
// should show removal widgets?
if( $isExistingPost &&
sb_canEdit( $inPostID ) ) {
?>
<TR><TD BGCOLOR=<?php echo $bgColor;?>></TD>
<TD BGCOLOR=<?php echo $bgColor;?>>
<INPUT TYPE="checkbox" NAME="remove" VALUE=1> Remove Post
</TD>
</TR>
<?php
}
?>
</TABLE>
</TD></TR>
<TR><TD COLSPAN=2 ALIGN=RIGHT BGCOLOR=#FFFFFF>
<INPUT TYPE="Submit" VALUE="<?php echo $buttonName;?>">
</TD></TR>
</TABLE>
<?php
if( preg_match( "/_comments/", $blog_name ) ){
// comments never expire
echo '<INPUT TYPE="hidden" NAME="never_expires" VALUE=1>';
}
?>
</FORM>
<?php
// end the page with our footer
include_once( $footer );
}
/**
* Updates a post from values submitted through editor form.
*
* @param $inBlogName the name of the blog to edit.
* @param $inPostID the post to update, or NULL to
* insert a new post.
*/
function sb_updatePost( $inBlogName, $inPostID ) {
global $return_url, $tableNamePrefix, $loggedInID;
$author_name = sb_getRequestVariableSafe( "author_name" );
$subject_line = sb_getRequestVariableSafe( "subject_line" );
$return_url = sb_getRequestVariableSafe( "return_url" );
// will encode illegal HTML tags whenver we display the post
$intro_text = sb_getRequestVariableRaw( "intro_text" );
$body_text = sb_getRequestVariableRaw( "body_text" );
$expire_month = sb_getRequestVariableSafe( "expire_month" );
$expire_day = sb_getRequestVariableSafe( "expire_day" );
$expire_year = sb_getRequestVariableSafe( "expire_year" );
$expire_hour = sb_getRequestVariableSafe( "expire_hour" );
$expire_minute = sb_getRequestVariableSafe( "expire_minute" );
$expire_ampm = sb_getRequestVariableSafe( "expire_ampm" );
$never_expires = sb_getRequestVariableSafe( "never_expires" );
// optional fields
$allow_comments = 0;
$show_permalink = 0;
$approve = 0;
$remove = 0;
if( isset( $_REQUEST[ "allow_comments" ] ) ) {
$allow_comments = sb_getRequestVariableSafe( "allow_comments" );
}
if( isset( $_REQUEST[ "show_permalink" ] ) ) {
$show_permalink = sb_getRequestVariableSafe( "show_permalink" );
}
if( isset( $_REQUEST[ "approve" ] ) ) {
$approve = sb_getRequestVariableSafe( "approve" );
}
if( isset( $_REQUEST[ "remove" ] ) ) {
$remove = sb_getRequestVariableSafe( "remove" );
}
if( preg_match( "/_comments/", $inBlogName ) ) {
// this is a comment post
// comments never allowed on comments
// permalinks always forced visible on comments
// make this check here (instead of on editor end) to prevent
// users from doctoring POST variables
$allow_comments = 0;
$show_permalink = 1;
}
$expiration_date = "NULL";
if( $never_expires != 1 ) {
// convert to date stamp
$expiration_date = sb_formatTime( $expire_year,
$expire_month,
$expire_day,
$expire_hour,
$expire_minute,
0, // ignore seconds
$expire_ampm );
$expiration_date = "'$expiration_date'";
}
$post_id = $inPostID;
$query = "";
/*
"CREATE TABLE posts(" .
"post_id VARCHAR(255) NOT NULL PRIMARY KEY," .
"blog_name VARCHAR(255) NOT NULL," .
"user_id VARCHAR(20) NOT NULL," .
"creation_date DATETIME NOT NULL," .
"change_date DATETIME NOT NULL," .
"expiration_date DATETIME," .
"allow_comments TINYINT NOT NULL," .
"show_permalink TINYINT NOT NULL," .
"approved TINYINT NOT NULL," .
"removed TINYINT NOT NULL," .
"subject_line VARCHAR(60) NOT NULL," .
"intro_text LONGTEXT," .
"body_text LONGTEXT );";
*/
global $header, $footer, $allowSubmissionsFromPublic;
$postAllowed = true;
$postApproved = 0;
$editingExisting = false;
if( $post_id == NULL ) {
if( strcmp( $loggedInID, "" ) == 0 &&
! $allowSubmissionsFromPublic &&
! preg_match( "/_comments/", $inBlogName ) ) {
// no one logged in, public posting forbidden, and this is not
// a comment list
$postAllowed = false;
// display failure page
sb_messagePage( "You must log in to submit posts." );
}
else if( strcmp( $author_name, "" ) != 0 &&
sb_doesUserExist( $author_name ) ) {
// a public (not logged in) user has specified an
// existing user's ID as their author name
$postAllowed = false;
sb_messagePage( "The name <B>$author_name</B> is already in".
" use by a registered user." );
}
else {
$post_id = sb_getUniquePostID();
global $autoApprovePosts, $loggedInID;
if( strcmp( $loggedInID, "" ) != 0 ) {
if( sb_getUserDatabaseField( $loggedInID,
"administrator" ) == 1 ) {
// admin posts auto-approved
$postApproved = 1;
}
else {
if( $autoApprovePosts ) {
// approve all posts from logged-in users
$postApproved = 1;
}
}
}
$user_id = "Anonymous";
if( strcmp( $loggedInID, "" ) != 0 ) {
$user_id = $loggedInID;
}
else {
// no one logged in, use author name if it is set
if( strcmp( $author_name, "" ) != 0 ) {
$user_id = $author_name;
}
}
// this query is processed below, outside this if block
$query = "INSERT INTO $tableNamePrefix"."posts VALUES ( " .
"'$post_id', '$inBlogName', '$user_id', CURRENT_TIMESTAMP, " .
"CURRENT_TIMESTAMP, $expiration_date, '$allow_comments',".
"'$show_permalink', '$postApproved', ".
"\"0\", '$subject_line', " .
"'$intro_text', '$body_text' );";
// update the map
// lock to ensure our update is atomic
$mapQuery = "SELECT map FROM $tableNamePrefix"."order_map ".
"WHERE blog_name = '$inBlogName' LOCK IN SHARE MODE;";
sb_connectToDatabase();
$result = sb_queryDatabase( $mapQuery );
if( mysql_numrows( $result ) == 1 ) {
$map = mysql_result( $result, 0, 0 );
// stick this post at the top of the list
$map = $post_id . "\n" . $map;
$mapQuery = "UPDATE $tableNamePrefix"."order_map SET ".
"map = '$map' WHERE blog_name = '$inBlogName';";
}
else {
// insert a new map containing only this post_id
$mapQuery = "INSERT INTO $tableNamePrefix"."order_map ".
"VALUES ( " .
"'$inBlogName', '$post_id' );";
}
sb_queryDatabase( $mapQuery );
sb_closeDatabase();
}
}
else {
// editing an existing post
$editingExisting = true;
if( !sb_canEdit( $post_id ) ) {
$postAllowed = false;
// display failure page
sb_messagePage( "You are not allowed to edit this post." );
}
else {
// deal with approval and removal
$removedDataString = "removed = \"0\",";
if( $remove == 1 ) {
$removedDataString = "removed = \"1\",";
}
// default to not changing approval status
$approvedDataString = "";
if( $approve == 1 &&
sb_isAdministrator() ) {
$approvedDataString = "approved = \"1\",";
}
$query = "UPDATE $tableNamePrefix"."posts SET " .
"change_date = CURRENT_TIMESTAMP, " .
"expiration_date = $expiration_date, " .
"allow_comments = '$allow_comments', ".
"show_permalink = '$show_permalink', ".
"$removedDataString " .
"$approvedDataString " .
"subject_line = '$subject_line', " .
"intro_text = '$intro_text', body_text = '$body_text' " .
"WHERE post_id = '$post_id';";
}
}
if( $postAllowed ) {
sb_connectToDatabase();
sb_queryDatabase( $query );
sb_closeDatabase();
if( $remove != 1 ) {
if( $postApproved == 1 ||
sb_isAdministrator() ||
$editingExisting ) {
// display the updated post
// redirect
header( "Location: $return_url" );
}
else {
// let the user know the post has been submitted
sb_messagePage( "The post has been submitted for approval." );
global $fullSeedBlogsURL, $emailAdminsAboutPendingItems;
if( $emailAdminsAboutPendingItems ) {
sb_sendAdminNotice(
"A new post is waiting for approval:\n\n".
"After you log in, check the following link for ".
"details:\n".
"$fullSeedBlogsURL?action=show_post_queue".
"&blog_name=$inBlogName" );
}
}
}
else {
// let the user know the post was removed
sb_messagePage( "The post has been removed." );
}
}
}
/**
* Moves a post up in the order map.
*
* @param $inBlogName the name of the blog.
* @param $inPostID the post to move up.
*/
function sb_moveUp( $inBlogName, $inPostID ) {
sb_movePost( $inBlogName, $inPostID, -1 );
}
/**
* Moves a post down in the order map.
*
* @param $inBlogName the name of the blog.
* @param $inPostID the post to move down.
*/
function sb_moveDown( $inBlogName, $inPostID ) {
sb_movePost( $inBlogName, $inPostID, 1 );
}
/**
* Moves a post in the order map.
*
* @param $inBlogName the name of the blog.
* @param $inPostID the post to move.
* @param $inMoveDirection -1 for up, or 1 for down.
*/
function sb_movePost( $inBlogName, $inPostID, $inMoveDirection ) {
global $return_url, $tableNamePrefix, $loggedInID;
// update the map
// lock to ensure our update is atomic
$mapQuery = "SELECT map FROM $tableNamePrefix"."order_map ".
"WHERE blog_name = '$inBlogName' LOCK IN SHARE MODE;";
sb_connectToDatabase();
$result = sb_queryDatabase( $mapQuery );
if( mysql_numrows( $result ) == 1 ) {
$map = mysql_result( $result, 0, 0 );
$mapArray = preg_split( "/\s+/", $map );
// move this post up in the list, skipping over expired, removed,
// or unapproved posts
// first, find the index of our post
$postIndex = -1;
for( $i=0; $i<count( $mapArray ) && $postIndex == -1; $i++ ) {
if( strcmp( $mapArray[$i], $inPostID ) == 0 ) {
$postIndex = $i;
}
}
if( $postIndex == -1 ) {
sb_fatalError( "Could not find post $inPostID in $inBlogName " .
"order map." );
}
// move post, ignoring invisible posts, until it passes
// one visible post
$limit = 0;
if( $inMoveDirection == 1 ) {
// moving down
$limit = count( $mapArray ) - 1;
}
$doneMoving = false;
if( $postIndex == $limit ) {
$doneMoving = true;
}
$passedOneVisible = false;
while( ! $doneMoving ) {
$nextHigherID = $mapArray[ $postIndex + $inMoveDirection ];
$nextVisible = sb_isPostVisible( $nextHigherID );
// move post up one spot
$mapArray[ $postIndex ] = $nextHigherID;
$mapArray[ $postIndex + $inMoveDirection ] = $inPostID;
$postIndex += $inMoveDirection;
if( $nextVisible || $postIndex == $limit ) {
// we've passed at least one visible, or we've hit the limit
$doneMoving = true;
}
}
$map = implode( $mapArray, "\n" );
$mapQuery = "UPDATE $tableNamePrefix"."order_map SET ".
"map = '$map' WHERE blog_name = '$inBlogName';";
}
else {
// insert a new map containing only this post_id
$mapQuery = "INSERT INTO $tableNamePrefix"."order_map ".
"VALUES ( " .
"'$inBlogName', '$post_id' );";
}
sb_queryDatabase( $mapQuery );
sb_closeDatabase();
// redirect to return URL
header( "Location: $return_url" );
}
/**
* Displays a full post.
*
* @param $inPostID the postID to display.
*/
function sb_displayPost( $inPostID ) {
global $tableNamePrefix;
$show_author = sb_getRequestVariableSafe( "show_author" );
$show_date = sb_getRequestVariableSafe( "show_date" );
global $return_url;
//if( $return_url == NULL ) {
// the display page should be the return destination after edits
$return_url = sb_getReturnURL();
$return_url = urlencode( $return_url );
// }
$query =
"SELECT * " .
"FROM $tableNamePrefix"."posts " .
"WHERE post_id = '$inPostID';";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
if( mysql_numrows( $result ) != 1 ) {
sb_closeDatabase();
sb_fatalError( "Post $inPostID does not exist in database." );
}
$row = mysql_fetch_array( $result, MYSQL_ASSOC );
$subject_line = $row[ "subject_line" ];
$intro_text = $row[ "intro_text" ];
$body_text = $row[ "body_text" ];
$blog_name = $row[ "blog_name" ];
$allow_comments = $row[ "allow_comments" ];
$show_permalink = $row[ "show_permalink" ];
$approved = $row[ "approved" ];
$user_id = $row[ "user_id" ];
$date = $row[ "creation_date" ];
sb_closeDatabase();
// trim leading/trailing whitespace
$subject_line = trim( $subject_line );
$intro_text = trim( $intro_text );
$body_text = trim( $body_text );
global $header, $footer;
include_once( $header );
global $storyBlockFormatOpen, $storyBlockFormatClose,
$headlineFormatOpen, $headlineFormatClose,
$textBlockFormatOpen, $textBlockFormatClose;
if( ! $show_author ) {
$user_id = NULL;
}
if( ! $show_date ) {
$date = NULL;
}
$showLinkToComments = 0;
$commentCount = sb_countComments( $inPostID, 1 );
if( $allow_comments && $commentCount == 0 ) {
// show link to comments, which will be a "submit comment" link
$showLinkToComments = 1;
}
sb_generateStoryBlock( $blog_name,
$inPostID,
$subject_line,
$user_id,
$date,
// hide up and down widgets
0,
0,
$intro_text,
$body_text,
1, // embed body text
$showLinkToComments,
$show_permalink,
$return_url,
// formatting options:
$storyBlockFormatOpen,
$storyBlockFormatClose,
$headlineFormatOpen,
$headlineFormatClose,
$textBlockFormatOpen,
$textBlockFormatClose );
if( $allow_comments ) {
if( $commentCount > 0 ) {
echo "<TABLE WIDTH=100% CELLSPACING=0 CELLPADDING=0 BORDER=0>";
echo "<TR><TD ALIGN=LEFT COLSPAN=2>";
echo "<A NAME=\"comments\">";
sb_showComments( $inPostID );
echo "</TD></TR></TABLE>";
}
}
//echo "</TD></TR></TABLE>";
echo "<BR>";
include_once( $footer );
}
/**
* Displays an archive for a blog using posted values to specify the range
* of posts to list.
*
* @param $inBlogName the name of the blog to show an archive for.
*/
function sb_showArchive( $inBlogName ) {
$offset = sb_getRequestVariableSafe( "offset" );
$count = sb_getRequestVariableSafe( "count" );
$order = sb_getRequestVariableSafe( "order" );
$show_intro = sb_getRequestVariableSafe( "show_intro" );
$show_authors = sb_getRequestVariableSafe( "show_authors" );
$show_dates = sb_getRequestVariableSafe( "show_dates" );
$show_submit_link_to_public =
sb_getRequestVariableSafe( "show_submit_link_to_public" );
// this archive page should be the return destination after edits
global $return_url;
$return_url = sb_getReturnURL();
$return_url = urlencode( $return_url );
// now simply display a seedBlog with the appropriate offset
global $header, $footer;
include( $header );
echo "<TABLE BORDER=0 WIDTH=100%><TR><TD>";
seedBlog( $inBlogName,
$show_intro,
$show_authors,
$show_dates,
$order,
$count,
$offset,
1, // show the archive
$show_submit_link_to_public );
echo "</TD></TR></TABLE>";
include( $footer );
}
/**
* Approves a post that is waiting in the admin queue.
*
* @param $inPostID the post to update, or NULL to
* insert a new post.
*/
function sb_approvePost( $inPostID ) {
global $return_url, $tableNamePrefix;
$post_id = $inPostID;
$query = "";
global $header, $footer;
$approvalAllowed = true;
if( $post_id == NULL ) {
$approvalAllowed = false;
// display failure page
sb_messagePage( "No post_id field given." );
}
else {
if( !sb_isAdministrator() ) {
$approvalAllowed = false;
// display failure page
sb_messagePage( "You must be an administrator to approve posts." );
}
else {
$query = "UPDATE $tableNamePrefix"."posts SET " .
"approved = '1' " .
"WHERE post_id = '$post_id';";
}
}
if( $approvalAllowed ) {
sb_connectToDatabase();
sb_queryDatabase( $query );
sb_closeDatabase();
// redirect to return URL
header( "Location: $return_url" );
}
}
/**
* Approves an account that is waiting in the admin queue according to POSTed
* values
*/
function sb_approveAccount() {
global $return_url, $tableNamePrefix;
$user_id = sb_getRequestVariableSafe( "user_id" );
$admin = sb_getRequestVariableSafe( "admin" );
$query = "";
global $header, $footer;
$approvalAllowed = true;
if( $user_id == NULL ) {
$approvalAllowed = false;
// display failure page
sb_messagePage( "No user_id field given." );
}
else {
if( !sb_isAdministrator() ) {
$approvalAllowed = false;
// display failure page
sb_messagePage( "You must be an administrator to approve accounts." );
}
else {
$adminClause = "";
if( $admin == 1 ) {
$adminClause = ", administrator = '1' ";
}
$query = "UPDATE $tableNamePrefix" . "users SET " .
"approved = '1' $adminClause" .
"WHERE user_id = '$user_id';";
}
}
if( $approvalAllowed ) {
sb_connectToDatabase();
sb_queryDatabase( $query );
sb_closeDatabase();
// send an email indicating approval
global $siteName, $mainSiteURL, $siteEmailAddress;
$email = sb_getUserDatabaseField( $user_id, "email" );
$adminMessage = "";
if( $admin ) {
$adminMessage = "You have been designated as an administrator.";
}
$mailHeaders = "From: $siteEmailAddress";
$result = mail( $email, "$siteName account approved",
"Your account request at $mainSiteURL has been ".
"approved.\n\n".
"$adminMessage\n",
$mailHeaders );
// redirect to return URL
header( "Location: $return_url" );
}
}
/**
* Changes the admin status of an account according to POSTed values.
*/
function sb_changeAdminStatus() {
global $return_url, $tableNamePrefix;
$user_id = sb_getRequestVariableSafe( "user_id" );
$admin = sb_getRequestVariableSafe( "admin" );
$query = "";
$approvalAllowed = true;
if( $user_id == NULL || $admin == NULL ) {
// display failure page
sb_messagePage( "Required fields are missing." );
}
else {
if( !sb_isAdministrator() ) {
$approvalAllowed = false;
// display failure page
sb_messagePage( "You must be an administrator to change accounts." );
}
else {
$adminClause = "administrator = '0'";
if( $admin == 1 ) {
$adminClause = "administrator = '1'";
}
$query = "UPDATE $tableNamePrefix" . "users SET" .
" $adminClause " .
"WHERE user_id = '$user_id';";
}
}
if( $approvalAllowed ) {
sb_connectToDatabase();
sb_queryDatabase( $query );
sb_closeDatabase();
// send an email indicating the change
global $siteName, $mainSiteURL, $siteEmailAddress;
$email = sb_getUserDatabaseField( $user_id, "email" );
$adminMessage = "";
if( $admin ) {
$adminMessage = "You have been designated as an administrator.";
}
else {
$adminMessage = "Your administrator status has been revoked.";
}
$mailHeaders = "From: $siteEmailAddress";
$result = mail( $email, "$siteName account changed",
"Your request at $mainSiteURL has been ".
"changed.\n\n".
"$adminMessage\n",
$mailHeaders );
// redirect to return URL
header( "Location: $return_url" );
}
}
/**
* Removes an account according to POSTed values.
*/
function sb_removeAccount() {
global $return_url, $tableNamePrefix;
$user_id = sb_getRequestVariableSafe( "user_id" );
$query = 0;
global $header, $footer;
$removalAllowed = true;
if( $user_id == NULL ) {
$removalAllowed = false;
// display failure page
sb_messagePage( "No user_id field given." );
}
else {
if( !sb_isAdministrator() ) {
$removalAllowed = false;
// display failure page
sb_messagePage( "You must be an administrator to remove accounts." );
}
else {
$query = "DELETE FROM $tableNamePrefix" . "users " .
"WHERE user_id = '$user_id';";
}
}
if( $removalAllowed ) {
sb_connectToDatabase();
sb_queryDatabase( $query );
sb_closeDatabase();
// redirect to return URL
header( "Location: $return_url" );
}
}
/**
* Displays the admin queue for a given blog.
*
* @param $inBlogName the name of the blog to show a queue for, or "*" to
* show queue for all blogs together.
*/
function sb_showPostQueue( $inBlogName ) {
global $header, $footer, $tableNamePrefix;
if( ! sb_isAdministrator() ) {
sb_messagePage( "You must be an administrator to view the queue." );
return;
}
$displayBlogName = "";
$blogNameQueryLine = "";
if( strcmp( $inBlogName, "*" ) != 0 ) {
$displayBlogName = "from <EM>$inBlogName</EM> ";
$blogNameQueryLine = "AND blog_name = '$inBlogName' ";
}
include( $header );
echo "<BR><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=5><TR><TD COLSPAN=4>";
echo "<FONT SIZE=4>Posts $displayBlogName".
"waiting for approval:</FONT></TD></TR>";
// get pending blog posts from the database
$orderClause = "ORDER BY creation_date DESC";
$query =
"SELECT * " .
"FROM $tableNamePrefix"."posts " .
"WHERE approved = '0' AND removed = '0' ".
"$blogNameQueryLine".
"AND ( expiration_date > CURRENT_TIMESTAMP OR " .
"expiration_date IS NULL ) " .
"$orderClause;";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
$numRows = mysql_numrows( $result );
global $currentColor, $altColor;
/**
* Resets the value of the bg colors.
*/
function sb_resetBGColors() {
global $currentColor, $altColor;
$currentColor = "#CCCCCC";
$altColor = "#EEEEEE";
}
/**
* Prints and alternating BGCOLOR attribute.
*/
function sb_printNextBGColor() {
global $currentColor, $altColor;
echo "BGCOLOR=$currentColor";
$tempColor = $currentColor;
$currentColor = $altColor;
$altColor = $tempColor;
}
if( $numRows == 0 ) {
echo "<TR><TD>[none]</TD></TR>";
}
else {
// table headers
echo "<TR><TD><B>Context:</B></TD>";
echo "<TD><B>Author:</B></TD>";
echo "<TD><B>Headline:</B></TD>";
echo "<TD></TD></TR>";
}
// this queue should be the return destination after edits
$return_url = sb_getReturnURL();
$return_url = urlencode( $return_url );
for( $i=0; $i<$numRows; $i++ ) {
// restart color cycling
sb_resetBGColors();
$blog_name = mysql_result( $result, $i, "blog_name" );
$subject_line = mysql_result( $result, $i, "subject_line" );
$post_id = mysql_result( $result, $i, "post_id" );
$author = mysql_result( $result, $i, "user_id" );
$context = $blog_name;
if( preg_match( "/_comments/", $blog_name ) ) {
preg_match( "/(.*)_comments/", $blog_name, $matches );
// matches[0] contains full matched string
// matches[1] contains first parenthesized subpattern
$parentPostID = $matches[1];
// fetch subject line of parent post
$query =
"SELECT * " .
"FROM $tableNamePrefix"."posts " .
"WHERE post_id = '$parentPostID';";
$contextResult = sb_queryDatabase( $query );
$context_subject_line =
mysql_result( $contextResult, 0, "subject_line" );
$context = "Comment to <A HREF=\"".
"seedBlogs.php?action=display_post" .
"&show_author=1&show_date=1".
"&post_id=$post_id&return_url=$return_url\">".
"$context_subject_line</A>";
}
echo "<TR><TD "; sb_printNextBGColor(); echo ">$context</TD>";
echo "<TD "; sb_printNextBGColor(); echo ">$author</TD>";
echo "<TD "; sb_printNextBGColor(); echo ">$subject_line</TD>";
echo "<TD NOWRAP "; sb_printNextBGColor();
echo ">[<A HREF=\"seedBlogs.php?action=display_post" .
"&show_author=1&show_date=1".
"&post_id=$post_id&return_url=$return_url\">View</A>]";
echo " - [<A HREF=\"seedBlogs.php?action=edit_post" .
"&post_id=$post_id&return_url=$return_url\">".
"Edit</A>]";
echo " - [<A HREF=\"seedBlogs.php?action=approve_post" .
"&post_id=$post_id&return_url=$return_url\">".
"Approve</A>]</TD></TR>";
// blank space
echo "<TR><TD COLSPAN=3 ALIGN=CENTER></TD></TR>";
}
echo "</TD></TR></TABLE><BR><BR>";
sb_closeDatabase();
include( $footer );
}
/**
* Displays the admin queue of pending account requests.
*/
function sb_showAccountQueue() {
global $header, $footer, $tableNamePrefix;
if( ! sb_isAdministrator() ) {
sb_messagePage( "You must be an administrator to view the queue." );
return;
}
include( $header );
echo "<BR><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=5><TR><TD COLSPAN=3>";
echo "<FONT SIZE=4>Account requests ".
"waiting for approval:</FONT></TD></TR>";
// get pending accounts from the database
$query =
"SELECT * " .
"FROM $tableNamePrefix"."users " .
"WHERE approved = '0';";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$numRows = mysql_numrows( $result );
global $currentColor, $altColor;
/**
* Resets the value of the bg colors.
*/
function sb_resetBGColors() {
global $currentColor, $altColor;
$currentColor = "#CCCCCC";
$altColor = "#EEEEEE";
}
/**
* Prints and alternating BGCOLOR attribute.
*/
function sb_printNextBGColor() {
global $currentColor, $altColor;
echo "BGCOLOR=$currentColor";
$tempColor = $currentColor;
$currentColor = $altColor;
$altColor = $tempColor;
}
if( $numRows == 0 ) {
echo "<TR><TD>[none]</TD></TR>";
}
else {
// table headers
echo "<TR><TD><B>User ID:</B></TD>";
echo "<TD><B>Email:</B></TD>";
echo "<TD></TD></TR>";
}
// this queue should be the return destination after edits
$return_url = sb_getReturnURL();
$return_url = urlencode( $return_url );
for( $i=0; $i<$numRows; $i++ ) {
// restart color cycling
sb_resetBGColors();
$user_id = mysql_result( $result, $i, "user_id" );
$email = mysql_result( $result, $i, "email" );
echo "<TR><TD "; sb_printNextBGColor(); echo ">$user_id</TD>";
echo "<TD "; sb_printNextBGColor(); echo ">$email</TD>";
echo "<TD NOWRAP "; sb_printNextBGColor();
echo ">[<A HREF=\"seedBlogs.php?action=remove_account" .
"&user_id=$user_id&return_url=$return_url\">reject</A>]";
echo " - [<A HREF=\"seedBlogs.php?action=approve_account" .
"&user_id=$user_id&admin=0&return_url=$return_url\">".
"approve</A>]";
echo " - [<A HREF=\"seedBlogs.php?action=approve_account" .
"&user_id=$user_id&admin=1&return_url=$return_url\">".
"approve and make admin</A>]</TD></TR>";
// blank space
echo "<TR><TD COLSPAN=3 ALIGN=CENTER></TD></TR>";
}
echo "</TD></TR></TABLE><BR><BR>";
include( $footer );
}
/**
* Displays the admin list of all approved accounts in the system.
*/
function sb_showAccountList() {
global $header, $footer, $tableNamePrefix;
if( ! sb_isAdministrator() ) {
sb_messagePage( "You must be an administrator to ".
"view the account list." );
return;
}
include( $header );
echo "<BR><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=5><TR><TD COLSPAN=4>";
echo "<FONT SIZE=4>Active Accounts:</FONT></TD></TR>";
// get pending accounts from the database
$query =
"SELECT * " .
"FROM $tableNamePrefix"."users " .
"WHERE approved = '1' ".
"ORDER BY user_id ASC;";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$numRows = mysql_numrows( $result );
global $currentColor, $altColor;
/**
* Resets the value of the bg colors.
*/
function sb_resetBGColors() {
global $currentColor, $altColor;
$currentColor = "#CCCCCC";
$altColor = "#EEEEEE";
}
/**
* Prints and alternating BGCOLOR attribute.
*/
function sb_printNextBGColor() {
global $currentColor, $altColor;
echo "BGCOLOR=$currentColor";
$tempColor = $currentColor;
$currentColor = $altColor;
$altColor = $tempColor;
}
if( $numRows == 0 ) {
echo "<TR><TD>[none]</TD></TR>";
}
else {
// table headers
echo "<TR><TD><B>User ID:</B></TD>";
echo "<TD><B>Email:</B></TD>";
echo "<TD><B>Status:</B></TD>";
echo "<TD></TD></TR>";
}
// this queue should be the return destination after edits
$return_url = sb_getReturnURL();
$return_url = urlencode( $return_url );
for( $i=0; $i<$numRows; $i++ ) {
// restart color cycling
sb_resetBGColors();
$user_id = mysql_result( $result, $i, "user_id" );
$email = mysql_result( $result, $i, "email" );
$administrator = mysql_result( $result, $i, "administrator" );
echo "<TR><TD "; sb_printNextBGColor(); echo ">$user_id</TD>";
echo "<TD "; sb_printNextBGColor(); echo ">$email</TD>";
if( $administrator ) {
echo "<TD "; sb_printNextBGColor(); echo ">admin</TD>";
}
else {
echo "<TD "; sb_printNextBGColor(); echo "></TD>";
}
echo "<TD NOWRAP "; sb_printNextBGColor();
echo ">[<A HREF=\"seedBlogs.php?action=remove_account" .
"&user_id=$user_id&return_url=$return_url\">remove</A>]";
if( $administrator == 1 ) {
echo " - [<A HREF=\"seedBlogs.php?action=change_admin_status" .
"&user_id=$user_id&admin=0&return_url=$return_url\">".
"revoke admin status</A>]";
}
else {
echo " - [<A HREF=\"seedBlogs.php?action=change_admin_status" .
"&user_id=$user_id&admin=1&return_url=$return_url\">".
"make admin</A>]";
}
// blank space
echo "<TR><TD COLSPAN=4 ALIGN=CENTER></TD></TR>";
}
echo "</TD></TR></TABLE><BR><BR>";
include( $footer );
}
/**
* Performs search using posted variables and displays a results page.
*/
function sb_search() {
global $tableNamePrefix;
$key_words = sb_getRequestVariableSafe( "key_words" );
// this result page should be the return destination after edits
$return_url = sb_getReturnURL();
$return_url = urlencode( $return_url );
$keywordArray = explode( " ", $key_words );
$keywordWhereClause = "";
foreach( $keywordArray as $name => $word ) {
$keywordWhereClause = $keywordWhereClause .
"AND ( subject_line LIKE '%$word%' " .
"OR intro_text LIKE '%$word%' ".
"OR body_text LIKE '%$word%' )";
}
$query =
"SELECT * " .
"FROM $tableNamePrefix"."posts " .
"WHERE approved = '1' AND removed = '0' ".
"AND ( expiration_date > CURRENT_TIMESTAMP OR " .
"expiration_date IS NULL ) " .
"$keywordWhereClause;";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$numRows = mysql_numrows( $result );
global $header, $footer;
include( $header );
echo "<TABLE BORDER=0 WIDTH=100%><TR><TD>";
echo "<FONT SIZE=5>Search for <EM>$key_words</EM>:</FONT><BR><BR>";
if( $numRows == 0 ) {
echo "[no results]<BR>";
}
global $storyBlockFormatOpen, $storyBlockFormatClose,
$headlineFormatOpen, $headlineFormatClose,
$textBlockFormatOpen, $textBlockFormatClose, $storySeparator;
for( $i=0; $i<$numRows; $i++ ) {
$post_id = mysql_result( $result, $i, "post_id" );
$blog_name = mysql_result( $result, $i, "blog_name" );
$user_id = mysql_result( $result, $i, "user_id" );
$subject_line = mysql_result( $result, $i, "subject_line" );
$intro_text = mysql_result( $result, $i, "intro_text" );
$body_text = mysql_result( $result, $i, "body_text" );
$creation_date = mysql_result( $result, $i, "creation_date" );
$allow_comments = mysql_result( $result, $i, "allow_comments" );
$show_permalink = mysql_result( $result, $i, "show_permalink" );
sb_generateStoryBlock( $blog_name,
$post_id,
trim( $subject_line ),
$user_id,
$creation_date,
// hide up and down widgets
0,
0,
trim( $intro_text ),
trim( $body_text ),
0, // show link to body text
$allow_comments,
$show_permalink,
$return_url,
// formatting options:
$storyBlockFormatOpen,
$storyBlockFormatClose,
$headlineFormatOpen,
$headlineFormatClose,
$textBlockFormatOpen,
$textBlockFormatClose );
if( $i < $numRows - 1 ) {
// separate from next story
echo "$storySeparator";
}
}
echo "</TD></TR></TABLE>";
include( $footer );
}
/**
* Generates HTML for a story block with intro text visible.
*
* The point of this function is to abstract out the basic story block
* rendering code so that seedBlogFormatted() and sb_search() can both use it.
*
* @param $inBlogName the name of the blog in the database.
* @param $inPostID the post ID.
* @param $inSubjectLine the whitespace trimmed subject line.
* @param $inUserID the author of the post, or NULL to hide the author byline.
* @param $inDateString the MySQL creation date string of this post, or NULL
* to hide the date from the display.
* @param $inShowUpWidget 1 to show up widgets for this post, or
* 0 to hide it.
* @param $inShowDownWidget 1 to show down widget for this post, or
* 0 to hide it.
* @param $inIntroText the raw intro text from the database, whitespace
* trimmed.
* @param $inBodyText the raw body text from the database, whitespace
* trimmed, or NULL if there is no body.
* @param $inEmbedBodyText 1 to include the body text in the story block,
* or 0 to show a "read more" link.
* @param $inAllowComments 1 to allow comments, or 0 to forbid them.
* @param $inShowPermalink 1 to show a permanent link, or 0 to hide it.
* @param $inReturnURL the URL of the page that this block is part of.
*
* Other parameters (formatting options) are identical to those passed into
* seedBlogFormatted.
*/
function sb_generateStoryBlock( $inBlogName,
$inPostID,
$inSubjectLine,
$inUserID,
$inDateString,
$inShowUpWidget,
$inShowDownWidget,
$inIntroText,
$inBodyText,
$inEmbedBodyText,
$inAllowComments,
$inShowPermalink,
$inReturnURL,
// formatting options:
$inStoryBlockFormatOpen,
$inStoryBlockFormatClose,
$inHeadlineFormatOpen,
$inHeadlineFormatClose,
$inTextBlockFormatOpen,
$inTextBlockFormatClose ) {
// open story block
echo "$inStoryBlockFormatOpen\n";
// formatted subject line (no link)
echo "$inHeadlineFormatOpen$inSubjectLine$inHeadlineFormatClose\n";
echo "$inTextBlockFormatOpen";
$show_author = 0;
$show_date = 0;
if( $inUserID != NULL || $inDateString != NULL ) {
echo "<TABLE WIDTH=100% CELLPADDING=0 CELLSPACING=0><TR>";
if( $inUserID != NULL ) {
echo "<TD>by $inUserID</TD>";
$show_author = 1;
}
if( $inDateString != NULL ) {
$timestamp = strtotime( $inDateString );
// format as in Sunday, July 7, 2005 [4:52 pm]
$dateString = date( "l, F j, Y [g:i a]", $timestamp );
if( $inUserID == NULL ) {
echo "<TD>";
}
else {
echo "<TD ALIGN=RIGHT>";
}
echo "<EM>$dateString</EM></TD>";
$show_date = 1;
}
echo "</TR></TABLE>";
}
if( sb_canEdit( $inPostID ) ) {
// Edit link next to subject
echo "[<A HREF=\"seedBlogs.php?action=edit_post".
"&blog_name=$inBlogName".
"&post_id=$inPostID&return_url=$inReturnURL".
"&show_author=$show_author&show_date=$show_date\">" .
"Edit</A>]";
if( sb_isAdministrator() ) {
// show an approve link, if post is pending approval
global $tableNamePrefix;
$query =
"SELECT * " .
"FROM $tableNamePrefix"."posts " .
"WHERE post_id = '$inPostID';";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$approved = mysql_result( $result, 0, "approved" );
if( $approved == 0 ) {
echo "[<A HREF=\"seedBlogs.php?action=approve_post" .
"&post_id=$inPostID&return_url=$inReturnURL\">".
"Approve</A>]";
}
}
if( $inShowUpWidget ) {
echo "[<A HREF=\"seedBlogs.php?action=move_up".
"&blog_name=$inBlogName".
"&post_id=$inPostID&return_url=$inReturnURL\">" .
"Move Up</A>]";
}
if( $inShowDownWidget ) {
echo "[<A HREF=\"seedBlogs.php?action=move_down".
"&blog_name=$inBlogName".
"&post_id=$inPostID&return_url=$inReturnURL\">" .
"Move Down</A>]";
}
}
if( $inIntroText != NULL ) {
// intro text
$formattedIntro = sb_rcb_blog2html( $inIntroText );
echo "<BR>$formattedIntro";
}
if( $inBodyText != NULL && $inEmbedBodyText ) {
$formattedBody = sb_rcb_blog2html( $inBodyText );
echo "<BR><BR>$formattedBody";
}
// only open a table for the links if we are going to show some links
if( $inShowPermalink ||
( $inBodyText != NULL && ! $inEmbedBodyText ) ||
$inAllowComments ) {
// links under text
echo
"<BR><BR><TABLE BORDER=0 WIDTH=100% CELLSPACING=0 CELLPADDING=0><TR>";
if( $inBodyText != NULL && ! $inEmbedBodyText ) {
// a read-more link
echo "<TD ALIGN=LEFT>".
"<A HREF=\"seedBlogs.php?action=display_post" .
"&post_id=$inPostID".
"&show_author=$show_author&show_date=$show_date".
"\" TITLE=\"View the entire post\">Read more...</A></TD>";
}
else if( $inShowPermalink ) {
// a perma link
echo "<TD ALIGN=LEFT>".
"[<A HREF=\"seedBlogs.php?action=display_post" .
"&post_id=$inPostID".
"&show_author=$show_author&show_date=$show_date".
"\" TITLE=\"Permanent link for this post\">Link</A>]</TD>";
}
if( $inAllowComments ) {
$approvedCount = sb_countComments( $inPostID, 1 );
$queuedCount = sb_countComments( $inPostID, 0 );
$isAdmin = sb_isAdministrator();
echo "<TD ALIGN=RIGHT>";
if( $approvedCount > 0 ||
( $isAdmin && $queuedCount > 0 ) ) {
echo "[<A HREF=\"seedBlogs.php?action=display_post" .
"&post_id=$inPostID".
"&show_author=$show_author&show_date=$show_date".
"#comments\" TITLE=\"View and add comments\">".
"$approvedCount Comment";
if( $approvedCount != 1 ) {
echo "s";
}
echo "</A>";
if( $isAdmin && $queuedCount > 0 ) {
echo ", $queuedCount in <A HREF=\"seedBlogs.php?".
"action=show_post_queue".
"&blog_name=$inPostID"."_comments".
"&return_url=$inReturnURL\">Queue</A>";
}
echo "]";
}
else {
// no comments yet, but show link for submission
$postLinkName = "Submit Comment";
$allowPost = false;
global $autoApprovePublicComments, $loggedInID;
if( $autoApprovePublicComments ||
strcmp( $loggedInID, "" ) != 0 ) {
// post directly, don't submit
$postLinkName = "Post Comment";
}
echo "[<A HREF=\"seedBlogs.php?action=edit_post".
"&blog_name=$inPostID"."_comments".
"&return_url=$inReturnURL\" ".
"TITLE=\"Submit a comment into the approval queue\">" .
"$postLinkName</A>]";
}
echo"</TD>";
}
echo "</TR></TABLE>";
}
// close text block
echo "$inTextBlockFormatClose";
// close story block
echo "$inStoryBlockFormatClose";
}
/**
* Generates RSS 2.0 XML for a blog, using posted variables to select the
* blog and configure the RSS feed.
*
* The following RSS 2.0 spec was followed:
* http://blogs.law.harvard.edu/tech/rss
*/
function sb_rssFeed() {
global $tableNamePrefix;
$blog_name = sb_getRequestVariableSafe( "blog_name" );
$channel_title =
sb_stripMagicQuotes( sb_getRequestVariableSafe( "channel_title" ) );
$channel_description =
sb_stripMagicQuotes( sb_getRequestVariableSafe( "channel_description" ) );
$max_number = sb_getRequestVariableSafe( "max_number" );
$show_authors = sb_getRequestVariableSafe( "show_authors" );
$show_dates = sb_getRequestVariableSafe( "show_dates" );
// for now, only order by creation date in RSS feed
$orderClause = "ORDER BY creation_date DESC";
$limitNumber = $max_number;
if( $max_number == -1 ) {
// use a large number, as suggested in the MySQL docs, to cause
// limit to be ignored
$limitNumber = 99999;
}
// LIMIT is only supported by MySQL
$query =
"SELECT * " .
"FROM $tableNamePrefix"."posts " .
"WHERE approved = '1' AND removed = '0' ".
"AND blog_name = '$blog_name' ".
"AND ( expiration_date > CURRENT_TIMESTAMP OR " .
"expiration_date IS NULL ) " .
"$orderClause LIMIT 0, $limitNumber;";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$numRows = mysql_numrows( $result );
global $mainSiteURL, $fullSeedBlogsURL;
header( "Content-type: application/xml" );
// echo this to avoid problems with <?
echo "<?xml version=\"1.0\"?>\n";
// now inline the rest of the XML
// tested this with a validator, and it is valid RSS
?>
<rss version="2.0">
<channel>
<title><?php echo $channel_title;?></title>
<link><?php echo $mainSiteURL;?></link>
<description><?php echo $channel_description;?></description>
<?php
for( $i=0; $i<$numRows; $i++ ) {
$subject_line = "";
$post_id = "";
$intro_text = "";
$date = "";
$subject_line = mysql_result( $result, $i, "subject_line" );
$post_id = mysql_result( $result, $i, "post_id" );
$intro_text = mysql_result( $result, $i, "intro_text" );
$date = mysql_result( $result, $i, "creation_date" );
// trim leading/trailing whitespace
$subject_line = trim( $subject_line );
$intro_text = trim( $intro_text );
// convert bbcode into HTML
// then encode the HTML for insertion into an XML document
$intro_text =
htmlspecialchars( sb_rcb_blog2html( strip_tags( $intro_text ) ) );
// & is forbidden in an XML document
$post_url =
$fullSeedBlogsURL .
"?action=display_post&amp;post_id=$post_id".
"&amp;show_author=$show_authors&amp;show_date=$show_dates";
$timestamp = strtotime( $date );
// format as in Sun, 19 May 2002 15:21:36 GMT
// format copied from RSS 2.0 spec, cited above
// Spec points to RFC822 for date format.
// Found this format string for RFC822 in the PHP 5.1 source code
$formatString_RFC822 = "D, d M Y H:i:s T";
$dateString = date( $formatString_RFC822, $timestamp );
?>
<item>
<title><?php echo $subject_line;?></title>
<link><?php echo $post_url;?></link>
<description><?php echo $intro_text?></description>
<pubDate><?php echo $dateString?></pubDate>
</item>
<?php
// end for loop over posts
}
?>
</channel>
</rss>
<?php
}
/**
* Generates a page showing comments for a given post.
*
* @param $inPostID the post to show comments for.
*/
function sb_showComments( $inPostID ) {
global $tableNamePrefix;
// first, get the post's subject line from the database
$query =
"SELECT * " .
"FROM $tableNamePrefix"."posts " .
"WHERE post_id = '$inPostID';";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
if( mysql_numrows( $result ) != 1 ) {
sb_closeDatabase();
sb_fatalError( "Post $inPostID does not exist in database." );
}
$row = mysql_fetch_array( $result, MYSQL_ASSOC );
$subject_line = $row[ "subject_line" ];
sb_closeDatabase();
// now display the comments for this post
// the name of the comment-holding blog in the database
$commentBlogName = $inPostID . "_comments";
global $headlineFormatOpen, $headlineFormatClose,
$commentListOpen, $commentListClose;
echo $commentListOpen;
// use a seedBlog to display the comments
// order oldest-first, so we can follow thread of discussion
seedBlog(
// name of this seed blog in the database
$commentBlogName,
// 1 = show intro text below headlines
// 0 = show only headlines
1,
// 1 = show creation date for each post
// 0 = hide dates
1,
// show authors
1,
// 2 = allow custom order tweaking with up/down widgets
// 1 = order by creation date (newest first)
// 0 = order by expiration date (oldest first)
// -1 = order by creation date (oldest first)
-1,
// show an unlimited number of comments
-1,
// skip none of them (start with first post)
0,
// show the archive link
0,
// show the submission link to public
1,
// never allow sub-comments
0
);
echo $commentListClose;
}
/**
* Counts the comments associated with a given post.
*
* @param $inPostID the post to count comments for.
* @param $inApproved set to 1 to count only approved comments, or
* 0 to count comments in the approval queue. Defaults to 1.
*
* @return the number of comments.
*/
function sb_countComments( $inPostID, $inApproved = 1 ) {
global $tableNamePrefix;
// the name of the comment-holding blog in the database
$commentBlogName = $inPostID . "_comments";
$query =
"SELECT COUNT(*) FROM $tableNamePrefix"."posts ".
"WHERE approved = \"$inApproved\" AND removed = \"0\" AND ".
"blog_name = \"$commentBlogName\";";
sb_connectToDatabase();
$result = sb_queryDatabase( $query );
$count = mysql_result( $result, 0, 0 );
sb_closeDatabase();
return $count;
}
// general-purpose functions down here, many copied from NCN
/**
* Connects to the database according to the database variables.
*/
function sb_connectToDatabase() {
global $databaseServer,
$databaseUsername, $databasePassword, $databaseName;
mysql_connect( $databaseServer, $databaseUsername, $databasePassword )
or sb_fatalError( "Could not connect to database server: " .
mysql_error() );
mysql_select_db( $databaseName )
or sb_fatalError( "Could not select $databaseName database: " .
mysql_error() );
}
/**
* Closes the database connection.
*/
function sb_closeDatabase() {
mysql_close();
}
/**
* Queries the database, and dies with an error message on failure.
*
* @param $inQueryString the SQL query string.
*
* @return a result handle that can be passed to other mysql functions.
*/
function sb_queryDatabase( $inQueryString ) {
$result = mysql_query( $inQueryString )
or sb_fatalError( "Database query failed:<BR>$inQueryString<BR><BR>" .
mysql_error() );
return $result;
}
/**
* Checks whether a table exists in the currently-connected database.
*
* @param $inTableName the name of the table to look for.
*
* @return 1 if the table exists, or 0 if not.
*/
function sb_doesTableExist( $inTableName ) {
// check if our table exists
$tableExists = 0;
$query = "SHOW TABLES";
$result = sb_queryDatabase( $query );
$numRows = mysql_numrows( $result );
for( $i=0; $i<$numRows && ! $tableExists; $i++ ) {
$tableName = mysql_result( $result, $i, 0 );
if( strcmp( $tableName, $inTableName ) == 0 ) {
$tableExists = 1;
}
}
return $tableExists;
}
/**
* Displays the error page and dies.
*
* @param $message the error message to display on the error page.
*/
function sb_fatalError( $message ) {
//global $errorMessage;
// set the variable that is displayed inside error.php
//$errorMessage = $message;
//include_once( "error.php" );
// for now, just print error message
echo( "<B>Fatal error:</B> $message<BR>" );
die();
}
/**
* Displays a message page.
*
* @param $message the message to display.
*/
function sb_messagePage( $message ) {
global $header, $footer;
include( $header );
echo( "<BR>$message<BR><BR>" );
include( $footer );
}
/**
* Prints form elements for selecting a date and time.
*
* @param $namePrefix the prefix to use in each form element
* name. For example, if $namePrefix is "my_", then the
* form elements will have the following names:
* my_month, my_day, my_year, my_hour, my_minute, my_ampm
* All fields have numerical posted values, except ampm, which
* is either "am" or "pm".
* @param $fillWithCurrentTime set to 1 to fill with current time.
* @param $selected____ indicates values that should be pre-selected.
*/
function sb_printDateTimeForm( $namePrefix,
$fillWithCurrentTime = 0,
$selectedMonth = NULL, $selectedDay = NULL,
$selectedYear = NULL, $selectedHour = NULL,
$selectedMinute = NULL,
$selectedAMPM = NULL ) {
if( $fillWithCurrentTime ) {
$currentDateAndTime = getdate();
$selectedHour = $currentDateAndTime[ "hours" ];
$selectedAMPM = "am";
if( $selectedHour > 11 ) {
if( $selectedHour < 24 ) {
$selectedAMPM = "pm";
}
$selectedHour = $selectedHour - 12;
}
$selectedMonth = $currentDateAndTime[ "mon" ];
$selectedDay = $currentDateAndTime[ "mday" ];
$selectedYear = $currentDateAndTime[ "year" ];
$selectedMinute = $currentDateAndTime[ "minutes" ];
}
$months = array( "January", "February", "March", "April",
"May", "June", "July", "August", "September",
"October", "November", "December" );
echo "<TABLE BORDER=0><TR>";
echo "<TD>Date:</TD><TD><SELECT NAME=\"$namePrefix" . "month\">\n";
foreach( $months as $i => $monthName ) {
$monthNumber = $i + 1;
$selectedState = "";
if( $selectedMonth == $monthNumber ) {
$selectedState = "SELECTED";
}
echo "<OPTION VALUE=\"$monthNumber\" " .
"$selectedState>$monthName</OPTION>\n";
}
echo "</SELECT>\n";
echo "<SELECT NAME=\"$namePrefix" . "day\">\n";
for( $day=1; $day<=31; $day++ ) {
$selectedState = "";
if( $selectedDay == $day ) {
$selectedState = "SELECTED";
}
echo "<OPTION $selectedState>$day</OPTION>\n";
}
echo "</SELECT>\n";
echo "<SELECT NAME=\"$namePrefix" . "year\">\n";
for( $year=2005; $year<=2015; $year++ ) {
$selectedState = "";
if( $selectedYear == $year ) {
$selectedState = "SELECTED";
}
echo "<OPTION $selectedState>$year</OPTION>\n";
}
echo "</SELECT></TD></TR>\n";
// start new line
echo "<TR>";
echo "<TD>Time:</TD><TD><SELECT NAME=\"$namePrefix" . "hour\">\n";
for( $hour=1; $hour<=12; $hour++ ) {
$selectedState = "";
if( $selectedHour == $hour ) {
$selectedState = "SELECTED";
}
echo "<OPTION $selectedState>$hour</OPTION>\n";
}
echo "</SELECT>\n";
echo "<SELECT NAME=\"$namePrefix" . "minute\">\n";
for( $minute=0; $minute<=9; $minute++ ) {
$selectedState = "";
if( $selectedMinute == $minute ) {
$selectedState = "SELECTED";
}
echo "<OPTION VALUE=\"$minute\" $selectedState>" .
"0$minute</OPTION>\n";
}
for( $minute=10; $minute<=59; $minute++ ) {
$selectedState = "";
if( $selectedMinute == $minute ) {
$selectedState = "SELECTED";
}
echo "<OPTION $selectedState>$minute</OPTION>\n";
}
echo "</SELECT>\n";
// radio for am/pm
$amCheckedState = "";
$pmCheckedState = "";
if( strcmp( $selectedAMPM, "am" ) == 0 ) {
$amCheckedState = "checked";
}
if( strcmp( $selectedAMPM, "pm" ) == 0 ) {
$pmCheckedState = "checked";
}
echo "<INPUT TYPE=\"radio\" NAME=\"$namePrefix" .
"ampm\" VALUE=\"am\" $amCheckedState>am ";
echo "<INPUT TYPE=\"radio\" NAME=\"$namePrefix" .
"ampm\" VALUE=\"pm\" $pmCheckedState>pm ";
echo "</TD></TR></TABLE>";
}
/**
* Prints form elements for selecting a date and time, preselecting a time
* using an SQL timestamp.
*
* @param $namePrefix the prefix to use in each form element
* name. For example, if $namePrefix is "my_", then the
* form elements will have the following names:
* my_month, my_day, my_year, my_hour, my_minute, my_ampm
* All fields have numerical posted values, except ampm, which
* is either "am" or "pm".
* @param $fillWithCurrentTime set to 1 to fill with current time.
* @param $selectedTimestamp the SQL timestamp to pre-select.
*/
function sb_printDateTimeFormFromTimestamp( $namePrefix,
$fillWithCurrentTime = 0,
$selectedTimestamp ) {
if( $fillWithCurrentTime ) {
// ignore selectedTimestamp
sb_printDateTimeForm( $namePrefix, $fillWithCurrentTime );
}
else {
$unixTimeInSeconds = strtotime( $selectedTimestamp );
// get array of separated time values
$timeValues = getdate( $unixTimeInSeconds );
$hours = $timeValues[ "hours" ];
// convert to 12-hour time
$ampm = "am";
if( $hours > 11 ) {
if( $hours < 24 ) {
$ampm = "pm";
}
$hours = $hours - 12;
}
sb_printDateTimeForm( $namePrefix,
$fillWithCurrentTime,
$timeValues[ "mon" ], $timeValues[ "mday" ],
$timeValues[ "year" ],
$hours,
$timeValues[ "minutes" ],
$ampm );
}
}
/**
* Formats time data as an SQL timestamp.
* An example timestamp: "2005-01-19 17:22:50"
*
* Most parameters are self-explanatory, except:
* @param $ampm one of "am", "pm", or NULL to indicate 24-hour time.
*/
function sb_formatTime( $year, $month, $day, $hour, $minute, $second, $ampm ) {
$formattedHour = $hour;
if( $ampm != NULL ) {
if( strcmp( $ampm, "pm" ) == 0) {
$formattedHour += 12;
}
}
if( $formattedHour < 10 ) {
$formattedHour = "0$formattedHour";
}
$formattedMinute = $minute;
if( $formattedMinute < 10 ) {
$formattedMinute = "0$formattedMinute";
}
$formattedSecond = $second;
if( $formattedSecond < 10 ) {
$formattedSecond = "0$formattedSecond";
}
$formattedDay = $day;
if( $formattedDay < 10 ) {
$formattedDay = "0$formattedDay";
}
$formattedMonth = $month;
if( $formattedMonth < 10 ) {
$formattedMonth = "0$formattedMonth";
}
return "$year-$formattedMonth-$formattedDay " .
"$formattedHour:$formattedMinute:$formattedSecond";
}
/**
* Gets a post ID that is guaranteed to be unique.
*
* A user must be logged in for this to work properly.
* In other words, the global $loggedInID must be set.
*
* This function queries the database to ensure that the ID is actually
* unique and tries IDs until a uniqe one is found
*
* The correctness of this function depends on the fact that a given
* user will only be inserting one item at a time into the database.
* If multiple items are being inserted, each INSERT querie must be
* performed before the next getUniqueListingID call.
*
* @return a unique ID.
*/
function sb_getUniquePostID() {
global $loggedInID, $tableNamePrefix;
// use current time as part of the ID string
$currentTime = time();
// keep trying until we create an ID that is unique in the database
// use counter in case more than one new item is inserted by
// a user in the same second (in which case, $currentTime will be
// the same for both items).
$uniqueListingCounter = 0;
sb_connectToDatabase();
$foundUnique = 0;
$uniqueID = "";
while( ! $foundUnique ) {
$uniqueID = "$loggedInID" . "_$currentTime" . "_$uniqueListingCounter";
$query = "SELECT * FROM $tableNamePrefix"."posts WHERE post_id = '$uniqueID';";
$result = sb_queryDatabase( $query );
$numRows = mysql_numrows( $result );
if( $numRows == 0 ) {
// found a unique ID
$foundUnique = 1;
}
else {
// collision with existing ID
// increment counter and try again
$uniqueListingCounter ++;
}
}
sb_closeDatabase();
return $uniqueID;
}
/**
* Computes cryptographic hash on a password.
*
* @param $user_id the user's ID.
* @param $password the user's password.
*
* @return the 32-character, hex-encoded MD5 hash.
*/
function sb_computePasswordHash( $user_id, $password ) {
global $siteShortName;
$currentTime = time();
$stringToHash = "$siteShortName$user_id$password";
$password_md5 = md5( $stringToHash );
return $password_md5;
}
/**
* Computes a session ID for a user.
*
* @param $user_id the user's ID.
* @param $password the user's password.
*
* @return the 32-character session ID.
*/
function sb_computeSessionID( $user_id, $password ) {
global $siteShortName;
$currentTime = time();
$session_id_string = "$siteShortName$user_id$password$currentTime";
$session_id = md5( $session_id_string );
return $session_id;
}
/**
* Refreshes a user's cookie.
*
* @param $user_id the user's ID.
* @param $session_id the session ID.
*/
function sb_refreshCookie( $user_id, $session_id ) {
global $cookieName;
// expire in 24 hours
$expireTime = time() + 60 * 60 * 24;
setcookie( $cookieName ."_user_id", sb_stripMagicQuotes( $user_id ),
$expireTime, "/" );
setcookie( $cookieName ."_session_id", $session_id, $expireTime, "/" );
}
/**
* Clears a user's cookie.
*
*/
function sb_clearCookie() {
global $cookieName;
// expire an hour ago
$expireTime = time() - 60 * 60;
setcookie( $cookieName ."_user_id", "", $expireTime, "/" );
setcookie( $cookieName ."_session_id", "", $expireTime, "/" );
}
/**
* Gets the ID of the user that is logged in.
*
* @return the user ID, or "" if no user is logged in.
*/
function sb_getLoggedInUser() {
global $cookieName;
$cookie_user_id = "";
if( isset( $_COOKIE[ $cookieName ."_user_id" ] ) ) {
$cookie_user_id = $_COOKIE[ $cookieName ."_user_id" ];
}
$cookie_session_id = "";
if( isset( $_COOKIE[ $cookieName ."_session_id" ] ) ) {
$cookie_session_id = $_COOKIE[ $cookieName ."_session_id" ];
}
global $justLoggedOut;
if( ! $justLoggedOut &&
strcmp( $cookie_user_id, "" ) != 0 &&
strcmp( $cookie_session_id, "" ) != 0 &&
// some versions of IE change cookie value to "deleted" upon deletion
// instead of clearing the cookie
strcmp( $cookie_user_id, "deleted" ) != 0 &&
strcmp( $cookie_session_id, "deleted" ) != 0) {
// check that session ID matches ID in database
$trueSessionID = sb_getUserDatabaseField( $cookie_user_id, "session_id" );
// session ID in database is set and
// it matches the cookie session ID
if( strcmp( $trueSessionID, "" ) != 0 &&
strcmp( $trueSessionID, $cookie_session_id ) == 0 ) {
return $cookie_user_id;
}
}
// else
return "";
}
/**
* Gets whether a user exists in the database.
*
* @param $user_id the user's ID.
*/
function sb_doesUserExist( $user_id ) {
global $tableNamePrefix;
sb_connectToDatabase();
$query = "SELECT * FROM $tableNamePrefix"."users " .
"WHERE user_id = '$user_id';";
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$numRows = mysql_numrows( $result );
if( $numRows == 1 ) {
return 1;
}
else {
return 0;
}
}
/**
* Gets whether the currently logged-in user has administrator status.
*
* @return true if user is an admin, or false otherwise.
*/
function sb_isAdministrator() {
global $loggedInID;
if( strcmp( $loggedInID, "" ) == 0 ) {
// public can never edit
return false;
}
if( sb_getUserDatabaseField( $loggedInID, "administrator" ) == 1 ) {
// admins can always edit
return true;
}
return false;
}
/**
* Gets the value of a user's field from the database.
*
* @param $user_id the user's ID.
* @param $fieldName the name of the field to get.
*/
function sb_getUserDatabaseField( $user_id, $fieldName ) {
global $tableNamePrefix;
sb_connectToDatabase();
$query = "SELECT $fieldName FROM $tableNamePrefix"."users " .
"WHERE user_id = '$user_id';";
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$numRows = mysql_numrows( $result );
if( $numRows == 1 ) {
$fieldValue = mysql_result( $result, 0, $fieldName );
return $fieldValue;
}
else {
sb_fatalError(
"Could not get database field $fieldName for user $user_id" );
}
}
/**
* Gets the value of a post's field from the database.
*
* @param $post_id the post's ID.
* @param $fieldName the name of the field to get.
*/
function sb_getPostDatabaseField( $post_id, $fieldName ) {
global $tableNamePrefix;
sb_connectToDatabase();
$query = "SELECT $fieldName FROM $tableNamePrefix"."posts " .
"WHERE post_id = '$post_id';";
$result = sb_queryDatabase( $query );
sb_closeDatabase();
$numRows = mysql_numrows( $result );
if( $numRows == 1 ) {
$fieldValue = mysql_result( $result, 0, $fieldName );
return $fieldValue;
}
else {
sb_fatalError(
"Could not get database field $fieldName for post $post_id" );
}
}
/**
* Sets the value of a user's field in the database.
*
* @param $user_id the user's ID.
* @param $fieldName the name of the field to set.
* @param $fieldValue the value to set, or NULL to set the field to NULL.
* @param $autoQuote set to 1 to automatically add quotes to the fieldValue.
* Defaults to 1.
*/
function sb_setUserDatabaseField( $user_id, $fieldName, $fieldValue,
$autoQuote = 1 ) {
global $tableNamePrefix;
sb_connectToDatabase();
$fieldData = $fieldValue;
if( $autoQuote ) {
$fieldData = "'$fieldValue'";
}
if( $fieldValue == NULL ) {
$fieldData = "NULL";
}
$query =
"UPDATE $tableNamePrefix"."users SET $fieldName = $fieldData ".
"WHERE user_id = '$user_id';";
$result = sb_queryDatabase( $query );
sb_closeDatabase();
}
/**
* Strips any magically escaped quotes from a string.
*
* Deals with PHP magic quotes (either on or off) automatically in conjunction
* with this script's $use_magic_quotes variable.
*
* This function is useful for user-submitted strings that are *not* destined
* for the SQL database (for example, when setting cookies or displaying
* such strings to the user).
*
* @param the string to strip.
*
* @return the stripped string, with any escaped quotes fixed into normal
* quotes.
*/
function sb_stripMagicQuotes( $string ) {
global $use_magic_quotes;
if( $use_magic_quotes ) {
// magic quotes on
// need to strip slashes
return stripSlashes( $string );
}
else {
// magic quotes off
// do nothing
return $string;
}
}
/**
* Recursively applies the addslashes function to arrays of arrays.
* This effectively forces magic_quote escaping behavior, eliminating
* a slew of possible database security issues.
*
* @inValue the value or array to addslashes to.
*
* @return the value or array with slashes added.
*/
function sb_addslashes_deep( $inValue ) {
return
( is_array( $inValue )
? array_map( 'sb_addslashes_deep', $inValue )
: addslashes( $inValue ) );
}
/**
* Recursively applies the stripslashes function to arrays of arrays.
* This effectively disables magic_quote escaping behavior.
*
* @inValue the value or array to stripslashes from.
*
* @return the value or array with slashes removed.
*/
function sb_stripslashes_deep( $inValue ) {
return
( is_array( $inValue )
? array_map( 'sb_stripslashes_deep', $inValue )
: stripslashes( $inValue ) );
}
/**
* Gets the raw contents of a variable from the HTTP request. This will
* include escaped quotes if magic quotes are enabled.
*
* @param $inVariableName the name of the variable.
*
* @return the value of the variable.
*/
function sb_getRequestVariableRaw( $inVariableName ) {
return $_REQUEST[ $inVariableName ];
}
/**
* Gets the filtered of a variable from the HTTP request. This will
* include escaped quotes if magic quotes are enabled.
* Example filtering behavior: HTML tags are removed.
*
* @param $inVariableName the name of the variable.
*
* @return the filtered value of the variable.
*/
function sb_getRequestVariableSafe( $inVariableName ) {
if( isset( $_REQUEST[ $inVariableName ] ) ) {
return strip_tags( $_REQUEST[ $inVariableName ] );
}
else {
return "";
}
}
/**
* Counts the number of users in the database.
*
* @return the number of users.
*/
function sb_getUserCount() {
global $tableNamePrefix;
sb_connectToDatabase();
$result =
sb_queryDatabase( "SELECT COUNT(*) FROM $tableNamePrefix"."users;" );
$userCount = mysql_result( $result, 0, 0 );
sb_closeDatabase();
return $userCount;
}
/**
* Tests whether the currently logged-in user can edit a post.
* Works even if no user is logged in.
*
* @param $inPostID the post ID to test edit powers for.
*
* @return true if editing is allowed, or false if editing is forbidden.
*/
function sb_canEdit( $inPostID ) {
global $loggedInID;
if( strcmp( $loggedInID, "" ) == 0 ) {
// public can never edit
return false;
}
if( sb_getUserDatabaseField( $loggedInID, "administrator" ) == 1 ) {
// admins can always edit
return true;
}
if( strcmp( $loggedInID,
sb_getPostDatabaseField( $inPostID, "user_id" ) ) == 0 ) {
// rest of users can only edit their own posts
return true;
}
else {
return false;
}
}
/**
* Tests whether a post is visible (approved, not removed, and not expired).
*
* Must be connected to database before calling.
*
* @param $inPostID the ID to check.
*
* @return true if visible, or false if not.
*/
function sb_isPostVisible( $inPostID ) {
global $tableNamePrefix;
$query =
"SELECT COUNT(*) " .
"FROM $tableNamePrefix"."posts " .
"WHERE approved = '1' AND removed = '0' ".
"AND post_id = '$inPostID' ".
"AND ( expiration_date > CURRENT_TIMESTAMP OR " .
"expiration_date IS NULL );";
$result = sb_queryDatabase( $query );
if( mysql_result( $result, 0, 0 ) == 1 ) {
return true;
}
else {
return false;
}
}
/**
* Gets the full URL that was called to invoke this script, including
* all GET query parameters.
*
* @return the full return URL.
*/
function sb_getReturnURL() {
$return_url =
"http://" . $_SERVER['HTTP_HOST'] . $_SERVER[ "SCRIPT_NAME" ];
$queryString = $_SERVER[ "QUERY_STRING" ];
if( strcmp( $queryString, "" ) != 0 ) {
$return_url = $return_url . "?" . $_SERVER[ "QUERY_STRING" ];
}
return $return_url;
}
/**
* Strips HTML tags from data, preparing them for presentation as pure
* text in the browser.
*
* This function written by Noah Medling <noah.medling@gmail.com> as part
* of RCBlog.
*
* @param $inData the data to strip.
*
* @return the stripped data.
*/
function sb_rcb_striphtml( $inData ){
$patterns = array( '/</', '/>/', '/"/' );
$replace = array( '&lt;', '&gt;', '&quot;' );
return preg_replace( $patterns, $replace, $inData );
}
/**
* Renders text containing BBCode as HTML for presentation in a browser.
*
* This function written by Noah Medling <noah.medling@gmail.com> as part
* of RCBlog.
*
* @param $inData the data to convert.
*
* @return the stripped data.
*/
function sb_rcb_blog2html( $inData ){
$patterns = array(
"@(\r\n|\r|\n)?\\[\\*\\](\r\n|\r|\n)?(.*?)(?=(\\[\\*\\])|(\\[/list\\]))@si",
// [b][/b], [i][/i], [u][/u], [mono][/mono]
"@\\[b\\](.*?)\\[/b\\]@si",
"@\\[i\\](.*?)\\[/i\\]@si",
"@\\[u\\](.*?)\\[/u\\]@si",
"@\\[mono\\](.*?)\\[/mono\\]@si",
// [color=][/color], [size=][/size]
"@\\[color=([^\\]\r\n]*)\\](.*?)\\[/color\\]@si",
"@\\[size=([0-9]+)\\](.*?)\\[/size\\]@si",
// [quote=][/quote], [quote][/quote], [code][/code]
"@\\[quote=&quot;([^\r\n]*)&quot;\\](\r\n|\r|\n)*(.*?)(\r\n|\r|\n)*\\[/quote\\](\r\n|\r|\n)?@si",
"@\\[quote\\](\r\n|\r|\n)*(.*?)(\r\n|\r|\n)*\\[/quote\\](\r\n|\r|\n)?@si",
"@\\[code\\](\r\n|\r|\n)*(.*?)(\r\n|\r|\n)*\\[/code\\](\r\n|\r|\n)?@si",
// [center][/center], [right][/right], [justify][/justify],
// [centerblock][/centerblock] (centers a left-aligned block of text)
"@\\[center\\](\r\n|\r|\n)?(.*?)(\r\n|\r|\n)?\\[/center\\](\r\n|\r|\n)?@si",
"@\\[right\\](\r\n|\r|\n)?(.*?)(\r\n|\r|\n)?\\[/right\\](\r\n|\r|\n)?@si",
"@\\[justify\\](\r\n|\r|\n)?(.*?)(\r\n|\r|\n)?\\[/justify\\](\r\n|\r|\n)?@si",
"@\\[centerblock\\](\r\n|\r|\n)?(.*?)(\r\n|\r|\n)?\\[/centerblock\\](\r\n|\r|\n)?@si",
// [list][*][/list], [list=][*][/list]
"@\\[list\\](\r\n|\r|\n)*(.*?)(\r\n|\r|\n)*\\[/list\\](\r\n|\r|\n)?@si",
"@\\[list=1\\](\r\n|\r|\n)*(.*?)(\r\n|\r|\n)*\\[/list\\](\r\n|\r|\n)?@si",
"@\\[list=a\\](\r\n|\r|\n)*(.*?)(\r\n|\r|\n)*\\[/list\\](\r\n|\r|\n)?@si",
"@\\[list=A\\](\r\n|\r|\n)*(.*?)(\r\n|\r|\n)*\\[/list\\](\r\n|\r|\n)?@si",
"@\\[list=i\\](\r\n|\r|\n)*(.*?)(\r\n|\r|\n)*\\[/list\\](\r\n|\r|\n)?@si",
"@\\[list=I\\](\r\n|\r|\n)*(.*?)(\r\n|\r|\n)*\\[/list\\](\r\n|\r|\n)?@si",
// "@(\r\n|\r|\n)?\\[\\*\\](\r\n|\r|\n)?([^\\[]*)@si",
// [url=][/url], [url][/url], [email][/email]
"@\\[url=([^\\]\r\n]+)\\](.*?)\\[/url\\]@si",
"@\\[url\\](.*?)\\[/url\\]@si",
"@\\[urls=([^\\]\r\n]+)\\](.*?)\\[/urls\\]@si",
"@\\[urls\\](.*?)\\[/urls\\]@si",
"@\\[email\\](.*?)\\[/email\\]@si",
"@\\[a=([^\\]\r\n]+)\\]@si",
// [img][/img], [img=][/img], [clear]
"@\\[img\\](.*?)\\[/img\\](\r\n|\r|\n)?@si",
"@\\[imgl\\](.*?)\\[/imgl\\](\r\n|\r|\n)?@si",
"@\\[imgr\\](.*?)\\[/imgr\\](\r\n|\r|\n)?@si",
"@\\[img=([^\\]\r\n]+)\\](.*?)\\[/img\\](\r\n|\r|\n)?@si",
"@\\[imgl=([^\\]\r\n]+)\\](.*?)\\[/imgl\\](\r\n|\r|\n)?@si",
"@\\[imgr=([^\\]\r\n]+)\\](.*?)\\[/imgr\\](\r\n|\r|\n)?@si",
"@\\[clear\\](\r\n|\r|\n)?@si",
// [hr], \n
"@\\[hr\\](\r\n|\r|\n)?@si",
"@(\r\n|\r|\n)@");
$replace = array(
'<li>$3</li>',
// [b][/b], [i][/i], [u][/u], [mono][/mono]
'<b>$1</b>',
'<i>$1</i>',
'<span style="text-decoration:underline">$1</span>',
'<span class="mono">$1</span>',
// [color=][/color], [size=][/size]
'<span style="color:$1">$2</span>',
'<span style="font-size:$1px">$2</span>',
// [quote][/quote], [code][/code]
'<div class="quote"><span style="font-size:0.9em;font-style:italic">$1 wrote:<br /><br /></span>$3</div>',
'<div class="quote">$2</div>',
'<div class="code">$2</div>',
// [center][/center], [right][/right], [justify][/justify],
// [centerblock][/centerblock]
'<div style="text-align:center">$2</div>',
'<div style="text-align:right">$2</div>',
'<div style="text-align:justify">$2</div>',
'<CENTER><TABLE BORDER=0><TR><TD>$2</TD></TR></TABLE></CENTER>',
// [list][*][/list], [list=][*][/list]
'<ul>$2</ul>',
'<ol style="list-style-type:decimal">$2</ol>',
'<ol style="list-style-type:lower-alpha">$2</ol>',
'<ol style="list-style-type:upper-alpha">$2</ol>',
'<ol style="list-style-type:lower-roman">$2</ol>',
'<ol style="list-style-type:upper-roman">$2</ol>',
// '<li />',
// [url=][/url], [url][/url], [email][/email]
'<a href="$1" rel="external">$2</a>',
'<a href="$1" rel="external">$1</a>',
'<a href="$1">$2</a>',
'<a href="$1">$1</a>',
'<a href="mailto:$1">$1</a>',
'<a name="$1"></a>',
// [img][/img], [img=][/img], [clear]
'<img border=0 src="$1" alt="$1" />',
'<img border=0 align="left" src="$1" alt="$1" />',
'<img border=0 align="right" src="$1" alt="$1" />',
'<img border=0 src="$1" alt="$2" title="$2" />',
'<img border=0 align="left" src="$1" alt="$2" title="$2" />',
'<img border=0 align="right" src="$1" alt="$2" title="$2" />',
'<div style="clear:both"></div>',
// [hr], \n
'<hr />',
'<br />');
return preg_replace($patterns, $replace, sb_rcb_striphtml( $inData ) );
}
?>