/** * Build the form object - it consists of * - displaying the QILL (query in local language) * - displaying elements for saving the search * * * @return void */ public function buildQuickForm() { // get the qill $query = new CRM_Contact_BAO_Query($this->get('queryParams')); $qill = $query->qill(); // need to save qill for the smarty template $this->assign('qill', $qill); // the name and description are actually stored with the group and not the saved search $this->add('text', 'title', ts('Name'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Group', 'title'), TRUE); $this->addElement('textarea', 'description', ts('Description'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Group', 'description')); $groupTypes = CRM_Core_OptionGroup::values('group_type', TRUE); unset($groupTypes['Access Control']); if (!CRM_Core_Permission::access('CiviMail')) { $isWorkFlowEnabled = CRM_Mailing_Info::workflowEnabled(); if ($isWorkFlowEnabled && !CRM_Core_Permission::check('create mailings') && !CRM_Core_Permission::check('schedule mailings') && !CRM_Core_Permission::check('approve mailings')) { unset($groupTypes['Mailing List']); } } if (!empty($groupTypes)) { $this->addCheckBox('group_type', ts('Group Type'), $groupTypes, NULL, NULL, NULL, NULL, ' '); } //CRM-14190 CRM_Group_Form_Edit::buildParentGroups($this); // get the group id for the saved search $groupID = NULL; if (isset($this->_id)) { $groupID = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $this->_id, 'id', 'saved_search_id'); $this->addDefaultButtons(ts('Update Smart Group')); } else { $this->addDefaultButtons(ts('Save Smart Group')); } $this->addRule('title', ts('Name already exists in Database.'), 'objectExists', array('CRM_Contact_DAO_Group', $groupID, 'title')); }
static function preProcessCommon(&$form, $useTable = true) { $form->_contactIds = array(); $form->_contactTypes = array(); $form->_searchFrom = $searchformName = 'contact'; $searchFrom = $form->get('searchFormName'); $pages = $form->controller->_pages; $prefix = 'contact'; if ($pages[$searchFrom]) { $prefix = $pages[$searchFrom]->getVar('_prefix'); if ($prefix == 'member_') { $searchformName = 'member'; } } if ($searchformName == 'member') { $form->_searchFrom = $searchformName; $values = $form->controller->exportValues($form->get('searchFormName')); $ids = array(); if ($values['radio_ts'] == 'ts_sel') { foreach ($values as $name => $value) { if (substr($name, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) { $ids[] = substr($name, CRM_Core_Form::CB_PREFIX_LEN); } } } else { $queryParams = $form->get('queryParams'); $sortOrder = null; if ($form->get(CRM_Utils_Sort::SORT_ORDER)) { $sortOrder = $form->get(CRM_Utils_Sort::SORT_ORDER); } $query = new CRM_Contact_BAO_Query($queryParams, NULL, NULL, FALSE, FALSE, CRM_Contact_BAO_Query::MODE_MEMBER); $query->_distinctComponentClause = ' civicrm_membership.id'; $query->_groupByComponentClause = ' GROUP BY civicrm_membership.id '; $result = $query->searchQuery(0, 0, $sortOrder); while ($result->fetch()) { $ids[] = $result->membership_id; } } if (!empty($ids)) { $form->_componentClause = ' civicrm_membership.id IN ( ' . implode(',', $ids) . ' ) '; $form->assign('totalSelectedMembers', count($ids)); } $form->_memberIds = $form->_componentIds = $ids; $form->_contactIds =& CRM_Core_DAO::getContactIDsFromComponent($ids, 'civicrm_membership'); $form->assign('totalSelectedContacts', count($form->_contactIds)); } else { parent::preProcessCommon($form); } }
/** * Test CRM_Contact_BAO_Query::searchQuery() * @dataProvider dataProvider */ function testSearch($fv, $count, $ids, $full) { $op = new PHPUnit_Extensions_Database_Operation_Insert(); $op->execute($this->_dbconn, new PHPUnit_Extensions_Database_DataSet_FlatXMLDataSet(dirname(__FILE__) . '/queryDataset.xml')); $params = CRM_Contact_BAO_Query::convertFormValues($fv); $obj = new CRM_Contact_BAO_Query($params); $obj->_useGroupBy = TRUE; $dao = $obj->searchQuery(); $contacts = array(); while ($dao->fetch()) { $contacts[] = $dao->contact_id; } sort($contacts, SORT_NUMERIC); $this->assertEquals($ids, $contacts, 'In line ' . __LINE__); }
/** * Load token data. * * @param TokenValueEvent $e * @throws TokenException */ public function onEvaluate(TokenValueEvent $e) { // For reasons unknown, replaceHookTokens requires a pre-computed list of // hook *categories* (aka entities aka namespaces). We'll cache // this in the TokenProcessor's context. $hookTokens = array(); \CRM_Utils_Hook::tokens($hookTokens); $categories = array_keys($hookTokens); $e->getTokenProcessor()->context['hookTokenCategories'] = $categories; $messageTokens = $e->getTokenProcessor()->getMessageTokens(); foreach ($e->getRows() as $row) { if (empty($row->context['contact'])) { $params = array(array('contact_id', '=', $row->context['contactId'], 0, 0)); list($contact, $_) = \CRM_Contact_BAO_Query::apiQuery($params); $contact = reset($contact); //CRM-4524 if (!$contact || is_a($contact, 'CRM_Core_Error')) { // FIXME: Need to differentiate errors which kill the batch vs the individual row. throw new TokenException("Failed to generate token data. Invalid contact ID: " . $row->context['contactId']); } } else { $contact = $row->context['contact']; } if (!empty($row->context['tmpTokenParams'])) { // merge activity tokens with contact array // this is pretty weird. $contact = array_merge($contact, $row->context['tmpTokenParams']); } // Note: This is a small contract change from the past; data should be missing // less randomly. //\CRM_Utils_Hook::tokenValues($contact, $row->context['contactId']); \CRM_Utils_Hook::tokenValues($contact, $row->context['contactId'], empty($row->context['mailingJob']) ? NULL : $row->context['mailingJob']->id, $messageTokens, $row->context['controller']); $row->context('contact', $contact); } }
/** * Check that running convertFormValues more than one doesn't mangle the array. * * Unfortunately the convertFormValues & indeed much of the query code is run in pre-process AND post-process. * * The convertFormValues function should cope with this until such time as we can rationalise that. */ public function testConvertEntityFieldMultipleValueEntityRefDoubleRun() { $formValues = array('membership_type_id' => '1,2'); $params = CRM_Contact_BAO_Query::convertFormValues($formValues, 0, FALSE, NULL, array('membership_type_id')); $this->assertEquals(array('membership_type_id', 'IN', array(1, 2), 0, 0), $params[0]); $params = CRM_Contact_BAO_Query::convertFormValues($params, 0, FALSE, NULL, array('membership_type_id')); $this->assertEquals(array('membership_type_id', 'IN', array(1, 2), 0, 0), $params[0]); $obj = new CRM_Contact_BAO_Query($params); $this->assertEquals(array('civicrm_membership.membership_type_id IN ("1", "2")'), $obj->_where[0]); }
/** * Checks wether a contact is a member of a group * * This function is a copy of CRM_Contact_BAO_GroupContact::isContactInGroup but with * a change so that the group contact cache won't be rebuild. Which somehow resulted * in a deadlock * * @param $contact_id * @param $group_id * @return bool */ public static function isContactInGroup($contact_id, $group_id) { if (!CRM_Utils_Rule::positiveInteger($contact_id) || !CRM_Utils_Rule::positiveInteger($group_id)) { return FALSE; } $params = array(array('group', 'IN', array($group_id => 1), 0, 0), array('contact_id', '=', $contact_id, 0, 0)); list($contacts, $_) = CRM_Contact_BAO_Query::apiQuery($params, array('contact_id'), null, null, 0, 1, false, false, true); if (!empty($contacts)) { return TRUE; } return FALSE; }
function __construct(&$formValues) { parent::__construct($formValues); $this->normalize(); $this->_columns = array(ts('') => 'contact_type', ts('Name') => 'sort_name', ts('Address') => 'street_address', ts('City') => 'city', ts('State') => 'state_province', ts('Postal') => 'postal_code', ts('Country') => 'country', ts('Email') => 'email', ts('Phone') => 'phone'); $params =& CRM_Contact_BAO_Query::convertFormValues($this->_formValues); $returnProperties = array(); foreach ($this->_columns as $name => $field) { $returnProperties[$field] = 1; } $this->_query =& new CRM_Contact_BAO_Query($params, $returnProperties, null, false, false, 1, false, false); }
/** * Test the function that extracts the arrays used to structure the output. * * The keys in the output fields array should by matched by field aliases in the sql query (with * exceptions of course - currently country is one - although maybe a future refactor can change that!). * * We are trying to move towards simpler processing in the per row iteration as that may be * repeated 100,000 times and in general we should simply be able to match the query fields to * our expected rows & do a little pseudoconstant mapping. */ public function testGetExportStructureArrays() { // This is how return properties are formatted internally within the function for passing to the BAO query. $returnProperties = array('first_name' => 1, 'last_name' => 1, 'receive_date' => 1, 'contribution_source' => 1, 'location' => array('Home' => array('street_address' => 1, 'city' => 1, 'country' => 1, 'email' => 1, 'im-1' => 1, 'im_provider' => 1, 'phone-1' => 1)), 'phone' => 1, 'trxn_id' => 1, 'contribution_id' => 1); $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id'); $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'); $contactRelationshipTypes = CRM_Contact_BAO_Relationship::getContactRelationshipType(NULL, NULL, NULL, NULL, TRUE, 'name', FALSE); $query = new CRM_Contact_BAO_Query(array(), $returnProperties, NULL, FALSE, FALSE, CRM_Contact_BAO_Query::MODE_CONTRIBUTE, FALSE, TRUE, TRUE, NULL, 'AND'); list($select) = $query->query(); $pattern = '/as `?([^`,]*)/'; $queryFieldAliases = array(); preg_match_all($pattern, $select, $queryFieldAliases, PREG_PATTERN_ORDER); list($outputFields) = CRM_Export_BAO_Export::getExportStructureArrays($returnProperties, $query, $phoneTypes, $imProviders, $contactRelationshipTypes, '', array()); foreach (array_keys($outputFields) as $fieldAlias) { if ($fieldAlias == 'Home-country') { $this->assertTrue(in_array($fieldAlias . '_id', $queryFieldAliases[1]), 'Country is subject to some funky translate so we make sure country id is present'); } else { $this->assertTrue(in_array($fieldAlias, $queryFieldAliases[1]), 'looking for field ' . $fieldAlias . ' in generaly the alias fields need to match the outputfields'); } } }
/** * Test the query from the selector class is consistent with the dataset expectation. * * @param array $dataSet * The data set to be tested. Note that when adding new datasets often only form_values and expected where * clause will need changing. * * @dataProvider querySets */ public function testSelectorQuery($dataSet) { $params = CRM_Contact_BAO_Query::convertFormValues($dataSet['form_values'], 0, FALSE, NULL, array()); foreach ($dataSet['settings'] as $setting) { $this->callAPISuccess('Setting', 'create', array($setting['name'] => $setting['value'])); } $selector = new CRM_Contact_Selector($dataSet['class'], $dataSet['form_values'], $params, $dataSet['return_properties'], $dataSet['action'], $dataSet['includeContactIds'], $dataSet['searchDescendentGroups'], $dataSet['context']); $queryObject = $selector->getQueryObject(); $sql = $queryObject->query(); $this->wrangleDefaultClauses($dataSet['expected_query']); foreach ($dataSet['expected_query'] as $index => $queryString) { $this->assertEquals($this->strWrangle($queryString), $this->strWrangle($sql[$index])); } }
/** * Class constructor. * * @param array $formValues */ public function __construct(&$formValues) { parent::__construct($formValues); $this->_columns = array('' => 'contact_type', ts('Name') => 'sort_name', ts('Address') => 'street_address', ts('City') => 'city', ts('State') => 'state_province', ts('Postal') => 'postal_code', ts('Country') => 'country', ts('Email') => 'email', ts('Phone') => 'phone'); $params = CRM_Contact_BAO_Query::convertFormValues($this->_formValues); $returnProperties = array(); $returnProperties['contact_sub_type'] = 1; $addressOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'address_options', TRUE, NULL, TRUE); foreach ($this->_columns as $name => $field) { if (in_array($field, array('street_address', 'city', 'state_province', 'postal_code', 'country')) && empty($addressOptions[$field])) { unset($this->_columns[$name]); continue; } $returnProperties[$field] = 1; } $this->_query = new CRM_Contact_BAO_Query($params, $returnProperties, NULL, FALSE, FALSE, 1, FALSE, FALSE); }
/** * process the form after the input has been submitted and validated * * @access public * @return void */ function postProcess() { // create the selector, controller and run - store results in session $fv = $this->get('formValues'); $query =& new CRM_Contact_BAO_Query($fv, null, null, false, false, CRM_CONTACT_BAO_QUERY_MODE_ALL); $returnProperties =& CRM_Contact_BAO_Query::defaultReturnProperties(CRM_CONTACT_BAO_QUERY_MODE_ALL); $properties = array('contact_id', 'contribution_id'); $header = array(ts('Contact ID'), ts('Contribution ID')); foreach ($returnProperties as $name => $dontCare) { $properties[] = $name; if (CRM_Utils_Array::value($name, $query->_fields) && CRM_Utils_Array::value('title', $query->_fields[$name])) { $header[] = $query->_fields[$name]['title']; } else { $header[] = $name; } } // header fixed for colomns are not expotable $headerArray = array('image_URL' => 'Image URL', 'contact_type' => 'Contact Type', 'sort_name' => 'Sort Name', 'display_name' => 'Display Name'); foreach ($header as $key => $value) { if (array_key_exists($value, $headerArray)) { $header[$key] = $headerArray[$value]; } } $result = $query->searchQuery(0, 0, null, false, false, false, false, false, $this->_contributionClause); $rows = array(); while ($result->fetch()) { $row = array(); $valid = false; foreach ($properties as $property) { $row[] = $result->{$property}; if (!CRM_Utils_System::isNull($result->{$property})) { $valid = true; } } if ($valid) { $rows[] = $row; } } require_once 'CRM/Core/Report/Excel.php'; CRM_Core_Report_Excel::writeCSVFile(CRM_Contribute_Form_Task_Export::getExportFileName(), $header, $rows); exit; }
function postProcess() { $params = $this->controller->exportValues($this->_name); CRM_Contact_BAO_Query::fixDateValues($params["mailing_relative"], $params['mailing_from'], $params['mailing_to']); $parent = $this->controller->getParent(); if (!empty($params)) { $fields = array('mailing_name', 'mailing_from', 'mailing_to', 'sort_name', 'campaign_id', 'mailing_status', 'sms', 'status_unscheduled', 'is_archived', 'hidden_find_mailings'); foreach ($fields as $field) { if (isset($params[$field]) && !CRM_Utils_System::isNull($params[$field])) { if (in_array($field, array('mailing_from', 'mailing_to')) && !$params["mailing_relative"]) { $time = $field == 'mailing_to' ? '235959' : NULL; $parent->set($field, CRM_Utils_Date::processDate($params[$field], $time)); } else { $parent->set($field, $params[$field]); } } else { $parent->set($field, NULL); } } } }
/** * Generate where for a single parameter. * * @param array $values * @param CRM_Contact_BAO_Query $query */ public static function whereClauseSingle(&$values, &$query) { list($name, $op, $value, $grouping) = $values; switch ($name) { case 'member_join_date_low': case 'member_join_date_high': $query->dateQueryBuilder($values, 'civicrm_membership', 'member_join_date', 'join_date', 'Member Since'); return; case 'member_start_date_low': case 'member_start_date_high': $query->dateQueryBuilder($values, 'civicrm_membership', 'member_start_date', 'start_date', 'Start Date'); return; case 'member_end_date_low': case 'member_end_date_high': $query->dateQueryBuilder($values, 'civicrm_membership', 'member_end_date', 'end_date', 'End Date'); return; case 'member_join_date': $op = '>='; $date = CRM_Utils_Date::format($value); if ($date) { $query->_where[$grouping][] = "civicrm_membership.join_date {$op} {$date}"; $format = CRM_Utils_Date::customFormat(CRM_Utils_Date::format(array_reverse($value), '-')); $query->_qill[$grouping][] = ts('Member Since %2 %1', array(1 => $format, 2 => $op)); } return; case 'member_source': $strtolower = function_exists('mb_strtolower') ? 'mb_strtolower' : 'strtolower'; $value = $strtolower(CRM_Core_DAO::escapeString(trim($value))); $query->_where[$grouping][] = "civicrm_membership.source {$op} '{$value}'"; $query->_qill[$grouping][] = ts('Source %2 %1', array(1 => $value, 2 => $op)); $query->_tables['civicrm_membership'] = $query->_whereTables['civicrm_membership'] = 1; return; // CRM-17011 These 2 variants appear in some smart groups saved at some time prior to 4.6.6. // CRM-17011 These 2 variants appear in some smart groups saved at some time prior to 4.6.6. case 'member_status_id': case 'member_membership_type_id': if (is_array($value)) { $op = 'IN'; $value = array_keys($value); } case 'membership_type_id': // CRM-17075 we are specifically handling the possibility we are dealing with the entity reference field // for membership_type_id here (although status would be handled if converted). The unhandled pathway at the moment // is from groupContactCache::load and this is a small fix to get the entity reference field to work. // However, it would seem the larger fix would be to NOT invoke the form formValues for // the load function. The where clause and the whereTables are saved so they should suffice to generate the query // to get a contact list. But, better to deal with in 4.8 now... if (is_string($value) && strpos($value, ',') && $op == '=') { $value = array('IN' => explode(',', $value)); } case 'membership_status': case 'membership_status_id': case 'membership_type': case 'member_id': if (strstr($name, 'status') && is_string($value) && !is_numeric($value)) { $value = CRM_Core_PseudoConstant::getKey('CRM_Member_BAO_Membership', 'status_id', $value); } if (strpos($name, 'status') !== FALSE) { $name = 'status_id'; $qillName = 'Membership Status(s)'; } elseif ($name == 'member_id') { $name = 'id'; $qillName = 'Membership ID'; } else { $name = 'membership_type_id'; $qillName = 'Membership Type(s)'; } $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_membership.{$name}", $op, $value, "Integer"); list($op, $value) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Member_DAO_Membership', $name, $value, $op); $query->_qill[$grouping][] = ts('%1 %2 %3', array(1 => $qillName, 2 => $op, 3 => $value)); $query->_tables['civicrm_membership'] = $query->_whereTables['civicrm_membership'] = 1; return; case 'member_test': // We dont want to include all tests for sql OR CRM-7827 if (!$value || $query->getOperator() != 'OR') { $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_membership.is_test", $op, $value, "Boolean"); if ($value) { $query->_qill[$grouping][] = ts('Membership is a Test'); } } $query->_tables['civicrm_membership'] = $query->_whereTables['civicrm_membership'] = 1; return; case 'member_auto_renew': $op = "!="; if ($value) { $query->_where[$grouping][] = " civicrm_membership.contribution_recur_id IS NOT NULL"; $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("ccr.contribution_status_id", $op, array_search('Cancelled', CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name')), "Integer"); $query->_qill[$grouping][] = ts("Membership is Auto-Renew"); } else { $query->_where[$grouping][] = " civicrm_membership.contribution_recur_id IS NULL"; $query->_qill[$grouping][] = ts("Membership is NOT Auto-Renew"); } $query->_tables['civicrm_membership'] = $query->_whereTables['civicrm_membership'] = 1; return; case 'member_pay_later': $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_membership.is_pay_later", $op, $value, "Integer"); if ($value) { $query->_qill[$grouping][] = ts("Membership is Pay Later"); } else { $query->_qill[$grouping][] = ts("Membership is NOT Pay Later"); } $query->_tables['civicrm_membership'] = $query->_whereTables['civicrm_membership'] = 1; return; case 'member_is_primary': if ($value) { $query->_where[$grouping][] = " civicrm_membership.owner_membership_id IS NULL"; $query->_qill[$grouping][] = ts("Primary Members Only"); } else { $query->_where[$grouping][] = " civicrm_membership.owner_membership_id IS NOT NULL"; $query->_qill[$grouping][] = ts("Related Members Only"); } $query->_tables['civicrm_membership'] = $query->_whereTables['civicrm_membership'] = 1; return; case 'member_is_override': $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_membership.is_override", $op, $value, "Boolean"); $query->_qill[$grouping][] = $value ? ts("Is Membership Status overriden? Yes") : ts("Is Membership Status overriden? No"); $query->_tables['civicrm_membership'] = $query->_whereTables['civicrm_membership'] = 1; return; case 'member_campaign_id': if (CRM_Utils_Array::value($op, $value)) { $value = $value[$op]; } $campParams = array('op' => $op, 'campaign' => $value, 'grouping' => $grouping, 'tableName' => 'civicrm_membership'); CRM_Campaign_BAO_Query::componentSearchClause($campParams, $query); return; } }
/** * Processing needed for buildForm and later. */ public function preProcess() { // set the various class variables $this->_group = CRM_Core_PseudoConstant::group(); $this->_groupIterator = CRM_Core_PseudoConstant::groupIterator(); $this->_tag = CRM_Core_BAO_Tag::getTags(); $this->_done = FALSE; /* * we allow the controller to set force/reset externally, useful when we are being * driven by the wizard framework */ $this->_reset = CRM_Utils_Request::retrieve('reset', 'Boolean', CRM_Core_DAO::$_nullObject); $this->_force = CRM_Utils_Request::retrieve('force', 'Boolean', CRM_Core_DAO::$_nullObject); $this->_groupID = CRM_Utils_Request::retrieve('gid', 'Positive', $this); $this->_amtgID = CRM_Utils_Request::retrieve('amtgID', 'Positive', $this); $this->_ssID = CRM_Utils_Request::retrieve('ssID', 'Positive', $this); $this->_sortByCharacter = CRM_Utils_Request::retrieve('sortByCharacter', 'String', $this); $this->_ufGroupID = CRM_Utils_Request::retrieve('id', 'Positive', $this); $this->_componentMode = CRM_Utils_Request::retrieve('component_mode', 'Positive', $this, FALSE, 1, $_REQUEST); $this->_operator = CRM_Utils_Request::retrieve('operator', 'String', $this, FALSE, 1, $_REQUEST, 'AND'); /** * set the button names */ $this->_searchButtonName = $this->getButtonName('refresh'); $this->_actionButtonName = $this->getButtonName('next', 'action'); $this->assign('actionButtonName', $this->_actionButtonName); // reset from session, CRM-3526 $session = CRM_Core_Session::singleton(); if ($this->_force && $session->get('selectedSearchContactIds')) { $session->resetScope('selectedSearchContactIds'); } // if we dont get this from the url, use default if one exsts $config = CRM_Core_Config::singleton(); if ($this->_ufGroupID == NULL && $config->defaultSearchProfileID != NULL) { $this->_ufGroupID = $config->defaultSearchProfileID; } // assign context to drive the template display, make sure context is valid $this->_context = CRM_Utils_Request::retrieve('context', 'String', $this, FALSE, 'search'); if (!CRM_Utils_Array::value($this->_context, self::validContext())) { $this->_context = 'search'; } $this->set('context', $this->_context); $this->assign('context', $this->_context); $this->_modeValue = self::getModeValue($this->_componentMode); $this->assign($this->_modeValue); $this->set('selectorName', self::$_selectorName); // get user submitted values // get it from controller only if form has been submitted, else preProcess has set this // $this->controller->isModal( ) returns TRUE if page is // valid, i.e all the validations are TRUE if (!empty($_POST) && !$this->controller->isModal()) { $this->_formValues = $this->controller->exportValues($this->_name); $this->normalizeFormValues(); $this->_params = CRM_Contact_BAO_Query::convertFormValues($this->_formValues); $this->_returnProperties =& $this->returnProperties(); // also get the uf group id directly from the post value $this->_ufGroupID = CRM_Utils_Array::value('uf_group_id', $_POST, $this->_ufGroupID); $this->_formValues['uf_group_id'] = $this->_ufGroupID; $this->set('id', $this->_ufGroupID); // also get the object mode directly from the post value $this->_componentMode = CRM_Utils_Array::value('component_mode', $_POST, $this->_componentMode); // also get the operator from the post value if set $this->_operator = CRM_Utils_Array::value('operator', $_POST, $this->_operator); $this->_formValues['operator'] = $this->_operator; $this->set('operator', $this->_operator); } else { $this->_formValues = $this->get('formValues'); $this->_params = CRM_Contact_BAO_Query::convertFormValues($this->_formValues); $this->_returnProperties =& $this->returnProperties(); if (!empty($this->_ufGroupID)) { $this->set('id', $this->_ufGroupID); } } if (empty($this->_formValues)) { //check if group is a smart group (fix for CRM-1255) if ($this->_groupID) { if ($ssId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $this->_groupID, 'saved_search_id')) { $this->_ssID = $ssId; } } // fix for CRM-1907 if (isset($this->_ssID) && $this->_context != 'smog') { // we only retrieve the saved search values if out current values are null $this->_formValues = CRM_Contact_BAO_SavedSearch::getFormValues($this->_ssID); //fix for CRM-1505 if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $this->_ssID, 'mapping_id')) { $this->_params = CRM_Contact_BAO_SavedSearch::getSearchParams($this->_ssID); } else { $this->_params = CRM_Contact_BAO_Query::convertFormValues($this->_formValues); } $this->_returnProperties =& $this->returnProperties(); } else { if (isset($this->_ufGroupID)) { // also set the uf group id if not already present $this->_formValues['uf_group_id'] = $this->_ufGroupID; } if (isset($this->_componentMode)) { $this->_formValues['component_mode'] = $this->_componentMode; } if (isset($this->_operator)) { $this->_formValues['operator'] = $this->_operator; } // FIXME: we should generalise in a way that components could inject url-filters // just like they build their own form elements foreach (array('mailing_id', 'mailing_delivery_status', 'mailing_open_status', 'mailing_click_status', 'mailing_reply_status', 'mailing_optout', 'mailing_forward', 'mailing_unsubscribe', 'mailing_date_low', 'mailing_date_high') as $mailingFilter) { $type = 'String'; if ($mailingFilter == 'mailing_id' && ($filterVal = CRM_Utils_Request::retrieve('mailing_id', 'Positive', $this))) { $this->_formValues[$mailingFilter] = array($filterVal); } elseif ($filterVal = CRM_Utils_Request::retrieve($mailingFilter, $type, $this)) { $this->_formValues[$mailingFilter] = $filterVal; } if ($filterVal) { $this->_openedPanes['Mailings'] = 1; $this->_formValues['hidden_CiviMail'] = 1; } } } } $this->assign('id', CRM_Utils_Array::value('uf_group_id', $this->_formValues)); $operator = CRM_Utils_Array::value('operator', $this->_formValues, 'AND'); $this->set('queryOperator', $operator); if ($operator == 'OR') { $this->assign('operator', ts('OR')); } else { $this->assign('operator', ts('AND')); } // show the context menu only when we’re not searching for deleted contacts; CRM-5673 if (empty($this->_formValues['deleted_contacts'])) { $menuItems = CRM_Contact_BAO_Contact::contextMenu(); $primaryActions = CRM_Utils_Array::value('primaryActions', $menuItems, array()); $this->_contextMenu = CRM_Utils_Array::value('moreActions', $menuItems, array()); $this->assign('contextMenu', $primaryActions + $this->_contextMenu); } if (!isset($this->_componentMode)) { $this->_componentMode = CRM_Contact_BAO_Query::MODE_CONTACTS; } $modeValues = self::getModeValue($this->_componentMode); self::$_selectorName = $this->_modeValue['selectorName']; $setDynamic = FALSE; if (strpos(self::$_selectorName, 'CRM_Contact_Selector') !== FALSE) { $selector = new self::$_selectorName($this->_customSearchClass, $this->_formValues, $this->_params, $this->_returnProperties, $this->_action, FALSE, TRUE, $this->_context, $this->_contextMenu); $setDynamic = TRUE; } else { $selector = new self::$_selectorName($this->_params, $this->_action, NULL, FALSE, NULL, "search", "advanced"); } $selector->setKey($this->controller->_key); $controller = new CRM_Contact_Selector_Controller($selector, $this->get(CRM_Utils_Pager::PAGE_ID), $this->get(CRM_Utils_Sort::SORT_ID), CRM_Core_Action::VIEW, $this, CRM_Core_Selector_Controller::TRANSFER); $controller->setEmbedded(TRUE); $controller->setDynamicAction($setDynamic); if ($this->_force) { $this->postProcess(); /* * Note that we repeat this, since the search creates and stores * values that potentially change the controller behavior. i.e. things * like totalCount etc */ $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)); } $controller = new CRM_Contact_Selector_Controller($selector, $this->get(CRM_Utils_Pager::PAGE_ID), $sortID, CRM_Core_Action::VIEW, $this, CRM_Core_Selector_Controller::TRANSFER); $controller->setEmbedded(TRUE); $controller->setDynamicAction($setDynamic); } $controller->moveFromSessionToTemplate(); }
/** * Gives required details of contacts in an indexed array format so we * can iterate in a nice loop and do token evaluation * * @param $contactIDs * @param array $returnProperties * Of required properties. * @param bool $skipOnHold Don't return on_hold contact info also. * Don't return on_hold contact info also. * @param bool $skipDeceased Don't return deceased contact info. * Don't return deceased contact info. * @param array $extraParams * Extra params. * @param array $tokens * The list of tokens we've extracted from the content. * @param null $className * @param int $jobID * The mailing list jobID - this is a legacy param. * * @return array */ public static function getTokenDetails($contactIDs, $returnProperties = NULL, $skipOnHold = TRUE, $skipDeceased = TRUE, $extraParams = NULL, $tokens = array(), $className = NULL, $jobID = NULL) { if (empty($contactIDs)) { // putting a fatal here so we can track if/when this happens CRM_Core_Error::fatal(); } // @todo this functions needs unit tests. $params = array(); foreach ($contactIDs as $key => $contactID) { $params[] = array(CRM_Core_Form::CB_PREFIX . $contactID, '=', 1, 0, 0); } // fix for CRM-2613 if ($skipDeceased) { $params[] = array('is_deceased', '=', 0, 0, 0); } //fix for CRM-3798 if ($skipOnHold) { $params[] = array('on_hold', '=', 0, 0, 0); } if ($extraParams) { $params = array_merge($params, $extraParams); } // if return properties are not passed then get all return properties if (empty($returnProperties)) { $fields = array_merge(array_keys(CRM_Contact_BAO_Contact::exportableFields()), array('display_name', 'checksum', 'contact_id')); foreach ($fields as $key => $val) { // The unavailable fields are not available as tokens, do not have a one-2-one relationship // with contacts and are expensive to resolve. // @todo see CRM-17253 - there are some other fields (e.g note) that should be excluded // and upstream calls to this should populate return properties. $unavailableFields = array('group', 'tag'); if (!in_array($val, $unavailableFields)) { $returnProperties[$val] = 1; } } } $custom = array(); foreach ($returnProperties as $name => $dontCare) { $cfID = CRM_Core_BAO_CustomField::getKeyID($name); if ($cfID) { $custom[] = $cfID; } } //get the total number of contacts to fetch from database. $numberofContacts = count($contactIDs); $query = new CRM_Contact_BAO_Query($params, $returnProperties); $details = $query->apiQuery($params, $returnProperties, NULL, NULL, 0, $numberofContacts); $contactDetails =& $details[0]; foreach ($contactIDs as $key => $contactID) { if (array_key_exists($contactID, $contactDetails)) { if (CRM_Utils_Array::value('preferred_communication_method', $returnProperties) == 1 && array_key_exists('preferred_communication_method', $contactDetails[$contactID])) { $pcm = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method'); // communication Preference $contactPcm = explode(CRM_Core_DAO::VALUE_SEPARATOR, $contactDetails[$contactID]['preferred_communication_method']); $result = array(); foreach ($contactPcm as $key => $val) { if ($val) { $result[$val] = $pcm[$val]; } } $contactDetails[$contactID]['preferred_communication_method'] = implode(', ', $result); } foreach ($custom as $cfID) { if (isset($contactDetails[$contactID]["custom_{$cfID}"])) { $contactDetails[$contactID]["custom_{$cfID}"] = CRM_Core_BAO_CustomField::getDisplayValue($contactDetails[$contactID]["custom_{$cfID}"], $cfID, $details[1]); } } // special case for greeting replacement foreach (array('email_greeting', 'postal_greeting', 'addressee') as $val) { if (!empty($contactDetails[$contactID][$val])) { $contactDetails[$contactID][$val] = $contactDetails[$contactID]["{$val}_display"]; } } } } // also call a hook and get token details CRM_Utils_Hook::tokenValues($details[0], $contactIDs, $jobID, $tokens, $className); return $details; }
/** * 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. * * @param * * @return void * @access public */ function postProcess() { if ($this->_done) { return; } $this->_done = TRUE; $this->_formValues = $this->controller->exportValues($this->_name); $this->fixFormValues(); // We don't show test records in summaries or dashboards if (empty($this->_formValues['member_test']) && $this->_force) { $this->_formValues["member_test"] = 0; } CRM_Core_BAO_CustomValue::fixFieldValueOfTypeMemo($this->_formValues); $this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues); $this->set('formValues', $this->_formValues); $this->set('queryParams', $this->_queryParams); $buttonName = $this->controller->getButtonName(); if ($buttonName == $this->_actionButtonName) { // 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)); } $this->_queryParams = CRM_Contact_BAO_Query::convertFormValues($this->_formValues); $selector = new CRM_Member_Selector_Search($this->_queryParams, $this->_action, NULL, $this->_single, $this->_limit, $this->_context); $selector->setKey($this->controller->_key); $prefix = NULL; if ($this->_context == 'basic') { $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(); $controller->run(); }
/** * @param $values * @param $query */ public static function whereClauseSingle(&$values, &$query) { list($name, $op, $value, $grouping, $wildcard) = $values; $fields = array(); $fields = self::getFields(); switch ($name) { case 'mailing_id': $selectedMailings = array_flip($value); $value = "(" . implode(',', $value) . ")"; $op = 'IN'; $query->_where[$grouping][] = "civicrm_mailing.id {$op} {$value}"; $mailings = CRM_Mailing_BAO_Mailing::getMailingsList(); foreach ($selectedMailings as $id => $dnc) { $selectedMailings[$id] = $mailings[$id]; } $selectedMailings = implode(' or ', $selectedMailings); $query->_qill[$grouping][] = "Mailing Name {$op} \"{$selectedMailings}\""; $query->_tables['civicrm_mailing'] = $query->_whereTables['civicrm_mailing'] = 1; $query->_tables['civicrm_mailing_recipients'] = $query->_whereTables['civicrm_mailing_recipients'] = 1; return; case 'mailing_name': $value = strtolower(addslashes($value)); if ($wildcard) { $value = "%{$value}%"; $op = 'LIKE'; } $query->_where[$grouping][] = "LOWER(civicrm_mailing.name) {$op} '{$value}'"; $query->_qill[$grouping][] = "Mailing Namename {$op} \"{$value}\""; $query->_tables['civicrm_mailing'] = $query->_whereTables['civicrm_mailing'] = 1; $query->_tables['civicrm_mailing_recipients'] = $query->_whereTables['civicrm_mailing_recipients'] = 1; return; case 'mailing_date': case 'mailing_date_low': case 'mailing_date_high': // process to / from date $query->_tables['civicrm_mailing'] = $query->_whereTables['civicrm_mailing'] = 1; $query->_tables['civicrm_mailing_event_queue'] = $query->_whereTables['civicrm_mailing_event_queue'] = 1; $query->_tables['civicrm_mailing_job'] = $query->_whereTables['civicrm_mailing_job'] = 1; $query->_tables['civicrm_mailing_recipients'] = $query->_whereTables['civicrm_mailing_recipients'] = 1; $query->dateQueryBuilder($values, 'civicrm_mailing_job', 'mailing_date', 'start_date', 'Mailing Delivery Date'); return; case 'mailing_delivery_status': $options = CRM_Mailing_PseudoConstant::yesNoOptions('delivered'); list($name, $op, $value, $grouping, $wildcard) = $values; if ($value == 'Y') { self::mailingEventQueryBuilder($query, $values, 'civicrm_mailing_event_delivered', 'mailing_delivery_status', ts('Mailing Delivery'), $options); } elseif ($value == 'N') { $options['Y'] = $options['N']; $values = array($name, $op, 'Y', $grouping, $wildcard); self::mailingEventQueryBuilder($query, $values, 'civicrm_mailing_event_bounce', 'mailing_delivery_status', ts('Mailing Delivery'), $options); } return; case 'mailing_bounce_types': $op = 'IN'; $values = array($name, $op, $value, $grouping, $wildcard); self::mailingEventQueryBuilder($query, $values, 'civicrm_mailing_event_bounce', 'bounce_type_id', ts('Bounce type(s)'), CRM_Core_PseudoConstant::get('CRM_Mailing_Event_DAO_Bounce', 'bounce_type_id', array('keyColumn' => 'id', 'labelColumn' => 'name'))); return; case 'mailing_open_status': self::mailingEventQueryBuilder($query, $values, 'civicrm_mailing_event_opened', 'mailing_open_status', ts('Mailing: Trackable Opens'), CRM_Mailing_PseudoConstant::yesNoOptions('open')); return; case 'mailing_click_status': self::mailingEventQueryBuilder($query, $values, 'civicrm_mailing_event_trackable_url_open', 'mailing_click_status', ts('Mailing: Trackable URL Clicks'), CRM_Mailing_PseudoConstant::yesNoOptions('click')); return; case 'mailing_reply_status': self::mailingEventQueryBuilder($query, $values, 'civicrm_mailing_event_reply', 'mailing_reply_status', ts('Mailing: Trackable Replies'), CRM_Mailing_PseudoConstant::yesNoOptions('reply')); return; case 'mailing_optout': $valueTitle = array(1 => ts('Opt-out Requests')); // include opt-out events only $query->_where[$grouping][] = "civicrm_mailing_event_unsubscribe.org_unsubscribe = 1"; self::mailingEventQueryBuilder($query, $values, 'civicrm_mailing_event_unsubscribe', 'mailing_unsubscribe', ts('Mailing: '), $valueTitle); return; case 'mailing_unsubscribe': $valueTitle = array(1 => ts('Unsubscribe Requests')); // exclude opt-out events $query->_where[$grouping][] = "civicrm_mailing_event_unsubscribe.org_unsubscribe = 0"; self::mailingEventQueryBuilder($query, $values, 'civicrm_mailing_event_unsubscribe', 'mailing_unsubscribe', ts('Mailing: '), $valueTitle); return; case 'mailing_forward': $valueTitle = array('Y' => ts('Forwards')); // since its a checkbox $values[2] = 'Y'; self::mailingEventQueryBuilder($query, $values, 'civicrm_mailing_event_forward', 'mailing_forward', ts('Mailing: '), $valueTitle); return; case 'mailing_job_status': if (!empty($value)) { if ($value != 'Scheduled' && $value != 'Canceled') { $query->_tables['civicrm_mailing_event_queue'] = $query->_whereTables['civicrm_mailing_event_queue'] = 1; } $query->_tables['civicrm_mailing'] = $query->_whereTables['civicrm_mailing'] = 1; $query->_tables['civicrm_mailing_job'] = $query->_whereTables['civicrm_mailing_job'] = 1; $query->_tables['civicrm_mailing_recipients'] = $query->_whereTables['civicrm_mailing_recipients'] = 1; $query->_where[$grouping][] = " civicrm_mailing_job.status = '{$value}' "; $query->_qill[$grouping][] = "Mailing Job Status IS \"{$value}\""; } return; case 'mailing_campaign_id': $name = 'campaign_id'; $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_mailing.{$name}", $op, $value, 'Integer'); list($op, $value) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Mailing_DAO_Mailing', $name, $value, $op); $query->_qill[$grouping][] = ts('Campaign %1 %2', array(1 => $op, 2 => $value)); $query->_tables['civicrm_mailing'] = $query->_whereTables['civicrm_mailing'] = 1; $query->_tables['civicrm_mailing_recipients'] = $query->_whereTables['civicrm_mailing_recipients'] = 1; return; } }
/** * Load the smart group cache for a saved search. * * @param object $group * The smart group that needs to be loaded. * @param bool $force * Should we force a search through. */ public static function load(&$group, $force = FALSE) { $groupID = $group->id; $savedSearchID = $group->saved_search_id; if (array_key_exists($groupID, self::$_alreadyLoaded) && !$force) { return; } // grab a lock so other processes don't compete and do the same query $lock = Civi::lockManager()->acquire("data.core.group.{$groupID}"); if (!$lock->isAcquired()) { // this can cause inconsistent results since we don't know if the other process // will fill up the cache before our calling routine needs it. // however this routine does not return the status either, so basically // its a "lets return and hope for the best" return; } self::$_alreadyLoaded[$groupID] = 1; // we now have the lock, but some other process could have actually done the work // before we got here, so before we do any work, lets ensure that work needs to be // done // we allow hidden groups here since we dont know if the caller wants to evaluate an // hidden group if (!$force && !self::shouldGroupBeRefreshed($groupID, TRUE)) { $lock->release(); return; } $sql = NULL; $idName = 'id'; $customClass = NULL; if ($savedSearchID) { $ssParams = CRM_Contact_BAO_SavedSearch::getSearchParams($savedSearchID); // rectify params to what proximity search expects if there is a value for prox_distance // CRM-7021 if (!empty($ssParams)) { CRM_Contact_BAO_ProximityQuery::fixInputParams($ssParams); } $returnProperties = array(); if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $savedSearchID, 'mapping_id')) { $fv = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID); $returnProperties = CRM_Core_BAO_Mapping::returnProperties($fv); } if (isset($ssParams['customSearchID'])) { // if custom search // we split it up and store custom class // so temp tables are not destroyed if they are used // hence customClass is defined above at top of function $customClass = CRM_Contact_BAO_SearchCustom::customClass($ssParams['customSearchID'], $savedSearchID); $searchSQL = $customClass->contactIDs(); $searchSQL = str_replace('ORDER BY contact_a.id ASC', '', $searchSQL); if (!strstr($searchSQL, 'WHERE')) { $searchSQL .= " WHERE ( 1 ) "; } $idName = 'contact_id'; } else { $formValues = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID); // CRM-17075 using the formValues in this way imposes extra logic and complexity. // we have the where_clause and where tables stored in the saved_search table // and should use these rather than re-processing the form criteria (which over-works // the link between the form layer & the query layer too). // It's hard to think of when you would want to use anything other than return // properties = array('contact_id' => 1) here as the point would appear to be to // generate the list of contact ids in the group. // @todo review this to use values in saved_search table (preferably for 4.8). $query = new CRM_Contact_BAO_Query($ssParams, $returnProperties, NULL, FALSE, FALSE, 1, TRUE, TRUE, FALSE, CRM_Utils_Array::value('display_relationship_type', $formValues), CRM_Utils_Array::value('operator', $formValues, 'AND')); $query->_useDistinct = FALSE; $query->_useGroupBy = FALSE; $searchSQL = $query->searchQuery(0, 0, NULL, FALSE, FALSE, FALSE, TRUE, TRUE, NULL, NULL, NULL, TRUE); } $groupID = CRM_Utils_Type::escape($groupID, 'Integer'); $sql = $searchSQL . " AND contact_a.id NOT IN (\n SELECT contact_id FROM civicrm_group_contact\n WHERE civicrm_group_contact.status = 'Removed'\n AND civicrm_group_contact.group_id = {$groupID} ) "; } if ($sql) { $sql = preg_replace("/^\\s*SELECT/", "SELECT {$groupID} as group_id, ", $sql); } // lets also store the records that are explicitly added to the group // this allows us to skip the group contact LEFT JOIN $sqlB = "\nSELECT {$groupID} as group_id, contact_id as {$idName}\nFROM civicrm_group_contact\nWHERE civicrm_group_contact.status = 'Added'\n AND civicrm_group_contact.group_id = {$groupID} "; $groupIDs = array($groupID); self::remove($groupIDs); $processed = FALSE; $tempTable = 'civicrm_temp_group_contact_cache' . rand(0, 2000); foreach (array($sql, $sqlB) as $selectSql) { if (!$selectSql) { continue; } $insertSql = "CREATE TEMPORARY TABLE {$tempTable} ({$selectSql});"; $processed = TRUE; CRM_Core_DAO::executeQuery($insertSql); CRM_Core_DAO::executeQuery("INSERT IGNORE INTO civicrm_group_contact_cache (contact_id, group_id)\n SELECT DISTINCT {$idName}, group_id FROM {$tempTable}\n "); CRM_Core_DAO::executeQuery(" DROP TEMPORARY TABLE {$tempTable}"); } self::updateCacheTime($groupIDs, $processed); if ($group->children) { //Store a list of contacts who are removed from the parent group $sql = "\nSELECT contact_id\nFROM civicrm_group_contact\nWHERE civicrm_group_contact.status = 'Removed'\nAND civicrm_group_contact.group_id = {$groupID} "; $dao = CRM_Core_DAO::executeQuery($sql); $removed_contacts = array(); while ($dao->fetch()) { $removed_contacts[] = $dao->contact_id; } $childrenIDs = explode(',', $group->children); foreach ($childrenIDs as $childID) { $contactIDs = CRM_Contact_BAO_Group::getMember($childID, FALSE); //Unset each contact that is removed from the parent group foreach ($removed_contacts as $removed_contact) { unset($contactIDs[$removed_contact]); } $values = array(); foreach ($contactIDs as $contactID => $dontCare) { $values[] = "({$groupID},{$contactID})"; } self::store($groupIDs, $values); } } $lock->release(); }
static function preProcessCommon(&$form, $useTable = FALSE) { $form->_caseIds = array(); $values = $form->controller->exportValues($form->get('searchFormName')); $form->_task = $values['task']; $caseTasks = CRM_Case_Task::tasks(); $form->assign('taskName', $caseTasks[$form->_task]); $ids = array(); if ($values['radio_ts'] == 'ts_sel') { foreach ($values as $name => $value) { if (substr($name, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) { $ids[] = substr($name, CRM_Core_Form::CB_PREFIX_LEN); } } } else { $queryParams = $form->get('queryParams'); $query = new CRM_Contact_BAO_Query($queryParams, NULL, NULL, FALSE, FALSE, CRM_Contact_BAO_Query::MODE_CASE); $query->_distinctComponentClause = " ( civicrm_case.id )"; $query->_groupByComponentClause = " GROUP BY civicrm_case.id "; $result = $query->searchQuery(0, 0, NULL); while ($result->fetch()) { $ids[] = $result->case_id; } } if (!empty($ids)) { $form->_componentClause = ' civicrm_case.id IN ( ' . implode(',', $ids) . ' ) '; $form->assign('totalSelectedCases', count($ids)); } $form->_caseIds = $form->_componentIds = $ids; //set the context for redirection for any task actions $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $form); $urlParams = 'force=1'; if (CRM_Utils_Rule::qfKey($qfKey)) { $urlParams .= "&qfKey={$qfKey}"; } $session = CRM_Core_Session::singleton(); $searchFormName = strtolower($form->get('searchFormName')); if ($searchFormName == 'search') { $session->replaceUserContext(CRM_Utils_System::url('civicrm/case/search', $urlParams)); } else { $session->replaceUserContext(CRM_Utils_System::url("civicrm/contact/search/{$searchFormName}", $urlParams)); } }
/** * Get the list the export fields. * * @param int $selectAll * User preference while export. * @param array $ids * Contact ids. * @param array $params * Associated array of fields. * @param string $order * Order by clause. * @param array $fields * Associated array of fields. * @param array $moreReturnProperties * Additional return fields. * @param int $exportMode * Export mode. * @param string $componentClause * Component clause. * @param string $componentTable * Component table. * @param bool $mergeSameAddress * Merge records if they have same address. * @param bool $mergeSameHousehold * Merge records if they belong to the same household. * * @param array $exportParams * @param string $queryOperator * */ public static function exportComponents($selectAll, $ids, $params, $order = NULL, $fields = NULL, $moreReturnProperties = NULL, $exportMode = CRM_Export_Form_Select::CONTACT_EXPORT, $componentClause = NULL, $componentTable = NULL, $mergeSameAddress = FALSE, $mergeSameHousehold = FALSE, $exportParams = array(), $queryOperator = 'AND') { $headerRows = $returnProperties = array(); $primary = $paymentFields = $selectedPaymentFields = FALSE; $origFields = $fields; $relationField = NULL; $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id'); $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'); $contactRelationshipTypes = CRM_Contact_BAO_Relationship::getContactRelationshipType(NULL, NULL, NULL, NULL, TRUE, 'name', FALSE); $queryMode = self::getQueryMode($exportMode); if ($fields) { //construct return properties $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'); $locationTypeFields = array('street_address', 'supplemental_address_1', 'supplemental_address_2', 'city', 'postal_code', 'postal_code_suffix', 'geo_code_1', 'geo_code_2', 'state_province', 'country', 'phone', 'email', 'im'); foreach ($fields as $key => $value) { $phoneTypeId = $imProviderId = NULL; $relationshipTypes = $fieldName = CRM_Utils_Array::value(1, $value); if (!$fieldName) { continue; } // get phoneType id and IM service provider id separately if ($fieldName == 'phone') { $phoneTypeId = CRM_Utils_Array::value(3, $value); } elseif ($fieldName == 'im') { $imProviderId = CRM_Utils_Array::value(3, $value); } if (array_key_exists($relationshipTypes, $contactRelationshipTypes)) { if (!empty($value[2])) { $relationField = CRM_Utils_Array::value(2, $value); if (trim(CRM_Utils_Array::value(3, $value))) { $relLocTypeId = CRM_Utils_Array::value(3, $value); } else { $relLocTypeId = 'Primary'; } if ($relationField == 'phone') { $relPhoneTypeId = CRM_Utils_Array::value(4, $value); } elseif ($relationField == 'im') { $relIMProviderId = CRM_Utils_Array::value(4, $value); } } elseif (!empty($value[4])) { $relationField = CRM_Utils_Array::value(4, $value); $relLocTypeId = CRM_Utils_Array::value(5, $value); if ($relationField == 'phone') { $relPhoneTypeId = CRM_Utils_Array::value(6, $value); } elseif ($relationField == 'im') { $relIMProviderId = CRM_Utils_Array::value(6, $value); } } } $contactType = CRM_Utils_Array::value(0, $value); $locTypeId = CRM_Utils_Array::value(2, $value); if ($relationField) { if (in_array($relationField, $locationTypeFields) && is_numeric($relLocTypeId)) { if ($relPhoneTypeId) { $returnProperties[$relationshipTypes]['location'][$locationTypes[$relLocTypeId]]['phone-' . $relPhoneTypeId] = 1; } elseif ($relIMProviderId) { $returnProperties[$relationshipTypes]['location'][$locationTypes[$relLocTypeId]]['im-' . $relIMProviderId] = 1; } else { $returnProperties[$relationshipTypes]['location'][$locationTypes[$relLocTypeId]][$relationField] = 1; } $relPhoneTypeId = $relIMProviderId = NULL; } else { $returnProperties[$relationshipTypes][$relationField] = 1; } } elseif (is_numeric($locTypeId)) { if ($phoneTypeId) { $returnProperties['location'][$locationTypes[$locTypeId]]['phone-' . $phoneTypeId] = 1; } elseif ($imProviderId) { $returnProperties['location'][$locationTypes[$locTypeId]]['im-' . $imProviderId] = 1; } else { $returnProperties['location'][$locationTypes[$locTypeId]][$fieldName] = 1; } } else { //hack to fix component fields //revert mix of event_id and title if ($fieldName == 'event_id') { $returnProperties['event_id'] = 1; } elseif ($exportMode == CRM_Export_Form_Select::EVENT_EXPORT && array_key_exists($fieldName, self::componentPaymentFields())) { $selectedPaymentFields = TRUE; $paymentTableId = 'participant_id'; $returnProperties[$fieldName] = 1; } else { $returnProperties[$fieldName] = 1; } } } $returnProperties[self::defaultReturnProperty($exportMode)] = 1; } else { $primary = TRUE; $fields = CRM_Contact_BAO_Contact::exportableFields('All', TRUE, TRUE); foreach ($fields as $key => $var) { if ($key && substr($key, 0, 6) != 'custom') { //for CRM=952 $returnProperties[$key] = 1; } } if ($primary) { $returnProperties['location_type'] = 1; $returnProperties['im_provider'] = 1; $returnProperties['phone_type_id'] = 1; $returnProperties['provider_id'] = 1; $returnProperties['current_employer'] = 1; } $extraReturnProperties = array(); $paymentFields = FALSE; switch ($queryMode) { case CRM_Contact_BAO_Query::MODE_EVENT: $paymentFields = TRUE; $paymentTableId = 'participant_id'; break; case CRM_Contact_BAO_Query::MODE_MEMBER: $paymentFields = TRUE; $paymentTableId = 'membership_id'; break; case CRM_Contact_BAO_Query::MODE_PLEDGE: $extraReturnProperties = CRM_Pledge_BAO_Query::extraReturnProperties($queryMode); $paymentFields = TRUE; $paymentTableId = 'pledge_payment_id'; break; case CRM_Contact_BAO_Query::MODE_CASE: $extraReturnProperties = CRM_Case_BAO_Query::extraReturnProperties($queryMode); break; } if ($queryMode != CRM_Contact_BAO_Query::MODE_CONTACTS) { $componentReturnProperties = CRM_Contact_BAO_Query::defaultReturnProperties($queryMode); if ($queryMode == CRM_Contact_BAO_Query::MODE_CONTRIBUTE) { // soft credit columns are not automatically populated, because contribution search doesn't require them by default $componentReturnProperties = array_merge($componentReturnProperties, CRM_Contribute_BAO_Query::softCreditReturnProperties(TRUE)); } $returnProperties = array_merge($returnProperties, $componentReturnProperties); if (!empty($extraReturnProperties)) { $returnProperties = array_merge($returnProperties, $extraReturnProperties); } // unset non exportable fields for components $nonExpoFields = array('groups', 'tags', 'notes', 'contribution_status_id', 'pledge_status_id', 'pledge_payment_status_id'); foreach ($nonExpoFields as $value) { unset($returnProperties[$value]); } } } if ($mergeSameAddress) { //make sure the addressee fields are selected //while using merge same address feature $returnProperties['addressee'] = 1; $returnProperties['postal_greeting'] = 1; $returnProperties['email_greeting'] = 1; $returnProperties['street_name'] = 1; $returnProperties['household_name'] = 1; $returnProperties['street_address'] = 1; $returnProperties['city'] = 1; $returnProperties['state_province'] = 1; // some columns are required for assistance incase they are not already present $exportParams['merge_same_address']['temp_columns'] = array(); $tempColumns = array('id', 'master_id', 'state_province_id', 'postal_greeting_id', 'addressee_id'); foreach ($tempColumns as $column) { if (!array_key_exists($column, $returnProperties)) { $returnProperties[$column] = 1; $column = $column == 'id' ? 'civicrm_primary_id' : $column; $exportParams['merge_same_address']['temp_columns'][$column] = 1; } } } if (!$selectAll && $componentTable && !empty($exportParams['additional_group'])) { // If an Additional Group is selected, then all contacts in that group are // added to the export set (filtering out duplicates). $query = "\nINSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_contact gc WHERE gc.group_id = {$exportParams['additional_group']} ON DUPLICATE KEY UPDATE {$componentTable}.contact_id = gc.contact_id"; CRM_Core_DAO::executeQuery($query); } if ($moreReturnProperties) { // fix for CRM-7066 if (!empty($moreReturnProperties['group'])) { unset($moreReturnProperties['group']); $moreReturnProperties['groups'] = 1; } $returnProperties = array_merge($returnProperties, $moreReturnProperties); } $exportParams['postal_mailing_export']['temp_columns'] = array(); if ($exportParams['exportOption'] == 2 && isset($exportParams['postal_mailing_export']) && CRM_Utils_Array::value('postal_mailing_export', $exportParams['postal_mailing_export']) == 1) { $postalColumns = array('is_deceased', 'do_not_mail', 'street_address', 'supplemental_address_1'); foreach ($postalColumns as $column) { if (!array_key_exists($column, $returnProperties)) { $returnProperties[$column] = 1; $exportParams['postal_mailing_export']['temp_columns'][$column] = 1; } } } // rectify params to what proximity search expects if there is a value for prox_distance // CRM-7021 if (!empty($params)) { CRM_Contact_BAO_ProximityQuery::fixInputParams($params); } $query = new CRM_Contact_BAO_Query($params, $returnProperties, NULL, FALSE, FALSE, $queryMode, FALSE, TRUE, TRUE, NULL, $queryOperator); //sort by state //CRM-15301 $query->_sort = $order; list($select, $from, $where, $having) = $query->query(); if ($mergeSameHousehold == 1) { if (!$returnProperties['id']) { $returnProperties['id'] = 1; } //also merge Head of Household $relationKeyMOH = CRM_Utils_Array::key('Household Member of', $contactRelationshipTypes); $relationKeyHOH = CRM_Utils_Array::key('Head of Household for', $contactRelationshipTypes); foreach ($returnProperties as $key => $value) { if (!array_key_exists($key, $contactRelationshipTypes)) { $returnProperties[$relationKeyMOH][$key] = $value; $returnProperties[$relationKeyHOH][$key] = $value; } } unset($returnProperties[$relationKeyMOH]['location_type']); unset($returnProperties[$relationKeyMOH]['im_provider']); unset($returnProperties[$relationKeyHOH]['location_type']); unset($returnProperties[$relationKeyHOH]['im_provider']); } $allRelContactArray = $relationQuery = array(); foreach ($contactRelationshipTypes as $rel => $dnt) { if ($relationReturnProperties = CRM_Utils_Array::value($rel, $returnProperties)) { $allRelContactArray[$rel] = array(); // build Query for each relationship $relationQuery[$rel] = new CRM_Contact_BAO_Query(NULL, $relationReturnProperties, NULL, FALSE, FALSE, $queryMode); list($relationSelect, $relationFrom, $relationWhere, $relationHaving) = $relationQuery[$rel]->query(); list($id, $direction) = explode('_', $rel, 2); // identify the relationship direction $contactA = 'contact_id_a'; $contactB = 'contact_id_b'; if ($direction == 'b_a') { $contactA = 'contact_id_b'; $contactB = 'contact_id_a'; } if ($exportMode == CRM_Export_Form_Select::CONTACT_EXPORT) { $relIDs = $ids; } elseif ($exportMode == CRM_Export_Form_Select::ACTIVITY_EXPORT) { $sourceID = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_ActivityContact', 'record_type_id', 'Activity Source'); $query = "SELECT contact_id FROM civicrm_activity_contact\n WHERE activity_id IN ( " . implode(',', $ids) . ") AND\n record_type_id = {$sourceID}"; $dao = CRM_Core_DAO::executeQuery($query); while ($dao->fetch()) { $relIDs[] = $dao->contact_id; } } else { $component = self::exportComponent($exportMode); if ($exportMode == CRM_Export_Form_Select::CASE_EXPORT) { $relIDs = CRM_Case_BAO_Case::retrieveContactIdsByCaseId($ids); } else { $relIDs = CRM_Core_DAO::getContactIDsFromComponent($ids, $component); } } $relationshipJoin = $relationshipClause = ''; if (!$selectAll && $componentTable) { $relationshipJoin = " INNER JOIN {$componentTable} ctTable ON ctTable.contact_id = {$contactA}"; } elseif (!empty($relIDs)) { $relID = implode(',', $relIDs); $relationshipClause = " AND crel.{$contactA} IN ( {$relID} )"; } $relationFrom = " {$relationFrom}\n INNER JOIN civicrm_relationship crel ON crel.{$contactB} = contact_a.id AND crel.relationship_type_id = {$id}\n {$relationshipJoin} "; //check for active relationship status only $today = date('Ymd'); $relationActive = " AND (crel.is_active = 1 AND ( crel.end_date is NULL OR crel.end_date >= {$today} ) )"; $relationWhere = " WHERE contact_a.is_deleted = 0 {$relationshipClause} {$relationActive}"; $relationGroupBy = " GROUP BY crel.{$contactA}"; $relationSelect = "{$relationSelect}, {$contactA} as refContact "; $relationQueryString = "{$relationSelect} {$relationFrom} {$relationWhere} {$relationHaving} {$relationGroupBy}"; $allRelContactDAO = CRM_Core_DAO::executeQuery($relationQueryString); while ($allRelContactDAO->fetch()) { //FIX Me: Migrate this to table rather than array // build the array of all related contacts $allRelContactArray[$rel][$allRelContactDAO->refContact] = clone $allRelContactDAO; } $allRelContactDAO->free(); } } // make sure the groups stuff is included only if specifically specified // by the fields param (CRM-1969), else we limit the contacts outputted to only // ones that are part of a group if (!empty($returnProperties['groups'])) { $oldClause = "( contact_a.id = civicrm_group_contact.contact_id )"; $newClause = " ( {$oldClause} AND ( civicrm_group_contact.status = 'Added' OR civicrm_group_contact.status IS NULL ) )"; // total hack for export, CRM-3618 $from = str_replace($oldClause, $newClause, $from); } if (!$selectAll && $componentTable) { $from .= " INNER JOIN {$componentTable} ctTable ON ctTable.contact_id = contact_a.id "; } elseif ($componentClause) { if (empty($where)) { $where = "WHERE {$componentClause}"; } else { $where .= " AND {$componentClause}"; } } // CRM-13982 - check if is deleted $excludeTrashed = TRUE; foreach ($params as $value) { if ($value[0] == 'contact_is_deleted') { $excludeTrashed = FALSE; } } $trashClause = $excludeTrashed ? "contact_a.is_deleted != 1" : "( 1 )"; if (empty($where)) { $where = "WHERE {$trashClause}"; } else { $where .= " AND {$trashClause}"; } $queryString = "{$select} {$from} {$where} {$having}"; $groupBy = ""; if (!empty($returnProperties['tags']) || !empty($returnProperties['groups']) || CRM_Utils_Array::value('notes', $returnProperties) || $queryMode & CRM_Contact_BAO_Query::MODE_CONTACTS && $query->_useGroupBy) { $groupBy = " GROUP BY contact_a.id"; } switch ($exportMode) { case CRM_Export_Form_Select::CONTRIBUTE_EXPORT: $groupBy = 'GROUP BY civicrm_contribution.id'; if (CRM_Contribute_BAO_Query::isSoftCreditOptionEnabled()) { // especial group by when soft credit columns are included $groupBy = 'GROUP BY contribution_search_scredit_combined.id, contribution_search_scredit_combined.scredit_id'; } break; case CRM_Export_Form_Select::EVENT_EXPORT: $groupBy = 'GROUP BY civicrm_participant.id'; break; case CRM_Export_Form_Select::MEMBER_EXPORT: $groupBy = " GROUP BY civicrm_membership.id"; break; } if ($queryMode & CRM_Contact_BAO_Query::MODE_ACTIVITY) { $groupBy = " GROUP BY civicrm_activity.id "; } $queryString .= $groupBy; // always add contact_a.id to the ORDER clause // so the order is deterministic //CRM-15301 if (strpos('contact_a.id', $order) === FALSE) { $order .= ", contact_a.id"; } if ($order) { list($field, $dir) = explode(' ', $order, 2); $field = trim($field); if (!empty($returnProperties[$field])) { //CRM-15301 $queryString .= " ORDER BY {$order}"; } } $multipleSelectFields = array('preferred_communication_method' => 1); $addPaymentHeader = FALSE; $paymentDetails = array(); if ($paymentFields || $selectedPaymentFields) { // get payment related in for event and members $paymentDetails = CRM_Contribute_BAO_Contribution::getContributionDetails($exportMode, $ids); //get all payment headers. // If we haven't selected specific payment fields, load in all the // payment headers. if (!$selectedPaymentFields) { $paymentHeaders = self::componentPaymentFields(); if (!empty($paymentDetails)) { $addPaymentHeader = TRUE; } } else { $paymentHeaders = array(); } $nullContributionDetails = array_fill_keys(array_keys($paymentHeaders), NULL); } $componentDetails = $headerRows = $sqlColumns = array(); $setHeader = TRUE; $rowCount = self::EXPORT_ROW_COUNT; $offset = 0; // we write to temp table often to avoid using too much memory $tempRowCount = 100; $count = -1; // for CRM-3157 purposes $i18n = CRM_Core_I18n::singleton(); $outputColumns = array(); //@todo - it would be clearer to start defining output columns earlier in this function rather than stick with return properties until this point // as the array is not actually 'returnProperties' after the sql query is formed - making the alterations to it confusing foreach ($returnProperties as $key => $value) { $outputColumns[$key] = $value; } while (1) { $limitQuery = "{$queryString} LIMIT {$offset}, {$rowCount}"; $dao = CRM_Core_DAO::executeQuery($limitQuery); if ($dao->N <= 0) { break; } while ($dao->fetch()) { $count++; $row = array(); //convert the pseudo constants // CRM-14398 there is problem in this architecture that is not easily solved. For now we are using the cloned // temporary iterationDAO object to get around it. // the issue is that the convertToPseudoNames function is adding additional properties (e.g for campaign) to the DAO object // these additional properties are NOT reset when the $dao cycles through the while loop // nor are they overwritten as they are not in the loop // the convertToPseudoNames will not adequately over-write them either as it doesn't 'kick-in' unless the // relevant property is set. // It may be that a long-term fix could be introduced there - however, it's probably necessary to figure out how to test the // export class before tackling a better architectural fix $iterationDAO = clone $dao; $query->convertToPseudoNames($iterationDAO); //first loop through output columns so that we return what is required, and in same order. $relationshipField = 0; foreach ($outputColumns as $field => $value) { //we should set header only once if ($setHeader) { $sqlDone = FALSE; // Split campaign into 2 fields for id and title if (substr($field, -14) == 'campaign_title') { $headerRows[] = ts('Campaign Title'); } elseif (substr($field, -11) == 'campaign_id') { $headerRows[] = ts('Campaign ID'); } elseif (isset($query->_fields[$field]['title'])) { $headerRows[] = $query->_fields[$field]['title']; } elseif ($field == 'phone_type_id') { $headerRows[] = ts('Phone Type'); } elseif ($field == 'provider_id') { $headerRows[] = ts('IM Service Provider'); } elseif (is_array($value) && $field == 'location') { // fix header for location type case foreach ($value as $ltype => $val) { foreach (array_keys($val) as $fld) { $type = explode('-', $fld); $hdr = "{$ltype}-" . $query->_fields[$type[0]]['title']; if (!empty($type[1])) { if (CRM_Utils_Array::value(0, $type) == 'phone') { $hdr .= "-" . CRM_Utils_Array::value($type[1], $phoneTypes); } elseif (CRM_Utils_Array::value(0, $type) == 'im') { $hdr .= "-" . CRM_Utils_Array::value($type[1], $imProviders); } } $headerRows[] = $hdr; self::sqlColumnDefn($query, $sqlColumns, $hdr); } $sqlDone = TRUE; } } elseif (substr($field, 0, 5) == 'case_') { if ($query->_fields['case'][$field]['title']) { $headerRows[] = $query->_fields['case'][$field]['title']; } elseif ($query->_fields['activity'][$field]['title']) { $headerRows[] = $query->_fields['activity'][$field]['title']; } } elseif (array_key_exists($field, $contactRelationshipTypes)) { $relName = $field; foreach ($value as $relationField => $relationValue) { // below block is same as primary block (duplicate) if (isset($relationQuery[$field]->_fields[$relationField]['title'])) { if ($relationQuery[$field]->_fields[$relationField]['name'] == 'name') { $headerName = $field . '-' . $relationField; } else { if ($relationField == 'current_employer') { $headerName = $field . '-' . 'current_employer'; } else { $headerName = $field . '-' . $relationQuery[$field]->_fields[$relationField]['name']; } } $headerRows[] = $headerName; self::sqlColumnDefn($query, $sqlColumns, $headerName); } elseif ($relationField == 'phone_type_id') { $headerName = $field . '-' . 'Phone Type'; $headerRows[] = $headerName; self::sqlColumnDefn($query, $sqlColumns, $headerName); } elseif ($relationField == 'provider_id') { $headerName = $field . '-' . 'Im Service Provider'; $headerRows[] = $headerName; self::sqlColumnDefn($query, $sqlColumns, $headerName); } elseif ($relationField == 'state_province_id') { $headerName = $field . '-' . 'state_province_id'; $headerRows[] = $headerName; self::sqlColumnDefn($query, $sqlColumns, $headerName); } elseif (is_array($relationValue) && $relationField == 'location') { // fix header for location type case foreach ($relationValue as $ltype => $val) { foreach (array_keys($val) as $fld) { $type = explode('-', $fld); $hdr = "{$ltype}-" . $relationQuery[$field]->_fields[$type[0]]['title']; if (!empty($type[1])) { if (CRM_Utils_Array::value(0, $type) == 'phone') { $hdr .= "-" . CRM_Utils_Array::value($type[1], $phoneTypes); } elseif (CRM_Utils_Array::value(0, $type) == 'im') { $hdr .= "-" . CRM_Utils_Array::value($type[1], $imProviders); } } $headerName = $field . '-' . $hdr; $headerRows[] = $headerName; self::sqlColumnDefn($query, $sqlColumns, $headerName); } } } } } elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) { $headerRows[] = CRM_Utils_Array::value($field, self::componentPaymentFields()); } else { $headerRows[] = $field; } if (!$sqlDone) { self::sqlColumnDefn($query, $sqlColumns, $field); } } // add im_provider to $dao object if ($field == 'im_provider' && property_exists($iterationDAO, 'provider_id')) { $iterationDAO->im_provider = $iterationDAO->provider_id; } //build row values (data) $fieldValue = NULL; if (property_exists($iterationDAO, $field)) { $fieldValue = $iterationDAO->{$field}; // to get phone type from phone type id if ($field == 'phone_type_id' && isset($phoneTypes[$fieldValue])) { $fieldValue = $phoneTypes[$fieldValue]; } elseif ($field == 'provider_id' || $field == 'im_provider') { $fieldValue = CRM_Utils_Array::value($fieldValue, $imProviders); } elseif ($field == 'master_id') { $masterAddressId = NULL; if (isset($iterationDAO->master_id)) { $masterAddressId = $iterationDAO->master_id; } // get display name of contact that address is shared. $fieldValue = CRM_Contact_BAO_Contact::getMasterDisplayName($masterAddressId, $iterationDAO->contact_id); } } if ($field == 'id') { $row[$field] = $iterationDAO->contact_id; // special case for calculated field } elseif ($field == 'source_contact_id') { $row[$field] = $iterationDAO->contact_id; } elseif ($field == 'pledge_balance_amount') { $row[$field] = $iterationDAO->pledge_amount - $iterationDAO->pledge_total_paid; // special case for calculated field } elseif ($field == 'pledge_next_pay_amount') { $row[$field] = $iterationDAO->pledge_next_pay_amount + $iterationDAO->pledge_outstanding_amount; } elseif (is_array($value) && $field == 'location') { // fix header for location type case foreach ($value as $ltype => $val) { foreach (array_keys($val) as $fld) { $type = explode('-', $fld); $fldValue = "{$ltype}-" . $type[0]; // CRM-14076 - fix label to work as the query object expects // FIXME: We should not be using labels as keys! $daoField = CRM_Utils_String::munge($ltype) . '-' . $type[0]; if (!empty($type[1])) { $fldValue .= "-" . $type[1]; $daoField .= "-" . $type[1]; } // CRM-3157: localise country, region (both have ‘country’ context) and state_province (‘province’ context) switch ($fld) { case 'country': case 'world_region': $row[$fldValue] = $i18n->crm_translate($iterationDAO->{$daoField}, array('context' => 'country')); break; case 'state_province': $row[$fldValue] = $i18n->crm_translate($iterationDAO->{$daoField}, array('context' => 'province')); break; case 'im_provider': $imFieldvalue = $daoField . "-provider_id"; $row[$fldValue] = CRM_Utils_Array::value($iterationDAO->{$imFieldvalue}, $imProviders); break; default: $row[$fldValue] = $iterationDAO->{$daoField}; break; } } } } elseif (array_key_exists($field, $contactRelationshipTypes)) { $relDAO = CRM_Utils_Array::value($iterationDAO->contact_id, $allRelContactArray[$field]); $relationQuery[$field]->convertToPseudoNames($relDAO); foreach ($value as $relationField => $relationValue) { if (is_object($relDAO) && property_exists($relDAO, $relationField)) { $fieldValue = $relDAO->{$relationField}; if ($relationField == 'phone_type_id') { $fieldValue = $phoneTypes[$relationValue]; } elseif ($relationField == 'provider_id') { $fieldValue = CRM_Utils_Array::value($relationValue, $imProviders); } elseif (is_object($relDAO) && in_array($relationField, array('email_greeting', 'postal_greeting', 'addressee'))) { //special case for greeting replacement $fldValue = "{$relationField}_display"; $fieldValue = $relDAO->{$fldValue}; } } elseif (is_object($relDAO) && $relationField == 'state_province') { $fieldValue = CRM_Core_PseudoConstant::stateProvince($relDAO->state_province_id); } elseif (is_object($relDAO) && $relationField == 'country') { $fieldValue = CRM_Core_PseudoConstant::country($relDAO->country_id); } else { $fieldValue = ''; } $field = $field . '_'; if (array_key_exists($relationField, $multipleSelectFields)) { $param = array($relationField => $fieldValue); $names = array($relationField => array('newName' => $relationField, 'groupName' => $relationField)); CRM_Core_OptionGroup::lookupValues($param, $names, FALSE); $fieldValue = $param[$relationField]; } if (is_object($relDAO) && $relationField == 'id') { $row[$field . $relationField] = $relDAO->contact_id; } elseif (is_array($relationValue) && $relationField == 'location') { foreach ($relationValue as $ltype => $val) { foreach (array_keys($val) as $fld) { $type = explode('-', $fld); $fldValue = "{$ltype}-" . $type[0]; if (!empty($type[1])) { $fldValue .= "-" . $type[1]; } // CRM-3157: localise country, region (both have ‘country’ context) // and state_province (‘province’ context) switch (TRUE) { case !is_object($relDAO): $row[$field . '_' . $fldValue] = ''; break; case in_array('country', $type): case in_array('world_region', $type): $row[$field . '_' . $fldValue] = $i18n->crm_translate($relDAO->{$fldValue}, array('context' => 'country')); break; case in_array('state_province', $type): $row[$field . '_' . $fldValue] = $i18n->crm_translate($relDAO->{$fldValue}, array('context' => 'province')); break; default: $row[$field . '_' . $fldValue] = $relDAO->{$fldValue}; break; } } } } elseif (isset($fieldValue) && $fieldValue != '') { //check for custom data if ($cfID = CRM_Core_BAO_CustomField::getKeyID($relationField)) { $row[$field . $relationField] = CRM_Core_BAO_CustomField::getDisplayValue($fieldValue, $cfID, $relationQuery[$field]->_options); } else { //normal relationship fields // CRM-3157: localise country, region (both have ‘country’ context) and state_province (‘province’ context) switch ($relationField) { case 'country': case 'world_region': $row[$field . $relationField] = $i18n->crm_translate($fieldValue, array('context' => 'country')); break; case 'state_province': $row[$field . $relationField] = $i18n->crm_translate($fieldValue, array('context' => 'province')); break; default: $row[$field . $relationField] = $fieldValue; break; } } } else { // if relation field is empty or null $row[$field . $relationField] = ''; } } } elseif (isset($fieldValue) && $fieldValue != '') { //check for custom data if ($cfID = CRM_Core_BAO_CustomField::getKeyID($field)) { $row[$field] = CRM_Core_BAO_CustomField::getDisplayValue($fieldValue, $cfID, $query->_options); } elseif (array_key_exists($field, $multipleSelectFields)) { //option group fixes $paramsNew = array($field => $fieldValue); if ($field == 'test_tutoring') { $name = array($field => array('newName' => $field, 'groupName' => 'test')); // for readers group } elseif (substr($field, 0, 4) == 'cmr_') { $name = array($field => array('newName' => $field, 'groupName' => substr($field, 0, -3))); } else { $name = array($field => array('newName' => $field, 'groupName' => $field)); } CRM_Core_OptionGroup::lookupValues($paramsNew, $name, FALSE); $row[$field] = $paramsNew[$field]; } elseif (in_array($field, array('email_greeting', 'postal_greeting', 'addressee'))) { //special case for greeting replacement $fldValue = "{$field}_display"; $row[$field] = $iterationDAO->{$fldValue}; } else { //normal fields with a touch of CRM-3157 switch ($field) { case 'country': case 'world_region': $row[$field] = $i18n->crm_translate($fieldValue, array('context' => 'country')); break; case 'state_province': $row[$field] = $i18n->crm_translate($fieldValue, array('context' => 'province')); break; case 'gender': case 'preferred_communication_method': case 'preferred_mail_format': case 'communication_style': $row[$field] = $i18n->crm_translate($fieldValue); break; default: $row[$field] = $fieldValue; break; } } } elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) { $paymentData = CRM_Utils_Array::value($iterationDAO->{$paymentTableId}, $paymentDetails); $payFieldMapper = array('componentPaymentField_total_amount' => 'total_amount', 'componentPaymentField_contribution_status' => 'contribution_status', 'componentPaymentField_payment_instrument' => 'pay_instru', 'componentPaymentField_transaction_id' => 'trxn_id', 'componentPaymentField_received_date' => 'receive_date'); $row[$field] = CRM_Utils_Array::value($payFieldMapper[$field], $paymentData, ''); } else { // if field is empty or null $row[$field] = ''; } } // add payment headers if required if ($addPaymentHeader && $paymentFields) { $headerRows = array_merge($headerRows, $paymentHeaders); foreach (array_keys($paymentHeaders) as $paymentHdr) { self::sqlColumnDefn($query, $sqlColumns, $paymentHdr); } } if ($setHeader) { $exportTempTable = self::createTempTable($sqlColumns); } //build header only once $setHeader = FALSE; // If specific payment fields have been selected for export, payment // data will already be in $row. Otherwise, add payment related // information, if appropriate. if ($addPaymentHeader) { if (!$selectedPaymentFields) { if ($paymentFields) { $paymentData = CRM_Utils_Array::value($row[$paymentTableId], $paymentDetails); if (!is_array($paymentData) || empty($paymentData)) { $paymentData = $nullContributionDetails; } $row = array_merge($row, $paymentData); } elseif (!empty($paymentDetails)) { $row = array_merge($row, $nullContributionDetails); } } } //remove organization name for individuals if it is set for current employer if (!empty($row['contact_type']) && $row['contact_type'] == 'Individual' && array_key_exists('organization_name', $row)) { $row['organization_name'] = ''; } // add component info // write the row to a file $componentDetails[] = $row; // output every $tempRowCount rows if ($count % $tempRowCount == 0) { self::writeDetailsToTable($exportTempTable, $componentDetails, $sqlColumns); $componentDetails = array(); } } $dao->free(); $offset += $rowCount; } if ($exportTempTable) { self::writeDetailsToTable($exportTempTable, $componentDetails, $sqlColumns); // do merge same address and merge same household processing if ($mergeSameAddress) { self::mergeSameAddress($exportTempTable, $headerRows, $sqlColumns, $exportParams); } // merge the records if they have corresponding households if ($mergeSameHousehold) { self::mergeSameHousehold($exportTempTable, $headerRows, $sqlColumns, $relationKeyMOH); self::mergeSameHousehold($exportTempTable, $headerRows, $sqlColumns, $relationKeyHOH); } // fix the headers for rows with relationship type if (!empty($relName)) { self::manipulateHeaderRows($headerRows, $contactRelationshipTypes); } // if postalMailing option is checked, exclude contacts who are deceased, have // "Do not mail" privacy setting, or have no street address if (isset($exportParams['postal_mailing_export']['postal_mailing_export']) && $exportParams['postal_mailing_export']['postal_mailing_export'] == 1) { self::postalMailingFormat($exportTempTable, $headerRows, $sqlColumns, $exportMode); } // call export hook CRM_Utils_Hook::export($exportTempTable, $headerRows, $sqlColumns, $exportMode); // now write the CSV file self::writeCSVFromTable($exportTempTable, $headerRows, $sqlColumns, $exportMode); // delete the export temp table and component table $sql = "DROP TABLE IF EXISTS {$exportTempTable}"; CRM_Core_DAO::executeQuery($sql); CRM_Utils_System::civiExit(); } else { CRM_Core_Error::fatal(ts('No records to export')); } }
/** * Given a saved search compute the clause and the tables and store it for future use. */ public function buildClause() { $fv = unserialize($this->form_values); if ($this->mapping_id) { $params = CRM_Core_BAO_Mapping::formattedFields($fv); } else { $params = CRM_Contact_BAO_Query::convertFormValues($fv); } if (!empty($params)) { $tables = $whereTables = array(); $this->where_clause = CRM_Contact_BAO_Query::getWhereClause($params, NULL, $tables, $whereTables); if (!empty($tables)) { $this->select_tables = serialize($tables); } if (!empty($whereTables)) { $this->where_tables = serialize($whereTables); } } }
/** * @param $params * @param $action * @param $sortID * @param null $displayRelationshipType * @param string $queryOperator * * @return CRM_Contact_DAO_Contact */ function contactIDQuery($params, $action, $sortID, $displayRelationshipType = NULL, $queryOperator = 'AND') { $sortOrder =& $this->getSortOrder($this->_action); $sort = new CRM_Utils_Sort($sortOrder, $sortID); // rectify params to what proximity search expects if there is a value for prox_distance // CRM-7021 CRM-7905 if (!empty($params)) { CRM_Contact_BAO_ProximityQuery::fixInputParams($params); } if (!$displayRelationshipType) { $query = new CRM_Contact_BAO_Query($params, $this->_returnProperties, NULL, FALSE, FALSE, 1, FALSE, TRUE, TRUE, NULL, $queryOperator); } else { $query = new CRM_Contact_BAO_Query($params, $this->_returnProperties, NULL, FALSE, FALSE, 1, FALSE, TRUE, TRUE, $displayRelationshipType, $queryOperator); } $value = $query->searchQuery(0, 0, $sort, FALSE, FALSE, FALSE, FALSE, FALSE); return $value; }
/** * @param $groupInfo * @param null $sort * @param null $showLinks * @param bool $returnOnlyCount * @param int $offset * @param int $rowCount * * @return array */ static function getGlobalContacts(&$groupInfo, $sort = NULL, $showLinks = NULL, $returnOnlyCount = FALSE, $offset = 0, $rowCount = 25) { $globalContacts = array(); $settingsProcessor = new CRM_Case_XMLProcessor_Settings(); $settings = $settingsProcessor->run(); if (!empty($settings)) { $groupInfo['name'] = $settings['groupname']; if ($groupInfo['name']) { $searchParams = array('name' => $groupInfo['name']); $results = array(); CRM_Contact_BAO_Group::retrieve($searchParams, $results); if ($results) { $groupInfo['id'] = $results['id']; $groupInfo['title'] = $results['title']; $params = array(array('group', 'IN', array($groupInfo['id'] => 1), 0, 0)); $return = array('contact_id' => 1, 'sort_name' => 1, 'display_name' => 1, 'email' => 1, 'phone' => 1); list($globalContacts) = CRM_Contact_BAO_Query::apiQuery($params, $return, NULL, $sort, $offset, $rowCount, TRUE, $returnOnlyCount); if ($returnOnlyCount) { return $globalContacts; } if ($showLinks) { foreach ($globalContacts as $idx => $contact) { $globalContacts[$idx]['sort_name'] = '<a href="' . CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$contact['contact_id']}") . '">' . $contact['sort_name'] . '</a>'; } } } } } return $globalContacts; }
/** * default set of return default hier return properties * * @return void * @access public */ static function &defaultHierReturnProperties() { if (!isset(self::$_defaultHierReturnProperties)) { self::$_defaultHierReturnProperties = array('home_URL' => 1, 'image_URL' => 1, 'legal_identifier' => 1, 'external_identifier' => 1, 'contact_type' => 1, 'contact_sub_type' => 1, 'sort_name' => 1, 'display_name' => 1, 'nick_name' => 1, 'first_name' => 1, 'middle_name' => 1, 'last_name' => 1, 'individual_prefix' => 1, 'individual_suffix' => 1, 'email_greeting' => 1, 'postal_greeting' => 1, 'addressee' => 1, 'birth_date' => 1, 'gender' => 1, 'preferred_communication_method' => 1, 'do_not_phone' => 1, 'do_not_email' => 1, 'do_not_mail' => 1, 'do_not_sms' => 1, 'do_not_trade' => 1, 'location' => array('1' => array('location_type' => 1, 'street_address' => 1, 'city' => 1, 'state_province' => 1, 'postal_code' => 1, 'postal_code_suffix' => 1, 'country' => 1, 'phone-Phone' => 1, 'phone-Mobile' => 1, 'phone-Fax' => 1, 'phone-1' => 1, 'phone-2' => 1, 'phone-3' => 1, 'im-1' => 1, 'im-2' => 1, 'im-3' => 1, 'email-1' => 1, 'email-2' => 1, 'email-3' => 1), '2' => array('location_type' => 1, 'street_address' => 1, 'city' => 1, 'state_province' => 1, 'postal_code' => 1, 'postal_code_suffix' => 1, 'country' => 1, 'phone-Phone' => 1, 'phone-Mobile' => 1, 'phone-1' => 1, 'phone-2' => 1, 'phone-3' => 1, 'im-1' => 1, 'im-2' => 1, 'im-3' => 1, 'email-1' => 1, 'email-2' => 1, 'email-3' => 1))); } return self::$_defaultHierReturnProperties; }
/** * Fill the acl contact cache for this contact id if empty. * * @param int $userID * @param int|string $type the type of operation (view|edit) * @param bool $force * Should we force a recompute. */ public static function cache($userID, $type = CRM_Core_Permission::VIEW, $force = FALSE) { static $_processed = array(); if ($type = CRM_Core_Permission::VIEW) { $operationClause = " operation IN ( 'Edit', 'View' ) "; $operation = 'View'; } else { $operationClause = " operation = 'Edit' "; $operation = 'Edit'; } if (!$force) { if (!empty($_processed[$userID])) { return; } // run a query to see if the cache is filled $sql = "\nSELECT count(id)\nFROM civicrm_acl_contact_cache\nWHERE user_id = %1\nAND {$operationClause}\n"; $params = array(1 => array($userID, 'Integer')); $count = CRM_Core_DAO::singleValueQuery($sql, $params); if ($count > 0) { $_processed[$userID] = 1; return; } } $tables = array(); $whereTables = array(); $permission = CRM_ACL_API::whereClause($type, $tables, $whereTables, $userID); $from = CRM_Contact_BAO_Query::fromClause($whereTables); CRM_Core_DAO::executeQuery("\nINSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )\nSELECT {$userID} as user_id, contact_a.id as contact_id, '{$operation}' as operation\n {$from}\nWHERE {$permission}\nGROUP BY contact_a.id\nON DUPLICATE KEY UPDATE\n user_id=VALUES(user_id),\n contact_id=VALUES(contact_id),\n operation=VALUES(operation)"); $_processed[$userID] = 1; }
/** * Set group by clause. */ public function groupBy() { $this->_groupBy = ""; $append = FALSE; if (!empty($this->_params['group_bys']) && is_array($this->_params['group_bys'])) { foreach ($this->_columns as $tableName => $table) { if (array_key_exists('group_bys', $table)) { foreach ($table['group_bys'] as $fieldName => $field) { if (!empty($this->_params['group_bys'][$fieldName])) { if (!empty($field['chart'])) { $this->assign('chartSupported', TRUE); } if (!empty($table['group_bys'][$fieldName]['frequency']) && !empty($this->_params['group_bys_freq'][$fieldName])) { $append = "YEAR({$field['dbAlias']});;"; if (in_array(strtolower($this->_params['group_bys_freq'][$fieldName]), array('year'))) { $append = ''; } if ($this->_params['group_bys_freq'][$fieldName] == 'FISCALYEAR') { $this->_groupBy[] = self::fiscalYearOffset($field['dbAlias']); } else { $this->_groupBy[] = "{$append} {$this->_params['group_bys_freq'][$fieldName]}({$field['dbAlias']})"; } $append = TRUE; } else { $this->_groupBy[] = $field['dbAlias']; } } } } } if (!empty($this->_statFields) && ($append && count($this->_groupBy) <= 1 || !$append) && !$this->_having) { $this->_rollup = " WITH ROLLUP"; } $groupBy = array(); foreach ($this->_groupBy as $key => $val) { if (strpos($val, ';;') !== FALSE) { $groupBy = array_merge($groupBy, explode(';;', $val)); } else { $groupBy[] = $this->_groupBy[$key]; } } $this->_groupBy = "GROUP BY " . implode(', ', $groupBy); } else { $groupBy = "{$this->_aliases['civicrm_contact']}.id"; $this->_groupBy = "GROUP BY {$this->_aliases['civicrm_contact']}.id"; } $this->_groupBy .= $this->_rollup; // append select with ANY_VALUE() keyword $this->_select = CRM_Contact_BAO_Query::appendAnyValueToSelect($this->_selectClauses, $groupBy); }
/** * @param $values * @param $query */ public static function whereClauseSingle(&$values, &$query) { list($name, $op, $value, $grouping, $wildcard) = $values; $fields = array_merge(CRM_Event_BAO_Event::fields(), CRM_Event_BAO_Participant::exportableFields()); switch ($name) { case 'event_start_date_low': case 'event_start_date_high': $query->dateQueryBuilder($values, 'civicrm_event', 'event_start_date', 'start_date', 'Start Date'); return; case 'event_end_date_low': case 'event_end_date_high': $query->dateQueryBuilder($values, 'civicrm_event', 'event_end_date', 'end_date', 'End Date'); return; case 'event_include_repeating_events': /** * Include Repeating Events */ //Get parent of this event $exEventId = ''; if ($query->_where[$grouping]) { foreach ($query->_where[$grouping] as $key => $val) { if (strstr($val, 'civicrm_event.id =')) { $exEventId = $val; $extractEventId = explode(" ", $val); $value = $extractEventId[2]; $where = $query->_where[$grouping][$key]; } else { if (strstr($val, 'civicrm_event.id IN')) { //extract the first event id if multiple events are selected preg_match('/civicrm_event.id IN \\(\\"(\\d+)/', $val, $matches); $value = $matches[1]; $where = $query->_where[$grouping][$key]; } } } if ($exEventId) { $extractEventId = explode(" ", $exEventId); $value = $extractEventId[2]; } else { if (!empty($matches[1])) { $value = $matches[1]; } } $where = $query->_where[$grouping][$key]; } $thisEventHasParent = CRM_Core_BAO_RecurringEntity::getParentFor($value, 'civicrm_event'); if ($thisEventHasParent) { $getAllConnections = CRM_Core_BAO_RecurringEntity::getEntitiesForParent($thisEventHasParent, 'civicrm_event'); $allEventIds = array(); foreach ($getAllConnections as $key => $val) { $allEventIds[] = $val['id']; } if (!empty($allEventIds)) { $op = "IN"; $value = "(" . implode(",", $allEventIds) . ")"; } } $query->_where[$grouping][] = "{$where} OR civicrm_event.id {$op} {$value}"; $query->_qill[$grouping][] = ts('Include Repeating Events'); $query->_tables['civicrm_event'] = $query->_whereTables['civicrm_event'] = 1; return; case 'participant_is_test': $key = array_search('civicrm_participant.is_test = 0', $query->_where[$grouping]); if (!empty($key)) { unset($query->_where[$grouping][$key]); } case 'participant_test': // We dont want to include all tests for sql OR CRM-7827 if (!$value || $query->getOperator() != 'OR') { $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_participant.is_test", $op, $value, "Boolean"); $isTest = $value ? 'a Test' : 'not a Test'; $query->_qill[$grouping][] = ts("Participant is %1", array(1 => $isTest)); $query->_tables['civicrm_participant'] = $query->_whereTables['civicrm_participant'] = 1; } return; case 'participant_fee_id': foreach ($value as $k => &$val) { $val = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', $val, 'label'); $val = CRM_Core_DAO::escapeString(trim($val)); } $feeLabel = implode('|', $value); $query->_where[$grouping][] = "civicrm_participant.fee_level REGEXP '{$feeLabel}'"; $query->_qill[$grouping][] = ts("Fee level") . " IN " . implode(', ', $value); $query->_tables['civicrm_participant'] = $query->_whereTables['civicrm_participant'] = 1; return; case 'participant_fee_amount_high': case 'participant_fee_amount_low': $query->numberRangeBuilder($values, 'civicrm_participant', 'participant_fee_amount', 'fee_amount', 'Fee Amount'); return; case 'participant_status_id': if ($value && is_array($value) && strpos($op, 'IN') === FALSE) { $op = 'IN'; } case 'participant_status': case 'participant_source': case 'participant_id': case 'participant_contact_id': case 'participant_is_pay_later': case 'participant_fee_amount': case 'participant_fee_level': case 'participant_campaign_id': $qillName = $name; if (in_array($name, array('participant_status_id', 'participant_source', 'participant_id', 'participant_contact_id', 'participant_fee_amount', 'participant_fee_level', 'participant_is_pay_later', 'participant_campaign_id'))) { $name = str_replace('participant_', '', $name); if ($name == 'is_pay_later') { $qillName = $name; } } elseif ($name == 'participant_status') { $name = 'status_id'; } $dataType = !empty($fields[$qillName]['type']) ? CRM_Utils_Type::typeToString($fields[$qillName]['type']) : 'String'; $tableName = empty($tableName) ? 'civicrm_participant' : $tableName; if (is_array($value) && in_array(key($value), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) { $op = key($value); $value = $value[$op]; } $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("{$tableName}.{$name}", $op, $value, $dataType); list($op, $value) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Event_DAO_Participant', $name, $value, $op); $query->_qill[$grouping][] = ts('%1 %2 %3', array(1 => $fields[$qillName]['title'], 2 => $op, 3 => $value)); $query->_tables['civicrm_participant'] = $query->_whereTables['civicrm_participant'] = 1; return; case 'participant_role': case 'participant_role_id': $qillName = $name; $name = 'role_id'; if (is_array($value) && in_array(key($value), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) { $op = key($value); $value = $value[$op]; } if (!strstr($op, 'NULL') && !strstr($op, 'EMPTY') && !strstr($op, 'LIKE')) { $regexOp = strstr($op, '!') || strstr($op, 'NOT') ? 'NOT REGEXP' : 'REGEXP'; $regexp = "[[:cntrl:]]*" . implode('[[:>:]]*|[[:<:]]*', (array) $value) . "[[:cntrl:]]*"; $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_participant.{$name}", $regexOp, $regexp, 'String'); } else { $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("{$tableName}.{$name}", $op, $value, $dataType); } list($op, $value) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Event_DAO_Participant', $name, $value, $op); $query->_qill[$grouping][] = ts('%1 %2 %3', array(1 => $fields[$qillName]['title'], 2 => $op, 3 => $value)); $query->_tables['civicrm_participant'] = $query->_whereTables['civicrm_participant'] = 1; return; case 'participant_register_date': case 'participant_register_date_high': case 'participant_register_date_low': $query->dateQueryBuilder($values, 'civicrm_participant', 'participant_register_date', 'register_date', 'Register Date'); return; case 'event_id': case 'participant_event_id': $name = str_replace('participant_', '', $name); case 'event_is_public': case 'event_type_id': case 'event_title': $qillName = $name; if (in_array($name, array('event_id', 'event_title', 'event_is_public'))) { $name = str_replace('event_', '', $name); } $dataType = !empty($fields[$qillName]['type']) ? CRM_Utils_Type::typeToString($fields[$qillName]['type']) : 'String'; $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_event.{$name}", $op, $value, $dataType); $query->_tables['civicrm_event'] = $query->_whereTables['civicrm_event'] = 1; if (!array_key_exists($qillName, $fields)) { break; } list($op, $value) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Event_DAO_Event', $name, $value, $op); $query->_qill[$grouping][] = ts('%1 %2 %3', array(1 => $fields[$qillName]['title'], 2 => $op, 3 => $value)); return; } }
/** * @param $values * @param $query */ public static function whereClauseSingle(&$values, &$query) { list($name, $op, $value, $grouping, $wildcard) = $values; $quoteValue = NULL; $fields = array_merge(CRM_Contribute_BAO_Contribution::fields(), self::getFields()); if (!empty($value) && !is_array($value)) { $quoteValue = "\"{$value}\""; } $strtolower = function_exists('mb_strtolower') ? 'mb_strtolower' : 'strtolower'; foreach (self::getRecurringFields() as $dateField => $dateFieldTitle) { if (self::buildDateWhere($values, $query, $name, $dateField, $dateFieldTitle)) { return; } } switch ($name) { case 'contribution_date': case 'contribution_date_low': case 'contribution_date_low_time': case 'contribution_date_high': case 'contribution_date_high_time': // process to / from date $query->dateQueryBuilder($values, 'civicrm_contribution', 'contribution_date', 'receive_date', 'Contribution Date'); return; case 'contribution_amount': case 'contribution_amount_low': case 'contribution_amount_high': // process min/max amount $query->numberRangeBuilder($values, 'civicrm_contribution', 'contribution_amount', 'total_amount', 'Contribution Amount', NULL); return; case 'contribution_thankyou_date_is_not_null': if ($value) { $op = "IS NOT NULL"; $query->_qill[$grouping][] = ts('Contribution Thank-you Sent'); } else { $op = "IS NULL"; $query->_qill[$grouping][] = ts('Contribution Thank-you Not Sent'); } $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.thankyou_date", $op); $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; return; case 'contribution_receipt_date_is_not_null': if ($value) { $op = "IS NOT NULL"; $query->_qill[$grouping][] = ts('Contribution Receipt Sent'); } else { $op = "IS NULL"; $query->_qill[$grouping][] = ts('Contribution Receipt Not Sent'); } $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.receipt_date", $op); $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; return; case 'financial_type': case 'contribution_page': case 'payment_instrument': case 'contribution_payment_instrument': case 'contribution_status': $name .= '_id'; case 'financial_type_id': case 'payment_instrument_id': case 'contribution_payment_instrument_id': case 'contribution_page_id': case 'contribution_status_id': case 'contribution_id': case 'contribution_currency_type': case 'contribution_currency': case 'contribution_source': case 'contribution_trxn_id': case 'contribution_check_number': case 'contribution_contact_id': case strpos($name, '_amount') !== FALSE: case strpos($name, '_date') !== FALSE: $qillName = $name; $pseudoExtraParam = NULL; if (strpos($name, '_amount') !== FALSE || strpos($name, '_date') !== FALSE || in_array($name, array('contribution_id', 'contribution_currency', 'contribution_source', 'contribution_trxn_id', 'contribution_check_number', 'contribution_payment_instrument_id', 'contribution_contact_id'))) { $name = str_replace('contribution_', '', $name); if (!in_array($name, array('source', 'id', 'contact_id'))) { $qillName = str_replace('contribution_', '', $qillName); } } if (in_array($name, array('contribution_currency', 'contribution_currency_type'))) { $qillName = $name = 'currency'; $pseudoExtraParam = array('labelColumn' => 'name'); } $dataType = !empty($fields[$qillName]['type']) ? CRM_Utils_Type::typeToString($fields[$qillName]['type']) : 'String'; $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.{$name}", $op, $value, $dataType); list($op, $value) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Contribute_DAO_Contribution', $name, $value, $op, $pseudoExtraParam); $query->_qill[$grouping][] = ts('%1 %2 %3', array(1 => $fields[$qillName]['title'], 2 => $op, 3 => $value)); $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; return; case 'contribution_pcp_made_through_id': case 'contribution_soft_credit_type_id': $qillName = $name; if ($name == 'contribution_pcp_made_through_id') { $qillName = $name = 'pcp_id'; $fields[$name] = array('title' => ts('Personal Campaign Page'), 'type' => 2); } if ($name == 'contribution_soft_credit_type_id') { $qillName = str_replace('_id', '', $qillName); $fields[$qillName]['type'] = $fields[$qillName]['data_type']; $name = str_replace('contribution_', '', $name); } $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution_soft.{$name}", $op, $value, CRM_Utils_Type::typeToString($fields[$qillName]['type'])); list($op, $value) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Contribute_DAO_ContributionSoft', $name, $value, $op); $query->_qill[$grouping][] = ts('%1 %2 %3', array(1 => $fields[$qillName]['title'], 2 => $op, 3 => $value)); $query->_tables['civicrm_contribution_soft'] = $query->_whereTables['civicrm_contribution_soft'] = 1; return; case 'contribution_or_softcredits': if ($value == 'only_scredits') { $query->_where[$grouping][] = "contribution_search_scredit_combined.scredit_id IS NOT NULL"; $query->_qill[$grouping][] = ts('Contributions OR Soft Credits? - Soft Credits Only'); $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; $query->_tables['civicrm_contribution_soft'] = $query->_whereTables['civicrm_contribution_soft'] = 1; } elseif ($value == 'both_related') { $query->_where[$grouping][] = "contribution_search_scredit_combined.filter_id IS NOT NULL"; $query->_qill[$grouping][] = ts('Contributions OR Soft Credits? - Soft Credits with related Hard Credit'); $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; $query->_tables['civicrm_contribution_soft'] = $query->_whereTables['civicrm_contribution_soft'] = 1; } elseif ($value == 'both') { $query->_qill[$grouping][] = ts('Contributions OR Soft Credits? - Both'); $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; $query->_tables['civicrm_contribution_soft'] = $query->_whereTables['civicrm_contribution_soft'] = 1; } // default option: $value == 'only_contribs' return; case 'contribution_is_test': // By default is Contribution Search form we choose is_test = 0 in otherwords always show active contribution // so in case if any one choose any Yes/No avoid the default clause otherwise it will be conflict in whereClause $key = array_search('civicrm_contribution.is_test = 0', $query->_where[$grouping]); if (!empty($key)) { unset($query->_where[$grouping][$key]); } case 'contribution_test': // We dont want to include all tests for sql OR CRM-7827 if (!$value || $query->getOperator() != 'OR') { $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.is_test", $op, $value, "Boolean"); if ($value) { $query->_qill[$grouping][] = ts("Only Display Test Contributions"); } $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; } return; case 'contribution_is_pay_later': case 'contribution_pay_later': $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.is_pay_later", $op, $value, "Boolean"); if ($value) { $query->_qill[$grouping][] = ts("Find Pay Later Contributions"); } else { $query->_qill[$grouping][] = ts("Exclude Pay Later Contributions"); } $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; return; case 'contribution_recurring': if ($value) { $query->_where[$grouping][] = "civicrm_contribution.contribution_recur_id IS NOT NULL"; $query->_qill[$grouping][] = ts("Find Recurring Contributions"); $query->_tables['civicrm_contribution_recur'] = $query->_whereTables['civicrm_contribution_recur'] = 1; } else { $query->_where[$grouping][] = "civicrm_contribution.contribution_recur_id IS NULL"; $query->_qill[$grouping][] = ts("Exclude Recurring Contributions"); } return; case 'contribution_recur_id': $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_contribution.contribution_recur_id", $op, $value, "Integer"); $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; return; case 'contribution_note': $value = $strtolower(CRM_Core_DAO::escapeString($value)); if ($wildcard) { $value = "%{$value}%"; $op = 'LIKE'; } $wc = $op != 'LIKE' ? "LOWER(civicrm_note.note)" : "civicrm_note.note"; $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($wc, $op, $value, "String"); $query->_qill[$grouping][] = ts('Contribution Note %1 %2', array(1 => $op, 2 => $quoteValue)); $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = $query->_whereTables['contribution_note'] = 1; return; case 'contribution_membership_id': $query->_where[$grouping][] = " civicrm_membership.id {$op} {$value}"; $query->_tables['contribution_membership'] = $query->_whereTables['contribution_membership'] = 1; return; case 'contribution_participant_id': $query->_where[$grouping][] = " civicrm_participant.id {$op} {$value}"; $query->_tables['contribution_participant'] = $query->_whereTables['contribution_participant'] = 1; return; case 'contribution_pcp_display_in_roll': $query->_where[$grouping][] = " civicrm_contribution_soft.pcp_display_in_roll {$op} '{$value}'"; if ($value) { $query->_qill[$grouping][] = ts("Personal Campaign Page Honor Roll"); } else { $query->_qill[$grouping][] = ts("NOT Personal Campaign Page Honor Roll"); } $query->_tables['civicrm_contribution_soft'] = $query->_whereTables['civicrm_contribution_soft'] = 1; return; case 'contribution_campaign_id': $campParams = array('op' => $op, 'campaign' => $value, 'grouping' => $grouping, 'tableName' => 'civicrm_contribution'); CRM_Campaign_BAO_Query::componentSearchClause($campParams, $query); return; case 'contribution_batch_id': $batches = CRM_Contribute_PseudoConstant::batch(); $query->_where[$grouping][] = " civicrm_entity_batch.batch_id {$op} {$value}"; $query->_qill[$grouping][] = ts('Batch Name %1 %2', array(1 => $op, 2 => $batches[$value])); $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; $query->_tables['contribution_batch'] = $query->_whereTables['contribution_batch'] = 1; return; default: //all other elements are handle in this case $fldName = substr($name, 13); if (!isset($fields[$fldName])) { // CRM-12597 CRM_Core_Session::setStatus(ts('We did not recognize the search field: %1. Please check and fix your contribution related smart groups.', array(1 => $fldName))); return; } $whereTable = $fields[$fldName]; $value = trim($value); $dataType = "String"; if (!empty($whereTable['type'])) { $dataType = CRM_Utils_Type::typeToString($whereTable['type']); } $wc = $op != 'LIKE' && $dataType != 'Date' ? "LOWER({$whereTable['where']})" : "{$whereTable['where']}"; $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($wc, $op, $value, $dataType); $query->_qill[$grouping][] = "{$whereTable['title']} {$op} {$quoteValue}"; list($tableName, $fieldName) = explode('.', $whereTable['where'], 2); $query->_tables[$tableName] = $query->_whereTables[$tableName] = 1; if ($tableName == 'civicrm_contribution_product') { $query->_tables['civicrm_product'] = $query->_whereTables['civicrm_product'] = 1; $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; } else { $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; } } }
/** * Retrieve financial items assigned for a batch. * * @param int $entityID * @param array $returnValues * @param bool $notPresent * @param array $params * @param bool $getCount * * @return CRM_Core_DAO */ public static function getBatchFinancialItems($entityID, $returnValues, $notPresent = NULL, $params = NULL, $getCount = FALSE) { if (!$getCount) { if (!empty($params['rowCount']) && $params['rowCount'] > 0) { $limit = " LIMIT {$params['offset']}, {$params['rowCount']} "; } } // action is taken depending upon the mode $select = 'civicrm_financial_trxn.id '; if (!empty($returnValues)) { $select .= " , " . implode(' , ', $returnValues); } $orderBy = " ORDER BY civicrm_financial_trxn.id"; if (!empty($params['sort'])) { $orderBy = ' ORDER BY ' . CRM_Utils_Type::escape($params['sort'], 'String'); } $from = "civicrm_financial_trxn\nLEFT JOIN civicrm_entity_financial_trxn ON civicrm_entity_financial_trxn.financial_trxn_id = civicrm_financial_trxn.id\nLEFT JOIN civicrm_entity_batch ON civicrm_entity_batch.entity_table = 'civicrm_financial_trxn'\nAND civicrm_entity_batch.entity_id = civicrm_financial_trxn.id\nLEFT JOIN civicrm_contribution ON civicrm_contribution.id = civicrm_entity_financial_trxn.entity_id\nLEFT JOIN civicrm_financial_type ON civicrm_financial_type.id = civicrm_contribution.financial_type_id\nLEFT JOIN civicrm_contact contact_a ON contact_a.id = civicrm_contribution.contact_id\nLEFT JOIN civicrm_contribution_soft ON civicrm_contribution_soft.contribution_id = civicrm_contribution.id\n"; $searchFields = array('sort_name', 'financial_type_id', 'contribution_page_id', 'payment_instrument_id', 'contribution_trxn_id', 'contribution_source', 'contribution_currency_type', 'contribution_pay_later', 'contribution_recurring', 'contribution_test', 'contribution_thankyou_date_is_not_null', 'contribution_receipt_date_is_not_null', 'contribution_pcp_made_through_id', 'contribution_pcp_display_in_roll', 'contribution_date_relative', 'contribution_amount_low', 'contribution_amount_high', 'contribution_in_honor_of', 'contact_tags', 'group', 'contribution_date_relative', 'contribution_date_high', 'contribution_date_low', 'contribution_check_number', 'contribution_status_id'); $values = array(); foreach ($searchFields as $field) { if (isset($params[$field])) { $values[$field] = $params[$field]; if ($field == 'sort_name') { $from .= " LEFT JOIN civicrm_contact contact_b ON contact_b.id = civicrm_contribution.contact_id\n LEFT JOIN civicrm_email ON contact_b.id = civicrm_email.contact_id"; } if ($field == 'contribution_in_honor_of') { $from .= " LEFT JOIN civicrm_contact contact_b ON contact_b.id = civicrm_contribution.contact_id"; } if ($field == 'contact_tags') { $from .= " LEFT JOIN civicrm_entity_tag `civicrm_entity_tag-{$params[$field]}` ON `civicrm_entity_tag-{$params[$field]}`.entity_id = contact_a.id"; } if ($field == 'group') { $from .= " LEFT JOIN civicrm_group_contact `civicrm_group_contact-{$params[$field]}` ON contact_a.id = `civicrm_group_contact-{$params[$field]}`.contact_id "; } if ($field == 'contribution_date_relative') { $relativeDate = explode('.', $params[$field]); $date = CRM_Utils_Date::relativeToAbsolute($relativeDate[0], $relativeDate[1]); $values['contribution_date_low'] = $date['from']; $values['contribution_date_high'] = $date['to']; } $searchParams = CRM_Contact_BAO_Query::convertFormValues($values); $query = new CRM_Contact_BAO_Query($searchParams, CRM_Contribute_BAO_Query::defaultReturnProperties(CRM_Contact_BAO_Query::MODE_CONTRIBUTE, FALSE), NULL, FALSE, FALSE, CRM_Contact_BAO_Query::MODE_CONTRIBUTE); if ($field == 'contribution_date_high' || $field == 'contribution_date_low') { $query->dateQueryBuilder($params[$field], 'civicrm_contribution', 'contribution_date', 'receive_date', 'Contribution Date'); } } } if (!empty($query->_where[0])) { $where = implode(' AND ', $query->_where[0]) . " AND civicrm_entity_batch.batch_id IS NULL\n AND civicrm_entity_financial_trxn.entity_table = 'civicrm_contribution'"; $where = str_replace('civicrm_contribution.payment_instrument_id', 'civicrm_financial_trxn.payment_instrument_id', $where); $searchValue = TRUE; } else { $searchValue = FALSE; } if (!$searchValue) { if (!$notPresent) { $where = " ( civicrm_entity_batch.batch_id = {$entityID}\n AND civicrm_entity_batch.entity_table = 'civicrm_financial_trxn'\n AND civicrm_entity_financial_trxn.entity_table = 'civicrm_contribution') "; } else { $where = " ( civicrm_entity_batch.batch_id IS NULL\n AND civicrm_entity_financial_trxn.entity_table = 'civicrm_contribution')"; } } $sql = "\nSELECT {$select}\nFROM {$from}\nWHERE {$where}\n {$orderBy}\n"; if (isset($limit)) { $sql .= "{$limit}"; } $result = CRM_Core_DAO::executeQuery($sql); return $result; }
/** * 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. * * @param * * @return void * @access public */ function postProcess() { if ($this->_done) { return; } $this->_done = true; $this->_formValues = $this->controller->exportValues($this->_name); $this->fixFormValues(); if (isset($this->_ssID) && empty($_POST)) { // if we are editing / running a saved search and the form has not been posted $this->_formValues = CRM_Contact_BAO_SavedSearch::getFormValues($this->_ssID); } require_once 'CRM/Contact/BAO/Query.php'; $this->_queryParams =& CRM_Contact_BAO_Query::convertFormValues($this->_formValues); $this->set('formValues', $this->_formValues); $this->set('queryParams', $this->_queryParams); $buttonName = $this->controller->getButtonName(); if ($buttonName == $this->_actionButtonName || $buttonName == $this->_printButtonName) { // 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)); } require_once 'CRM/Contact/BAO/Query.php'; $selector =& new CRM_Grant_Selector_Search($this->_queryParams, $this->_action, null, $this->_single, $this->_limit, $this->_context); $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(); }