Search.php 14.4 KB
Newer Older
totten's avatar
totten committed
1 2 3
<?php
/*
 +--------------------------------------------------------------------+
totten's avatar
totten committed
4
 | CiviCRM version 5                                                  |
totten's avatar
totten committed
5
 +--------------------------------------------------------------------+
Seamus Lee's avatar
Seamus Lee committed
6
 | Copyright CiviCRM LLC (c) 2004-2019                                |
totten's avatar
totten committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 +--------------------------------------------------------------------+
 | This file is a part of CiviCRM.                                    |
 |                                                                    |
 | CiviCRM is free software; you can copy, modify, and distribute it  |
 | under the terms of the GNU Affero General Public License           |
 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
 |                                                                    |
 | CiviCRM is distributed in the hope that it will be useful, but     |
 | WITHOUT ANY WARRANTY; without even the implied warranty of         |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
 | See the GNU Affero General Public License for more details.        |
 |                                                                    |
 | You should have received a copy of the GNU Affero General Public   |
 | License and the CiviCRM Licensing Exception along                  |
 | with this program; if not, contact CiviCRM LLC                     |
 | at info[AT]civicrm[DOT]org. If you have questions about the        |
 | GNU Affero General Public License or the licensing of CiviCRM,     |
 | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
 +--------------------------------------------------------------------+
26
 */
totten's avatar
totten committed
27 28 29 30

/**
 *
 * @package CRM
Seamus Lee's avatar
Seamus Lee committed
31
 * @copyright CiviCRM LLC (c) 2004-2019
totten's avatar
totten committed
32 33 34
 */

/**
eileenmcnaugton's avatar
eileenmcnaugton committed
35
 * Files required.
totten's avatar
totten committed
36
 */
37
class CRM_Campaign_Form_Search extends CRM_Core_Form_Search {
totten's avatar
totten committed
38 39

  /**
40
   * The params that are sent to the query.
totten's avatar
totten committed
41 42 43 44 45 46
   *
   * @var array
   */
  protected $_queryParams;

  /**
47
   * Are we restricting ourselves to a single contact.
totten's avatar
totten committed
48 49 50 51 52 53
   *
   * @var boolean
   */
  protected $_single = FALSE;

  /**
54
   * Are we restricting ourselves to a single contact.
totten's avatar
totten committed
55 56 57 58 59 60
   *
   * @var boolean
   */
  protected $_limit = NULL;

  /**
61
   * Prefix for the controller.
totten's avatar
totten committed
62 63 64 65 66 67 68
   */
  protected $_prefix = "survey_";


  private $_operation = 'reserve';

  /**
69
   * Processing needed for buildForm and later.
Eileen McNaughton's avatar
Eileen McNaughton committed
70
   */
Web Access's avatar
Web Access committed
71
  public function preProcess() {
totten's avatar
totten committed
72 73 74 75 76 77 78 79
    $this->_done = FALSE;
    $this->_defaults = array();

    //set the button name.
    $this->_searchButtonName = $this->getButtonName('refresh');
    $this->_printButtonName = $this->getButtonName('next', 'print');
    $this->_actionButtonName = $this->getButtonName('next', 'action');

80
    $this->loadStandardSearchOptionsFromUrl();
totten's avatar
totten committed
81 82 83 84 85

    //operation for state machine.
    $this->_operation = CRM_Utils_Request::retrieve('op', 'String', $this, FALSE, 'reserve');
    //validate operation.
    if (!in_array($this->_operation, array(
totten's avatar
totten committed
86 87
      'reserve',
      'release',
Web Access's avatar
Web Access committed
88
      'interview',
totten's avatar
totten committed
89 90
    ))
    ) {
totten's avatar
totten committed
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
      $this->_operation = 'reserve';
      $this->set('op', $this->_operation);
    }
    $this->set('searchVoterFor', $this->_operation);
    $this->assign('searchVoterFor', $this->_operation);
    $this->assign('isFormSubmitted', $this->isSubmitted());

    //do check permissions.
    if (!CRM_Core_Permission::check('administer CiviCampaign') &&
      !CRM_Core_Permission::check('manage campaign') &&
      !CRM_Core_Permission::check("{$this->_operation} campaign contacts")
    ) {
      CRM_Utils_System::permissionDenied();
      CRM_Utils_System::civiExit();
    }

    $this->assign("context", $this->_context);

    // get user submitted values
    // get it from controller only if form has been submitted, else preProcess has set this

    if (empty($_POST)) {
      $this->_formValues = $this->get('formValues');
    }
    else {
      $this->_formValues = $this->controller->exportValues($this->_name);
    }

    if ($this->_force) {
      $this->postProcess();
      $this->set('force', 0);
    }

    $sortID = NULL;
    if ($this->get(CRM_Utils_Sort::SORT_ID)) {
      $sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID),
        $this->get(CRM_Utils_Sort::SORT_DIRECTION)
      );
    }

    //get the voter clause.
    $voterClause = $this->voterClause();

    $this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);

    $selector = new CRM_Campaign_Selector_Search($this->_queryParams,
      $this->_action,
      $voterClause,
      $this->_single,
      $this->_limit,
      $this->_context
    );
    $prefix = NULL;
    if ($this->_context == 'user') {
      $prefix = $this->_prefix;
    }

    $this->assign("{$prefix}limit", $this->_limit);
    $this->assign("{$prefix}single", $this->_single);

    $controller = new CRM_Core_Selector_Controller($selector,
      $this->get(CRM_Utils_Pager::PAGE_ID),
      $sortID,
      CRM_Core_Action::VIEW,
      $this,
      CRM_Core_Selector_Controller::TRANSFER,
      $prefix
    );

    $controller->setEmbedded(TRUE);
    $controller->moveFromSessionToTemplate();

    //append breadcrumb to survey dashboard.
    if (CRM_Campaign_BAO_Campaign::accessCampaign()) {
      $url = CRM_Utils_System::url('civicrm/campaign', 'reset=1&subPage=survey');
      CRM_Utils_System::appendBreadCrumb(array(array('title' => ts('Survey(s)'), 'url' => $url)));
    }

    //set the form title.
    CRM_Utils_System::setTitle(ts('Find Respondents To %1', array(1 => ucfirst($this->_operation))));
  }

eileen's avatar
eileen committed
173 174 175 176 177
  /**
   * Load the default survey for all actions.
   *
   * @return array
   */
178
  public function setDefaultValues() {
totten's avatar
totten committed
179 180 181 182 183 184 185 186 187 188 189
    if (empty($this->_defaults)) {
      $defaultSurveyId = key(CRM_Campaign_BAO_Survey::getSurveys(TRUE, TRUE));
      if ($defaultSurveyId) {
        $this->_defaults['campaign_survey_id'] = $defaultSurveyId;
      }
    }

    return $this->_defaults;
  }

  /**
190
   * Build the form object.
totten's avatar
totten committed
191
   */
192
  public function buildQuickForm() {
193
    parent::buildQuickForm();
totten's avatar
totten committed
194 195 196 197 198 199
    //build the search form.
    CRM_Campaign_BAO_Query::buildSearchForm($this);

    $rows = $this->get('rows');
    if (is_array($rows)) {
      if (!$this->_single) {
200
        $this->addRowSelectors($rows);
totten's avatar
totten committed
201 202
      }

203
      $allTasks = CRM_Campaign_Task::permissionedTaskTitles(CRM_Core_Permission::getPermission());
totten's avatar
totten committed
204 205 206

      //hack to serve right page to state machine.
      $taskMapping = array(
207 208 209
        'interview' => CRM_Campaign_Task::INTERVIEW,
        'reserve' => CRM_Campaign_Task::RESERVE,
        'release' => CRM_Campaign_Task::RELEASE,
totten's avatar
totten committed
210 211 212 213
      );

      $currentTaskValue = CRM_Utils_Array::value($this->_operation, $taskMapping);
      $taskValue = array($currentTaskValue => $allTasks[$currentTaskValue]);
214
      if ($this->_operation == 'interview' && !empty($this->_formValues['campaign_survey_id'])) {
totten's avatar
totten committed
215 216 217 218 219 220 221 222 223
        $activityTypes = CRM_Core_PseudoConstant::activityType(FALSE, TRUE, FALSE, 'label', TRUE);

        $surveyTypeId = CRM_Core_DAO::getFieldValue('CRM_Campaign_DAO_Survey',
          $this->_formValues['campaign_survey_id'],
          'activity_type_id'
        );
        $taskValue = array(
          $currentTaskValue => ts('Record %1 Responses',
            array(1 => $activityTypes[$surveyTypeId])
Web Access's avatar
Web Access committed
224
          ),
totten's avatar
totten committed
225
        );
totten's avatar
totten committed
226 227
      }

228
      $this->addTaskMenu($taskValue);
totten's avatar
totten committed
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
    }

  }

  /**
   * The post processing of the form gets done here.
   *
   * Key things done during post processing are
   *      - check for reset or next request. if present, skip post procesing.
   *      - now check if user requested running a saved search, if so, then
   *        the form values associated with the saved search are used for searching.
   *      - if user has done a submit with new values the regular post submissing is
   *        done.
   * The processing consists of using a Selector / Controller framework for getting the
   * search results.
   */
