143 Admin Menu 0v3 Text to Hyperlink (How-to Video)
143 Admin Menu 0v3 Text to Hyperlink (Video)

Part of the “How to Write a WordPress Plugin” series
This Lesson – Overview
This lesson is part of the series covering the WordPress administration menus and options pages.
In this lesson we will go a step further with admin menus by demonstrating how to save your admin options to the database. We will accomplish this by expanding upon the, Text to Hyperlink, example I introduced in an earlier lesson.
Contents
- 110 WordPress Plugin Naming and Declaration (How-to Video)
- 120 The Plugin Class (How-to Video)
- 130 WordPress Hooks, Actions and Filters (How-to Video)
- 131 Text to Hyperlink Filter Example (How-to Video)
- 140 WordPress Administration Menus/Panels/Pages (How-to Video)
- 141 WordPress PK Admin Menu 0v1 Demo – A Simple Sub Menu (How-to Video)
- 142 WordPress PK Admin Menu 0v2 A Top-level and Sub-level Menu (How-to Video)
- 143 Admin Menu 0v3 Text to Hyperlink (How-to Video)
- 150 Database
- 161 Javascript Inclusion with Plugins
- 162 CSS Inclusion with Plugins
- 170 Plugin Release and Promotion
Objectives
This quite an extensive lesson, the primary aim of which is to construct a ‘user’ menu that will allow us to use the WordPress database to store the data for our Text to Hyperlink plugin.
So, in this lesson we will be taking what we have learned so far about admin menus, combining this knowledge with our Text to Hyperlink lesson, saving the user data in the WordPress database, retrieving that data, parsing page contents for a keyword and changing that keyword to a hyperlink.
The topics we need to implement to achieve this objective are:
- Construct admin menu.
- Construct user panel.
- Save ‘user’ data to the WordPress database.
- Retrieve data from the WordPress database.
- Modify data in the WordPress database.
- Delete data in the WordPress database.
- Parse page content for keyword.
- Modify keyword (if required).
- Attach hyperlink to keyword.
Other than the introduction of the database requirements, nothing is actually new in this lesson, just implemented a little differently. So although a few items may look a little different, just look back at the previous lessons and you will see that we are just covering the same stages and steps as before, they’re just a little more involved.
This lesson can be grouped into the following sections.
- The class and its declaration, which we’ve already covered.
- The plugin filter and action hooks, which we’ve also already covered.
- The Text to Hyperlink function which has been modified to accommodate database interaction.
- The admin menu function, which uses the same methods discussed in the previous lessons.
- The user page which contains the form and code for interacting with the database.
- Plugin cleanup.
I will briefly discuss all sections but concentrate on those areas covering form construction and database interaction in this lesson.
WordPress Plugins and Database Interaction
When writing your plugins, you will inevitably need to store and retrieve data. Most useful WordPress Plugins need to get some data from users and save it between sessions, for use in filter, action and template functions.
This information has to be saved in the WordPress database, in order to be persistent between sessions. Fortunately for us, WordPress makes data storage and retrieval a relatively simple task with Options and Database Objects.
Storing Data in a Database
For our purposes, there are two recommended ways to store data in the WordPress database:
- Use the WordPress “Option” mechanism.This method is appropriate for storing small amounts of relatively static, named pieces of data.
- Create your own database table.This method is appropriate for data not associated with individual posts, pages, attachments, or comments, the type of data that will grow as time goes on.
Unless your plugin requires an extensive database or you’re storing lots of records or variables, most plugins will not require their own database table and Options will suffice. We will cover WordPress Database Interaction in more detail in a latter lesson.
The WordPress “Option” Mechanism
Since this is a simple plugin we will use the WordPress Options mechanism in this lesson.
With WordPress options, saving and retrieving data from the database can be as simple as a function call. WordPress has four functions for options:
- add_option()
- update_option()
- get_option()
- delete_option()
add_option()
The add_option() creates a new option, i.e. adds data to the database. It does nothing if option already exists. The function accepts four variables, with the $name variable being required. The $name variable should be unique to prevent overwriting of existing options.
- I suggest you seriously consider using the update_option() function instead of this function as it does the same thing, but better.
start
add_option($name, // Required (string). Name of the option to be added. $value, // Optional (mixed). The option value to be stored. $deprecated, // Optional (string). Just pass an empty string or null. $autoload); // Optional, defaults = 'yes'.
end
update_option()
The update_option() either creates or updates an option value in the database. The function accepts two variables, both of which are required.
- This function is basically the same as the add_option().
- This is a much simpler method to use than the add_option() function.
update_option($option_name, // Required (string). Name of the option to update. $newvalue); // Required. (string|array|object) The new value for the option.
get_option()
The get_option() function allows you to retrieve a previously stored option from the database. It requires only one variable, which is the name of the option to retrieve.
get_option($option); // Required (string). Name of the option whose value you want returned.
delete_option()
The delete_option() function, as you might expect, deletes options from the database.
delete_option($option_name); // Required (string). Name of the option to delete.
A Code Example
One of the easiest methods of storing options in the database is as an associative array, $admin_options_array[] in the following example.
I also declare the database field name in a variable $pk_admin_options_name, in the example, rather than as a string in the get_options() function. This is better programming practice in my opinion.
This prevents storing multiple options, each of which would be a database call. The technique helps with code bloat and helps prevent naming collisions with other plugin authors.
// Assign a default option name var $pk_admin_options_name = 'pk_admin_options_data'; // Assign default option values var $admin_options_array = array( 'pk_search_text' => 'WordPress', 'pk_replace_text' => 'WORDPRESS', 'pk_url_text' => 'http://WordPress.org'); // Get options from database $pk_options = get_options($this->pk_admin_options_name); if (!empty($pk_options)) { foreach ($pk_options as $key => $option) $admin_options_array[$key] = $option; } else { update_options($this->pk_admin_options_name,$this->admin_options_array) }
Plugin Cleanup and Uninstall PHP
Cleaning up after plugin deletion is a topic we haven’t touched on before.
When deleting previous plugin examples, WordPress handled everything necessary for the plugins removal.
With database interaction comes the responsibility for cleaning up after ourselves. Luckily this can be accomplish relatively easily by including an uninstall file in our plugins directory called uninstall.php.
The WordPress Codex also details the register_uninstall_hook() which will be called when the user clicks on the uninstall link, so requiring the plugin to uninstall itself.
Personally I find this hook cumbersome at best and prefer using the ‘uninstall.php’ way of uninstalling plugins rather than the register_uninstall_hook().
To use ‘uninstall.php’, simply create a file named ‘uninstall.php’ in the base plugin folder. This file will be called, if it exists, during the uninstall process bypassing the uninstall hook.
Just place everything needed to cleanup the plugin in this file, think of it as a class destructor. Generally this will simply be a case of removing data and tables from the database using WordPress function calls.
In our case the only thing we need to do is delete the pk_admin_options_data record. This is accomplished with the delete_option() function.
The only thing you must remember when using ‘uninstall.php’ is to always check for the WP_UNINSTALL_PLUGIN constant, before executing any code. The WP_UNINSTALL_PLUGIN constant is defined by WordPress at runtime during a plugin uninstall, it will not be present if ‘uninstall.php’ is requested directly.
Uninstall PHP
<?php /** * @author Philip King * @url http://kingsolutions.org.uk/wordpress/ * * The pk-admin-menu-0v3 Uninstall script. */ if( defined( 'ABSPATH') && defined('WP_UNINSTALL_PLUGIN') ) { $pk_admin_options_name = 'pk_admin_options_data'; //Remove the plugin's settings delete_option( $pk_admin_options_name ); } ?>
Plugin Actions and Filter Hooks
In this lesson we use both the add_filter()and the add_action() WordPress hooks.
The add_filter() hook is used to pass post (page) content to our pk_text_to_hyperlink() function.
The add_action() hook is used to call our admin menu via the pk_add_pages() function.
// TODO: Enter Plugin Actions and Filters here add_filter('the_content', array($this,'pk_text_to_hyperlink'),1); add_action('admin_menu', array($this, 'pk_add_pages'));
Class Variable Declarations
As stated earlier the database field name we’ll be using is declared in the variable $pk_admin_options_name. This name must be unique.
The data for our example will be stored in the associative array, $admin_options_array[]. Notice the array has been given default values which match the values used in the previous lesson. There’s no particular reason for this, I just though it would be nice to continue from where we left off.
The $hidden_field_name variable is just the usual hidden form test parameter.
// TODO: Variable declarations go here var $pk_admin_options_name = 'pk_admin_options_data'; var $hidden_field_name = 'pk_submit_hidden'; // Assign default option values var $admin_options_array = array( 'pk_search_text' => 'WordPress', 'pk_replace_text' => 'WORDPRESS', 'pk_url_text' => 'http://WordPress.org');
Text to Hyperlink Function
The text to hyperlink function works basically the same as in previous lessons except, this time the values can be changed via an options page and they are now persistent as the values are stored in the database.
The function gets data from the WordPress database > options table > field pk_admin_options_name using the get_option() function. If there is no data the default values are used and the database updated.
The post content is then parsed for the stipulated keyword (or phrase) and modified as necessary before being returned to WordPress for further processing.
// TODO: Enter Action and Filter Methods here. // Change text to hyperlink function pk_text_to_hyperlink( $content ) { // Get options from database $pk_options = get_option($this->pk_admin_options_name); // If we have options then update the array if (!empty($pk_options)) { foreach ($pk_options as $key => $option) { $this->admin_options_array[$key] = $option; } } else { // Nothing in the database so update with defaults update_option( $this->pk_admin_options_name, $this->admin_options_array ); } $url = $this->admin_options_array['pk_url_text']; $replace = $this->admin_options_array['pk_replace_text']; $search = $this->admin_options_array['pk_search_text']; $replace_text = "<a href=' $url '> $replace</a>"; $content = str_ireplace($search, $replace_text, $content); return $content; } // End function pk_text_to_hyperlink
Action Function for the Add_Action, Admin_Menu Hook
The function pk_add_pages() simply adds the sub-menu, PK Test Settings, under the top-level Settings menu item.
// action function for the add_action/admin_menu hook function pk_add_pages() { // Add a new submenu under Settings: add_options_page('PK Test Settings', 'PK Test Settings', 'manage_options', 'testsettings', array($this, 'pk_test_setting_page')); }
The Options Page and User Panel
The options page is created by the pk_test_setting_page() function.
This begins by checking that the user has the required capability and then reading the existing option values from the database if they exist or using the default values if there are no entries in the database.
The user form is then placed on the page.
Should the user enter new data on the form and click the, ‘Save Changes’ button this function will test for the hidden field variable $hidden_field_name and if true the $admin_options_array[] updated with the new values which are then saved to the database.
// pk_test_setting_page() displays the page content for the PK Test Settings submenu
function pk_test_setting_page() {
…
}
Practical Exercise (Eclipse)
OK, lets see the code in action.
Copy the Plugin Class Template to a New Folder
Once again I’ll be using PDT Eclipse as my code editor in this exercise.
First we need to create a class for this plugin, so copy the pk-plugin-class template we created previously to a new folder in the wp-content\plugins folder and give it the name pk-admin-menu-0v3.
Now we need to rename the PHP file so open our new plugin folder and rename the pk-plugin-class.php file to pk-admin-menu-0v3.php. Remember the plugin file name has to be the same name as the folder with the PHP extension. Then open the file ready for editing.
Enter a New Plugin Name and Description
The first thing we need to do with our new plugin is enter a new plugin name and description. so that WordPress with recognize the plugin. Enter a new version number as well.
- Plugin Name: PK Admin Menu 0v3.
- Description: PK Admin Menu Demo 0v3. Text to Hyperlink with Database demonstration.
- Version: 0.3
Enter New Class Name
We now need to create a more appropriate class name which will be: pk_admin_menu_0v3. This is simply a case of renaming all the occurrences of the pk_plugin_template_class to pk_admin_menu_0v3. There are six changes to be made.
Enter New Instance Name
Now that we have our plugin class we need an instance of that class. So change the template instance $pk_plugin_demo to a more appropriate name, $pk_admin_menu_0v3_demo
Enter Class Variables
Now we are ready to enter our code. Begin by entering the local class variables just after the placeholder comment: // TODO: Variable declarations go here.
Enter Hooks
Next, we need to hook our functions into WordPress in two places. One hook for the Text to Hyperlink function and one hook for the Menu System. Enter both hooks, just after the placeholder comment, // TODO: Enter Plugin Actions and Filters here
Enter the Text to Hyperlink function
Now enter the Text to Hyperlink function, pk_text_to_hyperlink() just after the placeholder comment, // TODO: Enter Action and Filter Methods here.
Next, enter the pk_add_pages() function, directly after the pk_text_to_hyperlink() function.
Finally, enter the pk_test_setting_page() function directly after the pk_add_pages() function.
With the plugin code entered, save the file.
Create uninstall.php File
Create a file called uninstall.php in the same folder as our plugin, that’s the wp-content > plugins > pk-admin-menu-0v3 folder. Open the file for editing and enter the uninstall.php code. Save the file when ready.
With the code entered, lets save the file, and see what happens in WordPress.
Test the Plugin
Login to WordPress as the administrator. and navigate to Dashboard > Plugins > Installed Plugins to check that our plugin has been recognised but is inactive.
Begin by checking the current status of the blog. The ‘WordPress’ keyword should be unchanged at this stage.
Return to the plugins page and activate the plugin. Check the blog page again. This time the WordPress keyword should have been capitalised and changed to a hyperlink.
From the dashboard, select the Settings > PK Test Setting menu link, and change the keyword parameters.
Initially, keep the same keyword, but enter some new replacement text, i.e. (PK WordPress Demo Keyword) and a new hyperlink address, i.e. http://kingsolutions.org.uk/wordpress/.
Save the changes to the database, and check the blog page again. The WordPress keyword has been replaced with the new parameters and clicking the link brings you to the required web page.
Cleanup
Request WordPress to deactivate the plugin. Go to the blog page and check the plugin has been deactivated.
Request WordPress to delete the plugin. Check the record has been removed from the database (see video).
Conclusion – Summary
Hopefully this tutorial gave you a good insight into how simple an administration menu, options page, database interaction and cleanup can be.
Well, that’s all for this tutorial, see you in the next lesson.
Links Used in This Lesson
http://codex.WordPress.org/Function_Reference/add_option
http://codex.WordPress.org/Function_Reference/update_option
http://codex.WordPress.org/Function_Reference/get_option
http://codex.WordPress.org/Function_Reference/delete_option
http://codex.WordPress.org/Function_Reference/register_uninstall_hook
Lesson Code – Text to Hyperlink Filter
<?php
/*
Plugin Name: PK Admin Menu 0v3
Plugin URI: http://kingsolutions.org.uk/wordpress/wordpress/how-to-write-a-wp-plugin/
Description: PK Admin Menu Demo 0v3. Text to Hyperlink with Database demonstration.
Version: 0.3
Author: Philip King
Author URI: http://kingsolutions.org.uk/wordpress/
Licence: Licence GPL2
*/
/* Copyright 2011 Philip King (contact: http://kingsolutions.org.uk/wordpress/)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
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
*/
/**
* The Plugin Class
*/
if (!class_exists("pk_admin_menu_0v3")) {
class pk_admin_menu_0v3 {
// TODO: Variable declarations go here
var $pk_admin_options_name = 'pk_admin_options_data';
var $hidden_field_name = 'pk_submit_hidden';
// Assign default option values
var $admin_options_array = array(
'pk_search_text' => 'WordPress',
'pk_replace_text' => 'WORDXXXSS',
'pk_url_text' => 'http://wordpress.org');
// TODO: Constructor
function __construct() {
// TODO: Enter Plugin Actions and Filters here
add_filter('the_content', array($this,'pk_text_to_hyperlink'),1);
add_action('admin_menu', array($this, 'pk_add_pages'));
} // End constructor
// Core functions go here
// TODO: Enter Action and Filter Methods here
// Change text to hyperlink
function pk_text_to_hyperlink( $content )
{
// Get options from database
$pk_options = get_option($this->pk_admin_options_name);
// If we have options then update the array
if (!empty($pk_options)) {
foreach ($pk_options as $key => $option) {
$this->admin_options_array[$key] = $option;
}
} else {
// Nothing in the database so update with defaults
update_option( $this->pk_admin_options_name, $this->admin_options_array );
}
$url = $this->admin_options_array['pk_url_text'];
$replace = $this->admin_options_array['pk_replace_text'];
$search = $this->admin_options_array['pk_search_text'];
$replace_text = "<a href=' $url '> $replace</a>";
$content = str_ireplace($search, $replace_text, $content);
return $content;
} // End function pk_text_to_hyperlink
// action function for the add_action/admin_menu hook
function pk_add_pages() {
// Add a new submenu under Settings:
add_options_page('PK Test Settings', 'PK Test Settings', 'manage_options', 'testsettings', array($this, 'pk_test_setting_page'));
}
// pk_test_setting_page() displays the page content for the PK Test Settings submenu
function pk_test_setting_page() {
// MUST: Check the user has the required capability
if (!current_user_can('manage_options')) {
wp_die('You do not have sufficient permissions to access this page.' );
}
// Read existing option values from database
$tmp_options = get_option($this->pk_admin_options_name);
if ( !empty ( $tmp_options )) {
// Update default values with database values
foreach( $tmp_options as $key => $option ) {
$this->admin_options_array[$key] = $option;
}
}
// See if the user has posted information
// If they did, the hidden field will be set to 'Y'
if( isset($_POST[ $this->hidden_field_name ]) && $_POST[ $this->hidden_field_name ] == 'Y' ) {
// Read their posted value
foreach( $this->admin_options_array as $key => $option ){
$this->admin_options_array[$key] = $_POST[ $key ];
}
}
// Update the database
update_option($this->pk_admin_options_name, $this->admin_options_array);
// Put an settings updated message on the screen
?>
<div class="updated">
<p><strong><?php echo 'settings saved.'; ?></strong></p>
</div>
<?php
// Now display the settings editing screen
?>
<div class="wrap">
<h2>Menu Test - pk-admin-menu-0v3</h2>
<h2>with Database interation...</h2>
<form name="form1" method="post" action="">
<input type="hidden" name="<?php echo $this->hidden_field_name; ?>" value="Y">
<p>Search Text : <input type="text"
name='pk_search_text'
value="<?php echo $this->admin_options_array['pk_search_text']; ?>" size="30"></p>
<p>Replace Text : <input type="text"
name='pk_replace_text'
value="<?php echo $this->admin_options_array['pk_replace_text']; ?>" size="30"></p>
<p>Full URL : <input type="text"
name='pk_url_text'
value="<?php echo $this->admin_options_array['pk_url_text']; ?>" size="100"></p>
<hr />
<p class="submit"><input type="submit" name="Submit"
class="button-primary"
value="<?php esc_attr_e('Save Changes') ?>;" /></p>
</form>
</div>
<?php
} // End: function pk_test_setting_page()
// TODO: Enter Helper Methods here
} // End pk_admin_menu_0v3
} // End if (!class_exists("pk_admin_menu_0v3"))
/**
* Instantiate (create an instance of) the class
*/
if (class_exists("pk_admin_menu_0v3")) {
// TODO: Enter New Instance Name
$pk_admin_menu_0v3_demo = new pk_admin_menu_0v3();
} // End instantiate class
?>
Lesson Code – Uninstall.php
<?php
/**
* @author Philip King
* @url http://kingsolutions.org.uk/wordpress/
*
* The pk-admin-menu-0v3 Uninstall script.
*/
if( defined( 'ABSPATH') && defined('WP_UNINSTALL_PLUGIN') ) {
$pk_admin_options_name = 'pk_admin_options_data';
//Remove the plugin's settings
delete_option($pk_admin_options_name);
}
?>



