Korišćenje CodeIgniter biblioteka i helpera

U prethodnom tekstu o CodeIgniteru objašnjeno je kako da napravite sopstvene biblioteke i helpere. Danas ću prikazati korišćenje nekih biblioteka i helpera koje dolaze sa CodeIgniter-om. Budući da je primer koji dolazi dosta kompleksniji od prethodnih trebalo bi da dobro razumete osnove pre nego što krenete sa čitanjem, ali alternativa nešto težem primeru je bila puko nabrajanje biblioteka i njihovih sadržaja, što bi bilo dosadno kako za pisanje, tako verujem i za čitanje.

Kako učitati biblioteke

Sve biblioteke koje dolaze sa CodeIgniter-om se nalaze u /system/libraries. Njih možemo pozvati slično kao i biblioteke koje mi sami pravimo sa $this->load->library(“Ime_biblioteke“);, a ako vam je potrebno može se i učitati vise biblioteka od jednom na primer $this->load->library(array(‘ime_biblioteke1’, ‘ime_biblioteke2’, ‘ime_biblioteke3’)); pri čemu se imena biblioteka mogu ispisivati dok ne obuhvatimo sve biblioteke. Te biblioteke u kodu pozivamo sa $this->ime_biblioteke->ime_funkcije();. Ako biblioteke prihvataju argumente u konstruktoru možete to učiniti sa:

$data = array(“argument_1” => “1”, “argument_2” => “2”);
$this->load->library(“ime_biblioteke”, $data);

Kako učitati helpere

Slično bibliotekama, helperi se nalaze u /system/libraries. Njih učitavamo sa $this->load->helper(“Ime_helpera”), na primer $this->load->helper(“url”); . Po istom principu kao kod biblioteka možemo učitati i više helpera istovremeno: $this->load->helper(array(“helper_1”, “helper_2”, ”helper_3”));

Primer nekoliko češće korišćenih biblioteka i helpera

Prikazaću primer jednostavnog korisničkog logina i listanja boja iz jednog od prošlih tekstova, ali sada sa paginacijom. Za takav primer je neophodan širok spektar CodeIgniter biblioteka kao što su biblioteke za formu, bazu, session-ne, paginaciju, helperi za uri, formu, kao i dobar deo biblioteka što nisu sastavni deo paketa, dakle koje moramo ručno da napravimo.
Prvo treba da imamo kontroler koji ce imati u sebi formu. Nazovimo kontroler klasu Login. On u sebi sadrzi view fajl sa imenom form.php:

<html>
	<head>
		<title>My Form</title>
	</head>
	<body>
<br />
<div class=”validation_errors”>
			<?php echo validation_errors(); ?>
		</div>
<p>
		<?php echo form_open('login'); ?>
<br />
<h5>Username</h5>
<p>
		<input type="text" name="username" value="" />
<br />
<h5>Password</h5>
<p>
		<input type="password" name="password" value="" />

<div><input type="submit" value="Uloguj se" /></div>
<p>
		</form>
<p>
	</body>
</html>

Jednostavan view fajl. Postoji div koji ispisuje validacione greske ako one postoje, jednostavna CodeIgniter funkcija validation_errors() i forma sa korisnickim imenom i šifrom koja salje podatke na kontroler login.

Kontroler login je malo komplikovaniji:

