NR_BFREQUEST=9999; // user defined request $this->BPMapsByStream=false; // maps are coming as stream by default $this->BPLogFilePath=""; // set LogFilePath $this->eATCor = 1; // const for correction part of server answer $this->eATAns = 0; // const for answer part of server answer $this->BPMaxSocketWait=60; // wait 60 seconds per server for a socket connect $this->BPMaxCalcWait=60; // wait 60 seconds per server for the end of a request $this->BPMaximumFileAge=10; // leave the generated maps 10 seconds as a maximum on hard disk $this->BPStat_PropriError= 0; // unknown error $this->BPStat_Error = 1; // known error $this->BPStat_Success = 2; // success (one hit - geocoding) $this->BPGeoStat_Select = 3; // success (multiple hits - geocoding) $this->BPRouteStat_Select= 3; // should never happen (old value!) $this->BPRouteStat_NoLocFound = 4; // should never happen (old value!) $this->BPWINOS = false; // not used at the moment $this->BPUNIXOS = false; // not used at the moment $this->BFSetFileCount(); // get file count $this->BPStreamToDisk=true; // BPUrlNameMap = URL to map if correct parameters were passed $this->BPUrlNameMap = $this->BPParaBCUrl . $this->BPParaRequestFileName . $this->BPFileCount; // . "." . $this->BPPictureFormat; $this->Log_to_file("ALBasic.ALBasic: Passed successfully."); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BFGetTCPAnsLength // Gets the length from the response stream in byte. The length is defined // as a 12 byte string with leading 0s. E.g.: #0000000111#, answer is 111 // byte long function BFGetTCPAnsLength($fp) { if (!$fp || feof($fp)) return 0; //socket_set_timeout($fp,$this->BPMaxCalcWait); $bufferArray = explode("#",fread($fp,12)); return ((int)$bufferArray[1])-11; $this->Log_to_file("ALBasic.BFGetTCPAnsLength: Passed Succesfully"); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BFReadALSAnswer // Reads complete answer from TCP/IP stream and splits stream into // COR (correction) and ANS (answer) parts. Every line is read into // a single associative array function BFReadALSAnswer($servicenum) { if($this->TCPtemp=="") return false; // read complete answer stream into arrays if (($servicenum==$this->NR_NEXTREQUEST && $this->BPRequest["CLIENT"]["NEXTID"]=="") || $servicenum==$this->NR_ROUTEREQUEST || $servicenum==$this->NR_GEOREQUEST) { $this->BPTCPAnswer["COR"] = explode("^", $this->TCPtemp[2]); $this->BPTCPAnswer["ANS"] = explode("^", $this->TCPtemp[6]); } else $this->BPTCPAnswer["ANS"] = explode("^", $this->TCPtemp[2]); // read every single line of answer section ANS into an assoc. array for ($i = 0; $i < count($this->BPTCPAnswer["ANS"])-1 ;$i++) { $tmp = explode("~", $this->BPTCPAnswer["ANS"][$i]); if(substr($tmp[1],0,4)=="NODE") $this->BCAnswerList["ANS"][$tmp[0]][$tmp[1]]=str_replace($tmp[0]."~".$tmp[1]."~","",$this->BPTCPAnswer["ANS"][$i]); else $this->BCAnswerList["ANS"][$tmp[0]][$tmp[1]]=$tmp[2]; } // read every single line of correction section COR into an assoc. array if(is_array($this->BPTCPAnswer["COR"])) for ($i = 0; $i < count($this->BPTCPAnswer["COR"])-1 ;$i++) { $tmp = explode("~", $this->BPTCPAnswer["COR"][$i]); $this->BCAnswerList["COR"][$tmp[0]][$tmp[1]]=$tmp[2]; } // read maps from stream if applicable if($this->BPMapsByStream) { //[MAPS] //MAPSTREAMS=,|,|,|... $maps=explode("|",$this->BFGetParam($this->eATAns,"MAPS","MAPSTREAMS","")); if(count($maps)>0) { for($i=0;$iBPFPTCP,1); // read map from stream $mapstream=explode(",",$maps[$i]); $temp = fread($this->BPFPTCP, $mapstream[1]); $this->BPMapStream=array($i => $temp); // write map to file if($this->BPStreamToDisk && $this->BPStreamDirectory!="") { $fp=@fopen($this->BPStreamDirectory."/".$mapstream[0],"wb"); if($fp) { fwrite($fp,$temp); fclose($fp); } else $this->Log_to_file("ALBasic.BFReadALSAnswer: Error while writing map to hard disk: MapFile ".$this->BPStreamDirectory."/".$mapstream[0]); } } srand ((double)microtime()*1000000); if(rand(0,100)%2 == 0) // deletion is performed $this->BFDeleteOldFiles(); } } $this->Log_to_file("ALBasic.BFReadALSAnswer: Passed Succesfully"); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BFSetFileCount // Get single name for the naming of the generated files. Has to be // explicitly used by the user. This file count is not automatically // added to a file name! function BFSetFileCount() { $mytime=gettimeofday(); $this->BPFileCount = $mytime["sec"]."--".$mytime["usec"]; $this->Log_to_file("ALBasic.BFSetFileCount: Passed Succesfully"); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BFBuildOrder() // assembles request to server according to the content of the associative // arrays containing the properties and their values function BFBuildOrder() { $request=""; $separator="'^'"; // add user defined parameter for variables of ALBasic if($this->BPPictureFormat!="") $this->BPRequest["CLIENT"]["BPPICTUREFORMAT"]=$this->BPPictureFormat; // build all values concerning SERVER section if(is_array($this->BPRequest["SERVER"])) { reset($this->BPRequest["SERVER"]); while (list($key, $value) = each ($this->BPRequest["SERVER"])) $request .= "SERVER~$key~$value" . $separator; } // build all values concerning CLIENT section if(is_array($this->BPRequest["CLIENT"])) { reset($this->BPRequest["CLIENT"]); while (list($key, $value) = each ($this->BPRequest["CLIENT"])) $request .= "CLIENT~$key~$value" . $separator; } // build all values concerning CLIENT section if(is_array($this->BPRequest["DISTMATRIX"])) { reset($this->BPRequest["DISTMATRIX"]); while (list($key, $value) = each ($this->BPRequest["DISTMATRIX"])) $request .= "DISTMATRIX~$key~$value" . $separator; } // build all values concerning special section (login) if applicable // it's necesary for the function WRITE_OPTIONS where a section // called after the login name is available $login=strtoupper($this->BPRequest["CLIENT"]["LOGIN"]); if (sizeof($this->BPRequest[$login])>0) { reset($this->BPRequest[$login]); $numo=0; while (list($key, $value) = each ($this->BPRequest[$login])) { $numo++; $request .= $login."~OPTION".$numo."~$key^$value".$separator; } $request .= $login."~NUMOPTIONS~$numo".$separator; } // return ready built request $this->Log_to_file("ALBasic.BFBuildOrder: Passed Succesfully: Request: #BAL##FN#".$this->BPParaRequestFileName."#ENDFN#" . $request . "#SEP#" . $separator . "#ENDSEP##ENDBAL#"); return "#BAL##FN#".$this->BPParaRequestFileName."#ENDFN#" . $request . "#SEP#" . $separator . "#ENDSEP##ENDBAL#\r\n"; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BFWriteOrder // Opens TCP/IP connection and sends request to server. function BFWriteOrder($request) { // split list of all available servers $serverlist=explode("^",$this->BPALS); // check every server in round robin manner until timeout or connect for($x=0;$xBPALSTCP["NAME"],$this->BPALSTCP["IP"],$this->BPALSTCP["PORT"],$this->BPALSTCP["ACTIVE"])=explode(",",$serverlist[$x]); // if server is set to "active" in server list, try to connect if((int)$this->BPALSTCP["ACTIVE"]==1) { // reset connection $this->BPFPTCP = false; // connect to IP and port of server $this->BPFPTCP = @fsockopen ($this->BPALSTCP["IP"], $this->BPALSTCP["PORT"], &$errno, &$errstr, $this->BPMaxSocketWait); // if connection was enabled, write request if ($this->BPFPTCP && !feof($this->BPFPTCP)) { $answerlength=0; $starttime=time(); $small_result_without_error=false; while((int)$answerlength<100 && !$small_result_without_error && (time()-$starttime<(int)$this->BPMaxCalcWait)) { // write request @fputs ($this->BPFPTCP,$request); $this->Log_to_file("ALBasic.BFWriteOrder: succesful server connect: Server: ".$this->BPALSTCP["IP"].":".$this->BPALSTCP["PORT"]); // get answer length $answerlength=$this->BFGetTCPAnsLength($this->BPFPTCP); // #0000000024##DISABLED##ENDDISABLED# // #0000000037##BUSY#~#ENDBUSY# // #0000000042##ERROR##ENDERROR# $this->TCPtemp=""; $errno=$answerlength; // if answer length is less than 100, we received an error from server if($answerlength<100) { if($answerlength>0) $tcptmp=fgets($this->BPFPTCP, $answerlength); if($answerlength==24) $this->Log_to_file("ALBasic.BFWriteOrder: Server is disabled: Server: ".$this->BPALSTCP["IP"].":".$this->BPALSTCP["PORT"]." server answer: ".$tcptmp); else if($answerlength>0) $this->Log_to_file("ALBasic.BFWriteOrder: Server error: Server: ".$this->BPALSTCP["IP"].":".$this->BPALSTCP["PORT"]." server answer: ".$tcptmp); else $this->Log_to_file("ALBasic.BFWriteOrder: Server error: Server: ".$this->BPALSTCP["IP"].":".$this->BPALSTCP["PORT"]." server answer: none"); fclose($this->BPFPTCP); if(strpos ($tcptmp, "SERVER~ERRORCODE~0")) $small_result_without_error=true; if(!$small_result_without_error) { //usleep(300); // does not work with windows $mytime=time(); srand ((double)microtime()*1000000); $comp=rand(1,3); while(time()-$mytime<$comp); $this->BPFPTCP = @fsockopen ($this->BPALSTCP["IP"], $this->BPALSTCP["PORT"], &$errno, &$errstr, $this->BPMaxSocketWait); } } else { $this->TCPtemp = explode("#", fgets($this->BPFPTCP, $answerlength)); return $answerlength; break; } } // try to send request to one server (end while) if(!$small_result_without_error) fclose($this->BPFPTCP); } else { $this->Log_to_file("ALBasic.BFWriteOrder: Error while writing to socket: Server: ".$this->BPALSTCP["IP"].":".$this->BPALSTCP["PORT"]); } // end server connect } // server active } // end for if($this->TCPtemp=='') $this->Log_to_file("ALBasic.BFWriteOrder: Passed without server connect"); else $this->Log_to_file("ALBasic.BFWriteOrder: Passed Succesfully"); return $errno; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BFCheckParam // Check whether all necessary parameters are available dependent on // the service requested by the server. // returns clear text error message function BFCheckParam($servicenum) { $err_msg=''; // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // common parameters if ($this->BPALS == "") $err_msg = "Warning: No server defined!"; elseif (($servicenum==$this->NR_MAPREQUEST || $servicenum==$this->NR_ROUTINGREQUEST) && $this->BPParaRequestFileName == "") $err_msg = "Warning: No name for file to generate!"; $this->Log_to_file("ALBasic.BFCheckParam: Regular error message: ".$err_msg); if($err_msg!='') { if ($servicenum == $this->NR_GEOREQUEST) $this->GeoResponse = $err_msg; if ($servicenum == $this->NR_MAPREQUEST) $this->MapResponse = $err_msg; if ($servicenum == $this->NR_ROUTINGREQUEST) $this->RouteResponse = $err_msg; return $this->BPStat_Error; } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // error messages for geocoding service if ($servicenum == $this->NR_GEOREQUEST) { if ($this->ParaRequestType == "") { if ($servicenum == $this->NR_GEOREQUEST) $this->GeoResponse = "Warning: Parameter ParaRequestType not defined!"; $this->Log_to_file("ALBasic.BFCheckParam: Regular error message (geocoding): ".$this->GeoResponse); return $this->BPStat_Error; } } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // error messages for mapping service if ($servicenum == $this->NR_MAPREQUEST) { if ($this->MapRequestRect == "" && $this->MapObjectList && "" and $this->BPRequest[CLIENT][LOGICALRECT]=="" && $this->BPRequest["CLIENT"]["CST1"] =="" && $this->BPRequest["CLIENT"]["SHOWINITRECT"] !="TRUE") { $this->MapResponse = "Warning: No bounding rect and no objects defined!"; $this->Log_to_file("ALBasic.BFCheckParam: Regular error message (geocoding): ".$this->GeoResponse); return $this->BPStat_Error; } } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // error messages for routing service if ($servicenum == $this->NR_ROUTINGREQUEST) { if (($this->RouteStation[1] == "" and $this->RouteStation[2] == "") and (($this->BPRequest["CLIENT"]["STATION1"]=="") and ($this->BPRequest["CLIENT"]["STATION2"]=="") )) { $this->RouteResponse = "Warning: No starting and destination point defined!"; $this->Log_to_file("ALBasic.BFCheckParam: Regular error message (routing): ".$this->RouteResponse); return $this->BPStat_Error; } } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // error messages for next search service if ($servicenum == $this->NR_NEXTREQUEST) { if($this->SearchByCoord=="" && $this->SearchByTown=="") { $this->Response = "Warning: No search statement as SearchByTown or SearchByCoord defined!"; $this->Log_to_file("ALBasic.BFCheckParam: Regular error message (next search): ".$this->Response); return $this->BPStat_Error; } } $this->Log_to_file("ALBasic.BFCheckParam: Passed Succesfully"); return $this->BPStat_Success; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BFAddParam // add a property to the request without recheck by system function BFAddParam($app, $key, $value) { $this->BPRequest[strtoupper($app)][strtoupper($key)] = $value; $this->Log_to_file("ALBasic.BFAddParam: Passed successfully: ".$app." ".$key." ".$value); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BFGetParam // read a property directly from COR or ANS part of the TCP/IP answer function BFGetParam($answer_type, $section, $name, $def_value) { (($answer_type == $this->eATAns) ? $file = "ANS" : $file = "COR"); if($this->BCAnswerList[$file][strtoupper($section)][$name]!="") return $this->BCAnswerList[$file][strtoupper($section)][$name]; $this->Log_to_file("ALBasic.BFGetParam: Passed successfully: ".$answer_type." ".$section." ".$name." ".$def_value); return $def_value; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BFDeleteOldFiles // delete old files which are older than BPMaximumFileAge by random // because it takes a lot of time to check and delete files, we only // delete every second map generation. function BFDeleteOldFiles() { if(!$this->BPMapsByStream || $this->BPStreamDirectory=="") return false; $handle = opendir($this->BPStreamDirectory."/"); while (($file = readdir($handle))!==false) if($file!="." && $file!="..") if( (time()-filemtime($this->BPStreamDirectory."/".$file))>$this->BPMaximumFileAge*60) if(!unlink($this->BPStreamDirectory."/".$file)) $this->Log_to_file("AlBasic.BFDeleteOldFiles: Error while deltin old map files on hard disk. Path: ".$this->BPStreamDirectory); $this->Log_to_file("AlBasic.BFDeleteOldFiles: Passed successfully . Path: ".$this->BPStreamDirectory); // deletion was performed return true; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Log_to_file // write log output to file defined by BPLogFilePath function Log_to_file($logtext) { if($this->BPLogFilePath=='') return false; $fp=@fopen($this->BPLogFilePath,"a"); if($fp) { fwrite($fp,$logtext."\r\n"); fclose($fp); } else echo "
Error while writing to log file
"; return false; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // BFRequest // send user defined request to the server function BFRequest() { // build request $request = $this->BFBuildOrder(); // send request to server $answerlength=$this->BFWriteOrder($request); // if length is less than 45 byte, we had an error if($answerlength>45) { // return result code // count number of hits $reqerr=$this->BFReadALSAnswer($this->NR_BFREQUEST); if($this->BFGetParam(0,"SERVER","ERRORCODE","-1")=="0" || $this->BFGetParam(0,"DISTMATRIX","ERRORCODE","-1")=="0") return 2; else return $this->BPStat_Error; } else return $this->BPStat_Error; } } // end of class definition ?>