refactor mappers and exposers

This commit is contained in:
Leo Germani 2018-11-25 20:52:04 -02:00
parent 9c0a763692
commit 80a24cb488
25 changed files with 961 additions and 659 deletions

View File

@ -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')
];

View File

@ -303,6 +303,8 @@ class REST_Collections_Controller extends REST_Controller {
$response = $this->prepare_item_for_response($collection, $request);
do_action('tainacan-api-collection-created', $response, $request);
return new \WP_REST_Response($response, 201);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 = [];

View File

@ -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'
]
]
];

View File

@ -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();

View File

@ -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)) {

View File

@ -0,0 +1,61 @@
<?php
namespace Tainacan\Exposers;
/**
* Generate a Csv formated response
*
*/
class Csv extends Exposer {
/**
* List of supported mappers
* @var array
*/
public $mappers = ['Value'];
public $slug = 'csv'; // type slug for url safe
public $name = 'Comma-separated values';
/**
*
* {@inheritDoc}
* @see \Tainacan\Exposers\Types\Type::rest_request_after_callbacks()
*/
public function rest_request_after_callbacks( $response, $handler, $request ) {
$response->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;
}
}

View File

@ -1,12 +1,12 @@
<?php
namespace Tainacan\Exposers\Types;
namespace Tainacan\Exposers;
/**
* abstract class for implement exposer types
*
*/
abstract class Type {
abstract class Exposer {
protected $mappers = true; // List of supported mapper, leave true for all
protected $extension = 'tnc'; // extension sufix for multi operation system compatibility

View File

@ -0,0 +1,269 @@
<?php
namespace Tainacan;
use Tainacan\Mappers\Mapper;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Load exposers classes
*/
class Exposers_Handler {
protected $exposers = [];
private static $instance = null;
private static $request = null;
const TYPE_PARAM = 'exposer';
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
public function __construct() {
self::$instance = $this;
//$this->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;
}
}

View File

@ -1,453 +0,0 @@
<?php
namespace Tainacan\Exposers;
use Tainacan\Exposers\Mappers\Mapper;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Load exposers classes
*/
class Exposers {
protected $types = [];
protected $mappers = [];
private static $instance = null;
private static $request = null;
const MAPPER_CLASS_PREFIX = 'Tainacan\Exposers\Mappers\\';
const MAPPER_PARAM = 'mapper';
const TYPE_PARAM = 'exposer';
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
public function __construct() {
self::$instance = $this;
$this->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;
}
}

View File

@ -1,12 +1,12 @@
<?php
namespace Tainacan\Exposers\Types;
namespace Tainacan\Exposers;
/**
* Generate a Html formated response
*
*/
class Html extends Type {
class Html extends Exposer {
public $mappers = ['Value'];
public $slug = 'html'; // type slug for url safe
@ -19,14 +19,55 @@ class Html extends Type {
*/
public function rest_request_after_callbacks( $response, $handler, $request ) {
$response->set_headers( ['Content-Type: text/html; charset=' . get_option( 'blog_charset' )] );
$items = $response->get_data();
$html = '
<!DOCTYPE html>
<html>
<body>
<table>
<table border="1">
';
$html .= $this->array_to_html($response->get_data());
$html .= '
if (sizeof($items) > 0) {
$headers = array_map(function($a) {
return $a['name'];
}, $items[0]['metadata']);
$html .= '<thead><tr>';
foreach ( $items[0]['metadata'] as $slug => $meta ) {
$html .= '<th>' . $meta['name'] . '</th>';
}
$html .= '</tr></thead>' . "\n";
$html .= '<tbody>';
foreach ($items as $item) {
$values = array_map(function($a) {
return $a['value_as_string'];
}, $item['metadata']);
$html .= '<tr>';
foreach ( $item['metadata'] as $slug => $meta ) {
$html .= '<td>' . $meta['value_as_html'] . '</td>';
}
$html .= '</tr>' . "\n";
}
$html .= '</tbody>' . "\n";
}
$html .= '
</table>
</body>
</html>

View File

@ -1,12 +1,12 @@
<?php
namespace Tainacan\Exposers\Types;
namespace Tainacan\Exposers;
/**
* Generate a text formated response
*
*/
class JSON_LD extends Type {
class JSON_LD extends Exposer {
public $mappers = ['value', 'dublin-core'];
public $slug = 'json-ld'; // type slug for url safe
@ -24,7 +24,7 @@ class JSON_LD extends Type {
'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\Exposers::request_has_mapper($request);
$mapper = \Tainacan\Exposers_Handler::request_has_mapper($request);
if(property_exists($mapper, 'XML_namespace') && !empty($mapper->XML_namespace)) {
$namespace = $mapper->XML_namespace;
$context_slug = str_replace(':', '', $mapper->prefix);

View File

@ -1,12 +1,12 @@
<?php
namespace Tainacan\Exposers\Types;
namespace Tainacan\Exposers;
/**
* Generate a OAI_PMH/oai_dc formated response
*
*/
class OAI_PMH extends Xml {
class OAI_PMH extends Exposer {
public $mappers = ['Dublin Core'];
public $slug = 'oai-pmh'; // type slug for url safe

View File

@ -1,12 +1,12 @@
<?php
namespace Tainacan\Exposers\Types;
namespace Tainacan\Exposers;
/**
* Generate a text formated response
*
*/
class Txt extends Type {
class Txt extends Exposer {
public $mappers = ['Value'];
public $slug = 'txt'; // type slug for url safe

View File

@ -1,12 +1,12 @@
<?php
namespace Tainacan\Exposers\Types;
namespace Tainacan\Exposers;
/**
* Generate a Csv formated response
*
*/
class Xml extends Type {
class Xml extends Exposer {
/**
* {@inheritdoc}
* @see \Tainacan\Exposers\Types\Type::extension
@ -23,7 +23,7 @@ class Xml extends Type {
*/
public function rest_request_after_callbacks( $response, $handler, $request ) {
$response->set_headers( ['Content-Type: application/xml; charset=' . get_option( 'blog_charset' )] );
$mapper = \Tainacan\Exposers\Exposers::request_has_mapper($request);
$mapper = \Tainacan\Exposers_Handler::request_has_mapper($request);
$xml = new \SimpleXMLElement( '<?xml version="1.0"?><data></data>' );
$namespace = null;
$xml_root = $xml;

View File

@ -1,50 +0,0 @@
<?php
namespace Tainacan\Exposers\Types;
/**
* Generate a Csv formated response
*
*/
class Csv extends Type {
/**
* List of supported mappers
* @var array
*/
public $mappers = ['Value'];
public $slug = 'csv'; // type slug for url safe
public $name = 'Comma-separated values';
/**
*
* {@inheritDoc}
* @see \Tainacan\Exposers\Types\Type::rest_request_after_callbacks()
*/
public function rest_request_after_callbacks( $response, $handler, $request ) {
$response->set_headers( [
'Content-Type: text/csv; charset=' . get_option( 'blog_charset' ),
'Content-disposition: attachment;filename=tainacan.csv'] // TODO filter/optional
);
$csv = fopen('php://memory', 'w');
$this->array_to_csv($response->get_data(), apply_filters('tainacan-exposer-csv', $csv));
rewind($csv);
$ret_csv = stream_get_contents($csv);
fclose($csv);
$response->set_data($ret_csv);
return $response;
}
/**
* Convert Array to Csv
* @param array $data
* @param string $csv
* @return string
*/
protected function array_to_csv( $data, $csv ) {
fputcsv($csv, array_keys($data), apply_filters('tainacan-exposer-csv-delimiter', ';') );
fputcsv($csv, array_values($data), apply_filters('tainacan-exposer-csv-delimiter', ';') );
return $csv;
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace Tainacan\Exposers\Mappers;
namespace Tainacan\Mappers;
/**
* Support Dublin Core Mapping
@ -13,69 +13,56 @@ class Dublin_Core extends Mapper {
public $allow_extra_metadata = true;
public $context_url = 'http://dublincore.org/documents/dcmi-terms/';
public $header = '<?xml version="1.0"?><!DOCTYPE rdf:RDF SYSTEM "http://dublincore.org/2000/12/01-dcmes-xml-dtd.dtd"><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" ></rdf:RDF>';
public $prefix = 'dc:';
public $prefixes = [
'dc' => 'http://purl.org/dc/elements/1.1/'
];
public $metadata = [
'contributor' => [
'URI' => 'http://purl.org/dc/elements/1.1/contributor',
'dc:contributor' => [
'label' => 'Contributor'
],
'coverage' => [
'URI' => 'http://purl.org/dc/elements/1.1/coverage',
'dc:coverage' => [
'label' => 'Coverage'
],
'creator' => [
'URI' => 'http://purl.org/dc/elements/1.1/creator',
'dc:creator' => [
'label' => 'Creator'
],
'date' => [
'URI' => 'http://purl.org/dc/elements/1.1/date',
'dc:date' => [
'label' => 'Date',
'metadata_type' => 'date'
],
'description' => [
'URI' => 'http://purl.org/dc/elements/1.1/description',
'dc:description' => [
'label' => 'Description',
'core_metadatum' => 'description'
],
'format' => [
'URI' => 'http://purl.org/dc/elements/1.1/format',
'dc:format' => [
'label' => 'Format',
],
'identifier' => [
'URI' => 'http://purl.org/dc/elements/1.1/identifier',
'dc:identifier' => [
'label' => 'Identifier'
],
'language' => [
'URI' => 'http://purl.org/dc/elements/1.1/language',
'dc:language' => [
'label' => 'Language'
],
'publisher' => [
'URI' => 'http://purl.org/dc/elements/1.1/publisher',
'dc:publisher' => [
'label' => 'Publisher'
],
'relation' => [
'URI' => 'http://purl.org/dc/elements/1.1/relation',
'dc:relation' => [
'label' => 'Relation'
],
'rights' => [
'URI' => 'http://purl.org/dc/elements/1.1/rights',
'dc:rights' => [
'label' => 'Rights'
],
'source' => [
'URI' => 'http://purl.org/dc/elements/1.1/source',
'dc:source' => [
'label' => 'Source'
],
'subject' => [
'URI' => 'http://purl.org/dc/elements/1.1/subject',
'dc:subject' => [
'label' => 'Subject'
],
'title' => [
'URI' => 'http://purl.org/dc/elements/1.1/title',
'dc:title' => [
'label' => 'Title',
'core_metadatum' => 'title'
],
'type' => [
'URI' => 'http://purl.org/dc/elements/1.1/type',
'dc:type' => [
'label' => 'Type'
]
];

View File

@ -1,6 +1,6 @@
<?php
namespace Tainacan\Exposers\Mappers;
namespace Tainacan\Mappers;
abstract class Mapper {
public $slug = null; // Slug of Mapper, used as option on api call
@ -47,4 +47,23 @@ abstract class Mapper {
'header' => $this->header
];
}
/**
* Gets the semantic URL for a given metadatum of this mapper.
* Basically it identifies the property prefix and replace it with the URL of that prefix
*
* @param string $meta_slug The slug of the metadata present in this mapper to get the URL from
* @return string The semantic URL for this metadata. Empty string in case of failure
*/
public function get_url($meta_slug) {
$parts = explode(':', $meta_slug);
$url = '';
if (sizeof($parts) == 2) {
if (isset($this->prefixes[$parts[0]])) {
$url = trailingslashit( $this->prefixes[$parts[0]] ) . $parts[1];
}
}
return $url;
}
}

View File

@ -0,0 +1,321 @@
<?php
namespace Tainacan;
class Mappers_Handler {
private static $instance = null;
protected $mappers = [];
const MAPPER_CLASS_PREFIX = 'Tainacan\Mappers\\';
const MAPPER_PARAM = 'mapper';
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
public function __construct() {
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']);
add_action('tainacan-api-collection-created', [$this, 'create_mapped_collection'], 10, 2);
add_filter('tainacan-api-items-prepare-for-response', [$this, 'filter_item_api_response'], 10, 3);
}
/**
* register mappers class
*
* @param $class_name string | object The class name or the object instance
*/
public function register_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;
}
}
/**
* unregister mappers class
*
* @param $class_name string | object The class name or the object instance
*/
public function unregister_mapper( $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->mappers) ) {
unset($this->mappers[$obj->slug]);
}
}
/**
* 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;
}
/**
* 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;
}
/**
* 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_Mappers = self::get_instance();
$query_url_params = $request->get_query_params();
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;
} 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 false; // No mapper need, using Tainacan defautls
}
/**
* 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;
}
/**
* Return if mapper is registered
* @param string $mapper
* @return boolean
*/
public function mapper_exists($mapper) {
return in_array($this->check_class_name($mapper, false, self::MAPPER_CLASS_PREFIX), $this->mappers);
}
/**
* 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\Mapper\\') {
if(is_string($class_name)) {
if( 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;
}
/**
*
* @param array $collection collection passed by the collections API endpoint
* @param \WP_REST_Request $request
*/
public function create_mapped_collection( $collection, $request ) {
if ($mapper = $this->request_has_mapper($request)) {
$mapper_metadata = $mapper->metadata;
if(is_array($mapper_metadata) ) {
$id = $collection['id'];
$collection_object = \Tainacan\Repositories\Collections::get_instance()->fetch($id);
$Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance();
foreach ($mapper_metadata as $slug => $mapper_metadatum) {
if( array_key_exists('core_metadatum', $mapper_metadatum) ) {
$method = 'get_core_' . $mapper_metadatum['core_metadatum'] . '_metadatum';
if (method_exists($collection_object, $method)) {
$core_meta = $collection_object->$method();
$_meta_mapping = $core_meta->get_exposer_mapping();
$_meta_mapping[$mapper->slug] = $slug;
$core_meta->set_exposer_mapping($_meta_mapping);
if ($core_meta->validate()) {
$Tainacan_Metadata->insert($core_meta);
}
}
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->get_url($slug));
$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);
}
}
}
}
function filter_item_api_response($item_arr, $item, $request) {
$mapper = $this->request_has_mapper($request);
if (!$mapper) {
return $item_arr;
}
$mapper_meta = $mapper->metadata;
$mapped_meta = [];
foreach ($item_arr['metadata'] as $slug => $meta) {
if ( array_key_exists($mapper->slug, $meta['mapping']) ) {
$mapped_slug = $meta['mapping'][$mapper->slug];
// Extra metadata
if ( is_array($mapped_slug) ) {
$url = $mapped_slug['uri'];
$label = $mapped_slug['label'];
$mapped_slug = $mapped_slug['slug'];
} else {
$url = $mapper->get_url( $mapped_slug );
$label = $mapper->metadata[$mapped_slug]['label'];
}
$mapped_meta[ $mapped_slug ] = $meta;
$mapped_meta[ $mapped_slug ]['semantic_url'] = $url;
$mapped_meta[ $mapped_slug ]['name'] = $label;
$mapped_meta[ $mapped_slug ]['slug'] = $mapped_slug;
}
}
$item_arr['metadata'] = $mapped_meta;
return $item_arr;
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace Tainacan\Exposers\Mappers;
namespace Tainacan\Mappers;
/**
* Mapper class for export metadata in key => value format where key can be defined

View File

@ -193,8 +193,8 @@ class TAINACAN_REST_Export_Controller extends TAINACAN_UnitApiTestCase {
extract($this->create_requirements());
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::TYPE_PARAM => 'Xml',
\Tainacan\Exposers\Exposers::MAPPER_PARAM => 'Value',
\Tainacan\Exposers_Handler::TYPE_PARAM => 'Xml',
\Tainacan\Exposers_Handler::MAPPER_PARAM => 'Value',
'export-background' => false
]);
@ -232,7 +232,7 @@ class TAINACAN_REST_Export_Controller extends TAINACAN_UnitApiTestCase {
extract($this->create_requirements());
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::TYPE_PARAM => 'Xml',
\Tainacan\Exposers_Handler::TYPE_PARAM => 'Xml',
'exposer-map' => 'Value',
'export-background' => false
]);

View File

@ -38,7 +38,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
'collection' => $collection,
'metadata_type' => $type,
'exposer_mapping' => [
'dublin-core' => 'language'
'dublin-core' => 'dc:language'
]
),
true,
@ -53,7 +53,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
'collection' => $collection,
'metadata_type' => $type,
'exposer_mapping' => [
'dublin-core' => 'subject'
'dublin-core' => 'dc:subject'
]
),
true,
@ -101,11 +101,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$this->assertEquals($this->item->get_id(), $data['item']['id']);
$this->assertEquals('TestValues_exposers', $data['value']);
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::MAPPER_PARAM => 'Value',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/'. $this->metadatum->get_id() );
$request->set_body($item_exposer_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
@ -159,7 +155,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$this->assertEquals(200, $response->get_status());
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::TYPE_PARAM => 'Xml',
\Tainacan\Exposers_Handler::TYPE_PARAM => 'Xml',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/'. $this->metadatum->get_id() );
@ -179,7 +175,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$this->assertInstanceOf('SimpleXMLElement', @simplexml_load_string($data));
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::MAPPER_PARAM => 'Dublin Core',
\Tainacan\Exposers_Handler::MAPPER_PARAM => 'Dublin Core',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/'. $this->metadatum->get_id() );
$request->set_body($item_exposer_json);
@ -189,8 +185,8 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$this->assertEquals('TestValues_exposers', $data['dc:language']);
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::TYPE_PARAM => 'Xml',
\Tainacan\Exposers\Exposers::MAPPER_PARAM => 'Dublin Core',
\Tainacan\Exposers_Handler::TYPE_PARAM => 'Xml',
\Tainacan\Exposers_Handler::MAPPER_PARAM => 'Dublin Core',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
@ -233,7 +229,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$this->assertEquals('TestValues_exposers_slug', $data['value']);
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::MAPPER_PARAM => 'dublin-core',
\Tainacan\Exposers_Handler::MAPPER_PARAM => 'dublin-core',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata/'. $this->metadatum->get_id() );
$request->set_body($item_exposer_json);
@ -243,8 +239,8 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$this->assertEquals('TestValues_exposers_slug', $data['dc:language']);
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::TYPE_PARAM => 'xml',
\Tainacan\Exposers\Exposers::MAPPER_PARAM => 'dublin-core',
\Tainacan\Exposers_Handler::TYPE_PARAM => 'xml',
\Tainacan\Exposers_Handler::MAPPER_PARAM => 'dublin-core',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
@ -270,7 +266,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
extract($this->create_meta_requirements());
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::TYPE_PARAM => 'OAI-PMH',
\Tainacan\Exposers_Handler::TYPE_PARAM => 'OAI-PMH',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
@ -293,8 +289,8 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
extract($this->create_meta_requirements());
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::TYPE_PARAM => 'Html',
\Tainacan\Exposers\Exposers::MAPPER_PARAM => 'Value'
\Tainacan\Exposers_Handler::TYPE_PARAM => 'Html',
\Tainacan\Exposers_Handler::MAPPER_PARAM => 'Value'
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
@ -353,7 +349,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$this->assertEquals(200, $response->get_status());
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::TYPE_PARAM => 'Csv',
\Tainacan\Exposers_Handler::TYPE_PARAM => 'Csv',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
@ -426,7 +422,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
);
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::MAPPER_PARAM => 'Value',
\Tainacan\Exposers_Handler::MAPPER_PARAM => 'Value',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/items/' . $this->item->get_id() );
@ -445,7 +441,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
*/
public function test_mapped_new_collection() {
$collection_JSON = json_encode([
\Tainacan\Exposers\Exposers::MAPPER_PARAM => 'Dublin Core',
\Tainacan\Exposers_Handler::MAPPER_PARAM => 'Dublin Core',
'name' => 'TesteJsonAddDublin_Core',
'description' => 'Teste JSON Dublin Core mapped',
'status' => 'publish'
@ -501,8 +497,8 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$this->assertEquals('TestValues_exposers', $data['value']);
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::TYPE_PARAM => 'json-ld',
\Tainacan\Exposers\Exposers::MAPPER_PARAM => 'dublin-core',
\Tainacan\Exposers_Handler::TYPE_PARAM => 'json-ld',
\Tainacan\Exposers_Handler::MAPPER_PARAM => 'dublin-core',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $this->item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
@ -528,7 +524,7 @@ class TAINACAN_REST_Exposers extends TAINACAN_UnitApiTestCase {
$id = $item->get_id();
$base_url = "{$this->namespace}/items/{$id}/";
$urls = \Tainacan\Exposers\Exposers::get_exposer_urls($base_url);
$urls = \Tainacan\Exposers_Handler::get_exposer_urls($base_url);
var_dump($urls);return;
foreach ($urls as $type => $type_urls) {
foreach ($type_urls as $url) {

View File

@ -18,17 +18,15 @@ class TAINACAN_REST_Metadatum_Mappers_Controller extends TAINACAN_UnitApiTestCas
true
);
$type = $this->tainacan_metadatum_factory->create_metadatum('text');
$metadatum = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'test_MetadatumMappers',
'description' => 'descricao',
'collection' => $collection,
'metadata_type' => $type,
'metadata_type' => 'Tainacan\Metadata_Types\Text',
'exposer_mapping' => [
'dublin-core' => 'language'
'dublin-core' => 'dc:language'
]
),
true,
@ -41,7 +39,22 @@ class TAINACAN_REST_Metadatum_Mappers_Controller extends TAINACAN_UnitApiTestCas
'name' => 'test_MetadatumMappers2',
'description' => 'descricao2',
'collection' => $collection,
'metadata_type' => $type
'metadata_type' => 'Tainacan\Metadata_Types\Text'
),
true,
true
);
$metadatum3 = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'test_MetadatumMappers3',
'description' => 'descricao3',
'collection' => $collection,
'metadata_type' => 'Tainacan\Metadata_Types\Text',
'exposer_mapping' => [
'dublin-core' => 'dc:creator'
]
),
true,
true
@ -60,6 +73,8 @@ class TAINACAN_REST_Metadatum_Mappers_Controller extends TAINACAN_UnitApiTestCas
$this->collection = $collection;
$this->item = $item;
$this->metadatum = $metadatum;
$this->metadatum2 = $metadatum2;
$this->metadatum3 = $metadatum3;
return ['collection' => $collection, 'item' => $item, 'metadatum' => $metadatum, 'metadatum2' => $metadatum2];
}
@ -71,10 +86,10 @@ class TAINACAN_REST_Metadatum_Mappers_Controller extends TAINACAN_UnitApiTestCas
$data = $metadatum_mapper_response->get_data();
$Tainacan_Metadata = \Tainacan\Exposers\Exposers::get_instance();
$Tainacan_Metadata = \Tainacan\Mappers_Handler::get_instance();
$metadatum_mappers = $Tainacan_Metadata->get_mappers("OBJECT");
/** @var \Tainacan\Exposers\Mappers\Mapper $metadatum_mapper **/
/** @var \Tainacan\Mappers\Mapper $metadatum_mapper **/
foreach ($metadatum_mappers as $k => $metadatum_mapper) {
if(!$metadatum_mapper->show_ui) unset($metadatum_mappers[$k]);
}
@ -96,7 +111,7 @@ class TAINACAN_REST_Metadatum_Mappers_Controller extends TAINACAN_UnitApiTestCas
public function test_update_metadatum_mappers(){
extract($this->create_meta_requirements());
$dc = new \Tainacan\Exposers\Mappers\Dublin_Core();
$dc = new \Tainacan\Mappers\Dublin_Core();
$metadatum_mapper_request = new \WP_REST_Request('POST', $this->namespace . '/metadatum-mappers');
$metadatum_mapper_json = json_encode([
@ -104,7 +119,7 @@ class TAINACAN_REST_Metadatum_Mappers_Controller extends TAINACAN_UnitApiTestCas
['metadatum_id' => $metadatum->get_id(), 'mapper_metadata' => 'contributor'],
['metadatum_id' => $metadatum2->get_id(), 'mapper_metadata' => 'coverage']
],
\Tainacan\Exposers\Exposers::MAPPER_PARAM => $dc->slug
\Tainacan\Mappers_Handler::MAPPER_PARAM => $dc->slug
]);
$metadatum_mapper_request->set_body($metadatum_mapper_json);
$metadatum_mapper_response = $this->server->dispatch($metadatum_mapper_request);
@ -132,7 +147,7 @@ class TAINACAN_REST_Metadatum_Mappers_Controller extends TAINACAN_UnitApiTestCas
public function test_update_metadatum_mappers_new_meta(){
extract($this->create_meta_requirements());
$dc = new \Tainacan\Exposers\Mappers\Dublin_Core();
$dc = new \Tainacan\Mappers\Dublin_Core();
$metadatum_mapper_request = new \WP_REST_Request('POST', $this->namespace . '/metadatum-mappers');
$new_metadatum_mapper = new \stdClass();
@ -144,7 +159,7 @@ class TAINACAN_REST_Metadatum_Mappers_Controller extends TAINACAN_UnitApiTestCas
['metadatum_id' => $metadatum->get_id(), 'mapper_metadata' => 'contributor'],
['metadatum_id' => $metadatum2->get_id(), 'mapper_metadata' => $new_metadatum_mapper ]
],
\Tainacan\Exposers\Exposers::MAPPER_PARAM => $dc->slug
\Tainacan\Mappers_Handler::MAPPER_PARAM => $dc->slug
]);
$metadatum_mapper_request->set_body($metadatum_mapper_json);
$metadatum_mapper_response = $this->server->dispatch($metadatum_mapper_request);
@ -167,21 +182,108 @@ class TAINACAN_REST_Metadatum_Mappers_Controller extends TAINACAN_UnitApiTestCas
$this->assertEquals(200, $response->get_status());
$item_exposer_json = json_encode([
\Tainacan\Exposers\Exposers::TYPE_PARAM => 'OAI-PMH',
]);
$request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata' );
$request->set_body($item_exposer_json);
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
// $item_exposer_json = json_encode([
// \Tainacan\Exposers_Handler::TYPE_PARAM => 'OAI-PMH',
// ]);
// $request = new \WP_REST_Request('GET', $this->namespace . '/item/' . $item->get_id() . '/metadata' );
// $request->set_body($item_exposer_json);
// $response = $this->server->dispatch($request);
// $this->assertEquals(200, $response->get_status());
// $data = $response->get_data();
//
// $xml = new \SimpleXMLElement($data);
// $dc = $xml->children(\Tainacan\Exposers\Mappers\Dublin_Core::XML_DC_NAMESPACE);
// $this->assertEquals('adasdasdsaadsf', $dc->description);
// $this->assertEquals('item_teste_MetadatumMappers', $dc->title);
// $this->assertEquals('', $dc->contributor);
// $this->assertEquals('TestValues_exposersCustomMeta', $dc->TesteNewMeta);
$xml = new \SimpleXMLElement($data);
$dc = $xml->children(\Tainacan\Exposers\Mappers\Dublin_Core::XML_DC_NAMESPACE);
$this->assertEquals('adasdasdsaadsf', $dc->description);
$this->assertEquals('item_teste_MetadatumMappers', $dc->title);
$this->assertEquals('', $dc->contributor);
$this->assertEquals('TestValues_exposersCustomMeta', $dc->TesteNewMeta);
}
function test_create_new_mapped_collection() {
$dc = new \Tainacan\Mappers\Dublin_Core();
$metadatum_mapper_request = new \WP_REST_Request('POST', $this->namespace . '/collections');
$metadatum_mapper_request->set_body(json_encode([
\Tainacan\Mappers_Handler::MAPPER_PARAM => $dc->slug,
'name' => 'Test Collection'
]));
$metadatum_mapper_response = $this->server->dispatch($metadatum_mapper_request);
$this->assertEquals(201, $metadatum_mapper_response->get_status());
$data = $metadatum_mapper_response->get_data();
$collection = \Tainacan\Repositories\Collections::get_instance()->fetch( $data['id'] );
$mapper_meta = $dc->metadata;
$metadata = $collection->get_metadata();
$this->assertEquals(sizeof($metadata), sizeof($mapper_meta));
foreach ($metadata as $meta) {
$map = $meta->get_exposer_mapping();
if (isset($map[$dc->slug]) && isset($mapper_meta[$map[$dc->slug]])) {
unset($mapper_meta[$map[$dc->slug]]);
}
}
$this->assertEmpty($mapper_meta);
}
function test_api_get_items_from_mapped_collection() {
$this->create_meta_requirements();
$dc = new \Tainacan\Mappers\Dublin_Core();
$itemMeta1 = $this->tainacan_item_metadata_factory->create_item_metadata(
$this->item,
$this->metadatum,
'Value for meta 1');
$itemMeta2 = $this->tainacan_item_metadata_factory->create_item_metadata(
$this->item,
$this->metadatum2,
'Value for meta 2');
$itemMeta3 = $this->tainacan_item_metadata_factory->create_item_metadata(
$this->item,
$this->metadatum3,
'Value for meta 3');
$item_request = new \WP_REST_Request('GET', $this->namespace . '/collection/' . $this->collection->get_id() . '/items');
$item_request->set_body(json_encode([
\Tainacan\Mappers_Handler::MAPPER_PARAM => $dc->slug
]));
$response = $this->server->dispatch($item_request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertEquals(1, sizeof($data), 'Response should contain 1 item');
$item = $data[0];
$this->assertEquals(2, sizeof($item['metadata']), 'Item should contain only 2 mapped metadata');
//var_dump($item['metadata']);
$this->assertTrue( array_key_exists('dc:language', $item['metadata']), 'metadatum language should be present' );
$this->assertTrue( array_key_exists('dc:creator', $item['metadata']), 'metadatum creator should be present' );
$this->assertEquals('Value for meta 1', $item['metadata']['dc:language']['value']);
$this->assertEquals('Value for meta 3', $item['metadata']['dc:creator']['value']);
$this->assertEquals($dc->get_url('dc:language'), $item['metadata']['dc:language']['semantic_url']);
$this->assertEquals($dc->get_url('dc:creator'), $item['metadata']['dc:creator']['semantic_url']);
$this->assertEquals($dc->metadata['dc:language']['label'], $item['metadata']['dc:language']['name']);
$this->assertEquals($dc->metadata['dc:creator']['label'], $item['metadata']['dc:creator']['name']);
$this->assertEquals('dc:language', $item['metadata']['dc:language']['slug']);
$this->assertEquals('dc:creator', $item['metadata']['dc:creator']['slug']);
}