class Login extends CI_Controller 
{
	function index()
	{
		$this->load->helper(array('form', 'url'));
		$this->load->library('form_validation');

		//ucitavanje rucno napravljenog helpera
		$this->load->helper("login_validation");

		//ucitavanje pravila za validaciju iz funkcije u login_validation helperu
		$config = validation_rules();			
		$this->form_validation->set_rules($config);

		//ako je validacija uspela proveriti da li su uneti podatci ispravni
		if ($this->form_validation->run() == true)
		{
			//ucitavanje sopstvene biblioteke koja se bavi korisnicima
			$this->load->library("user_lib");

			//uzimanje postovanih informacija
			$username = $this->input->post("username");
			$password = $this->input->post("password");

			//user lib funkcija koja vraca true ako je korisnik uneo ispravne podatke, false u suprotnom
			$result = $this->user_lib->check_login($username, $password);

			//ako je model vratio true znaci da je korisnik uneo uspesne podatke, onda mu setujemo session i redirektujemo na pocetnu stranu
			if($result)
			{
				$result = $this->user_lib->set_session($username);

				//ako je seasson setovan sledi redirekcija
				if($result)
				{
					redirect('colors/pagination', 'location', 301);
				}
			}
		}

		//ako validacija nije uspela ili je model vratio false prikazujemo formu
		$this->load->view('form');	
	}
} 

Ovaj kontroler učitava ručno napravljeni helper login_validation_helper.php

	
if(!function_exists("validation_rules"))
{
	function validation_rules()
	{
		//postaviti validaciona pravila
		$config = array
		(
		array
		(
			'field'   => 'username', 
			'label'   => 'Username', 
			'rules'   => 'required|min_length[3]|max_length[12]'
		),
		array
		(
			'field'   => 'password', 
			'label'   => 'Password', 
			'rules'   => 'required|min_length[5]|max_length[12]'
		)
		);
		return $config;
	}
}

Kao i biblioteku koju korisnik treba da napravi User_lib.php

class User_lib
{
	//deklarisanje klasne promenjive CI
	private static $CI;
	public function __construct()
	{	    
		//ucitavanje CI super objekta u klasnu promenjivu
		self::$CI = & get_instance();
		self::$CI->load->model("users_model");
	}
	function check_login($username, $password)
	{
		//pozivanje funkcije u modelu za proveru
		$result = self::$CI->users_model->check_user($username, $password);
		return $result;
	}
	function set_session($username)
	{
		//definisanje podataka za session
		$session_data = array
		(
			'username'  => $username,
		'logged_in' => TRUE
		);
		//loadovanje session kalse
		self::$CI->load->library("session");
           	 
		//stavljanje podataka u session
		self::$CI->session->set_userdata($session_data);
			 
		//proverimo da li je stavljanje uspelo
		$logged_in = self::$CI->session->userdata("logged_in");
			 
		if(isset($logged_in) && $logged_in)
		{
			return true;
		}
		return false;
	}	
}

Par napomena:

  • Da biste koristili session klasu mora da se u config.php postavi enkripcioni ključ. On služi za kodiranje I dekodiranje session-a i bilo bi poželjno, iz bezbednostnih razloga, da bude jedinstven, nasumičan alfanumerički string. Nešto kao na primer “APANtByIGI1BpVXZTJgcsAG8GZl8pdwwa84”.
  • CodeIgniter funkcija redirect je prekidajući proces kao i kod php funkcije za redirektovanje ne sme da bude nikakvog outputa pre funkcije ili ona neće raditi. Ovde se redirektuje na već postojeći kontroler colors, na novododatu funkciju pagination_list().

Neophodna je i nova tabela u bazi sa imenom user

CREATE TABLE IF NOT EXISTS `user` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) CHARACTER SET latin1 NOT NULL,
  `password` text CHARACTER SET latin1 NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf16 AUTO_INCREMENT=2 ;

--
-- Dumping data for table `user`
--

INSERT INTO `user` (`ID`, `username`, `password`) VALUES
(1, 'test', ‘fa6977c99b809db68e1c56888ec38bd004719b39’);

Za one koji žele da testiraju sa copy paste:
Username: test
Password: qqqqqq
i model login_model.php koji se poziva iz login kontrolera:

