PageRenderTime 47ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/sites/all/modules/contrib/civicrm/api/v3/Generic/Getlist.php

https://gitlab.com/virtualrealms/d7civicrm
PHP | 290 lines | 189 code | 16 blank | 85 comment | 22 complexity | a03afd4c6b40c4ce1a4dc8a13f4b1cb2 MD5 | raw file
  1. <?php
  2. /*
  3. +--------------------------------------------------------------------+
  4. | CiviCRM version 5 |
  5. +--------------------------------------------------------------------+
  6. | Copyright CiviCRM LLC (c) 2004-2019 |
  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. /**
  28. * @package CiviCRM_APIv3
  29. */
  30. /**
  31. * Generic api wrapper used for quicksearch and autocomplete.
  32. *
  33. * @param array $apiRequest
  34. *
  35. * @return mixed
  36. */
  37. function civicrm_api3_generic_getList($apiRequest) {
  38. $entity = _civicrm_api_get_entity_name_from_camel($apiRequest['entity']);
  39. $request = $apiRequest['params'];
  40. $meta = civicrm_api3_generic_getfields(['action' => 'get'] + $apiRequest, FALSE);
  41. // Hey api, would you like to provide default values?
  42. $fnName = "_civicrm_api3_{$entity}_getlist_defaults";
  43. $defaults = function_exists($fnName) ? $fnName($request) : [];
  44. _civicrm_api3_generic_getList_defaults($entity, $request, $defaults, $meta['values']);
  45. // Hey api, would you like to format the search params?
  46. $fnName = "_civicrm_api3_{$entity}_getlist_params";
  47. $fnName = function_exists($fnName) ? $fnName : '_civicrm_api3_generic_getlist_params';
  48. $fnName($request);
  49. $request['params']['check_permissions'] = !empty($apiRequest['params']['check_permissions']);
  50. $result = civicrm_api3($entity, 'get', $request['params']);
  51. // Hey api, would you like to format the output?
  52. $fnName = "_civicrm_api3_{$entity}_getlist_output";
  53. $fnName = function_exists($fnName) ? $fnName : '_civicrm_api3_generic_getlist_output';
  54. $values = $fnName($result, $request, $entity, $meta['values']);
  55. _civicrm_api3_generic_getlist_postprocess($result, $request, $values);
  56. $output = ['page_num' => $request['page_num']];
  57. // Limit is set for searching but not fetching by id
  58. if (!empty($request['params']['options']['limit'])) {
  59. // If we have an extra result then this is not the last page
  60. $last = $request['params']['options']['limit'] - 1;
  61. $output['more_results'] = isset($values[$last]);
  62. unset($values[$last]);
  63. }
  64. return civicrm_api3_create_success($values, $request['params'], $entity, 'getlist', CRM_Core_DAO::$_nullObject, $output);
  65. }
  66. /**
  67. * Set defaults for api.getlist.
  68. *
  69. * @param string $entity
  70. * @param array $request
  71. * @param array $apiDefaults
  72. * @param array $fields
  73. */
  74. function _civicrm_api3_generic_getList_defaults($entity, &$request, $apiDefaults, $fields) {
  75. $defaults = [
  76. 'page_num' => 1,
  77. 'input' => '',
  78. 'image_field' => NULL,
  79. 'color_field' => isset($fields['color']) ? 'color' : NULL,
  80. 'id_field' => $entity == 'option_value' ? 'value' : 'id',
  81. 'description_field' => [],
  82. 'add_wildcard' => Civi::settings()->get('includeWildCardInName'),
  83. 'params' => [],
  84. 'extra' => [],
  85. ];
  86. // Find main field from meta
  87. foreach (['sort_name', 'title', 'label', 'name', 'subject'] as $field) {
  88. if (isset($fields[$field])) {
  89. $defaults['label_field'] = $defaults['search_field'] = $field;
  90. break;
  91. }
  92. }
  93. // Find fields to be used for the description
  94. foreach (['description'] as $field) {
  95. if (isset($fields[$field])) {
  96. $defaults['description_field'][] = $field;
  97. }
  98. }
  99. $resultsPerPage = Civi::settings()->get('search_autocomplete_count');
  100. if (isset($request['params']) && isset($apiDefaults['params'])) {
  101. $request['params'] += $apiDefaults['params'];
  102. }
  103. $request += $apiDefaults + $defaults;
  104. // Default api params
  105. $params = [
  106. 'sequential' => 1,
  107. 'options' => [],
  108. ];
  109. // When searching e.g. autocomplete
  110. if ($request['input']) {
  111. $params[$request['search_field']] = ['LIKE' => ($request['add_wildcard'] ? '%' : '') . $request['input'] . '%'];
  112. }
  113. // When looking up a field e.g. displaying existing record
  114. if (!empty($request['id'])) {
  115. if (is_string($request['id']) && strpos($request['id'], ',')) {
  116. $request['id'] = explode(',', trim($request['id'], ', '));
  117. }
  118. // Don't run into search limits when prefilling selection
  119. $params['options']['limit'] = NULL;
  120. unset($params['options']['offset'], $request['params']['options']['limit'], $request['params']['options']['offset']);
  121. $params[$request['id_field']] = is_array($request['id']) ? ['IN' => $request['id']] : $request['id'];
  122. }
  123. $request['params'] += $params;
  124. $request['params']['options'] += [
  125. // Add pagination parameters
  126. 'sort' => $request['label_field'],
  127. // Adding one extra result allows us to see if there are any more
  128. 'limit' => $resultsPerPage + 1,
  129. // Because sql is zero-based
  130. 'offset' => ($request['page_num'] - 1) * $resultsPerPage,
  131. ];
  132. }
  133. /**
  134. * Fallback implementation of getlist_params. May be overridden by individual apis.
  135. *
  136. * @param array $request
  137. */
  138. function _civicrm_api3_generic_getlist_params(&$request) {
  139. $fieldsToReturn = [$request['id_field'], $request['label_field']];
  140. if (!empty($request['image_field'])) {
  141. $fieldsToReturn[] = $request['image_field'];
  142. }
  143. if (!empty($request['color_field'])) {
  144. $fieldsToReturn[] = $request['color_field'];
  145. }
  146. if (!empty($request['description_field'])) {
  147. $fieldsToReturn = array_merge($fieldsToReturn, (array) $request['description_field']);
  148. }
  149. $request['params']['return'] = array_unique(array_merge($fieldsToReturn, $request['extra']));
  150. }
  151. /**
  152. * Fallback implementation of getlist_output. May be overridden by individual api functions.
  153. *
  154. * @param array $result
  155. * @param array $request
  156. * @param string $entity
  157. * @param array $fields
  158. *
  159. * @return array
  160. */
  161. function _civicrm_api3_generic_getlist_output($result, $request, $entity, $fields) {
  162. $output = [];
  163. if (!empty($result['values'])) {
  164. foreach ($result['values'] as $row) {
  165. $data = [
  166. 'id' => $row[$request['id_field']],
  167. 'label' => $row[$request['label_field']],
  168. ];
  169. if (!empty($request['description_field'])) {
  170. $data['description'] = [];
  171. foreach ((array) $request['description_field'] as $field) {
  172. if (!empty($row[$field])) {
  173. if (!isset($fields[$field]['pseudoconstant'])) {
  174. $data['description'][] = $row[$field];
  175. }
  176. else {
  177. $data['description'][] = CRM_Core_PseudoConstant::getLabel(
  178. _civicrm_api3_get_BAO($entity),
  179. $field,
  180. $row[$field]
  181. );
  182. }
  183. }
  184. }
  185. };
  186. if (!empty($request['image_field'])) {
  187. $data['image'] = isset($row[$request['image_field']]) ? $row[$request['image_field']] : '';
  188. }
  189. if (isset($row[$request['color_field']])) {
  190. $data['color'] = $row[$request['color_field']];
  191. }
  192. $output[] = $data;
  193. }
  194. }
  195. return $output;
  196. }
  197. /**
  198. * Common postprocess for getlist output
  199. *
  200. * @param $result
  201. * @param $request
  202. * @param $values
  203. */
  204. function _civicrm_api3_generic_getlist_postprocess($result, $request, &$values) {
  205. $chains = [];
  206. foreach ($request['params'] as $field => $param) {
  207. if (substr($field, 0, 4) === 'api.') {
  208. $chains[] = $field;
  209. }
  210. }
  211. if (!empty($result['values'])) {
  212. foreach (array_values($result['values']) as $num => $row) {
  213. foreach ($request['extra'] as $field) {
  214. $values[$num]['extra'][$field] = isset($row[$field]) ? $row[$field] : NULL;
  215. }
  216. foreach ($chains as $chain) {
  217. $values[$num][$chain] = isset($row[$chain]) ? $row[$chain] : NULL;
  218. }
  219. }
  220. }
  221. }
  222. /**
  223. * Provide metadata for this api
  224. *
  225. * @param array $params
  226. * @param array $apiRequest
  227. */
  228. function _civicrm_api3_generic_getlist_spec(&$params, $apiRequest) {
  229. $params += [
  230. 'page_num' => [
  231. 'title' => 'Page Number',
  232. 'description' => "Current page of a multi-page lookup",
  233. 'type' => CRM_Utils_Type::T_INT,
  234. ],
  235. 'input' => [
  236. 'title' => 'Search Input',
  237. 'description' => "String to search on",
  238. 'type' => CRM_Utils_Type::T_TEXT,
  239. ],
  240. 'params' => [
  241. 'title' => 'API Params',
  242. 'description' => "Additional filters to send to the {$apiRequest['entity']} API.",
  243. ],
  244. 'extra' => [
  245. 'title' => 'Extra',
  246. 'description' => 'Array of additional fields to return.',
  247. ],
  248. 'image_field' => [
  249. 'title' => 'Image Field',
  250. 'description' => "Field that this entity uses to store icons (usually automatic)",
  251. 'type' => CRM_Utils_Type::T_TEXT,
  252. ],
  253. 'id_field' => [
  254. 'title' => 'ID Field',
  255. 'description' => "Field that uniquely identifies this entity (usually automatic)",
  256. 'type' => CRM_Utils_Type::T_TEXT,
  257. ],
  258. 'description_field' => [
  259. 'title' => 'Description Field',
  260. 'description' => "Field that this entity uses to store summary text (usually automatic)",
  261. 'type' => CRM_Utils_Type::T_TEXT,
  262. ],
  263. 'label_field' => [
  264. 'title' => 'Label Field',
  265. 'description' => "Field to display as title of results (usually automatic)",
  266. 'type' => CRM_Utils_Type::T_TEXT,
  267. ],
  268. 'search_field' => [
  269. 'title' => 'Search Field',
  270. 'description' => "Field to search on (assumed to be the same as label field unless otherwise specified)",
  271. 'type' => CRM_Utils_Type::T_TEXT,
  272. ],
  273. ];
  274. }