[TASK] Provide QueryHelper to prepare SQL fragments for the QueryBuilder
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Database / Query / QueryHelper.php
1 <?php
2 declare (strict_types = 1);
3 namespace TYPO3\CMS\Core\Database\Query;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19
20 /**
21 * Contains misc helper methods to build syntactically valid SQL queries.
22 * Most helper functions are required to deal with legacy data where the
23 * format of the input is not strict enough to reliably use the SQL parts
24 * in queries directly.
25 *
26 * @internal
27 */
28 class QueryHelper
29 {
30 /**
31 * Takes an input, possibly prefixed with ORDER BY, and explodes it into
32 * and array of arrays where each item consists of a fieldName and a order
33 * direction.
34 *
35 * Each of the resulting fieldName/direction pairs can be used passed into
36 * QueryBuilder::orderBy() so sort a query result set.
37 *
38 * @param string $input eg . "ORDER BY title, uid
39 * @return array|array[] Array of arrays containing fieldName/direction pairs
40 */
41 public static function parseOrderBy(string $input): array
42 {
43 $input = preg_replace('/^(?:ORDER[[:space:]]*BY[[:space:]]*)+/i', '', trim($input)) ?: '';
44 $orderExpressions = GeneralUtility::trimExplode(',', $input, true);
45
46 return array_map(
47 function ($expression) {
48 list($fieldName, $order) = GeneralUtility::trimExplode(' ', $expression, true);
49
50 return [$fieldName, $order];
51 },
52 $orderExpressions
53 );
54 }
55
56 /**
57 * Removes the prefix "GROUP BY" from the input string.
58 *
59 * This function should be used when you can't guarantee that the string
60 * that you want to use as a GROUP BY fragment is not prefixed.
61 *
62 * @param string $input eg. "GROUP BY title, uid
63 * @return array|string[] column names to group by
64 */
65 public static function parseGroupBy(string $input): array
66 {
67 $input = preg_replace('/^(?:GROUP[[:space:]]*BY[[:space:]]*)+/i', '', trim($input)) ?: '';
68
69 return GeneralUtility::trimExplode(',', $input, true);
70 }
71
72 /**
73 * Removes the prefixes AND/OR from the input string.
74 *
75 * This function should be used when you can't guarantee that the string
76 * that you want to use as a WHERE fragment is not prefixed.
77 *
78 * @param string $constraint The where part fragment with a possible leading AND or OR operator
79 * @return string The modified where part without leading operator
80 */
81 public static function stripLogicalOperatorPrefix(string $constraint): string
82 {
83 return preg_replace('/^(?:(AND|OR)[[:space:]]*)+/i', '', trim($constraint)) ?: '';
84 }
85 }