r55353 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r55352‎ | r55353 | r55354 >
Date:21:51, 19 August 2009
Author:yaron
Status:deferred
Tags:
Comment:
Tag for version 0.1
Modified paths:
  • /tags/extensions/SemanticInternalObjects/REL_0_1 (added) (history)

Diff [purge]

Index: tags/extensions/SemanticInternalObjects/REL_0_1/SemanticInternalObjects.php
@@ -0,0 +1,54 @@
 2+<?php
 3+/**
 4+ * Initialization file for SemanticInternalObjects
 5+ *
 6+ * @file
 7+ * @ingroup SemanticInternalObjects
 8+ * @author Yaron Koren
 9+ */
 10+
 11+if ( !defined( 'MEDIAWIKI' ) ) die();
 12+
 13+define( 'SIO_VERSION', '0.1' );
 14+
 15+$wgExtensionCredits['parserhook'][] = array(
 16+ 'name' => 'Semantic Internal Objects',
 17+ 'version' => SIO_VERSION,
 18+ 'author' => 'Yaron Koren',
 19+ 'url' => 'http://www.mediawiki.org/wiki/Extension:Semantic_Internal_Objects',
 20+ 'description' => 'Setting of internal objects in Semantic MediaWiki',
 21+ 'descriptionmsg' => 'semanticinternalobjects-desc',
 22+);
 23+
 24+$wgExtensionFunctions[] = 'siofParserFunctions';
 25+$wgHooks['LanguageGetMagic'][] = 'siofLanguageGetMagic';
 26+$wgHooks['smwDeleteSemanticData'][] = 'SIOHandler::updateData';
 27+
 28+$siogIP = $IP . '/extensions/SemanticInternalObjects';
 29+$wgExtensionMessagesFiles['SemanticInternalObjects'] = $siogIP . '/SemanticInternalObjects.i18n.php';
 30+$wgAutoloadClasses['SIOHandler'] = $siogIP . '/SemanticInternalObjects_body.php';
 31+
 32+function siofParserFunctions() {
 33+ global $wgHooks, $wgParser;
 34+ if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 35+ $wgHooks['ParserFirstCallInit'][] = 'siofRegisterParserFunctions';
 36+ } else {
 37+ if ( class_exists( 'StubObject' ) && !StubObject::isRealObject( $wgParser ) ) {
 38+ $wgParser->_unstub();
 39+ }
 40+ siofRegisterParserFunctions( $wgParser );
 41+ }
 42+}
 43+
 44+function siofRegisterParserFunctions( &$parser ) {
 45+ $parser->setFunctionHook( 'set_internal', array( 'SIOHandler', 'doSetInternal' ) );
 46+ return true; // always return true, in order not to stop MW's hook processing!
 47+}
 48+
 49+function siofLanguageGetMagic( &$magicWords, $langCode = "en" ) {
 50+ switch ( $langCode ) {
 51+ default:
 52+ $magicWords['set_internal'] = array ( 0, 'set_internal' );
 53+ }
 54+ return true;
 55+}
