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.

parent::__construct();

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

}

}

2. Next, create the /path/to/codeigniter/application/controllers/days.

php file and add the following code to it:

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

access allowed');

class Days extends MY_Controller {

function __construct() {

parent::__construct();

}

function index() {

$days = array("Monday","Tuesday","Wednesday",

"Thursday","Friday","Saturday","Sunday"); echo random_element($days);

}

}

222

Chapter 9

How it works...

This is mostly Inheritance. Your child classes are inheriting attributes from parent classes.

However, specifically here, we are demonstrating how to load the array helper in the MY_Controller class and have the Days controller inherit the helper resource in order to execute the array helper function, random_element().

There are so many uses for this, for example, you could check to see if the user was logged in your MY_Controller Class, this would mean that you would only have to write this once rather than in every controller. Or you could go further and have an authenticated controller and unauthenticated controller extending MY_Controller. The MY_Controller file would call any files and perform any tasks common to authenticated and unauthenticated users, While, the authenticated controller would perform login checks, and so on.

Uploading a file with FTP

Every now and again, you'll be asked to generate a file—perhaps from a database export, or maybe some system logs. Most of the time, you'll be asked to e-mail that file to some location, but sometimes, you'll be asked to upload it to an FTP folder the client has access to. We're going to take a recipe from a previous chapter ( Generating a CSV from a database result from Chapter 6, Working with Databases), and adapt it so that it uploads to an FTP

location rather than stream an output.

Getting ready

1. We're going to be pulling some values from a database. To do that, we'll need a table to pull data from. The following is the schema for that table. Copy the following into your database:

CREATE TABLE ùsers` (

ùser_idìnt(11) NOT NULL AUTO_INCREMENT,

ùser_firstnamè varchar(255) NOT NULL,

ùser_lastnamè varchar(255) NOT NULL,

ùser_email` varchar(255) NOT NULL,

