diff --git a/src/admin/class-tainacan-admin.php b/src/admin/class-tainacan-admin.php index 5a6955a98..9bbe6458d 100644 --- a/src/admin/class-tainacan-admin.php +++ b/src/admin/class-tainacan-admin.php @@ -184,8 +184,8 @@ class Admin { 'theme_collection_list_url' => get_post_type_archive_link( 'tainacan-collection' ), 'custom_header_support' => get_theme_support('custom-header'), 'registered_view_modes' => \Tainacan\Theme_Helper::get_instance()->get_registered_view_modes(), - 'exposer_mapper_param' => \Tainacan\Exposers\Exposers::MAPPER_PARAM, - 'exposer_type_param' => \Tainacan\Exposers\Exposers::TYPE_PARAM, + 'exposer_mapper_param' => \Tainacan\Mappers_Handler::MAPPER_PARAM, + 'exposer_type_param' => \Tainacan\Exposers_Handler::TYPE_PARAM, 'repository_name' => get_bloginfo('name') ]; diff --git a/src/api/endpoints/class-tainacan-rest-collections-controller.php b/src/api/endpoints/class-tainacan-rest-collections-controller.php index a36a5f126..8da159ea4 100644 --- a/src/api/endpoints/class-tainacan-rest-collections-controller.php +++ b/src/api/endpoints/class-tainacan-rest-collections-controller.php @@ -302,6 +302,8 @@ class REST_Collections_Controller extends REST_Controller { $collection = $this->collections_repository->insert( $prepared_post ); $response = $this->prepare_item_for_response($collection, $request); + + do_action('tainacan-api-collection-created', $response, $request); return new \WP_REST_Response($response, 201); } diff --git a/src/api/endpoints/class-tainacan-rest-export-controller.php b/src/api/endpoints/class-tainacan-rest-export-controller.php index 485ac3df5..b28959e56 100644 --- a/src/api/endpoints/class-tainacan-rest-export-controller.php +++ b/src/api/endpoints/class-tainacan-rest-export-controller.php @@ -140,7 +140,7 @@ class REST_Export_Controller extends REST_Controller { */ public function export($request, $query, $args) { - $type = \Tainacan\Exposers\Exposers::request_has_type($request); + $type = \Tainacan\Exposers_Handler::request_has_type($request); $path = wp_upload_dir(); $path = $path['path']; $filename = $path.date('YmdHis').'-tainacan-export.'.$type->get_extension(); @@ -170,8 +170,8 @@ class REST_Export_Controller extends REST_Controller { [], 'error' ); - remove_filter( 'rest_request_after_callbacks', [\Tainacan\Exposers\Exposers::get_instance(), 'rest_request_after_callbacks'], 10, 3 ); //exposer mapping - remove_filter( 'tainacan-rest-response', [\Tainacan\Exposers\Exposers::get_instance(), 'rest_response'], 10, 2 ); // exposer types + remove_filter( 'rest_request_after_callbacks', [\Tainacan\Exposers_Handler::get_instance(), 'rest_request_after_callbacks'], 10, 3 ); //exposer mapping + remove_filter( 'tainacan-rest-response', [\Tainacan\Exposers_Handler::get_instance(), 'rest_response'], 10, 2 ); // exposer types return $log; } elseif ($pid) { // we are the parent or run at foreground try { @@ -265,8 +265,8 @@ class REST_Export_Controller extends REST_Controller { } } else { // we are the child - remove_filter( 'rest_request_after_callbacks', [\Tainacan\Exposers\Exposers::get_instance(), 'rest_request_after_callbacks'], 10, 3 ); //exposer mapping - remove_filter( 'tainacan-rest-response', [\Tainacan\Exposers\Exposers::get_instance(), 'rest_response'], 10, 2 ); // exposer types + remove_filter( 'rest_request_after_callbacks', [\Tainacan\Exposers_Handler::get_instance(), 'rest_request_after_callbacks'], 10, 3 ); //exposer mapping + remove_filter( 'tainacan-rest-response', [\Tainacan\Exposers_Handler::get_instance(), 'rest_response'], 10, 2 ); // exposer types return $log; } diff --git a/src/api/endpoints/class-tainacan-rest-items-controller.php b/src/api/endpoints/class-tainacan-rest-items-controller.php index 66892f292..17981f912 100644 --- a/src/api/endpoints/class-tainacan-rest-items-controller.php +++ b/src/api/endpoints/class-tainacan-rest-items-controller.php @@ -119,12 +119,13 @@ class REST_Items_Controller extends REST_Controller { $item_array['metadata'][ $slug ]['name'] = $metadatum->get_name(); if($metadatum->get_metadata_type_object()->get_primitive_type() === 'date') { $item_array['metadata'][ $slug ]['date_i18n'] = $item_metadata_array['date_i18n']; - } else { - $item_array['metadata'][ $slug ]['value'] = $item_metadata_array['value']; - $item_array['metadata'][ $slug ]['value_as_html'] = $item_metadata_array['value_as_html']; - $item_array['metadata'][ $slug ]['value_as_string'] = $item_metadata_array['value_as_string']; } + $item_array['metadata'][ $slug ]['value'] = $item_metadata_array['value']; + $item_array['metadata'][ $slug ]['value_as_html'] = $item_metadata_array['value_as_html']; + $item_array['metadata'][ $slug ]['value_as_string'] = $item_metadata_array['value_as_string']; + $item_array['metadata'][ $slug ]['multiple'] = $metadatum->get_multiple(); + $item_array['metadata'][ $slug ]['mapping'] = $metadatum->get_exposer_mapping(); } return $item_array; @@ -169,37 +170,41 @@ class REST_Items_Controller extends REST_Controller { } $item_arr['document_as_html'] = $item->get_document_html($img_size); - $item_arr['exposer_urls'] = \Tainacan\Exposers\Exposers::get_exposer_urls(rest_url("{$this->namespace}/{$this->rest_base}/{$item->get_id()}/")); - return $this->add_metadata_to_item( $item, $item_arr ); - } - - $attributes_to_filter = $request['fetch_only']; - - # Always returns id and collection id - if(is_array($attributes_to_filter)) { - $attributes_to_filter[] = 'id'; - $attributes_to_filter[] = 'collection_id'; + $item_arr['exposer_urls'] = \Tainacan\Exposers_Handler::get_exposer_urls(rest_url("{$this->namespace}/{$this->rest_base}/{$item->get_id()}/")); + $item_arr = $this->add_metadata_to_item( $item, $item_arr ); } else { - $attributes_to_filter = array($attributes_to_filter, 'id', 'collection_id'); + + $attributes_to_filter = $request['fetch_only']; + + # Always returns id and collection id + if(is_array($attributes_to_filter)) { + $attributes_to_filter[] = 'id'; + $attributes_to_filter[] = 'collection_id'; + } else { + $attributes_to_filter = array($attributes_to_filter, 'id', 'collection_id'); + } + + $item_arr = $this->filter_object_by_attributes($item, $attributes_to_filter); + + $item_arr = array_merge($extra_metadata_values, $item_arr); + + if(is_array($attributes_to_filter) && array_key_exists('meta', $attributes_to_filter)){ + + $args = array('post__in' => $attributes_to_filter['meta']); + + $item_arr = $this->add_metadata_to_item($item, $item_arr, $args); + } + + if ( $request['context'] === 'edit' ) { + $item_arr['current_user_can_edit'] = $item->can_edit(); + } + + $item_arr['url'] = get_permalink( $item_arr['id'] ); + $item_arr['exposer_urls'] = \Tainacan\Exposers_Handler::get_exposer_urls(get_rest_url(null, "{$this->namespace}/{$this->rest_base}/{$item->get_id()}/")); + } - $item_arr = $this->filter_object_by_attributes($item, $attributes_to_filter); - - $item_arr = array_merge($extra_metadata_values, $item_arr); - - if(is_array($attributes_to_filter) && array_key_exists('meta', $attributes_to_filter)){ - - $args = array('post__in' => $attributes_to_filter['meta']); - - $item_arr = $this->add_metadata_to_item($item, $item_arr, $args); - } - - if ( $request['context'] === 'edit' ) { - $item_arr['current_user_can_edit'] = $item->can_edit(); - } - - $item_arr['url'] = get_permalink( $item_arr['id'] ); - $item_arr['exposer_urls'] = \Tainacan\Exposers\Exposers::get_exposer_urls(get_rest_url(null, "{$this->namespace}/{$this->rest_base}/{$item->get_id()}/")); + $item_arr = apply_filters('tainacan-api-items-prepare-for-response', $item_arr, $item, $request); return $item_arr; } 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 721280aeb..5421deef6 100644 --- a/src/api/endpoints/class-tainacan-rest-metadatum-mappers-controller.php +++ b/src/api/endpoints/class-tainacan-rest-metadatum-mappers-controller.php @@ -65,9 +65,9 @@ class REST_Metadatum_Mappers_Controller extends REST_Controller { * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { - $Tainacan_Exposers = \Tainacan\Exposers\Exposers::get_instance(); + $Tainacan_Mappers = \Tainacan\Mappers_Handler::get_instance(); - $metadatum_mappers = $Tainacan_Exposers->get_mappers( 'OBJECT' ); + $metadatum_mappers = $Tainacan_Mappers->get_mappers( 'OBJECT' ); $prepared = []; foreach ($metadatum_mappers as $metadatum_mapper){ @@ -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\Exposers\Exposers::request_has_mapper($request) + \Tainacan\Mappers_Handler::request_has_mapper($request) ) { $metadatum_mapper = $body['metadata_mappers'][0]; $metadatum = \Tainacan\Repositories\Repository::get_entity_by_post($metadatum_mapper['metadatum_id']); @@ -118,10 +118,10 @@ class REST_Metadatum_Mappers_Controller extends REST_Controller { * @return \WP_Error|\WP_REST_Response */ public function update_item( $request ) { - $Tainacan_Exposers = \Tainacan\Exposers\Exposers::get_instance(); + $Tainacan_Mappers = \Tainacan\Mappers_Handler::get_instance(); $Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance(); $body = json_decode( $request->get_body(), true ); - if($mapper = $Tainacan_Exposers::request_has_mapper($request)) { + if($mapper = $Tainacan_Mappers::request_has_mapper($request)) { if(count($body['metadata_mappers']) > 0) { $response = []; $saved = []; diff --git a/src/classes/repositories/class-tainacan-metadata.php b/src/classes/repositories/class-tainacan-metadata.php index bc06a9c6c..d7ad0815e 100644 --- a/src/classes/repositories/class-tainacan-metadata.php +++ b/src/classes/repositories/class-tainacan-metadata.php @@ -677,9 +677,6 @@ class Metadata extends Repository { 'collection_id' => $collection->get_id(), 'metadata_type' => 'Tainacan\Metadata_Types\Core_Description', 'status' => 'publish', - 'exposer_mapping' => [ - 'dublin-core' => 'description' - ] ], 'core_title' => [ 'name' => 'Title', @@ -688,9 +685,6 @@ class Metadata extends Repository { 'metadata_type' => 'Tainacan\Metadata_Types\Core_Title', 'status' => 'publish', 'display' => 'yes', - 'exposer_mapping' => [ - 'dublin-core' => 'title' - ] ] ]; diff --git a/src/classes/tainacan-creator.php b/src/classes/tainacan-creator.php index fe9e4211a..b69163eaa 100644 --- a/src/classes/tainacan-creator.php +++ b/src/classes/tainacan-creator.php @@ -11,6 +11,7 @@ const TAINACAN_ENDPOINTS_DIR = __DIR__ . '/../api/endpoints/'; const TAINACAN_IMPORTER_DIR = __DIR__ . '/../importer/'; const TAINACAN_EXPORTER_DIR = __DIR__ . '/../exporter/'; const TAINACAN_EXPOSERS_DIR = __DIR__ . '/../exposers/'; +const TAINACAN_MAPPERS_DIR = __DIR__ . '/../mappers/'; const DIRS = [ TAINACAN_CLASSES_DIR, @@ -23,7 +24,8 @@ const DIRS = [ TAINACAN_ENDPOINTS_DIR, TAINACAN_IMPORTER_DIR, TAINACAN_EXPORTER_DIR, - TAINACAN_EXPOSERS_DIR + TAINACAN_EXPOSERS_DIR, + TAINACAN_MAPPERS_DIR ]; require_once('libs/wp-async-request.php'); @@ -35,7 +37,8 @@ require_once(TAINACAN_IMPORTER_DIR . 'class-tainacan-bg-importer.php'); require_once(TAINACAN_VENDOR_DIR . 'autoload.php'); require_once(TAINACAN_IMPORTER_DIR . 'class-tainacan-importer.php'); require_once(TAINACAN_IMPORTER_DIR . 'class-tainacan-importer-handler.php'); -require_once(TAINACAN_EXPOSERS_DIR . 'class-tainacan-exposers.php'); +require_once(TAINACAN_EXPOSERS_DIR . 'class-tainacan-exposers-handler.php'); +require_once(TAINACAN_MAPPERS_DIR . 'class-tainacan-mappers-handler.php'); require_once(TAINACAN_EXPORTER_DIR . 'class-tainacan-bg-exporter.php'); require_once(TAINACAN_EXPORTER_DIR . 'class-tainacan-export-handler.php'); @@ -68,6 +71,9 @@ function tainacan_autoload($class_name){ } else if( isset( $class_path[1] ) && $class_path[1] === 'Exposers' ){ $dir = TAINACAN_EXPOSERS_DIR; if(count($class_path) > 3) $dir .= strtolower($class_path[2]).DIRECTORY_SEPARATOR; + } else if( isset( $class_path[1] ) && $class_path[1] === 'Mappers' ){ + $dir = TAINACAN_MAPPERS_DIR; + if(count($class_path) > 3) $dir .= strtolower($class_path[2]).DIRECTORY_SEPARATOR; } else if( isset( $class_path[1] ) && $class_path[1] === 'API' ){ $dir = TAINACAN_TAPI_DIR; if(count($class_path) > 3) $dir .= strtolower($class_path[2]).DIRECTORY_SEPARATOR; @@ -133,7 +139,9 @@ $Tainacan_Terms = \Tainacan\Repositories\Terms::get_instance(); $Tainacan_Logs = \Tainacan\Repositories\Logs::get_instance(); -$Tainacan_Exposers = \Tainacan\Exposers\Exposers::get_instance(); +$Tainacan_Exposers = \Tainacan\Exposers_Handler::get_instance(); + +$Tainacan_Mappers = \Tainacan\Mappers_Handler::get_instance(); $Tainacan_Embed = \Tainacan\Embed::get_instance(); diff --git a/src/exporter/class-tainacan-exporter.php b/src/exporter/class-tainacan-exporter.php index f4db8257e..cfa239449 100644 --- a/src/exporter/class-tainacan-exporter.php +++ b/src/exporter/class-tainacan-exporter.php @@ -733,7 +733,7 @@ class Exporter extends CommunImportExport { } $this->mapping_accept[$method] = true; if($method == 'any') { - $Tainacan_Exposers = \Tainacan\Exposers\Exposers::get_instance(); + $Tainacan_Exposers = \Tainacan\Exposers_Handler::get_instance(); $metadatum_mappers = $Tainacan_Exposers->get_mappers(); $this->mapping_list = $metadatum_mappers; } else if(!empty($list)) { diff --git a/src/exposers/class-tainacan-csv.php b/src/exposers/class-tainacan-csv.php new file mode 100644 index 000000000..9977ce523 --- /dev/null +++ b/src/exposers/class-tainacan-csv.php @@ -0,0 +1,61 @@ +set_headers( [ + 'Content-Type: text/csv; charset=' . get_option( 'blog_charset' ), + 'Content-disposition: attachment;filename=tainacan.csv'] // TODO filter/optional + ); + + $items = $response->get_data(); + + if (sizeof($items) > 0) { + + $csv = fopen('php://memory', 'r+'); + + $headers = array_map(function($a) { + return $a['name']; + }, $items[0]['metadata']); + + fputcsv($csv, $headers, ';', '"' ); + + foreach ($items as $item) { + $values = array_map(function($a) { + return $a['value_as_string']; + }, $item['metadata']); + + fputcsv($csv, $values, ';', '"' ); + + } + rewind($csv); + $ret_csv = stream_get_contents($csv); + fclose($csv); + $response->set_data($ret_csv); + + } + + return $response; + + } + +} \ No newline at end of file diff --git a/src/exposers/types/class-tainacan-type.php b/src/exposers/class-tainacan-exposer.php similarity index 93% rename from src/exposers/types/class-tainacan-type.php rename to src/exposers/class-tainacan-exposer.php index 0574e0919..d05d9ae33 100644 --- a/src/exposers/types/class-tainacan-type.php +++ b/src/exposers/class-tainacan-exposer.php @@ -1,12 +1,12 @@ register_exposer('Tainacan\Exposers\Xml'); + //$this->register_exposer('Tainacan\Exposers\Txt'); + $this->register_exposer('Tainacan\Exposers\Html'); + $this->register_exposer('Tainacan\Exposers\Csv'); + //$this->register_exposer('Tainacan\Exposers\OAI_PMH'); + //$this->register_exposer('Tainacan\Exposers\JSON_LD'); + do_action('tainacan-register-exposer', $this); + + add_filter( 'rest_request_after_callbacks', [$this, 'rest_request_after_callbacks'], 10, 3 ); //exposer types + // add_filter( 'tainacan-rest-response', [$this, 'rest_response'], 10, 2 ); // exposer mapper + + } + + /** + * register exposers type + * + * @param $class_name string | object The class name or the instance + */ + public function register_exposer( $class_name ){ + $obj = $class_name; + if( is_object( $class_name ) ){ + $class_name = get_class( $class_name ); + } else { + $obj = new $class_name; + } + + if(!in_array( $class_name, $this->exposers)){ + $this->exposers[$obj->slug] = $class_name; + } + } + + /** + * unregister exposers type + * + * @param $class_name string | object The class name or the instance + */ + public function unregister_exposer( $class_name ){ + $obj = $class_name; + if( is_object( $class_name ) ){ + $class_name = get_class( $class_name ); + } else { + $obj = new $class_name; + } + + if ( array_key_exists($obj->slug, $this->exposers) ) { + unset($this->exposers[$obj->slug]); + } + + } + + + + /** + * Return namespaced class name + * @param string $class_name + * @param boolean $root + * @param string $prefix + * @return string + */ + public function check_class_name($class_name, $root = false, $prefix = 'Tainacan\Exposer\\') { + if(is_string($class_name)) { + if(array_key_exists($class_name, $this->exposers)) { + $class_name = $this->exposers[$class_name]; + $prefix = ''; + } + } + $class = $prefix.sanitize_text_field($class_name); + $class = str_replace(['-', ' '], ['_', '_'], $class); + + return ($root ? '\\' : '').$class; + } + + /** + * Check if rest response need mapper + * @param array $item_arr + * @param \WP_REST_Request $request + * @return array + */ + public function rest_response($item_arr, $request) { + if($request->get_method() == 'GET' && $this->is_tainacan_request($request)) { + if($exposer = $this->request_has_mapper($request)) { + if(substr($request->get_route(), 0, strlen('/tainacan/v2/items')) == '/tainacan/v2/items') { //TODO do it at rest not here + $repos_items = \Tainacan\Repositories\Items::get_instance(); + $item = $repos_items->fetch($item_arr['id']); + $items_metadata = $item->get_metadata(); + $prepared_item = []; + foreach ($items_metadata as $item_metadata){ + array_push($prepared_item, $item_metadata->_toArray()); + } + $item_arr = $prepared_item; + } + return $this->map($item_arr, $exposer, $request); //TODO request -> args + } + } + return $item_arr; + } + + + + /** + * check if is a tainacan request + * @param \WP_REST_Request $request + * @return boolean + */ + public function is_tainacan_request($request) { + return substr($request->get_route(), 0, strlen('/tainacan/v2')) == '/tainacan/v2'; + } + + /** + * check if query came from url + * @param \WP_REST_Request $request + */ + public static function request_has_url_param($request) { + $Tainacan_Exposers = self::get_instance(); + $query_url_params = $request->get_query_params(); + if ( + is_array($query_url_params) && array_key_exists(self::TYPE_PARAM, $query_url_params) && + $Tainacan_Exposers->exposer_exists($query_url_params[self::TYPE_PARAM]) + ) { + return true; + } + return false; + } + + /** + * adapt request response to exposer type + * @param \WP_REST_Response $response + * @param \WP_REST_Server $handler + * @param \WP_REST_Request $request + * @return \WP_REST_Response + */ + public function rest_request_after_callbacks( $response, $handler, $request ) { + if($this->is_tainacan_request($request) && $response instanceof \WP_REST_Response ) { + if($request->get_method() == 'GET') { + if($exposer = $this->request_has_exposer($request)) { + $type_responde = $exposer->rest_request_after_callbacks($response, $handler, $request); + if(self::request_has_url_param($request)) { + header(implode('', $response->get_headers())); + echo stripcslashes($response->get_data()); + exit(); + } + return $type_responde; + } + } + } + // default JSON response + return $response; + } + + /** + * Return if exposer is registered + * @param string $exposer + * @return boolean + */ + public function exposer_exists($exposer) { + return in_array($this->check_class_name($exposer), $this->exposers); + } + /** + * Return Exposer if request has exposer, false otherwise + * @param \WP_REST_Request $request + * @return Exposers\Exposer|boolean false + */ + public static function request_has_exposer($request) { + $body = json_decode( $request->get_body(), true ); + $query_url_params = $request->get_query_params(); + $Tainacan_Exposers = self::get_instance(); + if( + is_array($body) && array_key_exists(self::TYPE_PARAM, $body) && + $Tainacan_Exposers->exposer_exists($body[self::TYPE_PARAM]) + ) { + $exposer = $Tainacan_Exposers->check_class_name($body[self::TYPE_PARAM], true); + return new $exposer; + } elseif ( + is_array($query_url_params) && array_key_exists(self::TYPE_PARAM, $query_url_params) && + $Tainacan_Exposers->exposer_exists($query_url_params[self::TYPE_PARAM]) + ){ + $exposer = $Tainacan_Exposers->check_class_name($query_url_params[self::TYPE_PARAM], true); + return new $exposer; + } + return false; + } + + + + /** + * Return list of registered exposers + * @param string $output output format, ARRAY_N or OBJECT + * @return array of slug or array of \Tainacan\Exposers\Exposer + */ + public function get_exposers($output = \ARRAY_N) { + $ret = []; + switch ($output) { + case \OBJECT: + foreach ($this->exposers as $type) { + $ret[] = new $type; + } + break; + case \ARRAY_N: + default: + return $this->exposers; + break; + } + return $ret; + } + + + + /** + * + * @param string $base_url url base for exposer parameters append + * @return string|string[][] + */ + public static function get_exposer_urls($base_url = '') { + return []; + $Tainacan_Exposers = self::get_instance(); + $mappers = $Tainacan_Exposers->get_mappers(\OBJECT); + $types = $Tainacan_Exposers->get_types(\OBJECT); + $urls = []; + foreach ($types as $type) { + $url = $base_url.(strpos($base_url, '?') === false ? '?' : '&').self::TYPE_PARAM.'='.$type->slug; + $urls[$type->slug] = [$url]; + if(is_array($type->get_mappers())) { + $first = true; // first is default, jump + foreach ($type->get_mappers() as $type_mapper) { + if($first) { + $first = false; + continue; + } + $urls[$type->slug][] = $url.'&'.self::MAPPER_PARAM.'='.$type_mapper; + } + } else { + foreach ($mappers as $mapper) { + $urls[$type->slug][] = $url.'&'.self::MAPPER_PARAM.'='.$mapper->slug; + } + } + } + return $urls; + } +} \ No newline at end of file diff --git a/src/exposers/class-tainacan-exposers.php b/src/exposers/class-tainacan-exposers.php deleted file mode 100644 index 6f592f7c8..000000000 --- a/src/exposers/class-tainacan-exposers.php +++ /dev/null @@ -1,453 +0,0 @@ -register_exposer_type('Tainacan\Exposers\Types\Xml'); - $this->register_exposer_type('Tainacan\Exposers\Types\Txt'); - $this->register_exposer_type('Tainacan\Exposers\Types\Html'); - $this->register_exposer_type('Tainacan\Exposers\Types\Csv'); - $this->register_exposer_type('Tainacan\Exposers\Types\OAI_PMH'); - $this->register_exposer_type('Tainacan\Exposers\Types\JSON_LD'); - do_action('tainacan-register-exposer-types', $this); - $this->register_exposer_mapper('Tainacan\Exposers\Mappers\Dublin_Core'); - $this->register_exposer_mapper('Tainacan\Exposers\Mappers\Value'); - do_action('tainacan-register-exposer-mappers', $this); - - - add_filter( 'rest_request_after_callbacks', [$this, 'rest_request_after_callbacks'], 10, 3 ); //exposer types - add_filter( 'tainacan-rest-response', [$this, 'rest_response'], 10, 2 ); // exposer mapper - add_filter( 'tainacan-admin-i18n', [$this, 'mappers_i18n']); - } - - /** - * register exposers types class on array of types - * - * @param $class_name string | object The class name or the instance - */ - public function register_exposer_type( $class_name ){ - $obj = $class_name; - if( is_object( $class_name ) ){ - $class_name = get_class( $class_name ); - } else { - $obj = new $class_name; - } - - if(!in_array( $class_name, $this->types)){ - $this->types[$obj->slug] = $class_name; - } - } - - /** - * register exposers mappers class on array of types - * - * @param $class_name string | object The class name or the object instance - */ - public function register_exposer_mapper( $class_name ){ - $obj = $class_name; - if( is_object( $class_name ) ){ - $class_name = get_class( $class_name ); - } else { - $obj = new $class_name; - } - - if(!in_array( $class_name, $this->mappers)){ - $this->mappers[$obj->slug] = $class_name; - } - } - - /** - * Return namespaced class name - * @param string $class_name - * @param boolean $root - * @param string $prefix - * @return string - */ - public function check_class_name($class_name, $root = false, $prefix = 'Tainacan\Exposers\Types\\') { - if(is_string($class_name)) { - if(array_key_exists($class_name, $this->types)) { - $class_name = $this->types[$class_name]; - $prefix = ''; - } elseif( array_key_exists($class_name, $this->mappers)) { - $class_name = $this->mappers[$class_name]; - $prefix = ''; - } - } - $class = $prefix.sanitize_text_field($class_name); - $class = str_replace(['-', ' '], ['_', '_'], $class); - - return ($root ? '\\' : '').$class; - } - - /** - * Check if rest response need mapper - * @param array $item_arr - * @param \WP_REST_Request $request - * @return array - */ - public function rest_response($item_arr, $request) { - if($request->get_method() == 'GET' && $this->is_tainacan_request($request)) { - if($exposer = $this->request_has_mapper($request)) { - if(substr($request->get_route(), 0, strlen('/tainacan/v2/items')) == '/tainacan/v2/items') { //TODO do it at rest not here - $repos_items = \Tainacan\Repositories\Items::get_instance(); - $item = $repos_items->fetch($item_arr['id']); - $items_metadata = $item->get_metadata(); - $prepared_item = []; - foreach ($items_metadata as $item_metadata){ - array_push($prepared_item, $item_metadata->_toArray()); - } - $item_arr = $prepared_item; - } - return $this->map($item_arr, $exposer, $request); //TODO request -> args - } - } - return $item_arr; - } - - /** - * Return array of mapped metadatum - * @param array $item_arr - * @param Mappers\Mapper $mapper - * @return array - */ - protected function map_metadatum($item_arr, $mapper) { - $ret = $item_arr; - $metadatum_mapping = $item_arr['metadatum']['exposer_mapping']; - if(array_key_exists($mapper->slug, $metadatum_mapping)) { - if( - is_string($metadatum_mapping[$mapper->slug]) && is_array($mapper->metadata) && !array_key_exists( $metadatum_mapping[$mapper->slug], $mapper->metadata) || - is_array($metadatum_mapping[$mapper->slug]) && $mapper->allow_extra_metadata != true - ) { - throw new \Exception('Invalid Mapper Option'); - } - $slug = ''; - if(is_string($metadatum_mapping[$mapper->slug])) { - $slug = $metadatum_mapping[$mapper->slug]; - } else { - $slug = $metadatum_mapping[$mapper->slug]['slug']; - } - $ret = [$mapper->prefix.$slug.$mapper->sufix => $item_arr['value']]; //TODO Validate option - } elseif($mapper->slug == 'value') { - $ret = [$item_arr['metadatum']['name'] => $item_arr['value']]; - } else { - $ret = []; - } - return $ret; - } - - /** - * - * @param array $item_arr - * @param Mappers\Mapper $mapper - * @param \WP_REST_Request $resquest - * @return array - */ - protected function map($item_arr, $mapper, $resquest) { - $ret = $item_arr; - if(array_key_exists('metadatum', $item_arr)){ // getting a unique metadatum - $ret = $this->map_metadatum($item_arr, $mapper); - } else { // array of elements - $ret = []; - foreach ($item_arr as $item) { - if(array_key_exists('metadatum', $item)) { - $ret = array_merge($ret, $this->map($item, $mapper, $resquest) ); - } else { - $ret[] = $this->map($item, $mapper, $resquest); - } - } - } - return $ret; - } - - /** - * check if is a tainacan request - * @param \WP_REST_Request $request - * @return boolean - */ - public function is_tainacan_request($request) { - return substr($request->get_route(), 0, strlen('/tainacan/v2')) == '/tainacan/v2'; - } - - /** - * check if query came from url - * @param \WP_REST_Request $request - */ - public static function request_has_url_param($request) { - $Tainacan_Exposers = self::get_instance(); - $query_url_params = $request->get_query_params(); - if ( - is_array($query_url_params) && array_key_exists(self::TYPE_PARAM, $query_url_params) && - $Tainacan_Exposers->has_type($query_url_params[self::TYPE_PARAM]) - ) { - return true; - } - return false; - } - - /** - * adapt request response to exposer type - * @param \WP_REST_Response $response - * @param \WP_REST_Server $handler - * @param \WP_REST_Request $request - * @return \WP_REST_Response - */ - public function rest_request_after_callbacks( $response, $handler, $request ) { - if($this->is_tainacan_request($request) && $response instanceof \WP_REST_Response ) { - if($request->get_method() == 'GET') { - if($exposer = $this->request_has_type($request)) { - $type_responde = $exposer->rest_request_after_callbacks($response, $handler, $request); - if(self::request_has_url_param($request)) { - header(implode('', $response->get_headers())); - echo stripcslashes($response->get_data()); - exit(); - } - return $type_responde; - } - } elseif($request->get_method() == 'POST') { - if($mapper = $this->request_has_mapper($request)) { - return $this->create_mapped_metadata( $response, $handler, $request, $mapper ); - } - } - } - // default JSON response - return $response; - } - - /** - * Return if type is registered - * @param string $type - * @return boolean - */ - public function has_type($type) { - return in_array($this->check_class_name($type), $this->types); - } - /** - * Return Type if request has type, false otherwise - * @param \WP_REST_Request $request - * @return Types\Type|boolean false - */ - public static function request_has_type($request) { - $body = json_decode( $request->get_body(), true ); - $query_url_params = $request->get_query_params(); - $Tainacan_Exposers = self::get_instance(); - if( - is_array($body) && array_key_exists(self::TYPE_PARAM, $body) && - $Tainacan_Exposers->has_type($body[self::TYPE_PARAM]) - ) { - $type = $Tainacan_Exposers->check_class_name($body[self::TYPE_PARAM], true); - return new $type; - } elseif ( - is_array($query_url_params) && array_key_exists(self::TYPE_PARAM, $query_url_params) && - $Tainacan_Exposers->has_type($query_url_params[self::TYPE_PARAM]) - ){ - $type = $Tainacan_Exposers->check_class_name($query_url_params[self::TYPE_PARAM], true); - return new $type; - } - return false; - } - - /** - * Return if mapper is registered - * @param string $mapper - * @return boolean - */ - public function has_mapper($mapper) { - return in_array($this->check_class_name($mapper, false, self::MAPPER_CLASS_PREFIX), $this->mappers); - } - - /** - * Check if there is a mapper - * @param \WP_REST_Request $request - * @return Mappers\Mapper|boolean false - */ - public static function request_has_mapper($request) { - $body = json_decode( $request->get_body(), true ); - $Tainacan_Exposers = self::get_instance(); - $query_url_params = $request->get_query_params(); - - $type = self::request_has_type($request); - if( // There are a defined mapper - is_array($body) && array_key_exists(self::MAPPER_PARAM, $body) && - $Tainacan_Exposers->has_mapper($body[self::MAPPER_PARAM]) - ) { - if( - $type === false || // do not have a exposer type - $type->get_mappers() === true || // the type accept all mappers - ( is_array($type->get_mappers()) && in_array($body[self::MAPPER_PARAM], $type->get_mappers()) ) - ) { // the current mapper is accepted by type - $mapper = $Tainacan_Exposers->check_class_name($body[self::MAPPER_PARAM], true, self::MAPPER_CLASS_PREFIX); - return new $mapper; - } - } elseif( - is_array($query_url_params) && array_key_exists(self::MAPPER_PARAM, $query_url_params) && - $Tainacan_Exposers->has_mapper($query_url_params[self::MAPPER_PARAM]) - ) { - if( - $type === false || // do not have a exposer type - $type->get_mappers() === true || // the type accept all mappers - ( is_array($type->get_mappers()) && in_array($query_url_params[self::MAPPER_PARAM], $type->get_mappers()) ) - ) { // the current mapper is accepted by type - $mapper = $Tainacan_Exposers->check_class_name($query_url_params[self::MAPPER_PARAM], true, self::MAPPER_CLASS_PREFIX); - return new $mapper; - } - } elseif( is_object($type) && is_array($type->get_mappers()) && count($type->get_mappers()) > 0 ) { //there are no defined mapper, let use the first one o list if has a list - $mapper = $Tainacan_Exposers->check_class_name($type->get_mappers()[0], true, self::MAPPER_CLASS_PREFIX); - return new $mapper; - } - return false; // No mapper need, using Tainacan defautls - } - - /** - * Add mappers data to translations - * @param array $i18n_strings - * @return array - */ - public function mappers_i18n($i18n_strings) { - foreach ($this->mappers as $mapper) { - $obj = new $mapper; - $i18n_strings[$obj->slug] = $obj->slug; // For url breadcrumb translations - $i18n_strings[$obj->name] = $obj->name; - } - return $i18n_strings; - } - - /** - * Return list of registered mappers - * @param string $output output format, ARRAY_N or OBJECT - */ - public function get_mappers($output = ARRAY_N) { - $ret = []; - switch ($output) { - case OBJECT: - foreach ($this->mappers as $mapper) { - $ret[] = new $mapper; - } - break; - case ARRAY_N: - default: - return $this->mappers; - break; - } - return $ret; - } - - /** - * Return list of registered types - * @param string $output output format, ARRAY_N or OBJECT - * @return array of slug or array of \Tainacan\Exposers\Types\Type - */ - public function get_types($output = \ARRAY_N) { - $ret = []; - switch ($output) { - case \OBJECT: - foreach ($this->types as $type) { - $ret[] = new $type; - } - break; - case \ARRAY_N: - default: - return $this->types; - break; - } - return $ret; - } - - /** - * - * @param \WP_REST_Response $response - * @param \WP_REST_Server $handler - * @param \WP_REST_Request $request - * @param Mapper $mapper - */ - public function create_mapped_metadata( $response, $handler, $request, $mapper ) { - if($response instanceof \WP_REST_Response && $response->get_status() == 201) { - $collection_array = $response->get_data(); - $id = $collection_array['id']; - $mapper_metadata = $mapper->metadata; - if(is_array($mapper_metadata) ) { - $Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance(); - foreach ($mapper_metadata as $slug => $mapper_metadatum) { - if(array_key_exists('core_metadatum', $mapper_metadatum) && $mapper_metadatum['core_metadatum'] != false) continue; - - $metadatum = new \Tainacan\Entities\Metadatum(); - if( - array_key_exists('metadata_type', $mapper_metadatum) && - $mapper_metadatum['metadata_type'] != false && - class_exists($mapper_metadatum['metadata_type']) - ) { - $metadatum->set_metadata_type($mapper_metadatum['metadata_type']); - } else { - $metadatum->set_metadata_type('Tainacan\Metadata_Types\Text'); - } - $metadatum->set_name($mapper_metadatum['label']); - $metadatum->set_semantic_uri($mapper_metadatum['URI']); - $metadatum->set_exposer_mapping([ - $mapper->slug => $slug - ]); - $metadatum->set_status('publish'); - $metadatum->set_collection_id($id); - $metadatum->set_slug($slug); - if($metadatum->validate()) $Tainacan_Metadata->insert($metadatum); - } - } - } - return $response; - } - - /** - * - * @param string $base_url url base for exposer parameters append - * @return string|string[][] - */ - public static function get_exposer_urls($base_url = '') { - $Tainacan_Exposers = self::get_instance(); - $mappers = $Tainacan_Exposers->get_mappers(\OBJECT); - $types = $Tainacan_Exposers->get_types(\OBJECT); - $urls = []; - foreach ($types as $type) { - $url = $base_url.(strpos($base_url, '?') === false ? '?' : '&').self::TYPE_PARAM.'='.$type->slug; - $urls[$type->slug] = [$url]; - if(is_array($type->get_mappers())) { - $first = true; // first is default, jump - foreach ($type->get_mappers() as $type_mapper) { - if($first) { - $first = false; - continue; - } - $urls[$type->slug][] = $url.'&'.self::MAPPER_PARAM.'='.$type_mapper; - } - } else { - foreach ($mappers as $mapper) { - $urls[$type->slug][] = $url.'&'.self::MAPPER_PARAM.'='.$mapper->slug; - } - } - } - return $urls; - } -} \ No newline at end of file diff --git a/src/exposers/types/class-tainacan-html.php b/src/exposers/class-tainacan-html.php similarity index 61% rename from src/exposers/types/class-tainacan-html.php rename to src/exposers/class-tainacan-html.php index 1c7f45e52..f20d8f37d 100644 --- a/src/exposers/types/class-tainacan-html.php +++ b/src/exposers/class-tainacan-html.php @@ -1,12 +1,12 @@ set_headers( ['Content-Type: text/html; charset=' . get_option( 'blog_charset' )] ); + + $items = $response->get_data(); + $html = '
-' . $meta['name'] . ' | '; + } + + $html .= '
---|
' . $meta['value_as_html'] . ' | '; + } + + $html .= '