create verb identify and get record (ref. #181)

This commit is contained in:
Eduardo Humberto 2019-02-01 20:20:50 -02:00
parent 6a010d8d32
commit 00aff2b88f
6 changed files with 321 additions and 86 deletions

View File

@ -24,6 +24,8 @@ class REST_Oaipmh_Expose_Controller extends REST_Controller {
$this->list_sets = new \Tainacan\OAIPMHExpose\OAIPMH_List_Sets();
$this->list_metadata_formats = new \Tainacan\OAIPMHExpose\OAIPMH_List_Metadata_Formats();
$this->list_records = new \Tainacan\OAIPMHExpose\OAIPMH_List_Records();
$this->get_record = new \Tainacan\OAIPMHExpose\OAIPMH_Get_Record();
$this->identify = new \Tainacan\OAIPMHExpose\OAIPMH_Identify();
}
public function register_routes() {
@ -77,10 +79,32 @@ class REST_Oaipmh_Expose_Controller extends REST_Controller {
$this->list_records->list_records($request);
break;
case 'GetRecord':
if ( !isset($request['metadataPrefix']) ) {
$this->get_record->config();
$this->get_record->errors[] = $this->get_record->oai_error('missingArgument','metadataPrefix');
$this->get_record->oai_exit( $request, $this->get_record->errors );
}
if( !isset($request['identifier']) ){
$this->get_record->config();
$this->get_record->errors[] = $this->get_record->oai_error('missingArgument','identifier');
$this->get_record->oai_exit( $request, $this->get_record->errors );
}
$this->get_record->get_record( $request );
break;
case 'ListMetadataFormats':
$this->list_metadata_formats->list_metadata_formats($request);
break;
case 'Identify':
$this->identify->identify($request);
break;
default:
$this->controller_oai->config();
$this->controller_oai->errors[] = $this->controller_oai->oai_error('noVerb');

View File

@ -26,21 +26,19 @@ class OAIPMH_Expose {
var $xmlescaped;
var $text;
var $code;
/**
* @signature - config
* @return begin the class
* @author: Eduardo
*
*/
public function config() {
$this->CONTENT_TYPE = 'Content-Type: text/xml';
$this->identifyResponse["repositoryName"] = get_bloginfo( 'name');
$this->identifyResponse['protocolVersion'] = '2.0';
$this->identifyResponse['baseURL'] = get_bloginfo( 'url').'/oai/socialdb-oai/';
$this->identifyResponse['baseURL'] = get_bloginfo( 'url').'wp-json/tainacan/v2/oai/';
$this->identifyResponse["earliestDatestamp"] = '2006-06-01';
$this->identifyResponse["deletedRecord"] = 'no';
$this->identifyResponse["deletedRecord"] = 'transient';
$this->identifyResponse["granularity"] = 'YYYY-MM-DDThh:mm:ssZ';
//$this->deletedRecord = $identifyResponse["deletedRecord"]; // a shorthand for checking the configuration of Deleted Records
if (strcmp($this->identifyResponse["granularity"], 'YYYY-MM-DDThh:mm:ssZ') == 0) {
$this->identifyResponse["earliestDatestamp"] = $this->identifyResponse["earliestDatestamp"] . 'T00:00:00Z';
}
@ -82,6 +80,7 @@ class OAIPMH_Expose {
/** After 24 hours resumptionTokens become invalid. Unit is second. */
define('TOKEN_VALID', 24 * 3600);
define('MY_URI', get_bloginfo( 'url' ));
$this->expirationdatetime = gmstrftime('%Y-%m-%dT%TZ', time() + TOKEN_VALID);
/** Where token is saved and path is included */
@ -110,44 +109,6 @@ class OAIPMH_Expose {
$this->xmlescaped = false;
}
/** Dump information of a varible for debugging,
* only works when SHOW_QUERY_ERROR is true.
* \param $var_name Type: string Name of variable is being debugded
* \param $var Type: mix Any type of varibles used in PHP
* \see SHOW_QUERY_ERROR in oaidp-config.php
*/
function debug_var_dump($var_name, $var) {
if (SHOW_QUERY_ERROR) {
echo "Dumping \${$var_name}: \n";
var_dump($var) . "\n";
}
}
/** Prints human-readable information about a variable for debugging,
* only works when SHOW_QUERY_ERROR is true.
* \param $var_name Type: string Name of variable is being debugded
* \param $var Type: mix Any type of varibles used in PHP
* \see SHOW_QUERY_ERROR in oaidp-config.php
*/
function debug_print_r($var_name, $var) {
if (SHOW_QUERY_ERROR) {
echo "Printing \${$var_name}: \n";
print_r($var) . "\n";
}
}
/** Prints a message for debugging,
* only works when SHOW_QUERY_ERROR is true.
* PHP function print_r can be used to construct message with <i>return</i> parameter sets to true.
* \param $msg Type: string Message needs to be shown
* \see SHOW_QUERY_ERROR in oaidp-config.php
*/
function debug_message($msg) {
if (!SHOW_QUERY_ERROR)
return;
echo $msg, "\n";
}
/** Check if provided correct arguments for a request.
*
* Only number of parameters is checked.
@ -254,6 +215,7 @@ class OAIPMH_Expose {
return date("Y-m-d", $time_val);
}
}
/** Retrieve all defined 'setSpec' from configuraiton of $SETS.
* It is used by ANDS_TPA::create_obj_node();
*/
@ -266,6 +228,7 @@ class OAIPMH_Expose {
}
return $a;
}
/** Finish a request when there is an error: send back errors. */
function oai_exit($args,$errors) {
header($this->CONTENT_TYPE);
@ -332,43 +295,6 @@ class OAIPMH_Expose {
return $rtVal;
}
/**
* function has_mapping($collection_id)
* @param int $collection_id
* @return boolean
* @author: Eduardo Humberto
*/
public function has_mapping($collection_id) {
}
/**
* function get_mapping_harvested($collection_id)
* @param int $collection_id
* @return boolean
* @author: Eduardo Humberto
*/
public function get_mapping_harvested($collection_id) {
}
/**
* function list_collections_mapped()
* @author: Eduardo Humberto
*/
public function get_harvesting_mappings() {
}
/**
* function list_collections_mapped()
* @description metodo em retornar apenas as colecoes mapeadas
* @author: Eduardo Humberto
*/
public function list_collections_mapped() {
}
/** utility funciton to mapping error codes to readable messages */
function oai_error($code, $argument = '', $value = '') {
switch ($code) {

View File

@ -0,0 +1,233 @@
<?php
namespace Tainacan\OAIPMHExpose;
use Tainacan\Repositories;
use Tainacan\Entities;
class OAIPMH_Get_Record extends OAIPMH_Expose {
protected $working_node;
public $errors;
public $xml_creater;
public $restoken = '-';
public $expirationdatetime;
public $num_rows;
public $cursor;
public $deliveredrecords;
public $from;
public $until;
public $sets;
public $metadataPrefix;
/**
* @signature CONSTRUTOR
*
* getting the collection repository
* @author: Eduardo
*/
function __construct() {
$this->collection_repository = Repositories\Collections::get_instance();
$this->item_repository = Repositories\Items::get_instance();
}
/**
* @param $params
* @return bool|Entities\Item
* @throws \Exception
*/
public function get_item( $params ) {
$id = str_replace('oai:'.$this->repositoryIdentifier.':','', $params['identifier']);
$item = new Entities\Item( $id );
if( !$item->get_id() ){
return false;
}
$item->collection = $item->get_collection();
return $item;
}
/**
* @param $data
* @throws \Exception
*/
public function get_record( $data ) {
session_write_close();
$this->config();
$this->initiate_variables( $data );
$item = $this->get_item( $data );
if( $item ){
$formats = $this->get_metadata_formats();
$prefix = ( $data['metadataPrefix'] === 'oai_dc') ? 'dublin-core' : $data['metadataPrefix'];
if( empty($formats) || !in_array($prefix, $formats) ){
$this->errors[] = $this->oai_error('cannotDisseminateFormat');
$this->oai_exit($data,$this->errors);
}
}else{
$this->errors[] = $this->oai_error('idDoesNotExist');
$this->oai_exit( $data, $this->errors);
}
$this->xml_creater = new Xml_Response($data);
$collection = $item->collection;
$identifier = 'oai:'.$this->repositoryIdentifier.':'. $item->get_id();
$datestamp = $this->formatDatestamp($item->get_creation_date());
$setspec = $collection->get_id();
$cur_record = $this->xml_creater->create_record();
$this->xml_creater->create_header($identifier, $datestamp, $setspec,$cur_record, ( $item->get_status() === 'trash' ) ? true : false );
if( $item->get_status() !== 'trash' ){
$this->working_node = $this->xml_creater->create_metadata($cur_record);
$this->create_metadata_node( $item, $collection, $cur_record);
}
ob_start('ob_gzhandler');
header($this->CONTENT_TYPE);
if (isset($this->xml_creater)) {
$this->xml_creater->display();
} else {
exit("There is a bug in codes");
}
ob_end_flush();
}
/**
* Gets the current mapper object, if one was chosen by the user, false Otherwise
*/
public function get_current_mapper() {
$prefix = ($this->metadataPrefix === 'oai_dc') ? 'dublin-core' : $this->metadataPrefix;
return \Tainacan\Mappers_Handler::get_instance()->get_mapper($prefix);
}
/**
* @signature - create_metadata_node
* @param \Tainacan\Entities\Item $item
* @param wp_post $collection O objeto da colecao
* @return Adciona no noh <metadata> os valores necessarios
* @description - Metodo responsavel realizar o povoamento no noh metadata
* @author: Eduardo
*/
protected function create_metadata_node( $item, $collection,$record_node = null) {
$this->working_node = $this->xml_creater->addChild($this->working_node, 'oai_dc:dc');
$this->working_node->setAttribute('xmlns:oai_dc', "http://www.openarchives.org/OAI/2.0/oai_dc/");
$this->working_node->setAttribute('xmlns:dc', "http://purl.org/dc/elements/1.1/");
$this->working_node->setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance");
$this->working_node->setAttribute('xsi:schemaLocation', 'http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd');
$maps = $this->map_item_metadata($item);
try{
if ($maps) {
foreach ($maps as $key => $val) {
$this->xml_creater->addChild($this->working_node, $key, html_entity_decode($val));
}
}
}catch(Exception $e){
var_dump($e,$this->working_node,'dc:' . $key);
}
}
/**
* Gets an Item as input and return an array of ItemMetadataObjects
* If a mapper is selected, the array keys will be the slugs of the metadata
* declared by the mapper, in the same order.
* Note that if one of the metadata is not mapped, this array item will be null
*/
private function map_item_metadata(\Tainacan\Entities\Item $item) {
$prefix = ($this->metadataPrefix === 'oai_dc') ? 'dublin-core' : $this->metadataPrefix;
$mapper = $this->get_current_mapper();
$metadata = $item->get_metadata();
if (!$mapper) {
return $metadata;
}
$pre = [];
foreach ($metadata as $item_metadata) {
$metadatum = $item_metadata->get_metadatum();
$meta_mappings = $metadatum->get_exposer_mapping();
if ( array_key_exists($prefix, $meta_mappings) ) {
$pre[ $meta_mappings[$prefix] ] = $item_metadata;
}
}
// reorder
$return = [];
foreach ( $mapper->metadata as $meta_slug => $meta ) {
if ( array_key_exists($meta_slug, $pre) ) {
$return[$meta_slug] = $pre[$meta_slug];
} else {
$return[$meta_slug] = null;
}
}
return $return;
}
/**
* @param $data
*/
public function initiate_variables( $data ) {
if ( isset($data['resumptionToken']) ) {
if ( !file_exists(TOKEN_PREFIX . $data['resumptionToken']) ) {
$this->errors[] = $this->oai_error('badResumptionToken', '', $data['resumptionToken']);
} else {
$readings = $this->readResumToken(TOKEN_PREFIX . $data['resumptionToken']);
if ($readings == false) {
$this->errors[] = $this->oai_error('badResumptionToken', '', $data['resumptionToken']);
} else {
list($this->deliveredrecords, $this->from, $this->until, $sets, $this->metadataPrefix) = $readings;
if($sets=='-'){
$this->sets = array();
}else{
$this->sets = explode(',', $sets);
}
}
}
} else {
$this->deliveredrecords = 0;
if (isset($data['set'])) {
if (is_array($data['set'])) {
$this->sets = $data['set'];
} else {
$this->sets = array($data['set']);
}
} else {
$this->sets = array();
}
if (isset($data['from'])) {
$this->from = $data['from'];
} else {
$this->from = '-';
}
if (isset($data['until'])) {
$this->until = $data['until'];
} else {
$this->until = '-';
}
$this->metadataPrefix = $data['metadataPrefix'];
}
if(is_array($this->errors)&&count($this->errors)>0){
$this->oai_exit($data,$this->errors);
}
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace Tainacan\OAIPMHExpose;
class OAIPMH_Identify extends OAIPMH_Expose {
protected $working_node;
/**
* @param $data
*/
public function identify($data) {
$this->config();
$this->xml_creater = new Xml_Response($data);
$this->xml_creater->add2_verbNode('repositoryName',$this->identifyResponse["repositoryName"]);
$this->xml_creater->add2_verbNode('baseURL',$this->identifyResponse["baseURL"]);
$this->xml_creater->add2_verbNode('protocolVersion',$this->identifyResponse["protocolVersion"]);
$this->xml_creater->add2_verbNode('earliestDatestamp',$this->identifyResponse["earliestDatestamp"]);
$this->xml_creater->add2_verbNode('deletedRecord',$this->identifyResponse["deletedRecord"]);
$this->xml_creater->add2_verbNode('granularity',$this->identifyResponse["granularity"]);
$this->xml_creater->add2_verbNode('adminEmail',$this->adminEmail);
$description_node = $this->xml_creater->add2_verbNode('description');
$this->working_node = $this->xml_creater->addChild($description_node, 'oai-identifier');
$this->working_node->setAttribute('xmlns', "http://www.openarchives.org/OAI/2.0/oai-identifier");
$this->working_node->setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance");
$this->working_node->setAttribute('xsi:schemaLocation', 'http://www.openarchives.org/OAI/2.0/oai-identifier http://www.openarchives.org/OAI/2.0/oai-identifier.xsd');
$this->xml_creater->addChild($this->working_node, 'scheme', 'oai');
$this->xml_creater->addChild($this->working_node, 'repositoryIdentifier', $this->repositoryIdentifier);
$this->xml_creater->addChild($this->working_node, 'delimiter', ':');
$this->xml_creater->addChild($this->working_node, 'sampleIdentifier', 'oai:'.$this->repositoryIdentifier.':1');
header($this->CONTENT_TYPE);
if (isset($this->xml_creater)) {
$this->xml_creater->display();
} else {
exit("There is a bug in codes");
}
}
}

View File

@ -65,7 +65,8 @@ class OAIPMH_List_Records extends OAIPMH_Expose {
'posts_per_page' => $this->MAXRECORDS,
'paged' => $this->deliveredrecords == 0 ? 1 : ( $this->deliveredrecords / 100 ) + 1,
'order' => 'DESC',
'orderby' => 'ID'
'orderby' => 'ID',
'post_status' => array( 'trash', 'publish' )
];
if( !empty($this->sets) ){
@ -127,9 +128,13 @@ class OAIPMH_List_Records extends OAIPMH_Expose {
$datestamp = $this->formatDatestamp($item->get_creation_date());
$setspec = $collection->get_id();
$cur_record = $this->xml_creater->create_record();
$cur_header = $this->xml_creater->create_header($identifier, $datestamp, $setspec,$cur_record);
$this->working_node = $this->xml_creater->create_metadata($cur_record);
$this->create_metadata_node( $item, $collection, $cur_record);
$cur_header = $this->xml_creater->create_header($identifier, $datestamp, $setspec,$cur_record, ( $item->get_status() === 'trash' ) ? true : false );
if( $item->get_status() !== 'trash' ){
$this->working_node = $this->xml_creater->create_metadata($cur_record);
$this->create_metadata_node( $item, $collection, $cur_record);
}
}
//resumptionToken

View File

@ -45,12 +45,17 @@ class Xml_Response extends Xml_Create {
* In normal cases, $add_to_node is the \<record\> node created previously. When it is null, the newly created header node is attatched to $this->verbNode.
* Otherwise it will be attatched to the desired node defined in $add_to_node.
*/
public function create_header($identifier, $timestamp, $ands_class, $add_to_node = null) {
public function create_header($identifier, $timestamp, $ands_class, $add_to_node = null, $is_deleted = false) {
if (is_null($add_to_node)) {
$header_node = $this->add2_verbNode("header");
} else {
$header_node = $this->addChild($add_to_node, "header");
}
if( $is_deleted ){
$header_node->setAttribute('status', "deleted");
}
$this->addChild($header_node, "identifier", $identifier);
$this->addChild($header_node, "datestamp", $timestamp);
if (is_array($ands_class)) {