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.

'https://', 'http://',

$CI->config->config['base_url']);

if ($_SERVER['SERVER_PORT'] != 80) {

redirect($CI->uri->uri_string());

}

}

}

180

Chapter 7

Port 443 is the default HTTPS port; however, this might not always be the case, and the SSL port may be configured differently on your environment and it may be another number on the system you're developing on or developing for. Remember to use the correct port in your environment.

How it works...

Whichever controller we load (with_https or without_https), one of the first things done in the constructor is to load the helper, ssl_helper, with the following line: $this->load->helper('ssl_helper')

You can see this line highlighted in each controller. We then need to call the helper function, toggle_ssl(string), passing a string of either on or off to it. Obviously, on will enforce SSL and off will remove it. When the ssl_helper is called, it immediately calls (by reference: using & to copy by reference) the main CodeIgniter super object. We can see it being called by reference by inclusion of the ampersand character before the PHP function, get_instance(). The object is then stored for us to use in the helper as the variable, $CI, as follows:

$CI =& get_instance()

Depending on the value passed to it, the helper will do one of the following three things: f

If the value is on, then we wish to turn on SSL support. Using the PHP function, str_replace, we swap the http:// part of the base_url value to https://, saving that on the fly as CodeIgniter's new base_url value as follows: $CI->config->config['base_url'] = str_replace('https://',

'http://', $CI->config->config['base_url']);

f

If the value is off, we do exactly the same but in reverse. We swap the https://

part of the current base_url value to http:// as follows:

$CI->config->config['base_url'] = str_replace('https://',

'http://', $CI->config->config['base_url']);

After both preceding str_replace, we test the current value of the $_

SERVER array element, SERVER_PORT;, redirecting accordingly.

f

If the value passed to toggle_ssl isn't either on or off, then the default action will set SSL support to off.

181

Creating a Secure User Environment

There's more...

Some of you may not be familiar with setting up SSL on your machine. Setting SSL up is out of the scope of this book; however, it's quite simple to do. There's a great link from the Apache Foundation in the following section that details how to set up an SSL certificate.

Setting up HTTPS on localhost

It is possible to set up HTTPS on localhost (assuming that's what you're developing on).

I've found an URL that's particularly helpful in getting a self-certified SSL certificate on localhost.

A self-certified SSL certificate is just an SSL certificate which you've made yourself. It's going to be just as good as one you purchase; however, if you push it to a live production environment and an actual user visits. Their browser will tell them the issuing authority is unknown (because you made it yourself), the user will probably think that this means that the site is dangerous and leave. Therefore, for a live site, you'll need a certificate from a recognized issuing authority while for testing, you can make one yourself. The following links will help you make one:

http://httpd.apache.org/docs/2.2/ssl/ssl_faq.html

https://www.verisign.com

https://www.globalsign.co.uk/

Alternatively, if you have managed hosting a lot, your package or product from the host providing company will come with an SSL certificate, or it is likely that the host provider will be able to set one up for you (check the terms of the contract).

182

8

Calendaring, Right

Place, and Right Time

In this chapter, we will cover:

f

Building a CodeIgniter Calendar helper with database results

f

Building an appointment manager with Calendar Library

f

Creating a helper to work with a person's date of birth

f

Working with fuzzy dates in CodeIgniter

Introduction

CodeIgniter comes bundled with many functions and helpers to help support your application when working with time and dates, calendars, and so on. We're going to use a few of them in this chapter, but we will also create a few helpers of our own, which can be useful in everyday tasks, such as calculating a person's age (useful for an age verification script) and working with fuzzy dates (that is, writing a description of the date or time rather than just writing out an accurate date).

Building a CodeIgniter Calendar helper with

database results

CodeIgniter comes with a really useful calendar helper that allows you to display months in a grid. It is possible to develop functionality to pull events from a database (such as a table that stores diary appointments) and indicate to the user if there is an appointment on a given day.

Calendaring, Right Place, and Right Time

Getting ready

As we're storing appointments in a database, we'll need a database table. Copy the following code into your database:

CREATE TABLE àppointments` (

àpp_idìnt(11) NOT NULL AUTO_INCREMENT,

àpp_datè varchar(11) NOT NULL,

àpp_url` varchar(255) NOT NULL,

àpp_namè varchar(255) NOT NULL,

PRIMARY KEY (àpp_id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

INSERT INTO àppointments` (àpp_id`, àpp_datè, àpp_url`, àpp_

namè) VALUES

(1, '1375465528', 'http://localhost/1', 'My Appointment'),

(2, '1375638327', 'http://localhost/2', 'My Second Appointment'),

(3, '1375897527', 'http://localhost/3', 'My Third Appointment'),

(4, '1381167927', 'http://localhost/4', 'My Forth Name');

How to do it…

We're going to create two files:

f

/path/to/codeigniter/application/controllers/app_cal.php

f

/path/to/codeigniter/application/models/app_cal_model.php

f

/path/to/codeigniter/application/views/app_cal/view.php

In order to create those two files we execute the following steps: 1. Create the file /path/to/codeigniter/application/controllers/app_

cal.php and add the following code to it:

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

class App_cal extends CI_Controller {

function __construct() {

parent::__construct();

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

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

}

public function index() {

redirect('app_cal/show');

184

Chapter 8

}

public function show() {

$prefs = array (

'start_day' => 'monday',

'month_type' => 'long',

'day_type' => 'short',

'show_next_prev' => TRUE,

'next_prev_url' => 'http://www.your_domain.com/app_

cal/show/'

);

$this->load->library('calendar', $prefs);

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

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

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

} else {

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

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

}

$this->load->model('App_cal_model');

$appointments = $this->App_cal_model->get_

appointments($year, $month);

$data = array();

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

$data[(int)date("d",$row->app_date)] = $row->app_url;

}

$data['cal_data'] = $this->calendar->generate($year,

$month, $data);

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

}

}

2. Create the file /path/to/codeigniter/application/models/app_cal_

model.php and add the following code to it:

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

class App_cal_model extends CI_Model {

function __construct() {

parent::__construct();

}

function get_appointments($year, $month) {

185

Calendaring, Right Place, and Right Time

$month_as_written = array(

'01' => 'January',

'02' => 'February',

'03' => 'March',

'04' => 'April',

'05' => 'May',

'06' => 'June',

'07' => 'July',

'08' => 'August',

'09' => 'September',

'10' => 'October',

'11' => 'November',

'12' => 'December'

);

$start_date = '01' . ' ' . $month_as_written[$month] . ' '

. $year;

$start_of_month = strtotime($start_date);

$end_date = days_in_month($month, $year) . ' ' . $month_

as_written[$month] . ' ' . $year;

$end_of_month = strtotime($end_date);

$this->db->where('app_date > ', $start_of_month);

$this->db->where('app_date < ', $end_of_month);

$query = $this->db->get('appointments');

return $query;

}

}

3. Create the file /path/to/codeigniter/application/views/app_cal/view.

php and add the following code to it:

<?php echo $cal_data ; ?>

How it works…

We start off by loading the controller app_cal (that stands for Appointment Calendar, in case you were wondering) in our web browser. Note that we load the helpers 'url' and 'date' in the constructor:

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

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

186

Chapter 8

The first function loaded is index(), which redirects us to the show() function, where we immediately begin to define some preferences for the calendar functionality: $prefs = array (

'start_day' => 'monday',

'month_type' => 'long',

'day_type' => 'short',

'show_next_prev' => TRUE,

'next_prev_url' => 'http://www.your_domain.com/app_cal/

show/'

);

Each item is fairly self-explanatory but I'll go into them anyway: Preference

Description

start_day

Specifies which day of the week is leftmost in the calendar grid, so if you entered 'sunday', the day row (the row which describes the days) in the calendar grid will start at Sunday. If for some peculiar reason you wanted your calendar to start on a Wednesday, you would enter

'wednesday' and the calendar week would start with Wednesday.

But don't really do that; it would look odd!

month_type

Specifies how the month is written. 'long' is the full month name, such as August, and 'short' is a shortened version, such as Aug.

day_type

Specifies how the days of the week are written in the days row of the calendar grid. 'long' is Monday, Tuesday, Wednesday, and so on, and

'short' is Mon, Tue, Wed, and so on.

show_next_prev

Could be either TRUE or FALSE. This lets CodeIgniter know if it

should display the next and previous chevrons ( << and >>); clicking these will advance the calendar forward or backward one month at

a time. If this is set to TRUE (which it is in this recipe) you'll need to specify next_prev_url.

next_prev_url

Specifies the URL CodeIgniter should use for the << or >> links.

Next, we load the calendar library and pass the $prefs array to it as a second parameter.

Then, we test for the existence of a fourth uri segment:

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

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

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

} else {

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

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

}

187

Calendaring, Right Place, and Right Time

The third and fourth uri segments are years (YYYY) and months (MM) respectively, and if they don't exist, it is probably the first time the calendar is being loaded (or the calendar isn't being accessed via 'next_prev_url'). Either way, because we don't have a third or fourth uri segment to pass to our model, we'll have to make them up. But what should we use? How about the current month and current year (see the preceding highlighted code)?

Now, we load the model App_model and pass to it our $year and $month variables: $this->load->model('App_cal_model');

$appointments = $this->App_cal_model->get_appointments($year, $month); Let's take a look at the model now and see what's happening. We store our appointments in the database using timestamps, and because the years and months are being passed to the app_cal controller as the strings 'YYYY' and 'MM' we'll need to convert the 'YYYY', 'MM' strings to timestamps, so we can query the database and work out whether we have an appointment for a particular day in the selected month. This means we'll need to use the PHP

function strtotime.

Those of you who are familiar with the function (or even those who just read the function name) will understand that strtotime converts a string of written English to a Unix timestamp, so writing "last Wednesday", for example, will make strtotime return whatever the timestamp was for last Wednesday. It's a great way to get a timestamp, but it does mean that you'll need to generate some sort of string description for the date you wish to calculate.

We want to grab all the appointments for a particular month, which means generating a database query with a WHERE clause looking for "appointments greater than the timestamp representing the first day of a month and less than a timestamp representing the last day of a month". So, to get ready for that, let's take a look at the following $month_as_written array in the code:

$month_as_written = array(

'01' => 'January',

'02' => 'February',

'03' => 'March',

'04' => 'April',

'05' => 'May',

'06' => 'June',

'07' => 'July',

'08' => 'August',

'09' => 'September',

'10' => 'October',

'11' => 'November',

'12' => 'December'

);

You'll see that the key of each item in the array matches the format of $month (MM).

That's important, as we'll use the value in $month to write out in English the required month name.

188

Chapter 8

We'll prepend it with '01 ' to indicate the first of the month and append it with $year, like this: $start_date = '01' . ' ' . $month_as_written[$month] . ' ' . $year; $start_of_month = strtotime($start_date);

The written string is stored in the variable $start_date, which is then passed to strtotime(), which in turn returns the Unix timestamp for the start of the month.

Next, we calculate the end date:

$end_date = days_in_month($month, $year) . ' ' . $month_as_

written[$month] . ' ' . $year;

$end_of_month = strtotime($end_date);

Next, we use the CodeIgniter function days_in_month(); passing it $month and $year it will return the number of days in the month as an integer. We then concatenate this value with a space ' ' and the written month from the $month_as_written array before finishing with $year. The string is then passed to strtotime($end_date), which gives us the Unix timestamp for the end of the month; this value is stored in the variable $end_of_month.

Well use the two variables $start_of_month and $end_of_month in our database query, asking it to return appointments after the start but before the end of the calculated month: $this->db->where('app_date > ', $start_of_month);

$this->db->where('app_date < ', $end_of_month);

$query = $this->db->get('appointments');

return $query;

Next up, we need to build an array to store the appointments and URLs. First, let's declare the array:

$data = array();

Now, we'll loop through the App_model result (contained in the variable $appointments) building the array as we go:

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

$data[(int)date("d",$row->app_date)] = $row->app_url;

}

Once finished, the array should take this structure:

array(3) {

[2]=>

string(18) "http://localhost/1"

[4]=>

string(18) "http://localhost/2"

[7]=>

string(18) "http://localhost/3"

}

189

Calendaring, Right Place, and Right Time

The $data array is passed along with $year and $month to the calendar library function generate():

$data['cal_data'] = $this->calendar->generate($year, $month, $data); $this->load->view('app_cal/view', $data);

The product of this is stored in $data['cal_data'] and then passed to the view app_cal/

view, from where it is rendered to the screen.

Building an appointment manager with

Calendar Library

The preceding recipe used the CodeIgniter Calendar library to help build an interactive calendar. However, you could only view items in the calendar that were already in the database. The next logical step is building a small application that allows you to create items for the calendar with a form; a simple appointment manager would do the trick. We're basing this recipe on the previous one; however, you don't need to go back and work through that recipe. Everything you need is contained in this recipe.

Getting ready

We'll need to make a database table to store our appointments. If you have used the previous recipe, you should have the database table already; if so, run the following code in your database:

ALTER TABLE àppointmentsÀDD àpp_description` VARCHAR( 255 ) NOT

NULL AFTER àpp_nameÀlternatively, if you haven't already got the table, run this code in your database: CREATE TABLE àppointments` (

àpp_idìnt(11) NOT NULL AUTO_INCREMENT,

àpp_datè varchar(11) NOT NULL,

àpp_url` varchar(255) NOT NULL,

àpp_namè varchar(255) NOT NULL,

àpp_description` varchar(255) NOT NULL,

PRIMARY KEY (àpp_id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Now that the database is sorted, let's look at the code:

190

Chapter 8

How to do it…

We're going to create the following six files:

f

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

This contains all the code necessary to run the show, including the HTML 6

template for the calendar

f

/path/to/codeigniter/application/models/app_cal_model.php:

This contains all necessary code for interacting with the database f

/path/to/codeigniter/application/views/app_cal/view.php: This will display the calendar

f

/path/to/codeigniter/application/views/app_cal/appointment.php:

This will display a form where you can add appointments

f

/path/to/codeigniter/application/views/app_cal/new.php:

This displays a form allowing the user to create a new appointment f

/path/to/codeigniter/application/views/app_cal/delete.php:

This displays a delete confirmation message

We need to execute the following steps to create those files:

1. Create the file /path/to/codeigniter/application/controllers/

app_cal.php and add to it the following code (this is quite a big controller, so I'm going to break down the bigger functions to explain what they do):

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

class App_cal extends CI_Controller {

function __construct() {

parent::__construct();

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

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

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

$this->load->model('App_cal_model');

}

public function index() {

redirect('app_cal/show');

}

The public function show()will display the Calendar on the screen; it is responsible for deciding what month and what year to show.

public function show() {

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

191

Calendaring, Right Place, and Right Time

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

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

} else {

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

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

}

$tpl = '

{table_open}<table border="1" cellpadding="15"

cellspacing="1">{/table_open}

{heading_row_start}<tr>{/heading_row_start}

{heading_previous_cell}<th><a href="{previous_

url}">&lt;&lt;</a></th>{/heading_previous_cell}

{heading_title_cell}<th colspan="{colspan}">{heading}</

th>{/heading_title_cell}

{heading_next_cell}<th><a href="{next_url}">&gt;&gt;</

a></th>{/heading_next_cell}

{heading_row_end}</tr>{/heading_row_end}

{week_row_start}<tr>{/week_row_start}

{week_day_cell}<td>{week_day}</td>{/week_day_cell}

{week_row_end}</tr>{/week_row_end}

{cal_row_start}<tr>{/cal_row_start}

{cal_cell_start}<td>{/cal_cell_start}

{cal_cell_content}'.anchor('app_cal/

create/'.$year.'/'.$month.'/{day}', '+').' <a

href="{content}">{day}</a>{/cal_cell_content}

{cal_cell_content_today}<div class="highlight">'.

anchor('app_cal/create/'.$year.'/'.$month.'/{day}', '+').'<a

href="{content}">{day}</a></div>{/cal_cell_content_today}

{cal_cell_no_content}'.anchor('app_cal/

create/'.$year.'/'.$month.'/{day}', '+').' {day}{/cal_cell_no_

content}

{cal_cell_no_content_today}<div class="highlight">'.

anchor('app_cal/create/'.$year.'/'.$month.'/{day}', '+').'{day}</

div>{/cal_cell_no_content_today}

{cal_cell_blank}&nbsp;{/cal_cell_blank}

{cal_cell_end}</td>{/cal_cell_end}

192

Chapter 8

{cal_row_end}</tr>{/cal_row_end}

{table_close}</table>{/table_close}' ;

$prefs = array (

'start_day' => 'monday',

'month_type' => 'long',

'day_type' => 'short',

'show_next_prev' => TRUE,

'next_prev_url' => 'http://www.your_domain.com/

app_cal/show/',

'template' => $tpl

);

$this->load->library('calendar', $prefs);

$appointments = $this->App_cal_model->get_

appointments($year, $month);

$data = array();

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

$data[(int)date("d",$row->app_date)] = $row->app_url;

}

$data['cal_data'] = $this->calendar->generate($year,

$month, $data);

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

}

The public function create() will handle the creation of appointments, so it'll display the appointment form, validate input, and send data to the model for insertion into the database.

public function create() {

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

$this->form_validation->set_error_delimiters('', '<br

/>');

$this->form_validation->set_rules('app_

name', 'Appointment Name', 'required|min_length[1]|max_

length[255]|trim');

$this->form_validation->set_rules('app_description',

'Appointment Description', 'min_length[1]|max_length[255]|trim');

$this->form_validation->set_rules('day', 'Appointment

Start Day', 'required|min_length[1]|max_length[11]|trim');

193

Calendaring, Right Place, and Right Time

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

Start Month', 'required|min_length[1]|max_length[11]|trim');

$this->form_validation->set_rules('year', 'Appointment

Start Year', 'required|min_length[1]|max_length[11]|trim');

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

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

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

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

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