Get in Touch

A little tutorial on the Select2 JQUERY Plugin with a BASIC AJAX response via a PHP script.

On a recent project I was looking for an autocomplete jquery plugin that acts like a select box. The reason i need it as a select box is to prevent incorrect data choice. At first i was running the great jquery-ui plugins and using the autocomplete via a text box and retrieving data via ajax and json.
However I soon discovered that my clients could type data in the textbox and if the answer was not on the autoselect it added the text they have typed. Now when trying to search through a database for results this caused me a bit of a headache. So I plodded over to Google and looked for an alternative.

I understand that the Jquery-UI version has a bind method for select but it just seemed a bit messy and the coding was not the easiest to follow.

Next I found a great plugin called chosen : http://harvesthq.github.com/chosen/ and this was an excellent plugin. The only problem I had was loading the data via ajax for a keypress. For my particular project I had 68000 titles in a database I needed to search. Now that makes for a large select option list.
So I plodded back onto Google and found a link via Stack-Exchange for a plugin called Select2.

So I thought I would give this a go… Only issue was the ajax example was not easy to follow as they have used an advanced options to retrieve data from rotten tomatoes.
But this was the plugin I wanted. I found some help here : http://it.toolbox.com/blogs/rymoore/select2-jquery-select-boxes-54810 with the easy ajax answer.

I am writing this post to show you how to use php to send the json back to the ajax request.

Firstly the html required :

Option Value :

Should produce similar to this :

jqueryversion3blog2

Notice that because I am using ajax to get the result the field has to be hidden.
The name is the used as usual to send the value through the form.
The data-placeholder appears as the select box placeholder.

Now I added the following jquery :

$(document).ready(function(){

$('#selectbox-o').select2({

minimumInputLength: 2,

ajax: {

url: "../datafeeds/optionlist.php",

dataType: 'json',

data: function (term, page) {

return {

q: term

};

},

results: function (data, page) {

return { results: data };

}

}

});

});

The option I have set is minimumInputLength: 2,

This means that the ajax will not get called until 2 characters have been entered into the search box.
After 2 characters have been entered it does an ajax onto optionlist.php (change to your PHP file).
Datatype is set to json as the data is sent back from PHP via json.
term is characters entered and q being the string that is sent to the script in the form of a GET.
The results are then returned to data.

So the PHP script (optionlist.php) is a mysql query on a database to get a json string back.
The select2 plugin looks for the ajax to appear as : [{“id”:”blah”,”text”:”blah text”},{“id”:”blah2″,”text”:”Blah2 text”}]
This will show the text in the select box and the value of the input will be the id..
so if it was enetered as a standard select box :

Blah Text

Blah2 Text

Now for the magical PHP script.
I am using pdo with a prepared statement for added security.
I am not going to show connection process.

*** UPDATE ***
I have updated the syntax on this following the comment from Gustavo to avoid servers with error-reporting switched on all

How advanced you make the MySQL query is entirely down to you. In my picture I join the MySQL with a products database with a count to give me back the amount of items shown.

Please feel free to drop me a comment if you spot a mistake or you have any comments or suggestions.

Updated April 2015

There is now a newer version of the Select 2 plugin available. This is V4 at present. They have altered the way the ajax works so this tutorial will not work with this version.
View an updated tutorial for Select2 Version 4.

MySql Quick Tip

This is just a quick tip on how to kill a MySQL process that has become stuck.

This sometimes occurs when an update/create command on a large amount of database entries.

Firstly login to phpMyAdmin and find the appropriate database.

Select the SQL tab and in the window enter :

SHOW PROCESSLIST

This will then show all currently running MySQL processes.

Just find the process that is stuck and press the <Kill> text to finish that process.

Hopefully this quick tip may help.

As website developers, we all hope the day does not come when a client phones to tell you that their website has been hacked, or weird popups are appearing, or worse still the web hosting company has taken their site offline.

Well recently a clients WordPress site that we have just inherited was hacked, (just to be clear it was not a site we wrote or even host, we have just been given the site when their last developers closed).

So the first thing to do is browse through all the weird .php files that have popped up and insure they are not injected code.

Realistically the site will need to redone completely on the latest version of WordPress or Joomla.

The question is:
What is there to warn us of the possible file injection?

And the answer:
Well not a huge amount. I googled about and a lot of scripts on Github ran from SSH, or others were quite heavy in cost.

As the site was not hosted by us, SSH was out of the question. As the customer was running on a budget the costly versions were also a no.

After a few minutes of searching, I stumbled across a script by Mike Stowe (http://www.mikestowe.com) - https://www.mikestowe.com/blog/2010/10/php-malicious-code-scanner.php.

This scans the whole home directory and searches for ‘eval’ and other such injections.

You simply upload the script to the home directory, setup the email and run it manually or via a Cron job.

In our case, I did find another injection which was not found so we add another search for the extra code.

/* if you are looking for other injected code add here */        if(preg_match('/x65\/li\x6eweb/' , $contents)){            $this->infected_files[] = $file;            echo 'Infected File : '.$file.'';        }

This worked perfectly and gave us the results we needed. We were able to scan every hour and catch the code before it did any harm.

However, we decided that there were other things that we may require from the scanner, such as added files, modified files and removed files.

So we pulled the main scan script out and set about building a full class that will do these checks as well as the ‘eval scanner’.

First off we created a serialised array which stores the files in the home directory. This was quite straight forward as we were already grabbing a list of the files within the eval script.

/**     * Function will create a file containing a serialiazed array of files scanned     */    function writeFile() {        // debug. Uncomment to get a fresh file list        // $this->freshclean();         $data = serialize($this->fileindex);        $fopen = fopen('scanner-logs/scannerfiles.txt', 'w+');        fwrite($fopen, $data);        fclose($fopen);    }

This serialised data was then written to a file within a scanner-logs folder. We then pull this file and unserialize the text into an array.

/**     * Function to read the previously canned filenames and unserialize them to an array     * It will also return the last time a file list was created     */    function readFile() {        $this->oldfileindex = unserialize(file_get_contents('scanner-logs/scannerfiles.txt'));        $this->lastscan = filemtime('scanner-logs/scannerfiles.txt');    }

This file is only rewritten if any files have been updated, added or removed. We can use the date this file was modified as a point to check for modifications. ($this->lastscan)

So we now have 2 arrays, 1 with the new files listed and 1 with the old files. We also have our last modified point to check from.

Whilst scanning the directories for eval injection we check each file modified time against the last modified time of the stored old list.

/**     * Function to check the file contents for injections     * @string $contents Content of the file     * @string $file     Filename being checked     */    function check($contents,$file) {        $this->scanned_files[] = $file;        $this->fileindex[]     = $file;         // check for injection        if(preg_match('/eval\((base64|eval|\$_|\$\$|\$[A-Za-z_0-9\{]*(\(|\{|\[))/i',$contents)) {            $this->infected_files[] = $file;        }         /* if you are looking for other injected code add here */        if(preg_match('/x65\/li\x6eweb/' , $contents)){            $this->infected_files[] = $file;        }         // check for modification        if(filemtime($file) > $this->lastscan){            $this->modified[] = $file.' modified '.date ("F d Y H:i:s.", filemtime($file));        }    }

So to check for added files we do an array_diff on the new list against the old list. Gives us array of added files.

// files added        $difference = array_diff($this->fileindex, $this->oldfileindex);        if(count($difference) > 0){            // set flag for file write            $updateList = true;             $message .= "== FILES ADDED ==  ";            foreach ($difference as $added) {                $message .= $added."";            }        } else {            $message .= "== NO FILES HAVE BEEN ADDED ==  ";        }

Next, we do a check for removed files using an array_diff on the old list against the new list. Gives us array of removed files.

// files Removed        $removed = array_diff($this->oldfileindex, $this->fileindex);        if(count($removed) > 0){            // set flag for file write            $updateList = true;             // add results to message            $message .= "== FILES REMOVED ==  ";            foreach ($removed as $deleted) {                $message .= $deleted."";            }        } else {            $message .= "== NO FILES HAVE BEEN REMOVED ==  ";        }

So now we have 4 arrays:

One with any injected files listed

One with any modified files listed

One with any added files listed

One with any removed files listed

So now we create a message by looping through the arrays.

We can now send an email to the email list with all of this content.

$header = "

PHP Web Scanner Results

“; $footer .= ”

Website was scanned by PHP Web Scanner by DSM Design Design Ltd“; $headers = “MIME-Version: 1.0” . “\r\n”; $headers .= “Content-type:text/html;charset=UTF-8” . “\r\n”; // More headers $headers .= ‘From: PHP Website Scanner <‘.FROM_EMAIL.’>’ . “\r\n”; mail(EMAIL_ALERT, ‘Website Scan results’, $header.$message.$footer, $headers); echo $message;

To add to this we create a log file to keep a track of the results.

/**     * Function to log results for future reading     * @string $message Records a log of the results     */    function logResults($message) {        $fopen = fopen('scanner-logs/scan-results-'.date('H:i').'.log', 'w+');        fwrite($fopen, $message);        fclose($fopen);    }

(if run hourly the files overwrite themselves daily).

So we put all the functions together within our phpWebScanner class.

In our index file, we have a couple of variables to add in and we are complete.

// Setupdefine('EMAIL_ALERT','');define('DOMAIN', '');define('FROM_EMAIL', '');

Just run the scanner by going to <domain>/php-web-scanner.
or create the cronjob to ‘wget’ the file as often as you wish.

Feel free to download the whole package over at GitHub here

If you wish to edit, improve or help with the script please feel free to do so.

(please leave all original credits in place)

Recently a client requested that we display for them a percentage of how far through the tax year we are. I did some looking online however I couldn’t find anything which suited my needs.

Below is the code I ended up writing which will calculate the percentage value and display the output at the end.

$currentMonth     = date('n');

$currentYear      = date('Y');

$dayInYear        = date('z');

$taxYearStartYear = $currentMonth < 4 ? $currentYear - 1 : $currentYear;

$taxYearStart     = $taxYearStartYear . '-04-01 00:00:00';

$taxYearStartDay  = date('z', strtotime($taxYearStart));

$taxDayInYear     = $dayInYear < $taxYearStartDay ? ($dayInYear + 365) - $taxYearStartDay : $dayInYear - $taxYearStartDay;

$taxYearPassed    = ($taxDayInYear / 365) * 100;

echo $taxYearPassed.'% of the way through the tax year';

Since my last tutorial on the Select2 Jquery  plugin using remote data loaded using Ajax and PHP has been so successful, I am updating the tutorial to work with the newer Version 4 plugin.

If you don’t know what the Select2 plugin is : Its a Jquery plugin to turn an input/select field into a dropdown select box with searchable and stylable features.

Head over to https://select2.github.io/ to find out more.

So continuing their excellent plugin they have now improved and upgraded the plugin to Version 4. And although the documentation has improved, it still is quite hard to understand the concept of Ajax remote data pulled from a MySQL database into the plugin.

As my last tutorial on V3 of the plugin has been so helpful to many people and I have been asked about Version 4. I am going to show you how to use the plugin with a small PHP script to pull remote data from the database.

If you would prefer to use the Version 3 of this plugin you can view my tutorial here : jquery-select2-ajax-tutorial

Initial Instructions

Firstly, if you haven’t already downloaded the plugin go on over to their website or onto Github and grab a copy of the plugin.

For this tutorial you will need the CSS files and JS files located within the dist folder.

Within your head area make sure you include the location to the .css file.

And within the footer ensure you have loaded jquery and then the select 2 plugin.

So that the basics loaded into the page.

Now for the HTML Instructions

** The old version used to convert a hidden Input field into a select2 dropdown. **

So you add a Select box to your HTML form:

Product Name

And a little bit of Jquery

$( ".productName" ).select2({

ajax: {

url: "/ajax/productsList.php",

dataType: 'json',

delay: 250,

data: function (params) {

return {

q: params.term // search term

};

},

processResults: function (data) {

// parse the results into the format expected by Select2.

// since we are using custom formatting functions we do not need to

// alter the remote JSON data

return {

results: data

};

},

cache: true

},

minimumInputLength: 2

});

So after the input length has reached 2 characters it uses ajax to load the results from our page set in the URL element.
It is going to send the Search String through to the php as $_GET in the field name of : q.
So our ajax request will go : /ajax/productsList.php?q=

Now some PHP Instructions

We will use a small php script to connect to a MySQL Database and search for a matching field.
I always use PDO with MySQL and prepared statements. This should prevent any chance of MySQL Injection which older MySQL queries did not protect against Out of the box.
If you are unsure how to connect to a Database there are plenty of Tutorials on the web on how to do this.

If you view the remote data load on the Plugin page you see the results can be translated in many ways and styled in an image/list results.
Please read the documentation there to learn how to do this.

Hopefully this has helped you if you have upgraded from version 3 to version 4 of the Jquery Select2 plugin.