Saturday, 15 October 2016

Creating a VirtualHost in Apache 2.4

What is a VirualHost?

In apache a VirtualHost is a way to host multiple websites on a single apache instance. If you're a developer that works on more than one website this is the best way to test all those websites on one machine.
Creating a VirtualHost
Creating a VirtualHost is simple, we can achieve this in four easy steps. In the following example we will be creating a VirtualHost named "website.demo":

  1. Create the VirtualHost file
    sudo nano /etc/apache2/sites-available/website.demo.conf
    <VirtualHost *:80>
      DocumentRoot /home/username/Software/website
      ServerName website.demo
    </virtualhost>
  2. Create the hosts file entry
    $ sudo nano /etc/hosts
    127.0.0.1    website.demo
  3. Enable the new VirtualHost
    $ a2ensite website.demo
  4. Restart Apache
    $ sudo service apache2 restart
Now you can go to http://website.demo and you website (which is located at /home/username/Software/website) will be there.

The VirtualHost file

The VirtualHost file (/etc/apache2/sites-available/website.demo.conf) is loaded by apache on startup and serves website.demo on port 80 which means you can visit it via your web browser.
The DocumentRoot entry tells apache where the files for this VirtualHost are located. The ServerName entry tells apache what name to serve the website as.

a2ensite and a2dissite

a2ensite enables a VirtualHost inside your sites-available folder by creating a symbolic link to it from the sites-enabled folder (which apache loads during startup). a2dissite disables a VirtualHost by removing the symbolic link created by a2ensite.

And that's it, you should now be able to create your own VirtualHosts easily.

PHP Factory pattern

What is a Factory?

A factory is in essence a function that returns an instance of an object of the desired type when the class type that you want is unknown. For instance, let's say you have a Staff class with Teacher and Janitor sub-classes. When you fetch the list of all user's from the database and you want to loop through them and create the correct object type for each user without having to write an if-block each time you want to do this. This is where a Factory comes in.

A simple Factory

Again, assuming we have a Staff class with Teacher and Janitor sub-classes:

class Staff {
  public $staffType = 'Staff';
}

class Teacher extends Staff {
  public $staffType = 'Teacher';
}

class Janitor extends Staff {
  public $staffType = 'Janitor';
}
We now want to create a new staff-member object without writing an if block each time, let's build a Factory.
class StaffFactory {

  public static function buildStaffMemberObject (string $type) {
    if ($type === 'teacher') {
      return new Teacher();
    } elseif ($type === 'janitor') {
      return new Janitor();
    } else {
      return new Staff();
    }
  }

}
When we want to create an instance of a new staff-member object we can use:
$teacher = StaffFactory::buildStaffMemberObject('teacher');
$janitor = StaffFactory::buildStaffMemberObject('janitor');
That's it, you have a working Factory that builds objects of the correct type for you.

A more complex Factory

The above example works, but it's lacking in flexibility. Every time you want to add a new type you are going to have to add another condition inside the if/else if block. What if we had a Factory that could dynamically figure out which class type to load, let's take a look:
class StaffFactory {

  public static function buildStaffMemberObject (string $type) {
    $className = ucfirst($type);
    $className = class_exists($className) ? $className : 'Staff';
    return new $className();
  }

}
This time we are checking whether a class by the given name exists in the current namespace, otherwise we default back to 'Staff'. This way when you create a new staff member type, for example, "Management", all you have to do is create and include the class in you script and you can immediately create it via your Factory.

Monday, 10 October 2016

Creating an executable bash script

What is a bash script?

A bash script is an executable script that can be run from the command-line. It can then, in turn perform any other command-line commands. This way you can group commands and add logic around their order of execution, or pass variables to them and act upon those or pass them along to other scripts.

Creating a bash script:

To create a bash script you need to create a file with the extension ".sh".
$ nano script.sh
Now we need to add some functionality to our script, let's keep it simple at first:
clear
pwd
Our command is not quite ready to be run yet, now we need to give the file 'execute' permission, we can do this by running the command:
$ chmod +x script.sh
When we run this command the screen will be cleared and the current working directory will be printed on the screen.
$ ./script.sh
That's it, your bash script is created and you are now able to use it.

Accessing variables

In your script you can access variables passed to it and make decisions based on those variables or pass them along to other scripts. Variables are passed as number in the order that they appear in the given command. Let's build a script that check's out a certain branch in git.
branch=$1
git checkout $branch
Let's execute our command and see that the branch is checked-out:
$ ./script.sh master
Master will now be the checked out branch if we are in a git repository.

Making it more accessible

Creating scripts can be really cool and can help you in automating processes easily, but typing out ./script.sh option option ... can become quite tedious, so let's take a lesson from the bash aliases tutorial and add an alias for our script.
alias sc='~/script.sh'
And now you can execute your script easily by running:
$ sc master

Thursday, 6 October 2016

Bash aliases

What is an alias?

An alias is a bash command that runs one, or many other commands. An alias can also be created as a function and passed parameters.

How to add a new alias:

To create a new alias we want to add it in the correct bash startup file. In some instances (like the Ubuntu 16.04 LTS I am currently running) the default ~/.bashrc file already points us in the right place, it includes a ~/.bash_aliases file if one is present. This is a convenient way to seperate our aliases from the already full ~/.bashrc.

The alias:

Open the ~/.bash_aliases file with your editor of choice
--in terminal
$ nano ~/.bash_aliases

Create a new alias:
--in file ~/.bash_aliases
alias sftw='cd Software';

Close and re-open your terminal window or load the aliases with:
--in terminal
$ . ~/.bash_aliases

Now run the alias from the command line to see it in action:
--in terminal
$ sftw

You can also chain commands as you can in a normal terminal command by adding two ampersands (&&) in-between them:
--in file ~/.bash_aliases
alias startWeb1='cd Software/website1 && npm start'

If ~/.bash_aliases doesn't load

If your ~/.bashrc file does not contain a reference to the ~/.bash_aliases file you can add the reference like so:
--in terminal
$ nano ~/.bashrc

And add the following lines to the end:
--in file ~/.bashrc
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

Creating more complex aliases with functions

A function can take arguments and make multiple calls, for example:
--in file ~/.bash_aliases
gtst () {
        clear
        git branch 
        git status 
}
gtbr () {
        from=${2:-master}
        if ! `git checkout $1 &> /dev/null`; then
                `git checkout ${FROM}`
                `git checkout -b $1`
        fi
}
In the second function above we set a default value of "master" for variable 2 if no value exists. No alias entry is necessary, the function will be available.

Getting even fancier:

Let's wrap all these into a neat command called 'gt':
gt () {
        local argument2=$2
        local argument3=$3
        st () {
                clear
                git branch
                git status
        }
        br () {
                from=${argument3:-master}
                checkout=`git checkout ${argument2} 2>&1`
                if [ $? -eq 0 ]; then
                        echo "${checkout}"
                else
                        echo "`git checkout ${from}`"
                        `git checkout -b ${argument2}`
                fi
        }

        case "$1" in
                br) br;;
                st) st;;
        esac
}
Now we can call our new gt command from the command line as follows:
$ gt st
$ gt br existing-branch
$ gt br new-branch
$ gt br new-branch from-branch