3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 * $Id: Selector.php 11510 2007-09-18 09:21:34Z lobo $
20 * This class is used to retrieve and display a range of
21 * contacts that match the given criteria (specifically for
22 * results of advanced search options.
24 class CRM_Contact_Selector_Custom
extends CRM_Contact_Selector
{
27 * This defines two actions- View and Edit.
31 public static $_links = NULL;
34 * We use desc to remind us what that column is, name is used in the tpl
38 public static $_columnHeaders;
41 * Properties of contact we're interested in displaying
44 public static $_properties = ['contact_id', 'contact_type', 'display_name'];
47 * FormValues is the array returned by exportValues called on
48 * the HTML_QuickForm_Controller for that page.
55 * Params is the array in a value used by the search query creator
62 * Represent the type of selector
71 * The public visible fields to be shown to the user
78 * The object that implements the search interface
83 protected $_customSearchClass;
88 * @param $customSearchClass
89 * @param array $formValues
90 * Array of form values imported.
91 * @param array $params
92 * Array of parameters for query.
93 * @param null $returnProperties
94 * @param \const|int $action - action of search basic or advanced.
96 * @param bool $includeContactIds
97 * @param bool $searchChildGroups
98 * @param string $searchContext
99 * @param null $contextMenu
101 * @return \CRM_Contact_Selector_Custom
103 public function __construct(
107 $returnProperties = NULL,
108 $action = CRM_Core_Action
::NONE
,
109 $includeContactIds = FALSE,
110 $searchChildGroups = TRUE,
111 $searchContext = 'search',
114 $this->_customSearchClass
= $customSearchClass;
115 $this->_formValues
= $formValues;
116 $this->_includeContactIds
= $includeContactIds;
118 $ext = CRM_Extension_System
::singleton()->getMapper();
120 if (!$ext->isExtensionKey($customSearchClass)) {
121 if ($ext->isExtensionClass($customSearchClass)) {
122 $customSearchFile = $ext->classToPath($customSearchClass);
123 require_once $customSearchFile;
126 require_once str_replace('_', DIRECTORY_SEPARATOR
, $customSearchClass) . '.php';
128 $this->_search
= new $customSearchClass($formValues);
131 $fnName = $ext->keyToPath
;
132 $customSearchFile = $fnName($customSearchClass, 'search');
133 $className = $ext->keyToClass($customSearchClass, 'search');
134 $this->_search
= new $className($formValues);
139 * This method returns the links that are given for each search row.
141 * Currently the links added for each row are
147 public static function &links() {
148 list($key) = func_get_args();
149 $searchContext = "&context=custom";
150 $extraParams = ($key) ?
"&key={$key}" : NULL;
152 if (!(self
::$_links)) {
154 CRM_Core_Action
::VIEW
=> [
155 'name' => ts('View'),
156 'url' => 'civicrm/contact/view',
157 'qs' => "reset=1&cid=%%id%%{$extraParams}{$searchContext}",
158 'class' => 'no-popup',
159 'title' => ts('View Contact Details'),
161 CRM_Core_Action
::UPDATE
=> [
162 'name' => ts('Edit'),
163 'url' => 'civicrm/contact/add',
164 'qs' => 'reset=1&action=update&cid=%%id%%',
165 'class' => 'no-popup',
166 'title' => ts('Edit Contact Details'),
170 $config = CRM_Core_Config
::singleton();
171 //CRM-16552: mapAPIKey is not mandatory as google no longer requires an API Key
172 if ($config->mapProvider
&& ($config->mapAPIKey ||
$config->mapProvider
== 'Google')) {
173 self
::$_links[CRM_Core_Action
::MAP
] = [
175 'url' => 'civicrm/contact/map',
176 'qs' => 'reset=1&cid=%%id%%&searchType=custom',
177 'class' => 'no-popup',
178 'title' => ts('Map Contact'),
182 return self
::$_links;
186 * Getter for array of the parameters required for creating pager.
189 * @param array $params
191 public function getPagerParams($action, &$params) {
192 $params['status'] = ts('Contact %%StatusMessage%%');
193 $params['csvString'] = NULL;
194 $params['rowCount'] = CRM_Utils_Pager
::ROWCOUNT
;
196 $params['buttonTop'] = 'PagerTopButton';
197 $params['buttonBottom'] = 'PagerBottomButton';
201 * Returns the column headers as an array of tuples.
203 * Keys are name, sortName, key to the sort array.
205 * @param string $action
206 * The action being performed.
207 * @param string $output
208 * What should the result set include (web/email/csv).
211 * the column headers that need to be displayed
213 public function &getColumnHeaders($action = NULL, $output = NULL) {
214 $columns = $this->_search
->columns();
216 if ($output == CRM_Core_Selector_Controller
::EXPORT ||
$output == CRM_Core_Selector_Controller
::SCREEN
) {
217 foreach ($columns as $name => $key) {
218 $headers[$key] = $name;
223 foreach ($columns as $name => $key) {
228 'direction' => CRM_Utils_Sort
::ASCENDING
,
240 * Returns total number of rows for the query.
242 * @param null $action
245 * Total number of rows
247 public function getTotalCount($action) {
248 return $this->_search
->count();
252 * Returns all the rows in the given offset and rowCount.
254 * @param string $action
255 * The action being performed.
257 * The row number to start from.
258 * @param int $rowCount
259 * The number of rows to return.
260 * @param string $sort
261 * The sql string that describes the sort order.
262 * @param string $output
263 * What should the result set include (web/email/csv).
266 * the total number of rows for this action
268 public function &getRows($action, $offset, $rowCount, $sort, $output = NULL) {
270 $includeContactIDs = FALSE;
271 if (($output == CRM_Core_Selector_Controller
::EXPORT ||
272 $output == CRM_Core_Selector_Controller
::SCREEN
274 $this->_formValues
['radio_ts'] == 'ts_sel'
276 $includeContactIDs = TRUE;
279 $sql = $this->_search
->all($offset, $rowCount, $sort, $includeContactIDs);
280 // contact query object used for creating $sql
281 $contactQueryObj = NULL;
282 if (method_exists($this->_search
, 'getQueryObj') &&
283 is_a($this->_search
->getQueryObj(), 'CRM_Contact_BAO_Query')
285 $contactQueryObj = $this->_search
->getQueryObj();
288 $dao = CRM_Core_DAO
::executeQuery($sql);
290 $columns = $this->_search
->columns();
291 $columnNames = array_values($columns);
292 $links = self
::links($this->_key
);
294 $permissions = [CRM_Core_Permission
::getPermission()];
295 if (CRM_Core_Permission
::check('delete contacts')) {
296 $permissions[] = CRM_Core_Permission
::DELETE
;
298 $mask = CRM_Core_Action
::mask($permissions);
301 if (method_exists($this->_customSearchClass
,
307 if (is_a($this->_search
, 'CRM_Contact_Form_Search_Custom_Basic')) {
310 // process the result of the query
312 while ($dao->fetch()) {
316 // if contact query object present
317 // process pseudo constants
318 if ($contactQueryObj) {
319 $contactQueryObj->convertToPseudoNames($dao);
322 // the columns we are interested in
323 foreach ($columnNames as $property) {
324 // Get part of name after last . (if any)
325 $unqualified_property = CRM_Utils_Array
::First(array_slice(explode('.', $property), -1));
326 $row[$property] = $dao->$unqualified_property;
327 if (!empty($dao->$unqualified_property)) {
332 $contactID = $dao->contact_id ??
NULL;
334 $row['checkbox'] = CRM_Core_Form
::CB_PREFIX
. $contactID;
335 $row['action'] = CRM_Core_Action
::formLink($links,
337 ['id' => $contactID],
340 'contact.custom.actions',
344 $row['contact_id'] = $contactID;
347 $this->_search
->alterRow($row);
351 $row['contact_type'] = CRM_Contact_BAO_Contact_Utils
::getImage($dao->contact_sub_type ?
$dao->contact_sub_type
: $dao->contact_type
, FALSE, $contactID
358 $this->buildPrevNextCache($sort);
364 * Given the current formValues, gets the query in local language.
367 * which contains an array of strings
369 public function getQILL() {
378 public function getSummary() {
379 return $this->_search
->summary();
383 * Name of export file.
385 * @param string $output
391 public function getExportFileName($output = 'csv') {
392 return ts('CiviCRM Custom Search');
400 public function alphabetQuery() {
405 * Generate contact ID query.
407 * @param array $params
410 * @param null $displayRelationshipType
411 * @param string $queryOperator
415 public function contactIDQuery($params, $sortID, $displayRelationshipType = NULL, $queryOperator = 'AND') {
416 // $action, $displayRelationshipType and $queryOperator are unused. I have
417 // no idea why they are there.
419 // I wonder whether there is some helper function for this:
421 if (preg_match('/([0-9]*)(_(u|d))?/', $sortID, $matches)) {
422 $columns = array_values($this->_search
->columns());
423 $sort = $columns[$matches[1] - 1];
424 if (array_key_exists(3, $matches) && $matches[3] == 'd') {
432 $sql = $this->_search
->contactIDs(0, 0, $sort);
433 return CRM_Core_DAO
::executeQuery($sql);
441 public function addActions(&$rows) {
442 $links = self
::links($this->_key
);
444 $permissions = [CRM_Core_Permission
::getPermission()];
445 if (CRM_Core_Permission
::check('delete contacts')) {
446 $permissions[] = CRM_Core_Permission
::DELETE
;
448 $mask = CRM_Core_Action
::mask($permissions);
450 foreach ($rows as $id => & $row) {
451 $row['action'] = CRM_Core_Action
::formLink($links,
453 ['id' => $row['contact_id']],
456 'contact.custom.actions',
468 public function removeActions(&$rows) {
469 foreach ($rows as $rid => & $rValue) {
470 unset($rValue['action']);