summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/Fulltext/MySQLValueMatchConditionBuilder.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/Fulltext/MySQLValueMatchConditionBuilder.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/Fulltext/MySQLValueMatchConditionBuilder.php147
1 files changed, 147 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/Fulltext/MySQLValueMatchConditionBuilder.php b/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/Fulltext/MySQLValueMatchConditionBuilder.php
new file mode 100644
index 00000000..9580e2d5
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/Fulltext/MySQLValueMatchConditionBuilder.php
@@ -0,0 +1,147 @@
+<?php
+
+namespace SMW\SQLStore\QueryEngine\Fulltext;
+
+use SMW\Query\Language\ValueDescription;
+
+/**
+ * @license GNU GPL v2+
+ * @since 2.5
+ *
+ * @author mwjames
+ */
+class MySQLValueMatchConditionBuilder extends ValueMatchConditionBuilder {
+
+ /**
+ * @see ValueMatchConditionBuilder::canApplyFulltextSearchMatchCondition
+ * @since 2.5
+ *
+ * @param ValueDescription $description
+ *
+ * @return boolean
+ */
+ public function canApplyFulltextSearchMatchCondition( ValueDescription $description ) {
+
+ if ( !$this->isEnabled() ) {
+ return false;
+ }
+
+ if ( $description->getProperty() !== null && $this->isExemptedProperty( $description->getProperty() ) ) {
+ return false;
+ }
+
+ if ( !$this->searchTable->isValidByType( $description->getDataItem()->getDiType() ) ) {
+ return false;
+ }
+
+ $matchableText = $this->getMatchableTextFromDescription(
+ $description
+ );
+
+ $comparator = $description->getComparator();
+
+ if ( $matchableText && ( $comparator === SMW_CMP_LIKE || $comparator === SMW_CMP_NLKE ) ) {
+
+ // http://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html
+ // innodb_ft_min_token_size and innodb_ft_max_token_size are used
+ // for InnoDB search indexes. ft_min_word_len and ft_max_word_len
+ // are used for MyISAM search indexes
+
+ // Don't count any wildcard
+ return $this->hasMinTokenLength( str_replace( '*', '', $matchableText ) );
+ }
+
+ return false;
+ }
+
+ /**
+ * @see ValueMatchConditionBuilder::getWhereCondition
+ * @since 2.5
+ *
+ * @param ValueDescription $description
+ * @param string $temporaryTable
+ *
+ * @return string
+ */
+ public function getWhereCondition( ValueDescription $description, $temporaryTable = '' ) {
+
+ $affix = '';
+ $matchableText = $this->getMatchableTextFromDescription(
+ $description
+ );
+
+ // Any query modifier? Take care of it before any tokenizer or ngrams
+ // distort the marker
+ if (
+ ( $pos = strrpos( $matchableText, '&BOL' ) ) !== false ||
+ ( $pos = strrpos( $matchableText, '&INL' ) ) !== false ||
+ ( $pos = strrpos( $matchableText, '&QEX' ) ) !== false ) {
+ $affix = mb_strcut( $matchableText, $pos );
+ $matchableText = str_replace( $affix, '', $matchableText );
+ }
+
+ $value = $this->textSanitizer->sanitize(
+ $matchableText,
+ true
+ );
+
+ $value .= $affix;
+
+ // A leading or trailing minus sign indicates that this word must not
+ // be present in any of the rows that are returned.
+ // InnoDB only supports leading minus signs.
+ if ( $description->getComparator() === SMW_CMP_NLKE ) {
+ $value = '-' . $value;
+ }
+
+ $temporaryTable = $temporaryTable !== '' ? $temporaryTable . '.' : '';
+ $column = $temporaryTable . $this->searchTable->getIndexField();
+
+ $property = $description->getProperty();
+ $propertyCondition = '';
+
+ // Full text is collected in a single table therefore limit the match
+ // process by adding the PID as an additional condition
+ if ( $property !== null ) {
+ $propertyCondition = 'AND ' . $temporaryTable . 'p_id=' . $this->searchTable->getIdByProperty( $property );
+ }
+
+ $querySearchModifier = $this->getQuerySearchModifier(
+ $value
+ );
+
+ return "MATCH($column) AGAINST (" . $this->searchTable->addQuotes( $value ) . " $querySearchModifier) $propertyCondition";
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param string &$value
+ *
+ * @return string
+ */
+ public function getQuerySearchModifier( &$value ) {
+
+ // @see http://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html
+ // "MySQL can perform boolean full-text searches using the IN BOOLEAN
+ // MODE modifier. With this modifier, certain characters have special
+ // meaning at the beginning or end of words ..."
+ if ( strpos( $value, '&BOL' ) !== false ) {
+ $value = str_replace( '&BOL', '', $value );
+ return 'IN BOOLEAN MODE';
+ }
+
+ if ( strpos( $value, '&INL' ) !== false ) {
+ $value = str_replace( '&INL', '', $value );
+ return 'IN NATURAL LANGUAGE MODE';
+ }
+
+ if ( strpos( $value, '&QEX' ) !== false ) {
+ $value = str_replace( '&QEX', '', $value );
+ return 'WITH QUERY EXPANSION';
+ }
+
+ return 'IN BOOLEAN MODE';
+ }
+
+}