CRM-12865 - Define regions and CSS classes for profile forms
[civicrm-core.git] / CRM / Profile / Page / Listings.php
CommitLineData
6a488035
TO
1<?php
2
3/*
4 +--------------------------------------------------------------------+
5 | CiviCRM version 4.3 |
6 +--------------------------------------------------------------------+
7 | Copyright CiviCRM LLC (c) 2004-2013 |
8 +--------------------------------------------------------------------+
9 | This file is a part of CiviCRM. |
10 | |
11 | CiviCRM is free software; you can copy, modify, and distribute it |
12 | under the terms of the GNU Affero General Public License |
13 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | |
15 | CiviCRM is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Affero General Public |
21 | License and the CiviCRM Licensing Exception along |
22 | with this program; if not, contact CiviCRM LLC |
23 | at info[AT]civicrm[DOT]org. If you have questions about the |
24 | GNU Affero General Public License or the licensing of CiviCRM, |
25 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
26 +--------------------------------------------------------------------+
27*/
28
29/**
30 *
31 * @package CRM
32 * @copyright CiviCRM LLC (c) 2004-2013
33 * $Id$
34 *
35 */
36
37/**
38 * This implements the profile page for all contacts. It uses a selector
39 * object to do the actual dispay. The fields displayd are controlled by
40 * the admin
41 */
42class CRM_Profile_Page_Listings extends CRM_Core_Page {
43
44 /**
45 * all the fields that are listings related
46 *
47 * @var array
48 * @access protected
49 */
50 protected $_fields;
51
52 /**
53 * the custom fields for this domain
54 *
55 * @var array
56 * @access protected
57 */
58 protected $_customFields;
59
60 /**
61 * The input params from the request
62 *
63 * @var array
64 * @access protected
65 */
66 protected $_params;
67
68 /**
69 * The group id that we are editing
70 *
71 * @var int
72 */
73 protected $_gid;
74
75 /**
76 * state whether to display search form or not
77 *
78 * @var int
79 */
80 protected $_search;
81
82 /**
83 * Should we display a map
84 *
85 * @var int
86 */
87 protected $_map;
88
89 /**
90 * Store profile ids if multiple profile ids are passed using comma separated.
91 * Currently lets implement this functionality only for dialog mode
92 */
93 protected $_profileIds = array();
94
95 /**
96 * extracts the parameters from the request and constructs information for
97 * the selector object to do a query
98 *
99 * @return void
100 * @access public
101 *
102 */
103 function preProcess() {
104
105 $this->_search = TRUE;
106
107 $search = CRM_Utils_Request::retrieve('search', 'Boolean', $this, FALSE, 0, 'GET');
108 if (isset($search) && $search == 0) {
109 $this->_search = FALSE;
110 }
111
112 $this->_gid = $this->get('gid');
113 $this->_profileIds = $this->get('profileIds');
114
115 $gids = explode(',', CRM_Utils_Request::retrieve('gid', 'String', CRM_Core_DAO::$_nullObject, FALSE, 0, 'GET'));
116
117 if ((count($gids) > 1) && !$this->_profileIds && empty($this->_profileIds)) {
118 if (!empty($gids)) {
119 foreach ($gids as $pfId) {
120 $this->_profileIds[] = CRM_Utils_Type::escape($pfId, 'Positive');
121 }
122 }
123
124 // check if we are rendering mixed profiles
125 if (CRM_Core_BAO_UFGroup::checkForMixProfiles($this->_profileIds)) {
126 CRM_Core_Error::fatal(ts('You cannot combine profiles of multiple types.'));
127 }
128
129 $this->_gid = $this->_profileIds[0];
130 $this->set('profileIds', $this->_profileIds);
131 $this->set('gid', $this->_gid);
132 }
133
134 if (!$this->_gid) {
135 $this->_gid = CRM_Utils_Request::retrieve('gid', 'Positive', $this, FALSE, 0, 'GET');
136 }
137
138 if (empty($this->_profileIds)) {
139 $gids = $this->_gid;
140 }
141 else {
142 $gids = $this->_profileIds;
143 }
144
145 $this->_fields = CRM_Core_BAO_UFGroup::getListingFields(CRM_Core_Action::UPDATE,
146 CRM_Core_BAO_UFGroup::PUBLIC_VISIBILITY | CRM_Core_BAO_UFGroup::LISTINGS_VISIBILITY,
147 FALSE, $gids, FALSE, 'Profile',
148 CRM_Core_Permission::SEARCH
149 );
150
151 $this->_customFields = CRM_Core_BAO_CustomField::getFieldsForImport(NULL, FALSE, FALSE, FALSE, TRUE, TRUE);
152 $this->_params = array();
153
154 $resetArray = array(
155 'group', 'tag', 'preferred_communication_method', 'do_not_phone',
156 'do_not_email', 'do_not_mail', 'do_not_sms', 'do_not_trade', 'gender',
157 );
158
159 foreach ($this->_fields as $name => $field) {
160 if ((substr($name, 0, 6) == 'custom') && CRM_Utils_Array::value('is_search_range', $field)) {
161 $from = CRM_Utils_Request::retrieve($name . '_from', 'String',
162 $this, FALSE, NULL, 'REQUEST'
163 );
164 $to = CRM_Utils_Request::retrieve($name . '_to', 'String',
165 $this, FALSE, NULL, 'REQUEST'
166 );
167 $value = array();
168 if ($from && $to) {
169 $value['from'] = $from;
170 $value['to'] = $to;
171 }
172 elseif ($from) {
173 $value['from'] = $from;
174 }
175 elseif ($to) {
176 $value['to'] = $to;
177 }
178 }
179 elseif ((substr($name, 0, 7) == 'custom_') &&
180 (CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField',
181 substr($name, 7), 'html_type'
182 ) == 'TextArea')
183 ) {
184 $value = trim(CRM_Utils_Request::retrieve($name, 'String',
185 $this, FALSE, NULL, 'REQUEST'
186 ));
187 if (!empty($value) &&
188 !((substr($value, 0, 1) == '%') &&
189 (substr($value, -1, 1) == '%')
190 )
191 ) {
192 $value = '%' . $value . '%';
193 }
194 }
195 elseif (CRM_Utils_Array::value('html_type', $field) == 'Multi-Select State/Province'
196 || CRM_Utils_Array::value('html_type', $field) == 'Multi-Select Country'
197 ) {
198 $value = CRM_Utils_Request::retrieve($name, 'String', $this, FALSE, NULL, 'REQUEST');
199 if (!is_array($value)) {
200 $value = explode(CRM_Core_DAO::VALUE_SEPARATOR, substr($value, 1, -1));
201 }
202 }
203 elseif ($name == 'contact_sub_type') {
204 $v = CRM_Utils_Request::retrieve($name, 'String', $this, FALSE, NULL, 'REQUEST');
205 if ($v && !is_array($v)) {
206 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, trim($v, CRM_Core_DAO::VALUE_SEPARATOR));
207 }
208 if (!empty($v)) {
209 foreach ($v as $item) {
210 $value[$item] = 1;
211 }
212 }
213 }
214 else {
215 $value = CRM_Utils_Request::retrieve($name, 'String',
216 $this, FALSE, NULL, 'REQUEST'
217 );
218 }
219
220 if (($name == 'group' || $name == 'tag') && !empty($value) && !is_array($value)) {
221 $v = explode(',', $value);
222 $value = array();
223 foreach ($v as $item) {
224 $value[$item] = 1;
225 }
226 }
227
228 $customField = CRM_Utils_Array::value($name, $this->_customFields);
229
230 if (!empty($_POST) && !CRM_Utils_Array::value($name, $_POST)) {
231 if ($customField) {
232 // reset checkbox/radio because a form does not send null checkbox values
233 if (in_array($customField['html_type'],
234 array('Multi-Select', 'CheckBox', 'Multi-Select State/Province', 'Multi-Select Country', 'Radio')
235 )) {
236 // only reset on a POST submission if we dont see any value
237 $value = NULL;
238 $this->set($name, $value);
239 }
240 }
241 elseif (in_array($name, $resetArray)) {
242 $value = NULL;
243 $this->set($name, $value);
244 }
245 }
246
247 if (isset($value) && $value != NULL) {
248 if (!is_array($value)) {
249 $value = trim($value);
250 }
251 $this->_params[$name] = $this->_fields[$name]['value'] = $value;
252 }
253 }
254
255 // set the prox params
256 // need to ensure proximity searching is enabled
257 $proximityVars = array(
258 'street_address', 'city', 'postal_code', 'state_province_id',
259 'country_id', 'distance', 'distance_unit',
260 );
261 foreach ($proximityVars as $var) {
262 $value = CRM_Utils_Request::retrieve("prox_{$var}",
263 'String',
264 $this, FALSE, NULL, 'REQUEST'
265 );
266 if ($value) {
267 $this->_params["prox_{$var}"] = $value;
268 }
269 }
270
271
272 // set the params in session
273 $session = CRM_Core_Session::singleton();
274 $session->set('profileParams', $this->_params);
275 }
276
277 /**
278 * run this page (figure out the action needed and perform it).
279 *
280 * @return void
281 */
282 function run() {
283 $this->preProcess();
284
285 $this->assign('recentlyViewed', FALSE);
46312a4d 286 $this->assign('ufGroupName', 'unknown'); // override later (if possible)
6a488035
TO
287
288 if ($this->_gid) {
289 $ufgroupDAO = new CRM_Core_DAO_UFGroup();
290 $ufgroupDAO->id = $this->_gid;
291 if (!$ufgroupDAO->find(TRUE)) {
292 CRM_Core_Error::fatal();
293 }
294 }
295
296 if ($this->_gid) {
297 // set the title of the page
298 if ($ufgroupDAO->title) {
299 CRM_Utils_System::setTitle($ufgroupDAO->title);
300 }
46312a4d
TO
301 if ($ufgroupDAO->name) {
302 $this->assign('ufGroupName', $ufgroupDAO->name);
303 }
6a488035
TO
304 }
305
306 $this->assign('isReset', TRUE);
307
308 $formController = new CRM_Core_Controller_Simple('CRM_Profile_Form_Search',
309 ts('Search Profile'),
310 CRM_Core_Action::ADD
311 );
312 $formController->setEmbedded(TRUE);
313 $formController->set('gid', $this->_gid);
314 $formController->process();
315
316 $searchError = FALSE;
317 // check if there is a POST
318 if (!empty($_POST)) {
319 if ($formController->validate() !== TRUE) {
320 $searchError = TRUE;
321 }
322 }
323
324 // also get the search tpl name
325 $this->assign('searchTPL', $formController->getTemplateFileName());
326
327 $this->assign('search', $this->_search);
328
329 // search if search returned a form error?
330 if ((!CRM_Utils_Array::value('reset', $_GET) ||
331 CRM_Utils_Array::value('force', $_GET)
332 ) &&
333 !$searchError
334 ) {
335 $this->assign('isReset', FALSE);
336
337 $gidString = $this->_gid;
338 if (empty($this->_profileIds)) {
339 $gids = $this->_gid;
340 }
341 else {
342 $gids = $this->_profileIds;
343 $gidString = implode(',', $this->_profileIds);
344 }
345
346 $map = 0;
347 $linkToUF = 0;
348 $editLink = FALSE;
349 if ($this->_gid) {
350 $map = $ufgroupDAO->is_map;
351 $linkToUF = $ufgroupDAO->is_uf_link;
352 $editLink = $ufgroupDAO->is_edit_link;
353 }
354
355 if ($map) {
356 $this->assign('mapURL',
357 CRM_Utils_System::url('civicrm/profile/map',
358 "map=1&gid={$gidString}&reset=1"
359 )
360 );
361 }
362 if (CRM_Utils_Array::value('group', $this->_params)) {
363 foreach ($this->_params['group'] as $key => $val) {
364 if (!$val) {
365 unset($this->_params['group'][$key]);
366 }
367 }
368 }
369
370 // the selector will override this if the user does have
371 // edit permissions as determined by the mask, CRM-4341
372 // do not allow edit for anon users in joomla frontend, CRM-4668
373 $config = CRM_Core_Config::singleton();
374 if (!CRM_Core_Permission::check('access CiviCRM') ||
375 $config->userFrameworkFrontend == 1
376 ) {
377 $editLink = FALSE;
378 }
379
380 $selector = new CRM_Profile_Selector_Listings($this->_params, $this->_customFields, $gids,
381 $map, $editLink, $linkToUF
382 );
383
384 $controller = new CRM_Core_Selector_Controller($selector,
385 $this->get(CRM_Utils_Pager::PAGE_ID),
386 $this->get(CRM_Utils_Sort::SORT_ID),
387 CRM_Core_Action::VIEW,
388 $this,
389 CRM_Core_Selector_Controller::TEMPLATE
390 );
391 $controller->setEmbedded(TRUE);
392 $controller->run();
393 }
394
395 //CRM-6862 -run form cotroller after
396 //selector, since it erase $_POST
397 $formController->run();
398
399 return parent::run();
400 }
401
402 /**
403 * Function to get the list of contacts for a profile
404 *
405 * @param $form object
406 *
407 * @access public
408 */
409 function getProfileContact($gid) {
410 $session = CRM_Core_Session::singleton();
411 $params = $session->get('profileParams');
412
413 $details = array();
414 $ufGroupParam = array('id' => $gid);
415 CRM_Core_BAO_UFGroup::retrieve($ufGroupParam, $details);
416
417 // make sure this group can be mapped
418 if (!$details['is_map']) {
419 CRM_Core_Error::statusBounce(ts('This profile does not have the map feature turned on.'));
420 }
421
422 $groupId = CRM_Utils_Array::value('limit_listings_group_id', $details);
423
424 // add group id to params if a uf group belong to a any group
425 if ($groupId) {
426 if (CRM_Utils_Array::value('group', $params)) {
427 $params['group'][$groupId] = 1;
428 }
429 else {
430 $params['group'] = array($groupId => 1);
431 }
432 }
433
434 $fields = CRM_Core_BAO_UFGroup::getListingFields(
435 CRM_Core_Action::VIEW,
436 CRM_Core_BAO_UFGroup::PUBLIC_VISIBILITY | CRM_Core_BAO_UFGroup::LISTINGS_VISIBILITY,
437 FALSE,
438 $gid
439 );
440
441 $returnProperties = CRM_Contact_BAO_Contact::makeHierReturnProperties($fields);
442 $returnProperties['contact_type'] = 1;
443 $returnProperties['sort_name'] = 1;
444
445 $queryParams = CRM_Contact_BAO_Query::convertFormValues($params, 1);
446 $query = new CRM_Contact_BAO_Query($queryParams, $returnProperties, $fields);
447
448 $additionalWhereClause = 'contact_a.is_deleted = 0';
449
450 $ids = $query->searchQuery(0, 0, NULL,
451 FALSE, FALSE, FALSE,
452 TRUE, FALSE,
453 $additionalWhereClause
454 );
455
456 $contactIds = explode(',', $ids);
457
458 return $contactIds;
459 }
460
461 function checkTemplateFileExists($suffix = '') {
462 if ($this->_gid) {
463 $templateFile = "CRM/Profile/Page/{$this->_gid}/Listings.{$suffix}tpl";
464 $template = CRM_Core_Page::getTemplate();
465 if ($template->template_exists($templateFile)) {
466 return $templateFile;
467 }
468
469 // lets see if we have customized by name
470 $ufGroupName = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $this->_gid, 'name');
471 if ($ufGroupName) {
472 $templateFile = "CRM/Profile/Page/{$ufGroupName}/Listings.{$suffix}tpl";
473 if ($template->template_exists($templateFile)) {
474 return $templateFile;
475 }
476 }
477 }
478 return NULL;
479 }
480
481 function getTemplateFileName() {
482 $fileName = $this->checkTemplateFileExists();
483 return $fileName ? $fileName : parent::getTemplateFileName();
484 }
485
486 function overrideExtraTemplateFileName() {
487 $fileName = $this->checkTemplateFileExists('extra.');
488 return $fileName ? $fileName : parent::overrideExtraTemplateFileName();
489 }
490}
491