From 48d42aeb1391d001289d8b15d722b0d5e5e90c47 Mon Sep 17 00:00:00 2001 From: Leo Germani Date: Mon, 3 Dec 2018 15:19:13 -0200 Subject: [PATCH] validate request and return 404 when exposer dsnt suppor mapper --- .../class-tainacan-rest-items-controller.php | 10 +++ ...acan-rest-metadatum-mappers-controller.php | 4 +- src/exposers/class-tainacan-exposer.php | 3 +- .../class-tainacan-exposers-handler.php | 64 ++++++++++++++++++- src/exposers/class-tainacan-html.php | 2 + src/exposers/class-tainacan-json-ld.php | 2 +- src/exposers/class-tainacan-xml.php | 2 +- .../class-tainacan-mappers-handler.php | 16 +++-- src/mappers/class-tainacan-value.php | 18 ------ 9 files changed, 89 insertions(+), 32 deletions(-) delete mode 100644 src/mappers/class-tainacan-value.php diff --git a/src/api/endpoints/class-tainacan-rest-items-controller.php b/src/api/endpoints/class-tainacan-rest-items-controller.php index c440dcbf5..81c650374 100644 --- a/src/api/endpoints/class-tainacan-rest-items-controller.php +++ b/src/api/endpoints/class-tainacan-rest-items-controller.php @@ -240,6 +240,16 @@ class REST_Items_Controller extends REST_Controller { $args = $this->prepare_filters($request); + /** + * allow plugins to hijack the process. + * + * If it returns a \WP_REST_Response, the method will return it and ignore the rest of the script + */ + $alternate_response = apply_filters('tainacan-api-get-items-alternate', false, $request); + if ( $alternate_response instanceof \WP_REST_Response ) { + return $alternate_response; + } + $collection_id = []; if($request['collection_id']) { $collection_id = $request['collection_id']; diff --git a/src/api/endpoints/class-tainacan-rest-metadatum-mappers-controller.php b/src/api/endpoints/class-tainacan-rest-metadatum-mappers-controller.php index 5421deef6..206df004f 100644 --- a/src/api/endpoints/class-tainacan-rest-metadatum-mappers-controller.php +++ b/src/api/endpoints/class-tainacan-rest-metadatum-mappers-controller.php @@ -101,7 +101,7 @@ class REST_Metadatum_Mappers_Controller extends REST_Controller { array_key_exists('metadata_mappers', $body) && is_array($body['metadata_mappers']) && count($body['metadata_mappers']) > 0 && - \Tainacan\Mappers_Handler::request_has_mapper($request) + \Tainacan\Mappers_Handler::get_mapper_from_request($request) ) { $metadatum_mapper = $body['metadata_mappers'][0]; $metadatum = \Tainacan\Repositories\Repository::get_entity_by_post($metadatum_mapper['metadatum_id']); @@ -121,7 +121,7 @@ class REST_Metadatum_Mappers_Controller extends REST_Controller { $Tainacan_Mappers = \Tainacan\Mappers_Handler::get_instance(); $Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance(); $body = json_decode( $request->get_body(), true ); - if($mapper = $Tainacan_Mappers::request_has_mapper($request)) { + if($mapper = $Tainacan_Mappers::get_mapper_from_request($request)) { if(count($body['metadata_mappers']) > 0) { $response = []; $saved = []; diff --git a/src/exposers/class-tainacan-exposer.php b/src/exposers/class-tainacan-exposer.php index 2b29d1811..dea1eccab 100644 --- a/src/exposers/class-tainacan-exposer.php +++ b/src/exposers/class-tainacan-exposer.php @@ -80,6 +80,7 @@ abstract class Exposer { /** * Return list of supported mappers for this type + * @return array List of mappers */ public function get_mappers() { $mappers = apply_filters('tainacan-exporser-type-mappers', $this->mappers, $this); @@ -90,7 +91,7 @@ abstract class Exposer { } elseif (is_array($mappers)) { return $mappers; } - return null; + return []; } } \ No newline at end of file diff --git a/src/exposers/class-tainacan-exposers-handler.php b/src/exposers/class-tainacan-exposers-handler.php index 7cd960385..25c68c4b8 100644 --- a/src/exposers/class-tainacan-exposers-handler.php +++ b/src/exposers/class-tainacan-exposers-handler.php @@ -1,6 +1,7 @@ request_has_exposer($request); + $mapper = Mappers_Handler::get_instance()->get_mapper_from_request($request); + if ( false === $exposer ) { + return $response; + } + + $accpeted_mappers = $exposer->get_mappers(); + + if ( $exposer->accept_no_mapper ) { + // translators: To be displayed in a list of supported mappers of a exposer. Example: Supported mappers: No mapper, Dublin Core + array_unshift($accpeted_mappers, __('No mapper', 'tainacan')); + } + + $accpeted_mappers_string = implode(', ', $accpeted_mappers); + + $return404 = false; + + if ( $mapper == false ) { + + if ( $exposer->accept_no_mapper ) { + return $response; + } else { + $return404 = true; + // translators: 1: Exposer name, 2: List of accepted mappers. example: CSV exposer requires one of the following mappers: dublin-core, other-mapper + $error_message = sprintf( __('%1$s exposer requires one of the following mappers: %2$s', 'tainacan'), $exposer->get_name(), $accpeted_mappers_string); + } + } else { + + if ( in_array($mapper->slug, $accpeted_mappers) ) { + return $response; + } else { + $return404 = true; + // translators: 1: Exposer name. 2: List of accpeted mappers. example: CSV exposer does not support current mapper. Supported mappers are: dublin-core, other-mapper + $error_message = sprintf( __('%1$s exposer does not support current mapper. Supported mappers are: %2$s', 'tainacan'), $exposer->get_name(), $accpeted_mappers_string); + } + + } + + if ( $return404 ) { + $response = new \WP_REST_Response([ + 'error_message' => $error_message, + ], 404); + remove_filter( 'rest_request_after_callbacks', [$this, 'rest_request_after_callbacks']); + } + + return $response; + + + + } + /** * diff --git a/src/exposers/class-tainacan-html.php b/src/exposers/class-tainacan-html.php index 52013ce69..cbbc7d452 100644 --- a/src/exposers/class-tainacan-html.php +++ b/src/exposers/class-tainacan-html.php @@ -10,6 +10,8 @@ class Html extends Exposer { public $slug = 'html'; // type slug for url safe public $name = 'HyperText Markup Language'; + protected $mappers = true; + public $accept_no_mapper = true; function __construct() { $this->set_name( 'HTML' ); diff --git a/src/exposers/class-tainacan-json-ld.php b/src/exposers/class-tainacan-json-ld.php index 1376f4859..843845bae 100644 --- a/src/exposers/class-tainacan-json-ld.php +++ b/src/exposers/class-tainacan-json-ld.php @@ -24,7 +24,7 @@ class JSON_LD extends Exposer { 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ), 'Link: <'.get_bloginfo('url').'/item.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' ]); - $mapper = \Tainacan\Exposers_Handler::request_has_mapper($request); + $mapper = \Tainacan\Exposers_Handler::get_mapper_from_request($request); if(property_exists($mapper, 'XML_namespace') && !empty($mapper->XML_namespace)) { $namespace = $mapper->XML_namespace; $context_slug = str_replace(':', '', $mapper->prefix); diff --git a/src/exposers/class-tainacan-xml.php b/src/exposers/class-tainacan-xml.php index 068868c22..19cf1043c 100644 --- a/src/exposers/class-tainacan-xml.php +++ b/src/exposers/class-tainacan-xml.php @@ -23,7 +23,7 @@ class Xml extends Exposer { */ public function rest_request_after_callbacks( $response, $handler, $request ) { $response->set_headers( ['Content-Type: application/xml; charset=' . get_option( 'blog_charset' )] ); - $mapper = \Tainacan\Exposers_Handler::request_has_mapper($request); + $mapper = \Tainacan\Exposers_Handler::get_mapper_from_request($request); $xml = new \SimpleXMLElement( '' ); $namespace = null; $xml_root = $xml; diff --git a/src/mappers/class-tainacan-mappers-handler.php b/src/mappers/class-tainacan-mappers-handler.php index 6ad3aca1c..d26502184 100644 --- a/src/mappers/class-tainacan-mappers-handler.php +++ b/src/mappers/class-tainacan-mappers-handler.php @@ -23,7 +23,7 @@ class Mappers_Handler { self::$instance = $this; $this->register_mapper('Tainacan\Mappers\Dublin_Core'); - //$this->register_mapper('Tainacan\Mappers\Value'); + do_action('tainacan-register-mappers', $this); add_filter( 'tainacan-admin-i18n', [$this, 'mappers_i18n']); @@ -110,25 +110,27 @@ class Mappers_Handler { * @param \WP_REST_Request $request * @return Mappers\Mapper|boolean false */ - public static function request_has_mapper($request) { + public static function get_mapper_from_request($request) { $body = json_decode( $request->get_body(), true ); $Tainacan_Mappers = self::get_instance(); $query_url_params = $request->get_query_params(); + $return_mapper = false; + if( // There is a defined mapper is_array($body) && array_key_exists(self::MAPPER_PARAM, $body) && $Tainacan_Mappers->mapper_exists($body[self::MAPPER_PARAM]) ) { $mapper = $Tainacan_Mappers->check_class_name($body[self::MAPPER_PARAM], true, self::MAPPER_CLASS_PREFIX); - return new $mapper; + $return_mapper = new $mapper; } elseif( is_array($query_url_params) && array_key_exists(self::MAPPER_PARAM, $query_url_params) && $Tainacan_Mappers->mapper_exists($query_url_params[self::MAPPER_PARAM]) ) { $mapper = $Tainacan_Mappers->check_class_name($query_url_params[self::MAPPER_PARAM], true, self::MAPPER_CLASS_PREFIX); - return new $mapper; + $return_mapper = new $mapper; } - return false; // No mapper need, using Tainacan defautls + return apply_filters('tainacan-get-mapper-from-request', $return_mapper, $request); } /** @@ -224,7 +226,7 @@ class Mappers_Handler { public function create_mapped_collection( $collection, $request ) { - if ($mapper = $this->request_has_mapper($request)) { + if ($mapper = $this->get_mapper_from_request($request)) { $mapper_metadata = $mapper->metadata; if(is_array($mapper_metadata) ) { @@ -276,7 +278,7 @@ class Mappers_Handler { function filter_item_api_response($item_arr, $item, $request) { - $mapper = $this->request_has_mapper($request); + $mapper = $this->get_mapper_from_request($request); if (!$mapper) { return $item_arr; diff --git a/src/mappers/class-tainacan-value.php b/src/mappers/class-tainacan-value.php deleted file mode 100644 index 7dd20e030..000000000 --- a/src/mappers/class-tainacan-value.php +++ /dev/null @@ -1,18 +0,0 @@ - value format where key can be defined - * - */ -class Value extends Mapper { - public $slug = 'value'; - public $name = 'Value'; - public $allow_extra_metadata = true; - public $context_url = ''; - public $header = ''; - public $metadata = false; - public $show_ui = false; - -} \ No newline at end of file