diff --git a/ands_tpa.php b/ands_tpa.php
deleted file mode 100644
index 16a4dff..0000000
--- a/ands_tpa.php
+++ /dev/null
@@ -1,348 +0,0 @@
-create_metadata($cur_record);
- * $obj_node = new ANDS_TPA($outputObj, $metadata_node, $db);
- * try {
- * $obj_node->create_obj_node($record[$SQL['set']], $identifier);
- * } catch (Exception $e) {
- * echo 'Caught exception: ', $e->getMessage(), " when adding $identifier\n";
- * }
- * \endcode
- * \see Code in action can be seen in record_rif.php
- */
-
-class ANDS_TPA extends ANDS_RIFCS {
- //! Type: PDO. The database connection of the data source.
- //! \see __construct.
- private $db;
-
- /**
- * Constructor
- * The first two parameters are used by its parent class ANDS_RIFCS. The third is its own private property.
- *
- * \param $ands_response_doc ANDS_Response_XML. A XML Doc acts as the parent node.
- * \param $metadata_node DOMElement. The meta node which all subsequent nodes will be added to.
- * \param $db Type: PDO. The database connection of the data source.
- */
- function __construct($ands_response_doc, $metadata_node, $db) {
- parent::__construct($ands_response_doc, $metadata_node);
- $this->db = $db;
- }
-
-
- /**
- * This is the general entrence of creating actual content. It calls different functions for different type of RIF-CS model.
- * When anything goes wrong, e.g. found no record, or $set_name is not recognised, an exception will be thrown.
- * And for this implementation, data are stored in a database therefore a PDO is needed. But the source can be any.
- *
- * \param $set_name Type: string. The name of set is going to be created. Can be one of activity, collection or party.
- * \param $key Type: string. The main identifier used in ANDS system. There can be other identifier.
- *
- * \see create_activity, create_collection, create_party
- */
- function create_obj_node($set_name, $key) {
- $db = $this->db;
- $set_name = strtolower($set_name);
- if (in_array($set_name,prepare_set_names())) {
- try {
- // Get ori_id and which the original table is:
- $query = "select ori_table_name, ori_id from oai_headers where oai_identifier = '".$key."'";
- $res = exec_pdo_query($db, $query);
- $record = $res->fetch(PDO::FETCH_ASSOC);
- } catch (PDOException $e) {
- echo "$key returned no record.\n";
- echo $e->getMessage();
- }
-
- $processor = 'create_'.substr($set_name,6);
- $this->create_regObject(REG_OBJ_GROUP, $key, MY_URI);
- $this->$processor($record['ori_table_name'],$record['ori_id']);
- $this->create_identifier_node($key);
- $this->create_identifier_node('table='.$record['ori_table_name'].'+id='.$record['ori_id']);
- } else {
- throw new Exception('Wrong set name was used: '.$set_name);
- }
- }
-
- /** The processor for creating metadata node of Activity. Called from create_obj_node.
- * \param $table_name Type: string. The table name will be used to retrieve data from.
- * \param $id_project Type: integer. Internal project id associated to this activity-project.
- * \see Function create_obj_node.
- */
- private function create_activity($table_name, $id_project) {
- $db = $this->db;
-# // Get ori_id and which the original table is:
-# $query = "select ori_table_name, ori_id from oai_headers where oai_identifier = '".$key."'";
-# $res = exec_pdo_query($db, $query);
-# $record = $res->fetch(PDO::FETCH_ASSOC);
-# // $id_project will e used later, so save it:
-# $id_project = $record['ori_id'];
- // Get the content using the previously obtained infor:
- $query = sprintf("select inter_no,start_date, end_date,pub_descrip from %s where id_project = %s",$table_name,$id_project);
-
- try {
- $res = exec_pdo_query($db,$query);
- $record = $res->fetch(PDO::FETCH_ASSOC);
- } catch (Exception $e) {
- echo $e->getMessage();
- }
-
- $this->create_rifcs_node('activity','project');
- $c = $this->create_name_node();
- $this->create_namePart($c,'The Plant Accelerator Project '.$record['inter_no']);
- // Test codes for rich format.
-# // \n works
-# $this->create_description_node(sprintf("Line one:%s,\nLine two:%s.\nThird",'a','b'));
- $this->create_description_node(str_replace("\r\n","\n",$record['pub_descrip']));
-
- $this->create_description_node('The experiment was carried out between '.$record['start_date'].' and '.$record['end_date'],'note');
- $query = sprintf("select idr,stype from list_prj_ids_v2 where stype in ('dataset','person')",$id_project);
- // echo $query;
- try {
- $res = $db->query($query,PDO::FETCH_ASSOC);
- if ($res==false) {
- throw new Exception($query."\nIt found nothing.\n");
- }
- foreach ($res as $record) {
- switch ($record['stype']) {
- case 'dataset':
- $this->create_relatedObject($record['idr'],'hasOutput');
- break;
- case 'person':
- $this->create_relatedObject($record['idr'],'isManagedBy');
- break;
- }
- }
- // The Plant Accelerator always participates in Activity
- $this->create_relatedObject('0874ad60-ab4d-11df-aebd-0002a5d5c51b','hasParticipant');
- } catch (PDOException $e) {
- process_pdo_error($query, $e);
- }// end of try-catch block
- } // end of function create_activity($key, $id_project)
-
- /** The processor for creating metadata node of Collection. Called from create_obj_node.
- * \param $table_name Type: string. The table name will be used to retrieve data from.
- * \param $id_collect Type: integer. Internal collection id associated to this collection-dataset.
- * \see Function create_obj_node.
- */
- private function create_collection($table_name, $id_collect) {
- $db = $this->db;
- try {
- $query = sprintf("select plant,variety,start_date,end_date,img_freq,anzsrc from %s where id_collect = %s",$table_name,$id_collect);
- $res = exec_pdo_query($db, $query);
- $dataset = $res->fetch(PDO::FETCH_ASSOC);
-
- $res = exec_pdo_query($db, $query);
- $record = $res->fetch(PDO::FETCH_ASSOC);
-
- $query = 'select id_rep, inter_no, id_project from tpa_project_ids where id_collect = '.$id_collect;
- $res = exec_pdo_query($db, $query);
- $prj_info = $res->fetch(PDO::FETCH_ASSOC);
-
- $query = 'select email from tpa_person where id_rep = '.$prj_info['id_rep'];
- $res = exec_pdo_query($db, $query);
- $email = $res->fetch(PDO::FETCH_ASSOC);
- } catch (PDOException $e) {
- echo $query.' was failed\n';
- echo $e->getMessage();
- }
-
- $this->create_rifcs_node('collection','dataset');
- // Get the project inter_no as the name of this dataset
- $c = $this->create_name_node();
- $this->create_namePart($c,'Data set of Plant Accelerator Project '.$prj_info['inter_no']);
-
- // locatin node: contact person
- $l_node = $this->create_location_node();
- $a_node = $this->create_address_node($l_node);
- $this->create_e_node($a_node, $email['email']);
- // location node: TPA's physical address
- $l_node = $this->create_location_node();
- $a_node = $this->create_address_node($l_node);
- $this->create_physcial_addr_txt($a_node, 'The Plant Accelerator, Hartley Grove, Urrbrae, SA 5064') ;
- // Temporal coverage of colletion
- $dates = array(array('date'=>$dataset['start_date'],'type'=>'dateFrom'),array('date'=>$dataset['end_date'],'type'=>'dateTo'));
- $this->create_coverage_tempo($dates);
- // subject
- $this->create_subject_node($dataset['aznsrc']);
- // relatedOjbects
- $query = sprintf("select idr,stype from list_prj_ids_v2(%d) where stype in ('project','person')",$prj_info['id_project']);
- try {
- $res = $db->query($query,PDO::FETCH_ASSOC);
- if ($res==false) {
- throw new Exception($query."\nIt found nothing.\n");
- }
- foreach ($res as $record) {
- switch ($record['stype']) {
- case 'project':
- $this->create_relatedObject($record['idr'],'isOutputOf');
- break;
- case 'person':
- $this->create_relatedObject($record['idr'],'isOwnedBy');
- break;
- }
- }
- } catch (PDOException $e) {
- process_pdo_error($query, $e);
- }// end of try-catch block
-
- // right of accessing
- $this->create_description_node('For information on rights and access to this dataset, please contact the owner.','accessRights');
-
- // image data:
- $imgs = ''; $ex_conf = '';
- $dic = array('im_type_rgb'=>'RGB','im_type_nir'=>'NIR','im_type_fir'=>'FIR','im_type_nir_roots'=>'NIR Roots','im_type_fluo'=>'Fluorescence');
- $query = 'select im_type_rgb,im_type_nir,im_type_fir,im_type_nir_roots,im_type_fluo, lines, treatments, replicates, total from ands_collection where id_collect = '. $id_collect;
- $res = $db->query($query,PDO::FETCH_ASSOC);
- if ($res==false) {
- throw new Exception($query."\nIt found nothing.\n");
- }
- $info = $res->fetch();
- foreach ($info as $item => $v) {
- switch ($item) {
- case 'im_type_rgb':
- case 'im_type_nir':
- case 'im_type_fir':
- case 'im_type_nir_roots':
- case 'im_type_fluo':
- if (!empty($v)) { $imgs .= $dic[$item].', '; }
- break;
- default:
- if (!empty($v)) { $ex_conf .= ' '.$item.' = '.$v.', '; }
- break;
- }
- }
- if (empty($imgs)) $imgs = "Images data of RGB, FIR, NIR, NIR Roots and Fluorescence cameras., ";
- $imgs = substr($imgs,0,-2);
- if (!empty($ex_conf)) $imgs = $imgs."\n".substr($ex_conf,0,-2);
- $this->create_description_node($imgs);
- // imaging frequency
- $this->create_description_node('Imaging frequency: '.$dataset['img_freq'],'note');
- } // end of function create_collection($key,$id_collect)
-
- /** The processor for creating metadata node of Party. Called from create_obj_node. As party-person is different to party-group, there are two sub-functions are called accordingly.
- * \param $table_name Type: string. The table name will be used to retrieve data from.
- * \param $id_party Type: integer. Internal party id associated to this party.
- * \see Function create_obj_node.
- */
- private function create_party($table_name, $id_party) {
- $db = $this->db;
- $query = sprintf("SELECT set_type FROM oai_headers WHERE ori_table_name = '%s' AND ori_id = %s",$table_name,$id_party);
- $res = exec_pdo_query($db, $query);
- $party_type = $res->fetch(PDO::FETCH_ASSOC);
-
- if (in_array($party_type['set_type'],array('person','group'))) {
- $this->create_rifcs_node('party',$party_type['set_type']);
-
- if ($party_type['set_type']=='person') {
- $this->create_person($table_name, $id_party);
- } elseif ($party_type['set_type']=='group') {
- $this->create_group($table_name, $id_party); }
- } else {
- throw new Exception('Unsupported set_type: '.$party_type['set_type']);
- }
- } // end of function create_part($key,$id_party)
-
- /** The processor for creating metadata node of Party. Called from create_obj_node. As party-person is different to party-group, there are two sub-functions are called accordingly.
- * \param $table_name Type: string. The table name will be used to retrieve data from.
- * \param $id_party Type: integer. Internal party id associated to this party-person.
- * \see Function create_party.
- */
- private function create_person($table_name, $id_party) {
- $db = $this->db;
- $query = sprintf("SELECT id_org, title, first_name, family_name, tel, fax, email, www, address, post_code, city,state,country,duty FROM %s WHERE id_rep = %s",$table_name, $id_party);
- $res = exec_pdo_query($db, $query);
- $info = $res->fetch(PDO::FETCH_ASSOC);
- $c = $this->create_name_node();
- if (!empty($info['title'])) $this->create_namePart($c,$info['title'],'title');
- $this->create_namePart($c,$info['family_name'],'family');
- $this->create_namePart($c,$info['first_name'],'given');
-
- // locatin node: contact person
- $l_node = $this->create_location_node();
- $a_node = $this->create_address_node($l_node);
- $this->create_e_node($a_node, $info['email']);
- if (!empty($info['www'])) $this->create_e_node($a_node, $info['www'],'url');
- $this->create_physcial_fone_fax($a_node, $info['tel'],'telephoneNumber');
- if (!empty($info['fax'])) $this->create_physcial_fone_fax($a_node, $info['fax'],'faxNumber');
- $add_txt = trim($info['address']).', '.$info['city'].' '.$info['state'].' '.$info['post_code'].', '.$info['country'];
- // the strlength of ', , ' is 6
- if (strlen($add_txt)>6) $this->create_physcial_addr_txt($a_node,$add_txt);
-
- // related objects:
- // their group: id_customer is a foreign key of tpa_organisation
- $query = sprintf("SELECT get_identifier('tpa_organisation',%s)",$info['id_org']);
- $res = exec_pdo_query($db, $query);
- $info = $res->fetch(PDO::FETCH_NUM);
- $this->create_relatedObject($info[0],'isMemberOf');
-
- // their activities
- $query = "SELECT list_persons_objs($id_party,'project')";
- $res = exec_pdo_query($db, $query);
- $info = $res->fetch(PDO::FETCH_NUM);
- foreach ($info as $item) {
- $this->create_relatedObject($item,'isManagerOf');
- }
- // their collections
- $query = "SELECT list_persons_objs($id_party,'dataset')";
- $res = exec_pdo_query($db, $query);
- $info = $res->fetch(PDO::FETCH_NUM);
- foreach ($info as $item) {
- $this->create_relatedObject($item,'isOwnerOf');
- }
- }
-
- /** The processor for creating metadata node of Party. Called from create_obj_node. As party-person is different to party-group, there are two sub-functions are called accordingly.
- * \param $table_name Type: string. The table name will be used to retrieve data from.
- * \param $id_party Type: integer. Internal party id associated to this party-group.
- * \see Function create_party.
- */
- private function create_group($table_name, $id_party) {
- $db = $this->db;
- // echo 'table: ',$table_name,' party: ',$id_party,"\n";
- $query = sprintf("SELECT customer_name, abn, post_code, address, city, state, country, tel, fax, email, www, description FROM %s WHERE id_org = %s",$table_name, $id_party);
- //echo $query;
- $res = exec_pdo_query($db, $query);
- $info = $res->fetch(PDO::FETCH_ASSOC);
- $c = $this->create_name_node();
- $this->create_namePart($c,$info['customer_name']);
- if (!empty($info['abn'])) $this->create_identifier_node($info['abn'],'abn');
-
- if (!empty($info['description'])) $this->create_description_node($info['description']);
-
- $l_node = $this->create_location_node();
- $a_node = $this->create_address_node($l_node);
- $this->create_physcial_fone_fax($a_node, $info['tel'],'telephoneNumber');
- $this->create_physcial_fone_fax($a_node, $info['fax'],'faxNumber');
- $add_txt = trim($info['address']).', '.$info['city'].' '.$info['state'].' '.$info['post_code'].', '.$info['country'];
- $this->create_physcial_addr_txt($a_node,$add_txt);
-
- // related objects:
- // their members:
- $query = "SELECT list_pub_members($id_party)";
- $res = exec_pdo_query($db, $query);
- $info = $res->fetch(PDO::FETCH_NUM);
- foreach ($info as $item) {
- $this->create_relatedObject($item,'hasMember');
- }
- }
-} // end of class ANDS_TPA
diff --git a/config/database.php b/config/database.php
deleted file mode 100644
index fbf170b..0000000
--- a/config/database.php
+++ /dev/null
@@ -1,76 +0,0 @@
-$SQL: Settings for database and queries from database
- *
- * - $DSN: DSN for connecting your database. Reference PDO for details.
- *
- */
-
-// Data Source Name: This is the universal connection string
-// if you use something other than mysql edit accordingly.
-// Example for MySQL
-// $DSN = "mysql://$DB_USER:$DB_PASSWD@$DB_HOST/$DB_NAME";
-// Example for Oracle
-// $DSN = "oci8://$DB_USER:$DB_PASSWD@$DB_NAME";
-
-$DSN = "mysql:host={$DB_HOST};dbname={$DB_NAME};port=3306;";
-
-// the charset you store your metadata in your database
-// currently only utf-8 and iso8859-1 are supported
-$charset = "utf8";
-
-// if entities such as < > ' " in your metadata has already been escaped
-// then set this to true (e.g. you store < as < in your DB)
-$xmlescaped = false;
-
-// We store multiple entries for one element in a single row
-// in the database. SQL['split'] lists the delimiter for these entries.
-// If you do not do this, do not define $SQL['split']
-// $SQL['split'] = ';';
-
-// the name of the table where your store your metadata's header
-$SQL['table'] = 'oai_headers';
-
-// the name of the column where you store the unique identifiers
-// pointing to your item.
-// this is your internal identifier for the item
-$SQL['identifier'] = 'oai_identifier';
-
-$SQL['metadataPrefix'] = 'oai_metadataprefix';
-
-// If you want to expand the internal identifier in some way
-// use this (but not for OAI stuff, see next line)
-$idPrefix = '';
-
-// this is your external (OAI) identifier for the item
-// this will be expanded to
-// oai:$repositoryIdentifier:$idPrefix$SQL['identifier']
-// should not be changed
-//
-// Commented out 24/11/10 14:19:09
-// $oaiprefix = "oai".$delimiter.$repositoryIdentifier.$delimiter.$idPrefix;
-$oaiprefix = "";
-
-// adjust anIdentifier with sample contents an identifier
-// $sampleIdentifier = $oaiprefix.'anIdentifier';
-
-// the name of the column where you store your datestamps
-$SQL['datestamp'] = 'datestamp';
-
-// the name of the column where you store information whether
-// a record has been deleted. Leave it as it is if you do not use
-// this feature.
-$SQL['deleted'] = 'deleted';
-
-// to be able to quickly retrieve the sets to which one item belongs,
-// the setnames are stored for each item
-// the name of the column where you store sets
-$SQL['set'] = 'oai_set';
diff --git a/config/metadataformats.php b/config/metadataformats.php
deleted file mode 100644
index 58e8b40..0000000
--- a/config/metadataformats.php
+++ /dev/null
@@ -1,35 +0,0 @@
-$METADATAFORMATS: List of supported metadata formats. It is a two-dimensional array with keys.
- * Each supported format is one element of this array at the first dimension.
- * The key is the name of a metadata format.
- * The exact number of items within each format associated array depends on the nature of a metadata format.
- * Most definitions are done here but handlers themselves are defined in separated files because only the names of PHP script are listed here.
- * - metadataPrefix
- * - schema
- * - metadataNamespace
- * - myhandler
- * - other optional items: record_prefix, record_namespace and etc.
- */
-// define all supported metadata formats, has to be an array
-//
-// myhandler is the name of the file that handles the request for the
-// specific metadata format.
-// [record_prefix] describes an optional prefix for the metadata
-// [record_namespace] describe the namespace for this prefix
-
-
-$METADATAFORMATS = array (
- 'rif' => array('metadataPrefix'=>'rif',
- 'schema'=>'http://services.ands.org.au/sandbox/orca/schemata/registryObjects.xsd',
- 'metadataNamespace'=>'http://ands.org.au/standards/rif-cs/registryObjects/',
- ),
- 'oai_dc' => array('metadataPrefix'=>'oai_dc',
- 'schema'=>'http://www.openarchives.org/OAI/2.0/oai_dc.xsd',
- 'metadataNamespace'=>'http://www.openarchives.org/OAI/2.0/oai_dc/',
- 'record_prefix'=>'dc',
- 'record_namespace' => 'http://purl.org/dc/elements/1.1/'
- )
-);
-
-if (!is_array($METADATAFORMATS)) { exit("Configuration of METADATAFORMAT has been wrongly set. Correct your ".__FILE__);}
diff --git a/config/sets.php b/config/sets.php
deleted file mode 100644
index 7ae85a7..0000000
--- a/config/sets.php
+++ /dev/null
@@ -1,28 +0,0 @@
-$SETS: An array with key words . List of supported SETs.
- *
- */
-
-// define all supported sets in your repository
-$SETS = array (
- array('setSpec'=>'class:activity', 'setName'=>'Activities'),
- array('setSpec'=>'class:collection', 'setName'=>'Collections'),
- array('setSpec'=>'class:party', 'setName'=>'Parties'),
- /*
- array('setSpec'=>'math', 'setName'=>'Mathematics') ,
- array('setSpec'=>'phys', 'setName'=>'Physics'),
-
- array('setSpec'=>'phdthesis',
- 'setName'=>'PHD Thesis',
- 'setDescription'=>'
- This set contains metadata describing
- electronic music recordings made during the 1950ies
- ')
- */
-);
diff --git a/oai2.php b/oai2.php
index c1ab64f..1d1e6a1 100644
--- a/oai2.php
+++ b/oai2.php
@@ -8,62 +8,15 @@
* @see http://www.openarchives.org/OAI/2.0/openarchivesprotocol.htm
*
* It needs other files:
- * - oaidp-config.php : Configuration of provider
* - oaidp-util.php : Utility functions
* - xml_creater.php : XML generating functions
*
- * \todo Remember: to define your own classess for generating metadata records.
- * In common cases, you have to implement your own code to act fully and correctly.
- * For generic usage, you can try the ANDS_Response_XML defined in xml_creater.php.
*/
-/**
- * Supported attributes associate to verbs.
- */
-
-if (in_array($_SERVER['REQUEST_METHOD'],array('GET','POST'))) {
- $args = $_REQUEST;
-} else {
- $errors[] = oai_error('badRequestMethod', $_SERVER['REQUEST_METHOD']);
-}
+define('MY_URI', 'dev2.moodle.ufsc.br');
require_once('oaidp-util.php');
-
-// Always using htmlentities() function to encodes the HTML entities submitted by others.
-// No one can be trusted.
-foreach ($args as $key => $val) {
- $checking = htmlspecialchars(stripslashes($val));
- if (!is_valid_attrb($checking)) {
- $errors[] = oai_error('badArgument', $checking);
- } else {$args[$key] = $checking; }
-}
-if (!empty($errors)) {
- oai_exit();
-}
-
-$attribs = array ('from', 'identifier', 'metadataPrefix', 'set', 'resumptionToken', 'until');
-foreach($attribs as $val) {
- unset($$val);
-}
-
-require_once('oaidp-config.php');
-require_once('config/metadataformats.php');
-require_once('config/sets.php');
-require_once('config/database.php');
-
-// For generic usage or just trying:
-// require_once('xml_creater.php');
-// In common cases, you have to implement your own code to act fully and correctly.
-require_once('ands_tpa.php');
-
-// Default, there is no compression supported
-$compress = FALSE;
-if (isset($compression) && is_array($compression)) {
- if (in_array('gzip', $compression) && ini_get('output_buffering')) {
- $compress = TRUE;
- }
-}
-
+require_once('xml_creater.php');
require_once('oai2server.php');
/**
@@ -94,6 +47,73 @@ $identifyResponse["deletedRecord"] = 'no'; // How your repository handles deleti
// maintained. It MAY reveal a deleted status for records.
$identifyResponse["granularity"] = 'YYYY-MM-DDThh:mm:ssZ';
-$repositoryIdentifier = 'dev2.moodle.ufsc.br.';
+$oai2 = new OAI2Server($_REQUEST, $identifyResponse,
+ array(
+ 'ListMetadataFormats' =>
+ function($identifier = '') {
+ // throws new OAI2Exception('idDoesNotExist', '', $identifier)
+ return
+ array('rif' => array('metadataPrefix'=>'rif',
+ 'schema'=>'http://services.ands.org.au/sandbox/orca/schemata/registryObjects.xsd',
+ 'metadataNamespace'=>'http://ands.org.au/standards/rif-cs/registryObjects/',
+ ),
+ 'oai_dc' => array('metadataPrefix'=>'oai_dc',
+ 'schema'=>'http://www.openarchives.org/OAI/2.0/oai_dc.xsd',
+ 'metadataNamespace'=>'http://www.openarchives.org/OAI/2.0/oai_dc/',
+ 'record_prefix'=>'dc',
+ 'record_namespace' => 'http://purl.org/dc/elements/1.1/'));
+ },
-$oai2 = new OAI2Server($args, $repositoryIdentifier, $identifyResponse);
+ 'ListSets' =>
+ function($resumptionToken = '') {
+ return
+ array (
+ array('setSpec'=>'class:collection', 'setName'=>'Collections'),
+ array('setSpec'=>'math', 'setName'=>'Mathematics') ,
+ array('setSpec'=>'phys', 'setName'=>'Physics'),
+ array('setSpec'=>'phdthesis', 'setName'=>'PHD Thesis',
+ 'setDescription'=>
+ ' '.
+ ' This set contains metadata describing '.
+ ' electronic music recordings made during the 1950ies '.
+ ' '));
+ },
+
+ 'ListRecords' =>
+ function($metadataPrefix, $from = '', $until = '', $set = '', $count = false, $deliveredRecords = 0, $maxItems = 0) {
+ // throws new OAI2Exception('noRecordsMatch')
+ // throws new OAI2Exception('noSetHierarchy')
+ if ($count) {
+ return 10;
+ }
+ return array();
+ },
+
+ 'GetRecord' =>
+ function($identifier, $metadataPrefix) {
+ // throws new OAI2Exception('idDoesNotExist', '', $identifier) if record not found
+
+ return array('identifier' => 'dev.testing.pmh',
+ 'datestamp' => date('Y-m-d-H:s'),
+ 'set' => 'class:activity',
+ 'metadata' => array(
+ 'container_name' => 'oai_dc:dc',
+ 'container_attributes' => array(
+ 'xmlns:oai_dc' => "http://www.openarchives.org/OAI/2.0/oai_dc/",
+ 'xmlns:dc' => "http://purl.org/dc/elements/1.1/",
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
+ 'xsi:schemaLocation' =>
+ 'http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd'
+ ),
+ 'fields' => array(
+ 'dc:title' => 'Testing records',
+ 'dc:author' => 'Neis'
+ )
+ ));
+ },
+ )
+);
diff --git a/oai2exception.php b/oai2exception.php
new file mode 100644
index 0000000..600fc3e
--- /dev/null
+++ b/oai2exception.php
@@ -0,0 +1,78 @@
+errorTable = array(
+ 'badArgument' => array(
+ 'text' => "Attribute '{$argument}' is not allowed to appear in element 'request'.",
+ ),
+ 'badGranularity' => array(
+ 'text' => "The value '{$value}' of attribute '{$argument}' on element 'request' is not valid with respect to its type, 'UTCdatetimeType'.",
+ 'code' => 'badArgument',
+ ),
+
+ 'badResumptionToken' => array(
+ 'text' => "The resumptionToken '{$value}' does not exist or has already expired.",
+ ),
+ 'badRequestMethod' => array(
+ 'text' => "The request method '{$argument}' is unknown.",
+ 'code' => 'badVerb',
+ ),
+ 'badVerb' => array(
+ 'text' => "The value '{$argument}' of attribute 'verb' on element 'request' is not valid with respect to its type, 'verbType'",
+ ),
+ 'cannotDisseminateFormat' => array(
+ 'text' => "The metadata format '{$value}' given by {$argument} is not supported by this repository.",
+ ),
+ 'exclusiveArgument' => array(
+ 'text' => 'The usage of resumptionToken as an argument allows no other arguments.',
+ 'code' => 'badArgument',
+ ),
+ 'idDoesNotExist' => array(
+ 'text' => "The value '{$value}' of the identifier does not exist in this repository.",
+ /*
+ if (!is_valid_uri($value)) {
+ 'code' = 'badArgument',
+ 'text' .= ' Invalidated URI has been detected.',
+ }
+ */
+ ),
+ 'missingArgument' => array(
+ 'text' => "The required argument '{$argument}' is missing in the request.",
+ 'code' => 'badArgument',
+ ),
+ 'noRecordsMatch' => array(
+ 'text' => 'The combination of the given values results in an empty list.',
+ ),
+ 'noMetadataFormats' => array(
+ 'text' => 'There are no metadata formats available for the specified item.',
+ ),
+ 'noVerb' => array(
+ 'text' => 'The request does not provide any verb.',
+ 'code' => 'badVerb',
+ ),
+ 'noSetHierarchy' => array(
+ 'text' => 'This repository does not support sets.',
+ ),
+ 'sameArgument' => array(
+ 'text' => 'Do not use the same argument more than once.',
+ 'code' => 'badArgument',
+ ),
+ 'sameVerb' => array(
+ 'text' => 'Do not use verb more than once.',
+ 'code' => 'badVerb',
+ ),
+ 'notImp' => array(
+ 'text' => 'Not yet implemented.',
+ 'code' => 'debug',
+ ),
+ ''=> array(
+ 'text' => "Unknown error: code: '{'code'}', argument: '{$argument}', value: '{$value}'",
+ 'code' => 'badArgument',
+ )
+ );
+ parent::__construct($this->errorTable[$code]['text'], $code);
+ }
+}
diff --git a/oai2server.php b/oai2server.php
index d9f52e0..7875c50 100644
--- a/oai2server.php
+++ b/oai2server.php
@@ -1,95 +1,75 @@
args = $args;
- $this->repositoryIdentier = $repositoryIdentifier;
$this->identifyResponse = $identifyResponse;
+ $this->listMetadataFormatsCallback = $callbacks['ListMetadataFormats'];
+ $this->listSetsCallback = $callbacks['ListSets'];
+ $this->listRecordsCallback = $callbacks['ListRecords'];
+ $this->getRecordCallback = $callbacks['GetRecord'];
$this->respond();
}
private function respond() {
if (!isset($this->args['verb']) || empty($this->args['verb'])) {
- $this->errors[] = oai_error('noVerb');
+ $this->errors[] = new OAI2Exception('noVerb');
} else {
switch ($this->args['verb']) {
- case 'Identify':
- // we never use compression in Identify
- $compress = FALSE;
- $this->outputObj = $this->identify();
- break;
+ case 'Identify': $this->identify(); break;
- case 'ListMetadataFormats':
- $this->outputObj = $this->listMetadataFormats();
- break;
+ case 'ListMetadataFormats': $this->listMetadataFormats(); break;
- case 'ListSets':
- $this->outputObj = $this->listSets();
- break;
+ case 'ListSets': $this->listSets(); break;
case 'ListIdentifiers':
- case 'ListRecords':
- $this->outputObj = $this->listRecords();
- break;
+ case 'ListRecords': $this->listRecords(); break;
- case 'GetRecord':
- $this->outputObj = $this->getRecord();
- break;
+ case 'GetRecord': $this->getRecord(); break;
- default:
- // we never use compression with errors
- $compress = FALSE;
- $this->errors[] = oai_error('badVerb', $this->args['verb']);
+ default: $this->errors[] = new OAI2Exception('badVerb', $this->args['verb']);
}
}
if (empty($this->errors)) {
- $this->display();
+
+ if (isset($this->outputObj)) {
+ header(CONTENT_TYPE);
+ $this->outputObj->display();
+ } else {
+ exit("Nothing to output. May be a bug.");
+ }
} else {
$this->errorResponse();
}
}
- function errorResponse() {
- $e = new ANDS_Error_XML($this->args,$this->errors);
+ private function errorResponse() {
+ $e = new OAI2XMLError($this->args,$this->errors);
header(CONTENT_TYPE);
$e->display();
exit();
}
- function display() {
- if (isset($this->outputObj)) {
-
- if ($compress) {
- ob_start('ob_gzhandler');
- }
-
- header(CONTENT_TYPE);
- $this->outputObj->display();
-
- if ($compress) {
- ob_end_flush();
- }
-
- } else {
- exit("Nothing to output. May be a bug.");
- }
- }
-
/**
* Response to Verb Identify
*
@@ -97,193 +77,47 @@ class OAI2Server {
*
* http://www.openarchives.org/OAI/2.0/guidelines-oai-identifier.htm for details
*/
- public function identify($show_identifier, $repositoryIdentifier, $delimiter, $sampleIdentifier) {
+ public function identify() {
if (count($this->args) > 1) {
foreach($args as $key => $val) {
if(strcmp($key,"verb")!=0) {
- $this->errors[] = oai_error('badArgument', $key, $val);
+ $this->errors[] = new OAI2Exception('badArgument', $key, $val);
}
}
}
- $outputObj = new ANDS_Response_XML($this->args);
+ $this->outputObj = new ANDS_Response_XML($this->args);
foreach($this->identifyResponse as $key => $val) {
- $outputObj->add2_verbNode($key, $val);
+ $this->outputObj->add2_verbNode($key, $val);
}
-
- // A description MAY be included.
- // Use this if you choose to comply with a specific format of unique identifiers
- // for items.
- // See http://www.openarchives.org/OAI/2.0/guidelines-oai-identifier.htm
- // for details
-
- // As they will not be changed, using string for simplicity.
- $output = '';
- if ($this->show_identifier && $this->repositoryIdentifier && $this->delimiter && $this->sampleIdentifier) {
- $output .=
- '
-
- oai
- '.$repositoryIdentifier.'
- '.$delimiter.'
- '.$sampleIdentifier.'
-
- '."\n";
- }
-
- // A description MAY be included.
- // This example from arXiv.org is used by the e-prints community, please adjust
- // see http://www.openarchives.org/OAI/2.0/guidelines-eprints.htm for details
-
- // To include, change 'false' to 'true'.
- if (false) {
- $output .=
- '
-
-
- Author self-archived e-prints
-
-
-
-
-
- '."\n";
- }
-
- // If you want to point harvesters to other repositories, you can list their
- // base URLs. Usage of friends container is RECOMMENDED.
- // see http://www.openarchives.org/OAI/2.0/guidelines-friends.htm
- // for details
-
- // To include, change 'false' to 'true'.
- if (false) {
- $output .=
- '
-
- http://naca.larc.nasa.gov/oai2.0/
- http://techreports.larc.nasa.gov/ltrs/oai2.0/
- http://physnet.uni-oldenburg.de/oai/oai2.php
- http://cogprints.soton.ac.uk/perl/oai
- http://ub.uni-duisburg.de:8080/cgi-oai/oai.pl
- http://rocky.dlib.vt.edu/~jcdlpix/cgi-bin/OAI1.1/jcdlpix.pl
-
- '."\n";
- }
-
- // If you want to provide branding information, adjust accordingly.
- // Usage of friends container is OPTIONAL.
- // see http://www.openarchives.org/OAI/2.0/guidelines-branding.htm
- // for details
-
- // To include, change 'false' to 'true'.
- if (false) {
- $output .=
- '
-
-
- http://my.site/icon.png
- http://my.site/homepage.html
- MySite(tm)
- 88
- 31
-
- http://some.where/DCrender.xsl
- http://another.place/MARCrender.css
-
- '."\n";
- }
-
- if(strlen($output)>10) {
- $des = $outputObj->doc->createDocumentFragment();
- $des->appendXML($output);
- $outputObj->verbNode->appendChild($des);
- }
-
- return $outputObj;
}
/**
* Response to Verb ListMetadataFormats
*
- * The information of supported metadata formats :
- * try database table $SQL['table']
- * else try $METADATAFORMATS array from config-metadataformats.php
+ * The information of supported metadata formats
*/
public function listMetadataFormats() {
- global $DSN, $DB_USER, $DB_PASSWD, $METADATAFORMATS, $SQL;
$checkList = array("ops"=>array("identifier"));
$this->checkArgs($checkList);
- // Create a PDO object
try {
- $db = new PDO($DSN, $DB_USER, $DB_PASSWD);
- } catch (PDOException $e) {
- exit('Connection failed: ' . $e->getMessage());
- }
-
- if (isset($this->args['identifier'])) {
-
- $identifier = $this->args['identifier'];
- $query = 'select '.$SQL['metadataPrefix'].' FROM '.$SQL['table']. " WHERE ".$SQL['identifier']." = '".$id."'";
- $res = $db->query($query);
-
- if ($res==false) {
- if (SHOW_QUERY_ERROR) {
- echo __FILE__.','.__LINE__."
";
- echo "Query: $query
\n";
- die($db->errorInfo());
- } else {
- $this->errors[] = oai_error('idDoesNotExist','', $identifier);
- }
- } else {
- $record = $res->fetch();
- if($record===false) {
- $this->errors[] = oai_error('idDoesNotExist', '', $identifier);
- } else {
- $mf = explode(",",$record[$SQL['metadataPrefix']]);
+ if ($formats = call_user_func($this->listMetadataFormatsCallback, $this->args['identifier'])) {
+ $this->outputObj = new ANDS_Response_XML($this->args);
+ foreach($formats as $key => $val) {
+ $cmf = $this->outputObj->add2_verbNode("metadataFormat");
+ $this->outputObj->addChild($cmf,'metadataPrefix',$key);
+ $this->outputObj->addChild($cmf,'schema',$val['schema']);
+ $this->outputObj->addChild($cmf,'metadataNamespace',$val['metadataNamespace']);
}
+ return $outputObj;
}
+ $this->errors[] = new OAI2Exception('noMetadataFormats');
+ } catch (OAI2Exception $e) {
+ $this->errors[] = $e;
}
-
- //break and clean up on error
- if (!empty($this->errors)) {
- $this->errorResponse();
- }
-
- $outputObj = new ANDS_Response_XML($this->args);
- if (isset($mf)) {
- foreach($mf as $key) {
- $val = $METADATAFORMATS[$key];
- $this->addMetedataFormat($outputObj,$key, $val);
- }
- } elseif (is_array($METADATAFORMATS)) {
- foreach($METADATAFORMATS as $key=>$val) {
- $this->addMetedataFormat($outputObj,$key, $val);
- }
- } else { // a very unlikely event
- $this->errors[] = oai_error('noMetadataFormats');
- $this->errorResponse();
- }
-
- return $outputObj;
}
/**
@@ -293,36 +127,34 @@ class OAI2Server {
* This variable is filled in config-sets.php
*/
public function listSets() {
- global $SETS;
-
- $sets = $SETS;
if (isset($this->args['resumptionToken']) && count($this->args) > 2) {
- $this->errors[] = oai_error('exclusiveArgument');
+ $this->errors[] = new OAI2Exception('exclusiveArgument');
}
$checkList = array("ops"=>array("resumptionToken"));
$this->checkArgs($checkList);
- if (is_array($sets)) {
- $outputObj = new ANDS_Response_XML($this->args);
+ if ($sets = call_user_func($this->listSetsCallback)) {
+
+ $this->outputObj = new ANDS_Response_XML($this->args);
foreach($sets as $set) {
- $setNode = $outputObj->add2_verbNode("set");
+
+ $setNode = $this->outputObj->add2_verbNode("set");
+
foreach($set as $key => $val) {
if($key=='setDescription') {
- $desNode = $outputObj->addChild($setNode,$key);
- $des = $outputObj->doc->createDocumentFragment();
+ $desNode = $this->outputObj->addChild($setNode,$key);
+ $des = $this->outputObj->doc->createDocumentFragment();
$des->appendXML($val);
$desNode->appendChild($des);
} else {
- $outputObj->addChild($setNode,$key,$val);
+ $this->outputObj->addChild($setNode,$key,$val);
}
}
}
} else {
- $this->errors[] = oai_error('noSetHierarchy');
- oai_exit();
+ $this->errors[] = new OAI2Exception('noSetHierarchy');
}
- return $outputObj;
}
/**
@@ -335,62 +167,44 @@ class OAI2Server {
* The reset of information will be extracted from database based those two parameters.
*/
public function getRecord() {
- global $METADATAFORMATS, $DSN, $DB_USER, $DB_PASSWD, $SQL;
$checkList = array("required"=>array("metadataPrefix","identifier"));
$this->checkArgs($checkList);
$metadataPrefix = $this->args['metadataPrefix'];
- if (!isset($METADATAFORMATS[$metadataPrefix])) {
- $this->errors[] = oai_error('cannotDisseminateFormat', 'metadataPrefix', $metadataPrefix);
+ $metadataFormats = call_user_func($this->listMetadataFormatsCallback);
+
+ if (!isset($metadataFormats[$metadataPrefix])) {
+ $this->errors[] = new OAI2Exception('cannotDisseminateFormat', 'metadataPrefix', $metadataPrefix);
}
- // Create a PDO object
try {
- $db = new PDO($DSN, $DB_USER, $DB_PASSWD);
- } catch (PDOException $e) {
- exit('Connection failed: ' . $e->getMessage());
+ if ($record = call_user_func($this->getRecordCallback, $this->args['identifier'], $metadataPrefix)) {
+
+ $identifier = $record['identifier'];
+
+ $datestamp = formatDatestamp($record['datestamp']);
+
+ $set = $record['set'];
+
+ $status_deleted = (isset($record['deleted']) && ($record['deleted'] == 'true') &&
+ (($this->identifyResponse['deletedRecord'] == 'transient') ||
+ ($this->identifyResponse['deletedRecord'] == 'persistent')));
+
+ $this->outputObj = new ANDS_Response_XML($this->args);
+ $cur_record = $this->outputObj->create_record();
+ $cur_header = $this->outputObj->create_header($identifier, $datestamp, $set, $cur_record);
+ if ($status_deleted) {
+ $cur_header->setAttribute("status","deleted");
+ } else {
+ $this->add_metadata($cur_record, $record);
+
+ }
+ }
+ } catch (OAI2Exception $e) {
+ $this->errors[] = $e;
}
-
- $identifier = $this->args['identifier'];
- $query = selectallQuery($metadataPrefix, $identifier);
-
- $res = $db->query($query);
-
- if ($res===false) {
- $this->errors[] = oai_error('idDoesNotExist', '', $identifier);
- } elseif (!$res->rowCount()) { // based on PHP manual, it might only work for some DBs
- $this->errors[] = oai_error('idDoesNotExist', '', $identifier);
- }
-
- if (!empty($this->errors)) {
- oai_exit();
- }
-
- $record = $res->fetch(PDO::FETCH_ASSOC);
- if ($record===false) {
- $this->errors[] = oai_error('idDoesNotExist', '', $identifier);
- }
-
- $identifier = $record[$SQL['identifier']];;
-
- $datestamp = formatDatestamp($record[$SQL['datestamp']]);
-
- $status_deleted = (isset($record[$SQL['deleted']]) && ($record[$SQL['deleted']] == 'true') &&
- ($this->identifyResponse['deletedRecord'] == 'transient' || $this->identifyResponse['deletedRecord'] == 'persistent'));
-
- $outputObj = new ANDS_Response_XML($this->args);
- $cur_record = $outputObj->create_record();
- $cur_header = $outputObj->create_header($identifier, $datestamp,$record[$SQL['set']],$cur_record);
- // return the metadata record itself
- if ($status_deleted) {
- $cur_header->setAttribute("status","deleted");
- } else {
- call_user_func(array($this, "{$metadataPrefix}_create_metadata"),
- $outputObj, $cur_record, $identifier, $record[$SQL['set']], $db);
- }
- return $outputObj;
}
/**
@@ -402,13 +216,10 @@ class OAI2Server {
* Only 'metadataPrefix' is compulsory. All conditions are accessible through global array variable $args by keywords.
*/
public function listRecords() {
- global $SQL, $METADATAFORMATS, $DSN, $DB_USER, $DB_PASSWD, $SETS;
- $sets = $SETS;
-
- if(isset($this->args['resumptionToken'])) {
+ if (isset($this->args['resumptionToken'])) {
if (count($this->args) > 2) {
- $this->errors[] = oai_error('exclusiveArgument');
+ $this->errors[] = new OAI2Exception('exclusiveArgument');
}
$checkList = array("ops"=>array("resumptionToken"));
} else {
@@ -416,203 +227,103 @@ class OAI2Server {
}
$this->checkArgs($checkList);
+ $metadataFormats = call_user_func($this->listMetadataFormatsCallback, $this->args);
+ if (!isset($metadataFormats[$this->args['metadataPrefix']])) {
+ $this->errors[] = new OAI2Exception('cannotDisseminateFormat', 'metadataPrefix', $this->args['metadataPrefix']);
+ }
+
// Resume previous session?
if (isset($this->args['resumptionToken'])) {
+
if (!file_exists(TOKEN_PREFIX.$this->args['resumptionToken'])) {
- $this->errors[] = oai_error('badResumptionToken', '', $this->args['resumptionToken']);
+ $this->errors[] = new OAI2Exception('badResumptionToken', '', $this->args['resumptionToken']);
} else {
- $readings = readResumToken(TOKEN_PREFIX.$this->args['resumptionToken']);
- if ($readings == false) {
- $this->errors[] = oai_error('badResumptionToken', '', $this->args['resumptionToken']);
- } else {
- list($deliveredrecords, $extquery, $metadataPrefix) = $readings;
- }
- }
- } else { // no, we start a new session
- $deliveredrecords = 0;
- $extquery = '';
+ if ($readings = $this->readResumptionToken(TOKEN_PREFIX.$this->args['resumptionToken'])) {
+ list($deliveredRecords, $metadataPrefix, $from, $until, $set) = $readings;
+ } else {
+ $this->errors[] = new OAI2Exception('badResumptionToken', '', $this->args['resumptionToken']);
+ }
+
+ }
+
+ } else {
+ $deliveredRecords = 0;
$metadataPrefix = $this->args['metadataPrefix'];
-
- if (isset($args['from'])) {
- $from = checkDateFormat($this->args['from']);
- $extquery .= fromQuery($from);
- }
-
- if (isset($args['until'])) {
- $until = checkDateFormat($this->args['until']);
- $extquery .= untilQuery($until);
- }
-
- if (isset($args['set'])) {
- if (is_array($sets)) {
- $extquery .= setQuery($this->args['set']);
- } else {
- $this->errors[] = oai_error('noSetHierarchy');
- }
- }
- }
-
- if (!isset($METADATAFORMATS[$metadataPrefix])) {
- $this->errors[] = oai_error('cannotDisseminateFormat', 'metadataPrefix', $metadataPrefix);
+ $from = isset($this->args['from']) ? $this->args['from'] : '';
+ $until = isset($this->args['until']) ? $this->args['until'] : '';
+ $set = isset($this->args['set']) ? $this->args['set'] : '';
}
if (!empty($this->errors)) {
$this->errorResponse();
}
- // Create a PDO object
+ $maxItems = 1000;
try {
- $db = new PDO($DSN, $DB_USER, $DB_PASSWD);
- } catch (PDOException $e) {
- exit('Connection failed: ' . $e->getMessage());
- }
- $query = selectallQuery($metadataPrefix) . $extquery;
+ $records_count = call_user_func($this->listRecordsCallback, $metadataPrefix, $from, $until, $set, true);
- $res = $db->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
- $r = $res->execute();
- if ($r===false) {
- $this->errors[] = oai_error('noRecordsMatch');
- } else {
- $r = $res->setFetchMode(PDO::FETCH_ASSOC);
- if ($r===false) {
- exit("FetchMode is not supported");
- }
- $num_rows = rowCount($metadataPrefix, $extquery, $db);
- if ($num_rows==0) {
- $this->errors[] = oai_error('noRecordsMatch');
- }
- }
+ $records = call_user_func($this->listRecordsCallback, $metadataPrefix, $from, $until, $set, false, $deliveredRecords, $maxItems);
- if (!empty($this->errors)) {
- $this->errorResponse();
- }
+ $this->outputObj = new ANDS_Response_XML($this->args);
+ foreach ($records as $record) {
- // Will we need a new ResumptionToken?
- if($this->args['verb']=='ListRecords') {
- $maxItems = MAXRECORDS;
- } elseif($this->args['verb']=='ListIdentifiers') {
- $maxItems = MAXIDS;
- } else {
- exit("Check ".__FILE__." ".__LINE__.", there is something wrong.");
- }
- $maxrec = min($num_rows - $deliveredrecords, $maxItems);
+ $identifier = $record['identifier'];
+ $datestamp = formatDatestamp($record['datestamp']);
+ $setspec = $record[$SQL['set']];
- if ($num_rows - $deliveredrecords > $maxItems) {
- $cursor = (int)$deliveredrecords + $maxItems;
- $restoken = createResumToken($cursor, $extquery, $metadataPrefix);
- $expirationdatetime = gmstrftime('%Y-%m-%dT%TZ', time()+TOKEN_VALID);
- } elseif (isset($args['resumptionToken'])) {
- // Last delivery, return empty ResumptionToken
- $restoken = $args['resumptionToken']; // just used as an indicator
- unset($expirationdatetime);
- }
+ $status_deleted = (isset($record['deleted']) && ($record['deleted'] === true) &&
+ (($this->identifyResponse['deletedRecord'] == 'transient') ||
+ ($this->identifyResponse['deletedRecord'] == 'persistent')));
- if (isset($this->args['resumptionToken'])) {
- $record = $res->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_ABS, $deliveredrecords);
- }
- // Record counter
- $countrec = 0;
-
- // Publish a batch to $maxrec number of records
- $outputObj = new ANDS_Response_XML($this->args);
- while ($countrec++ < $maxrec) {
- $record = $res->fetch(PDO::FETCH_ASSOC);
- if ($record===false) {
- if (SHOW_QUERY_ERROR) {
- echo __FILE__.",". __LINE__."
";
- print_r($db->errorInfo());
- exit();
+ if($this->args['verb'] == 'ListRecords') {
+ $cur_record = $this->outputObj->create_record();
+ $cur_header = $this->outputObj->create_header($identifier, $datestamp,$setspec,$cur_record);
+ if (!$status_deleted) {
+ $this->add_metadata($cur_record, $record);
+ }
+ } else { // for ListIdentifiers, only identifiers will be returned.
+ $cur_header = $this->outputObj->create_header($identifier, $datestamp,$setspec);
+ }
+ if ($status_deleted) {
+ $cur_header->setAttribute("status","deleted");
}
}
- $identifier = $oaiprefix.$record[$SQL['identifier']];
- $datestamp = formatDatestamp($record[$SQL['datestamp']]);
- $setspec = $record[$SQL['set']];
+ // Will we need a new ResumptionToken?
+ if ($records_count - $deliveredRecords > $maxItems) {
- $status_deleted = (isset($record[$SQL['deleted']]) && ($record[$SQL['deleted']] === true) &&
- ($this->identifyResponse['deletedRecord'] == 'transient' || $this->identifyResponse['deletedRecord'] == 'persistent'));
+ $deliveredRecords += $maxItems;
+ $restoken = $this->createResumptionToken($deliveredRecords);
- if($this->args['verb']=='ListRecords') {
- $cur_record = $outputObj->create_record();
- $cur_header = $outputObj->create_header($identifier, $datestamp,$setspec,$cur_record);
- // return the metadata record itself
- if (!$status_deleted) {
- call_user_func(array($this, "{$metadataPrefix}_create_metadata"),
- $outputObj, $cur_record, $identifier, $setspec, $db);
- }
- } else { // for ListIdentifiers, only identifiers will be returned.
- $cur_header = $outputObj->create_header($identifier, $datestamp,$setspec);
+ $expirationDatetime = gmstrftime('%Y-%m-%dT%TZ', time()+TOKEN_VALID);
+
+ } elseif (isset($args['resumptionToken'])) {
+ // Last delivery, return empty ResumptionToken
+ $restoken = null;
+ $expirationDatetime = null;
}
- if ($status_deleted) {
- $cur_header->setAttribute("status","deleted");
+
+ if (isset($restoken)) {
+ $this->outputObj->create_resumpToken($restoken,$expirationDatetime,$records_count,$deliveredRecords);
}
- }
- // ResumptionToken
- if (isset($restoken)) {
- if(isset($expirationdatetime)) {
- $outputObj->create_resumpToken($restoken,$expirationdatetime,$num_rows,$cursor);
- } else {
- $outputObj->create_resumpToken('',null,$num_rows,$deliveredrecords);
- }
- }
- return $outputObj;
- }
-
- /**
- * Add a metadata format node to an ANDS_Response_XML
- * \param &$outputObj
- * type: ANDS_Response_XML. The ANDS_Response_XML object for output.
- * \param $key
- * type string. The name of new node.
- * \param $val
- * type: array. Values accessable through keywords 'schema' and 'metadataNamespace'.
- *
- */
- private function addMetedataFormat(&$outputObj,$key,$val) {
- $cmf = $outputObj->add2_verbNode("metadataFormat");
- $outputObj->addChild($cmf,'metadataPrefix',$key);
- $outputObj->addChild($cmf,'schema',$val['schema']);
- $outputObj->addChild($cmf,'metadataNamespace',$val['metadataNamespace']);
- }
-
- private function rif_create_metadata($outputObj, $cur_record, $identifier, $setspec, $db) {
-
- $metadata_node = $outputObj->create_metadata($cur_record);
- $obj_node = new ANDS_TPA($outputObj, $metadata_node, $db);
- try {
- $obj_node->create_obj_node($setspec, $identifier);
- } catch (Exception $e) {
- echo 'Caught exception: ', $e->getMessage(), " when adding $identifier\n";
+ } catch (OAI2Exception $e) {
+ $this->errors[] = $e;
}
}
- private function oai_dc_create_metadata($outputObj, $cur_record, $identifier, $setspec, $db) {
+ private function add_metadata($cur_record, $record) {
- $sql = "SELECT dc_title, dc_creator, dc_subject, dc_description, dc_contributor, dc_publisher,
- dc_date , dc_type , dc_format , dc_identifier , dc_source , dc_language,
- dc_relation , dc_coverage , dc_rights
- FROM oai_records
- WHERE oai_set = '{$setspec}'
- AND oai_identifier = '{$identifier}'";
+ $meta_node = $this->outputObj->addChild($cur_record ,"metadata");
- $res = exec_pdo_query($db,$sql);
- $record = $res->fetch(PDO::FETCH_ASSOC);
-
- $meta_node = $outputObj->addChild($cur_record ,"metadata");
-
- $schema_node = $outputObj->addChild($meta_node, 'oai_dc:dc');
- $schema_node->setAttribute('xmlns:oai_dc', "http://www.openarchives.org/OAI/2.0/oai_dc/");
- $schema_node->setAttribute('xmlns:dc',"http://purl.org/dc/elements/1.1/");
- $schema_node->setAttribute('xmlns:xsi',"http://www.w3.org/2001/XMLSchema-instance");
- $schema_node->setAttribute('xsi:schemaLocation',
- 'http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd');
- foreach ($record as $r => $v) {
- if (!empty($v)) {
- $outputObj->addChild($schema_node, str_replace('_', ':', $r), $v);
- }
+ $schema_node = $this->outputObj->addChild($meta_node, $record['metadata']['container_name']);
+ foreach ($record['metadata']['container_attributes'] as $name => $value) {
+ $schema_node->setAttribute($name, $value);
+ }
+ foreach ($record['metadata']['fields'] as $name => $value) {
+ $this->outputObj->addChild($schema_node, $name, $value);
}
}
@@ -626,7 +337,8 @@ class OAI2Server {
* is needed.
*/
private function checkArgs($checkList) {
- global $METADATAFORMATS;
+
+ $metadataFormats = call_user_func($this->listMetadataFormatsCallback);
// "verb" has been checked before, no further check is needed
$verb = $this->args["verb"];
@@ -637,17 +349,14 @@ class OAI2Server {
if(isset($checkList['required'])) {
for($i = 0; $i < count($checkList["required"]); $i++) {
- if(isset($test_args[$checkList['required'][$i]])==false) {
- $this->errors[] = oai_error('missingArgument', $checkList["required"][$i]);
+ if (isset($test_args[$checkList['required'][$i]]) == false) {
+ $this->errors[] = new OAI2Exception('missingArgument', $checkList["required"][$i]);
} else {
// if metadataPrefix is set, it is in required section
if(isset($test_args['metadataPrefix'])) {
$metadataPrefix = $test_args['metadataPrefix'];
- // Check if the format is supported, it has enough infor (an array), last if a handle has been defined.
- if (!array_key_exists($metadataPrefix, $METADATAFORMATS) ||
- !(is_array($METADATAFORMATS[$metadataPrefix]) ||
- !isset($METADATAFORMATS[$metadataPrefix]['myhandler']))) {
- $this->errors[] = oai_error('cannotDisseminateFormat', 'metadataPrefix', $metadataPrefix);
+ if (!isset($metadataFormats[$metadataPrefix])) {
+ $this->errors[] = new OAI2Exception('cannotDisseminateFormat', 'metadataPrefix', $metadataPrefix);
}
}
unset($test_args[$checkList["required"][$i]]);
@@ -655,28 +364,61 @@ class OAI2Server {
}
}
- if (!empty($this->errors)) return;
-
// check to see if there is unwanted
foreach($test_args as $key => $val) {
if(!in_array($key, $checkList["ops"])) {
- $this->errors[] = oai_error('badArgument', $key, $val);
+ $this->errors[] = new OAI2Exception('badArgument', $key, $val);
}
switch ($key) {
case 'from':
case 'until':
if(!checkDateFormat($val)) {
- $this->errors[] = oai_error('badGranularity', $key, $val);
+ $this->errors[] = new OAI2Exception('badGranularity', $key, $val);
}
break;
case 'resumptionToken':
- // only check for expairation
+ // only check for expiration
if((int)$val+TOKEN_VALID < time())
- $this->errors[] = oai_error('badResumptionToken');
+ $this->errors[] = new OAI2Exception('badResumptionToken');
break;
}
}
+
+ if (!empty($this->errors)) {
+ $this->errorResponse();
+ }
+ }
+
+ private function createResumptionToken($delivered_records) {
+
+ list($usec, $sec) = explode(" ", microtime());
+ $token = ((int)($usec*1000) + (int)($sec*1000));
+
+ $fp = fopen (TOKEN_PREFIX.$token, 'w');
+ if($fp==false) {
+ exit("Cannot write. Writer permission needs to be changed.");
+ }
+ fputs($fp, "$delivered_records#");
+ fputs($fp, "$metadataPrefix#");
+ fputs($fp, "{$this->args['from']}#");
+ fputs($fp, "{$this->args['until']}#");
+ fputs($fp, "{$this->args['set']}#");
+ fclose($fp);
+ return $token;
+ }
+
+ private function readResumptionToken($resumptionToken) {
+ $rtVal = false;
+ $fp = fopen($resumptionToken, 'r');
+ if ($fp != false) {
+ $filetext = fgets($fp, 255);
+ $textparts = explode('#', $filetext);
+ fclose($fp);
+ unlink($resumptionToken);
+ $rtVal = array_values($textparts);
+ }
+ return $rtVal;
}
}
diff --git a/oai2xml.php b/oai2xml.php
new file mode 100644
index 0000000..4fa7b1c
--- /dev/null
+++ b/oai2xml.php
@@ -0,0 +1,67 @@
+doc = new DOMDocument("1.0","UTF-8");
+ $oai_node = $this->doc->createElement("OAI-PMH");
+ $oai_node->setAttribute("xmlns","http://www.openarchives.org/OAI/2.0/");
+ $oai_node->setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
+ $oai_node->setAttribute("xsi:schemaLocation","http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd");
+ $this->addChild($oai_node,"responseDate",gmdate("Y-m-d\TH:i:s\Z"));
+ $this->doc->appendChild($oai_node);
+
+ $request = $this->addChild($this->doc->documentElement,"request",MY_URI);
+ foreach($request_args as $key => $value) {
+ $request->setAttribute($key,$value);
+ }
+ }
+
+ function display() {
+ $pr = new DOMDocument();
+ $pr->preserveWhiteSpace = false;
+ $pr->formatOutput = true;
+ $pr->loadXML($this->doc->saveXML());
+ echo $pr->saveXML();
+ }
+
+ /**
+ * Add a child node to a parent node on a XML Doc: a worker function.
+ *
+ * @param $mom_node
+ * Type: DOMNode. The target node.
+ *
+ * @param $name
+ * Type: string. The name of child nade is being added
+ *
+ * @param $value
+ * Type: string. Text for the adding node if it is a text node.
+ *
+ * @return DOMElement $added_node
+ * The newly created node, can be used for further expansion.
+ * If no further expansion is expected, return value can be igored.
+ */
+
+ function addChild($mom_node,$name, $value='') {
+ $added_node = $this->doc->createElement($name,$value);
+ $added_node = $mom_node->appendChild($added_node);
+ return $added_node;
+ }
+}
+
+class OAI2XMLError extends OAI2XML {
+
+ function __construct($request_args, $errors) {
+ parent::__construct($request_args);
+
+ $oai_node = $this->doc->documentElement;
+ foreach($errors as $e) {
+ $node = $this->addChild($oai_node,"error",$e->getMessage());
+ $node->setAttribute("code",$e->getCode());
+ }
+ }
+
+}
diff --git a/oaidp-config.php b/oaidp-config.php
deleted file mode 100644
index be37d47..0000000
--- a/oaidp-config.php
+++ /dev/null
@@ -1,77 +0,0 @@
-= '$from'";
-}
-
-/** filter for sets, appends to the end of SQL query */
-function setQuery($set) {
- global $SQL;
- // strip off "class:" which is not saved in database
- if(strstr($set,"class:")) $set = substr($set,6);
- return ' AND '.$SQL['set']." LIKE '%$set%'";
-}
-
-/** for accurately to assess how many records satisfy conditions for all DBs */
-function rowCount($metadataPrefix, $extQuery, $db) {
- global $SQL;
- $n = 0;
- $sql = "SELECT COUNT(*) FROM ".$SQL['table'] . " WHERE ".$SQL['metadataPrefix']." LIKE '%$metadataPrefix%'" . $extQuery;
- if ($res = $db->query($sql)) {
- $n = $res->fetchColumn();
- }
- return $n;
-}
-
-/** A worker function for processing an error when a query was executed
- * \param $query string, original query
- * \param $e PDOException, the PDOException object
- */
-function process_pdo_error($query, $e) {
- echo $query.' was failed\n';
- echo $e->getMessage();
-}
-
-/** When query return no result, throw an Exception of Not found.
- * \param $db PDO
- * \param $query string
- * \return $res PDOStatement
- */
-function exec_pdo_query($db, $query) {
- $res = $db->query($query);
- if ($res===false) {
- throw new Exception($query.":\nIt found nothing.\n");
- } else return $res;
-}
diff --git a/xml_creater.php b/xml_creater.php
index b46ec80..a2f0382 100644
--- a/xml_creater.php
+++ b/xml_creater.php
@@ -1,145 +1,15 @@
"ListRecords","resumptionToken"=>"9CD1DA87F59C3E960871F4F3C9D093887C17D174");
- * // Example 1: Error response
- * $error_array[] = oai_error("badVerb","Rubish");
- * $error_array[] = oai_error("sameVerb");
- * $e = new ANDS_Error_XML($par_array,$error_array);
- * $e->display();
- *
-
- * // Example 2: Normal response without error codes
+ * Example: Normal response without error codes
* $par_array = array("verb"=>"ListRecords","resumptionToken"=>"9CD1DA87F59C3E960871F4F3C9D093887C17D174");
* $test = new ANDS_Response_XML($par_array);
* $record_node = $test->create_record();
* $test->create_header("function: identifier string",gmdate("Y-m-d\TH:i:s\Z"),"collection",$record_node);
* $test->create_metadata($record_node);
* $test->display();
- * \endcode
- *
- * \see http://www.openarchives.org/OAI/openarchivesprotocol.html#ErrorConditions
*/
-/*
-http://www.openarchives.org/OAI/openarchivesprotocol.html#ErrorConditions
-
-badArgument:
- The request includes illegal arguments, is missing required arguments, includes a repeated argument, or values for arguments have an illegal syntax. Applied to all verbs.
-
-badResumptionToken:
- The value of the resumptionToken argument is invalid or expired. Applied to: ListIdentifiers, ListRecords, ListSets
-
-badVerb:
- Value of the verb argument is not a legal OAI-PMH verb, the verb argument is missing, or the verb argument is repeated. N/A
-
-cannotDisseminateFormat:
- The metadata format identified by the value given for the metadataPrefix argument is not supported by the item or by the repository. Applied to GetRecord, ListIdentifiers, ListRecords
-
-idDoesNotExist:
- The value of the identifier argument is unknown or illegal in this repository. Applied to GetRecord, ListMetadataFormats
-
-noRecordsMatch:
- The combination of the values of the from, until, set and metadataPrefix arguments results in an empty list. Applied to ListIdentifiers, ListRecords
-
-noMetadataFormats:
- There are no metadata formats available for the specified item. Applied to ListMetadataFormats.
-
-noSetHierarchy:
- The repository does not support sets. Applied to ListSets, ListIdentifiers, ListRecords
-
-*/
-
-/** utility funciton to mapping error codes to readable messages */
-function oai_error($code, $argument = '', $value = '') {
-
- switch ($code) {
- case 'badArgument' :
- $text = "Attribute '{$argument}' is not allowed to appear in element 'request'.";
- break;
-
- case 'badGranularity' :
- $text = "The value '{$value}' of attribute '{$argument}' on element 'request' is not valid with respect to its type, 'UTCdatetimeType'.";
- $code = 'badArgument';
- break;
-
- case 'badResumptionToken' :
- $text = "The resumptionToken '{$value}' does not exist or has already expired.";
- break;
-
- case 'badRequestMethod' :
- $text = "The request method '{$argument}' is unknown.";
- $code = 'badVerb';
- break;
-
- case 'badVerb' :
- $text = "The value '{$argument}' of attribute 'verb' on element 'request' is not valid with respect to its type, 'verbType'";
- break;
-
- case 'cannotDisseminateFormat' :
- $text = "The metadata format '{$value}' given by {$argument} is not supported by this repository.";
- break;
-
- case 'exclusiveArgument' :
- $text = 'The usage of resumptionToken as an argument allows no other arguments.';
- $code = 'badArgument';
- break;
-
- case 'idDoesNotExist' :
- $text = "The value '{$value}' of the identifier does not exist in this repository.";
- if (!is_valid_uri($value)) {
- $code = 'badArgument';
- $text .= ' Invalidated URI has been detected.';
- }
- break;
-
- case 'missingArgument' :
- $text = "The required argument '{$argument}' is missing in the request.";
- $code = 'badArgument';
- break;
-
- case 'noRecordsMatch' :
- $text = 'The combination of the given values results in an empty list.';
- break;
-
- case 'noMetadataFormats' :
- $text = 'There are no metadata formats available for the specified item.';
- break;
-
- case 'noVerb' :
- $text = 'The request does not provide any verb.';
- $code = 'badVerb';
- break;
-
- case 'noSetHierarchy' :
- $text = 'This repository does not support sets.';
- break;
-
- case 'sameArgument' :
- $text = 'Do not use the same argument more than once.';
- $code = 'badArgument';
- break;
-
- case 'sameVerb' :
- $text = 'Do not use verb more than once.';
- $code = 'badVerb';
- break;
-
- case 'notImp' :
- $text = 'Not yet implemented.';
- $code = 'debug';
- break;
-
- default:
- $text = "Unknown error: code: '{$code}', argument: '{$argument}', value: '{$value}'";
- $code = 'badArgument';
- }
- return $code."|".$text;
-}
/**
* A wraper of DOMDocument for data provider