PRIMARY KEY (ùser_id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;# MySQL

returned an empty result set (i.e. zero rows).

INSERT INTO ùsers` (ùser_id`, ùser_firstnamè, ùser_lastnamè,

ùser_email`) VALUES

(1, 'Rob', 'Foster', 'rf@domain.com'),

(2, 'Lucy', 'Welsh', 'lw@domain.com');# 2 rows affected.

2. Go to Chapter 6, Working with Databases, and copy out the code from the Generating a CSV from a database result recipe; then return here for further instructions.

223

Extending the Core

How to do it...

We're going to amend one file from the Generating a CSV from a database result recipe, that is, /path/to/codeigniter/application/controllers/export.php. This is the export controller from Chapter 6, Working with Databases. We're going to use it as the basis for this recipe. It will grab some data from the database that eventually generates a CSV for us.

3. Open export.php for editing and amend it to reflect the following code snippet (changes are highlighted):

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

access allowed');

class Export extends CI_Controller {

function __construct() {

parent::__construct();

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

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

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

$this->load->dbutil();

}

public function index() {

redirect('export/csv');

}

public function csv() {

$query = $this->db->query("SELECT * FROM users");

$delimiter = ",";

$newline = "\r\n";

$data = $this->dbutil->csv_from_result($query,

$delimiter, $newline);

$filename = 'myfile.csv';

$path = './'.$filename;

if (! write_file($path, $data)) {

echo 'Cannot write file - permissions maybe?';

exit;

}

$config['hostname'] = 'your-hostname';

$config['username'] = 'your-username';

$config['password'] = 'your-password';

$config['debug'] = TRUE;

$this->ftp->connect($config);

224

Chapter 9

$this->ftp->upload($path, '/dir_on_ftp/'.$filename,

'ascii', 0755);

$this->ftp->close();

}

}

There are some variables here that you should change to reflect the settings of your FTP environment such as:

$config['hostname'] = 'ftp.example.com';

$config['username'] = 'your-username';

$config['password'] = 'your-password';

...and the string dir_on_ftp in:

$this->ftp->upload($path, '/dir_on_ftp/'.$filename,

'ascii', 0755);

How it works...

As you would expect from a new recipe, there are some changes in the normal export controller that we've used in Chapter 6, Working with Databases. These changes are necessary to support the FTP helper in its job of uploading a file to an FTP server.

Let's take a look at what's going on.

First, we load the helpers we'll need--url, file, and FTP--in the Exporter controllers constructor to ensure that this export controller has the right support necessary to make the file transfer.

function __construct() {

parent::__construct();

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

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

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

$this->load->dbutil();

}

Everything then follows the functionality of the previous controller (from Chapter 6,

Working with Databases) ,that is, fetching a result set from the database table and using the CodeIgniter dbutil function, csv_from_result(), to generate a file for us. It's placed on the server by write_file() using the location defined in $path.

Then the FTP functionality kicks in. We define the login settings for the FTP server we want to write the file to--you can and probably should put these in your own config file (also explained in this chapter, see the Making your own configuration files and using the settings recipe), but for now, we'll define them here as it's easier to explain one thing at a time. The settings are fairly obvious until you see the $config['debug'] array setting. debug allows error reports to be displayed to you, the developer. Obviously, in a live production environment, you definitely want that set to be FALSE to prevent any sensitive and important information being shown.

225

Extending the Core

Anyways, using the login settings that we have defined in our $config array, we attempt to connect to the FTP server and try to upload a file, as shown in the following code snippet: $this->ftp->connect($config);

$this->ftp->upload($path, '/dir_on_ftp/'.$filename, 'ascii', 0755);

If all goes well, the file should be uploaded to your server. Log in with an FTP client and take a look to see if it's there--if it's not check that you're using the correct FTP settings and that the path you're writing to on the FTP server is writable and actually exists, that is, that the path defined here in bold exists:

$this->ftp->upload($path, ' /dir_on_ftp/'.$filename, 'ascii', 0755); An interesting point is the two function arguments at the end of the preceding upload() function: ascii and 0755. These state that we're encoding the file transfer as ascii (which is plain text) and setting its file permissions to 0755. This can also be defined in the config array if you wish.

Creating libraries and giving them access to

CodeIgniter resources

CodeIgniter allows you to create your own libraries and helpers in circumstances where you don't want or need to place code in controllers or models. Why would you place code in a library and not a helper? Well, some people become quite agitated by the reasoning for this and I'm sure that if you thought hard enough about it, you could come up with some strict rules that defines when a bit of code is a helper or a library. But life is far too short. As long as the code is well documented and is maintainable, stable, and secure, you can do whatever you like. However, as a general rule of thumb:

A library is for code which requires access to other resources, such as needing access to a database, or to an external system (perhaps through cURL), whereas a helper is a smaller bit of code which performs a specific task (such as checking a string being a valid e-mail or for a valid URL, for example).

I'm sure there are better definitions, but this one works for me; and I'm sure there will be times when you may want a helper to have access to a database or other resource; and I'm sure there will be times when a library doesn't need access to these resources. My point is, just make sure the code is documented and maintainable and don't get bogged down in conceptual design augments.

Having said that, let's look at creating a library and giving it access to CodeIgniter resources (because, by default, it won't).

226

Chapter 9

Getting ready

We're going to access a database through a library; however, to do that we'll need a database to access (of course), so copy the following code into your database: CREATE TABLE IF NOT EXISTS `person` (

ìdìnt(11) NOT NULL AUTO_INCREMENT,

`first_namè varchar(50) NOT NULL,

`last_namè varchar(50) NOT NULL,

èmail` varchar(255) NOT NULL,

PRIMARY KEY (ìd`)

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

INSERT INTÒperson` (ìd`, `first_namè, `last_namè, èmail`) VALUES

(1, 'Rob', 'Foster', 'rfoster@dudlydog.com'),

(2, 'Lucy', 'Welsh', 'lwelsh@cocopopet.com'),

(3, 'Chloe', 'Graves', 'cgraves@mia-cat.com'),

(4, 'Claire', 'Strickland', 'cstrickland@an-other-domain.com');

How to do it...

We're going to create the following three files:

f

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

f

/path/to/codeigniter/application/libraries/lib_to_call.php

f

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

1. Create the call_lib.php controller and add the following code to it:

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

access allowed');

class Call_lib extends CI_Controller {

function __construct() {

parent::__construct();

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

$this->load->database();

}

public function index() {

$result = $this->lib_to_call->get_users();

echo '<pre>';

var_dump($result->result());

echo '</pre>';

}

}

227

Extending the Core

2. Create the lib_to_call.php library and add the following code to it:

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

access allowed');

class Lib_to_call {

public function get_users() {

$CI =& get_instance();

$CI->load->model('Lib_model');

return $CI->Lib_model->get();

}

}

3. Then create the lib_model.php model and add the following code to it:

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

access allowed');

class Lib_model extends CI_Model {

function __construct() {

parent::__construct();

}

function get() {

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

return $query;

}

}

How it works...

In looking at how to give your libraries access to CodeIgniter resources, we're going to run through the preceding recipe. It's connecting to a model; however, it can be any type of CodeIgniter resource such as a Hook or a helper, and so on.

First, the call_lib.php controller loads in its constructor the lib_to_call library, as follows:

function __construct() {

parent::__construct();

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

}

228

Chapter 9

This makes the library available to the entire controller.

We then call public function index(), which calls the library function, get_users(), storing the returned results in the $result variable. Let's look at what the library function, get_users(), is doing, this is where we allow the library to get access to CodeIgniter resources.

Look at the following highlighted lines in the lib_to_call library: class Lib_to_call {

public function get_users() {

$CI =& get_instance();

$CI->load->model('Lib_model');

return $CI->Lib_model->get();

}

}

We're using the PHP function, get_instance(), to get our hands on a copy by reference (that means we're using the initial object rather than a copy of it) or the CodeIgniter object.

This object has access to the entire CodeIgniter system and its resources. We store this object in a local variable named $CI (standing for CodeIgniter). We can now call any CodeIgniter resource we like, just as we would from a controller, except that instead of using $this (as we would in a controller), we use $CI. So, to call a model or helper in a controller, we will do the following:

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

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

But to call helpers and models in the library, we now do the following: $CI->load->helper('helper_name');

$CI->load->model('model_name');

The model we've now loaded will query the database with Active Record, returning all rows in the table to the library, which in turn returns it to the controller for processing. In this case (to demonstrate that it worked), we var_dump() the result. If all goes well, this recipe should output as follows:

array(4) {

[0]=>

object(stdClass)#19 (4) {

["id"]=>

string(1) "1"

["first_name"]=>

string(3) "Rob"

["last_name"]=>

string(6) "Foster"

229

Extending the Core

["email"]=>

string(20) "rfoster@dudlydog.com"

}

[1]=>

object(stdClass)#20 (4) {

["id"]=>

string(1) "2"

["first_name"]=>

string(4) "Lucy"

["last_name"]=>

string(5) "Welsh"

["email"]=>

string(20) "lwelsh@cocopopet.com"

}

