Why we moved from OpenShift to Google Cloud

The good old days

When OpenShift was in its version 1 it was great from the customer’s point of view with a low budget. OpenShift v1 had free offers to deploy apps and add a custom domain to it. There was no SSL support but it could be handled via the CloudFlare solution, making the overall solution a great one.

Then there comes OpenShift v2

RedHat then launched OpenShift v2 and added a restriction that gears will be shut down after a certain period of inactivity and also removed the support for custom domain.

That was the time that we had to move to some other cloud platform that could support our apps with low resources and without investing anything. Because all good things in life are free.

Google Cloud to the rescue

So we came across the Google Cloud platform offering and we had $300 credit in a free trial for 6 months. That was more than enough for us to start with. And in fact, they have micro virtual machine instances that are free for life with 30GB storage. That is more than enough for small apps to run for free that are under experiment or don’t have any monetization plans.

So, we migrated several of our apps from OpenShift to Google Cloud and started leveraging free credits provided by Google.

Just this week we consumed all our credit and our trial expired. Our virtual machine instances were shut down, but it didn’t take long before we enabled billing on our project and downgraded our instances to micro ones which are free. That gave us such a relief that our apps are still running although with low resources but it is fine as they are not our revenue-generating apps and are just experiments.

Click here to read more about Google.

Different color for each menu item in WordPress

In a recent project, I got a requirement that each menu item should be highlighted in a different color when visited. The menu items and their required active colors were:

  • Home – Green
  • Portfolio – Blue
  • Team – Yellow
  • Contact – Red

These colors were to be applied only when that page is being visited otherwise color of the menu item should be the default black color.

So, if a user is visiting the home page then the menu item should something like this

home_menu.png

And if the user is visiting the Portfolio page then the menu should be something like this

portoflio_menu.png

Considering that this was a WordPress theme project where we were using Understrap as a base theme which is based on Twitter Bootstrap. So, when user visits, for example, a home page WordPress will attach a .active CSS class to it. Taking advantage of that we added different classes for each menu item and then used the following rule to make menu item colors different:

.navbar-nav > .home.active > a {
    color: green!important;
}
.navbar-nav > .portfolio.active > a {
    color: blue!important;
}
.navbar-nav > .team.active > a {
    color: yellow!important;
}
.navbar-nav > .connect.active > a {
    color: red!important;
}

CSS Class Chaining Method

We utilized the class chaining method here. If you note that .home.active classes are chained together without space and which means it will select an element with both these classes.
That did the trick and all menu items were in a different color.

Rollover image – Change image on hover/mouse over

Often when designing websites static or dynamic, PHP or ASP.Net, Laravel or WordPress, you have to design in a way that if the user hovers an image it gets changed and an alternate image is displayed. This can be easily achieved via simple HTML events. Here is the trick:

<img src="FIRST IMAGE URL GOES HERE"
onmouseover="this.src='SECOND IMAGE URL GOES HERE'"
onmouseout="this.src='FIRST IMAGE URL GOES HERE - AGAIN'" />

It is simple as that.

Click here to read more tips.

Laravel: Specified key was too long error on migration

When you install a new Laravel project with ‘laravel new’ and run the migration that comes with it you might get the following error:

#php artisan migrate
Migration table created successfully.


 [Illuminate\Database\QueryException]
 SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`))

[PDOException]
 SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes

To solve this error edit your app/Providers/AppServiceProvider.php file.

Add the namespace:

use Illuminate\Support\Facades\Schema;

and then add the following line in boot() method of your AppServiceProvider class.

use Illuminate\Support\Facades\Schema;

class AppServiceProvider extends ServiceProvider
{
 /**
 * Bootstrap any application services.
 *
 * @return void
 */
 public function boot()
 {
   Schema::defaultStringLength(191);
 } 
}

This should solve your problem. Just delete all the tables and rerun the migration.

Click here to read more about Laravel.

Setup CodeIgniter Docker container for development

Docker

Docker is the world’s leading software container platform. Developers use Docker to eliminate “works on my machine” problems when collaborating on code with co-workers. Operators use Docker to run and manage apps side-by-side in isolated containers to get better compute density. Enterprises use Docker to build agile software delivery pipelines to ship new features faster, more securely and with confidence for both Linux and Windows Server apps. If you want to learn more about Docker head to their What is Docker section here.

CodeIgniter

CodeIgniter is a powerful PHP framework with a very small footprint, built for developers who need a simple and elegant toolkit to create full-featured web applications. If you want to learn more then head to their official website which has great documentation as well at https://codeigniter.com/

CodeIgniter on Docker

If you’re excited about using Docker for your development and you are working on a CodeIgniter (CI) based PHP project then you are lucky. It is very easy to setup CI based project with Docker. Just follow the instructions below to setup a fresh CI project with Docker.

docker-compose up -d

It will spin up two containers—one for the app itself with Nginx and another for MariaDB for your DB. App container will create a directory in your project folder and install CodeIgniter in it.

Now browse http://localhost:8000 in your browser and you’ll see the CodeIgniter page. It’s that easy.

Click here to read more about Docker.

Setup Laravel with Docker containers

Docker

Docker has captured my attention lately and has been growing exponentially for last few years. Docker has revolutionized the virtualization space and has given DevOps engineers and developers a new set of tools that can ease their development as well as infrastructure resource utilization. Mostly Node.js apps have been deployed with Docker but it is not limited to only that. If you’ve been developing apps for web using PHP and Laravel framework then you are lucky that community has developed some great tools to utilize docker in their development workflow. If you are new to Docker and want to learn more about Docker then visit their website docker.com specially the section What is Docker?

Laradock

Laradock does the hard part and facilitate developers to quickly and easily setup Laravel development environment in seconds. Follow the these steps to get started.

Setup fresh environment then install Laravel inside docker

  • Create project directory. e.g. myproject
  • Create another directory within myproject directory for source that you will use commit to git repo. eg. app
  • Clone the laradock repo inside myproject folder, this will create laradock folder
git clone https://github.com/laradock/laradock.git
  • Edit the docker-compose.yml file to map to your project directory once you have it (eg. – ../app:/var/www)
  • Run the following command
docker-compose up -d nginx mysql redis beanstalkd
  • Enter the workspace
docker-compose exec workspace bash
  • cd to /var
  • Install Laravel
composer create-project laravel/laravel www
  • Open your .env file and set the following
DB_HOST=mysql
REDIS_HOST=redis
QUEUE_HOST=beanstalkd

Now open your browser and visit http://localhost

You will see running Laravel app. That was cool!

You can also connect to mysql using these settings.

Host: localhost
User: root
Password: root

If you want to add more services see the official laradock docs. It support tons of other services like memcache, pgsql etc.

Daily Use

Following are some docker related commands that you want to use on daily basis once your development environment is setup.

  • To bring up the servers to run application
docker-compose up -d nginx mysql
  • Enter workspace container to run commands like artisan, composer, phpunit, gulp etc.
docker-compose exec workspace bash

or on Windows PowerShell

docker exec -it {containerid} bash
  • List current running containers
docker ps
  • List current project containers
docker-compose ps
  • Close all running containers
docker-compose stop
  • Delete all existing containers
docker-compose down
  • View the log files
docker logs {container-name}

Override parent shortcodes in your WordPress Child Theme

Overriding shortcode defined in WordPress parent theme is pretty easy.

Just use a after_theme_setup section in functions.php of the child theme;

example:

add_action( 'after_setup_theme', 'my_child_theme_setup' );

function my_child_theme_setup() {
   remove_shortcode( 'your_shortcode' );
   add_shortcode( 'your_shortcode', 'my_shortcode_function' );
}

function my_shortcode_function( $atts, $content = null ) {
    extract(shortcode_atts(array(
    ), $atts));
    $out = 'content">'.do_shortcode($content).'</div>';
    return $out;
}

Click here to read more about WordPress.

Create your first real-time PHP application

If you ever wondered if there is a way to write a real-time web application using PHP where any event or message is delivered/pushed to all recipients as they occur, in real-time? Then you are at the right place. We’ll be building a sample real-time chat application using PHP and Ratchet and all messages will be pushed to all recipients in real-time. There are other technologies like node.js and socket.io but obviously, there is a learning curve. If you don’t have time to learn a new thing or just want to stick with PHP then keep reading.

Goal

The goal of this application is to write a simple Chat application. Chats in event-driven programming are the “Hello World!” of applications. The chat will accept all incoming messages and deliver that message to all other connections.

The Chat class

Note: This document assumes you are familiar with PSR-0 and Composer. See Installation if you’re not yet familiar with this.

We’re going to hold everything in the MyApp namespace. Your composer file should look something like this:

{
    "autoload": {
        "psr-0": {
            "MyApp": "src"
        }
    },
    "require": {
        "cboden/ratchet": "0.3.*"
    }
}

We’ll start off by creating a class. This class will be our chat “application”. This basic application will listen for 4 events:

  • onOpen – Called when a new client has Connected
  • onMessage – Called when a message is received by a Connection
  • onClose – Called when a Connection is closed
  • onError – Called when an error occurs on a Connection

Given those triggers, our class will implement the MessageComponentInterface:

<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface {
    public function onOpen(ConnectionInterface $conn) {
    }

    public function onMessage(ConnectionInterface $from, $msg) {
    }

    public function onClose(ConnectionInterface $conn) {
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
    }
}

You’ll notice, that in addition to just implementing methods from the MessageComponentInterface, we’ve given our application a namespace and are accepting the ConnectionInterfaceclasses. This class, usually implemented by a Connection instance, is a representation of a client’s connection on the other side of the socket. On each of the four triggered events, the client Connection representation is passed. These objects are re-used, and you will receive the same Connection sometimes.

Save this as /src/MyApp/Chat.php. We’ll come back to our Chat class soon.

Instantiation

Our Chat class will be our application logic. Next, we’re going to piece together our shell script. This is the script/file we will call from the command line to launch our application.

<?php
use Ratchet\Server\IoServer;
use MyApp\Chat;

    require dirname(__DIR__) . '/vendor/autoload.php';

    $server = IoServer::factory(
        new Chat(),
        8080
    );

    $server->run();

Above, you’ll see we create an I/O (Input/Output) server class. It stores all the established connections, mediates data sent between each client and our Chat application and catches errors. The new instance of the Chat class then wraps the I/O Server class. Finally, we tell the server to enter an event loop, listening for any incoming requests on port 8080.

Save this script as /bin/chat-server.php. Now, we can run it with the following command in your terminal:

$ php bin/chat-server.php

The script should now execute, taking possession of your terminal. You can cancel the script, as we’re not quite finished yet.

Logic

So far, we’ve just set up the structure, both in our shell script and our Chat class. Now, to add code to our Chat to complete our application.

Let’s add some logic to our Chat class. What we’re going to do, is track all incoming Connections, in order to send them messages. Typically, you would store a collection of items in an array, but we’re going to use something called SplObjectStorage. These storage containers are built to store objects, which is what the incoming Connections are.

<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface {
    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {
        // Store the new connection to send messages to later
        $this->clients->attach($conn);

        echo "New connection! ({$conn->resourceId})\n";
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        $numRecv = count($this->clients) - 1;
        echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
            , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');

        foreach ($this->clients as $client) {
            if ($from !== $client) {
                // The sender is not the receiver, send to each client connected
                $client->send($msg);
            }
        }
    }

    public function onClose(ConnectionInterface $conn) {
        // The connection is closed, remove it, as we can no longer send it messages
        $this->clients->detach($conn);

        echo "Connection {$conn->resourceId} has disconnected\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "An error has occurred: {$e->getMessage()}\n";

        $conn->close();
    }
}

Running It

Complete, let’s run it and test it. Open up three terminal windows, typing:

$ php bin/chat-server.php
$ telnet localhost 8080
$ telnet localhost 8080

In each of the telnet windows, type a message (“Hello World!”) and see it appear in the other!

Next Steps

Now that we have a basic working Chat application, let’s make that work in a web browser (Chrome, Firefox, or Safari [for now]). First, let’s go back to our chat-server.php script. We’re going to utilize another component of Ratchet; the WsServer class:

<?php
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;

    require dirname(__DIR__) . '/vendor/autoload.php';

    $server = IoServer::factory(
        new HttpServer(
            new WsServer(
                new Chat()
            )
        ),
        8080
    );

    $server->run();

Run the shell script again, open a couple of web browser windows, and open a javascript console or a page with the following javascript:

var conn = new WebSocket('ws://localhost:8080');
conn.onopen = function(e) {
    console.log("Connection established!");
};

conn.onmessage = function(e) {
    console.log(e.data);
};

Once you see the console message “Connection established!” you can start sending messages to other connected browsers:

conn.send('Hello World!');

This post was extracted from Ratchet documentation.


WooCommerce Per Product Shipping Price Calculation

If you have different rates depending on the item you will need to set up each one in the ‘Flat Rate‘ shipping method and ensure it is selected on the Product itself.

First, you will need to have a Shipping Class setup:

Go to the menu on the left hand, under Products you will find Shipping Classes.
Give your Shipping Class a name and a description and then hit “Add New Shipping Class”

Once that is done you can go back to the Shipping Setup, Under WooCommerce Settings.

Click on Flat Rate and at the bottom of the screen click on “Add New Rate”
Choose your Shipping Class.
Give it a cost and a handling fee.

Why will you need separate shipping classes?

Imagine you sell small items but just so happen to have one large item you want to sell on your site. You obviously cannot charge the same as you can with the small items.

Converting Oracle DATE types and PHP/Unix Timestamps

If you need to convert between Oracle date and PHP/Unix timestamp then you might need to implement two functions in Oracle.

The following two Oracle functions implement this for DATE types.

To convert a UNIX timestamp into an Oracle DATE type:

CREATE OR REPLACE
    FUNCTION unixts_to_date(unixts IN PLS_INTEGER) RETURN DATE IS
        /**
         * Converts a UNIX timestamp into an Oracle DATE 
         */
        unix_epoch DATE := TO_DATE('19700101000000','YYYYMMDDHH24MISS');
        max_ts PLS_INTEGER := 2145916799; -- 2938-12-31 23:59:59
        min_ts PLS_INTEGER := -2114380800; -- 1903-01-01 00:00:00
        oracle_date DATE;

        BEGIN

            IF unixts > max_ts THEN
                RAISE_APPLICATION_ERROR(
                    -20901,
                    'UNIX timestamp too large for 32 bit limit'
                );
            ELSIF unixts < min_ts THEN
                RAISE_APPLICATION_ERROR(
                    -20901,
                    'UNIX timestamp too small for 32 bit limit' );
            ELSE
                oracle_date := unix_epoch + NUMTODSINTERVAL(unixts, 'SECOND');
            END IF;

            RETURN (oracle_date);

    END;

The following PHP script shows how this might be used. Note that this script requires PHP 5.x+, as it uses the new OCI extension function names:

<?php
$conn = oci_connect('scott', 'tiger');

$sql = "
    SELECT
        *
    FROM EMP
    WHERE
        hiredate
    BETWEEN
        unixts_to_date(:startdate)
    AND
        unixts_to_date(:enddate)
    ORDER BY
        hiredate
    DESC
    ";

$stmt = oci_parse($conn, $sql);

// Bind a UNIX timestamps to :startdate and :enddate
oci_bind_by_name($stmt, ":startdate", mktime(0,0,0,1,1,1981));
oci_bind_by_name($stmt, ":enddate", mktime(0,0,0,1,1,1990));

oci_execute($stmt);

print "NAME  : HIREDATE\n";
while ( $row = oci_fetch_assoc($stmt) ) {
   print "{$row['ENAME']} : {$row['HIREDATE']}\n";
}
oci_free_statement($stmt);

oci_close($conn);
?>

In reverse, the following function returns a UNIX timestamp given an Oracle DATE type:

CREATE OR REPLACE
    FUNCTION date_to_unixts(oracle_date IN DATE) RETURN PLS_INTEGER IS
        /**
         * Converts an Oracle DATE to a UNIX timestamp
         */
        unix_epoch DATE := TO_DATE('19700101000000','YYYYMMDDHH24MISS');
        max_date DATE := TO_DATE('20380101000000','YYYYMMDDHH24MISS');
        min_date DATE := TO_DATE('19030101000000','YYYYMMDDHH24MISS');
        unix_ts PLS_INTEGER;

        BEGIN

            IF oracle_date > max_date THEN
                RAISE_APPLICATION_ERROR( -20902,'Date too large for 32bit UNIX timestamp' );
            ELSIF oracle_date < min_date THEN
                RAISE_APPLICATION_ERROR( -20902,'Date too small for 32bit UNIX timestamp' );
            ELSE
                unix_ts := (oracle_date - unix_epoch) / (1/86400);
            END IF;

            RETURN (unix_ts);

        END;

The following query shows how it might be used:SELECT
    ename,
    TO_CHAR(hiredate, 'YYYY') AS hired_year,
    TO_CHAR(hiredate, 'YYYYMM') AS hired_month,
    TO_CHAR(hiredate, 'ddth Mon, YYYY') AS hired_pretty
    date_to_unixts(hiredate) AS hired_unixts
FROM
    emp
ORDER BY
    hiredate

It’s now easy to convert the timestamp into a formatted date, using the date() function as you loop through the result set.