Skip to content

Instantly share code, notes, and snippets.

@Jach
Created January 5, 2011 02:49
Show Gist options
  • Save Jach/765851 to your computer and use it in GitHub Desktop.
Save Jach/765851 to your computer and use it in GitHub Desktop.
micro-framework pieces
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond $1 !^(index\.php|imgs|js|css|flex|public|robots\.txt)
RewriteRule ^(.*)$ /index.php?/$1 [L]
<?php
/* Core "framework" code.
* All Serviecs should inherit from this class.
*
* For App-Specific functions, use BaseAppService which inherits
* from this. In general, your Service classes should really
* inherit from the BaseAppService.
*/
class BaseService {
function display_page($template_data) {
// Required data:
// title -- page title
// master -- master source template, e.g. main.tpl
//
// Sample other data:
// content -- page content
if (!isset($template_data['title']))
$template_data['title'] = APP_TITLE;
if (!isset($template_data['master']))
$template_data['master'] = 'main.tpl';
if (!isset($template_data['content']))
$template_data['content'] = NULL;
extract($template_data);
if ($content && !is_array($content)) {
$file = APP_URI . "templates/$content";
if (substr($content, -4) == '.tpl' && file_exists($file))
$content = $this->get_include_contents($file, $template_data);
}
$master_file = APP_URI . "templates/$master";
if (file_exists($master_file))
require_once $master_file;
}
function get_include_contents($file, $vars=array()) {
// precondition: caller checks to see if file exists
extract($vars);
ob_start();
include $file;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
function insert_template($template, $vars = array()) {
extract($vars);
$file = APP_URI . "templates/$template";
if (file_exists($file))
require_once $file;
}
function map_url_to_func() {
$uri = (($_SERVER["REQUEST_URI"]!="/") ? $_SERVER["REQUEST_URI"] : "/home");
$uri = substr($uri, 1); // gets rid of first /
if ($uri{strlen($uri)-1} == '/')
$uri = substr($uri, 0, -1); // gets rid of last /
$uri_parts = explode('/',$uri);
$params = array();
$call = '';
foreach($this->urls as $url => $function) {
list($types, $url) = explode(':', $url);
if ($url{0} == '/')
$url = substr($url, 1); // chop the first / if there
$url_parts = explode('/', $url);
if (count($url_parts) != count($uri_parts)) {
continue; // not this url
} elseif ($url == implode('/', $uri_parts)) { // exact, found it
$call = $function;
if (stripos($types, 'get') !== FALSE)
$params = array_merge($params, $_GET);
if (stripos($types, 'post') !== FALSE)
$params = array_merge($params, $_POST);
break;
} else {
$vars = array();
foreach($url_parts as $key => $section) {
if ($section == $uri_parts[$key]) { // good so far
continue;
} elseif ($section{0} == '@') { // it's a var?
$var = substr($section, 1); // chop off @
$vars = array_merge($vars, array($var => $uri_parts[$key]));
$call = $function;
} else { // doesn't match at all
$call = '';
break;
}
}
if (!empty($call)) { // found it
$params = array_merge($params, $vars);
if (stripos($types, 'get') !== FALSE)
foreach($_GET as $k => $v)
if ($v)
$params[$k] = $v;
if (stripos($types, 'post') !== FALSE)
$params = array_merge($params, $_POST);
break;
}
}
}
return array('call' => $call, 'params' => $params);
}
function __construct($func_data = array()) {
// This and the mapping function is essentially my micro-framework heart.
// See HomeService or one of the other services for how it's used.
// Requirements at the bottom are json and output buffering,
// but are only really necessary if you want nice JavaScript interfacing.
if (empty($func_data)) {
$func_data = $this->map_url_to_func();
// semi expensive operation, no need to calculate it twice if
// we already had to for helping the caching system.
}
extract($func_data);
if (method_exists($this, $call)) {
$result = $this->$call($params);
// Comment the rest of this if you don't have json or OB
$contents = ob_get_contents();
if (empty($contents))
echo json_encode($result);
} else {
$this->not_found();
}
}
function render_response($func_data = array()) {
// Aliased in case you have instantiated something internally but want to render
// it in the end. (e.g. some implementation of a cacher.)
self::__construct($func_data);
}
}
?>
<?php
ob_start();
require_once '../app/config/config.inc.php';
require_once '../app/config/global_functions.php';
$uri = (($_SERVER["REQUEST_URI"]!="/") ? $_SERVER["REQUEST_URI"] : "/home");
$uri = substr($uri, 1); // gets rid of first /
if ($uri{strlen($uri)-1} == '/')
$uri = substr($uri, 0, -1); // gets rid of last /
$uri_parts = explode('/',$uri);
$service = $uri_parts[0];
switch($service) {
// Secure pages
case 'admin': $serviceClass = 'AdminService'; break;
case 'account': $serviceClass = 'AccountService'; break;
// Public pages
case 'user': $serviceClass = 'UserService'; break;
case 'feed': $serviceClass = 'FeedService'; break;
// Home (also public)
case 'index':
case 'home':
case 'about':
case 'view':
default: $serviceClass = 'HomeService'; break;
}
$handler = new $serviceClass();
// footer stuff
session_write_close();
if (isset($dbc)) {
mysqli_close($dbc);
unset($dbc);
}
ob_end_flush();
?>
<?php
class HomeService extends BaseAppService {
function __construct($internal=0) {
$this->urls = array(
'get:/index.php' => 'display_home_page'
, 'get:/home' => 'display_home_page'
, 'get:/index' => 'display_home_page'
, 'get:/home/page/@page' => 'display_home_page'
, ':/about' => 'display_about_page'
, 'get:/view/posts/count/@year/@month' => 'count_posts_from'
);
if(!$internal) parent::__construct();
}
...
function display_about_page($params) {
$template_data = array(
'title' => 'About Jach'
, 'content' => 'content/about.tpl'
, 'master' => 'main.tpl'
);
$this->display_page($template_data);
}
function count_posts_from($params) {
global $dbc;
$year = (int) $params['year'];
$month = isset($params['month']) ? (int) $params['month'] : 0;
$q = "SELECT COUNT(id) FROM posts WHERE YEAR(post_date) = $year ";
if ($month)
$q .= "AND MONTH(post_date) = $month";
$r = mysqli_query($dbc, $q);
$count = mysqli_fetch_row($r);
return $count[0];
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment