array(), 'rewrites' => array(),
'categories' => array(), 'feeds' => array());
# __construct()
function WPOMatic()
{
global $wpdb;
# Table names init
$this->db = array(
'campaign' => $wpdb->prefix . 'wpo_campaign',
'campaign_category' => $wpdb->prefix . 'wpo_campaign_category',
'campaign_feed' => $wpdb->prefix . 'wpo_campaign_feed',
'campaign_word' => $wpdb->prefix . 'wpo_campaign_word',
'campaign_post' => $wpdb->prefix . 'wpo_campaign_post',
'log' => $wpdb->prefix . 'wpo_log'
);
# Is installed ?
$this->installed = get_option('wpo_version') == $this->version;
$this->setup = get_option('wpo_setup');
# Actions
add_action('activate_wp-o-matic/wpomatic.php', array(&$this, 'install')); # Plugin installed
add_action('deactivate_wp-o-matic/wpomatic.php', array(&$this, 'uninstall')); # Plugin unintalled
add_action('init', array(&$this, 'init')); # Wordpress init
add_action('admin_footer', array(&$this, 'adminWarning')); # Admin footer
add_action('admin_menu', array(&$this, 'adminMenu')); # Admin menu creation
# Ajax actions
add_action('wp_ajax_delete-campaign', array(&$this, 'adminDelete'));
add_action('wp_ajax_test-feed', array(&$this, 'adminTestfeed'));
# WP-o-Matic URIs. Without trailing slash
$this->optionsurl = get_option('siteurl') . '/wp-admin/options-general.php';
$this->adminurl = $this->optionsurl . '?page=wpomatic.php';
$this->pluginpath = get_option('siteurl') . '/wp-content/plugins/wp-o-matic';
$this->helpurl = $this->pluginpath . '/help.php?item=';
$this->tplpath = $this->pluginpath . '/inc/admin';
$this->cachepath = WPODIR . get_option('wpo_cachepath');
# Cron command / url
$this->cron_command = attribute_escape('*/20 * * * * '. $php . ' ' . dirname(__FILE__) . '/cron.php?code=' . get_option('wpo_croncode'));
$this->cron_url = $this->pluginpath . '/cron.php?code=' . get_option('wpo_croncode');
}
/**
* Called when plugin is activated
*
*
*/
function install()
{
global $wpdb;
if(file_exists(ABSPATH . '/wp-admin/upgrade-functions.php'))
require_once(ABSPATH . '/wp-admin/upgrade-functions.php');
else
require_once(ABSPATH . '/wp-admin/includes/upgrade.php');
if(! $this->installed)
{
# wpo_campaign
dbDelta( "CREATE TABLE `{$this->db['campaign']}` (
`id` int(11) unsigned NOT NULL auto_increment,
`title` varchar(250) NOT NULL,
`active` tinyint(1) default '1',
`slug` varchar(250),
`template` MEDIUMTEXT,
`frequency` int(5) default '180',
`feeddate` tinyint(1) default '0',
`cacheimages` tinyint(1) default '1',
`posttype` varchar(50),
`authorid` int(11),
`allowcomments` tinyint(1) default '1',
`allowpings` tinyint(1) default '1',
`dopingbacks` tinyint(1) default '1',
`count` int(11),
`lastactive` timestamp,
`created_on` timestamp,
PRIMARY KEY (`id`)
);" );
# wpo_campaign_category
dbDelta( "CREATE TABLE `{$this->db['campaign_category']}` (
`id` int(11) unsigned NOT NULL auto_increment,
`category_id` int(11) NOT NULL,
`campaign_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
);" );
# wpo_campaign_feed
dbDelta( "CREATE TABLE `{$this->db['campaign_feed']}` (
`id` int(11) unsigned NOT NULL auto_increment,
`campaign_id` int(11) NOT NULL,
`url` varchar(255) NOT NULL,
`type` varchar(255) NOT NULL,
`title` varchar(255) NOT NULL,
`description` varchar(255) NOT NULL,
`logo` varchar(255),
`count` int(11),
`hash` varchar(255),
`lastactive` timestamp,
PRIMARY KEY (`id`)
);" );
# wpo_campaign_post
dbDelta( "CREATE TABLE `{$this->db['campaign_post']}` (
`id` int(11) unsigned NOT NULL auto_increment,
`campaign_id` int(11) NOT NULL,
`feed_id` int(11) NOT NULL,
`post_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
);" );
# wpo_campaign_word
dbDelta( "CREATE TABLE `{$this->db['campaign_word']}` (
`id` int(11) unsigned NOT NULL auto_increment,
`campaign_id` int(11) NOT NULL,
`word` varchar(255) NOT NULL,
`regex` tinyint(1) default '0',
`rewrite` tinyint(1) default '1',
`rewrite_to` varchar(255),
`relink` varchar(255),
PRIMARY KEY (`id`)
);" );
# wpo_log
dbDelta( "CREATE TABLE `{$this->db['log']}` (
`id` int(11) unsigned NOT NULL auto_increment,
`message` varchar(255) NOT NULL,
`created_on` timestamp,
PRIMARY KEY (`id`)
);" );
add_option('wpo_version', $this->version);
$this->installed = true;
}
# Options
WPOTools::addOptions(array(
'wpo_log' => array(1, 'Log WP-o-Matic actions'),
'wpo_unixcron' => array(WPOTools::isUnix(), 'Use unix-style cron'),
'wpo_croncode' => array(substr(md5(time()), 0, 8), 'Cron job password.'),
'wpo_cacheimages' => array(0, 'Cache all images. Overrides campaign options'),
'wpo_cachepath' => array('cache', 'Cache path relative to wpomatic directory')
));
}
/**
* Called when plugin is deactivated
*
*
*/
function uninstall()
{
global $wpdb;
// Delete tables
if($this->delete_tables)
{
foreach($this->db as $table)
$wpdb->query("DROP TABLE `{$table}` ");
}
// Delete options
WPOTools::deleteOptions(array('wpo_version', 'wpo_setup', 'wpo_log', 'wpo_unixcron', 'wpo_croncode', 'wpo_cacheimages', 'wpo_cachepath'));
}
/**
* Called when blog is initialized
*
*
*/
function init()
{
global $wpdb;
if($this->installed)
{
if(! get_option('wpo_unixcron'))
$this->processAll();
if(isset($_REQUEST['page']))
{
if(isset($_REQUEST['campaign_add']) || isset($_REQUEST['campaign_edit']))
$this->adminCampaignRequest();
$this->adminExportProcess();
$this->adminInit();
}
}
}
/**
* Saves a log message to database
*
*
* @param string $message Message to save
*/
function log($message)
{
global $wpdb;
if(get_option('wpo_log'))
{
$message = $wpdb->escape($message);
$wpdb->query("INSERT INTO `{$this->db['log']}` (message, created_on) VALUES ('$message', NOW()) ");
}
}
/**
* Called by cron.php to update the site
*
*
*/
function runCron($log = true)
{
$this->log('Running cron job');
$this->processAll();
}
/**
* Processes all campaigns
*
*/
function processAll()
{
@set_time_limit(0);
$campaigns = $this->getCampaigns('unparsed=1');
foreach($campaigns as $campaign)
{
if($campaign->active)
$this->processCampaign($campaign);
}
}
/**
* Processes a campaign
*
* @param object $campaign Campaign database object
* @return integer Number of processed items
*/
function processCampaign(&$campaign)
{
global $wpdb;
// Log
$this->log('Processing campaign ' . $campaign->title . ' (ID: ' . $campaign->id . ')');
// Get campaign
$campaign = is_integer($campaign) ? $this->getCampaignById($campaign) : $campaign;
// Get feeds
$count = 0;
$feeds = $this->getCampaignFeeds($campaign->id);
foreach($feeds as $feed)
$count += $this->processFeed($campaign, $feed);
$wpdb->query(WPOTools::updateQuery($this->db['campaign'], array(
'count' => $campaign->count + $count,
'lastactive' => current_time('mysql')
), "id = {$campaign->id}"));
return $count;
}
/**
* Processes a feed
*
* @param $campaign object Campaign database object
* @param $feed object Feed database object
* @return The number of items added to database
*/
function processFeed(&$campaign, &$feed)
{
global $wpdb;
// Log
$this->log('Processing feed ' . $feed->title . ' (ID: ' . $feed->id . ')');
// Access the feed
$simplepie = $this->fetchFeed($feed->url);
// Get posts (last is first)
$items = array();
$count = 0;
foreach($simplepie->get_items() as $item)
{
if($feed->hash == $this->getItemHash($item))
{
if($count == 0) $this->log('No new posts');
break;
}
$count++;
array_unshift($items, $item);
}
// Processes post stack
foreach($items as $item)
{
$this->processItem($campaign, $feed, $item);
$lasthash = $this->getItemHash($item);
}
// If we have added items, let's update the hash
if($count)
{
$wpdb->query(WPOTools::updateQuery($this->db['campaign_feed'], array(
'count' => $count,
'lastactive' => current_time('mysql'),
'hash' => $lasthash
), "id = {$feed->id}"));
$this->log( $count . ' posts added' );
}
return $count;
}
/**
* Processes an item
*
* @param $item object SimplePie_Item object
*/
function getItemHash($item)
{
return sha1($item->get_title() . $item->get_permalink());
}
/**
* Processes an item
*
* @param $campaign object Campaign database object
* @param $feed object Feed database object
* @param $item object SimplePie_Item object
*/
function processItem(&$campaign, &$feed, &$item)
{
global $wpdb;
$this->log('Processing item');
// Item content
$content = $this->parseItemContent($campaign, $feed, $item);
// Item date
if($campaign->feeddate && ($item->get_date('U') > (time() - $campaign->frequency) && $item->get_date('U') < time()))
$date = $item->get_date('U') + (get_option('gmt_offset') * 3600);
else
$date = null;
// Categories
$categories = $this->getCampaignData($campaign->id, 'categories');
// Meta
$meta = array(
'wpo_campaignid' => $campaign->id,
'wpo_feedid' => $feed->id,
'wpo_sourcepermalink' => $item->get_permalink()
);
// Create post
$postid = $this->insertPost($wpdb->escape($item->get_title()), $wpdb->escape($content), $date, $categories, $campaign->posttype, $campaign->authorid, $campaign->allowpings, $campaign->alowcomments, $meta);
// If pingback/trackbacks
if($campaign->dopingbacks)
{
require_once(ABSPATH . WPINC . '/comment.php');
pingback($content, $postid);
}
// Save post to log database
$wpdb->query(WPOTools::insertQuery($this->db['campaign_post'], array(
'campaign_id' => $campaign->id,
'feed_id' => $feed->id,
'post_id' => $postid
)));
}
/**
* Writes a post to blog
*
*
* @param string $title Post title
* @param string $content Post content
* @param integer $timestamp Post timestamp
* @param array $category Array of categories
* @param string $status 'draft', 'published' or 'private'
* @param integer $authorid ID of author.
* @param boolean $allowpings Allow pings
* @param boolean $allowcomments Allow comments
* @param array $meta Meta key / values
* @return integer Created post id
*/
function insertPost($title, $content, $timestamp = null, $category = null, $status = 'draft', $authorid = null, $allowpings = true, $allowcomments = true, $meta = array())
{
$date = ($timestamp) ? gmdate('Y-m-d H:i:s', $timestamp) : null;
$postid = wp_insert_post(array(
'post_title' => $title,
'post_content' => $content,
'post_content_filtered' => $content,
'post_category' => $category,
'post_status' => $status,
'post_author' => $authorid,
'post_date' => $date,
'comment_status' => $allowcomments,
'ping_status' => $allowpings
));
foreach($meta as $key => $value)
$this->insertPostMeta($postid, $key, $value);
return $postid;
}
/**
* insertPostMeta
*
*
*/
function insertPostMeta($postid, $key, $value) {
global $wpdb;
$result = $wpdb->query( "INSERT INTO `$wpdb->postmeta` (post_id,meta_key,meta_value ) "
. " VALUES ('$postid','$key','$value') ");
return $wpdb->insert_id;
}
/**
* Parses an item content
*
* @param $campaign object Campaign database object
* @param $feed object Feed database object
* @param $item object SimplePie_Item object
*/
function parseItemContent(&$campaign, &$feed, &$item)
{
$content = $item->get_content();
// Caching
if(get_option('wpo_cacheimages') || $campaign->cacheimages)
{
$images = WPOTools::parseImages($content);
$urls = $images[2];
if(sizeof($urls))
{
$this->log('Caching images');
foreach($urls as $url)
{
$newurl = $this->cacheRemoteImage($url);
if($newurl)
$content = str_replace($url, $newurl, $content);
}
}
}
// Template parse
$vars = array(
'{content}',
'{title}',
'{permalink}',
'{feedurl}',
'{feedtitle}',
'{feedlogo}',
'{campaigntitle}',
'{campaignid}',
'{campaignslug}'
);
$replace = array(
$content,
$item->get_title(),
$item->get_link(),
$feed->url,
$feed->title,
$feed->logo,
$campaign->title,
$campaign->id,
$campaign->slug
);
$content = str_replace($vars, $replace, ($campaign->template) ? $campaign->template : '{content}');
// Rewrite
$rewrites = $this->getCampaignData($campaign->id, 'rewrites');
foreach($rewrites as $rewrite)
{
$origin = $rewrite['origin']['search'];
if(isset($rewrite['rewrite']))
{
$reword = isset($rewrite['relink'])
? '' . $rewrite['rewrite'] . ''
: $rewrite['rewrite'];
if($rewrite['origin']['regex'])
{
$content = preg_replace($origin, $reword, $content);
} else
$content = str_replace($origin, $reword, $content);
} else if(isset($rewrite['relink']))
$content = str_replace($origin, '' . $origin . '', $content);
}
return $content;
}
/**
* Cache remote image
*
* @return string New url
*/
function cacheRemoteImage($url)
{
$contents = @file_get_contents($url);
$filename = substr(md5(time()), 0, 5) . '_' . basename($url);
$cachepath = $this->cachepath;
if(is_writeable($cachepath) && $contents)
{
file_put_contents($cachepath . '/' . $filename, $contents);
return $this->pluginpath . '/' . get_option('wpo_cachepath') . '/' . $filename;
}
return false;
}
/**
* Parses a feed with SimplePie
*
* @param boolean $stupidly_fast Set fast mode. Best for checks
* @return SimplePie_Item Feed object
* @return string Error string if $check is enabled
*/
function fetchFeed($url, $stupidly_fast = false)
{
# SimplePie
if(! class_exists('SimplePie'))
require_once( WPOINC . 'simplepie/simplepie.class.php' );
$feed = new SimplePie();
$feed->set_feed_url($url);
$feed->set_stupidly_fast($stupidly_fast);
$feed->enable_cache(false);
$feed->init();
$feed->handle_content_type();
return $feed;
}
/**
* Returns all blog categories
*
*
*/
function getBlogCategories()
{
global $wpdb;
$categories = get_categories('hide_empty=0');
return $categories;
}
/**
* Returns all data for a campaign
*
*
*/
function getCampaignData($id, $section = null)
{
global $wpdb;
$campaign = (array) $this->getCampaignById($id);
if($campaign)
{
$campaign_data = $this->campaign_structure;
// Main
if(!$section || $section == 'main')
{
$campaign_data['main'] = array_merge($campaign_data['main'], (array) $campaign);
$userdata = get_userdata($campaign_data['main']['authorid']);
$campaign_data['main']['author'] = $userdata->user_login;
}
// Categories
if(!$section || $section == 'categories')
{
$categories = $wpdb->get_results("SELECT * FROM `{$this->db['campaign_category']}` WHERE campaign_id = $id");
foreach($categories as $category)
$campaign_data['categories'][] = $category->category_id;
}
// Feeds
if(!$section || $section == 'feeds')
{
$campaign_data['feeds']['edit'] = array();
$feeds = $this->getCampaignFeeds($id);
foreach($feeds as $feed)
$campaign_data['feeds']['edit'][$feed->id] = $feed->url;
}
// Rewrites
if(!$section || $section == 'rewrites')
{
$rewrites = $wpdb->get_results("SELECT * FROM `{$this->db['campaign_word']}` WHERE campaign_id = $id");
foreach($rewrites as $rewrite)
{
$word = array('origin' => array('search' => $rewrite->word, 'regex' => $rewrite->regex), 'rewrite' => $rewrite->rewrite_to, 'relink' => $rewrite->relink);
if(! $rewrite->rewrite) unset($word['rewrite']);
if(empty($rewrite->relink)) unset($word['relink']);
$campaign_data['rewrites'][] = $word;
}
}
if($section)
return $campaign_data[$section];
return $campaign_data;
}
return false;
}
/**
* Retrieves logs from database
*
*
*/
function getLogs($args = '')
{
global $wpdb;
extract(WPOTools::getQueryArgs($args, array('orderby' => 'created_on',
'ordertype' => 'DESC',
'limit' => null,
'page' => null,
'perpage' => null)));
if(!is_null($page))
{
if($page == 0) $page = 1;
$page--;
$start = $page * $perpage;
$end = $start + $perpage;
$limit = "LIMIT {$start}, {$end}";
}
return $wpdb->get_results("SELECT * FROM `{$this->db['log']}` ORDER BY $orderby $ordertype $limit");
}
/**
* Retrieves a campaign by its id
*
*
*/
function getCampaignById($id)
{
global $wpdb;
$id = intval($id);
return $wpdb->get_row("SELECT * FROM `{$this->db['campaign']}` WHERE id = $id");
}
/**
* Retrieves a feed by its id
*
*
*/
function getFeedById($id)
{
global $wpdb;
$id = intval($id);
return $wpdb->get_row("SELECT * FROM `{$this->db['campaign_feed']}` WHERE id = $id");
}
/**
* Retrieves campaigns from database
*
*
*/
function getCampaigns($args = '')
{
global $wpdb;
extract(WPOTools::getQueryArgs($args, array('fields' => '*',
'search' => '',
'orderby' => 'created_on',
'ordertype' => 'DESC',
'where' => '',
'unparsed' => false,
'limit' => null)));
if(! empty($search))
$where .= "AND title LIKE '%{$search}%' ";
if($unparsed)
$where .= "AND (frequency + lastactive) < NOW()";
$sql = "SELECT $fields FROM `{$this->db['campaign']}` WHERE 1 = 1 $where "
. "ORDER BY $orderby $ordertype $limit";
return $wpdb->get_results($sql);
}
/**
* Retrieves feeds for a certain campaign
*
* @param integer $id Campaign id
*/
function getCampaignFeeds($id)
{
global $wpdb;
return $wpdb->get_results("SELECT * FROM `{$this->db['campaign_feed']}` WHERE campaign_id = $id");
}
/**
* Retrieves all WP posts for a certain campaign
*
* @param integer $id Campaign id
*/
function getCampaignPosts($id)
{
global $wpdb;
return $wpdb->get_results("SELECT post_id FROM `{$this->db['campaign_post']}` WHERE campaign_id = $id ");
}
/**
* Adds a feed by url and campaign id
*
*
*/
function addCampaignFeed($id, $feed)
{
global $wpdb;
$simplepie = $this->fetchFeed($feed, true);
$url = $wpdb->escape($simplepie->subscribe_url());
// If it already exists, ignore it
if(! $wpdb->get_var("SELECT id FROM `{$this->db['campaign_feed']}` WHERE campaign_id = $id AND url = '$url' "))
{
$wpdb->query(WPOTools::insertQuery($this->db['campaign_feed'],
array('url' => $url,
'title' => $wpdb->escape($simplepie->get_title()),
'description' => $wpdb->escape($simplepie->get_description()),
'logo' => $wpdb->escape($simplepie->get_image_url()),
'campaign_id' => $id)
));
return $wpdb->insert_id;
}
return false;
}
/**
* Retrieves feeds from database
*
* @param mixed $args
*/
function getFeeds($args = '')
{
global $wpdb;
extract(WPOTools::getQueryArgs($args, array('fields' => '*',
'campid' => '',
'join' => false,
'orderby' => 'created_on',
'ordertype' => 'DESC',
'limit' => null)));
$sql = "SELECT $fields FROM `{$this->db['campaign_feed']}` cf ";
if(!empty($join))
$sql .= "INNER JOIN `{$this->db['campaign']}` camp ON camp.id = cf.campaign_id ";
if(!empty($campid))
$sql .= "WHERE cf.campaign_id = $campid";
return $wpdb->get_results($sql);
}
/**
* Inserts a post into Wordpress
*
* @param object $campaign Campaign object
* @param object $feed Feed object
* @param array $post Post array (title, content, date, etc)
*/
function createPost($campaign, $feed, $data)
{
$this->log('Post created');
}
/**
* Called when WP-o-Matic admin pages initialize.
*
*
*/
function adminInit()
{
auth_redirect();
$this->section = ($this->setup) ? ($_REQUEST['s'] ? $_REQUEST['s'] : $this->sections[0]) : 'setup';
wp_enqueue_script('prototype');
wp_enqueue_script('wpoadmin', $this->tplpath . '/admin.js', array('prototype'), $this->version);
if($this->section == 'list')
wp_enqueue_script('listman');
if(WPOTools::isAjax())
{
$this->admin();
exit;
}
}
/**
* Shows a warning fading box
*
* -idea from Akismet plugin
*/
function adminWarning()
{
if(! $this->setup && $this->section != 'setup')
{
echo "
".sprintf(__('Please click here to setup and configure WP-o-Matic.', 'wpomatic'), $this->adminurl . '&s=setup')."
";
}
}
/**
* Executes the current section method.
*
*
*/
function admin()
{
if(in_array($this->section, $this->sections))
{
$method = 'admin' . ucfirst($this->section);
$this->$method();
}
}
/**
* Adds the WP-o-Matic item to menu
*
*
*/
function adminMenu()
{
add_submenu_page('options-general.php', 'WP-o-Matic', 'WP-o-Matic', 10, basename(__FILE__), array(&$this, 'admin'));
}
/**
* Outputs the admin header in a template
*
*
*/
function adminHeader()
{
$current = array();
foreach($this->sections as $s)
$current[$s] = ($s == $this->section) ? 'class="current"' : '';
include(WPOTPL . 'header.php');
}
/**
* Outputs the admin footer in a template
*
*
*/
function adminFooter()
{
include(WPOTPL . 'footer.php');
}
/**
* Home section
*
*
*/
function adminHome()
{
$logging = get_option('wpo_log');
$logs = $this->getLogs('limit=7');
$nextcampaigns = $this->getCampaigns('fields=id,title,lastactive,frequency&limit=5&orderby=UNIX_TIMESTAMP(lastactive)%2Bfrequency&ordertype=ASC');
$lastcampaigns = $this->getCampaigns('fields=id,title,lastactive,frequency&limit=5&where=AND UNIX_TIMESTAMP(lastactive)>0&orderby=lastactive');
$campaigns = $this->getCampaigns('fields=id,title,count&limit=5&orderby=count');
include(WPOTPL . 'home.php');
}
/**
* Setup admin
*
*
*/
function adminSetup()
{
if(isset($_POST['dosetup']))
{
update_option('wpo_unixcron', isset($_REQUEST['option_unixcron']));
update_option('wpo_setup', 1);
$this->adminHome();
exit;
}
$php = WPOTools::getBinaryPath('php', '/usr/bin/php');
$nophp = !file_exists($php);
$safe_mode = ini_get('safe_mode');
$command = $this->cron_command;
$url = $this->cron_url;
include(WPOTPL . 'setup.php');
}
/**
* List campaigns section
*
*
*/
function adminList()
{
global $wpdb;
if(isset($_REQUEST['q']))
{
$q = $wpdb->escape($_REQUEST['q']);
$campaigns = $this->getCampaigns('search=' . $q);
} else
$campaigns = $this->getCampaigns('orderby=CREATED_ON');
include(WPOTPL . 'list.php');
}
/**
* Add campaign section
*
*
*/
function adminAdd()
{
$data = $this->campaign_structure;
if(isset($_REQUEST['campaign_add']))
{
check_admin_referer('wpomatic-edit-campaign');
if($this->errno)
$data = $this->campaign_data;
else
$addedid = $this->adminProcessAdd();
}
$categories = $this->getBlogCategories();
$campaign_add = true;
include(WPOTPL . 'edit.php');
}
/**
* Edit campaign section
*
*
*/
function adminEdit()
{
$id = intval($_REQUEST['id']);
if(!$id) die("Can't be called directly");
if(isset($_REQUEST['campaign_edit']))
{
check_admin_referer('wpomatic-edit-campaign');
$data = $this->campaign_data;
$submitted = true;
if(! $this->errno)
{
$this->adminProcessEdit($id);
$edited = true;
$data = $this->getCampaignData($id);
}
} else
$data = $this->getCampaignData($id);
$categories = $this->getBlogCategories();
$campaign_edit = true;
include(WPOTPL . 'edit.php');
}
/**
* Resets a campaign (sets post count to 0, forgets last parsed post)
*
*
* @todo Make it ajax-compatible here and add javascript code
*/
function adminReset()
{
global $wpdb;
$id = intval($_REQUEST['id']);
if(! defined('DOING_AJAX'))
check_admin_referer('reset-campaign_'.$id);
// Reset count and lasactive
$wpdb->query(WPOTools::updateQuery($this->db['campaign'], array(
'count' => 0,
'lastactive' => 0
), "id = $id"));
// Reset feeds hashes, count, and lasactive
foreach($this->getCampaignFeeds($id) as $feed)
{
$wpdb->query(WPOTools::updateQuery($this->db['campaign_feed'], array(
'count' => 0,
'lastactive' => 0,
'hash' => ''
), "id = {$feed->id}"));
}
if(defined('DOING_AJAX'))
die('1');
else
header('Location: ' . $this->adminurl . '&s=list');
}
/**
* Deletes a campaign
*
*
*/
function adminDelete()
{
global $wpdb;
$id = intval($_REQUEST['id']);
// If not called through admin-ajax.php
if(! defined('DOING_AJAX'))
check_admin_referer('delete-campaign_'.$id);
$wpdb->query("DELETE FROM `{$this->db['campaign']}` WHERE id = $id");
$wpdb->query("DELETE FROM `{$this->db['campaign_feed']}` WHERE campaign_id = $id");
$wpdb->query("DELETE FROM `{$this->db['campaign_word']}` WHERE campaign_id = $id");
$wpdb->query("DELETE FROM `{$this->db['campaign_category']}` WHERE campaign_id = $id");
if(defined('DOING_AJAX'))
die('1');
else
header('Location: ' . $this->adminurl . '&s=list');
}
/**
* Options section
*
*
*/
function adminOptions()
{
if(isset($_REQUEST['update']))
{
update_option('wpo_unixcron', isset($_REQUEST['option_unixcron']));
update_option('wpo_log', isset($_REQUEST['option_logging']));
update_option('wpo_cacheimages', isset($_REQUEST['option_caching']));
update_option('wpo_cachepath', rtrim($_REQUEST['option_cachepath'], '/'));
$updated = 1;
}
if(!is_writable(WPODIR . get_option('wpo_cachepath')))
$not_writable = true;
include(WPOTPL . 'options.php');
}
/**
* Import section
*
*
*/
function adminImport()
{
global $wpdb;
@session_start();
if(!$_POST) unset($_SESSION['opmlimport']);
if(isset($_FILES['importfile']) || $_POST)
check_admin_referer('import-campaign');
if(!isset($_SESSION['opmlimport']))
{
if(isset($_FILES['importfile']))
{
if(is_uploaded_file($_FILES['importfile']['tmp_name']))
$file = $_FILES['importfile']['tmp_name'];
else
$file = false;
} else if(isset($_REQUEST['importurl']))
{
$fromurl = true;
$file = $_REQUEST['importurl'];
}
}
if(isset($file) || ($_POST && isset($_SESSION['opmlimport'])) )
{
require_once( WPOINC . 'xmlparser.class.php' );
$contents = (isset($file) ? @file_get_contents($file) : $_SESSION['opmlimport']);
$_SESSION['opmlimport'] = $contents;
# Get OPML data
$opml = new XMLParser($contents);
$opml = $opml->getTree();
# Check that it is indeed opml
if(is_array($opml) && isset($opml['OPML']))
{
$opml = $opml['OPML'][0];
$title = isset($opml['HEAD'][0]['TITLE'][0]['VALUE'])
? $opml['HEAD'][0]['TITLE'][0]['VALUE']
: null;
$opml = $opml['BODY'][0];
$success = 1;
# Campaigns dropdown
$campaigns = array();
foreach($this->getCampaigns() as $campaign)
$campaigns[$campaign->id] = $campaign->title;
}
else
$import_error = 1;
}
$this->adminImportProcess();
include(WPOTPL . 'import.php');
}
/**
* Import process
*
*
*/
function adminImportProcess()
{
global $wpdb;
if(isset($_REQUEST['add']))
{
if(!isset($_REQUEST['feed']))
$add_error = __('You must select at least one feed', 'wpomatic');
else
{
switch($_REQUEST['import_mode'])
{
// Several campaigns
case '1':
$created_campaigns = array();
foreach($_REQUEST['feed'] as $campaignid => $feeds)
{
if(!in_array($campaignid, $created_campaigns))
{
// Create campaign
$title = $wpdb->escape($_REQUEST['campaign'][$campaignid]);
if(!$title) continue;
$slug = $wpdb->escape(WPOTools::stripText($title));
$wpdb->query("INSERT INTO `{$this->db['campaign']}` (title, active, slug, lastactive, count) VALUES ('$title', 0, '$slug', 0, 0) ");
$created_campaigns[] = $wpdb->insert_id;
// Add feeds
foreach($feeds as $feedurl => $yes){
$this->addCampaignFeed($campaignid, urldecode($feedurl));
}
}
}
$this->add_success = __('Campaigns added successfully. Feel free to edit them', 'wpomatic');
break;
// All feeds into an existing campaign
case '2':
$campaignid = $_REQUEST['import_custom_campaign'];
foreach($_REQUEST['feed'] as $cid => $feeds)
{
// Add feeds
foreach($feeds as $feedurl => $yes)
$this->addCampaignFeed($campaignid, urldecode($feedurl));
}
$this->add_success = sprintf(__('Feeds added successfully. Edit campaign', 'wpomatic'), $this->adminurl . '&s=edit&id=' . $campaignid);
break;
// All feeds into new campaign
case '3':
$title = $wpdb->escape($_REQUEST['import_new_campaign']);
$slug = $wpdb->escape(WPOTools::stripText($title));
$wpdb->query("INSERT INTO `{$this->db['campaign']}` (title, active, slug, lastactive, count) VALUES ('$title', 0, '$slug', 0, 0) ");
$campaignid = $wpdb->insert_id;
// Add feeds
foreach($_REQUEST['feed'] as $cid => $feeds)
{
// Add feeds
foreach($feeds as $feedurl => $yes)
$this->addCampaignFeed($campaignid, urldecode($feedurl));
}
$this->add_success = sprintf(__('Feeds added successfully. Edit campaign', 'wpomatic'), $this->adminurl . '&s=edit&id=' . $campaignid);
break;
}
}
}
}
/**
* Export
*
*
*/
function adminExport()
{
if(isset($this->export_error))
$error = $this->export_error;
$campaigns = $this->getCampaigns();
include(WPOTPL . 'export.php');
}
/**
* Export process
*
*
*/
function adminExportProcess()
{
if($_POST)
{
if(!isset($_REQUEST['export_campaign']))
{
$this->export_error = __('Please select at least one campaign', 'wpomatic');
} else
{
$campaigns = array();
foreach($_REQUEST['export_campaign'] as $cid)
{
$campaign = $this->getCampaignById($cid);
$campaign->feeds = (array) $this->getCampaignFeeds($cid);
$campaigns[] = $campaign;
}
header("Content-type: text/x-opml");
header('Content-Disposition: attachment; filename="wpomatic.opml"');
include(WPOTPL . 'export.opml.php');
exit;
}
}
}
/**
* Tests a feed
*
*
*/
function adminTestfeed()
{
if(!isset($_REQUEST['url'])) return false;
$url = $_REQUEST['url'];
$feed = $this->fetchFeed($url, true);
$works = ! $feed->error(); // if no error returned
if(defined('DOING_AJAX')){
echo intval($works);
die();
} else
include(WPOTPL . 'testfeed.php');
}
/**
* Forcedfully processes a campaign
*
*
*/
function adminForcefetch()
{
$cid = intval($_REQUEST['id']);
if(! defined('DOING_AJAX'))
check_admin_referer('forcefetch-campaign_'.$cid);
$this->forcefetched = $this->processCampaign($cid);
if(defined('DOING_AJAX'))
die('1');
else
$this->adminList();
}
/**
* Checks submitted campaign edit form for errors
*
*
* @return array errors
*/
function adminCampaignRequest()
{
global $wpdb;
# Main data
$this->campaign_data = $this->campaign_structure;
$this->campaign_data['main'] = array(
'title' => $_REQUEST['campaign_title'],
'active' => isset($_REQUEST['campaign_active']),
'slug' => $_REQUEST['campaign_slug'],
'template' => (isset($_REQUEST['campaign_templatechk']))
? $_REQUEST['campaign_template'] : null,
'frequency' => intval($_REQUEST['campaign_frequency_d']) * 86400
+ intval($_REQUEST['campaign_frequency_h']) * 3600
+ intval($_REQUEST['campaign_frequency_m']) * 60,
'cacheimages' => isset($_REQUEST['campaign_cacheimages']),
'feeddate' => isset($_REQUEST['campaign_feeddate']),
'posttype' => $_REQUEST['campaign_posttype'],
'author' => sanitize_user($_REQUEST['campaign_author']),
'allowcomments' => isset($_REQUEST['campaign_allowcomments']),
'allowpings' => isset($_REQUEST['campaign_allowpings']),
'dopingbacks' => isset($_REQUEST['campaign_dopingbacks'])
);
// New feeds
foreach($_REQUEST['campaign_feed']['new'] as $i => $feed)
{
$feed = trim($feed);
if(!empty($feed))
{
if(!isset($this->campaign_data['feeds']['new']))
$this->campaign_data['feeds']['new'] = array();
$this->campaign_data['feeds']['new'][$i] = $feed;
}
}
// Existing feeds to delete
if(isset($_REQUEST['campaign_feed']['delete']))
{
$this->campaign_data['feeds']['delete'] = array();
foreach($_REQUEST['campaign_feed']['delete'] as $feedid => $yes)
$this->campaign_data['feeds']['delete'][] = intval($feedid);
}
// Existing feeds.
if(isset($_REQUEST['id']))
{
$this->campaign_data['feeds']['edit'] = array();
foreach($this->getCampaignFeeds(intval($_REQUEST['id'])) as $feed)
$this->campaign_data['feeds']['edit'][$feed->id] = $feed->url;
}
// Categories
if(isset($_REQUEST['campaign_categories']))
{
foreach($_REQUEST['campaign_categories'] as $category)
{
$id = intval($category);
$this->campaign_data['categories'][] = $category;
}
}
# New categories
if(isset($_REQUEST['campaign_newcat']))
{
foreach($_REQUEST['campaign_newcat'] as $k => $on)
{
$catname = $_REQUEST['campaign_newcatname'][$k];
if(!empty($catname))
{
if(!isset($this->campaign_data['categories']['new']))
$this->campaign_data['categories']['new'] = array();
$this->campaign_data['categories']['new'][] = $catname;
}
}
}
// Rewrites
if(isset($_REQUEST['campaign_word_origin']))
{
foreach($_REQUEST['campaign_word_origin'] as $id => $origin_data)
{
$rewrite = isset($_REQUEST['campaign_word_option_rewrite'])
&& isset($_REQUEST['campaign_word_option_rewrite'][$id]);
$relink = isset($_REQUEST['campaign_word_option_relink'])
&& isset($_REQUEST['campaign_word_option_relink'][$id]);
if($rewrite || $relink)
{
$rewrite_data = trim($_REQUEST['campaign_word_rewrite'][$id]);
$relink_data = trim($_REQUEST['campaign_word_relink'][$id]);
// Relink data field can't be empty
if(($relink && !empty($relink_data)) || !$relink)
{
$regex = isset($_REQUEST['campaign_word_option_regex'])
&& isset($_REQUEST['campaign_word_option_regex'][$id]);
$data = array();
$data['origin'] = array('search' => $origin_data, 'regex' => $regex);
if($rewrite)
$data['rewrite'] = $rewrite_data;
if($relink)
$data['relink'] = $relink_data;
$this->campaign_data['rewrites'][] = $data;
}
}
}
}
$errors = array('basic' => array(), 'feeds' => array(), 'categories' => array(),
'rewrite' => array(), 'options' => array());
# Main
if(empty($this->campaign_data['main']['title']))
{
$errors['basic'][] = __('You need to enter a campaign title', 'wpomatic');
$this->errno++;
}
# Feeds
$feedscount = 0;
if(isset($this->campaign_data['feeds']['new'])) $feedscount += count($this->campaign_data['feeds']['new']);
if(isset($this->campaign_data['feeds']['edit'])) $feedscount += count($this->campaign_data['feeds']['edit']);
if(isset($this->campaign_data['feeds']['delete'])) $feedscount -= count($this->campaign_data['feeds']['new']);
if(!$feedscount)
{
$errors['feeds'][] = __('You have to enter at least one feed', 'wpomatic');
} else {
if(isset($this->campaign_data['feeds']['new']))
{
foreach($this->campaign_data['feeds']['new'] as $feed)
{
$simplepie = $this->fetchFeed($feed, true);
if($simplepie->error())
{
$errors['feeds'][] = sprintf(__('Feed %s could not be parsed (SimplePie said: %s)', 'wpomatic'), $feed, $xmlerror);
$this->errno++;
}
}
}
}
# Categories
if(! sizeof($this->campaign_data['categories']))
{
$errors['categories'][] = __('Select at least one category', 'wpomatic');
$this->errno++;
}
# Rewrite
if(sizeof($this->campaign_data['rewrites']))
{
foreach($this->campaign_data['rewrites'] as $rewrite)
{
if($rewrite['origin']['regex'])
{
if(false === @preg_match($rewrite['origin']['search'], ''))
{
$errors['rewrites'][] = __('There\'s an error with the supplied RegEx expression', 'wpomatic');
$this->errno++;
}
}
}
}
# Options
if(! get_userdatabylogin($this->campaign_data['main']['author']))
{
$errors['options'][] = __('Author username not found', 'wpomatic');
$this->errno++;
}
if(! $this->campaign_data['main']['frequency'])
{
$errors['options'][] = __('Selected frequency is not valid', 'wpomatic');
$this->errno++;
}
if($this->campaign_data['main']['cacheimages'] && !is_writable($this->cachepath))
{
$errors['options'][] = sprintf(__('Cache path (in Options) must be writable before enabling image caching.', 'wpomatic'), $this->adminurl . '&s=options' );
$this->errno++;
}
$this->errors = $errors;
}
/**
* Creates a campaign, and runs processEdit. If processEdit fails, campaign is removed
*
* @return campaign id if created successfully, errors if not
*/
function adminProcessAdd()
{
global $wpdb;
// Insert a campaign with dumb data
$wpdb->query(WPOTools::insertQuery($this->db['campaign'], array('count' => 0)));
$cid = $wpdb->insert_id;
// Process the edit
$this->adminProcessEdit($cid);
return $cid;
}
/**
* Cleans everything for the given id, then redoes everything
*
* @param integer $id The id to edit
*/
function adminProcessEdit($id)
{
global $wpdb;
// If we need to execute a tool action we stop here
if($this->adminProcessTools()) return;
// Delete all do recreate
//$wpdb->query("DELETE FROM `{$this->db['campaign_feed']}` WHERE campaign_id = $id");
$wpdb->query("DELETE FROM `{$this->db['campaign_word']}` WHERE campaign_id = $id");
$wpdb->query("DELETE FROM `{$this->db['campaign_category']}` WHERE campaign_id = $id");
// Process categories
# New
if(isset($this->campaign_data['categories']['new']))
{
foreach($this->campaign_data['categories']['new'] as $category)
$this->campaign_data['categories'][] = wp_insert_category(array('cat_name' => $category));
unset($this->campaign_data['categories']['new']);
}
# All
foreach($this->campaign_data['categories'] as $category)
{
// Insert
$wpdb->query(WPOTools::insertQuery($this->db['campaign_category'],
array('category_id' => $category,
'campaign_id' => $id)
));
}
// Process feeds
# New
if(isset($this->campaign_data['feeds']['new']))
{
foreach($this->campaign_data['feeds']['new'] as $feed)
$this->addCampaignFeed($id, $feed);
}
# Delete
if(isset($this->campaign_data['feeds']['delete']))
{
foreach($this->campaign_data['feeds']['delete'] as $feed)
$wpdb->query("DELETE FROM `{$this->db['campaign_feed']}` WHERE id = $feed ");
}
// Process words
foreach($this->campaign_data['rewrites'] as $rewrite)
{
$wpdb->query(WPOTools::insertQuery($this->db['campaign_word'],
array('word' => $wpdb->escape($rewrite['origin']['search']),
'regex' => $rewrite['origin']['regex'],
'rewrite' => isset($rewrite['rewrite']),
'rewrite_to' => $wpdb->escape($rewrite['rewrite']),
'relink' => isset($rewrite['relink']) ? $wpdb->escape($rewrite['relink']) : null,
'campaign_id' => $id)
));
}
// Main
$main = array();
foreach($this->campaign_data['main'] as $k => $v)
$main[$k] = $wpdb->escape($v);
// Fetch author id
$author = get_userdatabylogin($this->campaign_data['main']['author']);
$main['authorid'] = $author->ID;
unset($main['author']);
$query = WPOTools::updateQuery($this->db['campaign'], $main, 'id = ' . intval($id));
$wpdb->query($query);
}
/**
* Processes edit campaign tools actions
*
*
*/
function adminProcessTools()
{
global $wpdb;
$id = intval($_REQUEST['id']);
if(isset($_REQUEST['tool_removeall']))
{
$posts = $this->getCampaignPosts($id);
foreach($posts as $post)
{
$wpdb->query("DELETE FROM `{$wpdb->posts}` WHERE ID = {$post->post_id} ");
}
// Delete log
$wpdb->query("DELETE FROM `{$this->db['campaign_post']}` WHERE campaign_id = {$id} ");
// Update feed and campaign posts count
$wpdb->query(WPOTools::updateQuery($this->db['campaign'], array('count' => 0), "id = {$id}"));
$wpdb->query(WPOTools::updateQuery($this->db['campaign_feed'], array('hash' => 0, 'count' => 0), "campaign_id = {$id}"));
$this->tool_success = __('All posts removed', 'wpomatic');
return true;
}
if(isset($_REQUEST['tool_changetype']))
{
$this->adminUpdateCampaignPosts($id, array(
'post_status' => $wpdb->escape($_REQUEST['campaign_tool_changetype'])
));
$this->tool_success = __('Posts status updated', 'wpomatic');
return true;
}
if(isset($_REQUEST['tool_changeauthor']))
{
$author = get_userdatabylogin($_REQUEST['campaign_tool_changeauthor']);
if($author)
{
$authorid = $author->ID;
$this->adminUpdateCampaignPosts($id, array('post_author' => $authorid));
} else {
$this->errno = 1;
$this->errors = array('tools' => array(sprintf(__('Author %s not found', 'wpomatic'), attribute_escape($_REQUEST['campaign_tool_changeauthor']))));
}
$this->tool_success = __('Posts status updated', 'wpomatic');
return true;
}
return false;
}
function adminUpdateCampaignPosts($id, $properties)
{
$posts = $this->getCampaignPosts($id);
foreach($posts as $post)
$wpdb->query(WPOTools::updateQuery($wpdb->posts, $properties, "ID = {$post->id}"));
}
/**
* Show logs
*
*
*/
function adminLogs()
{
global $wpdb;
// Clean logs?
if(isset($_REQUEST['clean_logs']))
{
check_admin_referer('clean-logs');
$wpdb->query("DELETE FROM `{$this->db['log']}` WHERE 1=1 ");
}
// Logs to show per page
$logs_per_page = 20;
$page = isset($_REQUEST['p']) ? intval($_REQUEST['p']) : 0;
$total = $wpdb->get_var("SELECT COUNT(*) as cnt FROM `{$this->db['log']}` ");
$logs = $this->getLogs("page={$page}&perpage={$logs_per_page}");
$paging = paginate_links(array(
'base' => $this->adminurl . '&s=logs&%_%',
'format' => 'p=%#%',
'total' => ceil($total / $logs_per_page),
'current' => $page,
'end_size' => 3
));
include(WPOTPL . 'logs.php');
}
}
$wpomatic = & new WPOMatic();