Category Archives: PHP

Including Responsive Videos in WordPress Posts

I've done a lot of things with WordPress to-date, but one thing I haven't done much with is videos. I was commissioned to build a plugin to embed responsive videos into WordPress posts. Naturally I started trying to figure out how to embed a simple Vimeo video into a post, this post right here in fact. I went to Vimeo.com and got the link for one of the videos my client is using. I am going to post just that plain text link on the next line below:

...and presto-magico! WordPress did most of the work for me! As you can see the video showed up just from me copy and pasting the Vimeo URL in the post! For example, I posted "https:// vimeo.com/ 155235235" without the quotes or spaces. I just added spaces so WordPress wouldn't make it a video like it did above.

Therefore, the only task left to me is to make the videos responsive.

How to make videos responsive in WordPress

The most basic method, which you may want to use if you only need to apply this fix to one or two videos on your site,  is to add a wrapper div to your video url when you insert it int o your blog post like this:

<div class="video-wrap"> VIDEO URL GOES HERE! </div>

Then add the following CSS to your theme's main style sheet, style.css:

.video-wrap{
    position: relative;
    padding-bottom: 56.25%;
    height: 0;
    overflow: hidden;
}
.video-wrap iframe, .video-wrap object, .video-wrap embed, .video-wrap video {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

That's all you have to do if you don't mind making manual edits each time you add a video to your blog.

Making a Simple WordPress Plugin to Make Videos Responsive

The logical option to use if you regularly embed videos in your WordPress site, is to create a very simple plugin that hooks into WordPress while it embeds videos and automatically wraps the embed code inside of a div and then applies style to that div to accomplish the same effect we did above without having to make changes each time we add a new video. Here is how:

Add the following code to a new php file and name it whatever you want to call your custom plugin or call it jafty-responsive-video-embedder as I did here:

<?php
/*
Plugin Name: Jafty Responsive Video Embedder
Plugin URI: http://jafty.com

Description: Adds a wrapper div around embedded videos and applies mobile style to them so they are responsive at all times regardless of the surrounding HTML.

Author: Ian L. of Jafty.com
Author URI: http://jafty.com

Version: 1.0.0

License: GNU General Public License v2.0
License URI: http://www.opensource.org/licenses/gpl-license.php
*/

//Code to make Videos more responsive:
function make_video_responsive( $html ) {
    return '<div class="video-wrap">' . $html . '</div>';
}
 
add_filter( 'embed_oembed_html', 'make_video_responsive', 10, 3 );
add_filter( 'video_embed_html', 'make_video_responsive' ); // Jetpack

function add_video_css(){
wp_enqueue_style("videocss", "/wp-content/plugins/outer-gain-engine/video.css");
}

add_action('wp_enqueue_scripts', 'add_video_css');

?>

Then create a file named video.css and copy and paste the follocing CSS code into it:

.video-wrap{
    position: relative;
    padding-bottom: 56.25%;
    height: 0;
    overflow: hidden;
}
.video-wrap iframe, .video-wrap object, .video-wrap embed, .video-wrap video {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

Summary

That's all there is to it. A simple, yet handy, plugin or fix for your WordPress videos. Feel free to modify the code to fit your individual needs. Good Luck!

Programmatically Add Page from a WordPress Plugin

In this tutorial, I'll show you how to make your WordPress plugin automatically create a WordPress page when the plugin is activated from wp-admin.

Let's just dive right in to the PHP code this time!

//Add Events page on activation:
function install_events_pg(){
        $new_page_title = 'Events';
        $new_page_content = 'This is your page content that automatically gets inserted into the Events page!';
        $new_page_template = ''; //ex. template-custom.php. Leave blank if you don't want a custom page template.
        //don't change the code below, unless you know what you're doing
        $page_check = get_page_by_title($new_page_title);
        $new_page = array(
                'post_type' => 'page',
                'post_title' => $new_page_title,
                'post_content' => $new_page_content,
                'post_status' => 'publish',
                'post_author' => 1,
        );
        if(!isset($page_check->ID)){
                $new_page_id = wp_insert_post($new_page);
                if(!empty($new_page_template)){
                        update_post_meta($new_page_id, '_wp_page_template', $new_page_template);
                }
        }
}//end install_events_pg function to add page to wp on plugin activation

register_activation_hook(__FILE__, 'install_events_pg');

That's really all there is to it. Of course, you'll want to edit the $new_pg_title to contain the title of your own custom page and you'll want to edit $new_pg_content to contain html elements for your page content, but this will get you started. Just by copy and pasting the above code into your plugin's main file, you will see the "Events" page added when you activate the plugin. If your plugin is already activated, simply deactivate and acti

How to Use jQuery UI Elements In a WordPress Plugin or Theme

Today I found myself once again needing to use jQuery in a new WordPress plugin I am developing for a client. I won't lie, I often dread having to use jQuery within WordPress. It has been getting easier however, especially since WordPress version 3.3.x when they made many of the jQuery UI libraries part of the WordPress core. The trick is knowing that and knowing how to use them! For example I didn't know about the jQuery UI libraries being part of the WP core until recently, so was just hacking my own jQuery into WordPress. The problem with hacking in a jQuery UI or any other jQuery code, is that it will usually break some other jQuery code in WordPress. Therefore I am putting together a quick reference guide on how to include jQuery and jQuery UI scripts in WordPress plugins and themes for my own reference and for other developers who can profit from this information.

First, here is a list of 35 jQueryUI elements already available within WordPress as of version 3.3.x:

Name: Enqueue Value: Dependency:
jQuery UI Core jquery-ui-core jquery
jQuery UI Widget jquery-ui-widget jquery
jQuery UI Accordion jquery-ui-accordion jquery
jQuery UI Autocomplete jquery-ui-autocomplete jquery
jQuery UI Button jquery-ui-button jquery
jQuery UI Datepicker jquery-ui-datepicker jquery
jQuery UI Dialog jquery-ui-dialog jquery
jQuery UI Draggable jquery-ui-draggable jquery
jQuery UI Droppable jquery-ui-droppable jquery
jQuery UI Menu jquery-ui-menu jquery
jQuery UI Mouse jquery-ui-mouse jquery
jQuery UI Position jquery-ui-position jquery
jQuery UI Progressbar jquery-ui-progressbar jquery
jQuery UI Selectable jquery-ui-selectable jquery
jQuery UI Resizable jquery-ui-resizable jquery
jQuery UI Selectmenu jquery-ui-selectmenu jquery
jQuery UI Sortable jquery-ui-sortable jquery
jQuery UI Slider jquery-ui-slider jquery
jQuery UI Spinner jquery-ui-spinner jquery
jQuery UI Tooltips jquery-ui-tooltip jquery
jQuery UI Tabs jquery-ui-tabs jquery
jQuery UI Effects jquery-effects-core jquery
jQuery UI Effects – Blind jquery-effects-blind jquery-effects-core
jQuery UI Effects – Bounce jquery-effects-bounce jquery-effects-core
jQuery UI Effects – Clip jquery-effects-clip jquery-effects-core
jQuery UI Effects – Drop jquery-effects-drop jquery-effects-core
jQuery UI Effects – Explode jquery-effects-explode jquery-effects-core
jQuery UI Effects – Fade jquery-effects-fade jquery-effects-core
jQuery UI Effects – Fold jquery-effects-fold jquery-effects-core
jQuery UI Effects – Highlight jquery-effects-highlight jquery-effects-core
jQuery UI Effects – Pulsate jquery-effects-pulsate jquery-effects-core
jQuery UI Effects – Scale jquery-effects-scale jquery-effects-core
jQuery UI Effects – Shake jquery-effects-shake jquery-effects-core
jQuery UI Effects – Slide jquery-effects-slide jquery-effects-core
jQuery UI Effects – Transfer jquery-effects-transfer jquery-effects-core

As you can see in the above table, the first 22 items in the list only require jQuery as a dependency. For those, you probably will only need to enqueue the value from the "Enqueue Value" column to make use of the library in your plugin or theme. You often will need to enqueue style for the jQuery library separately as well because as far as I know, WordPress doesn't include many of the styles yet. the last dozen or so in the above table all require jquery-effects-core, so to use those, I believe you'll need to enqueue that as well for them to work. For a complete list of other jQuery scripts that are already within the WordPress core, please visit the following codex page:

https://developer.wordpress.org/reference/functions/wp_enqueue_script/

That page also explains usage of the wp-enqueue-script function to  a degree, but not as detailed as my special-use case described here.

How to Enqueue jQuery UI Elements in WordPress Plugin or Theme

Next I'm explaining how to include a jQuery UI library into your own WordPress plugin or theme. If you're making a plugin, the code below will go into your plugin's main file and if you're working on a theme, then place the code below in the theme's functions.php file. In the following code examples, I'll demonstrate how to include both the jQuery UI element and the corresponding CSS file for using a datepicker in both the front-end and admin areas of WordPress. The code would be the same for any of the UI elements in the above table except that you would of course change the valuse to be enqueued for both the core jQuery file and the CSS file from googleapis.com.

PHP Code to use jQuery UI on the WordPress Front-End

function my_datepicker_function(){
//Enqueue date picker UI from WP core:
wp_enqueue_script('jquery-ui-datepicker');
//Enqueue the jQuery UI theme css file from google:
wp_enqueue_style('e2b-admin-ui-css','http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/themes/base/jquery-ui.css',false,"1.9.0",false);
}
add_action('wp_enqueue_scripts', 'my_datepicker_function');

How to add PHP Code to Use jQuery UI on the WordPress Admin or Back-End

The PHP code to include the same datepicker UI in a WordPress back-end, admin page is nearly the same. The only difference is the hook we use in the add_action line at the end of the code is different. For front-end use, we used the wp_enqueue_scripts hook, but for admin use, we will use the admin_enqueue_scripts hook instead. That's all folks!

Then simply include your HTML and  script tag wherever you want to use your datepicker in this case like so:

<div class="wrap">
<input type="text" class="datepicker" name="datepicker" value=""/>
</div>

<script>
jQuery(function() {
    jQuery( ".datepicker" ).datepicker({
        dateFormat : "dd-mm-yy"
    });
});
</script>

Summary

the above example code is just for datepicker UI, but can easily be manipulated for any of the jQuery UI elements in the above table, so experiment and find the one that works for you. You will often need to google the jQuery UI element's name and view an online demo of how it is used without WordPress to get exact code and then simply incorporate the above technique into what you learn. I did this with the sortable UI and it worked great. Good luck!

 

How to get Locations in a 50 Mile Radius with Google Maps API v.3

In this post, I will demonstrate how to make getting locations within a given radius simple. In order to make everyone understand, I will break it down into smaller, easy to read steps.

The Distance-Matrix

The key to creating a solution that gets all locations within a given distance radius is to use the Google Maps API Distance-Matrix. Let's examine a simple example request to the Distance-Matrix Json API:

Single Destination URL Example:

https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=44311&destinations=45735&key=Your_API_Key

copy and paste the above URL into a web browser and replace the text, Your_API_Key, with your google Maps V.3 API key. If you don't have an API key yet, they are surprisingly easy to obtain from https://developers.google.com/maps/web-services/

The Response:

The URL above will return a Json response of:

{
   "destination_addresses" : [ "Guysville, OH 45735, USA" ],
   "origin_addresses" : [ "Akron, OH 44311, USA" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "166 mi",
                  "value" : 267653
               },
               "duration" : {
                  "text" : "2 hours 30 mins",
                  "value" : 8989
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}

Notice that I only used zip codes for orgin and destination in my example URL. You can use any acceptable address format instead of just a zip code of you like, but I find that for getting distances, zip codes work quite efficiently. Examples of acceptable addresses include:

  • Cleveland, OH
  • 593 Brown Street, Akron, Ohio
  • 44319
  • Akron, Ohio 4319
  • 593 Brown Street, Akron, Ohio 44311
  • USA
  • Amsterdam

Those are just a few acceptable addresses that could be used for either the destination or orgin parameters in the URL used for an API request to the Distance-Matrix.

 

Multiple Destination URL Example:

One thing that's important to know about the Distance-Matrix API is that there are limits on it's free usage. At the time of writing this post, the limits were 2500 elements per day. A single request may take up several elements however, so be careful. However it is much more practical to include several destination addresses in a single request because it will make your script run significantly quicker. Here is a simple example that will return a response with two destination distances using just zip codes for addresses again:

https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=44311&destinations=45735|44319&key=Your_API_Key

This the json response will include the distances for both zip codes or addresses passed in the URL. Here is the response from the above URL with two destinations:

{
   "destination_addresses" : [ "Guysville, OH 45735, USA", "Akron, OH 44319, USA" ],
   "origin_addresses" : [ "Akron, OH 44311, USA" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "166 mi",
                  "value" : 267653
               },
               "duration" : {
                  "text" : "2 hours 30 mins",
                  "value" : 8989
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "8.9 mi",
                  "value" : 14385
               },
               "duration" : {
                  "text" : "14 mins",
                  "value" : 836
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}

Parsing Json data with PHP

The next task is to fetch a response from PHP and parse the Json data in your PHP code. Lets look at a practical example using our first URL example above that has a single zip code as the destination address and also a single zip code for the orgin. Here is the PHP code to make the request, get a Json response and parse the distance from that response:

<?php
$url = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=44311&destinations=45735&key=Your-API-Key";

    //fetch json response from googleapis.com:
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $response = json_decode(curl_exec($ch), true);
    //If google responds with a status of OK
    //Extract the distance text:
    if($response['status'] == "OK"){
        $dist = $response['rows'][0]['elements'][0]['distance']['text'];
        echo "<p>Dist: $dist</p>";
    }
?>

Now lets have a look at how we would modify the above code for a request with two destination addresses instead of one:

<?php
$url = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=44311&destinations=45735|44319&key=Your-API-Key";

    //fetch json response from googleapis.com:
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $response = json_decode(curl_exec($ch), true);
    //If google responds with a status of OK
    //Extract the distance text:
    if($response['status'] == "OK"){
        $dist = $response['rows'][0]['elements'][0]['distance']['text'];
        echo "<p>Dist: $dist</p>";
        $dist2 = $response['rows'][0]['elements'][1]['distance']['text'];
        echo "<p>Dist2: $dist2</p>";
    }
?>

If you insert your own API key in the above code and run it from your own server, the response would look like this:

Dist: 166 mi

Dist2: 8.9 mi

Notice the difference in the $dist and $dist2 variable values. The key of the elements is different. The first distance is stored in elements[0] while the second is stored in elements[1]. If we had three destinations in the request, the third would be in elements[2] and so on...

How to figure out the values

So, what if you want more than just distance from the returned json element? Lets examine the returned data and figure out how to get it into PHP variables. In the example code above, try placeing this code right after the line that reads "if($response['status'] == "OK"){" and it will show you what the PHP array looks like after the Json response was converted to a PHP object:

        echo "<pre>";
        print_r($response);
        echo "</pre>";

The above code inserted into the last code example would look like:

<?php
$url = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=44311&destinations=45735|44319&key=Your-API-Key";

    //fetch json response from googleapis.com:
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $response = json_decode(curl_exec($ch), true);
    //If google responds with a status of OK
    //Extract the distance text:
    if($response['status'] == "OK"){
        echo "<pre>";
        print_r($response);
        echo "</pre>";
        $dist = $response['rows'][0]['elements'][0]['distance']['text'];
        echo "<p>Dist: $dist</p>";
        $dist2 = $response['rows'][0]['elements'][1]['distance']['text'];
        echo "<p>Dist2: $dist2</p>";
    }
?>

Again, replace "Your-API-Key" in the URL variable with your own key and run the code. You should see results like this:

Array
(
    [destination_addresses] => Array
        (
            [0] => Guysville, OH 45735, USA
            [1] => Akron, OH 44319, USA
        )

    [origin_addresses] => Array
        (
            [0] => Akron, OH 44311, USA
        )

    [rows] => Array
        (
            [0] => Array
                (
                    [elements] => Array
                        (
                            [0] => Array
                                (
                                    [distance] => Array
                                        (
                                            [text] => 166 mi
                                            [value] => 267653
                                        )

                                    [duration] => Array
                                        (
                                            [text] => 2 hours 30 mins
                                            [value] => 8989
                                        )

                                    [status] => OK
                                )

                            [1] => Array
                                (
                                    [distance] => Array
                                        (
                                            [text] => 8.9 mi
                                            [value] => 14385
                                        )

                                    [duration] => Array
                                        (
                                            [text] => 14 mins
                                            [value] => 836
                                        )

                                    [status] => OK
                                )

                        )

                )

        )

    [status] => OK
)

Dist: 166 mi

Dist2: 8.9 mi

First you see the array printed out from the response after it's converted from Json to a PHP array, then you see the two distances printed to the screen in the last two lines. Examine the array closely and you can figure out the correct keys to use to pick out specific values from the array in your PHP code.

More info on the Distance-Matrix can be found at https://developers.google.com/maps/documentation/distance-matrix/start

How to Do Something Every Nth Iteration in a PHP Loop

If you're a PHP coder, you are sure to come across a scenario from time to time where you have a PHP loop and you need to execute specific code every other time the loop iterates or every four times the loop iterates etc.

Using the Modulus Operator

The key to making something happen every nth time in a loop is the modulus operator or %.

A common scenario where you would need to do something in a loop every fourth or fifth iteration only is when you are printing a series of HTML elements. Let's pretend we have 12 items in an array and we want to print them in groups of four per line. While printing the array you will need to print the <br /> tag every four iterations if you want four items on each line.  The code inside your PHP loop would look like this:

if($i % 4 == 0){echo "<br />";}

Now let's put this to the test with some test code using the above scenario. Below I fill an array with 12 words and print them out in a loop four per line:

<?php
$words = array('one','two','three','four','five','six','seven','eight','nine','ten','eleven','twelve');
$noof = count($words);
$i=0;
for($ii=0;$ii<$noof;$ii++){
    $i++;
    echo $words[$ii];
    echo " ";
    if($i % 4 == 0){echo "<br />";}
}//end for loop
?>

Noticed I used $ii in the for loop and set a second variable, $i for using with the modulus line. This is because $ii will start at zero and we need to start at 1 in this case. The results of the above code would be:

one two three four
five six seven eight
nine ten eleven twelve

Today however, I came across a more complex scenario where I was able to also use the modulus operator to save the day. This time I needed to print items from an array inside of HTML list elements. Lets modify the above scenario using lists instead of line breaks to display the array data:

<?php
$words = array('one','two','three','four','five','six','seven','eight','nine','ten','eleven','twelve');
$noof = count($words);
$i=0;
for($ii=0;$ii<$noof;$ii++){
    $i++;
    if($i % 4 == 1)echo "<ul>";
    echo "<li>";
    echo $words[$ii];
    echo "</li>";
    if($i % 4 == 0)echo "</ul>";
}//end for loop
?>

The output of the above PHP code would be:

  1. one
  2. two
  3. three
  4. four
  1. five
  2. six
  3. seven
  4. eight
  1. nine
  2. ten
  3. eleven
  4. twelve

 

The results were four separate ordered lists  as you can see. But how did we do this? Notice the difference in the modulus operator use for the opening <ol> tag and then for the closing </ol> tag.

The tricky part here is we can't use if($i % 4 == 0) on the opening <ol> tag because if you think about it you don't need <ol> printed on 4,8 and 12 which is what if($i % 4 == 0) would produce. In this case, we need to print an opening <ol> tag on iterations 1,5,9 and 13, so we try something else. Here is how I figured this problem out:

First a simple demo of the modulus operator as we first used it:

<?php
$i=0;
for($ii=0;$ii<20;$ii++){
    $i++;
    if($i % 4 == 0)echo "$i<br />";
}//end for loop
?>

The above code results in:

4
8
12
16
20

Which is fine for printing the end </ol> tags, but will not work for printing the opening <ol> tags as I explained earlier, so I tried this instead:

<?php
$i=0;
for($ii=0;$ii<20;$ii++){
    $i++;
    if($i % 4 == 1)echo "$i<br />";
}//end for loop
?>

This time the above code printed out:

1
5
9
13
17

So, if we used a one instead of a zero like if($i % 4 == 1), then it would execute the code in the if statement on iterations 1,5,9 and 13 just as we need! Just for fun, let's see what happens if we use a two instead of zero this time like if($i % 4 == 2). For example:

<?php
$i=0;
for($ii=0;$ii<20;$ii++){
    $i++;
    if($i % 4 == 2)echo "$i<br />";
}//end for loop
?>

This time the results would be:

2
6
10
14
18

so using a 2 to compare 4 modulus with results in the code executing on iterations 2,6,10....etc, but notice in each example where we use 4 as the first number, all the numbers are increments of 4 and when we use zero as the last number we get 4,8,12.... When we use 1 we get 1,5,9.... Finally if we use 2 we get 2,6,10.... From what we have learned I think it's safe to assume that we we used 3, the results would be 3,7,11,15....and so on.

Summary

I hope this article sheds some light on how to use the Modulus operator with PHP. Feel free to experiment by using other numbers in place of where I used 4 each time too! For example, if you want to do something every 5 times instead, you would use something like if($i % 5 == 0). Have fun with it!

 

Building a Custom WordPress Navigation Menu Plugin

This is a semi-advanced WordPress tutorial so you should have a little bit of existing knowledge of WordPress if you want to be able to understand the concepts involved. I will try to make it as easy to follow as possible none-the-less.

We are just going to dive right in a create a new Plugin. I'll be calling the plugin Jafty-Nav, you can follow suit if you wish to keep things simple or give it your own name if you feel comfortable making such changes.

Create a New Plugin

<?php
/**
* Plugin Name: Jafty Top Nav Plugin
* Plugin URI: http://jafty.com/blog/?p=9813
* Description: A Plugin that adds a custom top navigation menu to WordPress.
* Version: 1.0
* Author: Ian L. of Jafty.com
* Author URI: http://jafty.com
* License: GPL2
*/

Register a New Menu Location with WordPress

Add this PHP code to your plugin file you created above:

<?php
add_action('after_setup_theme', 'register_jafty_menu');
function register_jafty_menu(){
  register_nav_menu('jafty-top-nav', __('Primary Jafty Menu', 'jafty-top-nav-plugin'));
}
?>

Now that is actually enough to create a simple plugin. The plugin will add a menu location to wp-admin and that's it, but we'll build on it after we install it. So go ahead and install the plugin by putting it into a folder named "jafty-top-nav-plugin" and naming the file "index.php". Then upload to your WordPress plugins directory. Activate the Jafty Top Nav Plugin then go to your admin and click on "Appearance/Menus" then select the "Manage Locations" tab and you'll see the new menu location your plugin as added to the admin like in the image below.

menuLOC

Placing a new top nav in your theme

The next task is to edit your current WordPress theme to work with the Jafty Top Nav Plugin. You'll need to create a new header file and edit your page, post and/or home page templates to contain your new top navigation menu. Here is how:

  1. Go into your current theme's folder and download a copy of the header.php file to your desktop and rename it header-jafty.php.
  2. open header-jafty.php in notepad and find the section that looks something like this:<nav id="site-navigation" class="main-navigation" role="navigation">
    <button class="menu-toggle" aria-controls="primary-menu" aria-expanded="false"><?php esc_html_e( 'Primary Menu', 'outer-gain-dev' ); ?></button>
    <?php wp_nav_menu( array( 'theme_location' => 'menu-1', 'menu_id' => 'primary-menu' ) ); ?>
    </nav>
  3. Inside the code within the Nav tag in your header-jafty.php file, change the theme_location value to 'jafty-top-nav' and save the file.
  4. Now upload your header-jafty.php file to your active theme's folder.
  5. Next you'll want to add the new header to your template files, Some templates you might want to do this too are front-page.php, single.php, page.php and any custom page templates in your theme or child theme you might have. The process is very similar for adding the new header to any of the files, so I'll just demonstrate on the home page template file, front-page.php. Open the template file in your notepad and near the top of the code you should see something like this:
    get_header();
    or you may have something like this instead:
    get_template_part('templates/header.php');
    Regardless which you have, replace the line with:
    get_header('jafty');
    and that will call your new header.jafty.php template into the page template so your customized header will be shown.
  6. Save and upload your altered template file and repeat for all necessary page and post templates until you have your new top nav menu at the top of all desired pages and/or posts throughout your entire WordPress site.

Now that we have more control of it, let's customize that ugly top nav!

Customizing the WP Navigation Menu

It's time to get down and dirty with some real-world customization of the top navigation menu in WordPress. We are not just doing some simple CSS changes here, we are talking about a complete rewrite of the navigation system. This is why I went with a plugin for this. Now I had to find what WordPress core functions I could use to alter the menu completely. My goal is to make a menu similar to the one at Stripe.com, which is not a WordPress site by the way. I just love the dynamic drop downs that fade in and out and their use of icons in the sub-menu items. I'll get to how I duplicated all of that later on, first we need to know how to rebuild the entire menu structure because the stripe.com style menu is nothing like a standard WordPress menu. Here's what I figured out:

 

First we need to be able to retrieve our custom navigation links from the WordPress backend. Remember earlier we created a menu location? Well, we need to retrieve the menu assigned to that particular location in WordPress. Therefore the first thing we want to do is make sure there is a menu assigned to the "Primary Jafty Menu". You could pick one from the drop down, but we want to make a new one that is sure to have both main menu items and sub menu items so we can adequately test our menu when it's complete. Therefore we locate the "Primary Jafty Menu" and click the link to the right of it that reads "Use New Menu" as I've circled in red in the below image:

menuLOC2

When creating the new Primary Jafty Menu, give it a name of "Jafty 1". It's best to do everything exactly as I have done just to be sure you don't have any conflicts. You can always change names and such after you have a completed working plugin. When creating the menu, make sure to add at least 2 main menu items with at least 2 sub menu items each so we can test the drop down effects. Here is an image of the one I made for testing. If you don't have enough pages or posts to make that many links, don't worry, just use two real links for the main menu items and click on "custom links" and create outside links for all of your sub menu items as I have done in the below image:

menustructure

In the above image, "site settings" and "Hello world!" represent our two main menu items and the sub links rest below them indented to show their sub-link status. Notice I have "Primary Jafty Menu" checked under "Menu Setings" too. Once you have your menu, be sure you save it. Now we can return to developing our plugin!

Retrieve Menu and Sub Menu Items from WordPress Admin

It is time to develop some custom WordPress code to extract out menu items and sub-menu items from the database. Lucky for us, WordPress has some built-in core functions to assist us. Here is the code I come up with to extract all menu and sub-menu items for the "Jafty Primary Menu" from the database to display them on the front-end:

<?php
      $menuLocations = get_nav_menu_locations(); // Get nav locations
      $menuID = $menuLocations['jafty-top-nav']; //menu assigned to Jafty Primary Menu
      $theNav = wp_get_nav_menu_items($menuID);
                
                    foreach ($theNav as $navItem) {
                        //get the url for the link:
                        $navURL = $navItem->url;
                        //get the nav link text/title:
                        $navTXT = $navItem->title;
                        //Get the nav link's ID:
                        $navID = $navItem->ID;
                        //Get menu item parent(will be 0 if main link or parent ID if it's a sub link):
                        $navParent  = $navItem->menu_item_parent;
                        echo "ID: $navID, $navTXT, $navParent, $navURL<br />";
                    //echo '<li class="has-dropdown gallery" data-content="about"><a href="'.$navURL.'" title="'.$navItem->title.'">'.$navTXT.'</a></li>';
                    }
 ?>

The above code will go in out header file named header-jafty.php. Lets examine the code so you understand what it does.

The first line:

$menuLocations = get_nav_menu_locations(); // Get nav locations

as the comment says afterwards, it gets the navigation menu locations stored in WordPress. We added one of these in the beginning of the tutorial using the register_nav_menu function.

The second line reads:

$menuID = $menuLocations['jafty-top-nav']; //menu assigned to 'Primary Jafty Menu'

This line fetches the ID of the menu currently assigned to the menu location we created in the plugin file, "Primary Jafty Menu". We then use the id in the next line that reads:

$theNav = wp_get_nav_menu_items($menuID);

We now have a WordPress menu object stored in $theNav. If you do a print_r($theNav) command in PHP, you would see that the menu object holds all sorts of information about the menu we created earlier. However, we only need four key pieces of information from the menu object. We need to get:

  1. The Link URL
  2. The Link Text
  3. The Link ID
  4. The Link's Parent ID in case it is a sub-menu item.

We can get the four pieces of information we need using a foreach loop on the $theNav object like so:

     foreach ($theNav as $navItem) {
                        //get the url for the link:
                        $navURL = $navItem->url;
                        //get the nav link text/title:
                        $navTXT = $navItem->title;
                        //Get the nav link's ID:
                        $navID = $navItem->ID;
                        //Get menu item parent(will be 0 if main link or parent ID if it's a sub link):
                        $navParent  = $navItem->menu_item_parent;
                        echo "ID: $navID, $navTXT, $navParent, $navURL<br />";
                    //echo '<li class="has-dropdown gallery" data-content="about"><a href="'.$navURL.'" title="'.$navItem->title.'">'.$navTXT.'</a></li>';
                    }

We now have all the information we need about the menu items after running the above foreach loop on the menu object. We have the link text, URL, ID and Parent ID. It's important to note that the parent ID will always be 0 if the link is a main menu item and we can determine if the link is a sub-menu item if the parent ID is anything other than zero. Then we know which link to put the sub-link under by matching the sub-link's parent ID to the ID of the main link item. Pretty simply really, once you get accustomed to it.

Now we need to open our header-jafty.php file and find the line that reads something similar to:

<?php wp_nav_menu( array( 'theme_location' => 'jafty-top-nav', 'menu_id' => 'primary-menu' ) ); ?>

And replace it with the code we wrote above:

<?php
$menuLocations = get_nav_menu_locations(); // Get nav locations
$menuID = $menuLocations['jafty-top-nav']; // Get the *primary* menu ID
$theNav = wp_get_nav_menu_items($menuID);

foreach ($theNav as $navItem) {
//get the url for the link:
$navURL = $navItem->url;
//get the nav link text/title:
$navTXT = $navItem->title;
//Get the nav link's ID:
$navID = $navItem->ID;
//Get menu item parent(will be 0 if main link or parent ID if it's a sub link):
$navParent  = $navItem->menu_item_parent;
echo "ID: $navID, $navTXT, $navParent, $navURL<br />";
//echo '<li class="has-dropdown gallery" data-content="about"><a href="'.$navURL.'" title="'.$navItem->title.'">'.$navTXT.'</a></li>';
}
?>

Now save your header-jafty.php file and upload it to your active theme's folder and refresh your home page. You should see the following information printed in the header area of your site instead of a top nav now:

ID: 47, Site Settings, 0, http://dev.outergain.com/site-settings/
ID: 49, Jafty Interactive, 47, http://jafty.com
ID: 50, Jafty Blog, 47, http://jafty.com/blog
ID: 48, Hello world!, 0, http://dev.outergain.com/2016/12/30/hello-world/
ID: 51, Yahoo Search, 48, http://yahoo.com
ID: 52, Google Search, 48, http://google.com

As you can see my site returned 6 lines of text in the header, one for each of the two main menu items and one for each of the four sub-menu items in the menu I created in wp-admin. Each of the lines above contains the main ID first, followed by the link text, then the parent ID and finally the link text. I highlighted the parent IDs in blue so you can see how the two main menu items have a parent ID of zero while the other four have parent IDs equal to the two main menu items with zero for parent ID. Make sense? I hope so:-)

For all you professional WordPress plugin developers, I can probably stop there. Now you have enough to make your own custom top navigation menu for your WordPress theme. You clearly don't need to do this as a plugin, in fact, it would normally done by adding the plugin code to functions.php in the current theme instead. I am making it a plugin just as a learning exercise.

You can use the information it printed in your header to figure out how to add in the HTML and CSS for any type of custom nav you desire, or you can read on to see how I recreated the stripe.com-like top nav for one of my clients.

Make a Static Top Navigation Menu as a Demo

Before we go about coding the menu into WordPress, I like to create a static version first. I created mine based on looking at the top nav found on Stripe.com. You can click the link to see what I mean. I didn't copy it by any means, but I did use it as a model for creating a similar one with similar transition effects. In the static demo, I didn't create great detail in the drop downs. Instead I concentrated on getting the transition effects and infrastructure perfect. I can worry about making the content of the dropdown boxes look pretty when I code it into the actual WordPress site. Here is my static demo: http://jafty.com/nav_demo

I won't post all of the code to my static navigation menu demo here but you may feel free to use the link provided and use your browser's view source option to see how I made it and copy it if you so desire.

 

 

 

WordPress now has Post Templates

Great news for some WordPress developers, WordPress version 4.7 recently came out with an exciting new feature! They now allow post templates similar to the way page templates work.

Activating Post Templates

To activate the new post template feature all you have to do is add your first post template. The one requirement to make them show up in the admin area on the new or edit post screen is that you have to add the following lines to the very top of your new template files:

/*
* Template Name: Your Post Template Name Here
* Template Post Type: CPT, names
*/

That's all there is to it! Make up a template name for the first parameter and use the Custom Post Type name or names for the second parameter, Template Post Type:.

Lets say you created a custom post type named "movies" and you created a template named movie-posts.php, then your movie-posts.php file would start out like this:

/*
* Template Name: Movie Posts
* Template Post Type: movies
*/

Then go ahead and add your loop and other code to your template file and when you upload it you'll see a new "template" drop-down appear under the attributes heading in the right column of the edit posts and add new posts screen for that custom post type:

postemp

Summary:

Note that this also works with ACF plugin or Advanced Custom Fields Pro plugin. That should explain it all. I hope this becomes as useful for some of my readers as it already has for me!

The WordPress Loop

Today I finally decided to dedicate a single tutorial on the wonderful WordPress loop. I will demonstrate how to create a basic loop and show several examples of the loop in action. The loop is what gets post and/or page data in WordPress template files, so if you ever have a need to make a custom page or post template, you'll need to understand how the loop works.

 

The Basic WordPress Loop

Most often you will see the loop look something like this:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

<!------------This is where you present your post data....-------------->

<?php endwhile; else : ?>
    <p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php endif; ?>

The above example doesn't contain the middle part of the loop in order to demonstrate where the loop typically begins and ends. That way you can find the loop in your current theme and work with it by knowing where it starts and stops at least.  Next we'll discuss what to put in between where it says <!------------This is where you present your post data....-------------->.

Fetching Data Inside a WordPress Loop

Post Title:

First I'll show you how to display the Title as a link to the Post's permalink.

<h2><a href="<?php the_permalink(); ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>

Just place the above code example where it says you present your post data in the the loop example above.

Post Content:

You can display the Post's content in a div with the following code inside of your loop:

<div class="entry">
<?php the_content(); ?>
</div>

Again, use the above code in between the starting and ending loop code explained above and this will display the general content of the post as entered into the standard WYSIWYG editor in the WordPress admin.

Using More Than One Loop

If you need to use two more more loops in the same template file, then you will have to reset the WordPress loop with rewind posts function like this:

<?php rewind_posts(); ?>

Just use the above line before your second loop and any loops afterwards and they will reset and be ready to function again.

 

Understanding IP Addresses

Have you ever needed to know how an IP Address works? Have perhaps just wondered how they worked? Well in my line of work it has eventually become necessary for me to fully understand exactly how IP addresses work and are made up. Therefore I aim to share my knowledge on such with anyone who cares to read about IP addresses here on my wonderful blog.

First of all it's important to know that IP addresses are displayed in what is known as dotted-decimal format. For example your current IP address is 54.166.14.86

For anyone Interested, I got your IP address using the following PHP code:

<?php
$ipaddress2 = $_SERVER[REMOTE_ADDR];
echo "<h3>Your Current IP Address: $ipaddress2</h3>";
?>

Just notice the format of the IP address above for now though.

Two Main Parts of an IP Address

While an IP address appears to have 4 parts due to the dotted-decimal format used, in reality, IP addresses are made up of only two main parts. They are "Network ID" and "Host ID". The two parts are not equal or consistent. The Network ID is defined first and the Host ID will be the remaining portion of the IP address.

IP Address Classes

IP addresses are divided into different classes. There are actually five IP classes, but only three are in common use, they are Classes A,B, and C. Classes D and E are reserved classes. Class D is Reserved for Multicasting. Class E is Experimental; used for research. The three main classes are shown in the following examples:

  • Class A - Class A IP addresses use 8 bits for the Network ID(8 bits = 1 byte or 1 segment in dotted-decimal format or 1 octet). Class A addresses only include IP addresses from 1.x.x.x to 126.x.x.x. The IP range 127.x.x.x is reserved for loopback IP addresses. Therefore a Class A IP address might look like 19.23.20.100. From what we know about the two parts of an IP address now, we know that the "19." portion of this example IP address defines the Network ID and the  remaining part(23.20.100) represents the Host ID.
  • Class B - Class B IP addresses use 16 bits for the Network ID(16 bits = 2 bytes or 2 segments in dotted-decimal format or 2 octets). The remaining 16 bits are used for the Host ID of course.
  • Class C - Class C IP addresses use 24 bits for the Network ID(24 bits = 3 bytes or 3 segments in dotted-decimal format or 3 octets). The remaining 8 bits are used for the Host ID in this case.

How to Determine IP Address Class

Determining whether an IP address belongs to class A, B or C can be a daunting task if you don't understand how IP addresses function. That is why I will explain it clearly here for you! First you need to realize that IP classes are determined by the first few bits of the IP address. Then you need to know that bits are not the same as the dotted-decimal format you are accustomed to! For example My IP address now shows as 173.6.69.165 if I open this post in my current browser. What class does 173.6.69.165 belong to? Well here is how I found out:

First, convert the dotted-decimal formatted IP address of 173.6.69.165 to its binary form and count the bits. Actually, you can do just the first octet or 173 in this case. Here is how to convert a decimal octet to a binary Byte:

You divide the number(173 in this case) by 2 and take the answer with the remainder and note both. Then divide the answer by two and note the answer and remainder again....do this eight times. Start at the top of a sheet of paper and move to a new line each time you start a new calculation.  Be sure to circle the remainder each time as those are the 8 bits that make up the Byte we are after. Here is my sloppy example of how I did it with my IP address that began with 173:

binarypaper_ink_li Notice that I circled the remainder after each division problem above. The final step is to start at the bottom and write each circled remainder down in order.

So from the image above, I get the binary number: 10101101

The first three bits of the binary 10101101 determine it's class. In my case, the first three bits are 101.

Then refer to the following table to determine your class:

  • CLASS A: the binary will begin with a zero.
  • CLASS B: the binary must start with 10.
  • CLASS C: the binary must start with 110.

So as you can see from the above table and the image above that, my IP address of 173.6.69.165 converts to a binary number of 10101101 and can then be identified as a CLASS B IP address because its binary form begins with 10. Alot to do to figure out the class of an IP, but it is mostly for learning purposes that I have explained it all like I have. Really, all you have to do is refer to the following table of information which will allow you to convert it to a class using just the first octet of the IP address(173 in my case):

Quick & Easy Method to Determine IP Class

  • CLASS A: First 3 digits of the IP address will be from 0 to 127.
  • CLASS B: First 3 digits of the IP address will be from 128 to 191.
  • CLASS C: First 3 digits of the IP address will be from 192 to 223.

So again, my IP(173.6.69.165) starts with 173 so I can use the above three lines of data to confirm that it is indeed a CLASS C IP address because 173 falls in between 128 and 191.

 

 

mysqli_result function to replace old mysql_result

Many of us are busy upgrading our PHP and MySQL code when migrating from PHP5 to PHP7. One of the first things you learn is that the MySQL functions have been depreciated and removed completely in PHP7, therefore can no longer be used! That's a major pain in the butt for many of us, but luckily the fix is not too difficult most of the time. Simply doing and find and replace replacing "mysql" with "mysqli" is often a good first step, but you will also need to add the connection variable as an argument to many of the mysqli functions as well. Then some functions, such as the mysql_result function, do not have a mysqli counterpart. That means there is no mysqli_function defined in PHP7! Real pain right? well copy and paste the following functino into your PHP code and you can now use the mysqli_result function effectively. Be sure to pass it the connection variable as most mysqli functions require even though mysql counterparts did not. Here's the function:

function mysqli_result($res,$row=0,$col=0){ 
    $numrows = mysqli_num_rows($res); 
    if ($numrows && $row <= ($numrows-1) && $row >=0){
        mysqli_data_seek($res,$row);
        $resrow = (is_numeric($col)) ? mysqli_fetch_row($res) : mysqli_fetch_assoc($res);
        if (isset($resrow[$col])){
            return $resrow[$col];
        }
    }
    return false;
}

How to Use IPTables

What is iptables?

iptables is a fairly flexible firewall system developed for Linux/Unix operating systems and used commonly for web server administrators to block access to servers by IP address or groups of IP addresses. It can also be used to white-list IP addresses as well. It is a command line tool that allows server administrators to enter simply one line commands to add, edit or delete rules for accessing the web server from the outside world.

Understanding iptables Infrastructure

Understanding the infrastructure of iptables in an important component to learning how to use iptables. Basically there are tables, chains and rules. Tables contain chains and chains contain rules. Here is a simple graphic to illustrate my point:

iptables

There are four default tables in iptables and you can add others if you want to get deep into config options. However, I recommend using the default tables to keep things simple. In fact, the filter table is the only one we will be messing with for now. The four default tables are filter, nat, mangle and raw.

  • Filter Table - default table for iptables. If you do not define a table, you’ll be using the filter table. The filter table has the following built-in chains:
    1. Input Chain - handles incoming connections.
    2. Output Chain - handles outgoing connections.
    3. Forward Chain - handles routing of connections like a router.
  • Nat Table - Consists of prerouting, postrouting and output chains. The prerouting chain helps translate destination ip address of the packets to match the routing on the local server. The postrouting chain translates packets as they leave the system and alters packets after routing. The output chain is NAT(Network Address Translation) for locally generated packets on the firewall.
  • Mangle Table - for specialized packet alteration. We will leave this table alone for now as it it outside the scope of this tutorial, but just know it is there.
  • Raw Table - for configuration exemptions. Raw table has a prerouting chain and an output chain.

Chain? WTF does my server need Chains for? Is it winter already?

When using iptables, there are basically three types of chains that we are mainly interested in. They are input chains, output chains and forward chains, the three chains from the filter table described above.

  • Input Chain - used to control the behavior of incoming connections. For example, if a user attempts to SSH into your server, iptables will attempt to match the IP address and port to a rule in the input chain.
  • Output Chain - used with outgoing connections. For example, if you try to ping jafty.com, iptables will check its output chain to see what the rules are regarding ping and jafty.com before making a decision to allow or deny the attempt to connect.
  • Forward Chain - used for incoming connections that aren’t delivered locally. It is something like a router where data is always being sent to it but is not destined for the actual router. Data is forwarded to its target. Unless you’re doing some type of routing or NATing  that requires forwarding, you probably won't use a forward chain much if at all.

Understanding iptables Commands

In order to use iptables in Linux, you need to know the basic commands, so I'll go over some of the more common iptables commands here for your learning pleasure!

Note that after you make any change, it is important to save iptables with the following command on Debian/Ubuntu servers:

iptables-save

or in some cases

/sbin/iptables-save

The save command is a little different for other servers, so take note of the one that applies to your server as noted below:

  • Centos / Redhat: service iptables save or sudo service iptables save if you are not root user.
  • If that didn't work, try:  /etc/init.d/iptables save with and without sudo first.

If you don't save after a change by typing the above at your command prompt and hitting enter, you will most likely lose your changes and/or they will never take effect.

iptables Command to Block a Single Simple IP address

If you wish to simply block an IP such as 206.190.152.176 from accessing your server in any way and from any port, type this at your command prompt and press enter, then save:

iptables -A INPUT -s 206.190.152.176 -j DROP

Whenever possible, always test to be sure your iptables rules work after adding then to be safe. Be sure to save using the appropriate iptables save command as mentioned above after you successfully enter your new rule.

Blocking all IP addresses but your own with iptables

If your server is getting throttled and you want to lock it down immediately or you are simply under construction and don't want anyone but you to be able to access your server, here is how you can block all IP addresses from accessing your server and white-list just one or more IP addresses that will be able to access your server:

iptables -A INPUT -s 0.0.0.0 -j ACCEPT
iptables -A OUTPUT -d 0.0.0.0 -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT DROP

First, you should flush your current rules(see below). Then simply replace 0.0.0.0 with your own IP address in the commands above and enter each of the four commands one at a time from the command line, pressing enter after each, then save iptables.

Flushing iptables rules

To get rid of all active rules in iptables, enter the following command at the Linux command prompt:

iptables -F

Deleting Single iptables Rules

If you entered one or more iptables rules you want to delete without deleting the entire configuration, here is how to do it:

  1. List numbered rules using this command: sudo iptables -L INPUT -n --line-numbers
  2. To delete the first rule enter: sudo iptables -D INPUT 1(where 1 is the line number you want to delete)
  3. Confirm deletion took place by running the first command again and verify the rule is no longer present: sudo iptables -L INPUT -n --line-numbers
  4. Save iptables to be safe: sudo iptables-save

 

Restrict Number of Connections Per IP

Use connlimit to place restrictions on the number of connections allowed per IP address. To allow 4 ssh connections per client host, enter:
# iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 4 -j REJECT

Set HTTP requests to 20:
# iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j DROP
Where,

  1. --connlimit-above 3 : Match if the number of existing connections is above 3.
  2. --connlimit-mask 24 : Group hosts using the prefix length. For IPv4, this must be a number between (including) 0 and 32.

 

What is this nonsense after the slash in iptables ip addresses?

This is what I need to touch on before we go much further because you've no doubt seen existing rules in your iptables with IP addresses listed similar to:

188.0.0.0/8
or:
192.12.0.0/16

...and have surely wondered why there is a slash followed by a number after the ip addresses listed in your iptables rules. Well I'll explain as best as I can in the next section as it is a little complicated to explain...

Knowing how to read and write more complex iptables rules with CIDR notation.

Learning to write iptables rules can get very frustrating if you don't understand how the notation works. CIDR, Classless Inter Domain Routing notation, is often confused with network masks which are similar but not the same. I will offer my best explanation of CIDR notation here which I've gathered from several different sources to put together an explanation I feel comfortable with:

Imagine an IP address something like xxx.yyy.zzz.www/N, where N is the number of bits from 0 to 32. Each of the other numbers represents one byte out of the 4 bytes that make up an IP address. N says how many BITS of those 4 bytes matter. So any address that looks like 10.X.Y.Z/8 refers to ANY IP starting with "10.": 8 bits = 1 byte, meaning everything after the first byte is ignored. The convention is to use zeroes in the ignored positions, so the canonical name for that subnet is 10.0.0.0/8. Most of the time, N is a multiple of 8, so it says to ignore a certain number of bytes.

Once in a while, you'll see something other than that, like a /29. This means that PART of one of the bytes is ignored. For simplicity's sake however, we will stick to multiples of 8 in this guide.

It's also important to note that if the N is omitted, then it's usually assumed to be 32, i.e. a single IP address specification.

So, taking what I've just explained above regarding CIDR notation, Here are some general examples of how netmasks work in conjunction with iptables rules:

10.0.0.0/8  - A CIDR of 8 bits means that only 1 of 4 possible bytes of the IP address is noted as represented by the "10" here. so this would cover the IP range from 10.0.0.0 to 10.255.255.255. In other words any IP address starting with "10.".

100.50.0.0/16 - A CIDR of 16 means that 2 of 4 possible bytes of the IP address are noted as represented here by "100.50.". In this case, a range from 100.50.0.0 to 100.50.255.255 is covered.

92.50.8.0/24 - A CIDR of 24 means that 3 of the 4 IP address bytes are noted as seen here with "92.50.8." This time a range from 92.50.8.0 to 92.50.8.255 is represented.

Those should be the three most common types of CIDR notations. Following the above pattern of incrementing the number of bits by 8, the next logical example would be something like 92.50.8.210/32. While that is a perfectly good notation and will work, it is also moot because 32 bits would represent the entire IP address, so you might as well enter it without the CIDR notation(with no slash and number after the IP).  In iptables rules, 92.50.8.210/32 means the exact same thing as simply putting 92.50.8.210.

What do Bytes and Bits have to do with IP Addresses?

Good question, glad I asked myself! To properly understand how CIDR notation works you have to understand the math behind it. A Byte is made up of 8 bits(that's why we increment by 8 in our previous examples). An IP address is made up of 4 Bytes or 32 Bits(4x8=32).

As you probably know, an IP address is made of of four numbers separated by dots or periods(.) like this: N.N.N.N where N can be any number from 0 to 255. This raised a question in my mind: In an IP address byte, how does a range from 0 to 255 have 8 bits? Well my question just goes to show I don't fully understand how Bytes and Bits correspond with numbers because I googled around and discovered that indeed Eight binary bits can represent any whole number from zero to 255, so the segments of a dotted decimal address are decimal numbers with a range from 0 to 255.  I think it's enough for now to understand that it is correct without getting into exactly how Bytes and Bits work with IP addresses because I don't want this tutorial to confuse you even more. Let's just know for now that 1 Byte = 8 Bits and that a Byte can be any number from 0 to 255 in an IP address which is made up of 4 Bytes and/or 32 Bits. If anyone would like to explain how this works in more detail, feel free to make a comment on this post and I'll make sure it gets published.

wp_redirect Causing Page Isn’t Redirecting Properly Error

I was working on a client's WordPress website today and had to do a redirect after successful login to his WordPress site. I tried to use wp_redirect with several different hooks including init, wp, wp_login, wp_redirect....etc. and none worked. I kept getting an error in Firefox that looked like this saying "The page isn't redirecting properly....Firefox has detected that the server us redirecting the request for this address in a way that will never complete:

redirecterr

The Solution

So, in short Here is my solution. While I'm sure there may be another better way, this is the only one I found after two hours of trying to use wp_redirect. I simply used this line in place of where I would normally use wp_redirect:

echo "<script>document.location = '/my-account/';</script>";

So I essentially insert a JavaScript redirect into the page using PHP. Hackish? Yes, but it works and hopefully this post will save someone hours of wasted time trying to get wp_redirect to work!

 

Cron Job Not Working

Cron jobs seem to be one of the things I have to do often that give me trouble. That's why I'm putting together this guide full of troubleshooting tips for people having problems with cron jobs.

Just today, for example, I wasted several hours figuring out why my cron job didn't seem to be working and here is what happened:

I set up my cron job exactly as I always do according to my own tutorial I posted here:

Linux Cron Job Tutorial

however, it didn't seem to be working so I tried chaing the shebang, changing the php location, etc. with no luck at all.

The Solution

Finally after hours of wasting time, I figured out that the output of my cron job was not going where I thought it would go. For example, my test script created a file and wrote a line to that file to show the cron job ran. My cron test PHP file looked like this:

crontest.php:

<?php

#!/usr/bin/php
<?php
$myFile = "cronresults.txt";
$fh2 = fopen($myFile, 'a') or die("can't open file to append");
$stringData = "appended text from cron job...\n";
fwrite($fh2, $stringData);
fclose($fh2);
?>

Simple, right? well the trick is the $myFile variable works as expected in that it creates the file in the same directory as crontest.php when crontest is called from a web browser. So when I opened up Firefox and went to mysite.com/crontest.php, it worked fine, it would create a file named cronresults.txt in my public_html folder and write a simple line of text to it. However. HERE IS THE TRICKY PART! I call the script in crontest.php from a cron tab by adding the following line in crontab -e:

* * * * * /usr/bin/php   /var/www/mysite.com/public_html/crontest.php

but when I call it that way and look for the cronresults.txt file or look for the line of text it added to the file if it already exists, there is nothing so it appears as if the cron job didn't work! Oh damn! I say. Then I try everything I can think of to fix it. The problem is that is was never broken! When you call a PHP script from a cron job and you do not specify the file path of the results file, it assumes the current users home folder! Therefore, it was working the whole time, but was creating and writing to a file in my /home/root directory because that's the directory I called crontab -e from! THerefore my solution was as simply as replacing the $myFile line with this:

$myFile = "/var/www/mysite.com/public_html/cronresults.txt";

WHEN YOU USE THE ENTIRE PATH IT WORKS AS EXPECTED! I can't over emphasize the importance of this because I wasited several hours due to not knowing this.

Cron Job Troubleshooting Tips

  • Always use a simple test script to test cron jobs for the first time on a new server. You can use my example crontest.php script above, but be careful to set the $myFile variable with the entire path to the output file or you'll have the same problem I wrote about above in this post.
  • Always use a very simple command line in crontab when first testing your cron job. You can customize it after you get it working. I use something like:                               * * * * *  /usr/bin/php  /path/to/cron/crontest.php      then crontest.php will be executed every minute so you can quickly see if it is working. This makes testing and debugging much easier.
  • Can't figure out your Shebang or don't know where PHP is on your server? Then simply go to a command prompt on your server using putty remotely or any command prompt if you are on your own server and type the following command: "which php" without the quotes. That will give you the path to php for both your shebang and your crontab file, like where it says /usr/bin/php in my examples above.

How to Use PHP SESSION Variables in a WordPress Plugin

I was writing a WordPress plugin today that required me to use PHP SESSION variables so the app could save variables across multiple runs of the application. So at first, I tried using SESSION variables in my PHP code just like I would with any other PHP application outside of WordPress, but it failed. So read on for the solution I found that works perfectly and is as simple as adding three lines of code to your plugin or functions.php file.

Add this code to your main plugin file or theme's functions.php file:

function register_session(){
    if(!session_id()) session_start();
}
add_action('init','register_session');

Those four magic lines of code was all I had to add to my main plugin file to make the following code work:

<?php
// Start the session
session_start();

    if(isset($_SESSION['timesran'])){
        $_SESSION['timesran']++;
        $runno = $_SESSION['timesran'];
    }else{
        $runno = 1;
        $_SESSION['timesran'] = 1;
    }
    echo "Run number $runno<br />";
    ?>

So each time the WordPress plugin's application is ran, it increments the timesran session variable successfully as long as I have already added the previous code snippet above to my plugin's main file. The register_session function is needed for sessions to work and should be in your plugin's index.php file or whatever file is your plugin's main file. You can then use PHP session variables in any file within your plugin.

 

How to Restart a Web Server with PHP

Today, I had the task of having to write a PHP script that restarts a web server. This is not allowed by default. It should be noted before I continue, that it is not allowed because it opens a security hole. It makes possible a server attack that would lock up your server by constantly restarting it from PHP. However, now that you're aware of the risk, if you still wish to continue. Here is how it is done:

PHP Code:

    if(exec("sudo service nginx restart")) {
            echo "server restarted!<br />";
        }else{
            echo "ERROR! Server failed to restart!<br />";
        }

Test the above code. NOTE: it is likely not to work because normally you will have to edit the sudoers file on the server.

Edit the Sudoers File to Allow PHP to Use the Restart Command

On the Linode/Nginx server I am working on currently the sudoers file can be found at /etc/sudoers. It can be found in a similar location on most Linux servers. In order to edit the sudoers file on a Linux NGINX server, simply open the file and add the following to the end of the file and save it before restarting the web server:

www-data ALL=(ALL) NOPASSWD: /usr/sbin/service nginx start,/usr/sbin/service nginx stop,/usr/sbin/service nginx restart

Note that your server may require you to edit the sudoers file with visudo.

 

 

Extending WordPress XML-RPC Functions

XML-RPC is a great, somewhat little-known feature of WordPress that is perfect for accomplishing many remote tasks with WordPress. I have found it to be a valuable asset during plugin development. While there are numerous function built in to the XML-RPC WordPress library already, we are going to focus solely on extending the XML-RPC library to accomplish almost any remote WordPress tag you wish to. The focus of this article is going to be on using XML-RPC as a communication layer between two WordPress sites on different servers. The two sites could be on the same server, but it is important to know that they do not have to be.

Basic code to extend WordPress XML-RPC

function wp_testXMLRPC() {
$returnme = "XML-RPC is working!";
return $returnme;
}//end wp_testXMLRPC extended XML-RPC function

function wp_extend_xmlrpc_methods($methods) {
    $methods['wp.testXMLRPC'] = 'wp_testXMLRPC';
    return $methods;   
}//end wp_extend_xmlrpc_methods
add_filter('xmlrpc_methods', 'wp_extend_xmlrpc_methods');

That's it! Add that code to your plugin file or theme's functions.php file and you have successfully extended WordPress' XML-RPC capabilities by adding a test function to test communication between two WordPress websites. Next I'll show you how to use this code from another WordPress site. We can call the wp_testXMLRPC function from another WordPress website and it will return "XML-RPC is working!" if the XML-RPC functions are currently working on both WordPress sites involved.

Calling an XML-RPC function from another WordPress website

To call our custom extended XML-RPC function above from another WordPress site, we would make a custom page template or plugin file and add the following code where you want to display the results of the test_XMLRPC function:

<?php

$rpcurl = "http://example.com/xmlrpc.php";//URL of site with custom XML-RPC function
$request = xmlrpc_encode_request('wp.testXMLRPC');//wp_testXMLRPC = wp.testXMLRPC
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_URL, $rpcurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$results = curl_exec($ch);
curl_close($ch);

echo "<p>Results of XML-RPC wp_testXMLRPC function: $results</p>";//output results

?>

That's really all there is to it. However this is a simple function. It is also possible to create functions that accept and return parameter data and do complex WordPress actions etc.

How to pass parameters to an extended XML-RPC function and return values

The real power of XML-RPC becomes clear when you add the ability to pass values back and forth from one WordPress website to another! Soon we will examine how to pass a single parameter to an XML-RPC extended function. First, let's look at how to make the function for WordPress site one:

<?php

function wp_sayHi($arg) {
// Array of WP_User objects.
$yourName = $arg[0];
$returnme = "Hello $yourName!";
return $returnme;
}//end wp_sayHi extended XML-RPC function

?>

Then we have to add the code to extend the methods:

<php

function wp_extend_xmlrpc_methods($methods) {
    $methods['wp.sayHi'] = 'wp_sayHi';
    return $methods;   
}//end wp_extend_xmlrpc_methods
add_filter('xmlrpc_methods', 'wp_extend_xmlrpc_methods');

?>

The above two sections of code need to get added to your functions.php or plugin file on the first WordPress site, the one you want to retrieve the data from. On the second WordPress site, the one you pass the data from, you would add the following code wherever you wanted to present the results of the XML-RPC function we made:

<?php

$your_name = "Ian Lin";

$rpcurl = "http://example.com/xmlrpc.php";
$argparam = array($your_name);
$request = xmlrpc_encode_request('wp.sayHi',$argparam);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_URL, $rpcurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$results = curl_exec($ch);
curl_close($ch);

echo $results;

?>

The above code would print "Hello Ian Lin" to the screen wherever the code was called in a custom page template file or plugin file. Notice how we passed the $your_name vaiable as a parameter for the wp_sayHi function in lines 3 and 4 of the code above. $argparam puts the $your_name variable into a simple array before passing it to the $request made in the next line. Yes, XML-RPC functions accept arrays as parameters. Now let's look at what to do if you wanted to pass two or more values to an XML-RPC function.

Passing Two or More Values to an extended XML-RPC Function

Here is a valuable nugget I'll pass on to my readers that allows you to reset a user's password on WordPress site one from WordPress site two! Yes, it allows you to reset a password from another site. The function takes two parameters to work. It needs the user_login name and the new password. Here's the code that would go on WordPress site one:

<?php

function wp_syncPasswords($args) {
// Array of WP_User objects.
$userArg = $args[0];//gets user_login value passed in $args
$passArg = $args[1];//gets password from $args
//get user ID by login:
$userget = get_userdatabylogin($userArg);
$usergot = $userget->ID;//gets id of passed user
//update password:
wp_set_password($passArg, $usergot);
$returnme = $usergot."~".$userArg."~".$passArg;
return $returnme;
}//end wp_syncPasswords extended XML-RPC function

?>

There you have an XML-RPC function that allows you to actually change a user's password remotely! Pretty neat huh?

Take notice of the $returnme variable in the above wp_syncPasswords function. It returns 3 values in a string separated by a tilde character. You could use any special character to separate the values, but I find the tilde to be safe and reliable, so that's what I use a lot. I do this because you cannot return an array of values in an XML-RPC response. If I'm wrong, someone please enlighten me, but that's what I've learned from my experience anyway. Then we would simply parse out the values in the response on WordPress site two when we call the function and get $results.

Of course next to have to extend the XML-RPC methods just like we did earlier. Please note that if you already have other XML-RPC functions in your functions.php or plugin file, then you wouldn't rewrite the entire block of code to add additional functions as methods, you can simply add on to your previous functions. For example, here we'll add on to our last extended XML-RPC function from above:

<php

function wp_extend_xmlrpc_methods($methods) {
    $methods['wp.sayHi'] = 'wp_sayHi';

$methods['wp.syncPasswords'] = 'wp_suncPasswords';
    return $methods;   
}//end wp_extend_xmlrpc_methods
add_filter('xmlrpc_methods', 'wp_extend_xmlrpc_methods');

?>

Notice that this time, since we already had the wp_sayHi function extending XML-RPC previously, all we had to do is add the highlighted line to the wp_extend_xmlrpc_methods function above to make our new function valid and ready to call from another website such as WordPress site two.

Calling the wp_syncPasswords Function from a Remote WordPress Site Passing Two Parameters via XML-RPC

<?php

$userlog = "admin";//set WordPress user name
$new_pass ="YOUR_PASSWORD_HERE";//set new password
$rpcurl = "http://example.com/xmlrpc.php";
$argparam = array($userlog,$new_pass);
$request = xmlrpc_encode_request('wp.syncPasswords',$argparam);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_URL, $rpcurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$results = curl_exec($ch);
curl_close($ch);
}//end my_profile_update function by Ian L.

?>

Running the code above would change the password of the admin user to YOUR_PASSWORD_HERE, so be sure to change admin to an existing username on WordPress site one and change YOUR_PASSWORD_HERE to the value of the new password you want to set from WordPress site two. This code could go in a WordPress plugin, but probably not appropriate for a page template, however it is possible.

Notice in the above PHP code, how we passed two parameters by setting the value of $argparam to array($userlog, $new_pass). Then we pass $argparam array to WordPress site one in the XML-RPC request in the next line. It's important to note how we pass one, two, or more parameters to XML-RPC functions. Now you should know how!

Some of you might be saying, "Hey, what about the returned results?" Well, you got me, I left them out to keep the code simple. It will work as it is above, but if you wanted to show the results returned you could do so by parsing the three values from the $results variable using something like this:

<?php

$myArray = explode("~", $results);

$remoteUserID = $myArray[0];

$remoteUserLogin = $myArray[1];

$remoteUserPassword = $myArray[2];

echo "<h2>User id: $remoteUserID with user login: $remoteUserLogin has had their password reset to $remoteUserPassword on WordPress site one!</h2>";

?>

That just about covers everything you need to know about extending the XML-RPC functionality of WordPress. You can do just about anything you want with this tool of you are good with writing custom WordPress code. Happy coding!

Working with WordPress Advanced Custom Fields Image Repeater Fields

My latest WordPress project deals with remote updating of custom post types that use the Advanced Custom Fields Plugin. From here on out, I'll simply refer to this plugin as ACF since it is such a long name and ACF is the generally accepted name among WordPress developers...

I am writing this post mostly because when working with ACF and repeater fields that have a sub field type of image, I wasn't able to find sufficient documentation on the subject to complete my project. I did complete the project with a lot of trial and error and piecing together of bits of info from many sources. My goal is to document the subject as much as possible here in order to make life easier for anyone attempting to do similar tasks as I have done.

The Challenge:

My particular challenge was that I had to create a WordPress plugin that would sync posts that used a custom post type and ACF. The basic requirement was that the plugin would update several client sites with posts from a single master site. So, the master site had a custom post type named "farms" that had several ACF fields including a couple repeater fields, one of which used the "image" sub-field type which is the focus of this article. The main challenge for me was basically writing code to insert images into a post that used a repeater field that had two sub-fields(image and alt_tag) the image sub-field stored image data in an array and the alt_tag sub-field stored custom alt tag content for the image tag. Some of you might already be thinking: Why do you have an alt_tag sub-field when alt tag content is already stored in the image data array. Well, that is true. However, it was a requirement of the project, so that's what I did.

 

The solution:

How to add WordPress Advanced Custom Fields(ACF) Image Repeater Fields with PHP Code

Today's challenge is to add values to an ACF image repeater field from within a plugin or theme file using PHP code. I had a difficult time figuring this out myself due to not being able to find enough documentation on the subject, so I decided to document my findings here. I used a custom post type named "farms" with my example. You can use a regular post, page or any custom post type for your own project. Just note that wherever you see "farms" it is my custom post type and should be replaced with your own value.

Export one or more of the posts in question

A logical first step to solving this problem for me was to create an XML export file of one of the posts that I wanted to add repeater field values to. in order to accomplish this, first create a test post of the custom post type you will be working with and make sure that the repeater field is all set up using the ACF plugin. Be sure to add a minimum of two images under the repeater field so you can examine the data via the XML export file. See the image below for an example of my own test custom post type which was set up with proper data to export:

post

Now it's time to export the post you just edited. To do this from wp-admin, click on "tools/export" and select the name of your custom post type. In my case, I select "farms" and click to export the posts as in the following image:

export

Open your XML file you downloaded and search for the post by title. Once you find the title, you could extract just that one post's data by copying everything in between <item> and </item> and pasting it in a new  XML file. That makes it easier to read just the one post you are concerned with if you have a lot of posts and a long XML file to work with. Of course, this is an optional step. I have extracted my relevant post and also deleted some of the XML that wasn't relevant to the task and here are the results:

<item>
...
<wp:postmeta>
<wp:meta_key><![CDATA[your_own_farm_pics]]></wp:meta_key>
<wp:meta_value><![CDATA[2]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[_your_own_farm_pics]]></wp:meta_key>
<wp:meta_value><![CDATA[field_57ab934d407ed]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[your_own_farm_pics_0_image]]></wp:meta_key>
<wp:meta_value><![CDATA[1862]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[_your_own_farm_pics_0_image]]></wp:meta_key>
<wp:meta_value><![CDATA[field_57ab934d407ee]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[your_own_farm_pics_0_alt_tag]]></wp:meta_key>
<wp:meta_value><![CDATA[first alt tag]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[_your_own_farm_pics_0_alt_tag]]></wp:meta_key>
<wp:meta_value><![CDATA[field_57ab934d407ef]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[your_own_farm_pics_1_image]]></wp:meta_key>
<wp:meta_value><![CDATA[1861]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[_your_own_farm_pics_1_image]]></wp:meta_key>
<wp:meta_value><![CDATA[field_57ab934d407ee]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[your_own_farm_pics_1_alt_tag]]></wp:meta_key>
<wp:meta_value><![CDATA[second alt tag]]></wp:meta_value>
</wp:postmeta>
<wp:postmeta>
<wp:meta_key><![CDATA[_your_own_farm_pics_1_alt_tag]]></wp:meta_key>
<wp:meta_value><![CDATA[field_57ab934d407ef]]></wp:meta_value>
</wp:postmeta>
</item>

Once you've located your post's XML, you will want to find the portion that is relevant to your particular ACF repeater field. To do this, simply do a search for the repeater field slug name. My field was named "your own farm pics", so the slug name I would search for would be "your_own_farm_pics". The first instance you find of the repeater field name/slug will look something like this:

<wp:postmeta>
<wp:meta_key><![CDATA[your_own_farm_pics]]></wp:meta_key>
<wp:meta_value><![CDATA[2]]></wp:meta_value>
</wp:postmeta>

Due to the use of CDATA , the above may look a little more complex than it really is. For what we are doing, we can simply ignore all of the CDATA stuff so that the above would become more like this:

<wp:postmeta>
<wp:meta_key>your_own_farm_pics</wp:meta_key>
<wp:meta_value>2</wp:meta_value>
</wp:postmeta>

Basically what's in between the XML tags is this:
<![CDATA[your_own_farm_pics]]>
The part you want is in between the opening and closing brackets after the word, CDATA. The rest can be ignored. In this case, all we want is: your_own_farm_pics.

Then, to show one more example of extractig data from CDATA, the next line looks like:
<wp:meta_value><![CDATA[2]]></wp:meta_value>
and the only part we want is the part after "CDATA[", which is simply: 2

So examining the first poroption of relevent .xml code we can gather that the value of "your_own_farm_pics" is "2".

Lets look at the next portion of XML that reads:
<wp:postmeta>
<wp:meta_key><![CDATA[_your_own_farm_pics]]></wp:meta_key>
<wp:meta_value><![CDATA[field_57ab934d407ed]]></wp:meta_value>
</wp:postmeta>
...okay, from what we've learned, this is what you should extract from the above XML:
field name(or key): _your_own_farm_pics
value: field_57ab934d407ed
I hope this part is clear to you. If it is not, then you'll probably need to study an XML tutorial first to understand. But one thing you need to notice here is that the field name or key starts with an underscore, therefore it is different from the first meta key(_your_own_farm_pics instead of your_own_farm_pics).

Let's go ahead and extract all of the relevant data from the .xml file. Basically you should be able to extract something similar to the following key/value pairs from the relevant portion of XML code:

your_own_farm_pics
2

_your_own_farm_pics
field_57ab934d407ed

your_own_farm_pics_0_image
1862

_your_own_farm_pics_0_image
field_57ab934d407ee

your_own_farm_pics_0_alt_tag
first alt tag

_your_own_farm_pics_0_alt_tag
field_57ab934d407ef

your_own_farm_pics_1_image
1861

_your_own_farm_pics_1_image
field_57ab934d407ee

your_own_farm_pics_1_alt_tag
second alt tag

_your_own_farm_pics_1_alt_tag
field_57ab934d407ef

As you can see there are 4 pieces of data for each image in the repeater field. This is because there are two sub-fields in this repeater field and each sub-field uses two key/value pairs. Notice the incremented numbers starting at 0. There is only a 0 and a 1 in this example because there are two images stored in our repeater field. so all the key names containing _0_ are one image's data and then all the ones with key names containing _1_ are the second image's data.

There are three parts to each key name. Each key either starts with the repeater slug or the repeater slug preceded by an underscore. Then there is a incremented number starting at zero. Finally we have the sub-field name. Here's the pattern these sub-field key names follow:

repeater_field_name + incremented number + sub-field name

Above is the pattern for the data key. Below is the very similar patter for the field key:

underscore + repeater_field_name + incremented number + sub-field name

So knowing that, you should be able to know exactly how to read these XML files now. This also gives you a huge clue on how data is stored in the database as the key/value pairs in the XML file are exactly what is stored in the database. Therefore the values are exactly what needs to be written to the database in order to insert repeater images into a post or custom post type.

Let's examine some PHP code now. Knowing what we do about the XML file, we know what data needs inserted into the database now, so our PHP code for the example XML file above should look like this in order to insert two images into a repeater field for a single post:

Note that the below code is for adding two sets of repeater field values. The repeater field is set up with two sub fields, one image sub-field and one simple text sub-field named alt_tag.

<?php

$post_id = "1902";
//first two key/value pairs are for the repeater field name:
$key = "your_own_farm_pics";
$value = "2";
add_post_meta($post_id, $key, $value);

$key = "_your_own_farm_pics";
$value = "field_57ab934d407ee";
add_post_meta($post_id, $key, $value);

//next eight key/value pairs are for the two repeater field sub-field names:
//There are four key/value pairs for the first image and four more for the second:
//Start image one data:
$key = "your_own_farm_pics_0_image";
$value = "1867";
add_post_meta($post_id, $key, $value);

$key = "_your_own_farm_pics_0_image";
$value = "field_57ab934d407ee";
add_post_meta($post_id, $key, $value);

$key = "your_own_farm_pics_0_alt_tag";
$value = "Alt tag content for image 1";
add_post_meta($post_id, $key, $value);

$key = "_your_own_farm_pics_0_alt_tag";
$value = "field_57ab934d407ef";
add_post_meta($post_id, $key, $value);

//Start image two data:
$key = "your_own_farm_pics_1_image";
$value = "1869";
add_post_meta($post_id, $key, $value);

$key = "_your_own_farm_pics_1_image";
$value = "field_57ab934d407ee";
add_post_meta($post_id, $key, $value);

$key = "your_own_farm_pics_1_alt_tag";
$value = "Alt tag content for image 2";
add_post_meta($post_id, $key, $value);

$key = "_your_own_farm_pics_1_alt_tag";
$value = "field_57ab934d407ef";
add_post_meta($post_id, $key, $value);

?>

Of course the above PHP code would go in a custom plugin and wouldn't work as standalone php code, but you should get that if you have any experience with writing WordPress plugins and if you do not, then this topic is far to advanced for you anyway. Try one of my starter tutorials for WordPress plugin developers instead.

 

Code explained:

First, you should notice the $postid variable that gets set to the post id you want to update with repeater fields.

Then you see three lines of code setting the $key variable to "your_own_farm_pics" which you will change to the name of your own repeater field name. The value of this needs to be equal to the number of repeaters you want to add. In this case, we are adding 2 images, so we set the value to 2.

Next you see the key of _your_own_farm_pics. This is the field value that is set in the database and is crucial in identifying the repeater field correctly, so be sure to get this right. Do an export of the database and search for the repeater field name to find the value for this if you have to. All you have to do it export the database as  XML and do a text search for the field name and you'll see the value right below it. The code above uses the XML example code posted above in this post.

The next important section of code, where the comment says "//next eight key/value pairs are for the two repeater field sub-field names:", is where you will have eight  sections with 3 lines of code each for the two image repeaters you add.  The important part to notice here is the numbering system used. Notice that the the first four sections of code have a zero in the keys, for example:

$key = "your_own_farm_pics_0_image";

So the value of the $key variable in the above example is made up of three parts:

  1. repeater field name: your_own_farm_pics
  2. incremented number: 0
  3. sub-field name: image

In this example, my repeater field name is "your_own_farm_pics",  the numbers start at 0 and go as high as the total number of repeater fields you add, the sub-field name in this case is "image".

Then, skip down three more lines to where you see the code:

$key = "your_own_farm_pics_0_alt_tag";

this is the second sub-field for the first repeater. so we follow the same principle as we did with the first sub-field which was image. The second sub-field name in this case is alt_tag, so we have:

  1. repeater field name: your_own_farm_pics
  2. number: 0
  3. sub-field name: alt_tag

That covers the first repeater field with it's two sub-fields. Then we want to add another repeater field with the code starting at the comment that reads: "//Start image two data:".

Notice that the number in the two $key variables has incremented to 1 in the second image's code because the numbering starts at 0 and this is the second repeater or image added.

 Summary

I hope this article sheds some light on this dimly illuminated topic dealing with Advanced Custom Fields plugin and programming your own plugin to work with it. I had a very difficult time digging up enough information to piece the above code together myself, so I truly hope this helps someone attempting to do the same thing.

 

 

Passing PHP Variables to File included with get_template_part WordPress Function

Today I had a problem where I had a WordPress page template that used get_template_part to include a section of the page like WordPress themes often do. My problem was that I did some custom coding to the theme and found it necessary to pass a variable to the file included using get_template_part.

The Problem

Let's say you have a custom page template for showing search results called special-search.php. Now let's also say that the actual search results are displayed using another template file named content-searching.php. inside of special-search.php we would normally include the content-searching.php file something like this:

get_template_part( 'template-parts/content', 'searching' );

What's wrong with that? Well, nothing unless you need to use PHP variables from special-search.php inside of content-searchnig.php. Then we have a problem. Read on for the simple solution!

Making it Possible to Pass PHP Variables to Template Parts:

The solution is actually to simply not use the get_template_part function! We can very effectively replace get_template part with a combination of the common PHP include function and the WordPress locate_template function like this:

include(locate_template('template-parts/template-name.php', $load, $require_once));

As you can see the locate_template function is called inside of the include function and locate_template takes three parameters. While, you really only need to use the first parameter in many cases, it is good to know what the other two do as well, so here are all three parameters defined:

  1. 'template-parts/template-name' - will be changed to the path and filename to your template file you used to include with get_template_part. In our example case above, this parameter would get set to 'template-parts/content-searching.php'.
  2. $load - is an optional Boolean parameter that would be set to either true or false, but which is set to false by default which is the desired setting in this case. This parameter tells the function whether or not to load the template file. We don't want the template to be loaded by locate_template since it will get loaded by the include function in this case. So if we include this parameter, we would set it to false.
  3. $require_once - is the third parameter which is also optional and set to true by default. It simply determines whether we use require_once or require to include the template file. true = requrie_once and false = require.

Example Usage:

Still using our test case scenario from above, here is how we would use the include and locate_template function together to replace get_template_part and hence be able to use variables defined in the parent file inside of the template part file. Above we said we had a template file named special-search.php that used get_template_part to include a template part file named content-searching.php. Below I will demonstrate the change that would need to be made:

Change this line:

get_template_part( 'template-parts/content', 'searching' );

into this line:

include(locate_template('template-parts/content-searching.php'));

Notice how get_template_part doesn't use the actual whole filename due to it's unique naming convention rules, but our second method however must use the whole filename. Both cases call the same file however. If you change get_template_part into the include statement shown in our example, then you will now be able to use variables defined in special-search.php within content-searching.php. Problem solved!

How to add Custom Admin Meta Boxes to a WordPress Custom Post Type

I decided to write this detailed tutorial on how to add custom field meta boxes to the WordPress admin mostly because I couldn't find a decent description of how to do it anywhere online. Hopefully this will help others having trouble trying to learn how to add admin meta boxes with custom fields for a custom post type in WordPress. It is an essential step to learning WordPress plugin development.

Let's dive in and learn some code because I believe that is the quickest and easiest way to learn this advanced WordPress method. I say it is an advanced subject because it is a little complex for beginners. If you are not sure how to start your own plugin yet in WordPress, then this topic may be too advanced for you. You should at least learn how to make a very basic WordPress plugin first, so feel free to read one of my more basic WordPress plugin tutorials first.

First of all, I'll show you how to add a single meta box with a single field in it. It is also important to know that you can have more than one field inside a single meta box. It is equally important to know that you can have more than one meta box. Each meta box can have one or more fields in them. It just depends on your individual needs. Below is the basic code for how to add a custom post type with a custom field inside of an admin meta box. I'll also include a basic plugin heading so you may follow along and create a working example to work from:

Adding a Custom Post Type to WordPress Plugin

<?php
/**
 * Plugin Name: Jafty Metabox Example Plugin
 * Plugin URI: http://jafty.com/blog/crash-course-on-wordpress-plugin-development/
 * Description: A Plugin that adds metaboxes to your WordPress blog or site.
 * Version: 1.0
 * Author: Ian L. of Jafty.com
 * Author URI: http://jafty.com
 * License: GPL2
 */
 

 //Add new Custom Post Type named videos:
add_action('init', 'create_video_posttype');
function create_video_posttype(){
    register_post_type('videos',
        array(
            'labels' => array(
            'name' => __('Videos'),
            'singular_name' => __('Video')
            ),
        'public' => true,
        'has_archive' => true,
        'rewrite' => array('slug' => 'video'),
        )
    );
}//end create_video_posttype function

?>

Okay, now start a .php file and add the above code in green to the start of it. Name the file "jafty-metabox-example-plugin.php" and save it. Please NOTE: it is important to go into wp-admin/settings/permalinks and re-save those settings after activating a plugin with a custom post type or after adding a custom post type to a plugin. If you do not do this, the custom post type posts will not show up on the front end of your blog.

At this point, you should be able to upload the jafty-metabox-example-plugin.php file to your WordPress site's plugins folder and activate it. If it works, you'll see a new "Video" option in the left navigation menu of wp-admin as in the following photo:

videoCPT

Add a Metabox with a Custom Field to your CPT

Now here is the code to add to the end of the file you started above(just before the closing PHP tag) that will add a meta-box with a custom field inside of it to your plugin. It adds a field to the wp-admin edit screen for the videos CPT(custom post type):

//Add custom admin Meta Boxes:
add_action('add_meta_boxes', 'add_ians_metaboxes');
function add_ians_metaboxes(){
//add meta box for Video type and description:
add_meta_box('meta_box_html_id', 'Video Details', 'video_details_function', 'videos', 'normal', 'high');
}

//##################### Video Details Metabox: ################
function video_details_function() {
global $post;  
//Noncename needed to verify where the data originated
echo '<input type="hidden" name="eventmeta_noncename" id="eventmeta_noncename" value="' .
wp_create_nonce(plugin_basename(__FILE__)) . '" />';

//Get video description data if its already been entered
$video_desc = get_post_meta($post->ID, '_video_desc', true);
    
//Start video Description text field HTML:
?>
Video Description:
<input type="text" name="video_desc" value="<?php echo $video_desc; ?>" class="widefat" />
<?php
}//end video_details_function

Save the "jafty-metabox-example-plugin.php" file and update it on your site and click on the "Video" link in wp-admin and then click on "Add New" to see the add/edit screen for your new CPT. You will notice your  custom meta-box with the heading of "Video Details". You will also notice the meta-box contains a custom field named "Video Description". You can see both near the bottom of the photo below:

customField

Saving Custom Field Data

Your not quite done however. While the code above will display the metaboxes, it does not save the data as I soon discovered. To save the data, you'll need to add this code directly after your video_details callback function:

//hook into save_post to save the meta box data:
add_action ('save_post', 'save_video_desc');

function save_video_desc($post_id) {
//verify the metadata is set
     if (isset( $_POST['video_desc'])) {
     //save the metadata
     update_post_meta ($post_id, '_video_desc', strip_tags($_POST['video_desc']));
     }
}

 

 Adding Multiple Meta-Boxes and Custom Fields

Next I'll show you what out final plugin file would look like if we were to add another custom field to our meta-box and then another meta-box with yet another custom field inside of it. This way you can see how more than one meta-box is added and also how to add more than one field inside of a single meta-box. Here is the complete plugin code containing a total of two meta-boxes and three total custom fields:

<?php
/**
* Plugin Name: Jafty Metabox Example Plugin
* Plugin URI: http://jafty.com/blog/crash-course-on-wordpress-plugin-development/
* Description: A Plugin that adds metaboxes to your WordPress blog or site.
* Version: 1.0
* Author: Ian L. of Jafty.com
* Author URI: http://jafty.com
* License: GPL2
*/

//Add new Custom Post Type named videos:
add_action('init', 'create_video_posttype');
function create_video_posttype(){
register_post_type('videos',
array(
'labels' => array(
'name' => __('Videos'),
'singular_name' => __('Video')
),
'public' => true,
'has_archive' => true,
'rewrite' => array('slug' => 'video'),
)
);
}//end create_video_posttype function

//Add custom admin Meta Boxes:
add_action('add_meta_boxes', 'add_ians_metaboxes');
function add_ians_metaboxes(){
//add the first meta box for Video type and description:
add_meta_box('meta_box_html_id', 'Video Details', 'video_details_function', 'videos', 'normal', 'high');
//add a second meta box for Video Rating
add_meta_box('meta_box_html_id2', 'Video Rating', 'video_rating_function', 'videos', 'normal', 'high');
}
//################## Video Details Metabox: ####################
function video_details_function() {
global $post;

//Noncename needed to verify where the data originated
echo '<input type="hidden" name="eventmeta_noncename" id="eventmeta_noncename" value="' .
wp_create_nonce(plugin_basename(__FILE__)) . '" />';

//Get the video type  if its already been entered
$video_type = get_post_meta($post->ID, '_video_type', true);
// Get the video description if its already been entered
$video_desc = get_post_meta($post->ID, '_video_desc', true);

//Start type select field HTML:
?>
Video Type: <select name="video_type">
<option value="DVD"<?php if($video_type=="DVD")echo " selected";?>>DVD<option>
<option value="Blueray"<?php if($video_type=="Blueray")echo " selected";?>>Blueray<option>
</select><br />
<?php
// Start video description field HTML:
?>
Video Description:
<input type="text" name="_location" value="<?php echo $video_desc; ?>" class="widefat" />
<?php
}//end video_details_function
//##################### Video Rating Metabox: ###################
function video_rating_function() {
global $post;

//Noncename needed to verify where the data originated
echo '<input type="hidden" name="eventmeta_noncename" id="eventmeta_noncename" value="' .
wp_create_nonce(plugin_basename(__FILE__)) . '" />';

//Get the start_month data if its already been entered
$video_rating = get_post_meta($post->ID, '_video_rating', true);

//Start type select field HTML:
?>
Video Type: <select name="_video_rating">
<option value="R"<?php if($video_rating=="R")echo " selected";?>>R<option>
<option value="PG"<?php if($video_rating=="PG")echo " selected";?>>PG<option>
</select><br />
<?php
}//end video_rating_function
?>

//add your save data hook and function to save all fields here:

//hook into save_post to save the meta box data:
add_action ('save_post', 'save_video_data');

function save_video_data($post_id) {
//verify the metadata is set
     if (isset( $_POST['video_desc'])) {
     //save the metadata
     update_post_meta ($post_id, '_video_type', strip_tags($_POST['video_type']));

    update_post_meta ($post_id, '_video_desc', strip_tags($_POST['video_desc']));

    update_post_meta ($post_id, '_video_rating, strip_tags($_POST['video_rating']));
     }
}

That's it! Save the above code in a PHP file and name it the same name as before and allow it to overwrite the original plugin file if you were following along and it will add another meta-box and a couple more custom fields to your custom post type. Now you should have enough information to be able to make your own custom admin meta-boxes and fields for your next WordPress plugin or theme. Here is an image of the two meta-boxes from when I tested the above code myself:

metaboxes

Summary

Now you should know more than enough to make your own plugin or custom theme with its own admin meta-boxes and custom fields for any custom post types you may have. It is important to know that you can also use any other type of form element in the above examples. Feel free to experiment and use textareas, radio buttons, checkboxes etc in your own code.