Location: PHPKode > projects > Taxonomic Search Engine > ubio_wrapper.php
<?php

// $Id: ubio_wrapper.php,v 1.1.1.1 2005/05/19 10:31:10 rdmpage Exp $

/**
 * @brief Wrapper to talk to uBio using its SOAP web service
 *
 * <A HREF="http://www.ubio.org/services/network/index.html">uBio</A> provide a web service interface to their
 * Taxonomic Name Server. The service has a SOAP interface and is well documented with
 * example client PHP code and sample output. My class makes extensive use of that code.
 *
 * A key thing to remember is that uBio SOAP message use base64 encoding for strings.
 * uBio also returns arrays of results (as opposed to, say, XML), and so we construct our
 * own XML document from the returned array. 
 *
 * I have also experienced problems with Mindreef's SOAPscope and the uBio web service. If SOAPscope
 * is used as a proxy server then the message is corrupted.
 *
 */
 
 
/* Various experiments with entities */
/*
function utf2html ($str ) { 
$ret ="" ;
$max =strlen ($str ); 
$last =0; // keeps the index of the last regular character 
for ( $i =0;$i <$max ;$i ++) { 
 $c =$str {$i }; 
 $c1 =ord ($c ); 
 if ( $c1 >> 5== 6) {  // 110x xxxx, 110 prefix for 2 bytes unicode 
   $ret .= substr ($str ,$last ,$i -$last ); // append all the regular characters we've passed 
   $c1 &= 31 ;// remove the 3 bit two bytes prefix 
   $c2 =ord ($str {++ $i }); // the next byte 
   $c2 &= 63 ;  // remove the 2 bit trailing byte prefix 
   $c2 |= (( $c1 &3) << 6); // last 2 bits of c1 become first 2 of c2 
   $c1 >>= 2;// c1 shifts 2 to the right 
   $ret .= "&#" . ( $c1 *100 +$c2 ) . ";" ;// this is the fastest string concatenation 
   $last =$i +1;        
 } 
}
return $ret .substr ($str ,$last ,$i ); // append the last batch of regular characters 
}

function xmlentities ($string , $quote_style = ENT_QUOTES )
{
	$translation_table = get_html_translation_table( HTML_ENTITIES, $quote_style); 

	foreach ( $translation_table as $key => $value )
		$translation_table [$key ] = '&#' .ord ($key ). ';' ;
	// dont translate the '&' in case it is part of &xxx; 
	$translation_table [chr (38 )] = '&' ;


	// after the initial translation, _do_ map standalone '&' into '&#38;' 
 	return preg_replace ("/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/" ,"&#38;" , 
 		strtr ($string ,$translation_table )); 
}

*/
 
 
class uBioWrapper extends Wrapper {
	
	/**
	 * Store the address of the WSDL file for this service.
	 * @protected
	 */
	var $wsdl;

	
	//----------------------------------------------------------------------------
	/**
	 * Sets the WSDL address for the service 
	 * (currently <A HREF="http://uio.mbl.edu/service/uBioServiceWSDL.php#wsdl">
	 * http://uio.mbl.edu/service/uBioServiceWSDL.php#wsdl</a>),
	 * and sets the authority and namespace.
	 */
	function uBioWrapper ()
	{
	
		$this->wsdl = "http://uio.mbl.edu/service/index.php#wsdl";
		
		$this->authority = "ubio.org";
		$this->namespace = "namebankID";
		
		$this->xml = "";
		$this->StartXML();
	}
	
	//----------------------------------------------------------------------------
	/**
	 * @brief Tests if uBio is alive.
	 *
	 * @return true if service is live, false otherwise
	 */
	function IsAlive ()
	{
		$result = true; // for now
		return $result;
	}
		
	
	//----------------------------------------------------------------------------
	/**
	 * @brief Return details for a single record in uBio, using their SOAP interface
	 *
	 * @param id Index Fungorum of taxon name to retrieve
	 * @return Result in my XML format
	 */
	function GetDataForID ($id)
	{
		$result = "";
		
		global $config;
		
		$big = "";
		
		$data = $this->GetDataFromCache ("GetDataForID", "txt", $id);
		if ($data != "")
		{
			$big = unserialize($data);
		}
		else
		{
		
			// Search parameters. 
			$args = array(			
				"namebankID"=>$id,
				"vernacularFlag"=>1,
				"homotypicSynonymsFlag"=>1,
				"citationsFlag"=>0,
				"mappingsFlag"=>1,
				"basicFlag"=>1,
				"childrenFlag"=>1,
				"clientVersion"=>"0.1",
				"requestorIP"=>$_SERVER["SERVER_ADDR"],			
				"keyCode"=>$config["uBio_key"]
			);
			
	   		//$parameters = array('args'=>$args);
			//print_r ($parameters);
			
			// From 7 April 2005 uBio data structures changed (sigh).
			$parameters = $args;
			
			// Proxy settings
			$proxyhost = '';
			$proxyport = '';
			if ($config['proxy_name'] != '')
			{
				$proxyhost = $config['proxy_name'];
				$proxyport = $config['proxy_port'];
			}
			if ($config['soap_proxy_name'] != '')
			{
				$proxyhost = $config['soap_proxy_name'];
				$proxyport = $config['soap_proxy_port'];
			}
					
			// Create SOAP client from WSDL
			$soapclient = new soapclient($this->wsdl);
			if ($soapclient->fault)
			{
				$this->Error ("SOAP", $soapclient->getError());
				$this->EndXML();
				return $this->xml;
			}

			$soapclient->soap_defencoding = 'ISO-8859-1'; //'UTF-8';
	
			$soapclient->debug_flag=true;
	
			$soapclient->setHTTPProxy ($proxyhost, $proxyport);
	
			// Make the call
			$this->StartTimer();
			// Make the call
			$big = $soapclient->call('namebank_object', $parameters);
			
			$this->StopTimer();
				
			//print_r($big);
				
			//--------------------------------------------------------------------------------------------
			// Check for a fault
			if ($soapclient->fault)
			{
				$this->Error ("SOAP", $soapclient->getError());
				$this->EndXML();
				return $this->xml;
			} else
			{
			    // Check for errors
			    $err = $soapclient->getError();
			    if ($err)
			    {
					$this->Error ("SOAP", $soapclient->getError());
					$this->EndXML();
					return $this->xml;
			    }
			}
		}
		
		if ($big != "")
		{
	    	// Now for the fun
	 		//echo '<xmp>'.$soapclient->request.'</xmp>';
			//echo '<xmp>'.$soapclient->response.'</xmp>';
			
			// Metadata about result
			$serviceData = $big['serviceData'];
			
			//print_r($big);
			
			// Search result
			$this->ReportTimeUsed();	
			//$this->EndXML();	
			
			
			$myxml = "<?xml version='1.0' encoding='utf-8'?>\n";
			$myxml .= "<Result>\n";
			
			// Put out from array
			$name			= base64_decode($big["nameString"]);
			$namesAuthority = base64_decode ($big["authorityString"]); 
			// Watch out for '&' in authority
			$namesAuthority = htmlspecialchars ($namesAuthority, ENT_NOQUOTES, UTF-8);
			$rank			= ucfirst($big["defaultRankName"]);
			$status			= $big['availability'];
			
			
			// Make XML
			$myxml .= "<taxon authority=\"$this->authority\" namespace=\"$this->namespace\" id=\"$id\">\n";
			$myxml .= "   <name>$name</name>\n";
			$myxml .= "   <author>$namesAuthority</author>\n";
			$myxml .= "   <rank>$rank</rank>\n";
			$myxml .= "   <status>$status</status>\n";
						
			$vernacularNames =$big ["vernacularNames" ]; 
				 
				// print_r($vernacularNames);
				 
		   	for($i=0; $i<count($vernacularNames); $i++) 
		   	{
			   $nameString =  base64_decode($vernacularNames[$i]["nameString"]);
			   $languageCode = $vernacularNames[$i]["languageCode"]; 
			   
			   $myxml .= "<commonname xml:lang=\"$languageCode\">$nameString</commonname>\n";
			}

			$myxml .= "<url>http://www.ubio.org/SOAPbrowser/index.php?func=name_detail&amp;ubioID=$id</url>\n";
			$myxml .= "</taxon>\n";
			
			$myxml .= "</Result>\n";

			$this->xml = $myxml;
			
			//echo $this->xml;
			
			$this->StoreDataInCache ("GetDataForID", "txt", $id, serialize($big));
			

		}			
		
		return $this->xml;
	}
	

