"; $setup_footer = "
"; // 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 "[". "Create Admin Account]"; } else if( $justLoggedOut || strcmp( $loggedInID, "" ) == 0 ) { $encoded_return_url= urlencode( $return_url ); // show the login form ?>
User ID:
Password:
[New Account]
[Forgot Password?]
" . sb_stripMagicQuotes( $loggedInID ) . "
\n"; echo "[Log Out] "; echo "[". "Edit Account]\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 = "$pendingCount account requests"; if( $pendingCount == 1 ) { $countString = "$pendingCount account request"; } echo "
[" . "$countString waiting]"; } // 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 = "$pendingCount posts"; if( $pendingCount == 1 ) { $countString = "$pendingCount post"; } echo "
[" . "$countString pending approval]"; } echo "
[" . "Manage Accounts]
"; } } } /** * 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" ) ); } ?>
NAME="key_words" VALUE=""> "; } echo "
"; } /** * 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 "[" . "$postLinkName]
"; } 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 = "$pendingCount posts"; if( $pendingCount == 1 ) { $countString = "$pendingCount post"; } echo "[" . "$countString in queue]
"; } } if( $inShowIntroText ) { // extra space //echo "
"; } // 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]
"; } $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 $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 "$inHeadlineFormatOpen". "$subject_line". "$inHeadlineFormatClose"; 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 " [" . "Edit]"; } if( $inOrder == 2 && sb_isAdministrator() ) { // show up/down widgets $index = $i + $inNumToSkip; $upShown = false; if( $index > 0 ) { echo " [" . "Up]"; $upShown = true; } if( $index < count( $mapArray ) - 1 ) { if( ! $upShown ) { // insert space to separate down widget from headline echo " "; } echo "[" . "Down]"; } } 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 "

"; } // archive pages have 10 posts each // show link to archive $offset = $inNumToSkip + $numRows; echo "[$numOlderPosts ". "in Archive]
"; } } } /** * 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 "". "
". "". "
". "". "
". "RSS 2.0". "
"; } // 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 "

seedBlogs Web-based Setup

"; echo "Creating tables:
"; echo "
"; sb_setupDatabase(); echo "


"; echo "After you create an admin account, the setup process will be ". "complete.

"; echo "Step 2: "; echo "
"; seedBlogs_showLoginBox(); echo "
"; 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 "

seedBlogs Web-based Setup

"; echo "seedBlogs will walk you through a brief setup process.

"; echo "Step 1: ". "". "create the database tables"; 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 "$tableName table created
"; } else { echo "$tableName table already exists
"; } $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 "$tableName table created
"; } else { echo "$tableName table already exists
"; } $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 "$tableName table created
"; } else { echo "$tableName table already exists
"; } 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 " . sb_stripMagicQuotes( $user_id ) . " 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 " . sb_stripMagicQuotes( $user_id ) . " 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 "$inMessage"; 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"; } ?>
"; if( $editExisting ) { echo ""; } echo ""; if( !$editExisting ) { ?> "; } ?>
User ID:
Leave blank to keep old password
Password:
Re-type Password:
Email:
$inMessage
"; echo "Enter either your user ID or your email address:" ?>
User ID:
Email:
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.
". "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 $user_id already exists." ); } else if( !$updateExisting && strcmp( $user_id, "Anonymous" ) == 0 ) { sb_showRegisterForm( "User id Anonymous 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.
". "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.
". "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; ?>
'; } if( ! preg_match( "/_comments/", $blog_name ) ) { // no expiration dates allowed on comments ?>
> Your Name: >
> Headline: >
>
> Body Text:
> Expires: > > Never Expires
> > > Allow Comments
> > > Show Permanent Link
> > Approve Post
> > Remove Post
'; } ?>
$author_name 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 0 ) { echo ""; echo "
"; echo ""; sb_showComments( $inPostID ); echo "
"; } } //echo ""; echo "
"; 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 "
"; seedBlog( $inBlogName, $show_intro, $show_authors, $show_dates, $order, $count, $offset, 1, // show the archive $show_submit_link_to_public ); echo "
"; 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 $inBlogName "; $blogNameQueryLine = "AND blog_name = '$inBlogName' "; } include( $header ); echo "
"; // 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 ""; } else { // table headers echo ""; echo ""; echo ""; echo ""; } // 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 ". "$context_subject_line"; } echo ""; echo ""; echo ""; echo ""; // blank space echo ""; } echo "
"; echo "Posts $displayBlogName". "waiting for approval:
[none]
Context:Author:Headline:
$context$author$subject_line[View]"; echo " - [". "Edit]"; echo " - [". "Approve]


