a bunch of changes

This commit is contained in:
John Bintz 2009-02-06 19:10:58 -05:00
parent 91df87a151
commit f3068cd88e
8 changed files with 598 additions and 42 deletions

114
classes/PWAdboxesClient.php Normal file
View File

@ -0,0 +1,114 @@
<?php
require_once('PublisherInfo.php');
/**
* The interface to the PW database table.
*/
class PWAdboxesClient {
var $table_name;
function PWAdboxesClient() {
global $wpdb;
$this->table_name = $wpdb->prefix . "pw_adboxes";
$this->table_exists = false;
}
/**
* Initialize the table if it doesn't exist.
*/
function initialize() {
global $wpdb;
if ($wpdb->get_var("SHOW TABLES LIKE {$this->table_name}") != $this->table_name) {
if (!$wpdb->is_mock) {
$sql = "CREATE TABLE {$this->table_name} (
type int(1) NOT NULL,
adboxid int(11) NOT NULL,
sitename char(100) NOT NULL,
url char(255) NOT NULL,
dimensions char(10) NOT NULL,
rating char(10) NOT NULL,
category char(30) NOT NULL,
description text NOT NULL,
tags text NOT NULL,
standardcode text NOT NULL,
advancedcode text NOT NULL
);";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
}
}
/**
* Destroy the table.
*/
function destroy() {
global $wpdb;
$wpdb->query("DROP TABLE {$this->table_name}");
}
/**
* Post PublisherInfo to the database.
* @param PublisherInfo $ads The PublisherInfo to post to the database.
* @param integer $type The ad type.
*/
function post_ads($ads, $type = PW_ADBOXES_PROJECT_WONDERFUL) {
global $wpdb;
if (is_a($ads, 'PublisherInfo')) {
if ($ads->is_valid) {
$wpdb->query("DELETE FROM {$this->table_name} WHERE type = $type");
foreach ($ads->adboxes as $box) {
$columns = array("type");
$values = array($type);
foreach ((array)$box as $key => $value) {
if ($key !== "type") {
$columns[] = $key;
$values[] = '"' . $wpdb->escape($value) . '"';
}
}
$wpdb->query("INSERT INTO {$this->table_name} (" . implode(",", $columns) . ") VALUES (" . implode(",", $values) . ")");
}
}
}
}
/**
* Retrieve all ads from the database and create a new PublisherInfo object.
* @param integer $member_id The Project Wonderful member ID to use.
* @return PublisherInfo The PublisherInfo object for the ads, or false if no ads are found.
*/
function get_ads($member_id, $type = null) {
global $wpdb;
$query = "SELECT * FROM {$this->table_name}";
if (!is_null($type)) { $query .= " WHERE type = {$type}"; }
if (count($results = $wpdb->get_results($query)) > 0) {
$ads = new PublisherInfo();
$ads->memberid = $member_id;
$ads->adboxes = $results;
$ads->is_valid = true;
return $ads;
}
return false;
}
/**
* Remove all ads from the database.
*/
function clean_ads() {
global $wpdb;
$wpdb->query("DELETE FROM {$this->table_name}");
}
}
?>

View File

