return 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) { echo $msg,"\n"; } } /** Check if provided correct arguments for a request. * * Only number of parameters is checked. * metadataPrefix has to be checked before it is used. * set has to be checked before it is used. * resumptionToken has to be checked before it is used. * from and until can easily checked here because no extra information * is needed. */ function checkArgs($args, $checkList) { global $errors, $METADATAFORMATS; // "verb" has been checked before, no further check is needed unset($args["verb"]); if(isset($checkList['required'])) { for($i = 0; $i < count($checkList["required"]); $i++) { if(isset($args[$checkList['required'][$i]])==false) { $errors[] = oai_error('missingArgument', $checkList["required"][$i]); } else { // if metadataPrefix is set, it is in required section if(isset($args['metadataPrefix'])) { $metadataPrefix = $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']))) { $errors[] = oai_error('cannotDisseminateFormat', 'metadataPrefix', $metadataPrefix); } } unset($args[$checkList["required"][$i]]); } } } if (!empty($errors)) return; // check to see if there is unwanted foreach($args as $key => $val) { if(!in_array($key, $checkList["ops"])) { $errors[] = oai_error('badArgument', $key, $val); } switch ($key) { case 'from': case 'until': if(!checkDateFormat($val)) { $errors[] = oai_error('badGranularity', $key, $val); } break; case 'resumptionToken': // only check for expairation if((int)$val+TOKEN_VALID < time()) $errors[] = oai_error('badResumptionToken'); break; } } } /** Validates an identifier. The pattern is: '/^[-a-z\.0-9]+$/i' which means * it accepts -, letters and numbers. * Used only by function oai_error code idDoesNotExist. * \param $url Type: string */ function is_valid_uri($url) { return((bool)preg_match('/^[-a-z\.0-9]+$/i', $url)); } /** Validates attributes come with the query. * It accepts letters, numbers, ':', '_', '.' and -. * Here there are few more match patterns than is_valid_uri(): ':_'. * \param $attrb Type: string */ function is_valid_attrb($attrb) { return preg_match("/^[_a-zA-Z0-9\-\:\.]+$/",$attrb); } /** All datestamps used in this system are GMT even * return value from database has no TZ information */ function formatDatestamp($datestamp) { return date("Y-m-d\TH:i:s\Z",strtotime($datestamp)); } /** The database uses datastamp without time-zone information. * It needs to clean all time-zone informaion from time string and reformat it */ function checkDateFormat($date) { $date = str_replace(array("T","Z")," ",$date); $time_val = strtotime($date); if (SHOW_QUERY_ERROR) { echo "timeval: $time_val\n"; } if(!$time_val) return false; if(strstr($date,":")) { return date("Y-m-d H:i:s",$time_val); } else { return date("Y-m-d",$time_val); } } /** Retrieve all defined 'setSpec' from configuraiton of $SETS. * It is used by ANDS_TPA::create_obj_node(); */ function prepare_set_names() { global $SETS; $n = count($SETS); $a = array_fill(0,$n,''); for ($i = 0; $i <$n; $i++) { $a[$i] = $SETS[$i]['setSpec']; } return $a; } /** Finish a request when there is an error: send back errors. */ function oai_exit() { // global $CONTENT_TYPE; header(CONTENT_TYPE); global $args,$errors,$compress; $e = new ANDS_Error_XML($args,$errors); if ($compress) { ob_start('ob_gzhandler'); } $e->display(); if ($compress) { ob_end_flush(); } exit(); } // ResumToken section /** Generate a string based on the current Unix timestamp in microseconds for creating resumToken file name. */ function get_token() { list($usec, $sec) = explode(" ", microtime()); return ((int)($usec*1000) + (int)($sec*1000)); } /** Create a token file. * It has three parts which is separated by '#': cursor, extension of query, metadataPrefix. * Called by listrecords.php. */ function createResumToken($cursor, $extquery, $metadataPrefix) { $token = get_token(); $fp = fopen (TOKEN_PREFIX.$token, 'w'); if($fp==false) { exit("Cannot write. Writer permission needs to be changed."); } fputs($fp, "$cursor#"); fputs($fp, "$extquery#"); fputs($fp, "$metadataPrefix#"); fclose($fp); return $token; } /** Read a saved ResumToken */ function readResumToken($resumptionToken) { $rtVal = false; $fp = fopen($resumptionToken, 'r'); if ($fp!=false) { $filetext = fgets($fp, 255); $textparts = explode('#', $filetext); fclose($fp); unlink ($resumptionToken); $rtVal = array((int)$textparts[0], $textparts[1], $textparts[2]); } return $rtVal; } // Here are a couple of queries which might need to be adjusted to // your needs. Normally, if you have correctly named the columns above, // this does not need to be done. /** this function should generate a query which will return * all records * the useless condition id_column = id_column is just there to ease * further extensions to the query, please leave it as it is. */ function selectallQuery($metadPrefix = "rif", $id = ''){ global $SQL; $query = "SELECT * FROM ".$SQL['table'] . " WHERE ".$SQL['metadataPrefix']." LIKE '%$metadPrefix%'"; if ($id != '') { $query .= " AND ".$SQL['identifier']." ='$id'"; } return $query; } /** this function will return identifier and datestamp for all records * not very useful */ function idQuery($metadPrefix = "rif", $id = '') { global $SQL; if ($SQL['set'] != '') { $query = 'select '.$SQL['identifier'].','.$SQL['datestamp'].','.$SQL['set'].' FROM '.$SQL['table']. " WHERE ".$SQL['metadataPrefix']." LIKE '%$metadPrefix%'"; } else { $query = 'select '.$SQL['identifier'].','.$SQL['datestamp'].' FROM '.$SQL['table']. " WHERE ".$SQL['metadataPrefix']." LIKE '%$metadPrefix%'"; } if ($id != '') { $query .= " AND ".$SQL['identifier']." = '$id'"; } return $query; } /** filter for until, appends to the end of SQL query */ function untilQuery($until) { global $SQL; return ' AND '.$SQL['datestamp']." <= '$until'"; } /** filter for from , appends to the end of SQL query */ function fromQuery($from) { global $SQL; return ' AND '.$SQL['datestamp']." >= '$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; }