Monthly Archives: October 2014

Create a Dropdown of Product Categories in Woocommerce

A recent project demanded that I create a drop-down list of Woocommerce product categories for an admin page in a plugin I was creating. Here is the PHP and HTML code that accomplished the task:

<form method="post" action="">
<?php $args1 = array('taxonomy'  => 'product_cat'); ?>
  <?php wp_dropdown_categories( $args1 ); ?>
<input type="submit" name="cat_sel" value="SELECT PRODUCT CATEGORY" />
</form><hr />

Retrieve Selected Category in Form Processing Script

Now to retrieve the value, you will use the post variable named cat like so:

$chosen_cat = $_POST['cat'];

...and that will return a product ID. If you need a product name, here is cool PHP function I found that returns the post name/slug when feeding the function the ID we just stored in $chosen_cat above:

function get_product_category_by_id( $category_id ) {
    $term = get_term_by( 'id', $category_id, 'product_cat', 'ARRAY_A' );
    return $term['name'];
}
$product_category = get_product_category_by_id( $your_category_id );

 

How to Submit a Plugin Form to Another Page

In WordPress plugin development, the question often arises of how to properly submit a form to another page in your plugin directory. Say for example you are creating a plugin called Admin Notes that allows you to leave notes in the wp-admin dashboard. In this plugin you have a main directory folder named "jafty-admin-notes" that contains the jafty-admin-notes.php file, a sub-directory named "pics" and a sub-directory named "inc". Inside "inc" you have a file named "form.php" that has the form which submits to another page in "inc" named "form-processor.php". Finally there's an image in "pics" named "trash.gif" Which you can copy from here:

trash can gif image

(The above image is actually 16px by 16px but is enlarged here so you can easily click on it to save it to your desktop)

Here is what your admin notes plugin will look like when finished:

jafty admin notes plugin image

Below is what it looks like when it has submitted to a new page which while it doesn't appear to be in the wp-admin, it does include all the WordPress capabilities so you can use WordPress classes, functions and other WordPress objects in your PHP code. This is the DELETE process in a new page:

delete note image

Both the delete and add new note process are both performed in the same new page in a script named "form-processor.php" inside the inc folder as explained above.

THE CODE:

First, lets look at the main plugin file which is jafty-admin-notes/jafty-admin-notes.php. Here's the code:

<?php
/**
 * Plugin Name: Jafty Admin Notes
 * Plugin URI: http://jafty.com/blog/how-to-submit-a-plugin-form-to-another-page/
 * Description: A Plugin created for leaving admin notes inside of the wp-admin dashboard. Email Ian L. of Jafty.com for more info at: linian11@yahoo.com
 * Version: 1.00
 * Author: Ian L. of Jafty.com
 * Author URI: http://jafty.com
 * License: GPL2
 * Created on: 10-26-2014
 * Updated on: 10-26-2014
 */
 
function install_tbl () {
global $wpdb;
    $table_name = $wpdb->prefix . 'notes';

$sql = "CREATE TABLE $table_name (
  id int(9) NOT NULL AUTO_INCREMENT,
  time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
  content varchar(999) DEFAULT NULL,
  UNIQUE KEY id (id))";

    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    dbDelta( $sql );

require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );

//Now add some data to the table:
$field_content = 'this is a test note';

$wpdb->insert(
    $table_name,
    array(
        'time' => current_time('mysql'),
        'content' => $field_content,
    )
);

}//end install_tbl function

//call install_tbl function when plugin is activated by admin:
register_activation_hook( __FILE__, 'install_tbl' );

function pluginUninstall() {

        global $wpdb;
        $table = $wpdb->prefix."notes";

        //Delete any options thats stored also?
    //delete_option('wp_yourplugin_version');

    $wpdb->query("DROP TABLE IF EXISTS $table");
}//end pluginUninstall function

//hook into WordPress when its being deactivated:
register_deactivation_hook( __FILE__, 'pluginUninstall' );

//Add admin menu item to wp-admin:
add_action('admin_menu','add_notes_menu');

function add_notes_menu(){
add_menu_page('Jafty Admin Notes', 'Jafty Admin Notes', 'manage_options', 'jafty_admin_notes', 'create_admin_notes_pg','',4);
//add_submenu_page('jafty_super_importer','Notes', 'Notes','manage_options', 'manage_notes_slug', 'create_notes_pg');
}//end add_notes_menu function.

function create_admin_notes_pg(){
include "../wp-content/plugins/jafty-admin-notes/inc/form.php";
}//end create_admin_notes_pg function

//allow form.php to submit to different php script:
add_action('admin_post_submit-form', '_handle_form_action'); // If the user is logged in
add_action('admin_post_nopriv_submit-form', '_handle_form_action'); // If the user in not logged in
function _handle_form_action(){

include 'inc/form-processor.php';

}
?>

And here is the jafty-admin-notes/inc/form.php script:

<h1>Jafty Admin Notes</h1>
<p>A plugin created by Ian L. of <a href="http://jafty.com">Jafty.com</a> that allows wp-admin dashboard users to leave notes in the administration area of WordPress</p>
<form action="<?php echo get_admin_url();?>admin-post.php" method='post'>
<input type='hidden' name='action' value='submit-form' />
Note:<br />
<textarea name="note"></textarea>
<input type="submit" name="sbmt" value="Save Note" />
</form>
<hr />
<h2>Saved Notes:</h2>
<?php
global $wpdb;
$table_name = $wpdb->prefix."notes";
$myquery =     "SELECT * FROM $table_name";

$allnotes = $wpdb->get_results($myquery);

$i=1;
foreach($allnotes as $cur_note) {
$cid = $cur_note->id;
$ctime = $cur_note->time;
$cnote = $cur_note->content;
?>
<form style="display:inline;position:relative" action="<?php echo get_admin_url();?>admin-post.php" method='post'>
<input type='hidden' name='action' value='submit-form' />
<input type='hidden' name='del_id' value='<?php echo $cid; ?>' />
<input style="position:relative;top:6px" type='image' src='../wp-content/plugins/jafty-admin-notes/pics/trash.gif' />
</form>
<?php
echo "$i)$ctime - $cnote<hr />";
$i++;
}//end foreach note.
?>

And finally, the jafty-admin-notes/inc/form-processor.php script:

<?php
//form-processor.php
global $wpdb;
$table_name = $wpdb->prefix."notes";

if(isset($_POST['del_id'])){//if it is a delete request:
$did = $_POST['del_id'];
echo "Note ID# $did is being deleted.<br />";
$wpdb->delete($table_name, array('id' => $did));
?>
<hr />
You are now being redirected to the admin notes page...
<script>
window.location.href="http://jafty.com/blog/wp-admin/admin.php?page=jafty_admin_notes";
</script>
<?php
}else{//else, must be new note:
$note = $_POST['note'];

$wpdb->insert(
    $table_name,
    array(
        'time' => current_time('mysql'),
        'content' => $note,
    )
);

echo "The following NOTE has been entered into the wp_notes table:<br>$note<br>";
?>
<hr />
You are now being redirected to the admin notes page...
<script>
window.location.href="http://jafty.com/blog/wp-admin/admin.php?page=jafty_admin_notes";
</script>
<?php
}//end else must be new note
?>

Summary

I know I did not include much explanation above, but I hope to add more later as I am out of time. The code does work and was well tested, so it should speak for itself. Study the code and learn to implement your own plugin that submits to another page. The key is in the first script above, so pay attention to the last half a dozen or so lines of code. That is the key part in making the submit to page functionality work.

How to Get WordPress DataBase Name with PHP

To get your WordPress database name with PHP inside a WordPress plugin or theme file, simply use this simple PHP code:

<?php
//Get the db name using $wpdb:
global $wpdb;
$deename = $wpdb->dbname;
echo "Your Database: $deename<br />";
?>

The first line, global $wpdb initiates the wpdb class in WordPress which has a lot of handy MYSQL database functions within WordPress. Learn more about wpdb HERE.

How to Run Large or Long Running PHP Scripts

Many times, problems arise while trying to run PHP scripts that take to long to run, take up to much memory or both. There is always a solution of course. If you are lucky, your solution will be one of the easy ones given here. Otherwise, you are in for a hard time and a little more work than you prefer, I'm sure.

If you are lucky, these two magic lines of PHP code added to the top of your PHP script will work:

//increase max execution time of this script to 150 min:
ini_set('max_execution_time', 9000);
//increase Allowed Memory Size of this script:
ini_set('memory_limit','960M');

...if not, you are pretty much screwed. Sorry. But here are some possible solutions.

Change the php.ini settings to allow more execution time and memory