[2]=>

object(stdClass)#21 (4) {

["id"]=>

string(1) "3"

["first_name"]=>

string(5) "Chloe"

["last_name"]=>

string(6) "Graves"

["email"]=>

string(19) "cgraves@mia-cat.com"

}

[3]=>

object(stdClass)#22 (4) {

["id"]=>

string(1) "4"

["first_name"]=>

string(6) "Claire"

["last_name"]=>

string(10) "Strickland"

["email"]=>

string(31) "cstrickland@an-other-domain.com"

}

}

The preceding recipe access a database as a means of demonstrating how to gain access to a CodeIgniter super object from within a library. However, helpers, Hooks, and other elements can also be accessed. By using $CI =& get_instance(), we can gain access to the main CodeIgniter object. By using $CI rather than $this, this will give us access to all of CodeIgniter's resources, as shown in the following code snippet:

$CI =& get_instance();

$CI->load->model('Lib_model');

return $CI->Lib_model->get();

230

Chapter 9

Making your own configuration files and

using the settings

It's a great idea to have configuration settings in the same file—the benefits are obvious—so rather than having settings hidden in controllers, modules, helpers, libraries, or (God forbid) in views, you can put them in one location and refer to them from there. CodeIgniter comes with its own configuration files in the config folder; however, you can add your own files to the config folder and refer to them in your code. It's pretty handy and easy to do; let's take a look.

How to do it...

We're going to create the following two files:

f

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

f

/path/to/codeigniter/application/config/my_config_file.php

