diff --git a/src/sys/miniMVC.php b/src/sys/miniMVC.php index cf7815e..4446beb 100644 --- a/src/sys/miniMVC.php +++ b/src/sys/miniMVC.php @@ -9,151 +9,57 @@ * @link https://github.com/timw4mail/miniMVC * @license http://philsturgeon.co.uk/code/dbad-license */ - + // -------------------------------------------------------------------------- - + /** - * Extend PHP's PDO class to add some more functionality - * - * @extends PDO + * Parent class of base class, contains much of the magic */ -class db extends PDO { +class JSObject{ - private $statement; - private static $instance = array(); - - public static function &get_instance($dbname="default", $options=array()) - { - if ( ! isset(self::$instance[$dbname])) - { - //echo 'Creating new instance of db class.'; - self::$instance[$dbname] = self::_get_conf($dbname, $options); - } - - return self::$instance[$dbname]; - } - - // -------------------------------------------------------------------------- - /** - * Makes DSN from config file, and creates database object - * - * @param string $dbname - * @param array $options - * @return db object - */ - private static function _get_conf($dbname="default", $options=array()) - { - // Include the database config file - require(APP_PATH.'config/db.php'); - - // Get the correct database in the config file - if(is_like_array($db_conf[$dbname])) - { - // Array manipulation is too verbose - extract($db_conf[$dbname]); - } - else - { - // Apparently the database doesn't exist - $this->get_last_error(); - trigger_error("Database does not exist", E_USER_ERROR); - die(); - } - - // Sqlite doesn't use dbname param - $dsn = (stripos($type, "sqlite") === FALSE) ? "{$type}:dbname={$db}" : "{$type}:{$db}"; - - // Set hostname if applicable - if(isset($host)) - { - $dsn .= ($host !== "") ? ";host={$host}" : ""; - } - - // Set port if applicable - if(isset($port)) - { - $dsn .= ($port !== "") ? ";port={$port}" : ""; - } - - $user = ( ! empty($user)) ? $user : null; - $pass = ( ! empty($pass)) ? $pass : null; - - // Pre-set the error mode - $opts = array( - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - ); - - $options = $opts + $options; - - return new db($dsn, $user, $pass, $options); - } - - // -------------------------------------------------------------------------- - - /** - * Constructor to override PDO constructor - Quercus doesn't seem to override - * the parent constructor unless the arguments match. - * - * @param string $dsn - * @param string $user - * @param string $pass - * @param array $options - */ - function __construct($dsn, $user, $pass, $options) - { - // Let's try connecting now! - parent::__construct($dsn, $user, $pass, $options); - - } - - // -------------------------------------------------------------------------- - - /** - * Magic function called when cloning an object - */ - public function __clone() - { - trigger_error('Clone is not allowed.', E_USER_ERROR); - } - - // -------------------------------------------------------------------------- + * Constructor for creating the objects + */ + function __construct($members = array()) + { + // Add the passed parameters to the object + foreach($members as $name => $value) + { + $this->$name = $value; + } + } /** - * PHP magic method to facilitate dynamic methods - * - * @param string $name - * @param array $args - */ - function __call($name, $args) - { - if(is_callable($this->$name)) - { - //Add $this to the beginning of the args array - array_unshift($args, $this); - - //Call the dynamic function - return call_user_func_array($this->$name, $args); - } - } - - // -------------------------------------------------------------------------- - - /** - * PHP magic methods to call non-static methods statically - * - * @param string $name - * @param array $args - */ - public static function __callStatic($name, $args) - { - if(is_callable(parent::$name)) - { - return call_user_func_array(parent::$name, $args); - } - } - - // -------------------------------------------------------------------------- + * PHP magic method to facilitate dynamic methods + * + * @param string $name + * @param array $args + */ + function __call($name, $args) + { + if(is_callable($this->$name)) + { + //Add $this object to args + array_push($args, $this); + + //Call the dynamic function + return call_user_func_array($this->$name, $args); + } + } + + /** + * PHP magic method to facilitate dynamically set static methods + * + * @param string $name + * @param array $args + */ + public static function __callStatic($name, $args) + { + if(is_callable(self::$name)) + { + return call_user_func_array(self::$name, $args); + } + } /** * Prints out the contents of the object when used as a string @@ -202,85 +108,334 @@ class db extends PDO { } } - // -------------------------------------------------------------------------- - /** - * Simplifies prepared statements for database queries + * PHP magic method to facilitate dynamic class loading * - * @param string $sql - * @param array $data - * @return mixed PDOStatement / FALSE + * @param string $name */ - function prepare_query($sql, $data) - { - // Prepare the sql - $query = $this->prepare($sql); - - if( ! is_like_array($query)) + function __get($name) + { + $path = SYS_PATH."{$name}.php"; + $class = "{$name}"; + + if(class_exists($class, FALSE)) { - $this->get_last_error(); - return FALSE; - } - - // Set the statement in the class variable for easy later access - $this->statement =& $query; - - - if( ! is_like_array($data)) - { - trigger_error("Invalid data argument"); - return FALSE; - } - - // Bind the parameters - foreach($data as $k => $value) - { - $res = $query->bindValue($k, $value); - - if( ! $res) + if( ! isset($this->$name)) { - trigger_error("Parameter not successfully bound"); - return FALSE; + $this->$name = new $class; + return; } } - - return $query; - + + load_file($name, 'sys'); + + if(class_exists($class, FALSE)) + { + $this->$name = new $class; + } } - // -------------------------------------------------------------------------- - /** - * Returns the last error from the database - * - * @return string + * PHP magic method that is called when an object is treated as a function */ - function get_last_error() + public static function __invoke() { - $error = array(); - - if(isset($this->statement)) - { - $error = $this->statement->errorInfo(); - } - else - { - $error = $this->errorInfo(); - } - - $code = $error[0]; - $driver_code = $error[1]; - $message = $error[2]; - - // Contain the content for buffering - ob_start(); - - include(APP_PATH.'/errors/error_db.php'); - - $buffer = ob_get_contents(); - ob_end_clean(); - echo $buffer; + $class = __CLASS__; + return new $class; } } -// End of db.php \ No newline at end of file +// -------------------------------------------------------------------------- + +/** + * Base class for the framework + * + * @extends JSObject + */ +class miniMVC extends JSObject{ + + private static $instance; + private static $count; + + /** + * Constructor - Any classes loaded here become subclasses of miniMVC + */ + function __construct() + { + self::$instance =& $this; + } + + /** + * PHP magic method to facilitate dynamic methods + * + * @param string $name + * @param array $args + */ + function __call($name, $args) + { + if(is_callable(self::$instance->$name)) + { + //Add $this object to args + array_push($args, $this); + + //Call the dynamic function + return call_user_func_array(self::$instance->$name, $args); + } + } + + /** + * Magic function called when cloning an object + */ + public function __clone() + { + trigger_error('Clone is not allowed.', E_USER_ERROR); + } + + /** + * PHP magic method that is called when an object is treated as a function + */ + public static function __invoke() + { + return self::get_instance(); + } + + /** + * Singleton getter function + * + * @return miniMVC object + */ + public static function &get_instance() + { + if( ! isset(self::$count)) + { + self::$count = 0; + } + + if ( ! isset(self::$instance)) + { + self::$count++; + self::$instance = new miniMVC; + } + + $self =& self::$instance; + + return $self; + } + + /** + * Method to load classes into the singleton + * + * @param string $name + */ + function load_class($name, $type='class') + { + switch($type) + { + default: + $path = APP_PATH . "classes/{$name}.php"; + break; + + case "sys": + $path = SYS_PATH . "{$name}.php"; + break; + } + + // In a subdirectory? No problem + if(strpos("/", $name) !== FALSE) + { + $n = explode("/", $name); + $name = $n[count($n) -1]; + } + + $class = "{$name}"; + + if(class_exists($class, FALSE)) + { + if ( ! isset($this->$name)) + { + $this->$name = new $class; + return; + } + } + + if(is_file($path)) + { + require_once($path); + + if(class_exists($class, FALSE)) + { + if ( ! isset($this->$name)) + { + $this->$name = new $class; + return; + } + } + } + } + + /** + * Convenience function to remove an object from the singleton + * + * @param string $name + */ + function unload($name) + { + if(isset($this->$name)) + { + unset($this->$name); + } + } + + /** + * Convenience function to load config files + * + * @param string $name + */ + function load_config($name) + { + $path = APP_PATH . "config/{$name}.php"; + + if(is_file($path)) + { + require_once($path); + } + } + +} + +// -------------------------------------------------------------------------- + +/** + * Base Controller Class + * + * @extends miniMVC + */ +class MM_Controller extends miniMVC { + + public $output, $page; + + function __construct() + { + parent::__construct(); + + $this->output = new Output(); + $this->page = new Page(); + } + + /** + * Function for loading a model into the current class + * + * @param string $file + */ + function load_model($file, $args=array()) + { + $path = ""; + + // The module is the lower of the class name + // need to figure out a way to allow multiple controllers + // in one module + $module = strtolower(get_class($this)); + + $not_modules = array('miniMVC', 'page', 'db', 'output'); + + // If it's a module, look in the module view folder + if( ! in_array($module, $not_modules)) + { + $path = MOD_PATH . "{$module}/models/{$file}.php"; + } + + if(is_file($path)) + { + require_once($path); + } + + if( ! empty($args)) + { + + $this->$file = new $file($args); + } + else + { + $this->$file = new $file; + } + } + + /** + * Function for loading a view + * + * @param string $file + * @param array $data + * @return mixed + */ + function load_view($file, $data, $return=FALSE) + { + $path = ""; + + // The module is the lower of the class name + // need to figure out a way to allow multiple controllers + // in one module + $module = strtolower(get_class($this)); + + $not_modules = array('miniMVC', 'page', 'db', 'output'); + + // If it's a module, look in the module view folder + if( ! in_array($module, $not_modules)) + { + $path = MOD_PATH . "{$module}/views/{$file}.php"; + } + + // If it's not a module, or doesn't exist in the module view folder + // look in the app view folder + if( ! is_file($path)) + { + $path = APP_PATH . "views/{$file}.php"; + } + + // Contain the content for buffering + ob_start(); + + // Extract the data array + extract($data); + + // Include the file + include($path); + + $buffer = ob_get_contents(); + ob_end_clean(); + + if($return == TRUE) + { + return $buffer; + } + else + { + $this->output->append_output($buffer); + } + + } +} + +// -------------------------------------------------------------------------- + +/** + * Base Model Class + * + * @extends miniMVC + */ +class MM_Model extends miniMVC { + + function __construct() + { + parent::__construct(); + } + + /** + * Adds the database class to the current model class + */ + function load_db($name="default") + { + $this->db =& db::get_instance($name); + } + +} +// End of miniMVC.php \ No newline at end of file