Codeigniter by Beni - HTML preview

PLEASE NOTE: This is an HTML preview only and some elements such as links or page numbers may be incorrect.
Download the book in PDF, ePub, Kindle for a complete version.

<?php echo form_close() ; ?>

199

Calendaring, Right Place, and Right Time

How it works…

For the most part the functionality is broadly similar to the previous recipe, but there are some differences; we've added support to manage appointments. So, let's begin with looking at public function view(). You'll notice that we have moved some code around; the code which either grabs the dates from the uri or makes the date on the fly is now before the $prefs array — this is because of the $tpl variable. What's $tpl then?

The content of the $tpl variable string, more specifically it is a calendar template used by the Calendar library; the template supports a tag for days—{day}—but not for the month or year. This means that we have to insert these values manually into the template. But to do that, we need to know the year and month values beforehand; that's why the code to calculate the month and day is now moved up before the $prefs array. The template code that I use is a modified version of what is available from the CodeIgniter website user guide: http://

ellislab.com/codeigniter/user-guide/libraries/calendar.html.

From here onwards it's the same functionality as the view() function in the previous recipe: we load the Calendar library, fetch all appointments for the current month, and pass it to the app_cal/view.php view file. Let's go through some of the newer functions in more detail: The public function create()

When the user enters the new appointment's details and posts the create form, the public function create() first declares the validation rules for the new appointment. We'll then need to grab the year, month, and day for the specific appointment from either the post or get arrays. The public create()function checks for this and stores the date values in variables:

if ($this->uri->segment(3)) {

$year = $this->uri->segment(3);

$month = $this->uri->segment(4);

$day = $this->uri->segment(5);

} elseif ($this->input->post()) {

$year = $this->input->post('year');

$month = $this->input->post('month');

$day = $this->input->post('day');

} else {

$year = date("Y", time());

$month = date("m", time());

$day = date("j", time());

}

There are three tests here as the public function create() can be accessed in different ways. The first test looks for whether the page is accessed by someone by clicking on an add appointment link + in the calendar grid, the second test looks for the variables if the page has been posted, and the third (an else) is for when the New Appointment link is clicked.

200

Chapter 8

Next, we check if the page validation is passed or not; FALSE can mean a failure of validation or that create() is being accessed for the first time.

We set some form values for CodeIgniter to render in the view and begin to build the variables necessary for the date dropdowns:

$days_in_this_month = days_in_month($month,$year);

$days_i = array();

for ($i=1;$i<=$days_in_this_month;$i++) {

($i<10 ? $days_i['0'.$i] = '0'.$i : $days_i[$i] = $i) ;

}

We then show the view file and wait for the user to submit. Upon successful submission (that is, when the form passes validation), we calculate the Unix timestamp for the appointment date variable (day, month, and year) and package everything into the $data array, ready for insertion into the database. A successful insertion will redirect the user to the month and year in which their appointment sits.

The public function delete()

This is quite simple; we check for the existence of an appointment ID in either the get or post arrays:

if ($this->input->post('app_id')) {

$id = $this->input->post('app_id');

} else {

$id = $this->uri->segment(3);

}

We look in both get and post because the function can be accessed for the first time by someone clicking on a URL, and the second time by someone posting (when they click on the confirm delete button in the view).

If the form is being submitted with errors, or run for the first time, the appointment details are fetched from the database (having been passed $id from the preceding code).

$appointment = $this->App_cal_model->get_single($id);

foreach ($appointment->result() as $row) {

$data['app_name'] = $row->app_name;

$data['app_date'] = $row->app_date;

}

$this->load->view('app_cal/delete', $data);

201

Calendaring, Right Place, and Right Time

We then fetch app_name and app_date from the database result and store them as items in the $data array for passing to the app_cal/delete.php view file. Upon a successful submit (if nothing failed the validation) the model function delete() is called, and if a delete occurred the user is redirected to the same month and year where their deleted appointment previously sat.

Creating a helper to work with a person's

date of birth

From time to time, you'll need an age verification script, a method to ascertain whether or not a user is of a certain age. Based on their age, they may be allowed, or disallowed, from viewing content, for example, a website that promotes adult products, such as alcohol or tobacco or a games site that promotes a game rated for certain ages. The code in this recipe helps you to ascertain a user's age, compares that against a minimum age requirement, and displays an HTML file accordingly.

How to do it…

We're going to create five files:

f

/path/to/codeigniter/application/controllers/register.php: This is the controller for our recipe

f

/path/to/codeigniter/application/helpers/dob_val_helper.php:

This file calculates the user's age, compares it to the required age, and returns true or false depending on the result

f

/path/to/codeigniter/application/views/register/signup.php:

This file displays the age verification form

f

/path/to/codeigniter/application/views/register/enter.php: This is displayed if the user can enter

f

/path/to/codeigniter/application/views/register/noenter.php:

This is displayed if the user cannot enter

1. Create the controller file, register.php, and add the following code to it:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Register extends CI_Controller {

function __construct() {

parent::__construct();

$this->load->helper('form');

$this->load->helper('dob_val');

}

202

Chapter 8

public function index() {

$this->load->library('form_validation');

$this->form_validation->set_error_delimiters('', '<br />'); $this->form_validation->set_rules('year', 'Year',

'required|min_length[4]|max_length[4]|trim');

$this->form_validation->set_rules('month', 'Month',

'required|min_length[2]|max_length[2]|trim');

$this->form_validation->set_rules('day', 'Day', 'required|min_

length[2]|max_length[2]|trim');

if ($this->form_validation->run() == FALSE) {

$this->load->view('register/signup');

} else {

$dob = array(

'year' => $this->input->post('year'),

'month' => $this->input->post('month'),

'day' => $this->input->post('day')

);

$at_least = 18;

if (are_they_old_enough($dob, $at_least = 18)) {

$this->load->view('register/enter');

} else {

$this->load->view('register/noenter');

}

}

}

}

2. Create the helper file, dob_val_helper.php, and add the following code to it:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

function are_they_old_enough($dob, $at_least = 18) {

$birthday = strtotime($dob['year'].'-'.$dob['month'].'-

'.$dob['day']);

$diff = floor((time() - $birthday) / (60 * 60 * 24 * 365));

if ($diff >= $at_least) {

return true;

} else {

return false;

}

}

203

Calendaring, Right Place, and Right Time

3. Create the view file, signup.php, and add the following code to it:

<?php echo form_open() ; ?>

<?php echo validation_errors() ; ?>

Day <input type="text" name="day" size="5" value="<?php echo set_value('day') ; ?>"/>

Month <input type="text" name="month" size="5" value="<?php echo set_value('month') ; ?>"/>

Year <input type="text" name="year" size="5" value="<?php echo set_value('year') ; ?>"/>

<input type="submit" value="go" />

<?php echo form_close() ; ?>

4. Create the view file enter.php and add the following code to it:

<p>You are old enough to view page</p>

5. Create the view file noenter.php and add the following code to it:

<p>You are NOT old enough to view page</p>

How it works…

First off, we come to the controller; the controller loads the URL helper (as we're using the redirect() function and a helper we will create called dob_val):

function __construct() {

parent::__construct();

$this->load->helper('form');

$this->load->helper('dob_val');

}

We then set up form validation and set the rules for our day, month, and year fields from the HTML. The register/signup.php view file is loaded, ready for the user to enter their date of birth in the three form fields.

The user will press submit, and if the submission passes for validation, the three form values are put into the $dob array:

$dob = array(

'year' => $this->input->post('year'),

'month' => $this->input->post('month'),

204

Chapter 8

'day' => $this->input->post('day')

);

We set our minimum age (the age the user must be in order to view age restricted content) like this:

$at_least = 18;

Then, we pass the $dob array along with the $at_least variable to the dob_val helper: if (are_they_old_enough($dob, $at_least = 18)) {

$this->load->view('register/enter');

} else {

$this->load->view('register/noenter');

}

The helper calculates if the user is above or below the $at_least age, returning TRUE if they are above and FALSE if they are not. If they are, they see the register/enter view file, and if they aren't they see the register/noenter view file.

Working with fuzzy dates in CodeIgniter

What is a fuzzy date? A fuzzy date is a more familiar and general way to describe a data or time rather than an exact, precise time; it describes an event in a way that is more familiar to a reader than a precise timestamp. For example, rather than saying that an email was sent at 17:41, you could say it was sent "less than a minute ago" (assuming you sent it within the last minute) or even "a few moments ago". The precise time at which something occurred is considered unimportant—or at least unnecessary—information and it is instead replaced with a more general, informal, and conversational description of the date and time.

How to do it…

We're going to create two files:

f

/path/to/codeigniter/application/controllers/fuzzy_date.php:

This controller will call the fuzzy_date_helper.php file and pass to it some dates (as a Unix timestamp) for the helper to convert.

f

/path/to/codeigniter/application/helpers/fuzzy_date_helper.php:

This helper will be called by the controller and will convert the dates passed to it, returning a written description every time.

1. Create the controller file, fuzzy_date.php, and add the following code to it:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Fuzzy_date extends CI_Controller {

205

Calendaring, Right Place, and Right Time

function __construct() {

parent::__construct();

$this->load->helper('url');

$this->load->helper('fuzzy_date_helper');););

}

public function index() {

echo describe_the_time(time() + 30);

}

}

?>

2. Create the helper file, fuzzy_date_helper.php, and add the following code to it:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

function describe_the_time($time_in) {

define('SECOND', 1);

define('MINUTE', 60 * SECOND);

define('HOUR', 60 * MINUTE);

define('DAY', 24 * HOUR);

define('MONTH', 30 * DAY);

define('YEAR', 12 * MONTH);

$past_descriptions = array(

1 => 'about a minute ago',

2 => 'a few minutes ago',

3 => 'within the last hour',

4 => 'earlier today',

5 => 'yesterday',

6 => 'earlier this week',

7 => 'earlier this month',

8 => 'last month',

9 => 'earlier this year',

10 => 'last year',

11 => 'a long time ago',

12 => 'I don\'t know that time'

);

$future_descriptions = array(

1 => 'a minute from now',

2 => 'in the next few minutes',

3 => 'in the next hour',

206

Chapter 8

4 => 'later today',

5 => 'tomorrow',

6 => 'later this week',

7 => 'later this month',

8 => 'next month',

9 => 'later this year',

10 => 'next year',

11 => 'a long way off',

12 => 'I don\'t know that time'

);

$now = time();

if ($time_in < $now) {

if ($time_in > $now - MINUTE) { // About a minute ago

return $past_descriptions[1];

} elseif ( ($time_in >= $now - (MINUTE * 5) ) && ($time_in <=

$now ) ) { // A few minutes ago

return $past_descriptions[2];

} elseif ( ($time_in >= $now - (MINUTE * 60)) && ($time_in <=

$now ) ) { // Within the last hour

return $past_descriptions[3];

} elseif ( ($time_in >= $now - (HOUR * 24)) && ($time_in <=

$now - (MINUTE * 60) ) ) { // Earlier today

return $past_descriptions[4];

} elseif ( ($time_in >= $now - (HOUR * 48)) && ($time_in <=

$now - (HOUR * 24) ) ) { // Yesterday

return $past_descriptions[5];

} elseif ( ($time_in >= $now - (DAY * 7)) && ($time_in <= $now

- (HOUR * 48) ) ) { // Earlier this week

return $past_descriptions[6];

} elseif ( ($time_in >= $now - (DAY * 31)) && ($time_in <=

$now - (DAY * 7) ) ) { // Earlier this month

return $past_descriptions[7];

} elseif ( ($time_in >= $now - (DAY * 62)) && ($time_in <=

$now - (DAY * 31) ) ) { // Last Month

return $past_descriptions[8];

} elseif ( ($time_in >= $now - (MONTH * 12)) && ($time_in <=

$now - (MONTH * 31) ) ) { // Earlier this year

return $past_descriptions[9];

} elseif ( ($time_in >= $now - (MONTH * 24)) && ($time_in <=

$now - (MONTH * 12) ) ) { // Last year

return $past_descriptions[10];

} elseif ( ($time_in >= $now - (MONTH * 24) && ($time_in <=

$now - (MONTH * 12) ) ) ){ // Last year

207

Calendaring, Right Place, and Right Time

return $past_descriptions[11];

} else {

return $past_descriptions[12];

}

} else {

if ($time_in < $now + MINUTE) { // A minute from now

return $future_descriptions[1];

} elseif ( ($time_in <= $now + (MINUTE * 5) ) && ($time_in >=

$now ) ) { // In the next few minutes

return $future_descriptions[2];

} elseif ( ($time_in <= $now + (MINUTE * 59)) && ($time_in >=

$now ) ) { // In the next hour

return $future_descriptions[3];

} elseif ( ($time_in <= $now + (HOUR * 24)) && ($time_in >=

$now + (MINUTE * 59) ) ) { // Later today

return $future_descriptions[4];

} elseif ( ($time_in <= $now + (HOUR * 48)) && ($time_in >=

$now + (HOUR * 24) ) ) { // Yesterday

return $future_descriptions[5];

} elseif ( ($time_in <= $now + (DAY * 7)) && ($time_in >= $now

+ (HOUR * 48) ) ) { // Earlier this week

return $future_descriptions[6];

} elseif ( ($time_in <= $now + (DAY * 31)) && ($time_in >=

$now + (DAY * 7) ) ) { // Earlier this month

return $future_descriptions[7];

} elseif ( ($time_in <= $now + (DAY * 62)) && ($time_in >=

$now + (DAY * 31) ) ) { // Last Month

return $future_descriptions[8];

} elseif ( ($time_in <= $now + (MONTH * 12)) && ($time_in >=

$now + (MONTH * 31) ) ) { // Earlier this year

return $future_descriptions[9];

} elseif ( ($time_in <= $now + (MONTH * 24)) && ($time_in >=

$now + (MONTH * 12) ) ) { // Last year

return $future_descriptions[10];

} elseif ( ($time_in <= $now + (MONTH * 24) ) ) { // Last year

return $future_descriptions[11];

} else {

return $future_descriptions[12];

}

}

}

?>

208

Chapter 8

How it works…

Let's take a look at the fuzzy_date controller, the controller loads in the constructor, which in turn loads our fuzzy_date_helper, this is the helper which will translate Unix timestamps into descriptive text for us:

function __construct() {

parent::__construct();

$this->load->helper('url');

$this->load->helper('fuzzydate_helper');

}

We then load the public function index(), which calls fuzzydate_helper, passing to it a timestamp (at the moment, the input passed is set to be time() + 30).

Why time() + 30? Well, time() is the php function that returns the Unix timestamp for "now" (whenever "now" is for you), and the + 30 is 30 seconds added to the current timestamp value returned by time(), meaning "now plus 30 seconds" (or "30 seconds in the future"). I've set it to that for the initial demonstration, but I will describe how this can be altered later in the description.

In the controller we pass 'now plus 30 seconds' to the helper:

echo describe_the_time(time() + 30);

The incoming function augment (that is, what we defined in the controller) is declared locally for the helper as $time_in:

function describe_the_time($time_in) {

The helper takes the $time_in variable, looks at its value, and works out if the timestamp value is greater than, or less than, $now as defined in the helper as $now = time(): if ($time_in < $now) {

... // $time_in is in the past

} else {

... // $time_in is in the future

}

As 'now plus 30 seconds' is greater than now (30 seconds more, to be precise) the helper goes to the else part of the if structure and then begins a series of comparisons, trying to find a place where the value defined in $time_in will fit. As 'now plus 30 seconds' is less than 'now plus 60 seconds' (30 seconds less, in fact), the first if statement is applied and the helper returns the first item in the $future_descriptions array: if ($time_in < $now + MINUTE) { // A minute from now

return $future_descriptions[1];

}

209

Calendaring, Right Place, and Right Time

That would be a minute from now?

You can, of course, alter the timestamp passed to the helper in the controller; you could set it to time() + 250 (which would be now plus 250 seconds). Now, plus 250 seconds is greater than a minute (60 seconds) but less than 5 minutes (300 seconds), causing the second if statement to apply and return the text 'in the next few minutes'.

We can also pass a lower timestamp value than "now": time() – 4000 (that is "now minus 4000 seconds"). Passing a lower timestamp will cause the behavior of the helper to change.

How? Well, remember that initial if statement?

if ($time_in < $now) {

...

} else {

...

}

This time, we won't go down to the else part of it; instead, the initial if part will be triggered and the helper will begin to process times in the past. So, by setting the helper input to time() - 4000 (now minus 4000 seconds, which is more than a minute ago, more than 5 minutes ago, and more than an hour ago but less than a full day ago), the helper will return the text "earlier today".

You can, of course, add many, many more detailed comparisons and descriptions; in fact, I encourage you to do so—go nuts!

In a real situation, you would amend the helper function call in the controller, removing the input of time() + or – number_of_seconds to just the timestamp of the thing you want to describe – be it a blog post created date, file upload date, appointment date…whatever…you get the idea I'm sure.

210

9

Extending the Core

In this chapter, you will learn:

f

Using CodeIgniter Sparks

f

Creating PDFs with the DOMPDF Spark

f

Creating Hooks in CodeIgniter

f

Clearing dead sessions from the database

f

Extending your controllers

f

Uploading a file with FTP

f

Making your own configuration files and using the settings

f

Creating libraries and giving them access to CodeIgniter resources f

Using the language class – switching languages on the go

Introduction

CodeIgniter does pretty much most of what you need it to do right out of the box; but there are going to be times when you have to extend or alter the standard setup—whether it's creating Hooks so you don't have to hack the core (you really don't want to hack the core), or installing Sparks to add extra functionality and scope for new features—there are many ways to extend and build on CodeIgniter to get more out of it.

Extending the Core

Using CodeIgniter Sparks

Not too long ago, if you wanted to install an extension or some external software for CodeIgniter, you had to hunt it down. You'd need to search for what you were looking for on the Internet and if you were lucky, you would find a blog or someone's personal site, perhaps even a GitHub account or Google code repository where you could download and install a package.

Sometimes it worked, sometimes it didn't and whatever you downloaded it almost always needed some level of editing or re-writing.

Fast forward to, now! Thankfully, we have Sparks. Think of Sparks as extensions you can use with CodeIgniter. They're kept in one place (so you don't have to hunt them down across the Internet) at http://www.getsparks.org.

We touched on Sparks in Chapter 1, CodeIgniter Basics, however, let's go into more detail and get you to install and use a couple of Sparks which I have found useful over time.

So, if you haven't installed it until now, install Sparks in your CodeIgniter instance. Either go to Chapter 1, CodeIgniter Basics, for instructions on how to do this, or follow the instructions on the GetSparks website.

Getting ready

First, you need to navigate to the top level (or root) of your CodeIgniter directory.

How to do it...

If you are using MAC or Linux, download CodeIgniter Sparks as follows: 1. On the command line, navigate to the root of your CodeIgniter application, and type: php -r "$(curl -fsSL http://getsparks.org/go-sparks)"

This will download and install CodeIgniter Sparks to your specific CodeIgniter instance.

If you are using Windows, then you will need to download Sparks and unpack manually.

To do follow these instructions or check out the instructions on the GetSparks website for the latest version:

1. Create a folder named tools in the top level (root) of your CodeIgniter directory.

2. Go to the following URL: http://getsparks.org/install.

3. Go to the Normal Installation section and download the Sparks package.

4. Unpack the download into the tools folder you created in step 1.

5. Download the Loader class extension from: http://getsparks.org/static/

install/MY_Loader.php.txt.