http://www.mediawiki.org/wiki/Special:Code/MediaWiki/55343

Revision: 55343
Author:   yaron
Date:     2009-08-19 19:45:28 +0000 (Wed, 19 Aug 2009)

Log Message:
-----------
New extension

Added Paths:
-----------
    trunk/extensions/SemanticInternalObjects/
    trunk/extensions/SemanticInternalObjects/README
    
trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.i18n.magic.php
    trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.i18n.php
    trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.php
    trunk/extensions/SemanticInternalObjects/SemanticInternalObjects_body.php

Added: trunk/extensions/SemanticInternalObjects/README
===================================================================
--- trunk/extensions/SemanticInternalObjects/README                             
(rev 0)
+++ trunk/extensions/SemanticInternalObjects/README     2009-08-19 19:45:28 UTC 
(rev 55343)
@@ -0,0 +1,85 @@
+Semantic Internal Objects Extension
+
+        Version 0.1
+        Yaron Koren
+
+This is free software licensed under the GNU General Public License. Please
+see http://www.gnu.org/copyleft/gpl.html for further details, including the
+full text and terms of the license.
+
+== Overview ==
+
+Semantic Internal Objects is an extension to MediaWiki that defines a
+parser function, '#set_internal', that is used to define "internal objects"
+within the Semantic MediaWiki system. There are complex types of
+information sometimes known as 'n-ary relations' that involve more than one
+data value associated together. A simple example is in a cooking recipe; a
+recipe may call for 1 cup of flour, and the values "1", "cup" and "flour"
+must be encoded together; by themselves, the values are not meaningful (the
+third value has meaning, though not all of the meaning it could have). Such
+information can be stored already in SMW using multi-valued properties,
+though this approach is not flexible and currently leads to querying problems.
+Instead, #set_internal can be used to define "internal objects" within a page,
+which can then be queried as normal SMW pages would; a row of a recipe would
+be a good example of data that could be defined using #set_internal.
+
+The syntax of #set_internal is as follows:
+
+{{#set_internal:object_to_page_property
+|property1=value1
+|property2=value2
+...
+}}
+
+A sample call to #set_internal would be:
+
+{{#set_internal:Has recipe
+|Has quantity=1
+|Has unit=cup
+|Has ingredient=flour
+}}
+
+This call would be placed in a page for a recipe, and it would define an object
+that had an automatically-generated name; if it were in a page called "Carrot
+cake", for instance, the object would be called "Carrot cake#1". If that page
+had subsequent calls to #set_internal, the objects that those calls generated
+would be called "Carrot cake#2", "Carrot cake#3", etc.
+
+It should be noted that #set_internal does not display anything to the screen;
+display of the values has to be handled separately (this can be done easily
+if the function is called from a template).
+
+Internal objects, once stored, can be queried as if they were wiki pages. So
+the following query would show a table of all the recipes that contain more
+than 1/2 a cup of flour, and the number of cups they contain:
+
+{{#ask:[[Has recipe::+]][[Has ingredient::flour]][[Has unit::cup]][[Has 
quantity::>.5]]
+|mainlabel=-
+|? Has recipe
+|? Has quantity
+}}
+
+Note the "mainlabel=-" parameter in the query: that hides the names of the
+internal objects from users, since those names are meaningless.
+
+For more information, see the extension homepage at:
+http://www.mediawiki.org/wiki/Extension:Semantic_Internal_Objects
+
+== Requirements ==
+
+This version of the Semantic Internal Objects extension requires MediaWiki 1.8
+or higher and Semantic MediaWiki 1.4 or higher.
+
+== Installation ==
+
+To install the extension, place the entire 'SemanticInternalObjects' directory
+within your MediaWiki 'extensions' directory, then add the following
+line to your 'LocalSettings.php' file:
+
+     require_once( 
"$IP/extensions/SemanticInternalObjects/SemanticInternalObjects.php" );
+
+== Contact ==
+
+Comments, questions, suggestions and bug reports are welcome, and can
+be placed on the Talk page for the extension, or sent to Yaron at
+yaro...@gmail.com.

Added: 
trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.i18n.magic.php
===================================================================
--- 
trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.i18n.magic.php 
                            (rev 0)
+++ 
trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.i18n.magic.php 
    2009-08-19 19:45:28 UTC (rev 55343)
@@ -0,0 +1,7 @@
+<?php
+
+$magicWords = array();
+
+$magicWords['en'] = array(
+       'set_internal' => array( 0, 'set_internal' ),
+);

Added: trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.i18n.php
===================================================================
--- trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.i18n.php   
                        (rev 0)
+++ trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.i18n.php   
2009-08-19 19:45:28 UTC (rev 55343)
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Internationalization file for Semantic Internal Objects
+ *
+ * @file
+ * @ingroup Language
+ * @ingroup I18n
+ * @ingroup SemanticInternalObjects
+ */
+
+// FIXME: Can be enabled when new style magic words are used (introduced in 
r52503)
+// require_once( dirname( __FILE__ ) . 
'/SemanticInternalObjects.i18n.magic.php' );
+
+$messages = array();
+
+/** English
+ *  @author Yaron Koren
+ */
+$messages['en'] = array(
+       'semanticinternalobjects-desc'              => 'Setting of internal 
objects in Semantic MediaWiki',
+);
+
+/** Message documentation (Message documentation)
+ * @author Yaron Koren
+ */
+$messages['qqq'] = array(
+       'semanticinternalobjects-desc' => '{{desc}}',
+);

Added: trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.php
===================================================================
--- trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.php        
                        (rev 0)
+++ trunk/extensions/SemanticInternalObjects/SemanticInternalObjects.php        
2009-08-19 19:45:28 UTC (rev 55343)
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Initialization file for SemanticInternalObjects
+ *
+ * @file
+ * @ingroup SemanticInternalObjects
+ * @author Yaron Koren
+ */
+
+if (!defined('MEDIAWIKI')) die();
+
+define('SIO_VERSION', '0.1');
+
+$wgExtensionCredits['parserhook'][]= array(
+       'name'  => 'Semantic Internal Objects',
+       'version'       => SIO_VERSION,
+       'author'        => 'Yaron Koren',
+       'url'   => 
'http://www.mediawiki.org/wiki/Extension:Semantic_Internal_Objects',
+       'description'   =>  'Setting of internal objects in Semantic MediaWiki',
+       'descriptionmsg' => 'semanticinternalobjects-desc',
+);
+
+$wgExtensionFunctions[] = 'siofParserFunctions';
+$wgHooks['LanguageGetMagic'][] = 'siofLanguageGetMagic';
+$wgHooks['smwDeleteSemanticData'][] = 'SIOHandler::updateData';
+
+$siogIP = $IP . '/extensions/SemanticInternalObjects';
+$wgExtensionMessagesFiles['SemanticInternalObjects'] = $siogIP . 
'/SemanticInternalObjects.i18n.php';
+$wgAutoloadClasses['SIOHandler'] = $siogIP . 
'/SemanticInternalObjects_body.php';
+
+function siofParserFunctions() {
+       global $wgHooks, $wgParser;
+       if( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
+               $wgHooks['ParserFirstCallInit'][] = 
'siofRegisterParserFunctions';
+       } else {
+               if ( class_exists( 'StubObject' ) && !StubObject::isRealObject( 
$wgParser ) ) {
+                       $wgParser->_unstub();
+               }
+               siofRegisterParserFunctions( $wgParser );
+       }
+}
+
+function siofRegisterParserFunctions(&$parser) {
+       $parser->setFunctionHook( 'set_internal', 
array('SIOHandler','doSetInternal') );
+       return true; // always return true, in order not to stop MW's hook 
processing!
+}
+
+function siofLanguageGetMagic( &$magicWords, $langCode = "en" ) {
+       switch ( $langCode ) {
+       default:
+               $magicWords['set_internal'] = array ( 0, 'set_internal' );
+       }
+       return true;
+}

Added: trunk/extensions/SemanticInternalObjects/SemanticInternalObjects_body.php
===================================================================
--- trunk/extensions/SemanticInternalObjects/SemanticInternalObjects_body.php   
                        (rev 0)
+++ trunk/extensions/SemanticInternalObjects/SemanticInternalObjects_body.php   
2009-08-19 19:45:28 UTC (rev 55343)
@@ -0,0 +1,155 @@
+<?php
+/**
+ * @author Yaron Koren
+ */
+
+if (!defined('MEDIAWIKI')) die();
+
+/**
+ * Class that holds information on a single internal object, including all
+ * its properties.
+ */
+class SIOInternalObject {
+       var $main_title;
+       var $index;
+       var $property_value_pairs;
+
+       public function SIOInternalObject($main_title, $index) {
+               $this->main_title = $main_title;
+               $this->index = $index;
+               $this->property_value_pairs = array();
+       }
+
+       public function addPropertyAndValue($prop_name, $value) {
+               $property = SMWPropertyValue::makeUserProperty($prop_name);
+               $data_value = 
SMWDataValueFactory::newPropertyObjectValue($property, $value);
+               if ($data_value->isValid()) {
+                       $this->property_value_pairs[] = array($property, 
$data_value);
+               } // else - show an error message?
+       }
+
+       public function getName() {
+               return $this->main_title->getDBkey() . '#' . $this->index;
+       }
+}
+
+/**
+ * Class for all database-related actions.
+ * This class exists mostly because SMWSQLStore2's functions makeSMWPageID()
+ * and makeSMWPropertyID(), which are needed for the DB access, are both
+ * protected, and thus can't be accessed externally.
+ */
+class SIOSQLStore extends SMWSQLStore2 {
+       function deletePageObjects($page_name, $namespace) {
+               $ids = array();
+
+               $iw = '';
+               $db =& wfGetDB( DB_SLAVE );
+               $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());
+               while ($row = $db->fetchObject($res)) {
+                       $ids[] = $row->smw_id;
+               }
+               foreach ($ids as $id) {
+                       $db->delete('smw_rels2', array('s_id' => $id), 
'SIO::updateData::Rels2');
+                       $db->delete('smw_rels2', array('o_id' => $id), 
'SIO::updateData::Rels2');
+                       $db->delete('smw_atts2', array('s_id' => $id), 
'SMW::deleteSubject::Atts2');
+               }
+       }
+
+       function storeAllInfo($main_page_name, $namespace, $internal_object) {
+               $main_page_id = $this->makeSMWPageID($main_page_name, 
$namespace, '');
+               $io_id = $this->makeSMWPageID($internal_object->getName(), 
$namespace, '');
+               $up_rels2 = array();
+               $up_atts2 = array();
+               // set all the properties pointing from this internal object
+               foreach ($internal_object->property_value_pairs as 
$property_value_pair) {
+                       list($property, $value) = $property_value_pair;
+                       $mode = 
SMWSQLStore2::getStorageMode($property->getPropertyTypeID());
+                       switch ($mode) {
+                       case SMW_SQL2_RELS2:
+                               $up_rels2[] = array(
+                                       's_id' => $io_id,
+                                       'p_id' => 
$this->makeSMWPropertyID($property),
+                                       'o_id' => 
$this->makeSMWPageID($value->getDBkey(), $value->getNamespace(), 
$value->getInterwiki())
+                               );
+                               break;
+                       case SMW_SQL2_ATTS2:
+                               $keys = $value->getDBkeys();
+                               $up_atts2[] = array(
+                                       's_id' => $io_id,
+                                       'p_id' => 
$this->makeSMWPropertyID($property),
+                                       'value_unit' => $value->getUnit(),
+                                       'value_xsd' => $keys[0],
+                                       'value_num' => $value->getNumericValue()
+                               );
+                               break;
+                       }
+               }
+
+               // now save everything to the database
+               $db =& wfGetDB( DB_MASTER );
+               if (count($up_rels2) > 0) {
+                       $db->insert( 'smw_rels2', $up_rels2, 
'SMW::updateRel2Data');
+               }
+               if (count($up_atts2) > 0) {
+                       $db->insert( 'smw_atts2', $up_atts2, 
'SMW::updateAtt2Data');
+               }
+       }
+}
+
+/**
+ * Class for hook functions for creating and storing information
+ */
+class SIOHandler {
+
+       static $cur_page_name = '';
+       static $cur_page_namespace = 0;
+       static $internal_object_index = 1;
+       static $internal_objects = array();
+
+       public static function doSetInternal(&$parser) {
+               $main_page_name = $parser->getTitle()->getDBKey();
+               $main_page_namespace = $parser->getTitle()->getNamespace();
+               if ($main_page_name == self::$cur_page_name &&
+                       $main_page_namespace == self::$cur_page_namespace) {
+                       self::$internal_object_index++;
+               } else {
+                       self::$cur_page_name = $main_page_name;
+                       self::$cur_page_namespace = $main_page_namespace;
+                       self::$internal_object_index = 1;
+               }
+               $cur_object_num = self::$internal_object_index;
+               $params = func_get_args();
+               array_shift( $params ); // we already know the $parser...
+               $internal_object = new SIOInternalObject($parser->getTitle(), 
$cur_object_num);
+               $obj_to_page_prop_name = array_shift( $params );
+               $internal_object->addPropertyAndValue($obj_to_page_prop_name, 
$parser->getTitle());
+               foreach ( $params as $param ) {
+                       $parts = explode("=", trim($param));
+                       if (count($parts)==2) {
+                               $key = $parts[0];
+                               $value = $parts[1];
+                               $internal_object->addPropertyAndValue($key, 
$value);
+                       }
+               }
+               self::$internal_objects[] = $internal_object;
+       }
+
+       public static function updateData($subject) {
+               $sio_sql_store = new SIOSQLStore();
+               // Find all "pages" in the SMW IDs table that are internal
+               // objects for this page, and delete their properties from
+               // the SMW tables.
+               // Then save the current contents of the $internal_objects
+               // array.
+               $page_name = $subject->getDBKey();
+               $namespace = $subject->getNamespace();
+               $sio_sql_store->deletePageObjects($page_name, $namespace);
+               foreach (self::$internal_objects as $internal_object) {
+                       $sio_sql_store->storeAllInfo($page_name, $namespace, 
$internal_object);
+               }
+               self::$internal_objects = array();
+               return true;
+       }
+
+}



_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to