Index: tags/extensions/SemanticInternalObjects/REL_0_1/README
@@ -0,0 +1,85 @@
 2+Semantic Internal Objects Extension
 3+
 4+ Version 0.1
 5+ Yaron Koren
 6+
 7+This is free software licensed under the GNU General Public License. Please
 8+see http://www.gnu.org/copyleft/gpl.html for further details, including the
 9+full text and terms of the license.
 10+
 11+== Overview ==
 12+
 13+Semantic Internal Objects is an extension to MediaWiki that defines a
 14+parser function, '#set_internal', that is used to define "internal objects"
 15+within the Semantic MediaWiki system. There are complex types of
 16+information sometimes known as 'n-ary relations' that involve more than one
 17+data value associated together. A simple example is in a cooking recipe; a
 18+recipe may call for 1 cup of flour, and the values "1", "cup" and "flour"
 19+must be encoded together; by themselves, the values are not meaningful (the
 20+third value has meaning, though not all of the meaning it could have). Such
 21+information can be stored already in SMW using multi-valued properties,
 22+though this approach is not flexible and currently leads to querying problems.
 23+Instead, #set_internal can be used to define "internal objects" within a page,
 24+which can then be queried as normal SMW pages would; a row of a recipe would
 25+be a good example of data that could be defined using #set_internal.
 26+
 27+The syntax of #set_internal is as follows:
 28+
 29+{{#set_internal:object_to_page_property
 30+|property1=value1
 31+|property2=value2
 32+...
 33+}}
 34+
 35+A sample call to #set_internal would be:
 36+
 37+{{#set_internal:Has recipe
 38+|Has quantity=1
 39+|Has unit=cup
 40+|Has ingredient=flour
 41+}}
 42+
 43+This call would be placed in a page for a recipe, and it would define an object
 44+that had an automatically-generated name; if it were in a page called "Carrot
 45+cake", for instance, the object would be called "Carrot cake#1". If that page
 46+had subsequent calls to #set_internal, the objects that those calls generated
 47+would be called "Carrot cake#2", "Carrot cake#3", etc.
 48+
 49+It should be noted that #set_internal does not display anything to the screen;
 50+display of the values has to be handled separately (this can be done easily
 51+if the function is called from a template).
 52+
 53+Internal objects, once stored, can be queried as if they were wiki pages. So
 54+the following query would show a table of all the recipes that contain more
 55+than 1/2 a cup of flour, and the number of cups they contain:
 56+
 57+{{#ask:[[Has recipe::+]][[Has ingredient::flour]][[Has unit::cup]][[Has quantity::>.5]]
 58+|mainlabel=-
 59+|? Has recipe
 60+|? Has quantity
 61+}}
 62+
 63+Note the "mainlabel=-" parameter in the query: that hides the names of the
 64+internal objects from users, since those names are meaningless.
 65+
 66+For more information, see the extension homepage at:
 67+http://www.mediawiki.org/wiki/Extension:Semantic_Internal_Objects
 68+
 69+== Requirements ==
 70+
 71+This version of the Semantic Internal Objects extension requires MediaWiki 1.8
 72+or higher and Semantic MediaWiki 1.4 or higher.
 73+
 74+== Installation ==
 75+
 76+To install the extension, place the entire 'SemanticInternalObjects' directory
 77+within your MediaWiki 'extensions' directory, then add the following
 78+line to your 'LocalSettings.php' file:
 79+
 80+ require_once( "$IP/extensions/SemanticInternalObjects/SemanticInternalObjects.php" );
 81+
 82+== Contact ==
 83+
 84+Comments, questions, suggestions and bug reports are welcome, and can
 85+be placed on the Talk page for the extension, or sent to Yaron at
 86+yaron57@gmail.com.
Index: tags/extensions/SemanticInternalObjects/REL_0_1/SemanticInternalObjects.i18n.magic.php
@@ -0,0 +1,7 @@
 2+<?php
 3+
 4+$magicWords = array();
 5+
 6+$magicWords['en'] = array(
 7+ 'set_internal' => array( 0, 'set_internal' ),
 8+);
Index: tags/extensions/SemanticInternalObjects/REL_0_1/SemanticInternalObjects_body.php
@@ -0,0 +1,155 @@
 2+<?php
 3+/**
 4+ * @author Yaron Koren
 5+ */
 6+
 7+if ( !defined( 'MEDIAWIKI' ) ) die();
 8+
 9+/**
 10+ * Class that holds information on a single internal object, including all
 11+ * its properties.
 12+ */
 13+class SIOInternalObject {
 14+ var $main_title;
 15+ var $index;
 16+ var $property_value_pairs;
 17+
 18+ public function SIOInternalObject( $main_title, $index ) {
 19+ $this->main_title = $main_title;
 20+ $this->index = $index;
 21+ $this->property_value_pairs = array();
 22+ }
 23+
 24+ public function addPropertyAndValue( $prop_name, $value ) {
 25+ $property = SMWPropertyValue::makeUserProperty( $prop_name );
 26+ $data_value = SMWDataValueFactory::newPropertyObjectValue( $property, $value );
 27+ if ( $data_value->isValid() ) {
 28+ $this->property_value_pairs[] = array( $property, $data_value );
 29+ } // else - show an error message?
 30+ }
 31+
 32+ public function getName() {
 33+ return $this->main_title->getDBkey() . '#' . $this->index;
 34+ }
 35+}
 36+
 37+/**
 38+ * Class for all database-related actions.
 39+ * This class exists mostly because SMWSQLStore2's functions makeSMWPageID()
 40+ * and makeSMWPropertyID(), which are needed for the DB access, are both
 41+ * protected, and thus can't be accessed externally.
 42+ */
 43+class SIOSQLStore extends SMWSQLStore2 {
 44+ function deletePageObjects( $page_name, $namespace ) {
 45+ $ids = array();
 46+
 47+ $iw = '';
 48+ $db =& wfGetDB( DB_SLAVE );
 49+ $res = $db->select( 'smw_ids', array( 'smw_id' ), 'smw_title LIKE ' . $db->addQuotes( $page_name . '#%' ) . ' AND ' . 'smw_namespace=' . $db->addQuotes( $namespace ) . ' AND smw_iw=' . $db->addQuotes( $iw ), 'SIO::getSMWPageObjectIDs', array() );
 50+ while ( $row = $db->fetchObject( $res ) ) {
 51+ $ids[] = $row->smw_id;
 52+ }
 53+ foreach ( $ids as $id ) {
 54+ $db->delete( 'smw_rels2', array( 's_id' => $id ), 'SIO::updateData::Rels2' );
 55+ $db->delete( 'smw_rels2', array( 'o_id' => $id ), 'SIO::updateData::Rels2' );
 56+ $db->delete( 'smw_atts2', array( 's_id' => $id ), 'SMW::deleteSubject::Atts2' );
 57+ }
 58+ }
 59+
 60+ function storeAllInfo( $main_page_name, $namespace, $internal_object ) {
 61+ $main_page_id = $this->makeSMWPageID( $main_page_name, $namespace, '' );
 62+ $io_id = $this->makeSMWPageID( $internal_object->getName(), $namespace, '' );
 63+ $up_rels2 = array();
 64+ $up_atts2 = array();
 65+ // set all the properties pointing from this internal object
 66+ foreach ( $internal_object->property_value_pairs as $property_value_pair ) {
 67+ list( $property, $value ) = $property_value_pair;
 68+ $mode = SMWSQLStore2::getStorageMode( $property->getPropertyTypeID() );
 69+ switch ( $mode ) {
 70+ case SMW_SQL2_RELS2:
 71+ $up_rels2[] = array(
 72+ 's_id' => $io_id,
 73+ 'p_id' => $this->makeSMWPropertyID( $property ),
 74+ 'o_id' => $this->makeSMWPageID( $value->getDBkey(), $value->getNamespace(), $value->getInterwiki() )
 75+ );
 76+ break;
 77+ case SMW_SQL2_ATTS2:
 78+ $keys = $value->getDBkeys();
 79+ $up_atts2[] = array(
 80+ 's_id' => $io_id,
 81+ 'p_id' => $this->makeSMWPropertyID( $property ),
 82+ 'value_unit' => $value->getUnit(),
 83+ 'value_xsd' => $keys[0],
 84+ 'value_num' => $value->getNumericValue()
 85+ );
 86+ break;
 87+ }
 88+ }
 89+
 90+ // now save everything to the database
 91+ $db =& wfGetDB( DB_MASTER );
 92+ if ( count( $up_rels2 ) > 0 ) {
 93+ $db->insert( 'smw_rels2', $up_rels2, 'SMW::updateRel2Data' );
 94+ }
 95+ if ( count( $up_atts2 ) > 0 ) {
 96+ $db->insert( 'smw_atts2', $up_atts2, 'SMW::updateAtt2Data' );
 97+ }
 98+ }
 99+}
 100+
 101+/**
 102+ * Class for hook functions for creating and storing information
 103+ */
 104+class SIOHandler {
 105+
 106+ static $cur_page_name = '';
 107+ static $cur_page_namespace = 0;
 108+ static $internal_object_index = 1;
 109+ static $internal_objects = array();
 110+
 111+ public static function doSetInternal( &$parser ) {
 112+ $main_page_name = $parser->getTitle()->getDBKey();
 113+ $main_page_namespace = $parser->getTitle()->getNamespace();
 114+ if ( $main_page_name == self::$cur_page_name &&
 115+ $main_page_namespace == self::$cur_page_namespace ) {
 116+ self::$internal_object_index++;
 117+ } else {
 118+ self::$cur_page_name = $main_page_name;
 119+ self::$cur_page_namespace = $main_page_namespace;
 120+ self::$internal_object_index = 1;
 121+ }
 122+ $cur_object_num = self::$internal_object_index;
 123+ $params = func_get_args();
 124+ array_shift( $params ); // we already know the $parser...
 125+ $internal_object = new SIOInternalObject( $parser->getTitle(), $cur_object_num );
 126+ $obj_to_page_prop_name = array_shift( $params );
 127+ $internal_object->addPropertyAndValue( $obj_to_page_prop_name, $parser->getTitle() );
 128+ foreach ( $params as $param ) {
 129+ $parts = explode( "=", trim( $param ) );
 130+ if ( count( $parts ) == 2 ) {
 131+ $key = $parts[0];
 132+ $value = $parts[1];
 133+ $internal_object->addPropertyAndValue( $key, $value );
 134+ }
 135+ }
 136+ self::$internal_objects[] = $internal_object;
 137+ }
 138+
 139+ public static function updateData( $subject ) {
 140+ $sio_sql_store = new SIOSQLStore();
 141+ // Find all "pages" in the SMW IDs table that are internal
 142+ // objects for this page, and delete their properties from
 143+ // the SMW tables.
 144+ // Then save the current contents of the $internal_objects
 145+ // array.
 146+ $page_name = $subject->getDBKey();
 147+ $namespace = $subject->getNamespace();
 148+ $sio_sql_store->deletePageObjects( $page_name, $namespace );
 149+ foreach ( self::$internal_objects as $internal_object ) {
 150+ $sio_sql_store->storeAllInfo( $page_name, $namespace, $internal_object );
 151+ }
 152+ self::$internal_objects = array();
 153+ return true;
 154+ }
 155+
 156+}
Index: tags/extensions/SemanticInternalObjects/REL_0_1/SemanticInternalObjects.i18n.php
@@ -0,0 +1,28 @@
 2+<?php
 3+/**
 4+ * Internationalization file for Semantic Internal Objects
 5+ *
 6+ * @file
 7+ * @ingroup Language
 8+ * @ingroup I18n
 9+ * @ingroup SemanticInternalObjects
 10+ */
 11+
 12+// FIXME: Can be enabled when new style magic words are used (introduced in r52503)
 13+// require_once( dirname( __FILE__ ) . '/SemanticInternalObjects.i18n.magic.php' );
 14+
 15+$messages = array();
 16+
 17+/** English
 18+ * @author Yaron Koren
 19+ */
 20+$messages['en'] = array(
 21+ 'semanticinternalobjects-desc' => 'Setting of internal objects in Semantic MediaWiki',
 22+);
 23+
 24+/** Message documentation (Message documentation)
 25+ * @author Yaron Koren
 26+ */
 27+$messages['qqq'] = array(
 28+ 'semanticinternalobjects-desc' => '{{desc}}',
 29+);

Status & tagging log