core/ApiController.php
<?php
use fixate as f8;
use ProcessWire as PW;
abstract class ApiController implements IController
{
public $config = null;
public $fields = null;
public $input = null;
public $page = null;
public $pages = null;
public $permissions = null;
public $roles = null;
public $sanitizer = null;
public $session = null;
public $templates = null;
public $user = null;
public $users = null;
protected $request = null;
protected $response = null;
public function __construct(&$config, &$fields, &$input, &$page, &$pages, &$permissions, &$roles, &$sanitizer, &$session, &$templates, &$user, &$users)
{
$this->config = $config;
$this->fields = $fields;
$this->input = $input;
$this->page = $page;
$this->pages = $pages;
$this->permissions = $permissions;
$this->roles = $roles;
$this->sanitizer = $sanitizer;
$this->session = $session;
$this->templates = $templates;
$this->user = $user;
$this->users = $users;
}
public function call()
{
$req = $this->request = f8\HttpRequest::instance();
$this->response = new f8\HttpResponse();
$method = strtolower($req->method());
$ret = null;
try {
/**
* Implement HTTP verbs explicitly as public methods in your controller
*/
if (method_exists($this, $method)) {
$ret = $this->$method();
// Just die on redirect
if ($this->response->is_redirect()) {
die();
}
// Body set, just return the response
$body = $this->response->body();
if (!$this->empty($body)) {
return $this->response;
}
// Set created status on sucessfull post
if ($method == 'post' && $ret && $this->response->status() == 0) {
$this->response->set_status(201); // CREATED
}
} elseif (method_exists($this, 'all')) {
$ret = $this->all();
} elseif ($method == 'get') {
$ret = $this->page_data();
} else {
throw new f8\HttpException(405, "Method '$method' not allowed for resource.");
}
} catch (f8\HttpException $ex) {
$this->response->set_status($ex->getStatusCode());
$this->response->set_header('Allow', implode(', ', $this->get_allowed()));
$this->response->set_body(json_encode(array('error' => $ex->getMessage())));
} catch (Exception $ex) {
$this->response->set_status(500);
$this->response->set_body(json_encode(array('error' => $ex->getMessage())));
return $this->response;
}
// Set NO CONTENT on blank responses
$body = $this->response->body();
if ($this->empty($ret) && $this->empty($body)) {
if ($this->response->status() == 0) {
$this->response->set_status(204); // No content
}
return $this->response;
}
if (!$this->empty($ret)) {
// Serialize to JSON
if (is_array($ret) || is_object($ret)) {
$this->response->set_header('Content-Type', 'application/json');
$this->response->set_body(json_encode($ret));
} elseif (is_string($ret)) {
if (f8\Strings::starts_with(trim($ret), '<') && f8\Strings::ends_with(trim($ret), '>')) {
$this->response->set_header('Content-Type', 'text/html');
} else {
$this->response->set_header('Content-Type', 'text/plain');
}
$this->response->set_body($ret);
}
}
return $this->response;
}
// Do nothing - override if required
public function before()
{
}
public function after()
{
}
public function helper($func)
{
if (!is_callable($func)) {
$func = array($this, $func);
}
View::add_helper($func);
}
// Get user settings
protected function setting($name)
{
static $settings = null;
if ($settings == null) {
$settings = PW\wire('pages')->get('/settings/');
}
return $settings->$name;
}
// Get rendered partial
protected function partial($name, $data = array())
{
return $this->get_view()->partial($name, $data);
}
protected function get_view()
{
if (isset($this->view)) {
return $this->view;
}
$view = new View($this);
$view->set_base_path(f8\Paths::join($this->config->paths->templates, 'views'));
$view->set_asset_uri(f8\Paths::join($this->config->urls->templates, 'assets'));
return $this->view = $view;
}
protected function get_allowed()
{
return array_filter(f8\HttpRequest::$http_methods, function ($m) {
return $m == 'GET' || method_exists($this, strtolower($m));
});
}
protected function param($name)
{
if (!$this->request) {
return;
}
return $this->request->param($name);
}
protected function page_data()
{
$fields = func_get_args();
$page = &$this->page;
return $this->get_page_data($page, $fields);
}
protected function get_page_data($page, array $fields = [])
{
$outputFormatting = $page->outputFormatting;
$page->setOutputFormatting(false);
if (empty($fields)) {
$fields = array(
'id', 'parent_id', 'templates_id', 'name', 'status', 'sort',
'sortfield', 'numChildren', 'template', 'parent', 'data', 'url'
);
}
$data = array();
$has_data_field = false;
foreach ($fields as $f) {
switch ($f) {
case 'data':
$has_data_field = true;
break;
case 'template':
$data['template'] = $page->template->name;
break;
case 'parent':
$data['parent'] = $page->parent->path;
break;
default:
$data[$f] = $page->$f;
}
}
if ($has_data_field) {
$data['data'] = array();
foreach ($page->template->fieldgroup as $field) {
if ($field->type instanceof FieldtypeFieldsetOpen) {
continue;
}
$value = $page->get($field->name);
$data['data'][$field->name] = $field->type->sleepValue($page, $field, $value);
}
}
$page->setOutputFormatting($outputFormatting);
return $data;
}
private function empty($value)
{
return empty($value) && gettype($value) != 'array';
}
}