Merge pull request #15813 from eileenmcnaughton/fee
[civicrm-core.git] / Civi / Api4 / Generic / AbstractQueryAction.php
CommitLineData
19b53e5b
C
1<?php
2
380f3545
TO
3/*
4 +--------------------------------------------------------------------+
41498ac5 5 | Copyright CiviCRM LLC. All rights reserved. |
380f3545 6 | |
41498ac5
TO
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
380f3545
TO
10 +--------------------------------------------------------------------+
11 */
12
13/**
14 *
15 * @package CRM
ca5cec67 16 * @copyright CiviCRM LLC https://civicrm.org/licensing
380f3545
TO
17 * $Id$
18 *
19 */
20
21
19b53e5b
C
22namespace Civi\Api4\Generic;
23
24/**
25 * Base class for all actions that need to fetch records (Get, Update, Delete, etc)
26 *
27 * @package Civi\Api4\Generic
28 *
29 * @method $this setWhere(array $wheres)
30 * @method array getWhere()
31 * @method $this setOrderBy(array $order)
32 * @method array getOrderBy()
33 * @method $this setLimit(int $limit)
34 * @method int getLimit()
35 * @method $this setOffset(int $offset)
36 * @method int getOffset()
37 */
38abstract class AbstractQueryAction extends AbstractAction {
39
40 /**
41 * Criteria for selecting items.
42 *
43 * $example->addWhere('contact_type', 'IN', array('Individual', 'Household'))
44 *
45 * @var array
46 */
47 protected $where = [];
48
49 /**
50 * Array of field(s) to use in ordering the results
51 *
52 * Defaults to id ASC
53 *
54 * $example->addOrderBy('sort_name', 'ASC')
55 *
56 * @var array
57 */
58 protected $orderBy = [];
59
60 /**
61 * Maximum number of results to return.
62 *
63 * Defaults to unlimited.
64 *
65 * Note: the Api Explorer sets this to 25 by default to avoid timeouts.
66 * Change or remove this default for your application code.
67 *
68 * @var int
69 */
70 protected $limit = 0;
71
72 /**
73 * Zero-based index of first result to return.
74 *
75 * Defaults to "0" - first record.
76 *
77 * @var int
78 */
79 protected $offset = 0;
80
81 /**
82 * @param string $field
83 * @param string $op
84 * @param mixed $value
85 * @return $this
86 * @throws \API_Exception
87 */
88 public function addWhere($field, $op, $value = NULL) {
89 if (!in_array($op, \CRM_Core_DAO::acceptedSQLOperators())) {
90 throw new \API_Exception('Unsupported operator');
91 }
92 $this->where[] = [$field, $op, $value];
93 return $this;
94 }
95
96 /**
97 * Adds one or more AND/OR/NOT clause groups
98 *
99 * @param string $operator
100 * @param mixed $condition1 ... $conditionN
101 * Either a nested array of arguments, or a variable number of arguments passed to this function.
102 *
103 * @return $this
104 * @throws \API_Exception
105 */
106 public function addClause($operator, $condition1) {
107 if (!is_array($condition1[0])) {
108 $condition1 = array_slice(func_get_args(), 1);
109 }
110 $this->where[] = [$operator, $condition1];
111 return $this;
112 }
113
114 /**
115 * @param string $field
116 * @param string $direction
117 * @return $this
118 */
119 public function addOrderBy($field, $direction = 'ASC') {
120 $this->orderBy[$field] = $direction;
121 return $this;
122 }
123
124 /**
125 * A human-readable where clause, for the reading enjoyment of you humans.
126 *
127 * @param array $whereClause
128 * @param string $op
129 * @return string
130 */
131 protected function whereClauseToString($whereClause = NULL, $op = 'AND') {
132 if ($whereClause === NULL) {
133 $whereClause = $this->where;
134 }
135 $output = '';
136 if (!is_array($whereClause) || !$whereClause) {
137 return $output;
138 }
139 if (in_array($whereClause[0], ['AND', 'OR', 'NOT'])) {
140 $op = array_shift($whereClause);
141 if ($op == 'NOT') {
142 $output = 'NOT ';
143 $op = 'AND';
144 }
145 return $output . '(' . $this->whereClauseToString($whereClause, $op) . ')';
146 }
147 elseif (isset($whereClause[1]) && in_array($whereClause[1], \CRM_Core_DAO::acceptedSQLOperators())) {
148 $output = $whereClause[0] . ' ' . $whereClause[1] . ' ';
149 if (isset($whereClause[2])) {
150 $output .= is_array($whereClause[2]) ? '[' . implode(', ', $whereClause[2]) . ']' : $whereClause[2];
151 }
152 }
153 else {
154 $clauses = [];
155 foreach (array_filter($whereClause) as $clause) {
156 $clauses[] = $this->whereClauseToString($clause, $op);
157 }
158 $output = implode(" $op ", $clauses);
159 }
160 return $output;
161 }
162
163}