1. Create the config_settings.php controller, open it for editing, and add the following code to it:

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

access allowed');

class Config_settings extends CI_Controller {

function __construct() {

parent::__construct();

$this->config->load('my_config_file');

}

public function index() {

echo $this->config->item('first_config_item');

for($i = 0; $i < $this->config->item('stop_at'); $i++) {

echo $i . '<br />';

}

}

}

231

Extending the Core

2. Create the config file, my_config_file.php, open it for editing, and add the following code to it:

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

access allowed');

$config['first_config_item'] = "This is my config setting,

there are many like it but this one is mine<br />";

$config['stop_at'] = 10;

How it works...

To be honest, there are so many situations where putting information in a config file is useful that make it pointless writing a specific recipe for you, as the chances of it being the recipe you need are slim to none. So, this is just a proof of concept; it is there for you as a guide of the basic two files: a config file and another file (a controller) to grab information from it.

Take a look at the constructor in the controller, Config_settings. This is where we define the name of the config file. You can call it whatever you like (as long as the name isn't already taken by another config file). Here, I've called it my_config_file; it's a bit 1995, but it's good enough for the explanation and I'm sure you get the idea.

The next thing to happen is that public function index() is executed, which does two things: prints out a string of text (the text is set in our config file) and iterates through a for() loop, only stopping when it reaches the value specified in our my_config_file.

These two approaches show you how to work with config values: either echoing out to screen or using that value in some sort of structure.

Using the language class – switching

language on the go

Once you have developed your site to accommodate multiple languages, you'll obviously want to allow people to switch between them. For example, to switch from English to French, or French to German, or whatever region or language you're developing for. This can be handled in several ways, but in this example, we're going to use the CodeIgniter Session class to swap from one language to another.

Getting ready

We're going to use the Session class to store the user's language preference, which means, we'll need to use CodeIgniter sessions. This will require some configuration.

232

Chapter 9

We'll be editing the following files:

f

path/to/codeigniter/application/config/config.php

f

path/to/codeigniter/application/config/database.php

The following are the config settings:

1. Find the following config values in the path/to/codeigniter/application/

config/config.php file and amend them to reflect the following values: Config Item

Data Type

Change to Value Description

$config['sess_cookie_ String

ci_session

This is the name of the cookie

name']

written to the

user's computer.

$config['sess_

Integer

7200

This is the number of seconds

expiration']

a session should remain

active, after no user activity,

before becoming void.

$config['sess_expire_ Boolean

TRUE

This specifies that if the user

on_close']

(True/

closes their browser the

False)

session becomes void.

$config['sess_

Boolean

TRUE

This specifies if the cookie

encrypt_cookie']

(True/

should be encrypted on the

False)

user's computer. For security

purposes this should be set

to TRUE.

$config['sess_use_

Boolean

TRUE

This specifies weather or

database']

(True/

not to store sessions in

False)

the database. For security

purposes this should be set

to TRUE. You will also need

to create the session table,

the code for which can be

found in the upcoming page.

$config['sess_table_

String

sessions

This specifies the name of the

name']

database table used to store

session data. In this recipe,

I have called the sessions table

simple sessions; however,

you can keep the original

i_sessions--just make sure you

amend the SQL accordingly.

233

Extending the Core

Config Item

Data Type

Change to Value Description

$config['sess_match_

Boolean

TRUE

This specifies whether

ip']

(True/

CodeIgniter should monitor

False)

the IP address of requests

and against that of the

session_id. If the IP of

an incoming request doesn't

match the previous values,

the session is disallowed.

$config['sess_match_

Boolean

TRUE

This specifies whether

useragent']

(True/

CodeIgniter should monitor

False)

the user agent address of

requests and against that of

the session_id. If the user

agent of an incoming request

doesn't match the previous

values, the session

is disallowed.

2. Find the following config values in the path/to/codeigniter/application/

config/database.php file and amend them to reflect the correct settings to enable you to connect to your database:

Config Item

Data Type

Change to Value

Description

$db['default']

String

localhost

The hostname of your

['hostname']

database. This is usually

either localhost or an

IP address

$db['default']

String

The username you wish

['username']

to use to connect to

your database

$db['default']

String

The password used to

['password']

connect to your database

$db['default']