Index: trunk/WikiWord/WikiWord/src/main/php/wwutils.php |
— | — | @@ -1,14 +1,70 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +if (!defined('NS_IMAGE')) |
| 5 | + define('NS_IMAGE', 6); |
| 6 | + |
| 7 | +class ImageCollection { |
| 8 | + |
| 9 | + function __construct() { |
| 10 | + $this->images = array(); |
| 11 | + } |
| 12 | + |
| 13 | + static function compareRecords($a, $b) { |
| 14 | + return $b['score'] - $a['score']; //NOTE: descending |
| 15 | + } |
| 16 | + |
| 17 | + function size() { |
| 18 | + return count($this->images); |
| 19 | + } |
| 20 | + |
| 21 | + function listImages($max) { |
| 22 | + uasort($this->images, "Imagecollection::compareRecords"); |
| 23 | + |
| 24 | + if ($max) return array_slice($this->images, 0, $max); |
| 25 | + else return $this->images; |
| 26 | + } |
| 27 | + |
| 28 | + function addImage($image, $key, $usage = "page", $weight = 1) { |
| 29 | + if (!isset($this->images[$image])) { |
| 30 | + $rec = array( |
| 31 | + "name" => $image, |
| 32 | + "score" => 0 |
| 33 | + ); |
| 34 | + } |
| 35 | + |
| 36 | + $rec = $this->images[$image]; |
| 37 | + |
| 38 | + if (!isset($rec[$usage])) $rec[$usage] = array(); |
| 39 | + $rec[$usage][] = $key; |
| 40 | + $rec["score"] += $weight; |
| 41 | + |
| 42 | + $this->images[$image] = $rec; |
| 43 | + return $rec['score']; |
| 44 | + } |
| 45 | + |
| 46 | + function addImages($images, $key, $usage = "page", $weight = 1) { |
| 47 | + foreach ($images as $image) { |
| 48 | + $this->addImage($image, $key, $usage, $weight); |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | +} |
| 53 | + |
4 | 54 | class WWUtils { |
5 | 55 | var $debug = false; |
6 | 56 | var $db = NULL; |
| 57 | + var $wikidbs = array(); |
7 | 58 | |
| 59 | + var $dbuser; |
| 60 | + var $dbpassword; |
| 61 | + |
8 | 62 | function connect($server, $user, $password, $database) { |
9 | 63 | $db = mysql_connect($server, $user, $password) or die("Connection Failure to Database: " . mysql_error()); |
10 | 64 | mysql_select_db($database, $db) or die ("Database not found: " . mysql_error()); |
11 | 65 | mysql_query("SET NAMES UTF8;", $db) or die ("Database not found: " . mysql_error()); |
12 | 66 | |
| 67 | + $this->dbuser = $user; |
| 68 | + $this->dbpassword = $password; |
13 | 69 | $this->db = $db; |
14 | 70 | |
15 | 71 | return $db; |
— | — | @@ -36,11 +92,87 @@ |
37 | 93 | return $result; |
38 | 94 | } |
39 | 95 | |
| 96 | + function getWikiTableName($lang) { |
| 97 | + global $wwWikitableNamePattern; |
| 98 | + if ($wwWikitableNamePattern) return str_replace('{name}', $lang, $wwWikitableNamePattern); |
| 99 | + else return ""; |
| 100 | + } |
| 101 | + |
| 102 | + function quote($s) { |
| 103 | + return '"' . $this->quote($s) . '"'; |
| 104 | + } |
| 105 | + |
| 106 | + function getWikiInfo($lang) { |
| 107 | + global $wwWikiInfoTable; |
| 108 | + |
| 109 | + $dbname = "{$lang}wiki_p"; |
| 110 | + $sql = "select * from $wwWikiInfoTable "; |
| 111 | + $sql .= " where dbname = " . $this->quote($lang); |
| 112 | + |
| 113 | + $rs = $this->query($sql); |
| 114 | + $info = mysql_fetch_assoc($rs); |
| 115 | + mysql_free_result($rs); |
| 116 | + |
| 117 | + return $rs; |
| 118 | + } |
| 119 | + |
| 120 | + function getWikiConnection($lang) { |
| 121 | + if (isset($this->wikidbs[$lang])) return $this->wikidbs[$lang]; |
| 122 | + |
| 123 | + $info = $this->getWikiInfo($lang); |
| 124 | + if (!$info) $db = false; |
| 125 | + else { |
| 126 | + $db = mysql_connect($info['server'], $this->dbuser, $this->dbpassword) or die("Connection Failure to Database: " . mysql_error()); |
| 127 | + mysql_select_db($info['database'], $db) or die ("Database not found: " . mysql_error()); |
| 128 | + mysql_query("SET NAMES UTF8;", $db) or die ("Database not found: " . mysql_error()); |
| 129 | + } |
| 130 | + |
| 131 | + $this->wikidbs[$lang] = $db; |
| 132 | + return $db; |
| 133 | + } |
| 134 | + |
| 135 | + function queryWiki($lang, $sql) { |
| 136 | + $db = $this->getWikiConnection($lang); |
| 137 | + if (!$db) return false; |
| 138 | + |
| 139 | + return $this->query($sql, $db); |
| 140 | + } |
| 141 | + |
40 | 142 | function close() { |
41 | 143 | if ($this->db) mysql_close($this->db); |
42 | 144 | $this->db = NULL; |
| 145 | + |
| 146 | + foreach ($this->wikidbs as $name => $db) { |
| 147 | + if ($db) mysql_close($db); |
| 148 | + } |
| 149 | + |
| 150 | + $this->wikidbs = array(); |
43 | 151 | } |
44 | 152 | |
| 153 | + static function slurpList($rs, $field) { |
| 154 | + if (is_string($rs)) $rs = $this->query($rs); |
| 155 | + |
| 156 | + $list = array(); |
| 157 | + while ($row = mysql_fetch_assoc($rs)) { |
| 158 | + $list[] = $row[$field]; |
| 159 | + } |
| 160 | + |
| 161 | + return $list; |
| 162 | + } |
| 163 | + |
| 164 | + static function slurpAssoc($rs, $keyField, $valueField) { |
| 165 | + if (is_string($rs)) $rs = $this->query($rs); |
| 166 | + |
| 167 | + $list = array(); |
| 168 | + while ($row = mysql_fetch_assoc($rs)) { |
| 169 | + $key = $row[$keyField]; |
| 170 | + $value = $row[$valueField]; |
| 171 | + $list[$key] = $value; |
| 172 | + } |
| 173 | + |
| 174 | + return $list; |
| 175 | + } |
| 176 | + |
45 | 177 | function queryConceptsForTerm($lang, $term) { |
46 | 178 | global $wwTablePrefix, $wwThesaurusDataset; |
47 | 179 | |
— | — | @@ -56,6 +188,21 @@ |
57 | 189 | return $this->query($sql); |
58 | 190 | } |
59 | 191 | |
| 192 | + function queryLocalConcepts($id) { |
| 193 | + global $wwTablePrefix, $wwThesaurusDataset; |
| 194 | + $sql = "SELECT O.lang, O.local_concept_name from {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O "; |
| 195 | + $sql .= " WHERE O.global_concept = " . (int)$id; |
| 196 | + |
| 197 | + return $this->query($sql); |
| 198 | + } |
| 199 | + |
| 200 | + function getLocalConcepts($id) |
| 201 | + $rs = $this->queryLocalConcepts($id); |
| 202 | + $list = WWUtils::slurpAssoc($rs, "lang", "local_concept_name"); |
| 203 | + mysql_free_result($rs); |
| 204 | + return $list; |
| 205 | + } |
| 206 | + |
60 | 207 | function queryLocalConceptInfo($lang, $id) { |
61 | 208 | global $wwTablePrefix, $wwThesaurusDataset; |
62 | 209 | |
— | — | @@ -176,4 +323,175 @@ |
177 | 324 | |
178 | 325 | return $names; |
179 | 326 | } |
| 327 | + |
| 328 | + function queryImagesOnPage($lang, $ns, $title, $commonsOnly = false) { |
| 329 | + global $wwTablePrefix, $wwThesaurusDataset, $wwCommonsTablePrefix; |
| 330 | + |
| 331 | + if ($lang == "commons") $commonsOnly = false; |
| 332 | + |
| 333 | + $imagelinks_table = $this->getWikiTableName($lang, "imagelinks"); |
| 334 | + $page_table = $this->getWikiTableName($lang, "page"); |
| 335 | + $image_table = $this->getWikiTableName($lang, "image"); |
| 336 | + |
| 337 | + $sql = "SELECT I.il_to as name FROM $imagelinks_table as I "; |
| 338 | + $sql .= " JOIN $page_table as P on P.page_id = I.il_from "; |
| 339 | + if ($commonsOnly) $sql .= " LEFT JOIN $image_table as R on R.img_name = I.il_to "; |
| 340 | + if ($commonsOnly) $sql .= " JOIN {$wwCommonsTablePrefix}_image as C on C.img_name = I.il_to "; |
| 341 | + |
| 342 | + $sql .= " WHERE P.page_namespace = " . (int)$namespace; |
| 343 | + $sql .= " AND P.page_title = " . $this->quote($title); |
| 344 | + if ($commmonsOnly) $sql .= " AND R.img_name IS NULL"; |
| 345 | + |
| 346 | + return $this->queryWiki($lang, $sql); |
| 347 | + } |
| 348 | + |
| 349 | + function getImagesOnPage($lang, $ns, $title, $commonsOnly = false) |
| 350 | + $rs = $this->queryImagesOnPage($lang, $ns, $title, $commonsOnly); |
| 351 | + $list = WWUtils::slurpList($rs, "name"); |
| 352 | + mysql_free_result($rs); |
| 353 | + return $list; |
| 354 | + } |
| 355 | + |
| 356 | + function queryImagesOnPageTemplates($lang, $ns, $title, $commonsOnly = false) { |
| 357 | + global $wwTablePrefix, $wwThesaurusDataset, $wwCommonsTablePrefix; |
| 358 | + |
| 359 | + if ($lang == "commons") $commonsOnly = false; |
| 360 | + |
| 361 | + $imagelinks_table = $this->getWikiTableName($lang, "imagelinks"); |
| 362 | + $page_table = $this->getWikiTableName($lang, "page"); |
| 363 | + $image_table = $this->getWikiTableName($lang, "image"); |
| 364 | + $templatelinks_table = $this->getWikiTableName($lang, "templatelinks"); |
| 365 | + |
| 366 | + $sql = "SELECT I.il_to as name FROM $imagelinks_table as I "; |
| 367 | + $sql .= " JOIN $page_table as TP on TP.page_id = I.il_from "; |
| 368 | + $sql .= " JOIN $templatelinks_table as T on T.tl_namespace = TP.page_namespace AND T.tl_title = TP.page_title "; |
| 369 | + $sql .= " JOIN $page_table as P on P.page_id = T.tl_from "; |
| 370 | + if ($commonsOnly) $sql .= " LEFT JOIN $image as R on R.img_name = I.il_to "; |
| 371 | + if ($commonsOnly) $sql .= " JOIN {$wwCommonsTablePrefix}_image as C on C.img_name = I.il_to "; |
| 372 | + |
| 373 | + $sql .= " WHERE P.page_namespace = " . (int)$namespace; |
| 374 | + $sql .= " AND P.page_title = " . $this->quote($title); |
| 375 | + if ($commmonsOnly) $sql .= " AND R.img_name IS NULL"; |
| 376 | + |
| 377 | + return $this->queryWiki($lang, $sql); |
| 378 | + } |
| 379 | + |
| 380 | + function getImagesOnPageTemplates($lang, $ns, $title, $commonsOnly = false) |
| 381 | + $rs = $this->queryImagesOnPageTemplates($lang, $ns, $title, $commonsOnly); |
| 382 | + $list = WWUtils::slurpList($rs, "name"); |
| 383 | + mysql_free_result($rs); |
| 384 | + return $list; |
| 385 | + } |
| 386 | + |
| 387 | + function queryImagesInCategory($lang, $title) { |
| 388 | + global $wwTablePrefix, $wwThesaurusDataset, $wwCommonsTablePrefix; |
| 389 | + $categorylinks_table = $this->getWikiTableName($lang, "categorylinks"); |
| 390 | + $page_table = $this->getWikiTableName($lang, "page"); |
| 391 | + |
| 392 | + $sql = "SELECT P.page_title as name FROM $page_table as P "; |
| 393 | + $sql .= " JOIN $categorylinks_table as C on C.from = P.page_id "; |
| 394 | + |
| 395 | + $sql .= " WHERE C.cl_to = " . $this->quote($title); |
| 396 | + $sql .= " AND P.pange_namespace = " . NS_IMAGE; |
| 397 | + |
| 398 | + return $this->queryWiki($lang, $sql); |
| 399 | + } |
| 400 | + |
| 401 | + function getImagesInCategory($lang, $title) |
| 402 | + $rs = $this->queryImagesOnPage($lang, $title); |
| 403 | + $list = WWUtils::slurpList($rs, "name"); |
| 404 | + mysql_free_result($rs); |
| 405 | + return $list; |
| 406 | + } |
| 407 | + |
| 408 | + function getRelevantImagesOnPage($lang, $ns, $title, $commonsOnly = false) { |
| 409 | + $img = $this->getImagesOnPage($lang, 0, $title, true); |
| 410 | + $timg = $this->getImagesOnPageTemplates($lang, 0, $title, true); |
| 411 | + $img = array_diff($img, $timg); |
| 412 | + return $img; |
| 413 | + } |
| 414 | + |
| 415 | + function getImagesAbout($id, $max = 0) { |
| 416 | + global $wwFakeCommonsConcepts; |
| 417 | + |
| 418 | + $concepts = $this->getLocalConcepts($id); |
| 419 | + |
| 420 | + if ($wwFakeCommonsConcepts && isset($concepts['en'])) { |
| 421 | + $concepts['commons'] = @$concepts['en']; |
| 422 | + } |
| 423 | + |
| 424 | + $images = new ImageCollection(); |
| 425 | + |
| 426 | + foreach ($concepts as $lang => $title) { |
| 427 | + if ($lang == "commons") continue; |
| 428 | + |
| 429 | + $img = $this->getRelevantImagesOnPage($lang, 0, $title, true); //FIXME: resource mapping |
| 430 | + $images->addImages($images, $lang . ":" . $title, "article", 1); |
| 431 | + } |
| 432 | + |
| 433 | + if ($max && $images->size()>$max) |
| 434 | + return $images->listImages($max); |
| 435 | + |
| 436 | + if (isset($conceps['commons'])) { |
| 437 | + $title = $conceps['commons']; |
| 438 | + |
| 439 | + $img = $this->getRelevantImagesOnPage("commmons", 0, $title, false); //FIXME: resource mapping |
| 440 | + $images->addImages($images, "commons:" . $title, "gallery", 0.8); |
| 441 | + |
| 442 | + if ($max && $images->size()>$max) |
| 443 | + return $images->listImages($max); |
| 444 | + |
| 445 | + $img = $this->getImagesInCategory("commmons", $title); //FIXME: resource mapping |
| 446 | + $images->addImages($images, "commons:" . $title, "category", 0.5); |
| 447 | + } |
| 448 | + |
| 449 | + return $images->listImages($max); |
| 450 | + } |
| 451 | + |
| 452 | + function getThumbnailURL($image, $w = 120, $h = NULL) { |
| 453 | + global $wwThumbnailerURL; |
| 454 | + |
| 455 | + if (is_array($image)) $image = $image['name']; |
| 456 | + |
| 457 | + $u = $wwThumbnailerURL; |
| 458 | + $u = str_replace("{name}", urlencode($image), $u); |
| 459 | + $u = str_replace("{width}", !$width ? "" : urlencode($width), $u); |
| 460 | + $u = str_replace("{height}", !$height ? "" : urlencode($height), $u); |
| 461 | + |
| 462 | + return $u; |
| 463 | + } |
| 464 | + |
| 465 | + function getImagePageURL($image) { |
| 466 | + global $wwImagePageURL; |
| 467 | + |
| 468 | + if (is_array($image)) $image = $image['name']; |
| 469 | + |
| 470 | + $u = $wwImagePageURL; |
| 471 | + $u = str_replace("{name}", urlencode($image), $u); |
| 472 | + |
| 473 | + return $u; |
| 474 | + } |
| 475 | + |
| 476 | + function getThumbnailHTML($image, $w = 120, $h = NULL) { |
| 477 | + $thumb = $this->getThumbnailURL(); |
| 478 | + $page = $this->getImagePageURL(); |
| 479 | + |
| 480 | + if (is_array($image)) { |
| 481 | + $title = @$image['title']; |
| 482 | + $name = @$image['name']; |
| 483 | + } else { |
| 484 | + $name = $image; |
| 485 | + } |
| 486 | + |
| 487 | + if (!@$title) $title = $name; |
| 488 | + |
| 489 | + $html= "<img src=\"" . htmlspecialchars($thumb) . "\" alt=\"" . htmlspecialchars($title) . "\"/>"; |
| 490 | + $html= "<a href=\"" . htmlspecialchars($page) . "\" title=\"" . htmlspecialchars($title) . "\">$html</a>"; |
| 491 | + |
| 492 | + if (is_array($image)) { |
| 493 | + $html .= "<!-- " . htmlspecialchars( str_replace("--", "~~", var_export( $image, true ) ) ) . " -->"; |
| 494 | + } |
| 495 | + |
| 496 | + return $html; |
| 497 | + } |
180 | 498 | } |
Index: trunk/WikiWord/WikiWord/src/main/php/config.sample.php |
— | — | @@ -10,3 +10,12 @@ |
11 | 11 | $wwThesaurusDataset = "thesaurus"; |
12 | 12 | |
13 | 13 | #error_reporting(E_ALL); |
| 14 | + |
| 15 | +$wwThumbSite = 90; |
| 16 | +$wwThumbnailURL = "http://toolserver.org/tsthumb/tsthumb?f={name}&domain=commons.wikimedia.org&w={width}&h={height}"; |
| 17 | +$wwImagePageURL = "http://commons.wikimedia.org/wiki/File:{name}"; |
| 18 | + |
| 19 | +$wwFakeCommonsConcepts = true; |
| 20 | +$wwCommonsTablePrefix = "commonswiki_p."; |
| 21 | + |
| 22 | +$wwWikiInfoTable = "toolserver.wiki"; |
\ No newline at end of file |