<?php
/*
* This set of classes implement a subset of the DICT protocol
* and it is meant to be use to generate clients that
* query a DICT server
*
* By default, the class uses the dict.org server in
* the port 2628.
*
* (c) 2000, Jesus M. Castagnetto <jmcastagnetto@zkey.com>
*
* License: GPL, see http://www.gnu.org/copyleft/gpl.txt
*
* Changes:
*
* 2000/06/04 - added the correct link to the GPL license
* 2000/06/05 - added the in_array() method to the base class
* from a suggestion by Davor Cengija <davor@croart.com>
* who pointed out that PHP gained the in_array()
* function in 3.0.12, and 4.0.0
*/
//============================================================
/*
* class DictBase
*
* Base class for implementing the DICT protocol to communicate
* with dictionary servers. It defaults to dict.org and port 2628.
*/
class DictBase {
var $host = "dict.org";
var $port = "2628";
var $max_length = 6144; // 1024 * 6 to cover UTC8 chars
var $socket;
var $valid_codes =
array (
110, 111, 112, 113, 114, 130, 150, 151, 152,
210, 220, 221, 230, 250,
330,
420, 421,
500, 501, 502, 503, 530, 531, 532,
550, 551, 552, 554, 555
);
var $return_code = array();
function DictBase() {
// empty constructor
}
function set($var, $val) {
$this->$var = $val;
}
function get($var) {
return $this->$var;
}
function parse_code($str) {
ereg("^([0-9]{3}) (.+)", $str, &$reg);
$error = ( $reg[1] >= 300 );
$this->return_code = array( "error"=>$error,
"code"=>$reg[1],
"desc"=>$reg[2]);
}
function is_valid_code() {
return $this->in_array($this->return_code["code"], $this->valid_codes);
}
function is_error_code() {
return $this->return_code["error"];
}
function print_code() {
$out = $this->is_error_code() ? "<ERROR> " : "";
$out .= "[".$this->return_code["code"]."] ".$this->return_code["desc"]."\n";
echo $out;
}
function connect() {
$fp = fsockopen($this->host, $this->port, &$errno, &$errstr, 90);
if (!$fp) {
echo "Cannot connect: ".$errno." = ".$errstr."\n";
exit;
} else {
$this->socket = $fp;
}
}
function close() {
fputs($this->socket, "QUIT\r\n");
$tmp = fgets($this->socket, $this->max_length);
fclose($this->socket);
}
function read_data() {
while ($read = fgets($this->socket, $this->max_length)) {
if (ereg("^\.\r\n$",$read))
break;
$out .= $read;
}
return $out;
}
// To support old PHP3 versions ( older than 3.0.12 )
// A point I forgot and Davor Cengija reminded me about
function in_array($element, $arr) {
// figure out version
list($major, $minor, $release) = explode(".", phpversion());
if (($major == 3 && $relesase >= 12) || $major == 4) {
return in_array($element, $arr);
} else {
// assumes that we want to compare element value
while (list($key, $val) = each($arr)) {
if ($val == $element)
return true;
}
return false;
}
}
} // end of base class Dict
//============================================================
/*
* Class DictServerInfo
*
* To generate objects containing DICT server information.
* Extends the DictBase class.
*/
class DictServerInfo extends DictBase {
var $info = array();
function DictServerInfo($host="", $port="", $extended=false) {
$this->init($host, $port, $extended);
}
function init($host, $port, $extended) {
if ($host)
$this->set("host", $host);
if ($port)
$this->set("port", $port);
$this->connect();
// get connection response line
$line = fgets($this->socket, $this->max_length);
$this->parse_code($line);
if ($this->is_error_code()) {
$this->print_code();
exit;
}
// extract capabilities info from response line
ereg("^[0-9]{3} (.*) <([^<]*)> <(.*)>", $line, &$reg);
$this->info["signature"] = $reg[1];
$this->info["capabilities"] = explode(".", $reg[2]);
$this->info["msg-id"] = $reg[3];
// get description on the server and store verbatim
$this->info["server"] = $this->show("SERVER");
// get the dbs and strategies for this server
$dbs = $this->show("DB");
$this->store("databases",$dbs);
$strats = $this->show("STRAT");
$this->store("strategies",$strats);
// get the description of each database
// if extended info is requested
if ($extended)
$this->get_dbs_info();
// close the connection
$this->close();
}
function show($str) {
fputs($this->socket, "SHOW ".$str."\r\n");
$tmp = chop(fgets($this->socket, $this->max_length));
$tmp2 = explode (" ", $tmp);
if ($str == "DB")
$this->info["num_dbs"] = (int) $tmp2[1];
if ($str == "STRAT")
$this->info["num_strat"] = (int) $tmp2[1];
$data = $this->read_data();
$tmp = fgets($this->socket, $this->max_length);
return $data;
}
function store($str, $data) {
$arr = explode("\r\n", $data);
$out = array();
for ($i=0; $i<count($arr); $i++) {
if (chop($arr[$i]) == "")
continue;
ereg("^([^ ]+) \"?([^\"]+)\"?", $arr[$i], &$reg);
$out[$reg[1]] = $reg[2];
}
$this->info[$str] = $out;
}
function get_dbs_info() {
$ndb = $this->info["num_dbs"];
$dbs = $this->info["databases"];
$dbinfo = array();
while (list($k, $v) = each($dbs)) {
$dbinfo[$k] = $this->show("INFO ".$k);
}
$this->info["dbs_desc"] = $dbinfo;
}
function get_info ($str) {
return $this->info[$str];
}
} // end of class DictServerInfo
//============================================================
/*
* class DictQuery
*
* To create query objects to search a DICT server
*/
class DictQuery extends DictBase {
var $term = "";
var $method = "exact";
var $searchdb = "*";
var $query_type = "DEFINE";
var $valid_methods = array ("exact", "prefix", "substring", "suffix",
"re", "regexp", "soundex", "lev");
var $result = array();
var $numres = 0;
function DictQuery($host="", $port="") {
$this->init($host, $port);
}
function init($host, $port) {
if ($host)
$this->set("host", $host);
if ($port)
$this->set("port", $port);
$this->connect();
// get connection response line
$line = fgets($this->socket, $this->max_length);
$this->parse_code($line);
if ($this->is_error_code()) {
$this->print_code();
exit;
}
}
function search($term, $method, $db) {
if (!$this->is_method($method)) {
echo "**ERROR** invalid method: ".$method."\n";
exit;
}
$this->clear_results();
$this->term = $term;
$this->method = $method;
$this->searchdb = $db;
$query = ($method=="exact") ? "DEFINE $db " : "MATCH $db $method ";
$query .= "\"".$term."\"\r\n";
fputs($this->socket, $query);
$line = fgets($this->socket, $this->max_length);
ereg("^[0-9]{3} ([0-9]+) .+", $line, &$reg);
$this->numres = (int) $reg[1];
if ($method != "exact") {
$rlist = $this->read_data();
$this->result = explode("\r\n", chop($rlist));
} else {
$regex = "^[0-9]{3} \"([^\"]+)\" ([^\" ]+) \"([^\"]+)\"";
$allres = array();
$entry = array();
for ($i=0; $i<$this->numres; $i++) {
$line = chop(fgets($this->socket, $this->max_length));
if ($line == "")
continue;
ereg($regex, $line, &$reg);
$entry["term"] = $reg[1];
$entry["dbcode"] = $reg[2];
$entry["dbname"] = $reg[3];
$entry["definition"] = $this->read_data();
$this->result[$i] = $entry;
}
}
}
function define($term, $db="*") {
$this->search($term, "exact", $db);
$this->close();
}
function match($term, $method="prefix", $db="*") {
$this->search($term, $method, $db);
$this->close();
}
function is_method($method) {
return $this->in_array($method, $this->valid_methods);
}
function clear_results() {
$this->numres = 0;
$this->result = array();
}
} // end of class DictQuery
?>
|