This method is as simple as locating your server's php.ini file and finding all settings that mention execution time and memory limit and increasing the numbers or setting them to -1(unlimited). The problem with this is that many of you are probably on a Godaddy, Hostgator or similar shared server that doesn't give you access to these settings. If you are lucky enough to have a dedicated server that gives access to php.ini, then this may be the ultimate solution for you however and it also eliminates the need to put the above mentioned PHP code in the top of all of your PHP scripts.

Change the way your PHP Code Functions

In theory this sounds easy enough. Not always in practice however. It has saved my ass before when none of the above methods would work. Usually what makes a PHP script run too long or use too much memory is some type of PHP loop. To make that long-running script run without running out of memory or time, you have to periodically cause the script to write the output to the page to prolong execution time.

Another example of changing your code is to make changes that allow your code to run faster and hopefully fall short of the max execution time. One such method for speeding up PHP loops is to use ob_start() at the beginning of your code. ob_start() gives you a 5-15% boost in speed with little effort on your part.

Update: I actually did a benchmark test on the above ob_start() method after writing this. I was pleasantly surprised to discover that it increased my script's speed by the max suggested, 15%. I had a loop that did a lot of different things with domain names and without ob_start() at the start of the script it always returned right around 30 results. After adding ob_start() and nothing else to that script it was getting 45 results instead of 30 which is on the top end of what I read was to be expected.

Fix PHP Loops that Timeout Before Finishing

To fix a for or while loop that won't complete before it times out, try this secret I discovered.

Add this code right after starting the loop:

ob_start();

...and this code right before ending the loop:

echo ob_get_contents();
ob_end_flush();

Example:

foreach($xlsx->rows() as $k => $r) {
ob_start();
//whatever long running code here....

echo ob_get_contents();
ob_end_flush();
}//end foreach loop.

That is what saved my ass when I couldn't figure out how to get a for loop to work that kept timing out after 20 seconds while building a WordPress plugin with PHP.

I don't have time to put all the answers for optimizing PHP code for speed and memory here, but here is a link that provides much more information:

http://phplens.com/lens/php-book/optimizing-debugging-php.php

...and learn more about ob_start() here:

http://php.net/manual/en/function.ob-start.php

 

 

adminotes

WordPress Plugin Development – Part 2 Admin Menu

Here we will cover how to add menu items and admin pages to the WordPress admin area or the wp-admin dashboard.  This will be the first lesson in the crash course on WordPress development series where you will actually be creating a full working WordPress plugin!

Prerequisites

I explain a plugin's file structure and how to start your first plugin file in PHP in the primer for this series. Click the following link to read the primer for this tutorial:

Crash Course on WordPress Plugin Development

Other requirements are the same for the entire series of WordPress plugin tutorials and include:

  • Knowledge of PHP
  • Experience in HTML and HTML5
  • Knowledge of JavaScript
  • CSS experience
  • WordPress experience
  • Knowledge of MySQL database

Create a Plugin that adds an Admin Menu to the WordPress Dashboard

Starting with the PHP file template we made in our primer the plugin file that creates an admin menu and page for your WordPress dashboard will look like:

<?php
/**
 * Plugin Name: Jafty Part Two
 * Plugin URI: http://jafty.com/blog/crash-course-on-wordpress-plugin-development/
 * Description: A Plugin that adds a menu item and admin page to the wp-admin dashboard.
 * Version: 1.0
 * Author: Ian L. of Jafty.com
 * Author URI: http://jafty.com
 * License: GPL2
 */
 

//part two, add admin menu:
add_action('admin_menu','add_notes_menu');

function add_notes_menu(){
add_menu_page('Admin Notes', 'Admin Notes', 'manage_options', 'admin_notes', 'create_notes_pg','',3);
//add_submenu_page('admin_notes','Credits', 'Credits','manage_options', 'manage_notes_slug', 'create_credits_pg');
}//end add_notes_menu function.

function create_notes_pg(){
include "../wp-content/plugins/jafty-plugin/inc/admin_notes.php";
}//end create_notes_pg function
?>

Admin Page PHP File

Next we need to create the admin page. To accomplish this I like to create a new folder inside my plugin folder named "inc". Then create a file appropriately named after the admin page in question such as admin_notes.php. For demonstration purposes, the below HTML will be the temporary contents of your inc/admin_notes.php file. You can add your own PHP, CSS and/or JavaScript code as needed.

<h1>Add/Edit/Delete Admin Notes</h1>

You can put whatever HTML, CSS, JavaScript and PHP code you desire here by editing the jafty-plugni/inc/admin_notes.php file....

Code Explained

Okay, some of the above code(not the HTML we hope) is a little confusing if you are not familiar with the WordPress function used, especially the add_menu_page and add_submenu_page function. They do what they suggest. add_menu_page adds an admin page and a top level menu item to the admin dashboard's main left navigation menu. The add_submenu_page function, that we currently have commented out, would be used to add a submenu item to the admin navigation menu as well as another admin page. The submenu would appear under the main menu item set in the function's parameters. I'll go on to explain the add_menu_page function in detail below to help you better understand both.

WordPress add_menu_page Function

add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position );

As demonstrated above, the add_menu_page function takes up to 7 parameters:

  • page_title - this is what will show up inside the title HTML tag of the page and therefore shows up on the browser tab when the page is opened.
  • menu_title - this is the menu text that shows up in the main admin dashboard's navigation menu.
  • capability - is the user capability a user must have in order to view the admin page you are adding.(no longer use user levels here as this has been depreciated)
  • menu_slug - is the text that shows up in the URL when viewing your new admin page. (optionally you can use the PHP file name of the menu page here and not use the next function parameter to create the page. We do not use this method here though)
  • function - is where you name the PHP function that creates the admin page.(technically this is optional, but this is a much needed option for the method we use for creating admin pages and menus. If you do not include this, you do not use a function to create the page, but include the file name of the menu page in the previous menu_slug parameter instead)
  • icon_url - is an optional parameter that can be used to name an image file for the icon used in the navigation menu for this item. In our example above, we left this blank, but if you want to use the next parameter, as we have, you must put at least an empty quotation here to mark it's place. When not used, the standard gear icon is used as the icon for the menu item.
  • position - is an optional parameter used to define the position in the admin menu that you want your new menu item to appear. We used 3 here because that is the magic number that allows the menu item to appear directly after the "dashboard" menu item which is where I like to include more important menu items so they are easy to find. you can use a higher number here to make the menu item appear further down in the navigation menu.

Put it all together:

To put this all together into a working plugin, you could follow these simple steps:

  1. create a folder on your desktop named "Jafty_plugin_two", the name of this plugin.
  2. name your main plugin PHP file(the first one we made above) "jafty-plugin-2.php" and place it insde of the Jafty_plugin_two folder.
  3. Create a folder named "inc" inside of the main plugin folder, Jafty_plugin_two.
  4. Name the last file we created, that has only the HTML for the new admin page, "admin_notes.php" and place it inside of the "inc" folder.
  5. Finally upload the Jafty_plugin_two folder to your plugins directory and go to your dashboard's plugin tab and activate the "Jafty Part Two" plugin and you will see your admin menu item appear. Click on it and you should see something like the main image at the top of this article.

Summary

We demonstrated the code to create a functional plugin that adds a custom admin page and corresponding navigation menu item to the WordPress admin dashboard. Then we went on to explain the main function used to accomplish this. We also added the means in the plugin to expand it to include submenu items under the main menu item we added. We commented out this submenu code until it is needed. If you want to add a submenu item, simply remove the uncomment the line and make the first parameter the same as the fourth parameter in the corresponding add_menu_page function which is the menu slug parameter.

db

WordPress Plugin Development – Part 1 Tables

Welcome to part one of my crash course on WordPress plugin development, how to work with tables. A properly formed WordPress plugin will often not only store information in one or more database tables, but it will also do something specific with that data on deactivation of the plugin.

Prerequisites:

Since this is the first lesson in my Crash Course on WordPress Plugin Development, the only additional reading in this course would be the primer of the series where I demonstrate how to initiate a plugin. In the primer, I explain a plugin's file structure and how to start your first plugin file in PHP. Click the following link to read the primer for this tutorial:

Crash Course on WordPress Plugin Development

Other requirements are the same for the entire series of WordPress plugin tutorials and include:

  • Knowledge of PHP
  • Experience in HTML and HTML5
  • Knowledge of JavaScript
  • CSS experience
  • WordPress experience
  • Knowledge of MySQL database

Planning your plugin data needs

The first thing to do when planning out your plugins database is to plan out your data needs for both activation and deactivation. On activation, a plugin will usually create one or more tables to store data for the plugin such as plugin settings and user data. Then some plugins will also store some data in one or more of the tables it has created such as default settings or test content.

On deactivating a plugin you need to consider the best ways to handle the data. For example, a lot of the time, plugin developers opt to leave tables in place in case the user reactivates the plugin. That is usually a good idea since developers will often deactivate and reactivate plugins while testing and debugging a WordPress site. Imagine a plugin that stores user information such as a guest book plugin. The user has stored many entries in their guest book that is dependent on a table created by a plugin. If the plugin is deactivated and reactivated and the plugin is programmed to delete the table, the user will loose all their entries and be quite upset no doubt. So as you can see, it is important to consider how a plugin will be handled in real-life when considering your deactivation functions. However,  there are some cases where a plugin developer may wish to delete some tables when the plugin is deactivated. If a tables doesn't contain irreplaceable data, then it may be best to delete it, especially if it can very easily be replace when reactivating the plugin. Another option is to give the plugin user the option to either delete or save the database tables on deactivation. In this tutorial we will cover both how to create and delete tables within a plugin using the proper WordPress hooks.

Enough gibber jabber, Here is the PHP code to make a complete working example of a simple plugin that creates a table on activation, adds a row of data and then deletes the table on deactivation of the plugin. Remember, if you want to leave the table on deactivation so when a user reactivates the plugin, the retain their data, skip the code to delete the table. I included it here as an option, not a requirement for your plugin.

<?php
/**
 * Plugin Name: Jafty Plugin
 * Plugin URI: http://jafty.com/blog/crash-course-on-wordpress-plugin-development/
 * Description: A brief description of how to create a Plugin.
 * Version: 1.0
 * Author: Ian L. of Jafty.com
 * Author URI: http://jafty.com
 * License: GPL2
 */
 
 
 
function install_tbl () {
global $wpdb;
    $table_name = $wpdb->prefix . 'jafty_plugin';

$sql = "CREATE TABLE $table_name (
  id int(9) NOT NULL AUTO_INCREMENT,
  time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
  field varchar(25) DEFAULT NULL,
  content varchar(999) DEFAULT NULL,
  UNIQUE KEY id (id)
)";

    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    dbDelta( $sql );

require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );

//Now add some data to the table:
$field_name = 'item';
$field_content = 'this is the item description';

$wpdb->insert(
    $table_name,
    array(
        'time' => current_time('mysql'),
        'field' => $field_name,
        'content' => $field_content,
    )
);

}//end install_tbl function

//call install_tbl function when plugin is activated by admin:
register_activation_hook( __FILE__, 'install_tbl' );

function pluginUninstall() {

        global $wpdb;
        $table = $wpdb->prefix."jafty_plugin";

        //Delete any options thats stored also?
    //delete_option('wp_yourplugin_version');

    $wpdb->query("DROP TABLE IF EXISTS $table");
}//end pluginUninstall function

//hook into WordPress when its being deactivated:
register_deactivation_hook( __FILE__, 'pluginUninstall' );
?>

Code Explained

The above code is fairly simple. It consists of two functions followed by two hooks to hook into WordPress at activation and deactivation time. You will want to make some adjustments to the code to meet your own plugin requirements. The sql variable can be edited by changing the field names of id, time, field and content to the field names you need and edit the rest of the sql statement accordingly. If you have any experience with MySQL, this will come easy for you. If you don't, you can find the official MySQL documentation page at http://dev.mysql.com/doc/

Crash Course on WordPress Plugin Development

Ever wanted to learn how to make a WordPress plugin quickly? Then this crash course on WordPress plugin development should be what you are looking for. In this article, I will demonstrate how to make a simple WordPress plugin in less than 30 minutes.

Plugin Files

First you need to organize your plugin's file structure. A WordPress plugin can either be one single PHP file or many types of files in one directory, but if many, it must still include the main PHP file that defines the plugin. For our first, simple WordPress plugin, we will make a single PHP file plugin to keep it simple.

your_plugin.php

For this simple plugin, we will name Your Plugin and the PHP file named in traditional plugin format, will be your_plugin.php just for this tutorial. If you were creating an actual plugin that you were going to market, then you would want to check to be sure you have a unique name, but worry about that after you learn the basics;-) Here is the basic content that every plugin's main .php file should start with:

<?php
/**
 * Plugin Name: Jafty Plugin
 * Plugin URI: http://jafty.com/blog/crash-course-on-wordpress-plugin-development/
 * Description: A brief description of how to create a Plugin.
 * Version: 1.0
 * Author: Ian L. of Jafty.com
 * Author URI: http://jafty.com
 * License: GPL2
 */
 ?>

Make sure above file is saved using UTF-8 encoding.

To continue from here and create a plugin that actually does something, follow the below link and finish up a simple plugin:

WordPress Plugin Development – Part 1 Tables