00001 <?php
00002 require_once('error.php');
00003 require_once('const.php');
00004 require_once('config.php');
00005
00014
00015 ### configuration section
00016
00017 # The result of a Z3950 query is delivered as an associative array
00018 # in GRS format. Unfortunately, GRS records are quite hard to understand,
00019 # which is why we translate them to a more readable format, see
00020 # grs_analyze().
00021 #
00022 # Here, we define a mapping from GRS keys to human readable
00023 # keys. Regular expressions can be used to match several GRS keys.
00024 # It is also permitted to map several GRS keys to the same human
00025 # readable key.
00026
00027 $grs_dict = array (
00028 "/\(3,440\).*\(3,a\)/" => "title",
00029 "/\(3,245\).*\(3,a\)/" => "title",
00030 "/\(3,245\).*\(3,b\)/" => "title",
00031 "/\(3,440\).*\(3,v\)/" => "volume",
00032 "/\(3,700\)\(3,1 \)\(3,a\)/" => "author",
00033 "/\(3,100\).*\(3,a\)/" => "author",
00034 "/\(3,260\).*\(3,a\)/" => "publisher",
00035 "/\(3,260\).*\(3,b\)/" => "publisher",
00036 "/\(3,260\).*\(3,c\)/" => "year",
00037 "/\(3,250\).*\(3,a\)/" => "edition",
00038 "/\(3,001\)\(3,@\)/" => "ppn",
00039 "/^\(3,900\)\(3, \)\(3,d\)$/" => "signature",
00040 # "/^\(3,856\)\(3,4 \)\(3,u\)$/" => "url",
00041 );
00042
00043 ### end of configuration
00044
00047
00048 function is_wildcard ($term) {
00049 return (preg_match('/[?*]\s*$/', $term) == 1 );
00050 }
00051
00054
00055 function normalize($term) {
00056
00057 setlocale(LC_CTYPE,'de_DE');
00058
00059 # strip whitespace
00060
00061 $term = preg_replace('/\s\s+/', ' ', $term);
00062 $term = trim($term);
00063
00064 # strip non-word, non-space characters, e.g. comma, brace, etc.
00065 $term = preg_replace('/[^\w\s\/_-]/', '', $term);
00066
00067 $term = strtolower($term);
00068
00069 return $term;
00070 }
00071
00107
00108 function build_z3950_query($search) {
00109
00110 $i = 0;
00111 $z_query = "";
00112
00113
00114 foreach ($search as $key => $term) {
00115
00116 if (empty($term)) {continue;}
00117
00118 switch($key) {
00119
00120 case "signature":
00121 $z_query .= '@or @attr 5=1 @attr 1=54 "';
00122 $z_query .= normalize($term);
00123 $z_query .= '" @attr 5=1 @attr 1=53 "';
00124 $z_query .= normalize($term);
00125 $z_query .= '" ';
00126
00127 $i++;
00128 break;
00129
00130 case "isbn":
00131
00132 $z_query .= '@attr 5=1 @attr 1=7 "';
00133 $z_query .= normalize($term);
00134 $z_query .= '" ';
00135
00136 $i++;
00137 break;
00138
00139 case "author":
00140 case "title":
00141
00142 foreach (split(' ', $term) as $word) {
00143
00144 if (empty($term)) {continue;}
00145
00146 $z_query .= (is_wildcard($word)) ?
00147 "@attr 5=1 " : "";
00148
00149 $z_query .= '@attr 1=1016 "';
00150 $z_query .= normalize($word);
00151 $z_query .= '" ';
00152 $i++;
00153 }
00154
00155 break;
00156 }
00157 }
00158
00159 while ($i > 1) {
00160 $z_query = "@and " . $z_query;
00161 $i--;
00162 }
00163
00164
00165 return $z_query;
00166 }
00167
00175
00176 function grs_analyze($grs) {
00177 global $grs_dict;
00178
00179 $ans = array();
00180
00181 foreach ($grs_dict as $key => $value ) {
00182 foreach ($grs as $rec) {
00183 if (preg_match($key, $rec[0])) {
00184
00185 $v = preg_replace("/[,\/ ]*$/","",$rec[1]);
00186
00187 # The PICA z39.50 server delivers
00188 # the book signature mingled together with
00189 # the book's location. We strip the
00190 # location - which is enclosed in exclamation
00191 # marks - from the final result.
00192
00193 if ($value == "signature") {
00194 $v = preg_replace("/![^!]*!/","",$v);
00195 }
00196
00197 $ans[$value] .= "$v ; ";
00198 }
00199 }
00200
00201 # get rid of several semicolons, colons, commas, etc. in a row
00202
00203 $ans[$value] = preg_replace("/;\s*;/",";",$ans[$value]);
00204 $ans[$value] = preg_replace("/:\s*;/",":",$ans[$value]);
00205 $ans[$value] = preg_replace("/\/\s*;/","/",$ans[$value]);
00206 $ans[$value] = preg_replace("/\.\s*;/",".",$ans[$value]);
00207 }
00208
00209
00210 $s = split(";", $ans[signature]);
00211 $ans[signature] = $s[0];
00212
00213 foreach ($ans as $key => $value) {
00214 $ans[$key] = trim($value, " ;" );
00215 }
00216
00217 return $ans;
00218 }
00219
00234
00235 function book_info($search) {
00236 global $z_host, $z_port, $z_auth, $z_db, $z_query;
00237
00238 # connect to z39.50 server
00239
00240 $z_url = "$z_host:$z_port/$z_db";
00241 $z_opts = array("user" => $z_user, "password" => $z_pass);
00242
00243 $z_handle = yaz_connect($z_url, $z_opts) or
00244 user_error(yaz_error($z_handle), E_USER_ERROR);
00245
00246 yaz_syntax($z_handle, "usmarc");
00247 yaz_range($z_handle, 1,100);
00248 yaz_element($z_handle, "F");
00249
00250 # build query, perform search
00251
00252 $z_query =build_z3950_query($search);
00253
00254
00255 yaz_search($z_handle, "rpn", $z_query);
00256
00257 yaz_wait() or
00258 user_error( yaz_error($z_handle), E_USER_ERROR);
00259
00260 $ans = array();
00261
00262 $i = 1;
00263
00264 # analyze response, build answer
00265
00266 while ( $z_record = yaz_record($z_handle,$i++, "array")) {
00267
00268 $a = grs_analyze($z_record);
00269 # $a['signature'] = $sig;
00270 $ans[] = $a;
00271
00272 }
00273
00274 yaz_close($z_handle);
00275
00276 return $ans;
00277 }
00278
00300
00301 ?>