Netbrain has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/89815


Change subject: Initial import of code
......................................................................

Initial import of code

Change-Id: Iee080eec7c33b355433b3d13ddec35e4b857295c
---
A SemanticSifter.hooks.php
A SemanticSifter.i18n.magic.php
A SemanticSifter.i18n.php
A SemanticSifter.php
A css/ext.semanticsifter.css
A images/remove-filter.png
A js/ext.semanticsifter.js
7 files changed, 319 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/SemanticSifter 
refs/changes/15/89815/1

diff --git a/SemanticSifter.hooks.php b/SemanticSifter.hooks.php
new file mode 100644
index 0000000..ab41664
--- /dev/null
+++ b/SemanticSifter.hooks.php
@@ -0,0 +1,225 @@
+<?php
+
+class SemanticSifterHooks {
+       public static function parserFunctionInit(Parser &$parser){
+               $parser->setFunctionHook( 'sift', 
'SemanticSifterHooks::parserFunction' );
+               return true;
+       }
+
+       public static function parserFunction(Parser &$parser){
+               $parser->getOutput()->addModules( 'ext.semanticsifter' );
+               $parser->disableCache();
+
+               //get parameters
+               list($category, $properties) = 
self::getArguments(func_get_args());
+
+               //reconstruct filters
+               $filters = self::extractFilterParameter();
+
+               //create smw query filter
+               $tableFilters = self::createSMWQueryFilter($filters);
+
+               //create smw query
+               $tableComponent = self::createSMWQuery($parser, $category, 
$tableFilters, $properties);
+
+               //get smw property information and generate filterering 
component
+               $filteringComponent = self::createFilteringComponent($parser, 
$properties, $filters);
+
+               //create filters control
+               $filtersControl = self::createFiltersControl($parser, $filters);
+
+               //create final html output
+               $output = <<<EOT
+                       <div class="ss-container" style="display: none;">
+                                       $filtersControl
+                                       $filteringComponent
+                                       <div style="overflow:auto">
+                                               $tableComponent
+                                       </div>
+                       </div>
+EOT;
+
+               return array( $output, 'noparse' => true, 'isHTML' => true );
+
+       }
+
+       /**
+        * @param $args array
+        * @return array
+        */
+       private static function getArguments(array $args = array())
+       {
+               $category = $args[1];
+               $properties = array();
+               for ($i = 2; $i < count($args); $i++) {
+                       $properties[] = $args[$i];
+               }
+               return array($category, $properties);
+       }
+
+       /**
+        * @return array
+        */
+       private static function extractFilterParameter()
+       {
+               $filters = array();
+               if (isset($_GET['filter'])) {
+                       $rawFilters = explode(';', $_GET['filter']);
+                       for ($x = 0; $x < sizeof($rawFilters); $x++) {
+                               $parts = explode('::', 
base64_decode($rawFilters[$x]));
+                               if (sizeof($parts) !== 2) {
+                                       continue; //malformed query string
+                               }
+                               $property = $parts[0];
+                               $value = $parts[1];
+                               $filters[$property][$value] = null;
+                       }
+               }
+               return $filters;
+       }
+
+       /**
+        * @param $filters
+        * @return array
+        */
+       private static function createSMWQueryFilter($filters)
+       {
+               $tableFilters = '';
+               if (!empty($filters)) {
+                       foreach (array_keys($filters) as $property) {
+                               $c = 0;
+                               $tableFilters .= "[[$property::";
+                               foreach (array_keys($filters[$property]) as 
$value) {
+                                       if ($c > 0) {
+                                               $tableFilters .= '||';
+                                       }
+                                       $tableFilters .= $value;
+                                       $c++;
+                               }
+                               $tableFilters .= ']]';
+                       }
+               }
+               return $tableFilters;
+       }
+
+       /**
+        * @param Parser $parser
+        * @param $category
+        * @param $tableFilters
+        * @param $properties
+        * @return array
+        */
+       public static function createSMWQuery(Parser &$parser, $category, 
$tableFilters, $properties)
+       {
+               $noResults = '<div class="ss-noresults">No results</div>';
+               $tableQuery = "{{#ask: [[Category:$category]] 
$tableFilters|format=table|default=$noResults";
+               foreach ($properties as $p) {
+                       $tableQuery .= "|?$p";
+               }
+               $tableQuery .= "}}";
+               return $parser->recursiveTagParse($tableQuery);
+       }
+
+       /**
+        * @param $smwStore
+        * @param $property
+        * @return array
+        */
+       private static function getPropertyHits($smwStore, $property)
+       {
+               $wikiPages = $smwStore->getAllPropertySubjects($property);
+               $hits = array();
+               foreach ($wikiPages as $wp) {
+                       foreach ($smwStore->getPropertyValues($wp, $property) 
as $value) {
+                               $title = $value->getSerialization();
+                               if (!array_key_exists($title, $hits)) {
+                                       $hits[$title] = 0;
+                               }
+                               $hits[$title]++;
+                       }
+               }
+               return $hits;
+       }
+
+       /**
+        * @param Parser $parser
+        * @param $filters
+        * @return string
+        */
+       public static function createFiltersControl(Parser &$parser, $filters)
+       {
+               $filtersControl = '';
+               foreach (array_keys($filters) as $property) {
+                       foreach (array_keys($filters[$property]) as $value) {
+                               //remove the filter from the query param
+                               $replace = base64_encode("$property::$value");
+                               $filterArg = trim(str_replace($replace, '', 
$_GET['filter']), ';');
+                               if (!empty($filterArg)) {
+                                       $filterArg = "filter=$filterArg";
+                               }
+                               $filtersControl .= '<a href="' . 
$parser->recursiveTagParse("{{localurl:{{FULLPAGENAME}}|$filterArg}}") . 
'"><span class="ss-filterControl">' . $value . '</span></a>';
+                       }
+               }
+
+               if(!empty($filtersControl)){
+                       $clearButtonUrl = $parser->getTitle()->getLinkURL();
+                       $filtersControl = <<<EOT
+                               <div class="ss-filters">
+                                       <div class="ss-filterControls">Filters: 
$filtersControl</div>
+                                       <div>
+                                               <button 
onclick="window.location.href='$clearButtonUrl'">Clear all</button>
+                                       </div>
+                               </div>
+EOT;
+               }
+               return $filtersControl;
+       }
+
+       /**
+        * @param Parser $parser
+        * @param $properties
+        * @param $filters
+        * @return String
+        */
+       public static function createFilteringComponent(Parser &$parser, 
$properties, $filters)
+       {
+               $smwStore = \SMW\StoreFactory::getStore();
+               $filterTree = array();
+               foreach ($properties as $p) {
+                       $filterTree[$p] = array(
+                               "value" => "@$p",
+                               "children" => array()
+                       );
+
+                       $property = SMWDIProperty::newFromUserLabel($p);
+                       $hits = self::getPropertyHits($smwStore, $property);
+
+                       foreach ($hits as $title => $hit) {
+                               $filterLink = $filters;
+                               if (array_key_exists($p, $filterLink) && 
array_key_exists($title, $filterLink[$p])) {
+                                       continue;
+                               }
+
+                               $filterLink[$p][$title] = null;
+                               $filterArg = 'filter=';
+                               foreach (array_keys($filterLink) as $property) {
+                                       foreach 
(array_keys($filterLink[$property]) as $value) {
+                                               $filterArg .= 
base64_encode("$property::$value");
+                                               $filterArg .= ';';
+                                       }
+                               }
+                               $filterArg = substr($filterArg, 0, -1); 
//remove last ;
+                               $filterTree[$p]["children"][] = "* <span 
class=\"plainlinks\">[{{fullurl:{{FULLPAGENAME}}|$filterArg}} $title 
($hit)]</span>";
+                       }
+                       if (sizeof($filterTree[$p]["children"]) > 0) {
+                               $children = join("\n", 
$filterTree[$p]["children"]);
+                               $filterTree[$p] = 
"{$filterTree[$p]["value"]}\n$children";
+                       } else {
+                               unset($filterTree[$p]);
+                       }
+               }
+               $filterTree = join("\n", $filterTree);
+               $filteringComponent = 
$parser->recursivePreprocess("<sidebarmenu parser.menuitem.expanded=false 
editlink=off>Filter by property \n$filterTree</sidebarmenu>");
+               return $filteringComponent;
+       }
+}
\ No newline at end of file
diff --git a/SemanticSifter.i18n.magic.php b/SemanticSifter.i18n.magic.php
new file mode 100644
index 0000000..3ebb026
--- /dev/null
+++ b/SemanticSifter.i18n.magic.php
@@ -0,0 +1,5 @@
+<?php
+$magicWords = array();
+$magicWords['en'] = array(
+       'sift' => array( 0, 'sift' ),
+);
\ No newline at end of file
diff --git a/SemanticSifter.i18n.php b/SemanticSifter.i18n.php
new file mode 100644
index 0000000..c83e427
--- /dev/null
+++ b/SemanticSifter.i18n.php
@@ -0,0 +1,4 @@
+<?php
+$messages = array();
+$messages['en'] = array();
+$messages['qqq'] = array();
\ No newline at end of file
diff --git a/SemanticSifter.php b/SemanticSifter.php
new file mode 100644
index 0000000..f14a55c
--- /dev/null
+++ b/SemanticSifter.php
@@ -0,0 +1,36 @@
+<?php
+if ( !defined( 'MEDIAWIKI' ) ) {
+       echo( "This file is an extension to the MediaWiki software and cannot 
be used standalone.\n" );
+       die( 1 );
+}
+
+//credits
+$wgExtensionCredits['parserhook'][] = array(
+       'path' => __FILE__,
+       'name' => 'Semantic Sifter',
+       'description' => 'An extension which allows you to sift through 
semantic data',
+       'descriptionmsg' => 'semanticsifter-desc',
+       'version' => '0.1',
+       'author' => 'Kim Eik',
+);
+
+//autoload
+$wgAutoloadClasses['SemanticSifterHooks'] = dirname( __FILE__ ) . 
'/SemanticSifter.hooks.php';
+
+//hooks
+$wgHooks['ParserFirstCallInit'][] = 'SemanticSifterHooks::parserFunctionInit';
+
+//i18n
+$wgExtensionMessagesFiles['SemanticSifter'] = dirname( __FILE__ ) . 
'/SemanticSifter.i18n.php';
+$wgExtensionMessagesFiles['SemanticSifterMagic'] = dirname( __FILE__ ) . 
'/SemanticSifter.i18n.magic.php';
+
+//ajax
+$wgAjaxExportList[] = 'SemanticSifterAjax::filter';
+
+//resource modules
+$wgResourceModules['ext.semanticsifter'] = array(
+       'localBasePath' => dirname( __FILE__ ),
+       'remoteExtPath' => 'SemanticSifter',
+       'scripts' => '/js/ext.semanticsifter.js',
+       'styles' => '/css/ext.semanticsifter.css'
+);
\ No newline at end of file
diff --git a/css/ext.semanticsifter.css b/css/ext.semanticsifter.css
new file mode 100644
index 0000000..e71d275
--- /dev/null
+++ b/css/ext.semanticsifter.css
@@ -0,0 +1,44 @@
+.ss-filterControl {
+    margin: 3px;
+    padding: 3px;
+    padding-right: 25px;
+    border: 1px solid grey;
+    border-radius: 3px;
+    background-image: url('../images/remove-filter.png');
+    background-repeat:no-repeat;
+    background-position:right;
+    background-color: #f2f2f2;
+    display: inline-block;
+}
+
+.ss-filterControls a:active, .ss-filterControls a, ss-filterControls a:hover, 
ss-filterControls a:visited {
+    color:#0645ad;
+    text-decoration: none;
+}
+
+.ss-container .sidebar-menu-container a:visited,.ss-container 
.sidebar-menu-container a {
+    color:#0645ad;
+}
+
+.ss-container .sidebar-menu-container {
+    margin: 1em 5px 1em 0px;
+}
+
+.ss-container .sidebar-menu-container .sidebar-menu-item:first-child {
+    margin-top: 0px;
+}
+
+.ss-filters {
+    border: 1px solid #aaa;
+    background-color: #f9f9f9;
+    padding: 10px;
+}
+
+.ss-noresults {
+    background-color: #f9f9f9;
+    text-align: center;
+    font-weight: bold;
+    padding: 3px;
+    border: 1px solid #aaa;
+    margin: 1em 0px 0px 0px;
+}
diff --git a/images/remove-filter.png b/images/remove-filter.png
new file mode 100644
index 0000000..8a9d1ff
--- /dev/null
+++ b/images/remove-filter.png
Binary files differ
diff --git a/js/ext.semanticsifter.js b/js/ext.semanticsifter.js
new file mode 100644
index 0000000..f6de9ed
--- /dev/null
+++ b/js/ext.semanticsifter.js
@@ -0,0 +1,5 @@
+( function ( $, mw ) {
+    $(document).ready(function(){
+        $('.ss-container').fadeIn();
+    });
+})( $, mw );
\ No newline at end of file

-- 
To view, visit https://gerrit.wikimedia.org/r/89815
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iee080eec7c33b355433b3d13ddec35e4b857295c
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/SemanticSifter
Gerrit-Branch: master
Gerrit-Owner: Netbrain <k...@heldig.org>

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

Reply via email to