summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/Fulltext/SQLiteValueMatchConditionBuilder.php
blob: 5357da68852b3bc1c4a9470ecd7c9e1500a8d0b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?php

namespace SMW\SQLStore\QueryEngine\Fulltext;

use SMW\Query\Language\ValueDescription;

/**
 * @license GNU GPL v2+
 * @since 2.5
 *
 * @author mwjames
 */
class SQLiteValueMatchConditionBuilder 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 ) ) {
			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 = '' ) {

		$matchableText = $this->getMatchableTextFromDescription(
			$description
		);

		$value = $this->textSanitizer->sanitize(
			$matchableText,
			true
		);

		// 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;
		}

		// Something like [[Has text::!~database]] will cause a
		// "malformed MATCH expression" due to "An FTS query may not consist
		// entirely of terms or term-prefix queries with unary "-" operators
		// attached to them." and doing "NOT database" will result in an empty
		// result set

		$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->addQuotes(
				$this->searchTable->getIdByProperty( $property )
			);
		}

		return $column . " MATCH " . $this->searchTable->addQuotes( $value ) . "$propertyCondition";
	}

}