245
  public function postProcess() {
totten's avatar
totten committed
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
    if ($this->_done) {
      return;
    }

    $this->_done = TRUE;

    if (!empty($_POST)) {
      $this->_formValues = $this->controller->exportValues($this->_name);
    }

    $this->fixFormValues();

    //format params as per task.
    $this->formatParams();

    $this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);

    $this->set('formValues', $this->_formValues);
    $this->set('queryParams', $this->_queryParams);

    $buttonName = $this->controller->getButtonName();
267
    if ($buttonName == $this->_actionButtonName) {
totten's avatar
totten committed
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
      // check actionName and if next, then do not repeat a search, since we are going to the next page

      // hack, make sure we reset the task values
      $stateMachine = $this->controller->getStateMachine();
      $formName = $stateMachine->getTaskFormName();

      $this->controller->resetPage($formName);
      return;
    }

    $sortID = NULL;
    if ($this->get(CRM_Utils_Sort::SORT_ID)) {
      $sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID),
        $this->get(CRM_Utils_Sort::SORT_DIRECTION)
      );
    }

    //get the voter clause.
    $voterClause = $this->voterClause();

    $selector = new CRM_Campaign_Selector_Search($this->_queryParams,
      $this->_action,
      $voterClause,
      $this->_single,
      $this->_limit,
      $this->_context
    );
    $selector->setKey($this->controller->_key);

    $prefix = NULL;
    if ($this->_context == 'basic' ||
      $this->_context == 'user'
    ) {
      $prefix = $this->_prefix;
    }

    $controller = new CRM_Core_Selector_Controller($selector,
      $this->get(CRM_Utils_Pager::PAGE_ID),
      $sortID,
      CRM_Core_Action::VIEW,
      $this,
      CRM_Core_Selector_Controller::SESSION,
      $prefix
    );
    $controller->setEmbedded(TRUE);
    $query = $selector->getQuery();
    if ($this->_context == 'user') {
      $query->setSkipPermission(TRUE);
    }
    $controller->run();
  }

