simple-oai-pmh/ands_tpa.php

349 lines
17 KiB
PHP

<?php
/**
* \file
* \brief classes related to generating RIF-CS XML response file for ANDS from repository.
* It also serves as an exmaple how class ANDS_RIFCS can be used in a particular case.
*
*/
require_once('ands_rifcs.php');
/**
* \brief For creating RIF-CS metadata to meet the requirement of ANDS.
*
* Class ANDS_RIFCS provides all essential functionalities for creating ANDS RIF-CS records.
* The protected member functions are the backbone functions which can be used for creating any ANDS RIF-CS records.
* At the time of design only data source is database and there is only one set of outputs. Therefore there is only one class has been designed.
* Ideally, there should be a separated class for creating actual records which reflect data source and data models.
*
* Example usage: publish records meet ANDS RIF-CS requirements
*
* \code
* $metadata_node = $outputObj->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