Udi Mosayev

Programming, Business and my thoughts..

Archive for the ‘CodeIgniter’ Category

Book Review: “CodeIgniter 1.7 Professional Development” by Adam Griffiths

The book “CodeIgniter 1.7 Professional Development” written by Adam Griffiths. I’ve already wrote a little bit about the book before, and Few days ago I got it in the mail and finished reading it already.

The author is a well known developer in the CodeIgniter community, who also contributed nice authentication library. So as expected, I saw a lot of high quality information in the book, and the experience of the author with CodeIgniter is shown. If I only read the book a year ago, I could’ve become better CodeIgniter developer much faster.

Though the first chapter dedicated to get you started with CodeIgniter, I think its the best if you already have some experience with the framework. And even long-time CodeIgniter developers might find valuable information.

Personally I enjoyed reading about building large scale application [Chapter 7] and the timing is perfect because of the project I’m working on. In my opinion, before reading this book, you must have some experience with CodeIgniter [build 1 applicaiton in CI and you're good to go in my opinion], and this book really can turn you into professional. Use the knowledge you get from this book  and you’ll be much better CodeIgniter developer.

Another chapter I liked is Chapter 10 – Developing and Releasing Code to the Community. Although its quite short chapter, there is a lot of information regarding this subject. The author shared in the chapter his experience writing and maintaining the Authentication library and I really enjoyed it. It motivates you to create and share :) .

What I was missing in the book, and I think most of the beginners would find it useful is Application Structure examples. Discussing different ways you can build real life web applications that almost every developers writes at some point.

CodeIgniter is amazing PHP framework, its lightweight, very flexible and simple to understand. “CodeIgniter 1.7 Professional Development” contains very valuable information and practices, that can turn any newbie into skilled CodeIgniter developer. As I already said, if I only had this book a year ago, I could have become better CodeIgniter developer much faster.

For more information about the book & purchase, visit book’s page at PacktPub.com.


View Comments

Written by Udi Mosayev

June 4th, 2010 at 11:19 pm

My experience with CloudIgniter

Recently I got an opportunity to use CloudIgniter – Codeigniter Hosting, with your own database and ftp account.
In my account I can have 3 domains, I’ve added the first one: helloworld.co.il and I have few options:

  • Platform – CodeIgniter 1.7.2, CodeIgniter 2.0 beta
  • Application – Different versions of PyroCMS and MyClientBase.

I chose PyroCMS.

What it does, is installing the application on your account, in your Database, and login info to Pyro are automatically the login info to your CloudIgniter account and you can start working.

I’m located in Israel, and I have my experience with hosting servers outside Israel and most of them [Dreamhost for example] are nightmare for me, the FTP connection specially. But CloudIgniter servers are quite good, not as fast as Israeli servers I’m working on but their good [considering the distance].

The CloudIgniter admin panel is very simple to understand and navigate, you can find very simple Domain Management [with all the info you need], Usage information, setup Google Apps account for emails, and account settings.

To sum it up:

  • You have FTP account, Database, phpMyAdmin – everything you need.
  • Can manage more then 1 domain, I believe it will be part of their business plan. Each domain can be different CI installation/application.
  • There’s a backup plan, I don’t know which – but if you change the CI installation for certain domain it backups the old one.
  • Usage information – not full detailed, but good enough.
  • Clean and simple Admin Panel design.

CloudIgniter is at beta phase, you can go to CloudIgniter and ask for beta slot.

Good luck!


View Comments

Written by Udi Mosayev

May 29th, 2010 at 2:38 pm

MY_Model in CodeIgniter

Hi,

I wanted to share with you MY_Model I’ve written and use for most of my CodeIgniter apps.

/**
 * This is the basic model class.
 *
 * @package - Infrastructure
 * @category - Model
 * @author - Udi Mosayev @ umNet
 * @link - udi.mosayev@gmail.com
 * @since - Version 1.0
 */
class MY_Model extends CI_Model {

	// The main table name
	public $table;

	private $modelName;

	public function MY_Model() {
		parent::CI_Model();
		$this->table = '';
		$this->modelName = __CLASS__;
	}

	// Log as Error each time nonexisting method called.
	public function __call($name, $arguments) {
		$args = implode(',',$arguments);
		$this->log('error', $name.'('.$args.') Not exists');
		return FALSE;
	}