"; 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 "
"; // 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 ""; } else { // table headers echo ""; echo ""; echo ""; } // 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 ""; echo ""; echo ""; // blank space echo ""; } echo "
"; echo "Account requests ". "waiting for approval:
[none]
User ID:Email:
$user_id$email[reject]"; echo " - [". "approve]"; echo " - [". "approve and make admin]


"; 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 "
"; // 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 ""; } else { // table headers echo ""; echo ""; echo ""; echo ""; } // 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 ""; echo ""; if( $administrator ) { echo ""; } else { echo ""; } echo ""; } echo "
"; echo "Active Accounts:
[none]
User ID:Email:Status:
$user_id$emailadmin[remove]"; if( $administrator == 1 ) { echo " - [". "revoke admin status]"; } else { echo " - [". "make admin]"; } // blank space echo "


"; 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 "
"; echo "Search for $key_words:

"; if( $numRows == 0 ) { echo "[no results]
"; } 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 "
"; 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 ""; if( $inUserID != NULL ) { echo ""; $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 ""; $show_date = 1; } echo "
by $inUserID"; } else { echo ""; } echo "$dateString
"; } if( sb_canEdit( $inPostID ) ) { // Edit link next to subject echo "[" . "Edit]"; 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 "[". "Approve]"; } } if( $inShowUpWidget ) { echo "[" . "Move Up]"; } if( $inShowDownWidget ) { echo "[" . "Move Down]"; } } if( $inIntroText != NULL ) { // intro text $formattedIntro = sb_rcb_blog2html( $inIntroText ); echo "
$formattedIntro"; } if( $inBodyText != NULL && $inEmbedBodyText ) { $formattedBody = sb_rcb_blog2html( $inBodyText ); echo "

$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 "

"; if( $inBodyText != NULL && ! $inEmbedBodyText ) { // a read-more link echo ""; } else if( $inShowPermalink ) { // a perma link echo ""; } if( $inAllowComments ) { $approvedCount = sb_countComments( $inPostID, 1 ); $queuedCount = sb_countComments( $inPostID, 0 ); $isAdmin = sb_isAdministrator(); echo ""; } echo "
". "Read more...". "[Link]"; if( $approvedCount > 0 || ( $isAdmin && $queuedCount > 0 ) ) { echo "[". "$approvedCount Comment"; if( $approvedCount != 1 ) { echo "s"; } echo ""; if( $isAdmin && $queuedCount > 0 ) { echo ", $queuedCount in Queue"; } 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 "[" . "$postLinkName]"; } echo"
"; } // 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 \n"; // now inline the rest of the XML // tested this with a validator, and it is valid RSS ?> <?php echo $channel_title;?> <?php echo $subject_line;?> $inQueryString

" . 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( "Fatal error: $message
" ); die(); } /** * Displays a message page. * * @param $message the message to display. */ function sb_messagePage( $message ) { global $header, $footer; include( $header ); echo( "
$message

" ); 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 ""; echo "\n"; // start new line echo ""; echo "
Date:\n"; echo "\n"; echo "
Time:\n"; echo "\n"; // radio for am/pm $amCheckedState = ""; $pmCheckedState = ""; if( strcmp( $selectedAMPM, "am" ) == 0 ) { $amCheckedState = "checked"; } if( strcmp( $selectedAMPM, "pm" ) == 0 ) { $pmCheckedState = "checked"; } echo "am "; echo "pm "; echo "
"; } /** * 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 as part * of RCBlog. * * @param $inData the data to strip. * * @return the stripped data. */ function sb_rcb_striphtml( $inData ){ $patterns = array( '//', '/"/' ); $replace = array( '<', '>', '"' ); return preg_replace( $patterns, $replace, $inData ); } /** * Renders text containing BBCode as HTML for presentation in a browser. * * This function written by Noah Medling 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="([^\r\n]*)"\\](\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( '
  • $3
  • ', // [b][/b], [i][/i], [u][/u], [mono][/mono] '$1', '$1', '$1', '$1', // [color=][/color], [size=][/size] '$2', '$2', // [quote][/quote], [code][/code] '
    $1 wrote:

    $3
    ', '
    $2
    ', '
    $2
    ', // [center][/center], [right][/right], [justify][/justify], // [centerblock][/centerblock] '
    $2
    ', '
    $2
    ', '
    $2
    ', '
    $2
    ', // [list][*][/list], [list=][*][/list] '
      $2
    ', '
      $2
    ', '
      $2
    ', '
      $2
    ', '
      $2
    ', '
      $2
    ', // '
  • ', // [url=][/url], [url][/url], [email][/email] '$2', '$1', '$2', '$1', '$1', '', // [img][/img], [img=][/img], [clear] '$1', '$1', '$1', '$2', '$2', '$2', '
    ', // [hr], \n '
    ', '
    '); return preg_replace($patterns, $replace, sb_rcb_striphtml( $inData ) ); } ?>