r63774 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r63773‎ | r63774 | r63775 >
Date:16:26, 15 March 2010
Author:daniel
Status:deferred
Tags:
Comment:
restructured wikiword webapp codebase
Modified paths:
  • /trunk/WikiWord/WikiWord/src/main/php/api.php (deleted) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/common (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/common/wwclient.php (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/common/wwimages.php (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/common/wwtest.php (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/common/wwthesaurus.php (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/common/wwutils.php (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/common/wwwikis.php (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/maintenance (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/maintenance/build-concept-info.sh (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/maintenance/build-search-index.sh (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/maintenance/concept-info-local.sql (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/maintenance/concept-info.sql (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/maintenance/search-index-local.sql (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/maintenance/search-index.sql (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/search (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/search/wikipics.php (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/search/wikiword.php (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/web (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/web/api.php (added) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/wikipics.php (deleted) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/wikiword.php (deleted) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/wwclient.php (deleted) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/wwimages.php (deleted) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/wwtest.php (deleted) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/wwthesaurus.php (deleted) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/wwutils.php (deleted) (history)
  • /trunk/WikiWord/WikiWord/src/main/php/wwwikis.php (deleted) (history)

Diff [purge]

Index: trunk/WikiWord/WikiWord/src/main/php/wwclient.php
@@ -1,152 +0,0 @@
2 -<?php
3 -require_once( dirname( __FILE__ ) . "/wwutils.php" );
4 -
5 -class WWClient {
6 - var $api;
7 -
8 - function __construct( $api ) {
9 - $this->api = $api;
10 - }
11 -
12 - function query( $params ) {
13 - $url = $this->api . '?format=phps';
14 -
15 - foreach ( $params as $k => $v ) {
16 - if ($v===null) continue;
17 - if ($v===false) $v = "";
18 - if (is_array($v)) $v = implode("|", $v);
19 -
20 - $url .= '&';
21 - $url .= urlencode( $k );
22 - $url .= '=';
23 - $url .= urlencode( $v );
24 - }
25 -
26 - $data = file_get_contents( $url ); //TODO: CURL
27 - if ( !$data ) throw new Exception("failed to fetch data from $url");
28 -
29 - $data = unserialize($data);
30 - if ( !$data ) throw new Exception("failed to unserialize data from $url");
31 -
32 - if ( @$data['error'] ) throw new Exception("API returned error ".$data['error']['code'].": ".$data['error']['message']."; url: $url");
33 - return $data;
34 - }
35 -
36 - function getPagesForConcept( $id, $lang = null ) {
37 - $p = $this->getConceptInfo( $id, $lang );
38 - return $p['pages'];
39 - }
40 -
41 - /*
42 - function getLocalConcepts($id) { //NOTE: deprecated alias for backward compat
43 - return getPagesForConcept($id);
44 - }
45 -
46 - function getConcept( $id, $lang = null ) {
47 - $p = $this->getConceptProperties( $id, '', $lang );getConceptInfo
48 - return $p['pages'];
49 - }
50 -
51 - function getRelatedForConcept( $id, $lang = null ) {
52 - $p = $this->getConceptProperties( $id, 'related', $lang );
53 - return $p['related'];
54 - }
55 -
56 - function getBroaderForConcept( $id, $lang = null ) {
57 - $p = $this->getConceptProperties( $id, 'broader', $lang );
58 - return $p['broader'];
59 - }
60 -
61 - function getNarrowerForConcept( $id, $lang = null ) {
62 - $p = $this->getConceptProperties( $id, 'narrower', $lang );
63 - return $p['narrower'];
64 - }
65 -
66 - function getTermsForConcept( $id, $lang = null ) {
67 - $p = $this->getConceptProperties( $id, 'terms', $lang );
68 - return $p['terms'];
69 - }
70 -
71 - function getDefinitionForConcept( $id, $lang = null ) {
72 - $p = $this->getConceptProperties( $id, 'definition', $lang );
73 - return $p['definition'];
74 - }
75 -
76 - function getReferencesForConcept( $id, $lang = null ) {
77 - $p = $this->getConceptProperties( $id, 'links', $lang );
78 - return $p['references'];
79 - }
80 -
81 - function getLinksForConcept( $id, $lang = null ) {
82 - $p = $this->getConceptProperties( $id, 'links', $lang );
83 - return $p['links'];
84 - }
85 -
86 - function getScoresForConcept( $id, $lang = null ) {
87 - $p = $this->getConceptProperties( $id, 'scores', $lang );
88 - return $p['scores'];
89 - }*/
90 -
91 - function getConceptInfo( $id, $lang = null ) {
92 - $param = array(
93 - 'query' => 'info',
94 - 'gcid' => $id,
95 - 'lang' => $lang
96 - );
97 -
98 - $rs = $this->query( $param );
99 -
100 - if (!isset($rs['id'])) $rs['id'] = $id;
101 - if (!isset($rs['lang'])) $rs['lang'] = $lang;
102 -
103 - return $rs;
104 - }
105 -
106 - /*
107 - function getConceptProperties( $id, $props, $lang =$props null ) {
108 - $param = array(
109 - 'query' => 'properties',
110 - 'props' => ( is_array($props) ? join('|', $props) : $props ),
111 - 'gcid' => $id,
112 - );
113 -
114 - if ( $lang ) $param['lang'] = $lang;
115 -
116 - $rs = $this->query( $param );
117 -
118 - if (!isset($rs['id'])) $rs['id'] = $id;
119 - if (!isset($rs['lang'])) $rs['lang'] = $lang;
120 -
121 - return $rs;
122 - }*/
123 -
124 - function getConceptsForTerm( $qlang, $term, $languages, $norm = 1, $limit = 100 ) {
125 - if ( is_array( $languages ) ) $languages = implode('|', $languages);
126 -
127 - $param = array(
128 - 'query' => 'concepts',
129 - 'qlang' => $qlang,
130 - 'lang' => $languages,
131 - 'norm' => $norm,
132 - 'term' => $term,
133 - );
134 -
135 - $rs = $this->query( $param );
136 -
137 - return $rs['concepts'];
138 - }
139 -
140 - /*
141 - function getConceptsForPage( $lang, $page ) {
142 - $param = array(
143 - 'query' => 'concepts',
144 - 'lang' => $lang,
145 - 'page' => $page,
146 - );
147 -
148 - $rs = $this->query( $param );
149 -
150 - return $rs['concepts'];
151 - }
152 - */
153 -}
Index: trunk/WikiWord/WikiWord/src/main/php/wwtest.php
@@ -1,20 +0,0 @@
2 -<?php
3 -
4 -$IP = dirname(__FILE__);
5 -
6 -require_once("$IP/config.php");
7 -require_once("$IP/wwutils.php");
8 -
9 -$utils = new WWUtils();
10 -$utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
11 -
12 -$utils->debug = true;
13 -
14 -if (!isset($argv[1])) die("usage: wwtest <id>\n");
15 -
16 -$id = $argv[1];
17 -$max = @$argv[2];
18 -
19 -$images = $utils->getImagesAbout($id, $max);
20 -
21 -print_r($images);
\ No newline at end of file
Index: trunk/WikiWord/WikiWord/src/main/php/wikiword.php
@@ -1,481 +0,0 @@
2 -<?php
3 -
4 -$IP = dirname(__FILE__);
5 -
6 -require_once("$IP/config.php");
7 -require_once("$IP/wwimages.php");
8 -
9 -if ($wwAPI) require_once("$IP/wwclient.php");
10 -else require_once("$IP/wwthesaurus.php");
11 -
12 -function printLocalConceptList($lang, $concepts) {
13 - global $utils;
14 - if (is_string($concepts)) $concepts = $utils->unpickle($concepts, $lang, true, false, true);
15 -
16 - ?>
17 - <ul class="terselist">
18 - <?php
19 - foreach ($concepts as $c) {
20 - ?><li><?php
21 - printLocalConceptLink($lang, $c);
22 - ?></li><?php
23 - }
24 - ?>
25 - </ul>
26 - <?php
27 -}
28 -
29 -function printConceptImageList($concept, $class = "terselist") {
30 - global $utils, $wwThumbSize, $wwMaxPreviewImages;
31 -
32 - if (is_array($concept) && !isset($concept['id']) && isset($concept[0])) $images = $concept; #XXX: HACK
33 - else $images = $utils->getImagesAbout($concept, $wwMaxPreviewImages);
34 -
35 - ?>
36 - <ul class="<?php print $class; ?>">
37 - <?php
38 - foreach ($images as $img) {
39 - ?><li><?php
40 - print $utils->getThumbnailHTML($img, $wwThumbSize, $wwThumbSize);
41 - ?></li><?php
42 - }
43 - ?>
44 - </ul>
45 - <?php
46 -}
47 -
48 -function printLocalConceptLink($lang, $row) {
49 - global $wwSelf, $images;
50 -
51 - $row = normalizeConceptRow($lang, $row);
52 -
53 - extract($row);
54 -
55 - if (!isset($weight) && isset($freq)) $weight = $freq;
56 - if (!isset($weight) && isset($conf)) $weight = $conf;
57 - if (!isset($concept_name) && isset($name)) $concept_name = $name;
58 - if (!isset($concept_name)) $concept_name = NULL;
59 - if (!isset($concept) && isset($id)) $concept = $id;
60 - if (!isset($concept)) $concept = NULL;
61 -
62 - if ($lang == 'commons') $domain = 'commons.wikimedia.org';
63 - else $domain = "$lang.wikipedia.org";
64 -
65 - $wu = $concept_name ? "http://$domain/wiki/" . urlencode($concept_name) : NULL;
66 - $cu = "$wwSelf?id=" . urlencode($concept) . "&lang=" . urlencode($lang);
67 -
68 - if ($images) $cu .= "&images=1";
69 -
70 - ?>
71 - <li>
72 - <?php if ($concept_name) { ?>
73 - <a href="<?php print htmlspecialchars($cu); ?>"><?php print htmlspecialchars($concept_name); ?></a>
74 - <?php } ?>
75 - <?php if ($concept) { ?>
76 - (<a href="<?php print htmlspecialchars($wu); ?>" title="<?php print htmlspecialchars($concept_name); ?>">wiki page</a>)
77 - <?php } ?>
78 - </li>
79 - <?php
80 -}
81 -
82 -function printTermList($lang, $terms) {
83 - global $utils;
84 - if (is_string($terms)) $terms = $utils->unpickle($terms, $lang);
85 -
86 - ?>
87 - <ul class="terselist">
88 - <?php
89 - foreach ($terms as $t) {
90 - printTermLink($lang, $terms);
91 - }
92 - ?>
93 - </ul>
94 - <?php
95 -}
96 -
97 -function printTermLink($lang, $row) {
98 - global $wwSelf;
99 -
100 - extract($row);
101 -
102 - if (!isset($weight) && isset($freq)) $weight = $freq;
103 - if (!isset($weight) && isset($conf)) $weight = $conf;
104 - if (!isset($term_text) && isset($term)) $term_text = $term;
105 - if (!isset($term_text) && isset($text)) $term_text = $text;
106 - if (!isset($term_text) && isset($name)) $term_text = $name;
107 - if (!isset($term_text) && isset($value)) $term_text = $value;
108 -
109 - $tu = "$wwSelf?term=" . urlencode($term_text) . "&lang=" . urlencode($lang);
110 -
111 - ?>
112 - <li>
113 - <a href="<?php print htmlspecialchars($tu); ?>"><?php print htmlspecialchars($term_text); ?></a>
114 - </li>
115 - <?php
116 -}
117 -
118 -function normalizeConceptRow($lang, $row) {
119 - global $wwSelf;
120 -
121 - #FIXME: handle complex concept records!
122 -
123 - if (!$row) return $row;
124 -
125 - if (!isset($row['lang'])) $row['lang'] = $lang;
126 - if (!isset($row['weight']) && isset($row['freq'])) $row['weight'] = $row['freq'];
127 - if (!isset($row['weight']) && isset($row['conf'])) $row['weight'] = $row['conf'];
128 - if (!empty($row['local_concept_name'])) $row['concept_name'] = $row['local_concept_name'];
129 - if (!isset($row['concept_name']) && isset($row['name'])) $row['concept_name'] = $row['name'];
130 - if (!isset($row['concept_name']) && isset($row['global_concept_name'])) $row['concept_name'] = $row['global_concept_name'];
131 - if (!isset($row['reference_id']) && isset($row['global_id'])) $row['reference_id'] = $row['global_id'];
132 - if (!isset($row['reference_id']) && isset($row['global_concept'])) $row['reference_id'] = $row['global_concept'];
133 - if (!isset($row['reference_id']) && isset($row['concept'])) $row['reference_id'] = $row['concept'];
134 - if (!isset($row['reference_id']) && isset($row['id'])) $row['reference_id'] = $row['id'];
135 - if (!empty($row['definition']) && is_array($row['definition'])) $row['definition'] = $row['definition'][$lang];
136 -
137 - #print "<pre>";
138 - #print_r($row);
139 - #print "</pre>";
140 -
141 - $row['wu'] = "http://$lang.wikipedia.org/wiki/" . urlencode($row['concept_name']);
142 - #$row['cu'] = "$wwSelf?id=" . urlencode($row['concept']) . "&lang=" . urlencode($lang);
143 - $row['cu'] = "$wwSelf?id=" . urlencode($row['reference_id']) . "&lang=" . urlencode($lang);
144 - $row['gu'] = "$wwSelf?id=" . urlencode($row['reference_id']) . "&images=g";
145 -
146 - if (!isset($row['weight']) || !$row['weight']) {
147 - $row['wclass'] = "unknown";
148 - $row['weight'] = NULL;
149 - }
150 - else if ($row['weight']>1000) $row['wclass'] = "huge";
151 - else if ($row['weight']>100) $row['wclass'] = "big";
152 - else if ($row['weight']>10) $row['wclass'] = "normal";
153 - else if ($row['weight']>2) $row['wclass'] = "some";
154 - else $row['wclass'] = "little";
155 -
156 - return $row;
157 -}
158 -
159 -function printLocalConcept($a_lang, $a_row, $b_lang, $b_row, $pos = 0, $terse = true) {
160 - global $wwSelf, $images, $utils;
161 - global $wwMaxPreviewImages, $wwMaxGalleryImages;
162 -
163 - $a_row = normalizeConceptRow($a_lang, $a_row);
164 - $b_row = normalizeConceptRow($b_lang, $b_row);
165 -
166 - if ($a_lang && $a_row) extract($a_row, EXTR_PREFIX_ALL, "a");
167 - if ($b_lang && $b_row) extract($b_row, EXTR_PREFIX_ALL, "b");
168 -
169 - ?>
170 - <tr class="row_item">
171 - <td class="cell_weight <?php print "weight_$a_wclass"; ?>"><?php print htmlspecialchars($a_weight); ?></td>
172 - <td colspan="3" class="cell_name <?php print "weight_$a_wclass"; ?>">
173 - <h3>
174 - <a href="<?php print htmlspecialchars($a_cu); ?>"><?php print htmlspecialchars($a_concept_name); ?></a>
175 - <span class="conceptref">(<a href="<?php print htmlspecialchars($a_wu); ?>" title="<?php print htmlspecialchars($a_concept_name); ?>">wiki page</a>)</span>
176 - </h3>
177 - </td>
178 - <?php if ($b_row) { ?>
179 - <td colspan="3" class="cell_name <?php print "weight_$b_wclass"; ?>">
180 - <h3>
181 - <a href="<?php print htmlspecialchars($b_cu); ?>"><?php print htmlspecialchars($b_concept_name); ?></a>
182 - <span class="conceptref">(<a href="<?php print htmlspecialchars($b_wu); ?>" title="<?php print htmlspecialchars($b_concept_name); ?>">wiki page</a>)</span>
183 - </h3>
184 - </td>
185 - <?php } ?>
186 - </tr>
187 -
188 - <?php if (isset($a_definition) && !empty($a_definition)) { ?>
189 - <tr class="row_def">
190 - <td></td>
191 - <td class="cell_label">Definition:</td>
192 - <td colspan="2"><?php print htmlspecialchars($a_definition); ?></td>
193 - <?php if ($b_row) { ?>
194 - <td class="cell_label">Definition:</td>
195 - <td colspan="2"><?php print htmlspecialchars($b_definition); ?></td>
196 - <?php } ?>
197 - </tr>
198 - <?php } ?>
199 -
200 - <?php if (isset($a_terms) && !empty($a_terms)) { ?>
201 - <tr class="row_details row_terms">
202 - <td></td>
203 - <td class="cell_label">Terms:</td>
204 - <td class="cell_terms" colspan="2"><?php printTermList($a_lang, $a_terms); ?></td>
205 - <?php if ($b_row) { ?>
206 - <td class="cell_label">Terms:</td>
207 - <td class="cell_terms" colspan="2"><?php printTermList($b_lang, $b_terms); ?></td>
208 - <?php } ?>
209 - </tr>
210 - <?php } ?>
211 -
212 - <?php if ($images) { ?>
213 - <tr class="row_details row_images">
214 - <td></td>
215 - <td class="cell_label">Images:</td>
216 - <td class="cell_broader" colspan="<?php $b_row ? 5 : 2 ?>">
217 - <?php
218 - $gallery = $utils->getImagesAbout($a_reference_id, $terse ? $wwMaxPreviewImages : $wwMaxGalleryImages );
219 - $c = printConceptImageList( $gallery, $terse ? "terselist" : "gallery" );
220 - ?>
221 - </td>
222 - </tr>
223 - <?php } ?>
224 -
225 - <?php if (isset($a_similar) && !empty($a_similar)) { ?>
226 - <tr class="row_details row_similar">
227 - <td></td>
228 - <td class="cell_label">Similar:</td>
229 - <td class="cell_similar" colspan="2"><?php printLocalConceptList($a_lang, $a_similar); ?></td>
230 - <?php if ($b_row) { ?>
231 - <td class="cell_label">Similar:</td>
232 - <td class="cell_similar" colspan="2"><?php printLocalConceptList($b_lang, $b_similar); ?></td>
233 - <?php } ?>
234 - </tr>
235 - <?php } ?>
236 -
237 - <?php if (isset($a_related) && !empty($a_related)) { ?>
238 - <tr class="row_details row_related">
239 - <td></td>
240 - <td class="cell_label">Related:</td>
241 - <td class="cell_related" colspan="2"><?php printLocalConceptList($a_lang, $a_related); ?></td>
242 - <?php if ($b_row) { ?>
243 - <td class="cell_label">Related:</td>
244 - <td class="cell_related" colspan="2"><?php printLocalConceptList($b_lang, $b_related); ?></td>
245 - <?php } ?>
246 - </tr>
247 - <?php } ?>
248 -
249 - <?php if (isset($a_narrower) && !empty($a_narrower)) { ?>
250 - <tr class="row_details row_narrower">
251 - <td></td>
252 - <td class="cell_label">Narrower:</td>
253 - <td class="cell_narrower" colspan="2"><?php printLocalConceptList($a_lang, $a_narrower); ?></td>
254 - <?php if ($b_row) { ?>
255 - <td class="cell_label">Narrower:</td>
256 - <td class="cell_narrower" colspan="2"><?php printLocalConceptList($b_lang, $b_narrower); ?></td>
257 - <?php } ?>
258 - </tr>
259 - <?php } ?>
260 -
261 - <?php if (isset($a_broader) && !empty($a_broader)) { ?>
262 - <tr class="row_details row_broader">
263 - <td></td>
264 - <td class="cell_label">Broader:</td>
265 - <td class="cell_broader" colspan="2"><?php printLocalConceptList($a_lang, $a_broader); ?></td>
266 - <?php if ($b_row) { ?>
267 - <td class="cell_label">Broader:</td>
268 - <td class="cell_broader" colspan="2"><?php printLocalConceptList($b_lang, $b_broader); ?></td>
269 - <?php } ?>
270 - </tr>
271 - <?php } ?>
272 -
273 - <?php
274 - if (isset($a_weight) && $a_weight && $a_weight<2 && $pos>=3) return false;
275 - else return true;
276 -}
277 -
278 -$concept = @$_REQUEST['id'];
279 -$term = @$_REQUEST['term'];
280 -$lang = @$_REQUEST['lang'];
281 -$tolang = @$_REQUEST['tolang'];
282 -$images = (@$_REQUEST['images'] || $wwImageSearch === true ) && !($wwImageSearch === false);
283 -
284 -if (!isset($_REQUEST['translate'])) $tolang = NULL;
285 -if ($lang == $tolang) $tolang = NULL;
286 -
287 -if (!isset($wwSelf)) $wwSelf = @$_SERVER["PHP_SELF"];
288 -
289 -$error = NULL;
290 -
291 -if ($lang && !isset($wwLanguages[$lang])) {
292 - $lang = NULL;
293 - $error = "bad language code: $lang";
294 -}
295 -
296 -if ($wwAPI) $thesaurus = new WWClient($wwAPI);
297 -else {
298 - $thesaurus = new WWThesaurus();
299 - $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
300 -}
301 -
302 -$utils = new WWImages( $thesaurus );
303 -if ( !$utils->db ) $utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
304 -
305 -if (@$_REQUEST['debug']) $utils->debug = true;
306 -
307 -$limit = 20;
308 -
309 -$result = NULL;
310 -
311 -if (!$error) {
312 - try {
313 - if ($lang && $concept) {
314 - $result = $thesaurus->getConceptInfo($concept, $lang);
315 - if ( $result ) $result = array( $result ); //hack
316 - } else if ($lang && $term) {
317 - $result = $thesaurus->getConceptsForTerm($lang, $term, $limit);
318 - }
319 - } catch (Exception $e) {
320 - $error = $e->getMessage();
321 - }
322 -}
323 -
324 -
325 -?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
326 -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
327 -<head>
328 - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
329 - <title>WikiWord Navigator</title>
330 -
331 - <style type="text/css">
332 - body { font-family: verdana, helvetica, arial, sans-serif; }
333 - td { text-align: left; vertical-align: top; }
334 - th { text-align: left; vertical-align: top; font-weight:bold; }
335 - .error { color: red; font-weight: bold; }
336 - .weight_huge { font-size: 140%; font-weight:bold; }
337 - .weight_big { font-size: 120%; font-weight:bold; }
338 - .weight_normal { font-size: 110%; font-weight:bold; }
339 - .weight_some { font-size: 100%; font-weight:bold; }
340 - .weight_little { font-size: 90%; font-weight:bold; }
341 - .weight_unknown { font-size: 100%; font-weight:bold; }
342 - .row_def td { font-size: 80%; font-style:italic; }
343 - .row_details td { font-size: 80%; }
344 - .cell_weight { text-align: right; }
345 - .cell_label { text-align: right; }
346 - .header { text-align: left; }
347 - .inputform { text-align: center; margin:1ex auto; padding:1ex; width:80%; border:1px solid #666666; background-color:#DDDDDD; }
348 - .footer { font-size:80%; text-align: center; border-top: 1px solid #666666; }
349 - .note { font-size:80%; }
350 - .terselist, .terselist li { display: inline; margin:0; padding:0; }
351 - .terselist li { display: inline; }
352 - .terselist li:before { content:" - " }
353 - .terselist li:first-child:before { content:"" }
354 -
355 - .gallery li { display: inline; padding:0.5ex; margin:0.5ex; }
356 - </style>
357 -</head>
358 -<body>
359 - <div class="header">
360 - <h1>WikiWord Navigator</h1>
361 - <p>Experimental semantic navigator and thesaurus interface for Wikipedia.</p>
362 - <p>The WikiWord Navigator was created as part of the WikiWord project run by <a href="http://wikimedia.de">Wikimedia Deutschland e.V.</a>.
363 - It is based on a <a href="http://brightbyte.de/page/WikiWord">diploma thesis</a> by Daniel Kinzler, and runs on the <a href="http://toolserver.org/">Wikimedia Toolserver</a>. WikiWord is an ongoing research project. Please contact <a href="http://brightbyte.de/page/Special:Contact">Daniel Kinzler</a> for more information.</p>
364 - </div>
365 -
366 - <div class="inputform" >
367 - <form name="search" action="<?php print $wwSelf; ?>">
368 - <table border="0" class="inputgrid">
369 - <tr>
370 - <td>
371 - <label for="term">Term: </label><input type="text" name="term" id="term" size="24" value="<?php print htmlspecialchars($term); ?>"/>
372 - </td>
373 - <td>
374 - <label for="term" style="display:none">Language: </label>
375 - <?php WWUtils::printSelector("lang", $wwLanguages, $lang) ?>
376 - </td>
377 - <td>
378 - <input type="submit" name="go" value="go"/>
379 - </td>
380 - <?php if ($wwImageSearch === null) { ?>
381 - <td>
382 - <label for="images">Images: </label>
383 - <input type="checkbox" name="images" value="Images" <?php print $images ? " checked=\"checked\"" : ""?>/>
384 - </td>
385 - <?php } ?>
386 - </tr>
387 - <?php if ($wwAllowTranslate) { ?>
388 - <tr>
389 - <td>
390 - &nbsp;
391 - </td>
392 - <td>
393 - <label for="term" style="display:none">Translate: </label>
394 - <?php WWUtils::printSelector("tolang", $wwLanguages, @$_REQUEST['tolang']) ?>
395 - </td>
396 - <td>
397 - <input type="submit" name="translate" value="translate"/>
398 - </td>
399 - </tr>
400 - <?php } ?>
401 - </table>
402 - <p class="note">Note: this is a thesaurus lookup, not a full text search. Only exact matches are considered, matching is case-sensitive.</p>
403 - </form>
404 - </div>
405 -<?php
406 -if ($error) {
407 - print "<p class=\"error\">".htmlspecialchars($error)."</p>";
408 -}
409 -?>
410 -
411 -<?php
412 -if ($result && $concept) {
413 - foreach ( $result as $row ) {
414 - if (@$row['id']) $id = $row['id'];
415 - else if (@$row['concept']) $id = $row['concept'];
416 - else $id = "concept";
417 -
418 -?>
419 - <div id="<?php print htmlspecialchars("concept-$id")?>">
420 -
421 - <table border="0" class="results">
422 - <?php
423 - if ($lang) {
424 - $continue= printLocalConcept($lang, $row, NULL, NULL, 0, false);
425 - }
426 - //else $continue= printGlobalConcept($lang, $row, $count);
427 -
428 - if (!$continue) break;
429 - ?>
430 - </table>
431 - </div>
432 -
433 -<?php
434 - } #concept loop
435 -} else if ($result && $term) {
436 - if ($tolang) $title = "$lang: $term -> $tolang";
437 - else if ($term) $title = "$lang: $term";
438 -?>
439 - <h2><?php print htmlspecialchars($title); ?></h2>
440 - <table border="0" class="results">
441 - <?php
442 - $count = 0;
443 - foreach ( $result as $row ) {
444 - $count += 1;
445 -
446 - if ($lang) {
447 - $show_single = true;
448 -
449 - if ($tolang && isset($row['global_concept'])) {
450 - $toresult = $utils->queryConceptInfo($row['global_concept'], $tolang);
451 - while ($torow = mysql_fetch_assoc($toresult)) {
452 - $continue= printLocalConcept($lang, $row, $tolang, $torow, $count, true);
453 - $show_single = false;
454 - }
455 - mysql_free_result($toresult);
456 - }
457 -
458 - if ($show_single) {
459 - $continue= printLocalConcept($lang, $row, NULL, NULL, $count, true);
460 - }
461 - }
462 - //else $continue= printGlobalConcept($lang, $row, $count);
463 -
464 - if (!$continue) break;
465 - }
466 - ?>
467 - </table>
468 -
469 - <p>Found <?php print $count; ?> items.</p>
470 -
471 -<?php
472 -}
473 -?>
474 -
475 -<p class="footer">
476 -The WikiWord Navigator is part of the <a href="http://wikimedia.de">Wikimedia</a> project <a href="http://brightbyte.de/page/WikiWord">WikiWord</a>
477 -<p>
478 -</body>
479 -</html>
480 -<?php
481 -$utils->close();
482 -?>
\ No newline at end of file
Index: trunk/WikiWord/WikiWord/src/main/php/wwthesaurus.php
@@ -1,498 +0,0 @@
2 -<?php
3 -require_once(dirname(__FILE__)."/wwutils.php");
4 -
5 - /** Unknown type, SHOULD not occurr in final data. MAY be used for
6 - * resources that are referenced but where not available for analysis,
7 - * or have not yet been analyzed.
8 - **/
9 - define('WW_RC_TYPE_UNKNOWN', 0);
10 -
11 - /**
12 - * A "real" page, describing a concept.
13 - */
14 - define('WW_RC_TYPE_ARTICLE', 10);
15 -
16 - /**
17 - * This page is a supplemental part of an article, typically a transcluded
18 - * subpage or simmilar.
19 - */
20 - define('WW_RC_TYPE_SUPPLEMENT', 15);
21 -
22 -
23 - /**
24 - * A page solely defining a redirect/alias for another page
25 - */
26 - define('WW_RC_TYPE_REDIRECT', 20);
27 -
28 - /**
29 - * A disambuguation page, listing different meanings for the page title,
30 - * each linking to a article page.
31 - */
32 - define('WW_RC_TYPE_DISAMBIG', 30);
33 -
34 - /**
35 - * A page that contains a list of concepts that share some common property or quality,
36 - * usually each linking to a page describing that concept.
37 - */
38 - define('WW_RC_TYPE_LIST', 40);
39 -
40 - /**
41 - * A category page.
42 - */
43 - define('WW_RC_TYPE_CATEGORY', 50);
44 -
45 - /**
46 - * This page does not contain relevant information for WikiWord
47 - */
48 - define('WW_RC_TYPE_OTHER', 99);
49 -
50 - /**
51 - * A page that is broken in some way, or was marked as bad or disputed. Such pages
52 - * SHOULD generally be treated as if theys didn't exist.
53 - */
54 - define('WW_RC_TYPE_BAD', 100);
55 -
56 - /**
57 - * A resource that is not a page by itself, but merely a section of a page. Sections
58 - * SHOULD always be part of a page of type ARTICLE, and are expected to descibe
59 - * a narrower concept than the "parent" page.
60 - */
61 - define('WW_RC_TYPE_SECTION', 200);
62 -
63 -
64 -class WWThesaurus extends WWUTils {
65 -
66 - function normalizeSearchString( $s, $norm = 1 ) {
67 - if ( $norm >= 1 ) $s = mb_strtolower($s, "utf-8");
68 - if ( $norm >= 1 ) $s = str_replace("-", "", $s);
69 -
70 - #TODO: 2: whitespace and punctuation
71 - #TODO: 3: translit
72 -
73 - return $s;
74 - }
75 -
76 - function queryConceptsForTerm($qlang, $term, $languages, $norm = 1, $limit = 100) {
77 - global $wwTablePrefix, $wwThesaurusDataset, $wwLanguages;
78 -
79 - if ( !$languages ) $languages = array_keys( $wwLanguages );
80 -
81 - $term = $this->normalizeSearchString($term, $norm);
82 -
83 - $sql = "SELECT I.*, S.score FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info as I"
84 - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_search_index as S ON I.concept = S.concept "
85 - . " WHERE term = " . $this->quote($term)
86 - . " AND I.lang IN " . $this->quoteSet($languages)
87 - . " AND S.lang = " . $this->quote($qlang)
88 - . " AND S.norm <= " . (int)$norm
89 - . " ORDER BY S.score DESC, S.concept "
90 - . " LIMIT " . (int)$limit;
91 -
92 - #FIXME: query-lang vs. output-languages!
93 -
94 - return $this->query($sql);
95 - }
96 -
97 - function getConceptsForTerm($qlang, $term, $languages, $norm = 1, $limit = 100) {
98 - $rs = $this->queryConceptsForTerm($qlang, $term, $languages);
99 - $list = WWUtils::slurpRows($rs);
100 - mysql_free_result($rs);
101 - return $this->buildConcepts($list);
102 - }
103 -
104 - function getPagesForConcept( $id, $lang = null ) {
105 - $p = $this->getConceptInfo( $id, $lang );
106 - return $p['pages'];
107 - }
108 -
109 - /*
110 - function queryConceptsForPage($lang, $page, $limit = 100) {
111 - global $wwTablePrefix, $wwThesaurusDataset;
112 -
113 - $page = trim($page);
114 -
115 - $sql = "SELECT O.global_concept as id, O.* FROM {$wwTablePrefix}_{$lang}_resource as R "
116 - . " JOIN {$wwTablePrefix}_{$lang}_about as A ON A.resource = R.id "
117 - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($lang) . "\" AND A.concept = O.local_concept "
118 - . " WHERE R.name = \"" . mysql_real_escape_string($page) . "\""
119 - . " LIMIT " . (int)$limit;
120 -
121 - return $this->query($sql);
122 - }
123 -
124 - function getConceptsForPage($lang, $page, $limit = 100) {
125 - $rs = $this->queryConceptsForPage($lang, $page);
126 - $list = WWUtils::slurpRows($rs);
127 - mysql_free_result($rs);
128 - return $list;
129 - }
130 -
131 - function queryLocalConcepts($id) {
132 - global $wwTablePrefix, $wwThesaurusDataset;
133 - $sql = "SELECT O.lang, O.local_concept_name from {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ";
134 - $sql .= " WHERE O.global_concept = " . (int)$id;
135 -
136 - return $this->query($sql);
137 - }
138 -
139 - function getLocalConcepts($id) { //NOTE: deprecated alias for backward compat
140 - return getPagesForConcept($id);
141 - } */
142 -
143 - /*
144 - function queryLocalConceptInfo($lang, $id) {
145 - global $wwTablePrefix, $wwThesaurusDataset;
146 -
147 - $sql = "SELECT O.*, C.*, F.*, definition FROM {$wwTablePrefix}_{$lang}_concept_info as F "
148 - . " JOIN {$wwTablePrefix}_{$lang}_concept as C ON F.concept = C.id "
149 - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($lang) . "\" AND F.concept = O.local_concept "
150 - . " LEFT JOIN {$wwTablePrefix}_{$lang}_definition as D ON F.concept = D.concept "
151 - . " WHERE O.local_concept = $id ";
152 -
153 - return $this->query($sql);
154 - }
155 -
156 - function queryConceptInfo($id, $lang) {
157 - global $wwTablePrefix, $wwThesaurusDataset;
158 -
159 - $sql = "SELECT O.*, C.*, F.*, definition FROM {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O "
160 - . " LEFT JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info as F ON O.global_concept = F.concept "
161 - . " LEFT JOIN {$wwTablePrefix}_{$lang}_concept as C ON O.local_concept = C.id "
162 - . " LEFT JOIN {$wwTablePrefix}_{$lang}_definition as D ON O.local_concept = D.concept "
163 - . " WHERE O.global_concept = $id AND O.lang = \"" . mysql_real_escape_string($lang) . "\" ";
164 -
165 - return $this->query($sql);
166 - }*/
167 -
168 - /*function getConceptInfo( $id, $lang = null ) {
169 - $result = $this->getConcept($id, $lang);
170 -
171 - $result['broader'] = $this->getBroaderForConcept($id);
172 - $result['narrower'] = $this->getNarrowerForConcept($id);
173 - $result['related'] = $this->getRelatedForConcept($id);
174 -
175 - if ( $lang ) {
176 - $d = $this->getDefinitionForConcept($id);
177 - $result['related'] = $d[$lang];
178 - }
179 -
180 - return $result;
181 - }*/
182 -
183 - /*
184 - function unpickle($s, $lang, $hasId=true, $hasName=true, $hasConf=true) {
185 - $ss = explode("\x1E", $s);
186 - $items = array();
187 -
188 - $fetchNames = false;
189 -
190 - foreach ($ss as $i) {
191 - $r = explode("\x1F", $i);
192 - $offs = -1;
193 -
194 - if ($hasId) $r['id'] = @$r[$offs += 1];
195 - if ($hasName) $r['name'] = @$r[$offs += 1];
196 - if ($hasConf) $r['conf'] = @$r[$offs += 1];
197 -
198 - if ($hasId && !isset($r['name']))
199 - $fetchNames = true;
200 -
201 - if ($hasId) $items[ $r['id'] ] = $r;
202 - else $items[] = $r;
203 - }
204 -
205 - if ($fetchNames) {
206 - $names = $this->fetchNames(array_keys($items), $lang);
207 -
208 - $keys = array_keys($items);
209 - foreach ($keys as $k) {
210 - $id = $items[$k]['id'];
211 - $items[$k]['name'] = $names[$id];
212 - }
213 - }
214 -
215 - return $items;
216 - }
217 -
218 - function fetchNames($ids, $lang) {
219 - global $wwTablePrefix, $wwThesaurusDataset;
220 -
221 - $names = array();
222 - if (!$ids) return $names;
223 -
224 - $set = NULL;
225 - foreach ($ids as $id) {
226 - if ($set===NULL) $set = "";
227 - else $set .= ", ";
228 - $set .= $id;
229 - }
230 -
231 - $sql = "select global_concept as id, local_concept_name as name from {$wwTablePrefix}_{$wwThesaurusDataset}_origin ";
232 - $sql .= "where global_concept in ($set) and lang = \"" . mysql_real_escape_string($lang) . "\" ";
233 -
234 - $res = $this->query($sql);
235 -
236 - while ($row = mysql_fetch_assoc($res)) {
237 - $id = $row['id'];
238 - $names[$id] = $row['name'];
239 - }
240 -
241 - mysql_free_result($res);
242 -
243 - return $names;
244 - }
245 - */
246 -
247 - function splitPages( $s ) {
248 - $pp = explode("|", $s);
249 -
250 - $pages = array();
251 - foreach ($pp as $p) {
252 - list($t, $n) = explode(":", $p, 2);
253 - $pages[$n] = (int)$t;
254 - }
255 -
256 - return $pages;
257 - }
258 -
259 - function splitConcepts( $s ) {
260 - $ss = explode("|", $s);
261 -
262 - $concepts = array();
263 - foreach ($ss as $p) {
264 - list($id, $n) = explode(":", $p, 2);
265 - $id = (int)$id;
266 - $concepts[$id] = $n;
267 - }
268 -
269 - return $concepts;
270 - }
271 -
272 - /////////////////////////////////////////////////////////
273 - function getConceptInfo( $id, $lang = null, $fields = null ) {
274 - global $wwTablePrefix, $wwThesaurusDataset;
275 -
276 - #TODO: concept cache!
277 -
278 - if ( $fields && is_array($fields)) $fields = implode(", ", $fields);
279 - if ( !$fields ) $fields = "*";
280 -
281 - #TODO: scores, concept-type, ...
282 -
283 - $sql = "SELECT $fields FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info "
284 - . " WHERE concept = ".(int)$id;
285 -
286 - if ($lang) {
287 - if ( is_array($lang) ) $sql .= " AND lang IN " . $this->quoteSet($lang);
288 - else $sql .= " AND lang = " . $this->quote($lang);
289 - }
290 -
291 - $r = $this->getRows($sql);
292 - if (!$r) return false;
293 -
294 - return $this->buildConcept($r);
295 - }
296 -
297 - function buildConcepts($rows) {
298 - $concepts = array();
299 - $buff = array();
300 - $id = null;
301 - foreach($rows as $row) {
302 - if ( $id !== null && $id != $row['concept'] ) {
303 - if ($buff) {
304 - $concepts[$id] = $this->buildConcept($buff);
305 - $buff = array();
306 - }
307 -
308 - $id = null;
309 - $score = null;
310 - }
311 -
312 - if ($id === null) {
313 - $id = (int)$row['concept'];
314 - }
315 -
316 - $buff[] = $row;
317 - }
318 -
319 - usort($concepts, array('WWThesaurus', 'byScore'));
320 - return $concepts;
321 - }
322 -
323 - function byScore( $a, $b ) {
324 - if ( isset($a['score']) && isset($b['score']) ) return $b['score'] - $a['score'];
325 - if ( isset($a['conf']) && isset($b['conf']) ) return $b['conf'] - $a['conf'];
326 - if ( isset($a['freq']) && isset($b['freq']) ) return $b['freq'] - $a['freq'];
327 - if ( isset($a['id']) && isset($b['id']) ) return $a['id'] - $b['id'];
328 - return 0;
329 - }
330 -
331 - function buildConcept($rows) {
332 - $concept = array();
333 - $concept["languages"] = array();
334 -
335 - $broader = array();
336 - $narrower = array();
337 - $similar = array();
338 - $related = array();
339 -
340 - foreach ($rows as $row) {
341 - if (!isset($concept["id"]) && isset($row["concept"])) $concept["id"] = (int)$row["concept"];
342 - if (!isset($concept["score"]) && isset($row["score"])) $concept["score"] = (int)$row["score"];
343 -
344 - $lang = $row["lang"];
345 - $concept["languages"][] = $lang;
346 -
347 - #TODO: scores, concept-type, ...
348 -
349 - if (@$row["name"] !== null) $concept["name"][$lang] = $row["name"];
350 - if (@$row["definition"] !== null) $concept["definition"][$lang] = $row["definition"];
351 - if (@$row["pages"] !== null) $concept["pages"][$lang] = $this->splitPages($row["pages"]);
352 -
353 - if (@$row["broader"] !== null) $broader[$lang] = $this->splitConcepts($row["broader"]);
354 - if (@$row["narrower"] !== null) $narrower[$lang] = $this->splitConcepts($row["narrower"]);
355 - if (@$row["similar"] !== null) $similar[$lang] = $this->splitConcepts($row["similar"]);
356 - if (@$row["related"] !== null) $related[$lang] = $this->splitConcepts($row["related"]);
357 - }
358 -
359 - $concept["broader"] = $this->mogrifyLocalInfo($broader);
360 - $concept["narrower"] = $this->mogrifyLocalInfo($narrower);
361 - $concept["similar"] = $this->mogrifyLocalInfo($similar);
362 - $concept["related"] = $this->mogrifyLocalInfo($related);
363 -
364 - return $concept;
365 - }
366 -
367 - function mogrifyLocalInfo( $byLanguage ) {
368 - $byId = array();
369 -
370 - foreach ( $byLanguage as $lang => $items ) {
371 - foreach ( $items as $id => $name ) {
372 - $byId[$id][$lang] = $name;
373 - }
374 - }
375 -
376 - return $byId;
377 - }
378 -
379 - /*
380 - function getConcept( $id, $lang = null, $limit = 100 ) {
381 - return $this->getConceptInfo($id, $lang);
382 - }
383 -
384 - function getRelatedForConcept( $id, $lang = null, $limit = 100 ) {
385 - $concept = $this->getConceptInfo($id, $lang, "lang, related");
386 - if (!$concept) return false;
387 - else if ($lang) return $concept["related"][$lang];
388 - else return $concept["related"];
389 - }
390 -
391 - function getBroaderForConcept( $id, $lang = null, $limit = 100 ) {
392 - $concept = $this->getConceptInfo($id, $lang, "lang, broader");
393 - if (!$concept) return false;
394 - else if ($lang) return $concept["broader"][$lang];
395 - else return $concept["broader"];
396 - }
397 -
398 - function getNarrowerForConcept( $id, $lang = null, $limit = 100 ) {
399 - $concept = $this->getConceptInfo($id, $lang, "lang, narrower");
400 - if (!$concept) return false;
401 - else if ($lang) return $concept["narrower"][$lang];
402 - else return $concept["narrower"];
403 - }
404 -
405 - function getPagesForConcept( $id, $lang = null, $limit = 100 ) {
406 - if (!$lang) return false;
407 -
408 - $concept = $this->getConceptInfo($id, $lang, "lang, pages");
409 - if (!$concept) return false;
410 - else if ($lang) return array_keys( $concept["pages"][$lang] );
411 - }
412 -
413 - function getNamesForConcept( $id, $lang = null ) {
414 - $concept = $this->getConceptInfo($id, $lang, "lang, name");
415 - if (!$concept) return false;
416 -
417 - $result = array();
418 - foreach ($concept["languages"] as $ll) {
419 - if (@$concept["name@$ll"])
420 - $result[$ll] = $concept["name@$ll"];
421 - }
422 -
423 - return $result;
424 - }
425 -
426 - function getDefinitionForConcept( $id, $lang = null, $limit = 100 ) {
427 - $concept = $this->getConceptInfo($id, $lang, "lang, definition");
428 - if (!$concept) return false;
429 -
430 - $result = array();
431 - foreach ($concept["languages"] as $ll) {
432 - if (@$concept["definition@$ll"])
433 - $result[$ll] = $concept["definition@$ll"];
434 - }
435 -
436 - return $result;
437 - }*/
438 -
439 - function getTermsForConcept( $id, $lang = null, $limit = 100 ) {
440 - global $wwTablePrefix, $wwThesaurusDataset, $wwLanguages;
441 -
442 - if ( !$lang ) $lang = array_keys( $wwLanguages );
443 - if ( !is_array($lang) ) $lang = preg_split('![\\s,;|/:]\\s*!', $lang);
444 - $result = array();
445 -
446 - foreach ($lang as $ll) {
447 - $sql = "SELECT M.term_text FROM {$wwTablePrefix}_{$ll}_meaning as M"
448 - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($ll) . "\" AND M.concept = O.local_concept "
449 - . " WHERE O.global_concept = " . (int)$id
450 - . " ORDER BY freq DESC "
451 - . " LIMIT " . (int)$limit;
452 -
453 - $terms = $this->getList($sql, "term_text");
454 - if ( $terms === false || $terms === null ) return false;
455 - if ( !$terms ) continue;
456 -
457 - $result[$ll] = $terms;
458 - }
459 -
460 - return $result;
461 - }
462 -
463 - /*
464 - function getLinksForConcept( $id, $lang = null, $limit = 100 ) {
465 - global $wwTablePrefix, $wwThesaurusDataset;
466 -
467 - $sql = "SELECT C.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept as C "
468 - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_link as L ON L.target = C.id "
469 - . " WHERE L.anchor = ".(int)$id
470 - . " LIMIT " . (int)$limit;
471 -
472 - return $this->getRows($sql);
473 - }
474 -
475 - function getReferencesForConcept( $id, $lang = null, $limit = 100 ) {
476 - global $wwTablePrefix, $wwThesaurusDataset;
477 -
478 - $sql = "SELECT C.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept as C "
479 - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_link as L ON L.anchor = C.id "
480 - . " WHERE L.target = ".(int)$id
481 - . " LIMIT " . (int)$limit;
482 -
483 - return $this->getRows($sql);
484 - }
485 -
486 - function getScoresForConcept( $id, $lang = null ) {
487 - global $wwTablePrefix, $wwThesaurusDataset;
488 -
489 - $sql = "SELECT S.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_stats as S "
490 - . " WHERE S.concept = ".(int)$id
491 - ;
492 -
493 - $r = $this->getRows($sql);
494 - if ( !$r ) return false;
495 -
496 - return $r;
497 - }*/
498 -
499 -}
Index: trunk/WikiWord/WikiWord/src/main/php/wwwikis.php
@@ -1,72 +0,0 @@
2 -<?php
3 -require_once(dirname(__FILE__)."/wwutils.php");
4 -
5 -if (!defined('NS_IMAGE'))
6 - define('NS_IMAGE', 6);
7 -
8 -if (!defined('NS_TEMPLATE'))
9 - define('NS_TEMPLATE', 10);
10 -
11 -
12 -class WWWikis extends WWUtils {
13 - var $wikidbs = array();
14 -
15 - function getWikiTableName($lang, $table) {
16 - global $wwWikitableNamePattern, $wwCommonsTablePrefix;
17 -
18 - if ( $lang == "commons" && $wwCommonsTablePrefix ) return "$wwCommonsTablePrefix$table";
19 -
20 - if ($wwWikitableNamePattern) {
21 - return str_replace(array('{lang}', '{name}'), array($lang, $table), $wwWikitableNamePattern);
22 - }
23 -
24 - return $table;
25 - }
26 -
27 - function getWikiInfo($lang) {
28 - global $wwWikiInfoTable, $wwWikiDbName, $wwWikiServerName, $wwCommonsServerName;
29 -
30 - $db = str_replace('{lang}', $lang, $wwWikiDbName);
31 -
32 - $dbname = "{$lang}wiki_p";
33 - $sql = "select * from $wwWikiInfoTable ";
34 - $sql .= " where dbname = " . $this->quote("$db");
35 -
36 - $rs = $this->query($sql);
37 - $info = mysql_fetch_assoc($rs);
38 - mysql_free_result($rs);
39 -
40 - if (!$info) $info = false;
41 - else $info['server'] = str_replace('{num}', $info['server'], $wwWikiServerName);
42 -
43 - if ($lang == "commons" && $wwCommonsServerName) $info['server'] = $wwCommonsServerName;
44 -
45 - return $info;
46 - }
47 -
48 - function getWikiConnection($lang) {
49 - if (isset($this->wikidbs[$lang])) return $this->wikidbs[$lang];
50 -
51 - $info = $this->getWikiInfo($lang);
52 -
53 - if (!$info) {
54 - $db = false;
55 - } else {
56 - $db = mysql_connect($info['server'], $this->dbuser, $this->dbpassword);
57 - if (!$db) throw new Exception("Connection Failure to Database: " . mysql_error());
58 - if (!mysql_select_db($info['dbname'], $db)) throw new Exception ("Database not found: " . mysql_error());
59 - if (!mysql_query("SET NAMES Latin1;", $db)) throw new Exception ("Database not found: " . mysql_error());
60 - }
61 -
62 - $this->wikidbs[$lang] = $db;
63 - return $db;
64 - }
65 -
66 - function queryWiki($lang, $sql) {
67 - $db = $this->getWikiConnection($lang);
68 - if (!$db) throw new Exception ("Wiki not found: $lang");
69 -
70 - return $this->query($sql, $db);
71 - }
72 -
73 -}
Index: trunk/WikiWord/WikiWord/src/main/php/api.php
@@ -1,140 +0,0 @@
2 -<?php
3 -
4 -$IP = dirname(__FILE__);
5 -
6 -require_once("$IP/config.php");
7 -require_once("$IP/wwthesaurus.php");
8 -
9 -$query = @$_REQUEST['query'];
10 -
11 -if ( $query ) {
12 - $lang = @$_REQUEST['lang'];
13 - $qlang = @$_REQUEST['qlang'];
14 - $format = @$_REQUEST['format'];
15 - if ( !$format ) $format = 'phps';
16 -
17 - if ($lang) $lang = preg_replace('[^\\w\\d_]', '', $lang);
18 - if ($qlang) $qlang = preg_replace('[^\\w\\d_]', '', $qlang);
19 -
20 - if ($lang) {
21 - $lang = preg_split('![\\s,;|/:]\\s*!', $lang);
22 - if ( !$qlang ) $qlang = $lang[0];
23 - if (count($lang) == 1) $lang = $lang[0];
24 - }
25 -
26 - $result = array( 'query' => $query );
27 - $start = microtime(true);
28 -
29 - try {
30 - $thesaurus = new WWThesaurus();
31 - $db = $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
32 -
33 - if ( !$db ) {
34 - $result['error'] = array('code' => 1010, 'message' => "failed to connect to thesaurus database");
35 - } else if ($query == 'concepts') {
36 - $term = @$_REQUEST['term'];
37 - $norm = @$_REQUEST['norm'];
38 -
39 - if ( $norm === null ) $norm = 1;
40 - #$page = @$_REQUEST['page'];
41 -
42 - if ( $qlang === null ) $result['error'] = array('code' => 150, 'message' => "missing parameter qlang");
43 - else if ( $term !== null ) {
44 - $result['concepts'] = $thesaurus->getConceptsForTerm($qlang, $term, $lang, $norm); #TODO: limit!
45 - if ( $result['concepts'] === false || $result['concepts'] === null ) {
46 - $result['error'] = array('code' => 210, 'message' => "failed to retrieve concepts for term $langt:$term");
47 - }
48 - } /*else if ( $page !== null ) {
49 - $result['concepts'] = $thesaurus->getConceptsForPage($lang, $page);
50 - if ( $result['concepts'] === false || $result['concepts'] === null ) {
51 - $result['error'] = array('code' => 250, 'message' => "failed to retrieve concepts for page $langt:$page");
52 - }
53 - } */else {
54 - $result['error'] = array('code' => 110, 'message' => "missing parameter term");
55 - }
56 - } else if ($query == 'concept' || $query == 'info') {
57 - $gcid = @$_REQUEST['gcid'];
58 - if (!$gcid) $gcid = @$_REQUEST['id'];
59 -
60 - if ( $gcid === null ) {
61 - $result['error'] = array('code' => 120, 'message' => "missing parameter gcid");
62 - } else {
63 - $result['concept'] = $thesaurus->getConceptInfo($gcid, $lang); #TODO: limit!
64 - if ( $result['concept'] === false || $result['concept'] === null ) {
65 - $result['error'] = array('code' => 210, 'message' => "concept not found: $gcid");
66 - }
67 - }
68 - } else if ($query == 'properties') {
69 - $gcid = @$_REQUEST['gcid'];
70 - if (!$gcid) $gcid = @$_REQUEST['id'];
71 -
72 - $props = @$_REQUEST['props'];
73 -
74 - if ( $gcid === null ) $result['error'] = array('code' => 120, 'message' => "missing parameter gcid");
75 - else if ( $props === null ) $result['error'] = array('code' => 130, 'message' => "missing parameter props");
76 - else {
77 - $props = preg_split('![\\s,;|/:]\\s*!', $props);
78 -
79 - $info = $thesaurus->getConcept($gcid, $lang);
80 -
81 - if ( !$info ) $result['error'] = array('code' => 100, 'message' => "concept not found: $gcid");
82 - else {
83 - $result = array_merge($result, $info);
84 -
85 - foreach ( $props as $p ) {
86 - $m = "get" . ucfirst($p) . "ForConcept";
87 - if ( !method_exists($thesaurus, $m) ) {
88 - $result['error'] = array('code' => 190, 'message' => "unknown property: $p");
89 - break;
90 - }
91 -
92 - $result[$p] = $thesaurus->$m($gcid, $lang);
93 -
94 - if ( $result[$p] === false || $result[$p] === null ) {
95 - $result['error'] = array('code' => 220, 'message' => "failed to retrieve property $p for concept $gcid");
96 - break;
97 - }
98 - }
99 -
100 - if (!isset($result['id'])) $result['id'] = $gcid;
101 - if (!isset($result['lang'])) $result['lang'] = $lang;
102 - }
103 - }
104 - } else {
105 - $result['error'] = array('code' => 10, 'message' => "bad query: $query");
106 - }
107 - } catch (Exception $e) {
108 - $result['error'] = array('code' => 1000, 'message' => "unexpected exception: " . $e->getMessage());
109 - }
110 -
111 - $result['time'] = (microtime(true) - $start) . " sec";
112 -
113 - if ( isset($result['error']) ) {
114 - #TODO: HTTP error codce would be nice, but causes file_get_contents to swallow the data.
115 - # need to use CURL in client!
116 - #header("Status: 400 Bad Request", true, 400);
117 - }
118 -
119 - #TODO: JSON (+YAML?), WDDX
120 - if ($format == 'phps') {
121 - header("Content-Type: application/vnd.php.serialized"); #as proposed by http://www.alvestrand.no/pipermail/ietf-types/2004-August/001259.html
122 - $data = serialize($result);
123 - echo $data;
124 - } else if ($format == 'php') {
125 - header("Content-Type: text/php; charset=UTF-8");
126 - var_export($result);
127 - } else if ($format == 'text') {
128 - header("Content-Type: text/plain; charset=UTF-8");
129 - print_r($result);
130 - } else {
131 - header("Content-Type: text/plain; charset=UTF-8");
132 - header("Status: 400 Bad Request", true, 400);
133 - echo "Bad format: $format";
134 - }
135 -
136 - exit();
137 -}
138 -
139 -header("Content-Type: text/plain; charset=UTF-8");
140 -?>
141 -WikiWord REST API
\ No newline at end of file
Index: trunk/WikiWord/WikiWord/src/main/php/wwutils.php
@@ -1,200 +0,0 @@
2 -<?php
3 -
4 -class WWUtils {
5 - var $debug = false;
6 - var $db = NULL;
7 -
8 - var $dbuser;
9 - var $dbpassword;
10 -
11 - function connect($server, $user, $password, $database) {
12 - $db = mysql_connect($server, $user, $password) or die("Connection Failure to Database: " . htmlspecialchars(mysql_error())."\n");
13 - mysql_select_db($database, $db) or die ("Database not found: " . htmlspecialchars(mysql_error())."\n");
14 - mysql_query("SET NAMES UTF8;", $db) or die ("Database not found: " . htmlspecialchars(mysql_error())."\n");
15 -
16 - $this->dbuser = $user;
17 - $this->dbpassword = $password;
18 - $this->db = $db;
19 -
20 - return $db;
21 - }
22 -
23 - function query($sql, $db = NULL) {
24 - if ($db == NULL && isset($this)) $db = $this->db;
25 -
26 - if ($this->debug) {
27 - print "\n<br/>" . htmlspecialchars($sql) . "<br/>\n";
28 - }
29 -
30 - if (!$db) {
31 - throw new Exception("not connected!");
32 - }
33 -
34 - $result = mysql_query($sql, $db);
35 -
36 - if(!$result) {
37 - $error = mysql_error($db);
38 - $errno = mysql_errno($db);
39 - throw new Exception("$error (#$errno);\nlast query: $sql");
40 - }
41 -
42 - return $result;
43 - }
44 -
45 - function quote($s) {
46 - if (is_array($s)) throw new Exception("can't quote arrays, use quoteSet() instead.");
47 - if (is_null($s)) return "NULL";
48 -
49 - return '"' . mysql_real_escape_string($s) . '"';
50 - }
51 -
52 - function quoteSet($a) {
53 - if (!$a) throw new Exception("empty set literal not supported by mysql");
54 -
55 - if ( !is_array($a) ) $a = array( $a );
56 -
57 - $s = "";
58 -
59 - foreach ($a as $x) {
60 - if ($s) $s.= ", ";
61 -
62 - if (is_string($x)) $s .= $this->quote($x);
63 - else $s .= $x;
64 - }
65 -
66 - return '(' . $s . ')';
67 - }
68 -
69 - function close() {
70 - if ($this->db) mysql_close($this->db);
71 - $this->db = NULL;
72 -
73 - foreach ($this->wikidbs as $name => $db) {
74 - if ($db) mysql_close($db);
75 - }
76 -
77 - $this->wikidbs = array();
78 - }
79 -
80 - function getRows($sql, $key = NULL) {
81 - $rs = $this->query($sql);
82 - $list = WWUtils::slurpRows($rs, $key);
83 - mysql_free_result($rs);
84 - return $list;
85 - }
86 -
87 - function getList($sql, $valueField, $key = NULL) {
88 - $rs = $this->query($sql);
89 - $list = WWUtils::slurpList($rs, $valueField, $key);
90 - mysql_free_result($rs);
91 - return $list;
92 - }
93 -
94 - static function slurpList($rs, $field, $key = null) {
95 - if (is_string($rs)) $rs = $this->query($rs);
96 -
97 - $list = array();
98 - while ($row = mysql_fetch_assoc($rs)) {
99 - if (is_array($field)) {
100 - $value = array();
101 - foreach ($field as $f) {
102 - $value[$f] = $row[$f];
103 - }
104 - } else {
105 - $value = $row[$field];
106 - }
107 -
108 - if ($key) {
109 - $k = $row[$key];
110 - $list[$k] = $value;
111 - } else {
112 - $list[] = $value;
113 - }
114 - }
115 -
116 - return $list;
117 - }
118 -
119 - static function slurpRows($rs, $key = null) {
120 - if (is_string($rs)) $rs = $this->query($rs);
121 -
122 - $list = array();
123 - while ($row = mysql_fetch_assoc($rs)) {
124 - if ($key) {
125 - $k = $row[$key];
126 - $list[$k] = $row;
127 - } else {
128 - $list[] = $row;
129 - }
130 - }
131 -
132 - return $list;
133 - }
134 -
135 - static function slurpAssoc($rs, $keyField, $valueField) {
136 - if (is_string($rs)) $rs = $this->query($rs);
137 -
138 - $list = array();
139 - while ($row = mysql_fetch_assoc($rs)) {
140 - $key = $row[$keyField];
141 -
142 - if (is_array($valueField)) {
143 - $value = array();
144 - foreach ($valueField as $f) {
145 - $value[$f] = $row[$f];
146 - }
147 - } else {
148 - $value = $row[$valueField];
149 - }
150 -
151 - $list[$key] = $value;
152 - }
153 -
154 - return $list;
155 - }
156 -
157 - function pickLocal($items, $languages) {
158 - if ( is_string($languages) ) $languages = array( $languages, "en", "commons" );
159 -
160 - foreach ($languages as $lang) {
161 - if (isset($items[$lang])) return $items[$lang];
162 - }
163 -
164 - return false;
165 - }
166 -
167 - static function authFailed($realm) {
168 - header("Status: 401 Unauthorized", true, 401);
169 - header('WWW-Authenticate: Basic realm="'.$realm.'"');
170 - die();
171 - }
172 -
173 - static function doBasicHttpAuth($passwords, $realm) {
174 - if (!isset($_SERVER['PHP_AUTH_USER'])) {
175 - authFailed();
176 - }
177 -
178 - $usr = $_SERVER['PHP_AUTH_USER'];
179 - if (!isset($passwords[$usr])) {
180 - authFailed();
181 - }
182 -
183 - $pw = $_SERVER['PHP_AUTH_PW'];
184 - if ($pw != $passwords[$usr]) {
185 - authFailed();
186 - }
187 -
188 - return $usr;
189 - }
190 -
191 - static function printSelector($name, $choices, $current = NULL) {
192 - print "\n\t\t<select name=\"".htmlspecialchars($name)."\" id=\"".htmlspecialchars($name)."\">\n";
193 -
194 - foreach ($choices as $choice => $name) {
195 - $sel = $choice == $current ? " selected=\"selected\"" : "";
196 - print "\t\t\t<option value=\"".htmlspecialchars($choice)."\"$sel>".htmlspecialchars($name)."</option>\n";
197 - }
198 -
199 - print "</select>";
200 - }
201 -}
Index: trunk/WikiWord/WikiWord/src/main/php/wikipics.php
@@ -1,340 +0,0 @@
2 -<?php
3 -
4 -$IP = dirname(__FILE__);
5 -
6 -require_once("$IP/config.php");
7 -require_once("$IP/wwimages.php");
8 -
9 -if ($wwAPI) require_once("$IP/wwclient.php");
10 -else require_once("$IP/wwthesaurus.php");
11 -
12 -function printConceptList($concepts, $lang) {
13 - ?>
14 - <ul class="terselist">
15 - <?php
16 - foreach ($concepts as $c) {
17 - ?><li><?php
18 - print getConceptDetailsLink($lang, $c);
19 - ?></li><?php
20 - }
21 - ?>
22 - </ul>
23 - <?php
24 -}
25 -
26 -function printConceptImageList($concept, $class = "terselist") {
27 - global $utils, $wwThumbSize, $wwMaxPreviewImages;
28 -
29 - if (!$concept) return false;
30 -
31 - if (is_array($concept) && !isset($concept['id']) && isset($concept[0])) $images = $concept; #XXX: HACK
32 - else $images = $utils->getImagesAbout($concept, $wwMaxPreviewImages);
33 -
34 - ?>
35 - <ul class="<?php print $class; ?>">
36 - <?php
37 - foreach ($images as $img) {
38 - ?><li><?php
39 - print $utils->getThumbnailHTML($img, $wwThumbSize, $wwThumbSize);
40 - ?></li><?php
41 - }
42 - ?>
43 - </ul>
44 - <?php
45 -}
46 -
47 -function getConceptDetailsURL($langs, $concept) {
48 - global $wwSelf;
49 -
50 - if ( is_array($langs) ) $langs = implode('|', $langs);
51 -
52 - return "$wwSelf?id=" . urlencode($concept['id']) . "&lang=" . urlencode($langs);
53 -}
54 -
55 -function getConceptDetailsLink($langs, $concept) {
56 - global $utils;
57 - $name = $utils->pickLocal($concept['name'], $langs);
58 -
59 - $u = getConceptDetailsURL($langs, $concept);
60 - return '<a href="' . htmlspecialchars($u) . '">' . htmlspecialchars($name) . '</a>';
61 -}
62 -
63 -function pickPage( $pages ) {
64 - if (!$pages) return false;
65 -
66 - foreach ( $pages as $page => $type ) {
67 - if ($type == 10) return $page;
68 - }
69 -
70 - return $pages[0];
71 -}
72 -
73 -function getConceptPageURLs($lang, $concept) {
74 - if (!isset($concept['pages'][$lang]) || !$concept['pages'][$lang]) return false;
75 -
76 - if ($lang == 'commons') $domain = 'commons.wikimedia.org';
77 - else $domain = "$lang.wikipedia.org";
78 -
79 - $urls = array();
80 - foreach ($concept['pages'][$lang] as $page => $type) {
81 - $u = "http://$domain/wiki/" . urlencode($page);
82 - $links[$page] = $u;
83 - }
84 -
85 - return $urls;
86 -}
87 -
88 -function getConceptPageLinks($lang, $concept) {
89 - $urls = getConceptPageURLs($lang, $concept);
90 - if (!$urls) return false;
91 -
92 - foreach ($urls as $page => $u) {
93 - $u = "http://$domain/wiki/" . urlencode($page);
94 - $links[] = '<a href="' . htmlspecialchars($u) . '">' . htmlspecialchars( str_replace("_", " ", $page) ) . '</a>';
95 - }
96 -
97 - return $links;
98 -}
99 -
100 -function getAllConceptPageLinks($concept) {
101 - $links = array();
102 -
103 - foreach ( $concept['languages'] as $lang ) {
104 - $ll = getConceptPageLinks($lang, $concept);
105 - if ($ll) $links[$lang] = $ll;
106 - }
107 -
108 - return $links;
109 -}
110 -
111 -function printList($items, $escape = true, $class = "list") {
112 - ?>
113 - <ul class="<?php print htmlspecialchars($class); ?>">
114 - <?php
115 - foreach ($items as $item) {
116 - if ( $escape ) $item = htmlspecialchars($item);
117 - print "\t\t<li>" . $item . "</li>\n";
118 - }
119 - ?>
120 - </ul>
121 - <?php
122 -}
123 -
124 -function printDefList($items, $scapeKeys = true, $escapeValues = true, $class = "list") {
125 - ?>
126 - <dl class="<?php print htmlspecialchars($class); ?>">
127 - <?php
128 - foreach ($items as $key => $item) {
129 - if ( $escapeKeys ) $key = htmlspecialchars($key);
130 - print "\t\t<dt>" . $key . "</dt>\n";
131 -
132 - if ( $escapeValues ) $item = htmlspecialchars($item);
133 - print "\t\t\t<dd>" . $item . "</dd>\n";
134 - }
135 - ?>
136 - </sl>
137 - <?php
138 -}
139 -
140 -function getWeightClass($weight) {
141 - if (!isset($weight) || !$weight) {
142 - return "unknown";
143 - $weight = NULL;
144 - }
145 - else if ($weight>1000) return "huge";
146 - else if ($weight>100) return "big";
147 - else if ($weight>10) return "normal";
148 - else if ($weight>2) return "some";
149 - else return "little";
150 -}
151 -
152 -function printConcept($concept, $langs, $terse = true) {
153 - global $utils, $wwMaxPreviewImages, $wwMaxGalleryImages;
154 -
155 - extract( $concept );
156 - $wclass = getWeightClass($score);
157 -
158 - ?>
159 - <tr class="row_item">
160 - <td class="cell_weight <?php print "weight_$wclass"; ?>"><?php print htmlspecialchars($score); ?></td>
161 - <td colspan="3" class="cell_name <?php print "weight_$wclass"; ?>">
162 - <h3>
163 - <?php print getConceptDetailsLink($langs, $concept); ?>
164 - <?php /* TODO: wiki links */ ?>
165 - </h3>
166 - </td>
167 - </tr>
168 -
169 - <?php if (isset($definition) && !empty($definition)) {
170 - $definition = $utils->pickLocal($definition, $langs);
171 - ?>
172 -
173 - <tr class="row_def">
174 - <td></td>
175 - <td colspan="3"><?php print htmlspecialchars($definition); ?></td>
176 - </tr>
177 - <?php } ?>
178 -
179 - <tr class="row_details row_images">
180 - <td></td>
181 - <td class="cell_images" colspan="3">
182 - <?php
183 - $gallery = $utils->getImagesAbout($concept, $terse ? $wwMaxPreviewImages : $wwMaxGalleryImages );
184 - $c = printConceptImageList( $gallery, $terse ? "terselist" : "gallery" );
185 - ?>
186 - </td>
187 - </tr>
188 -
189 -
190 - <?php
191 - if (isset($score) && $score && $score<2 && $pos>=3) return false;
192 - else return true;
193 -}
194 -
195 -$conceptId = @$_REQUEST['id'];
196 -$term = @$_REQUEST['term'];
197 -$lang = @$_REQUEST['lang'];
198 -
199 -if (!isset($wwSelf)) $wwSelf = @$_SERVER["PHP_SELF"];
200 -
201 -$error = NULL;
202 -
203 -if ($lang && !isset($wwLanguages[$lang])) {
204 - $lang = NULL;
205 - $error = "bad language code: $lang";
206 -}
207 -
208 -if ($wwAPI) $thesaurus = new WWClient($wwAPI);
209 -else {
210 - $thesaurus = new WWThesaurus();
211 - $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
212 -}
213 -
214 -$utils = new WWImages( $thesaurus );
215 -if ( !$utils->db ) $utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
216 -
217 -if (@$_REQUEST['debug']) $utils->debug = true;
218 -
219 -$limit = 20;
220 -$norm = 1;
221 -
222 -$result = NULL;
223 -
224 -$languages = array( $lang, "en", "commons" ); #TODO: make the user define this list
225 -
226 -if (!$error) {
227 - try {
228 - if ($lang && $conceptId) {
229 - $result = $thesaurus->getConceptInfo($conceptId, $lang);
230 - if ( $result ) $result = array( $result ); //hack
231 - } else if ($lang && $term) {
232 - $result = $thesaurus->getConceptsForTerm($lang, $term, $languages, $norm, $limit);
233 - }
234 - } catch (Exception $e) {
235 - $error = $e->getMessage();
236 - }
237 -}
238 -
239 -
240 -?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
241 -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
242 -<head>
243 - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
244 - <title>WikiWord Navigator</title>
245 -
246 - <style type="text/css">
247 - body { font-family: verdana, helvetica, arial, sans-serif; }
248 - td { text-align: left; vertical-align: top; }
249 - th { text-align: left; vertical-align: top; font-weight:bold; }
250 - .error { color: red; font-weight: bold; }
251 - .weight_huge { font-size: 140%; font-weight:bold; }
252 - .weight_big { font-size: 120%; font-weight:bold; }
253 - .weight_normal { font-size: 110%; font-weight:bold; }
254 - .weight_some { font-size: 100%; font-weight:bold; }
255 - .weight_little { font-size: 90%; font-weight:bold; }
256 - .weight_unknown { font-size: 100%; font-weight:bold; }
257 - .row_def td { font-size: 80%; font-style:italic; }
258 - .row_details td { font-size: 80%; }
259 - .cell_weight { text-align: right; }
260 - .cell_label { text-align: right; }
261 - .header { text-align: left; }
262 - .inputform { text-align: center; margin:1ex auto; padding:1ex; width:80%; border:1px solid #666666; background-color:#DDDDDD; }
263 - .footer { font-size:80%; text-align: center; border-top: 1px solid #666666; }
264 - .note { font-size:80%; }
265 - .terselist, .terselist li { display: inline; margin:0; padding:0; }
266 - .terselist li { display: inline; }
267 - .terselist li:before { content:" - " }
268 - .terselist li:first-child:before { content:"" }
269 -
270 - .gallery li { display: inline; padding:0.5ex; margin:0.5ex; }
271 - </style>
272 -</head>
273 -<body>
274 - <div class="header">
275 - <h1>WikiWord Navigator</h1>
276 - <p>Experimental semantic navigator and thesaurus interface for Wikipedia.</p>
277 - <p>The WikiWord Navigator was created as part of the WikiWord project run by <a href="http://wikimedia.de">Wikimedia Deutschland e.V.</a>.
278 - It is based on a <a href="http://brightbyte.de/page/WikiWord">diploma thesis</a> by Daniel Kinzler, and runs on the <a href="http://toolserver.org/">Wikimedia Toolserver</a>. WikiWord is an ongoing research project. Please contact <a href="http://brightbyte.de/page/Special:Contact">Daniel Kinzler</a> for more information.</p>
279 - </div>
280 -
281 - <div class="inputform" >
282 - <form name="search" action="<?php print $wwSelf; ?>">
283 - <table border="0" class="inputgrid">
284 - <tr>
285 - <td>
286 - <label for="term">Term: </label><input type="text" name="term" id="term" size="24" value="<?php print htmlspecialchars($term); ?>"/>
287 - </td>
288 - <td>
289 - <label for="term" style="display:none">Language: </label>
290 - <?php WWUtils::printSelector("lang", $wwLanguages, $lang) ?>
291 - </td>
292 - <td>
293 - <input type="submit" name="go" value="go"/>
294 - </td>
295 - </tr>
296 - </table>
297 - <p class="note">Note: this is a thesaurus lookup, not a full text search. Only exact matches are considered.</p>
298 - </form>
299 - </div>
300 -<?php
301 -if ($error) {
302 - print "<p class=\"error\">".htmlspecialchars($error)."</p>";
303 -}
304 -?>
305 -
306 -<?php
307 -if ($result) {
308 - if ( $conceptId ) $terse = false;
309 - else $terse = true;
310 -
311 - $count = 0;
312 - foreach ( $result as $row ) {
313 - $count = $count + 1;
314 - $row['pos'] = $count;
315 -
316 -?>
317 - <table border="0" class="results">
318 - <?php
319 - $continue= printConcept($row, $languages, $terse);
320 -
321 - if (!$continue) break;
322 - ?>
323 - </table>
324 - </div>
325 -
326 -<?php
327 - } #concept loop
328 -
329 - if ($term) { ?>
330 - <p>Found <?php print $count; ?> items.</p>
331 - <?php }
332 -} ?>
333 -
334 -<p class="footer">
335 -The WikiWord Navigator is part of the <a href="http://wikimedia.de">Wikimedia</a> project <a href="http://brightbyte.de/page/WikiWord">WikiWord</a>
336 -<p>
337 -</body>
338 -</html>
339 -<?php
340 -$utils->close();
341 -?>
\ No newline at end of file
Index: trunk/WikiWord/WikiWord/src/main/php/wwimages.php
@@ -1,496 +0,0 @@
2 -<?php
3 -require_once(dirname(__FILE__)."/wwwikis.php");
4 -
5 -class ImageCollection {
6 -
7 - function __construct() {
8 - $this->images = array();
9 - }
10 -
11 - static function compareRecords($a, $b) {
12 - $d = (float)$b['score'] - (float)$a['score']; //NOTE: descending
13 -
14 - if ( $d > 0 ) return 1;
15 - else if ( $d < 0 ) return -1;
16 - else return 0;
17 - }
18 -
19 - function size() {
20 - return count($this->images);
21 - }
22 -
23 - function listImages($max) {
24 - uasort($this->images, "Imagecollection::compareRecords");
25 -
26 - if ($max) return array_slice($this->images, 0, $max);
27 - else return $this->images;
28 - }
29 -
30 - function addImage($image, $key, $usage = "page", $weight = 1) {
31 - if (!isset($this->images[$image])) {
32 - $rec = array(
33 - "name" => $image,
34 - "score" => 0,
35 - );
36 - } else {
37 - $rec = $this->images[$image];
38 - }
39 -
40 - if (!isset($rec[$usage])) $rec[$usage] = array();
41 - $rec[$usage][] = $key;
42 - $rec["score"] += $weight;
43 -
44 - $this->images[$image] = $rec;
45 - return $rec['score'];
46 - }
47 -
48 - function addImages($images, $key, $usage = "page", $weight = 1) {
49 - foreach ($images as $image) {
50 - $this->addImage($image, $key, $usage, $weight);
51 - }
52 - }
53 -
54 - function addImageUsage($image, $wiki, $usage = "page", $weight = 1) {
55 - $this->addImage($image, $key, $usage, $weight);
56 - }
57 -
58 - function addTags($image, $tags, $prefix = "") {
59 - global $wwTagScores;
60 -
61 - if (isset($this->images[$image])) {
62 - foreach ($tags as $tag => $weight) {
63 - if (is_int($tag)) {
64 - $tag = $prefix.$weight;
65 -
66 - if (isset($wwTagScores[$tag])) $weight = $wwTagScores[$tag];
67 - else $weight = 0;
68 - } else {
69 - $tag = $prefix.$tag;
70 - }
71 -
72 - $this->images[$image]['score'] += $weight;
73 - $this->images[$image]['tags'][] = $tag;
74 - }
75 - }
76 - }
77 -
78 -}
79 -
80 -class WWImages extends WWWikis {
81 - var $thesaurus;
82 -
83 - function __construct($thesaurus) {
84 - $this->thesaurus = $thesaurus;
85 - if ( !empty( $this->thesaurus->db ) ) $this->db = $thesaurus->db;
86 - }
87 -
88 - function queryImagesOnPage($lang, $ns, $title, $commonsOnly = false) {
89 - if ($lang == "commons") $commonsOnly = false;
90 -
91 - $imagelinks_table = $this->getWikiTableName($lang, "imagelinks");
92 - $page_table = $this->getWikiTableName($lang, "page");
93 - $image_table = $this->getWikiTableName($lang, "image");
94 - $commons_image_table = $this->getWikiTableName("commons", "image");
95 -
96 - $sql = "/* queryImagesOnPage(" . $this->quote($lang) . ", " . (int)$ns . ", " . $this->quote($title) . ", " . (int)$commonsOnly . ") */ ";
97 -
98 - $sql .= " SELECT I.il_to as name FROM $imagelinks_table as I ";
99 - $sql .= " JOIN $page_table as P on P.page_id = I.il_from ";
100 - if ($commonsOnly) $sql .= " LEFT JOIN $image_table as R on R.img_name = I.il_to ";
101 - if ($commonsOnly) $sql .= " JOIN $commons_image_table as C on C.img_name = I.il_to ";
102 -
103 - $sql .= " WHERE P.page_namespace = " . (int)$ns;
104 - $sql .= " AND P.page_title = " . $this->quote($title);
105 - if ($commonsOnly) $sql .= " AND R.img_name IS NULL";
106 -
107 - return $this->queryWiki($lang, $sql);
108 - }
109 -
110 - function getImagesOnPage($lang, $ns, $title, $commonsOnly = false) {
111 - $rs = $this->queryImagesOnPage($lang, $ns, $title, $commonsOnly);
112 -
113 - $list = WWUtils::slurpList($rs, "name");
114 - mysql_free_result($rs);
115 -
116 - return $list;
117 - }
118 -
119 - function queryImagesOnPageTemplates($lang, $ns, $title, $commonsOnly = false) {
120 - if ($lang == "commons") $commonsOnly = false;
121 -
122 - $imagelinks_table = $this->getWikiTableName($lang, "imagelinks");
123 - $page_table = $this->getWikiTableName($lang, "page");
124 - $image_table = $this->getWikiTableName($lang, "image");
125 - $commons_image_table = $this->getWikiTableName("commons", "image");
126 - $templatelinks_table = $this->getWikiTableName($lang, "templatelinks");
127 -
128 - $sql = "/* queryImagesOnPageTemplates(" . $this->quote($lang) . ", " . (int)$ns . ", " . $this->quote($title) . ", " . (int)$commonsOnly . ") */ ";
129 -
130 - $sql .= " SELECT I.il_to as name FROM $imagelinks_table as I ";
131 - $sql .= " JOIN $page_table as TP on TP.page_id = I.il_from ";
132 - $sql .= " JOIN $templatelinks_table as T on T.tl_namespace = TP.page_namespace AND T.tl_title = TP.page_title ";
133 - $sql .= " JOIN $page_table as P on P.page_id = T.tl_from ";
134 - if ($commonsOnly) $sql .= " LEFT JOIN $image_table as R on R.img_name = I.il_to ";
135 - if ($commonsOnly) $sql .= " JOIN $commons_image_table as C on C.img_name = I.il_to ";
136 -
137 - $sql .= " WHERE P.page_namespace = " . (int)$ns;
138 - $sql .= " AND P.page_title = " . $this->quote($title);
139 - if ($commonsOnly) $sql .= " AND R.img_name IS NULL";
140 -
141 - return $this->queryWiki($lang, $sql);
142 - }
143 -
144 - function getImagesOnPageTemplates($lang, $ns, $title, $commonsOnly = false) {
145 - $rs = $this->queryImagesOnPageTemplates($lang, $ns, $title, $commonsOnly);
146 - $list = WWUtils::slurpList($rs, "name");
147 - mysql_free_result($rs);
148 - return $list;
149 - }
150 -
151 - function queryImagesInCategory($lang, $title) {
152 - $categorylinks_table = $this->getWikiTableName($lang, "categorylinks");
153 - $page_table = $this->getWikiTableName($lang, "page");
154 -
155 - $sql = "/* queryImagesInCategory(" . $this->quote($lang) . ", " . $this->quote($title) . ") */ ";
156 -
157 - $sql .= " SELECT P.page_title as name FROM $page_table as P ";
158 - $sql .= " JOIN $categorylinks_table as C on C.cl_from = P.page_id ";
159 -
160 - $sql .= " WHERE C.cl_to = " . $this->quote($title);
161 - $sql .= " AND P.page_namespace = " . NS_IMAGE;
162 -
163 - return $this->queryWiki($lang, $sql);
164 - }
165 -
166 - function getImagesInCategory($lang, $title) {
167 - $rs = $this->queryImagesInCategory($lang, $title);
168 - $list = WWUtils::slurpList($rs, "name");
169 - mysql_free_result($rs);
170 - return $list;
171 - }
172 -
173 - function queryTagsForImages($lang, $images, $tagTable) {
174 - if (!$images) return false;
175 -
176 - $sql = "/* queryTagsForImages(" . $this->quote($lang) . ", " . $this->quoteSet($images) . ") */ ";
177 -
178 - $sql .= " SELECT image, group_concat( concat(type, ':', tag) separator '|') as tags ";
179 - $sql .= " FROM $tagTable as T ";
180 - $sql .= " WHERE T.image IN " . $this->quoteSet($images);
181 - $sql .= " GROUP BY image ";
182 -
183 - return $this->queryWiki($lang, $sql);
184 - }
185 -
186 - function getTagsForImages($lang, $images, $tagTable) {
187 - if (!$images) return array();
188 -
189 - $rs = $this->queryTagsForImages($lang, $images, $tagTable);
190 - $list = WWUtils::slurpAssoc($rs, "image", "tags");
191 - mysql_free_result($rs);
192 - return $list;
193 - }
194 -
195 - function queryTemplatesOnImagePage($lang, $image) {
196 - $page_table = $this->getWikiTableName($lang, "page");
197 - $templatelinks_table = $this->getWikiTableName($lang, "templatelinks");
198 -
199 - $sql = "/* queryTemplatesOnImagePage(" . $this->quote($lang) . ", " . $this->quote($image) . ") */ ";
200 -
201 - $sql .= " SELECT tl_title as template FROM $templatelinks_table as T ";
202 - $sql .= " JOIN $page_table as P on P.page_id = T.tl_from AND T.tl_namespace = " . NS_TEMPLATE . " ";
203 -
204 - $sql .= " WHERE P.page_title = " . $this->quote($image);
205 - $sql .= " AND P.page_namespace = " . NS_IMAGE;
206 -
207 - return $this->queryWiki($lang, $sql);
208 - }
209 -
210 - function getTemplatesOnImagePage($lang, $image) {
211 - $rs = $this->queryTemplatesOnImagePage($lang, $image);
212 - $list = WWUtils::slurpList($rs, "template");
213 - mysql_free_result($rs);
214 - return $list;
215 - }
216 -
217 - function queryCategoriesOfImagePage($lang, $image) {
218 - $page_table = $this->getWikiTableName($lang, "page");
219 - $categorylinks_table = $this->getWikiTableName($lang, "categorylinks");
220 -
221 - $sql = "/* queryCategoriesOfImagePage(" . $this->quote($lang) . ", " . $this->quote($image) . ") */ ";
222 -
223 - $sql .= " SELECT cl_to as category FROM $categorylinks_table as C ";
224 - $sql .= " JOIN $page_table as P on P.page_id = C.cl_from ";
225 -
226 - $sql .= " WHERE P.page_title = " . $this->quote($image);
227 - $sql .= " AND P.page_namespace = " . NS_IMAGE;
228 -
229 - return $this->queryWiki($lang, $sql);
230 - }
231 -
232 - function getCategoriesOfImagePage($lang, $image) {
233 - $rs = $this->queryCategoriesOfImagePage($lang, $image);
234 - $list = WWUtils::slurpList($rs, "category");
235 - mysql_free_result($rs);
236 - return $list;
237 - }
238 -
239 - function getTemplateScores($templates, $values = NULL) {
240 - global $wwTemplateScores;
241 - if ($values === NULL) $values = $wwTemplateScores;
242 -
243 - if (!$values) return 0;
244 -
245 - $score = 0;
246 - foreach ($templates as $t) {
247 - $v = @$values[$t];
248 - if ($v) $score += $v;
249 - }
250 -
251 - return $score;
252 - }
253 -
254 - function getRelevantImagesOnPage($lang, $ns, $title, $commonsOnly = false) {
255 - $img = $this->getImagesOnPage($lang, 0, $title, true);
256 - $timg = $this->getImagesOnPageTemplates($lang, 0, $title, true);
257 - $img = array_diff($img, $timg);
258 - return $img;
259 - }
260 -
261 - function queryImagesOnPagesGlobally( $concepts ) {
262 - global $wwLanguages;
263 -
264 - if (!$concepts) return false;
265 -
266 - $globalimagelinks_table = $this->getWikiTableName("commons", "globalimagelinks");
267 -
268 - $wikis = array();
269 - $pages = array();
270 -
271 - foreach ($concepts as $lang => $rc) {
272 - if (!isset($wwLanguages[$lang])) continue;
273 -
274 - $wiki = $lang . "wiki";
275 - if (!in_array($wiki, $wikis)) $wikis[] = $wiki;
276 -
277 - foreach ($rc as $r => $t) {
278 - if ( $t != 10) continue; //use only articles
279 - $p = "gil_wiki = " . $this->quote($wiki) . " AND gil_page_namespace_id = 0 AND gil_page_title = " . $this->quote($r);
280 - $pages[] = $p;
281 - }
282 - }
283 -
284 - if (!$pages || !$wikis) return false;
285 -
286 - $sql = " /* queryImagesOnPagesGlobally() */ ";
287 - $sql .= " SELECT distinct gil_to as image FROM $globalimagelinks_table ";
288 - $sql .= " WHERE gil_wiki in " . $this->quoteSet( $wikis );
289 - $sql .= " AND gil_page_namespace_id = 0 ";
290 - $sql .= " AND ( ( " . implode(" ) OR ( ", $pages) . " ) ) ";
291 -
292 - print "(** $sql **)";
293 -
294 - return $this->queryWiki("commons", $sql);
295 - }
296 -
297 - function getImagesOnPagesGlobally( $concepts ) {
298 - if (!$concepts) return array();
299 -
300 - $rs = $this->queryImagesOnPagesGlobally($concepts);
301 - if (!$rs) return false;
302 -
303 - $list = WWUtils::slurpList($rs, "image");
304 - mysql_free_result($rs);
305 - return $list;
306 - }
307 -
308 - function queryGlobalUsageCounts( $images, $wikis = ".*wiki" ) {
309 - if (!$images) return false;
310 -
311 - $globalimagelinks_table = $this->getWikiTableName("commons", "globalimagelinks");
312 -
313 - $sql = " /* queryGlobalUsageCounts() */ ";
314 - $sql .= " SELECT gil_to as image, gil_wiki as wiki, count(*) as linkcount FROM $globalimagelinks_table ";
315 - $sql .= " WHERE gil_page_namespace_id = 0 ";
316 - $sql .= " AND gil_to IN " . $this->quoteSet( $images );
317 -
318 - if ( $wikis ) {
319 - if ( is_array( $wikis ) ) $sql .= " AND gil_wiki IN " . $this->quoteSet( $wikis );
320 - else if ( is_array( $wikis ) ) $sql .= " AND gil_wiki REGEX " . $this->quote( '^' . $wikis . '$' );
321 -
322 - #TODO: could also limit to to x or min size n using toolserver.wiki !
323 - }
324 -
325 - $sql .= " GROUP BY gil_to, gil_wiki ";
326 - $sql .= " ORDER BY gil_to, gil_wiki ";
327 -
328 - return $this->queryWiki("commons", $sql);
329 - }
330 -
331 - function getGlobalUsageCounts( $images, $wikis = ".*wiki" ) {
332 - if (!$images) return array();
333 -
334 - $rs = $this->queryGlobalUsageCounts($images, $wikis);
335 - if (!$rs) return false;
336 -
337 - if (is_string($rs)) $rs = $this->query($rs);
338 -
339 - $imageUsage = array();
340 - $current = NULL;
341 - $stats = array();
342 - while ($row = mysql_fetch_assoc($rs)) {
343 - $image = $row["image"];
344 - $wiki = $row["wiki"];
345 - $linkcount = $row["linkcount"];
346 -
347 - if ( is_null($current) ) $current = $image;
348 - else if ($current != $image) {
349 - $imageUsage[$current] = $stats;
350 - $stats = array();
351 - $current = $image;
352 - }
353 -
354 - $stats[$wiki] = $linkcount;
355 - }
356 -
357 - if ($current) $imageUsage[$current] = $stats;
358 -
359 - return $imageUsage;
360 - }
361 -
362 - function getImagesAbout($concept, $max = 0) {
363 - global $wwLanguages, $wwFrequentImageThreshold; //FIXME: put config into member vars!
364 -
365 - $pages = null;
366 - if ( is_array($concept) ) {
367 - if (isset($concept['pages']) && $concept['pages']!==null) $pages = $concept['pages'];
368 - else if (isset($concept['id']) && $concept['id']!==null) $concept = $concept['id'];
369 - else if (isset($concept['concept'])) $concept = $concept['concept'];
370 - }
371 -
372 - if ($pages === null) {
373 - $pages = $this->thesaurus->getPagesForConcept($concept);
374 - if (!$pages) return false;
375 - }
376 -
377 - $images = new ImageCollection();
378 -
379 - $globalImageList = $this->getImagesOnPagesGlobally($pages); //use wikis for $wwLanguages only
380 - //TODO: sanity limit on number of images. $max * 5 ?
381 - $globalImageUsage = $this->getGlobalUsageCounts($globalImageList, ".*wiki"); //use all wikipedias
382 -
383 - foreach ($globalImageUsage as $image => $usage) {
384 - foreach ($usage as $wiki => $c) {
385 - if ( $c >= $wwFrequentImageThreshold ) continue;
386 - $images->addImageUsage($image, $wiki.":*", "article", 1);
387 - }
388 - }
389 -
390 - if ($max && $images->size()>$max) { //short-cirquit, if we already reached the max
391 - $this->addImageTags($images);
392 - return $images->listImages($max);
393 - }
394 -
395 - if (isset($pages['commons'])) {
396 - $cpages = $pages['commons'];
397 -
398 - foreach ($cpages as $cpage => $t) {
399 - if ( $t == 50 && preg_match('/^Category:(.*)$/', $cpage, $m) ) {
400 - if ( @$m[1] ) $cpage = $m[1]; //hack
401 - $img = $this->getImagesInCategory("commons", $cpage);
402 -
403 - if ($img) $images->addImages($img, "commons:category:" . $cpage, "category", 0.5);
404 - }
405 - }
406 - }
407 -
408 - $this->addImageTags($images);
409 - return $images->listImages($max);
410 - }
411 -
412 - function addImageTags($images) {
413 - global $wwTagsTable;
414 -
415 -
416 - if ( $wwTagsTable ) {
417 - $img = array();
418 - foreach ($images->images as $image) {
419 - $img[] = $image['name'];
420 - }
421 -
422 - $tagMap = $this->getTagsForImages('commons', $img, $wwTagsTable);
423 - foreach ($tagMap as $image => $tags) {
424 - if ($tags) {
425 - if (is_string($tags)) $tags = preg_split('/\s*[|;]\s*/', $tags);
426 - $images->addTags($image, $tags, "");
427 - }
428 - }
429 - } else {
430 - foreach ($images->images as $image) {
431 - $image = $image['name'];
432 -
433 - $tmps = $this->getTemplatesOnImagePage('commons', $image);
434 - if ($tmps) $images->addTags($image, $tmps, "Template:");
435 -
436 - $cats = $this->getCategoriesOfImagePage('commons', $image);
437 - if ($cats) $images->addTags($image, $cats, "Category:");
438 - }
439 - }
440 - }
441 -
442 - function getThumbnailURL($image, $width = 120, $height = NULL) {
443 - global $wwThumbnailURL;
444 -
445 - if (is_array($image)) $image = $image['name'];
446 -
447 - if (!$height) $height = $width;
448 -
449 - $u = $wwThumbnailURL;
450 - $u = str_replace("{name}", urlencode($image), $u);
451 - $u = str_replace("{width}", !$width ? "" : urlencode($width), $u);
452 - $u = str_replace("{height}", !$height ? "" : urlencode($height), $u);
453 -
454 - return $u;
455 - }
456 -
457 - function getImagePageURL($image) {
458 - global $wwImagePageURL;
459 -
460 - if (is_array($image)) $image = $image['name'];
461 -
462 - $u = $wwImagePageURL;
463 - $u = str_replace("{name}", urlencode($image), $u);
464 -
465 - return $u;
466 - }
467 -
468 - function getThumbnailHTML($image, $w = 120, $h = NULL) {
469 - $thumb = $this->getThumbnailURL($image, $w, $h);
470 - $page = $this->getImagePageURL($image);
471 -
472 - if (is_array($image)) {
473 - $title = @$image['title'];
474 - $name = @$image['name'];
475 - } else {
476 - $name = $image;
477 - }
478 -
479 - if (!@$title) $title = $name;
480 -
481 - $tags = "";
482 - if (isset($image['tags'])) {
483 - foreach ($image['tags'] as $tag) {
484 - $tags .= "tag-" . str_replace(":", "-", $tag) . " ";
485 - }
486 - }
487 -
488 - $html= "<img src=\"" . htmlspecialchars($thumb) . "\" alt=\"" . htmlspecialchars($title) . "\" border=\"0\"/>";
489 - $html= "<a href=\"" . htmlspecialchars($page) . "\" title=\"" . htmlspecialchars($title) . " (score " . htmlspecialchars($image['score']) . ")\" class=\"thumb-link $tags\">$html</a>";
490 -
491 - if (is_array($image)) {
492 - $html .= "<!-- " . str_replace("--", "~~", var_export( $image, true ) ) . " -->";
493 - }
494 -
495 - return $html;
496 - }
497 -}
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/build-search-index.sh
@@ -0,0 +1,15 @@
 2+#!/bin/bash
 3+set -e
 4+
 5+db="$1"
 6+collection="$2"
 7+thesaurus="$3"
 8+languages="en de fr nl it es pt pl"
 9+
 10+echo "preparing search index"
 11+replace '{collection}' "$collection" '{thesaurus}' "$thesaurus" < search-index.sql | mysql "$db"
 12+
 13+for n in $languages; do
 14+ echo "collection search index: $n"
 15+ replace '{collection}' "$collection" '{thesaurus}' "$thesaurus" '{lang}' "$n" < search-index-local.sql | mysql "$db"
 16+done
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/search-index-local.sql
@@ -0,0 +1,16 @@
 2+-- collect definitions
 3+insert into {collection}_{thesaurus}_search_index (
 4+ concept, concept_name, `type`,
 5+ `lang`, `term`, `score`, `norm` )
 6+select O.global_concept, M.concept_name, C.type, "{lang}",
 7+ REPLACE( LCASE( CAST(M.term_text as CHAR CHARACTER SET utf8) COLLATE utf8_general_ci ), "-", "" ),
 8+ M.rule * M.freq, 1
 9+from {collection}_{lang}_meaning as M
 10+join {collection}_{thesaurus}_origin as O on O.lang = "{lang}" and O.local_concept = M.concept
 11+join {collection}_{thesaurus}_concept as C on C.id = O.global_concept
 12+where (M.rule not in (10, 30) OR M.freq > 1) and C.type > 0
 13+on duplicate key update
 14+ score = if (score > values(score), score, values(score)),
 15+ norm = if (norm < values(norm), score, values(norm));
 16+
 17+-- FIXME: normalization levels! 0=none, 1=case-and-dash (+translit?), 2=whitespace-and-punctuation, 4=soundex
\ No newline at end of file
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/concept-info.sql
@@ -0,0 +1,20 @@
 2+SET SESSION group_concat_max_len = 262144; -- 1024*256
 3+
 4+create table if not exists {collection}_{thesaurus}_concept_info (
 5+ concept int(11) NOT NULL,
 6+ `lang` varbinary(10) NOT NULL,
 7+ `name` varbinary(255) NOT NULL,
 8+ `pages` MEDIUMBLOB DEFAULT NULL,
 9+ `definition` MEDIUMBLOB DEFAULT NULL,
 10+ `broader` MEDIUMBLOB DEFAULT NULL,
 11+ `narrower` MEDIUMBLOB DEFAULT NULL,
 12+ `similar` MEDIUMBLOB DEFAULT NULL,
 13+ `related` MEDIUMBLOB DEFAULT NULL,
 14+ PRIMARY KEY ( concept, lang )
 15+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
 16+
 17+truncate {collection}_{thesaurus}_concept_info;
 18+
 19+insert into {collection}_{thesaurus}_concept_info ( concept, lang, name )
 20+select global_concept, lang, local_concept_name
 21+from {collection}_{thesaurus}_origin;
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/search-index.sql
@@ -0,0 +1,13 @@
 2+create table if not exists {collection}_{thesaurus}_search_index (
 3+ concept int(11) NOT NULL,
 4+ concept_name varbinary(255) NOT NULL,
 5+ type int(11) NOT NULL,
 6+ `lang` varbinary(10) NOT NULL,
 7+ `term` varchar(255) character set utf8 collate utf8_general_ci NOT NULL,
 8+ `score` int NOT NULL,
 9+ `norm` int NOT NULL,
 10+ PRIMARY KEY ( lang, term, concept ),
 11+ KEY ( concept, lang )
 12+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
 13+
 14+truncate {collection}_{thesaurus}_search_index;
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/build-concept-info.sh
@@ -0,0 +1,15 @@
 2+#!/bin/bash
 3+set -e
 4+
 5+db="$1"
 6+collection="$2"
 7+thesaurus="$3"
 8+languages="commons en de fr nl it es pt pl"
 9+
 10+echo "preparing concept info"
 11+replace '{collection}' "$collection" '{thesaurus}' "$thesaurus" < concept-info.sql | mysql "$db"
 12+
 13+for n in $languages; do
 14+ echo "collection concept info: $n"
 15+ replace '{collection}' "$collection" '{thesaurus}' "$thesaurus" '{lang}' "$n" < concept-info-local.sql | mysql "$db"
 16+done
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/concept-info-local.sql
@@ -0,0 +1,61 @@
 2+SET SESSION group_concat_max_len = 262144; -- 1024*256
 3+
 4+-- collect definitions
 5+update {collection}_{thesaurus}_concept_info as I
 6+join {collection}_{thesaurus}_origin as O on I.lang = O.lang and I.concept = O.global_concept
 7+join {collection}_{lang}_definition as D on O.local_concept = D.concept and O.lang = "{lang}"
 8+set I.definition = D.definition
 9+where I.lang = "{lang}";
 10+
 11+-- collect wiki pages
 12+update {collection}_{thesaurus}_concept_info as I
 13+join ( select O.global_concept as concept, O.lang as lang,
 14+ group_concat(distinct concat(R.type, ":", R.name) separator "|" ) as pages
 15+ from {collection}_{thesaurus}_origin as O
 16+ join {collection}_{lang}_about as A on A.concept = O.local_concept and O.lang = "{lang}"
 17+ join {collection}_{lang}_resource as R on R.id = A.resource
 18+ where O.lang = "{lang}" and R.type IN (10, 50)
 19+ group by O.global_concept, O.lang
 20+ ) as X
 21+on I.concept = X.concept and I.lang = X.lang
 22+set I.pages = X.pages
 23+where I.lang = "{lang}";
 24+
 25+-- collect broader concepts
 26+update {collection}_{thesaurus}_concept_info as I
 27+join ( select narrow as concept, group_concat(distinct concat(broad, ":", if (local_concept_name is null, "", local_concept_name)) separator "|") as broader
 28+from {collection}_{thesaurus}_broader
 29+ left join {collection}_{thesaurus}_origin as O on O.global_concept = broad and O.lang = "{lang}"
 30+ group by narrow ) as X
 31+on X.concept = I.concept and I.lang = "{lang}"
 32+set I.broader = X.broader;
 33+
 34+-- collect narrower concepts
 35+update {collection}_{thesaurus}_concept_info as I
 36+join ( select broad as concept, group_concat(distinct concat(narrow, ":", if (local_concept_name is null, "", local_concept_name)) separator "|") as narrower
 37+from {collection}_{thesaurus}_broader
 38+ left join {collection}_{thesaurus}_origin as O on O.global_concept = narrow and O.lang = "{lang}"
 39+ group by broad ) as X
 40+on X.concept = I.concept and I.lang = "{lang}"
 41+set I.narrower = X.narrower;
 42+
 43+-- collect similar concepts
 44+update {collection}_{thesaurus}_concept_info as I
 45+join ( select concept1 as concept, group_concat(distinct concat(concept2, ":", if (local_concept_name is null, "", local_concept_name)) separator "|") as similar
 46+from {collection}_{thesaurus}_relation
 47+ left join {collection}_{thesaurus}_origin as O on O.global_concept = concept2 and O.lang = "{lang}"
 48+ where langmatch >= 1 or langref >= 1
 49+ group by concept1 ) as X
 50+on X.concept = I.concept and I.lang = "{lang}"
 51+set I.similar = X.similar;
 52+
 53+-- collect related concepts
 54+update {collection}_{thesaurus}_concept_info as I
 55+join ( select concept1 as concept, group_concat(distinct concat(concept2, ":", if (local_concept_name is null, "", local_concept_name)) separator "|") as related
 56+from {collection}_{thesaurus}_relation
 57+ left join {collection}_{thesaurus}_origin as O on O.global_concept = concept2 and O.lang = "{lang}"
 58+ where bilink >= 1
 59+ group by concept1 ) as X
 60+on X.concept = I.concept and I.lang = "{lang}"
 61+set I.related = X.related;
 62+
Index: trunk/WikiWord/WikiWord/src/main/php/search/wikiword.php
@@ -0,0 +1,481 @@
 2+<?php
 3+
 4+$IP = dirname(__FILE__);
 5+
 6+require_once("$IP/config.php");
 7+require_once("$IP/wwimages.php");
 8+
 9+if ($wwAPI) require_once("$IP/wwclient.php");
 10+else require_once("$IP/wwthesaurus.php");
 11+
 12+function printLocalConceptList($lang, $concepts) {
 13+ global $utils;
 14+ if (is_string($concepts)) $concepts = $utils->unpickle($concepts, $lang, true, false, true);
 15+
 16+ ?>
 17+ <ul class="terselist">
 18+ <?php
 19+ foreach ($concepts as $c) {
 20+ ?><li><?php
 21+ printLocalConceptLink($lang, $c);
 22+ ?></li><?php
 23+ }
 24+ ?>
 25+ </ul>
 26+ <?php
 27+}
 28+
 29+function printConceptImageList($concept, $class = "terselist") {
 30+ global $utils, $wwThumbSize, $wwMaxPreviewImages;
 31+
 32+ if (is_array($concept) && !isset($concept['id']) && isset($concept[0])) $images = $concept; #XXX: HACK
 33+ else $images = $utils->getImagesAbout($concept, $wwMaxPreviewImages);
 34+
 35+ ?>
 36+ <ul class="<?php print $class; ?>">
 37+ <?php
 38+ foreach ($images as $img) {
 39+ ?><li><?php
 40+ print $utils->getThumbnailHTML($img, $wwThumbSize, $wwThumbSize);
 41+ ?></li><?php
 42+ }
 43+ ?>
 44+ </ul>
 45+ <?php
 46+}
 47+
 48+function printLocalConceptLink($lang, $row) {
 49+ global $wwSelf, $images;
 50+
 51+ $row = normalizeConceptRow($lang, $row);
 52+
 53+ extract($row);
 54+
 55+ if (!isset($weight) && isset($freq)) $weight = $freq;
 56+ if (!isset($weight) && isset($conf)) $weight = $conf;
 57+ if (!isset($concept_name) && isset($name)) $concept_name = $name;
 58+ if (!isset($concept_name)) $concept_name = NULL;
 59+ if (!isset($concept) && isset($id)) $concept = $id;
 60+ if (!isset($concept)) $concept = NULL;
 61+
 62+ if ($lang == 'commons') $domain = 'commons.wikimedia.org';
 63+ else $domain = "$lang.wikipedia.org";
 64+
 65+ $wu = $concept_name ? "http://$domain/wiki/" . urlencode($concept_name) : NULL;
 66+ $cu = "$wwSelf?id=" . urlencode($concept) . "&lang=" . urlencode($lang);
 67+
 68+ if ($images) $cu .= "&images=1";
 69+
 70+ ?>
 71+ <li>
 72+ <?php if ($concept_name) { ?>
 73+ <a href="<?php print htmlspecialchars($cu); ?>"><?php print htmlspecialchars($concept_name); ?></a>
 74+ <?php } ?>
 75+ <?php if ($concept) { ?>
 76+ (<a href="<?php print htmlspecialchars($wu); ?>" title="<?php print htmlspecialchars($concept_name); ?>">wiki page</a>)
 77+ <?php } ?>
 78+ </li>
 79+ <?php
 80+}
 81+
 82+function printTermList($lang, $terms) {
 83+ global $utils;
 84+ if (is_string($terms)) $terms = $utils->unpickle($terms, $lang);
 85+
 86+ ?>
 87+ <ul class="terselist">
 88+ <?php
 89+ foreach ($terms as $t) {
 90+ printTermLink($lang, $terms);
 91+ }
 92+ ?>
 93+ </ul>
 94+ <?php
 95+}
 96+
 97+function printTermLink($lang, $row) {
 98+ global $wwSelf;
 99+
 100+ extract($row);
 101+
 102+ if (!isset($weight) && isset($freq)) $weight = $freq;
 103+ if (!isset($weight) && isset($conf)) $weight = $conf;
 104+ if (!isset($term_text) && isset($term)) $term_text = $term;
 105+ if (!isset($term_text) && isset($text)) $term_text = $text;
 106+ if (!isset($term_text) && isset($name)) $term_text = $name;
 107+ if (!isset($term_text) && isset($value)) $term_text = $value;
 108+
 109+ $tu = "$wwSelf?term=" . urlencode($term_text) . "&lang=" . urlencode($lang);
 110+
 111+ ?>
 112+ <li>
 113+ <a href="<?php print htmlspecialchars($tu); ?>"><?php print htmlspecialchars($term_text); ?></a>
 114+ </li>
 115+ <?php
 116+}
 117+
 118+function normalizeConceptRow($lang, $row) {
 119+ global $wwSelf;
 120+
 121+ #FIXME: handle complex concept records!
 122+
 123+ if (!$row) return $row;
 124+
 125+ if (!isset($row['lang'])) $row['lang'] = $lang;
 126+ if (!isset($row['weight']) && isset($row['freq'])) $row['weight'] = $row['freq'];
 127+ if (!isset($row['weight']) && isset($row['conf'])) $row['weight'] = $row['conf'];
 128+ if (!empty($row['local_concept_name'])) $row['concept_name'] = $row['local_concept_name'];
 129+ if (!isset($row['concept_name']) && isset($row['name'])) $row['concept_name'] = $row['name'];
 130+ if (!isset($row['concept_name']) && isset($row['global_concept_name'])) $row['concept_name'] = $row['global_concept_name'];
 131+ if (!isset($row['reference_id']) && isset($row['global_id'])) $row['reference_id'] = $row['global_id'];
 132+ if (!isset($row['reference_id']) && isset($row['global_concept'])) $row['reference_id'] = $row['global_concept'];
 133+ if (!isset($row['reference_id']) && isset($row['concept'])) $row['reference_id'] = $row['concept'];
 134+ if (!isset($row['reference_id']) && isset($row['id'])) $row['reference_id'] = $row['id'];
 135+ if (!empty($row['definition']) && is_array($row['definition'])) $row['definition'] = $row['definition'][$lang];
 136+
 137+ #print "<pre>";
 138+ #print_r($row);
 139+ #print "</pre>";
 140+
 141+ $row['wu'] = "http://$lang.wikipedia.org/wiki/" . urlencode($row['concept_name']);
 142+ #$row['cu'] = "$wwSelf?id=" . urlencode($row['concept']) . "&lang=" . urlencode($lang);
 143+ $row['cu'] = "$wwSelf?id=" . urlencode($row['reference_id']) . "&lang=" . urlencode($lang);
 144+ $row['gu'] = "$wwSelf?id=" . urlencode($row['reference_id']) . "&images=g";
 145+
 146+ if (!isset($row['weight']) || !$row['weight']) {
 147+ $row['wclass'] = "unknown";
 148+ $row['weight'] = NULL;
 149+ }
 150+ else if ($row['weight']>1000) $row['wclass'] = "huge";
 151+ else if ($row['weight']>100) $row['wclass'] = "big";
 152+ else if ($row['weight']>10) $row['wclass'] = "normal";
 153+ else if ($row['weight']>2) $row['wclass'] = "some";
 154+ else $row['wclass'] = "little";
 155+
 156+ return $row;
 157+}
 158+
 159+function printLocalConcept($a_lang, $a_row, $b_lang, $b_row, $pos = 0, $terse = true) {
 160+ global $wwSelf, $images, $utils;
 161+ global $wwMaxPreviewImages, $wwMaxGalleryImages;
 162+
 163+ $a_row = normalizeConceptRow($a_lang, $a_row);
 164+ $b_row = normalizeConceptRow($b_lang, $b_row);
 165+
 166+ if ($a_lang && $a_row) extract($a_row, EXTR_PREFIX_ALL, "a");
 167+ if ($b_lang && $b_row) extract($b_row, EXTR_PREFIX_ALL, "b");
 168+
 169+ ?>
 170+ <tr class="row_item">
 171+ <td class="cell_weight <?php print "weight_$a_wclass"; ?>"><?php print htmlspecialchars($a_weight); ?></td>
 172+ <td colspan="3" class="cell_name <?php print "weight_$a_wclass"; ?>">
 173+ <h3>
 174+ <a href="<?php print htmlspecialchars($a_cu); ?>"><?php print htmlspecialchars($a_concept_name); ?></a>
 175+ <span class="conceptref">(<a href="<?php print htmlspecialchars($a_wu); ?>" title="<?php print htmlspecialchars($a_concept_name); ?>">wiki page</a>)</span>
 176+ </h3>
 177+ </td>
 178+ <?php if ($b_row) { ?>
 179+ <td colspan="3" class="cell_name <?php print "weight_$b_wclass"; ?>">
 180+ <h3>
 181+ <a href="<?php print htmlspecialchars($b_cu); ?>"><?php print htmlspecialchars($b_concept_name); ?></a>
 182+ <span class="conceptref">(<a href="<?php print htmlspecialchars($b_wu); ?>" title="<?php print htmlspecialchars($b_concept_name); ?>">wiki page</a>)</span>
 183+ </h3>
 184+ </td>
 185+ <?php } ?>
 186+ </tr>
 187+
 188+ <?php if (isset($a_definition) && !empty($a_definition)) { ?>
 189+ <tr class="row_def">
 190+ <td></td>
 191+ <td class="cell_label">Definition:</td>
 192+ <td colspan="2"><?php print htmlspecialchars($a_definition); ?></td>
 193+ <?php if ($b_row) { ?>
 194+ <td class="cell_label">Definition:</td>
 195+ <td colspan="2"><?php print htmlspecialchars($b_definition); ?></td>
 196+ <?php } ?>
 197+ </tr>
 198+ <?php } ?>
 199+
 200+ <?php if (isset($a_terms) && !empty($a_terms)) { ?>
 201+ <tr class="row_details row_terms">
 202+ <td></td>
 203+ <td class="cell_label">Terms:</td>
 204+ <td class="cell_terms" colspan="2"><?php printTermList($a_lang, $a_terms); ?></td>
 205+ <?php if ($b_row) { ?>
 206+ <td class="cell_label">Terms:</td>
 207+ <td class="cell_terms" colspan="2"><?php printTermList($b_lang, $b_terms); ?></td>
 208+ <?php } ?>
 209+ </tr>
 210+ <?php } ?>
 211+
 212+ <?php if ($images) { ?>
 213+ <tr class="row_details row_images">
 214+ <td></td>
 215+ <td class="cell_label">Images:</td>
 216+ <td class="cell_broader" colspan="<?php $b_row ? 5 : 2 ?>">
 217+ <?php
 218+ $gallery = $utils->getImagesAbout($a_reference_id, $terse ? $wwMaxPreviewImages : $wwMaxGalleryImages );
 219+ $c = printConceptImageList( $gallery, $terse ? "terselist" : "gallery" );
 220+ ?>
 221+ </td>
 222+ </tr>
 223+ <?php } ?>
 224+
 225+ <?php if (isset($a_similar) && !empty($a_similar)) { ?>
 226+ <tr class="row_details row_similar">
 227+ <td></td>
 228+ <td class="cell_label">Similar:</td>
 229+ <td class="cell_similar" colspan="2"><?php printLocalConceptList($a_lang, $a_similar); ?></td>
 230+ <?php if ($b_row) { ?>
 231+ <td class="cell_label">Similar:</td>
 232+ <td class="cell_similar" colspan="2"><?php printLocalConceptList($b_lang, $b_similar); ?></td>
 233+ <?php } ?>
 234+ </tr>
 235+ <?php } ?>
 236+
 237+ <?php if (isset($a_related) && !empty($a_related)) { ?>
 238+ <tr class="row_details row_related">
 239+ <td></td>
 240+ <td class="cell_label">Related:</td>
 241+ <td class="cell_related" colspan="2"><?php printLocalConceptList($a_lang, $a_related); ?></td>
 242+ <?php if ($b_row) { ?>
 243+ <td class="cell_label">Related:</td>
 244+ <td class="cell_related" colspan="2"><?php printLocalConceptList($b_lang, $b_related); ?></td>
 245+ <?php } ?>
 246+ </tr>
 247+ <?php } ?>
 248+
 249+ <?php if (isset($a_narrower) && !empty($a_narrower)) { ?>
 250+ <tr class="row_details row_narrower">
 251+ <td></td>
 252+ <td class="cell_label">Narrower:</td>
 253+ <td class="cell_narrower" colspan="2"><?php printLocalConceptList($a_lang, $a_narrower); ?></td>
 254+ <?php if ($b_row) { ?>
 255+ <td class="cell_label">Narrower:</td>
 256+ <td class="cell_narrower" colspan="2"><?php printLocalConceptList($b_lang, $b_narrower); ?></td>
 257+ <?php } ?>
 258+ </tr>
 259+ <?php } ?>
 260+
 261+ <?php if (isset($a_broader) && !empty($a_broader)) { ?>
 262+ <tr class="row_details row_broader">
 263+ <td></td>
 264+ <td class="cell_label">Broader:</td>
 265+ <td class="cell_broader" colspan="2"><?php printLocalConceptList($a_lang, $a_broader); ?></td>
 266+ <?php if ($b_row) { ?>
 267+ <td class="cell_label">Broader:</td>
 268+ <td class="cell_broader" colspan="2"><?php printLocalConceptList($b_lang, $b_broader); ?></td>
 269+ <?php } ?>
 270+ </tr>
 271+ <?php } ?>
 272+
 273+ <?php
 274+ if (isset($a_weight) && $a_weight && $a_weight<2 && $pos>=3) return false;
 275+ else return true;
 276+}
 277+
 278+$concept = @$_REQUEST['id'];
 279+$term = @$_REQUEST['term'];
 280+$lang = @$_REQUEST['lang'];
 281+$tolang = @$_REQUEST['tolang'];
 282+$images = (@$_REQUEST['images'] || $wwImageSearch === true ) && !($wwImageSearch === false);
 283+
 284+if (!isset($_REQUEST['translate'])) $tolang = NULL;
 285+if ($lang == $tolang) $tolang = NULL;
 286+
 287+if (!isset($wwSelf)) $wwSelf = @$_SERVER["PHP_SELF"];
 288+
 289+$error = NULL;
 290+
 291+if ($lang && !isset($wwLanguages[$lang])) {
 292+ $lang = NULL;
 293+ $error = "bad language code: $lang";
 294+}
 295+
 296+if ($wwAPI) $thesaurus = new WWClient($wwAPI);
 297+else {
 298+ $thesaurus = new WWThesaurus();
 299+ $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
 300+}
 301+
 302+$utils = new WWImages( $thesaurus );
 303+if ( !$utils->db ) $utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
 304+
 305+if (@$_REQUEST['debug']) $utils->debug = true;
 306+
 307+$limit = 20;
 308+
 309+$result = NULL;
 310+
 311+if (!$error) {
 312+ try {
 313+ if ($lang && $concept) {
 314+ $result = $thesaurus->getConceptInfo($concept, $lang);
 315+ if ( $result ) $result = array( $result ); //hack
 316+ } else if ($lang && $term) {
 317+ $result = $thesaurus->getConceptsForTerm($lang, $term, $limit);
 318+ }
 319+ } catch (Exception $e) {
 320+ $error = $e->getMessage();
 321+ }
 322+}
 323+
 324+
 325+?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 326+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
 327+<head>
 328+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 329+ <title>WikiWord Navigator</title>
 330+
 331+ <style type="text/css">
 332+ body { font-family: verdana, helvetica, arial, sans-serif; }
 333+ td { text-align: left; vertical-align: top; }
 334+ th { text-align: left; vertical-align: top; font-weight:bold; }
 335+ .error { color: red; font-weight: bold; }
 336+ .weight_huge { font-size: 140%; font-weight:bold; }
 337+ .weight_big { font-size: 120%; font-weight:bold; }
 338+ .weight_normal { font-size: 110%; font-weight:bold; }
 339+ .weight_some { font-size: 100%; font-weight:bold; }
 340+ .weight_little { font-size: 90%; font-weight:bold; }
 341+ .weight_unknown { font-size: 100%; font-weight:bold; }
 342+ .row_def td { font-size: 80%; font-style:italic; }
 343+ .row_details td { font-size: 80%; }
 344+ .cell_weight { text-align: right; }
 345+ .cell_label { text-align: right; }
 346+ .header { text-align: left; }
 347+ .inputform { text-align: center; margin:1ex auto; padding:1ex; width:80%; border:1px solid #666666; background-color:#DDDDDD; }
 348+ .footer { font-size:80%; text-align: center; border-top: 1px solid #666666; }
 349+ .note { font-size:80%; }
 350+ .terselist, .terselist li { display: inline; margin:0; padding:0; }
 351+ .terselist li { display: inline; }
 352+ .terselist li:before { content:" - " }
 353+ .terselist li:first-child:before { content:"" }
 354+
 355+ .gallery li { display: inline; padding:0.5ex; margin:0.5ex; }
 356+ </style>
 357+</head>
 358+<body>
 359+ <div class="header">
 360+ <h1>WikiWord Navigator</h1>
 361+ <p>Experimental semantic navigator and thesaurus interface for Wikipedia.</p>
 362+ <p>The WikiWord Navigator was created as part of the WikiWord project run by <a href="http://wikimedia.de">Wikimedia Deutschland e.V.</a>.
 363+ It is based on a <a href="http://brightbyte.de/page/WikiWord">diploma thesis</a> by Daniel Kinzler, and runs on the <a href="http://toolserver.org/">Wikimedia Toolserver</a>. WikiWord is an ongoing research project. Please contact <a href="http://brightbyte.de/page/Special:Contact">Daniel Kinzler</a> for more information.</p>
 364+ </div>
 365+
 366+ <div class="inputform" >
 367+ <form name="search" action="<?php print $wwSelf; ?>">
 368+ <table border="0" class="inputgrid">
 369+ <tr>
 370+ <td>
 371+ <label for="term">Term: </label><input type="text" name="term" id="term" size="24" value="<?php print htmlspecialchars($term); ?>"/>
 372+ </td>
 373+ <td>
 374+ <label for="term" style="display:none">Language: </label>
 375+ <?php WWUtils::printSelector("lang", $wwLanguages, $lang) ?>
 376+ </td>
 377+ <td>
 378+ <input type="submit" name="go" value="go"/>
 379+ </td>
 380+ <?php if ($wwImageSearch === null) { ?>
 381+ <td>
 382+ <label for="images">Images: </label>
 383+ <input type="checkbox" name="images" value="Images" <?php print $images ? " checked=\"checked\"" : ""?>/>
 384+ </td>
 385+ <?php } ?>
 386+ </tr>
 387+ <?php if ($wwAllowTranslate) { ?>
 388+ <tr>
 389+ <td>
 390+ &nbsp;
 391+ </td>
 392+ <td>
 393+ <label for="term" style="display:none">Translate: </label>
 394+ <?php WWUtils::printSelector("tolang", $wwLanguages, @$_REQUEST['tolang']) ?>
 395+ </td>
 396+ <td>
 397+ <input type="submit" name="translate" value="translate"/>
 398+ </td>
 399+ </tr>
 400+ <?php } ?>
 401+ </table>
 402+ <p class="note">Note: this is a thesaurus lookup, not a full text search. Only exact matches are considered, matching is case-sensitive.</p>
 403+ </form>
 404+ </div>
 405+<?php
 406+if ($error) {
 407+ print "<p class=\"error\">".htmlspecialchars($error)."</p>";
 408+}
 409+?>
 410+
 411+<?php
 412+if ($result && $concept) {
 413+ foreach ( $result as $row ) {
 414+ if (@$row['id']) $id = $row['id'];
 415+ else if (@$row['concept']) $id = $row['concept'];
 416+ else $id = "concept";
 417+
 418+?>
 419+ <div id="<?php print htmlspecialchars("concept-$id")?>">
 420+
 421+ <table border="0" class="results">
 422+ <?php
 423+ if ($lang) {
 424+ $continue= printLocalConcept($lang, $row, NULL, NULL, 0, false);
 425+ }
 426+ //else $continue= printGlobalConcept($lang, $row, $count);
 427+
 428+ if (!$continue) break;
 429+ ?>
 430+ </table>
 431+ </div>
 432+
 433+<?php
 434+ } #concept loop
 435+} else if ($result && $term) {
 436+ if ($tolang) $title = "$lang: $term -> $tolang";
 437+ else if ($term) $title = "$lang: $term";
 438+?>
 439+ <h2><?php print htmlspecialchars($title); ?></h2>
 440+ <table border="0" class="results">
 441+ <?php
 442+ $count = 0;
 443+ foreach ( $result as $row ) {
 444+ $count += 1;
 445+
 446+ if ($lang) {
 447+ $show_single = true;
 448+
 449+ if ($tolang && isset($row['global_concept'])) {
 450+ $toresult = $utils->queryConceptInfo($row['global_concept'], $tolang);
 451+ while ($torow = mysql_fetch_assoc($toresult)) {
 452+ $continue= printLocalConcept($lang, $row, $tolang, $torow, $count, true);
 453+ $show_single = false;
 454+ }
 455+ mysql_free_result($toresult);
 456+ }
 457+
 458+ if ($show_single) {
 459+ $continue= printLocalConcept($lang, $row, NULL, NULL, $count, true);
 460+ }
 461+ }
 462+ //else $continue= printGlobalConcept($lang, $row, $count);
 463+
 464+ if (!$continue) break;
 465+ }
 466+ ?>
 467+ </table>
 468+
 469+ <p>Found <?php print $count; ?> items.</p>
 470+
 471+<?php
 472+}
 473+?>
 474+
 475+<p class="footer">
 476+The WikiWord Navigator is part of the <a href="http://wikimedia.de">Wikimedia</a> project <a href="http://brightbyte.de/page/WikiWord">WikiWord</a>
 477+<p>
 478+</body>
 479+</html>
 480+<?php
 481+$utils->close();
 482+?>
\ No newline at end of file
Property changes on: trunk/WikiWord/WikiWord/src/main/php/search/wikiword.php
___________________________________________________________________
Name: svn:mergeinfo
1483 +
Index: trunk/WikiWord/WikiWord/src/main/php/search/wikipics.php
@@ -0,0 +1,340 @@
 2+<?php
 3+
 4+$IP = dirname(__FILE__);
 5+
 6+require_once("$IP/config.php");
 7+require_once("$IP/wwimages.php");
 8+
 9+if ($wwAPI) require_once("$IP/wwclient.php");
 10+else require_once("$IP/wwthesaurus.php");
 11+
 12+function printConceptList($concepts, $lang) {
 13+ ?>
 14+ <ul class="terselist">
 15+ <?php
 16+ foreach ($concepts as $c) {
 17+ ?><li><?php
 18+ print getConceptDetailsLink($lang, $c);
 19+ ?></li><?php
 20+ }
 21+ ?>
 22+ </ul>
 23+ <?php
 24+}
 25+
 26+function printConceptImageList($concept, $class = "terselist") {
 27+ global $utils, $wwThumbSize, $wwMaxPreviewImages;
 28+
 29+ if (!$concept) return false;
 30+
 31+ if (is_array($concept) && !isset($concept['id']) && isset($concept[0])) $images = $concept; #XXX: HACK
 32+ else $images = $utils->getImagesAbout($concept, $wwMaxPreviewImages);
 33+
 34+ ?>
 35+ <ul class="<?php print $class; ?>">
 36+ <?php
 37+ foreach ($images as $img) {
 38+ ?><li><?php
 39+ print $utils->getThumbnailHTML($img, $wwThumbSize, $wwThumbSize);
 40+ ?></li><?php
 41+ }
 42+ ?>
 43+ </ul>
 44+ <?php
 45+}
 46+
 47+function getConceptDetailsURL($langs, $concept) {
 48+ global $wwSelf;
 49+
 50+ if ( is_array($langs) ) $langs = implode('|', $langs);
 51+
 52+ return "$wwSelf?id=" . urlencode($concept['id']) . "&lang=" . urlencode($langs);
 53+}
 54+
 55+function getConceptDetailsLink($langs, $concept) {
 56+ global $utils;
 57+ $name = $utils->pickLocal($concept['name'], $langs);
 58+
 59+ $u = getConceptDetailsURL($langs, $concept);
 60+ return '<a href="' . htmlspecialchars($u) . '">' . htmlspecialchars($name) . '</a>';
 61+}
 62+
 63+function pickPage( $pages ) {
 64+ if (!$pages) return false;
 65+
 66+ foreach ( $pages as $page => $type ) {
 67+ if ($type == 10) return $page;
 68+ }
 69+
 70+ return $pages[0];
 71+}
 72+
 73+function getConceptPageURLs($lang, $concept) {
 74+ if (!isset($concept['pages'][$lang]) || !$concept['pages'][$lang]) return false;
 75+
 76+ if ($lang == 'commons') $domain = 'commons.wikimedia.org';
 77+ else $domain = "$lang.wikipedia.org";
 78+
 79+ $urls = array();
 80+ foreach ($concept['pages'][$lang] as $page => $type) {
 81+ $u = "http://$domain/wiki/" . urlencode($page);
 82+ $links[$page] = $u;
 83+ }
 84+
 85+ return $urls;
 86+}
 87+
 88+function getConceptPageLinks($lang, $concept) {
 89+ $urls = getConceptPageURLs($lang, $concept);
 90+ if (!$urls) return false;
 91+
 92+ foreach ($urls as $page => $u) {
 93+ $u = "http://$domain/wiki/" . urlencode($page);
 94+ $links[] = '<a href="' . htmlspecialchars($u) . '">' . htmlspecialchars( str_replace("_", " ", $page) ) . '</a>';
 95+ }
 96+
 97+ return $links;
 98+}
 99+
 100+function getAllConceptPageLinks($concept) {
 101+ $links = array();
 102+
 103+ foreach ( $concept['languages'] as $lang ) {
 104+ $ll = getConceptPageLinks($lang, $concept);
 105+ if ($ll) $links[$lang] = $ll;
 106+ }
 107+
 108+ return $links;
 109+}
 110+
 111+function printList($items, $escape = true, $class = "list") {
 112+ ?>
 113+ <ul class="<?php print htmlspecialchars($class); ?>">
 114+ <?php
 115+ foreach ($items as $item) {
 116+ if ( $escape ) $item = htmlspecialchars($item);
 117+ print "\t\t<li>" . $item . "</li>\n";
 118+ }
 119+ ?>
 120+ </ul>
 121+ <?php
 122+}
 123+
 124+function printDefList($items, $scapeKeys = true, $escapeValues = true, $class = "list") {
 125+ ?>
 126+ <dl class="<?php print htmlspecialchars($class); ?>">
 127+ <?php
 128+ foreach ($items as $key => $item) {
 129+ if ( $escapeKeys ) $key = htmlspecialchars($key);
 130+ print "\t\t<dt>" . $key . "</dt>\n";
 131+
 132+ if ( $escapeValues ) $item = htmlspecialchars($item);
 133+ print "\t\t\t<dd>" . $item . "</dd>\n";
 134+ }
 135+ ?>
 136+ </sl>
 137+ <?php
 138+}
 139+
 140+function getWeightClass($weight) {
 141+ if (!isset($weight) || !$weight) {
 142+ return "unknown";
 143+ $weight = NULL;
 144+ }
 145+ else if ($weight>1000) return "huge";
 146+ else if ($weight>100) return "big";
 147+ else if ($weight>10) return "normal";
 148+ else if ($weight>2) return "some";
 149+ else return "little";
 150+}
 151+
 152+function printConcept($concept, $langs, $terse = true) {
 153+ global $utils, $wwMaxPreviewImages, $wwMaxGalleryImages;
 154+
 155+ extract( $concept );
 156+ $wclass = getWeightClass($score);
 157+
 158+ ?>
 159+ <tr class="row_item">
 160+ <td class="cell_weight <?php print "weight_$wclass"; ?>"><?php print htmlspecialchars($score); ?></td>
 161+ <td colspan="3" class="cell_name <?php print "weight_$wclass"; ?>">
 162+ <h3>
 163+ <?php print getConceptDetailsLink($langs, $concept); ?>
 164+ <?php /* TODO: wiki links */ ?>
 165+ </h3>
 166+ </td>
 167+ </tr>
 168+
 169+ <?php if (isset($definition) && !empty($definition)) {
 170+ $definition = $utils->pickLocal($definition, $langs);
 171+ ?>
 172+
 173+ <tr class="row_def">
 174+ <td></td>
 175+ <td colspan="3"><?php print htmlspecialchars($definition); ?></td>
 176+ </tr>
 177+ <?php } ?>
 178+
 179+ <tr class="row_details row_images">
 180+ <td></td>
 181+ <td class="cell_images" colspan="3">
 182+ <?php
 183+ $gallery = $utils->getImagesAbout($concept, $terse ? $wwMaxPreviewImages : $wwMaxGalleryImages );
 184+ $c = printConceptImageList( $gallery, $terse ? "terselist" : "gallery" );
 185+ ?>
 186+ </td>
 187+ </tr>
 188+
 189+
 190+ <?php
 191+ if (isset($score) && $score && $score<2 && $pos>=3) return false;
 192+ else return true;
 193+}
 194+
 195+$conceptId = @$_REQUEST['id'];
 196+$term = @$_REQUEST['term'];
 197+$lang = @$_REQUEST['lang'];
 198+
 199+if (!isset($wwSelf)) $wwSelf = @$_SERVER["PHP_SELF"];
 200+
 201+$error = NULL;
 202+
 203+if ($lang && !isset($wwLanguages[$lang])) {
 204+ $lang = NULL;
 205+ $error = "bad language code: $lang";
 206+}
 207+
 208+if ($wwAPI) $thesaurus = new WWClient($wwAPI);
 209+else {
 210+ $thesaurus = new WWThesaurus();
 211+ $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
 212+}
 213+
 214+$utils = new WWImages( $thesaurus );
 215+if ( !$utils->db ) $utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
 216+
 217+if (@$_REQUEST['debug']) $utils->debug = true;
 218+
 219+$limit = 20;
 220+$norm = 1;
 221+
 222+$result = NULL;
 223+
 224+$languages = array( $lang, "en", "commons" ); #TODO: make the user define this list
 225+
 226+if (!$error) {
 227+ try {
 228+ if ($lang && $conceptId) {
 229+ $result = $thesaurus->getConceptInfo($conceptId, $lang);
 230+ if ( $result ) $result = array( $result ); //hack
 231+ } else if ($lang && $term) {
 232+ $result = $thesaurus->getConceptsForTerm($lang, $term, $languages, $norm, $limit);
 233+ }
 234+ } catch (Exception $e) {
 235+ $error = $e->getMessage();
 236+ }
 237+}
 238+
 239+
 240+?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 241+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
 242+<head>
 243+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 244+ <title>WikiWord Navigator</title>
 245+
 246+ <style type="text/css">
 247+ body { font-family: verdana, helvetica, arial, sans-serif; }
 248+ td { text-align: left; vertical-align: top; }
 249+ th { text-align: left; vertical-align: top; font-weight:bold; }
 250+ .error { color: red; font-weight: bold; }
 251+ .weight_huge { font-size: 140%; font-weight:bold; }
 252+ .weight_big { font-size: 120%; font-weight:bold; }
 253+ .weight_normal { font-size: 110%; font-weight:bold; }
 254+ .weight_some { font-size: 100%; font-weight:bold; }
 255+ .weight_little { font-size: 90%; font-weight:bold; }
 256+ .weight_unknown { font-size: 100%; font-weight:bold; }
 257+ .row_def td { font-size: 80%; font-style:italic; }
 258+ .row_details td { font-size: 80%; }
 259+ .cell_weight { text-align: right; }
 260+ .cell_label { text-align: right; }
 261+ .header { text-align: left; }
 262+ .inputform { text-align: center; margin:1ex auto; padding:1ex; width:80%; border:1px solid #666666; background-color:#DDDDDD; }
 263+ .footer { font-size:80%; text-align: center; border-top: 1px solid #666666; }
 264+ .note { font-size:80%; }
 265+ .terselist, .terselist li { display: inline; margin:0; padding:0; }
 266+ .terselist li { display: inline; }
 267+ .terselist li:before { content:" - " }
 268+ .terselist li:first-child:before { content:"" }
 269+
 270+ .gallery li { display: inline; padding:0.5ex; margin:0.5ex; }
 271+ </style>
 272+</head>
 273+<body>
 274+ <div class="header">
 275+ <h1>WikiWord Navigator</h1>
 276+ <p>Experimental semantic navigator and thesaurus interface for Wikipedia.</p>
 277+ <p>The WikiWord Navigator was created as part of the WikiWord project run by <a href="http://wikimedia.de">Wikimedia Deutschland e.V.</a>.
 278+ It is based on a <a href="http://brightbyte.de/page/WikiWord">diploma thesis</a> by Daniel Kinzler, and runs on the <a href="http://toolserver.org/">Wikimedia Toolserver</a>. WikiWord is an ongoing research project. Please contact <a href="http://brightbyte.de/page/Special:Contact">Daniel Kinzler</a> for more information.</p>
 279+ </div>
 280+
 281+ <div class="inputform" >
 282+ <form name="search" action="<?php print $wwSelf; ?>">
 283+ <table border="0" class="inputgrid">
 284+ <tr>
 285+ <td>
 286+ <label for="term">Term: </label><input type="text" name="term" id="term" size="24" value="<?php print htmlspecialchars($term); ?>"/>
 287+ </td>
 288+ <td>
 289+ <label for="term" style="display:none">Language: </label>
 290+ <?php WWUtils::printSelector("lang", $wwLanguages, $lang) ?>
 291+ </td>
 292+ <td>
 293+ <input type="submit" name="go" value="go"/>
 294+ </td>
 295+ </tr>
 296+ </table>
 297+ <p class="note">Note: this is a thesaurus lookup, not a full text search. Only exact matches are considered.</p>
 298+ </form>
 299+ </div>
 300+<?php
 301+if ($error) {
 302+ print "<p class=\"error\">".htmlspecialchars($error)."</p>";
 303+}
 304+?>
 305+
 306+<?php
 307+if ($result) {
 308+ if ( $conceptId ) $terse = false;
 309+ else $terse = true;
 310+
 311+ $count = 0;
 312+ foreach ( $result as $row ) {
 313+ $count = $count + 1;
 314+ $row['pos'] = $count;
 315+
 316+?>
 317+ <table border="0" class="results">
 318+ <?php
 319+ $continue= printConcept($row, $languages, $terse);
 320+
 321+ if (!$continue) break;
 322+ ?>
 323+ </table>
 324+ </div>
 325+
 326+<?php
 327+ } #concept loop
 328+
 329+ if ($term) { ?>
 330+ <p>Found <?php print $count; ?> items.</p>
 331+ <?php }
 332+} ?>
 333+
 334+<p class="footer">
 335+The WikiWord Navigator is part of the <a href="http://wikimedia.de">Wikimedia</a> project <a href="http://brightbyte.de/page/WikiWord">WikiWord</a>
 336+<p>
 337+</body>
 338+</html>
 339+<?php
 340+$utils->close();
 341+?>
\ No newline at end of file
Property changes on: trunk/WikiWord/WikiWord/src/main/php/search/wikipics.php
___________________________________________________________________
Name: svn:mergeinfo
1342 +
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwclient.php
@@ -0,0 +1,152 @@
 2+<?php
 3+require_once( dirname( __FILE__ ) . "/wwutils.php" );
 4+
 5+class WWClient {
 6+ var $api;
 7+
 8+ function __construct( $api ) {
 9+ $this->api = $api;
 10+ }
 11+
 12+ function query( $params ) {
 13+ $url = $this->api . '?format=phps';
 14+
 15+ foreach ( $params as $k => $v ) {
 16+ if ($v===null) continue;
 17+ if ($v===false) $v = "";
 18+ if (is_array($v)) $v = implode("|", $v);
 19+
 20+ $url .= '&';
 21+ $url .= urlencode( $k );
 22+ $url .= '=';
 23+ $url .= urlencode( $v );
 24+ }
 25+
 26+ $data = file_get_contents( $url ); //TODO: CURL
 27+ if ( !$data ) throw new Exception("failed to fetch data from $url");
 28+
 29+ $data = unserialize($data);
 30+ if ( !$data ) throw new Exception("failed to unserialize data from $url");
 31+
 32+ if ( @$data['error'] ) throw new Exception("API returned error ".$data['error']['code'].": ".$data['error']['message']."; url: $url");
 33+ return $data;
 34+ }
 35+
 36+ function getPagesForConcept( $id, $lang = null ) {
 37+ $p = $this->getConceptInfo( $id, $lang );
 38+ return $p['pages'];
 39+ }
 40+
 41+ /*
 42+ function getLocalConcepts($id) { //NOTE: deprecated alias for backward compat
 43+ return getPagesForConcept($id);
 44+ }
 45+
 46+ function getConcept( $id, $lang = null ) {
 47+ $p = $this->getConceptProperties( $id, '', $lang );getConceptInfo
 48+ return $p['pages'];
 49+ }
 50+
 51+ function getRelatedForConcept( $id, $lang = null ) {
 52+ $p = $this->getConceptProperties( $id, 'related', $lang );
 53+ return $p['related'];
 54+ }
 55+
 56+ function getBroaderForConcept( $id, $lang = null ) {
 57+ $p = $this->getConceptProperties( $id, 'broader', $lang );
 58+ return $p['broader'];
 59+ }
 60+
 61+ function getNarrowerForConcept( $id, $lang = null ) {
 62+ $p = $this->getConceptProperties( $id, 'narrower', $lang );
 63+ return $p['narrower'];
 64+ }
 65+
 66+ function getTermsForConcept( $id, $lang = null ) {
 67+ $p = $this->getConceptProperties( $id, 'terms', $lang );
 68+ return $p['terms'];
 69+ }
 70+
 71+ function getDefinitionForConcept( $id, $lang = null ) {
 72+ $p = $this->getConceptProperties( $id, 'definition', $lang );
 73+ return $p['definition'];
 74+ }
 75+
 76+ function getReferencesForConcept( $id, $lang = null ) {
 77+ $p = $this->getConceptProperties( $id, 'links', $lang );
 78+ return $p['references'];
 79+ }
 80+
 81+ function getLinksForConcept( $id, $lang = null ) {
 82+ $p = $this->getConceptProperties( $id, 'links', $lang );
 83+ return $p['links'];
 84+ }
 85+
 86+ function getScoresForConcept( $id, $lang = null ) {
 87+ $p = $this->getConceptProperties( $id, 'scores', $lang );
 88+ return $p['scores'];
 89+ }*/
 90+
 91+ function getConceptInfo( $id, $lang = null ) {
 92+ $param = array(
 93+ 'query' => 'info',
 94+ 'gcid' => $id,
 95+ 'lang' => $lang
 96+ );
 97+
 98+ $rs = $this->query( $param );
 99+
 100+ if (!isset($rs['id'])) $rs['id'] = $id;
 101+ if (!isset($rs['lang'])) $rs['lang'] = $lang;
 102+
 103+ return $rs;
 104+ }
 105+
 106+ /*
 107+ function getConceptProperties( $id, $props, $lang =$props null ) {
 108+ $param = array(
 109+ 'query' => 'properties',
 110+ 'props' => ( is_array($props) ? join('|', $props) : $props ),
 111+ 'gcid' => $id,
 112+ );
 113+
 114+ if ( $lang ) $param['lang'] = $lang;
 115+
 116+ $rs = $this->query( $param );
 117+
 118+ if (!isset($rs['id'])) $rs['id'] = $id;
 119+ if (!isset($rs['lang'])) $rs['lang'] = $lang;
 120+
 121+ return $rs;
 122+ }*/
 123+
 124+ function getConceptsForTerm( $qlang, $term, $languages, $norm = 1, $limit = 100 ) {
 125+ if ( is_array( $languages ) ) $languages = implode('|', $languages);
 126+
 127+ $param = array(
 128+ 'query' => 'concepts',
 129+ 'qlang' => $qlang,
 130+ 'lang' => $languages,
 131+ 'norm' => $norm,
 132+ 'term' => $term,
 133+ );
 134+
 135+ $rs = $this->query( $param );
 136+
 137+ return $rs['concepts'];
 138+ }
 139+
 140+ /*
 141+ function getConceptsForPage( $lang, $page ) {
 142+ $param = array(
 143+ 'query' => 'concepts',
 144+ 'lang' => $lang,
 145+ 'page' => $page,
 146+ );
 147+
 148+ $rs = $this->query( $param );
 149+
 150+ return $rs['concepts'];
 151+ }
 152+ */
 153+}
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwclient.php
___________________________________________________________________
Name: svn:mergeinfo
1154 +
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwtest.php
@@ -0,0 +1,20 @@
 2+<?php
 3+
 4+$IP = dirname(__FILE__);
 5+
 6+require_once("$IP/config.php");
 7+require_once("$IP/wwutils.php");
 8+
 9+$utils = new WWUtils();
 10+$utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
 11+
 12+$utils->debug = true;
 13+
 14+if (!isset($argv[1])) die("usage: wwtest <id>\n");
 15+
 16+$id = $argv[1];
 17+$max = @$argv[2];
 18+
 19+$images = $utils->getImagesAbout($id, $max);
 20+
 21+print_r($images);
\ No newline at end of file
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwtest.php
___________________________________________________________________
Name: svn:mergeinfo
122 +
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwutils.php
@@ -0,0 +1,200 @@
 2+<?php
 3+
 4+class WWUtils {
 5+ var $debug = false;
 6+ var $db = NULL;
 7+
 8+ var $dbuser;
 9+ var $dbpassword;
 10+
 11+ function connect($server, $user, $password, $database) {
 12+ $db = mysql_connect($server, $user, $password) or die("Connection Failure to Database: " . htmlspecialchars(mysql_error())."\n");
 13+ mysql_select_db($database, $db) or die ("Database not found: " . htmlspecialchars(mysql_error())."\n");
 14+ mysql_query("SET NAMES UTF8;", $db) or die ("Database not found: " . htmlspecialchars(mysql_error())."\n");
 15+
 16+ $this->dbuser = $user;
 17+ $this->dbpassword = $password;
 18+ $this->db = $db;
 19+
 20+ return $db;
 21+ }
 22+
 23+ function query($sql, $db = NULL) {
 24+ if ($db == NULL && isset($this)) $db = $this->db;
 25+
 26+ if ($this->debug) {
 27+ print "\n<br/>" . htmlspecialchars($sql) . "<br/>\n";
 28+ }
 29+
 30+ if (!$db) {
 31+ throw new Exception("not connected!");
 32+ }
 33+
 34+ $result = mysql_query($sql, $db);
 35+
 36+ if(!$result) {
 37+ $error = mysql_error($db);
 38+ $errno = mysql_errno($db);
 39+ throw new Exception("$error (#$errno);\nlast query: $sql");
 40+ }
 41+
 42+ return $result;
 43+ }
 44+
 45+ function quote($s) {
 46+ if (is_array($s)) throw new Exception("can't quote arrays, use quoteSet() instead.");
 47+ if (is_null($s)) return "NULL";
 48+
 49+ return '"' . mysql_real_escape_string($s) . '"';
 50+ }
 51+
 52+ function quoteSet($a) {
 53+ if (!$a) throw new Exception("empty set literal not supported by mysql");
 54+
 55+ if ( !is_array($a) ) $a = array( $a );
 56+
 57+ $s = "";
 58+
 59+ foreach ($a as $x) {
 60+ if ($s) $s.= ", ";
 61+
 62+ if (is_string($x)) $s .= $this->quote($x);
 63+ else $s .= $x;
 64+ }
 65+
 66+ return '(' . $s . ')';
 67+ }
 68+
 69+ function close() {
 70+ if ($this->db) mysql_close($this->db);
 71+ $this->db = NULL;
 72+
 73+ foreach ($this->wikidbs as $name => $db) {
 74+ if ($db) mysql_close($db);
 75+ }
 76+
 77+ $this->wikidbs = array();
 78+ }
 79+
 80+ function getRows($sql, $key = NULL) {
 81+ $rs = $this->query($sql);
 82+ $list = WWUtils::slurpRows($rs, $key);
 83+ mysql_free_result($rs);
 84+ return $list;
 85+ }
 86+
 87+ function getList($sql, $valueField, $key = NULL) {
 88+ $rs = $this->query($sql);
 89+ $list = WWUtils::slurpList($rs, $valueField, $key);
 90+ mysql_free_result($rs);
 91+ return $list;
 92+ }
 93+
 94+ static function slurpList($rs, $field, $key = null) {
 95+ if (is_string($rs)) $rs = $this->query($rs);
 96+
 97+ $list = array();
 98+ while ($row = mysql_fetch_assoc($rs)) {
 99+ if (is_array($field)) {
 100+ $value = array();
 101+ foreach ($field as $f) {
 102+ $value[$f] = $row[$f];
 103+ }
 104+ } else {
 105+ $value = $row[$field];
 106+ }
 107+
 108+ if ($key) {
 109+ $k = $row[$key];
 110+ $list[$k] = $value;
 111+ } else {
 112+ $list[] = $value;
 113+ }
 114+ }
 115+
 116+ return $list;
 117+ }
 118+
 119+ static function slurpRows($rs, $key = null) {
 120+ if (is_string($rs)) $rs = $this->query($rs);
 121+
 122+ $list = array();
 123+ while ($row = mysql_fetch_assoc($rs)) {
 124+ if ($key) {
 125+ $k = $row[$key];
 126+ $list[$k] = $row;
 127+ } else {
 128+ $list[] = $row;
 129+ }
 130+ }
 131+
 132+ return $list;
 133+ }
 134+
 135+ static function slurpAssoc($rs, $keyField, $valueField) {
 136+ if (is_string($rs)) $rs = $this->query($rs);
 137+
 138+ $list = array();
 139+ while ($row = mysql_fetch_assoc($rs)) {
 140+ $key = $row[$keyField];
 141+
 142+ if (is_array($valueField)) {
 143+ $value = array();
 144+ foreach ($valueField as $f) {
 145+ $value[$f] = $row[$f];
 146+ }
 147+ } else {
 148+ $value = $row[$valueField];
 149+ }
 150+
 151+ $list[$key] = $value;
 152+ }
 153+
 154+ return $list;
 155+ }
 156+
 157+ function pickLocal($items, $languages) {
 158+ if ( is_string($languages) ) $languages = array( $languages, "en", "commons" );
 159+
 160+ foreach ($languages as $lang) {
 161+ if (isset($items[$lang])) return $items[$lang];
 162+ }
 163+
 164+ return false;
 165+ }
 166+
 167+ static function authFailed($realm) {
 168+ header("Status: 401 Unauthorized", true, 401);
 169+ header('WWW-Authenticate: Basic realm="'.$realm.'"');
 170+ die();
 171+ }
 172+
 173+ static function doBasicHttpAuth($passwords, $realm) {
 174+ if (!isset($_SERVER['PHP_AUTH_USER'])) {
 175+ authFailed();
 176+ }
 177+
 178+ $usr = $_SERVER['PHP_AUTH_USER'];
 179+ if (!isset($passwords[$usr])) {
 180+ authFailed();
 181+ }
 182+
 183+ $pw = $_SERVER['PHP_AUTH_PW'];
 184+ if ($pw != $passwords[$usr]) {
 185+ authFailed();
 186+ }
 187+
 188+ return $usr;
 189+ }
 190+
 191+ static function printSelector($name, $choices, $current = NULL) {
 192+ print "\n\t\t<select name=\"".htmlspecialchars($name)."\" id=\"".htmlspecialchars($name)."\">\n";
 193+
 194+ foreach ($choices as $choice => $name) {
 195+ $sel = $choice == $current ? " selected=\"selected\"" : "";
 196+ print "\t\t\t<option value=\"".htmlspecialchars($choice)."\"$sel>".htmlspecialchars($name)."</option>\n";
 197+ }
 198+
 199+ print "</select>";
 200+ }
 201+}
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwutils.php
___________________________________________________________________
Name: svn:mergeinfo
1202 +
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwthesaurus.php
@@ -0,0 +1,498 @@
 2+<?php
 3+require_once(dirname(__FILE__)."/wwutils.php");
 4+
 5+ /** Unknown type, SHOULD not occurr in final data. MAY be used for
 6+ * resources that are referenced but where not available for analysis,
 7+ * or have not yet been analyzed.
 8+ **/
 9+ define('WW_RC_TYPE_UNKNOWN', 0);
 10+
 11+ /**
 12+ * A "real" page, describing a concept.
 13+ */
 14+ define('WW_RC_TYPE_ARTICLE', 10);
 15+
 16+ /**
 17+ * This page is a supplemental part of an article, typically a transcluded
 18+ * subpage or simmilar.
 19+ */
 20+ define('WW_RC_TYPE_SUPPLEMENT', 15);
 21+
 22+
 23+ /**
 24+ * A page solely defining a redirect/alias for another page
 25+ */
 26+ define('WW_RC_TYPE_REDIRECT', 20);
 27+
 28+ /**
 29+ * A disambuguation page, listing different meanings for the page title,
 30+ * each linking to a article page.
 31+ */
 32+ define('WW_RC_TYPE_DISAMBIG', 30);
 33+
 34+ /**
 35+ * A page that contains a list of concepts that share some common property or quality,
 36+ * usually each linking to a page describing that concept.
 37+ */
 38+ define('WW_RC_TYPE_LIST', 40);
 39+
 40+ /**
 41+ * A category page.
 42+ */
 43+ define('WW_RC_TYPE_CATEGORY', 50);
 44+
 45+ /**
 46+ * This page does not contain relevant information for WikiWord
 47+ */
 48+ define('WW_RC_TYPE_OTHER', 99);
 49+
 50+ /**
 51+ * A page that is broken in some way, or was marked as bad or disputed. Such pages
 52+ * SHOULD generally be treated as if theys didn't exist.
 53+ */
 54+ define('WW_RC_TYPE_BAD', 100);
 55+
 56+ /**
 57+ * A resource that is not a page by itself, but merely a section of a page. Sections
 58+ * SHOULD always be part of a page of type ARTICLE, and are expected to descibe
 59+ * a narrower concept than the "parent" page.
 60+ */
 61+ define('WW_RC_TYPE_SECTION', 200);
 62+
 63+
 64+class WWThesaurus extends WWUTils {
 65+
 66+ function normalizeSearchString( $s, $norm = 1 ) {
 67+ if ( $norm >= 1 ) $s = mb_strtolower($s, "utf-8");
 68+ if ( $norm >= 1 ) $s = str_replace("-", "", $s);
 69+
 70+ #TODO: 2: whitespace and punctuation
 71+ #TODO: 3: translit
 72+
 73+ return $s;
 74+ }
 75+
 76+ function queryConceptsForTerm($qlang, $term, $languages, $norm = 1, $limit = 100) {
 77+ global $wwTablePrefix, $wwThesaurusDataset, $wwLanguages;
 78+
 79+ if ( !$languages ) $languages = array_keys( $wwLanguages );
 80+
 81+ $term = $this->normalizeSearchString($term, $norm);
 82+
 83+ $sql = "SELECT I.*, S.score FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info as I"
 84+ . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_search_index as S ON I.concept = S.concept "
 85+ . " WHERE term = " . $this->quote($term)
 86+ . " AND I.lang IN " . $this->quoteSet($languages)
 87+ . " AND S.lang = " . $this->quote($qlang)
 88+ . " AND S.norm <= " . (int)$norm
 89+ . " ORDER BY S.score DESC, S.concept "
 90+ . " LIMIT " . (int)$limit;
 91+
 92+ #FIXME: query-lang vs. output-languages!
 93+
 94+ return $this->query($sql);
 95+ }
 96+
 97+ function getConceptsForTerm($qlang, $term, $languages, $norm = 1, $limit = 100) {
 98+ $rs = $this->queryConceptsForTerm($qlang, $term, $languages);
 99+ $list = WWUtils::slurpRows($rs);
 100+ mysql_free_result($rs);
 101+ return $this->buildConcepts($list);
 102+ }
 103+
 104+ function getPagesForConcept( $id, $lang = null ) {
 105+ $p = $this->getConceptInfo( $id, $lang );
 106+ return $p['pages'];
 107+ }
 108+
 109+ /*
 110+ function queryConceptsForPage($lang, $page, $limit = 100) {
 111+ global $wwTablePrefix, $wwThesaurusDataset;
 112+
 113+ $page = trim($page);
 114+
 115+ $sql = "SELECT O.global_concept as id, O.* FROM {$wwTablePrefix}_{$lang}_resource as R "
 116+ . " JOIN {$wwTablePrefix}_{$lang}_about as A ON A.resource = R.id "
 117+ . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($lang) . "\" AND A.concept = O.local_concept "
 118+ . " WHERE R.name = \"" . mysql_real_escape_string($page) . "\""
 119+ . " LIMIT " . (int)$limit;
 120+
 121+ return $this->query($sql);
 122+ }
 123+
 124+ function getConceptsForPage($lang, $page, $limit = 100) {
 125+ $rs = $this->queryConceptsForPage($lang, $page);
 126+ $list = WWUtils::slurpRows($rs);
 127+ mysql_free_result($rs);
 128+ return $list;
 129+ }
 130+
 131+ function queryLocalConcepts($id) {
 132+ global $wwTablePrefix, $wwThesaurusDataset;
 133+ $sql = "SELECT O.lang, O.local_concept_name from {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ";
 134+ $sql .= " WHERE O.global_concept = " . (int)$id;
 135+
 136+ return $this->query($sql);
 137+ }
 138+
 139+ function getLocalConcepts($id) { //NOTE: deprecated alias for backward compat
 140+ return getPagesForConcept($id);
 141+ } */
 142+
 143+ /*
 144+ function queryLocalConceptInfo($lang, $id) {
 145+ global $wwTablePrefix, $wwThesaurusDataset;
 146+
 147+ $sql = "SELECT O.*, C.*, F.*, definition FROM {$wwTablePrefix}_{$lang}_concept_info as F "
 148+ . " JOIN {$wwTablePrefix}_{$lang}_concept as C ON F.concept = C.id "
 149+ . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($lang) . "\" AND F.concept = O.local_concept "
 150+ . " LEFT JOIN {$wwTablePrefix}_{$lang}_definition as D ON F.concept = D.concept "
 151+ . " WHERE O.local_concept = $id ";
 152+
 153+ return $this->query($sql);
 154+ }
 155+
 156+ function queryConceptInfo($id, $lang) {
 157+ global $wwTablePrefix, $wwThesaurusDataset;
 158+
 159+ $sql = "SELECT O.*, C.*, F.*, definition FROM {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O "
 160+ . " LEFT JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info as F ON O.global_concept = F.concept "
 161+ . " LEFT JOIN {$wwTablePrefix}_{$lang}_concept as C ON O.local_concept = C.id "
 162+ . " LEFT JOIN {$wwTablePrefix}_{$lang}_definition as D ON O.local_concept = D.concept "
 163+ . " WHERE O.global_concept = $id AND O.lang = \"" . mysql_real_escape_string($lang) . "\" ";
 164+
 165+ return $this->query($sql);
 166+ }*/
 167+
 168+ /*function getConceptInfo( $id, $lang = null ) {
 169+ $result = $this->getConcept($id, $lang);
 170+
 171+ $result['broader'] = $this->getBroaderForConcept($id);
 172+ $result['narrower'] = $this->getNarrowerForConcept($id);
 173+ $result['related'] = $this->getRelatedForConcept($id);
 174+
 175+ if ( $lang ) {
 176+ $d = $this->getDefinitionForConcept($id);
 177+ $result['related'] = $d[$lang];
 178+ }
 179+
 180+ return $result;
 181+ }*/
 182+
 183+ /*
 184+ function unpickle($s, $lang, $hasId=true, $hasName=true, $hasConf=true) {
 185+ $ss = explode("\x1E", $s);
 186+ $items = array();
 187+
 188+ $fetchNames = false;
 189+
 190+ foreach ($ss as $i) {
 191+ $r = explode("\x1F", $i);
 192+ $offs = -1;
 193+
 194+ if ($hasId) $r['id'] = @$r[$offs += 1];
 195+ if ($hasName) $r['name'] = @$r[$offs += 1];
 196+ if ($hasConf) $r['conf'] = @$r[$offs += 1];
 197+
 198+ if ($hasId && !isset($r['name']))
 199+ $fetchNames = true;
 200+
 201+ if ($hasId) $items[ $r['id'] ] = $r;
 202+ else $items[] = $r;
 203+ }
 204+
 205+ if ($fetchNames) {
 206+ $names = $this->fetchNames(array_keys($items), $lang);
 207+
 208+ $keys = array_keys($items);
 209+ foreach ($keys as $k) {
 210+ $id = $items[$k]['id'];
 211+ $items[$k]['name'] = $names[$id];
 212+ }
 213+ }
 214+
 215+ return $items;
 216+ }
 217+
 218+ function fetchNames($ids, $lang) {
 219+ global $wwTablePrefix, $wwThesaurusDataset;
 220+
 221+ $names = array();
 222+ if (!$ids) return $names;
 223+
 224+ $set = NULL;
 225+ foreach ($ids as $id) {
 226+ if ($set===NULL) $set = "";
 227+ else $set .= ", ";
 228+ $set .= $id;
 229+ }
 230+
 231+ $sql = "select global_concept as id, local_concept_name as name from {$wwTablePrefix}_{$wwThesaurusDataset}_origin ";
 232+ $sql .= "where global_concept in ($set) and lang = \"" . mysql_real_escape_string($lang) . "\" ";
 233+
 234+ $res = $this->query($sql);
 235+
 236+ while ($row = mysql_fetch_assoc($res)) {
 237+ $id = $row['id'];
 238+ $names[$id] = $row['name'];
 239+ }
 240+
 241+ mysql_free_result($res);
 242+
 243+ return $names;
 244+ }
 245+ */
 246+
 247+ function splitPages( $s ) {
 248+ $pp = explode("|", $s);
 249+
 250+ $pages = array();
 251+ foreach ($pp as $p) {
 252+ list($t, $n) = explode(":", $p, 2);
 253+ $pages[$n] = (int)$t;
 254+ }
 255+
 256+ return $pages;
 257+ }
 258+
 259+ function splitConcepts( $s ) {
 260+ $ss = explode("|", $s);
 261+
 262+ $concepts = array();
 263+ foreach ($ss as $p) {
 264+ list($id, $n) = explode(":", $p, 2);
 265+ $id = (int)$id;
 266+ $concepts[$id] = $n;
 267+ }
 268+
 269+ return $concepts;
 270+ }
 271+
 272+ /////////////////////////////////////////////////////////
 273+ function getConceptInfo( $id, $lang = null, $fields = null ) {
 274+ global $wwTablePrefix, $wwThesaurusDataset;
 275+
 276+ #TODO: concept cache!
 277+
 278+ if ( $fields && is_array($fields)) $fields = implode(", ", $fields);
 279+ if ( !$fields ) $fields = "*";
 280+
 281+ #TODO: scores, concept-type, ...
 282+
 283+ $sql = "SELECT $fields FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info "
 284+ . " WHERE concept = ".(int)$id;
 285+
 286+ if ($lang) {
 287+ if ( is_array($lang) ) $sql .= " AND lang IN " . $this->quoteSet($lang);
 288+ else $sql .= " AND lang = " . $this->quote($lang);
 289+ }
 290+
 291+ $r = $this->getRows($sql);
 292+ if (!$r) return false;
 293+
 294+ return $this->buildConcept($r);
 295+ }
 296+
 297+ function buildConcepts($rows) {
 298+ $concepts = array();
 299+ $buff = array();
 300+ $id = null;
 301+ foreach($rows as $row) {
 302+ if ( $id !== null && $id != $row['concept'] ) {
 303+ if ($buff) {
 304+ $concepts[$id] = $this->buildConcept($buff);
 305+ $buff = array();
 306+ }
 307+
 308+ $id = null;
 309+ $score = null;
 310+ }
 311+
 312+ if ($id === null) {
 313+ $id = (int)$row['concept'];
 314+ }
 315+
 316+ $buff[] = $row;
 317+ }
 318+
 319+ usort($concepts, array('WWThesaurus', 'byScore'));
 320+ return $concepts;
 321+ }
 322+
 323+ function byScore( $a, $b ) {
 324+ if ( isset($a['score']) && isset($b['score']) ) return $b['score'] - $a['score'];
 325+ if ( isset($a['conf']) && isset($b['conf']) ) return $b['conf'] - $a['conf'];
 326+ if ( isset($a['freq']) && isset($b['freq']) ) return $b['freq'] - $a['freq'];
 327+ if ( isset($a['id']) && isset($b['id']) ) return $a['id'] - $b['id'];
 328+ return 0;
 329+ }
 330+
 331+ function buildConcept($rows) {
 332+ $concept = array();
 333+ $concept["languages"] = array();
 334+
 335+ $broader = array();
 336+ $narrower = array();
 337+ $similar = array();
 338+ $related = array();
 339+
 340+ foreach ($rows as $row) {
 341+ if (!isset($concept["id"]) && isset($row["concept"])) $concept["id"] = (int)$row["concept"];
 342+ if (!isset($concept["score"]) && isset($row["score"])) $concept["score"] = (int)$row["score"];
 343+
 344+ $lang = $row["lang"];
 345+ $concept["languages"][] = $lang;
 346+
 347+ #TODO: scores, concept-type, ...
 348+
 349+ if (@$row["name"] !== null) $concept["name"][$lang] = $row["name"];
 350+ if (@$row["definition"] !== null) $concept["definition"][$lang] = $row["definition"];
 351+ if (@$row["pages"] !== null) $concept["pages"][$lang] = $this->splitPages($row["pages"]);
 352+
 353+ if (@$row["broader"] !== null) $broader[$lang] = $this->splitConcepts($row["broader"]);
 354+ if (@$row["narrower"] !== null) $narrower[$lang] = $this->splitConcepts($row["narrower"]);
 355+ if (@$row["similar"] !== null) $similar[$lang] = $this->splitConcepts($row["similar"]);
 356+ if (@$row["related"] !== null) $related[$lang] = $this->splitConcepts($row["related"]);
 357+ }
 358+
 359+ $concept["broader"] = $this->mogrifyLocalInfo($broader);
 360+ $concept["narrower"] = $this->mogrifyLocalInfo($narrower);
 361+ $concept["similar"] = $this->mogrifyLocalInfo($similar);
 362+ $concept["related"] = $this->mogrifyLocalInfo($related);
 363+
 364+ return $concept;
 365+ }
 366+
 367+ function mogrifyLocalInfo( $byLanguage ) {
 368+ $byId = array();
 369+
 370+ foreach ( $byLanguage as $lang => $items ) {
 371+ foreach ( $items as $id => $name ) {
 372+ $byId[$id][$lang] = $name;
 373+ }
 374+ }
 375+
 376+ return $byId;
 377+ }
 378+
 379+ /*
 380+ function getConcept( $id, $lang = null, $limit = 100 ) {
 381+ return $this->getConceptInfo($id, $lang);
 382+ }
 383+
 384+ function getRelatedForConcept( $id, $lang = null, $limit = 100 ) {
 385+ $concept = $this->getConceptInfo($id, $lang, "lang, related");
 386+ if (!$concept) return false;
 387+ else if ($lang) return $concept["related"][$lang];
 388+ else return $concept["related"];
 389+ }
 390+
 391+ function getBroaderForConcept( $id, $lang = null, $limit = 100 ) {
 392+ $concept = $this->getConceptInfo($id, $lang, "lang, broader");
 393+ if (!$concept) return false;
 394+ else if ($lang) return $concept["broader"][$lang];
 395+ else return $concept["broader"];
 396+ }
 397+
 398+ function getNarrowerForConcept( $id, $lang = null, $limit = 100 ) {
 399+ $concept = $this->getConceptInfo($id, $lang, "lang, narrower");
 400+ if (!$concept) return false;
 401+ else if ($lang) return $concept["narrower"][$lang];
 402+ else return $concept["narrower"];
 403+ }
 404+
 405+ function getPagesForConcept( $id, $lang = null, $limit = 100 ) {
 406+ if (!$lang) return false;
 407+
 408+ $concept = $this->getConceptInfo($id, $lang, "lang, pages");
 409+ if (!$concept) return false;
 410+ else if ($lang) return array_keys( $concept["pages"][$lang] );
 411+ }
 412+
 413+ function getNamesForConcept( $id, $lang = null ) {
 414+ $concept = $this->getConceptInfo($id, $lang, "lang, name");
 415+ if (!$concept) return false;
 416+
 417+ $result = array();
 418+ foreach ($concept["languages"] as $ll) {
 419+ if (@$concept["name@$ll"])
 420+ $result[$ll] = $concept["name@$ll"];
 421+ }
 422+
 423+ return $result;
 424+ }
 425+
 426+ function getDefinitionForConcept( $id, $lang = null, $limit = 100 ) {
 427+ $concept = $this->getConceptInfo($id, $lang, "lang, definition");
 428+ if (!$concept) return false;
 429+
 430+ $result = array();
 431+ foreach ($concept["languages"] as $ll) {
 432+ if (@$concept["definition@$ll"])
 433+ $result[$ll] = $concept["definition@$ll"];
 434+ }
 435+
 436+ return $result;
 437+ }*/
 438+
 439+ function getTermsForConcept( $id, $lang = null, $limit = 100 ) {
 440+ global $wwTablePrefix, $wwThesaurusDataset, $wwLanguages;
 441+
 442+ if ( !$lang ) $lang = array_keys( $wwLanguages );
 443+ if ( !is_array($lang) ) $lang = preg_split('![\\s,;|/:]\\s*!', $lang);
 444+ $result = array();
 445+
 446+ foreach ($lang as $ll) {
 447+ $sql = "SELECT M.term_text FROM {$wwTablePrefix}_{$ll}_meaning as M"
 448+ . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($ll) . "\" AND M.concept = O.local_concept "
 449+ . " WHERE O.global_concept = " . (int)$id
 450+ . " ORDER BY freq DESC "
 451+ . " LIMIT " . (int)$limit;
 452+
 453+ $terms = $this->getList($sql, "term_text");
 454+ if ( $terms === false || $terms === null ) return false;
 455+ if ( !$terms ) continue;
 456+
 457+ $result[$ll] = $terms;
 458+ }
 459+
 460+ return $result;
 461+ }
 462+
 463+ /*
 464+ function getLinksForConcept( $id, $lang = null, $limit = 100 ) {
 465+ global $wwTablePrefix, $wwThesaurusDataset;
 466+
 467+ $sql = "SELECT C.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept as C "
 468+ . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_link as L ON L.target = C.id "
 469+ . " WHERE L.anchor = ".(int)$id
 470+ . " LIMIT " . (int)$limit;
 471+
 472+ return $this->getRows($sql);
 473+ }
 474+
 475+ function getReferencesForConcept( $id, $lang = null, $limit = 100 ) {
 476+ global $wwTablePrefix, $wwThesaurusDataset;
 477+
 478+ $sql = "SELECT C.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept as C "
 479+ . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_link as L ON L.anchor = C.id "
 480+ . " WHERE L.target = ".(int)$id
 481+ . " LIMIT " . (int)$limit;
 482+
 483+ return $this->getRows($sql);
 484+ }
 485+
 486+ function getScoresForConcept( $id, $lang = null ) {
 487+ global $wwTablePrefix, $wwThesaurusDataset;
 488+
 489+ $sql = "SELECT S.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_stats as S "
 490+ . " WHERE S.concept = ".(int)$id
 491+ ;
 492+
 493+ $r = $this->getRows($sql);
 494+ if ( !$r ) return false;
 495+
 496+ return $r;
 497+ }*/
 498+
 499+}
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwthesaurus.php
___________________________________________________________________
Name: svn:mergeinfo
1500 +
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwimages.php
@@ -0,0 +1,496 @@
 2+<?php
 3+require_once(dirname(__FILE__)."/wwwikis.php");
 4+
 5+class ImageCollection {
 6+
 7+ function __construct() {
 8+ $this->images = array();
 9+ }
 10+
 11+ static function compareRecords($a, $b) {
 12+ $d = (float)$b['score'] - (float)$a['score']; //NOTE: descending
 13+
 14+ if ( $d > 0 ) return 1;
 15+ else if ( $d < 0 ) return -1;
 16+ else return 0;
 17+ }
 18+
 19+ function size() {
 20+ return count($this->images);
 21+ }
 22+
 23+ function listImages($max) {
 24+ uasort($this->images, "Imagecollection::compareRecords");
 25+
 26+ if ($max) return array_slice($this->images, 0, $max);
 27+ else return $this->images;
 28+ }
 29+
 30+ function addImage($image, $key, $usage = "page", $weight = 1) {
 31+ if (!isset($this->images[$image])) {
 32+ $rec = array(
 33+ "name" => $image,
 34+ "score" => 0,
 35+ );
 36+ } else {
 37+ $rec = $this->images[$image];
 38+ }
 39+
 40+ if (!isset($rec[$usage])) $rec[$usage] = array();
 41+ $rec[$usage][] = $key;
 42+ $rec["score"] += $weight;
 43+
 44+ $this->images[$image] = $rec;
 45+ return $rec['score'];
 46+ }
 47+
 48+ function addImages($images, $key, $usage = "page", $weight = 1) {
 49+ foreach ($images as $image) {
 50+ $this->addImage($image, $key, $usage, $weight);
 51+ }
 52+ }
 53+
 54+ function addImageUsage($image, $wiki, $usage = "page", $weight = 1) {
 55+ $this->addImage($image, $key, $usage, $weight);
 56+ }
 57+
 58+ function addTags($image, $tags, $prefix = "") {
 59+ global $wwTagScores;
 60+
 61+ if (isset($this->images[$image])) {
 62+ foreach ($tags as $tag => $weight) {
 63+ if (is_int($tag)) {
 64+ $tag = $prefix.$weight;
 65+
 66+ if (isset($wwTagScores[$tag])) $weight = $wwTagScores[$tag];
 67+ else $weight = 0;
 68+ } else {
 69+ $tag = $prefix.$tag;
 70+ }
 71+
 72+ $this->images[$image]['score'] += $weight;
 73+ $this->images[$image]['tags'][] = $tag;
 74+ }
 75+ }
 76+ }
 77+
 78+}
 79+
 80+class WWImages extends WWWikis {
 81+ var $thesaurus;
 82+
 83+ function __construct($thesaurus) {
 84+ $this->thesaurus = $thesaurus;
 85+ if ( !empty( $this->thesaurus->db ) ) $this->db = $thesaurus->db;
 86+ }
 87+
 88+ function queryImagesOnPage($lang, $ns, $title, $commonsOnly = false) {
 89+ if ($lang == "commons") $commonsOnly = false;
 90+
 91+ $imagelinks_table = $this->getWikiTableName($lang, "imagelinks");
 92+ $page_table = $this->getWikiTableName($lang, "page");
 93+ $image_table = $this->getWikiTableName($lang, "image");
 94+ $commons_image_table = $this->getWikiTableName("commons", "image");
 95+
 96+ $sql = "/* queryImagesOnPage(" . $this->quote($lang) . ", " . (int)$ns . ", " . $this->quote($title) . ", " . (int)$commonsOnly . ") */ ";
 97+
 98+ $sql .= " SELECT I.il_to as name FROM $imagelinks_table as I ";
 99+ $sql .= " JOIN $page_table as P on P.page_id = I.il_from ";
 100+ if ($commonsOnly) $sql .= " LEFT JOIN $image_table as R on R.img_name = I.il_to ";
 101+ if ($commonsOnly) $sql .= " JOIN $commons_image_table as C on C.img_name = I.il_to ";
 102+
 103+ $sql .= " WHERE P.page_namespace = " . (int)$ns;
 104+ $sql .= " AND P.page_title = " . $this->quote($title);
 105+ if ($commonsOnly) $sql .= " AND R.img_name IS NULL";
 106+
 107+ return $this->queryWiki($lang, $sql);
 108+ }
 109+
 110+ function getImagesOnPage($lang, $ns, $title, $commonsOnly = false) {
 111+ $rs = $this->queryImagesOnPage($lang, $ns, $title, $commonsOnly);
 112+
 113+ $list = WWUtils::slurpList($rs, "name");
 114+ mysql_free_result($rs);
 115+
 116+ return $list;
 117+ }
 118+
 119+ function queryImagesOnPageTemplates($lang, $ns, $title, $commonsOnly = false) {
 120+ if ($lang == "commons") $commonsOnly = false;
 121+
 122+ $imagelinks_table = $this->getWikiTableName($lang, "imagelinks");
 123+ $page_table = $this->getWikiTableName($lang, "page");
 124+ $image_table = $this->getWikiTableName($lang, "image");
 125+ $commons_image_table = $this->getWikiTableName("commons", "image");
 126+ $templatelinks_table = $this->getWikiTableName($lang, "templatelinks");
 127+
 128+ $sql = "/* queryImagesOnPageTemplates(" . $this->quote($lang) . ", " . (int)$ns . ", " . $this->quote($title) . ", " . (int)$commonsOnly . ") */ ";
 129+
 130+ $sql .= " SELECT I.il_to as name FROM $imagelinks_table as I ";
 131+ $sql .= " JOIN $page_table as TP on TP.page_id = I.il_from ";
 132+ $sql .= " JOIN $templatelinks_table as T on T.tl_namespace = TP.page_namespace AND T.tl_title = TP.page_title ";
 133+ $sql .= " JOIN $page_table as P on P.page_id = T.tl_from ";
 134+ if ($commonsOnly) $sql .= " LEFT JOIN $image_table as R on R.img_name = I.il_to ";
 135+ if ($commonsOnly) $sql .= " JOIN $commons_image_table as C on C.img_name = I.il_to ";
 136+
 137+ $sql .= " WHERE P.page_namespace = " . (int)$ns;
 138+ $sql .= " AND P.page_title = " . $this->quote($title);
 139+ if ($commonsOnly) $sql .= " AND R.img_name IS NULL";
 140+
 141+ return $this->queryWiki($lang, $sql);
 142+ }
 143+
 144+ function getImagesOnPageTemplates($lang, $ns, $title, $commonsOnly = false) {
 145+ $rs = $this->queryImagesOnPageTemplates($lang, $ns, $title, $commonsOnly);
 146+ $list = WWUtils::slurpList($rs, "name");
 147+ mysql_free_result($rs);
 148+ return $list;
 149+ }
 150+
 151+ function queryImagesInCategory($lang, $title) {
 152+ $categorylinks_table = $this->getWikiTableName($lang, "categorylinks");
 153+ $page_table = $this->getWikiTableName($lang, "page");
 154+
 155+ $sql = "/* queryImagesInCategory(" . $this->quote($lang) . ", " . $this->quote($title) . ") */ ";
 156+
 157+ $sql .= " SELECT P.page_title as name FROM $page_table as P ";
 158+ $sql .= " JOIN $categorylinks_table as C on C.cl_from = P.page_id ";
 159+
 160+ $sql .= " WHERE C.cl_to = " . $this->quote($title);
 161+ $sql .= " AND P.page_namespace = " . NS_IMAGE;
 162+
 163+ return $this->queryWiki($lang, $sql);
 164+ }
 165+
 166+ function getImagesInCategory($lang, $title) {
 167+ $rs = $this->queryImagesInCategory($lang, $title);
 168+ $list = WWUtils::slurpList($rs, "name");
 169+ mysql_free_result($rs);
 170+ return $list;
 171+ }
 172+
 173+ function queryTagsForImages($lang, $images, $tagTable) {
 174+ if (!$images) return false;
 175+
 176+ $sql = "/* queryTagsForImages(" . $this->quote($lang) . ", " . $this->quoteSet($images) . ") */ ";
 177+
 178+ $sql .= " SELECT image, group_concat( concat(type, ':', tag) separator '|') as tags ";
 179+ $sql .= " FROM $tagTable as T ";
 180+ $sql .= " WHERE T.image IN " . $this->quoteSet($images);
 181+ $sql .= " GROUP BY image ";
 182+
 183+ return $this->queryWiki($lang, $sql);
 184+ }
 185+
 186+ function getTagsForImages($lang, $images, $tagTable) {
 187+ if (!$images) return array();
 188+
 189+ $rs = $this->queryTagsForImages($lang, $images, $tagTable);
 190+ $list = WWUtils::slurpAssoc($rs, "image", "tags");
 191+ mysql_free_result($rs);
 192+ return $list;
 193+ }
 194+
 195+ function queryTemplatesOnImagePage($lang, $image) {
 196+ $page_table = $this->getWikiTableName($lang, "page");
 197+ $templatelinks_table = $this->getWikiTableName($lang, "templatelinks");
 198+
 199+ $sql = "/* queryTemplatesOnImagePage(" . $this->quote($lang) . ", " . $this->quote($image) . ") */ ";
 200+
 201+ $sql .= " SELECT tl_title as template FROM $templatelinks_table as T ";
 202+ $sql .= " JOIN $page_table as P on P.page_id = T.tl_from AND T.tl_namespace = " . NS_TEMPLATE . " ";
 203+
 204+ $sql .= " WHERE P.page_title = " . $this->quote($image);
 205+ $sql .= " AND P.page_namespace = " . NS_IMAGE;
 206+
 207+ return $this->queryWiki($lang, $sql);
 208+ }
 209+
 210+ function getTemplatesOnImagePage($lang, $image) {
 211+ $rs = $this->queryTemplatesOnImagePage($lang, $image);
 212+ $list = WWUtils::slurpList($rs, "template");
 213+ mysql_free_result($rs);
 214+ return $list;
 215+ }
 216+
 217+ function queryCategoriesOfImagePage($lang, $image) {
 218+ $page_table = $this->getWikiTableName($lang, "page");
 219+ $categorylinks_table = $this->getWikiTableName($lang, "categorylinks");
 220+
 221+ $sql = "/* queryCategoriesOfImagePage(" . $this->quote($lang) . ", " . $this->quote($image) . ") */ ";
 222+
 223+ $sql .= " SELECT cl_to as category FROM $categorylinks_table as C ";
 224+ $sql .= " JOIN $page_table as P on P.page_id = C.cl_from ";
 225+
 226+ $sql .= " WHERE P.page_title = " . $this->quote($image);
 227+ $sql .= " AND P.page_namespace = " . NS_IMAGE;
 228+
 229+ return $this->queryWiki($lang, $sql);
 230+ }
 231+
 232+ function getCategoriesOfImagePage($lang, $image) {
 233+ $rs = $this->queryCategoriesOfImagePage($lang, $image);
 234+ $list = WWUtils::slurpList($rs, "category");
 235+ mysql_free_result($rs);
 236+ return $list;
 237+ }
 238+
 239+ function getTemplateScores($templates, $values = NULL) {
 240+ global $wwTemplateScores;
 241+ if ($values === NULL) $values = $wwTemplateScores;
 242+
 243+ if (!$values) return 0;
 244+
 245+ $score = 0;
 246+ foreach ($templates as $t) {
 247+ $v = @$values[$t];
 248+ if ($v) $score += $v;
 249+ }
 250+
 251+ return $score;
 252+ }
 253+
 254+ function getRelevantImagesOnPage($lang, $ns, $title, $commonsOnly = false) {
 255+ $img = $this->getImagesOnPage($lang, 0, $title, true);
 256+ $timg = $this->getImagesOnPageTemplates($lang, 0, $title, true);
 257+ $img = array_diff($img, $timg);
 258+ return $img;
 259+ }
 260+
 261+ function queryImagesOnPagesGlobally( $concepts ) {
 262+ global $wwLanguages;
 263+
 264+ if (!$concepts) return false;
 265+
 266+ $globalimagelinks_table = $this->getWikiTableName("commons", "globalimagelinks");
 267+
 268+ $wikis = array();
 269+ $pages = array();
 270+
 271+ foreach ($concepts as $lang => $rc) {
 272+ if (!isset($wwLanguages[$lang])) continue;
 273+
 274+ $wiki = $lang . "wiki";
 275+ if (!in_array($wiki, $wikis)) $wikis[] = $wiki;
 276+
 277+ foreach ($rc as $r => $t) {
 278+ if ( $t != 10) continue; //use only articles
 279+ $p = "gil_wiki = " . $this->quote($wiki) . " AND gil_page_namespace_id = 0 AND gil_page_title = " . $this->quote($r);
 280+ $pages[] = $p;
 281+ }
 282+ }
 283+
 284+ if (!$pages || !$wikis) return false;
 285+
 286+ $sql = " /* queryImagesOnPagesGlobally() */ ";
 287+ $sql .= " SELECT distinct gil_to as image FROM $globalimagelinks_table ";
 288+ $sql .= " WHERE gil_wiki in " . $this->quoteSet( $wikis );
 289+ $sql .= " AND gil_page_namespace_id = 0 ";
 290+ $sql .= " AND ( ( " . implode(" ) OR ( ", $pages) . " ) ) ";
 291+
 292+ print "(** $sql **)";
 293+
 294+ return $this->queryWiki("commons", $sql);
 295+ }
 296+
 297+ function getImagesOnPagesGlobally( $concepts ) {
 298+ if (!$concepts) return array();
 299+
 300+ $rs = $this->queryImagesOnPagesGlobally($concepts);
 301+ if (!$rs) return false;
 302+
 303+ $list = WWUtils::slurpList($rs, "image");
 304+ mysql_free_result($rs);
 305+ return $list;
 306+ }
 307+
 308+ function queryGlobalUsageCounts( $images, $wikis = ".*wiki" ) {
 309+ if (!$images) return false;
 310+
 311+ $globalimagelinks_table = $this->getWikiTableName("commons", "globalimagelinks");
 312+
 313+ $sql = " /* queryGlobalUsageCounts() */ ";
 314+ $sql .= " SELECT gil_to as image, gil_wiki as wiki, count(*) as linkcount FROM $globalimagelinks_table ";
 315+ $sql .= " WHERE gil_page_namespace_id = 0 ";
 316+ $sql .= " AND gil_to IN " . $this->quoteSet( $images );
 317+
 318+ if ( $wikis ) {
 319+ if ( is_array( $wikis ) ) $sql .= " AND gil_wiki IN " . $this->quoteSet( $wikis );
 320+ else if ( is_array( $wikis ) ) $sql .= " AND gil_wiki REGEX " . $this->quote( '^' . $wikis . '$' );
 321+
 322+ #TODO: could also limit to to x or min size n using toolserver.wiki !
 323+ }
 324+
 325+ $sql .= " GROUP BY gil_to, gil_wiki ";
 326+ $sql .= " ORDER BY gil_to, gil_wiki ";
 327+
 328+ return $this->queryWiki("commons", $sql);
 329+ }
 330+
 331+ function getGlobalUsageCounts( $images, $wikis = ".*wiki" ) {
 332+ if (!$images) return array();
 333+
 334+ $rs = $this->queryGlobalUsageCounts($images, $wikis);
 335+ if (!$rs) return false;
 336+
 337+ if (is_string($rs)) $rs = $this->query($rs);
 338+
 339+ $imageUsage = array();
 340+ $current = NULL;
 341+ $stats = array();
 342+ while ($row = mysql_fetch_assoc($rs)) {
 343+ $image = $row["image"];
 344+ $wiki = $row["wiki"];
 345+ $linkcount = $row["linkcount"];
 346+
 347+ if ( is_null($current) ) $current = $image;
 348+ else if ($current != $image) {
 349+ $imageUsage[$current] = $stats;
 350+ $stats = array();
 351+ $current = $image;
 352+ }
 353+
 354+ $stats[$wiki] = $linkcount;
 355+ }
 356+
 357+ if ($current) $imageUsage[$current] = $stats;
 358+
 359+ return $imageUsage;
 360+ }
 361+
 362+ function getImagesAbout($concept, $max = 0) {
 363+ global $wwLanguages, $wwFrequentImageThreshold; //FIXME: put config into member vars!
 364+
 365+ $pages = null;
 366+ if ( is_array($concept) ) {
 367+ if (isset($concept['pages']) && $concept['pages']!==null) $pages = $concept['pages'];
 368+ else if (isset($concept['id']) && $concept['id']!==null) $concept = $concept['id'];
 369+ else if (isset($concept['concept'])) $concept = $concept['concept'];
 370+ }
 371+
 372+ if ($pages === null) {
 373+ $pages = $this->thesaurus->getPagesForConcept($concept);
 374+ if (!$pages) return false;
 375+ }
 376+
 377+ $images = new ImageCollection();
 378+
 379+ $globalImageList = $this->getImagesOnPagesGlobally($pages); //use wikis for $wwLanguages only
 380+ //TODO: sanity limit on number of images. $max * 5 ?
 381+ $globalImageUsage = $this->getGlobalUsageCounts($globalImageList, ".*wiki"); //use all wikipedias
 382+
 383+ foreach ($globalImageUsage as $image => $usage) {
 384+ foreach ($usage as $wiki => $c) {
 385+ if ( $c >= $wwFrequentImageThreshold ) continue;
 386+ $images->addImageUsage($image, $wiki.":*", "article", 1);
 387+ }
 388+ }
 389+
 390+ if ($max && $images->size()>$max) { //short-cirquit, if we already reached the max
 391+ $this->addImageTags($images);
 392+ return $images->listImages($max);
 393+ }
 394+
 395+ if (isset($pages['commons'])) {
 396+ $cpages = $pages['commons'];
 397+
 398+ foreach ($cpages as $cpage => $t) {
 399+ if ( $t == 50 && preg_match('/^Category:(.*)$/', $cpage, $m) ) {
 400+ if ( @$m[1] ) $cpage = $m[1]; //hack
 401+ $img = $this->getImagesInCategory("commons", $cpage);
 402+
 403+ if ($img) $images->addImages($img, "commons:category:" . $cpage, "category", 0.5);
 404+ }
 405+ }
 406+ }
 407+
 408+ $this->addImageTags($images);
 409+ return $images->listImages($max);
 410+ }
 411+
 412+ function addImageTags($images) {
 413+ global $wwTagsTable;
 414+
 415+
 416+ if ( $wwTagsTable ) {
 417+ $img = array();
 418+ foreach ($images->images as $image) {
 419+ $img[] = $image['name'];
 420+ }
 421+
 422+ $tagMap = $this->getTagsForImages('commons', $img, $wwTagsTable);
 423+ foreach ($tagMap as $image => $tags) {
 424+ if ($tags) {
 425+ if (is_string($tags)) $tags = preg_split('/\s*[|;]\s*/', $tags);
 426+ $images->addTags($image, $tags, "");
 427+ }
 428+ }
 429+ } else {
 430+ foreach ($images->images as $image) {
 431+ $image = $image['name'];
 432+
 433+ $tmps = $this->getTemplatesOnImagePage('commons', $image);
 434+ if ($tmps) $images->addTags($image, $tmps, "Template:");
 435+
 436+ $cats = $this->getCategoriesOfImagePage('commons', $image);
 437+ if ($cats) $images->addTags($image, $cats, "Category:");
 438+ }
 439+ }
 440+ }
 441+
 442+ function getThumbnailURL($image, $width = 120, $height = NULL) {
 443+ global $wwThumbnailURL;
 444+
 445+ if (is_array($image)) $image = $image['name'];
 446+
 447+ if (!$height) $height = $width;
 448+
 449+ $u = $wwThumbnailURL;
 450+ $u = str_replace("{name}", urlencode($image), $u);
 451+ $u = str_replace("{width}", !$width ? "" : urlencode($width), $u);
 452+ $u = str_replace("{height}", !$height ? "" : urlencode($height), $u);
 453+
 454+ return $u;
 455+ }
 456+
 457+ function getImagePageURL($image) {
 458+ global $wwImagePageURL;
 459+
 460+ if (is_array($image)) $image = $image['name'];
 461+
 462+ $u = $wwImagePageURL;
 463+ $u = str_replace("{name}", urlencode($image), $u);
 464+
 465+ return $u;
 466+ }
 467+
 468+ function getThumbnailHTML($image, $w = 120, $h = NULL) {
 469+ $thumb = $this->getThumbnailURL($image, $w, $h);
 470+ $page = $this->getImagePageURL($image);
 471+
 472+ if (is_array($image)) {
 473+ $title = @$image['title'];
 474+ $name = @$image['name'];
 475+ } else {
 476+ $name = $image;
 477+ }
 478+
 479+ if (!@$title) $title = $name;
 480+
 481+ $tags = "";
 482+ if (isset($image['tags'])) {
 483+ foreach ($image['tags'] as $tag) {
 484+ $tags .= "tag-" . str_replace(":", "-", $tag) . " ";
 485+ }
 486+ }
 487+
 488+ $html= "<img src=\"" . htmlspecialchars($thumb) . "\" alt=\"" . htmlspecialchars($title) . "\" border=\"0\"/>";
 489+ $html= "<a href=\"" . htmlspecialchars($page) . "\" title=\"" . htmlspecialchars($title) . " (score " . htmlspecialchars($image['score']) . ")\" class=\"thumb-link $tags\">$html</a>";
 490+
 491+ if (is_array($image)) {
 492+ $html .= "<!-- " . str_replace("--", "~~", var_export( $image, true ) ) . " -->";
 493+ }
 494+
 495+ return $html;
 496+ }
 497+}
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwimages.php
___________________________________________________________________
Name: svn:mergeinfo
1498 +
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwwikis.php
@@ -0,0 +1,72 @@
 2+<?php
 3+require_once(dirname(__FILE__)."/wwutils.php");
 4+
 5+if (!defined('NS_IMAGE'))
 6+ define('NS_IMAGE', 6);
 7+
 8+if (!defined('NS_TEMPLATE'))
 9+ define('NS_TEMPLATE', 10);
 10+
 11+
 12+class WWWikis extends WWUtils {
 13+ var $wikidbs = array();
 14+
 15+ function getWikiTableName($lang, $table) {
 16+ global $wwWikitableNamePattern, $wwCommonsTablePrefix;
 17+
 18+ if ( $lang == "commons" && $wwCommonsTablePrefix ) return "$wwCommonsTablePrefix$table";
 19+
 20+ if ($wwWikitableNamePattern) {
 21+ return str_replace(array('{lang}', '{name}'), array($lang, $table), $wwWikitableNamePattern);
 22+ }
 23+
 24+ return $table;
 25+ }
 26+
 27+ function getWikiInfo($lang) {
 28+ global $wwWikiInfoTable, $wwWikiDbName, $wwWikiServerName, $wwCommonsServerName;
 29+
 30+ $db = str_replace('{lang}', $lang, $wwWikiDbName);
 31+
 32+ $dbname = "{$lang}wiki_p";
 33+ $sql = "select * from $wwWikiInfoTable ";
 34+ $sql .= " where dbname = " . $this->quote("$db");
 35+
 36+ $rs = $this->query($sql);
 37+ $info = mysql_fetch_assoc($rs);
 38+ mysql_free_result($rs);
 39+
 40+ if (!$info) $info = false;
 41+ else $info['server'] = str_replace('{num}', $info['server'], $wwWikiServerName);
 42+
 43+ if ($lang == "commons" && $wwCommonsServerName) $info['server'] = $wwCommonsServerName;
 44+
 45+ return $info;
 46+ }
 47+
 48+ function getWikiConnection($lang) {
 49+ if (isset($this->wikidbs[$lang])) return $this->wikidbs[$lang];
 50+
 51+ $info = $this->getWikiInfo($lang);
 52+
 53+ if (!$info) {
 54+ $db = false;
 55+ } else {
 56+ $db = mysql_connect($info['server'], $this->dbuser, $this->dbpassword);
 57+ if (!$db) throw new Exception("Connection Failure to Database: " . mysql_error());
 58+ if (!mysql_select_db($info['dbname'], $db)) throw new Exception ("Database not found: " . mysql_error());
 59+ if (!mysql_query("SET NAMES Latin1;", $db)) throw new Exception ("Database not found: " . mysql_error());
 60+ }
 61+
 62+ $this->wikidbs[$lang] = $db;
 63+ return $db;
 64+ }
 65+
 66+ function queryWiki($lang, $sql) {
 67+ $db = $this->getWikiConnection($lang);
 68+ if (!$db) throw new Exception ("Wiki not found: $lang");
 69+
 70+ return $this->query($sql, $db);
 71+ }
 72+
 73+}
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwwikis.php
___________________________________________________________________
Name: svn:mergeinfo
174 +
Index: trunk/WikiWord/WikiWord/src/main/php/web/api.php
@@ -0,0 +1,140 @@
 2+<?php
 3+
 4+$IP = dirname(__FILE__);
 5+
 6+require_once("$IP/config.php");
 7+require_once("$IP/wwthesaurus.php");
 8+
 9+$query = @$_REQUEST['query'];
 10+
 11+if ( $query ) {
 12+ $lang = @$_REQUEST['lang'];
 13+ $qlang = @$_REQUEST['qlang'];
 14+ $format = @$_REQUEST['format'];
 15+ if ( !$format ) $format = 'phps';
 16+
 17+ if ($lang) $lang = preg_replace('[^\\w\\d_]', '', $lang);
 18+ if ($qlang) $qlang = preg_replace('[^\\w\\d_]', '', $qlang);
 19+
 20+ if ($lang) {
 21+ $lang = preg_split('![\\s,;|/:]\\s*!', $lang);
 22+ if ( !$qlang ) $qlang = $lang[0];
 23+ if (count($lang) == 1) $lang = $lang[0];
 24+ }
 25+
 26+ $result = array( 'query' => $query );
 27+ $start = microtime(true);
 28+
 29+ try {
 30+ $thesaurus = new WWThesaurus();
 31+ $db = $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase);
 32+
 33+ if ( !$db ) {
 34+ $result['error'] = array('code' => 1010, 'message' => "failed to connect to thesaurus database");
 35+ } else if ($query == 'concepts') {
 36+ $term = @$_REQUEST['term'];
 37+ $norm = @$_REQUEST['norm'];
 38+
 39+ if ( $norm === null ) $norm = 1;
 40+ #$page = @$_REQUEST['page'];
 41+
 42+ if ( $qlang === null ) $result['error'] = array('code' => 150, 'message' => "missing parameter qlang");
 43+ else if ( $term !== null ) {
 44+ $result['concepts'] = $thesaurus->getConceptsForTerm($qlang, $term, $lang, $norm); #TODO: limit!
 45+ if ( $result['concepts'] === false || $result['concepts'] === null ) {
 46+ $result['error'] = array('code' => 210, 'message' => "failed to retrieve concepts for term $langt:$term");
 47+ }
 48+ } /*else if ( $page !== null ) {
 49+ $result['concepts'] = $thesaurus->getConceptsForPage($lang, $page);
 50+ if ( $result['concepts'] === false || $result['concepts'] === null ) {
 51+ $result['error'] = array('code' => 250, 'message' => "failed to retrieve concepts for page $langt:$page");
 52+ }
 53+ } */else {
 54+ $result['error'] = array('code' => 110, 'message' => "missing parameter term");
 55+ }
 56+ } else if ($query == 'concept' || $query == 'info') {
 57+ $gcid = @$_REQUEST['gcid'];
 58+ if (!$gcid) $gcid = @$_REQUEST['id'];
 59+
 60+ if ( $gcid === null ) {
 61+ $result['error'] = array('code' => 120, 'message' => "missing parameter gcid");
 62+ } else {
 63+ $result['concept'] = $thesaurus->getConceptInfo($gcid, $lang); #TODO: limit!
 64+ if ( $result['concept'] === false || $result['concept'] === null ) {
 65+ $result['error'] = array('code' => 210, 'message' => "concept not found: $gcid");
 66+ }
 67+ }
 68+ } else if ($query == 'properties') {
 69+ $gcid = @$_REQUEST['gcid'];
 70+ if (!$gcid) $gcid = @$_REQUEST['id'];
 71+
 72+ $props = @$_REQUEST['props'];
 73+
 74+ if ( $gcid === null ) $result['error'] = array('code' => 120, 'message' => "missing parameter gcid");
 75+ else if ( $props === null ) $result['error'] = array('code' => 130, 'message' => "missing parameter props");
 76+ else {
 77+ $props = preg_split('![\\s,;|/:]\\s*!', $props);
 78+
 79+ $info = $thesaurus->getConcept($gcid, $lang);
 80+
 81+ if ( !$info ) $result['error'] = array('code' => 100, 'message' => "concept not found: $gcid");
 82+ else {
 83+ $result = array_merge($result, $info);
 84+
 85+ foreach ( $props as $p ) {
 86+ $m = "get" . ucfirst($p) . "ForConcept";
 87+ if ( !method_exists($thesaurus, $m) ) {
 88+ $result['error'] = array('code' => 190, 'message' => "unknown property: $p");
 89+ break;
 90+ }
 91+
 92+ $result[$p] = $thesaurus->$m($gcid, $lang);
 93+
 94+ if ( $result[$p] === false || $result[$p] === null ) {
 95+ $result['error'] = array('code' => 220, 'message' => "failed to retrieve property $p for concept $gcid");
 96+ break;
 97+ }
 98+ }
 99+
 100+ if (!isset($result['id'])) $result['id'] = $gcid;
 101+ if (!isset($result['lang'])) $result['lang'] = $lang;
 102+ }
 103+ }
 104+ } else {
 105+ $result['error'] = array('code' => 10, 'message' => "bad query: $query");
 106+ }
 107+ } catch (Exception $e) {
 108+ $result['error'] = array('code' => 1000, 'message' => "unexpected exception: " . $e->getMessage());
 109+ }
 110+
 111+ $result['time'] = (microtime(true) - $start) . " sec";
 112+
 113+ if ( isset($result['error']) ) {
 114+ #TODO: HTTP error codce would be nice, but causes file_get_contents to swallow the data.
 115+ # need to use CURL in client!
 116+ #header("Status: 400 Bad Request", true, 400);
 117+ }
 118+
 119+ #TODO: JSON (+YAML?), WDDX
 120+ if ($format == 'phps') {
 121+ header("Content-Type: application/vnd.php.serialized"); #as proposed by http://www.alvestrand.no/pipermail/ietf-types/2004-August/001259.html
 122+ $data = serialize($result);
 123+ echo $data;
 124+ } else if ($format == 'php') {
 125+ header("Content-Type: text/php; charset=UTF-8");
 126+ var_export($result);
 127+ } else if ($format == 'text') {
 128+ header("Content-Type: text/plain; charset=UTF-8");
 129+ print_r($result);
 130+ } else {
 131+ header("Content-Type: text/plain; charset=UTF-8");
 132+ header("Status: 400 Bad Request", true, 400);
 133+ echo "Bad format: $format";
 134+ }
 135+
 136+ exit();
 137+}
 138+
 139+header("Content-Type: text/plain; charset=UTF-8");
 140+?>
 141+WikiWord REST API
\ No newline at end of file
Property changes on: trunk/WikiWord/WikiWord/src/main/php/web/api.php
___________________________________________________________________
Name: svn:mergeinfo
1142 +

Status & tagging log