JavaScript Auto Complete for Text Field

Yesterday, I had a project that required me to create an auto complete feature for a text field. I searched for an existing solution online and couldn’t find one that fit my exact needs, so I created my own.  I created this particular solution using both PHP and JavaScript, but it could easily be modified to use only JavaScript if you prefer. However, if you have a long list of words or phrases you need to use for the auto complete feature, then you too may want to use PHP to call them into the JavaScript code as I have done.

A Working Example

Let’s start off by showing you a live working example so you can see what we are creating. Here is the link to the example I made as a proof of concept for the project I was working on:

http://jafty.com/test/cities.php

Type of Auto Complete

This particular type of auto complete feature is used on a regular text input field within a form. This auto complete feature is for when you have a list of words and/or phrases that you want to be made available as input into a text field. It is up to you if you want to allow values outside of that list or not. In my case I do not restrict my text field to values from the list, but I did consider it.

Why I Created a New Auto Complete Feature

I made this solution because I was working on a site for the country of Switzerland and had a need to allow Swiss users to enter a Swiss city into a form. I soon discovered that there are well over two thousand villages, towns and cities throughout Switzerland. I found a list that is supposed to contain all of the municipalities in Switzerland online. I wanted to make a script that would use that list for the auto complete feature for the city text field in that form. My solution allows for larger sized word/phrase lists to be employed with the auto complete feature for any text field you assign.

The Solution

Finally, let’s see some code! The code is mostly JavaScript with a bit of PHP. PHP is optional in this case, so if you desire a pure JavaScript solution, simply exclude the PHP file and hard-code the word/phrase list into the JavaScript code.

The Completed Code

Here is all the code from the cities.php file which is a full working example solution when paired with the towns.txt file which has the list of cities in it. Read the instructions provided near the end of this article to learn how to recreate a working example on your own server.

<style>
#town{
border: 1px solid #ccc;
padding-left:20px;
padding-right:15px;
width:165px;
margin-left:100px;
cursor: pointer;
}
</style>
<script>
//isGood JS function checks if char is a valid letter or not:
function isGood(c) {
return c.toLowerCase() != c.toUpperCase();
}

var first = ”;//used in suggest function to hold first letter entered into text field
var second = ”;//used in suggest function to hold 2nd letter entered into text field
var third = ”;//3rd letter…
var fourth = ”;//…
function suggest(c){
//build an array of cities:
var cities = [
<?php
$file = fopen(“towns.txt”, “r”) or exit(“Unable to open towns.txt file!”);
//Output a line of the file until the end is reached:
$line_no=0;
while(!feof($file)) {
$line_no++;
$line = fgets($file);
$curcity = trim($line);
echo “\”$curcity\”,”;
}//end while reading in lines from keywords.txt file
fclose($file);
?>
];
if(isGood(c)){
document.getElementById(‘town’).style.display=”;//shows the suggestions dropdown(town div)
//if only one letter so far:
if(c.length == 1){
//get first letter of c(what was entered into text field) and save it in “first” global variable:
first = c[0].toLowerCase();
}
if(c.length > 1){
second = c[1].toLowerCase();
}else{
second = ”;
}

if(c.length > 2){
third = c[2].toLowerCase();
}else{
third = ”;
}

if(c.length > 3){
fourth = c[3].toLowerCase();
}else{
fourth = ”;
}

con = ”;//empties contents of suggestions saved previously.
cities.forEach(foreachfunction);
document.getElementById(‘town’).innerHTML = ”;//empties the suggested cities first…
document.getElementById(‘town’).innerHTML = con;//fills the town div with suggested cities
}//end if letter is good
}//end suggest JS function by Ian L. of Jafty.com

var con = ”;//init a variable to hold content of the dropdown of suggested cities
//function ran for ea. city in the cities array:
function foreachfunction(city, index){
//get first letter of city:
var f = city[0].toLowerCase();
//see if first matches 1st letter of city(f):
if(f == first){//adds city to suggestions only if first letter is entered in text input:
//if more than one letter has been entered into text field, get 2nd letter of city too:
if(second != ”){//second is blank if only 1 letter, so if it’s not blank get 2nd letter:
if(city.length > 1)var s = city[1].toLowerCase();
if(city.length > 2)var t = city[2].toLowerCase();
if(city.length > 3)var f = city[3].toLowerCase();
if(fourth != ”){//fourth is blank only if 1,2,3 letters, so if it’s not blank, get 4th letter:
if(f == fourth && t == third && s == second){
con += “<div onclick=’addItem(this.innerHTML)’>”+city+”</div>”;
}
}else{
if(third != ”){//third is blank if only 1 or 2 letters, so if it’s not blank get 3rd letter:

if(t == third && s == second){
con += “<div onclick=’addItem(this.innerHTML)’>”+city+”</div>”;
}
}else{

if(s == second){
con += “<div onclick=’addItem(this.innerHTML)’>”+city+”</div>”;
}
}
}

}else{
con += “<div onclick=’addItem(this.innerHTML)’>”+city+”</div>”;
}
}
}//end foreachfunction JS function used within above suggest JS function by Ian L.

//function ran when one of the suggested cities is clicked upon:
function addItem(x){
document.getElementById(‘city’).value=x;
document.getElementById(‘town’).style.display=’none’;
}//end addItem JS function by Ian L. of Jafty.com
</script>
<form>
<table><tr><td>
Village / Town:<input style=”width:200px” type=”text” id=”city” name=”city” onkeyup=”suggest(this.value)” /><br />
<div style=”display:none;” id=”town” name=”town”>
</div>
</td><td>
<input type=”submit” id=”s” name=”s” value=”Suche” />
</td></tr></table>
</form>

The Word and/or Phrase List

In this example we have a long list of Swiss cities as our word list. Your word list can be a list of words and/or phrases which you would like to suggest as values to be entered into the text field for which you are applying the auto complete feature to. Each word or phrase can be as long as you like and should be formatted in a plain .txt file with one word and/or phrase per line. Generally you should probably try to keep your phrases short, but there is no actual limit that I am aware of regarding how long they can be. Just remember this is a “text” input not a “textarea” input, so it is meant for short values typically of one to six words approximately. My list is of city names so they are all relatively short and I’ve formatted the .txt file to list one city per line and saved it as “towns.txt” I have uploaded towns.txt to my personal server, so if you would like to copy it to use for testing your own script, you can do so by going to the following url and simply copying and pasting the word list into your own .txt file and naming it “towns.txt”. Here is the link to towns.txt:

http://jafty.com/test/towns.txt

Instructions to recreate your own auto complete feature

Follow these simple instructions if you want to create the live example on your own server. Then you may modify the code to fit your individual needs.

  1. First, copy the entire code example above in green text and save it to a .php file. I named my file cities.php, you can name yours whatever you like as long as it ends in “.php”.
  2. follow the above link to the towns.txt file and copy and paste it into a new .txt file and name it “towns.txt”. If you choose to name it something else, be sure to also change the name in the code wherever it is used by doing a search and replace for “towns.txt” and replacing it with your new name if you so choose.
  3. Upload both the PHP file and the TXT file to your server inside of the same directory. Then finally, you can visit the cities.php page in your browser and see it work! That’s all there is to it.

Creating a Pure JavaScript Solution Instead

If you prefer to have a pure JavaScript solution and your word list isn’t too large to handle within the JavaScript, follow these simple instructions:

  1. Follow the above instructions, but while doing step no. 1 above, after copying the green text above to a blank file, find the PHP section of code and simply delete it. Delete everything from “<?php” to after the closing PHP tag that looks like this: “?>”.
  2. Then where the php used to be, add the following code but replace the “one, two, three, four” text with your own personal word and/or phrase list.
    “one”,
    “two”,
    “three”,
    “four” , so your cities variable will look like t his now:
    var cities = [
    “one”,
    “two”,
    “three”,
    “four”
    ];
  3. Then you can save your file as an HTML file now since there is no more PHP code in it, so save it as cities.html and open it in your browser and it should work even from your desktop since HTML doesn’t require a server to function like PHP does.

Summary

That’s all there is to it! Feel free to modify this code to fit your needs as you wish. I hope it helps someone else as it did me. I found it very useful myself. I used this on a WordPress site as well, so it is WP friendly FYI.

 

 

 

The Best Way to Learn Mobile App Development

If you start looking into it or have already been researching on ways to learn mobile app development, you come to find out that there is a wide variety of options and decisions you have to make regarding how to learn Mobile App Development. I wrote this guide to help you get started in hopes that it will save you some time and get you coding your own mobile applications faster.

The Many Paths to Learning Mobile App Development

As I mentioned above, there are many different options when it comes to learning mobile app development. Here are just some of the decisions that you will have to make when first getting started with the development of mobile applications:

  • Android, IOS or Cross-Platorm – Do you start out learning to program for Android, IOS or both? What about other Operating Systems? Well the truth is, there really isn’t any other significant Operating Systems, Android and IOS hold about 98% of the market share right now, a mobile development team from UK finds. Worldwide, Android holds 75.22% of the market, while IOS controls 22.76% for a combined market share of 97.98%. So are we worried about the missing 2%? No, not as beginning developers breaking into the market, we’re not. The ratio of Android to IOS users varies significantly from country to country, so if you want to learn more about individual countries, you can go to https://deviceatlas.com/blog/android-v-ios-market-share and read all about it.  U.S. market share is a little bit unclear since I’ve read reports for the end of 2018 that put Android on top and conflicting reports that put IOS on top, so lets just say  it’s roughly 50/50 in the U.S. IOS usage is higher in countries with better economies. As most people know,  iPhones do not come cheap! I just read online that the new iPhone XS is selling for over $1500 dollars! That is much more than I ever care to pay for a phone, but it is impressive with 512gb storage and 4gb of ram. That’s almost as powerful as the laptop I use, amazing! In my opinion, that’s more than most of us need though. There are times when it would be nice, but most of the time I don’t think we need that much power in our cell phones. Surely not the average user at least. So, all arguments aside, Android is the clear winner to me because they have the largest market share world-wide and all of the multi-platform method of mobile app development I’ve seen and tested so far have not been good enough to build commercial applications with yet. So i think you should either pick Android or IOS to start with and eventually learn to develop for both since there is no viable cross-platform option available yet that I’ve seen.
  • What IDE, Framework or coding platform do you use? This question is heavily reliant upon the previous question because it mostly depends on what Operating System you have chosen to develop for. In my case, I’ve chosen to develop for Android first, so after checking out most available options, I’ve decided to go with Android Studio. I selected Android studio because it seems to be the most intuitive and it is very well documented. There’s nothing worse than downloading a new program and finding out that there is hardly any documentation on the web regarding how to operate that program. You won’t have that issue with Android Studio. It came out in May of 2013, so it’s been around for over 6 years now and has built quite the reputation in that short amount of time. I don’t think any of the choices available today are going to have been around for anymore than ten years or so just because the technology is so new. I did try a few other IDEs first and Android Studio was the one that I was able to build a working app the fastest on and it didn’t leave me scratching my head and thinking “Wow, I created an app, but I have no idea how I did it” as some of the other IDE options left me thinking. It’s also important to note here, I feel, that I have no reason to endorse any of the decisions I’ve made in this guide. No one paid me to write this and I do not endorse any products unless I truly think they are the best, but I have not been paid by anyone to endorse anything. So, if I say something is the best, I truly believe it is the best option. It’s as simple as that. That’s hard to believe sometimes in today’s fast paced economy, but it still holds true with me.
  • What coding languages do you learn? Again, this answer is dependent on how you answered both of the questions above, so my choice will only be relevant to your situation if you also choose to develop for Android. The official language for Android development is Java. There is also Kotlin for Android Studio users. Kotlin apps will run on any machine that supports the Java runtime environment and because most machines can, Kotlin is a relatively easy way to create android applications. If you chose to go with IOS on the other hand, Objective-C and Swift are the two most commonly used programming languages for IOS app development. My first choice was Java because it’s been around the longest for use with Android and seems to be the most documented of the two. Kotlin is newer and may have some neat new features, but for now, I’m going with old reliable…

Okay, so that about covers it, the three bullet points above cover the three most important questions you have to ask yourself when you first get into mobile application development. I took my time making the decisions I made to go with Android Studio IDE and the Java programming language to start building mobile apps with, but I can also learn the alternative methods after I perfect these Android application development methods. A true developer is always learning. They say you will need to know about seven different programming languages to be an expert mobile application developer. That sounds about right to me because that’s how many languages I had to learn to be an effective web developer. Speaking of which, I did look into using the languages I already know as a web developer for mobile application development. While there are platforms that make it possible, such as Cordova, in the end they are mostly using techniques to convert the code you write into Java anyway, so I figure it’s faster and more productive in the end to just start learning Java for Android Mobile Application Development. I may look into ways to convert my Java Apps into IOS apps when I am done making some mobile apps with Android Studio, but I suspect I will eventually learn to develop separate apps for IOS in the end.

How to Install NodeJS on Linux Server

In this article, I will cover how to very easily install Node.js on just about any Debian, Ubuntu or other Linux web server. I created this article to fill a great need for accurate information on this subject because I spent the better part of a full day getting Node.JS to work on the first server I had to install it on. Now that I’ve installed it on 3 or 4 different servers, I finally found a quick and easy way to make it work. I also had to make it so node could be called from PHP using the exec command, so it goes one step beyond just installing Node.js.

Here are the Four Quick and Easy Steps for Installing Node.JS on Linux Servers:

(use sudo in front of the command line commands if you are  not root user)

  1. Confirm that Curl is installed using “which curl” from command line and if it doesn’t return the curl location, then install curl before continuing.
  2. Confirm that Node isn’t already installed with the command line command “node –version”. if it doesn’t print a version no. then it needs installed.
  3. Using instructions from https://github.com/nodesource/distributions/blob/master/README.md#debinstall and If on a Debian server, go to command line and run(use sudo if not root user):
    curl -sL https://deb.nodesource.com/setup_8.x | bash –
    …and hit enter….then go to step 4.
    NOTE: if you’re not on a Debian server, follow the relative instructions for your particular server by scrolling to it in the above github URL instead of steps 3 and 4 here.
  4. then run this command from the command prompt(use sudo if not root user):
    apt-get install -y nodejs

Then you can verify that NodeJS works from the command line with:

node –version

and it shold return something like:

8.4.0

 

What Programming Language is Best for Mobile App Development?

If you’re a web developer and are considering getting more into mobile application development for IOS and/or Android operating systems for mobile phones, then you are likely go ask the question, “What Programming Language is Best for Mobile App Development?”.

The answer is somewhat complicated because there are many answers. To narrow down the possible options, I am going to make a couple assumptions. I will assume that you, like myself, like to stay away from platforms and drag and drop type UI tools to program with. I will also assume that you want to develop something for both Android and iPhone, not just one or the other.

Considering the above assumptions, there are still many options, so what makes it such a complicated choice? In my opinion the main factor that makes it so difficult to pick a coding language to specialize in for mobile app development is the fact that there are two main and competing mobile platforms that have chosen to use different languages with their operating systems. Of course I am speaking about Android Vs. iOS.

Android Vs. iOS, Which is More Popular?

A quick Google search shows me that just over 85% of smartphones are Android, while most of the remaining 15% are Apple iOS phones. According to an article I read on 9to5mac.com, Android and iOS together account for 99.1% of all smartphones in use today, which makes any other devices almost pointless to develop for. It is worth mentioning that of the 0.9% of devices that are not running Android or iOS operating systems, are mostly running Windows operating systems. Windows OS accounts for  0.6%, while 0.1% are Blackberry and the remaining 0.2% are various other operating systems that are not popular enough to be worth even mentioning here.

Best Languages for Android OS

JAVA

Since Android controls the majority of the market for smartphones today, let’s look at them first. If you are going with the most popular answer, than Android wins by far! Android operating systems use Java. If you are coding an app for Android phones, Java is most likely going to be your best programming language to choose as the base language for your app. In reality, many apps use a combination of several different languages. However, in my experience your language of choice will make up the majority of the app’s code.

Kotlin

Kotlin, a second app development language option, was designed and developed by JetBrains. They are a Czech company known for the popular IDE, IntelliJ IDEA. Google’s Android team recently announced that they are officially adding support for the Kotlin programming language. Kotlin was created to address some of the Java issues. Some say the Kotlin syntax is clean, simple, and leads to less code bloat.

Best Languages for iOS

While Apple’s iOS operating system only accounts for roughly 15% of the smartphone market, that is still a significant number of devices out there. Smart developers create apps for both Android and iOS, whether it be with separate apps for each or some sort of platform used to create a mashup that will allow a single app to function on both operating systems.

Apple iOS apps primarily use SWIFT or Objective-C

SWIFT

SWIFT is a quickly growing open source language popular with many starting out with app development today. Apple has heavily promoted the use of SWIFT making it clear that they intend for SWIFT to be the leading language choice for iOS application developers.

Objective-C

Objective-C was the original language of the iOS operating system, but is being phased out apparently since Apple is making it clear that SWIFT is the future, then that leaves Objective-C stuck in the past. While it is still a viable option, I would suggest using it only on an as-needed basis for iOS application development purposes.

Cross -Platform Mobile App Language Options

For some of you, particularly those of you who don’t want to make two separate apps, a cross-platform language option might seem more attractive. A cross-platform language in this context, is one that will allow a mobile application to function on both Android and iOS without the need to make two applications, one for each OS.

JavaScript

If you started out as a web developer as I did, then you are surely familiar with JavaScript. Not to be confused or associated with Java, JavaScript is it’s own language despite the similar name. JavaScript is very versatile in that you can complete many different types of tasks using the language. It is probably one of the most popular cross-platform options because it is effective and rather light-weight.

Several JavaScript frameworks exist today that target the mobile application development market. While I am not a huge fan of most frameworks in general, some of these deserve some serious consideration none-the-less. Some of the well known JavaScript frameworks popular today include PhoneGap by Cordova, Angular.js, jQuery Mobile and React. There are many more that are worth researching if you are looking for a cross-platform JavaScript framework or library to help build your next mobile application for Android and iOS. Actually, JavaScript apps will also work on the other less used Operating Systems as well such as Windows OS and Blackberry.

Using Ajax on Admin Page in WordPress Plugins

Today, I’m writing a rather simple WordPress Ajax example that demonstrates how to user Ajax in a wp-admin page from a WordPress Plugin.

Using Ajax in wp-admin is a little easier than using it on the front-end of a WordPress site because of the ajaxurl JavaScript global variable which refers to the admin-ajax.php url.

In the following code example the goal is to provide an admin page with a delete post link that is powered by Ajax. Therefore the code enables the deletion of a WordPress post without the obtrusive page refresh!

This is a pretty bare-bones example meant as a learning tool. It could be fleshed out much more to be more practical, but I wanted to keep it simple to get the main point across, which is how to do a simple Ajax request from wp-admin.

The Essential Code

First, for those of you that only need to see the basics, I’ll demonstrate the essential code for the Ajax to work. Further down this page, I’ll put it all together in a simple plugin for those of you that may need to see a working example to grasp the concept better. Here is the essential code to enable an Ajax delete post button:

First, a simple HTML line to call our JavaScript function onclick:

<span onclick=’ajax_delete_posts(<?php echo $ID; ?>)’ style=’color:red;cursor:pointer’ title=’Delete Person!’>X</span> <?php echo $title; ?><br />

In the above, you’ll notice the ajax_delete_posts JavaScript function is called. ajax_delete_posts is the function we must create! Of course you’ll need to define the post id in $ID and the post tile in $title using PHP, but this is just to show you how I intend to call the Ajax/JavaScript function

Second, we use PHP to generate our ajax_delete_posts function in JavaScript code:

You can rename the ajax_delete_posts as you wish, just make sure to rename it in your HTML above too if you do. Here’s the code to generate the JavaScript from within your PHP file, the plugin’s main file normally:

<?php

//add Ajax for deleting posts or custom post type(replace ‘post’ with cpt name):
add_action(‘admin_footer’, ‘del_posts_js’);
function del_posts_js() {
?>
    <script type=”text/javascript” >
    function ajax_delete_posts(t) {

        var data = {
            ‘action’: ‘del_posts_with_ajax’,
            ‘t’: t
        };

        // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
        jQuery.post(ajaxurl, data, function(response) {
            alert(‘Ajax server response: ‘ + response);
        });
    }//end Ian’s JS AJAX function
    </script>
<?php
}

?>

Notice in the above code how we pass the post id to the JavaScript function using the “t” variable. Also it’s important to note your data variable’s action value as you will need to use the same value for the function name in the below code. Feel free to use whatever text you want for the action as long as it can be an appropriate PHP function name in the code below as well.

Finally, the third step is to add your PHP function named after the action named above and also hook into it with “wp_ajax_” followed by the action named above as well, so in our case the hook we use would be “wp_ajax_del_posts_with_ajax”. However, if you use a different action, such as “do_aj” for example, then your action hook would read “wp_ajax_do_aj”. Got it? I hope so, but the code example should help too, so here it is:

<?php
add_action( ‘wp_ajax_del_posts_with_ajax’, ‘del_posts_with_ajax’ );

function del_posts_with_ajax() {

    $tpidof = $_POST[‘t’];
    
    if(wp_trash_post($tpidof)){
        echo $tpidof.” Deleted!”;
    }else{
        echo “$tpidof Failed to delete!”;
    }

    wp_die(); //required to terminate immediately and return response!
}
?>

In the above code example, we first set up our action hook by using the hook “wp_ajax_” followed by the action we used in the “var data” line further above.  Then we write a PHP function named exactly like the action we used above and be sure to also name the function as the parameter in the action hook as well and you will be good to go!

Putting it all together in a simple Ajax WordPress Plugin

Next I’ll show you the example plugin I created to demonstrate exactly how this all works together in case some of you failed to grasp it from my previous explanations. You can cut and paste the following PHP code into a file named “ajax_post_delete.php” and place it on your desktop in a folder named “ajax_post_delete” and I promise you the code will function on any standard WordPress installation as of the day I wrote this. Here is the complete “Ajax Post Delete” WordPress plugin code in a single file example plugin:

<?php
/*
Plugin Name: Ajax Post Delete
Plugin URI: http://jafty.com/ajax_post_delete

Description: A plugin used in the article at http://jafty.com/blog/?p=10739 in order to demo an admin ajax example

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
*/

//function to add wp-admin menu:
add_action(‘admin_menu’, ‘add_ajax_post_delte_admin_menu’);
function add_ajax_post_delte_admin_menu() {

    $page_title=’Delete posts’;
    $menu_title=’Delete posts’;
    $capability=’manage_options’;
    $menu_slug=’del_posts_pg’;
    $function=’mk_dele_pg’;
    $icon_url = ”;
    $position=’4′;
    
    add_menu_page($page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position);
    

}//————end add_ajax_post_delte_admin_menu function——————

function mk_dele_pg(){
?>
<h1>Delete posts</h1>
<?php
//get all posts:
$args = array(
‘post_type’ => ‘post’,
‘posts_per_page’=>-1
);
global $wp_query;
$wp_query = new WP_Query($args);
//start looping posts
while($wp_query->have_posts()) : $wp_query->the_post();
$person = get_the_title();
$personID = get_the_ID();
//echo $person.”<br />”;
echo “<span onclick=’ajax_delete_posts($personID)’ style=’color:red;cursor:pointer’ title=’Delete Person!’>X</span> $person<br />”;
endwhile;

}//end mk_dele_pg function

//add ajax for deleting touchpoint history for posts CPT:
add_action(‘admin_footer’, ‘del_posts_js’); // Write our JS below here

function del_posts_js() {
?>
    <script type=”text/javascript” >
    function ajax_delete_posts(t) {

        var data = {
            ‘action’: ‘del_posts_with_ajax’,
            ‘t’: t
        };

        // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
        jQuery.post(ajaxurl, data, function(response) {
            alert(‘Ajax server response: ‘ + response);
        });
    }//end Ian’s JS AJAX function
    </script>
<?php
}

add_action( ‘wp_ajax_del_posts_with_ajax’, ‘del_posts_with_ajax’ );

function del_posts_with_ajax() {

    $tpidof = $_POST[‘t’];
    
    if(wp_trash_post($tpidof)){
        echo $tpidof.” Deleted!”;
    }else{
        echo “$tpidof Failed to delete!”;
    }

    wp_die(); //required to terminate immediately and return response!
}

?>

That’s it! copy and paste the above code into your .php file and you’ve got a simple WordPress plugin that will demonstrate the use of Ajax effectively in a custom admin page of your WordPress website. Feel free to modify the code as needed, but please change the plugin name if you intend to distribute it. Thank you and Good Luck!

EDD Instant Updater WordPress Plugin

The EDD Instant Updater WordPress plugin is a plugin I created while working with a custom WordPress plugin that needed to have instant update notifications while using Easy Digital Downloads(EDD). EDD comes with it’s own updater class, but it uses the default WP standards which means you have to wait up to 12 hours after you push an update to get the notice in the WordPress dashboard! With the EDD Instant Updater plugin, you no longer have to wait, the plugin update notices come to you instantly! No more delays!

Interested? Contact Ian L of Jafty.com by email at linian11@yahoo.com for more information.

PHP WordPress Large background Importer Code

My wonderful client wanted me to add a .CSV importer that imports posts into a Custom Post Type(CPT) in large quantities of around 10k to 50k at a time.

What a standard WordPress site can handle

From my experience building plugins and importers for WordPress over the past 20 years, I have learned to expect trouble if you try to import anything more than 4k to 5k posts into WP at a time. The main requirement for the importer that I am building now is that it is able to import 20k posts in under 15 minutes. Not too difficult, but a challenge none-the-less because the average WP site will timeout after the first 4k posts on average. I also wanted to accomplish this goal without using any bloated PHP Que libraries or Worker Libraries, so I’ll be developing it completely from scratch, just like a grown up!

Step One, Break Large File into Smaller Chunks

The first thing I did while developing my large WP file import feature, was to handle the issue of having a huge .csv file with 20 thousand posts saved in it. What do you do? What I did was wrote a PHP script that reads in that huge file and breaks it up into manageable chunks and saves each chunk to its own separate .csv file. Kind of simple really, this is the easy part!

I created a file named file_split.php to handle this portion of the importer’s code. Here are the contents of that file:

<?php
$chunk_size = 2000;//size of ea. chunk file given in the no. of lines written to the file(excluding the first line with headings that will be at the top of ea. chunk file created).
$max_files = 0;//it will stop after writing this many files, set to 0 for no limmit
$u = $uploadpath;//”double_accounts-test.csv”;
//read a file line by line:
echo “<p>Opening $u to spit it into chunks……</p>”;
$file = fopen($u, “r”) or exit(“Unable to open $u!”);
//extract the first line from the file:
$first_line = fgets($file);
//Output a line of the file until the end is reached:
$i=0;
$ii=0;
$iii=0;
$chunk=$first_line;
while(!feof($file) &&($iii < $max_files||$max_files==0)) {
$i++;
$ii++;
$line = fgets($file);
//echo “$i) $line<br>”;
//add line to lines that get written to files:
$chunk .= $line;
//once we get to chunk_size lines, write a new file
if($ii == $chunk_size){
$iii++;
//echo “<h3>Chunk #$iii:</h3>”;
//echo $chunk;
//create dynamic filenames:
$fn = ABSPATH.”wp-content/plugins/YOUR-PLUGIN/temp/chunk$iii.csv”;
//echo “Writing file $fn….<br>”;
$fh = fopen($fn, ‘w’) or die(“can’t open $fn file to overwrite”);
fwrite($fh, $chunk);
fclose($fh);
$m = “<span style=’color:green’>Chunk Written to $fn</span><br>”;
//reset $ii var back to zero:
$ii = 0;
//empty the $chunk var and add first line to top of file content($chunk)
$chunk=$first_line;
//echo “<hr><span style=’text-align:center;color:orange;font-weight:bold;width:100%;margin-right:111px’>End File #$iii</span>$m<hr>”;
echo $m;
//add the file name to the fnames array:
$fnames[] = $fn;
}//end if $ii = $chunk_size
}
fclose($file);
//if $ii is greater than 0 and less then chunk_size, then there was a left over chunk at the end, so write it to a file too:
if($ii > 0 && $ii < $chunk_size){
$noof_files = $iii+1;
$fn = ABSPATH.”wp-content/plugins/YOUR-PLUGIN/temp/chunk$noof_files.csv”;
echo “Left over chunk of $ii lines remains, so writing it to final file named $fn….<br>”;
//echo “Writing Final file $fn….<br>”;
$fh = fopen($fn, ‘w’) or die(“can’t open $fn file to write final chunk!”);
fwrite($fh, $chunk);
fclose($fh);
echo “<h3 style=’color:green’>FINAL Chunk Written to $fn! DONE chunking $u file! Total files created: $noof_files</h3>”;
//add final file name to fnames array:
$fnames[] = $fn;
}else{
echo “Wow! We broke even with no left over chunk of less than $chunk_size lines, so finished writing files! Final file is $fn.<br>”;
}

?>

Put the file_split.php file up for now. We will include it in another file later when we have the rest of our import feature code written. You can test file_split.php easy enough by

MailChimp API 3.0 Helper PHP Function

I’ve been doing a lot of work with the MailChimp API V. 3.0 over the past year while developing the Cultivate CRM WordPress Plugin and I created the following helper function that has made live a lot easier for me since I have to make probably a dozen calls to the API within this one plugin.

MailChimp API 3.0 Helper Function

<?php
function mailchimp_request($mcAPIkey,$url,$req_type,$json=''){
//send a HTTP POST, GET or PUT request with curl:
 $ch = curl_init($url);
 curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $mcAPIkey);
 curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 curl_setopt($ch, CURLOPT_TIMEOUT, 100);
 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $req_type);//GET, PUT, POST
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 if($req_type!="GET")curl_setopt($ch, CURLOPT_POSTFIELDS, $json);//not needed for GET requests
 $result = curl_exec($ch);
 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
 curl_close($ch);
 // echo "http code: $httpCode<br />";

$body = json_decode($result);
 //echo "successfully got list for Cultivate CRM!<br />result:<hr />$result<hr />";
 $results['code'] = $httpCode ;
 $results['result'] = $result;
 // store the status message based on response code
 if ($httpCode == 200) {//if no error occurred:
 return $results;
 } else {//else an error occurred:
 return false;
 }//end else an error occurred
 }//end mailchimp_request PHP function by Ian L. of Jafty.com

Calling mailchimp_request Function

Here is how you use the above mailchimp_request PHP function:

<?php
//Construct the MailChimp API URL:
$mcAPIkey = 'YOUR-MC-API-KEY';
$mcListID = 'YOUR-MC-LIST-ID';
$email= 'MEMBER_EMAIL@EMAIL.COM';
$memberID = md5(strtolower($email));
$dataCenter = substr($mcAPIkey,strpos($mcAPIkey,'-')+1);
$url = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/lists/' . $mcListID . '/merge-fields/';    
//get the response:
$response = mailchimp_request($mcAPIkey,$url,'GET');
$httpcode = $response['code'];
$result = $response['result'];
$decoded_result = json_decode($result);
echo "http code: $httpcode<br>";
echo "Response data from getting address field data from MC API:
";
$merged_field_obj = $decoded_result->merge_fields;//should be an array of merged fields
print_r($merged_field_obj);
?>

MailChimp API

I’ve been doing a lot of work with the MailChimp API lately and figured it would be good to have a page dedicated to it here for future reference because it’s not very well documented online anywhere else… Hoping this will help some people who also have to use MailChimp’s API.

Understanding MailChimp Lists and the API

If you’ve ever dealt with MailChimp, you know that it is based on lists which can be segmented, grouped and managed all from the API as needed. Next I will demonstrate how to get a list of MailChimp lists and information on each list that exists.

Getting MailChimp List Information from API

Here’s the code I created to get all MailChimp Lists and information on each list from the MailChimp API using PHP code:

<h2>MailChimp List Info:</h2>
<?php
//Get API key :

$mcAPIkey =’Enter_your_own_API_key_HERE’;
//get info regarding MC lists
//use following url ‘https://usX.api.mailchimp.com/3.0/lists’

$dc = substr( $mcAPIkey, strpos( $mcAPIkey, ‘-‘ ) + 1 ); // datacenter, it is the part of your api key – us5, us8 etc
$args = array(
     ‘headers’ => array(
        ‘Authorization’ => ‘Basic ‘ . base64_encode( ‘user:’. $mcAPIkey )
    )
);

