<?php
/*
WPGet - retrieves WordPress posts from a database for display on a web pge
Copyright (C) 2006-2010 Peter Upfold.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
======================================================================
For more information:
Email: peter@upfold.org.uk
Web: http://peter.upfold.org.uk/projects/wpget
VERSION: 1.0
REVISION: $Rev: 20 $
*/
class wpGet {
// config
/********** START PASTING YOUR CONFIG HERE *********/
private $mysqluser = "username"; // your MySQL username for Wordpress
private $mysqlpass = "password"; // your MySQL password for Wordpress
private $mysqlhost = "localhost"; // your MySQL host
private $mysqldb = "wordpress"; // your MySQL database name for Wordpress
private $mysqlprefix="wp_"; // Wordpress table prefix - always include underscore at end if applicable
private $errorsto = false; // send error emails to whom?
// set the above to false if you don't want email error notifications
private $debugmode = false; // set to false when working on a real server so potential nasty people don't see MySQL errors
private $conn = false; // don't touch!
/********** STOP PASTING YOUR CONFIG HERE *********/
/****** PUBLIC VARIABLES (CAN BE CHANGED AT RUNTIME) *******/
public $dateformat = "Y-m-d H:i";
// date format for post date/time (the default above prints something like "17/10/2006 at 21:34" for October 17th)
// see http://www.php.net/date for details on the format
public $showcredit = true; // boolean
// controls whether the credit and link back to my site is shown (appreciated if you leave it on, but not compulsory)
public $categoriestoreturn = false;
// to return posts only from a particular category, turn this var
// into an array of the category names
// for example:
// var $categoriestoreturn = array();
// $categoriestoreturn[0] = "Category Name"
public $tagstoreturn = false;
// return posts only from certain tags. Works just like categoriestoreturn.
//Only use either categories or tags or neither, they do not work both at the same time currently.
public $daterange_start = false;
// Unix timestamp of the start of a daterange from which you would like to retrieve
// WordPress posts. Only posts within this var and daterange_end will be included
// in WPGet's output. Set to false to show posts regardless of date.
public $daterange_end = false;
// Unix timestamp of the end of a daterange from which you would like to retrieve
// WordPress posts. Only posts within daterange_start and this var will be included
// in WPGet's output. Set to false to show posts regardless of date.
public $searchtoreturn = false;
// Only return posts matching this search term. The post title and post content will
// be searched for this string. Only posts which match will be shown in WPGet's output.
// Leave as false to disable searching.
public $showauthor = true;
// show post author in WPGet's output
public $absoluteurldir = ".";
// if your wpget.php file is in a different directory
// to the file that will call it, specify the full web-accessible
// path (relative to the document root) of wpget.php
public $usestyle = false;
// use specified style for WPGet's output (or false for no style/custom)
/***** INTERNAL VARIABLES ONLY, DON'T CHANGE THEM *****/
private $categorylist = array();
private $catsearch = array();
private $taglist = array();
private $tagsearch = array();
private $qcount = 0;
/****** START OF CLASS FUNCTION DECLARATIONS *******/
// this function isn't mine - courtesy of mr at bbp dot biz (found at http://uk2.php.net/manual/en/function.substr.php#59719)
function html_substr($posttext, $minimum_length = 200, $length_offset = 20, $cut_words = FALSE, $dots = TRUE) {
// $minimum_length:
// The approximate length you want the concatenated text to be
// $length_offset:
// The variation in how long the text can be in this example text
// length will be between 200 and 200-20=180 characters and the
// character where the last tag ends
// Reset tag counter & quote checker
$tag_counter = 0;
$quotes_on = FALSE;
// Check if the text is too long
if (strlen($posttext) > $minimum_length) {
// Reset the tag_counter and pass through (part of) the entire text
$c = 0;
for ($i = 0; $i < strlen($posttext); $i++) {
// Load the current character and the next one
// if the string has not arrived at the last character
$current_char = substr($posttext,$i,1);
if ($i < strlen($posttext) - 1) {
$next_char = substr($posttext,$i + 1,1);
}
else {
$next_char = "";
}
// First check if quotes are on
if (!$quotes_on) {
// Check if it's a tag
// On a "<" add 3 if it's an opening tag (like <a href...)
// or add only 1 if it's an ending tag (like </a>)
if ($current_char == '<') {
if ($next_char == '/') {
$tag_counter += 1;
}
else {
$tag_counter += 3;
}
}
// Slash signifies an ending (like </a> or ... />)
// substract 2
if ($current_char == '/' && $tag_counter <> 0) $tag_counter -= 2;
// On a ">" substract 1
if ($current_char == '>') $tag_counter -= 1;
// If quotes are encountered, start ignoring the tags
// (for directory slashes)
if ($current_char == '"') $quotes_on = TRUE;
}
else {
// IF quotes are encountered again, turn it back off
if ($current_char == '"') $quotes_on = FALSE;
}
// Count only the chars outside html tags
if($tag_counter == 2 || $tag_counter == 0){
$c++;
}
// Check if the counter has reached the minimum length yet,
// then wait for the tag_counter to become 0, and chop the string there
if ($c > $minimum_length - $length_offset && $tag_counter == 0 && ($next_char == ' ' || $cut_words == TRUE)) {
$posttext = substr($posttext,0,$i + 1);
if($dots){
$posttext .= '...';
}
return $posttext;
}
}
}
return $posttext;
}
function connectToDB() {
if (!$this->conn)
{
// connects to the database and selects the right db ready for action
$this->conn = mysql_connect($this->mysqlhost, $this->mysqluser, $this->mysqlpass) or die($this->friendlyError(mysql_error(), "{Connect}"));
mysql_select_db($this->mysqldb) or die ($this->friendlyError(mysql_error(), "{Select DB}"));
}
} // end connectToDB()
function friendlyError($error, $query, $line = false, $file = false) {
// gives a friendly error should anything go wrong
echo "<h1>Error Loading This Page</h1><p>Please contact the site administrator and let them know that there is a configuration issue with WPGet.</p>";
if ($this->debugmode) {
echo "<p>MySQL said: <b>".$error."</b>.</p><p>It was running the following query: <b>".$query."</b>.</p><p>The query was called on line <b>".$line."</b> by file <b>".$file."</b>.";
}
// mail you telling you error details
else if ($this->errorsto != false) {
$mail = "Hey there,<br /><br />There was a database problem with the WPGet script on your site running on <b>".$_SERVER['HTTP_HOST']."</b>.<br /><br />
A user tried to view the page <b>".$_SERVER['REQUEST_URI']."</b> <i>(".$_SERVER['SCRIPT_FILENAME'].")</i>. Something went wrong with the database.
<br /><br />MySQL said:<b> ".$error."</b><br /><br />Query:<b> ".$query."</b>. Called on line <b>".$line."</b> by file <b>".$file."</b>.<br /><br />Have a nice day!";
if (error_log($mail, 1, $errorsto, "From: wpget@".$_SERVER['SERVER_NAME']."\nContent-type: text/html\n")) {
echo '<p>The site administrator has been notified of this error and should fix it soon.</p>';
}
else {
echo '<p>There was a problem automatically notifying the site administrator. Please contact the person who manages this site and tell them there is a problem with WPGet.</p>';
}
}
}// end friendlyError()
function query($sql, $line, $file) {
// wrapper function for all SQL queries (new as of 0.7), including new error handling
// and supression of PHP's errors
if (!$conn) {
$this->connectToDB();
}
$result = @mysql_query($sql, $this->conn) or die ($this->friendlyError(mysql_error(), $sql, $line, $file));
$this->qcount++;
return $result;
} // end query()
function crash() {
// crash function
$this->query("hfduhf", __LINE__, __FILE__);
} // end crash()
function convert_smart_quotes($string) // not mine either - thanks to Chris Shiflett at http://shiflett.org/archive/165
{
$search = array(chr(145),
chr(146),
chr(147),
chr(148),
chr(151));
$replace = array('‘',
'’',
'“',
'”',
'—');
return str_replace($search, $replace, $string);
}
function formatWPContent($wpdata, $chars, $stripimages, $stripembed, $stripscript, $striplinks) {
if ($chars > 0) {
$content = stripslashes($this->html_substr($wpdata['post_content'], $chars, 20));
$content = $this->convert_smart_quotes($content);
}
else {
$content = $wpdata['post_content'];
$content = $this->convert_smart_quotes($content);
}
// strip images from posts
if ($stripimages) {
$content = preg_replace('#</?img[^>]*>#is', '<!--img-->', $content);
}
if ($stripembed) {
// strip embeds from posts
$content = preg_replace('#</?embed[^>]*>(.+</embed[^>]*>|)#is', '<!--embed-->', $content);
}
if ($stripscript) {
// strip javascript from posts
$content = preg_replace('#</?script[^>]*>(.+</script[^>]*>|)#is', '<!--script-->', $content);
}
if ($striplinks) {
// strip any links (or other <a> tagged content) from posts
$content = preg_replace('#</?a[^>]*>#is', '<!--link-->', $content);
$content = preg_replace('#</?\/a[^>]*>#is', '<!--endlink-->', $content);
}
?><div class="__wpget_singleentry"><?php
echo '<h2><a href="'.$wpdata['guid'].'">'.$wpdata['post_title'].'</a></h2>'.nl2br($content).'<br /><br /><p>Posted on '.date($this->dateformat, strtotime($wpdata['post_date']));
if ($this->showauthor)
echo ' by '.$wpdata['display_name']; // print author name
echo '.<br />'.$wpdata['comment_count'];
if ($wpdata['comment_count'] > 0) {
$jump = "#comments";
}
else {
$jump = "#respond";
}
if ($wpdata['comment_count'] == 1) {
$comment = "comment";
}
else {
$comment = "comments";
}
echo ' <a href="'.$wpdata['guid'].$jump.'">'.$comment.'</a>.</p>';
?></div><?php
} // end formatWPContent()
function populateCategoryList() {
// now only compatible with 2.3/2.5.x series or higher.
// Support for < 2.2 is now dropped.
// this function populates an array of the available categories
// and their associated IDs so we can pull only relevant posts
$this->connectToDB();
$sql = "SELECT wpg_taxon.`term_taxonomy_id`, `name`, `slug`
FROM `".$this->mysqlprefix."terms` AS wpg_terms
INNER JOIN `".$this->mysqlprefix."term_taxonomy` AS wpg_taxon ON wpg_terms.`term_id` = wpg_taxon.`term_id`
WHERE wpg_taxon.`taxonomy` = 'category';";
$q = $this->query($sql, __LINE__, __FILE__);
while ($ar = mysql_fetch_array($q, MYSQL_ASSOC)) {
$this->categorylist[$ar['term_taxonomy_id']] = $ar['slug'];
} // end while
// now we want to create an array of the category IDs we are looking for
/* so iterate through all the categories we've been given and
match them to the numeric category IDs in the category list we
just created */
$i = 0;
// an array counter for us
foreach ($this->categoriestoreturn as $cat) {
$srch = array_search($cat, $this->categorylist);
if ($srch === false) { // treble equals to check if it is bool false and not just zero
// category not found, throw an error and halt execution
die("The category ".$cat." was not found, WPGet cannot get the posts!");
}
else {
$this->catsearch[$i] = $srch;
// set the list of categories to search to the ID of the current category
$i++;
// increment the counter
}
} // end foreach
} // end populateCategoryList()
function populateTagList() {
// pull posts from a set of tags
// only compatible with 2.3/2.5.x series or higher.
$this->connectToDB();
$sql = "SELECT wpg_taxon.`term_taxonomy_id`, `name`, `slug`
FROM `".$this->mysqlprefix."terms` AS wpg_terms
INNER JOIN `".$this->mysqlprefix."term_taxonomy` AS wpg_taxon ON wpg_terms.`term_id` = wpg_taxon.`term_id`
WHERE wpg_taxon.`taxonomy` = 'post_tag';";
$q = $this->query($sql, __LINE__, __FILE__);
while ($ar = mysql_fetch_array($q, MYSQL_ASSOC)) {
$this->taglist[$ar['term_taxonomy_id']] = $ar['slug'];
} // end while
// now we want to create an array of the category IDs we are looking for
/* so iterate through all the tags we've been given and
match them to the numeric tags IDs in the tag list we
just created */
$i = 0;
// an array counter for us
foreach ($this->tagstoreturn as $tag) {
$srch = array_search($tag, $this->taglist);
if ($srch === false) { // treble equals to check if it is bool false and not just zero
// tag not found, throw an error and halt execution
die("The tag ".$tag." was not found, WPGet cannot get the posts!");
}
else {
$this->tagsearch[$i] = $srch;
// set the list of tags to search to the ID of the current tag
$i++;
// increment the counter
}
} // end foreach
} // end populateTagList()
function getWordpressEntries($number = 5, $chars = 300, $stripimages = true, $stripembed = true, $stripscript = true, $striplinks = false) {
if (is_array($this->categoriestoreturn)) { // if we have selective categories on
// we do it a completely different way
// so populate the list
$this->populateCategoryList();
// then launch the alternative way to do it
$this->getCatWPEntries($this->catsearch, $number, $chars, $stripimages, $stripembed, $stripscript);
// and quit out of this function
return;
} // end if
else if (is_array($this->tagstoreturn)) { // selected tags are on
// populate tags
$this->populateTagList();
// launch category pull, passing in the tags
$this->getCatWPEntries($this->tagsearch, $number, $chars, $stripimages, $stripembed, $stripscript);
return;
}
$dateRangeClause = '';
$searchClause = '';
// if date range is set
if ($this->daterange_start !== false && $this->daterange_end !== false)
{
// get both start and end as Unix timestamps
if ((int) $this->daterange_start === $this->daterange_start)
{
// assume a timestamp
$start = (int) $this->daterange_start;
}
else {
$start = (int) strtotime($this->daterange_start);
}
if ((int) $this->daterange_end === $this->daterange_end)
{
// assume a timestamp
$end = (int) $this->daterange_end;
}
else {
$end = (int) strtotime($this->daterange_end);
}
if ($start == 0 || $end == 0)
{
// there is a problem with the date ranges
echo 'Invalid WPGet date ranges specified.';
if ($this->debugmode)
{
echo ' on line '.__LINE__.' of '.__FILE__;
}
return false;
}
$dateRangeClause = "AND UNIX_TIMESTAMP(posts.`post_date`) > {$start} AND UNIX_TIMESTAMP(posts.`post_date`) < {$end}";
}
if ($this->searchtoreturn !== false)
{
// do a post title/post content search -- only return posts which match the search
$this->connectToDB();
$search = mysql_real_escape_string($this->searchtoreturn);
$searchClause = "AND ((posts.post_title LIKE '%{$search}%') OR (posts.post_content LIKE '%{$search}%'))";
}
// if we have a style
if ($this->usestyle != false) {
$this->printStyleCSS($this->usestyle);
}
// gets $number of wordpress entries and prints in a friendly format
$this->connectToDB();
$sql = "SELECT *
FROM `".$this->mysqlprefix."posts` as posts INNER JOIN `".$this->mysqlprefix."users` as users ON users.ID = posts.post_author
WHERE posts.`post_status` = 'publish' AND posts.`post_type` = 'post'
{$dateRangeClause}
{$searchClause}
ORDER BY `post_date` DESC LIMIT {$number};";
$q = $this->query($sql, __LINE__, __FILE__);
?><div id="__wpget_entries"><?php
while ($ar = mysql_fetch_array($q)) {
$ar['post_ID'] = $ar[0]; // first row returned is posts.ID
$this->formatWPContent($ar, $chars, $stripimages, $stripembed, $stripscript, $striplinks);
}
// Credit to me can be disabled, see top for details
if ($this->showcredit) {
echo '<p style="font-size:0.8em">WordPress integration powered by <a href="http://peter.upfold.org.uk/projects/wpget">WPGet</a> by Peter Upfold.</p>';
}
?></div><?php
} // end getWordpressEntries()
function getSinglePost($postid, $chars = 0, $stripimages = true, $stripembed = true, $stripscript = true, $striplinks = false) {
// gets the specified post ID
$this->connectToDB();
settype($postid, int);
$postid = addslashes($postid);
$sql = "SELECT *, posts.`ID` as `post_ID`
FROM `".$this->mysqlprefix."posts` as posts INNER JOIN `".$this->mysqlprefix."users` as users ON users.ID = posts.post_author WHERE posts.`post_status` = 'publish' AND posts.`ID` = {$postid} AND users.`ID` = posts.`post_author`
ORDER BY `post_date` DESC LIMIT 1;";
$q = $this->query($sql, __LINE__, __FILE__);
$ar = mysql_fetch_assoc($q);
?><div id="__wpget_entries"><?php
$this->formatWPContent($ar, $chars, $stripimages, $stripembed, $stripscript, $striplinks);
// Credit to me can be disabled, see top for details
if ($this->showcredit) {
echo '<p style="font-size:0.8em">WordPress integration powered by <a href="http://peter.upfold.org.uk/projects/wpget">WPGet</a> by Peter Upfold.</p>';
}
?></div><?php
} // end getSinglePost
function getCatWPEntries($categories, $number = 5, $chars = 300, $stripimages = true, $stripembed = true, $stripscript = true, $striplinks = false) {
$i = 0; // counter
$catclause = "WHERE p2c.`term_taxonomy_id` IN (";
$catclause .= implode(',', $categories);
// implode our array of categories into a comma-delimited list for MySQL's 'IN'
$catclause .= ')';
$dateRangeClause = '';
$searchClause = '';
// if date range is set
if ($this->daterange_start !== false && $this->daterange_end !== false)
{
// get both start and end as Unix timestamps
if ((int) $this->daterange_start === $this->daterange_start)
{
// assume a timestamp
$start = (int) $this->daterange_start;
}
else {
$start = (int) strtotime($this->daterange_start);
}
if ((int) $this->daterange_end === $this->daterange_end)
{
// assume a timestamp
$end = (int) $this->daterange_end;
}
else {
$end = (int) strtotime($this->daterange_end);
}
if ($start == 0 || $end == 0)
{
// there is a problem with the date ranges
echo 'Invalid WPGet date ranges specified.';
if ($this->debugmode)
{
echo ' on line '.__LINE__.' of '.__FILE__;
}
return false;
}
$dateRangeClause = "AND UNIX_TIMESTAMP(posts.`post_date`) > {$start} AND UNIX_TIMESTAMP(posts.`post_date`) < {$end}";
}
if ($this->searchtoreturn !== false)
{
// do a post title/post content search -- only return posts which match the search
$this->connectToDB();
$search = mysql_real_escape_string($this->searchtoreturn);
$searchClause = "AND ((posts.post_title LIKE '%{$search}%') OR (posts.post_content LIKE '%{$search}%'))";
}
$sql = "SELECT * FROM
`{$this->mysqlprefix}posts` AS posts INNER JOIN
`{$this->mysqlprefix}term_relationships` AS p2c ON posts.`ID` = p2c.`object_id` INNER JOIN
`{$this->mysqlprefix}users` AS users ON users.`ID` = posts.`post_author`
{$catclause}
{$dateRangeClause}
{$searchClause}
AND posts.`post_status` = 'publish' AND posts.`post_type` = 'post'
ORDER BY p2c.`object_id` DESC
LIMIT {$number};";
$q = $this->query($sql, __LINE__, __FILE__);
// duplicate prevention
$shownPosts = array();
$spc = 0;
while ($ar = mysql_fetch_array($q)) {
$ar['post_ID'] = $ar['object_id']; // for formatWPContent()
if (!in_array($ar['object_id'], $shownPosts)) {
$shownPosts[$spc] = $ar['object_id'];
$spc++;
$this->formatWPContent($ar, $chars, $stripimages, $stripembed, $stripscript, $striplinks);
}
} // end while
// Credit to me can be disabled, see top for details
if ($this->showcredit) {
echo '<p style="font-size:0.8em">WordPress integration powered by <a href="http://peter.upfold.org.uk/projects/wpget">WPGet</a> by Peter Upfold.</p>';
}
} // end getCatWPEntries()
} // end class
?>
|