Yaron Koren has uploaded a new change for review.

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

Change subject: Added handling for new data type, 'Searchtext'
......................................................................

Added handling for new data type, 'Searchtext'

Change-Id: I263cd915cb14e44096349acf19d0a94263a71634
---
M Cargo.css
M Cargo.php
M CargoQueryDisplayer.php
M CargoSQLQuery.php
M extension.json
A search/CargoSearchMySQL.php
6 files changed, 109 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Cargo 
refs/changes/39/277839/1

diff --git a/Cargo.css b/Cargo.css
index bb048a6..5ccbd81 100644
--- a/Cargo.css
+++ b/Cargo.css
@@ -18,3 +18,10 @@
        padding: 5px;
        border: #ccc 1px solid;
 }
+
+span.searchresult {
+       font-size: 95%;
+}
+span.searchmatch {
+       font-weight: bold;
+}
diff --git a/Cargo.php b/Cargo.php
index 9b803ca..6a32edd 100644
--- a/Cargo.php
+++ b/Cargo.php
@@ -141,6 +141,7 @@
 $wgAutoloadClasses['CargoTagCloudFormat'] = $dir . 
'/formats/CargoTagCloudFormat.php';
 $wgAutoloadClasses['CargoExhibitFormat'] = $dir . 
'/formats/CargoExhibitFormat.php';
 $wgAutoloadClasses['CargoNativeFormat'] = $dir . 
'/formats/CargoNativeFormat.php';
+$wgAutoloadClasses['CargoSearchMySQL'] = $dir . '/search/CargoSearchMySQL.php';
 
 $wgAutoloadClasses['CargoPageSchemas'] = $dir . '/CargoPageSchemas.php';
 
diff --git a/CargoQueryDisplayer.php b/CargoQueryDisplayer.php
index 0d80fcd..8968080 100644
--- a/CargoQueryDisplayer.php
+++ b/CargoQueryDisplayer.php
@@ -145,6 +145,9 @@
                                        // cool, but those are apparently far
                                        // from universal symbols.
                                        $text = ( $value == true ) ? wfMessage( 
'htmlform-yes' )->text() : wfMessage( 'htmlform-no' )->text();
+                               } elseif ( $fieldType == 'Searchtext' && 
array_key_exists( $fieldName, $this->mSQLQuery->mSearchTerms ) ) {
+                                       $searchTerms = 
$this->mSQLQuery->mSearchTerms[$fieldName];
+                                       $text = Html::rawElement( 'span', 
array( 'class' => 'searchresult' ), self::getTextSnippet( $value, $searchTerms 
) );
                                } else {
                                        $text = self::formatFieldValue( $value, 
$fieldType, $fieldDescription, $this->mParser );
                                }
@@ -189,7 +192,14 @@
                        return $value;
                } elseif ( $type == 'Wikitext' || $type == '' ) {
                        return CargoUtils::smartParse( $value, $parser );
+               } elseif ( $type == 'Searchtext' ) {
+                       if ( strlen( $value ) > 300 ) {
+                               return substr( $value, 0, 300 ) . ' ...';
+                       } else {
+                               return $value;
+                       }
                }
+
                // If it's not any of these specially-handled types, just
                // return the value.
                return $value;
@@ -243,6 +253,32 @@
                }
        }
 