	/**
	 * Logs an error
	 * @param String $level
	 * @param String $msg
	 */
	protected function log($level, $msg) {
		log_message($level, __CLASS__.'->'.__METHOD__.' :: '.$msg.' | In: '.__FILE__.' Line: '.__LINE__);
	}
	/**
	 * This method inserts some array of data into the db
	 * @param Array $data
	 */
	public function save($data) {
		if(is_array($data)) {
			$this->db->insert($this->table, $data);
			return $this->db->insert_id();
		} else {
			$this->log('error', 'got non-array param.');
			return FALSE;
		}
	}

	/**
	 * This method updates fields in my table.
	 * @param String $fieldName
	 * @param String $value
	 * @param Integer $RowID
	 */
	public function updateField($fieldName, $fieldValue, $rowID) {
		if(empty($fieldName)) {
			$this->log('error', 'got empty fieldName');
			return FALSE;
		}
		else if(empty($fieldValue)) {
			$this->log('error','got empty fieldValue');
			return FALSE;
		}
		else if(!is_numeric($rowID)) {
			$this->log('error', 'got non-numeric RowID: '.$rowID);
			return FALSE;
		} else {
			// Wrtite the old&new data to history.
			$this->history->write($this->table, $rowID, $fieldName, $fieldValue);

			$this->db->where('ID', $rowID);
			$this->db->update($this->table, array($fieldName => $fieldValue));

			return TRUE;
		}
	}

	/**
	 * Updates whole row [unlike updateFIeld()]
	 * @param Array $RowData
	 * @param Integer $RowID
	 */
	public function update($RowData, $RowID) {

		if(!is_array($RowData)) {
			$this->log('error', 'supposed to get an array!');
			return FALSE;
		} else if(!is_numeric($RowID)) {
			$this->log('error', 'got non-numeric RowID: '.$RowID);
			return FALSE;
		} else {
			// write the old&new data to history
			foreach($RowData as $fieldName=>$fieldValue) {
				log_message('debug', 'Running history->write() with: history->write('.$this->table.', '.$RowID.', '.$fieldName.', '.$fieldValue.')');
				$this->history->write($this->table, $RowID, $fieldName, $fieldValue);
			}

			$this->db->where('ID', $RowID);
			$this->db->update($this->table, $RowData);
		}
	}

	/**
	 * This method returns all the rows of this model
	 * @param Array $where
	 */
	public function getWhere($where = "") {
		// if not array, then assign defaultive array for where clause
		if(!is_array($where)) $where = array('IsDeleted' => 0);
		$query = $this->db->get_where($this->table, $where);

		return $query;
	}

	/**
	 * This method gets 1 row from a table and returns it.
	 * @param Integer $RowID
	 */
	public function get($RowID) {
		if(!is_numeric($RowID)) {
			$this->log('error', 'Did NOT got a numeric RowID.');
			return FALSE;
		} else {
			$query = $this->db->get_where($this->table, array('ID' => $RowID));
			return $query;
		}
	}

	public function delete($RowID) {
		if(is_numeric($RowID)) {
			$this->updateField('IsDeleted', 1, $RowID);
			return TRUE;
		} else {
			return FALSE;
		}
	}
}

/* End of file MY_Model.php*/
/* Location: ./application/model/MY_Model.php */

I need to explain few things:

  • I use logical delete, I have field called IsDeleted its TINYINT, and if I want to delete certain row I update its value to 1. This method has lots of benefits which I can’t discuss now.
  • I use two “read” methods, get() and getWhere(), I KNOW that get() should use getWhere inside, but I don’t really have the time for this little fix :P
  • This class rewritten for CodeIgniter 2.0, so that’s why I extend CI_Model, if you’re using CodeIgniter 1.7 just write Model instead.
  • In each app I add more methods, methods that I need in all my models, or at least in some of them. For example a method that re-orders the item in the table.

Ask any thing you want, I’ll be happy to help.

UPDATE:

In line 98 you see this:

$this->history->write($this->table, $RowID, $fieldName, $fieldValue);

if you remember, I wrote about System Restore feature in Must Have Features in you CMS, this is my implementation for this feature. Thank you Zack for noticing!


View Comments

Written by Udi Mosayev

May 17th, 2010 at 5:55 pm

Database Interaction with Codeigniter 1.7

Hi,

Yesterday I wrote about the new CodeIgniter book: CodeIgniter 1.7 Professional Development By Adam Griffiths.
Packt Publishing extracted an article from the book, “Database Interaction with Codeigniter 1.7” which can be very helpful for beginners. You’ll read about the Database class, ActiveRecord and Database Forge class that gives you few methods to perform different [not so casual] operations in your database.

I really recommend you to not use ActiveRecord if you’re not familiar with SQL. If you’ll use ActiveRecord from day 1, you wouldn’t really know whats happening under the hood. My opinion is the same about PHP frameworks, I don’t think its good idea to start working with a framework before you know the language good enough.
Although not using ActiveRecord you won’t enjoy the security of injections-free queries and multiple DB types support – but in the long run its better for you as web developer.

Moreover, consider extending the native Model and writing simple CRUD [Create/Read/Update/Delete] methods that can help you working faster and better. I promise I’ll write about it more, I wrote for my self a quite powerful MY_Model class.

This is it for now,
If you already got the book, share your thoughts with me.


View Comments

Written by Udi Mosayev

May 15th, 2010 at 7:17 pm

New CodeIgniter Book: CodeIgniter 1.7 Professional Development (by Adam Griffiths)


Codeigniter 1.7 Professional Development

Codeigniter 1.7 Professional Development

Hi,

Recently, new Codeigniter book came out. CodeIgniter 1.7 Professional Development by Adam Griffiths. Packt Publishing asked me to review this book, so once I’ll get it in the mail I review it for you.
Take a look at the TOC of the book, Personally I’m really excited about Chapter 7: Building a Large-Scale Application and Chapter 10: Developing and Releasing Code to the Community , they look very interesting to me.

What you will learn from this book : [From Packt Publishing's Book page]

  • Learn the Model-View-Controller design pattern to structure your code.
  • Create more readable and maintainable queries using the Active Record implementation.
  • Create and maintain database tables using the Database Forge class.
  • Authenticate users using Twitter oAuth and Facebook Connect.
  • Create your own Authentication Library for more control over your user accounts.
  • Secure your application using CodeIgniter’s built-in functionality and some quick tips to help further.
  • Build a RESTful Web Service, opening up your application to third-party developers.
  • Create extended Controllers, grouping functionality into multiple Controllers helping to keep repeated code to a minimum.
  • Learn techniques used by professionals to scale CodeIgniter over multiple servers.
  • Learn top tips for releasing code to the community and giving support to the developers using your code.

Who this book is written for: [From Packt Publishing's Book page]

This book is written for advanced PHP developers with a good working knowledge of Object Oriented Programming techniques who are comfortable with developing applications and wish to use CodeIgniter to make their development easier, quicker, and more fun. Basic knowledge of CodeIgniter will be helpful. This book will suit developers who fall into three categories:

  • Professional Developers – employees of a software house or organization with in-house software development.
  • Freelance Developers – solo developers working in the industry on their own.
  • Just-for-fun Developers – people working with PHP building web applications is their spare time for fun.

Packt Publishing also released an article called “Database Interaction with Codeigniter 1.7” which I want to read and discuss here later this weekend.


View Comments

Written by Udi Mosayev

May 14th, 2010 at 3:34 pm

Posted in CodeIgniter

Tagged with ,

Continuous Deployment

I started to hear a lot about continuous deployment, which means to deploy every piece of code you commit right away. But what I found more interesting to me is the strong infrastructure needed in order to do that.

Eric Ries wrote “Continuous deployment in 5 easy steps” and I really liked the idea of automated tests tool and deployment script.
I also read “Deployment Infrastructure for Continuous Deployment” and saw the Deployment tool kaChing developers created.

I’ll keep reading about this subject and think how can I create useful tool with Codeigniter which will help CI developers test their application and deploy the code.
For the beginning I’ll start with simple deployment, connecting to FTP and uploading modified files.

You can read more about Continuous Deployment here


View Comments

Written by Udi Mosayev

May 7th, 2010 at 4:42 pm

Posted in CodeIgniter,PHP,Web Development

Tagged with

CodeIgniter 2.0

Hi,

EllisLab recently wrote about CodeIgniter 2.0 Baking and some other cool news. So yes, CodeIgniter 2.0 is in development right now and you can follow their process through BitBucket.

I won’t write the new cool features we already can see in CI 2.0-dev, because other great guys already done it, so I collected all the interesting posts from several developers about CI 2.0, enjoy:

Elliot Haughin – CodeIgniter 2.0 In Progress – The Critical Changes, Implications, and What You Should Know

Phil Sturgeon – CodeIgniter 2.0: Everything you need to know

Michael Wales – CodeIgniter 2.0 and Mercurial Transition

Personally, I’m really excited about this. Some of the features are very very important to me [like the packages for example] and I can’t wait for this version release.

CodeIgniter 2.0 Bakin


View Comments

Written by Udi Mosayev

March 13th, 2010 at 3:10 pm

Lessons I’ve learned working with Flash File Uploaders

For the last two weeks I’ve worked with two Flash File Uploaders:

I this post I’ll describe the problems I had with it and how I solved them.

Lesson 1: NO COOKIES

If you add the uploader to authentication based application you might see no files actually got uploaded.

Why is that? your/clients cookies are not recognizable with the Flash Uploader, so the uploader is like every other intruder that need to perform a login.
How I found out? Luckily I used Fiddler2 [more about it later] and the error/debug messages logging system I had helped me to find out what went wrong.
Solution? All modern uploaders support custom post data, so you can use it for session tokens or PHPSSID.

Lesson 2: Upload URL isn’t Found?

On my old development server I had the strangest problem ever – the existing-not-authenticated url that uploads the files was not found by the script.
I’ve activated Fiddler2 and saw that the response headers were 302 – not found. My logging messages showed me that no one accessed the url.

Why is that? In my case the problem was in my old development server provider – they have some mechanism that filters requests for some reason.
How I found out? This is the place to thank Fiddler2 – Fiddler2 is a HTTP monitoring software and FireFox addon that.. monitors HTTP requests. With Fiddler2 I saw the response headers and after few tryouts I’ve got as a response an abuse page of my server provider.
Solution? I contacted my server provider and they did what they had to in order for my uploader to work.

Lesson 3: Don’t be rude to Mac

Meanwhile, I switched the flash uploader and start using SWFUpload which is much much better in my opinion.
My upload script contains photo resizing and uploading to a distant server. Every special event is logged, every suspicious action is logged.
The nature of those flash uploaders is uploading the file, and then they reach 100% – but no Complete event because my script running now the resizing stuff.When the script finished, the uploader moved to the next file in queue, but for Mac users, even after the resizing, the file never got the “Complete” event.

Why is that? As I said, every little even in the upload process is logged, if something bad happens I know how to handle it. I didn’t echo/print any response, because I don’t need to, but Mac have to get some kind of response in order to move on. Its not clear to me why, but that’s the way it works.
How I Found Out?
really, just searched the web.
Solution?
just echo something..it might be useful if you wish to return event to the uploader and let him handle it.


View Comments

Written by Udi Mosayev

February 8th, 2010 at 1:21 am

Developing Content Managment System with CodeIgniter – Part 3

Hi.
Well, As my development process continues I would like to write you about the features and structure of my application now.

I’ve talked about the basics in my previous posts, I covered the structure of my application [modules], I showed you how I extend CI_Controller and CI_Model. Now I want to share with you the which features I have in my application that makes my live easier AND how I extended Controller and Model even more.

Features

    1. I Followed Phil Sturgeon’s How-To article for Support multiple production environments in CodeIgniter. This way I defined what to log and where, in what level, and the url’s of the local server, development server and production server [and Databases too].
    2. I’ve extended CI_Log class so its sending me email if some Error happens in PRODUCTION server [this is the application that the client is using].
    This way I can easily know what went wrong when I get the phone call from my client.
    3. History Class -> I wrote you in my Must have features in your CMS post about System Restore. So I wrote a simple model that has this method in it:
	/**
	 * This method writes data to history.
	 * @param String $table
	 * @param Integer $row
	 * @param String $field
	 * @param String $oldValue
	 * @param String $newValue
	 */
	public function write($table,$row, $field, $newValue) {

		// select only the field I need
		$this->db->select($field);
		// get the right row
		$data = $this->db->get_where($table, array('ID' => $row));
		// take the row and break to array
		$currentState = $data->row_array();
		// store the old value
		$oldValue = $currentState[$field];

		if($oldValue != $newValue) {
			$history = array(
				'TableName' => $table,
				'RowIndex' => $row,
				'FieldName' => $field,
				'OldValue' => $oldValue,
				'NewValue' => $newValue,
				'Created' => time()
			);
			$this->db->insert('history', $history);
			return TRUE;
		} else {
			return FALSE;
		}
	}

*I already see a mistake in this method – I have $this->table property in each model, and I don’t use it here – I write the table name directly in the insert method.*
This method activates before each update() method in my Models. The update() method written once in my MY_Model class, so I don’t really writing data to this “system restore” table myself [by calling this method each time] – everything happens in the background.

Extended CI_Controller

Well, I can’t share with you the whole code [I'm not allowed, I'll share certain methods], But I can write you the properties and methods I have and the purpose of them.

	// Module name. gallery/cart/content/contact/users...
	protected $module;

	// Basic authentication and permission system, UserLevel gets the
	// minimum level needed to enter this controller
	protected $userLevel;

	// The name of the controller
	protected $controllerName;

	public function MY_Controller() {
		parent::Controller();
		if(ENV == 'dev' OR ENV == 'local') $this->output->enable_profiler(TRUE);
		else if(ENV == 'live') $this->output->enable_profiler(FALSE);
		$this->controllerName = get_class($this);
	}

As you can see, If its a development environment I’m enabling the profiler, I use controllerName for better logging [knowing where error happened or any other message level].

I also have 2 methods that are loading views and models:

	/**
	 * This method is a shortcut for loading a view in my controllers.
	 * @param String $name The name of the view I want to load, inside the module folder.
	 * @param Text $content The HTML content I want the view to show.
	 * @param Bool $return Return the view content, or just show it?
	 */
	protected function _view($name, $content, $return = FALSE) {
		return $this->load->view($this->module.'/'.$name, $content, $return);
	}

The reason I did it is that I got tired writing

$this->load->view($this->module.'/viewName', '', TRUE)

And the current method really saves some time.

Extended CI_Model

	// The main table name
	public $table;
	private $modelName;

	public function MY_Model() {
		parent::Model();
		$this->table = '';
		$this->modelName = get_class($this);
	}

	// Log as Error each time none-existing method called.
	public function __call($name, $arguments) {
		$args = implode(',',$arguments);
		log_message('error', $this->modelName.'-> '.$name.'('.$args.') Not exists.');
		return FALSE;
	}

Well, everything is clear here I believe. I think that most of the developers don’t use __call method, but the use I did here is pretty useful.
Each method I have in the models and ofcourse MY_Model using $this->modelName for logging errors – if I didn’t got any $ID for updating some row its highly important for me to know why and where.

Well, I shared with you as much as I could. I don’t know if I’ll write another post in this area, I’ll see how my project goes and if there is something interesting to write about.

I really think I chose the wrong title for this post series :D but that’s ok.

Hope you learned something new, if you have any questions I’ll be happy to answer.


View Comments

Written by Udi Mosayev

January 1st, 2010 at 10:00 pm

Developing Content Managment System With CodeIgniter – Part 2

Hi, if  you haven’t read my previous post, please read it now: Developing Content Management System With CodeIgniter Part 1.

MY_Controller and other extended core libraries

As I told you, I always write my own controllers that extends CI’s Controllers. The method is simple, I write 2-3 Controllers and looking for similarities.

class Add extends Controller {

    public function Add() {
        parent::Controller();
        log_message('debug', 'User / Add Class Initialized.');
    }

    public function index() {
        // Loading the new user form..
    }

    public function process() {
        // Getting the input and activate
    }
}

The example above is a class for creating new user. index() methods loads the view of the new user form, and the process() gets the post data and inserts it to the database.
Controllers like this I have almost in each module I create, so why not writing this MY_Controller class? look:

class MY_Controller extends Controller {
    // The name of the module, User, Catalog, Photo Gallery..
    private $moduleName;

    // Add New Form
    private $addNewView;

    public function MY_Controller() {
        parent::Controller();

    }

    public function index() {
        $content = $this->load->view($this->moduleName.'/'.$this->addNewView, '', TRUE);

        // As I told you before, I create a TPL library that handles all my template stuff.
        $this->tpl->createTemplate($content);
    }

    public function process() {
        // This is the only function I write for each controller like this,
        // this method validates the data and activates the proper model
        // to insert this data in DB.
    }
}

So my new User Add class will look like this:

class Add extends MY_Controller {
    // The name of the module, User, Catalog, Photo Gallery..
    private $moduleName;

    // Add New Form
    private $addNewView;

    public function Add() {
        parent::MY_Controller();
        // Add New Form - the view I have in "views/user/" -
        // remember the module method from the last article?
        $this->addNewView = 'add';

        // This means that the Add.php class is sitting in controllers/user folder.
        $this->moduleName = 'user';
    }

// Because I already implemented index() method in MY_Controller class,
// All I left to do is write my own process() method that is unique for each controller.

    public function process() {
        // In my view, all the inputs of my form named data[xxx] -
        // for example: data[FirstName] and data[LastName], so I grab them as an array.
        $data = $this->input->post('data');

        // Some validation and manipulation..
        $this->user_model->add($data);

        // some more stuff..
    }
}

Conclusion

This concept in great for models too, if you’re not using ORM, you can create basic save() & deleted() methods in your MY_Model class.
The only thing you should do to see if you need this: look for similar code between controllers and models, DO NOT WRITE THE SAME CODE TWICE.

I hope my next part will come faster then this one.


View Comments

Written by Udi Mosayev

December 19th, 2009 at 6:28 pm