Using Objects with WordPress Plugins, p. 2
In the first part of the series I looked at the three stages of plugin development: Classless, Static, and Object Based. In this part I will be demonstrating how you can use an additional class to separate common tasks into objects that can be reused, and so simplify the core plugin code.
For this example I am going to create a textbox as an external object. The plugin will require three textboxes on an admin page and will save the results of the input to a WordPress option.
Each textbox needs to retrieve its value, make that available to our plugin, output appropriate html to allow it to be changed, and if it is changed save it back to the database.
Without objects the plugin can look like this:
//note: I have omitted some value checking and validation for ease of reading class my_plugin { //PHP 4 style constructor function my_plugin(){ add_action( ‘admin_menu’ , array(&$this , ‘add_admin_menu’) ); } function add_admin_menu(){ add_options_page(‘My Plugin Options’, ‘My Plugin Options’, 9, basename(__FILE__), array(&$this, ‘admin_page’)); } function admin_page(){ $option1 = get_option(‘my_plugin_option_1′); $option2 = get_option(‘my_plugin_option_2′); $option3 = get_option(‘my_plugin_option_3′); if ( isset( $_POST[’submit_my_plugin_options’] ) ) { $option1 = $_POST[‘my_plugin_option_1′]; $option2 = $_POST[‘my_plugin_option_2′]; $option3 = $_POST[‘my_plugin_option_3′]; update_option(‘my_plugin_option_1′, $option1); update_option(‘my_plugin_option_2′, $option2); update_option(‘my_plugin_option_3′, $option3); } ?> <div class="wrap"> <h2>My Admin Page</h2> <form method="post"> <p> <label for="my_plugin_option_1">Option1</label> <input type="text" name="my_plugin_option_1" value="<?php echo ( $option1 ) ? $option1 : ” ?> " /> </p> <p> <label for="my_plugin_option_2">Option2</label> <input type="text" name="my_plugin_option_2" value="<?php echo ( $option2 ) ? $option2 : ” ?> " /> </p> <p> <label for="my_plugin_option_3">Option3</label> <input type="text" name="my_plugin_option_3" value="<?php echo ( $option3 ) ? $option3 : ” ?> " /> </p> <p> <input type="submit" name="submit_my_plugin_options" value="Submit" /> </p> </form> </div> <?php } } $my_plugin = new my_plugin();
To make the object we need to move most of the contents of the admin page, into the textbox class. We’ll start with the empty object, including the constructor:
class my_text_box{ //php 4 constructor function my_text_box( ) { } }
So with an empty object, the first thing we need to do is to make sure that the option, and the form control will be unique. To do this we will create a prefix that will apply to any text box we create with this option and a name that will be set for each individual text box. At this point we’ll also declare a variable that will hold the value.
class my_text_box { var $prefix = ‘my_text_box_’; var $name = ”; var $value = ”; //php 4 constructor function my_text_box( $name ) { $this->name = $name; } }
Now we are in a position to interact with the database, via the WordPress options support, and with the user by outputing html.
We need to check to see if this textbox already has a value in the database, then check to see if the user is submitting a new value, and if so update that.
class my_text_box { var $prefix = ‘my_text_box_’; var $name = ”; var $value = ”; //php 4 constructor function my_text_box( $name ) { $this->name = $name; if ( $v = get_option( $this->prefix . $this->name ) ) { $this->value = $v; } if ( isset( $_POST[$this->prefix . $this->name] ) ) { $this->value = $_POST[$this->prefix . $this->name]; update_option( $this->prefix . $this->name , $this->value ); } } }
Finally we need to add a function to output the html to the page, so I have added another variable, a description, to the constructor that will be used for the label and a display function to output the html.
//note this example does not perform any validation. class my_text_box { var $prefix = ‘my_text_box_’; var $name = ”; var $value = ”; var $description = ”; //php 4 constructor function my_text_box( $name , $description ) { $this->name = $name; $this->description = $description; if ( $v = get_option( $this->prefix . $this->name ) ) { $this->value = $v; } if ( isset( $_POST[$this->prefix . $this->name] ) ) { $this->value = $_POST[$this->prefix . $this->name]; update_option( $this->prefix . $this->name , $this->value ); } } function display() { echo ‘<p>’; echo ‘<label for="’.$this->prefix . $this->name.‘">’.$this->description.‘</label>’; echo ‘<input type="text" name="’.$this->prefix . $this->name.‘" value="’.$this->value.‘" />’; echo ‘</p>’; } }
With this class as part of the plugin the textbox code will be identical for every text box and can be changed centrally. The final plugin will include the textbox class I have just created and the original plugin code we looked at, at the start of the post, can be reduced to this below:
class my_plugin { //PHP 4 style constructor function my_plugin(){ add_action( ‘admin_menu’ , array(&$this , ‘add_admin_menu’) ); } function add_admin_menu(){ add_options_page(‘My Plugin Options’, ‘My Plugin Options’, 9, basename(__FILE__), array(&$this, ‘admin_page’)); } function admin_page(){ $option1 = new my_text_box( ‘Option_1′ , ‘First Option’); $option2 = new my_text_box( ‘Option_2′ , ‘Second Option’); $option3 = new my_text_box( ‘Option_3′ , ‘Third Option’); ?> <div class="wrap"> <h2>My Admin Page</h2> <form method="post"> <p> <?php $option1->display(); ?> </p> <p> <?php $option2->display(); ?> </p> <p> <?php $option3->display(); ?> </p> <p> <input type="submit" name="submit_my_plugin_options" value="Submit" /> </p> </form> </div> <?php } } $my_plugin = new my_plugin();
You can download a sample plugin containing the finished code here.
It might not seem as though there is much of a saving in this example. If you think that you are right. In fact there are an extra 15-20 lines (including blanks) in the new version once the constructor has been added, but that is a result of the particularly simple example I have used.
Imagine though that your plugin has several admin pages and it starts to become a little clearer how much easier the actual plugin code itself will be.
There are also other occasions where objects are the natural choice.
My tabbed sidebars plugin allows the user to decide how many tabbed sidebars they want. However many they choose that is how many sidebars need to be registered, how many widgets need to be created and how many functions to tell the widgets what to display that need to be created. Using an object is the perfect way to handle this.
If you are considering whether to use objects I encourage you to take a look at the code for that plugin.
In this part I have demonstrated creating a separate object to perform routine tasks, such as creating textboxes and handling their submission; in part 3 I am going to look at how objects can inherit from other objects, making it easier to create complimentary objects, such as textareas, and textboxes.
Comments
Leave a Reply
I am currently testing a comment link policy which means commenters do not get a link. There is a poll, and open comments for feedback on the comment policy page.