	//----------------------------------------------------------------------------
	/**
	 * @brief Searches uBio for a name.
	 *
	 * @param name The taxon name to search for
	 * @param qualifier Kind of search (default is exact)
	 * @param max_results The maximum number of records to return (default is 1)
	 */
	function NameSearch ($name, $qualifier = EXACT, $max_results = 1) 
	{
		global $config;
		
		$id = nameToSafe ($name);

		//echo $id;

		$big = "";
		$this->StartTimer();
		
		$data = $this->GetDataFromCache ("NameSearch", "txt", $id);
		if ($data != "")
		{
			//echo "cache\n";
			$big = unserialize($data);
			$this->StopTimer();

		}
		else
		{
			$searchQualifier = "contains";
			if ($qualifier == EXACT) {$searchQualifier = "exact"; }

			// Search parameters.
			$args = array(
				"string"=>$name,
				"vernacularFlag"=>0,
				"scientificFlag"=>1,
				"clientVersion"=>"0.1",
				"requestorIP"=>$_SERVER["SERVER_ADDR"],					
				"order"=>"",
				"searchQualifier"=>$searchQualifier,
				"searchLimit"=>"",
				"keyCode"=>$config["uBio_key"],
			);

			//print_r($args);

//	    		$parameters = array('args'=>$args);

			// uBio data structure changed!
			$parameters = $args;

			// Proxy settings
			$proxyhost = '';
			$proxyport = '';
			if ($config['proxy_name'] != '')
			{
				$proxyhost = $config['proxy_name'];
				$proxyport = $config['proxy_port'];
			}
			if ($config['soap_proxy_name'] != '')
			{
				$proxyhost = $config['soap_proxy_name'];
				$proxyport = $config['soap_proxy_port'];
			}
					
			// Create SOAP client from WSDL
			$soapclient = new soapclient($this->wsdl, false);
			if ($soapclient->fault)
			{
				//print "error\n";
				$this->Error ("SOAP", $soapclient->getError());
				$this->EndXML();
				return $this->xml;
			}
			//$soapclient->soap_defencoding = 'UTF-8';

			$soapclient->debug_flag=true;

			$soapclient->setHTTPProxy ($proxyhost, $proxyport);

			// Make the call
			$big = $soapclient->call('namebank_search', $parameters);
			$this->StopTimer();
			
//			echo '<xmp>'.$soapclient->response.'</xmp>';


			if ($big == '')
			{
				// If the MySQL database server is down, then we don't get a
				// SOAP error but a MySQL error message in HTML.
				
				//echo '<xmp>'.$soapclient->response.'</xmp>';

				if (preg_match("/MySQL Error:/m",$soapclient->response))
				{
					$this->Error ("MySQL Error", "Problem with uBio database");
				}
				else
				{
					$this->Error ("Unknown", "Badness happened");
				}
				$this->ReportTimeUsed();
				$this->EndXML();
				return $this->xml;
				


			}
			//print_r($big);

			//--------------------------------------------------------------------------------------------
			// Check for a fault
			if ($soapclient->fault)
			{
				$this->Error ("SOAP", $soapclient->getError());
				$this->ReportTimeUsed();
				$this->EndXML();
				return $this->xml;
			} else
			{
			    // Check for errors
			    $err = $soapclient->getError();
			    if ($err)
			    {
					$this->Error ("SOAP", $soapclient->getError());
					$this->ReportTimeUsed();
					$this->EndXML();
					return $this->xml;
				}
			    else
			    {
					$this->StoreDataInCache ("NameSearch", "txt", $id, serialize($big));
				}

		    }

	    }


		if ($big != "")
		{
	
	    	// Now for the fun
//	 		echo '<xmp>'.$soapclient->request.'</xmp>';
//			echo '<xmp>'.$soapclient->response.'</xmp>';

			// Metadata about result
			$serviceData = $big['matching_names'];
			
			// Search result
			$this->ReportTimeUsed();

			if( $big ["scientificNames" ]) 
			{  
				 $seniorArray =$big ["scientificNames" ]; 
				 
				 //print_r($seniorArray);
				 
				   for($i=0; $i<count($seniorArray); $i++) {
						$ubioID			=$seniorArray[$i]["namebankID"];
						$namesAuthority = base64_decode($seniorArray[$i]["authorityString"]);
						// Watch out for '&' in authority
						$namesAuthority = htmlspecialchars ($namesAuthority, ENT_NOQUOTES, UTF-8);
						
						// Set the name to be empty when doing Species 2000 names,
						// because there seems to be a problem with entities in some
						// author names.
						$namesAuthority = "";
						
						$name			= base64_decode($seniorArray[$i]["nameString"]);
						$packageID		= $seniorArray[$i]["packageID"];
						$package		= $seniorArray[$i]["packageName"];
						$rank			= ucfirst($seniorArray[$i]["rankName"]);
						$date 			= $serviceData['dateStamp'];
						$version		= $serviceData['currentVersion'];
					
						
						$this->xml .= "<taxon authority=\"$this->authority\" namespace=\"$this->namespace\" id=\"$ubioID\">\n";
						$this->xml .= "   <name>$name</name>\n";
						$this->xml .= "   <author>$namesAuthority</author>\n";
						$this->xml .= "   <rank>$rank</rank>\n";
						$this->xml .= "   <kingdom></kingdom>\n";
						$this->xml .= "   <rank>$rank</rank>\n";
						$this->xml .= "   <date>$date</date>\n";
						$this->xml .= "   <version>$version</version>\n";
						$this->xml .= "   <url>http://www.ubio.org/SOAPbrowser/index.php?func=name_detail&amp;ubioID=$ubioID</url>\n";
						$this->xml .= "</taxon>\n";
	
	
					}	 
			} 
			else
			{
				//echo "No name matching &quot;$string&quot; found.<br/>";
			}
			$this->EndXML();
	
	    }			
		
		return $this->xml;
	}

}

?>
Return current item: Taxonomic Search Engine