+       /**
+        * Based heavily on MediaWiki's SearchResult::getTextSnippet()
+        */
+       function getTextSnippet( $text, $terms ) {
+               global $wgAdvancedSearchHighlighting;
+               list( $contextlines, $contextchars ) = 
SearchEngine::userHighlightPrefs();
+
+               foreach ( $terms as $i => $term ) {
+                       $terms[$i] = str_replace( array( '"', "'" ), '', $term 
);
+               }
+
+               $h = new SearchHighlighter();
+               if ( count( $terms ) > 0 ) {
+                       if ( $wgAdvancedSearchHighlighting ) {
+                               $snippet = $h->highlightText( $text, $terms, 
$contextlines, $contextchars );
+                       } else {
+                               $snippet = $h->highlightSimple( $text, $terms, 
$contextlines, $contextchars );
+                       }
+               } else {
+                       $snippet = $h->highlightNone( $text, $contextlines, 
$contextchars );
+               }
+
+               // Why is this necessary for Cargo, but not for MediaWiki?
+               return html_entity_decode( $snippet );
+       }
+
        public function displayQueryResults( $formatter, $queryResults ) {
                if ( count( $queryResults ) == 0 ) {
                        if ( array_key_exists( 'default', $this->mDisplayParams 
) ) {
diff --git a/CargoSQLQuery.php b/CargoSQLQuery.php
index c892f2e..6d21655 100644
--- a/CargoSQLQuery.php
+++ b/CargoSQLQuery.php
@@ -25,6 +25,7 @@
        public $mHavingStr;
        public $mOrderByStr;
        public $mQueryLimit;
+       public $mSearchTerms = array();
 
        /**
         * This is newFromValues() instead of __construct() so that an
@@ -59,6 +60,7 @@
                $sqlQuery->handleVirtualFields();
                $sqlQuery->handleVirtualCoordinateFields();
                $sqlQuery->handleDateFields();
+               $sqlQuery->handleSearchTextFields();
                $sqlQuery->setMWJoinConds( $cdb );
                $sqlQuery->mQueryLimit = $wgCargoDefaultQueryLimit;
                if ( $limitStr != '' ) {
@@ -922,10 +924,10 @@
                                // There are much better ways to do this, but
                                // for now, just make a "bounding box" instead
                                // of a bounding circle.
-                               $newWhere = "$tableName.{$fieldName}__lat >= " 
. max( $latitude - $latDistance, -90 ) .
+                               $newWhere = " $tableName.{$fieldName}__lat >= " 
. max( $latitude - $latDistance, -90 ) .
                                        " AND $tableName.{$fieldName}__lat <= " 
. min( $latitude + $latDistance, 90 ) .
                                        " AND $tableName.{$fieldName}__lon >= " 
. max( $longitude - $longDistance, -180 ) .
-                                       " AND $tableName.{$fieldName}__lon <= " 
. min( $longitude + $longDistance, 180 );
+                                       " AND $tableName.{$fieldName}__lon <= " 
. min( $longitude + $longDistance, 180 ) . ' ';
 
                                if ( $foundMatch1 ) {
                                        $this->mWhereStr = preg_replace( 
$pattern1, $newWhere, $this->mWhereStr );
@@ -1006,6 +1008,50 @@
                }
        }
 
+       function handleSearchTextFields() {
+               $searchTextFields = array();
+               foreach ( $this->mTableSchemas as $tableName => $tableSchema ) {
+                       foreach ( $tableSchema->mFieldDescriptions as 
$fieldName => $fieldDescription ) {
+                               if ( $fieldDescription->mType == 'Searchtext' ) 
{
+                                       $searchTextFields[] = array(
+                                               'fieldName' => $fieldName,
+                                               'tableName' => $tableName
+                                       );
+                               }
+                       }
+               }
+
+               $matches = array();
+               foreach ( $searchTextFields as $searchTextField ) {
+                       $fieldName = $searchTextField['fieldName'];
+                       $tableName = $searchTextField['tableName'];
+                       $patternSuffix = '(\s+MATCHES\s*)([^)\s]*)/i';
+
+                       $pattern1 = CargoUtils::getSQLTableAndFieldPattern( 
$tableName, $fieldName, false ) . $patternSuffix;
+                       $foundMatch1 = preg_match( $pattern1, $this->mWhereStr, 
$matches );
+                       $pattern2 = CargoUtils::getSQLFieldPattern( $fieldName, 
false ) . $patternSuffix;
+                       $foundMatch2 = false;
+
+                       if ( !$foundMatch1 ) {
+                               $foundMatch2 = preg_match( $pattern2, 
$this->mWhereStr, $matches );
+                       }
+                       if ( $foundMatch1 || $foundMatch2 ) {
+                               $searchString = $matches[3];
+                               $newWhere = " MATCH($tableName.$fieldName) 
AGAINST ($searchString IN BOOLEAN MODE) ";
+
+                               if ( $foundMatch1 ) {
+                                       $this->mWhereStr = preg_replace( 
$pattern1, $newWhere, $this->mWhereStr );
+                               } elseif ( $foundMatch2 ) {
+                                       $this->mWhereStr = preg_replace( 
$pattern2, $newWhere, $this->mWhereStr );
+                               }
+                               $searchEngine = new CargoSearchMySQL();
+                               $searchTerms = $searchEngine->getSearchTerms( 
$searchString );
+                               // @TODO - does $tableName need to be in there?
+                               $this->mSearchTerms[$fieldName] = $searchTerms;
+                       }
+               }
+       }
+
        /**
         * Adds the "cargo" table prefix for every element in the SQL query
         * except for 'tables' and 'join on' - for 'tables', the prefix is
diff --git a/extension.json b/extension.json
index ec8271c..cc95a96 100644
--- a/extension.json
+++ b/extension.json
@@ -96,6 +96,7 @@
                "CargoTagCloudFormat": "formats/CargoTagCloudFormat.php",
                "CargoExhibitFormat": "formats/CargoExhibitFormat.php",
                "CargoNativeFormat": "formats/CargoNativeFormat.php",
+               "CargoSearchMySQL": "search/CargoSearchMySQL.php",
                "CargoPageSchemas": "CargoPageSchemas.php",
                "CargoAppliedFilter": "drilldown/CargoAppliedFilter.php",
                "CargoFilter": "drilldown/CargoFilter.php",
diff --git a/search/CargoSearchMySQL.php b/search/CargoSearchMySQL.php
new file mode 100644
index 0000000..8b63132
--- /dev/null
+++ b/search/CargoSearchMySQL.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * We need to create subclasses, instead of just calling the functionality,
+ * because both filter() and, more importantly, $searchTerms are currently
+ * "protected".
+ */
+class CargoSearchMySQL extends SearchMySQL {
+
+       function getSearchTerms( $searchString ) {
+               $filteredTerm = $this->filter( $searchString );
+               $this->parseQuery( $filteredTerm, false );
+               return $this->searchTerms;
+       }
+
+}

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I263cd915cb14e44096349acf19d0a94263a71634
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Cargo
Gerrit-Branch: master
Gerrit-Owner: Yaron Koren <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to