diff --git a/.gitignore b/.gitignore index f185c72..5ab4d9c 100755 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ Desktop.ini *.log Uploads Storage +Config +!Config/Sample.*.php diff --git a/Bootstrap.php b/Bootstrap.php old mode 100755 new mode 100644 index 40116dc..91f54b9 --- a/Bootstrap.php +++ b/Bootstrap.php @@ -1,16 +1,4 @@ events as $event => $class) -{ - event($event, NULL, $class); -} +// Load the common functions (used next) +require(SP . 'MicroMVC.php'); /* -if(preg_match_all('/[\-a-z]{2,}/i', getenv('HTTP_ACCEPT_LANGUAGE'), $locales)) -{ - $locales = $locales[0]; -} -*/ + * Default Locale Settings + */ // Get locale from user agent if(isset($_COOKIE['lang'])) { - $preference = $_COOKIE['lang']; + $preference = (string) $_COOKIE['lang']; } else { @@ -80,7 +59,5 @@ // multibyte encoding mb_internal_encoding('UTF-8'); -// Enable global error handling -set_error_handler(array('\Core\Error', 'handler')); -register_shutdown_function(array('\Core\Error', 'fatal')); - +// Disable SimpleXML/DOM error output +libxml_use_internal_errors(true); diff --git a/CLI b/CLI index e8e0bb1..5c32f3c 100755 --- a/CLI +++ b/CLI @@ -35,7 +35,7 @@ try } catch (Exception $e) { - \Core\Error::exception($e); + \Micro\Error::exception($e); } // End diff --git a/Class/MyController.php b/Class/Example/Controller.php similarity index 62% rename from Class/MyController.php rename to Class/Example/Controller.php index 2ab2e58..6c4ec42 100755 --- a/Class/MyController.php +++ b/Class/Example/Controller.php @@ -1,6 +1,6 @@ $name); + $db = new \Micro\Database(config()->$name); // Set default ORM database connection - if(empty(\Core\ORM::$db)) + if(empty(\Micro\ORM::$db)) { - \Core\ORM::$db = $db; + \Micro\ORM::$db = $db; } return $db; @@ -50,7 +58,7 @@ public function load_database($name = 'database') public function show_404() { headers_sent() OR header('HTTP/1.0 404 Page Not Found'); - $this->content = new \Core\View('404'); + print new \View('Example/404'); } @@ -59,11 +67,11 @@ public function show_404() */ public function send() { - \Core\Session::save(); + \Micro\Session::save(); headers_sent() OR header('Content-Type: text/html; charset=utf-8'); - $layout = new \Core\View($this->template); + $layout = new \Micro\View($this->template); $layout->set((array) $this); print $layout; @@ -71,7 +79,7 @@ public function send() if(config()->debug_mode) { - print new \Core\View('System/Debug'); + print new \Micro\View('System/Debug'); } } diff --git a/Class/Controller/Index.php b/Class/Example/Controller/Index.php similarity index 58% rename from Class/Controller/Index.php rename to Class/Example/Controller/Index.php index 4038841..690471c 100755 --- a/Class/Controller/Index.php +++ b/Class/Example/Controller/Index.php @@ -10,22 +10,16 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Controller; +namespace Example\Controller; -class Index extends \MyController +class Index extends \Example\Controller { public function run() { - // Load database - //$this->db = new DB(config('database')); - - // Set ORM database connection - //ORM::$db = $this->db; - // Load the theme sidebar since we don't need the full page - $this->sidebar = new \Core\View('Sidebar'); + $this->sidebar = new \Micro\View('Example/Sidebar'); // Load the welcome view - $this->content = new \Core\View('Index/Index'); + $this->content = new \Micro\View('Example/Index'); } } diff --git a/Class/Controller/Page404.php b/Class/Example/Controller/Page404.php similarity index 73% rename from Class/Controller/Page404.php rename to Class/Example/Controller/Page404.php index e9dd0ef..0428430 100755 --- a/Class/Controller/Page404.php +++ b/Class/Example/Controller/Page404.php @@ -8,11 +8,11 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Controller; +namespace Example\Controller; -class Page404 extends \MyController +class Page404 extends \Example\Controller { - public function run() + public function index() { $this->show_404(); } diff --git a/Class/Controller/School.php b/Class/Example/Controller/School.php similarity index 85% rename from Class/Controller/School.php rename to Class/Example/Controller/School.php index 7c6f0fe..8df1ece 100755 --- a/Class/Controller/School.php +++ b/Class/Example/Controller/School.php @@ -10,9 +10,9 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Controller; +namespace Example\Controller; -class School extends \MyController +class School extends \Example\Controller { public function run() @@ -24,24 +24,24 @@ public function run() // Model_Name::$db = new DB(config('other_database')); // New Dorm - $d = new \Model\Dorm(); + $d = new \Example\Model\Dorm(); $d->name = 'Dorm 1'; $d->save(); // New Student in Dorm - $s1 = new \Model\Student(); + $s1 = new \Example\Model\Student(); $s1->name = 'Mary'; $s1->dorm_id = $d->id; $s1->save(); // New Student in Dorm - $s2 = new \Model\Student(); + $s2 = new \Example\Model\Student(); $s2->name = 'Jane'; $s2->dorm_id = $d->id; $s2->save(); // New Car for student - $c = new \Model\Car(); + $c = new \Example\Model\Car(); $c->name = 'Truck'; $c->student_id = $s1->id; $c->save(); // Insert @@ -50,25 +50,25 @@ public function run() $c->save(); // Update // New Softball club - $c = new \Model\Club(); + $c = new \Example\Model\Club(); $c->name = 'Softball'; $c->save(); // Mary is in softball - $m = new \Model\Membership(); + $m = new \Example\Model\Membership(); $m->club_id = $c->id; $m->student_id = $s1->id; $m->save(); // Jane is in softball - $m = new \Model\Membership(); + $m = new \Example\Model\Membership(); $m->club_id = $c->id; $m->student_id = $s2->id; $m->save(); $this->content = dump('Created school objects'); - $clubs = \Model\Club::fetch(); + $clubs = \Example\Model\Club::fetch(); foreach($clubs as $club) { $club->load(); @@ -88,7 +88,7 @@ public function run() $club->delete(); } - foreach(\Model\Dorm::fetch() as $dorm) + foreach(\Example\Model\Dorm::fetch() as $dorm) { $this->content .= dump('Removing the '. $dorm->name. ' dorm'); $dorm->delete(); // Delete the dorm @@ -97,10 +97,10 @@ public function run() $this->content .= dump('Removed school objects'); // Load the view file - $this->content .= new \Core\View('School/Index'); + $this->content .= new \Micro\View('Example/School'); // Load global theme sidebar - $this->sidebar = new \Core\View('Sidebar'); + $this->sidebar = new \Micro\View('Example/Sidebar'); } } diff --git a/Class/Model/Car.php b/Class/Example/Model/Car.php similarity index 79% rename from Class/Model/Car.php rename to Class/Example/Model/Car.php index 8e8acb7..9a14b56 100755 --- a/Class/Model/Car.php +++ b/Class/Example/Model/Car.php @@ -8,15 +8,15 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Model; +namespace Example\Model; -class Car extends \Core\ORM +class Car extends \Micro\ORM { public static $table = 'car'; public static $foreign_key = 'car_id'; public static $belongs_to = array( - 'student' => '\Model\Student', + 'student' => '\Example\Model\Student', ); } diff --git a/Class/Model/Club.php b/Class/Example/Model/Club.php similarity index 69% rename from Class/Model/Club.php rename to Class/Example/Model/Club.php index 9a7e1c2..662c43e 100755 --- a/Class/Model/Club.php +++ b/Class/Example/Model/Club.php @@ -8,21 +8,21 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Model; +namespace Example\Model; -class Club extends \Core\ORM +class Club extends \Micro\ORM { public static $table = 'club'; public static $foreign_key = 'club_id'; public static $has = array( - 'memberships' => '\Model\Membership' + 'memberships' => '\Example\Model\Membership' ); public static $has_many_through = array( 'students' => array( - 'club_id' => '\Model\Membership', - 'student_id' => '\Model\Student' + 'club_id' => '\Example\Model\Membership', + 'student_id' => '\Example\Model\Student' ), ); } diff --git a/Class/Model/Dorm.php b/Class/Example/Model/Dorm.php similarity index 78% rename from Class/Model/Dorm.php rename to Class/Example/Model/Dorm.php index a06f493..aed6772 100755 --- a/Class/Model/Dorm.php +++ b/Class/Example/Model/Dorm.php @@ -8,15 +8,15 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Model; +namespace Example\Model; -class Dorm extends \Core\ORM +class Dorm extends \Micro\ORM { public static $table = 'dorm'; public static $foreign_key = 'dorm_id'; public static $has = array( - 'students' => '\Model\Student', + 'students' => '\Example\Model\Student', ); } diff --git a/Class/Model/Membership.php b/Class/Example/Model/Membership.php similarity index 73% rename from Class/Model/Membership.php rename to Class/Example/Model/Membership.php index 78f284d..42d088f 100755 --- a/Class/Model/Membership.php +++ b/Class/Example/Model/Membership.php @@ -8,15 +8,15 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Model; +namespace Example\Model; -class Membership extends \Core\ORM +class Membership extends \Micro\ORM { public static $table = 'membership'; public static $foreign_key = 'membership_id'; public static $belongs_to = array( - 'student' => '\Model\Student', - 'club' => '\Model\Club', + 'student' => '\Example\Model\Student', + 'club' => '\Example\Model\Club', ); } diff --git a/Class/Model/Student.php b/Class/Example/Model/Student.php similarity index 66% rename from Class/Model/Student.php rename to Class/Example/Model/Student.php index 75a6f6c..9afe7b0 100755 --- a/Class/Model/Student.php +++ b/Class/Example/Model/Student.php @@ -8,27 +8,27 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Model; +namespace Example\Model; -class Student extends \Core\ORM +class Student extends \Micro\ORM { public static $table = 'student'; public static $foreign_key = 'student_id'; public static $cascade_delete = TRUE; public static $has = array( - 'car' => '\Model\Car', - 'memberships' => '\Model\Membership' + 'car' => '\Example\Model\Car', + 'memberships' => '\Example\Model\Membership' ); public static $belongs_to = array( - 'dorm' => '\Model\Dorm', + 'dorm' => '\Example\Model\Dorm', ); public static $has_many_through = array( 'clubs' => array( - 'student_id' => '\Model\Membership', - 'club_id' => '\Model\Club' + 'student_id' => '\Example\Model\Membership', + 'club_id' => '\Example\Model\Club' ), ); } diff --git a/Class/Core/Cipher.php b/Class/Micro/Cipher.php similarity index 99% rename from Class/Core/Cipher.php rename to Class/Micro/Cipher.php index 2fd023f..45662cc 100755 --- a/Class/Core/Cipher.php +++ b/Class/Micro/Cipher.php @@ -13,7 +13,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Cipher { diff --git a/Class/Core/Controller.php b/Class/Micro/Controller.php similarity index 93% rename from Class/Core/Controller.php rename to Class/Micro/Controller.php index 4e5d06e..b5e6257 100755 --- a/Class/Core/Controller.php +++ b/Class/Micro/Controller.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; abstract class Controller { @@ -23,7 +23,7 @@ abstract class Controller /** * Set error handling and start session */ - public function __construct($route, \Core\Dispatch $dispatch) + public function __construct($route, \Micro\Dispatch $dispatch) { $this->route = $route; $this->dispatch = $dispatch; diff --git a/Class/Core/Cookie.php b/Class/Micro/Cookie.php similarity index 98% rename from Class/Core/Cookie.php rename to Class/Micro/Cookie.php index 5ba649f..0b1b29d 100755 --- a/Class/Core/Cookie.php +++ b/Class/Micro/Cookie.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Cookie { diff --git a/Class/Core/Database.php b/Class/Micro/Database.php similarity index 61% rename from Class/Core/Database.php rename to Class/Micro/Database.php index ec5a492..40e8d67 100755 --- a/Class/Core/Database.php +++ b/Class/Micro/Database.php @@ -11,58 +11,24 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; +/** + * Query databases using PDO + */ class Database { - - public $pdo = NULL; - - public $type = NULL; - - public $i = '"'; - - public $statements = array(); - - protected $config = array(); - - public static $queries = array(); - - public static $last_query = NULL; + public $i='`', $c, $statements = array(), $type; + static $queries; /** - * Set the database type and save the config for later. + * Set the database connection on creation * - * @param array $config + * @param object $connection PDO connection object */ - public function __construct(array $config) + public function __construct($connection) { - // Auto-detect database type from DNS - $this->type = current(explode(':', $config['dns'], 2)); - - // Save config for connection - $this->config = $config; - - // MySQL uses a non-standard column identifier - if($this->type == 'mysql') $this->i = '`'; - } - - - /** - * Database lazy-loading to setup connection only when finally needed - */ - public function connect() - { - extract($this->config); - - // Clear config for security reasons - $this->config = NULL; - - // Connect to PDO - $this->pdo = new \PDO($dns, $username, $password, $params); - - // PDO should throw exceptions - $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + $this->c = $connection; } @@ -74,39 +40,38 @@ public function connect() */ public function quote($value) { - if( ! $this->pdo) $this->connect(); - return $this->pdo->quote($value); + return $this->c->quote($value); } /** - * Run a SQL query and return a single column (i.e. COUNT(*) queries) + * Fetch a column offset from the result set (COUNT() queries) * - * @param string $sql query to run - * @param array $params the prepared query params - * @param int $column the optional column to return - * @return mixed + * @param string $query query string + * @param array $params query parameters + * @param integer $key index of column offset + * @return array|null */ - public function column($sql, array $params = NULL, $column = 0) + public function column($query, $params = NULL, $key = 0) { - // If the query succeeds, fetch the column - return ($statement = $this->query($sql, $params)) ? $statement->fetchColumn($column) : NULL; + if($statement = $this->query($query, $params)) + return $statement->fetchColumn($key); } /** - * Run a SQL query and return a single row object + * Fetch a single query result row * - * @param string $sql query to run - * @param array $params the prepared query params + * @param string $query query string + * @param array $params query parameters * @param string $object the optional name of the class for this row - * @return array + * @return mixed */ - public function row($sql, array $params = NULL, $object = NULL) + public function row($query, $params = NULL, $object = NULL) { - if( ! $statement = $this->query($sql, $params)) return; + if(! $statement = $this->query($query, $params)) return; - $row = $statement->fetch(\PDO::FETCH_OBJ); + $row = $statement->fetch(); // If they want the row returned as a custom object if($object) $row = new $object($row); @@ -116,46 +81,41 @@ public function row($sql, array $params = NULL, $object = NULL) /** - * Run a SQL query and return an array of row objects or an array - * consisting of all values of a single column. + * Fetch all query result rows * - * @param string $sql query to run - * @param array $params the optional prepared query params + * @param string $query query string + * @param array $params query parameters * @param int $column the optional column to return * @return array */ - public function fetch($sql, array $params = NULL, $column = NULL) + public function fetch($query, $params = NULL, $column = NULL) { - if( ! $statement = $this->query($sql, $params)) return; + if( ! $statement = $this->query($query, $params)) return; // Return an array of records - if($column === NULL) return $statement->fetchAll(\PDO::FETCH_OBJ); + if($column === NULL) return $statement->fetchAll(); // Fetch a certain column from all rows - return $statement->fetchAll(\PDO::FETCH_COLUMN , $column); + return $statement->fetchAll(\PDO::FETCH_COLUMN, $column); } /** - * Run a SQL query and return the statement object + * Prepare and send a query returning the PDOStatement * - * @param string $sql query to run - * @param array $params the prepared query params - * @return PDOStatement + * @param string $query query string + * @param array $params query parameters + * @param boolean $cache_statement if true + * @return object|null */ - public function query($sql, array $params = NULL, $cache_statement = FALSE) + public function query($query, $params = NULL, $cache_statement = FALSE) { $time = microtime(TRUE); - self::$last_query = $sql; - - // Connect if needed - if( ! $this->pdo) $this->connect(); - // Should we cached PDOStatements? (Best for batch inserts/updates) if($cache_statement) { - $hash = md5($sql); + $hash = md5($query); if(isset($this->statements[$hash])) { @@ -163,37 +123,43 @@ public function query($sql, array $params = NULL, $cache_statement = FALSE) } else { - $statement = $this->statements[$hash] = $this->pdo->prepare($sql); + $statement = $this->statements[$hash] = $this->c->prepare($query); } } else { - $statement = $this->pdo->prepare($sql); + $statement = $this->c->prepare($query); } - $statement->execute($params); - //$statement = $this->pdo->query($sql); + $statement->execute((array) $params); // Save query results by database type - self::$queries[$this->type][] = array(microtime(TRUE) - $time, $sql); + self::$queries[] = array(microtime(TRUE) - $time, $query); return $statement; } /** - * Run a DELETE SQL query and return the number of rows deleted + * Issue a delete query * - * @param string $sql query to run - * @param array $params the prepared query params - * @return int + * @param string $table name + * @param array $where where conditions + * @return integer|null */ - public function delete($sql, array $params = NULL) + function delete($table, $where) { - if($statement = $this->query($sql, $params)) - { + $params; + + // Process WHERE conditions + if(is_array($where)) + list($where, $params) = $this->where($where); + + $i = $this->i; + + // Append WHERE conditions to query and add statement params + if($statement = $this->query("DELETE FROM $i$table$i WHERE " . $where, $params)) return $statement->rowCount(); - } } @@ -222,7 +188,7 @@ public function insert($table, array $data, $cache_statement = TRUE) } // Insert data and return the new row's ID - return $this->query($sql, array_values($data), $cache_statement) ? $this->pdo->lastInsertId() : NULL; + return $this->query($sql, array_values($data), $cache_statement) ? $this->c->lastInsertId() : NULL; } @@ -306,7 +272,7 @@ public function select($column, $table, $where = NULL, $limit = NULL, $offset = $sql .= $this->type == 'pgsql' ? " LIMIT $limit OFFSET $offset" : " LIMIT $offset, $limit"; } - return array($sql, $params); + return $this->fetch($sql, $params); } @@ -364,7 +330,6 @@ public function order_by($fields = NULL) // Remove ending ", " return substr($sql, 0, -2); } - } // END diff --git a/Class/Core/Directory.php b/Class/Micro/Directory.php similarity index 99% rename from Class/Core/Directory.php rename to Class/Micro/Directory.php index f1fa4f9..2f70749 100755 --- a/Class/Core/Directory.php +++ b/Class/Micro/Directory.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Directory { diff --git a/Class/Core/Dispatch.php b/Class/Micro/Dispatch.php similarity index 99% rename from Class/Core/Dispatch.php rename to Class/Micro/Dispatch.php index 93da6b3..4ca23d8 100644 --- a/Class/Core/Dispatch.php +++ b/Class/Micro/Dispatch.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Dispatch { diff --git a/Class/Core/Error.php b/Class/Micro/Error.php similarity index 99% rename from Class/Core/Error.php rename to Class/Micro/Error.php index 436c055..e3a863a 100755 --- a/Class/Core/Error.php +++ b/Class/Micro/Error.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Error { diff --git a/Class/Core/Form.php b/Class/Micro/Form.php similarity index 93% rename from Class/Core/Form.php rename to Class/Micro/Form.php index c6983ff..526ac91 100755 --- a/Class/Core/Form.php +++ b/Class/Micro/Form.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Form { @@ -204,18 +204,18 @@ protected function render_field() if($this->type == 'select') { - $html .= \Core\HTML::select($this->field, $this->options, $value, $attributes); + $html .= \Micro\HTML::select($this->field, $this->options, $value, $attributes); } elseif($this->type == 'textarea') { - $html .= \Core\HTML::tag('textarea', $value, $attributes); + $html .= \Micro\HTML::tag('textarea', $value, $attributes); } else { // Input field $attributes = $attributes + array('type' => $this->type, 'value' => $value); - $html .= \Core\HTML::tag('input', FALSE, $attributes); + $html .= \Micro\HTML::tag('input', FALSE, $attributes); } // If there was a validation error @@ -235,7 +235,7 @@ protected function render_field() if($this->tag) { - $html = \Core\HTML::tag($this->tag, $html . "\n") . "\n"; + $html = \Micro\HTML::tag($this->tag, $html . "\n") . "\n"; } return $html; diff --git a/Class/Core/GD.php b/Class/Micro/GD.php similarity index 99% rename from Class/Core/GD.php rename to Class/Micro/GD.php index f21c56e..7ea96c0 100755 --- a/Class/Core/GD.php +++ b/Class/Micro/GD.php @@ -11,7 +11,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class GD { @@ -50,7 +50,7 @@ public static function thumbnail($file, $width = 80, $height = 80, $quality = 80 /** - * Open a resource handle to a (png/gif/jpeg) image file for processing . + * Open a resource handle to a (png/gif/jpeg) image file for processing. * * @param string $file the file path to the image * @return resource diff --git a/Class/Core/HTML.php b/Class/Micro/HTML.php similarity index 99% rename from Class/Core/HTML.php rename to Class/Micro/HTML.php index 17c234d..2443f46 100755 --- a/Class/Core/HTML.php +++ b/Class/Micro/HTML.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class HTML { diff --git a/Class/Core/Migration.php b/Class/Micro/Migration.php similarity index 99% rename from Class/Core/Migration.php rename to Class/Micro/Migration.php index 927343b..87510d6 100755 --- a/Class/Core/Migration.php +++ b/Class/Micro/Migration.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; abstract class Migration { diff --git a/Class/Core/Migration/MySQL.php b/Class/Micro/Migration/MySQL.php similarity index 98% rename from Class/Core/Migration/MySQL.php rename to Class/Micro/Migration/MySQL.php index c4ab811..1f15429 100755 --- a/Class/Core/Migration/MySQL.php +++ b/Class/Micro/Migration/MySQL.php @@ -10,9 +10,9 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core\Migration; +namespace Micro\Migration; -class MySQL extends \Core\Migration +class MySQL extends \Micro\Migration { // Backup all existing data diff --git a/Class/Core/Migration/PGSQL.php b/Class/Micro/Migration/PGSQL.php similarity index 98% rename from Class/Core/Migration/PGSQL.php rename to Class/Micro/Migration/PGSQL.php index 6179ee4..cd2f69b 100755 --- a/Class/Core/Migration/PGSQL.php +++ b/Class/Micro/Migration/PGSQL.php @@ -10,9 +10,9 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core\Migration; +namespace Micro\Migration; -class PGSQL extends \Core\Migration +class PGSQL extends \Micro\Migration { // Backup all existing data diff --git a/Class/Core/ORM.php b/Class/Micro/ORM.php similarity index 99% rename from Class/Core/ORM.php rename to Class/Micro/ORM.php index c3ec867..8925207 100755 --- a/Class/Core/ORM.php +++ b/Class/Micro/ORM.php @@ -16,7 +16,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class ORM { diff --git a/Class/Core/ORM/APC.php b/Class/Micro/ORM/APC.php similarity index 92% rename from Class/Core/ORM/APC.php rename to Class/Micro/ORM/APC.php index 058fe50..2bb527c 100755 --- a/Class/Core/ORM/APC.php +++ b/Class/Micro/ORM/APC.php @@ -10,9 +10,9 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core\ORM; +namespace Micro\ORM; -class APC extends \Core\ORM +class APC extends \Micro\ORM { public static function cache_set($key, $value) diff --git a/Class/Core/Pagination.php b/Class/Micro/Pagination.php similarity index 99% rename from Class/Core/Pagination.php rename to Class/Micro/Pagination.php index e4a9488..af654c8 100755 --- a/Class/Core/Pagination.php +++ b/Class/Micro/Pagination.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Pagination { diff --git a/Class/Core/Service.php b/Class/Micro/Service.php similarity index 99% rename from Class/Core/Service.php rename to Class/Micro/Service.php index 60df31b..19c6a9a 100755 --- a/Class/Core/Service.php +++ b/Class/Micro/Service.php @@ -41,7 +41,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Service { diff --git a/Class/Core/Session.php b/Class/Micro/Session.php similarity index 99% rename from Class/Core/Session.php rename to Class/Micro/Session.php index 0f79506..3752c8a 100755 --- a/Class/Core/Session.php +++ b/Class/Micro/Session.php @@ -16,7 +16,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Session { diff --git a/Class/Core/Table.php b/Class/Micro/Table.php similarity index 99% rename from Class/Core/Table.php rename to Class/Micro/Table.php index 3a5e81d..58deebe 100644 --- a/Class/Core/Table.php +++ b/Class/Micro/Table.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Table { diff --git a/Class/Core/Upload.php b/Class/Micro/Upload.php similarity index 99% rename from Class/Core/Upload.php rename to Class/Micro/Upload.php index 72434d4..cfbc184 100755 --- a/Class/Core/Upload.php +++ b/Class/Micro/Upload.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Upload { diff --git a/Class/Core/Validation.php b/Class/Micro/Validation.php similarity index 99% rename from Class/Core/Validation.php rename to Class/Micro/Validation.php index 3396462..3d6c304 100755 --- a/Class/Core/Validation.php +++ b/Class/Micro/Validation.php @@ -11,7 +11,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class Validation { diff --git a/Class/Core/View.php b/Class/Micro/View.php similarity index 98% rename from Class/Core/View.php rename to Class/Micro/View.php index 3849427..066e6a3 100755 --- a/Class/Core/View.php +++ b/Class/Micro/View.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class View { diff --git a/Class/Core/XML.php b/Class/Micro/XML.php similarity index 98% rename from Class/Core/XML.php rename to Class/Micro/XML.php index 89ef6dc..1adbb09 100755 --- a/Class/Core/XML.php +++ b/Class/Micro/XML.php @@ -10,7 +10,7 @@ * @license http://micromvc.com/license ********************************** 80 Columns ********************************* */ -namespace Core; +namespace Micro; class XML { diff --git a/Class/Micro/readme.md b/Class/Micro/readme.md new file mode 100644 index 0000000..5521268 --- /dev/null +++ b/Class/Micro/readme.md @@ -0,0 +1,13 @@ +## Micro PHP Libraries + +These are the core system files for the [MicroMVC framework](https://github.com/Xeoncross/micromvc). These libraries have a focus on small and light-weight. + +## License (MIT License) + +Copyright (c) 2011 [David Pennington](http://xeoncross.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Command/Backup.php b/Command/Backup.php index ebf65d3..d7c8398 100755 --- a/Command/Backup.php +++ b/Command/Backup.php @@ -1,13 +1,13 @@ connect(); // Set name of migration object -$migration = '\Core\Migration\\' . ($db->type == 'mysql' ? 'MySQL' : 'PGSQL'); +$migration = '\Micro\Migration\\' . ($db->type == 'mysql' ? 'MySQL' : 'PGSQL'); // Create migration object $migration = new $migration; @@ -19,7 +19,7 @@ $migration->name = 'default'; // Load table configuration -$migration->tables = \Core\Config::load_all('Migration'); +$migration->tables = \Micro\Config::load_all('Migration'); // Backup existing database table $migration->backup_data(); diff --git a/Command/Create.php b/Command/Create.php index db3512f..d314e51 100755 --- a/Command/Create.php +++ b/Command/Create.php @@ -1,13 +1,13 @@ connect(); // Set name of migration object -$migration = '\Core\Migration\\' . ($db->type == 'mysql' ? 'MySQL' : 'PGSQL'); +$migration = '\Micro\Migration\\' . ($db->type == 'mysql' ? 'MySQL' : 'PGSQL'); // Create migration object $migration = new $migration; @@ -19,7 +19,7 @@ $migration->name = 'default'; // Load table configuration -$migration->tables = \Core\Config::load_all('Migration'); +$migration->tables = \Micro\Config::load_all('Migration'); // Backup existing database table $migration->create_schema(); diff --git a/Command/Restore.php b/Command/Restore.php index 12f0483..2c81d5a 100755 --- a/Command/Restore.php +++ b/Command/Restore.php @@ -1,13 +1,13 @@ connect(); // Set name of migration object -$migration = '\Core\Migration\\' . ($db->type == 'mysql' ? 'MySQL' : 'PGSQL'); +$migration = '\Micro\Migration\\' . ($db->type == 'mysql' ? 'MySQL' : 'PGSQL'); // Create migration object $migration = new $migration; @@ -19,7 +19,7 @@ $migration->name = 'default'; // Load table configuration -$migration->tables = \Core\Config::load_all('Migration'); +$migration->tables = \Micro\Config::load_all('Migration'); // Backup existing database table $migration->restore_data(); diff --git a/Command/Run.php b/Command/Run.php index 5c04cb7..ff216af 100755 --- a/Command/Run.php +++ b/Command/Run.php @@ -1,13 +1,13 @@ connect(); // Set name of migration object -$migration = '\Core\Migration\\' . ($db->type == 'mysql' ? 'MySQL' : 'PGSQL'); +$migration = '\Micro\Migration\\' . ($db->type == 'mysql' ? 'MySQL' : 'PGSQL'); // Create migration object $migration = new $migration; @@ -19,7 +19,7 @@ $migration->name = 'default'; // Load table configuration -$migration->tables = \Core\Config::load_all('Migration'); +$migration->tables = \Micro\Config::load_all('Migration'); // Backup existing database table $migration->backup_data(); diff --git a/Common.php b/Common.php deleted file mode 100755 index 3c2ff88..0000000 --- a/Common.php +++ /dev/null @@ -1,544 +0,0 @@ -' . h($value === NULL ? 'NULL' : (is_scalar($value) ? $value : print_r($value, TRUE))) . "\n"; - } - return $string; -} - - -/** - * Safely fetch a $_POST value, defaulting to the value provided if the key is - * not found. - * - * @param string $key name - * @param mixed $default value if key is not found - * @param boolean $string TRUE to require string type - * @return mixed - */ -function post($key, $default = NULL, $string = FALSE) -{ - if(isset($_POST[$key])) - { - return $string ? str($_POST[$key], $default) : $_POST[$key]; - } - return $default; -} - - -/** - * Safely fetch a $_GET value, defaulting to the value provided if the key is - * not found. - * - * @param string $key name - * @param mixed $default value if key is not found - * @param boolean $string TRUE to require string type - * @return mixed - */ -function get($key, $default = NULL, $string = FALSE) -{ - if(isset($_GET[$key])) - { - return $string ? str($_GET[$key], $default) : $_GET[$key]; - } - return $default; -} - - -/** - * Safely fetch a $_SESSION value, defaulting to the value provided if the key is - * not found. - * - * @param string $k the post key - * @param mixed $d the default value if key is not found - * @return mixed - */ -function session($k, $d = NULL) -{ - return isset($_SESSION[$k]) ? $_SESSION[$k] : $d; -} - - -/** - * Create a random 32 character MD5 token - * - * @return string - */ -function token() -{ - return md5(str_shuffle(chr(mt_rand(32, 126)) . uniqid() . microtime(TRUE))); -} - - -/** - * Write to the application log file using error_log - * - * @param string $message to save - * @return bool - */ -function log_message($message) -{ - $path = SP . 'Storage/Log/' . date('Y-m-d') . '.log'; - - // Append date and IP to log message - return error_log(date('H:i:s ') . getenv('REMOTE_ADDR') . " $message\n", 3, $path); -} - - -/** - * Send a HTTP header redirect using "location" or "refresh". - * - * @param string $url the URL string - * @param int $c the HTTP status code - * @param string $method either location or redirect - */ -function redirect($url = NULL, $code = 302, $method = 'location') -{ - if(strpos($url, '://') === FALSE) - { - $url = site_url($url); - } - - //print dump($url); - - header($method == 'refresh' ? "Refresh:0;url = $url" : "Location: $url", TRUE, $code); -} - - -/* - * Return the full URL to a path on this site or another. - * - * @param string $uri may contain another sites TLD - * @return string - * -function site_url($uri = NULL) -{ - return (strpos($uri, '://') === FALSE ? \Core\URL::get() : '') . ltrim($uri, '/'); -} -*/ - -/** - * Return the full URL to a location on this site - * - * @param string $path to use or FALSE for current path - * @param array $params to append to URL - * @return string - */ -function site_url($path = NULL, array $params = NULL) -{ - // In PHP 5.4, http_build_query will support RFC 3986 - return DOMAIN . ($path ? '/'. trim($path, '/') : PATH) - . ($params ? '?'. str_replace('+', '%20', http_build_query($params, TRUE, '&')) : ''); -} - - -/** - * Return the current URL with path and query params - * - * @return string - * -function current_url() -{ - return DOMAIN . getenv('REQUEST_URI'); -} -*/ - -/** - * Convert a string from one encoding to another encoding - * and remove invalid bytes sequences. - * - * @param string $string to convert - * @param string $to encoding you want the string in - * @param string $from encoding that string is in - * @return string - */ -function encode($string, $to = 'UTF-8', $from = 'UTF-8') -{ - // ASCII is already valid UTF-8 - if($to == 'UTF-8' AND is_ascii($string)) - { - return $string; - } - - // Convert the string - return @iconv($from, $to . '//TRANSLIT//IGNORE', $string); -} - - -/** - * Tests whether a string contains only 7bit ASCII characters. - * - * @param string $string to check - * @return bool - */ -function is_ascii($string) -{ - return ! preg_match('/[^\x00-\x7F]/S', $string); -} - - -/** - * Encode a string so it is safe to pass through the URL - * - * @param string $string to encode - * @return string - */ -function base64_url_encode($string = NULL) -{ - return strtr(base64_encode($string), '+/=', '-_~'); -} - - -/** - * Decode a string passed through the URL - * - * @param string $string to decode - * @return string - */ -function base64_url_decode($string = NULL) -{ - return base64_decode(strtr($string, '-_~', '+/=')); -} - - -/** - * Convert special characters to HTML safe entities. - * - * @param string $string to encode - * @return string - */ -function h($string) -{ - return htmlspecialchars($string, ENT_QUOTES, 'utf-8'); -} - - -/** - * Filter a valid UTF-8 string so that it contains only words, numbers, - * dashes, underscores, periods, and spaces - all of which are safe - * characters to use in file names, URI, XML, JSON, and (X)HTML. - * - * @param string $string to clean - * @param bool $spaces TRUE to allow spaces - * @return string - */ -function sanitize($string, $spaces = TRUE) -{ - $search = array( - '/[^\w\-\. ]+/u', // Remove non safe characters - '/\s\s+/', // Remove extra whitespace - '/\.\.+/', '/--+/', '/__+/' // Remove duplicate symbols - ); - - $string = preg_replace($search, array(' ', ' ', '.', '-', '_'), $string); - - if( ! $spaces) - { - $string = preg_replace('/--+/', '-', str_replace(' ', '-', $string)); - } - - return trim($string, '-._ '); -} - - -/** - * Create a SEO friendly URL string from a valid UTF-8 string. - * - * @param string $string to filter - * @return string - */ -function sanitize_url($string) -{ - return urlencode(mb_strtolower(sanitize($string, FALSE))); -} - - -/** - * Filter a valid UTF-8 string to be file name safe. - * - * @param string $string to filter - * @return string - */ -function sanitize_filename($string) -{ - return sanitize($string, FALSE); -} - - -/** - * Return a SQLite/MySQL/PostgreSQL datetime string - * - * @param int $timestamp - */ -function sql_date($timestamp = NULL) -{ - return date('Y-m-d H:i:s', $timestamp ?: time()); -} - - -/** - * Make a request to the given URL using cURL. - * - * @param string $url to request - * @param array $options for cURL object - * @return object - */ -function curl_request($url, array $options = NULL) -{ - $ch = curl_init($url); - - $defaults = array( - CURLOPT_HEADER => 0, - CURLOPT_RETURNTRANSFER => 1, - CURLOPT_TIMEOUT => 5, - ); - - // Connection options override defaults if given - curl_setopt_array($ch, (array) $options + $defaults); - - // Create a response object - $object = new stdClass; - - // Get additional request info - $object->response = curl_exec($ch); - $object->error_code = curl_errno($ch); - $object->error = curl_error($ch); - $object->info = curl_getinfo($ch); - - curl_close($ch); - - return $object; -} - - -/** - * Create a RecursiveDirectoryIterator object - * - * @param string $dir the directory to load - * @param boolean $recursive to include subfolders - * @return object - */ -function directory($dir, $recursive = TRUE) -{ - $i = new \RecursiveDirectoryIterator($dir); - - if( ! $recursive) return $i; - - return new \RecursiveIteratorIterator($i, \RecursiveIteratorIterator::SELF_FIRST); -} - - -/** - * Make sure that a directory exists and is writable by the current PHP process. - * - * @param string $dir the directory to load - * @param string $chmod value as octal - * @return boolean - */ -function directory_is_writable($dir, $chmod = 0755) -{ - // If it doesn't exist, and can't be made - if(! is_dir($dir) AND ! mkdir($dir, $chmod, TRUE)) return FALSE; - - // If it isn't writable, and can't be made writable - if(! is_writable($dir) AND !chmod($dir, $chmod)) return FALSE; - - return TRUE; -} - - -/** - * Convert any given variable into a SimpleXML object - * - * @param mixed $object variable object to convert - * @param string $root root element name - * @param object $xml xml object - * @param string $unknown element name for numeric keys - * @param string $doctype XML doctype - */ -function to_xml($object, $root = 'data', $xml = NULL, $unknown = 'element', $doctype = "") -{ - if(is_null($xml)) - { - $xml = simplexml_load_string("$doctype<$root/>"); - } - - foreach((array) $object as $k => $v) - { - if(is_int($k)) - { - $k = $unknown; - } - - if(is_scalar($v)) - { - $xml->addChild($k, h($v)); - } - else - { - $v = (array) $v; - $node = array_diff_key($v, array_keys(array_keys($v))) ? $xml->addChild($k) : $xml; - self::from($v, $k, $node); - } - } - - return $xml; -} - - -/** - * Return an IntlDateFormatter object using the current system locale - * - * @param string $locale string - * @param integer $datetype IntlDateFormatter constant - * @param integer $timetype IntlDateFormatter constant - * @param string $timezone Time zone ID, default is system default - * @return IntlDateFormatter - */ -function __date($locale = NULL, $datetype = IntlDateFormatter::MEDIUM, $timetype = IntlDateFormatter::SHORT, $timezone = NULL) -{ - return new IntlDateFormatter($locale ?: setlocale(LC_ALL, 0), $datetype, $timetype, $timezone); -} - - -/** - * Format the given string using the current system locale - * Basically, it's sprintf on i18n steroids. - * - * @param string $string to parse - * @param array $params to insert - * @return string - */ -function __($string, array $params = NULL) -{ - return msgfmt_format_message(setlocale(LC_ALL, 0), $string, $params); -} - - -/** - * Color output text for the CLI - * - * @param string $text to color - * @param string $color of text - * @param string $background color - */ -function colorize($text, $color, $bold = FALSE) -{ - // Standard CLI colors - $colors = array_flip(array(30 => 'gray', 'red', 'green', 'yellow', 'blue', 'purple', 'cyan', 'white', 'black')); - - // Escape string with color information - return"\033[" . ($bold ? '1' : '0') . ';' . $colors[$color] . "m$text\033[0m"; -} - -// End diff --git a/Config/Sample.Config.php b/Config/Sample.Config.php index 415db37..4a2b526 100755 --- a/Config/Sample.Config.php +++ b/Config/Sample.Config.php @@ -65,6 +65,21 @@ ); +/** + * Namespaces + * + * The location of the submodule files relative to the `Class/` folder. + */ +$config['namespaces'] = array( + //'Zend' => 'Zend/library/Zend' + //'Boilerplate' => 'Boilerplate/library/Boilerplate', + //'Doctrine' => 'Doctrine/lib/Doctrine', + //'Symfony' => 'Symfony/src/Symfony', + //'Gaufrette' => 'Gaufrette/src/Gaufrette', + //'Goutte' => 'Goutte/src/Goutte' +); + + /** * API Keys and Secrets * diff --git a/Config/Sample.Route.php b/Config/Sample.Route.php index d791c06..6f4cf82 100644 --- a/Config/Sample.Route.php +++ b/Config/Sample.Route.php @@ -24,9 +24,9 @@ $config = array(); $config['routes'] = array( - '' => '\Controller\Index', - '404' => '\Controller\Page404', - 'school' => '\Controller\School', + '' => '\Example\Controller\Index', + '404' => '\Example\Controller\Page404', + 'school' => '\Example\Controller\School', // Example paths //'example/path' => '\Controller\Example\Hander', diff --git a/Locale/.gitignore b/Locale/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/MicroMVC.php b/MicroMVC.php new file mode 100644 index 0000000..a6c1a40 --- /dev/null +++ b/MicroMVC.php @@ -0,0 +1,823 @@ + $closure) + { + $this->$key = $closure; + } + } + + /** + * Call the given closure function passing a copy of this object + * $proto->foo([$arg1, $arg2, ...]) + */ + public function __call($key, $args) + { + // Pass $this as first argument of callback (PHP 5.4 will be here soon!) + array_unshift($args, $this); + return call_user_func_array($this->$key, $args); + } +} + + +/** + * Validation class based on anonymous functions + * + * @see http://php.net/manual/en/functions.anonymous.php + */ +class Validation extends Prototype +{ + /** + * Validate the given array of data using the functions set + * + * @param array $data to validate + * @return array + */ + public function validate(array $data) + { + $errors; + foreach((array) $this as $key => $function) + { + if($error = $function(isset($data[$k]) ? $data[$k] : NULL, $key)) + { + $errors[$key] = $error; + } + } + return $errors; + } + + + /** + * See if the given string contains XML/HTML markup. This is useful + * for checking text input fields that should only contain usernames or + * post titles. + * + * @param string $string to check + * @return boolean + */ + public function markup($string) + { + // Simple check for markup tags + if(mb_strpos($string, '<') === FALSE AND mb_strpos($string, '>') === FALSE) + { + // Now lets get serious + if($xml = simplexml_load_string("$string")) + { + return $xml->count() !== 0; + } + } + + return TRUE; + } + + + /** + * Check to see if the email entered is valid. + * + * @param string $string to validate + * @return boolean + */ + public function isEmail($string) + { + return preg_match('/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i', $string); + } +} + + +/** + * UTF-8 i18n and l10n class for working with strings and dates. + * This class is based heavly on the great work done by Alix Alex. + * + * @see https://github.com/alixaxel/phunction + */ +class _ +{ + /** + * Convert a string to UTF-8 and remove invalid bytes sequences. + * + * @param string $string to convert + * @param string $encoding current encoding of string (default to UTF-8) + * @param string $control TRUE to keep "Other" characters + * @return string + */ + static function convert($string, $encoding = 0, $control = 1) + { + // Try to figureout what the encoding is if posible + if(function_exists('mb_detect_encoding')) $encoding = mb_detect_encoding($string, 'auto'); + + // Convert to valid UTF-8 + if(($string = @iconv( ! $encoding ? 'UTF-8' : $encoding, 'UTF-8//IGNORE', $string)) !== false) + { + // Optionally remove "other" characters and windows useless "\r" + return $control ? preg_replace('~\p{C}+~u', '', $string) : preg_replace(array('~\r\n?~', '~[^\P{C}\t\n]+~u'), array("\n", ''), $string); + } + } + + + /** + * Return an IntlDateFormatter object using the current system locale + * + * @see IntlDateFormatter + * @param string $locale string + * @param integer $datetype IntlDateFormatter constant + * @param integer $timetype IntlDateFormatter constant + * @param string $timezone Time zone ID, default is system default + * @return IntlDateFormatter + */ + static function date($locale = 0, $datetime = IntlDateFormatter::MEDIUM, $timetype = IntlDateFormatter::SHORT, $timezone = NULL) + { + return new IntlDateFormatter($locale ?: setlocale(LC_ALL,0), $datetime, $timetype, $timezone); + } + + + /** + * Format the given string using the current system locale + * Basically, it's sprintf on i18n steroids. + * + * @see MessageFormatter + * @param string $string to parse + * @param array $params to insert + * @return string + */ + static function format($string, array $params = NULL) + { + return msgfmt_format_message(setlocale(LC_ALL,0), $string, $params); + } + + + /** + * Normalize the given UTF-8 string + * + * @see http://stackoverflow.com/a/7934397/99923 + * @param string $string to normalize + * @param int $form to normalize as + * @return string + */ + static function normalize($string, $form = Normalizer::FORM_D) + { + return normalizer_normalize($string, $form); + } + + + /** + * Remove accents from characters + * + * @param string $string to remove accents from + * @return string + */ + static function unaccent($string) + { + // Only process if there are entities + if(strpos($string = htmlentities($string, ENT_QUOTES, 'UTF-8'), '&') !== false) + + // Remove accent HTML entities + return html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '$1', $string), ENT_QUOTES, 'UTF-8'); + } + + + /** + * Convert a string to an ASCII/URL/file name safe slug + * + * @param string $string to convert + * @param string $character to separate words with + * @param string $extra characters to include + * @return string + */ + static function slug($string, $character = '-', $extra = null) + { + $string = strtolower(trim(preg_replace('~[^0-9a-z' . preg_quote($extra,'~') . ']+~i', $character, self::unaccent($string)), $character)); + // Need to add this + return preg_replace("/$character{2,}/", $character, $string); + } + + + /** + * Tests whether a string contains only 7bit ASCII characters. + * + * @param string $string to check + * @return bool + */ + static function is_ascii($string) + { + return ! preg_match('/[^\x00-\x7F]/S', $string); + } + + + /** + * Encode a string so it is safe to pass through the URL + * + * @param string $string to encode + * @return string + */ + static function base64_url_encode($string = NULL) + { + return strtr(base64_encode($string), '+/=', '-_~'); + } + + + /** + * Decode a string passed through the URL + * + * @param string $string to decode + * @return string + */ + static function base64_url_decode($string = NULL) + { + return base64_decode(strtr($string, '-_~', '+/=')); + } +} + + +/** + * Fetch input values safely with support for default values. + */ +class I +{ + public static function __callStatic($method, $args) + { + // Function calls are slow + //$method = '_' . strtoupper($method); + + $types = array( + 'session' => '_SESSION', + 'post' => '_POST', + 'get' => '_GET', + 'server' => '_SERVER', + 'files' => '_FILES', + 'cookie' => '_COOKIE', + 'env' => '_ENV', + 'request' => '_REQUEST' + ); + + $method = $types[$method]; + + if(isset($GLOBALS[$method][$args[0]])) + { + return $GLOBALS[$method][$args[0]]; + } + + return isset($args[1]) ? $args[1] : NULL; + } +} + + +/** + * HTML template views + */ +class View +{ + static $path, $ext = '.php'; + public $view; + + /** + * Returns a new view object for the given view. + * + * @param string $file the view file to load + * @param string $path to load from + */ + public function __construct($file) + { + $this->view = $file; + } + + + /** + * Convert special characters to HTML safe entities. + * + * @param string $string to encode + * @return string + */ + public function e($string) + { + return htmlspecialchars($string, ENT_QUOTES, 'UTF-8'); + } + + + /** + * Convert dangerous HTML entities into special characters. + * + * @param string $s string to decode + * @return string + */ + public function d($string) + { + return htmlspecialchars_decode($string, ENT_QUOTES, 'UTF-8'); + } + + /** + * Set an array of values + * + * @param array $array of values + * @return this + */ + public function set($values) + { + foreach($values as $key => $value) $this->$key = $value; + return $this; + } + + + /** + * Load the given view + * + * @param string $__f file name + * @return string + */ + public function load($__f) + { + ob_start(); + extract((array) $this); + require self::$path.$__f.self::$ext; + return ob_get_clean(); + } + + + /** + * Allows setting view values while still returning the object instance. + * $view->title($title)->text($text); + * + * @return this + */ + public function __call($key, $args) + { + $this->$key = $args[0]; + return $this; + } + + + /** + * Return the view's HTML + * + * @return string + */ + public function __toString() + { + try { + return $this->load($this->view); + } + catch(Exception $exception) + { + return '' . $exception; + } + } + + + /** + * Compiles an array of HTML attributes into an attribute string and + * HTML escape it to prevent malformed (but not malicious) data. + * + * @param array $a the tag's attribute list + * @return string + */ + public static function attr($array) + { + $h = ''; + foreach((array)$array as $k => $v) $h .= " $k=\"$v\""; + return $h; + } + + + /** + * Auto creates a form select dropdown from the options given . + * + * @param string $name the select element name + * @param array $options the select options + * @param mixed $selected the selected options(s) + * @param array $a of additional tag settings + * @return string + */ + public function select($name, $options, $selected = NULL, $attr = NULL) + { + $attr['name'] = $name; + $h = '\n"; + } + + + /** + * The magic call static method is triggered when invoking inaccessible + * methods in a static context. This allows us to create tags from method + * calls. + * + * Html::div('This is div content.', array('id' => 'myDiv')); + * + * @param string $tag The method name being called + * @param array $args Parameters passed to the called method + * @return string + */ + public static function __callStatic($tag, $args) + { + $args[1] = isset($args[1]) ? self::attr($args[1]) : ''; + return "<$tag{$args[1]}>{$args[0]}\n"; + } +} + + +/** + * Adds template inheritance to standard view objects. + * This is a powerful class! + */ +class Template extends View +{ + public $blocks, $append; + + /** + * Extend this parent view + * + * @param string $__f name of view + */ + public function extend($__f) + { + ob_end_clean(); // Ignore this child class and load the parent! + print $this->load($__f); + ob_start(); + } + + + /** + * Start a new block + */ + public function start() + { + ob_start(); + } + + + /** + * Empty default block to be extended by child templates + * + * @param string $name of block + */ + public function block($name) + { + if(isset($this->blocks[$name])) + { + print $this->blocks[$name]; + } + } + + + /** + * End a block + * + * @param string $name name of block + * @param mixed $filter functions + * @param boolean $keep_parent true to append parent block contents + */ + public function end($name, $filters = NULL, $keep_parent = FALSE) + { + $buffer = ob_get_clean(); + + foreach((array) $filters as $filter) + { + $buffer = $filter($buffer); + } + + // This block is already set + if( ! isset($this->blocks[$name])) + { + $this->blocks[$name] = $buffer; + if($keep_parent) $this->append[$name] = TRUE; + } + elseif(isset($this->append[$name])) + { + $this->blocks[$name] .= $buffer; + } + + print $this->blocks[$name]; + } +} + + +/** + * Session + * + * Stores session data in encrypted cookies to save database/memcached load. + * Sessions stored in cookies must be under 4KB. + */ +class Session +{ + /** + * Start the session + * + * @param string $name of the session cookie + * @return mixed + */ + public static function start($name = 'session') + { + if( ! empty($_SESSION)) return $_SESSION = Cookie::get($name); + } + + + /** + * Called at end-of-page to save the current session data to the session cookie + * + * @param string $name of the session cookie + * return boolean + */ + public static function save($name = 'session') + { + return Cookie::set($name, $_SESSION); + } + + + /** + * Destroy the current users session + * + * @param string $name of the session cookie + */ + public static function destroy($name = 'session') + { + Cookie::set($name, ''); + unset($_COOKIE[$name], $_SESSION); + } +} + + +/* + * Common Functions + */ + + +/** + * Fetch a config value from a module configuration file + * + * @param string $file name of the config + * @param boolean $clear to clear the config object + * @return object + */ +function config($file = 'Config', $clear = FALSE) +{ + static $configs = array(); + + if($clear) + { + unset($configs[$file]); + return; + } + + if(empty($configs[$file])) + { + require(SP . 'Config/' . $file . EXT); + $configs[$file] = (object) $config; + } + + return $configs[$file]; +} + + +/** + * SplClassLoader implementation that implements the technical interoperability + * standards for PHP 5.3 namespaces and class names. + * + * http://groups.google.com/group/php-standards/web/final-proposal + * + * @param string $class name + */ +function __autoload($className) +{ + // Each namespace might have a custom path + $namespaces = config()->namespaces; + + $className = explode('/', str_replace('\\', '/', ltrim($className, '\\'))); + $fileName = str_replace('_', '/', array_pop($className)); + + // Is there a namespace left? + if($className) + { + $namespace = array_shift($className); + + if(isset($namespaces[$namespace])) + { + $namespace = $namespaces[$namespace]; + } + + array_unshift($className, $namespace); + + $fileName = join('/', $className) . '/' . $fileName; + } + else // Double-up the file name ('Micro' => 'Micro/Micro.php') + { + //$fileName .= '/' . $fileName; + } + + require SP . 'Class/' . $fileName . EXT; +} + + +/** + * Return an HTML safe dump of the given variable(s) surrounded by "pre" tags. + * You can pass any number of variables (of any type) to this function. + * + * @param mixed + * @return string + */ +function dump() +{ + $string = ''; + foreach(func_get_args() as $value) + { + $string .= '
' . h($value === NULL ? 'NULL' : (is_scalar($value) ? $value : print_r($value, TRUE))) . "
\n"; + } + return $string; +} + + +/** + * Write to the application log file using error_log + * + * @param string $message to save + * @return bool + */ +function log_message($message) +{ + $path = SP . 'Storage/Log/' . date('Y-m-d') . '.log'; + + // Append date and IP to log message + return error_log(date('H:i:s ') . getenv('REMOTE_ADDR') . " $message\n", 3, $path); +} + + +/** + * Send a HTTP header redirect using "location" or "refresh". + * + * @param string $url the URL string + * @param int $c the HTTP status code + * @param string $method either location or redirect + */ +function redirect($url = NULL, $code = 302, $method = 'location') +{ + if(strpos($url, '://') === FALSE) + { + $url = site_url($url); + } + + header($method == 'refresh' ? "Refresh:0;url = $url" : "Location: $url", TRUE, $code); +} + + +/** + * Return the full URL to a location on this site + * + * @param string $path to use or FALSE for current path + * @param array $params to append to URL + * @return string + */ +function site_url($path = NULL, array $params = NULL) +{ + // In PHP 5.4, http_build_query will support RFC 3986 + return DOMAIN . ($path ? '/'. trim($path, '/') : PATH) + . ($params ? '?'. str_replace('+', '%20', http_build_query($params, TRUE, '&')) : ''); +} + + +/** + * Return a SQLite/MySQL/PostgreSQL datetime string + * + * @param int $timestamp + */ +function sql_date($timestamp = NULL) +{ + return date('Y-m-d H:i:s', $timestamp ?: time()); +} + + +/** + * Color output text for the CLI + * + * @param string $text to color + * @param string $color of text + * @param string $background color + */ +function colorize($text, $color, $bold = FALSE) +{ + // Standard CLI colors + $colors = array_flip(array(30 => 'gray', 'red', 'green', 'yellow', 'blue', 'purple', 'cyan', 'white', 'black')); + + // Escape string with color information + return"\033[" . ($bold ? '1' : '0') . ';' . $colors[$color] . "m$text\033[0m"; +} + + +/** + * Make a request to the given URL using cURL. + * + * @param string $url to request + * @param array $options for cURL object + * @return object + */ +function curl_request($url, array $options = NULL) +{ + $ch = curl_init($url); + + $defaults = array( + CURLOPT_HEADER => 0, + CURLOPT_RETURNTRANSFER => 1, + CURLOPT_TIMEOUT => 5, + ); + + // Connection options override defaults if given + curl_setopt_array($ch, (array) $options + $defaults); + + // Create a response object + $object = new stdClass; + + // Get additional request info + $object->response = curl_exec($ch); + $object->error_code = curl_errno($ch); + $object->error = curl_error($ch); + $object->info = curl_getinfo($ch); + + curl_close($ch); + + return $object; +} + + +/** + * Create a RecursiveDirectoryIterator object + * + * @param string $dir the directory to load + * @param boolean $recursive to include subfolders + * @return object + */ +function directory($dir, $recursive = TRUE) +{ + $i = new \RecursiveDirectoryIterator($dir); + + if( ! $recursive) return $i; + + return new \RecursiveIteratorIterator($i, \RecursiveIteratorIterator::SELF_FIRST); +} + + +/** + * Make sure that a directory exists and is writable by the current PHP process. + * + * @param string $dir the directory to load + * @param string $chmod value as octal + * @return boolean + */ +function directory_is_writable($dir, $chmod = 0755) +{ + // If it doesn't exist, and can't be made + if(! is_dir($dir) AND ! mkdir($dir, $chmod, TRUE)) return FALSE; + + // If it isn't writable, and can't be made writable + if(! is_writable($dir) AND !chmod($dir, $chmod)) return FALSE; + + return TRUE; +} + diff --git a/Public/Admin/CSS/admin.css b/Public/Admin/CSS/admin.css deleted file mode 100755 index deaa2c1..0000000 --- a/Public/Admin/CSS/admin.css +++ /dev/null @@ -1,212 +0,0 @@ -/* Typography - Choose your font and size (base.css default is 16px) */ -body -{ - font-size:80%; - line-height:1.5em; - font-family:Helvetica,Arial,sans-serif; - background: #202020; -} -/*IE*/ -html>body{font-size:13px} -pre,code -{ - font-family:"DejaVu Sans Mono","Bitstream Vera Sans Mono",Monaco,"Courier New",monospace; -} - -a img, img { border: none; } -a {color: #2A90BF;text-decoration: none;} - -a:hover { -color: #BE4925; -text-decoration: underline; -text-decoration: none; -} - - -#main { -margin: 0 0 0 150px; -background: #ddd; -} - -#content { -background: #fff; -padding: 2em; -margin: 1em 1em 2em 1em; -margin: 0; -} - -#sidebar { width: 150px; float: left; } - -#sidebar h2 { -color: #777; -border: none; -font-size: 20px; -line-height: 50px; -text-align: center; -} - -#sidebar ul { -margin: 2em 0; -padding: 0; -list-style: none; -} - -#sidebar ul li {margin: 0;padding: 0;} - -#sidebar ul li a { -display: block; -line-height: 2.5em; -padding: 0 1em; -border-bottom: 1px solid #333; -color: #fff; -font-size: 14px; -font-weight: bold; -text-shadow:0 1px 2px #000000; -} - -/* -#sidebar ul li a.selected, -#sidebar ul li a:hover { -background: #ddd; -color: #000; -text-shadow:0 1px 2px #eee; -} -*/ - -#sidebar ul li a.selected, -#sidebar ul li a:hover { -background: #111; -text-shadow:0 1px 1px #777; -} - -/* Sub levels */ -#sidebar ul li ul { padding: 0; margin: 0; } -#sidebar ul li li a { color: #ccc; padding: 0 1em 0 3em; } - - -table thead a { color: #333;white-space:nowrap;} -table tbody tr:hover {background: #f1f1f1;} - - -/* - * Header - */ -#header { -background: #eee; -height: 30px; -line-height: 30px; -margin: 0; -border-bottom: 0px solid #ddd; -} - -/* - * Footer - */ - -#footer { -background: #eee; -height: 30px; -line-height: 30px; -margin: 0; -border-top: 1px solid #ddd; -color: #777; -} - - -/* - * Horizontal menu UL - */ -ul.horizontal_menu, -ul.horizontal_menu li { -margin: 0; -padding: 0; -list-style: none; -} -ul.horizontal_menu li { float: left; padding: 0 1em; } -ul.horizontal_menu li.right {float: right;} - - -.box { - padding: 1em; - margin: 1em 0; - background: #eee; - - border: 1px solid #fff; - -moz-box-shadow: 0px 1px 4px #bbb; - -webkit-box-shadow: 0px 1px 4px #bbb; - box-shadow: 0px 1px 4px #bbb; - - background: #F7F7F7; /* old browsers */ - background: -moz-linear-gradient(top, #F7F7F7 0%, #EAEAEA 100%); /* firefox */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#F7F7F7), color-stop(100%,#EAEAEA)); /* webkit */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F7F7F7', endColorstr='#EAEAEA',GradientType=0 ); /* ie */ -} - - -/* Create New link */ -.create_new { float: right; } - -.create_new a.button { - border-top: 1px solid #6ee653; - background: #57c246; - background: -webkit-gradient(linear, left top, left bottom, from(#57c246), to(#0c9427)); - background: -moz-linear-gradient(top, #57c246,#0c9427); - padding: 7px 15px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: rgba(0,0,0,1) 0 1px 0; - -moz-box-shadow: rgba(0,0,0,1) 0 1px 0; - box-shadow: rgba(0,0,0,1) 0 1px 0; - text-shadow: rgba(0,0,0,.4) 0 1px 0; - color: white; - text-decoration: none; - vertical-align: middle; - font-weight: bold; -} -.create_new a.button:hover { - background: #57c246; - background: -webkit-gradient(linear, left top, left bottom, from(#0c9427), to(#57c246)); - background: -moz-linear-gradient(top, #0c9427, #57c246); - color: #ffffff; -} -.create_new a.button:active { - border-top-color: #1b435e; - background: #264d07; -} - - -/* Pagination links */ -.pagination a { padding: 5px 10px; border: 1px solid #ddd; background: #f8f8f8; border-radius: 4px; } -.pagination a.current { color: #aaa; } - - - -/* Messages Boxes use the great Silk icons from http://famfamfam.com/ */ -.message, .warning, .error, .success -{ - margin: 1em auto; - display: block; - padding: .8em 50px; - border: 1px solid #fff; -} -.message -{ - background: #F8FAFC url(../images/message.png) 20px center no-repeat; - border-color: #B5D4FE; -} -.warning -{ - background: #fff6bf url(../images/warning.png) 20px center no-repeat; - border-color: #ffd324; -} -.error -{ - background: #fde6e9 url(../images/error.png) 20px center no-repeat; - border-color: #fb939f; -} -.success -{ - background: #EBFCE1 url(../images/success.png) 20px center no-repeat; - border-color: #B9DAA6; -} diff --git a/Public/Admin/CSS/base.css b/Public/Admin/CSS/base.css deleted file mode 100755 index 115b73a..0000000 --- a/Public/Admin/CSS/base.css +++ /dev/null @@ -1,90 +0,0 @@ -/* -A CSS framework by David Pennington -Copyright 2011, MIT License -http://xeoncross.com -*/ - -/* Master Reset */ -*{vertical-align:baseline} -html,body,div,form,fieldset,input,textarea,th,td,h1,h2,h3,h4,h5,h6{margin:0;padding:0} -article,aside,figure,figcaption,hgroup,footer,header,nav,section,video,object{display:block} -th,td{text-align:left;vertical-align:top;padding:.5em;border:1px solid} -table{border-collapse:collapse;border-spacing:0;width:100%} -abbr,acronym{cursor:help;border-bottom:1px dotted} -fieldset,img{border:0} -pre{width:100%;white-space:pre;overflow:auto} -.reset,.reset *{font-weight:inherit;font-family:inherit;font-style:inherit;font-size:1em;border:0;outline:0;padding:0;margin:0} - -/* Form Reset (IE7+) */ -input[type=text],input[type=email],input[type=password],input[type=url],input[type=tel],html>body textarea -{ - width:100%; - padding:.5em; - margin:0 0 1.5em 0; - -webkit-box-sizing:border-box; /* Safari/Chrome, other WebKit */ - -moz-box-sizing:border-box; /* Firefox, other Gecko */ - box-sizing:border-box; /* Opera/IE 8+ */ -} - -/* 12 Column Grid System */ - -/* 1024px, 1152px, & 1280 screens */ -.grid_1{width:50px} -.grid_2{width:130px} -.grid_3{width:210px} -.grid_4{width:290px} -.grid_5{width:370px} -.grid_6{width:450px} -.grid_7{width:530px} -.grid_8{width:610px} -.grid_9{width:690px} -.grid_10{width:770px} -.grid_11{width:850px} -.grid_12{width:930px} -.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12 -{margin-left:30px;float:left;display:inline;/*overflow:hidden;*/} -.container{width:930px;margin:0 auto;/*overflow:hidden;*/} -.container .first, .container .grid_12{margin-left:0;clear:left} - -/* +1400px screens */ -@media only screen and (min-width:1400px){ -.grid_1{width:70px} -.grid_2{width:170px} -.grid_3{width:270px} -.grid_4{width:370px} -.grid_5{width:470px} -.grid_6{width:570px} -.grid_7{width:670px} -.grid_8{width:770px} -.grid_9{width:870px} -.grid_10{width:970px} -.grid_11{width:1070px} -.grid_12{width:1170px} -.container{width:1170px} -} - -/* Mobile Devices */ -@media only screen and (max-width:700px){ -.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12 -{width:100%;margin-left:0px} -.container{width:auto;margin:0 2em} -} - -/* Vertical Rhythm - Auto-ajusting Font/Line-Height Ratio */ -body{font-size:100%;line-height:1.5em;font-family:Georgia,serif;}/*IE*/ -html>body{font-size:1em} -p{margin:0 0 1.5em 0;padding:0} -h1,h2,h3,h4{font-weight:normal;line-height:1.5em} -h1{font-size:4em} -h2{font-size:3em} -h3{font-size:1.5em;line-height:2em} -h4{font-size:1em;font-weight:bold} -table{margin:1em 0} -th,td{border:1px solid;padding:.5em} -blockquote{margin:1.5em;font-style:italic} -ul,ol,dl{margin:1.5em;padding:0} -ul ul,ol ol{margin:0 2em} -pre{margin:1.5em 0;line-height:1.5em} -input,select{font-family:inherit;font-size:1em;/*line-height:1.5em;height:1.5em;*/} -textarea{margin:0 0 1.5em 0;height:9em;font-family:inherit;font-size:1em;} - diff --git a/Public/Admin/CSS/style.css b/Public/Admin/CSS/style.css deleted file mode 100755 index 2ea5e95..0000000 --- a/Public/Admin/CSS/style.css +++ /dev/null @@ -1,37 +0,0 @@ -table thead tr -{ - border-bottom: 1px solid #fff; - -moz-box-shadow: 0px 1px 2px #ddd; - -webkit-box-shadow: 0px 1px 2px #ddd; - box-shadow: 0px 1px 2px #ddd; -} - -table th -{ - background: #F7F7F7; /* old browsers */ - background: -moz-linear-gradient(top, #F7F7F7 0%, #EAEAEA 100%); /* firefox */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#F7F7F7), color-stop(100%,#EAEAEA)); /* webkit */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F7F7F7', endColorstr='#EAEAEA',GradientType=0 ); /* ie */ -} - -table tr { border: 1px solid #eee;} -table td, table th { border: 0; } -tr:nth-of-type(odd) { background-color:#f8f8f8; } - -table tr.header { border-bottom: 1px solid #ddd; } -table tr.header td { background: #eee; } - -/* Column Sorting Table Headers */ -table th a.sort_by {padding-right: 20px;} -table th a.down {background: url(../images/bullet_arrow_down.png) right no-repeat;} -table th a.up {background: url(../images/bullet_arrow_up.png) right no-repeat;} - -/* Special Links */ -a.delete, a.edit {margin: 0 .5em;} - -/* Form Reset (IE7+) */ -input[type=text],input[type=email],input[type=password],input[type=url],input[type=tel],html>body textarea -{ - border: 1px solid; - border-color: #888 #bbb #e2e2e2; -} diff --git a/Public/Admin/Images/bullet_arrow_down.png b/Public/Admin/Images/bullet_arrow_down.png deleted file mode 100755 index 9b23c06..0000000 Binary files a/Public/Admin/Images/bullet_arrow_down.png and /dev/null differ diff --git a/Public/Admin/Images/bullet_arrow_up.png b/Public/Admin/Images/bullet_arrow_up.png deleted file mode 100755 index 24df0f4..0000000 Binary files a/Public/Admin/Images/bullet_arrow_up.png and /dev/null differ diff --git a/Public/Admin/Images/error.png b/Public/Admin/Images/error.png deleted file mode 100755 index 08f2493..0000000 Binary files a/Public/Admin/Images/error.png and /dev/null differ diff --git a/Public/Admin/Images/famfamfam.com b/Public/Admin/Images/famfamfam.com deleted file mode 100755 index 9ed36ef..0000000 --- a/Public/Admin/Images/famfamfam.com +++ /dev/null @@ -1 +0,0 @@ -Images from: http://famfamfam.com diff --git a/Public/Admin/Images/message.png b/Public/Admin/Images/message.png deleted file mode 100755 index 12cd1ae..0000000 Binary files a/Public/Admin/Images/message.png and /dev/null differ diff --git a/Public/Admin/Images/success.png b/Public/Admin/Images/success.png deleted file mode 100755 index 89c8129..0000000 Binary files a/Public/Admin/Images/success.png and /dev/null differ diff --git a/Public/Admin/Images/warning.png b/Public/Admin/Images/warning.png deleted file mode 100755 index 628cf2d..0000000 Binary files a/Public/Admin/Images/warning.png and /dev/null differ diff --git a/Public/CSS/base.css b/Public/CSS/base.css deleted file mode 100755 index 6b99ce6..0000000 --- a/Public/CSS/base.css +++ /dev/null @@ -1,89 +0,0 @@ -/* -A CSS framework by David Pennington -Copyright 2011, MIT License -http://xeoncross.com -*/ - -/* Master Reset */ -*{vertical-align:baseline} -html,body,div,form,fieldset,input,textarea,th,td,h1,h2,h3,h4,h5,h6{margin:0;padding:0} -article,aside,figure,figcaption,hgroup,footer,header,nav,section,video,object{display:block} -th,td{text-align:left;vertical-align:top;padding:.5em;border:1px solid} -table{border-collapse:collapse;border-spacing:0;width:100%} -abbr,acronym{cursor:help;border-bottom:1px dotted} -fieldset,img{border:0} -pre{width:100%;white-space:pre;overflow:auto} -.reset,.reset *{font-weight:inherit;font-family:inherit;font-style:inherit;font-size:1em;border:0;outline:0;padding:0;margin:0} - -/* Form Reset (IE7+) */ -input[type=text],input[type=email],input[type=password],input[type=url],input[type=tel],html>body textarea -{ - width:100%; - padding:.5em; - -webkit-box-sizing:border-box; /* Safari/Chrome, other WebKit */ - -moz-box-sizing:border-box; /* Firefox, other Gecko */ - box-sizing:border-box; /* Opera/IE 8+ */ -} - -/* 12 Column Grid System */ - -/* 1024px, 1152px, & 1280 screens */ -.grid_1{width:50px} -.grid_2{width:130px} -.grid_3{width:210px} -.grid_4{width:290px} -.grid_5{width:370px} -.grid_6{width:450px} -.grid_7{width:530px} -.grid_8{width:610px} -.grid_9{width:690px} -.grid_10{width:770px} -.grid_11{width:850px} -.grid_12{width:930px} -.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12 -{margin-left:30px;float:left;display:inline;/*overflow:hidden;*/} -.container{width:930px;margin:0 auto;/*overflow:hidden;*/} -.container .first, .container .grid_12{margin-left:0;clear:left} - -/* +1400px screens */ -@media only screen and (min-width:1400px){ -.grid_1{width:70px} -.grid_2{width:170px} -.grid_3{width:270px} -.grid_4{width:370px} -.grid_5{width:470px} -.grid_6{width:570px} -.grid_7{width:670px} -.grid_8{width:770px} -.grid_9{width:870px} -.grid_10{width:970px} -.grid_11{width:1070px} -.grid_12{width:1170px} -.container{width:1170px} -} - -/* Mobile Devices */ -@media only screen and (max-width:700px){ -.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12 -{width:100%;margin-left:0px} -.container{width:auto;margin:0 2em} -} - -/* Vertical Rhythm - Auto-ajusting Font/Line-Height Ratio */ -body{font-size:100%;line-height:1.5em;font-family:Georgia,serif;}/*IE*/ -html>body{font-size:1em} -p{margin:0 0 1.5em 0;padding:0} -h1,h2,h3,h4{font-weight:normal;line-height:1.5em} -h1{font-size:4em} -h2{font-size:3em} -h3{font-size:1.5em;line-height:2em} -h4{font-size:1em;font-weight:bold} -table{margin:1em 0} -th,td{border:1px solid;padding:.5em} -blockquote{margin:1.5em;font-style:italic} -ul,ol,dl{margin:1.5em;padding:0} -ul ul,ol ol{margin:0 2em} -pre{margin:1.5em 0;line-height:1.5em} -input,select{margin:0 0 1.5em 0;font-family:inherit;font-size:1em;/*line-height:1.5em;height:1.5em;*/} -textarea{margin:0 0 1.5em 0;height:9em;font-family:inherit;font-size:1em;} - diff --git a/Public/CSS/style.css b/Public/CSS/style.css deleted file mode 100755 index 3f01b95..0000000 --- a/Public/CSS/style.css +++ /dev/null @@ -1,86 +0,0 @@ -/* Typography - Choose your font and size (base.css default is 16px) */ -body -{ - font-size:80%; - line-height:1.5em; - font-family:Helvetica,"Helvetica Neue",Arial,sans-serif; -} /*IE*/ -html>body{font-size:13px} -pre,code -{ - font-family:"DejaVu Sans Mono","Bitstream Vera Sans Mono",Monaco,"Courier New",monospace; -} - -header, #main, footer { float: left; width: 100%; } -#main { margin: 2em 0; } -a { text-decoration: none; color: #4B6E89;font-weight: bold; } -a:hover { color: #000; } - -header { border-bottom: 1px solid #ddd; } -header h1 { color: #ddd; margin: 0;line-height: 100px; } - -nav ul{ list-style: none;margin: 0;padding: 0;} -nav ul li { float: right;margin: 0 2em 0 0;line-height: 100px; } - -#sidebar h3 { margin-bottom: 5px; } -#sidebar ul { margin: 0; } -#sidebar ul li {list-style: none;border-bottom: 1px solid #eee;line-height: 2.4em;} -#sidebar ul li:hover { background: #f8f8f8; } - -footer { border-top: 1px solid #ddd; padding: 1em 0;color: #999;font-size: 12px; } -footer .stats { text-align:right; } - -/* Form element label */ -form.formstyle label -{ - margin: 0px; - display: inline; - line-height: 2em; - float: left; - width: 100%; -} -form.formstyle label b { float: left; } -form.formstyle label span -{ - color: #999; - display: block; - font-size: 12px; - float: right; - text-align: right; -} -form.formstyle .form_error -{ - color: #E83D1B; - font-weight: bold; - margin: -1.5em 0 1.5em 0; -} - -/* Messages Boxes use the great Silk icons from http://famfamfam.com/ */ -.message, .warning, .error, .success -{ - margin: 1em auto; - display: block; - clear: both; - padding: .8em 50px; - border: 1px solid #fff; -} -.message -{ - background: #F8FAFC url(../Images/message.png) 20px center no-repeat; - border-color: #B5D4FE; -} -.warning -{ - background: #fff6bf url(../Images/warning.png) 20px center no-repeat; - border-color: #ffd324; -} -.error -{ - background: #fde6e9 url(../Images/error.png) 20px center no-repeat; - border-color: #fb939f; -} -.success -{ - background: #EBFCE1 url(../Images/success.png) 20px center no-repeat; - border-color: #B9DAA6; -} diff --git a/Public/Images/error.png b/Public/Images/error.png deleted file mode 100755 index 08f2493..0000000 Binary files a/Public/Images/error.png and /dev/null differ diff --git a/Public/Images/famfamfam.com.txt b/Public/Images/famfamfam.com.txt deleted file mode 100755 index fd3f4df..0000000 --- a/Public/Images/famfamfam.com.txt +++ /dev/null @@ -1 +0,0 @@ -http://famfamfam.com \ No newline at end of file diff --git a/Public/Images/message.png b/Public/Images/message.png deleted file mode 100755 index 12cd1ae..0000000 Binary files a/Public/Images/message.png and /dev/null differ diff --git a/Public/Images/success.png b/Public/Images/success.png deleted file mode 100755 index 89c8129..0000000 Binary files a/Public/Images/success.png and /dev/null differ diff --git a/Public/Images/warning.png b/Public/Images/warning.png deleted file mode 100755 index 628cf2d..0000000 Binary files a/Public/Images/warning.png and /dev/null differ diff --git a/Public/index.php b/Public/index.php old mode 100755 new mode 100644 index c77170e..7373c18 --- a/Public/index.php +++ b/Public/index.php @@ -1,38 +1,110 @@ routes; + +// Default homepage route +if(PATH === '') +{ + $controller = $routes['']; +} +// If this is not a valid, safe path (more complex params belong in GET/POST) +else +{ + foreach($routes as $route => $resource) + { + if( ! $route) continue; // Skip homepage route + + // Is this a regex? + if($route{0} === '/') + { + if(preg_match($route, $path, $matches)) + { + $complete = array_shift($matches); + + // The following code tries to solve: + // (Regex) "/^path/(\w+)/" + (Path) "path/word/other" = (Params) array(word, other) + + // Skip the regex match and continue from there + $params = explode('/', trim(mb_substr($path, mb_strlen($complete)), '/')); + + if($params[0]) + { + // Add captured group back into params + foreach($matches as $match) + { + array_unshift($params, $match); + } + } + else + { + $params = $matches; + } + + $controller = $resource; + } + } + else + { + if(mb_substr($path, 0, mb_strlen($route)) === $route) + { + $params = explode('/', trim(mb_substr($path, mb_strlen($route)), '/')); + $controller = $resource; + } + } + + if($controller) break; + } + + // Controller not found + if( ! $controller) + { + $controller = $routes['404']; + } +} + +// Remove to free memory +unset($routes); +config('Route', TRUE); + try { - // Anything else before we start? - event('system.startup'); + // Get the controller method + list($controller, $method) = explode('::', $controller) + array('', 'index'); - // Load controller dispatch passing URL routes - $dispatch = new \Core\Dispatch(config('Route')->routes); + // Load the controller + $controller = new $controller; - // Run controller based on URL path and HTTP request method - $controller = $dispatch->controller(PATH, getenv('REQUEST_METHOD')); + // Allow REST-specific methods (is it safe to use REQUEST_METHOD like this?) + if(method_exists($controller, getenv('REQUEST_METHOD') . $method)) + { + $method = getenv('REQUEST_METHOD') . $method; + } - // Send the controller response - $controller->send(); + // Run before + $controller->before($method); - // One last chance to do something - event('system.shutdown', $controller); + // Let the controller take it from here! + $result = call_user_func_array(array($controller, $method), $params); + + // Run after + $controller->after($method, $result); } catch (Exception $e) { - \Core\Error::exception($e); + \Micro\Error::exception($e); } - +// κόψη/bar/ዕንቁላል/Зарегистрируйте4сь +//var_dump(get_defined_vars()); diff --git a/README.markdown b/README.markdown index 804c8f0..b695910 100755 --- a/README.markdown +++ b/README.markdown @@ -10,21 +10,42 @@ MicroMVC is also fully PSR-0 compliant which means you can start using Symfony, All class methods are fully documented. Average class size is only 4kb which makes reading the codebase very easy and quick. IDE's such as eclipse or netbeans can pickup on the phpDoc comments to add instant auto-completion to your projects. In addition, full multi-byte string support is built into the system. -## Requirements +## Submodules + +This system is built to be used with *other PSR-0 compliant libraries*. These can be used easily by adding submodules to the `Class` directory and adding the correct "namespace" path to the `Config/Config.php` file. For example, to use [Zend Framework 2](https://github.com/zendframework/zf2) run the following commands. + + $ git submodule add git://github.com/zendframework/zf2.git Class/Zend + +Then add the following configuration path to the `Config/Config.php` file so the system knows where to load the classes from. + + $config['namespaces'] = array( + 'Zend' => 'Zend/library/Zend/' + ); + + +This system relies on the [Xeoncross/Micro](https://github.com/Xeoncross/Micro) submodule. After checking out a copy of the system, please run the following commands to pull the submodules. + + $ git submodule init + $ git submodule update + +You can add additional libraries as shown above. + +## Requirements * PHP 5.3+ * Nginx 0.7.x (legacy support for Apache with mod_rewrite) * PDO if using the Database -* mb_string, [gettext](http://php.net/gettext), [iconv](http://www.php.net/manual/en/book.iconv.php), [ICU INTL](http://php.net/manual/en/book.intl.php) & SPL classes +* mb_string, gettext, iconv, & SPL classes + + +## License (MIT License) -## Where is the Locale Class? +Copyright (c) 2011 [David Pennington](http://xeoncross.com) -If you have errors about missing classes make sure you have the required PHP extensions installed. +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -Ubuntu/Debian: `$ sudo apt-get install php5-intl php5-mycrypt php-gettext` +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -## License +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -[MicroMVC](http://micromvc.com) is licensed under the Open Source MIT license, so you can use it for any personal or corporate projects totally free!

-Built by [David Pennington](http://xeoncross.com) of [Code2Design](http://code2design.com) diff --git a/README/install.txt b/README/install.txt index 2e84558..156b919 100755 --- a/README/install.txt +++ b/README/install.txt @@ -11,3 +11,15 @@ A CLI console is provided for using the migrations $ php CLI create The code is very well commented, please read it. + +--- Submodules --- + +This system relies on the https://github.com/Xeoncross/Micro submodule. After checking out a copy of the system, please run the following commands to pull the submodules. + +$ git submodule init +$ git submodule update + +You can add additional libraries to the classes folder like so + +$ git submodule add git://github.com/[User]/[project].git Class/[project] + diff --git a/View/404.php b/View/Example/404.php similarity index 100% rename from View/404.php rename to View/Example/404.php diff --git a/View/Index/Index.php b/View/Example/Index.php similarity index 100% rename from View/Index/Index.php rename to View/Example/Index.php diff --git a/View/Layout.php b/View/Example/Layout.php similarity index 100% rename from View/Layout.php rename to View/Example/Layout.php diff --git a/View/School/Index.php b/View/Example/School.php similarity index 100% rename from View/School/Index.php rename to View/Example/School.php diff --git a/View/Sidebar.php b/View/Example/Sidebar.php similarity index 100% rename from View/Sidebar.php rename to View/Example/Sidebar.php diff --git a/View/System/Debug.php b/View/System/Debug.php index fb8f974..09930a5 100755 --- a/View/System/Debug.php +++ b/View/System/Debug.php @@ -20,14 +20,14 @@ ', TRUE),36)); }; - foreach(\Core\Database::$queries as $type => $queries) + foreach(\Micro\Database::$queries as $type => $queries) { print ''.$type.' ('. count($queries). ' queries)'; foreach($queries as $data) @@ -36,10 +36,10 @@ } } - if(\Core\Error::$found) + if(\Micro\Error::$found) { print 'Last Query Run'; - print '
'. $highlight(\Core\DataBase::$last_query). '
'; + print '
'. $highlight(\Micro\DataBase::$last_query). '
'; } } ?> diff --git a/View/System/Error.php b/View/System/Error.php index c06d187..c83851e 100755 --- a/View/System/Error.php +++ b/View/System/Error.php @@ -31,7 +31,7 @@ $line) diff --git a/View/System/Exception.php b/View/System/Exception.php index 669ec88..bad479e 100755 --- a/View/System/Exception.php +++ b/View/System/Exception.php @@ -51,7 +51,7 @@ // Print file, line, and source print ' in '. $line['file']. ' ['. $line['line']. ']'; - print ''. \Core\Error::source($line['file'], $line['line']). ''; + print ''. \Micro\Error::source($line['file'], $line['line']). ''; if(isset($line['args'])) {