320
  public function formatParams() {
totten's avatar
totten committed
321
    $interviewerId = CRM_Utils_Array::value('survey_interviewer_id', $this->_formValues);
322 323
    if ($interviewerId) {
      $this->set('interviewerId', $interviewerId);
totten's avatar
totten committed
324 325 326
    }

    //format multi-select group and contact types.
327
    foreach (array('group', 'contact_type') as $param) {
totten's avatar
totten committed
328 329 330 331 332 333 334 335 336 337 338 339 340 341
      if ($this->_force) {
        continue;
      }
      $paramValue = CRM_Utils_Array::value($param, $this->_formValues);
      if ($paramValue && is_array($paramValue)) {
        unset($this->_formValues[$param]);
        foreach ($paramValue as $key => $value) {
          $this->_formValues[$param][$value] = 1;
        }
      }
    }

    //apply filter of survey contact type for search.
    $contactType = CRM_Campaign_BAO_Survey::getSurveyContactType(CRM_Utils_Array::value('campaign_survey_id', $this->_formValues));
342
    if ($contactType && in_array($this->_operation, ['reserve', 'interview'])) {
totten's avatar
totten committed
343 344 345 346
      $this->_formValues['contact_type'][$contactType] = 1;
    }

    if ($this->_operation == 'reserve') {
347
      if (!empty($this->_formValues['campaign_survey_id'])) {
totten's avatar
totten committed
348 349 350 351 352 353 354 355 356 357 358
        $campaignId = CRM_Core_DAO::getFieldValue('CRM_Campaign_DAO_Survey',
          $this->_formValues['campaign_survey_id'],
          'campaign_id'
        );

        //allow voter search in sub-part of given constituents,
        //but make sure in case user does not select any group.
        //get all associated campaign groups in where filter, CRM-7406
        $groups = CRM_Utils_Array::value('group', $this->_formValues);
        if ($campaignId && CRM_Utils_System::isNull($groups)) {
          $campGroups = CRM_Campaign_BAO_Campaign::getCampaignGroups($campaignId);
totten's avatar
totten committed
359 360 361
          foreach ($campGroups as $id => $title) {
            $this->_formValues['group'][$id] = 1;
          }
totten's avatar
totten committed
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
        }

        //carry servey id w/ this.
        $this->set('surveyId', $this->_formValues['campaign_survey_id']);
        unset($this->_formValues['campaign_survey_id']);
      }
      unset($this->_formValues['survey_interviewer_id']);
    }
    elseif ($this->_operation == 'interview' ||
      $this->_operation == 'release'
    ) {
      //to conduct interview / release activity status should be scheduled.
      $activityStatus = CRM_Core_PseudoConstant::activityStatus('name');
      if ($scheduledStatusId = array_search('Scheduled', $activityStatus)) {
        $this->_formValues['survey_status_id'] = $scheduledStatusId;
      }
    }

    //pass voter search operation.
    $this->_formValues['campaign_search_voter_for'] = $this->_operation;
  }

384
  public function fixFormValues() {
totten's avatar
totten committed
385 386 387 388 389
    // if this search has been forced
    // then see if there are any get values, and if so over-ride the post values
    // note that this means that GET over-rides POST :)

    //since we have qfKey, no need to manipulate set defaults.
390
    $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String');
totten's avatar
totten committed
391 392 393 394 395 396

    if (!$this->_force || CRM_Utils_Rule::qfKey($qfKey)) {
      return;
    }

    // get survey id
397
    $surveyId = CRM_Utils_Request::retrieve('sid', 'Positive');
totten's avatar
totten committed
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430

    if ($surveyId) {
      $surveyId = CRM_Utils_Type::escape($surveyId, 'Integer');
    }
    else {
      // use default survey id
      $surveyId = key(CRM_Campaign_BAO_Survey::getSurveys(TRUE, TRUE));
    }
    if (!$surveyId) {
      CRM_Core_Error::fatal('Could not find valid Survey Id.');
    }
    $this->_formValues['campaign_survey_id'] = $this->_formValues['campaign_survey_id'] = $surveyId;

    $session = CRM_Core_Session::singleton();
    $userId = $session->get('userID');

    // get interviewer id
    $cid = CRM_Utils_Request::retrieve('cid', 'Positive',
      CRM_Core_DAO::$_nullObject, FALSE, $userId
    );
    //to force other contact as interviewer, user should be admin.
    if ($cid != $userId &&
      !CRM_Core_Permission::check('administer CiviCampaign')
    ) {
      CRM_Utils_System::permissionDenied();
      CRM_Utils_System::civiExit();
    }
    $this->_formValues['survey_interviewer_id'] = $cid;
    //get all in defaults.
    $this->_defaults = $this->_formValues;
    $this->_limit = CRM_Utils_Request::retrieve('limit', 'Positive', $this);
  }

431 432 433
  /**
   * @return array
   */
434
  public function voterClause() {
totten's avatar
totten committed
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462
    $params = array('campaign_search_voter_for' => $this->_operation);

    $clauseFields = array(
      'surveyId' => 'campaign_survey_id',
      'interviewerId' => 'survey_interviewer_id',
    );

    foreach ($clauseFields as $param => $key) {
      $params[$key] = CRM_Utils_Array::value($key, $this->_formValues);
      if (!$params[$key]) {
        $params[$key] = $this->get($param);
      }
    }

    //build the clause.
    $voterClause = CRM_Campaign_BAO_Query::voterClause($params);

    return $voterClause;
  }

  /**
   * Return a descriptive name for the page, used in wizard header
   *
   * @return string
   */
  public function getTitle() {
    return ts('Find Respondents');
  }
463

totten's avatar
totten committed
464
}