File: LikeValue.php

package info (click to toggle)
mediawiki 1%3A1.43.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 417,464 kB
  • sloc: php: 1,062,949; javascript: 664,290; sql: 9,714; python: 5,458; xml: 3,489; sh: 1,131; makefile: 64
file content (69 lines) | stat: -rw-r--r-- 1,812 bytes parent folder | download
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
<?php

namespace Wikimedia\Rdbms;

use InvalidArgumentException;
use Wikimedia\Rdbms\Database\DbQuoter;

/**
 * Content of like value
 *
 * @newable
 * @since 1.42
 */
class LikeValue {
	/** @var (string|LikeMatch)[] */
	private array $values = [];

	/**
	 * @param string|LikeMatch $value
	 * @param string|LikeMatch ...$values
	 */
	public function __construct( $value, ...$values ) {
		if ( !is_string( $value ) && !( $value instanceof LikeMatch ) ) {
			$type = get_debug_type( $value );
			throw new InvalidArgumentException( "\$value must be string or LikeMatch, got $type" );
		}
		$this->values = [ $value ];

		foreach ( $values as $value ) {
			if ( !is_string( $value ) && !( $value instanceof LikeMatch ) ) {
				$type = get_debug_type( $value );
				throw new InvalidArgumentException( "\$value must be string or LikeMatch, got $type" );
			}
			$this->values[] = $value;
		}
	}

	/**
	 * @internal to be used by rdbms library only
	 * @return-taint none
	 */
	public function toSql( DbQuoter $dbQuoter ): string {
		$s = '';

		// We use ` instead of \ as the default LIKE escape character, since addQuotes()
		// may escape backslashes, creating problems of double escaping. The `
		// character has good cross-DBMS compatibility, avoiding special operators
		// in MS SQL like ^ and %
		$escapeChar = '`';

		foreach ( $this->values as $value ) {
			if ( $value instanceof LikeMatch ) {
				$s .= $value->toString();
			} else {
				$s .= $this->escapeLikeInternal( $value, $escapeChar );
			}
		}

		return $dbQuoter->addQuotes( $s ) . ' ESCAPE ' . $dbQuoter->addQuotes( $escapeChar );
	}

	private function escapeLikeInternal( $s, $escapeChar = '`' ) {
		return str_replace(
			[ $escapeChar, '%', '_' ],
			[ "{$escapeChar}{$escapeChar}", "{$escapeChar}%", "{$escapeChar}_" ],
			$s
		);
	}
}