First commit
This commit is contained in:
commit
c6e2478c40
13918 changed files with 2303184 additions and 0 deletions
446
sites/all/modules/civicrm/CRM/Contact/Form/Search/Advanced.php
Normal file
446
sites/all/modules/civicrm/CRM/Contact/Form/Search/Advanced.php
Normal file
|
@ -0,0 +1,446 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
|
||||
/**
|
||||
* Advanced search, extends basic search.
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Advanced extends CRM_Contact_Form_Search {
|
||||
|
||||
/**
|
||||
* Processing needed for buildForm and later.
|
||||
*/
|
||||
public function preProcess() {
|
||||
$this->set('searchFormName', 'Advanced');
|
||||
|
||||
parent::preProcess();
|
||||
$openedPanes = CRM_Contact_BAO_Query::$_openedPanes;
|
||||
$openedPanes = array_merge($openedPanes, $this->_openedPanes);
|
||||
$this->assign('openedPanes', $openedPanes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the form object.
|
||||
*/
|
||||
public function buildQuickForm() {
|
||||
$this->set('context', 'advanced');
|
||||
|
||||
$this->_searchPane = CRM_Utils_Array::value('searchPane', $_GET);
|
||||
|
||||
$this->_searchOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
|
||||
'advanced_search_options'
|
||||
);
|
||||
|
||||
if (!$this->_searchPane || $this->_searchPane == 'basic') {
|
||||
CRM_Contact_Form_Search_Criteria::basic($this);
|
||||
}
|
||||
|
||||
$allPanes = array();
|
||||
$paneNames = array(
|
||||
ts('Address Fields') => 'location',
|
||||
ts('Custom Fields') => 'custom',
|
||||
ts('Activities') => 'activity',
|
||||
ts('Relationships') => 'relationship',
|
||||
ts('Demographics') => 'demographics',
|
||||
ts('Notes') => 'notes',
|
||||
ts('Change Log') => 'changeLog',
|
||||
);
|
||||
|
||||
//check if there are any custom data searchable fields
|
||||
$extends = array_merge(array('Contact', 'Individual', 'Household', 'Organization'),
|
||||
CRM_Contact_BAO_ContactType::subTypes()
|
||||
);
|
||||
$groupDetails = CRM_Core_BAO_CustomGroup::getGroupDetail(NULL, TRUE,
|
||||
$extends
|
||||
);
|
||||
// if no searchable fields unset panel
|
||||
if (empty($groupDetails)) {
|
||||
unset($paneNames[ts('Custom Fields')]);
|
||||
}
|
||||
|
||||
foreach ($paneNames as $name => $type) {
|
||||
if (!$this->_searchOptions[$type]) {
|
||||
unset($paneNames[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$components = CRM_Core_Component::getEnabledComponents();
|
||||
|
||||
$componentPanes = array();
|
||||
foreach ($components as $name => $component) {
|
||||
if (in_array($name, array_keys($this->_searchOptions)) &&
|
||||
$this->_searchOptions[$name] &&
|
||||
CRM_Core_Permission::access($component->name)
|
||||
) {
|
||||
$componentPanes[$name] = $component->registerAdvancedSearchPane();
|
||||
$componentPanes[$name]['name'] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
usort($componentPanes, array('CRM_Utils_Sort', 'cmpFunc'));
|
||||
foreach ($componentPanes as $name => $pane) {
|
||||
// FIXME: we should change the use of $name here to keyword
|
||||
$paneNames[$pane['title']] = $pane['name'];
|
||||
}
|
||||
|
||||
$hookPanes = array();
|
||||
CRM_Contact_BAO_Query_Hook::singleton()->registerAdvancedSearchPane($hookPanes);
|
||||
$paneNames = array_merge($paneNames, $hookPanes);
|
||||
|
||||
$this->_paneTemplatePath = array();
|
||||
foreach ($paneNames as $name => $type) {
|
||||
if (!array_key_exists($type, $this->_searchOptions) && !in_array($type, $hookPanes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$allPanes[$name] = array(
|
||||
'url' => CRM_Utils_System::url('civicrm/contact/search/advanced',
|
||||
"snippet=1&searchPane=$type&qfKey={$this->controller->_key}"
|
||||
),
|
||||
'open' => 'false',
|
||||
'id' => $type,
|
||||
);
|
||||
|
||||
// see if we need to include this paneName in the current form
|
||||
if ($this->_searchPane == $type || !empty($_POST["hidden_{$type}"]) ||
|
||||
CRM_Utils_Array::value("hidden_{$type}", $this->_formValues)
|
||||
) {
|
||||
$allPanes[$name]['open'] = 'true';
|
||||
|
||||
if (!empty($components[$type])) {
|
||||
$c = $components[$type];
|
||||
$this->add('hidden', "hidden_$type", 1);
|
||||
$c->buildAdvancedSearchPaneForm($this);
|
||||
$this->_paneTemplatePath[$type] = $c->getAdvancedSearchPaneTemplatePath();
|
||||
}
|
||||
elseif (in_array($type, $hookPanes)) {
|
||||
CRM_Contact_BAO_Query_Hook::singleton()->buildAdvancedSearchPaneForm($this, $type);
|
||||
CRM_Contact_BAO_Query_Hook::singleton()->setAdvancedSearchPaneTemplatePath($this->_paneTemplatePath, $type);
|
||||
}
|
||||
else {
|
||||
CRM_Contact_Form_Search_Criteria::$type($this);
|
||||
$template = ucfirst($type);
|
||||
$this->_paneTemplatePath[$type] = "CRM/Contact/Form/Search/Criteria/{$template}.tpl";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assign('allPanes', $allPanes);
|
||||
if (!$this->_searchPane) {
|
||||
parent::buildQuickForm();
|
||||
}
|
||||
else {
|
||||
$this->assign('suppressForm', TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the form name to create the tpl file name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTemplateFileName() {
|
||||
if (!$this->_searchPane) {
|
||||
return parent::getTemplateFileName();
|
||||
}
|
||||
else {
|
||||
if (isset($this->_paneTemplatePath[$this->_searchPane])) {
|
||||
return $this->_paneTemplatePath[$this->_searchPane];
|
||||
}
|
||||
else {
|
||||
$name = ucfirst($this->_searchPane);
|
||||
return "CRM/Contact/Form/Search/Criteria/{$name}.tpl";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default form values.
|
||||
*
|
||||
*
|
||||
* @return array
|
||||
* the default array reference
|
||||
*/
|
||||
public function setDefaultValues() {
|
||||
// Set ssID for unit tests.
|
||||
if (empty($this->_ssID)) {
|
||||
$this->_ssID = $this->get('ssID');
|
||||
}
|
||||
|
||||
$defaults = array_merge($this->_formValues, array(
|
||||
'privacy_toggle' => 1,
|
||||
'operator' => 'AND',
|
||||
));
|
||||
$this->normalizeDefaultValues($defaults);
|
||||
|
||||
if ($this->_context === 'amtg') {
|
||||
$defaults['task'] = CRM_Contact_Task::GROUP_CONTACTS;
|
||||
}
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 processing.
|
||||
* - 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 submitting is
|
||||
* done.
|
||||
* The processing consists of using a Selector / Controller framework for getting the
|
||||
* search results.
|
||||
*/
|
||||
public function postProcess() {
|
||||
$this->set('isAdvanced', '1');
|
||||
|
||||
// get user submitted values
|
||||
// get it from controller only if form has been submitted, else preProcess has set this
|
||||
if (!empty($_POST)) {
|
||||
$this->_formValues = $this->controller->exportValues($this->_name);
|
||||
$this->normalizeFormValues();
|
||||
// FIXME: couldn't figure out a good place to do this,
|
||||
// FIXME: so leaving this as a dependency for now
|
||||
if (array_key_exists('contribution_amount_low', $this->_formValues)) {
|
||||
foreach (array(
|
||||
'contribution_amount_low',
|
||||
'contribution_amount_high',
|
||||
) as $f) {
|
||||
$this->_formValues[$f] = CRM_Utils_Rule::cleanMoney($this->_formValues[$f]);
|
||||
}
|
||||
}
|
||||
|
||||
// set the group if group is submitted
|
||||
if (!empty($this->_formValues['uf_group_id'])) {
|
||||
$this->set('id', $this->_formValues['uf_group_id']);
|
||||
}
|
||||
else {
|
||||
$this->set('id', '');
|
||||
}
|
||||
}
|
||||
|
||||
// retrieve ssID values only if formValues is null, i.e. form has never been posted
|
||||
if (empty($this->_formValues) && isset($this->_ssID)) {
|
||||
$this->_formValues = CRM_Contact_BAO_SavedSearch::getFormValues($this->_ssID);
|
||||
}
|
||||
|
||||
if (isset($this->_groupID) && empty($this->_formValues['group'])) {
|
||||
$this->_formValues['group'] = array($this->_groupID => 1);
|
||||
}
|
||||
|
||||
//search for civicase
|
||||
if (is_array($this->_formValues)) {
|
||||
$allCases = FALSE;
|
||||
if (array_key_exists('case_owner', $this->_formValues) &&
|
||||
!$this->_formValues['case_owner'] &&
|
||||
!$this->_force
|
||||
) {
|
||||
foreach (array(
|
||||
'case_type_id',
|
||||
'case_status_id',
|
||||
'case_deleted',
|
||||
'case_tags',
|
||||
) as $caseCriteria) {
|
||||
if (!empty($this->_formValues[$caseCriteria])) {
|
||||
$allCases = TRUE;
|
||||
$this->_formValues['case_owner'] = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ($allCases) {
|
||||
if (CRM_Core_Permission::check('access all cases and activities')) {
|
||||
$this->_formValues['case_owner'] = 1;
|
||||
}
|
||||
else {
|
||||
$this->_formValues['case_owner'] = 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->_formValues['case_owner'] = 0;
|
||||
}
|
||||
}
|
||||
if (array_key_exists('case_owner', $this->_formValues) && empty($this->_formValues['case_deleted'])) {
|
||||
$this->_formValues['case_deleted'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// we dont want to store the sortByCharacter in the formValue, it is more like
|
||||
// a filter on the result set
|
||||
// this filter is reset if we click on the search button
|
||||
if ($this->_sortByCharacter !== NULL && empty($_POST)) {
|
||||
if (strtolower($this->_sortByCharacter) == 'all') {
|
||||
$this->_formValues['sortByCharacter'] = NULL;
|
||||
}
|
||||
else {
|
||||
$this->_formValues['sortByCharacter'] = $this->_sortByCharacter;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->_sortByCharacter = NULL;
|
||||
}
|
||||
|
||||
CRM_Core_BAO_CustomValue::fixCustomFieldValue($this->_formValues);
|
||||
|
||||
$this->_params = CRM_Contact_BAO_Query::convertFormValues($this->_formValues, 0, FALSE, NULL, $this->entityReferenceFields);
|
||||
$this->_returnProperties = &$this->returnProperties();
|
||||
parent::postProcess();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the form values to make it look similar to the advanced form values.
|
||||
*
|
||||
* This prevents a ton of work downstream and allows us to use the same code for
|
||||
* multiple purposes (queries, save/edit etc)
|
||||
*/
|
||||
public function normalizeFormValues() {
|
||||
$contactType = CRM_Utils_Array::value('contact_type', $this->_formValues);
|
||||
|
||||
if ($contactType && is_array($contactType)) {
|
||||
unset($this->_formValues['contact_type']);
|
||||
foreach ($contactType as $key => $value) {
|
||||
$this->_formValues['contact_type'][$value] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$config = CRM_Core_Config::singleton();
|
||||
$specialParams = array(
|
||||
'financial_type_id',
|
||||
'contribution_soft_credit_type_id',
|
||||
'contribution_status',
|
||||
'contribution_status_id',
|
||||
'contribution_source',
|
||||
'membership_status_id',
|
||||
'participant_status_id',
|
||||
'contribution_trxn_id',
|
||||
'activity_type_id',
|
||||
'status_id',
|
||||
'priority_id',
|
||||
'activity_subject',
|
||||
'activity_details',
|
||||
'contribution_page_id',
|
||||
'contribution_product_id',
|
||||
'payment_instrument_id',
|
||||
'group',
|
||||
'contact_tags',
|
||||
'preferred_communication_method',
|
||||
);
|
||||
$changeNames = array(
|
||||
'status_id' => 'activity_status_id',
|
||||
'priority_id' => 'activity_priority_id',
|
||||
);
|
||||
CRM_Contact_BAO_Query::processSpecialFormValue($this->_formValues, $specialParams, $changeNames);
|
||||
|
||||
$taglist = CRM_Utils_Array::value('contact_taglist', $this->_formValues);
|
||||
|
||||
if ($taglist && is_array($taglist)) {
|
||||
unset($this->_formValues['contact_taglist']);
|
||||
foreach ($taglist as $value) {
|
||||
if ($value) {
|
||||
$value = explode(',', $value);
|
||||
foreach ($value as $tId) {
|
||||
if (is_numeric($tId)) {
|
||||
$this->_formValues['contact_tags'][] = $tId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize default values for multiselect plugins.
|
||||
*
|
||||
* @param array $defaults
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function normalizeDefaultValues(&$defaults) {
|
||||
if (!is_array($defaults)) {
|
||||
$defaults = array();
|
||||
}
|
||||
$this->loadDefaultCountryBasedOnState($defaults);
|
||||
if ($this->_ssID && empty($_POST)) {
|
||||
$defaults = array_merge($defaults, CRM_Contact_BAO_SavedSearch::getFormValues($this->_ssID));
|
||||
}
|
||||
|
||||
/*
|
||||
* CRM-18656 - reverse the normalisation of 'contact_taglist' done in
|
||||
* self::normalizeFormValues(). Remove tagset tags from the default
|
||||
* 'contact_tags' and put them in 'contact_taglist[N]' where N is the
|
||||
* id of the tagset.
|
||||
*/
|
||||
if (isset($defaults['contact_tags'])) {
|
||||
foreach ($defaults['contact_tags'] as $key => $tagId) {
|
||||
if (!is_array($tagId)) {
|
||||
$parentId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $tagId, 'parent_id');
|
||||
$element = "contact_taglist[$parentId]";
|
||||
if ($this->elementExists($element)) {
|
||||
// This tag is a tagset
|
||||
unset($defaults['contact_tags'][$key]);
|
||||
if (!isset($defaults[$element])) {
|
||||
$defaults[$element] = array();
|
||||
}
|
||||
$defaults[$element][] = $tagId;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($defaults['contact_tags'])) {
|
||||
unset($defaults['contact_tags']);
|
||||
}
|
||||
}
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default country for the form.
|
||||
*
|
||||
* For performance reasons country might be removed from the form CRM-18125
|
||||
* but we need to include it in our defaults or the state will not be visible.
|
||||
*
|
||||
* @param array $defaults
|
||||
*/
|
||||
public function loadDefaultCountryBasedOnState(&$defaults) {
|
||||
if (!empty($defaults['state_province'])) {
|
||||
$defaults['country'] = CRM_Core_DAO::singleValueQuery(
|
||||
"SELECT country_id FROM civicrm_state_province
|
||||
WHERE id = %1",
|
||||
array(1 => array($defaults['state_province'][0], 'Integer'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
242
sites/all/modules/civicrm/CRM/Contact/Form/Search/Basic.php
Normal file
242
sites/all/modules/civicrm/CRM/Contact/Form/Search/Basic.php
Normal file
|
@ -0,0 +1,242 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base Search / View form for *all* listing of multiple contacts.
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Basic extends CRM_Contact_Form_Search {
|
||||
|
||||
/**
|
||||
* csv - common search values
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $csv = array('contact_type', 'group', 'tag');
|
||||
|
||||
/**
|
||||
* Build the form object.
|
||||
*/
|
||||
public function buildQuickForm() {
|
||||
$this->addSortNameField();
|
||||
|
||||
$searchOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
|
||||
'advanced_search_options'
|
||||
);
|
||||
|
||||
if (!empty($searchOptions['contactType'])) {
|
||||
$contactTypes = array('' => ts('- any contact type -')) + CRM_Contact_BAO_ContactType::getSelectElements();
|
||||
$this->add('select', 'contact_type',
|
||||
ts('is...'),
|
||||
$contactTypes,
|
||||
FALSE,
|
||||
array('class' => 'crm-select2')
|
||||
);
|
||||
}
|
||||
|
||||
// add select for groups
|
||||
// Get hierarchical listing of groups, respecting ACLs for CRM-16836.
|
||||
$groupHierarchy = CRM_Contact_BAO_Group::getGroupsHierarchy($this->_group, NULL, ' ', TRUE);
|
||||
if (!empty($searchOptions['groups'])) {
|
||||
$this->addField('group', array(
|
||||
'entity' => 'group_contact',
|
||||
'label' => ts('in'),
|
||||
'placeholder' => ts('- any group -'),
|
||||
'options' => $groupHierarchy,
|
||||
));
|
||||
}
|
||||
|
||||
if (!empty($searchOptions['tags'])) {
|
||||
// tag criteria
|
||||
if (!empty($this->_tag)) {
|
||||
$this->addField('tag', array(
|
||||
'entity' => 'entity_tag',
|
||||
'label' => ts('with'),
|
||||
'placeholder' => ts('- any tag -'),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
parent::buildQuickForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default form values.
|
||||
*
|
||||
*
|
||||
* @return array
|
||||
* the default array reference
|
||||
*/
|
||||
public function setDefaultValues() {
|
||||
$defaults = array();
|
||||
|
||||
$defaults['sort_name'] = CRM_Utils_Array::value('sort_name', $this->_formValues);
|
||||
foreach (self::$csv as $v) {
|
||||
if (!empty($this->_formValues[$v]) && is_array($this->_formValues[$v])) {
|
||||
$tmpArray = array_keys($this->_formValues[$v]);
|
||||
$defaults[$v] = array_pop($tmpArray);
|
||||
}
|
||||
else {
|
||||
$defaults[$v] = '';
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_context === 'amtg') {
|
||||
$defaults['task'] = CRM_Contact_Task::GROUP_CONTACTS;
|
||||
}
|
||||
|
||||
if ($this->_context === 'smog') {
|
||||
$defaults['group_contact_status[Added]'] = TRUE;
|
||||
}
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add local and global form rules.
|
||||
*/
|
||||
public function addRules() {
|
||||
$this->addFormRule(array('CRM_Contact_Form_Search_Basic', 'formRule'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Processing needed for buildForm and later.
|
||||
*/
|
||||
public function preProcess() {
|
||||
$this->set('searchFormName', 'Basic');
|
||||
|
||||
parent::preProcess();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function &getFormValues() {
|
||||
return $this->_formValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called for processing a submitted search form.
|
||||
*/
|
||||
public function postProcess() {
|
||||
$this->set('isAdvanced', '0');
|
||||
$this->set('isSearchBuilder', '0');
|
||||
|
||||
// get user submitted values
|
||||
// get it from controller only if form has been submitted, else preProcess has set this
|
||||
if (!empty($_POST)) {
|
||||
$this->_formValues = $this->controller->exportValues($this->_name);
|
||||
}
|
||||
|
||||
if (isset($this->_groupID) && empty($this->_formValues['group'])) {
|
||||
$this->_formValues['group'] = $this->_groupID;
|
||||
}
|
||||
elseif (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);
|
||||
|
||||
//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);
|
||||
}
|
||||
}
|
||||
|
||||
// we dont want to store the sortByCharacter in the formValue, it is more like
|
||||
// a filter on the result set
|
||||
// this filter is reset if we click on the search button
|
||||
if ($this->_sortByCharacter !== NULL && empty($_POST)) {
|
||||
if (strtolower($this->_sortByCharacter) == 'all') {
|
||||
$this->_formValues['sortByCharacter'] = NULL;
|
||||
}
|
||||
else {
|
||||
$this->_formValues['sortByCharacter'] = $this->_sortByCharacter;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->_sortByCharacter = NULL;
|
||||
}
|
||||
|
||||
$this->_params = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);
|
||||
$this->_returnProperties = &$this->returnProperties();
|
||||
|
||||
parent::postProcess();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a form rule for this form.
|
||||
*
|
||||
* If Go is pressed then we must select some checkboxes and an action.
|
||||
*
|
||||
* @param array $fields
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public static function formRule($fields) {
|
||||
// check actionName and if next, then do not repeat a search, since we are going to the next page
|
||||
if (array_key_exists('_qf_Search_next', $fields)) {
|
||||
if (empty($fields['task'])) {
|
||||
return array('task' => 'Please select a valid action.');
|
||||
}
|
||||
|
||||
if (CRM_Utils_Array::value('task', $fields) == CRM_Contact_Task::SAVE_SEARCH) {
|
||||
// dont need to check for selection of contacts for saving search
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// if the all contact option is selected, ignore the contact checkbox validation
|
||||
if ($fields['radio_ts'] == 'ts_all') {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
foreach ($fields as $name => $dontCare) {
|
||||
if (substr($name, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return array('task' => 'Please select one or more checkboxes to perform the action on.');
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a descriptive name for the page, used in wizard header
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle() {
|
||||
return ts('Find Contacts');
|
||||
}
|
||||
|
||||
}
|
524
sites/all/modules/civicrm/CRM/Contact/Form/Search/Builder.php
Normal file
524
sites/all/modules/civicrm/CRM/Contact/Form/Search/Builder.php
Normal file
|
@ -0,0 +1,524 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class is for search builder processing.
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Builder extends CRM_Contact_Form_Search {
|
||||
|
||||
/**
|
||||
* Number of columns in where.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $_columnCount;
|
||||
|
||||
/**
|
||||
* Number of blocks to be shown.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $_blockCount;
|
||||
|
||||
/**
|
||||
* Build the form object.
|
||||
*/
|
||||
public function preProcess() {
|
||||
$this->set('searchFormName', 'Builder');
|
||||
|
||||
$this->set('context', 'builder');
|
||||
parent::preProcess();
|
||||
|
||||
// Get the block count
|
||||
$this->_blockCount = $this->get('blockCount');
|
||||
// Initialize new form
|
||||
if (!$this->_blockCount) {
|
||||
$this->_blockCount = 4;
|
||||
$this->set('newBlock', 1);
|
||||
}
|
||||
|
||||
//get the column count
|
||||
$this->_columnCount = $this->get('columnCount');
|
||||
|
||||
for ($i = 1; $i < $this->_blockCount; $i++) {
|
||||
if (empty($this->_columnCount[$i])) {
|
||||
$this->_columnCount[$i] = 5;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_loadedMappingId = $this->get('savedMapping');
|
||||
|
||||
if ($this->get('showSearchForm')) {
|
||||
$this->assign('showSearchForm', TRUE);
|
||||
}
|
||||
else {
|
||||
$this->assign('showSearchForm', FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build quick form.
|
||||
*/
|
||||
public function buildQuickForm() {
|
||||
$fields = self::fields();
|
||||
// Get fields of type date
|
||||
// FIXME: This is a hack until our fields contain this meta-data
|
||||
$dateFields = array();
|
||||
$stringFields = array();
|
||||
$searchByLabelFields = array();
|
||||
foreach ($fields as $name => $field) {
|
||||
if (strpos($name, '_date') || CRM_Utils_Array::value('data_type', $field) == 'Date') {
|
||||
$dateFields[] = $name;
|
||||
}
|
||||
// it's necessary to know which of the fields are from string data type
|
||||
if (isset($field['type']) && $field['type'] === CRM_Utils_Type::T_STRING) {
|
||||
$stringFields[] = $name;
|
||||
}
|
||||
// it's necessary to know which of the fields are searchable by label
|
||||
if (isset($field['searchByLabel']) && $field['searchByLabel']) {
|
||||
$searchByLabelFields[] = $name;
|
||||
}
|
||||
}
|
||||
// Add javascript
|
||||
CRM_Core_Resources::singleton()
|
||||
->addScriptFile('civicrm', 'templates/CRM/Contact/Form/Search/Builder.js', 1, 'html-header')
|
||||
->addSetting(array(
|
||||
'searchBuilder' => array(
|
||||
// Index of newly added/expanded block (1-based index)
|
||||
'newBlock' => $this->get('newBlock'),
|
||||
'dateFields' => $dateFields,
|
||||
'fieldOptions' => self::fieldOptions(),
|
||||
'stringFields' => $stringFields,
|
||||
'searchByLabelFields' => $searchByLabelFields,
|
||||
'generalOperators' => array('' => ts('-operator-')) + CRM_Core_SelectValues::getSearchBuilderOperators(),
|
||||
'stringOperators' => array('' => ts('-operator-')) + CRM_Core_SelectValues::getSearchBuilderOperators(CRM_Utils_Type::T_STRING),
|
||||
),
|
||||
));
|
||||
//get the saved search mapping id
|
||||
$mappingId = NULL;
|
||||
if ($this->_ssID) {
|
||||
$mappingId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $this->_ssID, 'mapping_id');
|
||||
}
|
||||
|
||||
CRM_Core_BAO_Mapping::buildMappingForm($this, 'Search Builder', $mappingId, $this->_columnCount, $this->_blockCount);
|
||||
|
||||
parent::buildQuickForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add local and global form rules.
|
||||
*/
|
||||
public function addRules() {
|
||||
$this->addFormRule(array('CRM_Contact_Form_Search_Builder', 'formRule'), $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Global validation rules for the form.
|
||||
*
|
||||
* @param array $values
|
||||
* @param array $files
|
||||
* @param CRM_Core_Form $self
|
||||
*
|
||||
* @return array
|
||||
* list of errors to be posted back to the form
|
||||
*/
|
||||
public static function formRule($values, $files, $self) {
|
||||
if (!empty($values['addMore']) || !empty($values['addBlock'])) {
|
||||
return TRUE;
|
||||
}
|
||||
$fields = self::fields();
|
||||
$fld = CRM_Core_BAO_Mapping::formattedFields($values, TRUE);
|
||||
|
||||
$errorMsg = array();
|
||||
foreach ($fld as $k => $v) {
|
||||
if (!$v[1]) {
|
||||
$errorMsg["operator[$v[3]][$v[4]]"] = ts("Please enter the operator.");
|
||||
}
|
||||
else {
|
||||
// CRM-10338
|
||||
$v[2] = self::checkArrayKeyEmpty($v[2]);
|
||||
|
||||
if (in_array($v[1], array(
|
||||
'IS NULL',
|
||||
'IS NOT NULL',
|
||||
'IS EMPTY',
|
||||
'IS NOT EMPTY',
|
||||
)) &&
|
||||
!empty($v[2])
|
||||
) {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts('Please clear your value if you want to use %1 operator.', array(1 => $v[1]));
|
||||
}
|
||||
elseif (substr($v[0], 0, 7) === 'do_not_' or substr($v[0], 0, 3) === 'is_') {
|
||||
if (isset($v[2])) {
|
||||
$v2 = array($v[2]);
|
||||
if (!isset($v[2])) {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter a value.");
|
||||
}
|
||||
|
||||
$error = CRM_Utils_Type::validate($v2[0], 'Integer', FALSE);
|
||||
if ($error != $v2[0]) {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter a valid value.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter a value.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (substr($v[0], 0, 7) == 'custom_') {
|
||||
// Get rid of appended location type id
|
||||
list($fieldKey) = explode('-', $v[0]);
|
||||
$type = $fields[$fieldKey]['data_type'];
|
||||
|
||||
// hack to handle custom data of type state and country
|
||||
if (in_array($type, array(
|
||||
'Country',
|
||||
'StateProvince',
|
||||
))) {
|
||||
$type = "Integer";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$fldName = $v[0];
|
||||
// FIXME: no idea at this point what to do with this,
|
||||
// FIXME: but definitely needs fixing.
|
||||
if (substr($v[0], 0, 13) == 'contribution_') {
|
||||
$fldName = substr($v[0], 13);
|
||||
}
|
||||
|
||||
$fldValue = CRM_Utils_Array::value($fldName, $fields);
|
||||
$fldType = CRM_Utils_Array::value('type', $fldValue);
|
||||
$type = CRM_Utils_Type::typeToString($fldType);
|
||||
|
||||
if (strstr($v[1], 'IN')) {
|
||||
if (empty($v[2])) {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter a value.");
|
||||
}
|
||||
}
|
||||
// Check Empty values for Integer Or Boolean Or Date type For operators other than IS NULL and IS NOT NULL.
|
||||
elseif (!in_array($v[1],
|
||||
array('IS NULL', 'IS NOT NULL', 'IS EMPTY', 'IS NOT EMPTY'))
|
||||
) {
|
||||
if ((($type == 'Int' || $type == 'Boolean') && !is_array($v[2]) && !trim($v[2])) && $v[2] != '0') {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter a value.");
|
||||
}
|
||||
elseif ($type == 'Date' && !trim($v[2])) {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter a value.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($type && empty($errorMsg)) {
|
||||
// check for valid format while using IN Operator
|
||||
if (strstr($v[1], 'IN')) {
|
||||
if (!is_array($v[2])) {
|
||||
$inVal = trim($v[2]);
|
||||
//checking for format to avoid db errors
|
||||
if ($type == 'Int') {
|
||||
if (!preg_match('/^[A-Za-z0-9\,]+$/', $inVal)) {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter correct Data (in valid format).");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!preg_match('/^[A-Za-z0-9åäöÅÄÖüÜœŒæÆøØ()\,\s]+$/', $inVal)) {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter correct Data (in valid format).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate each value in parenthesis to avoid db errors
|
||||
if (empty($errorMsg)) {
|
||||
$parenValues = array();
|
||||
$parenValues = is_array($v[2]) ? (array_key_exists($v[1], $v[2])) ? $v[2][$v[1]] : $v[2] : explode(',', trim($inVal, "(..)"));
|
||||
foreach ($parenValues as $val) {
|
||||
if ($type == 'Date' || $type == 'Timestamp') {
|
||||
$val = CRM_Utils_Date::processDate($val);
|
||||
if ($type == 'Date') {
|
||||
$val = substr($val, 0, 8);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$val = trim($val);
|
||||
}
|
||||
if (!$val && $val != '0') {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter the values correctly.");
|
||||
}
|
||||
if (empty($errorMsg)) {
|
||||
$error = CRM_Utils_Type::validate($val, $type, FALSE);
|
||||
if ($error != $val) {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter a valid value.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (trim($v[2])) {
|
||||
//else check value for rest of the Operators
|
||||
$error = CRM_Utils_Type::validate($v[2], $type, FALSE);
|
||||
if ($error != $v[2]) {
|
||||
$errorMsg["value[$v[3]][$v[4]]"] = ts("Please enter a valid value.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($errorMsg)) {
|
||||
$self->set('showSearchForm', TRUE);
|
||||
$self->assign('rows', NULL);
|
||||
return $errorMsg;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise form values.
|
||||
*/
|
||||
public function normalizeFormValues() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert form values.
|
||||
*
|
||||
* @param array $formValues
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function convertFormValues(&$formValues) {
|
||||
return CRM_Core_BAO_Mapping::formattedFields($formValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get return properties.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function &returnProperties() {
|
||||
return CRM_Core_BAO_Mapping::returnProperties($this->_formValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the uploaded file.
|
||||
*/
|
||||
public function postProcess() {
|
||||
$this->set('isAdvanced', '2');
|
||||
$this->set('isSearchBuilder', '1');
|
||||
$this->set('showSearchForm', FALSE);
|
||||
|
||||
$params = $this->controller->exportValues($this->_name);
|
||||
if (!empty($params)) {
|
||||
// Add another block
|
||||
if (!empty($params['addBlock'])) {
|
||||
$this->set('newBlock', $this->_blockCount);
|
||||
$this->_blockCount += 3;
|
||||
$this->set('blockCount', $this->_blockCount);
|
||||
$this->set('showSearchForm', TRUE);
|
||||
return;
|
||||
}
|
||||
// Add another field
|
||||
$addMore = CRM_Utils_Array::value('addMore', $params);
|
||||
for ($x = 1; $x <= $this->_blockCount; $x++) {
|
||||
if (!empty($addMore[$x])) {
|
||||
$this->set('newBlock', $x);
|
||||
$this->_columnCount[$x] = $this->_columnCount[$x] + 5;
|
||||
$this->set('columnCount', $this->_columnCount);
|
||||
$this->set('showSearchForm', TRUE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->set('newBlock', NULL);
|
||||
$checkEmpty = NULL;
|
||||
foreach ($params['mapper'] as $key => $value) {
|
||||
foreach ($value as $k => $v) {
|
||||
if ($v[0]) {
|
||||
$checkEmpty++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$checkEmpty) {
|
||||
$this->set('newBlock', 1);
|
||||
CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/search/builder', '_qf_Builder_display=true'));
|
||||
}
|
||||
}
|
||||
|
||||
// get user submitted values
|
||||
// get it from controller only if form has been submitted, else preProcess has set this
|
||||
if (!empty($_POST)) {
|
||||
$this->_formValues = $this->controller->exportValues($this->_name);
|
||||
|
||||
// set the group if group is submitted
|
||||
if (!empty($this->_formValues['uf_group_id'])) {
|
||||
$this->set('id', $this->_formValues['uf_group_id']);
|
||||
}
|
||||
else {
|
||||
$this->set('id', '');
|
||||
}
|
||||
}
|
||||
|
||||
// we dont want to store the sortByCharacter in the formValue, it is more like
|
||||
// a filter on the result set
|
||||
// this filter is reset if we click on the search button
|
||||
if ($this->_sortByCharacter !== NULL && empty($_POST)) {
|
||||
if (strtolower($this->_sortByCharacter) == 'all') {
|
||||
$this->_formValues['sortByCharacter'] = NULL;
|
||||
}
|
||||
else {
|
||||
$this->_formValues['sortByCharacter'] = $this->_sortByCharacter;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->_sortByCharacter = NULL;
|
||||
}
|
||||
|
||||
$this->_params = $this->convertFormValues($this->_formValues);
|
||||
$this->_returnProperties = &$this->returnProperties();
|
||||
|
||||
// CRM-10338 check if value is empty array
|
||||
foreach ($this->_params as $k => $v) {
|
||||
$this->_params[$k][2] = self::checkArrayKeyEmpty($v[2]);
|
||||
}
|
||||
|
||||
parent::postProcess();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fields.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function fields() {
|
||||
$fields = array_merge(
|
||||
CRM_Contact_BAO_Contact::exportableFields('All', FALSE, TRUE),
|
||||
CRM_Core_Component::getQueryFields(),
|
||||
CRM_Contact_BAO_Query_Hook::singleton()->getFields(),
|
||||
CRM_Activity_BAO_Activity::exportableFields()
|
||||
);
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* CRM-9434 Hackish function to fetch fields with options.
|
||||
*
|
||||
* FIXME: When our core fields contain reliable metadata this will be much simpler.
|
||||
* @return array
|
||||
* (string => string) key: field_name value: api entity name
|
||||
* Note: options are fetched via ajax using the api "getoptions" method
|
||||
*/
|
||||
public static function fieldOptions() {
|
||||
// Hack to add options not retrieved by getfields
|
||||
// This list could go on and on, but it would be better to fix getfields
|
||||
$options = array(
|
||||
'group' => 'group_contact',
|
||||
'tag' => 'entity_tag',
|
||||
'on_hold' => 'yesno',
|
||||
'is_bulkmail' => 'yesno',
|
||||
'payment_instrument' => 'contribution',
|
||||
'membership_status' => 'membership',
|
||||
'membership_type' => 'membership',
|
||||
'member_campaign_id' => 'membership',
|
||||
'member_is_test' => 'yesno',
|
||||
'member_is_pay_later' => 'yesno',
|
||||
'is_override' => 'yesno',
|
||||
);
|
||||
$entities = array(
|
||||
'contact',
|
||||
'address',
|
||||
'activity',
|
||||
'participant',
|
||||
'pledge',
|
||||
'member',
|
||||
'contribution',
|
||||
'case',
|
||||
'grant',
|
||||
);
|
||||
CRM_Contact_BAO_Query_Hook::singleton()->alterSearchBuilderOptions($entities, $options);
|
||||
foreach ($entities as $entity) {
|
||||
$fields = civicrm_api3($entity, 'getfields');
|
||||
foreach ($fields['values'] as $field => $info) {
|
||||
if (!empty($info['options']) || !empty($info['pseudoconstant']) || !empty($info['option_group_id'])) {
|
||||
$options[$field] = $entity;
|
||||
// Hack for when search field doesn't match db field - e.g. "country" instead of "country_id"
|
||||
if (substr($field, -3) == '_id') {
|
||||
$options[substr($field, 0, -3)] = $entity;
|
||||
}
|
||||
}
|
||||
elseif (!empty($info['data_type']) && in_array($info['data_type'], array('StateProvince', 'Country'))) {
|
||||
$options[$field] = $entity;
|
||||
}
|
||||
elseif (in_array(substr($field, 0, 3), array(
|
||||
'is_',
|
||||
'do_',
|
||||
)) || CRM_Utils_Array::value('data_type', $info) == 'Boolean'
|
||||
) {
|
||||
$options[$field] = 'yesno';
|
||||
if ($entity != 'contact') {
|
||||
$options[$entity . '_' . $field] = 'yesno';
|
||||
}
|
||||
}
|
||||
elseif (strpos($field, '_is_')) {
|
||||
$options[$field] = 'yesno';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* CRM-10338 tags and groups use array keys for selection list.
|
||||
*
|
||||
* if using IS NULL/NOT NULL, an array with no array key is created
|
||||
* convert that to simple NULL so processing can proceed
|
||||
*
|
||||
* @param string $val
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public static function checkArrayKeyEmpty($val) {
|
||||
if (is_array($val)) {
|
||||
$v2empty = TRUE;
|
||||
foreach ($val as $vk => $vv) {
|
||||
if (!empty($vk)) {
|
||||
$v2empty = FALSE;
|
||||
}
|
||||
}
|
||||
if ($v2empty) {
|
||||
$val = NULL;
|
||||
}
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
}
|
538
sites/all/modules/civicrm/CRM/Contact/Form/Search/Criteria.php
Normal file
538
sites/all/modules/civicrm/CRM/Contact/Form/Search/Criteria.php
Normal file
|
@ -0,0 +1,538 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Criteria {
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public static function basic(&$form) {
|
||||
$form->addElement('hidden', 'hidden_basic', 1);
|
||||
|
||||
if ($form->_searchOptions['contactType']) {
|
||||
$contactTypes = CRM_Contact_BAO_ContactType::getSelectElements();
|
||||
|
||||
if ($contactTypes) {
|
||||
$form->add('select', 'contact_type', ts('Contact Type(s)'), $contactTypes, FALSE,
|
||||
array('id' => 'contact_type', 'multiple' => 'multiple', 'class' => 'crm-select2', 'style' => 'width: 100%;')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($form->_searchOptions['groups']) {
|
||||
// multiselect for groups
|
||||
if ($form->_group) {
|
||||
// Arrange groups into hierarchical listing (child groups follow their parents and have indentation spacing in title)
|
||||
$groupHierarchy = CRM_Contact_BAO_Group::getGroupsHierarchy($form->_group, NULL, ' ', TRUE);
|
||||
|
||||
$form->add('select', 'group', ts('Groups'), $groupHierarchy, FALSE,
|
||||
array('id' => 'group', 'multiple' => 'multiple', 'class' => 'crm-select2')
|
||||
);
|
||||
$groupOptions = CRM_Core_BAO_OptionValue::getOptionValuesAssocArrayFromName('group_type');
|
||||
$form->add('select', 'group_type', ts('Group Types'), $groupOptions, FALSE,
|
||||
array('id' => 'group_type', 'multiple' => 'multiple', 'class' => 'crm-select2')
|
||||
);
|
||||
$form->add('hidden', 'group_search_selected', 'group');
|
||||
}
|
||||
}
|
||||
|
||||
if ($form->_searchOptions['tags']) {
|
||||
// multiselect for categories
|
||||
$contactTags = CRM_Core_BAO_Tag::getTags();
|
||||
|
||||
if ($contactTags) {
|
||||
$form->add('select', 'contact_tags', ts('Tags'), $contactTags, FALSE,
|
||||
array('id' => 'contact_tags', 'multiple' => 'multiple', 'class' => 'crm-select2', 'style' => 'width: 100%;')
|
||||
);
|
||||
}
|
||||
|
||||
$parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_contact');
|
||||
CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_contact', NULL, TRUE, FALSE);
|
||||
|
||||
$used_for = CRM_Core_OptionGroup::values('tag_used_for');
|
||||
$tagsTypes = array();
|
||||
$showAllTagTypes = FALSE;
|
||||
foreach ($used_for as $key => $value) {
|
||||
//check tags for every type and find if there are any defined
|
||||
$tags = CRM_Core_BAO_Tag::getTagsUsedFor($key, FALSE, TRUE, NULL);
|
||||
// check if there are tags other than contact type, if no - keep checkbox hidden on adv search
|
||||
// we will hide searching contact by attachments tags until it will be implemented in core
|
||||
if (count($tags) && $key != 'civicrm_file' && $key != 'civicrm_contact') {
|
||||
//if tags exists then add type to display in adv search form help text
|
||||
$tagsTypes[] = ts($value);
|
||||
$showAllTagTypes = TRUE;
|
||||
}
|
||||
}
|
||||
$tagTypesText = implode(" or ", $tagsTypes);
|
||||
if ($showAllTagTypes) {
|
||||
$form->add('checkbox', 'all_tag_types', ts('Include tags used for %1', array(1 => $tagTypesText)));
|
||||
$form->add('hidden', 'tag_types_text', $tagTypesText);
|
||||
}
|
||||
}
|
||||
|
||||
// add text box for last name, first name, street name, city
|
||||
$form->addElement('text', 'sort_name', ts('Find...'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Contact', 'sort_name'));
|
||||
|
||||
// add text box for last name, first name, street name, city
|
||||
$form->add('text', 'email', ts('Contact Email'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Contact', 'sort_name'));
|
||||
|
||||
//added contact source
|
||||
$form->add('text', 'contact_source', ts('Contact Source'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Contact', 'contact_source'));
|
||||
|
||||
//added job title
|
||||
$form->addElement('text', 'job_title', ts('Job Title'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Contact', 'job_title'));
|
||||
|
||||
//added internal ID
|
||||
$form->add('number', 'contact_id', ts('Contact ID'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Contact', 'id') + array('min' => 1));
|
||||
$form->addRule('contact_id', ts('Please enter valid Contact ID'), 'positiveInteger');
|
||||
|
||||
//added external ID
|
||||
$form->addElement('text', 'external_identifier', ts('External ID'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Contact', 'external_identifier'));
|
||||
|
||||
if (CRM_Core_Permission::check('access deleted contacts') and Civi::settings()->get('contact_undelete')) {
|
||||
$form->add('checkbox', 'deleted_contacts', ts('Search in Trash') . '<br />' . ts('(deleted contacts)'));
|
||||
}
|
||||
|
||||
// add checkbox for cms users only
|
||||
$form->addYesNo('uf_user', ts('CMS User?'), TRUE);
|
||||
|
||||
// tag all search
|
||||
$form->add('text', 'tag_search', ts('All Tags'));
|
||||
|
||||
// add search profiles
|
||||
|
||||
// FIXME: This is probably a part of profiles - need to be
|
||||
// FIXME: eradicated from here when profiles are reworked.
|
||||
$types = array('Participant', 'Contribution', 'Membership');
|
||||
|
||||
// get component profiles
|
||||
$componentProfiles = array();
|
||||
$componentProfiles = CRM_Core_BAO_UFGroup::getProfiles($types);
|
||||
|
||||
$ufGroups = CRM_Core_BAO_UFGroup::getModuleUFGroup('Search Profile', 1);
|
||||
$accessibleUfGroups = CRM_Core_Permission::ufGroup(CRM_Core_Permission::VIEW);
|
||||
|
||||
$searchProfiles = array();
|
||||
foreach ($ufGroups as $key => $var) {
|
||||
if (!array_key_exists($key, $componentProfiles) && in_array($key, $accessibleUfGroups)) {
|
||||
$searchProfiles[$key] = $var['title'];
|
||||
}
|
||||
}
|
||||
|
||||
$form->add('select',
|
||||
'uf_group_id',
|
||||
ts('Views For Display Contacts'),
|
||||
array(
|
||||
'0' => ts('- default view -'),
|
||||
) + $searchProfiles,
|
||||
FALSE,
|
||||
array('class' => 'crm-select2')
|
||||
);
|
||||
|
||||
$componentModes = CRM_Contact_Form_Search::getModeSelect();
|
||||
$enabledComponents = CRM_Core_Component::getEnabledComponents();
|
||||
|
||||
// unset disabled components that must should have been enabled
|
||||
// to the option be viable
|
||||
if (!array_key_exists('CiviMail', $enabledComponents)) {
|
||||
unset($componentModes['8']);
|
||||
}
|
||||
|
||||
// unset contributions or participants if user does not have
|
||||
// permission on them
|
||||
if (!CRM_Core_Permission::access('CiviContribute')) {
|
||||
unset($componentModes['2']);
|
||||
}
|
||||
|
||||
if (!CRM_Core_Permission::access('CiviEvent')) {
|
||||
unset($componentModes['3']);
|
||||
}
|
||||
|
||||
if (!CRM_Core_Permission::access('CiviMember')) {
|
||||
unset($componentModes['5']);
|
||||
}
|
||||
|
||||
if (!CRM_Core_Permission::check('view all activities')) {
|
||||
unset($componentModes['4']);
|
||||
}
|
||||
|
||||
if (count($componentModes) > 1) {
|
||||
$form->add('select',
|
||||
'component_mode',
|
||||
ts('Display Results As'),
|
||||
$componentModes,
|
||||
FALSE,
|
||||
array('class' => 'crm-select2')
|
||||
);
|
||||
}
|
||||
|
||||
$form->addRadio(
|
||||
'operator',
|
||||
ts('Search Operator'),
|
||||
array(
|
||||
'AND' => ts('AND'),
|
||||
'OR' => ts('OR'),
|
||||
),
|
||||
array('allowClear' => FALSE)
|
||||
);
|
||||
|
||||
// add the option to display relationships
|
||||
$rTypes = CRM_Core_PseudoConstant::relationshipType();
|
||||
$rSelect = array('' => ts('- Select Relationship Type-'));
|
||||
foreach ($rTypes as $rid => $rValue) {
|
||||
if ($rValue['label_a_b'] == $rValue['label_b_a']) {
|
||||
$rSelect[$rid] = $rValue['label_a_b'];
|
||||
}
|
||||
else {
|
||||
$rSelect["{$rid}_a_b"] = $rValue['label_a_b'];
|
||||
$rSelect["{$rid}_b_a"] = $rValue['label_b_a'];
|
||||
}
|
||||
}
|
||||
|
||||
$form->addElement('select',
|
||||
'display_relationship_type',
|
||||
ts('Display Results as Relationship'),
|
||||
$rSelect,
|
||||
array('class' => 'crm-select2')
|
||||
);
|
||||
|
||||
// checkboxes for DO NOT phone, email, mail
|
||||
// we take labels from SelectValues
|
||||
$t = CRM_Core_SelectValues::privacy();
|
||||
$form->add('select',
|
||||
'privacy_options',
|
||||
ts('Privacy'),
|
||||
$t,
|
||||
FALSE,
|
||||
array(
|
||||
'id' => 'privacy_options',
|
||||
'multiple' => 'multiple',
|
||||
'class' => 'crm-select2',
|
||||
)
|
||||
);
|
||||
|
||||
$form->addElement('select',
|
||||
'privacy_operator',
|
||||
ts('Operator'),
|
||||
array(
|
||||
'OR' => ts('OR'),
|
||||
'AND' => ts('AND'),
|
||||
)
|
||||
);
|
||||
|
||||
$options = array(
|
||||
1 => ts('Exclude'),
|
||||
2 => ts('Include by Privacy Option(s)'),
|
||||
);
|
||||
$form->addRadio('privacy_toggle', ts('Privacy Options'), $options, array('allowClear' => FALSE));
|
||||
|
||||
// preferred communication method
|
||||
|
||||
$onHold[] = $form->createElement('advcheckbox', 'on_hold', NULL, '');
|
||||
$form->addGroup($onHold, 'email_on_hold', ts('Email On Hold'));
|
||||
|
||||
$form->addSelect('preferred_communication_method',
|
||||
array('entity' => 'contact', 'multiple' => 'multiple', 'label' => ts('Preferred Communication Method'), 'option_url' => NULL, 'placeholder' => ts('- any -')));
|
||||
|
||||
//CRM-6138 Preferred Language
|
||||
$form->addSelect('preferred_language', array('class' => 'twenty', 'context' => 'search'));
|
||||
|
||||
// Phone search
|
||||
$form->addElement('text', 'phone_numeric', ts('Phone'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_Phone', 'phone'));
|
||||
$locationType = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
|
||||
$phoneType = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id');
|
||||
$form->add('select', 'phone_location_type_id', ts('Phone Location'), array('' => ts('- any -')) + $locationType, FALSE, array('class' => 'crm-select2'));
|
||||
$form->add('select', 'phone_phone_type_id', ts('Phone Type'), array('' => ts('- any -')) + $phoneType, FALSE, array('class' => 'crm-select2'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public static function location(&$form) {
|
||||
$config = CRM_Core_Config::singleton();
|
||||
// Build location criteria based on _submitValues if
|
||||
// available; otherwise, use $form->_formValues.
|
||||
$formValues = $form->_submitValues;
|
||||
|
||||
if (empty($formValues) && !empty($form->_formValues)) {
|
||||
$formValues = $form->_formValues;
|
||||
}
|
||||
|
||||
$form->addElement('hidden', 'hidden_location', 1);
|
||||
|
||||
$addressOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
|
||||
'address_options', TRUE, NULL, TRUE
|
||||
);
|
||||
|
||||
$attributes = CRM_Core_DAO::getAttribute('CRM_Core_DAO_Address');
|
||||
|
||||
$elements = array(
|
||||
'street_address' => array(ts('Street Address'), $attributes['street_address'], NULL, NULL),
|
||||
'supplemental_address_1' => array(ts('Supplemental Address 1'), $attributes['supplemental_address_1'], NULL, NULL),
|
||||
'supplemental_address_2' => array(ts('Supplemental Address 2'), $attributes['supplemental_address_2'], NULL, NULL),
|
||||
'supplemental_address_3' => array(ts('Supplemental Address 3'), $attributes['supplemental_address_3'], NULL, NULL),
|
||||
'city' => array(ts('City'), $attributes['city'], NULL, NULL),
|
||||
'postal_code' => array(ts('Postal Code'), $attributes['postal_code'], NULL, NULL),
|
||||
'country' => array(ts('Country'), $attributes['country_id'], 'country', FALSE),
|
||||
'state_province' => array(ts('State/Province'), $attributes['state_province_id'], 'stateProvince', TRUE),
|
||||
'county' => array(ts('County'), $attributes['county_id'], 'county', TRUE),
|
||||
'address_name' => array(ts('Address Name'), $attributes['address_name'], NULL, NULL),
|
||||
'street_number' => array(ts('Street Number'), $attributes['street_number'], NULL, NULL),
|
||||
'street_name' => array(ts('Street Name'), $attributes['street_name'], NULL, NULL),
|
||||
'street_unit' => array(ts('Apt/Unit/Suite'), $attributes['street_unit'], NULL, NULL),
|
||||
);
|
||||
|
||||
$parseStreetAddress = CRM_Utils_Array::value('street_address_parsing', $addressOptions, 0);
|
||||
$form->assign('parseStreetAddress', $parseStreetAddress);
|
||||
foreach ($elements as $name => $v) {
|
||||
list($title, $attributes, $select, $multiSelect) = $v;
|
||||
|
||||
if (in_array($name,
|
||||
array('street_number', 'street_name', 'street_unit')
|
||||
)) {
|
||||
if (!$parseStreetAddress) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
elseif (!$addressOptions[$name]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$attributes) {
|
||||
$attributes = $attributes[$name];
|
||||
}
|
||||
|
||||
if ($select) {
|
||||
if ($select == 'stateProvince' || $select == 'county') {
|
||||
$element = $form->addChainSelect($name);
|
||||
}
|
||||
else {
|
||||
$selectElements = array('' => ts('- any -')) + CRM_Core_PseudoConstant::$select();
|
||||
$element = $form->add('select', $name, $title, $selectElements, FALSE, array('class' => 'crm-select2'));
|
||||
}
|
||||
if ($multiSelect) {
|
||||
$element->setMultiple(TRUE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$form->addElement('text', $name, $title, $attributes);
|
||||
}
|
||||
|
||||
if ($addressOptions['postal_code']) {
|
||||
$attr = array('class' => 'six') + (array) CRM_Utils_Array::value('postal_code', $attributes);
|
||||
$form->addElement('text', 'postal_code_low', NULL, $attr + array('placeholder' => ts('From')));
|
||||
$form->addElement('text', 'postal_code_high', NULL, $attr + array('placeholder' => ts('To')));
|
||||
}
|
||||
}
|
||||
|
||||
// extend addresses with proximity search
|
||||
if (!empty($config->geocodeMethod)) {
|
||||
$form->addElement('text', 'prox_distance', ts('Find contacts within'), array('class' => 'six'));
|
||||
$form->addElement('select', 'prox_distance_unit', NULL, array(
|
||||
'miles' => ts('Miles'),
|
||||
'kilos' => ts('Kilometers'),
|
||||
));
|
||||
$form->addRule('prox_distance', ts('Please enter positive number as a distance'), 'numeric');
|
||||
}
|
||||
|
||||
$form->addSelect('world_region', array('entity' => 'address', 'context' => 'search'));
|
||||
|
||||
// select for location type
|
||||
$locationType = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
|
||||
$form->add('select', 'location_type', ts('Address Location'), $locationType, FALSE, array(
|
||||
'multiple' => TRUE,
|
||||
'class' => 'crm-select2',
|
||||
'placeholder' => ts('Primary'),
|
||||
));
|
||||
|
||||
// custom data extending addresses
|
||||
CRM_Core_BAO_Query::addCustomFormFields($form, array('Address'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public static function activity(&$form) {
|
||||
$form->add('hidden', 'hidden_activity', 1);
|
||||
CRM_Activity_BAO_Query::buildSearchForm($form);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public static function changeLog(&$form) {
|
||||
$form->add('hidden', 'hidden_changeLog', 1);
|
||||
|
||||
// block for change log
|
||||
$form->addElement('text', 'changed_by', ts('Modified By'), NULL);
|
||||
|
||||
$dates = array(1 => ts('Added'), 2 => ts('Modified'));
|
||||
$form->addRadio('log_date', NULL, $dates, array('allowClear' => TRUE), '<br />');
|
||||
|
||||
CRM_Core_Form_Date::buildDateRange($form, 'log_date', 1, '_low', '_high', ts('From'), FALSE, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public static function task(&$form) {
|
||||
$form->add('hidden', 'hidden_task', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $form
|
||||
*/
|
||||
public static function relationship(&$form) {
|
||||
$form->add('hidden', 'hidden_relationship', 1);
|
||||
|
||||
$allRelationshipType = array();
|
||||
$allRelationshipType = CRM_Contact_BAO_Relationship::getContactRelationshipType(NULL, NULL, NULL, NULL, TRUE);
|
||||
$form->add('select', 'relation_type_id', ts('Relationship Type'), array('' => ts('- select -')) + $allRelationshipType, FALSE, array('class' => 'crm-select2'));
|
||||
$form->addElement('text', 'relation_target_name', ts('Target Contact'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Contact', 'sort_name'));
|
||||
// relation status
|
||||
$relStatusOption = array(ts('Active'), ts('Inactive'), ts('All'));
|
||||
$form->addRadio('relation_status', ts('Relationship Status'), $relStatusOption);
|
||||
$form->setDefaults(array('relation_status' => 0));
|
||||
// relation permission
|
||||
$relPermissionOption = array(ts('Any'), ts('Yes'), ts('No'));
|
||||
$form->addRadio('relation_permission', ts('Permissioned Relationship?'), $relPermissionOption);
|
||||
$form->setDefaults(array('relation_permission' => 0));
|
||||
|
||||
//add the target group
|
||||
if ($form->_group) {
|
||||
$form->add('select', 'relation_target_group', ts('Target Contact(s) in Group'), $form->_group, FALSE,
|
||||
array('id' => 'relation_target_group', 'multiple' => 'multiple', 'class' => 'crm-select2')
|
||||
);
|
||||
}
|
||||
CRM_Core_Form_Date::buildDateRange($form, 'relation_start_date', 1, '_low', '_high', ts('From:'), FALSE, FALSE);
|
||||
CRM_Core_Form_Date::buildDateRange($form, 'relation_end_date', 1, '_low', '_high', ts('From:'), FALSE, FALSE);
|
||||
|
||||
CRM_Core_Form_Date::buildDateRange($form, 'relation_active_period_date', 1, '_low', '_high', ts('From:'), FALSE, FALSE);
|
||||
|
||||
// Add reltionship dates
|
||||
CRM_Core_Form_Date::buildDateRange($form, 'relation_date', 1, '_low', '_high', ts('From:'), FALSE, FALSE);
|
||||
|
||||
// add all the custom searchable fields
|
||||
CRM_Core_BAO_Query::addCustomFormFields($form, array('Relationship'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $form
|
||||
*/
|
||||
public static function demographics(&$form) {
|
||||
$form->add('hidden', 'hidden_demographics', 1);
|
||||
// radio button for gender
|
||||
$genderOptions = array();
|
||||
$gender = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'gender_id');
|
||||
foreach ($gender as $key => $var) {
|
||||
$genderOptions[$key] = $form->createElement('radio', NULL,
|
||||
ts('Gender'), $var, $key,
|
||||
array('id' => "civicrm_gender_{$var}_{$key}")
|
||||
);
|
||||
}
|
||||
$form->addGroup($genderOptions, 'gender_id', ts('Gender'))->setAttribute('allowClear', TRUE);
|
||||
|
||||
$form->add('text', 'age_low', ts('Min Age'), array('size' => 6));
|
||||
$form->addRule('age_low', ts('Please enter a positive integer'), 'positiveInteger');
|
||||
$form->add('text', 'age_high', ts('Max Age'), array('size' => 6));
|
||||
$form->addRule('age_high', ts('Please enter a positive integer'), 'positiveInteger');
|
||||
$form->addDate('age_asof_date', ts('Age as of Date'), FALSE, array('formatType' => 'searchDate'));
|
||||
|
||||
CRM_Core_Form_Date::buildDateRange($form, 'birth_date', 1, '_low', '_high', ts('From'), FALSE, FALSE, 'birth');
|
||||
|
||||
CRM_Core_Form_Date::buildDateRange($form, 'deceased_date', 1, '_low', '_high', ts('From'), FALSE, FALSE, 'birth');
|
||||
|
||||
// radio button for is_deceased
|
||||
$form->addYesNo('is_deceased', ts('Deceased'), TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $form
|
||||
*/
|
||||
public static function notes(&$form) {
|
||||
$form->add('hidden', 'hidden_notes', 1);
|
||||
|
||||
$options = array(
|
||||
2 => ts('Body Only'),
|
||||
3 => ts('Subject Only'),
|
||||
6 => ts('Both'),
|
||||
);
|
||||
$form->addRadio('note_option', '', $options);
|
||||
|
||||
$form->addElement('text', 'note', ts('Note Text'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Contact', 'sort_name'));
|
||||
|
||||
$form->setDefaults(array('note_option' => 6));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the custom Data Fields based for those with is_searchable = 1.
|
||||
*
|
||||
* @param CRM_Contact_Form_Search $form
|
||||
*/
|
||||
public static function custom(&$form) {
|
||||
$form->add('hidden', 'hidden_custom', 1);
|
||||
$extends = array_merge(array('Contact', 'Individual', 'Household', 'Organization'),
|
||||
CRM_Contact_BAO_ContactType::subTypes()
|
||||
);
|
||||
$groupDetails = CRM_Core_BAO_CustomGroup::getGroupDetail(NULL, TRUE,
|
||||
$extends
|
||||
);
|
||||
|
||||
$form->assign('groupTree', $groupDetails);
|
||||
|
||||
foreach ($groupDetails as $key => $group) {
|
||||
$_groupTitle[$key] = $group['name'];
|
||||
CRM_Core_ShowHideBlocks::links($form, $group['name'], '', '');
|
||||
|
||||
foreach ($group['fields'] as $field) {
|
||||
$fieldId = $field['id'];
|
||||
$elementName = 'custom_' . $fieldId;
|
||||
if ($field['data_type'] == 'Date' && $field['is_search_range']) {
|
||||
CRM_Core_Form_Date::buildDateRange($form, $elementName, 1, '_from', '_to', ts('From:'), FALSE);
|
||||
}
|
||||
else {
|
||||
CRM_Core_BAO_CustomField::addQuickFormElement($form, $elementName, $fieldId, FALSE, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $form
|
||||
*/
|
||||
public static function CiviCase(&$form) {
|
||||
//Looks like obsolete code, since CiviCase is a component, but might be used by HRD
|
||||
$form->add('hidden', 'hidden_CiviCase', 1);
|
||||
CRM_Case_BAO_Query::buildSearchForm($form);
|
||||
}
|
||||
|
||||
}
|
199
sites/all/modules/civicrm/CRM/Contact/Form/Search/Custom.php
Normal file
199
sites/all/modules/civicrm/CRM/Contact/Form/Search/Custom.php
Normal file
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom extends CRM_Contact_Form_Search {
|
||||
|
||||
protected $_customClass = NULL;
|
||||
|
||||
public function preProcess() {
|
||||
$this->set('searchFormName', 'Custom');
|
||||
|
||||
$this->set('context', 'custom');
|
||||
|
||||
$csID = CRM_Utils_Request::retrieve('csid', 'Integer', $this);
|
||||
$ssID = CRM_Utils_Request::retrieve('ssID', 'Integer', $this);
|
||||
$gID = CRM_Utils_Request::retrieve('gid', 'Integer', $this);
|
||||
|
||||
list(
|
||||
$this->_customSearchID,
|
||||
$this->_customSearchClass,
|
||||
$formValues
|
||||
) = CRM_Contact_BAO_SearchCustom::details($csID, $ssID, $gID);
|
||||
|
||||
if (!$this->_customSearchID) {
|
||||
CRM_Core_Error::fatal('Could not get details for custom search.');
|
||||
}
|
||||
|
||||
// stash this as a hidden element so we can potentially go there if the session
|
||||
// is reset but this is available in the POST
|
||||
$this->addElement('hidden', 'csid', $csID);
|
||||
|
||||
if (!empty($formValues)) {
|
||||
$this->_formValues = $formValues;
|
||||
}
|
||||
|
||||
// set breadcrumb to return to Custom Search listings page
|
||||
$breadCrumb = array(
|
||||
array(
|
||||
'title' => ts('Custom Searches'),
|
||||
'url' => CRM_Utils_System::url('civicrm/contact/search/custom/list',
|
||||
'reset=1'
|
||||
),
|
||||
),
|
||||
);
|
||||
CRM_Utils_System::appendBreadCrumb($breadCrumb);
|
||||
|
||||
// use the custom selector
|
||||
self::$_selectorName = 'CRM_Contact_Selector_Custom';
|
||||
|
||||
$this->set('customSearchID', $this->_customSearchID);
|
||||
$this->set('customSearchClass', $this->_customSearchClass);
|
||||
|
||||
parent::preProcess();
|
||||
|
||||
// instantiate the new class
|
||||
$this->_customClass = new $this->_customSearchClass($this->_formValues);
|
||||
|
||||
// CRM-12747
|
||||
if (isset($this->_customClass->_permissionedComponent) &&
|
||||
!self::isPermissioned($this->_customClass->_permissionedComponent)
|
||||
) {
|
||||
CRM_Utils_System::permissionDenied();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default values of various form elements.
|
||||
*
|
||||
* @return array
|
||||
* reference to the array of default values
|
||||
*/
|
||||
public function setDefaultValues() {
|
||||
if (method_exists($this->_customSearchClass, 'setDefaultValues')) {
|
||||
return $this->_customClass->setDefaultValues();
|
||||
}
|
||||
return $this->_formValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the list of tasks or actions that a searcher can perform on a result set.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildTaskList() {
|
||||
// call the parent method to populate $this->_taskList for the custom search
|
||||
parent::buildTaskList();
|
||||
|
||||
return $this->_customClass->buildTaskList($this);
|
||||
}
|
||||
|
||||
public function buildQuickForm() {
|
||||
$this->_customClass->buildForm($this);
|
||||
|
||||
parent::buildQuickForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the form name to create the tpl file name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTemplateFileName() {
|
||||
|
||||
$ext = CRM_Extension_System::singleton()->getMapper();
|
||||
|
||||
if ($ext->isExtensionClass(CRM_Utils_System::getClassName($this->_customClass))) {
|
||||
$fileName = $ext->getTemplatePath(CRM_Utils_System::getClassName($this->_customClass)) . '/' . $ext->getTemplateName(CRM_Utils_System::getClassName($this->_customClass));
|
||||
}
|
||||
else {
|
||||
$fileName = $this->_customClass->templateFile();
|
||||
}
|
||||
|
||||
return $fileName ? $fileName : parent::getTemplateFileName();
|
||||
}
|
||||
|
||||
public function postProcess() {
|
||||
$this->set('isAdvanced', '3');
|
||||
$this->set('isCustom', '1');
|
||||
|
||||
// get user submitted values
|
||||
// get it from controller only if form has been submitted, else preProcess has set this
|
||||
if (!empty($_POST)) {
|
||||
$this->_formValues = $this->controller->exportValues($this->_name);
|
||||
|
||||
$this->_formValues['customSearchID'] = $this->_customSearchID;
|
||||
$this->_formValues['customSearchClass'] = $this->_customSearchClass;
|
||||
}
|
||||
|
||||
//use the custom selector
|
||||
self::$_selectorName = 'CRM_Contact_Selector_Custom';
|
||||
|
||||
parent::postProcess();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a descriptive name for the page, used in wizard header.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle() {
|
||||
return ts('Custom Search');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $components
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPermissioned($components) {
|
||||
if (empty($components)) {
|
||||
return TRUE;
|
||||
}
|
||||
if (is_array($components)) {
|
||||
foreach ($components as $component) {
|
||||
if (!CRM_Core_Permission::access($component)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!CRM_Core_Permission::access($components)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,432 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_ActivitySearch extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_formValues;
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
$this->_formValues = $formValues;
|
||||
|
||||
/**
|
||||
* Define the columns for search result rows
|
||||
*/
|
||||
$this->_columns = array(
|
||||
ts('Name') => 'sort_name',
|
||||
ts('Status') => 'activity_status',
|
||||
ts('Activity Type') => 'activity_type',
|
||||
ts('Activity Subject') => 'activity_subject',
|
||||
ts('Scheduled By') => 'source_contact',
|
||||
ts('Scheduled Date') => 'activity_date',
|
||||
' ' => 'activity_id',
|
||||
' ' => 'activity_type_id',
|
||||
' ' => 'case_id',
|
||||
ts('Location') => 'location',
|
||||
ts('Duration') => 'duration',
|
||||
ts('Details') => 'details',
|
||||
ts('Assignee') => 'assignee',
|
||||
);
|
||||
|
||||
$this->_groupId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup',
|
||||
'activity_status',
|
||||
'id',
|
||||
'name'
|
||||
);
|
||||
|
||||
//Add custom fields to columns array for inclusion in export
|
||||
$groupTree = CRM_Core_BAO_CustomGroup::getTree('Activity');
|
||||
|
||||
//use simplified formatted groupTree
|
||||
$groupTree = CRM_Core_BAO_CustomGroup::formatGroupTree($groupTree);
|
||||
|
||||
//cycle through custom fields and assign to _columns array
|
||||
foreach ($groupTree as $key) {
|
||||
foreach ($key['fields'] as $field) {
|
||||
$fieldlabel = $key['title'] . ": " . $field['label'];
|
||||
$this->_columns[$fieldlabel] = $field['column_name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
|
||||
/**
|
||||
* You can define a custom title for the search form
|
||||
*/
|
||||
$this->setTitle('Find Latest Activities');
|
||||
|
||||
/**
|
||||
* Define the search form fields here
|
||||
*/
|
||||
// Allow user to choose which type of contact to limit search on
|
||||
$form->add('select', 'contact_type', ts('Find...'), CRM_Core_SelectValues::contactType());
|
||||
|
||||
// Text box for Activity Subject
|
||||
$form->add('text',
|
||||
'activity_subject',
|
||||
ts('Activity Subject')
|
||||
);
|
||||
|
||||
// Select box for Activity Type
|
||||
$activityType = array('' => ' - select activity - ') + CRM_Core_PseudoConstant::activityType();
|
||||
|
||||
$form->add('select', 'activity_type_id', ts('Activity Type'),
|
||||
$activityType,
|
||||
FALSE
|
||||
);
|
||||
|
||||
// textbox for Activity Status
|
||||
$activityStatus = array('' => ' - select status - ') + CRM_Core_PseudoConstant::activityStatus();
|
||||
|
||||
$form->add('select', 'activity_status_id', ts('Activity Status'),
|
||||
$activityStatus,
|
||||
FALSE
|
||||
);
|
||||
|
||||
// Activity Date range
|
||||
$form->addDate('start_date', ts('Activity Date From'), FALSE, array('formatType' => 'custom'));
|
||||
$form->addDate('end_date', ts('...through'), FALSE, array('formatType' => 'custom'));
|
||||
|
||||
// Contact Name field
|
||||
$form->add('text', 'sort_name', ts('Contact Name'));
|
||||
|
||||
/**
|
||||
* If you are using the sample template, this array tells the template fields to render
|
||||
* for the search form.
|
||||
*/
|
||||
$form->assign('elements', array(
|
||||
'contact_type',
|
||||
'activity_subject',
|
||||
'activity_type_id',
|
||||
'activity_status_id',
|
||||
'start_date',
|
||||
'end_date',
|
||||
'sort_name',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the smarty template used to layout the search form and results listings.
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom/ActivitySearch.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the search query.
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0, $rowcount = 0, $sort = NULL,
|
||||
$includeContactIDs = FALSE, $justIDs = FALSE
|
||||
) {
|
||||
|
||||
// SELECT clause must include contact_id as an alias for civicrm_contact.id
|
||||
if ($justIDs) {
|
||||
$select = 'contact_a.id as contact_id';
|
||||
}
|
||||
else {
|
||||
$select = '
|
||||
contact_a.id as contact_id,
|
||||
contact_a.sort_name as sort_name,
|
||||
contact_a.contact_type as contact_type,
|
||||
activity.id as activity_id,
|
||||
activity.activity_type_id as activity_type_id,
|
||||
contact_b.sort_name as source_contact,
|
||||
ov1.label as activity_type,
|
||||
activity.subject as activity_subject,
|
||||
activity.activity_date_time as activity_date,
|
||||
ov2.label as activity_status,
|
||||
cca.case_id as case_id,
|
||||
activity.location as location,
|
||||
activity.duration as duration,
|
||||
activity.details as details,
|
||||
assignment.activity_id as assignment_activity,
|
||||
contact_c.display_name as assignee
|
||||
';
|
||||
}
|
||||
|
||||
$from = $this->from();
|
||||
|
||||
$where = $this->where($includeContactIDs);
|
||||
|
||||
if (!empty($where)) {
|
||||
$where = "WHERE $where";
|
||||
}
|
||||
|
||||
// add custom group fields to SELECT and FROM clause
|
||||
$groupTree = CRM_Core_BAO_CustomGroup::getTree('Activity');
|
||||
|
||||
foreach ($groupTree as $key) {
|
||||
if (!empty($key['extends']) && $key['extends'] == 'Activity') {
|
||||
$select .= ", " . $key['table_name'] . ".*";
|
||||
$from .= " LEFT JOIN " . $key['table_name'] . " ON " . $key['table_name'] . ".entity_id = activity.id";
|
||||
}
|
||||
}
|
||||
// end custom groups add
|
||||
|
||||
$sql = " SELECT $select FROM $from $where ";
|
||||
|
||||
//no need to add order when only contact Ids.
|
||||
if (!$justIDs) {
|
||||
// Define ORDER BY for query in $sort, with default value
|
||||
if (!empty($sort)) {
|
||||
if (is_string($sort)) {
|
||||
$sort = CRM_Utils_Type::escape($sort, 'String');
|
||||
$sql .= " ORDER BY $sort ";
|
||||
}
|
||||
else {
|
||||
$sql .= ' ORDER BY ' . trim($sort->orderBy());
|
||||
}
|
||||
}
|
||||
else {
|
||||
$sql .= 'ORDER BY contact_a.sort_name, activity.activity_date_time DESC, activity.activity_type_id, activity.status_id, activity.subject';
|
||||
}
|
||||
}
|
||||
else {
|
||||
//CRM-14107, since there could be multiple activities against same contact,
|
||||
//we need to provide GROUP BY on contact id to prevent duplicacy on prev/next entries
|
||||
$sql .= 'GROUP BY contact_a.id
|
||||
ORDER BY contact_a.sort_name';
|
||||
}
|
||||
|
||||
if ($rowcount > 0 && $offset >= 0) {
|
||||
$offset = CRM_Utils_Type::escape($offset, 'Int');
|
||||
$rowcount = CRM_Utils_Type::escape($rowcount, 'Int');
|
||||
$sql .= " LIMIT $offset, $rowcount ";
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alters the date display in the Activity Date Column. We do this after we already have
|
||||
* the result so that sorting on the date column stays pertinent to the numeric date value
|
||||
* @param $row
|
||||
*/
|
||||
public function alterRow(&$row) {
|
||||
$row['activity_date'] = CRM_Utils_Date::customFormat($row['activity_date'], '%B %E%f, %Y %l:%M %P');
|
||||
}
|
||||
|
||||
/**
|
||||
* Regular JOIN statements here to limit results to contacts who have activities.
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
$this->buildACLClause('contact_a');
|
||||
$activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate');
|
||||
$assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts);
|
||||
$targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts);
|
||||
$sourceID = CRM_Utils_Array::key('Activity Source', $activityContacts);
|
||||
|
||||
$from = "
|
||||
civicrm_activity activity
|
||||
LEFT JOIN civicrm_activity_contact target
|
||||
ON activity.id = target.activity_id AND target.record_type_id = {$targetID}
|
||||
JOIN civicrm_contact contact_a
|
||||
ON contact_a.id = target.contact_id
|
||||
JOIN civicrm_option_value ov1
|
||||
ON activity.activity_type_id = ov1.value AND ov1.option_group_id = 2
|
||||
JOIN civicrm_option_value ov2
|
||||
ON activity.status_id = ov2.value AND ov2.option_group_id = {$this->_groupId}
|
||||
LEFT JOIN civicrm_activity_contact sourceContact
|
||||
ON activity.id = sourceContact.activity_id AND sourceContact.record_type_id = {$sourceID}
|
||||
JOIN civicrm_contact contact_b
|
||||
ON sourceContact.contact_id = contact_b.id
|
||||
LEFT JOIN civicrm_case_activity cca
|
||||
ON activity.id = cca.activity_id
|
||||
LEFT JOIN civicrm_activity_contact assignment
|
||||
ON activity.id = assignment.activity_id AND assignment.record_type_id = {$assigneeID}
|
||||
LEFT JOIN civicrm_contact contact_c
|
||||
ON assignment.contact_id = contact_c.id {$this->_aclFrom}";
|
||||
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* WHERE clause is an array built from any required JOINS plus conditional filters based on search criteria field values.
|
||||
*
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$clauses = array();
|
||||
|
||||
// add contact name search; search on primary name, source contact, assignee
|
||||
$contactname = $this->_formValues['sort_name'];
|
||||
if (!empty($contactname)) {
|
||||
$dao = new CRM_Core_DAO();
|
||||
$contactname = $dao->escape($contactname);
|
||||
$clauses[] = "(contact_a.sort_name LIKE '%{$contactname}%' OR
|
||||
contact_b.sort_name LIKE '%{$contactname}%' OR
|
||||
contact_c.display_name LIKE '%{$contactname}%')";
|
||||
}
|
||||
|
||||
$subject = $this->_formValues['activity_subject'];
|
||||
|
||||
if (!empty($this->_formValues['contact_type'])) {
|
||||
$clauses[] = "contact_a.contact_type LIKE '%{$this->_formValues['contact_type']}%'";
|
||||
}
|
||||
|
||||
if (!empty($subject)) {
|
||||
$dao = new CRM_Core_DAO();
|
||||
$subject = $dao->escape($subject);
|
||||
$clauses[] = "activity.subject LIKE '%{$subject}%'";
|
||||
}
|
||||
|
||||
if (!empty($this->_formValues['activity_status_id'])) {
|
||||
$clauses[] = "activity.status_id = {$this->_formValues['activity_status_id']}";
|
||||
}
|
||||
|
||||
if (!empty($this->_formValues['activity_type_id'])) {
|
||||
$clauses[] = "activity.activity_type_id = {$this->_formValues['activity_type_id']}";
|
||||
}
|
||||
|
||||
$startDate = $this->_formValues['start_date'];
|
||||
if (!empty($startDate)) {
|
||||
$startDate .= '00:00:00';
|
||||
$startDateFormatted = CRM_Utils_Date::processDate($startDate);
|
||||
if ($startDateFormatted) {
|
||||
$clauses[] = "activity.activity_date_time >= $startDateFormatted";
|
||||
}
|
||||
}
|
||||
|
||||
$endDate = $this->_formValues['end_date'];
|
||||
if (!empty($endDate)) {
|
||||
$endDate .= '23:59:59';
|
||||
$endDateFormatted = CRM_Utils_Date::processDate($endDate);
|
||||
if ($endDateFormatted) {
|
||||
$clauses[] = "activity.activity_date_time <= $endDateFormatted";
|
||||
}
|
||||
}
|
||||
|
||||
if ($includeContactIDs) {
|
||||
$contactIDs = array();
|
||||
foreach ($this->_formValues as $id => $value) {
|
||||
if ($value &&
|
||||
substr($id, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX
|
||||
) {
|
||||
$contactIDs[] = substr($id, CRM_Core_Form::CB_PREFIX_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($contactIDs)) {
|
||||
$contactIDs = implode(', ', $contactIDs);
|
||||
$clauses[] = "contact_a.id IN ( $contactIDs )";
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_aclWhere) {
|
||||
$clauses[] = " {$this->_aclWhere} ";
|
||||
}
|
||||
return implode(' AND ', $clauses);
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions below generally don't need to be modified
|
||||
*/
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function count() {
|
||||
$sql = $this->all();
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql,
|
||||
CRM_Core_DAO::$_nullArray
|
||||
);
|
||||
return $dao->N;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL Not used; included for consistency with parent; SQL is always returned
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = TRUE) {
|
||||
return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function &columns() {
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function summary() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,260 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_Base {
|
||||
|
||||
protected $_formValues;
|
||||
|
||||
protected $_columns;
|
||||
|
||||
protected $_stateID;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
$this->_formValues = &$formValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the list of tasks or actions that a searcher can perform on a result set.
|
||||
*
|
||||
* The returned array completely replaces the task list, so a child class that
|
||||
* wants to modify the existing list should manipulate the result of this method.
|
||||
*
|
||||
* @param CRM_Core_Form_Search $form
|
||||
* @return array
|
||||
*/
|
||||
public function buildTaskList(CRM_Core_Form_Search $form) {
|
||||
return $form->getVar('_taskList');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function count() {
|
||||
return CRM_Core_DAO::singleValueQuery($this->sql('count(distinct contact_a.id) as total'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function summary() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = FALSE) {
|
||||
$sql = $this->sql(
|
||||
'contact_a.id as contact_id',
|
||||
$offset,
|
||||
$rowcount,
|
||||
$sort
|
||||
);
|
||||
$this->validateUserSQL($sql);
|
||||
|
||||
if ($returnSQL) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
return CRM_Core_DAO::composeQuery($sql, CRM_Core_DAO::$_nullArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $selectClause
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param null $groupBy
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sql(
|
||||
$selectClause,
|
||||
$offset = 0,
|
||||
$rowcount = 0,
|
||||
$sort = NULL,
|
||||
$includeContactIDs = FALSE,
|
||||
$groupBy = NULL
|
||||
) {
|
||||
|
||||
$sql = "SELECT $selectClause " . $this->from();
|
||||
$where = $this->where();
|
||||
if (!empty($where)) {
|
||||
$sql .= " WHERE " . $where;
|
||||
}
|
||||
|
||||
if ($includeContactIDs) {
|
||||
$this->includeContactIDs($sql,
|
||||
$this->_formValues
|
||||
);
|
||||
}
|
||||
|
||||
if ($groupBy) {
|
||||
$sql .= " $groupBy ";
|
||||
}
|
||||
|
||||
$this->addSortOffset($sql, $offset, $rowcount, $sort);
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function templateFile() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public function &columns() {
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sql
|
||||
* @param $formValues
|
||||
*/
|
||||
public static function includeContactIDs(&$sql, &$formValues) {
|
||||
$contactIDs = array();
|
||||
foreach ($formValues as $id => $value) {
|
||||
if ($value &&
|
||||
substr($id, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX
|
||||
) {
|
||||
$contactIDs[] = substr($id, CRM_Core_Form::CB_PREFIX_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($contactIDs)) {
|
||||
$contactIDs = implode(', ', $contactIDs);
|
||||
$sql .= " AND contact_a.id IN ( $contactIDs )";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sql
|
||||
* @param $offset
|
||||
* @param $rowcount
|
||||
* @param $sort
|
||||
*/
|
||||
public function addSortOffset(&$sql, $offset, $rowcount, $sort) {
|
||||
if (!empty($sort)) {
|
||||
if (is_string($sort)) {
|
||||
$sort = CRM_Utils_Type::escape($sort, 'String');
|
||||
$sql .= " ORDER BY $sort ";
|
||||
}
|
||||
else {
|
||||
$sql .= " ORDER BY " . trim($sort->orderBy());
|
||||
}
|
||||
}
|
||||
|
||||
if ($rowcount > 0 && $offset >= 0) {
|
||||
$offset = CRM_Utils_Type::escape($offset, 'Int');
|
||||
$rowcount = CRM_Utils_Type::escape($rowcount, 'Int');
|
||||
|
||||
$sql .= " LIMIT $offset, $rowcount ";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sql
|
||||
* @param bool $onlyWhere
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function validateUserSQL(&$sql, $onlyWhere = FALSE) {
|
||||
$includeStrings = array('contact_a');
|
||||
$excludeStrings = array('insert', 'delete', 'update');
|
||||
|
||||
if (!$onlyWhere) {
|
||||
$includeStrings += array('select', 'from', 'where', 'civicrm_contact');
|
||||
}
|
||||
|
||||
foreach ($includeStrings as $string) {
|
||||
if (stripos($sql, $string) === FALSE) {
|
||||
CRM_Core_Error::fatal(ts('Could not find \'%1\' string in SQL clause.',
|
||||
array(1 => $string)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($excludeStrings as $string) {
|
||||
if (preg_match('/(\s' . $string . ')|(' . $string . '\s)/i', $sql)) {
|
||||
CRM_Core_Error::fatal(ts('Found illegal \'%1\' string in SQL clause.',
|
||||
array(1 => $string)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $where
|
||||
* @param array $params
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function whereClause(&$where, &$params) {
|
||||
return CRM_Core_DAO::composeQuery($where, $params, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* override this method to define the contact query object
|
||||
* used for creating $sql
|
||||
* @return null
|
||||
*/
|
||||
public function getQueryObj() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title.
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_Basic extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_query;
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
|
||||
/**
|
||||
* 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
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
$contactTypes = array('' => ts('- any contact type -')) + CRM_Contact_BAO_ContactType::getSelectElements();
|
||||
$form->add('select', 'contact_type', ts('Find...'), $contactTypes, FALSE, array('class' => 'crm-select2 huge'));
|
||||
|
||||
// add select for groups
|
||||
$group = array('' => ts('- any group -')) + CRM_Core_PseudoConstant::nestedGroup();
|
||||
$form->addElement('select', 'group', ts('in'), $group, array('class' => 'crm-select2 huge'));
|
||||
|
||||
// add select for categories
|
||||
$tag = array('' => ts('- any tag -')) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
|
||||
$form->addElement('select', 'tag', ts('Tagged'), $tag, array('class' => 'crm-select2 huge'));
|
||||
|
||||
// text for sort_name
|
||||
$form->add('text', 'sort_name', ts('Name'));
|
||||
|
||||
$form->assign('elements', array('sort_name', 'contact_type', 'group', 'tag'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CRM_Contact_DAO_Contact
|
||||
*/
|
||||
public function count() {
|
||||
return $this->_query->searchQuery(0, 0, NULL, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowCount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return CRM_Contact_DAO_Contact
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0,
|
||||
$rowCount = 0,
|
||||
$sort = NULL,
|
||||
$includeContactIDs = FALSE,
|
||||
$justIDs = FALSE
|
||||
) {
|
||||
return $this->_query->searchQuery(
|
||||
$offset,
|
||||
$rowCount,
|
||||
$sort,
|
||||
FALSE,
|
||||
$includeContactIDs,
|
||||
FALSE,
|
||||
$justIDs,
|
||||
TRUE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
$this->buildACLClause('contact_a');
|
||||
$from = $this->_query->_fromClause;
|
||||
$from .= "{$this->_aclFrom}";
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
if ($whereClause = $this->_query->whereClause()) {
|
||||
if ($this->_aclWhere) {
|
||||
$whereClause .= " AND {$this->_aclWhere}";
|
||||
}
|
||||
return $whereClause;
|
||||
}
|
||||
return ' (1) ';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Basic.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CRM_Contact_BAO_Query
|
||||
*/
|
||||
public function getQueryObj() {
|
||||
return $this->_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,425 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_ContribSYBNT extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_formValues;
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
public $_permissionedComponent;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
$this->_formValues = self::formatSavedSearchFields($formValues);
|
||||
$this->_permissionedComponent = 'CiviContribute';
|
||||
|
||||
$this->_columns = array(
|
||||
ts('Contact ID') => 'contact_id',
|
||||
ts('Name') => 'display_name',
|
||||
ts('Contribution Count') => 'donation_count',
|
||||
ts('Contribution Amount') => 'donation_amount',
|
||||
);
|
||||
|
||||
$this->_amounts = array(
|
||||
'min_amount_1' => ts('Min Amount One'),
|
||||
'max_amount_1' => ts('Max Amount One'),
|
||||
'min_amount_2' => ts('Min Amount Two'),
|
||||
'max_amount_2' => ts('Max Amount Two'),
|
||||
'exclude_min_amount' => ts('Exclusion Min Amount'),
|
||||
'exclude_max_amount' => ts('Exclusion Max Amount'),
|
||||
);
|
||||
|
||||
$this->_dates = array(
|
||||
'start_date_1' => ts('Start Date One'),
|
||||
'end_date_1' => ts('End Date One'),
|
||||
'start_date_2' => ts('Start Date Two'),
|
||||
'end_date_2' => ts('End Date Two'),
|
||||
'exclude_start_date' => ts('Exclusion Start Date'),
|
||||
'exclude_end_date' => ts('Exclusion End Date'),
|
||||
);
|
||||
|
||||
$this->_checkboxes = array('is_first_amount' => ts('First Donation?'));
|
||||
|
||||
foreach ($this->_amounts as $name => $title) {
|
||||
$this->{$name} = CRM_Utils_Array::value($name, $this->_formValues);
|
||||
}
|
||||
|
||||
foreach ($this->_checkboxes as $name => $title) {
|
||||
$this->{$name} = CRM_Utils_Array::value($name, $this->_formValues, FALSE);
|
||||
}
|
||||
|
||||
foreach ($this->_dates as $name => $title) {
|
||||
if (!empty($this->_formValues[$name])) {
|
||||
$this->{$name} = $this->_formValues[$name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
|
||||
foreach ($this->_amounts as $name => $title) {
|
||||
$form->add('text',
|
||||
$name,
|
||||
$title
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($this->_dates as $name => $title) {
|
||||
$form->add('datepicker', $name, $title, array(), FALSE, array('time' => FALSE));
|
||||
}
|
||||
|
||||
foreach ($this->_checkboxes as $name => $title) {
|
||||
$form->add('checkbox',
|
||||
$name,
|
||||
$title
|
||||
);
|
||||
}
|
||||
|
||||
$this->setTitle('Contributions made in Year X and not Year Y');
|
||||
// @TODO: Decide on better names for "Exclusion"
|
||||
// @TODO: Add rule to ensure that exclusion dates are not in the inclusion range
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function count() {
|
||||
$sql = $this->all();
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql);
|
||||
return $dao->N;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL Not used; included for consistency with parent; SQL is always returned
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = TRUE) {
|
||||
return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0,
|
||||
$rowcount = 0,
|
||||
$sort = NULL,
|
||||
$includeContactIDs = FALSE,
|
||||
$justIDs = FALSE
|
||||
) {
|
||||
|
||||
$where = $this->where();
|
||||
if (!empty($where)) {
|
||||
$where = " AND $where";
|
||||
}
|
||||
|
||||
$having = $this->having();
|
||||
if ($having) {
|
||||
$having = " HAVING $having ";
|
||||
}
|
||||
|
||||
$from = $this->from();
|
||||
|
||||
$select = $this->select();
|
||||
if ($justIDs) {
|
||||
$select .= ', contact_a.id, display_name';
|
||||
}
|
||||
else {
|
||||
$select = "
|
||||
DISTINCT contact_a.id as contact_id,
|
||||
contact_a.display_name as display_name,
|
||||
$select ";
|
||||
}
|
||||
$this->buildACLClause('contact_a');
|
||||
$sql = "
|
||||
SELECT $select
|
||||
FROM civicrm_contact AS contact_a {$this->_aclFrom}
|
||||
LEFT JOIN civicrm_contribution contrib_1 ON contrib_1.contact_id = contact_a.id
|
||||
$from
|
||||
WHERE contrib_1.contact_id = contact_a.id
|
||||
AND contrib_1.is_test = 0
|
||||
$where
|
||||
GROUP BY contact_a.id
|
||||
$having
|
||||
ORDER BY donation_amount desc
|
||||
";
|
||||
|
||||
if ($justIDs) {
|
||||
CRM_Core_DAO::executeQuery("DROP TEMPORARY TABLE IF EXISTS CustomSearch_SYBNT_temp");
|
||||
$query = "CREATE TEMPORARY TABLE CustomSearch_SYBNT_temp AS ({$sql})";
|
||||
CRM_Core_DAO::executeQuery($query);
|
||||
$sql = "SELECT contact_a.id as contact_id FROM CustomSearch_SYBNT_temp as contact_a";
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function select() {
|
||||
if (!empty($this->start_date_2) || !empty($this->end_date_2)) {
|
||||
return "
|
||||
sum(contrib_1.total_amount) + sum(contrib_2.total_amount) AS donation_amount,
|
||||
count(contrib_1.id) + count(contrib_1.id) AS donation_count
|
||||
";
|
||||
}
|
||||
else {
|
||||
return "
|
||||
sum(contrib_1.total_amount) AS donation_amount,
|
||||
count(contrib_1.id) AS donation_count
|
||||
";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function from() {
|
||||
$from = NULL;
|
||||
if (!empty($this->start_date_2) || !empty($this->end_date_2)) {
|
||||
$from .= " LEFT JOIN civicrm_contribution contrib_2 ON contrib_2.contact_id = contact_a.id ";
|
||||
}
|
||||
|
||||
if (!empty($this->exclude_start_date) ||
|
||||
!empty($this->exclude_end_date) ||
|
||||
!empty($this->is_first_amount)
|
||||
) {
|
||||
$from .= " LEFT JOIN XG_CustomSearch_SYBNT xg ON xg.contact_id = contact_a.id ";
|
||||
}
|
||||
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$clauses = array();
|
||||
|
||||
if (!empty($this->start_date_1)) {
|
||||
$clauses[] = CRM_Core_DAO::composeQuery('contrib_1.receive_date >= %1', array(1 => array($this->start_date_1, 'String')));
|
||||
}
|
||||
|
||||
if (!empty($this->end_date_1)) {
|
||||
$clauses[] = CRM_Core_DAO::composeQuery('contrib_1.receive_date <= %1', array(1 => array($this->end_date_1, 'String')));
|
||||
}
|
||||
|
||||
if (!empty($this->start_date_2) || !empty($this->end_date_2)) {
|
||||
$clauses[] = "contrib_2.is_test = 0";
|
||||
|
||||
if (!empty($this->start_date_2)) {
|
||||
$clauses[] = CRM_Core_DAO::composeQuery('contrib_2.receive_date >= %1', array(1 => array($this->start_date_2, 'String')));
|
||||
}
|
||||
|
||||
if (!empty($this->end_date_2)) {
|
||||
$clauses[] = CRM_Core_DAO::composeQuery('contrib_2.receive_date <= %1', array(1 => array($this->end_date_2, 'String')));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->exclude_start_date) ||
|
||||
!empty($this->exclude_end_date) ||
|
||||
!empty($this->is_first_amount)
|
||||
) {
|
||||
|
||||
// first create temp table to store contact ids
|
||||
$sql = "DROP TEMPORARY TABLE IF EXISTS XG_CustomSearch_SYBNT";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
$sql = "CREATE TEMPORARY TABLE XG_CustomSearch_SYBNT ( contact_id int primary key) ENGINE=HEAP";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
$excludeClauses = array();
|
||||
if ($this->exclude_start_date) {
|
||||
$excludeClauses[] = CRM_Core_DAO::composeQuery('c.receive_date >= %1', array(1 => array($this->exclude_start_date, 'String')));
|
||||
}
|
||||
|
||||
if ($this->exclude_end_date) {
|
||||
$excludeClauses[] = CRM_Core_DAO::composeQuery('c.receive_date <= %1', array(1 => array($this->exclude_end_date, 'String')));
|
||||
}
|
||||
|
||||
$excludeClause = NULL;
|
||||
if ($excludeClauses) {
|
||||
$excludeClause = ' AND ' . implode(' AND ', $excludeClauses);
|
||||
}
|
||||
|
||||
$having = array();
|
||||
if ($this->exclude_min_amount) {
|
||||
$having[] = "sum(c.total_amount) >= {$this->exclude_min_amount}";
|
||||
}
|
||||
|
||||
if ($this->exclude_max_amount) {
|
||||
$having[] = "sum(c.total_amount) <= {$this->exclude_max_amount}";
|
||||
}
|
||||
|
||||
$havingClause = NULL;
|
||||
if (!empty($having)) {
|
||||
$havingClause = "HAVING " . implode(' AND ', $having);
|
||||
}
|
||||
|
||||
if ($excludeClause || $havingClause) {
|
||||
// Run subquery
|
||||
$query = "
|
||||
REPLACE INTO XG_CustomSearch_SYBNT
|
||||
SELECT DISTINCT contact_id AS contact_id
|
||||
FROM civicrm_contribution c
|
||||
WHERE c.is_test = 0
|
||||
$excludeClause
|
||||
GROUP BY c.contact_id
|
||||
$havingClause
|
||||
";
|
||||
|
||||
CRM_Core_DAO::executeQuery($query);
|
||||
}
|
||||
|
||||
// now ensure we dont consider donors that are not first time
|
||||
if ($this->is_first_amount) {
|
||||
$query = "
|
||||
REPLACE INTO XG_CustomSearch_SYBNT
|
||||
SELECT DISTINCT contact_id AS contact_id
|
||||
FROM civicrm_contribution c
|
||||
WHERE c.is_test = 0
|
||||
AND c.receive_date < {$this->start_date_1}
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($query);
|
||||
}
|
||||
|
||||
$clauses[] = " xg.contact_id IS NULL ";
|
||||
}
|
||||
if ($this->_aclWhere) {
|
||||
$clauses[] .= " {$this->_aclWhere} ";
|
||||
}
|
||||
return implode(' AND ', $clauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function having($includeContactIDs = FALSE) {
|
||||
$clauses = array();
|
||||
$min = CRM_Utils_Array::value('min_amount', $this->_formValues);
|
||||
if ($min) {
|
||||
$clauses[] = "sum(contrib_1.total_amount) >= $min";
|
||||
}
|
||||
|
||||
$max = CRM_Utils_Array::value('max_amount', $this->_formValues);
|
||||
if ($max) {
|
||||
$clauses[] = "sum(contrib_1.total_amount) <= $max";
|
||||
}
|
||||
|
||||
return implode(' AND ', $clauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function &columns() {
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom/ContribSYBNT.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function summary() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format saved search fields for this custom group
|
||||
*
|
||||
* @param array $formValues
|
||||
*
|
||||
*/
|
||||
public static function formatSavedSearchFields(&$formValues) {
|
||||
$dateFields = array(
|
||||
'start_date_1',
|
||||
'end_date_1',
|
||||
'start_date_2',
|
||||
'end_date_2',
|
||||
'exclude_start_date',
|
||||
'exclude_end_date',
|
||||
);
|
||||
foreach ($formValues as $element => $value) {
|
||||
if (in_array($element, $dateFields) && !empty($value)) {
|
||||
$formValues[$element] = date('Y-m-d', strtotime($value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,328 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_ContributionAggregate extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_formValues;
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
public $_permissionedComponent;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
$this->_formValues = $formValues;
|
||||
|
||||
// Define the columns for search result rows
|
||||
$this->_columns = array(
|
||||
ts('Contact ID') => 'contact_id',
|
||||
ts('Name') => 'sort_name',
|
||||
ts('Contribution Count') => 'donation_count',
|
||||
ts('Contribution Amount') => 'donation_amount',
|
||||
);
|
||||
|
||||
// define component access permission needed
|
||||
$this->_permissionedComponent = 'CiviContribute';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build form.
|
||||
*
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
|
||||
/**
|
||||
* You can define a custom title for the search form
|
||||
*/
|
||||
$this->setTitle('Find Contributors by Aggregate Totals');
|
||||
|
||||
/**
|
||||
* Define the search form fields here
|
||||
*/
|
||||
$form->add('text',
|
||||
'min_amount',
|
||||
ts('Aggregate Total Between $')
|
||||
);
|
||||
$form->addRule('min_amount', ts('Please enter a valid amount (numbers and decimal point only).'), 'money');
|
||||
|
||||
$form->add('text',
|
||||
'max_amount',
|
||||
ts('...and $')
|
||||
);
|
||||
$form->addRule('max_amount', ts('Please enter a valid amount (numbers and decimal point only).'), 'money');
|
||||
CRM_Core_Form_Date::buildDateRange($form, 'contribution_date', 1, '_low', '_high', ts('From:'), FALSE, FALSE);
|
||||
|
||||
$form->addSelect('financial_type_id',
|
||||
array('entity' => 'contribution', 'multiple' => 'multiple', 'context' => 'search')
|
||||
);
|
||||
|
||||
/**
|
||||
* If you are using the sample template, this array tells the template fields to render
|
||||
* for the search form.
|
||||
*/
|
||||
$form->assign('elements', array('min_amount', 'max_amount'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the smarty template used to layout the search form and results listings.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom/ContributionAggregate.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the search query.
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param string|object $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0, $rowcount = 0, $sort = NULL,
|
||||
$includeContactIDs = FALSE, $justIDs = FALSE
|
||||
) {
|
||||
|
||||
// SELECT clause must include contact_id as an alias for civicrm_contact.id
|
||||
if ($justIDs) {
|
||||
$select = "contact_a.id as contact_id";
|
||||
}
|
||||
else {
|
||||
$select = "
|
||||
DISTINCT contact_a.id as contact_id,
|
||||
contact_a.sort_name as sort_name,
|
||||
sum(contrib.total_amount) AS donation_amount,
|
||||
count(contrib.id) AS donation_count
|
||||
";
|
||||
}
|
||||
$from = $this->from();
|
||||
|
||||
$where = $this->where($includeContactIDs);
|
||||
|
||||
$having = $this->having();
|
||||
if ($having) {
|
||||
$having = " HAVING $having ";
|
||||
}
|
||||
|
||||
$sql = "
|
||||
SELECT $select
|
||||
FROM $from
|
||||
WHERE $where
|
||||
GROUP BY contact_a.id
|
||||
$having
|
||||
";
|
||||
//for only contact ids ignore order.
|
||||
if (!$justIDs) {
|
||||
// Define ORDER BY for query in $sort, with default value
|
||||
if (!empty($sort)) {
|
||||
if (is_string($sort)) {
|
||||
$sort = CRM_Utils_Type::escape($sort, 'String');
|
||||
$sql .= " ORDER BY $sort ";
|
||||
}
|
||||
else {
|
||||
$sql .= " ORDER BY " . trim($sort->orderBy());
|
||||
}
|
||||
}
|
||||
else {
|
||||
$sql .= "ORDER BY donation_amount desc";
|
||||
}
|
||||
}
|
||||
|
||||
if ($rowcount > 0 && $offset >= 0) {
|
||||
$offset = CRM_Utils_Type::escape($offset, 'Int');
|
||||
$rowcount = CRM_Utils_Type::escape($rowcount, 'Int');
|
||||
$sql .= " LIMIT $offset, $rowcount ";
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
$this->buildACLClause('contact_a');
|
||||
$from = "
|
||||
civicrm_contribution AS contrib,
|
||||
civicrm_contact AS contact_a {$this->_aclFrom}
|
||||
";
|
||||
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* WHERE clause is an array built from any required JOINS plus conditional filters based on search criteria field values.
|
||||
*
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$clauses = array(
|
||||
"contrib.contact_id = contact_a.id",
|
||||
"contrib.is_test = 0",
|
||||
);
|
||||
|
||||
$dateParams = array(
|
||||
'contribution_date_relative' => $this->_formValues['contribution_date_relative'],
|
||||
'contribution_date_low' => $this->_formValues['contribution_date_low'],
|
||||
'contribution_date_high' => $this->_formValues['contribution_date_high'],
|
||||
);
|
||||
foreach (CRM_Contact_BAO_Query::convertFormValues($dateParams) as $values) {
|
||||
list($name, $op, $value) = $values;
|
||||
if (strstr($name, '_low')) {
|
||||
$clauses[] = "contrib.receive_date >= " . CRM_Utils_Date::processDate($value);
|
||||
}
|
||||
else {
|
||||
$clauses[] = "contrib.receive_date <= " . CRM_Utils_Date::processDate($value);
|
||||
}
|
||||
}
|
||||
|
||||
if ($includeContactIDs) {
|
||||
$contactIDs = array();
|
||||
foreach ($this->_formValues as $id => $value) {
|
||||
if ($value &&
|
||||
substr($id, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX
|
||||
) {
|
||||
$contactIDs[] = substr($id, CRM_Core_Form::CB_PREFIX_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($contactIDs)) {
|
||||
$contactIDs = implode(', ', $contactIDs);
|
||||
$clauses[] = "contact_a.id IN ( $contactIDs )";
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->_formValues['financial_type_id'])) {
|
||||
$financial_type_ids = implode(',', array_values($this->_formValues['financial_type_id']));
|
||||
$clauses[] = "contrib.financial_type_id IN ($financial_type_ids)";
|
||||
}
|
||||
if ($this->_aclWhere) {
|
||||
$clauses[] = " {$this->_aclWhere} ";
|
||||
}
|
||||
|
||||
return implode(' AND ', $clauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function having($includeContactIDs = FALSE) {
|
||||
$clauses = array();
|
||||
$min = CRM_Utils_Array::value('min_amount', $this->_formValues);
|
||||
if ($min) {
|
||||
$min = CRM_Utils_Rule::cleanMoney($min);
|
||||
$clauses[] = "sum(contrib.total_amount) >= $min";
|
||||
}
|
||||
|
||||
$max = CRM_Utils_Array::value('max_amount', $this->_formValues);
|
||||
if ($max) {
|
||||
$max = CRM_Utils_Rule::cleanMoney($max);
|
||||
$clauses[] = "sum(contrib.total_amount) <= $max";
|
||||
}
|
||||
|
||||
return implode(' AND ', $clauses);
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions below generally don't need to be modified
|
||||
*/
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function count() {
|
||||
$sql = $this->all();
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql,
|
||||
CRM_Core_DAO::$_nullArray
|
||||
);
|
||||
return $dao->N;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL Not used; included for consistency with parent; SQL is always returned
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = TRUE) {
|
||||
return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function &columns() {
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function summary() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,458 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_DateAdded extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_debug = 0;
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
parent::__construct($formValues);
|
||||
|
||||
$this->_includeGroups = CRM_Utils_Array::value('includeGroups', $formValues, array());
|
||||
$this->_excludeGroups = CRM_Utils_Array::value('excludeGroups', $formValues, array());
|
||||
|
||||
$this->_columns = array(
|
||||
ts('Contact ID') => 'contact_id',
|
||||
ts('Contact Type') => 'contact_type',
|
||||
ts('Name') => 'sort_name',
|
||||
ts('Date Added') => 'date_added',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
$form->addDate('start_date', ts('Start Date'), FALSE, array('formatType' => 'custom'));
|
||||
$form->addDate('end_date', ts('End Date'), FALSE, array('formatType' => 'custom'));
|
||||
|
||||
$groups = CRM_Core_PseudoConstant::nestedGroup();
|
||||
|
||||
$select2style = array(
|
||||
'multiple' => TRUE,
|
||||
'style' => 'width: 100%; max-width: 60em;',
|
||||
'class' => 'crm-select2',
|
||||
'placeholder' => ts('- select -'),
|
||||
);
|
||||
|
||||
$form->add('select', 'includeGroups',
|
||||
ts('Include Group(s)'),
|
||||
$groups,
|
||||
FALSE,
|
||||
$select2style
|
||||
);
|
||||
|
||||
$form->add('select', 'excludeGroups',
|
||||
ts('Exclude Group(s)'),
|
||||
$groups,
|
||||
FALSE,
|
||||
$select2style
|
||||
);
|
||||
|
||||
$this->setTitle('Search by date added to CiviCRM');
|
||||
|
||||
//redirect if group not available for search criteria
|
||||
if (count($groups) == 0) {
|
||||
CRM_Core_Error::statusBounce(ts("Atleast one Group must be present for search."),
|
||||
CRM_Utils_System::url('civicrm/contact/search/custom/list',
|
||||
'reset=1'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* if you are using the standard template, this array tells the template what elements
|
||||
* are part of the search criteria
|
||||
*/
|
||||
$form->assign('elements', array('start_date', 'end_date', 'includeGroups', 'excludeGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function summary() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = FALSE) {
|
||||
return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0, $rowcount = 0, $sort = NULL,
|
||||
$includeContactIDs = FALSE, $justIDs = FALSE
|
||||
) {
|
||||
|
||||
$this->_includeGroups = CRM_Utils_Array::value('includeGroups', $this->_formValues, array());
|
||||
|
||||
$this->_excludeGroups = CRM_Utils_Array::value('excludeGroups', $this->_formValues, array());
|
||||
|
||||
$this->_allSearch = FALSE;
|
||||
$this->_groups = FALSE;
|
||||
|
||||
if (empty($this->_includeGroups) && empty($this->_excludeGroups)) {
|
||||
//empty search
|
||||
$this->_allSearch = TRUE;
|
||||
}
|
||||
|
||||
if (!empty($this->_includeGroups) || !empty($this->_excludeGroups)) {
|
||||
//group(s) selected
|
||||
$this->_groups = TRUE;
|
||||
}
|
||||
|
||||
if ($justIDs) {
|
||||
$selectClause = "contact_a.id as contact_id";
|
||||
$groupBy = " GROUP BY contact_a.id";
|
||||
$sort = "contact_a.id";
|
||||
}
|
||||
else {
|
||||
$selectClause = "contact_a.id as contact_id,
|
||||
contact_a.contact_type as contact_type,
|
||||
contact_a.sort_name as sort_name,
|
||||
d.date_added as date_added";
|
||||
$groupBy = " GROUP BY contact_id ";
|
||||
}
|
||||
|
||||
return $this->sql($selectClause,
|
||||
$offset, $rowcount, $sort,
|
||||
$includeContactIDs, $groupBy
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
//define table name
|
||||
$randomNum = md5(uniqid());
|
||||
$this->_tableName = "civicrm_temp_custom_{$randomNum}";
|
||||
|
||||
//grab the contacts added in the date range first
|
||||
$sql = "CREATE TEMPORARY TABLE dates_{$this->_tableName} ( id int primary key, date_added date ) ENGINE=HEAP";
|
||||
if ($this->_debug > 0) {
|
||||
print "-- Date range query: <pre>";
|
||||
print "$sql;";
|
||||
print "</pre>";
|
||||
}
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
$startDate = CRM_Utils_Date::mysqlToIso(CRM_Utils_Date::processDate($this->_formValues['start_date']));
|
||||
$endDateFix = NULL;
|
||||
if (!empty($this->_formValues['end_date'])) {
|
||||
$endDate = CRM_Utils_Date::mysqlToIso(CRM_Utils_Date::processDate($this->_formValues['end_date']));
|
||||
# tack 11:59pm on to make search inclusive of the end date
|
||||
$endDateFix = "AND date_added <= '" . substr($endDate, 0, 10) . " 23:59:00'";
|
||||
}
|
||||
|
||||
$dateRange = "INSERT INTO dates_{$this->_tableName} ( id, date_added )
|
||||
SELECT
|
||||
civicrm_contact.id,
|
||||
min(civicrm_log.modified_date) AS date_added
|
||||
FROM
|
||||
civicrm_contact LEFT JOIN civicrm_log
|
||||
ON (civicrm_contact.id = civicrm_log.entity_id AND
|
||||
civicrm_log.entity_table = 'civicrm_contact')
|
||||
GROUP BY
|
||||
civicrm_contact.id
|
||||
HAVING
|
||||
date_added >= '$startDate'
|
||||
$endDateFix";
|
||||
|
||||
if ($this->_debug > 0) {
|
||||
print "-- Date range query: <pre>";
|
||||
print "$dateRange;";
|
||||
print "</pre>";
|
||||
}
|
||||
|
||||
CRM_Core_DAO::executeQuery($dateRange, CRM_Core_DAO::$_nullArray);
|
||||
|
||||
// Only include groups in the search query of one or more Include OR Exclude groups has been selected.
|
||||
// CRM-6356
|
||||
if ($this->_groups) {
|
||||
//block for Group search
|
||||
$smartGroup = array();
|
||||
$group = new CRM_Contact_DAO_Group();
|
||||
$group->is_active = 1;
|
||||
$group->find();
|
||||
while ($group->fetch()) {
|
||||
$allGroups[] = $group->id;
|
||||
if ($group->saved_search_id) {
|
||||
$smartGroup[$group->saved_search_id] = $group->id;
|
||||
}
|
||||
}
|
||||
$includedGroups = implode(',', $allGroups);
|
||||
|
||||
if (!empty($this->_includeGroups)) {
|
||||
$iGroups = implode(',', $this->_includeGroups);
|
||||
}
|
||||
else {
|
||||
//if no group selected search for all groups
|
||||
$iGroups = $includedGroups;
|
||||
}
|
||||
if (is_array($this->_excludeGroups)) {
|
||||
$xGroups = implode(',', $this->_excludeGroups);
|
||||
}
|
||||
else {
|
||||
$xGroups = 0;
|
||||
}
|
||||
|
||||
$sql = "DROP TEMPORARY TABLE IF EXISTS Xg_{$this->_tableName}";
|
||||
CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray);
|
||||
$sql = "CREATE TEMPORARY TABLE Xg_{$this->_tableName} ( contact_id int primary key) ENGINE=HEAP";
|
||||
CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray);
|
||||
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$excludeGroup = "INSERT INTO Xg_{$this->_tableName} ( contact_id )
|
||||
SELECT DISTINCT civicrm_group_contact.contact_id
|
||||
FROM civicrm_group_contact, dates_{$this->_tableName} AS d
|
||||
WHERE
|
||||
d.id = civicrm_group_contact.contact_id AND
|
||||
civicrm_group_contact.status = 'Added' AND
|
||||
civicrm_group_contact.group_id IN( {$xGroups})";
|
||||
|
||||
CRM_Core_DAO::executeQuery($excludeGroup, CRM_Core_DAO::$_nullArray);
|
||||
|
||||
//search for smart group contacts
|
||||
foreach ($this->_excludeGroups as $keys => $values) {
|
||||
if (in_array($values, $smartGroup)) {
|
||||
$ssId = CRM_Utils_Array::key($values, $smartGroup);
|
||||
|
||||
$smartSql = CRM_Contact_BAO_SavedSearch::contactIDsSQL($ssId);
|
||||
|
||||
$smartSql = $smartSql . " AND contact_a.id NOT IN (
|
||||
SELECT contact_id FROM civicrm_group_contact
|
||||
WHERE civicrm_group_contact.group_id = {$values} AND civicrm_group_contact.status = 'Removed')";
|
||||
|
||||
$smartGroupQuery = " INSERT IGNORE INTO Xg_{$this->_tableName}(contact_id) $smartSql";
|
||||
|
||||
CRM_Core_DAO::executeQuery($smartGroupQuery, CRM_Core_DAO::$_nullArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "DROP TEMPORARY TABLE IF EXISTS Ig_{$this->_tableName}";
|
||||
CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray);
|
||||
$sql = "CREATE TEMPORARY TABLE Ig_{$this->_tableName}
|
||||
( id int PRIMARY KEY AUTO_INCREMENT,
|
||||
contact_id int,
|
||||
group_names varchar(64)) ENGINE=HEAP";
|
||||
|
||||
if ($this->_debug > 0) {
|
||||
print "-- Include groups query: <pre>";
|
||||
print "$sql;";
|
||||
print "</pre>";
|
||||
}
|
||||
|
||||
CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray);
|
||||
|
||||
$includeGroup = "INSERT INTO Ig_{$this->_tableName} (contact_id, group_names)
|
||||
SELECT d.id as contact_id, civicrm_group.name as group_name
|
||||
FROM dates_{$this->_tableName} AS d
|
||||
INNER JOIN civicrm_group_contact
|
||||
ON civicrm_group_contact.contact_id = d.id
|
||||
LEFT JOIN civicrm_group
|
||||
ON civicrm_group_contact.group_id = civicrm_group.id";
|
||||
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$includeGroup .= " LEFT JOIN Xg_{$this->_tableName}
|
||||
ON d.id = Xg_{$this->_tableName}.contact_id";
|
||||
}
|
||||
$includeGroup .= " WHERE
|
||||
civicrm_group_contact.status = 'Added' AND
|
||||
civicrm_group_contact.group_id IN($iGroups)";
|
||||
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$includeGroup .= " AND Xg_{$this->_tableName}.contact_id IS null";
|
||||
}
|
||||
|
||||
if ($this->_debug > 0) {
|
||||
print "-- Include groups query: <pre>";
|
||||
print "$includeGroup;";
|
||||
print "</pre>";
|
||||
}
|
||||
|
||||
CRM_Core_DAO::executeQuery($includeGroup, CRM_Core_DAO::$_nullArray);
|
||||
|
||||
//search for smart group contacts
|
||||
foreach ($this->_includeGroups as $keys => $values) {
|
||||
if (in_array($values, $smartGroup)) {
|
||||
|
||||
$ssId = CRM_Utils_Array::key($values, $smartGroup);
|
||||
|
||||
$smartSql = CRM_Contact_BAO_SavedSearch::contactIDsSQL($ssId);
|
||||
|
||||
$smartSql .= " AND contact_a.id IN (
|
||||
SELECT id AS contact_id
|
||||
FROM dates_{$this->_tableName} )";
|
||||
|
||||
$smartSql .= " AND contact_a.id NOT IN (
|
||||
SELECT contact_id FROM civicrm_group_contact
|
||||
WHERE civicrm_group_contact.group_id = {$values} AND civicrm_group_contact.status = 'Removed')";
|
||||
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$smartSql .= " AND contact_a.id NOT IN (SELECT contact_id FROM Xg_{$this->_tableName})";
|
||||
}
|
||||
|
||||
$smartGroupQuery = " INSERT IGNORE INTO
|
||||
Ig_{$this->_tableName}(contact_id)
|
||||
$smartSql";
|
||||
|
||||
CRM_Core_DAO::executeQuery($smartGroupQuery, CRM_Core_DAO::$_nullArray);
|
||||
if ($this->_debug > 0) {
|
||||
print "-- Smart group query: <pre>";
|
||||
print "$smartGroupQuery;";
|
||||
print "</pre>";
|
||||
}
|
||||
$insertGroupNameQuery = "UPDATE IGNORE Ig_{$this->_tableName}
|
||||
SET group_names = (SELECT title FROM civicrm_group
|
||||
WHERE civicrm_group.id = $values)
|
||||
WHERE Ig_{$this->_tableName}.contact_id IS NOT NULL
|
||||
AND Ig_{$this->_tableName}.group_names IS NULL";
|
||||
CRM_Core_DAO::executeQuery($insertGroupNameQuery, CRM_Core_DAO::$_nullArray);
|
||||
if ($this->_debug > 0) {
|
||||
print "-- Smart group query: <pre>";
|
||||
print "$insertGroupNameQuery;";
|
||||
print "</pre>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end if( $this->_groups ) condition
|
||||
$this->buildACLClause('contact_a');
|
||||
$from = "FROM civicrm_contact contact_a";
|
||||
|
||||
/* We need to join to this again to get the date_added value */
|
||||
|
||||
$from .= " INNER JOIN dates_{$this->_tableName} d ON (contact_a.id = d.id) {$this->_aclFrom}";
|
||||
|
||||
// Only include groups in the search query of one or more Include OR Exclude groups has been selected.
|
||||
// CRM-6356
|
||||
if ($this->_groups) {
|
||||
$from .= " INNER JOIN Ig_{$this->_tableName} temptable1 ON (contact_a.id = temptable1.contact_id)";
|
||||
}
|
||||
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$where = '(1)';
|
||||
if ($this->_aclWhere) {
|
||||
$where .= " AND {$this->_aclWhere} ";
|
||||
}
|
||||
return $where;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function count() {
|
||||
$sql = $this->all();
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql,
|
||||
CRM_Core_DAO::$_nullArray
|
||||
);
|
||||
return $dao->N;
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
//drop the temp. tables if they exist
|
||||
if (!empty($this->_includeGroups)) {
|
||||
$sql = "DROP TEMPORARY TABLE IF EXISTS Ig_{$this->_tableName}";
|
||||
CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray);
|
||||
}
|
||||
|
||||
if (!empty($this->_excludeGroups)) {
|
||||
$sql = "DROP TEMPORARY TABLE IF EXISTS Xg_{$this->_tableName}";
|
||||
CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,377 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_EventAggregate extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_formValues;
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
public $_permissionedComponent;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
$this->_formValues = $formValues;
|
||||
$this->_permissionedComponent = array('CiviContribute', 'CiviEvent');
|
||||
|
||||
/**
|
||||
* Define the columns for search result rows
|
||||
*/
|
||||
$this->_columns = array(
|
||||
ts('Event') => 'event_name',
|
||||
ts('Type') => 'event_type',
|
||||
ts('Number of<br />Participant') => 'participant_count',
|
||||
ts('Total Payment') => 'payment_amount',
|
||||
ts('Fee') => 'fee',
|
||||
ts('Net Payment') => 'net_payment',
|
||||
ts('Participant') => 'participant',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
|
||||
/**
|
||||
* You can define a custom title for the search form
|
||||
*/
|
||||
$this->setTitle('Find Totals for Events');
|
||||
|
||||
/**
|
||||
* Define the search form fields here
|
||||
*/
|
||||
|
||||
$form->addElement('checkbox', 'paid_online', ts('Only show Credit Card Payments'));
|
||||
|
||||
$form->addElement('checkbox', 'show_payees', ts('Show payees'));
|
||||
|
||||
$event_type = CRM_Core_OptionGroup::values('event_type', FALSE);
|
||||
foreach ($event_type as $eventId => $eventName) {
|
||||
$form->addElement('checkbox', "event_type_id[$eventId]", 'Event Type', $eventName);
|
||||
}
|
||||
$events = CRM_Event_BAO_Event::getEvents(1);
|
||||
$form->add('select', 'event_id', ts('Event Name'), array('' => ts('- select -')) + $events);
|
||||
|
||||
$form->addDate('start_date', ts('Payments Date From'), FALSE, array('formatType' => 'custom'));
|
||||
$form->addDate('end_date', ts('...through'), FALSE, array('formatType' => 'custom'));
|
||||
|
||||
/**
|
||||
* If you are using the sample template, this array tells the template fields to render
|
||||
* for the search form.
|
||||
*/
|
||||
$form->assign('elements', array(
|
||||
'paid_online',
|
||||
'start_date',
|
||||
'end_date',
|
||||
'show_payees',
|
||||
'event_type_id',
|
||||
'event_id',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the smarty template used to layout the search form and results listings.
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom/EventDetails.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the search query.
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0, $rowcount = 0, $sort = NULL,
|
||||
$includeContactIDs = FALSE, $justIDs = FALSE
|
||||
) {
|
||||
// SELECT clause must include contact_id as an alias for civicrm_contact.id if you are going to use "tasks" like export etc.
|
||||
$select = "civicrm_participant.event_id as event_id,
|
||||
COUNT(civicrm_participant.id) as participant_count,
|
||||
GROUP_CONCAT(DISTINCT(civicrm_event.title)) as event_name,
|
||||
civicrm_event.event_type_id as event_type_id,
|
||||
civicrm_option_value.label as event_type,
|
||||
IF(civicrm_contribution.payment_instrument_id <>0 , 'Yes', 'No') as payment_instrument_id,
|
||||
SUM(civicrm_contribution.total_amount) as payment_amount,
|
||||
format(sum(if(civicrm_contribution.payment_instrument_id <>0,(civicrm_contribution.total_amount *.034) +.45,0)),2) as fee,
|
||||
format(sum(civicrm_contribution.total_amount - (if(civicrm_contribution.payment_instrument_id <>0,(civicrm_contribution.total_amount *.034) +.45,0))),2) as net_payment";
|
||||
|
||||
$from = $this->from();
|
||||
|
||||
$onLine = CRM_Utils_Array::value('paid_online',
|
||||
$this->_formValues
|
||||
);
|
||||
if ($onLine) {
|
||||
$from .= "
|
||||
inner join civicrm_entity_financial_trxn
|
||||
on (civicrm_entity_financial_trxn.entity_id = civicrm_participant_payment.contribution_id and civicrm_entity_financial_trxn.entity_table='civicrm_contribution')";
|
||||
}
|
||||
|
||||
$showPayees = CRM_Utils_Array::value('show_payees',
|
||||
$this->_formValues
|
||||
);
|
||||
if ($showPayees) {
|
||||
$select .= ", GROUP_CONCAT(DISTINCT(civicrm_contact.display_name)) as participant ";
|
||||
$from .= " inner join civicrm_contact
|
||||
on civicrm_contact.id = civicrm_participant.contact_id";
|
||||
}
|
||||
else {
|
||||
unset($this->_columns[ts('Participant')]);
|
||||
}
|
||||
|
||||
$where = $this->where();
|
||||
$groupFromSelect = "civicrm_option_value.label, civicrm_contribution.payment_instrument_id";
|
||||
|
||||
$groupBy = "event_id, event_type_id, {$groupFromSelect}";
|
||||
if (!empty($this->_formValues['event_type_id'])) {
|
||||
$groupBy = "event_type_id, event_id, {$groupFromSelect}";
|
||||
}
|
||||
|
||||
$sql = "
|
||||
SELECT $select
|
||||
FROM $from
|
||||
WHERE $where
|
||||
GROUP BY $groupBy
|
||||
";
|
||||
// Define ORDER BY for query in $sort, with default value
|
||||
if (!empty($sort)) {
|
||||
if (is_string($sort)) {
|
||||
$sql .= " ORDER BY $sort ";
|
||||
}
|
||||
else {
|
||||
$sql .= " ORDER BY " . trim($sort->orderBy());
|
||||
}
|
||||
}
|
||||
else {
|
||||
$sql .= "ORDER BY event_name desc";
|
||||
}
|
||||
|
||||
if ($rowcount > 0 && $offset >= 0) {
|
||||
$offset = CRM_Utils_Type::escape($offset, 'Int');
|
||||
$rowcount = CRM_Utils_Type::escape($rowcount, 'Int');
|
||||
$sql .= " LIMIT $offset, $rowcount ";
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
$this->buildACLClause('contact_a');
|
||||
$from = "
|
||||
civicrm_participant_payment
|
||||
left join civicrm_participant
|
||||
on civicrm_participant_payment.participant_id=civicrm_participant.id
|
||||
|
||||
left join civicrm_contact contact_a
|
||||
on civicrm_participant.contact_id = contact_a.id
|
||||
|
||||
left join civicrm_event on
|
||||
civicrm_participant.event_id = civicrm_event.id
|
||||
|
||||
left join civicrm_contribution
|
||||
on civicrm_contribution.id = civicrm_participant_payment.contribution_id
|
||||
|
||||
left join civicrm_option_value on
|
||||
( civicrm_option_value.value = civicrm_event.event_type_id AND civicrm_option_value.option_group_id = 14) {$this->_aclFrom}";
|
||||
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* WHERE clause is an array built from any required JOINS plus conditional filters based on search criteria field values.
|
||||
*
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$clauses = array();
|
||||
|
||||
$clauses[] = "civicrm_participant.status_id in ( 1 )";
|
||||
$clauses[] = "civicrm_contribution.is_test = 0";
|
||||
$onLine = CRM_Utils_Array::value('paid_online',
|
||||
$this->_formValues
|
||||
);
|
||||
if ($onLine) {
|
||||
$clauses[] = "civicrm_contribution.payment_instrument_id <> 0";
|
||||
}
|
||||
|
||||
$startDate = CRM_Utils_Date::processDate($this->_formValues['start_date']);
|
||||
if ($startDate) {
|
||||
$clauses[] = "civicrm_contribution.receive_date >= $startDate";
|
||||
}
|
||||
|
||||
$endDate = CRM_Utils_Date::processDate($this->_formValues['end_date']);
|
||||
if ($endDate) {
|
||||
$clauses[] = "civicrm_contribution.receive_date <= {$endDate}235959";
|
||||
}
|
||||
|
||||
if (!empty($this->_formValues['event_id'])) {
|
||||
$clauses[] = "civicrm_event.id = {$this->_formValues['event_id']}";
|
||||
}
|
||||
|
||||
if ($includeContactIDs) {
|
||||
$contactIDs = array();
|
||||
foreach ($this->_formValues as $id => $value) {
|
||||
if ($value &&
|
||||
substr($id, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX
|
||||
) {
|
||||
$contactIDs[] = substr($id, CRM_Core_Form::CB_PREFIX_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($contactIDs)) {
|
||||
$contactIDs = implode(', ', $contactIDs);
|
||||
$clauses[] = "contact.id IN ( $contactIDs )";
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->_formValues['event_type_id'])) {
|
||||
$event_type_ids = implode(',', array_keys($this->_formValues['event_type_id']));
|
||||
$clauses[] = "civicrm_event.event_type_id IN ( $event_type_ids )";
|
||||
}
|
||||
if ($this->_aclWhere) {
|
||||
$clauses[] = "{$this->_aclWhere} ";
|
||||
}
|
||||
return implode(' AND ', $clauses);
|
||||
}
|
||||
|
||||
|
||||
/* This function does a query to get totals for some of the search result columns and returns a totals array. */
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function summary() {
|
||||
$totalSelect = "
|
||||
SUM(civicrm_contribution.total_amount) as payment_amount,COUNT(civicrm_participant.id) as participant_count,
|
||||
format(sum(if(civicrm_contribution.payment_instrument_id <>0,(civicrm_contribution.total_amount *.034) +.45,0)),2) as fee,
|
||||
format(sum(civicrm_contribution.total_amount - (if(civicrm_contribution.payment_instrument_id <>0,(civicrm_contribution.total_amount *.034) +.45,0))),2) as net_payment";
|
||||
|
||||
$from = $this->from();
|
||||
|
||||
$onLine = CRM_Utils_Array::value('paid_online',
|
||||
$this->_formValues
|
||||
);
|
||||
if ($onLine) {
|
||||
$from .= "
|
||||
inner join civicrm_entity_financial_trxn
|
||||
on (civicrm_entity_financial_trxn.entity_id = civicrm_participant_payment.contribution_id and civicrm_entity_financial_trxn.entity_table='civicrm_contribution')";
|
||||
}
|
||||
|
||||
$where = $this->where();
|
||||
|
||||
$sql = "
|
||||
SELECT $totalSelect
|
||||
FROM $from
|
||||
WHERE $where
|
||||
";
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql,
|
||||
CRM_Core_DAO::$_nullArray
|
||||
);
|
||||
$totals = array();
|
||||
while ($dao->fetch()) {
|
||||
$totals['payment_amount'] = $dao->payment_amount;
|
||||
$totals['fee'] = $dao->fee;
|
||||
$totals['net_payment'] = $dao->net_payment;
|
||||
$totals['participant_count'] = $dao->participant_count;
|
||||
}
|
||||
return $totals;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions below generally don't need to be modified
|
||||
*/
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function count() {
|
||||
$sql = $this->all();
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql,
|
||||
CRM_Core_DAO::$_nullArray
|
||||
);
|
||||
return $dao->N;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL Not used; included for consistency with parent; SQL is always returned
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = TRUE) {
|
||||
return $this->all($offset, $rowcount, $sort);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function &columns() {
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,554 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_FullText extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
const LIMIT = 10;
|
||||
|
||||
/**
|
||||
* @var array CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery
|
||||
*/
|
||||
protected $_partialQueries = NULL;
|
||||
|
||||
protected $_formValues;
|
||||
|
||||
protected $_columns;
|
||||
|
||||
protected $_text = NULL;
|
||||
|
||||
protected $_table = NULL;
|
||||
|
||||
protected $_tableName = NULL;
|
||||
|
||||
protected $_entityIDTableName = NULL;
|
||||
|
||||
protected $_tableFields = NULL;
|
||||
|
||||
/**
|
||||
* @var array|null NULL if no limit; or array(0 => $limit, 1 => $offset)
|
||||
*/
|
||||
protected $_limitClause = NULL;
|
||||
|
||||
/**
|
||||
* @var array|null NULL if no limit; or array(0 => $limit, 1 => $offset)
|
||||
*/
|
||||
protected $_limitRowClause = NULL;
|
||||
|
||||
/**
|
||||
* @var array|null NULL if no limit; or array(0 => $limit, 1 => $offset)
|
||||
*/
|
||||
protected $_limitDetailClause = NULL;
|
||||
|
||||
protected $_limitNumber = 10;
|
||||
protected $_limitNumberPlus1 = 11; // this should be one more than self::LIMIT
|
||||
|
||||
protected $_foundRows = array();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
$this->_partialQueries = array(
|
||||
new CRM_Contact_Form_Search_Custom_FullText_Contact(),
|
||||
new CRM_Contact_Form_Search_Custom_FullText_Activity(),
|
||||
new CRM_Contact_Form_Search_Custom_FullText_Case(),
|
||||
new CRM_Contact_Form_Search_Custom_FullText_Contribution(),
|
||||
new CRM_Contact_Form_Search_Custom_FullText_Participant(),
|
||||
new CRM_Contact_Form_Search_Custom_FullText_Membership(),
|
||||
);
|
||||
|
||||
$formValues['table'] = $this->getFieldValue($formValues, 'table', 'String');
|
||||
$this->_table = $formValues['table'];
|
||||
|
||||
$formValues['text'] = trim($this->getFieldValue($formValues, 'text', 'String', ''));
|
||||
$this->_text = $formValues['text'];
|
||||
|
||||
if (!$this->_table) {
|
||||
$this->_limitClause = array($this->_limitNumberPlus1, NULL);
|
||||
$this->_limitRowClause = $this->_limitDetailClause = array($this->_limitNumber, NULL);
|
||||
}
|
||||
else {
|
||||
// when there is table specified, we would like to use the pager. But since
|
||||
// 1. this custom search has slightly different structure ,
|
||||
// 2. we are in constructor right now,
|
||||
// we 'll use a small hack -
|
||||
$rowCount = CRM_Utils_Array::value('crmRowCount', $_REQUEST, CRM_Utils_Pager::ROWCOUNT);
|
||||
$pageId = CRM_Utils_Array::value('crmPID', $_REQUEST, 1);
|
||||
$offset = ($pageId - 1) * $rowCount;
|
||||
$this->_limitClause = NULL;
|
||||
$this->_limitRowClause = array($rowCount, NULL);
|
||||
$this->_limitDetailClause = array($rowCount, $offset);
|
||||
}
|
||||
|
||||
$this->_formValues = $formValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value from $formValues. If missing, get it from the request.
|
||||
*
|
||||
* @param $formValues
|
||||
* @param $field
|
||||
* @param $type
|
||||
* @param null $default
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getFieldValue($formValues, $field, $type, $default = NULL) {
|
||||
$value = CRM_Utils_Array::value($field, $formValues);
|
||||
if (!$value) {
|
||||
return CRM_Utils_Request::retrieve($field, $type, CRM_Core_DAO::$_nullObject, FALSE, $default);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
}
|
||||
|
||||
public function initialize() {
|
||||
static $initialized = FALSE;
|
||||
|
||||
if (!$initialized) {
|
||||
$initialized = TRUE;
|
||||
|
||||
$this->buildTempTable();
|
||||
|
||||
$this->fillTable();
|
||||
}
|
||||
}
|
||||
|
||||
public function buildTempTable() {
|
||||
$randomNum = md5(uniqid());
|
||||
$this->_tableName = "civicrm_temp_custom_details_{$randomNum}";
|
||||
|
||||
$this->_tableFields = array(
|
||||
'id' => 'int unsigned NOT NULL AUTO_INCREMENT',
|
||||
'table_name' => 'varchar(16)',
|
||||
'contact_id' => 'int unsigned',
|
||||
'sort_name' => 'varchar(128)',
|
||||
'display_name' => 'varchar(128)',
|
||||
'assignee_contact_id' => 'int unsigned',
|
||||
'assignee_sort_name' => 'varchar(128)',
|
||||
'target_contact_id' => 'int unsigned',
|
||||
'target_sort_name' => 'varchar(128)',
|
||||
'activity_id' => 'int unsigned',
|
||||
'activity_type_id' => 'int unsigned',
|
||||
'record_type' => 'varchar(16)',
|
||||
'client_id' => 'int unsigned',
|
||||
'case_id' => 'int unsigned',
|
||||
'case_start_date' => 'datetime',
|
||||
'case_end_date' => 'datetime',
|
||||
'case_is_deleted' => 'tinyint',
|
||||
'subject' => 'varchar(255)',
|
||||
'details' => 'varchar(255)',
|
||||
'contribution_id' => 'int unsigned',
|
||||
'financial_type' => 'varchar(255)',
|
||||
'contribution_page' => 'varchar(255)',
|
||||
'contribution_receive_date' => 'datetime',
|
||||
'contribution_total_amount' => 'decimal(20,2)',
|
||||
'contribution_trxn_Id' => 'varchar(255)',
|
||||
'contribution_source' => 'varchar(255)',
|
||||
'contribution_status' => 'varchar(255)',
|
||||
'contribution_check_number' => 'varchar(255)',
|
||||
'participant_id' => 'int unsigned',
|
||||
'event_title' => 'varchar(255)',
|
||||
'participant_fee_level' => 'varchar(255)',
|
||||
'participant_fee_amount' => 'int unsigned',
|
||||
'participant_source' => 'varchar(255)',
|
||||
'participant_register_date' => 'datetime',
|
||||
'participant_status' => 'varchar(255)',
|
||||
'participant_role' => 'varchar(255)',
|
||||
'membership_id' => 'int unsigned',
|
||||
'membership_fee' => 'int unsigned',
|
||||
'membership_type' => 'varchar(255)',
|
||||
'membership_start_date' => 'datetime',
|
||||
'membership_end_date' => 'datetime',
|
||||
'membership_source' => 'varchar(255)',
|
||||
'membership_status' => 'varchar(255)',
|
||||
// We may have multiple files to list on one record.
|
||||
// The temporary-table approach can't store full details for all of them
|
||||
'file_ids' => 'varchar(255)', // comma-separate id listing
|
||||
);
|
||||
|
||||
$sql = "
|
||||
CREATE TEMPORARY TABLE {$this->_tableName} (
|
||||
";
|
||||
|
||||
foreach ($this->_tableFields as $name => $desc) {
|
||||
$sql .= "$name $desc,\n";
|
||||
}
|
||||
|
||||
$sql .= "
|
||||
PRIMARY KEY ( id )
|
||||
) ENGINE=HEAP DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
$this->_entityIDTableName = "civicrm_temp_custom_entityID_{$randomNum}";
|
||||
$sql = "
|
||||
CREATE TEMPORARY TABLE {$this->_entityIDTableName} (
|
||||
id int unsigned NOT NULL AUTO_INCREMENT,
|
||||
entity_id int unsigned NOT NULL,
|
||||
|
||||
UNIQUE INDEX unique_entity_id ( entity_id ),
|
||||
PRIMARY KEY ( id )
|
||||
) ENGINE=HEAP DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
if (!empty($this->_formValues['is_unit_test'])) {
|
||||
$this->_tableNameForTest = $this->_tableName;
|
||||
}
|
||||
}
|
||||
|
||||
public function fillTable() {
|
||||
foreach ($this->_partialQueries as $partialQuery) {
|
||||
/** @var $partialQuery CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery */
|
||||
if (!$this->_table || $this->_table == $partialQuery->getName()) {
|
||||
if ($partialQuery->isActive()) {
|
||||
$result = $partialQuery->fillTempTable($this->_text, $this->_entityIDTableName, $this->_tableName, $this->_limitClause, $this->_limitDetailClause);
|
||||
$this->_foundRows[$partialQuery->getName()] = $result['count'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->filterACLContacts();
|
||||
}
|
||||
|
||||
public function filterACLContacts() {
|
||||
if (CRM_Core_Permission::check('view all contacts')) {
|
||||
CRM_Core_DAO::executeQuery("DELETE FROM {$this->_tableName} WHERE contact_id IN (SELECT id FROM civicrm_contact WHERE is_deleted = 1)");
|
||||
return;
|
||||
}
|
||||
|
||||
$session = CRM_Core_Session::singleton();
|
||||
$contactID = $session->get('userID');
|
||||
if (!$contactID) {
|
||||
$contactID = 0;
|
||||
}
|
||||
|
||||
CRM_Contact_BAO_Contact_Permission::cache($contactID);
|
||||
|
||||
$params = array(1 => array($contactID, 'Integer'));
|
||||
|
||||
$sql = "
|
||||
DELETE t.*
|
||||
FROM {$this->_tableName} t
|
||||
WHERE NOT EXISTS ( SELECT c.contact_id
|
||||
FROM civicrm_acl_contact_cache c
|
||||
WHERE c.user_id = %1 AND t.contact_id = c.contact_id )
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql, $params);
|
||||
|
||||
$sql = "
|
||||
DELETE t.*
|
||||
FROM {$this->_tableName} t
|
||||
WHERE t.table_name = 'Activity' AND
|
||||
NOT EXISTS ( SELECT c.contact_id
|
||||
FROM civicrm_acl_contact_cache c
|
||||
WHERE c.user_id = %1 AND ( t.target_contact_id = c.contact_id OR t.target_contact_id IS NULL ) )
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql, $params);
|
||||
|
||||
$sql = "
|
||||
DELETE t.*
|
||||
FROM {$this->_tableName} t
|
||||
WHERE t.table_name = 'Activity' AND
|
||||
NOT EXISTS ( SELECT c.contact_id
|
||||
FROM civicrm_acl_contact_cache c
|
||||
WHERE c.user_id = %1 AND ( t.assignee_contact_id = c.contact_id OR t.assignee_contact_id IS NULL ) )
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
$config = CRM_Core_Config::singleton();
|
||||
|
||||
$form->applyFilter('__ALL__', 'trim');
|
||||
$form->add('text',
|
||||
'text',
|
||||
ts('Find'),
|
||||
TRUE
|
||||
);
|
||||
|
||||
// also add a select box to allow the search to be constrained
|
||||
$tables = array('' => ts('All tables'));
|
||||
foreach ($this->_partialQueries as $partialQuery) {
|
||||
/** @var $partialQuery CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery */
|
||||
if ($partialQuery->isActive()) {
|
||||
$tables[$partialQuery->getName()] = $partialQuery->getLabel();
|
||||
}
|
||||
}
|
||||
|
||||
$form->add('select', 'table', ts('Tables'), $tables);
|
||||
|
||||
$form->assign('csID', $form->get('csid'));
|
||||
|
||||
// also add the limit constant
|
||||
$form->assign('limit', self::LIMIT);
|
||||
|
||||
// set form defaults
|
||||
if (!empty($form->_formValues)) {
|
||||
$defaults = array();
|
||||
|
||||
if (isset($form->_formValues['text'])) {
|
||||
$defaults['text'] = $form->_formValues['text'];
|
||||
}
|
||||
|
||||
if (isset($form->_formValues['table'])) {
|
||||
$defaults['table'] = $form->_formValues['table'];
|
||||
$form->assign('table', $form->_formValues['table']);
|
||||
}
|
||||
|
||||
$form->setDefaults($defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* You can define a custom title for the search form
|
||||
*/
|
||||
$this->setTitle(ts('Full-text Search'));
|
||||
|
||||
$searchService = CRM_Core_BAO_File::getSearchService();
|
||||
$form->assign('allowFileSearch', !empty($searchService) && CRM_Core_Permission::check('access uploaded files'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function &columns() {
|
||||
$this->_columns = array(
|
||||
ts('Contact ID') => 'contact_id',
|
||||
ts('Name') => 'sort_name',
|
||||
);
|
||||
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function summary() {
|
||||
$this->initialize();
|
||||
|
||||
$summary = array();
|
||||
foreach ($this->_partialQueries as $partialQuery) {
|
||||
/** @var $partialQuery CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery */
|
||||
$summary[$partialQuery->getName()] = array();
|
||||
}
|
||||
|
||||
// now iterate through the table and add entries to the relevant section
|
||||
$sql = "SELECT * FROM {$this->_tableName}";
|
||||
if ($this->_table) {
|
||||
$sql .= " {$this->toLimit($this->_limitRowClause)} ";
|
||||
}
|
||||
$dao = CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
$activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, TRUE);
|
||||
$roleIds = CRM_Event_PseudoConstant::participantRole();
|
||||
while ($dao->fetch()) {
|
||||
$row = array();
|
||||
foreach ($this->_tableFields as $name => $dontCare) {
|
||||
if ($name != 'activity_type_id') {
|
||||
$row[$name] = $dao->$name;
|
||||
}
|
||||
else {
|
||||
$row['activity_type'] = CRM_Utils_Array::value($dao->$name, $activityTypes);
|
||||
}
|
||||
}
|
||||
if (isset($row['participant_role'])) {
|
||||
$participantRole = explode(CRM_Core_DAO::VALUE_SEPARATOR, $row['participant_role']);
|
||||
$viewRoles = array();
|
||||
foreach ($participantRole as $v) {
|
||||
$viewRoles[] = $roleIds[$v];
|
||||
}
|
||||
$row['participant_role'] = implode(', ', $viewRoles);
|
||||
}
|
||||
if (!empty($row['file_ids'])) {
|
||||
$fileIds = (explode(',', $row['file_ids']));
|
||||
$fileHtml = '';
|
||||
foreach ($fileIds as $fileId) {
|
||||
$paperclip = CRM_Core_BAO_File::paperIconAttachment('*', $fileId);
|
||||
if ($paperclip) {
|
||||
$fileHtml .= implode('', $paperclip);
|
||||
}
|
||||
}
|
||||
$row['fileHtml'] = $fileHtml;
|
||||
}
|
||||
$summary[$dao->table_name][] = $row;
|
||||
}
|
||||
|
||||
$summary['Count'] = array();
|
||||
foreach (array_keys($summary) as $table) {
|
||||
$summary['Count'][$table] = CRM_Utils_Array::value($table, $this->_foundRows);
|
||||
if ($summary['Count'][$table] >= self::LIMIT) {
|
||||
$summary['addShowAllLink'][$table] = TRUE;
|
||||
}
|
||||
else {
|
||||
$summary['addShowAllLink'][$table] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function count() {
|
||||
$this->initialize();
|
||||
|
||||
if ($this->_table) {
|
||||
return $this->_foundRows[$this->_table];
|
||||
}
|
||||
else {
|
||||
return CRM_Core_DAO::singleValueQuery("SELECT count(id) FROM {$this->_tableName}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = FALSE) {
|
||||
$this->initialize();
|
||||
|
||||
if ($returnSQL) {
|
||||
return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
|
||||
}
|
||||
else {
|
||||
return CRM_Core_DAO::singleValueQuery("SELECT contact_id FROM {$this->_tableName}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all($offset = 0, $rowcount = 0, $sort = NULL, $includeContactIDs = FALSE, $justIDs = FALSE) {
|
||||
$this->initialize();
|
||||
|
||||
if ($justIDs) {
|
||||
$select = "contact_a.id as contact_id";
|
||||
}
|
||||
else {
|
||||
$select = "
|
||||
contact_a.contact_id as contact_id ,
|
||||
contact_a.sort_name as sort_name
|
||||
";
|
||||
}
|
||||
|
||||
$sql = "
|
||||
SELECT $select
|
||||
FROM {$this->_tableName} contact_a
|
||||
{$this->toLimit($this->_limitRowClause)}
|
||||
";
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function from() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom/FullText.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function setDefaultValues() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $row
|
||||
*/
|
||||
public function alterRow(&$row) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|array $limit
|
||||
* @return string
|
||||
* SQL
|
||||
* @see CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery::toLimit
|
||||
*/
|
||||
public function toLimit($limit) {
|
||||
if (is_array($limit)) {
|
||||
list ($limit, $offset) = $limit;
|
||||
}
|
||||
if (empty($limit)) {
|
||||
return '';
|
||||
}
|
||||
$result = "LIMIT {$limit}";
|
||||
if ($offset) {
|
||||
$result .= " OFFSET {$offset}";
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,344 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
abstract class CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $label;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $label
|
||||
*/
|
||||
public function __construct($name, $label) {
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get label.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel() {
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a query and write out a page worth of matches to $detailTable.
|
||||
*
|
||||
* TODO: Consider removing $entityIDTableName from the function-signature. Each implementation could be
|
||||
* responsible for its own temp tables.
|
||||
*
|
||||
* TODO: Understand why $queryLimit and $detailLimit are different
|
||||
*
|
||||
* @param string $queryText
|
||||
* A string of text to search for.
|
||||
* @param string $entityIDTableName
|
||||
* A temporary table into which we can write a list of all matching IDs.
|
||||
* @param string $detailTable
|
||||
* A table into which we can write details about a page worth of matches.
|
||||
* @param array|NULL $queryLimit overall limit (applied when building $entityIDTableName)
|
||||
* NULL if no limit; or array(0 => $limit, 1 => $offset)
|
||||
* @param array|NULL $detailLimit final limit (applied when building $detailTable)
|
||||
* NULL if no limit; or array(0 => $limit, 1 => $offset)
|
||||
* @return array
|
||||
* keys: match-descriptor
|
||||
* - count: int
|
||||
*/
|
||||
public abstract function fillTempTable($queryText, $entityIDTableName, $detailTable, $queryLimit, $detailLimit);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tables
|
||||
* @param $extends
|
||||
*/
|
||||
public function fillCustomInfo(&$tables, $extends) {
|
||||
$sql = "
|
||||
SELECT cg.table_name, cf.column_name
|
||||
FROM civicrm_custom_group cg
|
||||
INNER JOIN civicrm_custom_field cf ON cf.custom_group_id = cg.id
|
||||
WHERE cg.extends IN $extends
|
||||
AND cg.is_active = 1
|
||||
AND cf.is_active = 1
|
||||
AND cf.is_searchable = 1
|
||||
AND cf.html_type IN ( 'Text', 'TextArea', 'RichTextEditor' )
|
||||
";
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql);
|
||||
while ($dao->fetch()) {
|
||||
if (!array_key_exists($dao->table_name, $tables)) {
|
||||
$tables[$dao->table_name] = array(
|
||||
'id' => 'entity_id',
|
||||
'fields' => array(),
|
||||
);
|
||||
}
|
||||
$tables[$dao->table_name]['fields'][$dao->column_name] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run queries.
|
||||
*
|
||||
* @param string $queryText
|
||||
* @param array $tables
|
||||
* A list of places to query. Keys may be:.
|
||||
* - sql: an array of SQL queries to execute
|
||||
* - final: an array of SQL queries to execute at the end
|
||||
* - *: All other keys are treated as table names
|
||||
* @param string $entityIDTableName
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
* Keys: match-descriptor
|
||||
* - count: int
|
||||
* - files: NULL | array
|
||||
* @throws \CRM_Core_Exception
|
||||
*/
|
||||
public function runQueries($queryText, &$tables, $entityIDTableName, $limit) {
|
||||
$sql = "TRUNCATE {$entityIDTableName}";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
$files = NULL;
|
||||
|
||||
foreach ($tables as $tableName => $tableValues) {
|
||||
if ($tableName == 'final') {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if ($tableName == 'sql') {
|
||||
foreach ($tableValues as $sqlStatement) {
|
||||
$sql = "
|
||||
REPLACE INTO {$entityIDTableName} ( entity_id )
|
||||
$sqlStatement
|
||||
{$this->toLimit($limit)}
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
}
|
||||
}
|
||||
elseif ($tableName == 'file') {
|
||||
$searcher = CRM_Core_BAO_File::getSearchService();
|
||||
if (!($searcher && CRM_Core_Permission::check('access uploaded files'))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$query = $tableValues + array(
|
||||
'text' => CRM_Utils_QueryFormatter::singleton()
|
||||
->format($queryText, CRM_Utils_QueryFormatter::LANG_SOLR),
|
||||
);
|
||||
list($intLimit, $intOffset) = $this->parseLimitOffset($limit);
|
||||
$files = $searcher->search($query, $intLimit, $intOffset);
|
||||
$matches = array();
|
||||
foreach ($files as $file) {
|
||||
$matches[] = array('entity_id' => $file['xparent_id']);
|
||||
}
|
||||
if ($matches) {
|
||||
$insertSql = CRM_Utils_SQL_Insert::into($entityIDTableName)->usingReplace()->rows($matches)->toSQL();
|
||||
CRM_Core_DAO::executeQuery($insertSql);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$fullTextFields = array(); // array (string $sqlColumnName)
|
||||
$clauses = array(); // array (string $sqlExpression)
|
||||
|
||||
foreach ($tableValues['fields'] as $fieldName => $fieldType) {
|
||||
if ($fieldType == 'Int') {
|
||||
if (is_numeric($queryText)) {
|
||||
$clauses[] = "$fieldName = {$queryText}";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$fullTextFields[] = $fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($fullTextFields)) {
|
||||
$clauses[] = $this->matchText($tableName, $fullTextFields, $queryText);
|
||||
}
|
||||
|
||||
if (empty($clauses)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$whereClause = implode(' OR ', $clauses);
|
||||
|
||||
//resolve conflict between entity tables.
|
||||
if ($tableName == 'civicrm_note' &&
|
||||
$entityTable = CRM_Utils_Array::value('entity_table', $tableValues)
|
||||
) {
|
||||
$whereClause .= " AND entity_table = '{$entityTable}'";
|
||||
}
|
||||
|
||||
$sql = "
|
||||
REPLACE INTO {$entityIDTableName} ( entity_id )
|
||||
SELECT {$tableValues['id']}
|
||||
FROM $tableName
|
||||
WHERE ( $whereClause )
|
||||
AND {$tableValues['id']} IS NOT NULL
|
||||
GROUP BY {$tableValues['id']}
|
||||
{$this->toLimit($limit)}
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($tables['final'])) {
|
||||
foreach ($tables['final'] as $sqlStatement) {
|
||||
CRM_Core_DAO::executeQuery($sqlStatement);
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'count' => CRM_Core_DAO::singleValueQuery("SELECT count(*) FROM {$entityIDTableName}"),
|
||||
'files' => $files,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a SQL expression for matching against a list of.
|
||||
* text columns.
|
||||
*
|
||||
* @param string $table
|
||||
* Eg "civicrm_note" or "civicrm_note mynote".
|
||||
* @param array|string $fullTextFields list of field names
|
||||
* @param string $queryText
|
||||
* @return string
|
||||
* SQL, eg "MATCH (col1) AGAINST (queryText)" or "col1 LIKE '%queryText%'"
|
||||
*/
|
||||
public function matchText($table, $fullTextFields, $queryText) {
|
||||
return CRM_Utils_QueryFormatter::singleton()->formatSql($table, $fullTextFields, $queryText);
|
||||
}
|
||||
|
||||
/**
|
||||
* For any records in $toTable that originated with this query,
|
||||
* append file information.
|
||||
*
|
||||
* @param string $toTable
|
||||
* @param string $parentIdColumn
|
||||
* @param array $files
|
||||
* See return format of CRM_Core_FileSearchInterface::search.
|
||||
*/
|
||||
public function moveFileIDs($toTable, $parentIdColumn, $files) {
|
||||
if (empty($files)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$filesIndex = CRM_Utils_Array::index(array('xparent_id', 'file_id'), $files);
|
||||
// ex: $filesIndex[$xparent_id][$file_id] = array(...the file record...);
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery("
|
||||
SELECT distinct {$parentIdColumn}
|
||||
FROM {$toTable}
|
||||
WHERE table_name = %1
|
||||
", array(
|
||||
1 => array($this->getName(), 'String'),
|
||||
));
|
||||
while ($dao->fetch()) {
|
||||
if (empty($filesIndex[$dao->{$parentIdColumn}])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CRM_Core_DAO::executeQuery("UPDATE {$toTable}
|
||||
SET file_ids = %1
|
||||
WHERE table_name = %2 AND {$parentIdColumn} = %3
|
||||
", array(
|
||||
1 => array(implode(',', array_keys($filesIndex[$dao->{$parentIdColumn}])), 'String'),
|
||||
2 => array($this->getName(), 'String'),
|
||||
3 => array($dao->{$parentIdColumn}, 'Int'),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|array $limit
|
||||
* @return string
|
||||
* SQL
|
||||
* @see CRM_Contact_Form_Search_Custom_FullText::toLimit
|
||||
*/
|
||||
public function toLimit($limit) {
|
||||
if (is_array($limit)) {
|
||||
list ($limit, $offset) = $limit;
|
||||
}
|
||||
if (empty($limit)) {
|
||||
return '';
|
||||
}
|
||||
$result = "LIMIT {$limit}";
|
||||
if ($offset) {
|
||||
$result .= " OFFSET {$offset}";
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|int $limit
|
||||
* @return array
|
||||
* (0 => $limit, 1 => $offset)
|
||||
*/
|
||||
public function parseLimitOffset($limit) {
|
||||
if (is_scalar($limit)) {
|
||||
$intLimit = $limit;
|
||||
}
|
||||
else {
|
||||
list ($intLimit, $intOffset) = $limit;
|
||||
}
|
||||
if (!$intOffset) {
|
||||
$intOffset = 0;
|
||||
}
|
||||
return array($intLimit, $intOffset);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_FullText_Activity extends CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery {
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct('Activity', ts('Activities'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Is search active for this user.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive() {
|
||||
return CRM_Core_Permission::check('view all activities');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fillTempTable($queryText, $entityIDTableName, $toTable, $queryLimit, $detailLimit) {
|
||||
$queries = $this->prepareQueries($queryText, $entityIDTableName);
|
||||
$result = $this->runQueries($queryText, $queries, $entityIDTableName, $queryLimit);
|
||||
$this->moveIDs($entityIDTableName, $toTable, $detailLimit);
|
||||
if (!empty($result['files'])) {
|
||||
$this->moveFileIDs($toTable, 'activity_id', $result['files']);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $queryText
|
||||
* @param string $entityIDTableName
|
||||
*
|
||||
* @return array
|
||||
* list tables/queries (for runQueries)
|
||||
*/
|
||||
public function prepareQueries($queryText, $entityIDTableName) {
|
||||
// Note: For available full-text indices, see CRM_Core_InnoDBIndexer
|
||||
|
||||
$contactSQL = array();
|
||||
|
||||
$contactSQL[] = "
|
||||
SELECT distinct ca.id
|
||||
FROM civicrm_activity ca
|
||||
INNER JOIN civicrm_activity_contact cat ON cat.activity_id = ca.id
|
||||
INNER JOIN civicrm_contact c ON cat.contact_id = c.id
|
||||
LEFT JOIN civicrm_email e ON cat.contact_id = e.contact_id
|
||||
LEFT JOIN civicrm_option_group og ON og.name = 'activity_type'
|
||||
LEFT JOIN civicrm_option_value ov ON ( ov.option_group_id = og.id )
|
||||
WHERE (
|
||||
({$this->matchText('civicrm_contact c', array('sort_name', 'display_name', 'nick_name'), $queryText)})
|
||||
OR
|
||||
({$this->matchText('civicrm_email e', 'email', $queryText)} AND ca.activity_type_id = ov.value AND ov.name IN ('Inbound Email', 'Email') )
|
||||
)
|
||||
AND (ca.is_deleted = 0 OR ca.is_deleted IS NULL)
|
||||
AND (c.is_deleted = 0 OR c.is_deleted IS NULL)
|
||||
";
|
||||
|
||||
$contactSQL[] = "
|
||||
SELECT et.entity_id
|
||||
FROM civicrm_entity_tag et
|
||||
INNER JOIN civicrm_tag t ON et.tag_id = t.id
|
||||
INNER JOIN civicrm_activity ca ON et.entity_id = ca.id
|
||||
WHERE et.entity_table = 'civicrm_activity'
|
||||
AND et.tag_id = t.id
|
||||
AND ({$this->matchText('civicrm_tag t', 'name', $queryText)})
|
||||
AND (ca.is_deleted = 0 OR ca.is_deleted IS NULL)
|
||||
GROUP BY et.entity_id
|
||||
";
|
||||
|
||||
$contactSQL[] = "
|
||||
SELECT distinct ca.id
|
||||
FROM civicrm_activity ca
|
||||
WHERE ({$this->matchText('civicrm_activity ca', array('subject', 'details'), $queryText)})
|
||||
AND (ca.is_deleted = 0 OR ca.is_deleted IS NULL)
|
||||
";
|
||||
|
||||
$final = array();
|
||||
|
||||
$tables = array(
|
||||
'civicrm_activity' => array('fields' => array()),
|
||||
'file' => array(
|
||||
'xparent_table' => 'civicrm_activity',
|
||||
),
|
||||
'sql' => $contactSQL,
|
||||
'final' => $final,
|
||||
);
|
||||
|
||||
$this->fillCustomInfo($tables, "( 'Activity' )");
|
||||
return $tables;;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move IDs.
|
||||
*
|
||||
* @param string $fromTable
|
||||
* @param string $toTable
|
||||
* @param int $limit
|
||||
*/
|
||||
public function moveIDs($fromTable, $toTable, $limit) {
|
||||
$sql = "
|
||||
INSERT INTO {$toTable}
|
||||
( table_name, activity_id, subject, details, contact_id, sort_name, record_type,
|
||||
activity_type_id, case_id, client_id )
|
||||
SELECT 'Activity', ca.id, substr(ca.subject, 1, 50), substr(ca.details, 1, 250),
|
||||
c1.id, c1.sort_name, cac.record_type_id,
|
||||
ca.activity_type_id,
|
||||
cca.case_id,
|
||||
ccc.contact_id as client_id
|
||||
FROM {$fromTable} eid
|
||||
INNER JOIN civicrm_activity ca ON ca.id = eid.entity_id
|
||||
INNER JOIN civicrm_activity_contact cac ON cac.activity_id = ca.id
|
||||
INNER JOIN civicrm_contact c1 ON cac.contact_id = c1.id
|
||||
LEFT JOIN civicrm_case_activity cca ON cca.activity_id = ca.id
|
||||
LEFT JOIN civicrm_case_contact ccc ON ccc.case_id = cca.case_id
|
||||
WHERE (ca.is_deleted = 0 OR ca.is_deleted IS NULL)
|
||||
{$this->toLimit($limit)}
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_FullText_Case extends CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery {
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct('Case', ts('Cases'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Is CiviCase active?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive() {
|
||||
$config = CRM_Core_Config::singleton();
|
||||
return in_array('CiviCase', $config->enableComponents);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fillTempTable($queryText, $entityIDTableName, $toTable, $queryLimit, $detailLimit) {
|
||||
$queries = $this->prepareQueries($queryText, $entityIDTableName);
|
||||
$result = $this->runQueries($queryText, $queries, $entityIDTableName, $queryLimit);
|
||||
$this->moveIDs($entityIDTableName, $toTable, $detailLimit);
|
||||
if (!empty($result['files'])) {
|
||||
$this->moveFileIDs($toTable, 'case_id', $result['files']);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare queries.
|
||||
*
|
||||
* @param string $queryText
|
||||
* @param string $entityIDTableName
|
||||
*
|
||||
* @return array
|
||||
* list tables/queries (for runQueries)
|
||||
*/
|
||||
public function prepareQueries($queryText, $entityIDTableName) {
|
||||
// Note: For available full-text indices, see CRM_Core_InnoDBIndexer
|
||||
|
||||
$contactSQL = array();
|
||||
|
||||
$contactSQL[] = "
|
||||
SELECT distinct cc.id
|
||||
FROM civicrm_case cc
|
||||
LEFT JOIN civicrm_case_contact ccc ON cc.id = ccc.case_id
|
||||
LEFT JOIN civicrm_contact c ON ccc.contact_id = c.id
|
||||
WHERE ({$this->matchText('civicrm_contact c', array('sort_name', 'display_name', 'nick_name'), $queryText)})
|
||||
AND (cc.is_deleted = 0 OR cc.is_deleted IS NULL)
|
||||
";
|
||||
|
||||
if (is_numeric($queryText)) {
|
||||
$contactSQL[] = "
|
||||
SELECT distinct cc.id
|
||||
FROM civicrm_case cc
|
||||
LEFT JOIN civicrm_case_contact ccc ON cc.id = ccc.case_id
|
||||
LEFT JOIN civicrm_contact c ON ccc.contact_id = c.id
|
||||
WHERE cc.id = {$queryText}
|
||||
AND (cc.is_deleted = 0 OR cc.is_deleted IS NULL)
|
||||
";
|
||||
}
|
||||
|
||||
$contactSQL[] = "
|
||||
SELECT et.entity_id
|
||||
FROM civicrm_entity_tag et
|
||||
INNER JOIN civicrm_tag t ON et.tag_id = t.id
|
||||
WHERE et.entity_table = 'civicrm_case'
|
||||
AND et.tag_id = t.id
|
||||
AND ({$this->matchText('civicrm_tag t', 'name', $queryText)})
|
||||
GROUP BY et.entity_id
|
||||
";
|
||||
|
||||
$tables = array(
|
||||
'civicrm_case' => array('fields' => array()),
|
||||
'file' => array(
|
||||
'xparent_table' => 'civicrm_case',
|
||||
),
|
||||
'sql' => $contactSQL,
|
||||
);
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move IDs.
|
||||
*
|
||||
* @param string $fromTable
|
||||
* @param string $toTable
|
||||
* @param int $limit
|
||||
*/
|
||||
public function moveIDs($fromTable, $toTable, $limit) {
|
||||
$sql = "
|
||||
INSERT INTO {$toTable}
|
||||
( table_name, contact_id, sort_name, case_id, case_start_date, case_end_date, case_is_deleted )
|
||||
SELECT 'Case', c.id, c.sort_name, cc.id, DATE(cc.start_date), DATE(cc.end_date), cc.is_deleted
|
||||
FROM {$fromTable} ct
|
||||
INNER JOIN civicrm_case cc ON cc.id = ct.entity_id
|
||||
LEFT JOIN civicrm_case_contact ccc ON cc.id = ccc.case_id
|
||||
LEFT JOIN civicrm_contact c ON ccc.contact_id = c.id
|
||||
{$this->toLimit($limit)}
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_FullText_Contact extends CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery {
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct('Contact', ts('Contacts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if search is permitted.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive() {
|
||||
return CRM_Core_Permission::check('view all contacts');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fillTempTable($queryText, $entityIDTableName, $toTable, $queryLimit, $detailLimit) {
|
||||
$queries = $this->prepareQueries($queryText, $entityIDTableName);
|
||||
$result = $this->runQueries($queryText, $queries, $entityIDTableName, $queryLimit);
|
||||
$this->moveIDs($entityIDTableName, $toTable, $detailLimit);
|
||||
if (!empty($result['files'])) {
|
||||
$this->moveFileIDs($toTable, 'contact_id', $result['files']);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $queryText
|
||||
* @param string $entityIDTableName
|
||||
* @return array
|
||||
* list tables/queries (for runQueries)
|
||||
*/
|
||||
public function prepareQueries($queryText, $entityIDTableName) {
|
||||
// Note: For available full-text indices, see CRM_Core_InnoDBIndexer
|
||||
|
||||
$contactSQL = array();
|
||||
$contactSQL[] = "
|
||||
SELECT et.entity_id
|
||||
FROM civicrm_entity_tag et
|
||||
INNER JOIN civicrm_tag t ON et.tag_id = t.id
|
||||
WHERE et.entity_table = 'civicrm_contact'
|
||||
AND et.tag_id = t.id
|
||||
AND ({$this->matchText('civicrm_tag t', 'name', $queryText)})
|
||||
GROUP BY et.entity_id
|
||||
";
|
||||
|
||||
// lets delete all the deceased contacts from the entityID box
|
||||
// this allows us to keep numbers in sync
|
||||
// when we have acl contacts, the situation gets even more murky
|
||||
$final = array();
|
||||
$final[] = "DELETE FROM {$entityIDTableName} WHERE entity_id IN (SELECT id FROM civicrm_contact WHERE is_deleted = 1)";
|
||||
|
||||
$tables = array(
|
||||
'civicrm_contact' => array(
|
||||
'id' => 'id',
|
||||
'fields' => array(
|
||||
'sort_name' => NULL,
|
||||
'nick_name' => NULL,
|
||||
'display_name' => NULL,
|
||||
),
|
||||
),
|
||||
'civicrm_address' => array(
|
||||
'id' => 'contact_id',
|
||||
'fields' => array(
|
||||
'street_address' => NULL,
|
||||
'city' => NULL,
|
||||
'postal_code' => NULL,
|
||||
),
|
||||
),
|
||||
'civicrm_email' => array(
|
||||
'id' => 'contact_id',
|
||||
'fields' => array('email' => NULL),
|
||||
),
|
||||
'civicrm_phone' => array(
|
||||
'id' => 'contact_id',
|
||||
'fields' => array('phone' => NULL),
|
||||
),
|
||||
'civicrm_note' => array(
|
||||
'id' => 'entity_id',
|
||||
'entity_table' => 'civicrm_contact',
|
||||
'fields' => array(
|
||||
'subject' => NULL,
|
||||
'note' => NULL,
|
||||
),
|
||||
),
|
||||
'file' => array(
|
||||
'xparent_table' => 'civicrm_contact',
|
||||
),
|
||||
'sql' => $contactSQL,
|
||||
'final' => $final,
|
||||
);
|
||||
|
||||
// get the custom data info
|
||||
$this->fillCustomInfo($tables,
|
||||
"( 'Contact', 'Individual', 'Organization', 'Household' )"
|
||||
);
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move IDs.
|
||||
*
|
||||
* @param $fromTable
|
||||
* @param $toTable
|
||||
* @param $limit
|
||||
*/
|
||||
public function moveIDs($fromTable, $toTable, $limit) {
|
||||
$sql = "
|
||||
INSERT INTO {$toTable}
|
||||
( id, contact_id, sort_name, display_name, table_name )
|
||||
SELECT c.id, ct.entity_id, c.sort_name, c.display_name, 'Contact'
|
||||
FROM {$fromTable} ct
|
||||
INNER JOIN civicrm_contact c ON ct.entity_id = c.id
|
||||
{$this->toLimit($limit)}
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_FullText_Contribution extends CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery {
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct('Contribution', ts('Contributions'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if search is permitted.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive() {
|
||||
$config = CRM_Core_Config::singleton();
|
||||
return in_array('CiviContribute', $config->enableComponents) &&
|
||||
CRM_Core_Permission::check('access CiviContribute');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fillTempTable($queryText, $entityIDTableName, $toTable, $queryLimit, $detailLimit) {
|
||||
$queries = $this->prepareQueries($queryText, $entityIDTableName);
|
||||
$result = $this->runQueries($queryText, $queries, $entityIDTableName, $queryLimit);
|
||||
$this->moveIDs($entityIDTableName, $toTable, $detailLimit);
|
||||
if (!empty($result['files'])) {
|
||||
$this->moveFileIDs($toTable, 'contribution_id', $result['files']);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get contribution ids in entity tables.
|
||||
*
|
||||
* @param string $queryText
|
||||
* @param string $entityIDTableName
|
||||
* @return array
|
||||
* list tables/queries (for runQueries)
|
||||
*/
|
||||
public function prepareQueries($queryText, $entityIDTableName) {
|
||||
// Note: For available full-text indices, see CRM_Core_InnoDBIndexer
|
||||
|
||||
$contactSQL = array();
|
||||
$contactSQL[] = "
|
||||
SELECT distinct cc.id
|
||||
FROM civicrm_contribution cc
|
||||
INNER JOIN civicrm_contact c ON cc.contact_id = c.id
|
||||
WHERE ({$this->matchText('civicrm_contact c', array('sort_name', 'display_name', 'nick_name'), $queryText)})
|
||||
";
|
||||
$tables = array(
|
||||
'civicrm_contribution' => array(
|
||||
'id' => 'id',
|
||||
'fields' => array(
|
||||
'source' => NULL,
|
||||
'amount_level' => NULL,
|
||||
'trxn_Id' => NULL,
|
||||
'invoice_id' => NULL,
|
||||
'check_number' => 'Int', // Odd: This is really a VARCHAR, so why are we searching like an INT?
|
||||
'total_amount' => 'Int',
|
||||
),
|
||||
),
|
||||
'file' => array(
|
||||
'xparent_table' => 'civicrm_contribution',
|
||||
),
|
||||
'sql' => $contactSQL,
|
||||
'civicrm_note' => array(
|
||||
'id' => 'entity_id',
|
||||
'entity_table' => 'civicrm_contribution',
|
||||
'fields' => array(
|
||||
'subject' => NULL,
|
||||
'note' => NULL,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// get the custom data info
|
||||
$this->fillCustomInfo($tables, "( 'Contribution' )");
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move IDs.
|
||||
*
|
||||
* @param string $fromTable
|
||||
* @param string $toTable
|
||||
* @param int $limit
|
||||
*/
|
||||
public function moveIDs($fromTable, $toTable, $limit) {
|
||||
$sql = "
|
||||
INSERT INTO {$toTable}
|
||||
( table_name, contact_id, sort_name, contribution_id, financial_type, contribution_page, contribution_receive_date,
|
||||
contribution_total_amount, contribution_trxn_Id, contribution_source, contribution_status, contribution_check_number )
|
||||
SELECT 'Contribution', c.id, c.sort_name, cc.id, cct.name, ccp.title, cc.receive_date,
|
||||
cc.total_amount, cc.trxn_id, cc.source, contribution_status.label, cc.check_number
|
||||
FROM {$fromTable} ct
|
||||
INNER JOIN civicrm_contribution cc ON cc.id = ct.entity_id
|
||||
LEFT JOIN civicrm_contact c ON cc.contact_id = c.id
|
||||
LEFT JOIN civicrm_financial_type cct ON cct.id = cc.financial_type_id
|
||||
LEFT JOIN civicrm_contribution_page ccp ON ccp.id = cc.contribution_page_id
|
||||
LEFT JOIN civicrm_option_group option_group_contributionStatus ON option_group_contributionStatus.name = 'contribution_status'
|
||||
LEFT JOIN civicrm_option_value contribution_status ON
|
||||
( contribution_status.option_group_id = option_group_contributionStatus.id AND contribution_status.value = cc.contribution_status_id )
|
||||
{$this->toLimit($limit)}
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_FullText_Membership extends CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery {
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct('Membership', ts('Memberships'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if search is permitted.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive() {
|
||||
$config = CRM_Core_Config::singleton();
|
||||
return in_array('CiviMember', $config->enableComponents) &&
|
||||
CRM_Core_Permission::check('access CiviMember');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fillTempTable($queryText, $entityIDTableName, $toTable, $queryLimit, $detailLimit) {
|
||||
$queries = $this->prepareQueries($queryText, $entityIDTableName);
|
||||
$result = $this->runQueries($queryText, $queries, $entityIDTableName, $queryLimit);
|
||||
$this->moveIDs($entityIDTableName, $toTable, $detailLimit);
|
||||
if (!empty($result['files'])) {
|
||||
$this->moveFileIDs($toTable, 'membership_id', $result['files']);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get membership ids in entity tables.
|
||||
*
|
||||
* @param string $queryText
|
||||
* @param string $entityIDTableName
|
||||
*
|
||||
* @return array
|
||||
* list tables/queries (for runQueries)
|
||||
*/
|
||||
public function prepareQueries($queryText, $entityIDTableName) {
|
||||
// Note: For available full-text indices, see CRM_Core_InnoDBIndexer
|
||||
|
||||
$contactSQL = array();
|
||||
$contactSQL[] = "
|
||||
SELECT distinct cm.id
|
||||
FROM civicrm_membership cm
|
||||
INNER JOIN civicrm_contact c ON cm.contact_id = c.id
|
||||
WHERE ({$this->matchText('civicrm_contact c', array('sort_name', 'display_name', 'nick_name'), $queryText)})
|
||||
";
|
||||
$tables = array(
|
||||
'civicrm_membership' => array(
|
||||
'id' => 'id',
|
||||
'fields' => array('source' => NULL),
|
||||
),
|
||||
'file' => array(
|
||||
'xparent_table' => 'civicrm_membership',
|
||||
),
|
||||
'sql' => $contactSQL,
|
||||
);
|
||||
|
||||
// get the custom data info
|
||||
$this->fillCustomInfo($tables, "( 'Membership' )");
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move IDs.
|
||||
*
|
||||
* @param string $fromTable
|
||||
* @param string $toTable
|
||||
* @param int $limit
|
||||
*/
|
||||
public function moveIDs($fromTable, $toTable, $limit) {
|
||||
$sql = "
|
||||
INSERT INTO {$toTable}
|
||||
( table_name, contact_id, sort_name, membership_id, membership_type, membership_fee, membership_start_date,
|
||||
membership_end_date, membership_source, membership_status )
|
||||
SELECT 'Membership', c.id, c.sort_name, cm.id, cmt.name, cc.total_amount, cm.start_date, cm.end_date, cm.source, cms.name
|
||||
FROM {$fromTable} ct
|
||||
INNER JOIN civicrm_membership cm ON cm.id = ct.entity_id
|
||||
LEFT JOIN civicrm_contact c ON cm.contact_id = c.id
|
||||
LEFT JOIN civicrm_membership_type cmt ON cmt.id = cm.membership_type_id
|
||||
LEFT JOIN civicrm_membership_payment cmp ON cmp.membership_id = cm.id
|
||||
LEFT JOIN civicrm_contribution cc ON cc.id = cmp.contribution_id
|
||||
LEFT JOIN civicrm_membership_status cms ON cms.id = cm.status_id
|
||||
{$this->toLimit($limit)}
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_FullText_Participant extends CRM_Contact_Form_Search_Custom_FullText_AbstractPartialQuery {
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct('Participant', ts('Participants'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user has permission.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive() {
|
||||
$config = CRM_Core_Config::singleton();
|
||||
return in_array('CiviEvent', $config->enableComponents) &&
|
||||
CRM_Core_Permission::check('view event participants');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fillTempTable($queryText, $entityIDTableName, $toTable, $queryLimit, $detailLimit) {
|
||||
$queries = $this->prepareQueries($queryText, $entityIDTableName);
|
||||
$result = $this->runQueries($queryText, $queries, $entityIDTableName, $queryLimit);
|
||||
$this->moveIDs($entityIDTableName, $toTable, $detailLimit);
|
||||
if (!empty($result['files'])) {
|
||||
$this->moveFileIDs($toTable, 'participant_id', $result['files']);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get participant ids in entity tables.
|
||||
*
|
||||
* @param string $queryText
|
||||
* @param string $entityIDTableName
|
||||
*
|
||||
* @return array
|
||||
* list tables/queries (for runQueries)
|
||||
*/
|
||||
public function prepareQueries($queryText, $entityIDTableName) {
|
||||
// Note: For available full-text indices, see CRM_Core_InnoDBIndexer
|
||||
|
||||
$contactSQL = array();
|
||||
$contactSQL[] = "
|
||||
SELECT distinct cp.id
|
||||
FROM civicrm_participant cp
|
||||
INNER JOIN civicrm_contact c ON cp.contact_id = c.id
|
||||
WHERE ({$this->matchText('civicrm_contact c', array('sort_name', 'display_name', 'nick_name'), $queryText)})
|
||||
";
|
||||
$tables = array(
|
||||
'civicrm_participant' => array(
|
||||
'id' => 'id',
|
||||
'fields' => array(
|
||||
'source' => NULL,
|
||||
'fee_level' => NULL,
|
||||
'fee_amount' => 'Int',
|
||||
),
|
||||
),
|
||||
'file' => array(
|
||||
'xparent_table' => 'civicrm_participant',
|
||||
),
|
||||
'sql' => $contactSQL,
|
||||
'civicrm_note' => array(
|
||||
'id' => 'entity_id',
|
||||
'entity_table' => 'civicrm_participant',
|
||||
'fields' => array(
|
||||
'subject' => NULL,
|
||||
'note' => NULL,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// get the custom data info
|
||||
$this->fillCustomInfo($tables, "( 'Participant' )");
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move IDs.
|
||||
* @param string $fromTable
|
||||
* @param string $toTable
|
||||
* @param int $limit
|
||||
*/
|
||||
public function moveIDs($fromTable, $toTable, $limit) {
|
||||
$sql = "
|
||||
INSERT INTO {$toTable}
|
||||
( table_name, contact_id, sort_name, participant_id, event_title, participant_fee_level, participant_fee_amount,
|
||||
participant_register_date, participant_source, participant_status, participant_role )
|
||||
SELECT 'Participant', c.id, c.sort_name, cp.id, ce.title, cp.fee_level, cp.fee_amount, cp.register_date, cp.source,
|
||||
participantStatus.label, cp.role_id
|
||||
FROM {$fromTable} ct
|
||||
INNER JOIN civicrm_participant cp ON cp.id = ct.entity_id
|
||||
LEFT JOIN civicrm_contact c ON cp.contact_id = c.id
|
||||
LEFT JOIN civicrm_event ce ON ce.id = cp.event_id
|
||||
LEFT JOIN civicrm_participant_status_type participantStatus ON participantStatus.id = cp.status_id
|
||||
{$this->toLimit($limit)}
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,643 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_Group extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_formValues;
|
||||
|
||||
protected $_tableName = NULL;
|
||||
|
||||
protected $_where = ' (1) ';
|
||||
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
$this->_formValues = $formValues;
|
||||
$this->_columns = array(
|
||||
ts('Contact ID') => 'contact_id',
|
||||
ts('Contact Type') => 'contact_type',
|
||||
ts('Name') => 'sort_name',
|
||||
ts('Group Name') => 'gname',
|
||||
ts('Tag Name') => 'tname',
|
||||
);
|
||||
|
||||
$this->_includeGroups = CRM_Utils_Array::value('includeGroups', $this->_formValues, array());
|
||||
$this->_excludeGroups = CRM_Utils_Array::value('excludeGroups', $this->_formValues, array());
|
||||
$this->_includeTags = CRM_Utils_Array::value('includeTags', $this->_formValues, array());
|
||||
$this->_excludeTags = CRM_Utils_Array::value('excludeTags', $this->_formValues, array());
|
||||
|
||||
//define variables
|
||||
$this->_allSearch = FALSE;
|
||||
$this->_groups = FALSE;
|
||||
$this->_tags = FALSE;
|
||||
$this->_andOr = CRM_Utils_Array::value('andOr', $this->_formValues);
|
||||
//make easy to check conditions for groups and tags are
|
||||
//selected or it is empty search
|
||||
if (empty($this->_includeGroups) && empty($this->_excludeGroups) &&
|
||||
empty($this->_includeTags) && empty($this->_excludeTags)
|
||||
) {
|
||||
//empty search
|
||||
$this->_allSearch = TRUE;
|
||||
}
|
||||
|
||||
$this->_groups = (!empty($this->_includeGroups) || !empty($this->_excludeGroups));
|
||||
|
||||
$this->_tags = (!empty($this->_includeTags) || !empty($this->_excludeTags));
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
// mysql drops the tables when connection is terminated
|
||||
// cannot drop tables here, since the search might be used
|
||||
// in other parts after the object is destroyed
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
|
||||
$this->setTitle(ts('Include / Exclude Search'));
|
||||
|
||||
$groups = CRM_Core_PseudoConstant::nestedGroup();
|
||||
|
||||
$tags = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
|
||||
if (count($groups) == 0 || count($tags) == 0) {
|
||||
CRM_Core_Session::setStatus(ts("At least one Group and Tag must be present for Custom Group / Tag search."), ts('Missing Group/Tag'));
|
||||
$url = CRM_Utils_System::url('civicrm/contact/search/custom/list', 'reset=1');
|
||||
CRM_Utils_System::redirect($url);
|
||||
}
|
||||
|
||||
$select2style = array(
|
||||
'multiple' => TRUE,
|
||||
'style' => 'width: 100%; max-width: 60em;',
|
||||
'class' => 'crm-select2',
|
||||
'placeholder' => ts('- select -'),
|
||||
);
|
||||
|
||||
$form->add('select', 'includeGroups',
|
||||
ts('Include Group(s)'),
|
||||
$groups,
|
||||
FALSE,
|
||||
$select2style
|
||||
);
|
||||
|
||||
$form->add('select', 'excludeGroups',
|
||||
ts('Exclude Group(s)'),
|
||||
$groups,
|
||||
FALSE,
|
||||
$select2style
|
||||
);
|
||||
|
||||
$andOr = array(
|
||||
'1' => ts('Show contacts that meet the Groups criteria AND the Tags criteria'),
|
||||
'0' => ts('Show contacts that meet the Groups criteria OR the Tags criteria'),
|
||||
);
|
||||
$form->addRadio('andOr', ts('AND/OR'), $andOr, NULL, '<br />', TRUE);
|
||||
|
||||
$form->add('select', 'includeTags',
|
||||
ts('Include Tag(s)'),
|
||||
$tags,
|
||||
FALSE,
|
||||
$select2style
|
||||
);
|
||||
|
||||
$form->add('select', 'excludeTags',
|
||||
ts('Exclude Tag(s)'),
|
||||
$tags,
|
||||
FALSE,
|
||||
$select2style
|
||||
);
|
||||
|
||||
/**
|
||||
* if you are using the standard template, this array tells the template what elements
|
||||
* are part of the search criteria
|
||||
*/
|
||||
$form->assign('elements', array('includeGroups', 'excludeGroups', 'andOr', 'includeTags', 'excludeTags'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param NULL $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0, $rowcount = 0, $sort = NULL,
|
||||
$includeContactIDs = FALSE, $justIDs = FALSE
|
||||
) {
|
||||
|
||||
if ($justIDs) {
|
||||
$selectClause = "contact_a.id as contact_id";
|
||||
}
|
||||
else {
|
||||
$selectClause = "contact_a.id as contact_id,
|
||||
contact_a.contact_type as contact_type,
|
||||
contact_a.sort_name as sort_name";
|
||||
|
||||
//distinguish column according to user selection
|
||||
if (($this->_includeGroups && !$this->_includeTags)) {
|
||||
unset($this->_columns[ts('Tag Name')]);
|
||||
$selectClause .= ", GROUP_CONCAT(DISTINCT group_names ORDER BY group_names ASC ) as gname";
|
||||
}
|
||||
elseif ($this->_includeTags && (!$this->_includeGroups)) {
|
||||
unset($this->_columns[ts('Group Name')]);
|
||||
$selectClause .= ", GROUP_CONCAT(DISTINCT tag_names ORDER BY tag_names ASC ) as tname";
|
||||
}
|
||||
elseif (!empty($this->_includeTags) && !empty($this->_includeGroups)) {
|
||||
$selectClause .= ", GROUP_CONCAT(DISTINCT group_names ORDER BY group_names ASC ) as gname , GROUP_CONCAT(DISTINCT tag_names ORDER BY tag_names ASC ) as tname";
|
||||
}
|
||||
else {
|
||||
unset($this->_columns[ts('Tag Name')]);
|
||||
unset($this->_columns[ts('Group Name')]);
|
||||
}
|
||||
}
|
||||
|
||||
$from = $this->from();
|
||||
|
||||
$where = $this->where($includeContactIDs);
|
||||
|
||||
if (!$justIDs && !$this->_allSearch) {
|
||||
$groupBy = " GROUP BY contact_a.id";
|
||||
}
|
||||
else {
|
||||
// CRM-10850
|
||||
// we do this since this if stmt is called by the smart group part of the code
|
||||
// adding a groupBy clause and saving it as a smart group messes up the query and
|
||||
// bad things happen
|
||||
// andrew hunt seemed to have rewritten this piece when he worked on this search
|
||||
$groupBy = NULL;
|
||||
}
|
||||
|
||||
$sql = "SELECT $selectClause $from WHERE $where $groupBy";
|
||||
|
||||
// Define ORDER BY for query in $sort, with default value
|
||||
if (!$justIDs) {
|
||||
if (!empty($sort)) {
|
||||
if (is_string($sort)) {
|
||||
$sort = CRM_Utils_Type::escape($sort, 'String');
|
||||
$sql .= " ORDER BY $sort ";
|
||||
}
|
||||
else {
|
||||
$sql .= " ORDER BY " . trim($sort->orderBy());
|
||||
}
|
||||
}
|
||||
else {
|
||||
$sql .= " ORDER BY contact_id ASC";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$sql .= " ORDER BY contact_a.id ASC";
|
||||
}
|
||||
|
||||
if ($offset >= 0 && $rowcount > 0) {
|
||||
$sql .= " LIMIT $offset, $rowcount ";
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function from() {
|
||||
|
||||
$iGroups = $xGroups = $iTags = $xTags = 0;
|
||||
|
||||
//define table name
|
||||
$randomNum = md5(uniqid());
|
||||
$this->_tableName = "civicrm_temp_custom_{$randomNum}";
|
||||
|
||||
//block for Group search
|
||||
$smartGroup = array();
|
||||
if ($this->_groups || $this->_allSearch) {
|
||||
$group = new CRM_Contact_DAO_Group();
|
||||
$group->is_active = 1;
|
||||
$group->find();
|
||||
while ($group->fetch()) {
|
||||
$allGroups[] = $group->id;
|
||||
if ($group->saved_search_id) {
|
||||
$smartGroup[$group->saved_search_id] = $group->id;
|
||||
}
|
||||
}
|
||||
$includedGroups = implode(',', $allGroups);
|
||||
|
||||
if (!empty($this->_includeGroups)) {
|
||||
$iGroups = implode(',', $this->_includeGroups);
|
||||
}
|
||||
else {
|
||||
//if no group selected search for all groups
|
||||
$iGroups = NULL;
|
||||
}
|
||||
if (is_array($this->_excludeGroups)) {
|
||||
$xGroups = implode(',', $this->_excludeGroups);
|
||||
}
|
||||
else {
|
||||
$xGroups = 0;
|
||||
}
|
||||
|
||||
$sql = "CREATE TEMPORARY TABLE Xg_{$this->_tableName} ( contact_id int primary key) ENGINE=InnoDB";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$excludeGroup = "INSERT INTO Xg_{$this->_tableName} ( contact_id )
|
||||
SELECT DISTINCT civicrm_group_contact.contact_id
|
||||
FROM civicrm_group_contact, civicrm_contact
|
||||
WHERE
|
||||
civicrm_contact.id = civicrm_group_contact.contact_id AND
|
||||
civicrm_group_contact.status = 'Added' AND
|
||||
civicrm_group_contact.group_id IN( {$xGroups})";
|
||||
|
||||
CRM_Core_DAO::executeQuery($excludeGroup);
|
||||
|
||||
//search for smart group contacts
|
||||
foreach ($this->_excludeGroups as $keys => $values) {
|
||||
if (in_array($values, $smartGroup)) {
|
||||
$ssGroup = new CRM_Contact_DAO_Group();
|
||||
$ssGroup->id = $values;
|
||||
if (!$ssGroup->find(TRUE)) {
|
||||
CRM_Core_Error::fatal();
|
||||
}
|
||||
CRM_Contact_BAO_GroupContactCache::load($ssGroup);
|
||||
|
||||
$smartSql = "
|
||||
SELECT gcc.contact_id
|
||||
FROM civicrm_group_contact_cache gcc
|
||||
WHERE gcc.group_id = {$ssGroup->id}
|
||||
";
|
||||
$smartGroupQuery = " INSERT IGNORE INTO Xg_{$this->_tableName}(contact_id) $smartSql";
|
||||
CRM_Core_DAO::executeQuery($smartGroupQuery);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "CREATE TEMPORARY TABLE Ig_{$this->_tableName} ( id int PRIMARY KEY AUTO_INCREMENT,
|
||||
contact_id int,
|
||||
group_names varchar(64)) ENGINE=InnoDB";
|
||||
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
if ($iGroups) {
|
||||
$includeGroup = "INSERT INTO Ig_{$this->_tableName} (contact_id, group_names)
|
||||
SELECT civicrm_contact.id as contact_id, civicrm_group.title as group_name
|
||||
FROM civicrm_contact
|
||||
INNER JOIN civicrm_group_contact
|
||||
ON civicrm_group_contact.contact_id = civicrm_contact.id
|
||||
LEFT JOIN civicrm_group
|
||||
ON civicrm_group_contact.group_id = civicrm_group.id";
|
||||
}
|
||||
else {
|
||||
$includeGroup = "INSERT INTO Ig_{$this->_tableName} (contact_id, group_names)
|
||||
SELECT civicrm_contact.id as contact_id, ''
|
||||
FROM civicrm_contact";
|
||||
}
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$includeGroup .= " LEFT JOIN Xg_{$this->_tableName}
|
||||
ON civicrm_contact.id = Xg_{$this->_tableName}.contact_id";
|
||||
}
|
||||
|
||||
if ($iGroups) {
|
||||
$includeGroup .= " WHERE
|
||||
civicrm_group_contact.status = 'Added' AND
|
||||
civicrm_group_contact.group_id IN($iGroups)";
|
||||
}
|
||||
else {
|
||||
$includeGroup .= " WHERE ( 1 ) ";
|
||||
}
|
||||
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$includeGroup .= " AND Xg_{$this->_tableName}.contact_id IS null";
|
||||
}
|
||||
|
||||
CRM_Core_DAO::executeQuery($includeGroup);
|
||||
|
||||
//search for smart group contacts
|
||||
|
||||
foreach ($this->_includeGroups as $keys => $values) {
|
||||
if (in_array($values, $smartGroup)) {
|
||||
$ssGroup = new CRM_Contact_DAO_Group();
|
||||
$ssGroup->id = $values;
|
||||
if (!$ssGroup->find(TRUE)) {
|
||||
CRM_Core_Error::fatal();
|
||||
}
|
||||
CRM_Contact_BAO_GroupContactCache::load($ssGroup);
|
||||
|
||||
$smartSql = "
|
||||
SELECT gcc.contact_id
|
||||
FROM civicrm_group_contact_cache gcc
|
||||
WHERE gcc.group_id = {$ssGroup->id}
|
||||
";
|
||||
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$smartSql .= " AND gcc.contact_id NOT IN (SELECT contact_id FROM Xg_{$this->_tableName})";
|
||||
}
|
||||
|
||||
$smartGroupQuery = " INSERT IGNORE INTO Ig_{$this->_tableName}(contact_id)
|
||||
$smartSql";
|
||||
|
||||
CRM_Core_DAO::executeQuery($smartGroupQuery);
|
||||
$insertGroupNameQuery = "UPDATE IGNORE Ig_{$this->_tableName}
|
||||
SET group_names = (SELECT title FROM civicrm_group
|
||||
WHERE civicrm_group.id = $values)
|
||||
WHERE Ig_{$this->_tableName}.contact_id IS NOT NULL
|
||||
AND Ig_{$this->_tableName}.group_names IS NULL";
|
||||
CRM_Core_DAO::executeQuery($insertGroupNameQuery);
|
||||
}
|
||||
}
|
||||
}
|
||||
//group contact search end here;
|
||||
|
||||
//block for Tags search
|
||||
if ($this->_tags || $this->_allSearch) {
|
||||
//find all tags
|
||||
$tag = new CRM_Core_DAO_Tag();
|
||||
$tag->is_active = 1;
|
||||
$tag->find();
|
||||
while ($tag->fetch()) {
|
||||
$allTags[] = $tag->id;
|
||||
}
|
||||
$includedTags = implode(',', $allTags);
|
||||
|
||||
if (!empty($this->_includeTags)) {
|
||||
$iTags = implode(',', $this->_includeTags);
|
||||
}
|
||||
else {
|
||||
//if no group selected search for all groups
|
||||
$iTags = NULL;
|
||||
}
|
||||
if (is_array($this->_excludeTags)) {
|
||||
$xTags = implode(',', $this->_excludeTags);
|
||||
}
|
||||
else {
|
||||
$xTags = 0;
|
||||
}
|
||||
|
||||
$sql = "CREATE TEMPORARY TABLE Xt_{$this->_tableName} ( contact_id int primary key) ENGINE=InnoDB";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
//used only when exclude tag is selected
|
||||
if ($xTags != 0) {
|
||||
$excludeTag = "INSERT INTO Xt_{$this->_tableName} ( contact_id )
|
||||
SELECT DISTINCT civicrm_entity_tag.entity_id
|
||||
FROM civicrm_entity_tag, civicrm_contact
|
||||
WHERE
|
||||
civicrm_entity_tag.entity_table = 'civicrm_contact' AND
|
||||
civicrm_contact.id = civicrm_entity_tag.entity_id AND
|
||||
civicrm_entity_tag.tag_id IN( {$xTags})";
|
||||
|
||||
CRM_Core_DAO::executeQuery($excludeTag);
|
||||
}
|
||||
|
||||
$sql = "CREATE TEMPORARY TABLE It_{$this->_tableName} ( id int PRIMARY KEY AUTO_INCREMENT,
|
||||
contact_id int,
|
||||
tag_names varchar(64)) ENGINE=InnoDB";
|
||||
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
if ($iTags) {
|
||||
$includeTag = "INSERT INTO It_{$this->_tableName} (contact_id, tag_names)
|
||||
SELECT civicrm_contact.id as contact_id, civicrm_tag.name as tag_name
|
||||
FROM civicrm_contact
|
||||
INNER JOIN civicrm_entity_tag
|
||||
ON ( civicrm_entity_tag.entity_table = 'civicrm_contact' AND
|
||||
civicrm_entity_tag.entity_id = civicrm_contact.id )
|
||||
LEFT JOIN civicrm_tag
|
||||
ON civicrm_entity_tag.tag_id = civicrm_tag.id";
|
||||
}
|
||||
else {
|
||||
$includeTag = "INSERT INTO It_{$this->_tableName} (contact_id, tag_names)
|
||||
SELECT civicrm_contact.id as contact_id, ''
|
||||
FROM civicrm_contact";
|
||||
}
|
||||
|
||||
//used only when exclude tag is selected
|
||||
if ($xTags != 0) {
|
||||
$includeTag .= " LEFT JOIN Xt_{$this->_tableName}
|
||||
ON civicrm_contact.id = Xt_{$this->_tableName}.contact_id";
|
||||
}
|
||||
if ($iTags) {
|
||||
$includeTag .= " WHERE civicrm_entity_tag.tag_id IN($iTags)";
|
||||
}
|
||||
else {
|
||||
$includeTag .= " WHERE ( 1 ) ";
|
||||
}
|
||||
|
||||
//used only when exclude tag is selected
|
||||
if ($xTags != 0) {
|
||||
$includeTag .= " AND Xt_{$this->_tableName}.contact_id IS null";
|
||||
}
|
||||
|
||||
CRM_Core_DAO::executeQuery($includeTag);
|
||||
}
|
||||
|
||||
$from = " FROM civicrm_contact contact_a";
|
||||
|
||||
/*
|
||||
* CRM-10850 / CRM-10848
|
||||
* If we use include / exclude groups as smart groups for ACL's having the below causes
|
||||
* a cycle which messes things up. Hence commenting out for now
|
||||
* $this->buildACLClause('contact_a');
|
||||
*/
|
||||
|
||||
/*
|
||||
* check the situation and set booleans
|
||||
*/
|
||||
$Ig = ($iGroups != 0);
|
||||
$It = ($iTags != 0);
|
||||
$Xg = ($xGroups != 0);
|
||||
$Xt = ($xTags != 0);
|
||||
|
||||
//PICK UP FROM HERE
|
||||
if (!$this->_groups && !$this->_tags) {
|
||||
$this->_andOr = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set from statement depending on array sel
|
||||
*/
|
||||
$whereitems = array();
|
||||
foreach (array('Ig', 'It') as $inc) {
|
||||
if ($this->_andOr == 1) {
|
||||
if ($$inc) {
|
||||
$from .= " INNER JOIN {$inc}_{$this->_tableName} temptable$inc ON (contact_a.id = temptable$inc.contact_id)";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($$inc) {
|
||||
$from .= " LEFT JOIN {$inc}_{$this->_tableName} temptable$inc ON (contact_a.id = temptable$inc.contact_id)";
|
||||
}
|
||||
}
|
||||
if ($$inc) {
|
||||
$whereitems[] = "temptable$inc.contact_id IS NOT NULL";
|
||||
}
|
||||
}
|
||||
$this->_where = $whereitems ? "(" . implode(' OR ', $whereitems) . ')' : '(1)';
|
||||
foreach (array('Xg', 'Xt') as $exc) {
|
||||
if ($$exc) {
|
||||
$from .= " LEFT JOIN {$exc}_{$this->_tableName} temptable$exc ON (contact_a.id = temptable$exc.contact_id)";
|
||||
$this->_where .= " AND temptable$exc.contact_id IS NULL";
|
||||
}
|
||||
}
|
||||
|
||||
$from .= " LEFT JOIN civicrm_email ON ( contact_a.id = civicrm_email.contact_id AND ( civicrm_email.is_primary = 1 OR civicrm_email.is_bulkmail = 1 ) ) {$this->_aclFrom}";
|
||||
|
||||
if ($this->_aclWhere) {
|
||||
$this->_where .= " AND {$this->_aclWhere} ";
|
||||
}
|
||||
|
||||
// also exclude all contacts that are deleted
|
||||
// CRM-11627
|
||||
$this->_where .= " AND (contact_a.is_deleted != 1) ";
|
||||
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
if ($includeContactIDs) {
|
||||
$contactIDs = array();
|
||||
|
||||
foreach ($this->_formValues as $id => $value) {
|
||||
if ($value &&
|
||||
substr($id, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX
|
||||
) {
|
||||
$contactIDs[] = substr($id, CRM_Core_Form::CB_PREFIX_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($contactIDs)) {
|
||||
$contactIDs = implode(', ', $contactIDs);
|
||||
$clauses[] = "contact_a.id IN ( $contactIDs )";
|
||||
}
|
||||
$where = "{$this->_where} AND " . implode(' AND ', $clauses);
|
||||
}
|
||||
else {
|
||||
$where = $this->_where;
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions below generally don't need to be modified
|
||||
*/
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function count() {
|
||||
$sql = $this->all();
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql);
|
||||
return $dao->N;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param NULL $sort
|
||||
* @param bool $returnSQL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = FALSE) {
|
||||
return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function &columns() {
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get summary.
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
public function summary() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title on search.
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build ACL clause.
|
||||
*
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,302 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_MultipleValues extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_groupTree;
|
||||
protected $_tables;
|
||||
protected $_options;
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
protected $fieldInfo = array();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
parent::__construct($formValues);
|
||||
|
||||
$this->_groupTree = CRM_Core_BAO_CustomGroup::getTree("'Contact', 'Individual', 'Organization', 'Household'", NULL, NULL, -1);
|
||||
|
||||
$this->_group = CRM_Utils_Array::value('group', $this->_formValues);
|
||||
|
||||
$this->_tag = CRM_Utils_Array::value('tag', $this->_formValues);
|
||||
|
||||
$this->_columns = array(
|
||||
ts('Contact ID') => 'contact_id',
|
||||
ts('Contact Type') => 'contact_type',
|
||||
ts('Name') => 'sort_name',
|
||||
);
|
||||
|
||||
$this->_customGroupIDs = CRM_Utils_Array::value('custom_group', $formValues);
|
||||
|
||||
if (!empty($this->_customGroupIDs)) {
|
||||
$this->addColumns();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all the fields for chosen groups
|
||||
*/
|
||||
public function addColumns() {
|
||||
$this->_tables = array();
|
||||
foreach ($this->_groupTree as $groupID => $group) {
|
||||
if (empty($this->_customGroupIDs[$groupID])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->fieldInfo += $group['fields'];
|
||||
|
||||
// now handle all the fields
|
||||
foreach ($group['fields'] as $fieldID => $field) {
|
||||
$this->_columns[$field['label']] = "custom_{$field['id']}";
|
||||
if (!array_key_exists($group['table_name'], $this->_tables)) {
|
||||
$this->_tables[$group['table_name']] = array();
|
||||
}
|
||||
$this->_tables[$group['table_name']][$field['id']] = $field['column_name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
|
||||
$this->setTitle('Multiple Value Custom Group Search and Export');
|
||||
|
||||
$form->add('text', 'sort_name', ts('Contact Name'), TRUE);
|
||||
|
||||
$contactTypes = array('' => ts('- any contact type -')) + CRM_Contact_BAO_ContactType::getSelectElements();
|
||||
$form->add('select', 'contact_type', ts('Find...'), $contactTypes, array('class' => 'crm-select2 huge'));
|
||||
|
||||
// add select for groups
|
||||
$group = array('' => ts('- any group -')) + CRM_Core_PseudoConstant::group();
|
||||
$form->addElement('select', 'group', ts('in'), $group, array('class' => 'crm-select2 huge'));
|
||||
|
||||
// add select for tags
|
||||
$tag = array('' => ts('- any tag -')) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
|
||||
$form->addElement('select', 'tag', ts('Tagged'), $tag, array('class' => 'crm-select2 huge'));
|
||||
|
||||
if (empty($this->_groupTree)) {
|
||||
CRM_Core_Error::statusBounce(ts("Atleast one Custom Group must be present, for Custom Group search."),
|
||||
CRM_Utils_System::url('civicrm/contact/search/custom/list',
|
||||
'reset=1'
|
||||
)
|
||||
);
|
||||
}
|
||||
// add the checkbox for custom_groups
|
||||
foreach ($this->_groupTree as $groupID => $group) {
|
||||
if ($groupID == 'info') {
|
||||
continue;
|
||||
}
|
||||
$form->addElement('checkbox', "custom_group[$groupID]", NULL, $group['title']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function summary() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = FALSE) {
|
||||
return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all($offset = 0, $rowcount = 0, $sort = NULL, $includeContactIDs = FALSE, $justIDs = FALSE) {
|
||||
//redirect if custom group not select in search criteria
|
||||
if (empty($this->_formValues['custom_group'])) {
|
||||
CRM_Core_Error::statusBounce(ts("You must select at least one Custom Group as a search criteria."),
|
||||
CRM_Utils_System::url('civicrm/contact/search/custom',
|
||||
"reset=1&csid={$this->_formValues['customSearchID']}",
|
||||
FALSE, NULL, FALSE, TRUE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($justIDs) {
|
||||
$selectClause = "contact_a.id as contact_id";
|
||||
$sort = "contact_a.id";
|
||||
|
||||
return $this->sql($selectClause, $offset, $rowcount, $sort, $includeContactIDs, NULL);
|
||||
}
|
||||
else {
|
||||
$selectClause = "
|
||||
contact_a.id as contact_id ,
|
||||
contact_a.contact_type as contact_type,
|
||||
contact_a.sort_name as sort_name,
|
||||
";
|
||||
}
|
||||
|
||||
$customClauses = array();
|
||||
foreach ($this->_tables as $tableName => $fields) {
|
||||
foreach ($fields as $fieldID => $fieldName) {
|
||||
$customClauses[] = "{$tableName}.{$fieldName} as custom_{$fieldID}";
|
||||
}
|
||||
}
|
||||
$selectClause .= implode(',', $customClauses);
|
||||
|
||||
return $this->sql($selectClause,
|
||||
$offset, $rowcount, $sort,
|
||||
$includeContactIDs, NULL
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
$this->buildACLClause('contact_a');
|
||||
$from = "FROM civicrm_contact contact_a {$this->_aclFrom}";
|
||||
$customFrom = array();
|
||||
// lets do an INNER JOIN so we get only relevant values rather than all values
|
||||
if (!empty($this->_tables)) {
|
||||
foreach ($this->_tables as $tableName => $fields) {
|
||||
$customFrom[] = " INNER JOIN $tableName ON {$tableName}.entity_id = contact_a.id ";
|
||||
}
|
||||
$from .= implode(' ', $customFrom);
|
||||
}
|
||||
|
||||
// This prevents duplicate rows when contacts have more than one tag any you select "any tag"
|
||||
if ($this->_tag) {
|
||||
$from .= " LEFT JOIN civicrm_entity_tag t ON (t.entity_table='civicrm_contact'
|
||||
AND contact_a.id = t.entity_id)";
|
||||
}
|
||||
|
||||
if ($this->_group) {
|
||||
$from .= " LEFT JOIN civicrm_group_contact cgc ON ( cgc.contact_id = contact_a.id
|
||||
AND cgc.status = 'Added')";
|
||||
}
|
||||
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$count = 1;
|
||||
$clause = array();
|
||||
$params = array();
|
||||
$name = CRM_Utils_Array::value('sort_name',
|
||||
$this->_formValues
|
||||
);
|
||||
if ($name != NULL) {
|
||||
if (strpos($name, '%') === FALSE) {
|
||||
$name = "%{$name}%";
|
||||
}
|
||||
$params[$count] = array($name, 'String');
|
||||
$clause[] = "contact_a.sort_name LIKE %{$count}";
|
||||
$count++;
|
||||
}
|
||||
|
||||
$contact_type = CRM_Utils_Array::value('contact_type',
|
||||
$this->_formValues
|
||||
);
|
||||
if ($contact_type != NULL) {
|
||||
$contactType = explode('__', $contact_type);
|
||||
if (count($contactType) > 1) {
|
||||
$clause[] = "contact_a.contact_type = '$contactType[0]' AND contact_a.contact_sub_type = '$contactType[1]'";
|
||||
}
|
||||
else {
|
||||
$clause[] = "contact_a.contact_type = '$contactType[0]'";
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_tag) {
|
||||
$clause[] = "t.tag_id = {$this->_tag}";
|
||||
}
|
||||
|
||||
if ($this->_group) {
|
||||
$clause[] = "cgc.group_id = {$this->_group}";
|
||||
}
|
||||
if ($this->_aclWhere) {
|
||||
$clause[] = " {$this->_aclWhere}";
|
||||
}
|
||||
|
||||
$where = '( 1 )';
|
||||
if (!empty($clause)) {
|
||||
$where .= ' AND ' . implode(' AND ', $clause);
|
||||
}
|
||||
|
||||
return $this->whereClause($where, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom/MultipleValues.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $row
|
||||
*/
|
||||
public function alterRow(&$row) {
|
||||
foreach ($row as $fieldName => &$field) {
|
||||
if (strpos($fieldName, 'custom_') === 0) {
|
||||
$field = CRM_Core_BAO_CustomField::displayValue($field, $fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_PostalMailing extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
parent::__construct($formValues);
|
||||
|
||||
$this->_columns = array(
|
||||
// If possible, don't use aliases for the columns you select.
|
||||
// You can prefix columns with table aliases, if needed.
|
||||
//
|
||||
// If you don't do this, selecting individual records from the
|
||||
// custom search result won't work if your results are sorted on the
|
||||
// aliased colums.
|
||||
// (This is why we map Contact ID on contact_a.id, and not on contact_id).
|
||||
ts('Contact ID') => 'contact_a.id',
|
||||
ts('Address') => 'street_address',
|
||||
ts('Contact Type') => 'contact_type',
|
||||
ts('Name') => 'sort_name',
|
||||
// You need to provide a table alias if there field exists in multiple
|
||||
// tables of your join. Name is also a field of address, so we prefix it
|
||||
// by state_province.
|
||||
// If you don't do this, the patch of CRM-16587 might cause database
|
||||
// errors.
|
||||
ts('State') => 'state_province.name',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
$groups = array('' => ts('- select group -')) + CRM_Core_PseudoConstant::nestedGroup(FALSE);
|
||||
$form->addElement('select', 'group_id', ts('Group'), $groups, array('class' => 'crm-select2 huge'));
|
||||
|
||||
/**
|
||||
* if you are using the standard template, this array tells the template what elements
|
||||
* are part of the search criteria
|
||||
*/
|
||||
$form->assign('elements', array('group_id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = FALSE) {
|
||||
return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0, $rowcount = 0, $sort = NULL,
|
||||
$includeContactIDs = FALSE, $justIDs = FALSE
|
||||
) {
|
||||
if ($justIDs) {
|
||||
$selectClause = "contact_a.id as contact_id";
|
||||
// Don't change sort order when $justIDs is TRUE, see CRM-14920.
|
||||
}
|
||||
else {
|
||||
// YOU NEED to select contact_a.id as contact_id, if you want to be able
|
||||
// to select individual records from the result.
|
||||
// But if you want to display the contact ID in your result set, you
|
||||
// also need to select contact_a.id. This is because of the patch we
|
||||
// use for CRM-16587.
|
||||
$selectClause = "
|
||||
DISTINCT contact_a.id as contact_id ,
|
||||
contact_a.id,
|
||||
contact_a.contact_type as contact_type,
|
||||
contact_a.sort_name as sort_name,
|
||||
address.street_address,
|
||||
state_province.name
|
||||
";
|
||||
}
|
||||
|
||||
return $this->sql($selectClause,
|
||||
$offset, $rowcount, $sort,
|
||||
$includeContactIDs, NULL
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
$this->buildACLClause('contact_a');
|
||||
$from = "
|
||||
FROM civicrm_group_contact as cgc,
|
||||
civicrm_contact as contact_a
|
||||
LEFT JOIN civicrm_address address ON (address.contact_id = contact_a.id AND
|
||||
address.is_primary = 1 )
|
||||
LEFT JOIN civicrm_state_province state_province ON state_province.id = address.state_province_id {$this->_aclFrom}
|
||||
";
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$params = array();
|
||||
|
||||
$count = 1;
|
||||
$clause = array();
|
||||
$groupID = CRM_Utils_Array::value('group_id',
|
||||
$this->_formValues
|
||||
);
|
||||
if ($groupID) {
|
||||
$params[$count] = array($groupID, 'Integer');
|
||||
$clause[] = "cgc.group_id = %{$count}";
|
||||
}
|
||||
|
||||
$clause[] = "cgc.status = 'Added'";
|
||||
$clause[] = "contact_a.id = IF( EXISTS(select cr.id from civicrm_relationship cr where (cr.contact_id_a = cgc.contact_id AND (cr.relationship_type_id = 7 OR cr.relationship_type_id = 6))),
|
||||
(select cr.contact_id_b from civicrm_relationship cr where (cr.contact_id_a = cgc.contact_id AND (cr.relationship_type_id = 7 OR cr.relationship_type_id = 6))),
|
||||
cgc.contact_id )";
|
||||
$clause[] = "contact_a.contact_type IN ('Individual','Household')";
|
||||
|
||||
if ($this->_aclWhere) {
|
||||
$clause[] = " {$this->_aclWhere} ";
|
||||
}
|
||||
|
||||
if (!empty($clause)) {
|
||||
$where = implode(' AND ', $clause);
|
||||
}
|
||||
|
||||
return $this->whereClause($where, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,366 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_PriceSet extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_eventID = NULL;
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
protected $_tableName = NULL;
|
||||
public $_permissionedComponent;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
parent::__construct($formValues);
|
||||
|
||||
$this->_eventID = CRM_Utils_Array::value('event_id',
|
||||
$this->_formValues
|
||||
);
|
||||
|
||||
$this->setColumns();
|
||||
|
||||
if ($this->_eventID) {
|
||||
$this->buildTempTable();
|
||||
$this->fillTable();
|
||||
}
|
||||
|
||||
// define component access permission needed
|
||||
$this->_permissionedComponent = 'CiviEvent';
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
/*
|
||||
if ( $this->_eventID ) {
|
||||
$sql = "DROP TEMPORARY TABLE {$this->_tableName}";
|
||||
CRM_Core_DAO::executeQuery( $sql );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public function buildTempTable() {
|
||||
$randomNum = md5(uniqid());
|
||||
$this->_tableName = "civicrm_temp_custom_{$randomNum}";
|
||||
$sql = "
|
||||
CREATE TEMPORARY TABLE {$this->_tableName} (
|
||||
id int unsigned NOT NULL AUTO_INCREMENT,
|
||||
contact_id int unsigned NOT NULL,
|
||||
participant_id int unsigned NOT NULL,
|
||||
";
|
||||
|
||||
foreach ($this->_columns as $dontCare => $fieldName) {
|
||||
if (in_array($fieldName, array(
|
||||
'contact_id',
|
||||
'participant_id',
|
||||
'display_name',
|
||||
))) {
|
||||
continue;
|
||||
}
|
||||
$sql .= "{$fieldName} int default 0,\n";
|
||||
}
|
||||
|
||||
$sql .= "
|
||||
PRIMARY KEY ( id ),
|
||||
UNIQUE INDEX unique_participant_id ( participant_id )
|
||||
) ENGINE=HEAP
|
||||
";
|
||||
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
}
|
||||
|
||||
public function fillTable() {
|
||||
$sql = "
|
||||
REPLACE INTO {$this->_tableName}
|
||||
( contact_id, participant_id )
|
||||
SELECT c.id, p.id
|
||||
FROM civicrm_contact c,
|
||||
civicrm_participant p
|
||||
WHERE p.contact_id = c.id
|
||||
AND p.is_test = 0
|
||||
AND p.event_id = {$this->_eventID}
|
||||
AND p.status_id NOT IN (4,11,12)
|
||||
AND ( c.is_deleted = 0 OR c.is_deleted IS NULL )
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
$sql = "
|
||||
SELECT c.id as contact_id,
|
||||
p.id as participant_id,
|
||||
l.price_field_value_id as price_field_value_id,
|
||||
l.qty
|
||||
FROM civicrm_contact c,
|
||||
civicrm_participant p,
|
||||
civicrm_line_item l
|
||||
WHERE c.id = p.contact_id
|
||||
AND p.event_id = {$this->_eventID}
|
||||
AND p.id = l.entity_id
|
||||
AND l.entity_table ='civicrm_participant'
|
||||
ORDER BY c.id, l.price_field_value_id;
|
||||
";
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
// first store all the information by option value id
|
||||
$rows = array();
|
||||
while ($dao->fetch()) {
|
||||
$contactID = $dao->contact_id;
|
||||
$participantID = $dao->participant_id;
|
||||
if (!isset($rows[$participantID])) {
|
||||
$rows[$participantID] = array();
|
||||
}
|
||||
|
||||
$rows[$participantID][] = "price_field_{$dao->price_field_value_id} = {$dao->qty}";
|
||||
}
|
||||
|
||||
foreach (array_keys($rows) as $participantID) {
|
||||
$values = implode(',', $rows[$participantID]);
|
||||
$sql = "
|
||||
UPDATE {$this->_tableName}
|
||||
SET $values
|
||||
WHERE participant_id = $participantID;
|
||||
";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $eventID
|
||||
*
|
||||
* @return Object
|
||||
*/
|
||||
public function priceSetDAO($eventID = NULL) {
|
||||
|
||||
// get all the events that have a price set associated with it
|
||||
$sql = "
|
||||
SELECT e.id as id,
|
||||
e.title as title,
|
||||
p.price_set_id as price_set_id
|
||||
FROM civicrm_event e,
|
||||
civicrm_price_set_entity p
|
||||
|
||||
WHERE p.entity_table = 'civicrm_event'
|
||||
AND p.entity_id = e.id
|
||||
";
|
||||
|
||||
$params = array();
|
||||
if ($eventID) {
|
||||
$params[1] = array($eventID, 'Integer');
|
||||
$sql .= " AND e.id = $eventID";
|
||||
}
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql,
|
||||
$params
|
||||
);
|
||||
return $dao;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
$dao = $this->priceSetDAO();
|
||||
|
||||
$event = array();
|
||||
while ($dao->fetch()) {
|
||||
$event[$dao->id] = $dao->title;
|
||||
}
|
||||
|
||||
if (empty($event)) {
|
||||
CRM_Core_Error::fatal(ts('There are no events with Price Sets'));
|
||||
}
|
||||
|
||||
$form->add('select',
|
||||
'event_id',
|
||||
ts('Event'),
|
||||
$event,
|
||||
TRUE
|
||||
);
|
||||
|
||||
/**
|
||||
* You can define a custom title for the search form
|
||||
*/
|
||||
$this->setTitle('Price Set Export');
|
||||
|
||||
/**
|
||||
* if you are using the standard template, this array tells the template what elements
|
||||
* are part of the search criteria
|
||||
*/
|
||||
$form->assign('elements', array('event_id'));
|
||||
}
|
||||
|
||||
public function setColumns() {
|
||||
$this->_columns = array(
|
||||
ts('Contact ID') => 'contact_id',
|
||||
ts('Participant ID') => 'participant_id',
|
||||
ts('Name') => 'display_name',
|
||||
);
|
||||
|
||||
if (!$this->_eventID) {
|
||||
return;
|
||||
}
|
||||
|
||||
// for the selected event, find the price set and all the columns associated with it.
|
||||
// create a column for each field and option group within it
|
||||
$dao = $this->priceSetDAO($this->_formValues['event_id']);
|
||||
|
||||
if ($dao->fetch() &&
|
||||
!$dao->price_set_id
|
||||
) {
|
||||
CRM_Core_Error::fatal(ts('There are no events with Price Sets'));
|
||||
}
|
||||
|
||||
// get all the fields and all the option values associated with it
|
||||
$priceSet = CRM_Price_BAO_PriceSet::getSetDetail($dao->price_set_id);
|
||||
if (is_array($priceSet[$dao->price_set_id])) {
|
||||
foreach ($priceSet[$dao->price_set_id]['fields'] as $key => $value) {
|
||||
if (is_array($value['options'])) {
|
||||
foreach ($value['options'] as $oKey => $oValue) {
|
||||
$columnHeader = CRM_Utils_Array::value('label', $value);
|
||||
if (CRM_Utils_Array::value('html_type', $value) != 'Text') {
|
||||
$columnHeader .= ' - ' . $oValue['label'];
|
||||
}
|
||||
|
||||
$this->_columns[$columnHeader] = "price_field_{$oValue['id']}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function summary() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0, $rowcount = 0, $sort = NULL,
|
||||
$includeContactIDs = FALSE, $justIDs = FALSE
|
||||
) {
|
||||
if ($justIDs) {
|
||||
$selectClause = "contact_a.id as contact_id";
|
||||
}
|
||||
else {
|
||||
$selectClause = "
|
||||
contact_a.id as contact_id ,
|
||||
contact_a.display_name as display_name";
|
||||
|
||||
foreach ($this->_columns as $dontCare => $fieldName) {
|
||||
if (in_array($fieldName, array(
|
||||
'contact_id',
|
||||
'display_name',
|
||||
))) {
|
||||
continue;
|
||||
}
|
||||
$selectClause .= ",\ntempTable.{$fieldName} as {$fieldName}";
|
||||
}
|
||||
}
|
||||
|
||||
return $this->sql($selectClause,
|
||||
$offset, $rowcount, $sort,
|
||||
$includeContactIDs, NULL
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
$this->buildACLClause('contact_a');
|
||||
$from = "
|
||||
FROM civicrm_contact contact_a
|
||||
INNER JOIN {$this->_tableName} tempTable ON ( tempTable.contact_id = contact_a.id ) {$this->_aclFrom}
|
||||
";
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$where = ' ( 1 ) ';
|
||||
if ($this->_aclWhere) {
|
||||
$where .= " AND {$this->_aclWhere} ";
|
||||
}
|
||||
return $where;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $row
|
||||
*/
|
||||
public function alterRow(&$row) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Export Price Set Info for an Event'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,323 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_Proximity extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_latitude = NULL;
|
||||
protected $_longitude = NULL;
|
||||
protected $_distance = NULL;
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
parent::__construct($formValues);
|
||||
|
||||
// unset search profile and other search params if set
|
||||
unset($this->_formValues['uf_group_id']);
|
||||
unset($this->_formValues['component_mode']);
|
||||
unset($this->_formValues['operator']);
|
||||
|
||||
if (!empty($this->_formValues)) {
|
||||
// add the country and state
|
||||
if (!empty($this->_formValues['country_id'])) {
|
||||
$this->_formValues['country'] = CRM_Core_PseudoConstant::country($this->_formValues['country_id']);
|
||||
}
|
||||
|
||||
if (!empty($this->_formValues['state_province_id'])) {
|
||||
$this->_formValues['state_province'] = CRM_Core_PseudoConstant::stateProvince($this->_formValues['state_province_id']);
|
||||
}
|
||||
|
||||
// use the address to get the latitude and longitude
|
||||
CRM_Utils_Geocode_Google::format($this->_formValues);
|
||||
|
||||
if (!is_numeric(CRM_Utils_Array::value('geo_code_1', $this->_formValues)) ||
|
||||
!is_numeric(CRM_Utils_Array::value('geo_code_2', $this->_formValues)) ||
|
||||
!isset($this->_formValues['distance'])
|
||||
) {
|
||||
CRM_Core_Error::fatal(ts('Could not geocode input'));
|
||||
}
|
||||
|
||||
$this->_latitude = $this->_formValues['geo_code_1'];
|
||||
$this->_longitude = $this->_formValues['geo_code_2'];
|
||||
|
||||
if ($this->_formValues['prox_distance_unit'] == "miles") {
|
||||
$conversionFactor = 1609.344;
|
||||
}
|
||||
else {
|
||||
$conversionFactor = 1000;
|
||||
}
|
||||
$this->_distance = $this->_formValues['distance'] * $conversionFactor;
|
||||
}
|
||||
$this->_group = CRM_Utils_Array::value('group', $this->_formValues);
|
||||
|
||||
$this->_tag = CRM_Utils_Array::value('tag', $this->_formValues);
|
||||
|
||||
$this->_columns = array(
|
||||
ts('Name') => 'sort_name',
|
||||
ts('Street Address') => 'street_address',
|
||||
ts('City') => 'city',
|
||||
ts('Postal Code') => 'postal_code',
|
||||
ts('State') => 'state_province',
|
||||
ts('Country') => 'country',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
|
||||
$config = CRM_Core_Config::singleton();
|
||||
$countryDefault = $config->defaultContactCountry;
|
||||
|
||||
$form->add('text', 'distance', ts('Distance'), NULL, TRUE);
|
||||
|
||||
$proxUnits = array('km' => ts('km'), 'miles' => ts('miles'));
|
||||
$form->add('select', 'prox_distance_unit', ts('Units'), $proxUnits, TRUE);
|
||||
|
||||
$form->add('text',
|
||||
'street_address',
|
||||
ts('Street Address')
|
||||
);
|
||||
|
||||
$form->add('text',
|
||||
'city',
|
||||
ts('City')
|
||||
);
|
||||
|
||||
$form->add('text',
|
||||
'postal_code',
|
||||
ts('Postal Code')
|
||||
);
|
||||
|
||||
$defaults = array();
|
||||
if ($countryDefault) {
|
||||
$defaults['country_id'] = $countryDefault;
|
||||
}
|
||||
$form->addChainSelect('state_province_id');
|
||||
|
||||
$country = array('' => ts('- select -')) + CRM_Core_PseudoConstant::country();
|
||||
$form->add('select', 'country_id', ts('Country'), $country, TRUE, array('class' => 'crm-select2'));
|
||||
|
||||
$group = array('' => ts('- any group -')) + CRM_Core_PseudoConstant::nestedGroup();
|
||||
$form->addElement('select', 'group', ts('Group'), $group, array('class' => 'crm-select2 huge'));
|
||||
|
||||
$tag = array('' => ts('- any tag -')) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
|
||||
$form->addElement('select', 'tag', ts('Tag'), $tag, array('class' => 'crm-select2 huge'));
|
||||
|
||||
/**
|
||||
* You can define a custom title for the search form
|
||||
*/
|
||||
$this->setTitle('Proximity Search');
|
||||
|
||||
/**
|
||||
* if you are using the standard template, this array tells the template what elements
|
||||
* are part of the search criteria
|
||||
*/
|
||||
$form->assign('elements', array(
|
||||
'distance',
|
||||
'prox_distance_unit',
|
||||
'street_address',
|
||||
'city',
|
||||
'postal_code',
|
||||
'country_id',
|
||||
'state_province_id',
|
||||
'group',
|
||||
'tag',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0, $rowcount = 0, $sort = NULL,
|
||||
$includeContactIDs = FALSE, $justIDs = FALSE
|
||||
) {
|
||||
if ($justIDs) {
|
||||
$selectClause = "contact_a.id as contact_id";
|
||||
}
|
||||
else {
|
||||
$selectClause = "
|
||||
contact_a.id as contact_id ,
|
||||
contact_a.sort_name as sort_name ,
|
||||
address.street_address as street_address,
|
||||
address.city as city ,
|
||||
address.postal_code as postal_code ,
|
||||
state_province.name as state_province,
|
||||
country.name as country
|
||||
";
|
||||
}
|
||||
|
||||
return $this->sql($selectClause,
|
||||
$offset, $rowcount, $sort,
|
||||
$includeContactIDs, NULL
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
$this->buildACLClause('contact_a');
|
||||
$f = "
|
||||
FROM civicrm_contact contact_a
|
||||
LEFT JOIN civicrm_address address ON ( address.contact_id = contact_a.id AND
|
||||
address.is_primary = 1 )
|
||||
LEFT JOIN civicrm_state_province state_province ON state_province.id = address.state_province_id
|
||||
LEFT JOIN civicrm_country country ON country.id = address.country_id {$this->_aclFrom}
|
||||
";
|
||||
|
||||
// This prevents duplicate rows when contacts have more than one tag any you select "any tag"
|
||||
if ($this->_tag) {
|
||||
$f .= "
|
||||
LEFT JOIN civicrm_entity_tag t ON (t.entity_table='civicrm_contact' AND contact_a.id = t.entity_id)
|
||||
";
|
||||
}
|
||||
if ($this->_group) {
|
||||
$f .= "
|
||||
LEFT JOIN civicrm_group_contact cgc ON ( cgc.contact_id = contact_a.id AND cgc.status = 'Added')
|
||||
";
|
||||
}
|
||||
|
||||
return $f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$params = array();
|
||||
$clause = array();
|
||||
|
||||
$where = CRM_Contact_BAO_ProximityQuery::where($this->_latitude,
|
||||
$this->_longitude,
|
||||
$this->_distance,
|
||||
'address'
|
||||
);
|
||||
|
||||
if ($this->_tag) {
|
||||
$where .= "
|
||||
AND t.tag_id = {$this->_tag}
|
||||
";
|
||||
}
|
||||
if ($this->_group) {
|
||||
$where .= "
|
||||
AND cgc.group_id = {$this->_group}
|
||||
";
|
||||
}
|
||||
|
||||
$where .= " AND contact_a.is_deleted != 1 ";
|
||||
|
||||
if ($this->_aclWhere) {
|
||||
$where .= " AND {$this->_aclWhere} ";
|
||||
}
|
||||
|
||||
return $this->whereClause($where, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom/Proximity.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function setDefaultValues() {
|
||||
if (!empty($this->_formValues)) {
|
||||
return $this->_formValues;
|
||||
}
|
||||
$config = CRM_Core_Config::singleton();
|
||||
$countryDefault = $config->defaultContactCountry;
|
||||
$stateprovinceDefault = $config->defaultContactStateProvince;
|
||||
$defaults = array();
|
||||
|
||||
if ($countryDefault) {
|
||||
if ($countryDefault == '1228' || $countryDefault == '1226') {
|
||||
$defaults['prox_distance_unit'] = 'miles';
|
||||
}
|
||||
else {
|
||||
$defaults['prox_distance_unit'] = 'km';
|
||||
}
|
||||
$defaults['country_id'] = $countryDefault;
|
||||
if ($stateprovinceDefault) {
|
||||
$defaults['state_province_id'] = $stateprovinceDefault;
|
||||
}
|
||||
return $defaults;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $row
|
||||
*/
|
||||
public function alterRow(&$row) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,402 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_RandomSegment extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_debug = 0;
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
parent::__construct($formValues);
|
||||
|
||||
$this->_columns = array(
|
||||
ts('Contact ID') => 'contact_id',
|
||||
ts('Contact Type') => 'contact_type',
|
||||
ts('Name') => 'sort_name',
|
||||
ts('Email') => 'email',
|
||||
);
|
||||
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
public function initialize() {
|
||||
$this->_segmentSize = CRM_Utils_Array::value('segmentSize', $this->_formValues);
|
||||
|
||||
$this->_includeGroups = CRM_Utils_Array::value('includeGroups', $this->_formValues);
|
||||
|
||||
$this->_excludeGroups = CRM_Utils_Array::value('excludeGroups', $this->_formValues);
|
||||
|
||||
$this->_allSearch = FALSE;
|
||||
$this->_groups = FALSE;
|
||||
|
||||
if (empty($this->_includeGroups) && empty($this->_excludeGroups)) {
|
||||
//empty search
|
||||
$this->_allSearch = TRUE;
|
||||
}
|
||||
|
||||
if (!empty($this->_includeGroups) || !empty($this->_excludeGroups)) {
|
||||
//group(s) selected
|
||||
$this->_groups = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
$form->add('text',
|
||||
'segmentSize',
|
||||
ts('Segment Size'),
|
||||
TRUE
|
||||
);
|
||||
|
||||
$groups = CRM_Core_PseudoConstant::nestedGroup();
|
||||
|
||||
$select2style = array(
|
||||
'multiple' => TRUE,
|
||||
'style' => 'width: 100%; max-width: 60em;',
|
||||
'class' => 'crm-select2',
|
||||
'placeholder' => ts('- select -'),
|
||||
);
|
||||
|
||||
$form->add('select', 'includeGroups',
|
||||
ts('Include Group(s)'),
|
||||
$groups,
|
||||
FALSE,
|
||||
$select2style
|
||||
);
|
||||
|
||||
$form->add('select', 'excludeGroups',
|
||||
ts('Exclude Group(s)'),
|
||||
$groups,
|
||||
FALSE,
|
||||
$select2style
|
||||
);
|
||||
|
||||
$this->setTitle('Create a random segment of contacts');
|
||||
|
||||
/**
|
||||
* if you are using the standard template, this array tells the template what elements
|
||||
* are part of the search criteria
|
||||
*/
|
||||
$form->assign('elements', array('segmentSize', 'includeGroups', 'excludeGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function summary() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0, $rowcount = 0, $sort = NULL,
|
||||
$includeContactIDs = FALSE, $justIDs = FALSE
|
||||
) {
|
||||
if ($justIDs) {
|
||||
$selectClause = "contact_a.id as contact_id";
|
||||
}
|
||||
else {
|
||||
$selectClause = "contact_a.id as contact_id,
|
||||
contact_a.contact_type as contact_type,
|
||||
contact_a.sort_name as sort_name,
|
||||
civicrm_email.email as email";
|
||||
}
|
||||
|
||||
return $this->sql($selectClause,
|
||||
$offset, $rowcount, $sort,
|
||||
$includeContactIDs, NULL
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
//define table name
|
||||
$randomNum = md5(uniqid());
|
||||
$this->_tableName = "civicrm_temp_custom_{$randomNum}";
|
||||
|
||||
//block for Group search
|
||||
$smartGroup = array();
|
||||
$group = new CRM_Contact_DAO_Group();
|
||||
$group->is_active = 1;
|
||||
$group->find();
|
||||
while ($group->fetch()) {
|
||||
$allGroups[] = $group->id;
|
||||
if ($group->saved_search_id) {
|
||||
$smartGroup[$group->saved_search_id] = $group->id;
|
||||
}
|
||||
}
|
||||
$includedGroups = implode(',', $allGroups);
|
||||
|
||||
if (!empty($this->_includeGroups)) {
|
||||
$iGroups = implode(',', $this->_includeGroups);
|
||||
}
|
||||
else {
|
||||
//if no group selected search for all groups
|
||||
$iGroups = $includedGroups;
|
||||
}
|
||||
if (is_array($this->_excludeGroups)) {
|
||||
$xGroups = implode(',', $this->_excludeGroups);
|
||||
}
|
||||
else {
|
||||
$xGroups = 0;
|
||||
}
|
||||
|
||||
$sql = "DROP TEMPORARY TABLE IF EXISTS Xg_{$this->_tableName}";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
$sql = "CREATE TEMPORARY TABLE Xg_{$this->_tableName} ( contact_id int primary key) ENGINE=HEAP";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$excludeGroup = "INSERT INTO Xg_{$this->_tableName} ( contact_id )
|
||||
SELECT DISTINCT civicrm_group_contact.contact_id
|
||||
FROM civicrm_group_contact
|
||||
WHERE
|
||||
civicrm_group_contact.status = 'Added' AND
|
||||
civicrm_group_contact.group_id IN ( {$xGroups} )";
|
||||
|
||||
CRM_Core_DAO::executeQuery($excludeGroup);
|
||||
|
||||
//search for smart group contacts
|
||||
foreach ($this->_excludeGroups as $keys => $values) {
|
||||
if (in_array($values, $smartGroup)) {
|
||||
$ssId = CRM_Utils_Array::key($values, $smartGroup);
|
||||
|
||||
$smartSql = CRM_Contact_BAO_SavedSearch::contactIDsSQL($ssId);
|
||||
|
||||
$smartSql = $smartSql . " AND contact_a.id NOT IN (
|
||||
SELECT contact_id FROM civicrm_group_contact
|
||||
WHERE civicrm_group_contact.group_id = {$values} AND civicrm_group_contact.status = 'Removed')";
|
||||
|
||||
$smartGroupQuery = " INSERT IGNORE INTO Xg_{$this->_tableName}(contact_id) $smartSql";
|
||||
|
||||
CRM_Core_DAO::executeQuery($smartGroupQuery);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "DROP TEMPORARY TABLE IF EXISTS Ig_{$this->_tableName}";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
$sql = "CREATE TEMPORARY TABLE Ig_{$this->_tableName}
|
||||
( id int PRIMARY KEY AUTO_INCREMENT,
|
||||
contact_id int,
|
||||
group_names varchar(64)) ENGINE=HEAP";
|
||||
|
||||
if ($this->_debug > 0) {
|
||||
print "-- Include groups query: <pre>";
|
||||
print "$sql;";
|
||||
print "</pre>";
|
||||
}
|
||||
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
$includeGroup = "INSERT INTO Ig_{$this->_tableName} (contact_id, group_names)
|
||||
SELECT civicrm_group_contact.contact_id, civicrm_group.name as group_name
|
||||
FROM civicrm_group_contact
|
||||
LEFT JOIN civicrm_group
|
||||
ON civicrm_group_contact.group_id = civicrm_group.id";
|
||||
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$includeGroup .= " LEFT JOIN Xg_{$this->_tableName}
|
||||
ON civicrm_group_contact.contact_id = Xg_{$this->_tableName}.contact_id";
|
||||
}
|
||||
$includeGroup .= " WHERE
|
||||
civicrm_group_contact.status = 'Added' AND
|
||||
civicrm_group_contact.group_id IN($iGroups)";
|
||||
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$includeGroup .= " AND Xg_{$this->_tableName}.contact_id IS null";
|
||||
}
|
||||
|
||||
if ($this->_debug > 0) {
|
||||
print "-- Include groups query: <pre>";
|
||||
print "$includeGroup;";
|
||||
print "</pre>";
|
||||
}
|
||||
|
||||
CRM_Core_DAO::executeQuery($includeGroup);
|
||||
|
||||
//search for smart group contacts
|
||||
foreach ($this->_includeGroups as $keys => $values) {
|
||||
if (in_array($values, $smartGroup)) {
|
||||
|
||||
$ssId = CRM_Utils_Array::key($values, $smartGroup);
|
||||
|
||||
$smartSql = CRM_Contact_BAO_SavedSearch::contactIDsSQL($ssId);
|
||||
|
||||
$smartSql .= " AND contact_a.id NOT IN (
|
||||
SELECT contact_id FROM civicrm_group_contact
|
||||
WHERE civicrm_group_contact.group_id = {$values} AND civicrm_group_contact.status = 'Removed')";
|
||||
|
||||
//used only when exclude group is selected
|
||||
if ($xGroups != 0) {
|
||||
$smartSql .= " AND contact_a.id NOT IN (SELECT contact_id FROM Xg_{$this->_tableName})";
|
||||
}
|
||||
|
||||
$smartGroupQuery = " INSERT IGNORE INTO Ig_{$this->_tableName}(contact_id)
|
||||
$smartSql";
|
||||
|
||||
CRM_Core_DAO::executeQuery($smartGroupQuery);
|
||||
$insertGroupNameQuery = "UPDATE IGNORE Ig_{$this->_tableName}
|
||||
SET group_names = (SELECT title FROM civicrm_group
|
||||
WHERE civicrm_group.id = $values)
|
||||
WHERE Ig_{$this->_tableName}.contact_id IS NOT NULL
|
||||
AND Ig_{$this->_tableName}.group_names IS NULL";
|
||||
CRM_Core_DAO::executeQuery($insertGroupNameQuery);
|
||||
}
|
||||
}
|
||||
$this->buildACLClause('contact_a');
|
||||
|
||||
$from = "FROM civicrm_contact contact_a";
|
||||
|
||||
$fromTail = "LEFT JOIN civicrm_email ON ( contact_a.id = civicrm_email.contact_id AND civicrm_email.is_primary = 1 )";
|
||||
|
||||
$fromTail .= " INNER JOIN Ig_{$this->_tableName} temptable1 ON (contact_a.id = temptable1.contact_id)";
|
||||
|
||||
// now create a temp table to store the randomized contacts
|
||||
$sql = "DROP TEMPORARY TABLE IF EXISTS random_{$this->_tableName}";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
$sql = "CREATE TEMPORARY TABLE random_{$this->_tableName} ( id int primary key ) ENGINE=HEAP";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
if (substr($this->_segmentSize, -1) == '%') {
|
||||
$countSql = "SELECT DISTINCT contact_a.id $from $fromTail
|
||||
WHERE " . $this->where();
|
||||
$dao = CRM_Core_DAO::executeQuery($countSql);
|
||||
$totalSize = $dao->N;
|
||||
$multiplier = substr($this->_segmentSize, 0, strlen($this->_segmentSize) - 1);
|
||||
$multiplier /= 100;
|
||||
$this->_segmentSize = round($totalSize * $multiplier);
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO random_{$this->_tableName} ( id )
|
||||
SELECT DISTINCT contact_a.id $from $fromTail
|
||||
WHERE " . $this->where() . "
|
||||
ORDER BY RAND()
|
||||
LIMIT {$this->_segmentSize}";
|
||||
CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
$from = "FROM random_{$this->_tableName} random";
|
||||
|
||||
$from .= " INNER JOIN civicrm_contact contact_a ON random.id = contact_a.id {$this->_aclFrom}";
|
||||
|
||||
$from .= " $fromTail";
|
||||
|
||||
return $from;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$where = '(1)';
|
||||
|
||||
if ($this->_aclWhere) {
|
||||
$where .= " AND {$this->_aclWhere} ";
|
||||
}
|
||||
|
||||
return '(1)';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function count() {
|
||||
$sql = $this->all();
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql);
|
||||
return $dao->N;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor function.
|
||||
*/
|
||||
public function __destruct() {
|
||||
// the temporary tables are dropped automatically
|
||||
// so we don't do it here
|
||||
// but let mysql clean up
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_Sample extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
parent::__construct($formValues);
|
||||
|
||||
if (!isset($formValues['state_province_id'])) {
|
||||
$this->_stateID = CRM_Utils_Request::retrieve('stateID', 'Integer');
|
||||
if ($this->_stateID) {
|
||||
$formValues['state_province_id'] = $this->_stateID;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_columns = array(
|
||||
ts('Contact ID') => 'contact_id',
|
||||
ts('Contact Type') => 'contact_type',
|
||||
ts('Name') => 'sort_name',
|
||||
ts('State') => 'state_province',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build form.
|
||||
*
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
|
||||
$form->add('text',
|
||||
'household_name',
|
||||
ts('Household Name'),
|
||||
TRUE
|
||||
);
|
||||
|
||||
$stateProvince = array('' => ts('- any state/province -')) + CRM_Core_PseudoConstant::stateProvince();
|
||||
$form->addElement('select', 'state_province_id', ts('State/Province'), $stateProvince);
|
||||
|
||||
/**
|
||||
* You can define a custom title for the search form
|
||||
*/
|
||||
$this->setTitle(ts('My Search Title'));
|
||||
|
||||
/**
|
||||
* if you are using the standard template, this array tells the template what elements
|
||||
* are part of the search criteria
|
||||
*/
|
||||
$form->assign('elements', array('household_name', 'state_province_id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function summary() {
|
||||
$summary = array(
|
||||
'summary' => 'This is a summary',
|
||||
'total' => 50.0,
|
||||
);
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = FALSE) {
|
||||
return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all($offset = 0, $rowcount = 0, $sort = NULL, $includeContactIDs = FALSE, $justIDs = FALSE) {
|
||||
if ($justIDs) {
|
||||
$selectClause = "contact_a.id as contact_id";
|
||||
$sort = 'contact_a.id';
|
||||
}
|
||||
else {
|
||||
$selectClause = "
|
||||
contact_a.id as contact_id ,
|
||||
contact_a.contact_type as contact_type,
|
||||
contact_a.sort_name as sort_name,
|
||||
state_province.name as state_province
|
||||
";
|
||||
}
|
||||
|
||||
return $this->sql($selectClause,
|
||||
$offset, $rowcount, $sort,
|
||||
$includeContactIDs, NULL
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
$this->buildACLClause('contact_a');
|
||||
$from = "
|
||||
FROM civicrm_contact contact_a
|
||||
LEFT JOIN civicrm_address address ON ( address.contact_id = contact_a.id AND
|
||||
address.is_primary = 1 )
|
||||
LEFT JOIN civicrm_email ON ( civicrm_email.contact_id = contact_a.id AND
|
||||
civicrm_email.is_primary = 1 )
|
||||
LEFT JOIN civicrm_state_province state_province ON state_province.id = address.state_province_id {$this->_aclFrom}
|
||||
";
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$params = array();
|
||||
$where = "contact_a.contact_type = 'Household'";
|
||||
|
||||
$count = 1;
|
||||
$clause = array();
|
||||
$name = CRM_Utils_Array::value('household_name',
|
||||
$this->_formValues
|
||||
);
|
||||
if ($name != NULL) {
|
||||
if (strpos($name, '%') === FALSE) {
|
||||
$name = "%{$name}%";
|
||||
}
|
||||
$params[$count] = array($name, 'String');
|
||||
$clause[] = "contact_a.household_name LIKE %{$count}";
|
||||
$count++;
|
||||
}
|
||||
|
||||
$state = CRM_Utils_Array::value('state_province_id',
|
||||
$this->_formValues
|
||||
);
|
||||
if (!$state &&
|
||||
$this->_stateID
|
||||
) {
|
||||
$state = $this->_stateID;
|
||||
}
|
||||
|
||||
if ($state) {
|
||||
$params[$count] = array($state, 'Integer');
|
||||
$clause[] = "state_province.id = %{$count}";
|
||||
}
|
||||
|
||||
if ($this->_aclWhere) {
|
||||
$clause[] = " {$this->_aclWhere} ";
|
||||
}
|
||||
|
||||
if (!empty($clause)) {
|
||||
$where .= ' AND ' . implode(' AND ', $clause);
|
||||
}
|
||||
|
||||
return $this->whereClause($where, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function setDefaultValues() {
|
||||
return array_merge(array('household_name' => ''), $this->_formValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $row
|
||||
*/
|
||||
public function alterRow(&$row) {
|
||||
$row['sort_name'] .= ' ( altered )';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,285 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_TagContributions extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
|
||||
protected $_formValues;
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
public $_permissionedComponent;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
$this->_formValues = $formValues;
|
||||
$this->_permissionedComponent = 'CiviContribute';
|
||||
|
||||
/**
|
||||
* Define the columns for search result rows
|
||||
*/
|
||||
$this->_columns = array(
|
||||
ts('Contact ID') => 'contact_id',
|
||||
ts('Full Name') => 'sort_name',
|
||||
ts('First Name') => 'first_name',
|
||||
ts('Last Name') => 'last_name',
|
||||
ts('Tag') => 'tag_name',
|
||||
ts('Totals') => 'amount',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
|
||||
/**
|
||||
* You can define a custom title for the search form
|
||||
*/
|
||||
$this->setTitle('Find Contribution Amounts by Tag');
|
||||
|
||||
/**
|
||||
* Define the search form fields here
|
||||
*/
|
||||
|
||||
$form->addDate('start_date', ts('Contribution Date From'), FALSE, array('formatType' => 'custom'));
|
||||
$form->addDate('end_date', ts('...through'), FALSE, array('formatType' => 'custom'));
|
||||
$tag = array('' => ts('- any tag -')) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
|
||||
$form->addElement('select', 'tag', ts('Tagged'), $tag);
|
||||
|
||||
/**
|
||||
* If you are using the sample template, this array tells the template fields to render
|
||||
* for the search form.
|
||||
*/
|
||||
$form->assign('elements', array('start_date', 'end_date', 'tag'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the smarty template used to layout the search form and results listings.
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the search query.
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param string $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $onlyIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0, $rowcount = 0, $sort = NULL,
|
||||
$includeContactIDs = FALSE, $onlyIDs = FALSE
|
||||
) {
|
||||
|
||||
// SELECT clause must include contact_id as an alias for civicrm_contact.id
|
||||
if ($onlyIDs) {
|
||||
$select = "contact_a.id as contact_id";
|
||||
}
|
||||
else {
|
||||
$select = "
|
||||
DISTINCT
|
||||
contact_a.id as contact_id,
|
||||
contact_a.sort_name as sort_name,
|
||||
contact_a.first_name as first_name,
|
||||
contact_a.last_name as last_name,
|
||||
GROUP_CONCAT(DISTINCT civicrm_tag.name ORDER BY civicrm_tag.name ASC ) as tag_name,
|
||||
sum(civicrm_contribution.total_amount) as amount
|
||||
";
|
||||
}
|
||||
$from = $this->from();
|
||||
|
||||
$where = $this->where($includeContactIDs);
|
||||
|
||||
$sql = "
|
||||
SELECT $select
|
||||
FROM $from
|
||||
WHERE $where
|
||||
";
|
||||
|
||||
$sql .= " GROUP BY contact_a.id";
|
||||
// Define ORDER BY for query in $sort, with default value
|
||||
if (!empty($sort)) {
|
||||
if (is_string($sort)) {
|
||||
$sort = CRM_Utils_Type::escape($sort, 'String');
|
||||
$sql .= " ORDER BY $sort ";
|
||||
}
|
||||
else {
|
||||
$sql .= " ORDER BY " . trim($sort->orderBy());
|
||||
}
|
||||
}
|
||||
else {
|
||||
$sql .= "";
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
$this->buildACLClause('contact_a');
|
||||
$from = "
|
||||
civicrm_contribution,
|
||||
civicrm_contact contact_a
|
||||
LEFT JOIN civicrm_entity_tag ON ( civicrm_entity_tag.entity_table = 'civicrm_contact' AND
|
||||
civicrm_entity_tag.entity_id = contact_a.id )
|
||||
LEFT JOIN civicrm_tag ON civicrm_tag.id = civicrm_entity_tag.tag_id {$this->_aclFrom}
|
||||
";
|
||||
return $from;
|
||||
}
|
||||
|
||||
/*
|
||||
* WHERE clause is an array built from any required JOINS plus conditional filters based on search criteria field values
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$clauses = array();
|
||||
|
||||
$clauses[] = "contact_a.contact_type = 'Individual'";
|
||||
$clauses[] = "civicrm_contribution.contact_id = contact_a.id";
|
||||
|
||||
$startDate = CRM_Utils_Date::processDate($this->_formValues['start_date']);
|
||||
if ($startDate) {
|
||||
$clauses[] = "civicrm_contribution.receive_date >= $startDate";
|
||||
}
|
||||
|
||||
$endDate = CRM_Utils_Date::processDate($this->_formValues['end_date']);
|
||||
if ($endDate) {
|
||||
$clauses[] = "civicrm_contribution.receive_date <= $endDate";
|
||||
}
|
||||
|
||||
$tag = CRM_Utils_Array::value('tag', $this->_formValues);
|
||||
if ($tag) {
|
||||
$clauses[] = "civicrm_entity_tag.tag_id = $tag";
|
||||
$clauses[] = "civicrm_tag.id = civicrm_entity_tag.tag_id";
|
||||
}
|
||||
else {
|
||||
$clauses[] = "civicrm_entity_tag.tag_id IS NOT NULL";
|
||||
}
|
||||
|
||||
if ($includeContactIDs) {
|
||||
$contactIDs = array();
|
||||
foreach ($this->_formValues as $id => $value) {
|
||||
if ($value &&
|
||||
substr($id, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX
|
||||
) {
|
||||
$contactIDs[] = substr($id, CRM_Core_Form::CB_PREFIX_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($contactIDs)) {
|
||||
$contactIDs = implode(', ', $contactIDs);
|
||||
$clauses[] = "contact_a.id IN ( $contactIDs )";
|
||||
}
|
||||
}
|
||||
if ($this->_aclWhere) {
|
||||
$clauses[] = " {$this->_aclWhere} ";
|
||||
}
|
||||
return implode(' AND ', $clauses);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Functions below generally don't need to be modified
|
||||
*/
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function count() {
|
||||
$sql = $this->all();
|
||||
|
||||
$dao = CRM_Core_DAO::executeQuery($sql,
|
||||
CRM_Core_DAO::$_nullArray
|
||||
);
|
||||
return $dao->N;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL Not used; included for consistency with parent; SQL is always returned
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = TRUE) {
|
||||
return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function &columns() {
|
||||
return $this->_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function summary() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Contact_Form_Search_Custom_ZipCodeRange extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
|
||||
protected $_aclFrom = NULL;
|
||||
protected $_aclWhere = NULL;
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues) {
|
||||
parent::__construct($formValues);
|
||||
|
||||
$this->_columns = array(
|
||||
// If possible, don't use aliases for the columns you select.
|
||||
// You can prefix columns with table aliases, if needed.
|
||||
//
|
||||
// If you don't do this, selecting individual records from the
|
||||
// custom search result won't work if your results are sorted on the
|
||||
// aliased colums.
|
||||
// (This is why we map Contact ID on contact_a.id, and not on contact_id).
|
||||
ts('Contact ID') => 'contact_a.id',
|
||||
ts('Name') => 'sort_name',
|
||||
ts('Email') => 'email',
|
||||
ts('Zip') => 'postal_code',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form) {
|
||||
$form->add('text',
|
||||
'postal_code_low',
|
||||
ts('Postal Code Start'),
|
||||
TRUE
|
||||
);
|
||||
|
||||
$form->add('text',
|
||||
'postal_code_high',
|
||||
ts('Postal Code End'),
|
||||
TRUE
|
||||
);
|
||||
|
||||
/**
|
||||
* You can define a custom title for the search form
|
||||
*/
|
||||
$this->setTitle('Zip Code Range Search');
|
||||
|
||||
/**
|
||||
* if you are using the standard template, this array tells the template what elements
|
||||
* are part of the search criteria
|
||||
*/
|
||||
$form->assign('elements', array('postal_code_low', 'postal_code_high'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function summary() {
|
||||
$summary = array();
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $returnSQL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = FALSE) {
|
||||
return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function all(
|
||||
$offset = 0, $rowcount = 0, $sort = NULL,
|
||||
$includeContactIDs = FALSE, $justIDs = FALSE
|
||||
) {
|
||||
if ($justIDs) {
|
||||
$selectClause = "contact_a.id as contact_id";
|
||||
// Don't change sort order when $justIDs is TRUE, see CRM-14920.
|
||||
}
|
||||
else {
|
||||
// We select contact_a.id twice. Once as contact_a.id,
|
||||
// because it is used to fill the prevnext_cache. And once
|
||||
// as contact_a.id, for the patch of CRM-16587 to work when
|
||||
// the results are sorted on contact ID.
|
||||
$selectClause = "
|
||||
contact_a.id as contact_id ,
|
||||
contact_a.id as id ,
|
||||
contact_a.sort_name as sort_name ,
|
||||
email.email as email ,
|
||||
address.postal_code as postal_code
|
||||
";
|
||||
}
|
||||
return $this->sql($selectClause,
|
||||
$offset, $rowcount, $sort,
|
||||
$includeContactIDs, NULL
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function from() {
|
||||
$this->buildACLClause('contact_a');
|
||||
$from = "
|
||||
FROM civicrm_contact contact_a
|
||||
LEFT JOIN civicrm_address address ON ( address.contact_id = contact_a.id AND
|
||||
address.is_primary = 1 )
|
||||
LEFT JOIN civicrm_email email ON ( email.contact_id = contact_a.id AND
|
||||
email.is_primary = 1 ) {$this->_aclFrom}
|
||||
";
|
||||
return $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeContactIDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE) {
|
||||
$params = array();
|
||||
|
||||
$low = CRM_Utils_Array::value('postal_code_low',
|
||||
$this->_formValues
|
||||
);
|
||||
$high = CRM_Utils_Array::value('postal_code_high',
|
||||
$this->_formValues
|
||||
);
|
||||
if ($low == NULL || $high == NULL) {
|
||||
CRM_Core_Error::statusBounce(ts('Please provide start and end postal codes'),
|
||||
CRM_Utils_System::url('civicrm/contact/search/custom',
|
||||
"reset=1&csid={$this->_formValues['customSearchID']}",
|
||||
FALSE, NULL, FALSE, TRUE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$where = "ROUND(address.postal_code) >= %1 AND ROUND(address.postal_code) <= %2";
|
||||
$params = array(
|
||||
1 => array(trim($low), 'Integer'),
|
||||
2 => array(trim($high), 'Integer'),
|
||||
);
|
||||
|
||||
if ($this->_aclWhere) {
|
||||
$where .= " AND {$this->_aclWhere} ";
|
||||
}
|
||||
return $this->whereClause($where, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function templateFile() {
|
||||
return 'CRM/Contact/Form/Search/Custom.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
if ($title) {
|
||||
CRM_Utils_System::setTitle($title);
|
||||
}
|
||||
else {
|
||||
CRM_Utils_System::setTitle(ts('Search'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableAlias
|
||||
*/
|
||||
public function buildACLClause($tableAlias = 'contact') {
|
||||
list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
|
||||
}
|
||||
|
||||
}
|
134
sites/all/modules/civicrm/CRM/Contact/Form/Search/Interface.php
Normal file
134
sites/all/modules/civicrm/CRM/Contact/Form/Search/Interface.php
Normal file
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------+
|
||||
| CiviCRM version 4.7 |
|
||||
+--------------------------------------------------------------------+
|
||||
| Copyright CiviCRM LLC (c) 2004-2017 |
|
||||
+--------------------------------------------------------------------+
|
||||
| This file is a part of CiviCRM. |
|
||||
| |
|
||||
| CiviCRM is free software; you can copy, modify, and distribute it |
|
||||
| under the terms of the GNU Affero General Public License |
|
||||
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
|
||||
| |
|
||||
| CiviCRM is distributed in the hope that it will be useful, but |
|
||||
| WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
||||
| See the GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| You should have received a copy of the GNU Affero General Public |
|
||||
| License and the CiviCRM Licensing Exception along |
|
||||
| with this program; if not, contact CiviCRM LLC |
|
||||
| at info[AT]civicrm[DOT]org. If you have questions about the |
|
||||
| GNU Affero General Public License or the licensing of CiviCRM, |
|
||||
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
interface CRM_Contact_Form_Search_Interface {
|
||||
|
||||
/**
|
||||
* The constructor gets the submitted form values.
|
||||
*
|
||||
* @param array $formValues
|
||||
*/
|
||||
public function __construct(&$formValues);
|
||||
|
||||
/**
|
||||
* Builds the list of tasks or actions that a searcher can perform on a result set.
|
||||
*
|
||||
* @param CRM_Core_Form_Search $form
|
||||
* @return array
|
||||
*/
|
||||
public function buildTaskList(CRM_Core_Form_Search $form);
|
||||
|
||||
/**
|
||||
* Builds the quickform for this search.
|
||||
*
|
||||
* @param CRM_Core_Form $form
|
||||
*/
|
||||
public function buildForm(&$form);
|
||||
|
||||
/**
|
||||
* Builds the search query for various cases. We break it down into finer cases
|
||||
* since you can optimize each query independently. All the functions below return
|
||||
* a sql clause with only SELECT, FROM, WHERE sub-parts. The ORDER BY and LIMIT is
|
||||
* added at a later stage
|
||||
*/
|
||||
|
||||
/**
|
||||
* Count of records that match the current input parameters.
|
||||
*
|
||||
* Used by pager.
|
||||
*/
|
||||
public function count();
|
||||
|
||||
/**
|
||||
* Summary information for the query that can be displayed in the template.
|
||||
*
|
||||
* This is useful to pass total / sub total information if needed
|
||||
*/
|
||||
public function summary();
|
||||
|
||||
/**
|
||||
* List of contact ids that match the current input parameters.
|
||||
*
|
||||
* Used by different tasks. Will be also used to optimize the
|
||||
* 'all' query below to avoid excessive LEFT JOIN blowup
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
*/
|
||||
public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL);
|
||||
|
||||
/**
|
||||
* Retrieve all the values that match the current input parameters.
|
||||
*
|
||||
* Used by the selector
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int $rowcount
|
||||
* @param null $sort
|
||||
* @param bool $includeContactIDs
|
||||
* @param bool $justIDs
|
||||
*/
|
||||
public function all($offset = 0, $rowcount = 0, $sort = NULL, $includeContactIDs = FALSE, $justIDs = FALSE);
|
||||
|
||||
/**
|
||||
* The below two functions (from and where) are ONLY used if you want to
|
||||
* expose a custom group as a smart group and be able to send a mailing
|
||||
* to them via CiviMail. civicrm_email should be part of the from clause
|
||||
* The from clause should be a valid sql from clause including the word FROM
|
||||
* CiviMail will pick up the contacts where the email is primary and
|
||||
* is not on hold / opt out / do not email
|
||||
*/
|
||||
|
||||
/**
|
||||
* The from clause for the query.
|
||||
*/
|
||||
public function from();
|
||||
|
||||
/**
|
||||
* The where clause for the query.
|
||||
*
|
||||
* @param bool $includeContactIDs
|
||||
*/
|
||||
public function where($includeContactIDs = FALSE);
|
||||
|
||||
/**
|
||||
* The template FileName to use to display the results.
|
||||
*/
|
||||
public function templateFile();
|
||||
|
||||
/**
|
||||
* Returns an array of column headers and field names and sort options.
|
||||
*/
|
||||
public function &columns();
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue