Welcome Guest, Not a member yet? Register   Sign In
Object Programming with CodeIgniter
#1
Rainbow 

Hey everybody,

I was wondering how to deal with plain PHP object and CodeIgniter framework, so here is what I did first :

I created a PHP Class in libraries folder for my object, "User" in that case, with accessors. So far everything was ok with my Class, I tested it in a separate test environement without CI. Then I tried to integrate it to my project so in my controller I included with a

PHP Code:
$this->load->library("User"); 

But then I was only able to have one instance of User at a time ! That's fine for a User I think but I will have to deal with a lot of instances of some objects and so I "tricked CI" by including in the controller  Rolleyes

PHP Code:
require(....); 

And that way I was able to have multiple User objects but then I realized that I wanted to use my simple CRUD overriding of CI_Model into my User Class, that way I would be able to make the code for a user authentication very small in controller and easy to understand and also to maintain (yes, it's becoming a huge crap in my controllers, also I splitted a lot my operations into small functions, it's harder and harder to make modifications and most of time it breaks something else when I add/mod something). So, I thinked about it and told myself

Quote:Ok, think about your classes, an Object here represents one or more entries in DB, so It must be between the Model and the Controller.

That way I ended with a User_model but had the same problem with the Loader Class because only one instance was "allowed"... So I made a User Class which extends a User_Model Class which extends MY_Model Class which extends CI_Model Class............... Tongue

I don't explain you what CI_Model does... MY_Model :

PHP Code:
<?php defined('BASEPATH') OR exit('No direct script access allowed');

 
   class MY_Model extends CI_Model {
 
       private $table;

 
       protected function create(__________) {
 
           ____________
            ____________
            ____________
        
}

 
       protected function read(__________) {
 
           ____________
            ____________
            ____________
        
}

 
       protected function update(__________) {
 
           ____________
            ____________
            ____________
        
}

 
       protected function delete(__________) {
 
           ____________
            ____________
            ____________
        
}

 
       protected function count(__________) {
 
           ____________
            ____________
            ____________
        
}

 
       protected function getTable() {
 
           return $this->table;
 
       }

 
       protected function setTable($table) {
 
           $this->table $table;

 
           return $this;
 
       }
 
   

User_model

PHP Code:
<?php defined('BASEPATH') OR exit('No direct script access allowed');

 
   class User_model extends MY_Model {
 
       public function __construct() {
 
           parent::__construct();

 
           if(!class_exists("User")) {
 
               require(APPPATH.'/models/User.php');
 
           }

 
           $this->setTable("users");
 
       }
 
   

User

PHP Code:
<?php

    class User 
extends User_model {
 
       /**
         * Fields
         */
 
       ________
        ________
        ________

        function __construct
() {
 
           parent::__construct();
 
       }

 
       /**
         * Accessors
         */
 
       ________
        ________
        ________

        
/**
         * Some usefull functions
         */
 
       public function doLogin($login$password) {
 
           ______________
            ______________
        
}

 
       private function authenticate($query$password) {
 
           ______________
            ______________
        
}

 
       public function getFromSession() {
 
           ______________
            ______________
        
}

 
       { ......... }
 
   

By the way, I can use $this to call CI Classes like session, db, and others as well as MY_Model functions. I also can change the table while running with the protected accessors for $table field of MY_Model.

Then my login function is a lot easier to understand :

PHP Code:
public function login() {
    
// Get POST data and check validity
    
$login $this->input->post("login");
    
$password $this->input->post("password");
    if(!empty(
$login) && !empty($password)) {
        try {
            
$user = new User();
            
$user->doLogin($login$password);
            
$this->layout->view("authentication", array(
                                
"title" => "Logged in",
                                
"message" => var_dump($user->getFromSession()),
                                
"state" => ""
            
));
        } catch(
Exception $e) {
            switch(
$e->getCode()) {
                case 
0:
                case 
1:
                    
$this->layout->view("authentication", array(
                                        
"title" => "Something went wrong...",
                                        
"message" => "Please check your credentials",
                                        
"state" => "error"
                    
));
                    break;
                case 
2:
                    
$this->layout->view("authentication", array(
                                        
"title" => "Something went wrong...",
                                        
"message" => "Contact data error",
                                        
"state" => "error"
                    
));
                    break;
            }
        }
    } else {
        
$this->layout->view("authentication", array("title" => "Credentials not provided""message" => "Please provide both login and password""state" => "error"));
    }


SO !

Everything works very well now and I love to abstract a Web Application, objects are so cool Cool  Big Grin
I was just wondering if any of you works with your own-baked Objects. If you are, please share the stuff !

And also, if anyone has anything to say about my approach : tell me, I wan't to here your thoughts about this way of working !

Thanks to read Wink
Reply
#2

Greate tell me more.. And what is the library you used in $this->layout ???? I am searching template library
Reply
#3

(04-28-2015, 12:57 AM)Vimal Wrote: Greate tell me more.. And what is the library you used in $this->layout ???? I am searching template library

Concerning the Layout it's a library which is auto-loaded and working with an asset helper (also auto-loaded) and layout views.

Layout Class (in application/libraries folder)

PHP Code:
<?php defined('BASEPATH') OR exit('No direct script access allowed');

    class 
Layout {
        private 
$CI;
        private 
$data = array();
        private 
$layout "default";

        public function 
__construct() {
            
$this->CI =& get_instance();
            
$this->data["output"] = "";
            
$this->data["title"] = "Your title here";
            
$this->data["charset"] = $this->CI->config->item("charset");
            
$this->data["css"] = array("font-awesome.css""foundation.css""toast.css");
            
$this->data["js"] = array("modernizr.js""jquery-1.11.2.js""foundation.min.js""toast.js""launchFoundation.js");
        }

        public function 
view($name$data = array()) {
            
$this->data["output"] .= $this->CI->load->view($name$datatrue);
            
$this->CI->load->view("layouts/".$this->layout$this->data);
        }

        public function 
setTitle($title) {
            if(!empty(
$title) && is_string($title)) {
                
$this->data["title"] = $title." - OGMA";

                return 
true;
            }

            return 
false;
        }

        public function 
setLayout($layout) {
            if(!empty(
$layout) && file_exists(APPPATH.'views/layouts/'.$layout.'.php')) {
                
$this->layout $layout;

                return 
true;
            }

            return 
false;
        }

        public function 
setMenu($menu) {
            if(!empty(
$menu) && is_string($menu)) {
                
$this->data["menu"] = $menu;

                return 
true;
            }

            return 
false;
        }

        public function 
addCSS($name) {
            if(!empty(
$name) && file_exists(css_path().$name.".css")) {
                
$this->data["css"][] = $name.".css";

                return 
true;
            }

            return 
false;
        }

        public function 
addJS($name) {
            if(!empty(
$name) && is_string($name) && file_exists(js_path().$name.".js")) {
                
$this->data["js"][] = $name.".js";

                return 
true;
            }

            return 
false;
        }
    } 

Asset Helper

Default Layout View (in application/views/layouts folder, you have to create the layouts one)

PHP Code:
<!doctype html>
<
html class="no-js" lang="en">
    <
head>
        <
meta charset="<?= $charset; ?>" />
        <
meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <
title><?= $title?></title>
        <?php
            
foreach($css as $stylesheet) {
                echo 
css($stylesheet);
            }
        
?>
    </head>
    <body>
        <nav>
            <menu>
                <?= img("logo-small.png", array("alt" => "Logo""class" => "logo")); ?>
                <span class="brand">Brand <small>v1</small></span>
                <?= $menu?>
            </menu>
        </nav>
        <main>
            <?= $output ?>
        </main>
        <?php
            
foreach($js as $script) {
                echo 
js($script);
            }
        
?>
    </body>
</html> 

Then you are free to add for example a menuMaker like I did (it simply use a config array and build all links with the makeMenu() function) or whatever you think would be useful !

I took the Layout Class from the internet but can't manage to find it again so sorry for no credits...
Reply
#4

Sounds like you came up with a pretty good solution in the end. Smile

I have become a huge fan of Composer. To handle the situations like yours, I would enable Composer in CodeIgniter's config file

Code:
$config['composer_autoload'] = TRUE;[/url]

Then, I would edit the composer.json file to create autoloading for my application as a whole. Sometimes, I will point this to the default 'application' folder. Other times, I would point this a separate folder. I guess it depends on what I think the app will need and my mood that day :) Assuming we're using the default application folder, I would modify the composer.json file like this:

[code]
"autoload": {
       "psr-4": {
           "App\\": "application/"
       }
   },

Then, I would make that User class, still located in application/libraries, to have a namespace of App\Libraries.

Code:
<?php namespace App\Libraries;

class User  {
   protected $model;

   public function __construct( App\Models\User_model $model)
   {
       $this->model = $model;
   }
}

Then, in your other classes all you have to do is create a new User object.

Code:
$user = new App\Libraries\User( $this->user_model );

Something like that anyway. I'm still revising my tasks to be easier for testing, but I believe that would all work. While I probably went overboard there, hopefully you see the main point of using Composer as an autoloader. Smile[/code]
Reply
#5

Excellent Idea about layout.. Let me think about it.. Thanks bro..
Reply




Theme © iAndrew 2016 - Forum software by © MyBB