In this second part of our tutorial series “Simple WordPress Advertising Plugin” we will learn how to display our ads, add additional information and even schedule the ending of our ads. We will also use some simple caching so that our ads are retrieved much faster.
This tutorial is a part of a tutorial series “Simple WordPress Advertising Plugin“. The series consists of several tutorials which are:
- The Introduction – Create the base of the plugin, create Ads in the admin area and more
- Displaying Ads – Displaying Ads on the front page, caching them on a daily basis and more
- Tracking Ads – tracking Ad impressions and clicks, calculating CTR (click-through-rate)
- Widget and Shortcode – creating a simple widget and a shortcode to display the Ads in sidebar or content
This will be a little longer that the last tutorial so be ready for some great learning. We will start by editing our main class.
If you are eager to read the code rather then reading, then you can download the code here.
Editing the Main Class
We will add some new attributes and methods. Since our main class Simple_WP_Ads is a singleton instance, only one of object will be available and everything in that object can be used through the whole WordPress life cycle when our page loads.
Due to that, we will store ads in that class so that we can easily display them on the top and on the bottom of the page. Before we get into displaying them, let’s define our new attributes and methods. We will also need to edit some of the methods previously defined.
At the top of our main class add this:
$ads will store our ads. We have two mutator methods
set_ads. They are used to change the value of our attribute
There is another method
has_ad_position. This method will check our attribute
$ads for the provided position and return
false. We have defined this method because we will have two positions for ads: top and bottom.
We will store our ads in the attribute
$ads based on their positions. So the actual array will have to look something like this:
For our new functionality we will have to create new files. We will just create them for now and populate through this article. In the folder
simple_wp_ads/inc create two new files:
We have to add those dependencies in our method
If you copied the code, you may have notices that we removed the two
add_action hooks. We will still use them, but in another method.
Running Simple WordPress Advertising Plugin
I have called this new method
run becuase everything needed for our plugin will be called here. This method will be used for every possible hook we will have to use.
The first action hook is the one we have defined in the previous article. This hook was placed in our file
inc/swa-cpt.php, so please open that file and remove the hook at the bottom.
The next hook is
swa_ad_ended and this hook will call the function with the same name. This hook is our own hook which we will define in our scheduling part. Inside
is_admin we are adding the action hooks which we have previously removed from the
load_dependencies. We are also hooking our new function
swa_save_ad to the action
This function will do the scheduling part. When we are not in the admin area, we will:
- add our inline style using
- get our ads before even rendering our page using
- add new body classes based on our ads
- render the ads on the bottom of the page using
We have used the
init hook twice but the important difference is the priority. With priority we have defined that we will first get the ads from the cache or database (priority:
20) and only after that we will define our body classes (priority:
We had to do that because we need to be sure we have our attribute
$ads populated before we begin adding new body classes which are based on our ads.
All the functions added to the mentioned hooks will be defined in our new files.
We will schedule our ads using the function
swa_save_ad. Open the file
inc/swa-functions.php and add this:
First, we are checking if we are saving our ad. If not, we are stop processing our scheduling. This may seem a bit complicated but try to stay focused. I am sure you will understand everything.
We are getting the actual timestamp from the date on which our Ad has been published. This will be used so that we can calculate the end timestamp of our Ad.
We are then getting the server time in
$current_time and the WordPress time
$wp_current_time saved in Settings > General. Both are in a timestamp format. These variables will be used if the WordPress time is saved without timezones such as UTC+0, UTC+1 and similar settings.
After that, we are getting the offset which will give us an hourly value such as -1, +2 and similar. After that we are also getting the timezone setting. If there is no timezone, then it means the time and date settings are saved as UTC+0 or similar values.
If that is the case, we need to calculate the difference. Since our server time may be different from the WordPress time, we need to calculate the difference to be accurate when scheduling. If there is a timezone, then we are setting the server time on that timezone so that we are also getting the daylight setting (such can help on summer/winter days when there is a +/- hour transition).
We are then getting the end time of our Ad.
$the_end_time stores the timestamp of our published date. We need to add the duration of our Ad to get the final end time. We are adding the duration by multiplying it with the seconds of 1 day.
If the end time is lower than the current time, it means that we have already pass the ending date and so we will not schedule it.
If we are still to schedule our Ad and our Ad has a status of
ended, we will transition our Ad back to the status
publish. This is done by our custom function
swa_set_status which we will define next.
After that, we are checking if there is a cron job for our Ad. If there is, we are unscheduling it. We need to do that because we do not know if the previous scheduled event for our Ad has the same ending time.
The last step is scheduling the ending of our Ad. When our Ad has ended, the action hook
swa_ad_ended will be called. We have hooked a function
swa_ad_ended to that action in our method
To set different statuses, as we have seen in the previous code, we have to update the database row of our Ad. We will do that by using
$wpdb. Add this code to our file
First we are checking if we are to change the post type passed to that function. If that is true, we are updating the database table
posts where the ID is our passed
$post_id, post type and also the status from which we want to change. If a row has been changed, we are returning
true, instead we will return
Ending the Ad
The last entry in our file
inc/swa-functions.php will be a function that will be triggered when the action hook
swa_ad_ended is called. Add this code:
This is a simple function. We are setting the status of our Ad to
ended and we are also clearing our temporary cache
swa_ads. This cache will be set when we are retrieving Ads.
Ads Metabox Fields
We also need to create some additional information for our Ads. We will have a field for URL where the visitor will get redirected if he/she clicks on the Ad. Another field will also be the position of our Ad. Open the file
inc/swa-metaboxes.php and add this to the bottom:
Now we can get the Ads and display them:)
Getting the Ads
In the action
init we hooked the function
swa_get_ads. Let’s define that function in the file
We are checking if there are Ads cached. If there is no cache, we are getting them from the database. Once we get the Ads, we are creating the array of Ads with the function
swa_create_ads_array. Once we create it, we save the constructed array in the cache.
The constructed array is also set to our main class using the method
Constructing the Ads array
In the previous method we have also mentioned a new function
swa_create_ads_array. Let’s add the next code:
We are first creating an empty array with both
positions. Both of those positions are empty arrays. After that we are going through all our ads which were retrieved from the database.
For each Ad, we are also getting the metadata saved from our metabox. After that, we create a new Ad array to hold the information for that particular Ad. Once we created the array
$new_ad, we push that array to our main Ads array
$ads_array under the position we got from the metadata.
If there are no Ads under both positions, we return false. Otherwise, we return the array.
Displaying the Ads
To display the Ads, we have to set the styles. We will create inline styles so that we save on HTTP requests. Add this to the file
We are first checking if there are any Ads. If there are, only then we will render those styles. You can easily change the styles to your own theme.
As you can see, for our styles and Ads to render correctly, we need to add some body classes. This can be done by using the filter hook
body_class. We have hooked our function
swa_add_body_classes to the action
init. Now, let’s define that function:
In this function we are checking for Ads under a certain position. If there is one, we are hooking our function(s) to that filter.
The last thing we have to do now is to render the Ads. This is done by the function
swa_display_ads which is hooked in
wp_footer. Add this code:
In this function we are getting the Ads which were retrieved from the cache or from the database. If there are any Ads, we are getting Ads for both
bottom. We check if there are Ads in any of those positions and if there are, then we get only one Ad from each position which we then render using the function
You can easily change the rendering HTML to display the Ads in the way you want.
In this tutorial we have created many new functions used to get the Ads, cache them and display them. By using various action and filter hooks, you can extend the front and the back of WordPress.
Using some simple caching we were able to fasten our WordPress site. We have now a simple WordPress advertising plugin that we can use to display the Ads. The next thing we have to do is to track the impressions, clicks and click-through-rate. This will be done in the next tutorial, so stay tuned!
If you had a hard time understanding any of the code above, please do say in the comments so that I can describe the code even better.