Passed
Push — master ( 45c7a2...54b5a7 )
by Aimeos
02:20
created

SQL::getConnection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2023
7
 * @package Base
8
 * @subpackage Common
9
 */
10
11
12
namespace Aimeos\Base\Criteria\Expression\Sort;
13
14
15
/**
16
 * SQL implementation for sorting objects.
17
 *
18
 * @package Base
19
 * @subpackage Common
20
 */
21
class SQL extends Base
22
{
23
	private static $operators = array( '+' => 'ASC', '-' => 'DESC' );
24
	private \Aimeos\Base\DB\Connection\Iface $conn;
25
26
27
	/**
28
	 * Initializes the object.
29
	 *
30
	 * @param \Aimeos\Base\DB\Connection\Iface $conn Database connection object
31
	 * @param string $operator Sorting operator ("+": ascending, "-": descending)
32
	 * @param string $name Name of the variable or column to sort
33
	 */
34
	public function __construct( \Aimeos\Base\DB\Connection\Iface $conn, string $operator, string $name )
35
	{
36
		if( !isset( self::$operators[$operator] ) ) {
37
			throw new \Aimeos\Base\Exception( sprintf( 'Invalid operator "%1$s"', $operator ) );
38
		}
39
40
		parent::__construct( $operator, $name );
41
		$this->conn = $conn;
42
	}
43
44
45
	/**
46
	 * Returns the available operators for the expression.
47
	 *
48
	 * @return array List of available operators
49
	 */
50
	public static function getOperators() : array
51
	{
52
		return array_keys( self::$operators );
53
	}
54
55
56
	/**
57
	 * Generates a string from the expression objects.
58
	 *
59
	 * @param array $types Associative list of variable or column names as keys and their corresponding types
60
	 * @param array $translations Associative list of variable or column names that should be translated
61
	 * @param \Aimeos\Base\Criteria\Plugin\Iface[] $plugins Associative list of item names as keys and plugin objects as values
62
	 * @param array $funcs Associative list of item names and functions modifying the conditions
63
	 * @return mixed Expression that evaluates to a boolean result
64
	 */
65
	public function toSource( array $types, array $translations = [], array $plugins = [], array $funcs = [] )
66
	{
67
		$this->setPlugins( $plugins );
68
69
		$name = $this->getName();
70
		$transname = $this->translateName( $name, $translations, $funcs );
71
72
		if( !$transname ) {
73
			throw new \Aimeos\Base\Exception( sprintf( 'Invalid sorting "%1$s"', $this->getName() ) );
74
		}
75
76
		if( !isset( $types[$name] ) ) {
77
			throw new \Aimeos\Base\Exception( sprintf( 'Invalid name "%1$s"', $name ) );
78
		}
79
80
		return $transname . ' ' . self::$operators[$this->getOperator()];
0 ignored issues
show
Bug introduced by
Are you sure $transname of type array|mixed can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

80
		return /** @scrutinizer ignore-type */ $transname . ' ' . self::$operators[$this->getOperator()];
Loading history...
81
	}
82
83
84
	/**
85
	 * Escapes the value so it can be inserted into a SQL statement
86
	 *
87
	 * @param string $operator Operator used for the expression
88
	 * @param string $type Type constant
89
	 * @param mixed $value Value that the variable or column should be compared to
90
	 * @return string Escaped value
91
	 */
92
	protected function escape( string $operator, string $type, $value ) : string
93
	{
94
		$value = $this->translateValue( $this->getName(), $value, $type );
95
96
		switch( $type )
97
		{
98
			case \Aimeos\Base\DB\Statement\Base::PARAM_NULL:
99
				$value = 'null'; break;
100
			case \Aimeos\Base\DB\Statement\Base::PARAM_BOOL:
101
				$value = (int) (bool) $value; break;
102
			case \Aimeos\Base\DB\Statement\Base::PARAM_INT:
103
				$value = $value !== '' ? (int) $value : 'null'; break;
104
			case \Aimeos\Base\DB\Statement\Base::PARAM_FLOAT:
105
				$value = $value !== '' ? (double) $value : 'null'; break;
106
			case \Aimeos\Base\DB\Statement\Base::PARAM_STR:
107
				if( $operator === '~=' ) {
108
					$value = '\'%' . str_replace( ['#', '%', '_', '['], ['##', '#%', '#_', '#['], $this->getConnection()->escape( (string) $value ) ) . '%\''; break;
109
				}
110
				if( $operator === '=~' ) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment if this fall-through is intended.
Loading history...
111
					$value = '\'' . str_replace( ['#', '%', '_', '['], ['##', '#%', '#_', '#['], $this->getConnection()->escape( (string) $value ) ) . '%\''; break;
112
				}
113
			default: // all other operators: escape in default case
114
				$value = '\'' . $this->getConnection()->escape( (string) $value ) . '\'';
115
		}
116
117
		return $value;
118
	}
119
120
121
	/**
122
	 * Returns the connection object.
123
	 *
124
	 * return \Aimeos\Base\DB\Connection\Iface Connection object
125
	 */
126
	public function getConnection() : \Aimeos\Base\DB\Connection\Iface
127
	{
128
		return $this->conn;
129
	}
130
131
132
	/**
133
	 * Returns the internal type of the function parameter.
134
	 *
135
	 * @param mixed &$item Reference to parameter value (will be updated if necessary)
136
	 * @return string Internal parameter type
137
	 * @throws \Aimeos\Base\Exception If an error occurs
138
	 */
139
	protected function getParamType( &$item ) : string
140
	{
141
		if( is_null( $item ) ) {
142
			return \Aimeos\Base\DB\Statement\Base::PARAM_NULL;
143
		} elseif( is_float( $item ) ) {
144
			return \Aimeos\Base\DB\Statement\Base::PARAM_FLOAT;
145
		} elseif( is_int( $item ) ) {
146
			return \Aimeos\Base\DB\Statement\Base::PARAM_INT;
147
		}
148
149
		return \Aimeos\Base\DB\Statement\Base::PARAM_STR;
150
	}
151
}
152