@ -1,7 +1,12 @@
<?php
define("PW_ADBOXES_PROJECT_WONDERFUL", 0);
/**
* Information about an ad publisher.
*/
class PublisherInfo {
var $parser, $current_adbox, $is_valid, $memberid, $adboxes, $current_string;
var $parser, $current_type, $current_adbox, $is_valid, $memberid, $adboxes, $current_string;
function PublisherInfo() {
foreach (array('memberid', 'adboxes') as $param) {
@ -9,12 +14,14 @@ class PublisherInfo {
}
}
function parse($string) {
function parse($string, $type = PW_ADBOXES_PROJECT_WONDERFUL) {
$this->parser = xml_parser_create();
xml_set_object($this->parser, $this);
xml_set_element_handler($this->parser, 'start_element_handler', 'end_element_handler');
xml_set_character_data_handler($this->parser, 'character_data_handler');
$this->current_type = $type;
$this->is_valid = true;
if (($result = xml_parse($this->parser, $string, true)) != 1) { $this->is_valid = false; }
xml_parser_free($this->parser);
@ -64,6 +71,7 @@ class PublisherInfo {
}
if ($this->is_valid) {
$new_attributes['type'] = $this->current_type;
$this->current_adbox = (object)$new_attributes;
}
}
@ -94,6 +102,27 @@ class PublisherInfo {
function character_data_handler($parser, $data) {
$this->current_string .= $data;
}
/**
* Get information to create widgets.
* @return array The widget information.
*/
function get_sidebar_widget_info() {
if ($this->is_valid) {
$widgets = array();
foreach ($this->adboxes as $adbox) {
$widgets[] = array(
"id" => "project_wonderful_{$this->memberid}_{$adbox->adboxid}",
"name" => sprintf(__('PW %1$s %2$s (%3$s)', 'comicpress-manager'), $adbox->dimensions, $adbox->sitename, $adbox->adboxid),
"options" => array("adboxid" => $adbox->adboxid)
);
}
return $widgets;
} else {
return false;
}
}
}
?>

162
plugin-wonderful.php Normal file
View File

@ -0,0 +1,162 @@
<?php
/*
Plugin Name: Plugin Wonderful
Plugin URI: http://www.coswellproductions.com
Description: Easily embed a Project Wonderful publisher's advertisements.
Version: 0.1
Author: John Bintz
Author URI: http://www.coswellproductions.org/wordpress/
Copyright 2009 John Bintz (email : jcoswell@coswellproductions.org)
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 2 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, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
require_once('classes/PWAdboxesClient.php');
define('PLUGIN_WONDERFUL_XML_URL', 'http://www.projectwonderful.com/xmlpublisherdata.php?publisher=%d');
class PluginWonderful {
var $messages, $adboxes_client, $publisher_info, $member_id;
function PluginWonderful() {
$this->messages = array();
$this->adboxes_client = new PWAdboxesClient();
$this->publisher_info = false;
if ($member_id = get_option('plugin-wonderful-memberid')) {
$this->publisher_info = $this->adboxes_client->get_ads($member_id);
}
if (!empty($_POST)) { $this->handle_action(); }
}
function render_widget($options, $adboxid) {
if ($this->publisher_info !== false) {
foreach ($this->publisher_info->adboxes as $adbox) {
if ($adbox->adboxid == $adboxid) {
if (get_option("plugin-wonderful-use-standardcode") == 1) {
echo $adbox->standardcode;
} else {
echo $adbox->advancedcode;
}
break;
}
}
}
}
function set_up_menu() {
add_options_page('Plugin Wonderful', __("Plugin Wonderful", 'plugin-wonderful'), 5, __FILE__, array($this, "plugin_wonderful_main"));
}
function set_up_widgets() {
if ($this->publisher_info !== false) {
foreach ($this->publisher_info->get_sidebar_widget_info() as $widget_info) {
extract($widget_info);
wp_register_sidebar_widget($id, $name, array($this, 'render_widget'), "", $options['adboxid']);
}
}
}
function handle_activation() {
$this->adboxes_client->initialize();
}
function plugin_wonderful_main() {
$this->get_view(__FUNCTION__);
}
function show_messages() {
if (count($this->messages) > 0) {
echo '<div id="message" class="updated fade below-h2">';
foreach ($this->messages as $message) { echo '<p>' . $message . '</p>'; }
echo '</div>';
}
}
function _create_target($name, $source) {
return ABSPATH . PLUGINDIR . '/' . dirname(plugin_basename(__FILE__)) . "/{$source}/{$name}.php";
}
function get_view($function_name) {
$target = $this->_create_target(str_replace('plugin_wonderful_', '', $function_name), "views");
if (file_exists($target)) {
echo '<div class="wrap">';
echo '<div id="icon-edit" class="icon32"><br /></div>';
echo '<h2>' . __("Plugin Wonderful", 'plugin-wonderful') . '</h2>';
$this->show_messages();
include($target);
echo '<div style="margin-top: 20px; border-top: solid #E3E3E3 1px">';
echo 'Plugin Wonderful Version 0.1 by <a href="mailto:john@coswellproductions.com">John Bintz</a> | ';
echo '<a href="http://www.projectwonderful.com/login.php">Manage your Project Wonderful publisher account</a>';
echo '</div>';
echo '</div>';
} else {
die("View not found: " . str_replace('plugin-wonderful_', '', $function_name));
}
}
function handle_action() {
$action = "handle_action_" . str_replace("-", "_", preg_replace('#[^a-z\-]#', '', strtolower($_POST['action'])));
if (method_exists($this, $action)) { call_user_func(array($this, $action)); }
}
function handle_action_change_memberid() {
if (trim($_POST['memberid'])) {
if (trim($_POST['memberid']) === (string)(int)$_POST['memberid']) {
if (($result = file_get_contents(sprintf(PLUGIN_WONDERFUL_XML_URL, (int)$_POST['memberid']))) !== false) {
update_option('plugin-wonderful-memberid', (int)$_POST['memberid']);
$this->publisher_info = new PublisherInfo();
$this->publisher_info->parse($result);
$this->adboxes_client->post_ads($publisher_info);
$this->messages[] = sprintf(__('Member ID changed to %s and adbox information redownloaded.', 'plugin-wonderful'), (int)$_POST['memberid']);
} else {
$this->messages[] = __("Unable to read publisher data from Project Wonderful.", 'plugin-wonderful');
}
} else {
$this->messages[] = __("Member IDs need to be numeric.", 'plugin-wonderful');
}
} else {
$this->messages[] = __("Existing adbox information removed.", 'plugin-wonderful');
update_option('plugin-wonderful-memberid', "");
$this->publisher_info = false;
}
update_option('plugin-wonderful-use-standardcode', isset($_POST['use-standardcode']) ? "1" : "0");
}
}
$plugin_wonderful = new PluginWonderful();
add_action('admin_menu', array($plugin_wonderful, 'set_up_menu'));
add_action('init', array($plugin_wonderful, 'set_up_widgets'));
register_activation_hook(__FILE__, array($plugin_wonderful, 'handle_activation'));
function the_project_wonderful_ad($adboxid) {
global $plugin_wonderful;
$plugin_wonderful->render_widget(array(), $adboxid);
}
?>

View File

@ -1,28 +0,0 @@
<?php
/*
Plugin Name: Plugin Wonderful
Plugin URI: http://www.coswellproductions.com
Description: Easily embed a Project Wonderful advertiser's PW ads
Version: 0.1
Author: John Bintz
Author URI: http://www.coswellproductions.org/wordpress/
Copyright 2009 John Bintz (email : jcoswell@coswellproductions.org)
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 2 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, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
?>

View File

@ -0,0 +1,148 @@
<?php
require_once('../classes/PWAdboxesClient.php');
class TestPWAdboxesClient extends PHPUnit_Framework_TestCase {
private $database_client;
private $sample_ad;
function setUp() {
global $wpdb;
$this->database_client = new PWAdboxesClient();
$this->sample_ad = (object)array('adboxid' => 1, 'sitename' => "a", 'url' => "http://meow.raow/",
'dimensions' => "1x1", 'rating' => "a", 'category' => "a",
'description' => "a", 'tags' => 'a', 'standardcode' => 'a',
'advancedcode' => 'a');
}
function testCreateTables() {
global $wpdb;
$wpdb = $this->getMock('wpdb', array('get_var'));
$wpdb->prefix = "wp_";
$wpdb->is_mock = true;
$wpdb->expects($this->once())->method('get_var')->with($this->equalTo("SHOW TABLES LIKE {$this->database_client->table_name}"));
$this->database_client->initialize();
}
function testDestroyTables() {
global $wpdb;
$wpdb = $this->getMock('wpdb', array('query'));
$wpdb->prefix = "wp_";
$wpdb->is_mock = true;
$wpdb->expects($this->once())->method('query')->with($this->equalTo("DROP TABLE {$this->database_client->table_name}"));
$this->database_client->destroy();
}
function testPostAds() {
global $wpdb;
$wpdb = $this->getMock('wpdb', array('escape', 'query'));
$wpdb->prefix = "wp_";
$ads = $this->getMock('PublisherInfo', array());
$ads->member_id = "1";
$ads->is_valid = true;
$ads->adboxes = array($this->sample_ad);
$wpdb->expects($this->exactly(10))->method('escape');
$wpdb->expects($this->exactly(2))->method('query')->will($this->returnCallback(array($this, 'postAdsCallback')));
$this->database_client->post_ads($ads, PW_ADBOXES_PROJECT_WONDERFUL);
}
function testRetrieveAds() {
global $wpdb;
$wpdb = $this->getMock('wpdb', array('get_results'));
$wpdb->prefix = "wp_";
$wpdb->expects($this->once())
->method('get_results')
->with($this->equalTo("SELECT * FROM {$this->database_client->table_name}"))
->will($this->returnValue(array($this->sample_ad)));
$result = $this->database_client->get_ads("1");
$this->assertType("PublisherInfo", $result);
}
function testCleanAds() {
global $wpdb;
$wpdb = $this->getMock('wpdb', array('query'));
$wpdb->prefix = "wp_";
$wpdb->expects($this->once())
->method('query')
->with($this->equalTo("DELETE FROM {$this->database_client->table_name}"));
$this->database_client->clean_ads();
}
function testRetrieveAdsForSpecificType() {
global $wpdb;
$wpdb = $this->getMock('wpdb', array('get_results'));
$wpdb->prefix = "wp_";
$type = 10;
$wpdb->expects($this->once())
->method('get_results')
->with($this->equalTo("SELECT * FROM {$this->database_client->table_name} WHERE type = {$type}"))
->will($this->returnValue(array()));
$result = $this->database_client->get_ads("1", $type);
$this->assertFalse($result);
}
function testRetrieveNoAds() {
global $wpdb;
$wpdb = $this->getMock('wpdb', array('get_results'));
$wpdb->prefix = "wp_";
$wpdb->expects($this->once())
->method('get_results')
->with($this->equalTo("SELECT * FROM {$this->database_client->table_name}"))
->will($this->returnValue(array()));
$result = $this->database_client->get_ads("1");
$this->assertFalse($result);
}
function testFilterTypeFromAd() {
global $wpdb;
$wpdb = $this->getMock('wpdb', array('escape', 'query'));
$wpdb->prefix = "wp_";
$ads = $this->getMock('PublisherInfo', array());
$ads->member_id = "1";
$ads->is_valid = true;
$this->sample_ad->type = "3";
$ads->adboxes = array($this->sample_ad);
$wpdb->expects($this->exactly(2))->method('query')->will($this->returnCallback(array($this, 'postAdsFilterCallback')));
$this->database_client->post_ads($ads, PW_ADBOXES_PROJECT_WONDERFUL);
}
function postAdsCallback($query) {
if (strpos($query, "DELETE") === 0) {
return $query == ("DELETE FROM {$this->database_client->table_name} WHERE type = " . PW_ADBOXES_PROJECT_WONDERFUL);
} else {
return true;
}
}
function postAdsFilterCallback($query) {
if (strpos($query, "INSERT") === 0) {
return count(explode("type", $query)) === 3;
} else {
return true;
}
}
}
?>

View File

@ -0,0 +1,15 @@
<?php
require_once('TestPWAdboxesClient.php');
require_once('TestPublisherInfo.php');
class TestPluginWonderful {
public static function suite() {
$suite = new PHPUnit_Framework_TestSuite();
$suite->addTestSuite(new ReflectionClass("TestPWAdboxesClient"));
$suite->addTestSuite(new ReflectionClass("TestPublisherInfo"));
return $suite;
}
}
?>

View File

@ -3,10 +3,23 @@
require_once('../classes/PublisherInfo.php');
class TestPublisherInfo extends PHPUnit_Framework_TestCase {
private $parser;
private $parser, $default_data;
public function setup() {
$this->parser = new PublisherInfo();
$this->default_data = array(
array("3", 'adboxid'),
array("a", 'sitename'),
array("http://meow.raow/", 'url'),
array("1x1", 'dimensions'),
array("a", 'rating'),
array("a", 'description'),
array("a", 'tags'),
array("a", 'standardcode'),
array("a", 'advancedcode'),
array(PW_ADBOXES_PROJECT_WONDERFUL, "type")
);
}
public static function badDataProvider() {
@ -34,7 +47,7 @@ class TestPublisherInfo extends PHPUnit_Framework_TestCase {
public static function goodDataProvider() {
return array(
array('<pw:member memberid="1"><pw:adboxes></pw:adboxes></pw:member>'),
array('<pw:member memberid="1"><pw:adboxes><pw:adbox adboxid="1" sitename="a" url="http://meow.raow/" dimensions="1x1" rating="a" category="a"><pw:description>a</pw:description><pw:tags>a</pw:tags><pw:standardcode>a</pw:standardcode><pw:advancedcode>a</pw:advancedcode></pw:adbox></pw:adboxes></pw:member>')
array('<pw:member memberid="1"><pw:adboxes><pw:adbox adboxid="5" sitename="a" url="http://meow.raow/" dimensions="1x1" rating="a" category="a"><pw:description>a</pw:description><pw:tags>a</pw:tags><pw:standardcode>a</pw:standardcode><pw:advancedcode>a</pw:advancedcode></pw:adbox></pw:adboxes></pw:member>')
);
}
@ -46,20 +59,59 @@ class TestPublisherInfo extends PHPUnit_Framework_TestCase {
}
public function testPWAPI() {
$this->parser->parse('<pw:member memberid="1"><pw:adboxes><pw:adbox adboxid="1" sitename="a" url="http://meow.raow/" dimensions="1x1" rating="a" category="a"><pw:description>a</pw:description><pw:tags>a</pw:tags><pw:standardcode>a</pw:standardcode><pw:advancedcode>a</pw:advancedcode></pw:adbox></pw:adboxes></pw:member>');
$this->parser->parse('<pw:member memberid="1"><pw:adboxes><pw:adbox adboxid="3" sitename="a" url="http://meow.raow/" dimensions="1x1" rating="a" category="a"><pw:description>a</pw:description><pw:tags>a</pw:tags><pw:standardcode>a</pw:standardcode><pw:advancedcode>a</pw:advancedcode></pw:adbox></pw:adboxes></pw:member>');
$this->assertEquals(1, $this->parser->memberid);
$this->assertEquals(1, count($this->parser->adboxes));
$this->assertEquals(1, $this->parser->adboxes[0]->adboxid);
$this->assertEquals("a", $this->parser->adboxes[0]->sitename);
$this->assertEquals("http://meow.raow/", $this->parser->adboxes[0]->url);
$this->assertEquals("1x1", $this->parser->adboxes[0]->dimensions);
$this->assertEquals("a", $this->parser->adboxes[0]->rating);
$this->assertEquals("a", $this->parser->adboxes[0]->description);
$this->assertEquals("a", $this->parser->adboxes[0]->tags);
$this->assertEquals("a", $this->parser->adboxes[0]->standardcode);
$this->assertEquals("a", $this->parser->adboxes[0]->advancedcode);
foreach ($this->default_data as $info) {
list($value, $param) = $info;
$this->assertEquals($value, $this->parser->adboxes[0]->{$param}, $param);
}
}
function testGetSidebarInformation() {
$this->parser->is_valid = true;
$this->parser->memberid = "1";
$default_data_as_hash = array();
foreach ($this->default_data as $info) {
list($value, $param) = $info;
$default_data_as_hash[$param] = $value;
}
$this->parser->adboxes = array((object)$default_data_as_hash);
$sidebar_info = array(
array(
"id" => "project_wonderful_1_{$default_data_as_hash['adboxid']}",
"name" => "PW {$default_data_as_hash['dimensions']} {$default_data_as_hash['sitename']} ({$default_data_as_hash['adboxid']})",
"options" => array("adboxid" => $default_data_as_hash['adboxid'])
)
);
$this->assertEquals($sidebar_info, $this->parser->get_sidebar_widget_info());
$this->parser->is_valid = false;
$this->assertFalse($this->parser->get_sidebar_widget_info());
}
function testChangeSidebarAdType() {
$this->parser->is_valid = true;
$this->parser->memberid = "1";
$default_data_as_hash = array();
foreach ($this->default_data as $info) {
list($value, $param) = $info;
$default_data_as_hash[$param] = $value;
}
$this->parser->adboxes = array((object)$default_data_as_hash);
}
}
function __($string, $domain) { return $string; }
?>

64
views/main.php Normal file
View File

@ -0,0 +1,64 @@
<form id="pw-handler" action="" method="post">
<input type="hidden" name="action" value="change-memberid" />
<table class="form-table">
<tr>
<th scope="row">Your advertiser number</th>
<td>
<input id="memberid" name="memberid" value="<?php echo get_option("plugin-wonderful-memberid") ?>" />
</td>
</tr>
<tr>
<th scope="row">Use Standard Adboxes?</th>
<td>
<label>
<input type="checkbox"
name="use-standardcode"
value="yes"
<?php echo (get_option("plugin-wonderful-use-standardcode") == 1) ? "checked" : "" ?> />
<em>(If you want to use standard code adboxes instead of advanced code, enable this option)</em>
</label>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<input type="submit" value="Change" class="button" />
</td>
</tr>
</table>
</form>
<?php if ($this->publisher_info !== false) { ?>
<h3>Adbox Information</h3>
<table class="widefat post fixed">
<tr>
<th width="20%" class="manage-column">Site Name</th>
<th width="30%" class="manage-column">Description</th>
<th class="manage-column" align="center">Dimensions</th>
<th class="manage-column" align="center">Category</th>
<th style="text-align: right !important" width="25%" class="manage-column">Template Tag <em>(for direct use in theme)</em></th>
</tr>
<?php
$first_adboxid = null;
foreach ($this->publisher_info->adboxes as $adbox) {
$first_adboxid = $adbox->adboxid; ?>
<tr>
<td><a href="<?php echo $adbox->url ?>" target="_top" title="Ad for use on <?php echo $adbox->url ?> (opens in new window)"><?php echo $adbox->sitename ?></a></td>
<td><?php echo $adbox->description ?></td>
<td><?php echo $adbox->dimensions ?></td>
<td><?php echo $adbox->category ?></td>
<td align="right"><tt>the_project_wonderful_ad(<?php echo $adbox->adboxid ?>)</tt></td>
</tr>
<?php
}
?>
</table>
<h3>Using the Template Tags in Your Theme</h3>
<p>
Find the location in your theme where you want the ad to appear. Type in the template tag, surrounded in PHP tags, like this:
</p>
<tt>
&lt;?php the_project_wonderful_ad(<?php echo $first_adboxid ?>) ?&gt;
</tt>
<?php } ?>