My first widget! Random quote of the day/aphorism/fact etc
In response to a question from a friend of mine, I’ve just finished writing a quick widget/plugin to present a random aphorism (or whatever) as a sidebar widget. Much like Hello Dolly but widgetised.
here it is for those who want it. I will, at some stage, write a management interface to allow upload/management of aphorisms. Also add a configuration option to make the aphorism daily cached instead of re-generated each page refresh.
Update: second version now updated with management interface. Or at least a partial interface!
<?php /* Plugin Name: random Fact Widget Plugin URI: Description: This widget looks up a random fact from a database Author: Justin Adie Version: 0.2.0 Author URI: http://rathercurious.net */ /* * installation: * drop this file in your wordpress/wp-content/plugins directory * go to your plugins management and activate this plugin * * then go to your widget dashboard in Design->Widget (within the admin menu) and click Add . Place where you want. * Don't forget to save the changes... * */ /** * namespace mono-instance class for WP widget/plugin * * class allows a widget to display a random aphorism/fact or whatever, in widgetised themes. * assumption is that there is a table in the WP database with a field called id (as primary key) and randomFact */ class randomFact_Widget{ public $factTable = ''; public $aph =''; public $version = '0.2.0'; /** * method called by the add_action hook. this registers the sidebar widget * * has to be done quite late in the process * * @return void */ public function init(){ register_sidebar_widget("Daily Random", array($this, "widgetDisplay")); add_action('admin_menu', array($this, 'addManagementPage')); } public function __construct(){ global $wpdb; //$wpdb->show_errors(true); //for debugging $this->factTable = $wpdb->prefix . 'randomFact'; } public function addManagementPage(){ add_management_page('Random Facts', 'Random Facts', 8, __FILE__, array($this, "pageDisplay")); } /** * method to manage the installation routine * * @return */ public function install(){ global $wpdb; $result = $wpdb->query("create table if not exists {$this->factTable} (id mediumint(9) NOT NULL AUTO_INCREMENT PRIMARY KEY, randomFact longtext)"); if ($result){ update_option ('randomFact_Version', $this->version); } } /** * private function to retrieve and cache the aphorism/fact * * @return void */ private function getAph(){ global $wpdb; /* * this is an optimised method of retrieving random rows from a large dataset */ $sql = <<<SQL SELECT randomFact FROM {$this->factTable} order by rand() LIMIT 1 SQL; $aph = $wpdb->get_var($sql); $this->aph = empty($aph) ? $this->getErrorMessage() : $aph; } /** * private method to return a nil results string. * to debug this turn on $wpdb->show_errors or define WP_DEBUG as true in wp-config.php * * @return error string */ private function getErrorMessage(){ return "No facts found in the database, or a database error occurred"; } /** * public method to output the aphorism to the widget * * the args are automatically provided by Wordpress. * @return void * @param $args array */ public function widgetDisplay($args){ extract ($args); if (empty($this->aph)){ $this->getAph(); } echo <<<HTML $before_widget $before_title Random Fact $after_title {$this->aph} $after_widget HTML; } /** * set up the management page for the random Facts * * @return void */ public function pageDisplay() { $hidden_field_name = "randomFact_Widget_uploadAphorism_Type"; $upload = ''; if ( !empty($_POST[$hidden_field_name]) && $_POST[$hidden_field_name] == 'Y'){ if ($this->checkNonce()){} $upload = $_POST['randomFact_Widget_Fact']; $upload = str_replace("\r\n", "\n", $upload); $facts = explode("\n",$upload); $num = 0; foreach ($facts as $fact){ if (empty($fact)) continue; $result = $this->insertFact ($fact); if($result) { $num++; } } $upload = <<<HTML <div class="updated"> <p><strong>{$num} new facts saved to database</strong></p> </div> HTML; } $formUrl = str_replace( '%7E', '~', $_SERVER['REQUEST_URI']); $facts = $this->getFacts(); $rows = ''; foreach ($facts as $fact){ $rows .= <<<HTML <tr> <td id="randomFact_{$fact->id}">{$fact->randomFact}</td> <td> </td> </tr> HTML; } echo <<<HTML <div class="wrap"> <h2>Random Facts - Management</h2> <h3>Upload Facts</h3> {$upload} <form name="form1" method="post" action="{$formUrl}"> <p>Paste your fact below. Insert multiple facts separated by a line break</p> <p><textarea name="randomFact_Widget_Fact" rows="8" wrap="soft"></textarea></p> <hr /> <p class="submit"> <input type="submit" name="Submit" value="Insert Fact" /> <input type="hidden" name="{$hidden_field_name}" value="Y"> {$this->deliverNonce()} </p> </form> <hr/> <h3>Current Facts</h3> <p> <table class="widefat"> <thead> <tr> <th scope="col">Random Fact</th><th scope="col"> </th> </tr> </thead> <tbody> {$rows} </tbody> </table> </p> </div> HTML; } /** * method to add facts to the database * * @return bool if the fact is in the database, or there is a db error, it will return fale, else true * @param object $fact */ private function insertFact($fact){ global $wpdb; $oldValue = $wpdb->show_errors(true); //check that the fact is not in the database $chk = $wpdb->get_var($wpdb->prepare("select count(*) from {$this->factTable} where randomFact=%s", $fact)); if ($chk > 0){ return false; } $result = $wpdb->query($wpdb->prepare("insert into {$this->factTable} (id, randomFact) values (NULL, %s)", $fact)); if ($result){ return true; } else { return false; } } /** * method to return an associative array of fact objects * * @return array of objects */ private function getFacts(){ global $wpdb; $sql = "Select id, randomFact from {$this->factTable} order by id asc"; $results = $wpdb->get_results($sql); return $results; } /** * wrapper method to deliver a nonce * * @return void */ private function deliverNonce(){ if (function_exists('wp_nonce_field')){ wp_nonce_field($this->nonce); } } /** * method to check a nonce * @return */ private function checkNonce(){ check_admin_referer(); } } /* * this is my preference for plugins/widgets. * using a class prevents namespace clashes */ $randomFact_Widget = new randomFact_Widget; /* * this is the hook to make sure that this widget is enabled in WP */ add_action ('plugins_loaded', array(&$randomFact_Widget, 'init')); /* * register the activation hook for the plugin */ register_activation_hook(__FILE__, array(&$randomFact_Widget, 'install')); ?> |
Have installed this and populated a table called facts. Have kept your fields id and randomFact and changed the table to facts.
Getting this message:
>>>
No facts found in the database, or a database error occurred
<<<
Andy
I think you may be using the wrong version of the code. The first version had a small SQL error that always resulted in nil results. the query was also not compatible with my sqlite driver for PDO For WP. So i have migrated to a simpler, more traditional form of randomisation. This does not scale well on large datasets and I may post a code (rather than sql) based optimisation in the next few days.