class Users_model extends CI_Model 
	{
		function check_user($username, $password)
		{
			//eskejpovanje stringoa
			$username = $this->db->escape_str($username);
			$password = sha1($this->db->escape_str($password));
			//generisanje kveri stringa
			$query_string = "SELECT ID FROM user WHERE username = '$username' AND password = '$password'";
			//izvrsenje kverija
			$result =  $this->db->query($query_string);
			//vracanje rezultata
			if($result && $result->num_rows() > 0)
			{
				return true;
			}
			return false;
		}	
	} // END class 	

Dakle, sada imamo kontroler login koji prima zahtev. On učitava neophodne bilbioteke i helpere i proverava da li je validacija uspela. Ako je prošla uzima postovani username i password i šalje ih u bilbioteku koja, ako su ispravni podaci, vraća true, ako nisu false. Ako je vraćeno true, postavlja se session i korisnik se redirektuje na listu boja. Ako nije prošla validacija ili su username ili password netačni (što uključuje i prvi dolazak na stranu, tj. kada ništa nije ukucano) prikazujemo view fajl sa formom.

Redirekt je deo url helpera. Dobra praksa je da iznad funkcija pišete u kome se helperu se funkcija nalazi pogotovo ako pišete veliki broj sopstvenih, jer se lako desi da se zaboravi koja je odakle. A onda provedete dva sata jureći odakle su nekih 10 funkcija iz 20 mogućih helpera da bi ste prepravili nekoliko karaktera.

Form validation biblioteka zahteva da se postave određeni parametri da bi radila. Neophodno je postaviti niz koji sadrži ime polja, labelu i pravila za validaciju. Pored toga je zanimljivo napomenuti da je moguće dodati i sopstvene poruke za svako od pravila, tj. šta će se ispisati ako ne uspe. To se radi sa $this->form_validation->set_message(“pravilo”, “Ovde ide poruka”);

Nakon što krenete da radite postove preko ajax-a, a samim tim js validaciju korisničke strane, ova validacija dobija malo drugačiji i jednostavniji oblik, tako da nema potrebe da se previše detaljno izučava.

Što se session-a tiče, jednostavno napravite niz koji želite da stavite u session i pozovete $this->session->set_userdata($niz) ; , a onda uzimate informacije iz delova postavljenog niza sa $this->session->userdata(“deo_niza”); . Session klasa u CodeIgniteru poseduje i mogućnost smeštanja informacije iz sessiona u bazu automatski uz malu izmenu config.php, kao i neke druge mogućnosti.

$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_expire_on_close']	= TRUE;
$config['sess_encrypt_cookie'] = TRUE;
$config['sess_use_database'] = FALSE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_match_useragent']	= TRUE;
$config['sess_time_to_update'] = 300;

Moguće je konfigurisati dužinu trajanja session-a, da li će koristiti enkripciju, da li će se produžavati na neku akciju, da li će koristiti tabelu, da li će proveravati da li se IP poklapa, kako se tabela zove itd.

Sada sledi deo nakon redirektovanja, prvo kontroler colors.php

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Colors extends CI_Controller { public function __construct() { parent::__construct(); //ucitavanje helpera i biblioteka $this->load->library("session");
		$this->load->helper("url");
            
		//uzimanje seassion podataka
		$user = $this->session->userdata("logged_in");
           
		//ako seassion nije setovan rediretkovati na login
		if(!$user)
		{
			redirect("login");
		}
	}		 
	function pagination()
	{
		//ucitavanje helpera i biblioteka potrebnih za ovu funkciju
		//paginacija je CI biblioteka, color_lib custom
		$this->load->library("pagination");
		$this->load->library("color_lib");
		
		//uzimanje uri segmenta
		$current_page = $this->uri->segment(3);
		
		//ako nema nista znaci da je pocetna strana
		if(!is_numeric($current_page))
		{
			$current_page = 0;
		}
			
		//koliko zelimo itema po strani da nam se prikazuje
		$items_per_page = 2;
		
		//uzimanje podataka o bojama iz baze preko biblioteke
		$data = $this->color_lib->get_list($current_page, $items_per_page);
			
		//konfiguracija paginacije
		//bazni url
		$config['base_url'] = 'http://example.com/index.php/colors/pagination/';
		//koliko itema po strani
		$config['per_page'] = $items_per_page;
		//koliko ima ukupno itema
		$config['total_rows'] = $data['total'];
		//u kom uri segmentu se nalazi na kojoj smo strani
		$config['uri_segment'] = 3;
		//koliko brojeva ce se nalaziti pored trenutne strane
		$config['num_links'] = 4;
		
		//inicijalizovati paginaciju
		$this->pagination->initialize($config); 

		//pozvati view fajl
		$this->load->view("color_list_view", $data);	
	}
}

