20 August 2017

Sites that offer free stock images

Here is a collection sites that offer free stock images you can use for your projects. Please check the current licensing status for each site as it might have changed as of writing this.

The Stocks

http://thestocks.im/ - the best royalty free stock photos in one place


https://www.splitshire.com/about/ - Helping you to be awesome out there with great content.

Pic Jumbo

https://picjumbo.com/ - picjumbo is free stock photo site created by designer & photographer Viktor Hanacek in 2013.


http://gratisography.com/ - Free high-resolution pictures you can use on your personal and commercial projects. New awesome pictures added weekly! All pictures were photographed by Ryan McGuire and free of copyright restrictions.

Startup Stock Photos

http://startupstockphotos.com/ - Free photos for startups, bloggers, publishers, websites, designers, developers, creators, & everyone else.

Negative Space

https://negativespace.co/ - Beautiful, Free High-Resolution Photos with No Restrictions For personal or commercial projects, all of our CC0 licensed images are completely free to use!

Life of Pix

http://www.lifeofpix.com/ - Free, high resolution photography.


https://unsplash.com/ - Beautiful, free photos. Gifted by the world’s most generous community of photographers.

Endless Icons

http://www.endlessicons.com/- Endless Icon is a project bulid by Min Kim who runs Email-Gallery, App Monstr, and Endless Photos. I created it to share some of the icons and creative stuff with the design community. Cheers!

26 July 2017

Get a Windows licence key from a machine after it's been uninstalled

It turns out you can get the Windows licence key from a machine, even after it's been uninstalled, using Linux. Run this in the console

sudo hexdump -s 56 -e '"MSDM key: " /29 "%s\n"' /sys/firmware/acpi/tables/MSDM

If the key is in your machine's firmware, you should see it.

15 July 2017

I've been using the wrong date delimiters in PHP for JavaScript

So I've been making dates in PHP like this

$dt = new DateTime("2017-07-15");
$date = $dt->format("Y-m-d");

and passing that to JS like this

echo "foo = new Date(\"$date\");";
// returns: Sat Jul 15 2017 00:00:00 GMT+0300 (FLE Summer Time)

and that was working fine in Chrome and Firefox. However, if you try and call foo in Safari, you'll get an invalid date error. This is because Safari doesn't currently support the dash delimiter format. More info.

To avoid this in the future, I need to start remembering to format my dates in php with / instead of - when I'm going to be using it in the web-page. So like this

$dt = new DateTime("2017/07/15");
$date = $dt->format("Y/m/d");

The only thing I can see still needing dashes, would be in URLs. If you need to switch to dashes while in JS, you can do something like .replace(/\//g, "-")

I've been neglecting testing in Safari which is pretty bad. Luckily, you can still download an old version of Safari for Windows, so testing is easy enough.

24 June 2017

CodeIgniter 3 Sessions

CI sessions are an alternative to php sessions. It is advised to autoload the sessions so they are always available. CI sessions simplify using native php sessions, ie the $_SESSION superglobal. For example, there is no need to include the session_start() function (to start a new or resume an existing session). Session data is simply an array, associated with a particular session ID (cookie).

As well as read, set and unset values, CI also provides 2 special types of session data, flashdata and tempdata.

To read a session variable use either $_SESSION['item_key_name'] (or the magic getter) $this->session->item_key_name

To retrieve all of the existing userdata, you can simply omit the item key $_SESSION for example print_r($_SESSION) (the magic getter only works for properties).

You can assign (set) data to the $_SESSION array, as with any other variable. Or as a property of $this->session. For example $_SESSION['something'] = 'hello' or $this->session->something = 'hello'

Check if a session variable exists: isset($_SESSION['some_name'])

To remove session variables, use for example, unset($_SESSION['some_name']) or multiple values: unset($_SESSION['some_name'], $_SESSION['another_name'])

Session Flashdata

Flashdata is data that will only be available for the next request, and is then automatically cleared. This can be very useful, especially for one-time informational, error or status messages. To create a session variable as flashdata:

$_SESSION['item'] = 'value';

Or more concisely:

$this->session->set_flashdata('item', 'value');

Read flashdata variables the same way as regular session data $_SESSION['item']

However, if you want to be sure that you’re reading “flashdata” (and not any other kind), you can also use the flashdata() method:


Or to get an array with all flashdata, simply omit the key parameter:


If you find that you need to preserve a flashdata variable through an additional request, you can do so using the keep_flashdata() method.



Tempdata is session data with a specific expiration time. To mark an existing item as tempdata, simply pass its key and expiry time (in seconds!) to the mark_as_temp() method:

$_SESSION['item'] = 'value';
$this->session->mark_as_temp('item', 300); // erased after 300 seconds

Or concisely:

$this->session->set_tempdata('item', 'value', 300);

Read tempdata variables the same way as regular session data $_SESSION['item']

Destroying a Session

To clear the current session both of these will work in exactly the same way session_destroy() or $this->session->sess_destroy()


You can still use the native php session functions with the CI session library and for simplicity, I think this is best practice. You then only need to learn the extra CI session methods (ie. flashdata, tempdata). The added bonus to the CI's session library is that you don't have to add session_start() to every file that uses sessions.

30 May 2017

CodeIgniter's last_query()

I had an issue running codeigniter's $this->db->last_query().

It returns the last query that was run (the query string, not the result). But, remember to run the query, ie call the get() method before the last_query() method.


// note, you have to call get()
$query = $this->db->get();
echo $this->db->last_query();

It's a great function to call when you are having issues converting your SQL statements to the query builder class.

25 April 2017

Running Vagrant on Windows

Recently Packt Publishing kindly gave away Learning PHP 7 in a short 24 hour promotion. I've been going through it and had a problem setting up Vagrant 1.9.3 on Windows. Specifically running vagrant up returned this error

C:/Program Files (x86)/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.9.3/lib/vagrant/util/is_port_open.rb:21:in `initialize': The requested address is not valid in its context. - connect(2) for "" port 8080 (Errno::EADDRNOTAVAIL) 

Here is the reported error and fix Vagrant 1.9.3 up fails.

None of this is the book's falt of course. Technology changes fast and it's tough to keep up to date with it.

Next problem I had was the book assumes you have an ssh client installed on windows, which I didn't, so the command vagrant ssh returned another error. Although this time, the error simply instructed me to install an ssh client and even suggested some. I chose Git, but found there was one more step to do after installing it. You need to add C:\Program Files\Git\bin and C:\Program Files\Git\usr\bin to your Windows environment path. This latter path contains ssh.exe along with a bunch of other tools.

Now you can easily run vagrant up and vagrant ssh from your project folder path.

The chapter index in this book looks fantastic! There are lots of new things I need to learn there, and some other things I should master. Good luck.

24 April 2017

QPython Hello World over SSH

QPython is a script engine that allows you to run python programs on Android. It comes with SL4A (Scripting Layer for Android) built in. SL4A has access to many of the APIs available to full-fledged Android applications, but has a greatly simplified interface that makes it easy to get things done by wrapping it in Python modules. It supports my really old Gingerbread 2.3.5 OS and can be installed directly from the PlayStore. It really is a great piece of standalone software that will get you coding in minutes, but I decided to run this over SSH with SSHDroid. Take your time to properly setup and protect SSHDroid, get things like the IP address, then try this hello world application.

On your local PC, create a file called test.py and add

import androidhelper
droid.makeToast("hello world!")

Copy it to the QPython scripts folder on the SD card (note, your ssh port number and IP Address will be different)

scp -P 2017 test.py root@

To test the script, you can do it via the QPython GUI interface. You can also run it by calling QPython's python interpreter from a logged in SSH session, and pass it your script to execute. It's a bit like calling python test.py

ssh -p 2017 root@
/data/data/org.qpython.qpy/files/bin/qpython.sh /mnt/sdcard/qpython/scripts/test.py

If all looks good, you might want to now call it over SSH. Log out of your SSH session. Wrap your whole command in an alias to issue a quick command from your Linux terminal

alias phone-helloworld = 'ssh -p 2017 root@ "/data/data/org.qpython.qpy/files/bin/qpython.sh /mnt/sdcard/qpython/scripts/test.py"'

26 March 2017

Tweaking the vertical position of an image

Positioning images/icons alongside text or other elements can be tricky. The following CSS will allow you to slide the image along the vertical axis.

.something img {
    transform:translateY(-35%); /* play with this */

23 February 2017

Running CodeIgniter in Heroku

Note: This does not include a database setup.

Grab a copy of the latest codeigniter and navigate to the root folder

cd diylingo/CodeIgniter-3.1.3/

Login to heroku

heroku login

Add git

git init

Identify heroku as the remote repository for git to use

heroku create diylingo

In codeigniter, open config.php and add the heroku address outputted from the create command to

$config['base_url'] = 'https://diylingo.herokuapp.com/';

Because this will be detected as a php app and there is a composer.lock file which demands you satisfy all dependencies, you'll need to run

composer update

Now prepare the files for upload

git add .

git commit -m "initial commit"

Push your code to the remote heroku git repository

git push heroku master

Check the result

open heroku

You should have the CodeIgniter welcome page opened for you in the browser.

16 February 2017

Getting started with pagination in CodeIgniter


Sometimes your database can return a lot of data. Like hundreds (or even thousands) of rows that may need to be outputted to the user. In these kinds of situations, it’s good to use pagination, which codeigniter has an built-in library for.

Pagination is the process of dividing this data into chunks, like pages in a book. On your webpage, this often looks like a series of clickable number links, but can also be formatted to just previous and next links. Behind the scenes though, pagination works with SQL’s LIMIT and OFFSET clauses. These two clauses in essence specify a range of results (database rows) to output.

In CodeIgniter, the pagination library takes care of figuring out how many pagination links are required, and inserts the OFFSET clause value as a method argument to the controller method you are calling it from. Here is an example of just one pagination link

<a href="/language/read/20" data-ci-pagination-page="2">2</a>

How to do it

Here is how I attempted to use pagination.


public function read($pagination_offset = 0)
  $pagination_config['base_url'] = base_url('language/read'); // the controller you are calling
  $pagination_config['per_page'] = 20; // sql query LIMIT number

  $this->data['languages'] = $this->language_model->get_languages($pagination_config['per_page'], $pagination_offset); // your database call with LIMIT and OFFSET arguments
  $total_query_rows = $this->db->query('SELECT id FROM languages')->num_rows(); // what the database would have yielded without the LIMIT and OFFSET clauses (*see Notes)

  $pagination_config['total_rows'] = $total_query_rows;
  $this->pagination->initialize($pagination_config); // prepares the pagination based on your configurations

  $this->data['pagination'] = $this->pagination->create_links(); // outputs the pagination as a string (*see Notes)
  $this->load->view('language', $data);


public function get_languages($limit, $pagination_offset)
  $query = $this->db->query("
    languages.id AS id,
    languages.title AS language,
    COUNT(courses.id) AS number_of_courses
  FROM languages
  LEFT JOIN courses
  ON languages.id = courses.language_id
  GROUP BY languages.title
  LIMIT $limit OFFSET $pagination_offset
  return $query->result();


The three most important things here are

  • $pagination_config['base_url'] the controller method to call.
  • $pagination_config['per_page'] the SQL LIMIT or how many results per page you want to see.
  • $pagination_config['total_query_rows'] all the rows in the results set, so the pagination library can figure out how many links to create.

In $total_query_rows instead of writing the whole query without LIMIT and OFFSET, I wrote a much simpler one because I knew it would return the same number of rows every time.

If there is no pagination to show, create_links() will output an empty string.

In the model, you can of course use the query class library to pass LIMIT and OFFSET clauses.

Changing the view output

Above is the minimum you need to get pagination working, but it’s likely you will want to style or customise your output. To do this you can edit the default preferences which are passed to the initialize() function. I prefer to do this by creating a pagination.php file in the config folder. Here is an example using the W3.CSS front-end CSS framework


defined('BASEPATH') OR exit('No direct script access allowed');

$config['full_tag_open'] = '<ul class="w3-pagination w3-border w3-light-grey">';
$config['full_tag_close'] = '</ul>';

$config['first_link'] = 'First'; // might require more than 5 pages by default to show up
$config['first_tag_open'] = '<li>';
$config['first_tag_close'] = '</li>';
// $config['first_url'] = ''; // An alternative URL to use for the “first page” link.

$config['last_link'] = 'Last';
$config['last_tag_open'] = '<li>';
$config['last_tag_close'] = '</li>';

$config['next_link'] = '&raquo;';
$config['next_tag_open'] = '<li>';
$config['next_tag_close'] = '</li>';

$config['prev_link'] = '&laquo;';
$config['prev_tag_open'] = '<li>';
$config['prev_tag_close'] = '</li>';

$config['cur_tag_open'] = '<li><b><a class="w3-green">';
$config['cur_tag_close'] = '</a></b></li>';

$config['num_tag_open'] = '<li>';
$config['num_tag_close'] = '</li>';


<?php if (!empty($pagination)): ?>
  <div class="w3-container">
    <div class="w3-card-2 w3-padding w3-light-grey">
      <?php echo $pagination; ?>
<?php endif; ?>