Created
June 9, 2013 19:09
-
-
Save betaman/5744783 to your computer and use it in GitHub Desktop.
Elefant CMS JSON App: Retrieve Data as JSON For Singlepage Websites
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Json extends \Restful { | |
// Accessible via: | |
// `GET /json/api/run/layout/index` | |
// retrieves controller run data from page and all includes in a layout template | |
// `GET /json/api/run/page/index` | |
// retrieves controller run data from page | |
// `GET /json/api/run/blocks/index?id=sidebar-testpage' | |
// retrieves controller run data from handler | |
// TODO get data of db table | |
// `GET /json/api/data/layout/index` | |
// retrieves data from page and all includes in a layout template | |
// `GET /json/api/data/page/index` | |
// retrieves data from page | |
// `GET /json/api/data/blocks/index?id=sidebar-testpage' | |
// retrieves data from handler | |
public function get_run(){ | |
// get arguments and params | |
$params = func_get_args (); | |
$data = $_GET; | |
$this->wrap = true; | |
$handler = $params[0]; | |
// return page or page and all includes of the layout | |
if ($handler === "page" || $handler === "layout") { | |
// get pageId | |
$id = $params[1]; | |
if ($id) { | |
$page = $this->get_rendered_page ($id); | |
if ($handler === "layout") { | |
$page->includes = $this->get_includes($page->layout, $id); | |
} | |
return $page; | |
} | |
} | |
// return the include | |
else { | |
return $this->get_include(); | |
} | |
} | |
private function get_template_file ($template) { | |
$tpl = new Template(); | |
// Resolve the template to a file name, in one of: | |
// `apps/appname/views/filename.html` | |
// `layouts/themename/filename.html` | |
// `layouts/filename.html` | |
// `layouts/filename/filename.html` | |
// `layouts/default.html` | |
if (strstr ($template, '/')) { | |
list ($app, $view) = preg_split ('/\//', $template, 2); | |
$file = sprintf ($tpl->view_folders, $app, $view . '.' . $tpl->file_extension); | |
if (! file_exists ($file)) { | |
$file = $tpl->layouts_folder . '/' . $app . '/' . $view . '.' . $tpl->file_extension; | |
if (! file_exists ($file)) { | |
throw new RuntimeException ('Template not found: ' . $template); | |
} | |
} | |
} elseif (file_exists ($tpl->layouts_folder . '/' . $template . '.' . $tpl->file_extension)) { | |
$file = $tpl->layouts_folder . '/' . $template . '.' . $tpl->file_extension; | |
} elseif (file_exists ($tpl->layouts_folder . '/' . $template . '/' . $template . '.' . $tpl->file_extension)) { | |
$file = $tpl->layouts_folder . '/' . $template . '/' . $template . '.' . $tpl->file_extension; | |
} else { | |
$file = $tpl->layouts_folder . '/' . $tpl->default_layout . '.' . $tpl->file_extension; | |
} | |
$out = file_get_contents ($file); | |
return $out; | |
// TODO caching | |
/* | |
// The cache file is named based on the original | |
$cache = $this->cache_folder . '/' . str_replace ('/', '-', $template) . '.php'; | |
if (! file_exists ($cache) || filemtime ($file) > filemtime ($cache)) { | |
// Regenerate cached file | |
$out = file_get_contents ($file); | |
$out = $this->parse_template ($out); | |
if (! is_writeable (dirname ($cache))) { | |
die ('Cache folder must be writeable to continue. Please check the <a href="http://www.elefantcms.com/wiki/Installing-Elefant" target="_blank">installation instructions</a> and try again.'); | |
} | |
if (! file_put_contents ($cache, $out)) { | |
throw new RuntimeException ('Failed to generate cached template: ' . $cache); | |
} | |
} | |
ob_start (); | |
require ($cache); | |
return ob_get_clean (); | |
*/ | |
} | |
// returns an array with all includes used in the layout template | |
// (ie '/layouts/default.html' ) | |
private function get_includes($layout, $id){ | |
$val = $this->get_template_file($layout); | |
$tpl = new Template(); | |
// remove spaces | |
$val = preg_replace ('/[\t\n ]+(\?|\&)/', '\1', trim ($val)); | |
// normalize <span data-embed> tags to {! tags !} | |
$val = preg_replace ('/<[^>]*?data-embed="([^"]+)".*?>.*?<\/.*?>/', '{! \1 !}', $val); | |
$parts = preg_split ('/(\{\! ?.*? ?\!\})/e', $val, -1, PREG_SPLIT_DELIM_CAPTURE); | |
$out = ''; | |
$includes = array(); | |
foreach ($parts as $part) { | |
if (strpos ($part, '{! ') === 0) { | |
$part = trim ($part, '{! }'); | |
$part = str_replace("[id]", $id, $part); | |
$include = array(handler=>$part, rendered=>$this->get_include($part)); | |
array_push($includes, $include); | |
} | |
} | |
return $includes; | |
} | |
private function get_include($val="") { | |
// if no value is provided | |
// host, path and params are extracted from the URI | |
if($val === ""){ | |
array_shift($this->controller->params); | |
$params = $this->controller->params; | |
$data = $_GET; | |
$url['host'] = ''; | |
$url['path'] = implode("/", $params ); | |
} | |
// if a value is provided | |
// host, path and params are extracted from the passed String | |
else { | |
$url = parse_url ($val); | |
if (! isset ($url['host'])) { | |
$url['host'] = ''; | |
} | |
$params = explode("/", $url['path']); | |
if (isset ($url['query'])) { | |
parse_str (html_entity_decode ($url['query'], ENT_COMPAT, 'UTF-8'), $data); | |
} else { | |
$data = array (); | |
} | |
} | |
// run the controller to get the output | |
$out = $this->controller->run ($url['host'] . $url['path'], $data); | |
return $out; | |
} | |
private function get_rendered_page ($id) { | |
if (! User::require_admin ()) { | |
$page = Webpage::query () | |
->where ('access', 'public') | |
->where ('id', $id) | |
->single (); | |
} else { | |
$page = Webpage::query () | |
->where ('id', $id) | |
->single (); | |
} | |
if ($page) { | |
// convert it from a Webpage object into an ordinary object | |
$orig = $page->orig (); | |
// create the Output Object | |
$out = new stdClass(); | |
$out->id = $id; | |
$out->title = $orig->title; | |
$out->menu_title = ($orig->menu_title === "") ? $out->title : $orig->menu_title; | |
$out->window_title = ($orig->window_title === "") ? $out->title : $orig->window_title; | |
$out->access = $orig->access; | |
$out->layout = $orig->layout; | |
$out->description = $orig->description; | |
$out->keywords = $orig->keywords; | |
// use Navigation to get the path | |
$n = new Navigation; | |
$out->path = $n->path ($id); | |
// run the controller to get the output | |
$controller = new Controller (conf ('Hooks')); | |
$tpl = new Template (conf ('General', 'charset'), $controller); | |
$out->body = $tpl->run_includes ($orig->body); | |
if (User::require_admin ()) { | |
// show admin edit buttons | |
if (User::is_valid () && User::is ('admin')) { | |
$lock = new Lock ('Webpage', $id); | |
$out->locked = $lock->exists (); | |
$out->body = $tpl->render ('admin/editable', $orig) . $out->body; | |
} | |
} | |
$out->body = str_replace("/json/api/page/", "/", $out->body); | |
} | |
// Return some data | |
return $out; | |
} | |
//TODO povide an Interface for PUT, POST and DELETE | |
// Accessible via `POST /myapp/api/article` | |
public function post_page () { | |
// Return an error | |
return $this->error ('Error message'); | |
} | |
} | |
?> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment