How to create a custom WordPress plugin from scratch


During the past week I was thinking about a new tutorial on how to create a custom WordPress plugin from scratch. The task is not that hard to be done, especially when you have a good idea how WordPress works and what is its files structure.

The following will be a detailed tutorial for custom WordPress plugin creation. I will provide step by step instructions on how to start developing a simple plugin. For better understanding I will add a little piece of code that will query the database and generate backups.

Custom wordpress plugin installation

Let’s start from the point that you have default WordPress installation. What you have to is login to its admin panel and navigate to plugins page. If no new plugin are installed so  far you would see the following on your screen:

WordPress plugins page

WordPress plugins page

These are the plugins that come by default. At this point you are on plugins page and this is the place where our plugin will appear soon. Here is what to do next:

Using FTP client you should access the root folder of your WordPress instance and then open wp-content folder. Inside it you will see plugins folder, open it and create new one named dbmechanic. The name can be of course changed. If you refresh plugin page you will see no change. This is because we create the folder of our plugin, but there is no code to trigger WordPress hooks.

Custom plugin development

As a next step, we have to create a new file that will contain the code of our future plugin. The file name could be dbmechanic.php.

Again WordPress plugin page does not show any signs about a new plugin because we have a folder and main file, but there is no code. So now we have to open dbmechanic.php and add the following header to it:

<?php
/*
Plugin Name: Simple database mechanic
Plugin URI: http://wppotion.com/
Description: A simple database mechanic plugin
Version: 1.0
Author: Leonid G.
Author URI: http://wppotion.com/
License: GPL
*/
?>

 

Now go back to plugins page and refresh it. If everything is fine, you will see our custom plugin in the list.

Custom WordPress plugin

Custom WordPress plugin

As you can see the information from the headers corresponds correctly with WordPress hooks and the name, version, URI and author are displayed as expected on the page.

We have now the basic file and we can proceed and add some options to it. As adding the code piece by piece may break it and generate fatal errors I will paste the entire code and then explain the lines:

<?php
/*
Plugin Name: Simple database mechanic
Plugin URI: http:// wppotion.com/
Description: A simple database mechanic plugin
Version: 1.0
Author: Leonid G.
Author URI: http://wppotion.com/
License: GPL
*/
add_action('admin_menu', 'dbmechanic_admin_actions');
/*
Here we use admin_menu hook and a functions that contains instructions to add a submenu to the general Settings page
*/
function dbmechanic_admin_actions()
{
add_options_page('DBmechanic', 'DB-mechanic', 'manage_options','__FILE__', 'mechanic_admin');
}
/*
As you can see add_options_page takes 5 arguments which define the title of the page, the name of the submenu, 'manage_options' defines who can control the submenu, the next one is the menu slug, mechanic_admin is the function that will display the plugin page.
*/
function mechanic_admin ()
{
/*
Now we will develop the function itself. As you can see there is no closing tag, because we will put some PHP and HTML inside it and the closing tag will be placed in the end.
*/
?>
<!--
Here we close PHP Tag, because what comes next is pure HTML code which should not be messed up with PHP
-->
<div class="wrap">
<h4> Database details: </h4>
<?php
echo "Database ";
echo "&nbsp; &nbsp; &nbsp;".DB_NAME;
echo "<br />";
echo "Mysql user ";
echo "&nbsp;".DB_USER;
echo "<br />";
echo "Password";
echo "&nbsp; &nbsp; &nbsp;".DB_PASSWORD;
echo "<br />";
echo "Hostname";
echo "&nbsp; &nbsp; &nbsp;".DB_HOST;
?>
<!--
Using a little PHP snippet we extract WordPress Mysql details. We do this just to show how the code interacts with wpdb object.
-->
<hr />
<form action="" method="POST" >
<input type="submit" name="database_check" value="Database Check" class="button-primary" />
</form>
<!--
This is form button that works using POST. We also use class that is defined by WordPress as button-primary
-->
<?php
global $wpdb;
if(isset($_POST['database_check']))
{
$AllRecordsCheck = $wpdb->query(
"
SELECT *
FROM $wpdb->options;
"
);
echo "<hr />";
echo 'All records in options table - '.$wpdb->num_rows ;
echo "<hr />";
/*
This code queries wpdb object and extracts and counts the number of rows in options table
*/
$TrRecordsCheck = $wpdb->query(
"
SELECT *
FROM $wpdb->options
WHERE option_name LIKE '\_transient\_feed\_%'
OR option_name LIKE '\_transient\_timeout\_feed\_%'
OR option_name LIKE '\_site\_transient\_timeout\_browser\_%'
OR option_name LIKE '\_transient\_dash\_%'
OR option_name LIKE '\_site\_transient\_browser\_%'
"
);
echo 'Transient rows ( not needed ) - '.$wpdb->num_rows;
/*
Here we extract the rows that contains transient or its variations in the names
*/
echo "<hr />";
$reduction = ($TrRecordsCheck / $AllRecordsCheck )*100;
$rounded = round($reduction, 2);
echo "Possible reduction - approximately <b>$rounded %</b>";
}
/*
Here we calculate the possible reduction and print the percentage.
*/
echo "<hr />";
?>
<form action="" method="POST" >
<input type="submit" name="database_backup" value="Database Backup" class="button-primary" />
</form>
<?php
$dir = plugin_dir_path( __FILE__ );
$url = plugin_dir_url( __FILE__ );
if(isset($_POST['database_backup']))
{
$backupFile = "$dir/backup_db/".DB_NAME."-".date("Y-m-d-H-i-s").".sql.gz";
$exp = "mysqldump --opt -u ".DB_USER." -p'".DB_PASSWORD."' -h ".DB_HOST."  ".DB_NAME." | gzip -9 -c > $backupFile";
system($exp);
echo " </br >Backup generated</br >";
echo "</br >Phisical location of the file <b>$backupFile</b></br >";
}
?>
<!--
This portion here generates a backup button and give instructions on how and where the backup to be generated and kept.
-->
<hr />
<form action="" method="POST" >
<input type="submit" name="database_optimize" value="Database Optimize" class="button-primary" />
</form>
<?php
if(isset($_POST['database_optimize']))
{
$TrRecordsDrop = $wpdb->query(
"
DELETE
FROM $wpdb->options
WHERE option_name LIKE '_transient_feed_%'
OR option_name LIKE '\_transient\_timeout\_feed\_%'
OR option_name LIKE '\_site\_transient\_timeout\_browser\_%'
OR option_name LIKE '\_transient\_dash\_%'
OR option_name LIKE '\_site\_transient\_browser\_%'
"
);
echo "<br />Optimization - done<br />";
}
?>
<!--
Here we perform the optimization itself
-->
<hr />
<form action="" method="POST" >
<input type="submit" name="database_manage" value="Manage Backups" class="button-primary" />
</form>
<?php
if(isset($_POST['database_manage']))
{
?>
<table class="widefat">
<thead>
<tr>
<th>List of the available backups</th>
</tr>
</thead>
<tfoot>
<tr>
<th>
<?php
echo "
<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js\"></script>
<script type=\"text/javascript\">
function deleteBackup(backupfile){
$.get( \"".$url."delete.php?delete=\"+backupfile, function( data ) {
//    $( \".result\" ).html( data );
var removedDiv = document.getElementById(backupfile);
removedDiv.parentNode.removeChild(removedDiv);
});
}
</script>
";
$path = "$dir/backup_db";
$dh = opendir($path);
$i=1;
while (($file = readdir($dh)) !== false) {
if($file != "." && $file != "..") {
echo "<div id='$file'>$i. <a href='".$url."backup_db/$file' title='Click to Download'>$file</a> | <a href='#' onclick=\"javascript: deleteBackup('$file')\">Delete Backup</a><br /></div>\n";
$i++;
}
}
closedir($dh);
?>
</th>
</tr>
</tfoot>
<tbody>
</tbody>
<!--
Here we give the option to control the available backups.
-->
<?php
}
?>
<?php
}
?>

Now if everything is fine, you have created your first custom WordPress plugin. Just refresh the plugin page and you will see the following on your screen:

Simple WordPress plugin

Simple WordPress plugin

Summary
Custom wordpress plugin installation and development - how to
Article Name
Custom wordpress plugin installation and development - how to
Description
Custom wordpress plugin installation and development - hooks, functions and comments
Author
Publisher Name
wppotion


Do you want to share your opinion?

Your email address will not be published. Required fields are marked *


*

We are not industry specific. We are WordPress specific. We work with everyone to help them find solutions with their troubles.
If you show us the problem you are experiencing, we will show you how to fix it. It is that simple.


Reported WordPress issues

  1. Wordpress.org doesn't send me the email with the password for the wp.org account
  2. how to create custom advanced search in wordpress
  3. WordPress: Placing a function underneath the title instead of above it
  4. Is There A Way To Stop Other WP Plugins Features Being Available On My Wordpress Plugins Pages?
  5. wpdb Cannot Update column in Database
  6. Homepage redirects to /wordpress
  7. How to can implement bootstrap widget code for custom header in WordPress?
  8. Tracking Wordpress Ninja Forms Form with Google Tag Manager
  9. Not able to retrieve the exact queried response using Alamofire
  10. Show item from a array only to admins

WordPress problems we are working on

  1. LIST of phrases AFTER a parameter from URL in wordpress
  2. How to display a value from a radio button in the options menu in wordpress
  3. How to specify a cache validator for PNG and JS files in .htaccess?
  4. Changing font size within declaration
  5. Is there anyway to use colspan on the do_settings_fields in WordPress
  6. API Call doesn't echo items
  7. PHP Warning: A non-numeric value encountered in /home/bradlux/public_html/wp-content/plugins/wp-automatic/core.php on line 3797 [on hold]
  8. Bypass cannot redeclare function (including Wordpress in Osclass)
  9. ACF get data for all posts
  10. TinyMCE Paste as text but keep spaces

Resolved issues

  1. I can't get my WordPress site load speed any faster
  2. Error establishing a database connection in my localhost
  3. Redirect loop in wordpress behind Azure Application Gateway
  4. How to attach custom taxonomy to a post in Wordpress?
  5. Php Script For Data Retrieval Giving Same Results On Server
  6. Connection between custom database and wordpress database
  7. Xpath expression: How can I get all XML elements that have a child node with a specific value?
  8. Avada Custom Element Creation
  9. Error message reads timber not activated or scheduled maintenance
  10. Tooltip with title and featured image Wordpress function
wppotion - powered by persistence and passion