Category Archives: Software Testing & Debugging

How to Figure Out Relative Humidity with PHP

Today, I had to calculate relative humidity using PHP and I have documented my findings below:

First, let's just use an example situation where we have a temperature of 60.1 and a dew point of 42.7, both in Fahrenheit, so...:

dew point in Fahrenheit: 42.7

temperature in Fahrenheit: 60.1

1) The first step is to convert to Celsius using the following formulas
Tc=5.0/9.0*(Tf-32.0)

Tdc=5.0/9.0*(Tdf-32.0)

Formulas explained:
Tc=air temperature in degrees Celsius, Tf=air temperature in degrees Fahrenheit

Tdc=dewpoint temperature in degrees Celsius

Tdf=dewpoint temperature in degrees Fahrenheit

Notice: If your temperature and dewpoint are in degrees Celsius, you can skip step 1 and proceed to step 2.

answer for equations:
Temp in Celsius: 15.61

Tc=5.0/9.0*(Tf-32.0)
5.0/9.0*(60.1-32.0)
5.0/9.0*28.1
0.5555555555555556 * 28.1 = 15.61111111111111

dewpoint in Celsius: 5.94
5.0/9.0*(Tdf-32.0)
5.0/9.0*10.7
0.5555555555555556 *  10.7 = 5.944444444444444

2) calculate saturation vapor pressure(Es) and actual vapor pressure(E) in millibars:
NOTE: first line is the equation and the subsequent lines represent one step solved at a time:
Es=6.11*10.0**(7.5*Tc/(237.7+Tc))
Es=6.11*10.0**(7.5*15.61/(237.7+15.61))
Es=61.1 ** (7.5*15.61/(237.7+15.61))
Es=61.1 ** (117.075/253.31)
Es = 61.1**0.4621807271722395
Es = 6.6907349413770067935260257174923

E=6.11*10.0**(7.5*Tdc/(237.7+Tdc))
E=6.11*10.0**(7.5*5.94/(237.7+5.94))
E=61.1 ** (7.5*5.94/(237.7+5.94))
E=61.1 ** (44.55/243.64)
E=61.1 ** 0.1828517484813659497619438515843
E = 2.1211957981192776150462474985589

3)  Once you have the saturation vapor pressure and actual vapor pressure, relative humidity(RH) can be computed by dividing the actual vapor pressure by the saturation vapor pressure and then multiplying by 100 to convert the quantity to a percent:
RH =(E/Es)*100
RH =(2.1211957981192776150462474985589/6.6907349413770067935260257174923)*100
RH = 0.31703479762758596814611114744566 * 100
RH = 31.703479762758596814611114744566%
SO... Humidity is 31.7%

And note here that ** means to the power of. I figured I'de clue anyone in that is as ignorant is I was when I had to figure it out.

How to Search and Replace File Names

A lot of times I am required to rename large quantities of files according to various rules. Sometimes this task can take hours to complete. Today I had a job requiring me to rename all files in a program that contained "xi" with "nap". The program had thousands of files in a dozen different directories. It would have taken days for me to go through them all manually and replace ea. occurrence of "xi" in the file names with "nap", so I tested several tools to help me do the job. The most capable tool I found was named simply "ReNamer" and can be downloaded from:
https://www.den4b.com/products/renamer

I downloaded the "portable" version of ReNamer version 6.7 Here is a screenshot of ReNamer's simply UI:
ReNamer

How to Download and Open ReNamer for First Use

First things first, so here is how to get started:

Use the link https://www.den4b.com/products/renamer to download the portable version of ReNamer and it will download a zip file to your PC. Place the file on your desktop and right click it and select "Extract All". Windows will extract the files and probably open the folder for you. Then click on renamer.exe to start the app. You will see the UI as in the above image. I like using this portable version because it is very light-weight and can be used on any PC. When I'm done using it, I simply delete the entire unzipped folder but I save the .zip folder I downloaded so I can use it again when needed and it doesn't waste any space on my PC when it's not in use. Next time I need it, I simply extract the files again and use it. Then I delete the folder when done again.

Find and Replace Text in File Names of Many Files at Once

It is easy as pie to use too! It only took me a couple of test runs to achieve the renaming rules I needed to do the job at hand. Just  click where it says "Click here to add a rule" and add a rule. I needed to find and replace text in the file names, so in my case, I clicked on "replace" in the left panel so the add rule screen looks like this:

renamerules

 

All I had to do was simply enter "xi" in the "find" field and "nap" in the "replace" field and click the "Add Rule" button to save your new rule. Then all you have to do is drag the folder containing all the files you want to rename into the UI as in the first image above, where it says "Drag Your Files Here". Then it gives you a preview of what files it will rename. Once you are happy with how it's doing the renaming, click the "Rename" button in the upper right corner of the UI and it will rename all of the files just like it showed you. If you have tested any of the other features of this tool, please comment below and describe your experience!

Understanding ARIA Click Button to Show or Hide Content Example Code

Understanding ARIA

ARIA stands for "Accessible Rich Internet Applications". Also known as the WAI-ARIA standard, it is a standard developed to help coders to provide proper semantics for custom widgets and to make them accessible, usable, and interoperable with assistive technologies for people with disabilities. To be clear, ARIA doesn't add functionality to an object. It adds roles and states that assist in identifying the intent and state of an object. However, usually JavaScript code is still needed to add any dynamic action to that object. I state this clearly at the top of this post because at first, I was under the impression that ARIA also added certain functionalities to HTML objects and was seriously disappointed when I found out otherwise. For example, when ARIA is used on a button that hides and shows content in a div, it only defines the roles and states of the button and corresponding div. JavaScript is still needed to do that work of hiding and showing the div in question.

Example Code

Here is an example of correctly implementing ARIA controls when making a button that hides and shows a div on the click of your mouse. It also binds the space bar and enter key to the div as well, so pressing either of those keys toggles the visibility of the div as well. Without any further ado, the code:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Aria Examples</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<style>
div.topic {
    display: none;
    margin-bottom: 1em;
    padding: .25em;
    border: black thin solid;
    background-color: #EEEEFF;
    width: 40em;
}
</style>
</head>
<body>

<p class="button">
    <button id="button1" class="buttonControl" aria-controls="t1" aria-expanded="false"><span>Show</span> Topic 1</button>
</p>

<div id="t1" class="topic" role="region" tabindex="-1" >
    Topic 1 is all about being Topic 1 and may or may not have anything to do with other topics.
</div>

<script>
$(document).ready(function() {

   var hs1 = new hideShow('button1');
  // var hs2 = new hideShow('button2');
  // var hs3 = new hideShow('button3');
  // var hs4 = new hideShow('button4');
 
}); // end ready()

//
// function hideShow() is the constructor for a hideShow widget. it accepts the html ID of
// an element to attach to.
//
// @param(id string) id is the html ID of the element to attach to
//
// @return N/A
//
function hideShow(id) {

   this.$id = $('#' + id);
   this.$region = $('#' + this.$id.attr('aria-controls'));

   this.keys = {
               enter: 13,
               space: 32
               };

   this.toggleSpeed = 100;

   // bind handlers
   this.bindHandlers();

} // end hidShow() constructor

//
// Function bindHandlers() is a member function to bind event handlers to the hideShow region
//
// return N/A
//
hideShow.prototype.bindHandlers = function() {

   var thisObj = this;

   this.$id.click(function(e) {

      thisObj.toggleRegion();

      e.stopPropagation();
      return false;
   });
}

//
// Function toggleRegion() is a member function to toggle the display of the hideShow region
//
// return N/A
//
hideShow.prototype.toggleRegion = function() {

      var thisObj = this;

    // toggle the region
    this.$region.slideToggle(this.toggleSpeed, function() {

      if ($(this).attr('aria-expanded') == 'false') { // region is collapsed

        // update the aria-expanded attribute of the region
        $(this).attr('aria-expanded', 'true');

        // move focus to the region
        $(this).focus();

        // update the button label
        thisObj.$id.find('span').html('Hide');

      }
      else { // region is expanded

        // update the aria-expanded attribute of the region
        $(this).attr('aria-expanded', 'false');

        // update the button label
        thisObj.$id.find('span').html('Show');
      }
    });

} // end toggleRegion()
</script>
</body>
</html>

Thank you oaa-accessibility.org for providing me with enough knowledge to create and use the above example! They have the best example code for ARIA usage that I could find online after many Google searches. See their complete list of example ARIA examples at http://oaa-accessibility.org/

ARIA and WordPress

I noticed ARIA controls for the first time in the header.php file for my WordPress theme. I was trying to fix a mobile navigation menu and thought couldn't find the code that makes the menu appear on mobile devices when the button is clicked and thought ARIA had something to do with it. I was basically wrong. ARIA code was only present to mark the navigation menu and make it's role and states readily accessible. It is after all an accessibility feature.

Summary

So ARIA and the WAI-ARIA standard are used to enable more accessible HTML markup for disabled people. While it is a great initiative, it doesn't add much dynamic functionality to your HTML objects, JavaScript is still needed for that. ARIA combined with HTML, CSS and JavaScript can be used to make accessible web pages more user-friendly.

Get IP Address from Domain Name

Here is a simple little tool written in PHP that will return the IP address of any given domain name or if there are more than one, a list of IP addresses will be returned.

 

Get Domain Name's IP Address

Returns the IP address associated with the domain name you enter into the form. It will return a list of IP addresses if more than one is associated with the given domain name.


Get Domain Name's IP Address

Returns the IP address associated with the domain name you enter into the form. It will return a list of IP addresses if more than one is associated with the given domain name.

Domain name:

 

PHP Function explode

The PHP explode function is one of the most used PHP functions, at least by me. It is used to turn a string into an array. Let's say you had the following string:

$str = "Pizza, Pork, Ham, Sub, Chicken, Lamb, Rice, Noodles";

You can very easily turn such a string into an array using the PHP explode function like this:

$foods = explode(",", $str);

Now you have the equivalent of this:

$foods = array('Pizza', 'Pork', 'Ham', 'Sub', 'Chicken', 'Lamb', 'Rice', 'Noodles');

Here is a complete PHP example that demonstrates the use of explode:

$str = "Pizza, Pork, Ham, Sub, Chicken, Lamb, Rice, Noodles";

$foods = explode(",", $str);

foreach($foods as $food){

echo $food."<br />";

}

The above example simply uses explode to break the $str string into the $foods array by splitting the string up by the commas.

Arguments

The PHP explode function takes two arguments:

explode('split-by', $string);

  • split-by - can be any value in $string that you want to separate the string into an array by.
  • $string - is the string you want to turn into an array.

Summary

This post should give you a good idea of how to use the explode function. If not, feel free to post your comments on this post and I'll be happy to explain. Also, feel free to publish your own example code that users explode in the comments.

How to Remove Slugs for a Custom Post Type in WordPress

So, back in the day, not to long ago, one could remove slugs in a CPT(Custom Post Type), simply by adding the following line to the arguments array when calling the register_post_type function:

'rewrite' => array('slug' => ''),//NOT THE SOLUTION!

However, that no longer works as of WordPress version 4.7.?, so I put together the following two function from various other solutions I've seen. This solution works for a single post type or multiple post types. I am publishing it because I haven't seen any elsewhere that could handle more than one CPT at a time. I wrote this to remove slugs for two CPTs, but you could us it for one or as many as you want, the two functions are as follows and can be added to functions.php or, as I do, to a plugin file, below the register_post_type functions:

<?php

//Two functions to remove slug from team_member and event CPTs:
function remove_evil_slugs($post_link, $post, $leavename) {

    if('team_member' != $post->post_type || 'event' != $post->post_type ||'publish' != $post->post_status) {
        return $post_link;
    }

    $post_link = str_replace('/' . $post->post_type . '/', '/', $post_link);

    return $post_link;
}
add_filter('post_type_link', 'remove_evil_slugs', 10, 3);

function  parse_evil_slugs($query) {

    if(!$query->is_main_query() || 2 != count($query->query) || !isset($query->query['page'])) {
        return;
    }

    if(!empty($query->query['name'])) {
        $query->set('post_type', array('post', 'team_member', 'event', 'page'));
    }
}
add_action('pre_get_posts', 'parse_evil_slugs');

?>

Those are the two functions that accomplish the goal. Simply replace all occurrences of "team_member" and "event" with the names of your own custom post types. If you use any rewrite rules in the args parameter for the register_post_type function, comment it out. For example if you see anything that looks like this:

'rewrite' => array('slug' => ''),

or

'rewrite' =>false,

...either comment it out of delete it all together from the function that creates the custom post type(CPT).

Update 3-27-2017

I've noticed that on some servers, the above solution no longer works, so I was able to program a new solution for NGINX servers. If your server is not an NGINX server, I found a solution here that should work for all even though it is a bit outdated: https://github.com/jonbish/remove-slug-from-custom-post-type. The code below is code I wrote based on that link but updated for nginx servers:

<?php
class JAFTY_CPT_SlugKiller{
    
    static $_s = null;
    private $htaccess_tag = 'SLUG KILLER REMOVE SLUG RULES';
    
    public function __construct() {
        $this->rewrite_rules();
        
        add_action('wp_insert_post', array(&$this, 'post_save'));

        add_filter('post_type_link', array(&$this, 'remove_slug'), 10, 3);
        
    }
    
    
    static public function init() {
        if (self::$_s == null) {
            self::$_s = new self();
        }
        return self::$_s;
    }
    
    static public function flush_rewrite_rules() {
        $jafty_o = self::init();
        $jafty_o->rewrite_rules(true);    
        //$jafty_o->add_rules_htaccess();
    }

    public function post_save($post_id) {
        global $wp_post_types;
        $post_type = get_post_type($post_id);
        foreach ($wp_post_types as $type=>$custom_post) {
            if ($custom_post->_builtin == false && $type == $post_type) {
                $this->rewrite_rules(true);
                //$this->add_rules_htaccess();
                flush_rewrite_rules();
            }
        }
    }
    
    public function remove_slug($permalink, $post, $leavename) {
        global $wp_post_types;

        foreach ($wp_post_types as $type=>$custom_post) {
            if ($custom_post->_builtin == false && $type == "team_member") {
                $custom_post->rewrite['slug'] = trim($custom_post->rewrite['slug'], '/');
                $permalink = str_replace(get_bloginfo('url') . '/' . $custom_post->rewrite['slug'] . '/', get_bloginfo('url') . "/", $permalink);
            }
        }
        return $permalink;
    }
    
    public function rewrite_rules($flash = false) {
        global $wp_post_types, $wpdb;
        foreach ($wp_post_types as $type=>$custom_post) {
            if ($custom_post->_builtin == false && $type == "team_member") {
                $querystr = "SELECT {$wpdb->posts}.post_name
                                FROM {$wpdb->posts}
                                WHERE {$wpdb->posts}.post_status = 'publish'
                                        AND {$wpdb->posts}.post_type = '{$type}'
                                        AND {$wpdb->posts}.post_date < NOW()";
                $posts = $wpdb->get_results($querystr, OBJECT);
                foreach ($posts as $post) {
                    $regex = "{$post->post_name}\$";
                    add_rewrite_rule($regex, "index.php?{$custom_post->query_var}={$post->post_name}", 'top');            
                }
            }
        }
        if ($flash == true)
            flush_rewrite_rules(false);
    }
    
    
    private function add_rules_htaccess() {
        global $wp_post_types;
        $suffix = get_option('jafty_permalink_customtype_suffix');
        $write = array();
        $htaccess_filename = ABSPATH . '/.htaccess';
        if(is_readable($htaccess_filename)){
            $htaccess = fopen($htaccess_filename, 'r');
            $content = fread($htaccess, filesize($htaccess_filename));
            foreach ($wp_post_types as $type=>$custom_post) {
                $rewrite_rule = (!empty($suffix))
                            ? "RewriteRule ^{$custom_post->query_var}/(.+)/\$ /\$1\.{$suffix} [R=301,l]"
                            : "RewriteRule ^{$custom_post->query_var}/(.+)/\$ /\$1 [R=301,L]";
                if (strpos($content, $rewrite_rule) == false && $custom_post->_builtin == false)
                    $write[] = $rewrite_rule;
            }
            fclose($htaccess);
        }else{
            add_action('admin_notices', array(&$this, 'compatibility_notice'));
            return;
        }
        
        if (!empty($write) && is_writable($htaccess_filename)) {
            $new_rules = '# BEGIN ' . $this->htaccess_tag . PHP_EOL;
            $new_rules .= str_replace('$', '\\$', implode(PHP_EOL, $write)) . PHP_EOL;
            $new_rules .= '# END ' . $this->htaccess_tag;
            if (strpos($content, "# BEGIN {$this->htaccess_tag}") === false) {
                file_put_contents($htaccess_filename, $new_rules . PHP_EOL . PHP_EOL . $content);
            }
            else {
                $pattern = "/# BEGIN {$this->htaccess_tag}.*?# END {$this->htaccess_tag}/ims";
                $content = preg_replace($pattern, $new_rules, $content);
                file_put_contents($htaccess_filename, $content);
            }
        }else if(!is_writable($htaccess_filename))
            add_action('admin_notices', array(&$this, 'compatibility_notice'));
    }//end add_rules_htaccess function

    
    public function compatibility_notice() {
        global $wp_post_types;
        $rules = '';
        foreach ($wp_post_types as $type=>$custom_post) {
            if ($custom_post->_builtin == false && $type == "team_member") {
                $slug = str_replace('/', '', $custom_post->rewrite['slug']);
                $rules .= 'RewriteRule ^' . $slug . '/(.+)$ /$1 [R=301,L]<br />';
            }
        }
        
        echo '<div class="error fade" style="background-color:red;"><p><strong>Remove Slug Custom post type error!</strong><br />.htaccess is not writable, please add following lines to complete your installation: <br />'.$rules.'</p></div>';
    }
}//End JAFTY_CPT_SlugKiller class to remove slugs from team_member CPT

//actions and hooks for above class to remove slug from team_member CPT:
add_action('init', array('JAFTY_CPT_SlugKiller', 'init'), 99);
//the following two lines make it so you don't have to manually go to settings/permalinks and re-save settings for links to work:
register_activation_hook( __FILE__, array('JAFTY_CPT_SlugKiller', 'flush_rewrite_rules') );
register_deactivation_hook( __FILE__, array('JAFTY_CPT_SlugKiller', 'flush_rewrite_rules') );
//END CODE TO ENABLE NO SLUG FOR team_member CPT

?>

The above code can be added to a plugin file or your themes functions.php.

NOTE: although the above code hasn't been thoroughly tested on non-nginx servers, it should work if you un-comment the two lines that call the add_rules_htaccess function. Simply do a search for "add_rules_htaccess" and remove the "//" before it in two occurrences and this code should work on any server as long as your .htaccess file is writable.

Get the Nth Weekday of Any Month and Year with JavaScript

In today's challenge for a client of mine, I had to write a JavaScript function that returns the Nth Weekday of any given month and year. For example it can tell you what the 1st Monday is in December, 2017. It can do past, present and future so if you needed to know the 4th Friday in August of 1910, this function can tell you. If you need to know what the second Sunday of January 2050 is going to be, this JavaScript function will tell you!

Without any further time wasting, here is the JavaScript code that can determine the first, second, third, fourth or even fifth Monday, Tuesday, Wednesday, Thursday, Friday, Saturday or Sunday for any month and year you pass it:

JavaScript Code Returns Nth Weekday for any Given Month & Year:

<script>
/* JavaScript getMonthlyWeekday Function:
 * Written by Ian L. of Jafty.com
 *
 * Description:
 * Gets Nth weekday for given month/year. For example, it can give you the date of the first monday in January, 2017 or it could give you the third Friday of June, 1999. Can get up to the fifth weekday of any given month, but will return FALSE if there is no fifth day in the given month/year.
 *
 *
 * Parameters:
 *    n = 1-5 for first, second, third, fourth or fifth weekday of the month
 *    d = full spelled out weekday Monday-Friday
 *    m = Full spelled out month like June
 *    y = Four digit representation of the year like 2017
 *
 * Return Values:
 * returns 1-31 for the date of the queried month/year that the nth weekday falls on.
 * returns false if there isn't an nth weekday in the queried month/year
*/
function getMonthlyWeekday(n,d,m,y){
var targetDay, curDay=0, i=1, seekDay;
    if(d=="Sunday") seekDay = 0;
    if(d=="Monday") seekDay = 1;
    if(d=="Tuesday") seekDay = 2;
    if(d=="Wednesday") seekDay = 3;
    if(d=="Thursday") seekDay = 4;
    if(d=="Friday") seekDay = 5;
    if(d=="Saturday") seekDay = 6;
while(curDay < n && i < 31){
    targetDay = new Date(i++ + " "+m+" "+y);
    if(targetDay.getDay()==seekDay) curDay++;
}
if(curDay==n){
targetDay = targetDay.getDate();
return targetDay;
}else{return false;}
}//end getMonthlyWeekday JS function
</script>
<a href="JavaScript:var dy = getMonthlyWeekday(1,'Sunday','March', 2017);alert('1st Sunday in March, 2017 falls on March, '+dy);">Get first sunday in March, 2017</a><br />
<a href="JavaScript:var dy = getMonthlyWeekday(2,'Sunday','March', 2017);alert('2nd Sunday in March, 2017 falls on March, '+dy);">Get second sunday in March, 2017</a><br />
<a href="JavaScript:var dy = getMonthlyWeekday(5,'Sunday','March', 2017);alert('5th Sunday in March, 2017 falls on March, '+dy);">Get fifth sunday in March, 2017</a><br />
<a href="JavaScript:var dy = getMonthlyWeekday(4,'Friday','April', 2017);alert('4th Friday in April, 2017 falls on April, '+dy);">Get 4th Friday in April, 2017</a><br />
<a href="JavaScript:var dy = getMonthlyWeekday(5,'Monday','April', 2017);alert('5th Monday in April, 2017 falls on April, '+dy);">Get 5th Monday in April, 2017</a><br />
<a href="JavaScript:var dy = getMonthlyWeekday(3,'Wednesday','October', 1995);alert('3rd Wednesday in October, 1995 falls on October, '+dy);">Get 3rd Wednesday in October, 1995</a><br />
<a href="JavaScript:var dy = getMonthlyWeekday(4,'Wednesday','October', 1995);alert('4th Wednesday in October, 1995 falls on October, '+dy);">Get 4th Wednesday in October, 1995</a><br />
<a href="JavaScript:var dy = getMonthlyWeekday(4,'Wednesday','May', 1975);alert('4rd Wednesday in May, 1975 falls on May, '+dy);">Get 4th Wednesday in May, 1975</a><br />

Summary

That will do the job! All you have to do is copy and paste the above code in green into a blank text file and name it something like weekdays.html or test.html and open it in any web browser to test the code. Then feel free to alter it to fit your exact needs. Have fun!

 

 

 

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.

 

 

 

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.162.27.162

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;
}

Find a file using Linux find Command

If you need to find a file anywhere on a server, what directory it is in or not, the Linux Find command is your go to command! Here are some basic usage cases:

Find a file in the current directory:

find . -name "this-file.php"

Find a file anywhere on the server above the root directory:

find / -name "filename.php"

Notice in the first example we used a period and in the second we used a forward slash. The period means to search the current directory and the forward slash means to search from the root directory and will basically find a file anywhere on the file in the root directory or any of its sub-directories.

Perform a case-insensitive search:

The above commands all use the -name parameter which performs a case-sensitive search. To perform a case-insensitive search, replace -name with -iname in the above examples, like so:

find / -iname "filename.php"

Perform a wildcard search:

The wildcard character is *. If you want to find all .php files, for example, use the following command:

find / -iname "*.php"

 

 

How to change DNS settings on your local PC

Have you ever been working on a website, changed your DNS settings over to a different server and later needed to access that server again from the old domain name for some reason? Well if you are an active developer, this situation is somewhat common. I'll explain or you can skip the rest of this paragraph to quickly learn now to do it. Let's say you own the domain name example.com and a web server with an IP address of 111.111.111.111. Now assume you have a WordPress blog on that server that you had to move to another server with IP 222.222.222.222. Let's say you already changed the DNS settings for domain.com to point to the new server with IP 222.222.222.222 but you need to go back to the original WordPress site on the other server with an IP of 111.111.111.111. What do you do? We all know a WordPress site won't function properly with just the IP address, so that is out. What you need to do is repoint example.com to 111.111.111.111 in order to access that WordPress site again. What a PITA, right? Well read on and I'll show you a fast and easy way to make the site on the original server work with example.com even after you've pointed it to another IP address or web server! It's as simply as controlling a local host file on your local PC to make example.com route to 111.111.111.111 even though the internet routes it to 222.222.222.222! Here's how:

Using hosts file to override DNS settings for your PC

A lot of people don't realize that when you make a request to the Internet using your local computer it first checks a local copy of the hosts file for an entry and only if one isn’t present it goes out to the Internet DNS servers. Therefore there's an opportunity present for you to redirect example.com only for your own PC if you wanted to! Here are the easy steps:

  1. Open file explorer and navigate to C:\Windows\System32\drivers\etc.
  2. Open the file named "hosts" in notepad or another text editor that could be used as a code editor such as Notepad++, which is what I use.
  3. Now simply add a line to the end of the hosts file that contains the IP address of the server you want to route the domain name too followed by a space and then the domain name you want to reroute. So in our example scenario above, you would enter a new line that reads simply: 111.111.111.111 example.com
  4. Save the hosts file and open your browser and navigate to the domain which in our example was example.com. Note that there is a difference between example.com and www.example.com, so if you want it to work with www, you have to add another entry for www.example.com.

If you're using Notepad++ or similar as I was, you'll need to open it in administrator mode in order to be able to save the hosts file. Good luck! That's all there is to it.

How to change local DNS settings on a Mac

If you're on a Mac, the instructions are basically the same but do this instead:

From the terminal, type:

nano /private/etc/hosts
and then add the IP and domain name as described above, so the only real difference between Mac and a PC when it comes to changing DNS settings is that you will use a different editor and the hosts file is located in different places.

 

 

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.

 

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 Share Your Internet Connection in Windows 10

So I've used a couple different methods to share internet connections on several different computers. What's a real pain is that some methods only work on some PCs and some PCs don't have all the components or programs needed to run ICS(Internet Connection Sharing) properly. So, I finally may have found a great, easy to use solution. It does require installing a simple app in Windows, but it doesn't seem to have any adware or nonsense in it. I will update this post if I do find any malicious content from the app later on though.

Using an App for Internet Connection Sharing

Some peope are against using an app for this, but let me tell you, it is easier if you have to deal with this issue regularly. The app is called Virtual Router and can be downloaded from: https://virtualrouter.codeplex.com/downloads/get/621827.

Screenshot (11)

Using CSS Media Queries in Responsive Web Design

That's right! The post of the day is going to be on how to use CSS media queries to make a responsive web page or application. The project I'm working on requires me to create a responsive events calendar application that looks good in all sized browser windows as well as mobile devices including iPhone and Android phones and tablets. This can be done very well with CSS media queries and a basic understanding of HTML and CSS. Making today's task a little more challenging is the fact that we will be using HTML table elements. If you have any experience with HTML tables, you probably know that they can be tricky to size according to specific requirements most times. We will overcome the table cell sizing limitations in this article however.

Common Screen Sizes

One of the most important things to take into consideration when developing a fully responsive web application for both computers and mobile devices is your users screen size. What are your users likely to be using? Some will be on a PC, some on a tablet, others on an iPhone and yet others will be on an Android or other device. The ugly truth is that there are a lot of possibilities. I have found from experience that it's best to take into consideration the most commonly used screen sizes. I program for the most common and try to make it work resonably well in the uncommon sized screens as well because roughly up to 3% of your users could be using an odd sized screen that you haven't programmed for. While 3% may not sound very significant, think of it like this: If your site has 1000 visitors a day like mine does, then that means up to 30 people a day are viewing your site on a less-common screen size. 30 is 3% of 1000. Here are some of the latest statistics I could find on common screen sizes used:

First I want to show you common screen sizes of Mobile Devices since they are probably the fasting growing segment of 2016:

2016 Total iOS* Android Windows Others
February 5.15 % 1.08 % 3.49 % 0.42 % 0.16 %
January 5.38 % 1.17 % 3.69 % 0.37 % 0.15 %

The above information was collected by the website w3schools.com. The data represents the users of their website according to information collected by thier servers. It shows that only slightly greater than 5% of thier website viewers view thier site on a mobile device, but your site could have more because I think the w3schools website is one that developers reference a lot and developers do their work on a computer more often than on a mobile device. That may account for some of the low figures for mobile users. Now lets look at the most commone screen sizes according to rapidtables.com:

Common screen resolutions of rapidtables.com visitors (2/2014):

Screen resolution Display
ratio
Usage Screen size / type
1366x768 16:9 19.1% 14'' Notebook / 15.6'' Laptop / 18.5'' monitor
1920x1080 16:9 9.4% 21.5'' monitor / 23'' monitor / 1080p TV
1280x800 8:5 8.5% 14'' Notebook
320x568 9:16 6.4% 4'' iPhone 5
1440x900 8:5 5.7% 19'' monitor
1280x1024 5:4 5.5% 19'' monitor
320x480 2:3 5.2% 3.5'' iPhone
1600x900 16:9 4.6% 20'' monitor
768x1024 3:4 4.5% 9.7'' iPad
1024x768 4:3 3.9% 15'' monitor
1680x1050 8:5 2.8% 22'' monitor
360x640 9:16 2.3%
1920x1200 8:5 1.7% 24'' monitor
720x1280 9:16 1.6% 4.8'' Galaxy S
480x800 3:5 1.1%
1360x768 16:9 0.9%
1280x720 16:9 0.9% 720p TV

If you study the numbers above, they suggest that rapidtables.com visitors are much more likely to be on a smaller screen size device or mobile device than are w3scools.com users. I guess from reading the above data that their website has roughly up to 12% of their users using smaller screened devices such as iPhones, Androids and other mobile devices.

CSS Media Queries

I choose to use one simple type of CSS media queries in this challenge. I like to call it the max-width technique for sizing web pages at various sizes. This is due to the fact that the technique uses ony the max-width media query as you will see with the demonstration code below.

From studying the more common screen sizes, I've come up with a simple plan to make my calendar application look good on just about any possible screen size. Here is my rudimentary logic:

I plan to set the maximum with of the calendar to 1000 pixels and centering it on the page. By doing this I eliminate the need for any media queries for screens over 1000 px wide! As you can see from the charts above,  there are 17 screen sizes represented and 11 of them are over 1000px wide! We have already made our work a lot easier since we only have 4 other screen widths to worry about(because 3 of them have 320px wide screens). Obviously 320px is of great concern as it is one of the most common widts on mobile phones, but I'll also take into considertion the widths of 360px, 480px, 720px and 768px. However, some will be taken care of by the same media queries as you'll soon discover. Here are the basic rules we will go by when making out calendar application:

  • web page will be no wider than 1000px and centered.
  • first media query will be set for max-width of 800px meaning that if the page size is under 800px wide the styles inside of the media query definition will be altered.
  • A second media query set for a max-width of 500px will apply changes for any screen size under 500px down to the next media query.
  • A third media query set for a max-width of 400px will account for any screen between400px and the next media query.
  • A forth and final media query set for max-width of  320px will account for the common screen sizes of 320px and under which are the smallest group of mobile phones, so no other media queries after this one will be required.

I have outlined my logic above, now I can add my media queries to my CSS style sheet as follows:

/*add styles for screen sizes of 800px and up. These don't need to be inside of a media query because the table's width for the calendar will be set to 1000px and centered. Tables are generally flexible enough to be reduced from 1000 to 800px without any problems given it is styled and tested correctly.*/

@media(max-width: 800px) {
//add styles for screen sizes from 500 to 800px:
}

@media(max-width: 500px) {
//add styles for screen sizes from 400 to 500px:
}

@media(max-width: 400px) {
//add styles for screen sizes from 320 to 400px:
}

@media(max-width: 320px) {
//add styles for screen sizes 320px and under:
}

The above is a good way to start your CSS style sheet for a resposive design. You may find that you may not need to use one or more of the media query definitions. You may also find yourself adding one or two media query definitions. None-the-less, this is a good start.

Writing and Testing your CSS Code

When I make a responsive web page, I first make the basic page with basic CSS and no media queries. Then when the basic page is complete, I start testing it at different screen sizes by making my browser window smaller and larger and seeing how the page looks at every possible width and height. Then I add styles to media queries and edit them until the page looks good at every possible size. Finally I test on actual devices such as an iPhone, Android phone and a tablet while making final adjustments according to how the page looks on the actual devices.

How to Make Putty Automatically Login with User and Password

In this article, you'll learn to make a one-click Putty shortcut to your server from your desktop. What's so great about that? If you are a web developer or operate your own server and use Putty, then you probably know how much of a pain it is to have to open putty and enter the URL, user and password each time you need to open a command prompt on your remote server. Imagine being able to simply click a link on your desktop to open a command prompt to your remote server! Wouldn't that be great? I think it is. Here is how you can make a direct single click link to a remote server on your desktop:

  1. Locate your Putty program. Normally it would be somewhere like C:/ProgramFiles/Putty or similar. However, it could be anywhere. I installed mine in a special C:/Desktop/Tools directory as you can see in the image below, but yours is most likely in ProgramFiles.puttyfile
  2. Once you locate putty.exe as in the image above, right click on putty.exe and select "send to/Desktop(create shortcut)" to create a shortcut on your desktop. It will look like this:puttyshortcut
  3. Right click on the shortcut like in the above image and select "rename" and give the shortcut a name that identifies it as a link to your server such as example.com or whatever name you like.
  4. Right click on your new example.com shortcut and select "properties" and edit the target attribute to read: "C:\ProgramFiles\putty.exe root@207.150.12.233 -pw YourPassword". Be sure to change "C:\ProgramFIles" to the correct path of your putty.exe file. Change "root" to the user you would use to login to your remote server and edit "207.150.12.233" to equal either the IP address of the remote server or the domain name such as "example.com". Finally, edit "YourPassword" so that it is the correct password for the username you used in place of "root" previously. Once the target field is correct, click "Apply" then "OK" to commit the change.
  5. Now simply double click on your new shortcut and a command prompt to your server will magically open! Magic!

I've been using Putty for years and always thought there was no way to store a password for a remote server connection using Putty, so I was absolutely thrilled to learn of this little known secret for creating a desktop shortcut that logs you into your server with putty and without having to enter your password every time!