$response = wp_remote_get( ‘https://’.$dc.’.api.mailchimp.com/3.0/lists/’, $args );
$body = json_decode(wp_remote_retrieve_body($response));

$rcode = wp_remote_retrieve_response_code($response);
$tot_itms = $body->total_items;
echo “Response code was $rcode …$tot_itms items found!<br /><hr />”;
echo “<pre><code>”;
print_r($body);
echo “</code></pre><hr />”;
?>

The above code would return something like this for a MailChimp account that has one saved list:

MailChimp List Info:

Response code was 200 …1 items found!


stdClass Object
(
    [lists] => Array
        (
            [0] => stdClass Object
                (
                    [id] => xxxxxxxxx
                    [web_id] => xxxxxx
                    [name] => List Name
                    [contact] => stdClass Object
                        (
                            [company] => Company Name
                            [address1] => 1001 Your Road
                            [address2] => 
                            [city] => Adolphus
                            [state] => KY
                            [zip] => 42120
                            [country] => US
                            [phone] => 
                        )

                    [permission_reminder] => You signed up to learn more about how our team can better serve you.
                    [use_archive_bar] => 1
                    [campaign_defaults] => stdClass Object
                        (
                            [from_name] => First Last
                            [from_email] => your_email@domain.com
                            [subject] => 
                            [language] => en
                        )

                    [notify_on_subscribe] => 
                    [notify_on_unsubscribe] => 
                    [date_created] => 2018-02-25T02:01:38+00:00
                    [list_rating] => 0
                    [email_type_option] => 
                    [subscribe_url_short] => http://eepurl.com/dBXF4r
                    [subscribe_url_long] => https://yourcompany.us13.list-manage.com/subscribe?u=bf405c1xxxxxxxxb48df64c3&id=xxxxxxxxxx
                    [beamer_address] => us13-5df785xxxxx-xxx@inbound.mailchimp.com
                    [visibility] => pub
                    [double_optin] => 1
                    [marketing_permissions] => 
                    [modules] => Array
                        (
                        )

                    [stats] => stdClass Object
                        (
                            [member_count] => 3
                            [unsubscribe_count] => 0
                            [cleaned_count] => 0
                            [member_count_since_send] => 5
                            [unsubscribe_count_since_send] => 0
                            [cleaned_count_since_send] => 0
                            [campaign_count] => 2
                            [campaign_last_sent] => 
                            [merge_field_count] => 4
                            [avg_sub_rate] => 1
                            [avg_unsub_rate] => 0
                            [target_sub_rate] => 0
                            [open_rate] => 0
                            [click_rate] => 0
                            [last_sub_date] => 2018-04-28T20:26:38+00:00
                            [last_unsub_date] => 
                        )

                    [_links] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [rel] => self
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/edxxxxxxxxx
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/Response.json
                                )

                            [1] => stdClass Object
                                (
                                    [rel] => parent
                                    [href] => https://us13.api.mailchimp.com/3.0/lists
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/CollectionResponse.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/CollectionLinks/Lists.json
                                )

                            [2] => stdClass Object
                                (
                                    [rel] => update
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/edxxxxxxxxx
                                    [method] => PATCH
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/Response.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/PATCH.json
                                )

                            [3] => stdClass Object
                                (
                                    [rel] => batch-sub-unsub-members
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxxxx
                                    [method] => POST
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/BatchPOST-Response.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/BatchPOST.json
                                )

                            [4] => stdClass Object
                                (
                                    [rel] => delete
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxxxxxx
                                    [method] => DELETE
                                )

                            [5] => stdClass Object
                                (
                                    [rel] => abuse-reports
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxx/abuse-reports
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/Abuse/CollectionResponse.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/CollectionLinks/Lists/Abuse.json
                                )

                            [6] => stdClass Object
                                (
                                    [rel] => activity
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxxx/activity
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/Activity/Response.json
                                )

                            [7] => stdClass Object
                                (
                                    [rel] => clients
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxxxxxxx/clients
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/Clients/Response.json
                                )

                            [8] => stdClass Object
                                (
                                    [rel] => growth-history
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxxxxxxxxxx/growth-history
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/Growth/CollectionResponse.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/CollectionLinks/Lists/Growth.json
                                )

                            [9] => stdClass Object
                                (
                                    [rel] => interest-categories
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxxxx/interest-categories
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/InterestCategories/CollectionResponse.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/CollectionLinks/Lists/InterestCategories.json
                                )

                            [10] => stdClass Object
                                (
                                    [rel] => members
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxxx/members
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/CollectionResponse.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/CollectionLinks/Lists/Members.json
                                )

                            [11] => stdClass Object
                                (
                                    [rel] => merge-fields
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxxxx/merge-fields
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/MergeFields/CollectionResponse.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/CollectionLinks/Lists/MergeFields.json
                                )

                            [12] => stdClass Object
                                (
                                    [rel] => segments
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxxxxxx/segments
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/Segments/CollectionResponse.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/CollectionLinks/Lists/Segments.json
                                )

                            [13] => stdClass Object
                                (
                                    [rel] => webhooks
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxx/webhooks
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/Webhooks/CollectionResponse.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/CollectionLinks/Lists/Webhooks.json
                                )

                            [14] => stdClass Object
                                (
                                    [rel] => signup-forms
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxxxxxx/signup-forms
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/SignupForms/CollectionResponse.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/CollectionLinks/Lists/SignupForms.json
                                )

                            [15] => stdClass Object
                                (
                                    [rel] => locations
                                    [href] => https://us13.api.mailchimp.com/3.0/lists/xxxxxxxxxxx/locations
                                    [method] => GET
                                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/Locations/CollectionResponse.json
                                    [schema] => https://us13.api.mailchimp.com/schema/3.0/CollectionLinks/Lists/Locations.json
                                )

                        )

                )

        )

    [total_items] => 1
    [_links] => Array
        (
            [0] => stdClass Object
                (
                    [rel] => self
                    [href] => https://us13.api.mailchimp.com/3.0/lists
                    [method] => GET
                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/CollectionResponse.json
                    [schema] => https://us13.api.mailchimp.com/schema/3.0/CollectionLinks/Lists.json
                )

            [1] => stdClass Object
                (
                    [rel] => parent
                    [href] => https://us13.api.mailchimp.com/3.0/
                    [method] => GET
                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Root/Response.json
                )

            [2] => stdClass Object
                (
                    [rel] => create
                    [href] => https://us13.api.mailchimp.com/3.0/lists
                    [method] => POST
                    [targetSchema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/Response.json
                    [schema] => https://us13.api.mailchimp.com/schema/3.0/Definitions/Lists/POST.json
                )

        )

)

Learning WooCommerce API Manger

What is WooCommerce API Manger?

WooCommerce API Manger is used to secure your software with API License Key activation, deactivation and automatic updates of WordPress plugins and/or themes. However it can also be used for some applications outside of WordPress as well, but we will be talking mostly about how to use it with a custom WordPress plugin.

Prerequisites

You need to at least make sure you have at least PHP Version 7.00. Here’s how you can check from the linux command line:

php -v

Type the above command and press enter and you should get results that look similar to this:

php-v

 

Alternative Solution to WooCommerce API Manager

You may have noticed this article isn’t complete. That is because I decided to go with a different system for selling WordPress plugins on my site with API keys, WooCommerce didn’t provide the level of support I needed and their documentation was poor. I discovered Easy Digital Downloads which was much simpler to deploy. Easy Digital Downloads(EDD) in combination with the EDD Software Licensing add-on and the EDD Instant Updater for plugins that I developed myself, became the ultimate solution for selling WordPress plugins outside of WordPress.org. If anyone is interested in how I did it, email me at linian11@yahoo.com and I can assist you.

 

 

How to Send SMS Text Messages From PHP

In this PHP tutorial, I’ll be showing you how to send text messages to cell phones from a website or app using PHP with a simple HTML form to collect the data. The only drawback to sending messages from PHP is that you typically need to know the receiving party’s cell phone carrier in addition to their phone number. The only existing method of getting around having to know the person’s cell phone carrier is to use a paid service to send SMS messages such as an SMSC or Short Message Service Center. One provider of SMS services is https://www.twilio.com/.

What are your SMS messaging needs?

This is an important question you should answer before proceeding because if you need to be able to send text messages  with just a phone number and the message content, then you’ll need an SMSC like Twilio, otherwise, if you don’t mind making the user enter their Cell Phone Carrier name in addition to their phone number in a form to send a text message to them, then the free solution I’m about to show you will work fine for you.

Sending Text Messages From PHP

The basic high level steps to building an application to send out text messages from a web form are as follows:

  1. Built an HTML form that submits to a PHP processing script and that collects the receiving party’s phone number, cell carrier name and the text message content.
  2. Create the PHP processing script to receive and process the information gathered in the form and send out the text message, using an email service, to the receiving party.

The entire process in it’s simplest form is outlined below:

Write the HTML form. I created a folder named “SMS” and put a new PHP file named “index.php” inside the folder, then added the HTML for the text messaging form as you see here:

<form method=”post” action=””>
Phone No.: <input type=”text” id=”ph” name=”ph” value=”1231231234″ /><br />
<br />
Carrier: <select id=”ca” name=”ca”>
<option value=””>[Select a Provider]</option><option value=””>–Popular Providers–</option><option value=”alltel”>Alltel Wireless</option>
<option value=”@att.txt.net”>AT&amp;T</option>
<option value=”@myboostmobile.com”>Boost Mobile</option>
<option value=”@sms.mycricket.com”>Cricket</option>
<option value=”@messaging.nextel.com”>Nextel</option>
<option value=”@messaging.sprintpcs.com”>Sprint</option>
<option value=”@tmomail.net”>T-Mobile / Voice Stream</option>
<option value=”@tmomail.net”>TracFone</option>
<option value=”@vtext.com”>Verizon Wireless</option>
</select>
<br />
<br />
<textarea rows=”5″ cols=”65″ id=”msg” name=”msg”></textarea>
<br />
<input type=”submit” id=”sbtsms” name=”sbtsms” value=”Send Text!” /><br />

</form>

Above is your HTML form, next write some PHP code to process the above form like so:

<?php
if(isset($_POST[‘ca’])){//if info was submitted, send sms msg:
$ca=”;
$ph = $_POST[‘ph’];
$ca = $_POST[‘ca’];
$msg = $_POST[‘msg’];

//if carrier is still blank, set the default carrier(verizon is the most used carrier in the U.S., so….:
if($ca==”)$ca=’@vtext.com’;

//combine the phone number and the carrier to make the email address to send SMS messages to:
$send_to = $ph.$ca;
echo “Attempting to reach $ph via $ca carrier…..<br />”;
echo “Sending Message to $send_to:<br />$msg<hr />”;
$sent_sms = mail($send_to, ”, $msg);
if($sent_sms){
echo “<h2 style=’color:lime’>Message Sent!</h2>”;
}else{
echo “<h3 style=’color:red’>Oops! Something went wrong, try again later. Make sure you selected the right carrier and phone number.</h3>”;
}
}//end if info was submitted, send msg
?>

…the above code goes right after the </form> tag from above, then save the file as sms.php and upload it to your server and try to send yourself a message. If you use a different carrier than the ones provided in the code, you may need to add some options. A complete list of carriers can be downloaded online from https://davidwalsh.name/demo/SMS-Carriers.pdf

Here is a ready to copy and paste version you can simply copy all the below code into a file and save it as a .php file and it should work out of the box for the carriers listed in the provided dropdown:

<!DOCTYPE html>
<html>
<head>
<title>SMS via PHP</title>
</head>
<body>
<h1>Send Text Messages Online for Free!</h1>
<p>Yes, you can send SMS or Text messages online for free using PHP and sendmail. You simply have to provide all of the information requested in the below form and click the send text button to deliver it to the phone number you entered. You must know the receiving party’s phone carrier for this to work however.</p><p>Tip: you can usually get the carrier of someone’s phone by looking at an email they have sent you and reading the part after the @ symbol in the “From” email in the header of the email you received.</p>

<form method=”post” action=””>
Phone No.: <input type=”text” id=”ph” name=”ph” value=”1231231234″ /><br />
<br />
Carrier: <select id=”ca” name=”ca”>
<option value=””>[Select a Provider]</option><option value=””>–Popular Providers–</option><option value=”alltel”>Alltel Wireless</option>
<option value=”@att.txt.net”>AT&amp;T</option>
<option value=”@myboostmobile.com”>Boost Mobile</option>
<option value=”@sms.mycricket.com”>Cricket</option>
<option value=”@messaging.nextel.com”>Nextel</option>
<option value=”@messaging.sprintpcs.com”>Sprint</option>
<option value=”@tmomail.net”>T-Mobile / Voice Stream</option>
<option value=”@tmomail.net”>TracFone</option>
<option value=”@vtext.com”>Verizon Wireless</option>
</select>
<br />
<br />
<textarea rows=”5″ cols=”65″ id=”msg” name=”msg”></textarea>
<br />
<input type=”submit” id=”sbtsms” name=”sbtsms” value=”Send Text!” /><br />

</form>

<?php
if(isset($_POST[‘ca’])){//if info was submitted, send sms msg:
$ca=”;
$ph = $_POST[‘ph’];
$ca = $_POST[‘ca’];
$msg = $_POST[‘msg’];

//if carrier is still blank, set the default carrier(verizon is the most used carrier in the U.S., so….:
if($ca==”)$ca=’@vtext.com’;

//combine the phone number and the carrier to make the email address to send SMS messages to:
$send_to = $ph.$ca;
echo “Attempting to reach $ph via $ca carrier…..<br />”;
echo “Sending Message to $send_to:<br />$msg<hr />”;
$sent_sms = mail($send_to, ”, $msg);
if($sent_sms){
    echo “<h2 style=’color:lime’>Message Sent!</h2>”;
}else{
    echo “<h3 style=’color:red’>Oops! Something went wrong, try again later. Make sure you selected the right carrier and phone number.</h3>”;
}
}//end if info was submitted, send msg
?>

</body>
</html>

Taking it further

The main drawback to this method is that you have to also know the cell phone carrier, but I’ve thought of a way to overcome that with a bit of extra coding.  I found this site that takes the phone number in three parameters so for my business line,(234) 650-2011, it would be like this:

http://fonefinder.net/findome.php?npa=234&nxx=650&thoublock=2011

I plan to write a PHP script to resolve the address and scrape the results to get the carrier name. It will be a little complicated because you’ll need to get the carrier name and then translate it into the actual email for ea. carrier, but it is definitely possible with some work.

Summary:

That’s all there is to it! You can definitely improve upon this version of course as it is just meant to get you started. There is no form authentication and only very limited cell phone carriers listed in the dropdown, but the resource is provided to add more carriers from https://davidwalsh.name/demo/SMS-Carriers.pdf, so feel free to build onto what I’ve started here and let us know what improvements you’ve made in a comment so others can learn from it!

 

How to Clone a MYSQLI Table From Command Line

Here are the two commands you can run from the Mysqli Command Prompt to successfully clone a database table. In the example we will name our tables new_table_name and old_table_name where old_table_name is the table we wish to clone. This is the best way I have found to-date to create a backup of a mysqli table from the command line:

CREATE TABLE new_table_name LIKE old_table_name;
INSERT new_table_name SELECT * FROM old_table_name;

Be sure to enter line one above and press enter, then do the same with the second line.

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.

Is Payoneer Better Than PayPal?

PayPal has worked for me for several years and, while they have been mostly good to me, when you do need help, their customer service is practically non-existent. I had a horrible experience with them recently that has made me decide not to use them any longer for a while. I’m almost exclusively a seller and almost never a buyer which makes PayPal a poor choice for me it seems now. I have never had a dispute in all the years I’ve used PayPal until recently and I can not forgive the way PayPal handled that dispute. If you want to hear my story, read on, if you want to get right to using Payoneer as I suggest if you are a seller of goods or services like me, use this link to sign up for Payoneer now:

https://share.payoneer.com/nav/Z0p1ilVwR6cXc5rK-hfGzOqAEhykGqdX9Q20h_PXFPXbJvtO-8cjY1wD_4Db8uwuUY0QGJmc9EVKLQ-V_ld1OA2

My Experience with PayPal

My bad experience that makes me want to completely stop using PayPal has to do with a former client of mine that filed a dispute after I had to inform them that I had to quit working for them because another client needed me(the other client that needed me has been a client for many years and the client I quit working for was new). When I quit working for the new client, he still owed me roughly $200 in my opinion. He had paid me a deposit of $200 when I started working with him because I always get a deposit to protect me from newer clients. I had completed a total of $400 worth of work before I quit working for him however, so really he still owed me $200. I was going to forgive the money he owed me however, since I had quit because I figured he wouldn’t pay it anyway. So, for being a nice guy, the new client rewards me by filing a dispute on PayPal asking me to return $95 to him! I was shocked, but had confidence that PayPal would see it for what it was, an attempt by a client to get his money back even though I had completd the work, Fraud. So I refused to return the money and he escalated his false claim. To my surprise, without doing any investigation what-so-ever, PayPal made a decision in his favor. Okay, so I lost, I could have handled that without closing my account, but the kicker is that they didn’t just reward the client the $95 he was asking for, they reversed the entire $200 payment he ad sent me! After losing the dispute, I first tried to call PayPal’s “customer support” and was told I would have to wait on hold for over an hour! I waited on hold regardless of the ridiculous amount of hold time, but the call was never answered so I gave up after over an hour of waiting for a human to speak with about my issue. Then I sent them sent an email asking them why and got a computer reply that had absolutely nothing to do with the questions I asked in the email. So obviously, I was getting nowhere and it is clear now that I just got ripped off for $200 by PayPal and my former client. So, hello Payoneer! I’ll let you all know how this new payment method works for me. Hopefully better than my experience with PayPal! Again, here’s the link for Payoneer if anyone else wants to check them out:

payoneer.com

My experience with Payoneer

So, while I am new to Payoneer, I will post my experiences here so others can benefit from them. First off, if you want or need to get your money immediately(Like you could with a PayPal Credit card if you were lucky enough to be approved), then Payoneer might not be the best service for you. I sent out my first invoice several days ago, on a Thursday to a client I completely trust and that client informed me that he paid the invoice immediately that same day, so the invoice was paid on Thursday. It is now the following Saturday and the invoice is yet to be even marked as paid in my Payoneer account. That kind of worries me. I read in their F.A.Q. that it can take from 3-5 business days, so luck me, it’s the weekend! Right? Oh well, so that means it has only been one business day so far and the fifth business day would be next Thursday. I have to say that it it in fact takes that long, I won’t be happy with the services at all. On the other hand, it the payment is in my account by Monday or Tuesday, I will be satisfied, not perfectly happy, but barely satisfied. I currently hate PayPal so much that I don’t mind waiting a few days to get paid another way. However, a week is too long, so I’ll let you all know asap when I can actually get the funds that were sent to me last Thursday. FYI, here’s an image from Payoneer’s website regarding information about the billing service I used to send my first invoice to my long-time trusted client:

payoneertable

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!

Enabling Multiple Domain Names and Sites on Apache2 Server

Today I set up a new server and I am documenting exactly how to set up multiple domain names, sub domains and websites on a new Apache2 Server. I am using Ubuntu, but I believe these directions are similar for any Linux Apache2 web server.

Pointing your domain or sub-domain

It is a good practice to point your domain name or sub-domain first, before you set it up on your server which I’ll cover afterwards below, so let’s go ahead and point our domain. Whether you are using a new domain name or a sub-domain on one of your existing domain names, the process is similar for pointing the domain name or sub domain name to your server IP address. You will need to go to your domain management console and create a Type “A” record. This will normally be done in your DNS provider’s advanced DNS settings or zone file settings. Use the following settings to create two new records:

  • Name: if there is a name field, enter the domain name or sub-domain name(most require you to follow the domain with a “.” so for my sub domain I entered “subdom.jafty.com.“.
  • Type: “A” for both records.
  • Hostname field: enter “www” in the first record and “@” in the second.
  • Destination IPv4 address(sometimes just called Address): Use your server’s IP address for both records.
  • TTL: use “14400” for both records.

That should be enough information for you to figure out how to create your two host records on just about any platform, but if your platform differs, ask your provider for assistance or google the providers name followed by DNS instructions or “How to point a name with Provider Name”. You are creating two similar records, one for WWW and one for @. That way visitors of your site can access with either www.example.com or just example.com. The Hostname of @ makes the record for the domain without “www” in front of it. If your provider’s DNS settings do not include the Host or Hostname field where we put either www or @, then you probably need to create two records with different names instead. For example, name one record “example.com.” and name the other “www.example.com.”. If you’re using a sub domain then name one “sub.example.com.” and the other “www.sub.example.com.” You don’t really need a www record for sub domains usually, but you can use one if you want, it won’t hurt anything and might help some users find your site.

Steps to adding  a second domain name to your server

Here I am going to explain how I set up a sub domain as as second domain name pointing to a second website on my Linux/Apache2 web server:

Note: My first site was already set up in var/www/html. Most people prefer to set up multiple websites under the var/www directory, but to keep things simple, I’m going to use the var/www/html folder and not var/www. It really makes no difference. It’s just a preference.

  1. Create your directory structure for your new website that will reside on your new domain or sub-domain. I’m creating a sub domain like subdir.jafty.com, but these directions are the same as if I were using just jafty.com instead. First, create the directory /var/www/html/subdir.jafty.com. Then create /var/www/html/subdir.jafty.com/logs and /var/www/html/subdir.jafty.com/public_html. If you are logged into FileZilla as root, you can create these from there, otherwise log in with putty and create them using the sudo command.
  2. Create your log files. Simple make two empty files named access.log and error.log and upload them to the logs folder you created in step one above.
  3. Create a VHOSTS file named after the domain or sub-domain followed by .conf, so in my case, I’d name my file subdir.jafty.com.conf. THen copy and paste the  content below under the heading “VHOSTS Example File Contents” into it then change all instances of my sub-domain name with your own domain or sub domain and upload that file to /etc/apache2/sites-available.
  4. Next, use the a2ensite tool from the Linux command line to finalize the new site with the following command(replace example.com with your domain or sub-domain):  sudo a2ensite example.com.conf
  5. Reset apache2 with: sudo service apache2 restart

VHOSTS Example File Contents

<Directory /var/www/html/planner.jafty.com/public_html>
    Require all granted
</Directory>
<VirtualHost *:80>
    ServerName planner.jafty.com
    ServerAlias www.planner.jafty.com

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/planner.jafty.com/public_html

    ErrorLog /var/www/html/planner.jafty.com/logs/error.log
    CustomLog /var/www/html/planner.jafty.com/logs/access.log combined
</VirtualHost>

Automating the process of setting up domain names and sub domains

If you have to do this often or alter DNS records often and create lots of virtual hosts, you should probably look into automating the process. I provide such a service and have done so for several of my clients. What I do is create a simple user interface in a secure admin web page on your own server where you can simply enter the domain name or sub domain name into a form field and press GO and it does all the above work for you! A real time saver if you have to do this more than once in a great while! IF you are interested in this service, contact me, Ian L. of Jafty.com for a fast, free quote by email or Skype. My email is linian11@yahoo.com and my Skype name is ianlin11. Or use the contact link on this site.

Summary

That is how you do it!