/* End of file colors.php */
/* Location: ./application/controllers/colors.php */

Ovde pozivamo biblioteku koja nije deo CodeIgniter-a, a nalazi se u applications/libraries/Color_lib.php

class Color_lib
	{
		function get_list($current_page, $items_per_page)
		{
			$CI = & get_instance();
			
			$CI->load->model("colors_model");
			
			//uzimanje liste boja
			$data['color_list'] = $CI->colors_model->get_list($current_page, $items_per_page);
			
			//uzeti totalni broj boja u tabeli
			$data['total'] = $CI->colors_model->get_total();
			
			return $data;
		}
	}

Ova biblioteka poziva colors_model iz colors_model.php.

class Colors_model extends CI_Model 
{	
	function get_list($current_page, $items_per_page)
	{
		//eskejpovati podatke
		$current_page = $this->db->escape_str($current_page);
		$items_per_page = $this->db->escape($items_per_page);
			
		//generisati kveri string
		$query_string ="SELECT color_name, color_hex_value FROM colors LIMIT $items_per_page OFFSET $current_page";
			
		//izvrsiti kveri
		$result =  $this->db->query($query_string);
		
		//ako je kveri uspeo vratiti resultat
		if($result && $result->num_rows() > 0)
		{
			return $result->result_array();
		}
		return false;
	}	
		
	function get_total()
	{
		//generisati kveri
		$query_string = "SELECT COUNT(ID) as 'cnt' FROM colors";
			
		//izvrsiti kveri
		$result =  $this->db->query($query_string);
			
		//ako je kveri uspeo vratiti rezultat
		if($result)
		{
			return $result->row()->cnt;
		}
		return false;
	}
}

Dakle, u konstruktoru kontrolera colors proveravamo da li je korisnik ulogovan. Ako nije redirektuje se na login stranu. Tako omogućavamo da samo ulogovani korisnici mogu da pristupe ovoj strani. Naravno, treba napomenuti da ovako napravljen primer i nije preterano bezbedan od upada i da je bolje da dizajnirate neki sopstveni bezbednostni protokol ako već pravite login.

U samoj funkciji pagination() uzimamo informacije iz baze, konfigurišemo parametre za konfiguraciju i učitavamo view fajl. Uz pomoć CodeIgniter helpera iz URL-a uzimamo informaciju o tome na kojoj smo trenutno strani. $this->uri->segment(3) znači da uzimamo treći segment.

URI

Iz baze dobijamo nekoliko elemenata liste boja, koliko zavisi od vrednosti promenljive $items_per_page, od trenutne strane, kao i koliko ukupno elemenata ima da bi formirali paginaciju. Moguće je uprostiti ovo i stalno iz baze uzimati celu listu, ali na velikoj količini redova u listi postaje veoma neefikasno.

I na kraju u view fajlu prikazujemo kao i obično listu boju, samo što sada postoji i funkcija iz biblioteke za paginaciju koja omogućava da vidimo linkove za naredne strane.

Za kraj

Naravno, ovo je samo mali deo funkcija koje ove biblioteke poseduju, kompletnu listu mozete pogledati na CodeIgniter-ovom sajtu. Neke od njih, kao i neke od ostalih biblioteka, biće korišćene u narednim temama i primerima u serijalu.

Tagovi: