Alpha 2 version Core Changes:
- deprecated database pattern rewrited new loader::database() functionality
- added get_config, register_base, register, register_static functions to common.php
- added routes.php (config route file) to /application/config/ folder
- added new functionality a Library Class like Model
- added /extends folder and Ob_user.php (super static user class)
- added Ob.php and SSC (super static class) Class.
- Model, Controller and Library class extended to ob class.
- added asn_to_libraries(); func to loader::library()
- loader extended to user class , added loader::pear(); function.
- added show404(); error function to Errors.php
- added Php5 OB_Router, OB_Config and OB_URI classes that derived from CI Libraries.
- changed $this->db->prepare function as $this->db->prep();
Directory structure:
Understanding MVC-SSC:
SSC (Super Static Controllers) pattern a new term that i found in the php world.Look at (http://develturk.com/2009/09/25/new-term-in-the-php-world-introducing-new-php-mvc-ssc-pattern/)
We have three main classes; Controller , Model and Library which extends to Ob class.ob , user, loader and SSC classes means a big php SSC scope, we can call none static functions ($this->class->method) inside from static functions (class::method) using these classes.
Look at controller php it extends to ob class.
<?php
if( !defined('BASE') ) exit('Access Denied!');
/**
* Obullo Framework (c) 2009.
*
* PHP5 MVC-min Framework software for PHP 5.2.4 or newer
* Derived from Code Igniter
*
* @package obullo
* @filename base/libraries/Controller.php
* @author obullo.com
* @copyright Ersin Güvenç (c) 2009.
* @since Version 1.0
* @filesource
* @license
*/
/**
* Obullo Controller
*
* @package Obullo
* @subpackage Base.libraries
* @category Libraries
* @version 1.0
* @version 1.1 renamed Register as base_register
* @version 1.2 added extend to ob
*/
Class Controller extends ob
{
function __construct()
{
$this->ob_init();
parent::__construct();
}
function ob_init()
{
// Load Automatically None Static Classes.
$Classes = array(
'config' => 'Config',
'input' => 'Input',
'uri' => 'URI',
);
foreach ($Classes as $public_var => $Class)
{
$this->$public_var = base_register($Class);
}
// from now on we can none static classes like this
// like this $this->class->function();
} //end function.
} //end class.
?>
Look at model class also it extends to ob class.
<?php
if( !defined('BASE') ) exit('Access Denied!');
/**
* Obullo Framework (c) 2009.
*
* PHP5 MVC Framework software for PHP 5.2.4 or newer
*
* @package Obullo
* @author Obullo.com
* @subpackage Base.libraries
* @copyright Copyright (c) 2009 Ersin Güvenç.
* @license http://www.opensource.org/licenses/gpl-3.0.html GPL
* @since Version 1.0 @alpha
* @filesource
*/
/**
* Model Class.
*
* Main model class.
*
* @package Obullo
* @subpackage Base.libraries
* @category Libraries
* @version 0.1
* @version 0.2 added extend to ob
*/
Class Model extends ob {
public $myself; // called model
function __construct()
{
// assign obullo libraries to all called models
$this->_asn_lib();
// this is just called model name
$this->myself = ucfirst(get_class($this));
}
function _asn_lib()
{
$OB = ob::instance();
// declared objects
$dec_ob = array_keys(get_object_vars($OB));
foreach ($dec_ob as $key)
{
if( ! isset($this->$key) AND $key != $this->myself) // this is wrong
{
$this->$key = $OB->$key;
}
}
} // end func.
}
// End Model Class
And open base/libraries/Ob.php we extends to new SSC class, this class our super static controller and we define every system functions here.Ssc makes easier our life because of we don’t need write every time like this codes: $this->input->post()
look at SSC (Ob.php)
<?php
if( !defined('BASE') ) exit('Access Denied!');
/**
* Obullo Framework (c) 2009.
*
* PHP5 MVC-min Framework software for PHP 5.2.4 or newer
* Derived from Code Igniter
*
* @package obullo
* @filename base/libraries/Controller.php
* @author obullo.com
* @copyright Ersin Güvenç (c) 2009.
* @since Version 1.0
* @filesource
* @license
*/
/**
* o SSC Pattern (c) 2009 Ersin Güvenç
* o We use Super Static Controllers
* o for prevent long writing ($this->navigation->nav_level1())
* o we just write like this user::nav_level1();
*/
/**
* Obullo Super Static Controller (SSC)
*
* We put all static main codes here
* Like cookie , session, register
* Goal of the SSC to get all static functions
* like this ob::instance(), ob::session_set(),
* ob::cookie_get(),ob::dbconnect() you can
* also use $this var inside from static
* functions.
*
* @version 0.1
* @version 0.2 added core functions like ob::register
* @version 0.3 moved some func to common.php like
* ob::register functions
*/
Class SSC extends loader
{
/**
* Gets a config item
*
* @access public
* @return mixed
*/
public function config_item($item)
{
static $config_item = array();
if ( ! isset($config_item[$item]))
{
$config =& get_config();
if ( ! isset($config[$item]))
{
return FALSE;
}
$config_item[$item] = $config[$item];
}
return $config_item[$item];
}
// get current database settings
static function config_db_item(){}
static function config_set(){}
// $this->config->site_url();
static function config_url(){}
static function config_baseurl(){}
// $this->config->system_url();
static function config_system(){}
/**
* ob::input_post();
*
* @author Ersin Güvenç
* @param mixed $key form field
* @version 1.0
* @return void
*/
public function post($key)
{
return $this->input->post($key);
}
public function get($key)
{
return $this->input->get($key);
}
// identical CI $this->input->get_both
static function both($key,$bool){}
// identical CI $this->input->get_post
static function xss(){}
/**
* ob::input_ip();
* Validate ip address
* @param mixed $key ip addres
* @version 1.0
* @return void
*/
public function ip()
{
return $this->input->ip();
}
public function input_server($key){}
public function user_agent(){echo 'ok';}
// sessions
public function session_set($key,$array = NULL)
{
// kullanıcı ilan edicek
// OB_Session::session_set sadece bunu yaz.
}
public function session_set_userdata($array = NULL){}
public function session_userdata($array = NULL){}
public function session_flashdata($array = NULL){}
// cookies..
public function cookie_get(){}
public function cookie_set(){}
// language class
// otomatik yada kullanıcı tarafından yukleniyor.
// load library ile
public function lang(){}
// redirect function
public function redirect(){}
} // end ssc class.
Class OBException extends CommonException {}
/**
* Obullo Super Object (c) 2009
*
* @version 0.1
* @version 0.2 added core functions like ob::register
* @version 0.3 added extending to SSC, moved register
* functions to common.php
*/
Class ob extends SSC
{
/**
* Obullo instance
*
* @var object
*/
private static $instance;
/**
* Construct func.
* @return void
*/
public function __construct()
{
self::$instance = $this;
parent::__construct();
}
/**
* ob::instance();
*
* Get the Obullo Super Object Every Where
*
* @author Ersin Güvenç
* @version 1.0
* @version 1.1 getInstance renamed and moved into ob class
* @return object
*/
static function instance()
{
return self::$instance;
}
/**
* ob::dbconnect();
* Factory and Connect to database driver
* Get pdo database handle
*
* @author Ersin Güvenç
* @version 1.0
* @version 1.1 moved into ob class
* @return object - pdo database handle
*/
static function dbconnect()
{
return OB_DBFactory::Connect();
}
} // end class.
?>
Forexample we define $this->input->post() function into SSC class and we can call it as ob::post(); instead of $this->input->post() code.This functionality especially for developers but we have a Global user class that the loader extends to it, and this means users also can define their custom static functions inside to user super static class.
Normally in Code Igniter you must write below the codes for every controllers.
<?php
class Test extends Controller {
var $base;
var $base_img;
var $css;
var $css_print;
var $password_salt;
function Test() {
parent::Controller();
$this->base = $this->config->item('base_url');
$this->base_img = $this->config->item('base_image_url');
$this->css = $this->config->item('css');
$this->css_print = $this->config->item('css_print');
}
?>
But in obullo you don’t need write them everytime, SSC Pattern makes your life to easier.You will just write parent::__user(); (top constructor for every controllers)
Class Test extends Controller
{
function __construct()
{
parent::__construct();
// top constructor for every controllers.
parent::__user();
}
}
Look at Global user class /extends/Ob_user.php (user class).
Users put their common special functions here and “user” functions works everytime for every controller..
<?php
/**
* OBULLO USER DEFINED COMMON FUNCTIONS
*
* o SSC Pattern (c) 2009 Ersin Güvenç
* o We use Super Static Controllers
* o for prevent long writing ($this->navigation->nav_level1())
* o we just write user::nav_level1();
*
* Just Put your common special functions here !!
* "user" functions works everytime for every controller
* So you should put your common functions in
* your application which interested in like
* this categories..
*
* o site navigation menu func.,
* o authentication functions
* o module functions
* o
*
* it will work like this ob_user::yourfunction
*/
Class user
{
public $base_url = 'http://localhost/obullo/';
public $base_img;
public $base_css;
/**
* parent::__user();
* User common __construct for all controllers
*/
function __user()
{
// ALSO YOU CAN load your static classes like this !
// loader::library('mystatic_class',true);
// loader::library('mystatic_class2',true);
loader::library('navigation');
//loader::library('session');
echo 'this my top __Constructor for all controllers ! It comes from /application/extends/Ob_user.php<br />';
}
// SSC Pattern (c) 2009 Ersin Güvenç
// We use super static controllers
// for prevent long writing ($this->navigation->nav_level1())
// we just write user::nav_level1();
public function nav_level1()
{
return $this->navigation->nav_level1().'<br />';
}
public function nav_level2()
{
return $this->navigation->nav_level2().'<br />';
}
} // end class.
?>
New Library functionality of Obullo:
I added a Library functionality to obullo like Model class.This means extending to Library class again makes your life to easier. You don’t need to write get_instance() function (in CI) or ob::instance() (in Obullo) for every user Library files.Just you will extend to main Library class and you will write parent::_construct() like a model.
You can also call static functions from the library files.Like SSC class functions ob::ip(); or Global user class functions user::nav_level1();
Look at the example library file.(application/libraries/mylibrary.php)
<?php
Class mylibrary extends Library
{
function __construct()
{
parent::__construct();
loader::database();
// you don't need it if you declare it before in test controller
// parent::__user();
}
function test_ssc()
{
echo '<br />'.$this->base_url.' <-- this comes from ob_user.php<br />';
// I can use db class directly from my lib.
// WITHOUT ci = &get_instance() func unlike CI
echo '<br /><b>i can use db functions directly from library.(Without get_instance() func.)</b><br />';
$this->db->drivers();
echo '<br /><b>i can use static functions from library:</b> '.ob::ip().'<br />';
// My Super Static Class Functions
// Look at application/extends/Ob_user.php
user::nav_level1();
echo '<br />';
user::nav_level2();
}
}
?>
Integrating Code Igniter Router and URI classes to Obullo:
We need to a router functionality for our framework.I used CI libraries and i just convert php4 functions to php5.
Like this
Class RouterException extends CommonException {}
/**
* Router Class
* Derived from Code Igniter library
* Parses URIs and determines routing
*
* @package Obullo
* @subpackage Libraries
* @category URI
* @author Code Igniter - ExpressionEngine Dev Team
* @author Ersin Güvenç
* @link
*/
class OB_Router {
public $config;
public $routes = array();
public $error_routes = array();
public $class = '';
public $method = 'index';
public $directory = '';
public $uri_protocol = 'auto';
public $default_controller;
/**
* Constructor
*
* Runs the route mapping function.
*/
function __construct()
{
$this->config = base_register('Config');
$this->uri = base_register('URI');
$this->_set_routing();
// log_message('debug', "Router Class Initialized");
}
.
.
.
.
Now we can integrate Router and URI classes into index.php file.
index.php
<?php
/**
* Obullo Framework (c) 2009.
*
* PHP5 MVC-min Software for PHP 5.2.4 or newer
* Derived from Code Igniter.
*
* @package obullo
* @filesource index.php
* @author obullo.com
* @copyright Ersin Güvenç (c) 2009.
* @since Version 1.0 @alpha
* @license http://www.opensource.org/licenses/gpl-3.0.html GPL
*/
/* ---------------------------------------------------------------------------*/
header('Content-type: text/html;charset=UTF-8');
Class CommonException extends Exception {}
// Base paths
define('DS',DIRECTORY_SEPARATOR);
define('BASE', 'base'.DS);
define('APP', 'application'.DS);
define('EXT', '.php');
define('MODEL', 'application'.DS.'controllers'.DS);
define('VIEW', 'application'.DS.'controllers'.DS);
define('CONTROLLER', 'application'.DS.'controllers'.DS);
define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
require (BASE.'libraries'.DS.'Registry'.EXT);
require (BASE.'libraries'.DS.'Library_factory'.EXT);
require (BASE.'Common'.EXT);
require (BASE.'libraries'.DS.'Errors'.EXT);
$Config = base_register('Config');
$Uri = base_register('URI');
$Router = base_register('Router');
//echo 'class: '.$Router->fetch_class().'<br />';
//echo 'method: '.$Router->fetch_method(); exit;
$GLOBALS['c'] = $Router->fetch_class(); // Get requested controller
$GLOBALS['m'] = $Router->fetch_method(); // Get requested method
// Check the controller exists or not
if ( ! file_exists(APP.'controllers'.DS.$GLOBALS['c'].DS.$GLOBALS['c'].EXT))
{
new CommonException('Unable to load your default controller.
Please make sure the controller specified in your Routes.php file is valid.');
}
require (BASE.'libraries'.DS.'Loader'.EXT);
require (BASE.'libraries'.DS.'Ob'.EXT);
require (BASE.'libraries'.DS.'Controller'.EXT);
require (BASE.'libraries'.DS.'Library'.EXT);
require (BASE.'libraries'.DS.'Model'.EXT);
// call the controller.
require (CONTROLLER.$GLOBALS['c'].DS.$GLOBALS['c'].EXT);
if ( ! class_exists($GLOBALS['c'])
OR $GLOBALS['m'] == 'controller'
OR strncmp($GLOBALS['m'], '_', 1) == 0
OR in_array(strtolower($GLOBALS['m']), array_map('strtolower', get_class_methods('Controller')))
)
{
show_404("{$GLOBALS['c']}/{$GLOBALS['m']}");
}
// If Everyting ok !
$OB = new $GLOBALS['c']();
// Check method exist or not
if ( ! in_array(strtolower($GLOBALS['m']), array_map('strtolower', get_class_methods($OB))))
{
show_404("{$GLOBALS['c']}/{$GLOBALS['m']}");
}
// Call the requested method.
// Any URI segments present (besides the class/function) will be passed to the method for convenience
call_user_func_array(array($OB, $GLOBALS['m']), array_slice($Uri->rsegments, 2));
?>
I added router class and methods inside to GLOBAL variables because of we use current controller name and method in everywhere.Especially loader class use $GLOBALS['c'] (controller name) in Loader.php library and model functions.
<?php $GLOBALS['c'] = $Router->fetch_class(); // Get requested controller $GLOBALS['m'] = $Router->fetch_method(); // Get requested method ?>
Look at also Loader.php
Run the index.php (test controller.)
Click to Link !
Integrated Router Class to Obullo.
Download Obullo Framework 1.0 @alpha 2



Absolute fantastic work. I’m a big fan of your MVC Framework series and the SSC is a really interesting thing. I’m looking forward to the next part(s).
Keep going
I found this series today and I must say - it’s very interesting and I hope you’ll continue to work on this
Thanks man!
Good job! keep working
What’s about Part 4? What can I expect?
A session and authentification class would be very nice. I wonder, in part 2 there already was a session class!?
im working on obullo style directory routing
CI directory route: /class/method/arguments…
Obullo will be like this: /directory/class/method/arguments..
and about part2’s session class it was just an example and it was very basic.I will integrate CI session class to Obullo because of its very secure.
So part 4 subjects:
- Advanced Routing
- Session Class Integration
- Calling session functions with SSC
Sexy, you kicking ass. Very nice lightweight framework taking advantage of new methods
I can’t wait to read part4
you should wait it i will also tell integrating CI active record with PDO
Thanks for releasing your framework..
Codeigniter is great Framework but not used the power of php5 ^_^
Download and test it