r80725 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r80724‎ | r80725 | r80726 >
Date:23:10, 21 January 2011
Author:jeroendedauw
Status:deferred
Tags:
Comment:
Importing FolkTagCloud extension from mediawiki.org wiki after adding i18n file and stylizing the thing
Modified paths:
  • /trunk/extensions/FolkTagCloud (added) (history)
  • /trunk/extensions/FolkTagCloud/FolkTagCloud.i18n.php (added) (history)
  • /trunk/extensions/FolkTagCloud/FolkTagCloud.php (added) (history)

Diff [purge]

Index: trunk/extensions/FolkTagCloud/FolkTagCloud.i18n.php
@@ -0,0 +1,20 @@
 2+<?php
 3+
 4+/**
 5+ * Internationalization file for the FolkTagCloud extension.
 6+ *
 7+ * @file FolkTagCloud.i18n.php
 8+ * @ingroup FolkTagCloud
 9+ *
 10+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
 11+ */
 12+
 13+$messages = array();
 14+
 15+/** English
 16+ * @author Jeroen De Dauw
 17+ */
 18+$messages['en'] = array(
 19+ 'folktagcloud-desc' => 'Adds an SMW property for tagging wiki pages with user-defined labels and a parser tag for displaying them in a tag cloud.',
 20+);
 21+
Property changes on: trunk/extensions/FolkTagCloud/FolkTagCloud.i18n.php
___________________________________________________________________
Added: svn:eol-style
122 + native
Index: trunk/extensions/FolkTagCloud/FolkTagCloud.php
@@ -0,0 +1,362 @@
 2+<?php
 3+/**
 4+ * FolkTagCloud
 5+ * @author Katharina Wäschle
 6+ * @version 1.1
 7+ *
 8+ * This program is free software; you can redistribute it and/or
 9+ * modify it under the terms of the GNU General Public License
 10+ * as published by the Free Software Foundation; either version 2
 11+ * of the License, or (at your option) any later version.
 12+ *
 13+ * This program is distributed in the hope that it will be useful,
 14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 16+ * GNU General Public License for more details.
 17+ */
 18+
 19+if ( !defined( 'MEDIAWIKI' ) ) {
 20+ die( 'This is an extension to the MediaWiki package and cannot be run standalone.' );
 21+}
 22+
 23+define( 'FolkTagCloud_VERSION', '1.2 alpha' );
 24+
 25+# credits
 26+$wgExtensionCredits['parserhook'][] = array (
 27+ 'name' => 'FolkTagCloud',
 28+ 'path' => __FILE__,
 29+ 'url' => 'http://www.mediawiki.org/wiki/Extension:FolkTagCloud',
 30+ 'version' => FolkTagCloud_VERSION,
 31+ 'author' => 'Katharina W&auml;schle',
 32+ 'descriptionmsg' => 'folktagcloud-desc'
 33+);
 34+
 35+$wgExtensionMessagesFiles['FolkTagCloud'] = dirname( __FILE__ ) . '/FolkTagCloud.i18n.php';
 36+
 37+$wgExtensionFunctions[] = 'registerFolkTagCloudExtension';
 38+$wgHooks['smwInitProperties'][] = 'initFolkTagProperty';
 39+
 40+# registering extension
 41+function registerFolkTagCloudExtension() {
 42+ global $wgParser;
 43+ $wgParser->setHook( 'folktagcloud', 'renderFolkTagCloud' );
 44+}
 45+
 46+# initialising predefined property 'FolkTag'
 47+function initFolkTagProperty() {
 48+ SMWPropertyValue::registerProperty( '_FT_TAG', '_str', 'FolkTag', true );
 49+ return true;
 50+}
 51+
 52+# user defined sort function
 53+function compareLowercase( $x, $y )
 54+{
 55+ if ( strtolower( $x ) == strtolower( $y ) )
 56+ return 0;
 57+ else if ( strtolower( $x ) < strtolower( $y ) )
 58+ return -1;
 59+ else
 60+ return 1;
 61+}
 62+
 63+# parser function
 64+function renderFolkTagCloud( $input, $args, $parser ) {
 65+ # definition of variables
 66+ $append = '';
 67+ $count = 0;
 68+ $max_tags = 1000;
 69+ $min_count = 1;
 70+ $increase_factor = 100;
 71+ $min_font_size = 77;
 72+ $font_size = 0;
 73+ $htmlout = '';
 74+
 75+ # disable cache
 76+ $parser->disableCache();
 77+
 78+ # not needed with searchlink data
 79+ # build URL path
 80+ # global $wgServer, $wgArticlePath;
 81+ # $path = $wgServer . $wgArticlePath;
 82+
 83+ # default tagging property
 84+ $tag_name = 'FolkTag';
 85+
 86+ # use a user-defined tagging property as default
 87+ global $wgFTCTagName;
 88+ if ( isset( $wgFTCTagName ) ) {
 89+ $tag_name = $wgFTCTagName;
 90+ }
 91+
 92+ # use a user-defined tagging property for this tag cloud
 93+ if ( isset( $args['property'] ) ) {
 94+ $tag_name = str_replace( ' ', '_', ucfirst( $args['property'] ) );
 95+ }
 96+
 97+ # maximum of tags shown
 98+ if ( isset( $args['maxtags'] ) ) {
 99+ $max_tags = intval( $args['maxtags'] );
 100+ }
 101+
 102+ # minimum frequency for tags to be shown
 103+ if ( isset( $args['mincount'] ) ) {
 104+ $min_count = intval( $args['mincount'] );
 105+ }
 106+
 107+ # increase factor
 108+ if ( isset( $args['increasefactor'] ) ) {
 109+ $increase_factor = intval( $args['increasefactor'] );
 110+ }
 111+
 112+ # minimum font size
 113+ if ( isset( $args['minfontsize'] ) ) {
 114+ $min_font_size = intval( $args['minfontsize'] );
 115+ }
 116+
 117+ # get database
 118+ $db = &wfGetDB( DB_SLAVE );
 119+ $store = new SMWSQLStore2;
 120+ extract( $db->tableNames( 'categorylinks', 'page' ) );
 121+
 122+ # make tagging property an SMWPorpertyValue in order to access store
 123+ $property = SMWPropertyValue::makeProperty( $tag_name );
 124+
 125+ # initialising result arrays
 126+ $values = array();
 127+ $result = array();
 128+ $links = array();
 129+
 130+ # if there is no filter category:
 131+ if ( $input == NULL ) {
 132+ $values = ft_getPropertyValues( $property, $store );
 133+ # $values = $store->getPropertyValues(NULL, $property);
 134+ }
 135+ # if there are one or more filter catgories:
 136+ else {
 137+ $categories = explode( ',', $input );
 138+
 139+ # include subcategories:
 140+ if ( isset( $args['subcategorylevel'] ) ) {
 141+ $subcategories = array();
 142+ foreach ( $categories as $category ) {
 143+ $subcategories = array_merge( $subcategories,
 144+ getSubCategories( $category, intval( $args['subcategorylevel'] ) ) );
 145+ }
 146+ $categories = array_merge( $categories, $subcategories );
 147+ }
 148+
 149+ # start building sql
 150+ $sql = "SELECT page_title, page_namespace
 151+ FROM $page
 152+ INNER JOIN $categorylinks
 153+ ON $page.page_id = $categorylinks.cl_from
 154+ AND (";
 155+
 156+ # disjunction of filter categories
 157+ foreach ( $categories as $category ) {
 158+ $category = trim( $category );
 159+ $category = str_replace( ' ', '_', $category );
 160+ $category = str_replace( "'", "\'", $category );
 161+
 162+ $sql .= "$categorylinks.cl_to = '$category' OR ";
 163+ }
 164+
 165+ # remainder of sql (FALSE is required to absorb the last OR)
 166+ $sql .= "FALSE) GROUP BY page_title";
 167+ # query
 168+ $res = $db->query( $sql );
 169+
 170+ # parsing result of sql query: get name and namespace of pages placed in the
 171+ # filter categories and look up all values of the given property for each page
 172+ for ( $i = 0; $i < $db->numRows( $res ); $i++ ) {
 173+ $row = $db->fetchObject( $res );
 174+ $pagename = $row->page_title;
 175+ $namespace = $row->page_namespace;
 176+ $values = array_merge( $values,
 177+ $store->getPropertyValues( SMWWikiPageValue::makePage( $pagename,
 178+ $namespace ), $property ) );
 179+ }
 180+
 181+ $db->freeResult( $res );
 182+ }
 183+
 184+
 185+ # counting frequencies
 186+ foreach ( $values as $value ) {
 187+ # get surface form of property value
 188+ $tag = $value->getShortHTMLText();
 189+ # get Searchlink data for property and current property value
 190+ $link = SMWInfolink::newPropertySearchLink( $tag,
 191+ $tag_name, $tag )->getHTML();
 192+ if ( array_key_exists( $tag, $result ) ) {
 193+ $result[$tag] += 1;
 194+ }
 195+ else {
 196+ $result[$tag] = 1;
 197+ $links[$tag] = $link;
 198+ }
 199+ }
 200+
 201+ # sorting results
 202+ arsort( $result );
 203+
 204+ # if too many tags are found, remove rear part of result array
 205+ if ( count( $result ) > $max_tags ) {
 206+ $result = array_slice( $result, 0, $max_tags, true );
 207+ }
 208+
 209+ # get minimum and maximum frequency for computing font sizes
 210+ $min = end( $result ) or $min = 0;
 211+ $max = reset( $result ) or $max = 1;
 212+
 213+ if ( $max == $min ) { $max += 1; }
 214+
 215+ # sorting results by frequency
 216+ if ( isset( $args['order'] ) ) {
 217+ if ( $args['order'] != "frequency" ) {
 218+ # ksort($result, SORT_STRING);
 219+ uksort( $result, 'compareLowercase' );
 220+ }
 221+ }
 222+ else { uksort( $result, 'compareLowercase' ); } ;
 223+
 224+ # start building html output
 225+ $htmlOut = $htmlOut . "<div align=justify>";
 226+
 227+ foreach ( $result as $label => $count ) {
 228+ if ( $count >= $min_count ) {
 229+ if ( isset( $args['increase'] ) ) {
 230+ # computing font size (logarithmic)
 231+ if ( $args[increase] = 'log' ) {
 232+ $font_size = $min_font_size +
 233+ $increase_factor *
 234+ ( log( $count ) -log( $min ) ) / ( log( $max ) -log( $min ) );
 235+ }
 236+ # computing font size (linear)
 237+ else { $font_size = $min_font_size +
 238+ $increase_factor * ( $count -$min ) / ( $max -$min ); }
 239+ }
 240+ else { $font_size = $min_font_size +
 241+ $increase_factor * ( $count -$min ) / ( $max -$min ); }
 242+ $style = "font-size: $font_size%;";
 243+ # link to special page search by property with parameters
 244+ # property=tagging property and value=current tag
 245+
 246+ # find URL in searchlink data
 247+ $matches = array();
 248+ preg_match( '/href="(.)*"/U', $links[$label], $matches );
 249+ $url = $matches[0];
 250+ # include freqency in brackets in output
 251+ if ( $args['count'] ) {
 252+ $append = " ($count)";
 253+ }
 254+ # appending tag
 255+ $currentRow = "<a style=\"{$style}\" {$url}>" . $label . $append .
 256+ "</a>&nbsp; ";
 257+ $htmlOut = $htmlOut . $currentRow;
 258+ }
 259+ }
 260+
 261+ $htmlOut = $htmlOut . "</div>";
 262+ return $htmlOut;
 263+}
 264+
 265+# modified version of SMWSQLStore2::getPropertyValues in order to get all values
 266+# of a property, not only distinct ones
 267+function ft_getPropertyValues( $property, $store ) {
 268+ $pid = $store->getSMWPropertyID( $property );
 269+ $db =& wfGetDB( DB_SLAVE );
 270+ $result = array();
 271+ $mode = SMWSQLStore2::getStorageMode( $property->getPropertyTypeID() );
 272+ switch ( $mode ) {
 273+ case SMW_SQL2_TEXT2:
 274+ $res = $db->select( 'smw_text2', 'value_blob',
 275+ 'p_id=' . $db->addQuotes( $pid ) );
 276+ while ( $row = $db->fetchObject( $res ) ) {
 277+ $dv = SMWDataValueFactory::newPropertyObjectValue( $property );
 278+ $dv->setOutputFormat( $outputformat );
 279+ $dv->setDBkeys( array( $row->value_blob ) );
 280+ $result[] = $dv;
 281+ }
 282+ $db->freeResult( $res );
 283+ break;
 284+ case SMW_SQL2_RELS2:
 285+ $res = $db->select( array( 'smw_rels2', 'smw_ids' ),
 286+ 'smw_namespace, smw_title, smw_iw',
 287+ 'p_id=' . $db->addQuotes( $pid ) . ' AND o_id=smw_id' );
 288+ while ( $row = $db->fetchObject( $res ) ) {
 289+ $dv = SMWDataValueFactory::newPropertyObjectValue( $property );
 290+ $dv->setOutputFormat( $outputformat );
 291+ $dv->setDBkeys( array( $row->smw_title, $row->smw_namespace, $row->smw_iw ) );
 292+ $result[] = $dv;
 293+ }
 294+ $db->freeResult( $res );
 295+ break;
 296+ case SMW_SQL2_ATTS2:
 297+ if ( ( $requestoptions !== NULL ) && ( $requestoptions->boundary !== NULL ) ) {
 298+ $value_column = $requestoptions->boundary->isNumeric() ? 'value_num':'value_xsd';
 299+ } else {
 300+ $testval = SMWDatavalueFactory::newTypeIDValue( $property->getPropertyTypeID() );
 301+ $value_column = $testval->isNumeric() ? 'value_num':'value_xsd';
 302+ }
 303+ $sql = 'p_id=' . $db->addQuotes( $pid );
 304+ $res = $db->select( 'smw_atts2', 'value_unit, value_xsd',
 305+ 'p_id=' . $db->addQuotes( $pid ) );
 306+ while ( $row = $db->fetchObject( $res ) ) {
 307+ $dv = SMWDataValueFactory::newPropertyObjectValue( $property );
 308+ $dv->setOutputFormat( $outputformat );
 309+ $dv->setDBkeys( array( $row->value_xsd, $row->value_unit ) );
 310+ $result[] = $dv;
 311+ }
 312+ $db->freeResult( $res );
 313+ break;
 314+ }
 315+ return $result;
 316+}
 317+
 318+# derived from Semantic Drilldown (http://www.mediawiki.org/wiki/Extension:Semantic_Drilldown)
 319+function getSubCategories( $category_name, $levels ) {
 320+ if ( $levels == 0 ) {
 321+ return array();
 322+ }
 323+
 324+ # result arrays
 325+ $result = array();
 326+ $subcategories = array();
 327+
 328+ # get database and table names
 329+ $db = wfGetDB( DB_SLAVE );
 330+ extract( $db->tableNames( 'page', 'categorylinks' ) );
 331+
 332+ $cat_ns = NS_CATEGORY;
 333+
 334+ # preparing categories
 335+ $query_category = trim( $category_name );
 336+ $query_category = str_replace( ' ', '_', $query_category );
 337+ $query_category = str_replace( "'", "\'", $query_category );
 338+
 339+ $sql = "SELECT p.page_title, p.page_namespace
 340+ FROM $categorylinks cl
 341+ JOIN $page p on cl.cl_from = p.page_id
 342+ WHERE cl.cl_to = '$query_category'
 343+ AND p.page_namespace = $cat_ns
 344+ ORDER BY cl.cl_sortkey";
 345+
 346+ $res = $db->query( $sql );
 347+
 348+ # parsing result
 349+ while ( $row = $db->fetchRow( $res ) ) {
 350+ $subcategories[] = $row[0];
 351+ $result[] = $row[0];
 352+ }
 353+
 354+ $db->freeResult( $res );
 355+
 356+ # merging recursive
 357+ foreach ( $subcategories as $subcategory ) {
 358+ $result = array_merge( $result,
 359+ getSubCategories( $subcategory, $levels -1 ) );
 360+ }
 361+
 362+ return $result;
 363+}
Property changes on: trunk/extensions/FolkTagCloud/FolkTagCloud.php
___________________________________________________________________
Added: svn:eol-style
1364 + native

Status & tagging log