ESN 14617-090111-633010-85


Document Name: My First Look at WordPress Plugins
Document Description: My First Look at WordPress Plugins

My First Look at WordPress Plugins


2009/01/11

As I mentioned the post just before this, I want to learn a bit more about Wordpress, specificaly plugins (no, I won't be doing any theme designs!). As it happened, someone had read my post about generating Numly tags and they happened to have a non-working plugin that was supposed to get Numly tags automatically. As the plugin was published under a GNU license, I agreed to take a look at it.

That offer was somehat brazen. At that moment I knew nothing whatsoever about WordPress plugins other than that they existed and were written in Php. My Php skills are weak - I prefer Perl. But hey, Php is very similar to Perl - if you can write Perl you can surely read Php - and while I may not know much about WordPress, I had a pretty good idea how plugns would be likely to work. So I said, sure, go ahead and send me the code.

The code is two files - I've added both of them to the bottom of this post so that you can read the whole thing if you like.

The first thing I noticed is that it looked like the code would go out and get a tag from Numly. I noticed this line:

 add_action('publish_post','numly_publish_post');
 

I assumed that this would call "numly_publish_post" when WordPress published a post. That function looked like it checked to see if it already had acquired a Numly ESN and would go get one if it had not. I didn't know if it would make that call before, during or just after publishing, but it looked reasonable to me.

So I went ahead and installed the plugin, set its administrative parameters and created a new post. I got email from Numly instantly, which told me that it had indeed generated to ESN. I then dropped back to the command line and dumped the WordPress database to see if it had stored the data correctly:

 $ mysqldump wordpress -p | grep numly_key
 Enter password: 
 INSERT INTO `wp_postmeta` VALUES
 (1,3,'_edit_lock','1231683620'),(2,3,'_edit_last','1'),(5,6,
 '_edit_lock','1231691097'),(6,6,'_edit_last','1'),
 (8,6,'numly_key','9374309011185456164');
 

("wordpress" is the name I chose for the database)

So that looks good, and it has the right data, you can go to Numly.com with that "9374309011185456164" and look up the copyright. So that's all good.. but what makes it appear on the page?

Well, it looks like the "numly_output" function will do that; it just needs to be passed a page id. But what calls it? I saw nothing that would cause this code to run. Possibly I misunderstand plugins - maybe that function gets called automagically, but I doubt it. So I tried adding a new line: "add_action('comment_form','numly_output');" (shown in bold in the code below) and yes, that worked.

Well, "worked", but I'm not happy with it. It plops a link below the comments and doesn't seem to want to show the barcode. I'm confident I can fix all that and make it look better, so there is more to do but I was happy to find that WordPress plugins are as simple as I expected.

Here's the code:

 blogbling_functions.php
 <?php if (!function_exists('blogbling_version_check')) {
 
 function blogbling_version_check
 ($plugin_name='',$last_check_time,$interval=7) {
   /*
    * Version Check code.  * This is a bit verbose. I'd
    like to cut it down a bit. I know this works * in
    almost all cases. Some places may not have curl
    installed. I could do * it in AJAX calling the plugin
    itself with a parameter and firing off a * call but
    that's basically the same as what I'm doing here. So
    why bother.  */ $interval        = intval($interval);
   $current_version = -1; if
   (($last_check_time+(86400*$interval))<mktime()) {
 
   $current_version =
   blogbling_url_get('http://blog.calevans.com/plugin_version_checker.php?plugin='.$plugin_name);
   } else {
   $current_version = -1; }// if
   (($notable_settings['last_version_check']+(86400*7))<mktime())
 return $current_version; } // function blogbling_version_check
 ($plugin_name)
 
 
 // depricated. Code moved back into wp-alexadex because it's
 too specific.  function blogbling_url_get($url) {
   // user send_to_host whenever possible, it's better.
   $return_value = ''; $elements = parse_url($url); if
   ($fp = @fsockopen($elements['host'],80)) {
   fputs($fp, sprintf("GET %s HTTP/1.0\r\n" .
   "Host: %s\r\n\r\n", $elements['path'] . (isset
   ($elements['query']) ? '?'. $elements['query']
   : ''), $elements['host'])); while (!feof($fp))
   $line .= fgets($fp, 4096); fclose($fp); $line
   = urldecode(trim(strtr($line,"\n\r\t\0","
   "))); $work_array = explode("  ",$line); /*
    * This does not allow for any additional
    messages to be passed. It * assumes that the
    last time coming in is the version #.  */
   $return_value = $work_array[count($work_array)-1];
   } // if ($fp) return $return_value; } // function
 blogbling_url_fetch($url)
 
 
 function blogbling_get_version($file_name) {
   if (!empty($file_name)) {
   /*
    * Ripped out of WordPress Not sure if I'll
    ever use any more of this but I'll * leave
    them in just for fun.  */ $plugin_data =
   implode('', file($file_name)); if
   (preg_match("|Version:(.*)|i", $plugin_data,
   $version)) {
   $version = $version[1];
   } // if (preg_match("|Version:(.*)|i",
   $plugin_data, $version)) } // if (!empty($filename))
   return $version; } // function blogbling_get_version($file_name)
 
 
 function
 blogbling_send_to_host($host,$method,$path,$data,$return_full_headers=false)
 {
 
     $method = empty($method)?'GET':strtoupper($method); if
     ($method == 'GET') $path .= '?' . $data; $output  = '';
     $output .= $method." ".$path." HTTP/1.1\r\n"; $output .=
     "Host: ".$host."\r\n"; $output .= "Content-type:
     application/x-www-form-urlencoded\r\n"; $output .=
     "Content-length: ".strlen($data)."\r\n"; $output .=
     "Connection: close\r\n\r\n"; $output .=
     ($method=='POST'?$data:'')."\n";
 
     $fp = fsockopen($host, 80);
   $switch = false; fputs($fp,$output); /*
    * Change this to store headers in one array and lines
    in another. If * return full headers is true then
    concat before returning.  */ while (!feof($fp)) {
   $line =
   strtr(fgets($fp,128),array("\n"=>"","\r"=>""));
   if (!$switch and empty($line)) {
   $switch = (!$switch); } else if
   ($switch) {
   $buf .= $line; } // if (!$switch and
   empty($line)) } // while (!feof($fp)) fclose($fp);
     return $buf; } // function
 blogbling_sendToHost($host,$method,$path,$data,$useragent=0)
 
 
 function blogbling_fetch_options($prefix='blogbling') {
   $output = array(); $output=get_option($prefix.'_options');
   return $output; } // function
 blogbling_fetch_options($prefix='blogbling')
 
 
 function blogbling_post_options($prefix='blogbling',$source_array)
 {
   update_option($prefix.'_options',$source_array);
   return; } // if (!function_exists('blogbling_version_check'))
 } // if (!function_exists('blogbling_version_check')) ?>
 
 wp-numly.php
 <?PHP /* Plugin Name:wp-numly Plugin URI:
 http://www.calevans.com/view.php/page/numly Description:
 Electronic Standard Book Number (numly) is the unique identifier
 of electronic content and media. numlys are recognized worldwide
 by electronic publishing companies and electronic content
 providers. They serve as branded identifier or copyright for
 individuals or companies developing electronic content and
 media. numlys are assigned and managed by <a
 href="http://www.numly.org">numly.ORG</a>.  This plugin
 automatically grnerates an numly for each new post. This plugin
 requires Wordpress 2.0+ Version: 1.5 Author: Cal Evans
 <cal@calevans.com> Author URI: http://blog.calevans.com/ */
 
 /*
  *  Copyright 2005  Cal Evans  (email: cal@calevans.com) * *
  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., 59
  Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
 /*
  * History * 1.0 03/02/2006 - Cal * Initial Coding * * 1.1
  03/04/2006 - Cal * Initial Release * * 1.1 03/04/2006 - Cal
  * receoded the options into a single database hit.  * * 1.5
  04/18/2006 - Cal * Changed name to numly.  */
 
 require_once('blogbling_functions.php');
 
 function numly_output($id=0) {
   $numly_settings = blogbling_fetch_options('numly');
   $numly_current_key = get_post_meta($id,'numly_key'); $output
   = ''; $license_array = numly_prepare_license_array(); if
   (is_array($numly_current_key)) $numly_current_key =
   $numly_current_key[0];
 
   if (!empty($numly_current_key)) { $output  = '<div
   class="numly-output">'; $output .= '<a
   href="http://www.numly.com/numly/verify.asp?id='.$numly_current_key.'"
   target="_blank">';
 
 
 
   $output .= '<center><img alt="numly"
   src="http://numly.com/numly/numicon.gif" border="0"/>';
   $output .= ''.$numly_current_key.' </center>';
 
 
 
   if ($numly_settings['show_barcode']=='yes') { $output .=
   '<br /><img
   src="http://numly.org/numly/barcode.asp?code='.$numly_current_key.'&height=20&width=1&mode=code39"/>';
   } // if ($numly_settings['show_barcode']=='yes') $output .=
   '</a></div>';
 
   if ($numly_settings['cc_license']!='reserved') { $output .=
   '<div ><!--Creative Commons License--><a rel="license"
   href="http://creativecommons.org/licenses/'.$numly_settings['cc_license'].'/3.0/">
 
 
 
 
 <!--<img alt="Creative Commons License"
 border="0"src="http://creativecommons.org/images/public/somerights20.png"/></a><br/>-->
 
 <!--This work is licensed under a <a rel="license"
 href="http://creativecommons.org/licenses/'.$numly_settings['cc_license'].'/3.0/">Creative
 Commons '.$license_array[$numly_settings['cc_license']].' 3.0
 License</a>.--> <hr color="blue" size="2"> <br> </br> <br>
 </br> <br> </br>
 
 
 <!--/Creative Commons License--><!-- <rdf:RDF
 xmlns="http://web.resource.org/cc/"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><Work
 rdf:about=""><license
 rdf:resource="http://creativecommons.org/licenses/'.$numly_settings['cc_license'].'/3.0/"
 /></Work><License
 rdf:about="http://creativecommons.org/licenses/by-nd/3.0/"><permits
 rdf:resource="http://web.resource.org/cc/Reproduction"/><permits
 rdf:resource="http://web.resource.org/cc/Distribution"/><requires
 rdf:resource="http://web.resource.org/cc/Notice"/><requires
 rdf:resource="http://web.resource.org/cc/Attribution"/></License></rdf:RDF>
 --></div>';
   } // if ($numly_settings['cc_license']!='reserved')
 
   } // if (!empty($numly_current_key)) echo $output; return;
 } // function numly_output()
 
 
 function numly_prepare_license_array() {
   $license_array = array(); $license_array["reserved"] = "All
   Rights Reserved"; $license_array["by"]       = "Attribution";
   $license_array["by-nc"]    = "Attribution-NonCommercial";
   $license_array["by-nc-nd"] = "Attribution-NonCommercial-NoDerivs";
   $license_array["by-nc-sa"] = "Attribution-NonCommercial-ShareAlike";
   $license_array["by-nd"]    = "Attribution-NoDerivs";
   $license_array["by-sa"]    = "Attribution-ShareAlike";
 
   return $license_array;
 
 } // function numly_prepare_license_array()
 
 
 /*
  * The options Page */ function numly_options_page() {
   $version = blogbling_get_version(__file__);
 
   /*
    * Process a POSTED form.  */ if (isset($_POST['info_update']))
   { blogbling_post_options('numly',$_POST['numly_settings']);
   } // if (isset($_POST['info_update']))
 
 
   $numly_settings = blogbling_fetch_options('numly');
   $license_array = numly_prepare_license_array() ?>
 
 <?PHP if (isset($_POST['info_update'])) {?><div id="message"
 class="updated fade"><p><strong>Options Saved</strong></p></div><?PHP
 } ?>
 
 <div class=wrap>
   <form method="post">
     <h2>numly Configuration Options</h2> <input type = "hidden"
 	 name = "numly_settings[numly_last_version_check]"
 	       value="<?=$numly_settings['numly_last_version_check'];?>"
 	       />
 
     <fieldset name="user_name"> <legend>Your numly User Name<br
   />(Note: The plugin will not operate without it.)</legend>
   <input type="text"
 	       name="numly_settings[username]"
 	       value="<?=$numly_settings['username'];?>"
 	       size="75" />
   </fieldset>
 
     <fieldset name="publisher"> <legend>Your Name or the name
   of the publisher of the content.</legend> <input type="text"
 	       name="numly_settings[publisher]"
 	       value="<?=$numly_settings['publisher'];?>"
 	       size="75" />
   </fieldset>
 
     <fieldset name="show_barcode"> <input type  = "checkbox"
 	 name  = "numly_settings[show_barcode]" value = "yes"
      <?=$numly_settings['show_barcode']=='yes'?'CHECKED':'';?>
      /> <label>Display the barcode?</label> </fieldset>
     <fieldset name="cc_license"> <legend>What Creative Commons
   License would you like to use?</legend>
 
   <select name="numly_settings[cc_license]"> <?PHP
 foreach($license_array as $key=>$value) { ?>
   <option value="<?=$key?>"
   <?=($numly_settings['cc_license']==$key)?'SELECTED':''?>
   ><?=$value;?></option> <?PHP } // foreach($license_array as
 $key=>$value) ?>
   <option value="publicdomain">Public Domain</option> </select>
     </fieldset>
 
   <!-- Standard BlogBling stuff --> <fieldset
   name="version_check_interval"> <legend>Days Between Version
   Checks</legend> <input type      = "text"
 	 name      = "numly_settings[version_check_interval]"
      value     = "<?=$numly_settings['version_check_interval'];?>"
      size      = "2" maxlength = "2" /> </fieldset>
 
 <div class="submit">
   <input type="submit" name="info_update" value="<?php
   _e('Update', 'Localization name')?>" /> </div>
   </form> </div> <?PHP
   if ($numly_settings['version_check_interval']>0) {
   $current_version =
   blogbling_version_check(basename(__FILE__,'.php'),$numly_settings['last_version_check'],$numly_settings['version_check_interval']);
   if ($current_version!=-1) { if ($version!=$current_version)
   { ?>
   <div class="wrap" style="border:solid 1px red;">This is
   version <?=$version;?>. The current version of the plugin
   is <?=$current_version;?>. Click <a
   href="http://www.calevans.com/view.php/page/numly" target="_NEW"
   title="Opens a new window.">here</a> to go to the project
   page to find out more. </div> <?PHP
   } else { ?>
   <div class="wrap" >This is version is up to date. </div>
 <?PHP
   } // if ($version!=$current_version)
   $numly_settings['last_version_check']=mktime();
   blogbling_post_options('numly',$numly_settings); } // if
   ($current_version!=-1) } // if
   ($numly_settings['version_check_interval']>0) ?>
   <div class="wrap" > <?PHP ?> <table border="0" width="100%">
   <tr> <td alignt="left" width="50%">Contact the <a
   href="mailto:cal@calevans.com">Author</a> if you are having
   problems or read his <a href="http://blog.calevans.com"
   target="_NEW" title="Postcards From My Life">blog</a><br
   /><a href="http://blog.calevans.com/blog-bling" target="_NEW"
   style="border:none;"><image
   src="/wp-content/plugins/blogbling/images/blogbling.gif"
   alt="Blog Bling"></a></td><td align="right" width="50%">Get
   an numly account or manage the one you have.<br /><a
   href="http://www.numly.org" target="_BLANK"><img
   src="/wp-content/plugins/blogbling/images/numlyicon.gif"
   alt="numly" /></a></td> </tr> </table> </div> <?PHP }
 
 
 function numly_publish_post($id = 0) {
   $numly_current_key = get_post_meta($id,'numly_key');
 
   if (strlen($_POST['post_password'])<1 and empty($numly_current_key))
   { // get the options $numly_settings = blogbling_fetch_options('numly');
   $user_info = get_userdata($_POST['post_author']);
 
   if (is_object($user_info)) { $numly_data = array();
   $numly_data['username']  = $numly_settings['username'];
   $numly_data['docname']   = $_POST['post_title'];
   $numly_data['docdesc']   = $_POST['content']; $numly_data['author']
   = $user_info->display_name; $numly_data['publisher'] =
   $numly_settings ['publisher']; $numly_data['licensee']  =
   $user_info->display_name; $numly_data['licemail']  =
   $user_info->user_email; $numly_data['url']       =
   get_settings('siteurl').'/index.php?p='.$id; $numly_data['idonly']
   = 'true';
 
   $numly_query = ''; foreach ($numly_data as $key=>$value) {
   $numly_query .= urlencode(trim($key))."=".urlencode(trim($value))."&";
   }  // foreach ($numly_data as $key=>$value)
 
   // call the site $numly_id =
   blogbling_send_to_host('www.numly.com','POST','/numly/generate.asp',$numly_query);
   } // if (is_array($user_info)) // save off the meta.  if
   (is_array($numly_id)) $numly_id = $numly_id[0]; if
   (is_numeric($numly_id)) { add_post_meta($id,'numly_key',$numly_id,true);
   } // if (is_numeric($numly_id)) } // if (empty($numly_current_key))
 
 
 } // function numly_publish_post()
 
 
 function numly_add_option_page() {
   add_options_page("numly Configurator", 'numly', 7, __FILE__,
   'numly_options_page'); } // function numly_add_option_page()
 
 
 /*
  * Undo the damage we may have done. if this plugin has alreayd
  been installed * then let's hit the database, grab the options,
  store them all in one array * then write the back out.  */
 function numly_install() {
   $output = array(); $output['username']               =
   get_option('numly_username'); $output['publisher']
   = get_option('numly_publisher'); $output['show_barcode']
   = get_option('numly_show_barcode'); $output['last_version_check']
   = get_option('numly_last_version_check');
   $output['version_check_interval'] =
   get_option('numly_version_check_interval');
 
   delete_option('numly_username'); delete_option('numly_publisher');
   delete_option('numly_show_barcode');
   delete_option('numly_last_version_check');
   delete_option('numly_version_check_interval');
 
   /*
    * Set Defaults */ $output['username']               =
   empty($output['username'])?'':$output['username'];
   $output['publisher']              =
   empty($output['publisher'])?'':$output['publisher'];
   $output['show_barcode']           =
   ($output['show_barcode']=='yes')?'yes':'no';
   $output['last_version_check']     =
   empty($output['last_version_check'])?0:$output['last_version_check'];
   $output['version_check_interval'] =
   empty($output['version_check_interval'])?7:$output['version_check_interval'];
   $output['cc_license']             =
   empty($output['cc_license'])?'reserved':$output['cc_license'];
 
   blogbling_post_options('numly',$output);
 
   return; } // function numly_install()
 
 
 /*
  * Register our intentions with WordPress.  */ if (isset($wp_version))
 {
   add_action('admin_menu', 'numly_add_option_page');
   add_action('publish_post','numly_publish_post');
   add_action('comment_form','numly_output');
   register_activation_hook(__file__, 'numly_install'); } //
 if (isset($wp_version)) /*
 
 
 <!--Creative Commons License--><a rel="license"
 href="http://creativecommons.org/licenses/by-nc/3.0/"><img
 alt="Creative Commons License" border="0"
 src="http://creativecommons.org/images/public/somerights20.png"/></a><br/>
 
 <!-- <rdf:RDF xmlns="http://web.resource.org/cc/"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
   <Work rdf:about=""> <license
   rdf:resource="http://creativecommons.org/licenses/by-nc/3.0/"
   /> </Work> <License
   rdf:about="http://creativecommons.org/licenses/by-nc/3.0/"><permits
   rdf:resource="http://web.resource.org/cc/Reproduction"/><permits
   rdf:resource="http://web.resource.org/cc/Distribution"/><requires
   rdf:resource="http://web.resource.org/cc/Notice"/><requires
   rdf:resource="http://web.resource.org/cc/Attribution"/><prohibits
   rdf:resource="http://web.resource.org/cc/CommercialUse"/><permits
   rdf:resource="http://web.resource.org/cc/DerivativeWorks"/></License></rdf:RDF>
   -->
 
 
 <!--Creative Commons License--><a rel="license"
 href="http://creativecommons.org/licenses/by-nd/3.0/"><img
 alt="Creative Commons License" border="0"
 src="http://creativecommons.org/images/public/somerights20.png"/></a><br/>
 
 
 
 
 
 
 
 
 <!--/Creative Commons License--><!-- <rdf:RDF
 xmlns="http://web.resource.org/cc/"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
   <Work rdf:about=""> <license
   rdf:resource="http://creativecommons.org/licenses/by-nd/3.0/"
   /> </Work> <License
   rdf:about="http://creativecommons.org/licenses/by-nd/3.0/"><permits
   rdf:resource="http://web.resource.org/cc/Reproduction"/><permits
   rdf:resource="http://web.resource.org/cc/Distribution"/><requires
   rdf:resource="http://web.resource.org/cc/Notice"/><requires
   rdf:resource="http://web.resource.org/cc/Attribution"/></License></rdf:RDF>
   --> */
 
 ?>
 

Author: Anthony Lawrence - Contact Author
Publisher: Anthony Lawrence
Licensee Name: Anthony Lawrence
Reference URL: http://aplawrence.com/Web/first_wp_plugin.html
Copyright: All Rights Reserved
Registration Date: 1/11/2009 6:36:24 PM UTC
Views: 178




NUMLY.COM