diff --git a/bin/request b/bin/request index 03c11bc..613dc0a 100644 --- a/bin/request +++ b/bin/request @@ -1,33 +1,33 @@ _args = $args; - + if(!Shell::instance()->isLoggedIn()){ throw new Exception('Valid authentication token must be supplied.'); } if(!Shell::instance()->Author->isDeveloper()){ throw new Exception('Only developers can enable maintenance mode'); - } + } require_once(CORE . '/class.frontend.php'); // include the extension core require_once(EXTENSIONS . '/rest_api/lib/class.rest_api.php'); - + $_REQUEST['token'] = Shell::instance()->Author->createAuthToken(); $_REQUEST['url'] = $this->get_argument('path', '/'); $_REQUEST['format'] = strtolower($this->get_argument('format', 'xml')); $_SERVER['REQUEST_METHOD'] = strtolower($this->get_argument('method', 'GET')); - + REST_API::init(); - + } - + private function get_argument($name, $default) { foreach($this->_args as $i=> $args) { if($args == ('-' . $name)) { @@ -36,7 +36,7 @@ } return $default; } - + } return 'Request_REST_API'; diff --git a/data-sources/data.rest_api_entries.php b/data-sources/data.rest_api_entries.php index fd0a27a..17496df 100644 --- a/data-sources/data.rest_api_entries.php +++ b/data-sources/data.rest_api_entries.php @@ -3,7 +3,7 @@ require_once(TOOLKIT . '/class.datasource.php'); require_once(TOOLKIT . '/class.fieldmanager.php'); require_once(EXTENSIONS . '/rest_api/plugins/entries/rest.entries.php'); - + Class DatasourceREST_API_Entries extends SectionDatasource { public $dsParamROOTELEMENT = 'response'; @@ -30,7 +30,7 @@ public function getSource(){ return REST_Entries::getSectionId(); } - public function grab(array &$param_pool = NULL){ + public function grab(array &$param_pool = null){ // remove placeholder elements unset($this->dsParamINCLUDEDELEMENTS); @@ -76,7 +76,7 @@ public function grab(array &$param_pool = NULL){ foreach(REST_Entries::getDatasourceParam('filters') as $field_handle => $filter_value) { $filter_value = rawurldecode($filter_value); $field_id = FieldManager::fetchFieldIDFromElementName( - $field_handle, + $field_handle, REST_Entries::getSectionId() ); if(is_numeric($field_id)) $this->dsParamFILTERS[$field_id] = $filter_value; @@ -87,4 +87,4 @@ public function grab(array &$param_pool = NULL){ return $this->execute($param_pool); } - } \ No newline at end of file + } diff --git a/extension.driver.php b/extension.driver.php index 1ca8f4d..ad29d5e 100644 --- a/extension.driver.php +++ b/extension.driver.php @@ -1,7 +1,7 @@ + + - Update for Symphony 4.x + - PHP7 Compatibility + - Replace deprecated method fetch() by select() + - Update for Symphony 2.6 diff --git a/lib/class.rest_api.php b/lib/class.rest_api.php index 37b293e..842c559 100644 --- a/lib/class.rest_api.php +++ b/lib/class.rest_api.php @@ -3,122 +3,122 @@ if(!class_exists('XMLToArray')) require_once('class.xmltoarray.php'); Class REST_API { - - private static $_is_frontend_page = FALSE; - - private static $_uri = NULL; - private static $_token = NULL; - private static $_output_type = NULL; - private static $_http_method = NULL; - private static $_plugin_name = NULL; - private static $_plugin_class = NULL; - + + private static $_is_frontend_page = false; + + private static $_uri = null; + private static $_token = null; + private static $_output_type = null; + private static $_http_method = null; + private static $_plugin_name = null; + private static $_plugin_class = null; + private static function __authenticate() { $logged_in = Symphony::Engine()->isLoggedIn(); if (!$logged_in) self::sendError('API is private. Authentication failed.', 403); } - - public static function isFrontendPageRequest($is_frontend_page=NULL) { + + public static function isFrontendPageRequest($is_frontend_page = null) { if(isset($is_frontend_page)) self::$_is_frontend_page = $is_frontend_page; return self::$_is_frontend_page; } - + public static function getOutputFormat() { return self::$_output_type; } - + public static function getHTTPMethod() { return self::$_http_method; } - + public static function init() { - + // store request parameters for later self::$_token = trim($_REQUEST['token']); - self::$_output_type = (isset($_REQUEST['format']) ? $_REQUEST['format'] : 'xml'); + self::$_output_type = (isset($_REQUEST['format']) ? $_REQUEST['format'] : 'xml'); self::$_uri = explode('/', trim($_REQUEST['url'], '/')); self::$_http_method = strtolower($_SERVER['REQUEST_METHOD']); - + // get plugin name from the first segment in the URL // and remove it from the URL segments list $plugin_name = strtolower(self::$_uri[0]); self::$_plugin_name = $plugin_name; self::$_plugin_class = 'REST_' . ucfirst($plugin_name); array_shift(self::$_uri); - + // include the plugin! require_once(EXTENSIONS . "/rest_api/plugins/$plugin_name/rest.$plugin_name.php"); if (!class_exists(self::$_plugin_class)) REST_API::sendError(sprintf("Plugin '%s' does not exist.", self::$_plugin_class), 404); - + // perform global API authentication self::__authenticate($plugin_class); - + // initialise the plugin if(method_exists(self::$_plugin_class, 'init')) call_user_func(array(self::$_plugin_class, 'init')); - + // perform plugin authentication if(method_exists(self::$_plugin_class, 'authenticate')) call_user_func(array(self::$_plugin_class, 'authenticate')); - + if(method_exists(self::$_plugin_class, self::$_http_method)) { call_user_func(array(self::$_plugin_class, self::$_http_method)); } else { REST_API::sendError(sprintf("Plugin '%s' does not support HTTP %s.", self::$_plugin_class, strtoupper($method)), 401); } } - + public static function getRequestURI() { return self::$_uri; } - - public static function sendOutput($response_body=NULL, $code=200) { - + + public static function sendOutput($response_body = null, $code = 200) { + switch($code) { case 200: header('HTTP/1.0 200 OK'); break; case 401: header('HTTP/1.0 401 Bad Request'); break; case 403: header('HTTP/1.0 403 Forbidden'); break; case 404: header('HTTP/1.0 404 Not Found'); break; } - + $xml = $response_body; if(is_array($xml)) $xml = reset($xml); - if($xml instanceOf XMLElement) $xml = $xml->generate(TRUE); - + if($xml instanceOf XMLElement) $xml = $xml->generate(true); + switch(self::$_output_type) { - + case 'json': header('Content-Type: text/plain; charset=utf-8'); - $output = json_encode(XMLToArray::convert($xml)); + $output = json_encode(XMLToArray::convert($xml)); break; - + case 'serialise': case 'serialize': header('Content-Type: text/plain; charset=utf-8'); $output = serialize(XMLToArray::convert($xml)); break; - + case 'yaml': header('Content-Type: text/plain; charset=utf-8'); require_once('spyc-0.4.5/spyc.php'); $output = Spyc::YAMLDump(XMLToArray::convert($xml)); break; - + case 'xml': header('Content-Type: text/xml; charset=utf-8'); $output = $xml; break; - + case 'csv': header('Content-Type: text/plain; charset=utf-8'); - + $entries = XMLToArray::convert($xml); $entries = $entries['response']['entry']; - + $file_name = sprintf('%s/%s-%d.csv', TMP, self::$_plugin_name, time()); $csv = fopen($file_name, 'w'); - + $columns = array(); $rows = array(); - + // iterate over all entries to build columns. do not assume that the // first entry has all fields (if a value is missing the field will not be present!) foreach($entries as $entry) { @@ -126,9 +126,9 @@ public static function sendOutput($response_body=NULL, $code=200) { if(!in_array($handle, $columns)) $columns[] = $handle; } } - + fputcsv($csv, $columns, ',', '"'); - + foreach($entries as $entry) { $row = array(); // build the data for each field in this entry @@ -149,26 +149,26 @@ public static function sendOutput($response_body=NULL, $code=200) { } fputcsv($csv, $row, ',', '"'); } - + fclose($csv); $output = file_get_contents($file_name); unlink($file_name); - + break; } - + echo $output; exit; } - - public static function sendError($message=NULL, $code=200, $format=NULL) { + + public static function sendError($message = null, $code = 200, $format = null) { if($format) self::$_output_type = $format; - $response = new XMLElement('response', NULL, array( + $response = new XMLElement('response', null, array( 'result' => 'error', 'code' => $code )); $response->appendChild(new XMLElement('error', $message)); self::sendOutput($response, $code); } - -} \ No newline at end of file + +} diff --git a/plugins/authors/rest.authors.php b/plugins/authors/rest.authors.php index 7497d13..f482e7b 100644 --- a/plugins/authors/rest.authors.php +++ b/plugins/authors/rest.authors.php @@ -3,15 +3,15 @@ require_once(TOOLKIT . '/class.authormanager.php'); Class REST_Authors { - + public static function init() { if(REST_API::getOutputFormat() == 'csv') { REST_API::sendError(sprintf('%s output format not supported.', strtoupper(REST_API::getOutputFormat())), 401, 'xml'); } } - + public static function get() { - + $url_parts = REST_API::getRequestURI(); $author_url = $url_parts[0]; @@ -19,24 +19,27 @@ public static function get() { if (isset($author_url)) { if (is_numeric($author_url)) { - $author = AuthorManager::fetchByID($author_url); + $author = AuthorManager::fetchByID($author_url); } else { $author = AuthorManager::fetchByUsername($author_url); } if(!$author) REST_API::sendError('Author not found.', 404); $response->appendChild(self::__buildAuthorXML($author)); } else { - $authors = AuthorManager::fetch(); + $authors = (new AuthorManager) + ->select() + ->execute() + ->rows(); foreach($authors as $author){ $response->appendChild(self::__buildAuthorXML($author)); } } - - REST_API::sendOutput($response); + + REST_API::sendOutput($response); } - + private static function __buildAuthorXML($author){ - + $author_xml = new XMLElement('author'); foreach($author->get() as $key => $value){ @@ -47,8 +50,8 @@ private static function __buildAuthorXML($author){ ); } } - + return $author_xml; } - -} \ No newline at end of file + +} diff --git a/plugins/entries/rest.entries.php b/plugins/entries/rest.entries.php index 90a51b4..d5acfaf 100644 --- a/plugins/entries/rest.entries.php +++ b/plugins/entries/rest.entries.php @@ -5,34 +5,34 @@ require_once(TOOLKIT . '/class.fieldmanager.php'); Class REST_Entries { - - private static $_section_handle = NULL; - private static $_section_id = NULL; - private static $_entry_id = NULL; + + private static $_section_handle = null; + private static $_section_id = null; + private static $_entry_id = null; private static $_ds_params = array(); - + public static function setDatasourceParam($name, $value) { self::$_ds_params[$name] = $value; } - + public static function getDatasourceParam($name) { return self::$_ds_params[$name]; } - + public static function getSectionId() { return self::$_section_id; } - + public static function getSectionHandle() { return self::$_section_handle; } - + public static function getEntryId() { return self::$_entry_id; } - + public static function init() { - + if(REST_API::getOutputFormat() == 'csv' && !REST_API::getHTTPMethod() == 'get') { REST_API::sendError(sprintf( '%s output format not supported for %s requests.', @@ -40,40 +40,44 @@ public static function init() { strtoupper(REST_API::getHTTPMethod()) ), 401, 'xml'); } - + $request_uri = REST_API::getRequestURI(); - + self::$_section_handle = $request_uri[0]; self::$_entry_id = $request_uri[1]; - + $section_id = SectionManager::fetchIDFromHandle(self::$_section_handle); - + if (!$section_id) REST_API::sendError('Section not found.', 404); self::$_section_id = $section_id; - + self::setDatasourceParam('included_elements', $_REQUEST['fields']); self::setDatasourceParam('limit', $_REQUEST['limit']); self::setDatasourceParam('page', $_REQUEST['page']); self::setDatasourceParam('sort', $_REQUEST['sort']); self::setDatasourceParam('order', $_REQUEST['order']); self::setDatasourceParam('groupby', $_REQUEST['groupby']); - + $filters = $_REQUEST['filter']; if (!is_null($filters) && !is_array($filters)) $filters = array($filters); self::setDatasourceParam('filters', $filters); - + } - + public static function delete() { - $entry = EntryManager::fetch(self::$_entry_id); - + $entry = (new EntryManager) + ->select() + ->entry(self::$_entry_id) + ->execute() + ->next(); + if(!$entry) { REST_API::sendError('Entry not found.', 404); } else { EntryManager::delete(self::$_entry_id); - $response = new XMLElement('response', NULL, array( + $response = new XMLElement('response', null, array( 'id' => self::$_entry_id, 'result' => 'success', 'type' => 'deleted' @@ -83,7 +87,7 @@ public static function delete() { } } - + /* GET and POST instantiate a frontend page. This resolved to the "index" page of your site then replaces the page data sources/events with the REST API ones, and lets the page load @@ -91,15 +95,15 @@ public static function delete() { the page does not fully load — we return the API response before the page XSLT transformation occurs */ public static function post() { - REST_API::isFrontendPageRequest(TRUE); - Frontend::instance()->display(NULL); + REST_API::isFrontendPageRequest(true); + Frontend::instance()->display(null); } - + public static function get() { - REST_API::isFrontendPageRequest(TRUE); - Frontend::instance()->display(NULL); + REST_API::isFrontendPageRequest(true); + Frontend::instance()->display(null); } - + public static function sendOutput($xml) { switch(REST_API::getHTTPMethod()) { @@ -119,5 +123,5 @@ public static function sendOutput($xml) { break; } } - + } diff --git a/plugins/sections/rest.sections.php b/plugins/sections/rest.sections.php index 2386288..2a1d1ac 100644 --- a/plugins/sections/rest.sections.php +++ b/plugins/sections/rest.sections.php @@ -5,58 +5,71 @@ require_once(TOOLKIT . '/class.entrymanager.php'); Class REST_Sections { - - private static $_sections = NULL; + + private static $_sections = null; private static $_field_attributes = array('id', 'label', 'type', 'sortorder', 'location', 'show_column'); - + public static function init() { - + if(REST_API::getOutputFormat() == 'csv') { REST_API::sendError(sprintf('%s output format not supported.', strtoupper(REST_API::getOutputFormat())), 401, 'xml'); } - + $request_uri = REST_API::getRequestURI(); - + $section_reference = $request_uri[0]; - $sections = NULL; - + $sections = null; + if(is_null($section_reference)) { - $sections = SectionManager::fetch(); + $sections = (new SectionManager) + ->select() + ->execute() + ->rows(); } elseif(is_numeric($section_reference)) { - $sections = SectionManager::fetch($section_reference); + $sections = (new SectionManager) + ->select() + ->section($section_reference) + ->execute() + ->next(); } else { $section_id = SectionManager::fetchIDFromHandle($section_reference); - if($section_id) $sections = SectionManager::fetch($section_id); + if ($section_id) { + $sections = (new SectionManager) + ->select() + ->section($section_id) + ->execute() + ->next(); + } } - + if(!is_array($sections)) $sections = array($sections); - + if (!reset($sections) instanceOf Section) REST_API::sendError(sprintf("Section '%s' not found.", $section_reference), 404); - + self::$_sections = $sections; } - + public static function get() { - + $response = new XMLElement('response'); - + foreach(self::$_sections as $section) { - + $section_xml = new XMLElement('section'); - + $meta = $section->get(); foreach($meta as $key => $value) $section_xml->setAttribute(Lang::createHandle($key), $value); - + $fields = $section->fetchFields(); - + foreach($fields as $field) { $meta = $field->get(); unset($meta['field_id']); - - $field_xml = new XMLElement($meta['element_name'], null); - + + $field_xml = new XMLElement($meta['element_name'], null); + foreach(self::$_field_attributes as $attr) $field_xml->setAttribute(Lang::createHandle($attr), $meta[$attr]); - + foreach($meta as $key => $value) { if (in_array($key, self::$_field_attributes)) continue; $value = General::sanitize($value); @@ -64,16 +77,16 @@ public static function get() { $field_xml->appendChild(new XMLElement(Lang::createHandle($key), General::sanitize($value))); } } - + $section_xml->appendChild($field_xml); } - + $response->appendChild($section_xml); - + } - + REST_API::sendOutput($response); - + } - -} \ No newline at end of file + +}