Commit | Line | Data |
---|---|---|
8bcc0d86 CW |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
4 | | CiviCRM version 4.7 | | |
5 | +--------------------------------------------------------------------+ | |
3b8eef99 | 6 | | Copyright CiviCRM LLC (c) 2004-2017 | |
8bcc0d86 CW |
7 | +--------------------------------------------------------------------+ |
8 | | This file is a part of CiviCRM. | | |
9 | | | | |
10 | | CiviCRM is free software; you can copy, modify, and distribute it | | |
11 | | under the terms of the GNU Affero General Public License | | |
12 | | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | | |
13 | | | | |
14 | | CiviCRM is distributed in the hope that it will be useful, but | | |
15 | | WITHOUT ANY WARRANTY; without even the implied warranty of | | |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | | |
17 | | See the GNU Affero General Public License for more details. | | |
18 | | | | |
19 | | You should have received a copy of the GNU Affero General Public | | |
20 | | License and the CiviCRM Licensing Exception along | | |
21 | | with this program; if not, contact CiviCRM LLC | | |
22 | | at info[AT]civicrm[DOT]org. If you have questions about the | | |
23 | | GNU Affero General Public License or the licensing of CiviCRM, | | |
24 | | see the CiviCRM license FAQ at http://civicrm.org/licensing | | |
25 | +--------------------------------------------------------------------+ | |
26 | */ | |
27 | namespace Civi\API; | |
28 | ||
29 | /** | |
30 | */ | |
31 | class Api3SelectQuery extends SelectQuery { | |
32 | ||
33 | protected $apiVersion = 3; | |
34 | ||
35 | /** | |
36 | * @inheritDoc | |
37 | */ | |
38 | protected function buildWhereClause() { | |
39 | foreach ($this->where as $key => $value) { | |
40 | $table_name = NULL; | |
41 | $column_name = NULL; | |
42 | ||
43 | if (substr($key, 0, 7) == 'filter.') { | |
44 | // Legacy support for old filter syntax per the test contract. | |
45 | // (Convert the style to the later one & then deal with them). | |
46 | $filterArray = explode('.', $key); | |
47 | $value = array($filterArray[1] => $value); | |
48 | $key = 'filters'; | |
49 | } | |
50 | ||
51 | // Legacy support for 'filter's construct. | |
52 | if ($key == 'filters') { | |
53 | foreach ($value as $filterKey => $filterValue) { | |
54 | if (substr($filterKey, -4, 4) == 'high') { | |
55 | $key = substr($filterKey, 0, -5); | |
56 | $value = array('<=' => $filterValue); | |
57 | } | |
58 | ||
59 | if (substr($filterKey, -3, 3) == 'low') { | |
60 | $key = substr($filterKey, 0, -4); | |
61 | $value = array('>=' => $filterValue); | |
62 | } | |
63 | ||
64 | if ($filterKey == 'is_current' || $filterKey == 'isCurrent') { | |
65 | // Is current is almost worth creating as a 'sql filter' in the DAO function since several entities have the concept. | |
66 | $todayStart = date('Ymd000000', strtotime('now')); | |
67 | $todayEnd = date('Ymd235959', strtotime('now')); | |
68 | $a = self::MAIN_TABLE_ALIAS; | |
69 | $this->query->where("($a.start_date <= '$todayStart' OR $a.start_date IS NULL) | |
70 | AND ($a.end_date >= '$todayEnd' OR $a.end_date IS NULL) | |
71 | AND a.is_active = 1"); | |
72 | } | |
73 | } | |
74 | } | |
75 | // Ignore the "options" param if it is referring to api options and not a field in this entity | |
76 | if ( | |
77 | $key === 'options' && is_array($value) | |
78 | && !in_array(\CRM_Utils_Array::first(array_keys($value)), \CRM_Core_DAO::acceptedSQLOperators()) | |
79 | ) { | |
80 | continue; | |
81 | } | |
82 | $field = $this->getField($key); | |
83 | if ($field) { | |
84 | $key = $field['name']; | |
85 | } | |
86 | if (in_array($key, $this->entityFieldNames)) { | |
87 | $table_name = self::MAIN_TABLE_ALIAS; | |
88 | $column_name = $key; | |
89 | } | |
90 | elseif (($cf_id = \CRM_Core_BAO_CustomField::getKeyID($key)) != FALSE) { | |
91 | list($table_name, $column_name) = $this->addCustomField($this->apiFieldSpec['custom_' . $cf_id], 'INNER'); | |
92 | } | |
93 | elseif (strpos($key, '.')) { | |
94 | $fkInfo = $this->addFkField($key, 'INNER'); | |
95 | if ($fkInfo) { | |
96 | list($table_name, $column_name) = $fkInfo; | |
97 | $this->validateNestedInput($key, $value); | |
98 | } | |
99 | } | |
100 | // I don't know why I had to specifically exclude 0 as a key - wouldn't the others have caught it? | |
101 | // We normally silently ignore null values passed in - if people want IS_NULL they can use acceptedSqlOperator syntax. | |
102 | if ((!$table_name) || empty($key) || is_null($value)) { | |
103 | // No valid filter field. This might be a chained call or something. | |
104 | // Just ignore this for the $where_clause. | |
105 | continue; | |
106 | } | |
107 | if (!is_array($value)) { | |
108 | $this->query->where(array("`$table_name`.`$column_name` = @value"), array( | |
109 | "@value" => $value, | |
110 | )); | |
111 | } | |
112 | else { | |
113 | // We expect only one element in the array, of the form | |
114 | // "operator" => "rhs". | |
115 | $operator = \CRM_Utils_Array::first(array_keys($value)); | |
116 | if (!in_array($operator, \CRM_Core_DAO::acceptedSQLOperators())) { | |
117 | $this->query->where(array("{$table_name}.{$column_name} = @value"), array("@value" => $value)); | |
118 | } | |
119 | else { | |
120 | $this->query->where(\CRM_Core_DAO::createSQLFilter("{$table_name}.{$column_name}", $value)); | |
121 | } | |
122 | } | |
123 | } | |
124 | } | |
125 | ||
126 | /** | |
127 | * @inheritDoc | |
128 | */ | |
129 | protected function getFields() { | |
130 | require_once 'api/v3/Generic.php'; | |
131 | // Call this function directly instead of using the api wrapper to force unique field names off | |
132 | $apiSpec = \civicrm_api3_generic_getfields(array( | |
133 | 'entity' => $this->entity, | |
134 | 'version' => 3, | |
135 | 'params' => array('action' => 'get'), | |
136 | ), FALSE); | |
137 | return $apiSpec['values']; | |
138 | } | |
139 | ||
140 | /** | |
141 | * Fetch a field from the getFields list | |
142 | * | |
143 | * Searches by name, uniqueName, and api.aliases | |
144 | */ | |
145 | protected function getField($fieldName) { | |
146 | if (!$fieldName) { | |
147 | return NULL; | |
148 | } | |
149 | if (isset($this->apiFieldSpec[$fieldName])) { | |
150 | return $this->apiFieldSpec[$fieldName]; | |
151 | } | |
152 | foreach ($this->apiFieldSpec as $field) { | |
153 | if ( | |
154 | $fieldName == \CRM_Utils_Array::value('uniqueName', $field) || | |
155 | array_search($fieldName, \CRM_Utils_Array::value('api.aliases', $field, array())) !== FALSE | |
156 | ) { | |
157 | return $field; | |
158 | } | |
159 | } | |
160 | return NULL; | |
161 | } | |
162 | ||
163 | } |