First commit

This commit is contained in:
Theodotos Andreou 2018-01-14 13:10:16 +00:00
commit c6e2478c40
13918 changed files with 2303184 additions and 0 deletions

View file

@ -0,0 +1,158 @@
<?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 |
+--------------------------------------------------------------------+
*/
use Civi\ActionSchedule\RecipientBuilder;
/**
* Class CRM_Contact_ActionMapping
*
* This defines the scheduled-reminder functionality for contact
* entities. It is useful for, e.g., sending a reminder based on
* birth date, modification date, or other custom dates on
* the contact record.
*/
class CRM_Contact_ActionMapping extends \Civi\ActionSchedule\Mapping {
/**
* The value for civicrm_action_schedule.mapping_id which identifies the
* "Contact" mapping.
*
* Note: This value is chosen to match legacy DB IDs.
*/
const CONTACT_MAPPING_ID = 6;
/**
* Register Contact-related action mappings.
*
* @param \Civi\ActionSchedule\Event\MappingRegisterEvent $registrations
*/
public static function onRegisterActionMappings(\Civi\ActionSchedule\Event\MappingRegisterEvent $registrations) {
$registrations->register(CRM_Contact_ActionMapping::create(array(
'id' => CRM_Contact_ActionMapping::CONTACT_MAPPING_ID,
'entity' => 'civicrm_contact',
'entity_label' => ts('Contact'),
'entity_value' => 'civicrm_contact',
'entity_value_label' => ts('Date Field'),
'entity_status' => 'contact_date_reminder_options',
'entity_status_label' => ts('Annual Options'),
'entity_date_start' => 'date_field',
)));
}
private $contactDateFields = array(
'birth_date',
'created_date',
'modified_date',
);
/**
* Determine whether a schedule based on this mapping is sufficiently
* complete.
*
* @param \CRM_Core_DAO_ActionSchedule $schedule
* @return array
* Array (string $code => string $message).
* List of error messages.
*/
public function validateSchedule($schedule) {
$errors = array();
if (CRM_Utils_System::isNull($schedule->entity_value) || $schedule->entity_value === '0') {
$errors['entity'] = ts('Please select a specific date field.');
}
elseif (count(CRM_Utils_Array::explodePadded($schedule->entity_value)) > 1) {
$errors['entity'] = ts('You may only select one contact field per reminder');
}
elseif (CRM_Utils_System::isNull($schedule->entity_status) || $schedule->entity_status === '0') {
$errors['entity'] = ts('Please select whether the reminder is sent each year.');
}
return $errors;
}
/**
* Generate a query to locate recipients who match the given
* schedule.
*
* @param \CRM_Core_DAO_ActionSchedule $schedule
* The schedule as configured by the administrator.
* @param string $phase
* See, e.g., RecipientBuilder::PHASE_RELATION_FIRST.
* @param array $defaultParams
*
* @return \CRM_Utils_SQL_Select
* @throws \CRM_Core_Exception
* @see RecipientBuilder
*/
public function createQuery($schedule, $phase, $defaultParams) {
$selectedValues = (array) \CRM_Utils_Array::explodePadded($schedule->entity_value);
$selectedStatuses = (array) \CRM_Utils_Array::explodePadded($schedule->entity_status);
// FIXME: This assumes that $values only has one field, but UI shows multiselect.
// Properly supporting multiselect would require total rewrite of this function.
if (count($selectedValues) != 1 || !isset($selectedValues[0])) {
throw new \CRM_Core_Exception("Error: Scheduled reminders may only have one contact field.");
}
elseif (in_array($selectedValues[0], $this->contactDateFields)) {
$dateDBField = $selectedValues[0];
$query = \CRM_Utils_SQL_Select::from("{$this->entity} e")->param($defaultParams);
$query->param(array(
'casAddlCheckFrom' => 'civicrm_contact e',
'casContactIdField' => 'e.id',
'casEntityIdField' => 'e.id',
'casContactTableAlias' => 'e',
));
$query->where('e.is_deleted = 0 AND e.is_deceased = 0');
}
else {
//custom field
$customFieldParams = array('id' => substr($selectedValues[0], 7));
$customGroup = $customField = array();
\CRM_Core_BAO_CustomField::retrieve($customFieldParams, $customField);
$dateDBField = $customField['column_name'];
$customGroupParams = array('id' => $customField['custom_group_id'], $customGroup);
\CRM_Core_BAO_CustomGroup::retrieve($customGroupParams, $customGroup);
$query = \CRM_Utils_SQL_Select::from("{$customGroup['table_name']} e")->param($defaultParams);
$query->param(array(
'casAddlCheckFrom' => "{$customGroup['table_name']} e",
'casContactIdField' => 'e.entity_id',
'casEntityIdField' => 'e.id',
'casContactTableAlias' => NULL,
));
$query->where('1'); // possible to have no "where" in this case
}
$query['casDateField'] = 'e.' . $dateDBField;
if (in_array(2, $selectedStatuses)) {
$query['casAnniversaryMode'] = 1;
$query['casDateField'] = 'DATE_ADD(' . $query['casDateField'] . ', INTERVAL ROUND(DATEDIFF(DATE(' . $query['casNow'] . '), ' . $query['casDateField'] . ') / 365) YEAR)';
}
return $query;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,205 @@
<?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_BAO_Contact_Location {
/**
* Get the display name, primary email, location type and location id of a contact.
*
* @param int $id
* Id of the contact.
*
* @param bool $isPrimary
* @param int $locationTypeID
*
* @return array
* Array of display_name, email, location type and location id if found, or (null,null,null, null)
*/
public static function getEmailDetails($id, $isPrimary = TRUE, $locationTypeID = NULL) {
$primaryClause = NULL;
if ($isPrimary) {
$primaryClause = " AND civicrm_email.is_primary = 1";
}
$locationClause = NULL;
if ($locationTypeID) {
$locationClause = " AND civicrm_email.location_type_id = $locationTypeID";
}
$sql = "
SELECT civicrm_contact.display_name,
civicrm_email.email,
civicrm_email.location_type_id,
civicrm_email.id
FROM civicrm_contact
LEFT JOIN civicrm_email ON ( civicrm_contact.id = civicrm_email.contact_id {$primaryClause} {$locationClause} )
WHERE civicrm_contact.id = %1";
$params = array(1 => array($id, 'Integer'));
$dao = CRM_Core_DAO::executeQuery($sql, $params);
if ($dao->fetch()) {
return array($dao->display_name, $dao->email, $dao->location_type_id, $dao->id);
}
return array(NULL, NULL, NULL, NULL);
}
/**
* Get the sms number and display name of a contact.
*
* @param int $id
* Id of the contact.
*
* @param null $type
*
* @return array
* tuple of display_name and sms if found, or (null,null)
*/
public static function getPhoneDetails($id, $type = NULL) {
if (!$id) {
return array(NULL, NULL);
}
$cond = NULL;
if ($type) {
$cond = " AND civicrm_phone.phone_type_id = '$type'";
}
$sql = "
SELECT civicrm_contact.display_name, civicrm_phone.phone, civicrm_contact.do_not_sms
FROM civicrm_contact
LEFT JOIN civicrm_phone ON ( civicrm_phone.contact_id = civicrm_contact.id )
WHERE civicrm_phone.is_primary = 1
$cond
AND civicrm_contact.id = %1";
$params = array(1 => array($id, 'Integer'));
$dao = CRM_Core_DAO::executeQuery($sql, $params);
if ($dao->fetch()) {
return array($dao->display_name, $dao->phone, $dao->do_not_sms);
}
return array(NULL, NULL, NULL);
}
/**
* Get the information to map a contact.
*
* @param array $ids
* The list of ids for which we want map info.
* $param int $locationTypeID
*
* @param int $locationTypeID
* @param bool $imageUrlOnly
*
* @return null|string
* display name of the contact if found
*/
public static function &getMapInfo($ids, $locationTypeID = NULL, $imageUrlOnly = FALSE) {
$idString = ' ( ' . implode(',', $ids) . ' ) ';
$sql = "
SELECT civicrm_contact.id as contact_id,
civicrm_contact.contact_type as contact_type,
civicrm_contact.contact_sub_type as contact_sub_type,
civicrm_contact.display_name as display_name,
civicrm_address.street_address as street_address,
civicrm_address.supplemental_address_1 as supplemental_address_1,
civicrm_address.supplemental_address_2 as supplemental_address_2,
civicrm_address.supplemental_address_3 as supplemental_address_3,
civicrm_address.city as city,
civicrm_address.postal_code as postal_code,
civicrm_address.postal_code_suffix as postal_code_suffix,
civicrm_address.geo_code_1 as latitude,
civicrm_address.geo_code_2 as longitude,
civicrm_state_province.abbreviation as state,
civicrm_country.name as country,
civicrm_location_type.name as location_type
FROM civicrm_contact
LEFT JOIN civicrm_address ON civicrm_address.contact_id = civicrm_contact.id
LEFT JOIN civicrm_state_province ON civicrm_address.state_province_id = civicrm_state_province.id
LEFT JOIN civicrm_country ON civicrm_address.country_id = civicrm_country.id
LEFT JOIN civicrm_location_type ON civicrm_location_type.id = civicrm_address.location_type_id
WHERE civicrm_address.geo_code_1 IS NOT NULL
AND civicrm_address.geo_code_2 IS NOT NULL
AND civicrm_contact.id IN $idString ";
$params = array();
if (!$locationTypeID) {
$sql .= " AND civicrm_address.is_primary = 1";
}
else {
$sql .= " AND civicrm_address.location_type_id = %1";
$params[1] = array($locationTypeID, 'Integer');
}
$dao = CRM_Core_DAO::executeQuery($sql, $params);
$locations = array();
$config = CRM_Core_Config::singleton();
while ($dao->fetch()) {
$location = array();
$location['contactID'] = $dao->contact_id;
$location['displayName'] = addslashes($dao->display_name);
$location['city'] = $dao->city;
$location['state'] = $dao->state;
$location['postal_code'] = $dao->postal_code;
$location['lat'] = $dao->latitude;
$location['lng'] = $dao->longitude;
$location['marker_class'] = $dao->contact_type;
$address = '';
CRM_Utils_String::append($address, '<br />',
array(
$dao->street_address,
$dao->supplemental_address_1,
$dao->supplemental_address_2,
$dao->supplemental_address_3,
$dao->city,
)
);
CRM_Utils_String::append($address, ', ',
array($dao->state, $dao->postal_code)
);
CRM_Utils_String::append($address, '<br /> ',
array($dao->country)
);
$location['address'] = addslashes($address);
$location['displayAddress'] = str_replace('<br />', ', ', addslashes($address));
$location['url'] = CRM_Utils_System::url('civicrm/contact/view', 'reset=1&cid=' . $dao->contact_id);
$location['location_type'] = $dao->location_type;
$location['image'] = CRM_Contact_BAO_Contact_Utils::getImage(isset($dao->contact_sub_type) ? $dao->contact_sub_type : $dao->contact_type, $imageUrlOnly, $dao->contact_id
);
$locations[] = $location;
}
return $locations;
}
}

View file

@ -0,0 +1,190 @@
<?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_BAO_Contact_Optimizer {
/**
* Edit function.
*
* @param array $newValues
* @param array $oldValues
*/
public static function edit(&$newValues, &$oldValues) {
// still need to do more work on this
// CRM-10192
return;
self::website($newValues, $oldValues);
}
/**
* @param $newValues
* @param $oldValues
*/
public static function website(&$newValues, &$oldValues) {
$oldWebsiteValues = CRM_Utils_Array::value('website', $oldValues);
$newWebsiteValues = CRM_Utils_Array::value('website', $newValues);
if ($oldWebsiteValues == NULL || $newWebsiteValues == NULL) {
return;
}
// check if we had a value in the old
$oldEmpty = $newEmpty = TRUE;
$old = $new = array();
foreach ($oldWebsiteValues as $idx => $value) {
if (!empty($value['url'])) {
$oldEmpty = FALSE;
$old[] = array('website_type_id' => $value['website_type_id'], 'url' => $value['url']);
}
}
foreach ($newWebsiteValues as $idx => $value) {
if (!empty($value['url'])) {
$newEmpty = FALSE;
$new[] = array('website_type_id' => $value['website_type_id'], 'url' => $value['url']);
}
}
// if both old and new are empty, we can delete new and avoid a write
if ($oldEmpty && $newEmpty) {
unset($newValues['website']);
}
// if different number of non-empty entries, return
if (count($new) != count($old)) {
return;
}
// same number of entries, check if they are exactly the same
foreach ($old as $oldID => $oldValues) {
$found = FALSE;
foreach ($new as $newID => $newValues) {
if (
$old['website_type_id'] == $new['website_type_id'] &&
$old['url'] == $new['url']
) {
$found = TRUE;
unset($new[$newID]);
break;
}
if (!$found) {
return;
}
}
}
// if we've come here, this means old and new are the same
// we can skip saving new and return
unset($newValues['website']);
}
/**
* @param $newValues
* @param $oldValues
*/
public static function email(&$newValues, &$oldValues) {
$oldEmailValues = CRM_Utils_Array::value('email', $oldValues);
$newEmailValues = CRM_Utils_Array::value('email', $newValues);
if ($oldEmailValues == NULL || $newEmailValues == NULL) {
return;
}
// check if we had a value in the old
$oldEmpty = $newEmpty = TRUE;
$old = $new = array();
foreach ($oldEmailValues as $idx => $value) {
if (!empty($value['email'])) {
$oldEmpty = FALSE;
$old[] = array(
'email' => $value['email'],
'location_type_id' => $value['location_type_id'],
'on_hold' => $value['on_hold'] ? 1 : 0,
'is_primary' => $value['is_primary'] ? 1 : 0,
'is_bulkmail' => $value['is_bulkmail'] ? 1 : 0,
'signature_text' => $value['signature_text'] ? $value['signature_text'] : '',
'signature_html' => $value['signature_html'] ? $value['signature_html'] : '',
);
}
}
foreach ($newEmailValues as $idx => $value) {
if (!empty($value['email'])) {
$newEmpty = FALSE;
$new[] = array(
'email' => $value['email'],
'location_type_id' => $value['location_type_id'],
'on_hold' => $value['on_hold'] ? 1 : 0,
'is_primary' => $value['is_primary'] ? 1 : 0,
'is_bulkmail' => $value['is_bulkmail'] ? 1 : 0,
'signature_text' => $value['signature_text'] ? $value['signature_text'] : '',
'signature_html' => $value['signature_html'] ? $value['signature_html'] : '',
);
}
}
// if both old and new are empty, we can delete new and avoid a write
if ($oldEmpty && $newEmpty) {
unset($newValues['email']);
}
// if different number of non-empty entries, return
if (count($new) != count($old)) {
return;
}
// same number of entries, check if they are exactly the same
foreach ($old as $oldID => $oldValues) {
$found = FALSE;
foreach ($new as $newID => $newValues) {
if (
$old['email_type_id'] == $new['email_type_id'] &&
$old['url'] == $new['url']
) {
$found = TRUE;
unset($new[$newID]);
break;
}
if (!$found) {
return;
}
}
}
// if we've come here, this means old and new are the same
// we can skip saving new and return
unset($newValues['email']);
}
}

View file

@ -0,0 +1,488 @@
<?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_BAO_Contact_Permission {
/**
* Check which of the given contact IDs the logged in user
* has permissions for the operation type according to:
* - general permissions (e.g. 'edit all contacts')
* - deletion status (unless you have 'access deleted contacts')
* - ACL
* - permissions inherited through relationships (also second degree if enabled)
*
* @param array $contact_ids
* Contact IDs.
* @param int $type the type of operation (view|edit)
*
* @see CRM_Contact_BAO_Contact_Permission::allow
*
* @return array
* list of contact IDs the logged in user has the given permission for
*/
public static function allowList($contact_ids, $type = CRM_Core_Permission::VIEW) {
$result_set = array();
if (empty($contact_ids)) {
// empty contact lists would cause trouble in the SQL. And be pointless.
return $result_set;
}
// make sure the the general permissions are given
if (CRM_Core_Permission::check('edit all contacts')
|| $type == CRM_Core_Permission::VIEW && CRM_Core_Permission::check('view all contacts')
) {
// if the general permission is there, all good
if (CRM_Core_Permission::check('access deleted contacts')) {
// if user can access deleted contacts -> fine
return $contact_ids;
}
else {
// if the user CANNOT access deleted contacts, these need to be filtered
$contact_id_list = implode(',', $contact_ids);
$filter_query = "SELECT DISTINCT(id) FROM civicrm_contact WHERE id IN ($contact_id_list) AND is_deleted = 0";
$query = CRM_Core_DAO::executeQuery($filter_query);
while ($query->fetch()) {
$result_set[(int) $query->id] = TRUE;
}
return array_keys($result_set);
}
}
// get logged in user
$contactID = CRM_Core_Session::getLoggedInContactID();
if (empty($contactID)) {
return array();
}
// make sure the cache is filled
self::cache($contactID, $type);
// compile query
$operation = ($type == CRM_Core_Permission::VIEW) ? 'View' : 'Edit';
// add clause for deleted contacts, if the user doesn't have the permission to access them
$LEFT_JOIN_DELETED = $AND_CAN_ACCESS_DELETED = '';
if (!CRM_Core_Permission::check('access deleted contacts')) {
$LEFT_JOIN_DELETED = "LEFT JOIN civicrm_contact ON civicrm_contact.id = contact_id";
$AND_CAN_ACCESS_DELETED = "AND civicrm_contact.is_deleted = 0";
}
// RUN the query
$contact_id_list = implode(',', $contact_ids);
$query = "
SELECT contact_id
FROM civicrm_acl_contact_cache
{$LEFT_JOIN_DELETED}
WHERE contact_id IN ({$contact_id_list})
AND user_id = {$contactID}
AND operation = '{$operation}'
{$AND_CAN_ACCESS_DELETED}";
$result = CRM_Core_DAO::executeQuery($query);
while ($result->fetch()) {
$result_set[(int) $result->contact_id] = TRUE;
}
// if some have been rejected, double check for permissions inherited by relationship
if (count($result_set) < count($contact_ids)) {
$rejected_contacts = array_diff_key($contact_ids, $result_set);
// @todo consider storing these to the acl cache for next time, since we have fetched.
$allowed_by_relationship = self::relationshipList($rejected_contacts);
foreach ($allowed_by_relationship as $contact_id) {
$result_set[(int) $contact_id] = TRUE;
}
}
return array_keys($result_set);
}
/**
* Check if the logged in user has permissions for the operation type.
*
* @param int $id
* Contact id.
* @param int|string $type the type of operation (view|edit)
*
* @return bool
* true if the user has permission, false otherwise
*/
public static function allow($id, $type = CRM_Core_Permission::VIEW) {
// get logged in user
$contactID = CRM_Core_Session::getLoggedInContactID();
// first: check if contact is trying to view own contact
if ($contactID == $id && ($type == CRM_Core_Permission::VIEW && CRM_Core_Permission::check('view my contact')
|| $type == CRM_Core_Permission::EDIT && CRM_Core_Permission::check('edit my contact'))
) {
return TRUE;
}
# FIXME: push this somewhere below, to not give this permission so many rights
$isDeleted = (bool) CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $id, 'is_deleted');
if (CRM_Core_Permission::check('access deleted contacts') && $isDeleted) {
return TRUE;
}
// short circuit for admin rights here so we avoid unneeeded queries
// some duplication of code, but we skip 3-5 queries
if (CRM_Core_Permission::check('edit all contacts') ||
($type == CRM_ACL_API::VIEW && CRM_Core_Permission::check('view all contacts'))
) {
return TRUE;
}
// check permission based on relationship, CRM-2963
if (self::relationshipList(array($id))) {
return TRUE;
}
// We should probably do a cheap check whether it's in the cache first.
// check permission based on ACL
$tables = array();
$whereTables = array();
$permission = CRM_ACL_API::whereClause($type, $tables, $whereTables, NULL, FALSE, FALSE, TRUE);
$from = CRM_Contact_BAO_Query::fromClause($whereTables);
$query = "
SELECT contact_a.id
$from
WHERE contact_a.id = %1 AND $permission
LIMIT 1
";
if (CRM_Core_DAO::singleValueQuery($query, array(1 => array($id, 'Integer')))) {
return TRUE;
}
return FALSE;
}
/**
* Fill the acl contact cache for this contact id if empty.
*
* @param int $userID
* @param int|string $type the type of operation (view|edit)
* @param bool $force
* Should we force a recompute.
*/
public static function cache($userID, $type = CRM_Core_Permission::VIEW, $force = FALSE) {
// FIXME: maybe find a better way of keeping track of this. @eileen pointed out
// that somebody might flush the cache away from under our feet,
// but the alternative would be a SQL call every time this is called,
// and a complete rebuild if the result was an empty set...
static $_processed = array(
CRM_Core_Permission::VIEW => array(),
CRM_Core_Permission::EDIT => array());
if ($type == CRM_Core_Permission::VIEW) {
$operationClause = " operation IN ( 'Edit', 'View' ) ";
$operation = 'View';
}
else {
$operationClause = " operation = 'Edit' ";
$operation = 'Edit';
}
$queryParams = array(1 => array($userID, 'Integer'));
if (!$force) {
// skip if already calculated
if (!empty($_processed[$type][$userID])) {
return;
}
// run a query to see if the cache is filled
$sql = "
SELECT count(*)
FROM civicrm_acl_contact_cache
WHERE user_id = %1
AND $operationClause
";
$count = CRM_Core_DAO::singleValueQuery($sql, $queryParams);
if ($count > 0) {
$_processed[$type][$userID] = 1;
return;
}
}
$tables = array();
$whereTables = array();
$permission = CRM_ACL_API::whereClause($type, $tables, $whereTables, $userID, FALSE, FALSE, TRUE);
$from = CRM_Contact_BAO_Query::fromClause($whereTables);
CRM_Core_DAO::executeQuery("
INSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )
SELECT DISTINCT $userID as user_id, contact_a.id as contact_id, '{$operation}' as operation
$from
LEFT JOIN civicrm_acl_contact_cache ac ON ac.user_id = $userID AND ac.contact_id = contact_a.id AND ac.operation = '{$operation}'
WHERE $permission
AND ac.user_id IS NULL
");
// Add in a row for the logged in contact. Do not try to combine with the above query or an ugly OR will appear in
// the permission clause.
if (CRM_Core_Permission::check('edit my contact') ||
($type == CRM_Core_Permission::VIEW && CRM_Core_Permission::check('view my contact'))) {
if (!CRM_Core_DAO::singleValueQuery("
SELECT count(*) FROM civicrm_acl_contact_cache WHERE user_id = %1 AND contact_id = %1 AND operation = '{$operation}' LIMIT 1", $queryParams)) {
CRM_Core_DAO::executeQuery("INSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation ) VALUES(%1, %1, '{$operation}')", $queryParams);
}
}
$_processed[$type][$userID] = 1;
}
/**
* @param string $contactAlias
*
* @return array
*/
public static function cacheClause($contactAlias = 'contact_a') {
if (CRM_Core_Permission::check('view all contacts') ||
CRM_Core_Permission::check('edit all contacts')
) {
if (is_array($contactAlias)) {
$wheres = array();
foreach ($contactAlias as $alias) {
// CRM-6181
$wheres[] = "$alias.is_deleted = 0";
}
return array(NULL, '(' . implode(' AND ', $wheres) . ')');
}
else {
// CRM-6181
return array(NULL, "$contactAlias.is_deleted = 0");
}
}
$contactID = (int) CRM_Core_Session::getLoggedInContactID();
self::cache($contactID);
if (is_array($contactAlias) && !empty($contactAlias)) {
//More than one contact alias
$clauses = array();
foreach ($contactAlias as $k => $alias) {
$clauses[] = " INNER JOIN civicrm_acl_contact_cache aclContactCache_{$k} ON {$alias}.id = aclContactCache_{$k}.contact_id AND aclContactCache_{$k}.user_id = $contactID ";
}
$fromClause = implode(" ", $clauses);
$whereClase = NULL;
}
else {
$fromClause = " INNER JOIN civicrm_acl_contact_cache aclContactCache ON {$contactAlias}.id = aclContactCache.contact_id ";
$whereClase = " aclContactCache.user_id = $contactID AND $contactAlias.is_deleted = 0";
}
return array($fromClause, $whereClase);
}
/**
* Generate acl subquery that can be placed in the WHERE clause of a query or the ON clause of a JOIN.
*
* This is specifically for VIEW operations.
*
* @return string|null
*/
public static function cacheSubquery() {
if (!CRM_Core_Permission::check(array(array('view all contacts', 'edit all contacts')))) {
$contactID = (int) CRM_Core_Session::getLoggedInContactID();
self::cache($contactID);
return "IN (SELECT contact_id FROM civicrm_acl_contact_cache WHERE user_id = $contactID)";
}
return NULL;
}
/**
* Filter a list of contact_ids by the ones that the
* currently active user as a permissioned relationship with
*
* @param array $contact_ids
* List of contact IDs to be filtered
*
* @return array
* List of contact IDs that the user has permissions for
*/
public static function relationshipList($contact_ids) {
$result_set = array();
// no processing empty lists (avoid SQL errors as well)
if (empty($contact_ids)) {
return array();
}
// get the currently logged in user
$contactID = CRM_Core_Session::getLoggedInContactID();
if (empty($contactID)) {
return array();
}
// compile a list of queries (later to UNION)
$queries = array();
$contact_id_list = implode(',', $contact_ids);
// add a select statement for each direection
$directions = array(array('from' => 'a', 'to' => 'b'), array('from' => 'b', 'to' => 'a'));
// NORMAL/SINGLE DEGREE RELATIONSHIPS
foreach ($directions as $direction) {
$user_id_column = "contact_id_{$direction['from']}";
$contact_id_column = "contact_id_{$direction['to']}";
// add clause for deleted contacts, if the user doesn't have the permission to access them
$LEFT_JOIN_DELETED = $AND_CAN_ACCESS_DELETED = '';
if (!CRM_Core_Permission::check('access deleted contacts')) {
$LEFT_JOIN_DELETED = "LEFT JOIN civicrm_contact ON civicrm_contact.id = {$contact_id_column} ";
$AND_CAN_ACCESS_DELETED = "AND civicrm_contact.is_deleted = 0";
}
$queries[] = "
SELECT civicrm_relationship.{$contact_id_column} AS contact_id
FROM civicrm_relationship
{$LEFT_JOIN_DELETED}
WHERE civicrm_relationship.{$user_id_column} = {$contactID}
AND civicrm_relationship.{$contact_id_column} IN ({$contact_id_list})
AND civicrm_relationship.is_active = 1
AND civicrm_relationship.is_permission_{$direction['from']}_{$direction['to']} = 1
$AND_CAN_ACCESS_DELETED";
}
// FIXME: secondDegRelPermissions should be a setting
$config = CRM_Core_Config::singleton();
if ($config->secondDegRelPermissions) {
foreach ($directions as $first_direction) {
foreach ($directions as $second_direction) {
// add clause for deleted contacts, if the user doesn't have the permission to access them
$LEFT_JOIN_DELETED = $AND_CAN_ACCESS_DELETED = '';
if (!CRM_Core_Permission::check('access deleted contacts')) {
$LEFT_JOIN_DELETED = "LEFT JOIN civicrm_contact first_degree_contact ON first_degree_contact.id = second_degree_relationship.contact_id_{$second_direction['from']}\n";
$LEFT_JOIN_DELETED .= "LEFT JOIN civicrm_contact second_degree_contact ON second_degree_contact.id = second_degree_relationship.contact_id_{$second_direction['to']} ";
$AND_CAN_ACCESS_DELETED = "AND first_degree_contact.is_deleted = 0\n";
$AND_CAN_ACCESS_DELETED .= "AND second_degree_contact.is_deleted = 0 ";
}
$queries[] = "
SELECT second_degree_relationship.contact_id_{$second_direction['to']} AS contact_id
FROM civicrm_relationship first_degree_relationship
LEFT JOIN civicrm_relationship second_degree_relationship ON first_degree_relationship.contact_id_{$first_direction['to']} = second_degree_relationship.contact_id_{$first_direction['from']}
{$LEFT_JOIN_DELETED}
WHERE first_degree_relationship.contact_id_{$first_direction['from']} = {$contactID}
AND second_degree_relationship.contact_id_{$second_direction['to']} IN ({$contact_id_list})
AND first_degree_relationship.is_active = 1
AND first_degree_relationship.is_permission_{$first_direction['from']}_{$first_direction['to']} = 1
AND second_degree_relationship.is_active = 1
AND second_degree_relationship.is_permission_{$second_direction['from']}_{$second_direction['to']} = 1
$AND_CAN_ACCESS_DELETED";
}
}
}
// finally UNION the queries and call
$query = "(" . implode(")\nUNION DISTINCT (", $queries) . ")";
$result = CRM_Core_DAO::executeQuery($query);
while ($result->fetch()) {
$result_set[(int) $result->contact_id] = TRUE;
}
return array_keys($result_set);
}
/**
* @param int $contactID
* @param CRM_Core_Form $form
* @param bool $redirect
*
* @return bool
*/
public static function validateOnlyChecksum($contactID, &$form, $redirect = TRUE) {
// check if this is of the format cs=XXX
if (!CRM_Contact_BAO_Contact_Utils::validChecksum($contactID,
CRM_Utils_Request::retrieve('cs', 'String', $form, FALSE)
)
) {
if ($redirect) {
// also set a message in the UF framework
$message = ts('You do not have permission to edit this contact record. Contact the site administrator if you need assistance.');
CRM_Utils_System::setUFMessage($message);
$config = CRM_Core_Config::singleton();
CRM_Core_Error::statusBounce($message,
$config->userFrameworkBaseURL
);
// does not come here, we redirect in the above statement
}
return FALSE;
}
// set appropriate AUTH source
self::initChecksumAuthSrc(TRUE, $form);
// so here the contact is posing as $contactID, lets set the logging contact ID variable
// CRM-8965
CRM_Core_DAO::executeQuery('SET @civicrm_user_id = %1',
array(1 => array($contactID, 'Integer'))
);
return TRUE;
}
/**
* @param bool $checkSumValidationResult
* @param null $form
*/
public static function initChecksumAuthSrc($checkSumValidationResult = FALSE, $form = NULL) {
$session = CRM_Core_Session::singleton();
if ($checkSumValidationResult && $form && CRM_Utils_Request::retrieve('cs', 'String', $form, FALSE)) {
// if result is already validated, and url has cs, set the flag.
$session->set('authSrc', CRM_Core_Permission::AUTH_SRC_CHECKSUM);
}
elseif (($session->get('authSrc') & CRM_Core_Permission::AUTH_SRC_CHECKSUM) == CRM_Core_Permission::AUTH_SRC_CHECKSUM) {
// if checksum wasn't present in REQUEST OR checksum result validated as FALSE,
// and flag was already set exactly as AUTH_SRC_CHECKSUM, unset it.
$session->set('authSrc', CRM_Core_Permission::AUTH_SRC_UNKNOWN);
}
}
/**
* @param int $contactID
* @param CRM_Core_Form $form
* @param bool $redirect
*
* @return bool
*/
public static function validateChecksumContact($contactID, &$form, $redirect = TRUE) {
if (!self::allow($contactID, CRM_Core_Permission::EDIT)) {
// check if this is of the format cs=XXX
return self::validateOnlyChecksum($contactID, $form, $redirect);
}
return TRUE;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,948 @@
<?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_BAO_ContactType extends CRM_Contact_DAO_ContactType {
/**
* Fetch object based on array of properties.
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
* @param array $defaults
* (reference ) an assoc array to hold the flattened values.
*
* @return CRM_Contact_BAO_ContactType|null
* object on success, null otherwise
*/
public static function retrieve(&$params, &$defaults) {
$contactType = new CRM_Contact_DAO_ContactType();
$contactType->copyValues($params);
if ($contactType->find(TRUE)) {
CRM_Core_DAO::storeValues($contactType, $defaults);
return $contactType;
}
return NULL;
}
/**
* Is this contact type active.
*
* @param string $contactType
*
* @return bool
*/
public static function isActive($contactType) {
$contact = self::contactTypeInfo(FALSE);
$active = array_key_exists($contactType, $contact) ? TRUE : FALSE;
return $active;
}
/**
* Retrieve basic contact type information.
*
* @param bool $all
*
* @return array
* Array of basic contact types information.
*/
public static function basicTypeInfo($all = FALSE) {
static $_cache = NULL;
if ($_cache === NULL) {
$_cache = array();
}
$argString = $all ? 'CRM_CT_BTI_1' : 'CRM_CT_BTI_0';
if (!array_key_exists($argString, $_cache)) {
$cache = CRM_Utils_Cache::singleton();
$_cache[$argString] = $cache->get($argString);
if (!$_cache[$argString]) {
$sql = "
SELECT *
FROM civicrm_contact_type
WHERE parent_id IS NULL
";
if ($all === FALSE) {
$sql .= " AND is_active = 1";
}
$params = array();
$dao = CRM_Core_DAO::executeQuery($sql,
$params,
FALSE,
'CRM_Contact_DAO_ContactType'
);
while ($dao->fetch()) {
$value = array();
CRM_Core_DAO::storeValues($dao, $value);
$_cache[$argString][$dao->name] = $value;
}
$cache->set($argString, $_cache[$argString]);
}
}
return $_cache[$argString];
}
/**
* Retrieve all basic contact types.
*
* @param bool $all
*
* @return array
* Array of basic contact types
*/
public static function basicTypes($all = FALSE) {
return array_keys(self::basicTypeInfo($all));
}
/**
* @param bool $all
* @param string $key
*
* @return array
*/
public static function basicTypePairs($all = FALSE, $key = 'name') {
$subtypes = self::basicTypeInfo($all);
$pairs = array();
foreach ($subtypes as $name => $info) {
$index = ($key == 'name') ? $name : $info[$key];
$pairs[$index] = $info['label'];
}
return $pairs;
}
/**
* Retrieve all subtypes Information.
*
* @param array $contactType
* ..
* @param bool $all
* @param bool $ignoreCache
* @param bool $reset
*
* @return array
* Array of sub type information
*/
public static function subTypeInfo($contactType = NULL, $all = FALSE, $ignoreCache = FALSE, $reset = FALSE) {
static $_cache = NULL;
if ($reset === TRUE) {
$_cache = NULL;
}
if ($_cache === NULL) {
$_cache = array();
}
if ($contactType && !is_array($contactType)) {
$contactType = array($contactType);
}
$argString = $all ? 'CRM_CT_STI_1_' : 'CRM_CT_STI_0_';
if (!empty($contactType)) {
$argString .= implode('_', $contactType);
}
if ((!array_key_exists($argString, $_cache)) || $ignoreCache) {
$cache = CRM_Utils_Cache::singleton();
$_cache[$argString] = $cache->get($argString);
if (!$_cache[$argString] || $ignoreCache) {
$_cache[$argString] = array();
$ctWHERE = '';
if (!empty($contactType)) {
$ctWHERE = " AND parent.name IN ('" . implode("','", $contactType) . "')";
}
$sql = "
SELECT subtype.*, parent.name as parent, parent.label as parent_label
FROM civicrm_contact_type subtype
INNER JOIN civicrm_contact_type parent ON subtype.parent_id = parent.id
WHERE subtype.name IS NOT NULL AND subtype.parent_id IS NOT NULL {$ctWHERE}
";
if ($all === FALSE) {
$sql .= " AND subtype.is_active = 1 AND parent.is_active = 1 ORDER BY parent.id";
}
$dao = CRM_Core_DAO::executeQuery($sql, array(),
FALSE, 'CRM_Contact_DAO_ContactType'
);
while ($dao->fetch()) {
$value = array();
CRM_Core_DAO::storeValues($dao, $value);
$value['parent'] = $dao->parent;
$value['parent_label'] = $dao->parent_label;
$_cache[$argString][$dao->name] = $value;
}
$cache->set($argString, $_cache[$argString]);
}
}
return $_cache[$argString];
}
/**
*
* retrieve all subtypes
*
* @param array $contactType
* ..
* @param bool $all
* @param string $columnName
* @param bool $ignoreCache
*
* @return array
* all subtypes OR list of subtypes associated to
* a given basic contact type
*/
public static function subTypes($contactType = NULL, $all = FALSE, $columnName = 'name', $ignoreCache = FALSE) {
if ($columnName == 'name') {
return array_keys(self::subTypeInfo($contactType, $all, $ignoreCache));
}
else {
return array_values(self::subTypePairs($contactType, FALSE, NULL, $ignoreCache));
}
}
/**
*
* retrieve subtype pairs with name as 'subtype-name' and 'label' as value
*
* @param array $contactType
* @param bool $all
* @param string $labelPrefix
* @param bool $ignoreCache
*
* @return array
* list of subtypes with name as 'subtype-name' and 'label' as value
*/
public static function subTypePairs($contactType = NULL, $all = FALSE, $labelPrefix = '- ', $ignoreCache = FALSE) {
$subtypes = self::subTypeInfo($contactType, $all, $ignoreCache);
$pairs = array();
foreach ($subtypes as $name => $info) {
$pairs[$name] = $labelPrefix . $info['label'];
}
return $pairs;
}
/**
*
* retrieve list of all types i.e basic + subtypes.
*
* @param bool $all
*
* @return array
* Array of basic types + all subtypes.
*/
public static function contactTypes($all = FALSE) {
return array_keys(self::contactTypeInfo($all));
}
/**
* Retrieve info array about all types i.e basic + subtypes.
*
* @param bool $all
* @param bool $reset
*
* @return array
* Array of basic types + all subtypes.
*/
public static function contactTypeInfo($all = FALSE, $reset = FALSE) {
static $_cache = NULL;
if ($reset === TRUE) {
$_cache = NULL;
}
if ($_cache === NULL) {
$_cache = array();
}
$argString = $all ? 'CRM_CT_CTI_1' : 'CRM_CT_CTI_0';
if (!array_key_exists($argString, $_cache)) {
$cache = CRM_Utils_Cache::singleton();
$_cache[$argString] = $cache->get($argString);
if (!$_cache[$argString]) {
$_cache[$argString] = array();
$sql = "
SELECT type.*, parent.name as parent, parent.label as parent_label
FROM civicrm_contact_type type
LEFT JOIN civicrm_contact_type parent ON type.parent_id = parent.id
WHERE type.name IS NOT NULL
";
if ($all === FALSE) {
$sql .= " AND type.is_active = 1";
}
$dao = CRM_Core_DAO::executeQuery($sql,
array(),
FALSE,
'CRM_Contact_DAO_ContactType'
);
while ($dao->fetch()) {
$value = array();
CRM_Core_DAO::storeValues($dao, $value);
if (array_key_exists('parent_id', $value)) {
$value['parent'] = $dao->parent;
$value['parent_label'] = $dao->parent_label;
}
$_cache[$argString][$dao->name] = $value;
}
$cache->set($argString, $_cache[$argString]);
}
}
return $_cache[$argString];
}
/**
* Retrieve basic type pairs with name as 'built-in name' and 'label' as value.
*
* @param bool $all
* @param null $typeName
* @param null $delimiter
*
* @return array
* Array of basictypes with name as 'built-in name' and 'label' as value
*/
public static function contactTypePairs($all = FALSE, $typeName = NULL, $delimiter = NULL) {
$types = self::contactTypeInfo($all);
if ($typeName && !is_array($typeName)) {
$typeName = explode(CRM_Core_DAO::VALUE_SEPARATOR, trim($typeName, CRM_Core_DAO::VALUE_SEPARATOR));
}
$pairs = array();
if ($typeName) {
foreach ($typeName as $type) {
if (array_key_exists($type, $types)) {
$pairs[$type] = $types[$type]['label'];
}
}
}
else {
foreach ($types as $name => $info) {
$pairs[$name] = $info['label'];
}
}
return !$delimiter ? $pairs : implode($delimiter, $pairs);
}
/**
* Get a list of elements for select box.
* Note that this used to default to using the hex(01) character - which results in an invalid character being used in form fields
* which was not handled well be anything that loaded & resaved the html (outside core)
* The use of this separator is now explicit in the calling functions as a step towards it's removal
*
* @param bool $all
* @param bool $isSeparator
* @param string $separator
*
* @return mixed
*/
public static function getSelectElements(
$all = FALSE,
$isSeparator = TRUE,
$separator = '__'
) {
static $_cache = NULL;
if ($_cache === NULL) {
$_cache = array();
}
$argString = $all ? 'CRM_CT_GSE_1' : 'CRM_CT_GSE_0';
$argString .= $isSeparator ? '_1' : '_0';
$argString .= $separator;
if (!array_key_exists($argString, $_cache)) {
$cache = CRM_Utils_Cache::singleton();
$_cache[$argString] = $cache->get($argString);
if (!$_cache[$argString]) {
$_cache[$argString] = array();
$sql = "
SELECT c.name as child_name , c.label as child_label , c.id as child_id,
p.name as parent_name, p.label as parent_label, p.id as parent_id
FROM civicrm_contact_type c
LEFT JOIN civicrm_contact_type p ON ( c.parent_id = p.id )
WHERE ( c.name IS NOT NULL )
";
if ($all === FALSE) {
$sql .= "
AND c.is_active = 1
AND ( p.is_active = 1 OR p.id IS NULL )
";
}
$sql .= " ORDER BY c.id";
$values = array();
$dao = CRM_Core_DAO::executeQuery($sql);
while ($dao->fetch()) {
if (!empty($dao->parent_id)) {
$key = $isSeparator ? $dao->parent_name . $separator . $dao->child_name : $dao->child_name;
$label = "- {$dao->child_label}";
$pName = $dao->parent_name;
}
else {
$key = $dao->child_name;
$label = $dao->child_label;
$pName = $dao->child_name;
}
if (!isset($values[$pName])) {
$values[$pName] = array();
}
$values[$pName][] = array('key' => $key, 'label' => $label);
}
$selectElements = array();
foreach ($values as $pName => $elements) {
foreach ($elements as $element) {
$selectElements[$element['key']] = $element['label'];
}
}
$_cache[$argString] = $selectElements;
$cache->set($argString, $_cache[$argString]);
}
}
return $_cache[$argString];
}
/**
* Check if a given type is a subtype.
*
* @param string $subType
* Contact subType.
* @param bool $ignoreCache
*
* @return bool
* true if subType, false otherwise.
*/
public static function isaSubType($subType, $ignoreCache = FALSE) {
return in_array($subType, self::subTypes(NULL, TRUE, 'name', $ignoreCache));
}
/**
* Retrieve the basic contact type associated with given subType.
*
* @param array /string $subType contact subType.
* @return array/string of basicTypes.
*/
public static function getBasicType($subType) {
static $_cache = NULL;
if ($_cache === NULL) {
$_cache = array();
}
$isArray = TRUE;
if ($subType && !is_array($subType)) {
$subType = array($subType);
$isArray = FALSE;
}
$argString = implode('_', $subType);
if (!array_key_exists($argString, $_cache)) {
$_cache[$argString] = array();
$sql = "
SELECT subtype.name as contact_subtype, type.name as contact_type
FROM civicrm_contact_type subtype
INNER JOIN civicrm_contact_type type ON ( subtype.parent_id = type.id )
WHERE subtype.name IN ('" . implode("','", $subType) . "' )";
$dao = CRM_Core_DAO::executeQuery($sql);
while ($dao->fetch()) {
if (!$isArray) {
$_cache[$argString] = $dao->contact_type;
break;
}
$_cache[$argString][$dao->contact_subtype] = $dao->contact_type;
}
}
return $_cache[$argString];
}
/**
* Suppress all subtypes present in given array.
*
* @param array $subTypes
* Contact subTypes.
* @param bool $ignoreCache
*
* @return array
* Array of suppressed subTypes.
*/
public static function suppressSubTypes(&$subTypes, $ignoreCache = FALSE) {
$subTypes = array_diff($subTypes, self::subTypes(NULL, TRUE, 'name', $ignoreCache));
return $subTypes;
}
/**
* Verify if a given subtype is associated with a given basic contact type.
*
* @param string $subType
* Contact subType.
* @param string $contactType
* Contact Type.
* @param bool $ignoreCache
* @param string $columnName
*
* @return bool
* true if contact extends, false otherwise.
*/
public static function isExtendsContactType($subType, $contactType, $ignoreCache = FALSE, $columnName = 'name') {
$subType = (array) CRM_Utils_Array::explodePadded($subType);
$subtypeList = self::subTypes($contactType, TRUE, $columnName, $ignoreCache);
$intersection = array_intersect($subType, $subtypeList);
return $subType == $intersection;
}
/**
* Create shortcuts menu for contactTypes.
*
* @return array
* of contactTypes
*/
public static function getCreateNewList() {
$shortCuts = array();
//@todo FIXME - using the CRM_Core_DAO::VALUE_SEPARATOR creates invalid html - if you can find the form
// this is loaded onto then replace with something like '__' & test
$separator = CRM_Core_DAO::VALUE_SEPARATOR;
$contactTypes = self::getSelectElements(FALSE, TRUE, $separator);
foreach ($contactTypes as $key => $value) {
if ($key) {
$typeValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $key);
$cType = CRM_Utils_Array::value('0', $typeValue);
$typeUrl = 'ct=' . $cType;
if ($csType = CRM_Utils_Array::value('1', $typeValue)) {
$typeUrl .= "&cst=$csType";
}
$shortCut = array(
'path' => 'civicrm/contact/add',
'query' => "$typeUrl&reset=1",
'ref' => "new-$value",
'title' => $value,
);
if ($csType = CRM_Utils_Array::value('1', $typeValue)) {
$shortCuts[$cType]['shortCuts'][] = $shortCut;
}
else {
$shortCuts[$cType] = $shortCut;
}
}
}
return $shortCuts;
}
/**
* Delete Contact SubTypes.
*
* @param int $contactTypeId
* ID of the Contact Subtype to be deleted.
*
* @return bool
*/
public static function del($contactTypeId) {
if (!$contactTypeId) {
return FALSE;
}
$params = array('id' => $contactTypeId);
self::retrieve($params, $typeInfo);
$name = $typeInfo['name'];
// check if any custom group
$custom = new CRM_Core_DAO_CustomGroup();
$custom->whereAdd("extends_entity_column_value LIKE '%" .
CRM_Core_DAO::VALUE_SEPARATOR .
$name .
CRM_Core_DAO::VALUE_SEPARATOR . "%'"
);
if ($custom->find()) {
return FALSE;
}
// remove subtype for existing contacts
$sql = "
UPDATE civicrm_contact SET contact_sub_type = NULL
WHERE contact_sub_type = '$name'";
CRM_Core_DAO::executeQuery($sql);
// remove subtype from contact type table
$contactType = new CRM_Contact_DAO_ContactType();
$contactType->id = $contactTypeId;
$contactType->delete();
// remove navigation entry if any
if ($name) {
$sql = "
DELETE
FROM civicrm_navigation
WHERE name = %1";
$params = array(1 => array("New $name", 'String'));
$dao = CRM_Core_DAO::executeQuery($sql, $params);
CRM_Core_BAO_Navigation::resetNavigation();
}
return TRUE;
}
/**
* Add or update Contact SubTypes.
*
* @param array $params
* An assoc array of name/value pairs.
*
* @return object|void
*/
public static function add(&$params) {
// label or name
if (empty($params['id']) && empty($params['label'])) {
return NULL;
}
if (!empty($params['parent_id']) &&
!CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_ContactType', $params['parent_id'])
) {
return NULL;
}
$contactType = new CRM_Contact_DAO_ContactType();
$contactType->copyValues($params);
$contactType->id = CRM_Utils_Array::value('id', $params);
$contactType->is_active = CRM_Utils_Array::value('is_active', $params, 0);
$contactType->save();
if ($contactType->find(TRUE)) {
$contactName = $contactType->name;
$contact = ucfirst($contactType->label);
$active = $contactType->is_active;
}
if (!empty($params['id'])) {
$params = array('name' => "New $contactName");
$newParams = array(
'label' => "New $contact",
'is_active' => $active,
);
CRM_Core_BAO_Navigation::processUpdate($params, $newParams);
}
else {
$name = self::getBasicType($contactName);
if (!$name) {
return;
}
$value = array('name' => "New $name");
CRM_Core_BAO_Navigation::retrieve($value, $navinfo);
$navigation = array(
'label' => "New $contact",
'name' => "New $contactName",
'url' => "civicrm/contact/add?ct=$name&cst=$contactName&reset=1",
'permission' => 'add contacts',
'parent_id' => $navinfo['id'],
'is_active' => $active,
);
CRM_Core_BAO_Navigation::add($navigation);
}
CRM_Core_BAO_Navigation::resetNavigation();
// reset the cache after adding
self::subTypeInfo(NULL, FALSE, FALSE, TRUE);
return $contactType;
}
/**
* Update the is_active flag in the db.
*
* @param int $id
* Id of the database record.
* @param bool $is_active
* Value we want to set the is_active field.
*
* @return Object
* DAO object on success, null otherwise
*/
public static function setIsActive($id, $is_active) {
$params = array('id' => $id);
self::retrieve($params, $contactinfo);
$params = array('name' => "New $contactinfo[name]");
$newParams = array('is_active' => $is_active);
CRM_Core_BAO_Navigation::processUpdate($params, $newParams);
CRM_Core_BAO_Navigation::resetNavigation();
return CRM_Core_DAO::setFieldValue('CRM_Contact_DAO_ContactType', $id,
'is_active', $is_active
);
}
/**
* @param string $typeName
*
* @return mixed
*/
public static function getLabel($typeName) {
$types = self::contactTypeInfo(TRUE);
if (array_key_exists($typeName, $types)) {
return $types[$typeName]['label'];
}
return $typeName;
}
/**
* Check whether allow to change any contact's subtype
* on the basis of custom data and relationship of specific subtype
* currently used in contact/edit form amd in import validation
*
* @param int $contactId
* Contact id.
* @param string $subType
* Subtype.
*
* @return bool
*/
public static function isAllowEdit($contactId, $subType = NULL) {
if (!$contactId) {
return TRUE;
}
if (empty($subType)) {
$subType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
$contactId,
'contact_sub_type'
);
}
if (self::hasCustomData($subType, $contactId) || self::hasRelationships($contactId, $subType)) {
return FALSE;
}
return TRUE;
}
/**
* @param $contactType
* @param int $contactId
*
* @return bool
*/
public static function hasCustomData($contactType, $contactId = NULL) {
$subTypeClause = '';
if (self::isaSubType($contactType)) {
$subType = $contactType;
$contactType = self::getBasicType($subType);
// check for empty custom data which extends subtype
$subTypeValue = CRM_Core_DAO::VALUE_SEPARATOR . $subType . CRM_Core_DAO::VALUE_SEPARATOR;
$subTypeClause = " AND extends_entity_column_value LIKE '%{$subTypeValue}%' ";
}
$query = "SELECT table_name FROM civicrm_custom_group WHERE extends = '{$contactType}' {$subTypeClause}";
$dao = CRM_Core_DAO::executeQuery($query);
while ($dao->fetch()) {
$sql = "SELECT count(id) FROM {$dao->table_name}";
if ($contactId) {
$sql .= " WHERE entity_id = {$contactId}";
}
$sql .= " LIMIT 1";
$customDataCount = CRM_Core_DAO::singleValueQuery($sql);
if (!empty($customDataCount)) {
$dao->free();
return TRUE;
}
}
return FALSE;
}
/**
* @todo what does this function do?
* @param int $contactId
* @param $contactType
*
* @return bool
*/
public static function hasRelationships($contactId, $contactType) {
$subTypeClause = NULL;
if (self::isaSubType($contactType)) {
$subType = $contactType;
$contactType = self::getBasicType($subType);
$subTypeClause = " AND ( ( crt.contact_type_a = '{$contactType}' AND crt.contact_sub_type_a = '{$subType}') OR
( crt.contact_type_b = '{$contactType}' AND crt.contact_sub_type_b = '{$subType}') ) ";
}
else {
$subTypeClause = " AND ( crt.contact_type_a = '{$contactType}' OR crt.contact_type_b = '{$contactType}' ) ";
}
// check relationships for
$relationshipQuery = "
SELECT count(cr.id) FROM civicrm_relationship cr
INNER JOIN civicrm_relationship_type crt ON
( cr.relationship_type_id = crt.id {$subTypeClause} )
WHERE ( cr.contact_id_a = {$contactId} OR cr.contact_id_b = {$contactId} )
LIMIT 1";
$relationshipCount = CRM_Core_DAO::singleValueQuery($relationshipQuery);
if (!empty($relationshipCount)) {
return TRUE;
}
return FALSE;
}
/**
* @todo what does this function do?
* @param $contactType
* @param array $subtypeSet
*
* @return array
*/
public static function getSubtypeCustomPair($contactType, $subtypeSet = array()) {
if (empty($subtypeSet)) {
return $subtypeSet;
}
$customSet = $subTypeClause = array();
foreach ($subtypeSet as $subtype) {
$subtype = CRM_Utils_Type::escape($subtype, 'String');
$subtype = CRM_Core_DAO::VALUE_SEPARATOR . $subtype . CRM_Core_DAO::VALUE_SEPARATOR;
$subTypeClause[] = "extends_entity_column_value LIKE '%{$subtype}%' ";
}
$query = "SELECT table_name
FROM civicrm_custom_group
WHERE extends = %1 AND " . implode(" OR ", $subTypeClause);
$dao = CRM_Core_DAO::executeQuery($query, array(1 => array($contactType, 'String')));
while ($dao->fetch()) {
$customSet[] = $dao->table_name;
}
return array_unique($customSet);
}
/**
* Function that does something.
* @todo what does this function do?
*
* @param int $contactID
* @param $contactType
* @param array $oldSubtypeSet
* @param array $newSubtypeSet
*
* @return bool
*/
public static function deleteCustomSetForSubtypeMigration(
$contactID,
$contactType,
$oldSubtypeSet = array(),
$newSubtypeSet = array()
) {
$oldCustomSet = self::getSubtypeCustomPair($contactType, $oldSubtypeSet);
$newCustomSet = self::getSubtypeCustomPair($contactType, $newSubtypeSet);
$customToBeRemoved = array_diff($oldCustomSet, $newCustomSet);
foreach ($customToBeRemoved as $customTable) {
self::deleteCustomRowsForEntityID($customTable, $contactID);
}
return TRUE;
}
/**
* Delete content / rows of a custom table specific to a subtype for a given custom-group.
* This function currently works for contact subtypes only and could be later improved / genralized
* to work for other subtypes as well.
*
* @param int $gID
* Custom group id.
* @param array $subtypes
* List of subtypes related to which entry is to be removed.
*
* @return bool
*/
public static function deleteCustomRowsOfSubtype($gID, $subtypes = array(), $subtypesToPreserve = array()) {
if (!$gID or empty($subtypes)) {
return FALSE;
}
$tableName = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $gID, 'table_name');
// drop triggers CRM-13587
CRM_Core_DAO::dropTriggers($tableName);
foreach ($subtypesToPreserve as $subtypeToPreserve) {
$subtypeToPreserve = CRM_Utils_Type::escape($subtypeToPreserve, 'String');
$subtypesToPreserveClause[] = "(civicrm_contact.contact_sub_type NOT LIKE '%" . CRM_Core_DAO::VALUE_SEPARATOR . $subtypeToPreserve . CRM_Core_DAO::VALUE_SEPARATOR . "%')";
}
$subtypesToPreserveClause = implode(' AND ', $subtypesToPreserveClause);
$subtypeClause = array();
foreach ($subtypes as $subtype) {
$subtype = CRM_Utils_Type::escape($subtype, 'String');
$subtypeClause[] = "( civicrm_contact.contact_sub_type LIKE '%" . CRM_Core_DAO::VALUE_SEPARATOR . $subtype . CRM_Core_DAO::VALUE_SEPARATOR . "%'"
. " AND " . $subtypesToPreserveClause . ")";
}
$subtypeClause = implode(' OR ', $subtypeClause);
$query = "DELETE custom.*
FROM {$tableName} custom
INNER JOIN civicrm_contact ON civicrm_contact.id = custom.entity_id
WHERE ($subtypeClause)";
CRM_Core_DAO::singleValueQuery($query);
// rebuild triggers CRM-13587
CRM_Core_DAO::triggerRebuild($tableName);
}
/**
* Delete content / rows of a custom table specific entity-id for a given custom-group table.
*
* @param int $customTable
* Custom table name.
* @param int $entityID
* Entity id.
*
* @return null|string
*/
public static function deleteCustomRowsForEntityID($customTable, $entityID) {
$customTable = CRM_Utils_Type::escape($customTable, 'String');
$query = "DELETE FROM {$customTable} WHERE entity_id = %1";
return CRM_Core_DAO::singleValueQuery($query, array(1 => array($entityID, 'Integer')));
}
}

View file

@ -0,0 +1,33 @@
<?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_BAO_DashboardContact extends CRM_Contact_DAO_DashboardContact {
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,798 @@
<?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_BAO_GroupContact extends CRM_Contact_DAO_GroupContact {
/**
* Class constructor.
*/
public function __construct() {
parent::__construct();
}
/**
* Takes an associative array and creates a groupContact object.
*
* the function extract all the params it needs to initialize the create a
* group object. the params array could contain additional unused name/value
* pairs
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
*
* @return CRM_Contact_BAO_Group
*/
public static function add(&$params) {
$dataExists = self::dataExists($params);
if (!$dataExists) {
return NULL;
}
$groupContact = new CRM_Contact_BAO_GroupContact();
$groupContact->copyValues($params);
CRM_Contact_BAO_SubscriptionHistory::create($params);
$groupContact->save();
return $groupContact;
}
/**
* Check if there is data to create the object.
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
*
* @return bool
*/
public static function dataExists(&$params) {
// return if no data present
if ($params['group_id'] == 0) {
return FALSE;
}
return TRUE;
}
/**
* Given the list of params in the params array, fetch the object
* and store the values in the values array
*
* @param array $params
* Input parameters to find object.
* @param array $values
* Output values of the object.
*
* @return array
* (reference) the values that could be potentially assigned to smarty
*/
public static function getValues(&$params, &$values) {
if (empty($params)) {
return NULL;
}
$values['group']['data'] = CRM_Contact_BAO_GroupContact::getContactGroup($params['contact_id'],
'Added',
3
);
// get the total count of groups
$values['group']['totalCount'] = CRM_Contact_BAO_GroupContact::getContactGroup($params['contact_id'],
'Added',
NULL,
TRUE
);
return NULL;
}
/**
* Given an array of contact ids, add all the contacts to the group
*
* @param array $contactIds
* The array of contact ids to be added.
* @param int $groupId
* The id of the group.
* @param string $method
* @param string $status
* @param int $tracking
*
* @return array
* (total, added, notAdded) count of contacts added to group
*/
public static function addContactsToGroup(
$contactIds,
$groupId,
$method = 'Admin',
$status = 'Added',
$tracking = NULL
) {
if (empty($contactIds) || empty($groupId)) {
return array();
}
CRM_Utils_Hook::pre('create', 'GroupContact', $groupId, $contactIds);
list($numContactsAdded, $numContactsNotAdded)
= self::bulkAddContactsToGroup($contactIds, $groupId, $method, $status, $tracking);
CRM_Contact_BAO_Contact_Utils::clearContactCaches();
CRM_Utils_Hook::post('create', 'GroupContact', $groupId, $contactIds);
return array(count($contactIds), $numContactsAdded, $numContactsNotAdded);
}
/**
* Given an array of contact ids, remove all the contacts from the group
*
* @param array $contactIds
* (reference ) the array of contact ids to be removed.
* @param int $groupId
* The id of the group.
*
* @param string $method
* @param string $status
* @param NULL $tracking
*
* @return array
* (total, removed, notRemoved) count of contacts removed to group
*/
public static function removeContactsFromGroup(
&$contactIds,
$groupId,
$method = 'Admin',
$status = 'Removed',
$tracking = NULL
) {
if (!is_array($contactIds)) {
return array(0, 0, 0);
}
if ($status == 'Removed' || $status == 'Deleted') {
$op = 'delete';
}
else {
$op = 'edit';
}
CRM_Utils_Hook::pre($op, 'GroupContact', $groupId, $contactIds);
$date = date('YmdHis');
$numContactsRemoved = 0;
$numContactsNotRemoved = 0;
$group = new CRM_Contact_DAO_Group();
$group->id = $groupId;
$group->find(TRUE);
foreach ($contactIds as $contactId) {
if ($status == 'Deleted') {
$query = "DELETE FROM civicrm_group_contact WHERE contact_id=$contactId AND group_id=$groupId";
$dao = CRM_Core_DAO::executeQuery($query);
$historyParams = array(
'group_id' => $groupId,
'contact_id' => $contactId,
'status' => $status,
'method' => $method,
'date' => $date,
'tracking' => $tracking,
);
CRM_Contact_BAO_SubscriptionHistory::create($historyParams);
}
else {
$groupContact = new CRM_Contact_DAO_GroupContact();
$groupContact->group_id = $groupId;
$groupContact->contact_id = $contactId;
// check if the selected contact id already a member, or if this is
// an opt-out of a smart group.
// if not a member remove to groupContact else keep the count of contacts that are not removed
if ($groupContact->find(TRUE) || $group->saved_search_id) {
// remove the contact from the group
$numContactsRemoved++;
}
else {
$numContactsNotRemoved++;
}
//now we grant the negative membership to contact if not member. CRM-3711
$historyParams = array(
'group_id' => $groupId,
'contact_id' => $contactId,
'status' => $status,
'method' => $method,
'date' => $date,
'tracking' => $tracking,
);
CRM_Contact_BAO_SubscriptionHistory::create($historyParams);
$groupContact->status = $status;
$groupContact->save();
}
}
CRM_Contact_BAO_Contact_Utils::clearContactCaches();
CRM_Utils_Hook::post($op, 'GroupContact', $groupId, $contactIds);
return array(count($contactIds), $numContactsRemoved, $numContactsNotRemoved);
}
/**
* Get list of all the groups and groups for a contact.
*
* @param int $contactId
* Contact id.
*
* @param bool $visibility
*
*
* @return array
* this array has key-> group id and value group title
*/
public static function getGroupList($contactId = 0, $visibility = FALSE) {
$group = new CRM_Contact_DAO_Group();
$select = $from = $where = '';
$select = 'SELECT civicrm_group.id, civicrm_group.title ';
$from = ' FROM civicrm_group ';
$where = " WHERE civicrm_group.is_active = 1 ";
if ($contactId) {
$from .= ' , civicrm_group_contact ';
$where .= " AND civicrm_group.id = civicrm_group_contact.group_id
AND civicrm_group_contact.contact_id = " . CRM_Utils_Type::escape($contactId, 'Integer');
}
if ($visibility) {
$where .= " AND civicrm_group.visibility != 'User and User Admin Only'";
}
$groupBy = " GROUP BY civicrm_group.id";
$orderby = " ORDER BY civicrm_group.name";
$sql = $select . $from . $where . $groupBy . $orderby;
$group->query($sql);
$values = array();
while ($group->fetch()) {
$values[$group->id] = $group->title;
}
return $values;
}
/**
* Get the list of groups for contact based on status of group membership.
*
* @param int $contactId
* Contact id.
* @param string $status
* State of membership.
* @param int $numGroupContact
* Number of groups for a contact that should be shown.
* @param bool $count
* True if we are interested only in the count.
* @param bool $ignorePermission
* True if we should ignore permissions for the current user.
* useful in profile where permissions are limited for the user. If left
* at false only groups viewable by the current user are returned
* @param bool $onlyPublicGroups
* True if we want to hide system groups.
*
* @param bool $excludeHidden
*
* @param int $groupId
*
* @param bool $includeSmartGroups
* Include or Exclude Smart Group(s)
*
* @return array|int $values
* the relevant data object values for the contact or the total count when $count is TRUE
*/
public static function getContactGroup(
$contactId,
$status = NULL,
$numGroupContact = NULL,
$count = FALSE,
$ignorePermission = FALSE,
$onlyPublicGroups = FALSE,
$excludeHidden = TRUE,
$groupId = NULL,
$includeSmartGroups = FALSE
) {
if ($count) {
$select = 'SELECT count(DISTINCT civicrm_group_contact.id)';
}
else {
$select = 'SELECT
civicrm_group_contact.id as civicrm_group_contact_id,
civicrm_group.title as group_title,
civicrm_group.visibility as visibility,
civicrm_group_contact.status as status,
civicrm_group.id as group_id,
civicrm_group.is_hidden as is_hidden,
civicrm_subscription_history.date as date,
civicrm_subscription_history.method as method';
}
$where = " WHERE contact_a.id = %1 AND civicrm_group.is_active = 1";
if (!$includeSmartGroups) {
$where .= " AND saved_search_id IS NULL";
}
if ($excludeHidden) {
$where .= " AND civicrm_group.is_hidden = 0 ";
}
$params = array(1 => array($contactId, 'Integer'));
if (!empty($status)) {
$where .= ' AND civicrm_group_contact.status = %2';
$params[2] = array($status, 'String');
}
if (!empty($groupId)) {
$where .= " AND civicrm_group.id = %3 ";
$params[3] = array($groupId, 'Integer');
}
$tables = array(
'civicrm_group_contact' => 1,
'civicrm_group' => 1,
'civicrm_subscription_history' => 1,
);
$whereTables = array();
if ($ignorePermission) {
$permission = ' ( 1 ) ';
}
else {
$permission = CRM_Core_Permission::getPermissionedStaticGroupClause(CRM_Core_Permission::VIEW, $tables, $whereTables);
}
$from = CRM_Contact_BAO_Query::fromClause($tables);
$where .= " AND $permission ";
if ($onlyPublicGroups) {
$where .= " AND civicrm_group.visibility != 'User and User Admin Only' ";
}
$order = $limit = '';
if (!$count) {
$order = ' ORDER BY civicrm_group.title, civicrm_subscription_history.date ASC';
if ($numGroupContact) {
$limit = " LIMIT 0, $numGroupContact";
}
}
$sql = $select . $from . $where . $order . $limit;
if ($count) {
$result = CRM_Core_DAO::singleValueQuery($sql, $params);
return $result;
}
else {
$dao = CRM_Core_DAO::executeQuery($sql, $params);
$values = array();
while ($dao->fetch()) {
$id = $dao->civicrm_group_contact_id;
$values[$id]['id'] = $id;
$values[$id]['group_id'] = $dao->group_id;
$values[$id]['title'] = $dao->group_title;
$values[$id]['visibility'] = $dao->visibility;
$values[$id]['is_hidden'] = $dao->is_hidden;
switch ($dao->status) {
case 'Added':
$prefix = 'in_';
break;
case 'Removed':
$prefix = 'out_';
break;
default:
$prefix = 'pending_';
}
$values[$id][$prefix . 'date'] = $dao->date;
$values[$id][$prefix . 'method'] = $dao->method;
if ($status == 'Removed') {
$query = "SELECT `date` as `date_added` FROM civicrm_subscription_history WHERE id = (SELECT max(id) FROM civicrm_subscription_history WHERE contact_id = %1 AND status = \"Added\" AND group_id = $dao->group_id )";
$dateDAO = CRM_Core_DAO::executeQuery($query, $params);
if ($dateDAO->fetch()) {
$values[$id]['date_added'] = $dateDAO->date_added;
}
}
}
return $values;
}
}
/**
* Returns membership details of a contact for a group.
*
* @param int $contactId
* Id of the contact.
* @param int $groupID
* Id of a particular group.
* @param string $method
* If we want the subscription history details for a specific method.
*
* @return object
* of group contact
*/
public static function getMembershipDetail($contactId, $groupID, $method = 'Email') {
$leftJoin = $where = $orderBy = NULL;
if ($method) {
//CRM-13341 add group_id clause
$leftJoin = "
LEFT JOIN civicrm_subscription_history
ON ( civicrm_group_contact.contact_id = civicrm_subscription_history.contact_id
AND civicrm_subscription_history.group_id = {$groupID} )";
$where = "AND civicrm_subscription_history.method ='Email'";
$orderBy = "ORDER BY civicrm_subscription_history.id DESC";
}
$query = "
SELECT *
FROM civicrm_group_contact
$leftJoin
WHERE civicrm_group_contact.contact_id = %1
AND civicrm_group_contact.group_id = %2
$where
$orderBy
";
$params = array(
1 => array($contactId, 'Integer'),
2 => array($groupID, 'Integer'),
);
$dao = CRM_Core_DAO::executeQuery($query, $params);
$dao->fetch();
return $dao;
}
/**
* Method to get Group Id.
*
* @param int $groupContactID
* Id of a particular group.
*
*
* @return groupID
*/
public static function getGroupId($groupContactID) {
$dao = new CRM_Contact_DAO_GroupContact();
$dao->id = $groupContactID;
$dao->find(TRUE);
return $dao->group_id;
}
/**
* Takes an associative array and creates / removes
* contacts from the groups
*
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
* @param array $contactId
* Contact id.
*
* @param bool $visibility
* @param string $method
*/
public static function create(&$params, $contactId, $visibility = FALSE, $method = 'Admin') {
$contactIds = array();
$contactIds[] = $contactId;
//if $visibility is true we are coming in via profile mean $method = 'Web'
$ignorePermission = FALSE;
if ($visibility) {
$ignorePermission = TRUE;
}
if ($contactId) {
$contactGroupList = CRM_Contact_BAO_GroupContact::getContactGroup($contactId, 'Added',
NULL, FALSE, $ignorePermission
);
if (is_array($contactGroupList)) {
foreach ($contactGroupList as $key) {
$groupId = $key['group_id'];
$contactGroup[$groupId] = $groupId;
}
}
}
// get the list of all the groups
$allGroup = CRM_Contact_BAO_GroupContact::getGroupList(0, $visibility);
// this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
if (!is_array($params)) {
$params = array();
}
// this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
if (!isset($contactGroup) || !is_array($contactGroup)) {
$contactGroup = array();
}
// check which values has to be add/remove contact from group
foreach ($allGroup as $key => $varValue) {
if (!empty($params[$key]) && !array_key_exists($key, $contactGroup)) {
// add contact to group
CRM_Contact_BAO_GroupContact::addContactsToGroup($contactIds, $key, $method);
}
elseif (empty($params[$key]) && array_key_exists($key, $contactGroup)) {
// remove contact from group
CRM_Contact_BAO_GroupContact::removeContactsFromGroup($contactIds, $key, $method);
}
}
}
/**
* @param int $contactID
* @param int $groupID
*
* @return bool
*/
public static function isContactInGroup($contactID, $groupID) {
if (!CRM_Utils_Rule::positiveInteger($contactID) ||
!CRM_Utils_Rule::positiveInteger($groupID)
) {
return FALSE;
}
$params = array(
array('group', 'IN', array($groupID), 0, 0),
array('contact_id', '=', $contactID, 0, 0),
);
list($contacts, $_) = CRM_Contact_BAO_Query::apiQuery($params, array('contact_id'));
if (!empty($contacts)) {
return TRUE;
}
return FALSE;
}
/**
* Function merges the groups from otherContactID to mainContactID.
* along with subscription history
*
* @param int $mainContactId
* Contact id of main contact record.
* @param int $otherContactId
* Contact id of record which is going to merge.
*
* @see CRM_Dedupe_Merger::cpTables()
*
* TODO: use the 3rd $sqls param to append sql statements rather than executing them here
*/
public static function mergeGroupContact($mainContactId, $otherContactId) {
$params = array(
1 => array($mainContactId, 'Integer'),
2 => array($otherContactId, 'Integer'),
);
// find all groups that are in otherContactID but not in mainContactID, copy them over
$sql = "
SELECT cOther.group_id
FROM civicrm_group_contact cOther
LEFT JOIN civicrm_group_contact cMain ON cOther.group_id = cMain.group_id AND cMain.contact_id = %1
WHERE cOther.contact_id = %2
AND cMain.contact_id IS NULL
";
$dao = CRM_Core_DAO::executeQuery($sql, $params);
$otherGroupIDs = array();
while ($dao->fetch()) {
$otherGroupIDs[] = $dao->group_id;
}
if (!empty($otherGroupIDs)) {
$otherGroupIDString = implode(',', $otherGroupIDs);
$sql = "
UPDATE civicrm_group_contact
SET contact_id = %1
WHERE contact_id = %2
AND group_id IN ( $otherGroupIDString )
";
CRM_Core_DAO::executeQuery($sql, $params);
$sql = "
UPDATE civicrm_subscription_history
SET contact_id = %1
WHERE contact_id = %2
AND group_id IN ( $otherGroupIDString )
";
CRM_Core_DAO::executeQuery($sql, $params);
}
$sql = "
SELECT cOther.group_id as group_id,
cOther.status as group_status
FROM civicrm_group_contact cMain
INNER JOIN civicrm_group_contact cOther ON cMain.group_id = cOther.group_id
WHERE cMain.contact_id = %1
AND cOther.contact_id = %2
";
$dao = CRM_Core_DAO::executeQuery($sql, $params);
$groupIDs = array();
while ($dao->fetch()) {
// only copy it over if it has added status and migrate the history
if ($dao->group_status == 'Added') {
$groupIDs[] = $dao->group_id;
}
}
if (!empty($groupIDs)) {
$groupIDString = implode(',', $groupIDs);
$sql = "
UPDATE civicrm_group_contact
SET status = 'Added'
WHERE contact_id = %1
AND group_id IN ( $groupIDString )
";
CRM_Core_DAO::executeQuery($sql, $params);
$sql = "
UPDATE civicrm_subscription_history
SET contact_id = %1
WHERE contact_id = %2
AND group_id IN ( $groupIDString )
";
CRM_Core_DAO::executeQuery($sql, $params);
}
// delete all the other group contacts
$sql = "
DELETE
FROM civicrm_group_contact
WHERE contact_id = %2
";
CRM_Core_DAO::executeQuery($sql, $params);
$sql = "
DELETE
FROM civicrm_subscription_history
WHERE contact_id = %2
";
CRM_Core_DAO::executeQuery($sql, $params);
}
/**
* Given an array of contact ids, add all the contacts to the group
*
* @param array $contactIDs
* The array of contact ids to be added.
* @param int $groupID
* The id of the group.
* @param string $method
* @param string $status
* @param NULL $tracking
*
* @return array
* (total, added, notAdded) count of contacts added to group
*/
public static function bulkAddContactsToGroup(
$contactIDs,
$groupID,
$method = 'Admin',
$status = 'Added',
$tracking = NULL
) {
$numContactsAdded = 0;
$numContactsNotAdded = 0;
$contactGroupSQL = "
REPLACE INTO civicrm_group_contact ( group_id, contact_id, status )
VALUES
";
$subscriptioHistorySQL = "
INSERT INTO civicrm_subscription_history( group_id, contact_id, date, method, status, tracking )
VALUES
";
$date = date('YmdHis');
// to avoid long strings, lets do BULK_INSERT_HIGH_COUNT values at a time
while (!empty($contactIDs)) {
$input = array_splice($contactIDs, 0, CRM_Core_DAO::BULK_INSERT_HIGH_COUNT);
$contactStr = implode(',', $input);
// lets check their current status
$sql = "
SELECT GROUP_CONCAT(contact_id) as contactStr
FROM civicrm_group_contact
WHERE group_id = %1
AND status = %2
AND contact_id IN ( $contactStr )
";
$params = array(
1 => array($groupID, 'Integer'),
2 => array($status, 'String'),
);
$presentIDs = array();
$dao = CRM_Core_DAO::executeQuery($sql, $params);
if ($dao->fetch()) {
$presentIDs = explode(',', $dao->contactStr);
$presentIDs = array_flip($presentIDs);
}
$gcValues = $shValues = array();
foreach ($input as $cid) {
if (isset($presentIDs[$cid])) {
$numContactsNotAdded++;
continue;
}
$gcValues[] = "( $groupID, $cid, '$status' )";
$shValues[] = "( $groupID, $cid, '$date', '$method', '$status', '$tracking' )";
$numContactsAdded++;
}
if (!empty($gcValues)) {
$cgSQL = $contactGroupSQL . implode(",\n", $gcValues);
CRM_Core_DAO::executeQuery($cgSQL);
$shSQL = $subscriptioHistorySQL . implode(",\n", $shValues);
CRM_Core_DAO::executeQuery($shSQL);
}
}
return array($numContactsAdded, $numContactsNotAdded);
}
/**
* Get options for a given field.
* @see CRM_Core_DAO::buildOptions
*
* @param string $fieldName
* @param string $context
* @see CRM_Core_DAO::buildOptionsContext
* @param array $props
* whatever is known about this dao object.
*
* @return array|bool
*/
public static function buildOptions($fieldName, $context = NULL, $props = array()) {
$params = array();
$options = CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $params, $context);
// Sort group list by hierarchy
// TODO: This will only work when api.entity is "group_contact". What about others?
if (($fieldName == 'group' || $fieldName == 'group_id') && ($context == 'search' || $context == 'create')) {
$options = CRM_Contact_BAO_Group::getGroupsHierarchy($options, NULL, '- ', TRUE);
}
return $options;
}
}

View file

@ -0,0 +1,766 @@
<?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_BAO_GroupContactCache extends CRM_Contact_DAO_GroupContactCache {
static $_alreadyLoaded = array();
/**
* Get a list of caching modes.
*
* @return array
*/
public static function getModes() {
return array(
// Flush expired caches in response to user actions.
'opportunistic' => ts('Opportunistic Flush'),
// Flush expired caches via background cron jobs.
'deterministic' => ts('Cron Flush'),
);
}
/**
* Check to see if we have cache entries for this group.
*
* If not, regenerate, else return.
*
* @param array $groupIDs
* Of group that we are checking against.
*
* @return bool
* TRUE if we did not regenerate, FALSE if we did
*/
public static function check($groupIDs) {
if (empty($groupIDs)) {
return TRUE;
}
return self::loadAll($groupIDs);
}
/**
* Formulate the query to see which groups needs to be refreshed.
*
* The calculation is based on their cache date and the smartGroupCacheTimeOut
*
* @param string $groupIDClause
* The clause which limits which groups we need to evaluate.
* @param bool $includeHiddenGroups
* Hidden groups are excluded by default.
*
* @return string
* the sql query which lists the groups that need to be refreshed
*/
public static function groupRefreshedClause($groupIDClause = NULL, $includeHiddenGroups = FALSE) {
$smartGroupCacheTimeoutDateTime = self::getCacheInvalidDateTime();
$query = "
SELECT g.id
FROM civicrm_group g
WHERE ( g.saved_search_id IS NOT NULL OR g.children IS NOT NULL )
AND g.is_active = 1
AND (
g.cache_date IS NULL
OR cache_date <= $smartGroupCacheTimeoutDateTime
OR NOW() >= g.refresh_date
)";
if (!$includeHiddenGroups) {
$query .= "AND (g.is_hidden = 0 OR g.is_hidden IS NULL)";
}
if (!empty($groupIDClause)) {
$query .= " AND ( $groupIDClause ) ";
}
return $query;
}
/**
* Check to see if a group has been refreshed recently.
*
* This is primarily used in a locking scenario when some other process might have refreshed things underneath
* this process
*
* @param int $groupID
* The group ID.
* @param bool $includeHiddenGroups
* Hidden groups are excluded by default.
*
* @return string
* the sql query which lists the groups that need to be refreshed
*/
public static function shouldGroupBeRefreshed($groupID, $includeHiddenGroups = FALSE) {
$query = self::groupRefreshedClause("g.id = %1", $includeHiddenGroups);
$params = array(1 => array($groupID, 'Integer'));
// if the query returns the group ID, it means the group is a valid candidate for refreshing
return CRM_Core_DAO::singleValueQuery($query, $params);
}
/**
* Check to see if we have cache entries for this group.
*
* if not, regenerate, else return
*
* @param int|array $groupIDs groupIDs of group that we are checking against
* if empty, all groups are checked
* @param int $limit
* Limits the number of groups we evaluate.
*
* @return bool
* TRUE if we did not regenerate, FALSE if we did
*/
public static function loadAll($groupIDs = NULL, $limit = 0) {
// ensure that all the smart groups are loaded
// this function is expensive and should be sparingly used if groupIDs is empty
if (empty($groupIDs)) {
$groupIDClause = NULL;
$groupIDs = array();
}
else {
if (!is_array($groupIDs)) {
$groupIDs = array($groupIDs);
}
// note escapeString is a must here and we can't send the imploded value as second argument to
// the executeQuery(), since that would put single quote around the string and such a string
// of comma separated integers would not work.
$groupIDString = CRM_Core_DAO::escapeString(implode(', ', $groupIDs));
$groupIDClause = "g.id IN ({$groupIDString})";
}
$query = self::groupRefreshedClause($groupIDClause);
$limitClause = $orderClause = NULL;
if ($limit > 0) {
$limitClause = " LIMIT 0, $limit";
$orderClause = " ORDER BY g.cache_date, g.refresh_date";
}
// We ignore hidden groups and disabled groups
$query .= "
$orderClause
$limitClause
";
$dao = CRM_Core_DAO::executeQuery($query);
$processGroupIDs = array();
$refreshGroupIDs = $groupIDs;
while ($dao->fetch()) {
$processGroupIDs[] = $dao->id;
// remove this id from refreshGroupIDs
foreach ($refreshGroupIDs as $idx => $gid) {
if ($gid == $dao->id) {
unset($refreshGroupIDs[$idx]);
break;
}
}
}
if (!empty($refreshGroupIDs)) {
$refreshGroupIDString = CRM_Core_DAO::escapeString(implode(', ', $refreshGroupIDs));
$time = self::getRefreshDateTime();
$query = "
UPDATE civicrm_group g
SET g.refresh_date = $time
WHERE g.id IN ( {$refreshGroupIDString} )
AND g.refresh_date IS NULL
";
CRM_Core_DAO::executeQuery($query);
}
if (empty($processGroupIDs)) {
return TRUE;
}
else {
self::add($processGroupIDs);
return FALSE;
}
}
/**
* Build the smart group cache for given groups.
*
* @param array $groupIDs
*/
public static function add($groupIDs) {
$groupIDs = (array) $groupIDs;
foreach ($groupIDs as $groupID) {
// first delete the current cache
self::clearGroupContactCache($groupID);
$params = array(array('group', 'IN', array($groupID), 0, 0));
// the below call updates the cache table as a byproduct of the query
CRM_Contact_BAO_Query::apiQuery($params, array('contact_id'), NULL, NULL, 0, 0, FALSE);
}
}
/**
* Store values into the group contact cache.
*
* @todo review use of INSERT IGNORE. This function appears to be slower that inserting
* with a left join. Also, 200 at once seems too little.
*
* @param array $groupID
* @param array $values
*/
public static function store($groupID, &$values) {
$processed = FALSE;
// sort the values so we put group IDs in front and hence optimize
// mysql storage (or so we think) CRM-9493
sort($values);
// to avoid long strings, lets do BULK_INSERT_COUNT values at a time
while (!empty($values)) {
$processed = TRUE;
$input = array_splice($values, 0, CRM_Core_DAO::BULK_INSERT_COUNT);
$str = implode(',', $input);
$sql = "INSERT IGNORE INTO civicrm_group_contact_cache (group_id,contact_id) VALUES $str;";
CRM_Core_DAO::executeQuery($sql);
}
self::updateCacheTime($groupID, $processed);
}
/**
* Change the cache_date.
*
* @param array $groupID
* @param bool $processed
* Whether the cache data was recently modified.
*/
public static function updateCacheTime($groupID, $processed) {
// only update cache entry if we had any values
if ($processed) {
// also update the group with cache date information
$now = date('YmdHis');
$refresh = 'null';
}
else {
$now = 'null';
$refresh = 'null';
}
$groupIDs = implode(',', $groupID);
$sql = "
UPDATE civicrm_group
SET cache_date = $now, refresh_date = $refresh
WHERE id IN ( $groupIDs )
";
CRM_Core_DAO::executeQuery($sql);
}
/**
* @deprecated function - the best function to call is
* CRM_Contact_BAO_Contact::updateContactCache at the moment, or api job.group_cache_flush
* to really force a flush.
*
* Remove this function altogether by mid 2018.
*
* However, if updating code outside core to use this (or any BAO function) it is recommended that
* you add an api call to lock in into our contract. Currently there is not really a supported
* method for non core functions.
*/
public static function remove() {
Civi::log()
->warning('Deprecated code. This function should not be called without groupIDs. Extensions can use the api job.group_cache_flush for a hard flush or add an api option for soft flush', array('civi.tag' => 'deprecated'));
CRM_Contact_BAO_GroupContactCache::opportunisticCacheFlush();
}
/**
* Function to clear group contact cache and reset the corresponding
* group's cache and refresh date
*
* @param int $groupID
*
*/
public static function clearGroupContactCache($groupID) {
$transaction = new CRM_Core_Transaction();
$query = "
DELETE g
FROM civicrm_group_contact_cache g
WHERE g.group_id = %1 ";
$update = "
UPDATE civicrm_group g
SET cache_date = null, refresh_date = null
WHERE id = %1 ";
$params = array(
1 => array($groupID, 'Integer'),
);
CRM_Core_DAO::executeQuery($query, $params);
// also update the cache_date for these groups
CRM_Core_DAO::executeQuery($update, $params);
unset(self::$_alreadyLoaded[$groupID]);
$transaction->commit();
}
/**
* Refresh the smart group cache tables.
*
* This involves clearing out any aged entries (based on the site timeout setting) and resetting the time outs.
*
* This function should be called via the opportunistic or deterministic cache refresh function to make the intent
* clear.
*/
protected static function flushCaches() {
try {
$lock = self::getLockForRefresh();
}
catch (CRM_Core_Exception $e) {
// Someone else is kindly doing the refresh for us right now.
return;
}
$params = array(1 => array(self::getCacheInvalidDateTime(), 'String'));
// @todo this is consistent with previous behaviour but as the first query could take several seconds the second
// could become inaccurate. It seems to make more sense to fetch them first & delete from an array (which would
// also reduce joins). If we do this we should also consider how best to iterate the groups. If we do them one at
// a time we could call a hook, allowing people to manage the frequency on their groups, or possibly custom searches
// might do that too. However, for 2000 groups that's 2000 iterations. If we do all once we potentially create a
// slow query. It's worth noting the speed issue generally relates to the size of the group but if one slow group
// is in a query with 500 fast ones all 500 get locked. One approach might be to calculate group size or the
// number of groups & then process all at once or many query runs depending on what is found. Of course those
// preliminary queries would need speed testing.
CRM_Core_DAO::executeQuery(
"
DELETE gc
FROM civicrm_group_contact_cache gc
INNER JOIN civicrm_group g ON g.id = gc.group_id
WHERE g.cache_date <= %1
",
$params
);
// Clear these out without resetting them because we are not building caches here, only clearing them,
// so the state is 'as if they had never been built'.
CRM_Core_DAO::executeQuery(
"
UPDATE civicrm_group g
SET cache_date = NULL,
refresh_date = NULL
WHERE g.cache_date <= %1
",
$params
);
$lock->release();
}
/**
* Check if the refresh is already initiated.
*
* We have 2 imperfect methods for this:
* 1) a static variable in the function. This works fine within a request
* 2) a mysql lock. This works fine as long as CiviMail is not running, or if mysql is version 5.7+
*
* Where these 2 locks fail we get 2 processes running at the same time, but we have at least minimised that.
*
* @return \Civi\Core\Lock\LockInterface
* @throws \CRM_Core_Exception
*/
protected static function getLockForRefresh() {
if (!isset(Civi::$statics[__CLASS__]['is_refresh_init'])) {
Civi::$statics[__CLASS__] = array('is_refresh_init' => FALSE);
}
if (Civi::$statics[__CLASS__]['is_refresh_init']) {
throw new CRM_Core_Exception('A refresh has already run in this process');
}
$lock = Civi::lockManager()->acquire('data.core.group.refresh');
if ($lock->isAcquired()) {
Civi::$statics[__CLASS__]['is_refresh_init'] = TRUE;
return $lock;
}
throw new CRM_Core_Exception('Mysql lock unavailable');
}
/**
* Do an opportunistic cache refresh if the site is configured for these.
*
* Sites that do not run the smart group clearing cron job should refresh the
* caches on demand. The user session will be forced to wait so it is less
* ideal.
*/
public static function opportunisticCacheFlush() {
if (Civi::settings()->get('smart_group_cache_refresh_mode') == 'opportunistic') {
self::flushCaches();
}
}
/**
* Do a forced cache refresh.
*
* This function is appropriate to be called by system jobs & non-user sessions.
*/
public static function deterministicCacheFlush() {
if (self::smartGroupCacheTimeout() == 0) {
CRM_Core_DAO::executeQuery("TRUNCATE civicrm_group_contact_cache");
CRM_Core_DAO::executeQuery("
UPDATE civicrm_group g
SET cache_date = null, refresh_date = null");
}
else {
self::flushCaches();
}
}
/**
* Remove one or more contacts from the smart group cache.
*
* @param int|array $cid
* @param int $groupId
*
* @return bool
* TRUE if successful.
*/
public static function removeContact($cid, $groupId = NULL) {
$cids = array();
// sanitize input
foreach ((array) $cid as $c) {
$cids[] = CRM_Utils_Type::escape($c, 'Integer');
}
if ($cids) {
$condition = count($cids) == 1 ? "= {$cids[0]}" : "IN (" . implode(',', $cids) . ")";
if ($groupId) {
$condition .= " AND group_id = " . CRM_Utils_Type::escape($groupId, 'Integer');
}
$sql = "DELETE FROM civicrm_group_contact_cache WHERE contact_id $condition";
CRM_Core_DAO::executeQuery($sql);
return TRUE;
}
return FALSE;
}
/**
* Load the smart group cache for a saved search.
*
* @param object $group
* The smart group that needs to be loaded.
* @param bool $force
* Should we force a search through.
*/
public static function load(&$group, $force = FALSE) {
$groupID = $group->id;
$savedSearchID = $group->saved_search_id;
if (array_key_exists($groupID, self::$_alreadyLoaded) && !$force) {
return;
}
// grab a lock so other processes don't compete and do the same query
$lock = Civi::lockManager()->acquire("data.core.group.{$groupID}");
if (!$lock->isAcquired()) {
// this can cause inconsistent results since we don't know if the other process
// will fill up the cache before our calling routine needs it.
// however this routine does not return the status either, so basically
// its a "lets return and hope for the best"
return;
}
self::$_alreadyLoaded[$groupID] = 1;
// we now have the lock, but some other process could have actually done the work
// before we got here, so before we do any work, lets ensure that work needs to be
// done
// we allow hidden groups here since we dont know if the caller wants to evaluate an
// hidden group
if (!$force && !self::shouldGroupBeRefreshed($groupID, TRUE)) {
$lock->release();
return;
}
$sql = NULL;
$idName = 'id';
$customClass = NULL;
if ($savedSearchID) {
$ssParams = CRM_Contact_BAO_SavedSearch::getSearchParams($savedSearchID);
// rectify params to what proximity search expects if there is a value for prox_distance
// CRM-7021
if (!empty($ssParams)) {
CRM_Contact_BAO_ProximityQuery::fixInputParams($ssParams);
}
$returnProperties = array();
if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $savedSearchID, 'mapping_id')) {
$fv = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID);
$returnProperties = CRM_Core_BAO_Mapping::returnProperties($fv);
}
if (isset($ssParams['customSearchID'])) {
// if custom search
// we split it up and store custom class
// so temp tables are not destroyed if they are used
// hence customClass is defined above at top of function
$customClass = CRM_Contact_BAO_SearchCustom::customClass($ssParams['customSearchID'], $savedSearchID);
$searchSQL = $customClass->contactIDs();
$searchSQL = str_replace('ORDER BY contact_a.id ASC', '', $searchSQL);
if (!strstr($searchSQL, 'WHERE')) {
$searchSQL .= " WHERE ( 1 ) ";
}
$idName = 'contact_id';
}
else {
$formValues = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID);
// CRM-17075 using the formValues in this way imposes extra logic and complexity.
// we have the where_clause and where tables stored in the saved_search table
// and should use these rather than re-processing the form criteria (which over-works
// the link between the form layer & the query layer too).
// It's hard to think of when you would want to use anything other than return
// properties = array('contact_id' => 1) here as the point would appear to be to
// generate the list of contact ids in the group.
// @todo review this to use values in saved_search table (preferably for 4.8).
$query
= new CRM_Contact_BAO_Query(
$ssParams, $returnProperties, NULL,
FALSE, FALSE, 1,
TRUE, TRUE,
FALSE,
CRM_Utils_Array::value('display_relationship_type', $formValues),
CRM_Utils_Array::value('operator', $formValues, 'AND')
);
$query->_useDistinct = FALSE;
$query->_useGroupBy = FALSE;
$searchSQL
= $query->searchQuery(
0, 0, NULL,
FALSE, FALSE,
FALSE, TRUE,
TRUE,
NULL, NULL, NULL,
TRUE
);
}
$groupID = CRM_Utils_Type::escape($groupID, 'Integer');
$sql = $searchSQL . " AND contact_a.id NOT IN (
SELECT contact_id FROM civicrm_group_contact
WHERE civicrm_group_contact.status = 'Removed'
AND civicrm_group_contact.group_id = $groupID ) ";
}
if ($sql) {
$sql = preg_replace("/^\s*SELECT/", "SELECT $groupID as group_id, ", $sql);
}
// lets also store the records that are explicitly added to the group
// this allows us to skip the group contact LEFT JOIN
$sqlB = "
SELECT $groupID as group_id, contact_id as $idName
FROM civicrm_group_contact
WHERE civicrm_group_contact.status = 'Added'
AND civicrm_group_contact.group_id = $groupID ";
self::clearGroupContactCache($groupID);
$processed = FALSE;
$tempTable = 'civicrm_temp_group_contact_cache' . rand(0, 2000);
foreach (array($sql, $sqlB) as $selectSql) {
if (!$selectSql) {
continue;
}
$insertSql = "CREATE TEMPORARY TABLE $tempTable ($selectSql);";
$processed = TRUE;
CRM_Core_DAO::executeQuery($insertSql);
CRM_Core_DAO::executeQuery(
"INSERT IGNORE INTO civicrm_group_contact_cache (contact_id, group_id)
SELECT DISTINCT $idName, group_id FROM $tempTable
");
CRM_Core_DAO::executeQuery(" DROP TEMPORARY TABLE $tempTable");
}
self::updateCacheTime(array($groupID), $processed);
if ($group->children) {
//Store a list of contacts who are removed from the parent group
$sql = "
SELECT contact_id
FROM civicrm_group_contact
WHERE civicrm_group_contact.status = 'Removed'
AND civicrm_group_contact.group_id = $groupID ";
$dao = CRM_Core_DAO::executeQuery($sql);
$removed_contacts = array();
while ($dao->fetch()) {
$removed_contacts[] = $dao->contact_id;
}
$childrenIDs = explode(',', $group->children);
foreach ($childrenIDs as $childID) {
$contactIDs = CRM_Contact_BAO_Group::getMember($childID, FALSE);
//Unset each contact that is removed from the parent group
foreach ($removed_contacts as $removed_contact) {
unset($contactIDs[$removed_contact]);
}
$values = array();
foreach ($contactIDs as $contactID => $dontCare) {
$values[] = "({$groupID},{$contactID})";
}
self::store(array($groupID), $values);
}
}
$lock->release();
}
/**
* Retrieve the smart group cache timeout in minutes.
*
* This checks if a timeout has been configured. If one has then smart groups should not
* be refreshed more frequently than the time out. If a group was recently refreshed it should not
* refresh again within that period.
*
* @return int
*/
public static function smartGroupCacheTimeout() {
$config = CRM_Core_Config::singleton();
if (
isset($config->smartGroupCacheTimeout) &&
is_numeric($config->smartGroupCacheTimeout)
) {
return $config->smartGroupCacheTimeout;
}
// Default to 5 minutes.
return 5;
}
/**
* Get all the smart groups that this contact belongs to.
*
* Note that this could potentially be a super slow function since
* it ensure that all contact groups are loaded in the cache
*
* @param int $contactID
* @param bool $showHidden
* Hidden groups are shown only if this flag is set.
*
* @return array
* an array of groups that this contact belongs to
*/
public static function contactGroup($contactID, $showHidden = FALSE) {
if (empty($contactID)) {
return NULL;
}
if (is_array($contactID)) {
$contactIDs = $contactID;
}
else {
$contactIDs = array($contactID);
}
self::loadAll();
$hiddenClause = '';
if (!$showHidden) {
$hiddenClause = ' AND (g.is_hidden = 0 OR g.is_hidden IS NULL) ';
}
$contactIDString = CRM_Core_DAO::escapeString(implode(', ', $contactIDs));
$sql = "
SELECT gc.group_id, gc.contact_id, g.title, g.children, g.description
FROM civicrm_group_contact_cache gc
INNER JOIN civicrm_group g ON g.id = gc.group_id
WHERE gc.contact_id IN ($contactIDString)
$hiddenClause
ORDER BY gc.contact_id, g.children
";
$dao = CRM_Core_DAO::executeQuery($sql);
$contactGroup = array();
$prevContactID = NULL;
while ($dao->fetch()) {
if (
$prevContactID &&
$prevContactID != $dao->contact_id
) {
$contactGroup[$prevContactID]['groupTitle'] = implode(', ', $contactGroup[$prevContactID]['groupTitle']);
}
$prevContactID = $dao->contact_id;
if (!array_key_exists($dao->contact_id, $contactGroup)) {
$contactGroup[$dao->contact_id]
= array('group' => array(), 'groupTitle' => array());
}
$contactGroup[$dao->contact_id]['group'][]
= array(
'id' => $dao->group_id,
'title' => $dao->title,
'description' => $dao->description,
'children' => $dao->children,
);
$contactGroup[$dao->contact_id]['groupTitle'][] = $dao->title;
}
if ($prevContactID) {
$contactGroup[$prevContactID]['groupTitle'] = implode(', ', $contactGroup[$prevContactID]['groupTitle']);
}
if ((!empty($contactGroup[$contactID]) && is_numeric($contactID))) {
return $contactGroup[$contactID];
}
else {
return $contactGroup;
}
}
/**
* Get the datetime from which the cache should be considered invalid.
*
* Ie if the smartgroup cache timeout is 5 minutes ago then the cache is invalid if it was
* refreshed 6 minutes ago, but not if it was refreshed 4 minutes ago.
*
* @return string
*/
public static function getCacheInvalidDateTime() {
return date('YmdHis', strtotime("-" . self::smartGroupCacheTimeout() . " Minutes"));
}
/**
* Get the date when the cache should be refreshed from.
*
* Ie. now + the offset & we will delete anything prior to then.
*
* @return string
*/
public static function getRefreshDateTime() {
return date('YmdHis', strtotime("+ " . self::smartGroupCacheTimeout() . " Minutes"));
}
}

View file

@ -0,0 +1,198 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright U.S. PIRG Education Fund (c) 2007 |
| Licensed to CiviCRM under the Academic Free License version 3.0. |
+--------------------------------------------------------------------+
| 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 U.S. PIRG 2007
*/
class CRM_Contact_BAO_GroupNesting extends CRM_Contact_DAO_GroupNesting {
/**
* Adds a new group nesting record.
*
* @param int $parentID
* Id of the group to add the child to.
* @param int $childID
* Id of the new child group.
*
* @return \CRM_Contact_DAO_GroupNesting
*/
public static function add($parentID, $childID) {
$dao = new CRM_Contact_DAO_GroupNesting();
$dao->child_group_id = $childID;
$dao->parent_group_id = $parentID;
if (!$dao->find(TRUE)) {
$dao->save();
}
return $dao;
}
/**
* Removes a child group from it's parent.
*
* Does not delete child group, just the association between the two
*
* @param int $parentID
* The id of the group to remove the child from.
* @param int $childID
* The id of the child group being removed.
*/
public static function remove($parentID, $childID) {
$dao = new CRM_Contact_DAO_GroupNesting();
$dao->child_group_id = $childID;
$dao->parent_group_id = $parentID;
if ($dao->find(TRUE)) {
$dao->delete();
}
}
/**
* Checks whether the association between parent and child is present.
*
* @param int $parentID
* The parent id of the association.
*
* @param int $childID
* The child id of the association.
*
* @return bool
* True if association is found, false otherwise.
*/
public static function isParentChild($parentID, $childID) {
$dao = new CRM_Contact_DAO_GroupNesting();
$dao->child_group_id = $childID;
$dao->parent_group_id = $parentID;
if ($dao->find()) {
return TRUE;
}
return FALSE;
}
/**
* Checks whether groupId has 1 or more parent groups.
*
* @param int $groupId
* The id of the group to check for parent groups.
*
* @return bool
* True if 1 or more parent groups are found, false otherwise.
*/
public static function hasParentGroups($groupId) {
$dao = new CRM_Contact_DAO_GroupNesting();
$query = "SELECT parent_group_id FROM civicrm_group_nesting WHERE child_group_id = $groupId LIMIT 1";
$dao->query($query);
if ($dao->fetch()) {
return TRUE;
}
return FALSE;
}
/**
* Returns array of group ids of child groups of the specified group.
*
* @param array $groupIds
* An array of valid group ids (passed by reference).
*
* @return array
* List of groupIds that represent the requested group and its children
*/
public static function getChildGroupIds($groupIds) {
if (!is_array($groupIds)) {
$groupIds = array($groupIds);
}
$dao = new CRM_Contact_DAO_GroupNesting();
$query = "SELECT child_group_id FROM civicrm_group_nesting WHERE parent_group_id IN (" . implode(',', $groupIds) . ")";
$dao->query($query);
$childGroupIds = array();
while ($dao->fetch()) {
$childGroupIds[] = $dao->child_group_id;
}
return $childGroupIds;
}
/**
* Returns array of group ids of parent groups of the specified group.
*
* @param array $groupIds
* An array of valid group ids (passed by reference).
*
* @return array
* List of groupIds that represent the requested group and its parents
*/
public static function getParentGroupIds($groupIds) {
if (!is_array($groupIds)) {
$groupIds = array($groupIds);
}
$dao = new CRM_Contact_DAO_GroupNesting();
$query = "SELECT parent_group_id FROM civicrm_group_nesting WHERE child_group_id IN (" . implode(',', $groupIds) . ")";
$dao->query($query);
$parentGroupIds = array();
while ($dao->fetch()) {
$parentGroupIds[] = $dao->parent_group_id;
}
return $parentGroupIds;
}
/**
* Returns array of group ids of descendent groups of the specified group.
*
* @param array $groupIds
* An array of valid group ids (passed by reference).
*
* @param bool $includeSelf
*
* @return array
* List of groupIds that represent the requested group and its descendents
*/
public static function getDescendentGroupIds($groupIds, $includeSelf = TRUE) {
if (!is_array($groupIds)) {
$groupIds = array($groupIds);
}
$dao = new CRM_Contact_DAO_GroupNesting();
$query = "SELECT child_group_id, parent_group_id FROM civicrm_group_nesting WHERE parent_group_id IN (" . implode(',', $groupIds) . ")";
$dao->query($query);
$tmpGroupIds = array();
$childGroupIds = array();
if ($includeSelf) {
$childGroupIds = $groupIds;
}
while ($dao->fetch()) {
// make sure we're not following any cyclical references
if (!array_key_exists($dao->parent_group_id, $childGroupIds) && $dao->child_group_id != $groupIds[0]) {
$tmpGroupIds[] = $dao->child_group_id;
}
}
if (!empty($tmpGroupIds)) {
$newChildGroupIds = self::getDescendentGroupIds($tmpGroupIds);
$childGroupIds = array_merge($childGroupIds, $newChildGroupIds);
}
return $childGroupIds;
}
}

View file

@ -0,0 +1,268 @@
<?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_BAO_GroupNestingCache {
/**
* Update cache.
*
* @throws \Exception
*/
static public function update() {
// lets build the tree in memory first
$sql = "
SELECT n.child_group_id as child ,
n.parent_group_id as parent
FROM civicrm_group_nesting n,
civicrm_group gc,
civicrm_group gp
WHERE n.child_group_id = gc.id
AND n.parent_group_id = gp.id
";
$dao = CRM_Core_DAO::executeQuery($sql);
$tree = array();
while ($dao->fetch()) {
if (!array_key_exists($dao->child, $tree)) {
$tree[$dao->child] = array(
'children' => array(),
'parents' => array(),
);
}
if (!array_key_exists($dao->parent, $tree)) {
$tree[$dao->parent] = array(
'children' => array(),
'parents' => array(),
);
}
$tree[$dao->child]['parents'][] = $dao->parent;
$tree[$dao->parent]['children'][] = $dao->child;
}
if (self::checkCyclicGraph($tree)) {
CRM_Core_Error::fatal(ts("We detected a cycle which we can't handle. aborting"));
}
// first reset the current cache entries
$sql = "
UPDATE civicrm_group
SET parents = null,
children = null
";
CRM_Core_DAO::executeQuery($sql);
$values = array();
foreach (array_keys($tree) as $id) {
$parents = implode(',', $tree[$id]['parents']);
$children = implode(',', $tree[$id]['children']);
$parents = $parents == NULL ? 'null' : "'$parents'";
$children = $children == NULL ? 'null' : "'$children'";
$sql = "
UPDATE civicrm_group
SET parents = $parents ,
children = $children
WHERE id = $id
";
CRM_Core_DAO::executeQuery($sql);
}
// this tree stuff is quite useful, so lets store it in the cache
CRM_Core_BAO_Cache::setItem($tree, 'contact groups', 'nestable tree hierarchy');
}
/**
* @param $tree
*
* @return bool
*/
public static function checkCyclicGraph(&$tree) {
// lets keep this simple, we should probably use a graph algorithm here at some stage
// foreach group that has a parent or a child, ensure that
// the ancestors and descendants dont intersect
foreach ($tree as $id => $dontCare) {
if (self::isCyclic($tree, $id)) {
return TRUE;
}
}
return FALSE;
}
/**
* @param $tree
* @param int $id
*
* @return bool
*/
public static function isCyclic(&$tree, $id) {
$parents = $children = array();
self::getAll($parent, $tree, $id, 'parents');
self::getAll($child, $tree, $id, 'children');
$one = array_intersect($parents, $children);
$two = array_intersect($children, $parents);
if (!empty($one) ||
!empty($two)
) {
CRM_Core_Error::debug($id, $tree);
CRM_Core_Error::debug($id, $one);
CRM_Core_Error::debug($id, $two);
return TRUE;
}
return FALSE;
}
/**
* @param int $id
* @param $groups
*
* @return array
*/
public static function getPotentialCandidates($id, &$groups) {
$tree = CRM_Core_BAO_Cache::getItem('contact groups', 'nestable tree hierarchy');
if ($tree === NULL) {
self::update();
$tree = CRM_Core_BAO_Cache::getItem('contact groups', 'nestable tree hierarchy');
}
$potential = $groups;
// remove all descendants
self::invalidate($potential, $tree, $id, 'children');
// remove all ancestors
self::invalidate($potential, $tree, $id, 'parents');
return array_keys($potential);
}
/**
* @param $potential
* @param $tree
* @param int $id
* @param $token
*/
public static function invalidate(&$potential, &$tree, $id, $token) {
unset($potential[$id]);
if (!isset($tree[$id]) ||
empty($tree[$id][$token])
) {
return;
}
foreach ($tree[$id][$token] as $tokenID) {
self::invalidate($potential, $tree, $tokenID, $token);
}
}
/**
* @param $all
* @param $tree
* @param int $id
* @param $token
*/
public static function getAll(&$all, &$tree, $id, $token) {
// if seen before, dont do anything
if (isset($all[$id])) {
return;
}
$all[$id] = 1;
if (!isset($tree[$id]) ||
empty($tree[$id][$token])
) {
return;
}
foreach ($tree[$id][$token] as $tokenID) {
self::getAll($all, $tree, $tokenID, $token);
}
}
/**
* @return string
*/
public static function json() {
$tree = CRM_Core_BAO_Cache::getItem('contact groups', 'nestable tree hierarchy');
if ($tree === NULL) {
self::update();
$tree = CRM_Core_BAO_Cache::getItem('contact groups', 'nestable tree hierarchy');
}
// get all the groups
$groups = CRM_Core_PseudoConstant::group();
foreach ($groups as $id => $name) {
$string = "id:'$id', name:'$name'";
if (isset($tree[$id])) {
$children = array();
if (!empty($tree[$id]['children'])) {
foreach ($tree[$id]['children'] as $child) {
$children[] = "{_reference:'$child'}";
}
$children = implode(',', $children);
$string .= ", children:[$children]";
if (empty($tree[$id]['parents'])) {
$string .= ", type:'rootGroup'";
}
else {
$string .= ", type:'middleGroup'";
}
}
else {
$string .= ", type:'leafGroup'";
}
}
else {
$string .= ", children:[], type:'rootGroup'";
}
$values[] = "{ $string }";
}
$items = implode(",\n", $values);
$json = "{
identifier:'id',
label:'name',
items:[ $items ]
}";
return $json;
}
}

View file

@ -0,0 +1,153 @@
<?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_BAO_GroupOrganization extends CRM_Contact_DAO_GroupOrganization {
/**
* Class constructor.
*/
public function __construct() {
parent::__construct();
}
/**
* Takes an associative array and creates a groupOrganization object.
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
*
* @return CRM_Contact_DAO_GroupOrganization
*/
public static function add(&$params) {
$formattedValues = array();
self::formatValues($params, $formattedValues);
$dataExists = self::dataExists($formattedValues);
if (!$dataExists) {
return NULL;
}
$groupOrganization = new CRM_Contact_DAO_GroupOrganization();
$groupOrganization->copyValues($formattedValues);
// we have ensured we have group_id & organization_id so we can do a find knowing that
// this can only find a matching record
$groupOrganization->find(TRUE);
$groupOrganization->save();
return $groupOrganization;
}
/**
* Format the params.
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
* @param array $formatedValues
* (reference ) an assoc array of name/value pairs.
*/
public static function formatValues(&$params, &$formatedValues) {
if (!empty($params['group_organization'])) {
$formatedValues['id'] = $params['group_organization'];
}
if (!empty($params['group_id'])) {
$formatedValues['group_id'] = $params['group_id'];
}
if (!empty($params['organization_id'])) {
$formatedValues['organization_id'] = $params['organization_id'];
}
}
/**
* Check if there is data to create the object.
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
*
* @return bool
*/
public static function dataExists($params) {
// return if no data present
if (!empty($params['organization_id']) && !empty($params['group_id'])) {
return TRUE;
}
return FALSE;
}
/**
* @param int $groupID
* @param $defaults
*/
public static function retrieve($groupID, &$defaults) {
$dao = new CRM_Contact_DAO_GroupOrganization();
$dao->group_id = $groupID;
if ($dao->find(TRUE)) {
$defaults['group_organization'] = $dao->id;
$defaults['organization_id'] = $dao->organization_id;
}
}
/**
* Method to check group organization relationship exist.
*
* @param int $contactID
*
* @return bool
*/
public static function hasGroupAssociated($contactID) {
$orgID = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_GroupOrganization',
$contactID, 'group_id', 'organization_id'
);
if ($orgID) {
return TRUE;
}
return FALSE;
}
/**
* Delete Group Organization.
*
* @param int $groupOrganizationID
* Group organization id that needs to be deleted.
*
* @return int|null
* no of deleted group organization on success, false otherwise
*/
public static function deleteGroupOrganization($groupOrganizationID) {
$results = NULL;
$groupOrganization = new CRM_Contact_DAO_GroupOrganization();
$groupOrganization->id = $groupOrganizationID;
$results = $groupOrganization->delete();
return $results;
}
}

View file

@ -0,0 +1,72 @@
<?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_BAO_Household extends CRM_Contact_DAO_Contact {
/**
* Class constructor.
*/
public function __construct() {
parent::__construct();
}
/**
* Update the household with primary contact id.
*
* @param int $primaryContactId
* Null if deleting primary contact.
* @param int $contactId
* Contact id.
*
* @return Object
* DAO object on success
*/
public static function updatePrimaryContact($primaryContactId, $contactId) {
$queryString = "UPDATE civicrm_contact
SET primary_contact_id = ";
$params = array();
if ($primaryContactId) {
$queryString .= '%1';
$params[1] = array($primaryContactId, 'Integer');
}
else {
$queryString .= "null";
}
$queryString .= " WHERE id = %2";
$params[2] = array($contactId, 'Integer');
return CRM_Core_DAO::executeQuery($queryString, $params);
}
}

View file

@ -0,0 +1,421 @@
<?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 contains functions for individual contact type.
*/
class CRM_Contact_BAO_Individual extends CRM_Contact_DAO_Contact {
/**
* Class constructor.
*/
public function __construct() {
}
/**
* Function is used to format the individual contact values.
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
* @param CRM $contact
* Contact object.
*
* @return CRM_Contact_BAO_Contact
*/
public static function format(&$params, &$contact) {
if (!self::dataExists($params)) {
return NULL;
}
// "null" value for example is passed by dedupe merge in order to empty.
// Display name computation shouldn't consider such values.
foreach (array('first_name', 'middle_name', 'last_name', 'nick_name', 'formal_title', 'birth_date', 'deceased_date') as $displayField) {
if (CRM_Utils_Array::value($displayField, $params) == "null") {
$params[$displayField] = '';
}
}
$sortName = $displayName = '';
$firstName = CRM_Utils_Array::value('first_name', $params, '');
$middleName = CRM_Utils_Array::value('middle_name', $params, '');
$lastName = CRM_Utils_Array::value('last_name', $params, '');
$nickName = CRM_Utils_Array::value('nick_name', $params, '');
$prefix_id = CRM_Utils_Array::value('prefix_id', $params, '');
$suffix_id = CRM_Utils_Array::value('suffix_id', $params, '');
$formalTitle = CRM_Utils_Array::value('formal_title', $params, '');
// get prefix and suffix names
$prefix = $suffix = NULL;
if ($prefix_id) {
$params['individual_prefix'] = $prefix = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', 'prefix_id', $prefix_id);
}
if ($suffix_id) {
$params['individual_suffix'] = $suffix = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', 'suffix_id', $suffix_id);
}
$params['is_deceased'] = CRM_Utils_Array::value('is_deceased', $params, FALSE);
$individual = NULL;
if ($contact->id) {
$individual = new CRM_Contact_BAO_Contact();
$individual->id = $contact->id;
if ($individual->find(TRUE)) {
//lets allow to update single name field though preserveDBName
//but if db having null value and params contain value, CRM-4330.
$useDBNames = array();
foreach (array('last', 'middle', 'first', 'nick') as $name) {
$dbName = "{$name}_name";
$value = $individual->$dbName;
// the db has name values
if ($value && !empty($params['preserveDBName'])) {
$useDBNames[] = $name;
}
}
foreach (array('prefix', 'suffix') as $name) {
$dbName = "{$name}_id";
$value = $individual->$dbName;
if ($value && !empty($params['preserveDBName'])) {
$useDBNames[] = $name;
}
}
if ($individual->formal_title && !empty($params['preserveDBName'])) {
$useDBNames[] = 'formal_title';
}
// CRM-4430
//1. preserve db name if want
//2. lets get value from param if exists.
//3. if not in params, lets get from db.
foreach (array('last', 'middle', 'first', 'nick') as $name) {
$phpName = "{$name}Name";
$dbName = "{$name}_name";
$value = $individual->$dbName;
if (in_array($name, $useDBNames)) {
$params[$dbName] = $value;
$contact->$dbName = $value;
$$phpName = $value;
}
elseif (array_key_exists($dbName, $params)) {
$$phpName = $params[$dbName];
}
elseif ($value) {
$$phpName = $value;
}
}
foreach (array('prefix', 'suffix') as $name) {
$dbName = "{$name}_id";
$value = $individual->$dbName;
if (in_array($name, $useDBNames)) {
$params[$dbName] = $value;
$contact->$dbName = $value;
if ($value) {
$$name = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', $dbName, $value);
}
else {
$$name = NULL;
}
}
elseif (array_key_exists($dbName, $params)) {
// CRM-5278
if (!empty($params[$dbName])) {
$$name = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', $dbName, $params[$dbName]);
}
}
elseif ($value) {
$$name = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', $dbName, $value);
}
}
if (in_array('formal_title', $useDBNames)) {
$params['formal_title'] = $individual->formal_title;
$contact->formal_title = $individual->formal_title;
$formalTitle = $individual->formal_title;
}
elseif (array_key_exists('formal_title', $params)) {
$formalTitle = $params['formal_title'];
}
elseif ($individual->formal_title) {
$formalTitle = $individual->formal_title;
}
}
}
//first trim before further processing.
foreach (array('lastName', 'firstName', 'middleName') as $fld) {
$$fld = trim($$fld);
}
if ($lastName || $firstName || $middleName) {
// make sure we have values for all the name fields.
$formatted = $params;
$nameParams = array(
'first_name' => $firstName,
'middle_name' => $middleName,
'last_name' => $lastName,
'nick_name' => $nickName,
'individual_suffix' => $suffix,
'individual_prefix' => $prefix,
'prefix_id' => $prefix_id,
'suffix_id' => $suffix_id,
'formal_title' => $formalTitle,
);
// make sure we have all the name fields.
foreach ($nameParams as $name => $value) {
if (empty($formatted[$name]) && $value) {
$formatted[$name] = $value;
}
}
$tokens = array();
CRM_Utils_Hook::tokens($tokens);
$tokenFields = array();
foreach ($tokens as $catTokens) {
foreach ($catTokens as $token => $label) {
$tokenFields[] = $token;
}
}
//build the sort name.
$format = Civi::settings()->get('sort_name_format');
$sortName = CRM_Utils_Address::format($formatted, $format,
FALSE, FALSE, TRUE, $tokenFields
);
$sortName = trim($sortName);
//build the display name.
$format = Civi::settings()->get('display_name_format');
$displayName = CRM_Utils_Address::format($formatted, $format,
FALSE, FALSE, TRUE, $tokenFields
);
$displayName = trim($displayName);
}
//start further check for email.
if (empty($sortName) || empty($displayName)) {
$email = NULL;
if (!empty($params['email']) &&
is_array($params['email'])
) {
foreach ($params['email'] as $emailBlock) {
if (isset($emailBlock['is_primary'])) {
$email = $emailBlock['email'];
break;
}
}
}
$uniqId = CRM_Utils_Array::value('user_unique_id', $params);
if (!$email && $contact->id) {
$email = CRM_Contact_BAO_Contact::getPrimaryEmail($contact->id);
}
}
//now set the names.
$names = array('displayName' => 'display_name', 'sortName' => 'sort_name');
foreach ($names as $value => $name) {
if (empty($$value)) {
if ($email) {
$$value = $email;
}
elseif ($uniqId) {
$$value = $uniqId;
}
elseif (!empty($params[$name])) {
$$value = $params[$name];
}
// If we have nothing else going on set sort_name to display_name.
elseif ($displayName) {
$$value = $displayName;
}
}
//finally if we could not pass anything lets keep db.
if (!empty($$value)) {
$contact->$name = $$value;
}
}
$format = CRM_Utils_Date::getDateFormat('birth');
if ($date = CRM_Utils_Array::value('birth_date', $params)) {
if (in_array($format, array(
'dd-mm',
'mm/dd',
))) {
$separator = '/';
if ($format == 'dd-mm') {
$separator = '-';
}
$date = $date . $separator . '1902';
}
elseif (in_array($format, array(
'yy-mm',
))) {
$date = $date . '-01';
}
elseif (in_array($format, array(
'M yy',
))) {
$date = $date . '-01';
}
elseif (in_array($format, array(
'yy',
))) {
$date = $date . '-01-01';
}
$contact->birth_date = CRM_Utils_Date::processDate($date);
}
elseif ($contact->birth_date) {
$contact->birth_date = CRM_Utils_Date::isoToMysql($contact->birth_date);
}
if ($date = CRM_Utils_Array::value('deceased_date', $params)) {
if (in_array($format, array(
'dd-mm',
'mm/dd',
))) {
$separator = '/';
if ($format == 'dd-mm') {
$separator = '-';
}
$date = $date . $separator . '1902';
}
elseif (in_array($format, array(
'yy-mm',
))) {
$date = $date . '-01';
}
elseif (in_array($format, array(
'M yy',
))) {
$date = $date . '-01';
}
elseif (in_array($format, array(
'yy',
))) {
$date = $date . '-01-01';
}
$contact->deceased_date = CRM_Utils_Date::processDate($date);
}
elseif ($contact->deceased_date) {
$contact->deceased_date = CRM_Utils_Date::isoToMysql($contact->deceased_date);
}
if ($middle_name = CRM_Utils_Array::value('middle_name', $params)) {
$contact->middle_name = $middle_name;
}
return $contact;
}
/**
* Regenerates display_name for contacts with given prefixes/suffixes.
*
* @param array $ids
* The array with the prefix/suffix id governing which contacts to regenerate.
* @param int $action
* The action describing whether prefix/suffix was UPDATED or DELETED.
*/
public static function updateDisplayNames(&$ids, $action) {
// get the proper field name (prefix_id or suffix_id) and its value
$fieldName = '';
foreach ($ids as $key => $value) {
switch ($key) {
case 'individualPrefix':
$fieldName = 'prefix_id';
$fieldValue = $value;
break 2;
case 'individualSuffix':
$fieldName = 'suffix_id';
$fieldValue = $value;
break 2;
}
}
if ($fieldName == '') {
return;
}
// query for the affected individuals
$fieldValue = CRM_Utils_Type::escape($fieldValue, 'Integer');
$contact = new CRM_Contact_BAO_Contact();
$contact->$fieldName = $fieldValue;
$contact->find();
// iterate through the affected individuals and rebuild their display_names
while ($contact->fetch()) {
$contact = new CRM_Contact_BAO_Contact();
$contact->id = $contact->contact_id;
if ($action == CRM_Core_Action::DELETE) {
$contact->$fieldName = 'NULL';
$contact->save();
}
$contact->display_name = $contact->displayName();
$contact->save();
}
}
/**
* Creates display name.
*
* @return string
* the constructed display name
*/
public function displayName() {
$prefix = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'prefix_id');
$suffix = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'suffix_id');
return str_replace(' ', ' ', trim($prefix[$this->prefix_id] . ' ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name . ' ' . $suffix[$this->suffix_id]));
}
/**
* Check if there is data to create the object.
*
* @param array $params
*
* @return bool
*/
public static function dataExists($params) {
if ($params['contact_type'] == 'Individual') {
return TRUE;
}
return FALSE;
}
}

View file

@ -0,0 +1,398 @@
<?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_BAO_ProximityQuery {
/**
* Trigonometry for calculating geographical distances.
*
* Modification made in: CRM-13904
* http://en.wikipedia.org/wiki/Great-circle_distance
* http://www.movable-type.co.uk/scripts/latlong.html
*
* All function arguments and return values measure distances in metres
* and angles in degrees. The ellipsoid model is from the WGS-84 datum.
* Ka-Ping Yee, 2003-08-11
* earth_radius_semimajor = 6378137.0;
* earth_flattening = 1/298.257223563;
* earth_radius_semiminor = $earth_radius_semimajor * (1 - $earth_flattening);
* earth_eccentricity_sq = 2*$earth_flattening - pow($earth_flattening, 2);
* This library is an implementation of UCB CS graduate student, Ka-Ping Yee (http://www.zesty.ca).
* This version has been taken from Drupal's location module: http://drupal.org/project/location
*/
static protected $_earthFlattening;
static protected $_earthRadiusSemiMinor;
static protected $_earthRadiusSemiMajor;
static protected $_earthEccentricitySQ;
public static function initialize() {
static $_initialized = FALSE;
if (!$_initialized) {
$_initialized = TRUE;
self::$_earthFlattening = 1.0 / 298.257223563;
self::$_earthRadiusSemiMajor = 6378137.0;
self::$_earthRadiusSemiMinor = self::$_earthRadiusSemiMajor * (1.0 - self::$_earthFlattening);
self::$_earthEccentricitySQ = 2 * self::$_earthFlattening - pow(self::$_earthFlattening, 2);
}
}
/*
* Latitudes in all of U. S.: from -7.2 (American Samoa) to 70.5 (Alaska).
* Latitudes in continental U. S.: from 24.6 (Florida) to 49.0 (Washington).
* Average latitude of all U. S. zipcodes: 37.9.
*/
/**
* Estimate the Earth's radius at a given latitude.
* Default to an approximate average radius for the United States.
*
* @param float $latitude
* @return float
*/
public static function earthRadius($latitude) {
$lat = deg2rad($latitude);
$x = cos($lat) / self::$_earthRadiusSemiMajor;
$y = sin($lat) / self::$_earthRadiusSemiMinor;
return 1.0 / sqrt($x * $x + $y * $y);
}
/**
* Convert longitude and latitude to earth-centered earth-fixed coordinates.
* X axis is 0 long, 0 lat; Y axis is 90 deg E; Z axis is north pole.
*
* @param float $longitude
* @param float $latitude
* @param float|int $height
*
* @return array
*/
public static function earthXYZ($longitude, $latitude, $height = 0) {
$long = deg2rad($longitude);
$lat = deg2rad($latitude);
$cosLong = cos($long);
$cosLat = cos($lat);
$sinLong = sin($long);
$sinLat = sin($lat);
$radius = self::$_earthRadiusSemiMajor / sqrt(1 - self::$_earthEccentricitySQ * $sinLat * $sinLat);
$x = ($radius + $height) * $cosLat * $cosLong;
$y = ($radius + $height) * $cosLat * $sinLong;
$z = ($radius * (1 - self::$_earthEccentricitySQ) + $height) * $sinLat;
return array($x, $y, $z);
}
/**
* Convert a given angle to earth-surface distance.
*
* @param float $angle
* @param float $latitude
* @return float
*/
public static function earthArcLength($angle, $latitude) {
return deg2rad($angle) * self::earthRadius($latitude);
}
/**
* Estimate the min and max longitudes within $distance of a given location.
*
* @param float $longitude
* @param float $latitude
* @param float $distance
* @return array
*/
public static function earthLongitudeRange($longitude, $latitude, $distance) {
$long = deg2rad($longitude);
$lat = deg2rad($latitude);
$radius = self::earthRadius($latitude);
$angle = $distance / $radius;
$diff = asin(sin($angle) / cos($lat));
$minLong = $long - $diff;
$maxLong = $long + $diff;
if ($minLong < -pi()) {
$minLong = $minLong + pi() * 2;
}
if ($maxLong > pi()) {
$maxLong = $maxLong - pi() * 2;
}
return array(
rad2deg($minLong),
rad2deg($maxLong),
);
}
/**
* Estimate the min and max latitudes within $distance of a given location.
*
* @param float $longitude
* @param float $latitude
* @param float $distance
* @return array
*/
public static function earthLatitudeRange($longitude, $latitude, $distance) {
$long = deg2rad($longitude);
$lat = deg2rad($latitude);
$radius = self::earthRadius($latitude);
$angle = $distance / $radius;
$minLat = $lat - $angle;
$maxLat = $lat + $angle;
$rightangle = pi() / 2.0;
// wrapped around the south pole
if ($minLat < -$rightangle) {
$overshoot = -$minLat - $rightangle;
$minLat = -$rightangle + $overshoot;
if ($minLat > $maxLat) {
$maxLat = $minLat;
}
$minLat = -$rightangle;
}
// wrapped around the north pole
if ($maxLat > $rightangle) {
$overshoot = $maxLat - $rightangle;
$maxLat = $rightangle - $overshoot;
if ($maxLat < $minLat) {
$minLat = $maxLat;
}
$maxLat = $rightangle;
}
return array(
rad2deg($minLat),
rad2deg($maxLat),
);
}
/**
* @param float $latitude
* @param float $longitude
* @param float $distance
* @param string $tablePrefix
*
* @return string
*/
public static function where($latitude, $longitude, $distance, $tablePrefix = 'civicrm_address') {
self::initialize();
$params = array();
$clause = array();
list($minLongitude, $maxLongitude) = self::earthLongitudeRange($longitude, $latitude, $distance);
list($minLatitude, $maxLatitude) = self::earthLatitudeRange($longitude, $latitude, $distance);
// DONT consider NAN values (which is returned by rad2deg php function)
// for checking BETWEEN geo_code's criteria as it throws obvious 'NAN' field not found DB: Error
$geoCodeWhere = array();
if (!is_nan($minLatitude)) {
$geoCodeWhere[] = "{$tablePrefix}.geo_code_1 >= $minLatitude ";
}
if (!is_nan($maxLatitude)) {
$geoCodeWhere[] = "{$tablePrefix}.geo_code_1 <= $maxLatitude ";
}
if (!is_nan($minLongitude)) {
$geoCodeWhere[] = "{$tablePrefix}.geo_code_2 >= $minLongitude ";
}
if (!is_nan($maxLongitude)) {
$geoCodeWhere[] = "{$tablePrefix}.geo_code_2 <= $maxLongitude ";
}
$geoCodeWhereClause = implode(' AND ', $geoCodeWhere);
$where = "
{$geoCodeWhereClause} AND
ACOS(
COS(RADIANS({$tablePrefix}.geo_code_1)) *
COS(RADIANS($latitude)) *
COS(RADIANS({$tablePrefix}.geo_code_2) - RADIANS($longitude)) +
SIN(RADIANS({$tablePrefix}.geo_code_1)) *
SIN(RADIANS($latitude))
) * 6378137 <= $distance
";
return $where;
}
/**
* Process form.
*
* @param CRM_Contact_BAO_Query $query
* @param array $values
*
* @return null
* @throws Exception
*/
public static function process(&$query, &$values) {
list($name, $op, $distance, $grouping, $wildcard) = $values;
// also get values array for all address related info
$proximityVars = array(
'street_address' => 1,
'city' => 1,
'postal_code' => 1,
'state_province_id' => 0,
'country_id' => 0,
'state_province' => 0,
'country' => 0,
'distance_unit' => 0,
);
$proximityAddress = array();
$qill = array();
foreach ($proximityVars as $var => $recordQill) {
$proximityValues = $query->getWhereValues("prox_{$var}", $grouping);
if (!empty($proximityValues) &&
!empty($proximityValues[2])
) {
$proximityAddress[$var] = $proximityValues[2];
if ($recordQill) {
$qill[] = $proximityValues[2];
}
}
}
if (empty($proximityAddress)) {
return NULL;
}
if (isset($proximityAddress['state_province_id'])) {
$proximityAddress['state_province'] = CRM_Core_PseudoConstant::stateProvince($proximityAddress['state_province_id']);
$qill[] = $proximityAddress['state_province'];
}
$config = CRM_Core_Config::singleton();
if (!isset($proximityAddress['country_id'])) {
// get it from state if state is present
if (isset($proximityAddress['state_province_id'])) {
$proximityAddress['country_id'] = CRM_Core_PseudoConstant::countryIDForStateID($proximityAddress['state_province_id']);
}
elseif (isset($config->defaultContactCountry)) {
$proximityAddress['country_id'] = $config->defaultContactCountry;
}
}
if (!empty($proximityAddress['country_id'])) {
$proximityAddress['country'] = CRM_Core_PseudoConstant::country($proximityAddress['country_id']);
$qill[] = $proximityAddress['country'];
}
if (
isset($proximityAddress['distance_unit']) &&
$proximityAddress['distance_unit'] == 'miles'
) {
$qillUnits = " {$distance} " . ts('miles');
$distance = $distance * 1609.344;
}
else {
$qillUnits = " {$distance} " . ts('km');
$distance = $distance * 1000.00;
}
$qill = ts('Proximity search to a distance of %1 from %2',
array(
1 => $qillUnits,
2 => implode(', ', $qill),
)
);
$fnName = isset($config->geocodeMethod) ? $config->geocodeMethod : NULL;
if (empty($fnName)) {
CRM_Core_Error::fatal(ts('Proximity searching requires you to set a valid geocoding provider'));
}
$query->_tables['civicrm_address'] = $query->_whereTables['civicrm_address'] = 1;
require_once str_replace('_', DIRECTORY_SEPARATOR, $fnName) . '.php';
$fnName::format($proximityAddress);
if (
!is_numeric(CRM_Utils_Array::value('geo_code_1', $proximityAddress)) ||
!is_numeric(CRM_Utils_Array::value('geo_code_2', $proximityAddress))
) {
// we are setting the where clause to 0 here, so we wont return anything
$qill .= ': ' . ts('We could not geocode the destination address.');
$query->_qill[$grouping][] = $qill;
$query->_where[$grouping][] = ' (0) ';
return NULL;
}
$query->_qill[$grouping][] = $qill;
$query->_where[$grouping][] = self::where(
$proximityAddress['geo_code_1'],
$proximityAddress['geo_code_2'],
$distance
);
return NULL;
}
/**
* @param array $input
* retun void
*
* @return null
*/
public static function fixInputParams(&$input) {
foreach ($input as $param) {
if (CRM_Utils_Array::value('0', $param) == 'prox_distance') {
// add prox_ prefix to these
$param_alter = array('street_address', 'city', 'postal_code', 'state_province', 'country');
foreach ($input as $key => $_param) {
if (in_array($_param[0], $param_alter)) {
$input[$key][0] = 'prox_' . $_param[0];
// _id suffix where needed
if ($_param[0] == 'country' || $_param[0] == 'state_province') {
$input[$key][0] .= '_id';
// flatten state_province array
if (is_array($input[$key][2])) {
$input[$key][2] = $input[$key][2][0];
}
}
}
}
return NULL;
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,167 @@
<?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
*/
/**
* Delegate query functions based on hook system.
*/
class CRM_Contact_BAO_Query_Hook {
/**
* @var array of CRM_Contact_BAO_Query_Interface objects
*/
protected $_queryObjects = NULL;
/**
* Singleton function used to manage this object.
*
* @return object
*/
public static function singleton() {
static $singleton = NULL;
if (!$singleton) {
$singleton = new CRM_Contact_BAO_Query_Hook();
}
return $singleton;
}
/**
* Get or build the list of search objects (via hook).
*
* @return array
* Array of CRM_Contact_BAO_Query_Interface objects
*/
public function getSearchQueryObjects() {
if ($this->_queryObjects === NULL) {
$this->_queryObjects = array();
CRM_Utils_Hook::queryObjects($this->_queryObjects, 'Contact');
}
return $this->_queryObjects;
}
/**
* @return array
*/
public function &getFields() {
$extFields = array();
foreach (self::getSearchQueryObjects() as $obj) {
$flds = $obj->getFields();
$extFields = array_merge($extFields, $flds);
}
return $extFields;
}
/**
* @param $apiEntities
* @param $fieldOptions
*/
public function alterSearchBuilderOptions(&$apiEntities, &$fieldOptions) {
foreach (self::getSearchQueryObjects() as $obj) {
$obj->alterSearchBuilderOptions($apiEntities, $fieldOptions);
}
}
/**
* Alter search query.
*
* @param string $query
* @param string $fnName
*/
public function alterSearchQuery(&$query, $fnName) {
foreach (self::getSearchQueryObjects() as $obj) {
$obj->$fnName($query);
}
}
/**
* @param string $fieldName
* @param $mode
* @param $side
*
* @return string
*/
public function buildSearchfrom($fieldName, $mode, $side) {
$from = '';
foreach (self::getSearchQueryObjects() as $obj) {
$from .= $obj->from($fieldName, $mode, $side);
}
return $from;
}
/**
* @param $tables
*/
public function setTableDependency(&$tables) {
foreach (self::getSearchQueryObjects() as $obj) {
$obj->setTableDependency($tables);
}
}
/**
* @param $panes
*/
public function registerAdvancedSearchPane(&$panes) {
foreach (self::getSearchQueryObjects() as $obj) {
$obj->registerAdvancedSearchPane($panes);
}
}
/**
* @param $panes
*/
public function getPanesMapper(&$panes) {
foreach (self::getSearchQueryObjects() as $obj) {
$obj->getPanesMapper($panes);
}
}
/**
* @param CRM_Core_Form $form
* @param $type
*/
public function buildAdvancedSearchPaneForm(&$form, $type) {
foreach (self::getSearchQueryObjects() as $obj) {
$obj->buildAdvancedSearchPaneForm($form, $type);
}
}
/**
* @param $paneTemplatePathArray
* @param $type
*/
public function setAdvancedSearchPaneTemplatePath(&$paneTemplatePathArray, $type) {
foreach (self::getSearchQueryObjects() as $obj) {
$obj->setAdvancedSearchPaneTemplatePath($paneTemplatePathArray, $type);
}
}
}

View file

@ -0,0 +1,124 @@
<?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 for search BAO query objects
*/
abstract class CRM_Contact_BAO_Query_Interface {
abstract public function &getFields();
/**
* @param string $fieldName
* @param $mode
* @param $side
*
* @return mixed
*/
abstract public function from($fieldName, $mode, $side);
/**
* @param $query
*
* @return null
*/
public function select(&$query) {
return NULL;
}
/**
* @param $query
*
* @return null
*/
public function where(&$query) {
return NULL;
}
/**
* @param $tables
*
* @return null
*/
public function setTableDependency(&$tables) {
return NULL;
}
/**
* @param $panes
*
* @return null
*/
public function registerAdvancedSearchPane(&$panes) {
return NULL;
}
/**
* @param CRM_Core_Form $form
* @param $type
*
* @return null
*/
public function buildAdvancedSearchPaneForm(&$form, $type) {
return NULL;
}
/**
* @param $paneTemplatePathArray
* @param $type
*
* @return null
*/
public function setAdvancedSearchPaneTemplatePath(&$paneTemplatePathArray, $type) {
return NULL;
}
/**
* Describe options for available for use in the search-builder.
*
* The search builder determines its options by examining the API metadata corresponding to each
* search field. This approach assumes that each field has a unique-name (ie that the field's
* unique-name in the API matches the unique-name in the search-builder).
*
* @param array $apiEntities
* List of entities whose options should be automatically scanned using API metadata.
* @param array $fieldOptions
* Keys are field unique-names; values describe how to lookup the options.
* For boolean options, use value "yesno". For pseudoconstants/FKs, use the name of an API entity
* from which the metadata of the field may be queried. (Yes - that is a mouthful.)
* @void
*/
public function alterSearchBuilderOptions(&$apiEntities, &$fieldOptions) {
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,183 @@
<?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_BAO_RelationshipType extends CRM_Contact_DAO_RelationshipType {
/**
* Class constructor.
*/
public function __construct() {
parent::__construct();
}
/**
* Fetch object based on array of properties.
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
* @param array $defaults
* (reference ) an assoc array to hold the flattened values.
*
* @return CRM_Contact_BAO_RelationshipType
*/
public static function retrieve(&$params, &$defaults) {
$relationshipType = new CRM_Contact_DAO_RelationshipType();
$relationshipType->copyValues($params);
if ($relationshipType->find(TRUE)) {
CRM_Core_DAO::storeValues($relationshipType, $defaults);
$relationshipType->free();
return $relationshipType;
}
return NULL;
}
/**
* Update the is_active flag in the db.
*
* @param int $id
* Id of the database record.
* @param bool $is_active
* Value we want to set the is_active field.
*
* @return Object
* DAO object on success, null otherwise
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Contact_DAO_RelationshipType', $id, 'is_active', $is_active);
}
/**
* Add the relationship type in the db.
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
* @param array $ids
* The array that holds all the db ids.
*
* @return CRM_Contact_DAO_RelationshipType
*/
public static function add(&$params, &$ids) {
//to change name, CRM-3336
if (empty($params['label_a_b']) && !empty($params['name_a_b'])) {
$params['label_a_b'] = $params['name_a_b'];
}
if (empty($params['label_b_a']) && !empty($params['name_b_a'])) {
$params['label_b_a'] = $params['name_b_a'];
}
// set label to name if it's not set - but *only* for
// ADD action. CRM-3336 as part from (CRM-3522)
if (empty($ids['relationshipType'])) {
if (empty($params['name_a_b']) && !empty($params['label_a_b'])) {
$params['name_a_b'] = $params['label_a_b'];
}
if (empty($params['name_b_a']) && !empty($params['label_b_a'])) {
$params['name_b_a'] = $params['label_b_a'];
}
}
// action is taken depending upon the mode
$relationshipType = new CRM_Contact_DAO_RelationshipType();
$relationshipType->copyValues($params);
// if label B to A is blank, insert the value label A to B for it
if (!strlen(trim($strName = CRM_Utils_Array::value('name_b_a', $params)))) {
$relationshipType->name_b_a = CRM_Utils_Array::value('name_a_b', $params);
}
if (!strlen(trim($strName = CRM_Utils_Array::value('label_b_a', $params)))) {
$relationshipType->label_b_a = CRM_Utils_Array::value('label_a_b', $params);
}
$relationshipType->id = CRM_Utils_Array::value('relationshipType', $ids);
$result = $relationshipType->save();
CRM_Core_PseudoConstant::relationshipType('label', TRUE);
CRM_Core_PseudoConstant::relationshipType('name', TRUE);
CRM_Case_XMLProcessor::flushStaticCaches();
return $result;
}
/**
* Delete Relationship Types.
*
* @param int $relationshipTypeId
*
* @throws CRM_Core_Exception
* @return mixed
*/
public static function del($relationshipTypeId) {
// make sure relationshipTypeId is an integer
// @todo review this as most delete functions rely on the api & form layer for this
// or do a find first & throw error if no find
if (!CRM_Utils_Rule::positiveInteger($relationshipTypeId)) {
throw new CRM_Core_Exception(ts('Invalid relationship type'));
}
//check dependencies
// delete all relationships
$relationship = new CRM_Contact_DAO_Relationship();
$relationship->relationship_type_id = $relationshipTypeId;
$relationship->delete();
// remove this relationship type from membership types
$mems = civicrm_api3('MembershipType', 'get', array(
'relationship_type_id' => array('LIKE' => "%{$relationshipTypeId}%"),
'return' => array('id', 'relationship_type_id', 'relationship_direction'),
));
foreach ($mems['values'] as $membershipTypeId => $membershipType) {
$pos = array_search($relationshipTypeId, $membershipType['relationship_type_id']);
// Api call may have returned false positives but currently the relationship_type_id uses
// nonstandard serialization which makes anything more accurate impossible.
if ($pos !== FALSE) {
unset($membershipType['relationship_type_id'][$pos], $membershipType['relationship_direction'][$pos]);
civicrm_api3('MembershipType', 'create', $membershipType);
}
}
//fixed for CRM-3323
$mappingField = new CRM_Core_DAO_MappingField();
$mappingField->relationship_type_id = $relationshipTypeId;
$mappingField->find();
while ($mappingField->fetch()) {
$mappingField->delete();
}
$relationshipType = new CRM_Contact_DAO_RelationshipType();
$relationshipType->id = $relationshipTypeId;
return $relationshipType->delete();
}
}

View file

@ -0,0 +1,496 @@
<?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
*/
/**
* Business object for Saved searches.
*/
class CRM_Contact_BAO_SavedSearch extends CRM_Contact_DAO_SavedSearch {
/**
* Class constructor.
*/
public function __construct() {
parent::__construct();
}
/**
* Query the db for all saved searches.
*
* @return array
* contains the search name as value and and id as key
*/
public function getAll() {
$savedSearch = new CRM_Contact_DAO_SavedSearch();
$savedSearch->selectAdd();
$savedSearch->selectAdd('id, name');
$savedSearch->find();
while ($savedSearch->fetch()) {
$aSavedSearch[$savedSearch->id] = $savedSearch->name;
}
return $aSavedSearch;
}
/**
* Retrieve DB object based on input parameters.
*
* It also stores all the retrieved values in the default array.
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
* @param array $defaults
* (reference ) an assoc array to hold the flattened values.
*
* @return CRM_Contact_BAO_SavedSearch
*/
public static function retrieve(&$params, &$defaults) {
$savedSearch = new CRM_Contact_DAO_SavedSearch();
$savedSearch->copyValues($params);
if ($savedSearch->find(TRUE)) {
CRM_Core_DAO::storeValues($savedSearch, $defaults);
return $savedSearch;
}
return NULL;
}
/**
* Given an id, extract the formValues of the saved search.
*
* @param int $id
* The id of the saved search.
*
* @return array
* the values of the posted saved search used as default values in various Search Form
*/
public static function getFormValues($id) {
$fv = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $id, 'form_values');
$result = NULL;
if ($fv) {
// make sure u unserialize - since it's stored in serialized form
$result = unserialize($fv);
}
$specialFields = array('contact_type', 'group', 'contact_tags', 'member_membership_type_id', 'member_status_id');
foreach ($result as $element => $value) {
if (CRM_Contact_BAO_Query::isAlreadyProcessedForQueryFormat($value)) {
$id = CRM_Utils_Array::value(0, $value);
$value = CRM_Utils_Array::value(2, $value);
if (is_array($value) && in_array(key($value), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) {
$op = key($value);
$value = CRM_Utils_Array::value($op, $value);
if (in_array($op, array('BETWEEN', '>=', '<='))) {
self::decodeRelativeFields($result, $id, $op, $value);
unset($result[$element]);
continue;
}
}
if (strpos($id, '_date_low') !== FALSE || strpos($id, '_date_high') !== FALSE) {
$entityName = strstr($id, '_date', TRUE);
if (!empty($result['relative_dates']) && array_key_exists($entityName, $result['relative_dates'])) {
$result[$id] = NULL;
$result["{$entityName}_date_relative"] = $result['relative_dates'][$entityName];
}
else {
$result[$id] = $value;
$result["{$entityName}_date_relative"] = 0;
}
}
else {
$result[$id] = $value;
}
unset($result[$element]);
continue;
}
if (!empty($value) && is_array($value)) {
if (in_array($element, $specialFields)) {
// Remove the element to minimise support for legacy formats. It is stored in $value
// so will be re-set with the right name.
unset($result[$element]);
$element = str_replace('member_membership_type_id', 'membership_type_id', $element);
$element = str_replace('member_status_id', 'membership_status_id', $element);
CRM_Contact_BAO_Query::legacyConvertFormValues($element, $value);
$result[$element] = $value;
}
// As per the OK (Operator as Key) value format, value array may contain key
// as an operator so to ensure the default is always set actual value
elseif (in_array(key($value), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) {
$result[$element] = CRM_Utils_Array::value(key($value), $value);
if (is_string($result[$element])) {
$result[$element] = str_replace("%", '', $result[$element]);
}
}
}
if (substr($element, 0, 7) == 'custom_' &&
(substr($element, -5, 5) == '_from' || substr($element, -3, 3) == '_to')
) {
// Ensure the _relative field is set if from or to are set to ensure custom date
// fields with 'from' or 'to' values are displayed when the are set in the smart group
// being loaded. (CRM-17116)
if (!isset($result[CRM_Contact_BAO_Query::getCustomFieldName($element) . '_relative'])) {
$result[CRM_Contact_BAO_Query::getCustomFieldName($element) . '_relative'] = 0;
}
}
// check to see if we need to convert the old privacy array
// CRM-9180
if (!empty($result['privacy'])) {
if (is_array($result['privacy'])) {
$result['privacy_operator'] = 'AND';
$result['privacy_toggle'] = 1;
if (isset($result['privacy']['do_not_toggle'])) {
if ($result['privacy']['do_not_toggle']) {
$result['privacy_toggle'] = 2;
}
unset($result['privacy']['do_not_toggle']);
}
$result['privacy_options'] = array();
foreach ($result['privacy'] as $name => $val) {
if ($val) {
$result['privacy_options'][] = $name;
}
}
}
unset($result['privacy']);
}
}
if ($customSearchClass = CRM_Utils_Array::value('customSearchClass', $result)) {
// check if there is a special function - formatSavedSearchFields defined in the custom search form
if (method_exists($customSearchClass, 'formatSavedSearchFields')) {
$customSearchClass::formatSavedSearchFields($result);
}
}
return $result;
}
/**
* Get search parameters.
*
* @param int $id
*
* @return array
*/
public static function getSearchParams($id) {
$fv = self::getFormValues($id);
//check if the saved search has mapping id
if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $id, 'mapping_id')) {
return CRM_Core_BAO_Mapping::formattedFields($fv);
}
elseif (!empty($fv['customSearchID'])) {
return $fv;
}
else {
return CRM_Contact_BAO_Query::convertFormValues($fv);
}
}
/**
* Get the where clause for a saved search.
*
* @param int $id
* Saved search id.
* @param array $tables
* (reference ) add the tables that are needed for the select clause.
* @param array $whereTables
* (reference ) add the tables that are needed for the where clause.
*
* @return string
* the where clause for this saved search
*/
public static function whereClause($id, &$tables, &$whereTables) {
$params = self::getSearchParams($id);
if ($params) {
if (!empty($params['customSearchID'])) {
// this has not yet been implemented
}
else {
return CRM_Contact_BAO_Query::getWhereClause($params, NULL, $tables, $whereTables);
}
}
return NULL;
}
/**
* Contact IDS Sql (whatever that means!).
*
* @param int $id
*
* @return string
*/
public static function contactIDsSQL($id) {
$params = self::getSearchParams($id);
if ($params && !empty($params['customSearchID'])) {
return CRM_Contact_BAO_SearchCustom::contactIDSQL(NULL, $id);
}
else {
$tables = $whereTables = array('civicrm_contact' => 1);
$where = CRM_Contact_BAO_SavedSearch::whereClause($id, $tables, $whereTables);
if (!$where) {
$where = '( 1 )';
}
$from = CRM_Contact_BAO_Query::fromClause($whereTables);
return "
SELECT contact_a.id
$from
WHERE $where";
}
}
/**
* Get from where email (whatever that means!).
*
* @param int $id
*
* @return array
*/
public static function fromWhereEmail($id) {
$params = self::getSearchParams($id);
if ($params) {
if (!empty($params['customSearchID'])) {
return CRM_Contact_BAO_SearchCustom::fromWhereEmail(NULL, $id);
}
else {
$tables = $whereTables = array('civicrm_contact' => 1, 'civicrm_email' => 1);
$where = CRM_Contact_BAO_SavedSearch::whereClause($id, $tables, $whereTables);
$from = CRM_Contact_BAO_Query::fromClause($whereTables);
return array($from, $where);
}
}
else {
// fix for CRM-7240
$from = "
FROM civicrm_contact contact_a
LEFT JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id AND civicrm_email.is_primary = 1)
";
$where = " ( 1 ) ";
$tables['civicrm_contact'] = $whereTables['civicrm_contact'] = 1;
$tables['civicrm_email'] = $whereTables['civicrm_email'] = 1;
return array($from, $where);
}
}
/**
* Given a saved search compute the clause and the tables and store it for future use.
*/
public function buildClause() {
$fv = unserialize($this->form_values);
if ($this->mapping_id) {
$params = CRM_Core_BAO_Mapping::formattedFields($fv);
}
else {
$params = CRM_Contact_BAO_Query::convertFormValues($fv);
}
if (!empty($params)) {
$tables = $whereTables = array();
$this->where_clause = CRM_Contact_BAO_Query::getWhereClause($params, NULL, $tables, $whereTables);
if (!empty($tables)) {
$this->select_tables = serialize($tables);
}
if (!empty($whereTables)) {
$this->where_tables = serialize($whereTables);
}
}
}
/**
* Save the search.
*
* @param bool $hook
*/
public function save($hook = TRUE) {
// first build the computed fields
$this->buildClause();
parent::save($hook);
}
/**
* Given an id, get the name of the saved search.
*
* @param int $id
* The id of the saved search.
*
* @param string $value
*
* @return string
* the name of the saved search
*/
public static function getName($id, $value = 'name') {
$group = new CRM_Contact_DAO_Group();
$group->saved_search_id = $id;
if ($group->find(TRUE)) {
return $group->$value;
}
return NULL;
}
/**
* Create a smart group from normalised values.
*
* @param array $params
*
* @return \CRM_Contact_DAO_SavedSearch
*/
public static function create(&$params) {
$savedSearch = new CRM_Contact_DAO_SavedSearch();
if (isset($params['formValues']) &&
!empty($params['formValues'])
) {
$savedSearch->form_values = serialize($params['formValues']);
}
else {
$savedSearch->form_values = NULL;
}
$savedSearch->is_active = CRM_Utils_Array::value('is_active', $params, 1);
$savedSearch->mapping_id = CRM_Utils_Array::value('mapping_id', $params, 'null');
$savedSearch->custom_search_id = CRM_Utils_Array::value('custom_search_id', $params, 'null');
$savedSearch->id = CRM_Utils_Array::value('id', $params, NULL);
$savedSearch->save();
return $savedSearch;
}
/**
* Assign test value.
*
* @param string $fieldName
* @param array $fieldDef
* @param int $counter
*/
protected function assignTestValue($fieldName, &$fieldDef, $counter) {
if ($fieldName == 'form_values') {
// A dummy value for form_values.
$this->{$fieldName} = serialize(
array('sort_name' => "SortName{$counter}"));
}
else {
parent::assignTestValues($fieldName, $fieldDef, $counter);
}
}
/**
* Store relative dates in separate array format
*
* @param array $queryParams
* @param array $formValues
*/
public static function saveRelativeDates(&$queryParams, $formValues) {
$relativeDates = array('relative_dates' => array());
foreach ($formValues as $id => $value) {
if (preg_match('/_date_relative$/', $id) && !empty($value)) {
$entityName = strstr($id, '_date', TRUE);
$relativeDates['relative_dates'][$entityName] = $value;
}
}
// merge with original queryParams if relative date value(s) found
if (count($relativeDates['relative_dates'])) {
$queryParams = array_merge($queryParams, $relativeDates);
}
}
/**
* Store search variables in $queryParams which were skipped while processing query params,
* precisely at CRM_Contact_BAO_Query::fixWhereValues(...). But these variable are required in
* building smart group criteria otherwise it will cause issues like CRM-18585,CRM-19571
*
* @param array $queryParams
* @param array $formValues
*/
public static function saveSkippedElement(&$queryParams, $formValues) {
// these are elements which are skipped in a smart group criteria
$specialElements = array(
'operator',
'component_mode',
'display_relationship_type',
);
foreach ($specialElements as $element) {
if (!empty($formValues[$element])) {
$queryParams[] = array($element, '=', $formValues[$element], 0, 0);
}
}
}
/**
* Decode relative custom fields (converted by CRM_Contact_BAO_Query->convertCustomRelativeFields(...))
* into desired formValues
*
* @param array $formValues
* @param string $fieldName
* @param string $op
* @param array|string|int $value
*/
public static function decodeRelativeFields(&$formValues, $fieldName, $op, $value) {
// check if its a custom date field, if yes then 'searchDate' format the value
$isCustomDateField = CRM_Contact_BAO_Query::isCustomDateField($fieldName);
// select date range as default
if ($isCustomDateField) {
$formValues[$fieldName . '_relative'] = 0;
}
switch ($op) {
case 'BETWEEN':
if ($isCustomDateField) {
list($formValues[$fieldName . '_from'], $formValues[$fieldName . '_from_time']) = CRM_Utils_Date::setDateDefaults($value[0], 'searchDate');
list($formValues[$fieldName . '_to'], $formValues[$fieldName . '_to_time']) = CRM_Utils_Date::setDateDefaults($value[1], 'searchDate');
}
else {
list($formValues[$fieldName . '_from'], $formValues[$fieldName . '_to']) = $value;
}
break;
case '>=':
if ($isCustomDateField) {
list($formValues[$fieldName . '_from'], $formValues[$fieldName . '_from_time']) = CRM_Utils_Date::setDateDefaults($value, 'searchDate');
}
else {
$formValues[$fieldName . '_from'] = $value;
}
break;
case '<=':
if ($isCustomDateField) {
list($formValues[$fieldName . '_to'], $formValues[$fieldName . '_to_time']) = CRM_Utils_Date::setDateDefaults($value, 'searchDate');
}
else {
$formValues[$fieldName . '_to'] = $value;
}
break;
}
}
}

View file

@ -0,0 +1,166 @@
<?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_BAO_SearchCustom {
/**
* Get details.
*
* @param int $csID
* @param int $ssID
* @param int $gID
*
* @return array
* @throws Exception
*/
public static function details($csID, $ssID = NULL, $gID = NULL) {
$error = array(NULL, NULL, NULL);
if (!$csID &&
!$ssID &&
!$gID
) {
return $error;
}
$customSearchID = $csID;
$formValues = array();
if ($ssID || $gID) {
if ($gID) {
$ssID = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $gID, 'saved_search_id');
}
$formValues = CRM_Contact_BAO_SavedSearch::getFormValues($ssID);
$customSearchID = CRM_Utils_Array::value('customSearchID',
$formValues
);
}
if (!$customSearchID) {
return $error;
}
// check that the csid exists in the db along with the right file
// and implements the right interface
$customSearchClass = civicrm_api3('OptionValue', 'getvalue', array(
'option_group_id' => 'custom_search',
'return' => 'name',
'value' => $customSearchID,
));
$ext = CRM_Extension_System::singleton()->getMapper();
if (!$ext->isExtensionKey($customSearchClass)) {
$customSearchFile = str_replace('_',
DIRECTORY_SEPARATOR,
$customSearchClass
) . '.php';
}
else {
$customSearchFile = $ext->keyToPath($customSearchClass);
$customSearchClass = $ext->keyToClass($customSearchClass);
}
$error = include_once $customSearchFile;
if ($error == FALSE) {
CRM_Core_Error::fatal('Custom search file: ' . $customSearchFile . ' does not exist. Please verify your custom search settings in CiviCRM administrative panel.');
}
return array($customSearchID, $customSearchClass, $formValues);
}
/**
* @param int $csID
* @param int $ssID
*
* @return mixed
* @throws Exception
*/
public static function customClass($csID, $ssID) {
list($customSearchID, $customSearchClass, $formValues) = self::details($csID, $ssID);
if (!$customSearchID) {
CRM_Core_Error::fatal('Could not resolve custom search ID');
}
// instantiate the new class
$customClass = new $customSearchClass($formValues);
return $customClass;
}
/**
* @param int $csID
* @param int $ssID
*
* @return mixed
*/
public static function contactIDSQL($csID, $ssID) {
$customClass = self::customClass($csID, $ssID);
return $customClass->contactIDs();
}
/**
* @param $args
*
* @return array
*/
public static function &buildFormValues($args) {
$args = trim($args);
$values = explode("\n", $args);
$formValues = array();
foreach ($values as $value) {
list($n, $v) = CRM_Utils_System::explode('=', $value, 2);
if (!empty($v)) {
$formValues[$n] = $v;
}
}
return $formValues;
}
/**
* @param int $csID
* @param int $ssID
*
* @return array
*/
public static function fromWhereEmail($csID, $ssID) {
$customClass = self::customClass($csID, $ssID);
$from = $customClass->from();
$where = $customClass->where();
return array($from, $where);
}
}

View file

@ -0,0 +1,74 @@
<?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
*/
/**
* BAO object for crm_email table.
*/
class CRM_Contact_BAO_SubscriptionHistory extends CRM_Contact_DAO_SubscriptionHistory {
/**
* Class constructor.
*/
public function __construct() {
parent::__construct();
}
/**
* Create a new subscription history record.
*
* @param array $params
* Values for the new history record.
*
* @return object
* $history The new history object
*/
public static function &create(&$params) {
$history = new CRM_Contact_BAO_SubscriptionHistory();
$history->date = date('Ymd');
$history->copyValues($params);
$history->save();
return $history;
}
/**
* Erase a contact's subscription history records.
*
* @param int $id
* The contact id.
*/
public static function deleteContact($id) {
$history = new CRM_Contact_BAO_SubscriptionHistory();
$history->contact_id = $id;
$history->delete();
}
}

View file

@ -0,0 +1,101 @@
<?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 used by the Search functionality.
*
* - the search controller is used for building/processing multiform
* searches.
*
* Typically the first form will display the search criteria and it's results
*
* The second form is used to process search results with the associated actions.
*/
class CRM_Contact_Controller_Search extends CRM_Core_Controller {
/**
* Class constructor.
*
* @param string $title
* @param bool $modal
* @param int|mixed|null $action
*/
public function __construct($title = NULL, $modal = TRUE, $action = CRM_Core_Action::NONE) {
parent::__construct($title, $modal);
$this->_stateMachine = new CRM_Contact_StateMachine_Search($this, $action);
// create and instantiate the pages
$this->addPages($this->_stateMachine, $action);
// add all the actions
$this->addActions();
}
/**
* @return mixed
*/
public function selectorName() {
return $this->get('selectorName');
}
public function invalidKey() {
$message = ts('Because your session timed out, we have reset the search page.');
CRM_Core_Session::setStatus($message);
// see if we can figure out the url and redirect to the right search form
// note that this happens really early on, so we can't use any of the form or controller
// variables
$config = CRM_Core_Config::singleton();
$qString = $_GET[$config->userFrameworkURLVar];
$args = "reset=1";
$path = 'civicrm/contact/search/advanced';
if (strpos($qString, 'basic') !== FALSE) {
$path = 'civicrm/contact/search/basic';
}
elseif (strpos($qString, 'builder') !== FALSE) {
$path = 'civicrm/contact/search/builder';
}
elseif (
strpos($qString, 'custom') !== FALSE &&
isset($_REQUEST['csid'])
) {
$path = 'civicrm/contact/search/custom';
$args = "reset=1&csid={$_REQUEST['csid']}";
}
$url = CRM_Utils_System::url($path, $args);
CRM_Utils_System::redirect($url);
}
}

View file

@ -0,0 +1,234 @@
<?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
*
* Generated from xml/schema/CRM/Contact/ACLContactCache.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:09f2e2cc85dd5a51fa2c23ec4f8dc6ee)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_ACLContactCache constructor.
*/
class CRM_Contact_DAO_ACLContactCache extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_acl_contact_cache';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = false;
/**
* primary key
*
* @var int unsigned
*/
public $id;
/**
* FK to civicrm_contact (could be null for anon user)
*
* @var int unsigned
*/
public $user_id;
/**
* FK to civicrm_contact
*
* @var int unsigned
*/
public $contact_id;
/**
* What operation does this user have permission on?
*
* @var string
*/
public $operation;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_acl_contact_cache';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'user_id', 'civicrm_contact', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'contact_id', 'civicrm_contact', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('ACL Contact Cache ID') ,
'description' => 'primary key',
'required' => true,
'table_name' => 'civicrm_acl_contact_cache',
'entity' => 'ACLContactCache',
'bao' => 'CRM_Contact_DAO_ACLContactCache',
'localizable' => 0,
) ,
'user_id' => array(
'name' => 'user_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Contact ID') ,
'description' => 'FK to civicrm_contact (could be null for anon user)',
'table_name' => 'civicrm_acl_contact_cache',
'entity' => 'ACLContactCache',
'bao' => 'CRM_Contact_DAO_ACLContactCache',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact',
) ,
'contact_id' => array(
'name' => 'contact_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Contact ID') ,
'description' => 'FK to civicrm_contact',
'required' => true,
'table_name' => 'civicrm_acl_contact_cache',
'entity' => 'ACLContactCache',
'bao' => 'CRM_Contact_DAO_ACLContactCache',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact',
) ,
'operation' => array(
'name' => 'operation',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Operation') ,
'description' => 'What operation does this user have permission on?',
'required' => true,
'maxlength' => 8,
'size' => CRM_Utils_Type::EIGHT,
'table_name' => 'civicrm_acl_contact_cache',
'entity' => 'ACLContactCache',
'bao' => 'CRM_Contact_DAO_ACLContactCache',
'localizable' => 0,
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'callback' => 'CRM_ACL_BAO_ACL::operation',
)
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return self::$_tableName;
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'acl_contact_cache', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'acl_contact_cache', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array(
'UI_user_contact_operation' => array(
'name' => 'UI_user_contact_operation',
'field' => array(
0 => 'user_id',
1 => 'contact_id',
2 => 'operation',
) ,
'localizable' => false,
'unique' => true,
'sig' => 'civicrm_acl_contact_cache::1::user_id::contact_id::operation',
) ,
);
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,301 @@
<?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
*
* Generated from xml/schema/CRM/Contact/ContactType.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:0323c01f0e0b176df66fe4fa02e0a342)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_ContactType constructor.
*/
class CRM_Contact_DAO_ContactType extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_contact_type';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = false;
/**
* Contact Type ID
*
* @var int unsigned
*/
public $id;
/**
* Internal name of Contact Type (or Subtype).
*
* @var string
*/
public $name;
/**
* localized Name of Contact Type.
*
* @var string
*/
public $label;
/**
* localized Optional verbose description of the type.
*
* @var text
*/
public $description;
/**
* URL of image if any.
*
* @var string
*/
public $image_URL;
/**
* Optional FK to parent contact type.
*
* @var int unsigned
*/
public $parent_id;
/**
* Is this entry active?
*
* @var boolean
*/
public $is_active;
/**
* Is this contact type a predefined system type
*
* @var boolean
*/
public $is_reserved;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_contact_type';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'parent_id', 'civicrm_contact_type', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Contact Type ID') ,
'description' => 'Contact Type ID',
'required' => true,
'table_name' => 'civicrm_contact_type',
'entity' => 'ContactType',
'bao' => 'CRM_Contact_BAO_ContactType',
'localizable' => 0,
) ,
'name' => array(
'name' => 'name',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Name') ,
'description' => 'Internal name of Contact Type (or Subtype).',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_contact_type',
'entity' => 'ContactType',
'bao' => 'CRM_Contact_BAO_ContactType',
'localizable' => 0,
) ,
'label' => array(
'name' => 'label',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Contact Type Label') ,
'description' => 'localized Name of Contact Type.',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_contact_type',
'entity' => 'ContactType',
'bao' => 'CRM_Contact_BAO_ContactType',
'localizable' => 1,
) ,
'description' => array(
'name' => 'description',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('Contact Type Description') ,
'description' => 'localized Optional verbose description of the type.',
'rows' => 2,
'cols' => 60,
'table_name' => 'civicrm_contact_type',
'entity' => 'ContactType',
'bao' => 'CRM_Contact_BAO_ContactType',
'localizable' => 1,
'html' => array(
'type' => 'TextArea',
) ,
) ,
'image_URL' => array(
'name' => 'image_URL',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Contact Type Image URL') ,
'description' => 'URL of image if any.',
'maxlength' => 255,
'size' => CRM_Utils_Type::HUGE,
'table_name' => 'civicrm_contact_type',
'entity' => 'ContactType',
'bao' => 'CRM_Contact_BAO_ContactType',
'localizable' => 0,
) ,
'parent_id' => array(
'name' => 'parent_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Contact Type Parent') ,
'description' => 'Optional FK to parent contact type.',
'table_name' => 'civicrm_contact_type',
'entity' => 'ContactType',
'bao' => 'CRM_Contact_BAO_ContactType',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_ContactType',
'pseudoconstant' => array(
'table' => 'civicrm_contact_type',
'keyColumn' => 'id',
'labelColumn' => 'label',
'condition' => 'parent_id IS NULL',
)
) ,
'is_active' => array(
'name' => 'is_active',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Contact Type Is Active?') ,
'description' => 'Is this entry active?',
'table_name' => 'civicrm_contact_type',
'entity' => 'ContactType',
'bao' => 'CRM_Contact_BAO_ContactType',
'localizable' => 0,
) ,
'is_reserved' => array(
'name' => 'is_reserved',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Contact Type is Reserved?') ,
'description' => 'Is this contact type a predefined system type',
'table_name' => 'civicrm_contact_type',
'entity' => 'ContactType',
'bao' => 'CRM_Contact_BAO_ContactType',
'localizable' => 0,
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return CRM_Core_DAO::getLocaleTableName(self::$_tableName);
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'contact_type', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'contact_type', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array(
'contact_type' => array(
'name' => 'contact_type',
'field' => array(
0 => 'name',
) ,
'localizable' => false,
'unique' => true,
'sig' => 'civicrm_contact_type::1::name',
) ,
);
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

View file

@ -0,0 +1,255 @@
<?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
*
* Generated from xml/schema/CRM/Contact/DashboardContact.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:bcefe0743f9e78a86266236b31f37fe4)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_DashboardContact constructor.
*/
class CRM_Contact_DAO_DashboardContact extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_dashboard_contact';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = false;
/**
*
* @var int unsigned
*/
public $id;
/**
* Dashboard ID
*
* @var int unsigned
*/
public $dashboard_id;
/**
* Contact ID
*
* @var int unsigned
*/
public $contact_id;
/**
* column no for this widget
*
* @var boolean
*/
public $column_no;
/**
* Is this widget active?
*
* @var boolean
*/
public $is_active;
/**
* Ordering of the widgets.
*
* @var int
*/
public $weight;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_dashboard_contact';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'dashboard_id', 'civicrm_dashboard', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'contact_id', 'civicrm_contact', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Dashboard Contact ID') ,
'required' => true,
'table_name' => 'civicrm_dashboard_contact',
'entity' => 'DashboardContact',
'bao' => 'CRM_Contact_BAO_DashboardContact',
'localizable' => 0,
) ,
'dashboard_id' => array(
'name' => 'dashboard_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Dashboard') ,
'description' => 'Dashboard ID',
'required' => true,
'table_name' => 'civicrm_dashboard_contact',
'entity' => 'DashboardContact',
'bao' => 'CRM_Contact_BAO_DashboardContact',
'localizable' => 0,
'FKClassName' => 'CRM_Core_DAO_Dashboard',
) ,
'contact_id' => array(
'name' => 'contact_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Dashboard Contact') ,
'description' => 'Contact ID',
'required' => true,
'table_name' => 'civicrm_dashboard_contact',
'entity' => 'DashboardContact',
'bao' => 'CRM_Contact_BAO_DashboardContact',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact',
) ,
'column_no' => array(
'name' => 'column_no',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Column No') ,
'description' => 'column no for this widget',
'table_name' => 'civicrm_dashboard_contact',
'entity' => 'DashboardContact',
'bao' => 'CRM_Contact_BAO_DashboardContact',
'localizable' => 0,
) ,
'is_active' => array(
'name' => 'is_active',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Dashlet is Active?') ,
'description' => 'Is this widget active?',
'table_name' => 'civicrm_dashboard_contact',
'entity' => 'DashboardContact',
'bao' => 'CRM_Contact_BAO_DashboardContact',
'localizable' => 0,
) ,
'weight' => array(
'name' => 'weight',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Order') ,
'description' => 'Ordering of the widgets.',
'table_name' => 'civicrm_dashboard_contact',
'entity' => 'DashboardContact',
'bao' => 'CRM_Contact_BAO_DashboardContact',
'localizable' => 0,
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return self::$_tableName;
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'dashboard_contact', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'dashboard_contact', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array(
'index_dashboard_id_contact_id' => array(
'name' => 'index_dashboard_id_contact_id',
'field' => array(
0 => 'dashboard_id',
1 => 'contact_id',
) ,
'localizable' => false,
'unique' => true,
'sig' => 'civicrm_dashboard_contact::1::dashboard_id::contact_id',
) ,
);
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

View file

@ -0,0 +1,55 @@
<?php
/**
* Class CRM_Contact_DAO_Factory
*/
class CRM_Contact_DAO_Factory {
static $_classes = array(
'Address' => 'data',
'Contact' => 'data',
'Email' => 'data',
'Household' => 'data',
'IM' => 'data',
'Individual' => 'data',
'Location' => 'data',
'LocationType' => 'data',
'Organization' => 'data',
'Phone' => 'data',
'Relationship' => 'data',
);
static $_prefix = array(
'business' => 'CRM/Contact/BAO/',
'data' => 'CRM/Contact/DAO/',
);
static $_suffix = '.php';
/**
* @param string $className
*
* @return mixed
*/
static function &create($className) {
$type = CRM_Utils_Array::value($className, self::$_classes);
if (!$type) {
return CRM_Core_DAO_Factory::create($className);
}
$file = self::$_prefix[$type] . $className;
$class = str_replace('/', '_', $file);
require_once($file . self::$_suffix);
if ($type == 'singleton') {
$newObj = $class::singleton();
}
else {
// this is either 'business' or 'data'
$newObj = new $class;
}
return $newObj;
}
}

View file

@ -0,0 +1,523 @@
<?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
*
* Generated from xml/schema/CRM/Contact/Group.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:4c9dfb678f18129fd9d667de3727dfeb)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_Group constructor.
*/
class CRM_Contact_DAO_Group extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_group';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = true;
/**
* Group ID
*
* @var int unsigned
*/
public $id;
/**
* Internal name of Group.
*
* @var string
*/
public $name;
/**
* Name of Group.
*
* @var string
*/
public $title;
/**
* Optional verbose description of the group.
*
* @var text
*/
public $description;
/**
* Module or process which created this group.
*
* @var string
*/
public $source;
/**
* FK to saved search table.
*
* @var int unsigned
*/
public $saved_search_id;
/**
* Is this entry active?
*
* @var boolean
*/
public $is_active;
/**
* In what context(s) is this field visible.
*
* @var string
*/
public $visibility;
/**
* the sql where clause if a saved search acl
*
* @var text
*/
public $where_clause;
/**
* the tables to be included in a select data
*
* @var text
*/
public $select_tables;
/**
* the tables to be included in the count statement
*
* @var text
*/
public $where_tables;
/**
* FK to group type
*
* @var string
*/
public $group_type;
/**
* Date when we created the cache for a smart group
*
* @var timestamp
*/
public $cache_date;
/**
* Date and time when we need to refresh the cache next.
*
* @var timestamp
*/
public $refresh_date;
/**
* IDs of the parent(s)
*
* @var text
*/
public $parents;
/**
* IDs of the child(ren)
*
* @var text
*/
public $children;
/**
* Is this group hidden?
*
* @var boolean
*/
public $is_hidden;
/**
*
* @var boolean
*/
public $is_reserved;
/**
* FK to contact table.
*
* @var int unsigned
*/
public $created_id;
/**
* FK to contact table.
*
* @var int unsigned
*/
public $modified_id;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_group';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'saved_search_id', 'civicrm_saved_search', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'created_id', 'civicrm_contact', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'modified_id', 'civicrm_contact', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group ID') ,
'description' => 'Group ID',
'required' => true,
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'name' => array(
'name' => 'name',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Group Name') ,
'description' => 'Internal name of Group.',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'title' => array(
'name' => 'title',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Group Title') ,
'description' => 'Name of Group.',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 1,
) ,
'description' => array(
'name' => 'description',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('Group Description') ,
'description' => 'Optional verbose description of the group.',
'rows' => 2,
'cols' => 60,
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
'html' => array(
'type' => 'TextArea',
) ,
) ,
'source' => array(
'name' => 'source',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Group Source') ,
'description' => 'Module or process which created this group.',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'saved_search_id' => array(
'name' => 'saved_search_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Saved Search ID') ,
'description' => 'FK to saved search table.',
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_SavedSearch',
) ,
'is_active' => array(
'name' => 'is_active',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Group Enabled') ,
'description' => 'Is this entry active?',
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'visibility' => array(
'name' => 'visibility',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Group Visibility Setting') ,
'description' => 'In what context(s) is this field visible.',
'maxlength' => 24,
'size' => CRM_Utils_Type::MEDIUM,
'default' => 'User and User Admin Only',
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'callback' => 'CRM_Core_SelectValues::groupVisibility',
)
) ,
'where_clause' => array(
'name' => 'where_clause',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('Group Where Clause') ,
'description' => 'the sql where clause if a saved search acl',
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'select_tables' => array(
'name' => 'select_tables',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('Tables For Select Clause') ,
'description' => 'the tables to be included in a select data',
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'where_tables' => array(
'name' => 'where_tables',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('Tables For Where Clause') ,
'description' => 'the tables to be included in the count statement',
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'group_type' => array(
'name' => 'group_type',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Group Type') ,
'description' => 'FK to group type',
'maxlength' => 128,
'size' => CRM_Utils_Type::HUGE,
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
'pseudoconstant' => array(
'optionGroupName' => 'group_type',
'optionEditPath' => 'civicrm/admin/options/group_type',
)
) ,
'cache_date' => array(
'name' => 'cache_date',
'type' => CRM_Utils_Type::T_TIMESTAMP,
'title' => ts('Group Cache Date') ,
'description' => 'Date when we created the cache for a smart group',
'required' => false,
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'refresh_date' => array(
'name' => 'refresh_date',
'type' => CRM_Utils_Type::T_TIMESTAMP,
'title' => ts('Next Group Refresh Time') ,
'description' => 'Date and time when we need to refresh the cache next.',
'required' => false,
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'parents' => array(
'name' => 'parents',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('Group Parents') ,
'description' => 'IDs of the parent(s)',
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'children' => array(
'name' => 'children',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('Group Children') ,
'description' => 'IDs of the child(ren)',
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'is_hidden' => array(
'name' => 'is_hidden',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Group is Hidden') ,
'description' => 'Is this group hidden?',
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'is_reserved' => array(
'name' => 'is_reserved',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Group is Reserved') ,
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
) ,
'created_id' => array(
'name' => 'created_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group Created By') ,
'description' => 'FK to contact table.',
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact',
) ,
'modified_id' => array(
'name' => 'modified_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group Modified By') ,
'description' => 'FK to contact table.',
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact',
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return CRM_Core_DAO::getLocaleTableName(self::$_tableName);
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'group', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'group', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array(
'index_group_type' => array(
'name' => 'index_group_type',
'field' => array(
0 => 'group_type',
) ,
'localizable' => false,
'sig' => 'civicrm_group::0::group_type',
) ,
'UI_title' => array(
'name' => 'UI_title',
'field' => array(
0 => 'title',
) ,
'localizable' => true,
'unique' => true,
'sig' => 'civicrm_group::1::title',
) ,
'UI_name' => array(
'name' => 'UI_name',
'field' => array(
0 => 'name',
) ,
'localizable' => false,
'unique' => true,
'sig' => 'civicrm_group::1::name',
) ,
);
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

View file

@ -0,0 +1,277 @@
<?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
*
* Generated from xml/schema/CRM/Contact/GroupContact.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:2545d3926c711a25b5075a6ac980ed99)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_GroupContact constructor.
*/
class CRM_Contact_DAO_GroupContact extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_group_contact';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = true;
/**
* primary key
*
* @var int unsigned
*/
public $id;
/**
* FK to civicrm_group
*
* @var int unsigned
*/
public $group_id;
/**
* FK to civicrm_contact
*
* @var int unsigned
*/
public $contact_id;
/**
* status of contact relative to membership in group
*
* @var string
*/
public $status;
/**
* Optional location to associate with this membership
*
* @var int unsigned
*/
public $location_id;
/**
* Optional email to associate with this membership
*
* @var int unsigned
*/
public $email_id;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_group_contact';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'group_id', 'civicrm_group', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'contact_id', 'civicrm_contact', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'location_id', 'civicrm_loc_block', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'email_id', 'civicrm_email', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group Contact ID') ,
'description' => 'primary key',
'required' => true,
'table_name' => 'civicrm_group_contact',
'entity' => 'GroupContact',
'bao' => 'CRM_Contact_BAO_GroupContact',
'localizable' => 0,
) ,
'group_id' => array(
'name' => 'group_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group ID') ,
'description' => 'FK to civicrm_group',
'required' => true,
'table_name' => 'civicrm_group_contact',
'entity' => 'GroupContact',
'bao' => 'CRM_Contact_BAO_GroupContact',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Group',
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'table' => 'civicrm_group',
'keyColumn' => 'id',
'labelColumn' => 'title',
)
) ,
'contact_id' => array(
'name' => 'contact_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Contact ID') ,
'description' => 'FK to civicrm_contact',
'required' => true,
'table_name' => 'civicrm_group_contact',
'entity' => 'GroupContact',
'bao' => 'CRM_Contact_BAO_GroupContact',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact',
) ,
'status' => array(
'name' => 'status',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Group Contact Status') ,
'description' => 'status of contact relative to membership in group',
'maxlength' => 8,
'size' => CRM_Utils_Type::EIGHT,
'table_name' => 'civicrm_group_contact',
'entity' => 'GroupContact',
'bao' => 'CRM_Contact_BAO_GroupContact',
'localizable' => 0,
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'callback' => 'CRM_Core_SelectValues::groupContactStatus',
)
) ,
'location_id' => array(
'name' => 'location_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group Contact Location') ,
'description' => 'Optional location to associate with this membership',
'table_name' => 'civicrm_group_contact',
'entity' => 'GroupContact',
'bao' => 'CRM_Contact_BAO_GroupContact',
'localizable' => 0,
'FKClassName' => 'CRM_Core_DAO_LocBlock',
) ,
'email_id' => array(
'name' => 'email_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group Contact Email') ,
'description' => 'Optional email to associate with this membership',
'table_name' => 'civicrm_group_contact',
'entity' => 'GroupContact',
'bao' => 'CRM_Contact_BAO_GroupContact',
'localizable' => 0,
'FKClassName' => 'CRM_Core_DAO_Email',
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return self::$_tableName;
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'group_contact', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'group_contact', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array(
'UI_contact_group' => array(
'name' => 'UI_contact_group',
'field' => array(
0 => 'contact_id',
1 => 'group_id',
) ,
'localizable' => false,
'unique' => true,
'sig' => 'civicrm_group_contact::1::contact_id::group_id',
) ,
);
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

View file

@ -0,0 +1,217 @@
<?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
*
* Generated from xml/schema/CRM/Contact/GroupContactCache.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:2ee24826ad267586e2e757ce3b0442a1)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_GroupContactCache constructor.
*/
class CRM_Contact_DAO_GroupContactCache extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_group_contact_cache';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = false;
/**
* primary key
*
* @var int unsigned
*/
public $id;
/**
* FK to civicrm_group
*
* @var int unsigned
*/
public $group_id;
/**
* FK to civicrm_contact
*
* @var int unsigned
*/
public $contact_id;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_group_contact_cache';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'group_id', 'civicrm_group', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'contact_id', 'civicrm_contact', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group Contact Cache ID') ,
'description' => 'primary key',
'required' => true,
'table_name' => 'civicrm_group_contact_cache',
'entity' => 'GroupContactCache',
'bao' => 'CRM_Contact_BAO_GroupContactCache',
'localizable' => 0,
) ,
'group_id' => array(
'name' => 'group_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group') ,
'description' => 'FK to civicrm_group',
'required' => true,
'table_name' => 'civicrm_group_contact_cache',
'entity' => 'GroupContactCache',
'bao' => 'CRM_Contact_BAO_GroupContactCache',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Group',
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'table' => 'civicrm_group',
'keyColumn' => 'id',
'labelColumn' => 'title',
)
) ,
'contact_id' => array(
'name' => 'contact_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Contact ID') ,
'description' => 'FK to civicrm_contact',
'required' => true,
'table_name' => 'civicrm_group_contact_cache',
'entity' => 'GroupContactCache',
'bao' => 'CRM_Contact_BAO_GroupContactCache',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact',
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return self::$_tableName;
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'group_contact_cache', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'group_contact_cache', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array(
'UI_contact_group' => array(
'name' => 'UI_contact_group',
'field' => array(
0 => 'contact_id',
1 => 'group_id',
) ,
'localizable' => false,
'unique' => true,
'sig' => 'civicrm_group_contact_cache::1::contact_id::group_id',
) ,
);
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

View file

@ -0,0 +1,198 @@
<?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
*
* Generated from xml/schema/CRM/Contact/GroupNesting.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:00fc9bc828e1b87acf20aa16b24b1bac)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_GroupNesting constructor.
*/
class CRM_Contact_DAO_GroupNesting extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_group_nesting';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = true;
/**
* Relationship ID
*
* @var int unsigned
*/
public $id;
/**
* ID of the child group
*
* @var int unsigned
*/
public $child_group_id;
/**
* ID of the parent group
*
* @var int unsigned
*/
public $parent_group_id;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_group_nesting';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'child_group_id', 'civicrm_group', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'parent_group_id', 'civicrm_group', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group Nesting ID') ,
'description' => 'Relationship ID',
'required' => true,
'table_name' => 'civicrm_group_nesting',
'entity' => 'GroupNesting',
'bao' => 'CRM_Contact_BAO_GroupNesting',
'localizable' => 0,
) ,
'child_group_id' => array(
'name' => 'child_group_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Child Group') ,
'description' => 'ID of the child group',
'required' => true,
'table_name' => 'civicrm_group_nesting',
'entity' => 'GroupNesting',
'bao' => 'CRM_Contact_BAO_GroupNesting',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Group',
) ,
'parent_group_id' => array(
'name' => 'parent_group_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Parent Group') ,
'description' => 'ID of the parent group',
'required' => true,
'table_name' => 'civicrm_group_nesting',
'entity' => 'GroupNesting',
'bao' => 'CRM_Contact_BAO_GroupNesting',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Group',
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return self::$_tableName;
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'group_nesting', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'group_nesting', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array();
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

View file

@ -0,0 +1,217 @@
<?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
*
* Generated from xml/schema/CRM/Contact/GroupOrganization.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:8fcd7c11b9077c52f8d932eb20379618)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_GroupOrganization constructor.
*/
class CRM_Contact_DAO_GroupOrganization extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_group_organization';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = true;
/**
* Relationship ID
*
* @var int unsigned
*/
public $id;
/**
* ID of the group
*
* @var int unsigned
*/
public $group_id;
/**
* ID of the Organization Contact
*
* @var int unsigned
*/
public $organization_id;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_group_organization';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'group_id', 'civicrm_group', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'organization_id', 'civicrm_contact', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group Organization ID') ,
'description' => 'Relationship ID',
'required' => true,
'table_name' => 'civicrm_group_organization',
'entity' => 'GroupOrganization',
'bao' => 'CRM_Contact_BAO_GroupOrganization',
'localizable' => 0,
) ,
'group_id' => array(
'name' => 'group_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group') ,
'description' => 'ID of the group',
'required' => true,
'table_name' => 'civicrm_group_organization',
'entity' => 'GroupOrganization',
'bao' => 'CRM_Contact_BAO_GroupOrganization',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Group',
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'table' => 'civicrm_group',
'keyColumn' => 'id',
'labelColumn' => 'title',
)
) ,
'organization_id' => array(
'name' => 'organization_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Organization') ,
'description' => 'ID of the Organization Contact',
'required' => true,
'table_name' => 'civicrm_group_organization',
'entity' => 'GroupOrganization',
'bao' => 'CRM_Contact_BAO_GroupOrganization',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact',
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return self::$_tableName;
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'group_organization', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'group_organization', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array(
'UI_group_organization' => array(
'name' => 'UI_group_organization',
'field' => array(
0 => 'group_id',
1 => 'organization_id',
) ,
'localizable' => false,
'unique' => true,
'sig' => 'civicrm_group_organization::1::group_id::organization_id',
) ,
);
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

View file

@ -0,0 +1,365 @@
<?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
*
* Generated from xml/schema/CRM/Contact/Relationship.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:a5a833da9d5016f0aeb06ba7c1058b3c)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_Relationship constructor.
*/
class CRM_Contact_DAO_Relationship extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_relationship';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = true;
/**
* Relationship ID
*
* @var int unsigned
*/
public $id;
/**
* id of the first contact
*
* @var int unsigned
*/
public $contact_id_a;
/**
* id of the second contact
*
* @var int unsigned
*/
public $contact_id_b;
/**
* id of the relationship
*
* @var int unsigned
*/
public $relationship_type_id;
/**
* date when the relationship started
*
* @var date
*/
public $start_date;
/**
* date when the relationship ended
*
* @var date
*/
public $end_date;
/**
* is the relationship active ?
*
* @var boolean
*/
public $is_active;
/**
* Optional verbose description for the relationship.
*
* @var string
*/
public $description;
/**
* is contact a has permission to view / edit contact and
related data for contact b ?
*
* @var boolean
*/
public $is_permission_a_b;
/**
* is contact b has permission to view / edit contact and
related data for contact a ?
*
* @var boolean
*/
public $is_permission_b_a;
/**
* FK to civicrm_case
*
* @var int unsigned
*/
public $case_id;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_relationship';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'contact_id_a', 'civicrm_contact', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'contact_id_b', 'civicrm_contact', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'relationship_type_id', 'civicrm_relationship_type', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'case_id', 'civicrm_case', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Relationship ID') ,
'description' => 'Relationship ID',
'required' => true,
'table_name' => 'civicrm_relationship',
'entity' => 'Relationship',
'bao' => 'CRM_Contact_BAO_Relationship',
'localizable' => 0,
) ,
'contact_id_a' => array(
'name' => 'contact_id_a',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Contact A') ,
'description' => 'id of the first contact',
'required' => true,
'table_name' => 'civicrm_relationship',
'entity' => 'Relationship',
'bao' => 'CRM_Contact_BAO_Relationship',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact',
) ,
'contact_id_b' => array(
'name' => 'contact_id_b',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Contact B') ,
'description' => 'id of the second contact',
'required' => true,
'table_name' => 'civicrm_relationship',
'entity' => 'Relationship',
'bao' => 'CRM_Contact_BAO_Relationship',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact',
'html' => array(
'type' => 'EntityRef',
) ,
) ,
'relationship_type_id' => array(
'name' => 'relationship_type_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Relationship Type') ,
'description' => 'id of the relationship',
'required' => true,
'table_name' => 'civicrm_relationship',
'entity' => 'Relationship',
'bao' => 'CRM_Contact_BAO_Relationship',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_RelationshipType',
'html' => array(
'type' => 'Select',
) ,
) ,
'start_date' => array(
'name' => 'start_date',
'type' => CRM_Utils_Type::T_DATE,
'title' => ts('Relationship Start Date') ,
'description' => 'date when the relationship started',
'table_name' => 'civicrm_relationship',
'entity' => 'Relationship',
'bao' => 'CRM_Contact_BAO_Relationship',
'localizable' => 0,
'html' => array(
'type' => 'Select Date',
) ,
) ,
'end_date' => array(
'name' => 'end_date',
'type' => CRM_Utils_Type::T_DATE,
'title' => ts('Relationship End Date') ,
'description' => 'date when the relationship ended',
'table_name' => 'civicrm_relationship',
'entity' => 'Relationship',
'bao' => 'CRM_Contact_BAO_Relationship',
'localizable' => 0,
'html' => array(
'type' => 'Select Date',
) ,
) ,
'is_active' => array(
'name' => 'is_active',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Relationship Is Active') ,
'description' => 'is the relationship active ?',
'default' => '1',
'table_name' => 'civicrm_relationship',
'entity' => 'Relationship',
'bao' => 'CRM_Contact_BAO_Relationship',
'localizable' => 0,
'html' => array(
'type' => 'CheckBox',
) ,
) ,
'description' => array(
'name' => 'description',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Relationship Description') ,
'description' => 'Optional verbose description for the relationship.',
'maxlength' => 255,
'size' => CRM_Utils_Type::HUGE,
'table_name' => 'civicrm_relationship',
'entity' => 'Relationship',
'bao' => 'CRM_Contact_BAO_Relationship',
'localizable' => 0,
'html' => array(
'type' => 'Text',
) ,
) ,
'is_permission_a_b' => array(
'name' => 'is_permission_a_b',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Contact A has Permission Over Contact B') ,
'description' => 'is contact a has permission to view / edit contact and
related data for contact b ?
',
'table_name' => 'civicrm_relationship',
'entity' => 'Relationship',
'bao' => 'CRM_Contact_BAO_Relationship',
'localizable' => 0,
'html' => array(
'type' => 'CheckBox',
) ,
) ,
'is_permission_b_a' => array(
'name' => 'is_permission_b_a',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Contact B has Permission Over Contact A') ,
'description' => 'is contact b has permission to view / edit contact and
related data for contact a ?
',
'table_name' => 'civicrm_relationship',
'entity' => 'Relationship',
'bao' => 'CRM_Contact_BAO_Relationship',
'localizable' => 0,
'html' => array(
'type' => 'CheckBox',
) ,
) ,
'case_id' => array(
'name' => 'case_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Relationship Case') ,
'description' => 'FK to civicrm_case',
'default' => 'NULL',
'table_name' => 'civicrm_relationship',
'entity' => 'Relationship',
'bao' => 'CRM_Contact_BAO_Relationship',
'localizable' => 0,
'FKClassName' => 'CRM_Case_DAO_Case',
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return self::$_tableName;
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'relationship', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'relationship', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array();
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

View file

@ -0,0 +1,400 @@
<?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
*
* Generated from xml/schema/CRM/Contact/RelationshipType.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:8fb00d8376af049ce62bc57ca01bc1bf)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_RelationshipType constructor.
*/
class CRM_Contact_DAO_RelationshipType extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_relationship_type';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = true;
/**
* Primary key
*
* @var int unsigned
*/
public $id;
/**
* name for relationship of contact_a to contact_b.
*
* @var string
*/
public $name_a_b;
/**
* label for relationship of contact_a to contact_b.
*
* @var string
*/
public $label_a_b;
/**
* Optional name for relationship of contact_b to contact_a.
*
* @var string
*/
public $name_b_a;
/**
* Optional label for relationship of contact_b to contact_a.
*
* @var string
*/
public $label_b_a;
/**
* Optional verbose description of the relationship type.
*
* @var string
*/
public $description;
/**
* If defined, contact_a in a relationship of this type must be a specific contact_type.
*
* @var string
*/
public $contact_type_a;
/**
* If defined, contact_b in a relationship of this type must be a specific contact_type.
*
* @var string
*/
public $contact_type_b;
/**
* If defined, contact_sub_type_a in a relationship of this type must be a specific contact_sub_type.
*
* @var string
*/
public $contact_sub_type_a;
/**
* If defined, contact_sub_type_b in a relationship of this type must be a specific contact_sub_type.
*
* @var string
*/
public $contact_sub_type_b;
/**
* Is this relationship type a predefined system type (can not be changed or de-activated)?
*
* @var boolean
*/
public $is_reserved;
/**
* Is this relationship type currently active (i.e. can be used when creating or editing relationships)?
*
* @var boolean
*/
public $is_active;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_relationship_type';
parent::__construct();
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Relationship Type ID') ,
'description' => 'Primary key',
'required' => true,
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 0,
) ,
'name_a_b' => array(
'name' => 'name_a_b',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Relationship Type Name A to B') ,
'description' => 'name for relationship of contact_a to contact_b.',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 0,
) ,
'label_a_b' => array(
'name' => 'label_a_b',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Relationship Type Label A to B') ,
'description' => 'label for relationship of contact_a to contact_b.',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 1,
) ,
'name_b_a' => array(
'name' => 'name_b_a',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Relationship Type Name B to A') ,
'description' => 'Optional name for relationship of contact_b to contact_a.',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 0,
) ,
'label_b_a' => array(
'name' => 'label_b_a',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Relationship Type Label B to A') ,
'description' => 'Optional label for relationship of contact_b to contact_a.',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 1,
) ,
'description' => array(
'name' => 'description',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Relationship Description') ,
'description' => 'Optional verbose description of the relationship type.',
'maxlength' => 255,
'size' => CRM_Utils_Type::HUGE,
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 1,
) ,
'contact_type_a' => array(
'name' => 'contact_type_a',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Contact Type for Contact A') ,
'description' => 'If defined, contact_a in a relationship of this type must be a specific contact_type.',
'maxlength' => 12,
'size' => CRM_Utils_Type::TWELVE,
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 0,
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'table' => 'civicrm_contact_type',
'keyColumn' => 'name',
'labelColumn' => 'label',
'condition' => 'parent_id IS NULL',
)
) ,
'contact_type_b' => array(
'name' => 'contact_type_b',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Contact Type for Contact B') ,
'description' => 'If defined, contact_b in a relationship of this type must be a specific contact_type.',
'maxlength' => 12,
'size' => CRM_Utils_Type::TWELVE,
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 0,
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'table' => 'civicrm_contact_type',
'keyColumn' => 'name',
'labelColumn' => 'label',
'condition' => 'parent_id IS NULL',
)
) ,
'contact_sub_type_a' => array(
'name' => 'contact_sub_type_a',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Contact Subtype A') ,
'description' => 'If defined, contact_sub_type_a in a relationship of this type must be a specific contact_sub_type.
',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 0,
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'table' => 'civicrm_contact_type',
'keyColumn' => 'name',
'labelColumn' => 'label',
'condition' => 'parent_id IS NOT NULL',
)
) ,
'contact_sub_type_b' => array(
'name' => 'contact_sub_type_b',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Contact Subtype B') ,
'description' => 'If defined, contact_sub_type_b in a relationship of this type must be a specific contact_sub_type.
',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 0,
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'table' => 'civicrm_contact_type',
'keyColumn' => 'name',
'labelColumn' => 'label',
'condition' => 'parent_id IS NOT NULL',
)
) ,
'is_reserved' => array(
'name' => 'is_reserved',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Relationship Type is Reserved') ,
'description' => 'Is this relationship type a predefined system type (can not be changed or de-activated)?',
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 0,
) ,
'is_active' => array(
'name' => 'is_active',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('Relationship Type is Active') ,
'description' => 'Is this relationship type currently active (i.e. can be used when creating or editing relationships)?
',
'default' => '1',
'table_name' => 'civicrm_relationship_type',
'entity' => 'RelationshipType',
'bao' => 'CRM_Contact_BAO_RelationshipType',
'localizable' => 0,
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return CRM_Core_DAO::getLocaleTableName(self::$_tableName);
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'relationship_type', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'relationship_type', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array(
'UI_name_a_b' => array(
'name' => 'UI_name_a_b',
'field' => array(
0 => 'name_a_b',
) ,
'localizable' => false,
'unique' => true,
'sig' => 'civicrm_relationship_type::1::name_a_b',
) ,
'UI_name_b_a' => array(
'name' => 'UI_name_b_a',
'field' => array(
0 => 'name_b_a',
) ,
'localizable' => false,
'unique' => true,
'sig' => 'civicrm_relationship_type::1::name_b_a',
) ,
);
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

View file

@ -0,0 +1,263 @@
<?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
*
* Generated from xml/schema/CRM/Contact/SavedSearch.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:8e799b35db1b6a38deee5a757d4183c0)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_SavedSearch constructor.
*/
class CRM_Contact_DAO_SavedSearch extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_saved_search';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = false;
/**
* Saved Search ID
*
* @var int unsigned
*/
public $id;
/**
* Submitted form values for this search
*
* @var text
*/
public $form_values;
/**
* Foreign key to civicrm_mapping used for saved search-builder searches.
*
* @var int unsigned
*/
public $mapping_id;
/**
* Foreign key to civicrm_option value table used for saved custom searches.
*
* @var int unsigned
*/
public $search_custom_id;
/**
* the sql where clause if a saved search acl
*
* @var text
*/
public $where_clause;
/**
* the tables to be included in a select data
*
* @var text
*/
public $select_tables;
/**
* the tables to be included in the count statement
*
* @var text
*/
public $where_tables;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_saved_search';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'mapping_id', 'civicrm_mapping', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Saved Search ID') ,
'description' => 'Saved Search ID',
'required' => true,
'table_name' => 'civicrm_saved_search',
'entity' => 'SavedSearch',
'bao' => 'CRM_Contact_BAO_SavedSearch',
'localizable' => 0,
) ,
'form_values' => array(
'name' => 'form_values',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('Submitted Form Values') ,
'description' => 'Submitted form values for this search',
'import' => true,
'where' => 'civicrm_saved_search.form_values',
'headerPattern' => '',
'dataPattern' => '',
'export' => true,
'table_name' => 'civicrm_saved_search',
'entity' => 'SavedSearch',
'bao' => 'CRM_Contact_BAO_SavedSearch',
'localizable' => 0,
) ,
'mapping_id' => array(
'name' => 'mapping_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Mapping ID') ,
'description' => 'Foreign key to civicrm_mapping used for saved search-builder searches.',
'table_name' => 'civicrm_saved_search',
'entity' => 'SavedSearch',
'bao' => 'CRM_Contact_BAO_SavedSearch',
'localizable' => 0,
'FKClassName' => 'CRM_Core_DAO_Mapping',
) ,
'search_custom_id' => array(
'name' => 'search_custom_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Option Value ID') ,
'description' => 'Foreign key to civicrm_option value table used for saved custom searches.',
'table_name' => 'civicrm_saved_search',
'entity' => 'SavedSearch',
'bao' => 'CRM_Contact_BAO_SavedSearch',
'localizable' => 0,
) ,
'where_clause' => array(
'name' => 'where_clause',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('Where Clause') ,
'description' => 'the sql where clause if a saved search acl',
'table_name' => 'civicrm_saved_search',
'entity' => 'SavedSearch',
'bao' => 'CRM_Contact_BAO_SavedSearch',
'localizable' => 0,
) ,
'select_tables' => array(
'name' => 'select_tables',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('Select Tables') ,
'description' => 'the tables to be included in a select data',
'table_name' => 'civicrm_saved_search',
'entity' => 'SavedSearch',
'bao' => 'CRM_Contact_BAO_SavedSearch',
'localizable' => 0,
) ,
'where_tables' => array(
'name' => 'where_tables',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('Where Tables') ,
'description' => 'the tables to be included in the count statement',
'table_name' => 'civicrm_saved_search',
'entity' => 'SavedSearch',
'bao' => 'CRM_Contact_BAO_SavedSearch',
'localizable' => 0,
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return self::$_tableName;
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'saved_search', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'saved_search', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array();
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

View file

@ -0,0 +1,286 @@
<?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
*
* Generated from xml/schema/CRM/Contact/SubscriptionHistory.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:8b7f0a4e3593bc26947b4bb6cf54c2d2)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_Contact_DAO_SubscriptionHistory constructor.
*/
class CRM_Contact_DAO_SubscriptionHistory extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_subscription_history';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = true;
/**
* Internal Id
*
* @var int unsigned
*/
public $id;
/**
* Contact Id
*
* @var int unsigned
*/
public $contact_id;
/**
* Group Id
*
* @var int unsigned
*/
public $group_id;
/**
* Date of the (un)subscription
*
* @var timestamp
*/
public $date;
/**
* How the (un)subscription was triggered
*
* @var string
*/
public $method;
/**
* The state of the contact within the group
*
* @var string
*/
public $status;
/**
* IP address or other tracking info
*
* @var string
*/
public $tracking;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_subscription_history';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'contact_id', 'civicrm_contact', 'id');
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'group_id', 'civicrm_group', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group Membership History ID') ,
'description' => 'Internal Id',
'required' => true,
'table_name' => 'civicrm_subscription_history',
'entity' => 'SubscriptionHistory',
'bao' => 'CRM_Contact_BAO_SubscriptionHistory',
'localizable' => 0,
) ,
'contact_id' => array(
'name' => 'contact_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Contact ID') ,
'description' => 'Contact Id',
'required' => true,
'table_name' => 'civicrm_subscription_history',
'entity' => 'SubscriptionHistory',
'bao' => 'CRM_Contact_BAO_SubscriptionHistory',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Contact',
) ,
'group_id' => array(
'name' => 'group_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Group') ,
'description' => 'Group Id',
'table_name' => 'civicrm_subscription_history',
'entity' => 'SubscriptionHistory',
'bao' => 'CRM_Contact_BAO_SubscriptionHistory',
'localizable' => 0,
'FKClassName' => 'CRM_Contact_DAO_Group',
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'table' => 'civicrm_group',
'keyColumn' => 'id',
'labelColumn' => 'title',
)
) ,
'date' => array(
'name' => 'date',
'type' => CRM_Utils_Type::T_TIMESTAMP,
'title' => ts('Group Membership Action Date') ,
'description' => 'Date of the (un)subscription',
'required' => true,
'default' => 'CURRENT_TIMESTAMP',
'table_name' => 'civicrm_subscription_history',
'entity' => 'SubscriptionHistory',
'bao' => 'CRM_Contact_BAO_SubscriptionHistory',
'localizable' => 0,
) ,
'method' => array(
'name' => 'method',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Group Membership Action') ,
'description' => 'How the (un)subscription was triggered',
'maxlength' => 8,
'size' => CRM_Utils_Type::EIGHT,
'table_name' => 'civicrm_subscription_history',
'entity' => 'SubscriptionHistory',
'bao' => 'CRM_Contact_BAO_SubscriptionHistory',
'localizable' => 0,
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'callback' => 'CRM_Core_SelectValues::getSubscriptionHistoryMethods',
)
) ,
'status' => array(
'name' => 'status',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Group Membership Status') ,
'description' => 'The state of the contact within the group',
'maxlength' => 8,
'size' => CRM_Utils_Type::EIGHT,
'table_name' => 'civicrm_subscription_history',
'entity' => 'SubscriptionHistory',
'bao' => 'CRM_Contact_BAO_SubscriptionHistory',
'localizable' => 0,
'pseudoconstant' => array(
'callback' => 'CRM_Core_SelectValues::groupContactStatus',
)
) ,
'tracking' => array(
'name' => 'tracking',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('Group Membership Tracking') ,
'description' => 'IP address or other tracking info',
'maxlength' => 255,
'size' => CRM_Utils_Type::HUGE,
'table_name' => 'civicrm_subscription_history',
'entity' => 'SubscriptionHistory',
'bao' => 'CRM_Contact_BAO_SubscriptionHistory',
'localizable' => 0,
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return self::$_tableName;
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'subscription_history', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'subscription_history', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array();
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,322 @@
<?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 generates form components for custom data.
*
* It delegates the work to lower level subclasses and integrates the changes
* back in. It also uses a lot of functionality with the CRM API's, so any change
* made here could potentially affect the API etc. Be careful, be aware, use unit tests.
*/
class CRM_Contact_Form_CustomData extends CRM_Core_Form {
/**
* The table id, used when editing/creating custom data
*
* @var int
*/
protected $_tableId;
/**
* Entity type of the table id
*
* @var string
*/
protected $_entityType;
/**
* Entity sub type of the table id
*
* @var string
*/
protected $_entitySubType;
/**
* The group tree data
*
* @var array
*/
//protected $_groupTree;
/**
* Which blocks should we show and hide.
*
* @var CRM_Core_ShowHideBlocks
*/
protected $_showHide;
/**
* Array group titles.
*
* @var array
*/
protected $_groupTitle;
/**
* Array group display status.
*
* @var array
*/
protected $_groupCollapseDisplay;
/**
* Custom group id
*
* @int
*/
public $_groupID;
public $_multiRecordDisplay;
public $_copyValueId;
/**
* Pre processing work done here.
*
* Gets session variables for table name, id of entity in table, type of entity and stores them.
*/
public function preProcess() {
$this->_cdType = CRM_Utils_Array::value('type', $_GET);
$this->assign('cdType', FALSE);
$this->_multiRecordDisplay = CRM_Utils_Request::retrieve('multiRecordDisplay', 'String', $this);
if ($this->_cdType || $this->_multiRecordDisplay == 'single') {
if ($this->_cdType) {
$this->assign('cdType', TRUE);
}
// NOTE : group id is not stored in session from within CRM_Custom_Form_CustomData::preProcess func
// this is due to some condition inside it which restricts it from saving in session
// so doing this for multi record edit action
$entityId = CRM_Utils_Request::retrieve('entityID', 'Positive', $this);
if (!empty($entityId)) {
$subType = CRM_Contact_BAO_Contact::getContactSubType($entityId, ',');
}
CRM_Custom_Form_CustomData::preProcess($this, NULL, $subType, NULL, NULL, $entityId);
if ($this->_multiRecordDisplay) {
$this->_groupID = CRM_Utils_Request::retrieve('groupID', 'Positive', $this);
$this->_tableID = $this->_entityId;
$this->_contactType = CRM_Contact_BAO_Contact::getContactType($this->_tableID);
$mode = CRM_Utils_Request::retrieve('mode', 'String', $this);
$hasReachedMax = CRM_Core_BAO_CustomGroup::hasReachedMaxLimit($this->_groupID, $this->_tableID);
if ($hasReachedMax && $mode == 'add') {
CRM_Core_Error::statusBounce(ts('The maximum record limit is reached'));
}
$this->_copyValueId = CRM_Utils_Request::retrieve('copyValueId', 'Positive', $this);
$groupTitle = CRM_Core_BAO_CustomGroup::getTitle($this->_groupID);
$mode = CRM_Utils_Request::retrieve('mode', 'String', CRM_Core_DAO::$_nullObject, FALSE, NULL, 'GET');
$mode = ucfirst($mode);
CRM_Utils_System::setTitle(ts('%1 %2 Record', array(1 => $mode, 2 => $groupTitle)));
if (!empty($_POST['hidden_custom'])) {
$this->assign('postedInfo', TRUE);
}
}
return;
}
$this->_groupID = CRM_Utils_Request::retrieve('groupID', 'Positive', $this, TRUE);
$this->_tableID = CRM_Utils_Request::retrieve('tableId', 'Positive', $this, TRUE);
$this->_contactType = CRM_Contact_BAO_Contact::getContactType($this->_tableID);
$this->_contactSubType = CRM_Contact_BAO_Contact::getContactSubType($this->_tableID, ',');
$this->assign('contact_type', $this->_contactType);
$this->assign('contact_subtype', $this->_contactSubType);
list($displayName, $contactImage) = CRM_Contact_BAO_Contact::getDisplayAndImage($this->_tableID);
CRM_Utils_System::setTitle($displayName, $contactImage . ' ' . $displayName);
// when custom data is included in this page
if (!empty($_POST['hidden_custom'])) {
for ($i = 1; $i <= $_POST['hidden_custom_group_count'][$this->_groupID]; $i++) {
CRM_Custom_Form_CustomData::preProcess($this, NULL, $this->_contactSubType, $i, $this->_contactType, $this->_tableID);
CRM_Custom_Form_CustomData::buildQuickForm($this);
CRM_Custom_Form_CustomData::setDefaultValues($this);
}
}
}
/**
* Build the form object.
*/
public function buildQuickForm() {
if ($this->_cdType || $this->_multiRecordDisplay == 'single') {
// buttons display for multi-valued fields to perform independednt actions
if ($this->_multiRecordDisplay) {
$isMultiple = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup',
$this->_groupID,
'is_multiple'
);
if ($isMultiple) {
$this->assign('multiRecordDisplay', $this->_multiRecordDisplay);
$saveButtonName = $this->_copyValueId ? ts('Save a Copy') : ts('Save');
$this->addButtons(array(
array(
'type' => 'upload',
'name' => $saveButtonName,
'isDefault' => TRUE,
),
array(
'type' => 'upload',
'name' => ts('Save and New'),
'subName' => 'new',
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
}
}
return CRM_Custom_Form_CustomData::buildQuickForm($this);
}
//need to assign custom data type and subtype to the template
$this->assign('entityID', $this->_tableID);
$this->assign('groupID', $this->_groupID);
// make this form an upload since we dont know if the custom data injected dynamically
// is of type file etc
$this->addButtons(array(
array(
'type' => 'upload',
'name' => ts('Save'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
}
/**
* Set the default form values.
*
*
* @return array
* the default array reference
*/
public function setDefaultValues() {
if ($this->_cdType || $this->_multiRecordDisplay == 'single') {
if ($this->_copyValueId) {
// cached tree is fetched
$groupTree = CRM_Core_BAO_CustomGroup::getTree($this->_type,
NULL,
$this->_entityId,
$this->_groupID,
array(),
NULL,
TRUE,
NULL,
FALSE,
TRUE,
$this->_copyValueId
);
$valueIdDefaults = array();
$groupTreeValueId = CRM_Core_BAO_CustomGroup::formatGroupTree($groupTree, $this->_copyValueId, $this);
CRM_Core_BAO_CustomGroup::setDefaults($groupTreeValueId, $valueIdDefaults, FALSE, FALSE, $this->get('action'));
$tableId = $groupTreeValueId[$this->_groupID]['table_id'];
foreach ($valueIdDefaults as $valueIdElementName => $value) {
// build defaults for COPY action for new record saving
$valueIdElementNamePieces = explode('_', $valueIdElementName);
$valueIdElementNamePieces[2] = "-{$this->_groupCount}";
$elementName = implode('_', $valueIdElementNamePieces);
$customDefaultValue[$elementName] = $value;
}
}
else {
$customDefaultValue = CRM_Custom_Form_CustomData::setDefaultValues($this);
}
return $customDefaultValue;
}
$groupTree = CRM_Core_BAO_CustomGroup::getTree($this->_contactType,
NULL,
$this->_tableID,
$this->_groupID,
$this->_contactSubType
);
if (empty($_POST['hidden_custom_group_count'])) {
// custom data building in edit mode (required to handle multi-value)
$groupTree = CRM_Core_BAO_CustomGroup::getTree($this->_contactType, NULL, $this->_tableID,
$this->_groupID, $this->_contactSubType
);
$customValueCount = CRM_Core_BAO_CustomGroup::buildCustomDataView($this, $groupTree, TRUE, $this->_groupID, NULL, NULL, $this->_tableID);
}
else {
$customValueCount = $_POST['hidden_custom_group_count'][$this->_groupID];
}
$this->assign('customValueCount', $customValueCount);
$defaults = array();
return $defaults;
}
/**
* Process the user submitted custom data values.
*/
public function postProcess() {
// Get the form values and groupTree
//CRM-18183
$params = $this->controller->exportValues($this->_name);
CRM_Core_BAO_CustomValueTable::postProcess($params,
'civicrm_contact',
$this->_tableID,
$this->_entityType
);
$table = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $this->_groupID, 'table_name');
$cgcount = CRM_Core_BAO_CustomGroup::customGroupDataExistsForEntity($this->_tableID, $table, TRUE);
$cgcount += 1;
$buttonName = $this->controller->getButtonName();
if ($buttonName == $this->getButtonName('upload', 'new')) {
CRM_Core_Session::singleton()
->pushUserContext(CRM_Utils_System::url('civicrm/contact/view/cd/edit', "reset=1&type={$this->_contactType}&groupID={$this->_groupID}&entityID={$this->_tableID}&cgcount={$cgcount}&multiRecordDisplay=single&mode=add"));
}
// Add entry in the log table
CRM_Core_BAO_Log::register($this->_tableID,
'civicrm_contact',
$this->_tableID
);
if (CRM_Core_Resources::isAjaxMode()) {
$this->ajaxResponse += CRM_Contact_Form_Inline::renderFooter($this->_tableID);
}
CRM_Contact_BAO_GroupContactCache::opportunisticCacheFlush();
}
}

View file

@ -0,0 +1,106 @@
<?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 generates form components for DedupeRules.
*/
class CRM_Contact_Form_DedupeFind extends CRM_Admin_Form {
/**
* Pre processing.
*/
public function preProcess() {
$this->rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE, 0);
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$groupList = array('' => ts('- All Contacts -')) + CRM_Core_PseudoConstant::nestedGroup();
$this->add('select', 'group_id', ts('Select Group'), $groupList, FALSE, array('class' => 'crm-select2 huge'));
if (Civi::settings()->get('dedupe_default_limit')) {
$this->add('text', 'limit', ts('No of contacts to find matches for '));
}
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Continue'),
'isDefault' => TRUE,
),
//hack to support cancel button functionality
array(
'type' => 'submit',
'class' => 'cancel',
'icon' => 'fa-times',
'name' => ts('Cancel'),
),
)
);
}
/**
* Set the default values for the form.
*
* @return array
*/
public function setDefaultValues() {
$this->_defaults['limit'] = Civi::settings()->get('dedupe_default_limit');
return $this->_defaults;
}
/**
* Process the form submission.
*/
public function postProcess() {
$values = $this->exportValues();
if (!empty($_POST['_qf_DedupeFind_submit'])) {
//used for cancel button
CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/deduperules', 'reset=1'));
return;
}
$url = CRM_Utils_System::url('civicrm/contact/dedupefind', "reset=1&action=update&rgid={$this->rgid}");
if ($values['group_id']) {
$url .= "&gid={$values['group_id']}";
}
if (!empty($values['limit'])) {
$url .= '&limit=' . $values['limit'];
}
CRM_Utils_System::redirect($url);
}
}

View file

@ -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
*/
/**
* This class generates form components for DedupeRules.
*/
class CRM_Contact_Form_DedupeRules extends CRM_Admin_Form {
const RULES_COUNT = 5;
protected $_contactType;
protected $_fields = array();
protected $_rgid;
/**
* Explicitly declare the entity api name.
*/
public function getDefaultEntity() {
return 'RuleGroup';
}
/**
* Pre processing.
*/
public function preProcess() {
// Ensure user has permission to be here
if (!CRM_Core_Permission::check('administer dedupe rules')) {
CRM_Utils_System::permissionDenied();
CRM_Utils_System::civiExit();
}
$this->_options = CRM_Core_SelectValues::getDedupeRuleTypes();
$this->_rgid = CRM_Utils_Request::retrieve('id', 'Positive', $this, FALSE, 0);
$contactTypes = civicrm_api3('Contact', 'getOptions', array('field' => "contact_type"));
$contactType = CRM_Utils_Request::retrieve('contact_type', 'String', $this, FALSE, 0);
if (CRM_Utils_Array::value($contactType, $contactTypes['values'])) {
$this->_contactType = CRM_Utils_Array::value($contactType, $contactTypes['values']);
}
elseif (!empty($contactType)) {
throw new CRM_Core_Exception('Contact Type is Not valid');
}
if ($this->_rgid) {
$rgDao = new CRM_Dedupe_DAO_RuleGroup();
$rgDao->id = $this->_rgid;
$rgDao->find(TRUE);
$this->_defaults['threshold'] = $rgDao->threshold;
$this->_contactType = $rgDao->contact_type;
$this->_defaults['used'] = $rgDao->used;
$this->_defaults['title'] = $rgDao->title;
$this->_defaults['name'] = $rgDao->name;
$this->_defaults['is_reserved'] = $rgDao->is_reserved;
$this->assign('isReserved', $rgDao->is_reserved);
$this->assign('ruleName', $rgDao->name);
$ruleDao = new CRM_Dedupe_DAO_Rule();
$ruleDao->dedupe_rule_group_id = $this->_rgid;
$ruleDao->find();
$count = 0;
while ($ruleDao->fetch()) {
$this->_defaults["where_$count"] = "{$ruleDao->rule_table}.{$ruleDao->rule_field}";
$this->_defaults["length_$count"] = $ruleDao->rule_length;
$this->_defaults["weight_$count"] = $ruleDao->rule_weight;
$count++;
}
}
$supported = CRM_Dedupe_BAO_RuleGroup::supportedFields($this->_contactType);
if (is_array($supported)) {
foreach ($supported as $table => $fields) {
foreach ($fields as $field => $title) {
$this->_fields["$table.$field"] = $title;
}
}
}
asort($this->_fields);
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$this->addField('title', array('label' => ts('Rule Name')), TRUE);
$this->addRule('title', ts('A duplicate matching rule with this name already exists. Please select another name.'),
'objectExists', array('CRM_Dedupe_DAO_RuleGroup', $this->_rgid, 'title')
);
$this->addField('used', array('label' => ts('Usage')), TRUE);
$disabled = array();
$reserved = $this->addField('is_reserved', array('label' => ts('Reserved?')));
if (!empty($this->_defaults['is_reserved'])) {
$reserved->freeze();
}
$attributes = array('class' => 'two');
if (!empty($disabled)) {
$attributes = array_merge($attributes, $disabled);
}
for ($count = 0; $count < self::RULES_COUNT; $count++) {
$this->add('select', "where_$count", ts('Field'),
array(
NULL => ts('- none -'),
) + $this->_fields, FALSE, $disabled
);
$this->addField("length_$count", array('entity' => 'Rule', 'name' => 'rule_length') + $attributes);
$this->addField("weight_$count", array('entity' => 'Rule', 'name' => 'rule_weight') + $attributes);
}
$this->addField('threshold', array('label' => ts("Weight Threshold to Consider Contacts 'Matching':")) + $attributes);
$this->assign('contact_type', $this->_contactType);
$this->addFormRule(array('CRM_Contact_Form_DedupeRules', 'formRule'), $this);
parent::buildQuickForm();
}
/**
* Global validation rules for the form.
*
* @param array $fields
* Posted values of the form.
*
* @param $files
* @param $self
*
* @return array
* list of errors to be posted back to the form
*/
public static function formRule($fields, $files, $self) {
$errors = array();
$fieldSelected = FALSE;
for ($count = 0; $count < self::RULES_COUNT; $count++) {
if (!empty($fields["where_$count"]) || (isset($self->_defaults['is_reserved']) && !empty($self->_defaults["where_$count"]))) {
$fieldSelected = TRUE;
break;
}
}
if (empty($fields['threshold'])) {
// CRM-20607 - Don't validate the threshold of hard-coded rules
if (!(CRM_Utils_Array::value('is_reserved', $fields) &&
CRM_Utils_File::isIncludable("CRM/Dedupe/BAO/QueryBuilder/{$self->_defaultValues['name']}.php"))) {
$errors['threshold'] = ts('Threshold weight cannot be empty or zero.');
}
}
if (!$fieldSelected) {
$errors['_qf_default'] = ts('Please select at least one field.');
}
return empty($errors) ? TRUE : $errors;
}
/**
* Set default values for the form. MobileProvider that in edit/view mode
* the default values are retrieved from the database
*
*
* @return array
*/
/**
* @return array
*/
public function setDefaultValues() {
return $this->_defaults;
}
/**
* Process the form submission.
*/
public function postProcess() {
$values = $this->exportValues();
//FIXME: Handle logic to replace is_default column by usage
// reset used column to General (since there can only
// be one 'Supervised' or 'Unsupervised' rule)
if ($values['used'] != 'General') {
$query = "
UPDATE civicrm_dedupe_rule_group
SET used = 'General'
WHERE contact_type = %1
AND used = %2";
$queryParams = array(
1 => array($this->_contactType, 'String'),
2 => array($values['used'], 'String'),
);
CRM_Core_DAO::executeQuery($query, $queryParams);
}
$rgDao = new CRM_Dedupe_DAO_RuleGroup();
if ($this->_action & CRM_Core_Action::UPDATE) {
$rgDao->id = $this->_rgid;
}
$rgDao->title = $values['title'];
$rgDao->is_reserved = CRM_Utils_Array::value('is_reserved', $values, FALSE);
$rgDao->used = $values['used'];
$rgDao->contact_type = $this->_contactType;
$rgDao->threshold = $values['threshold'];
$rgDao->save();
// make sure name is set only during insert
if ($this->_action & CRM_Core_Action::ADD) {
// generate name based on title
$rgDao->name = CRM_Utils_String::titleToVar($values['title']) . "_{$rgDao->id}";
$rgDao->save();
}
// lets skip updating of fields for reserved dedupe group
if (CRM_Utils_Array::value('is_reserved', $this->_defaults)) {
CRM_Core_Session::setStatus(ts("The rule '%1' has been saved.", array(1 => $rgDao->title)), ts('Saved'), 'success');
return;
}
$ruleDao = new CRM_Dedupe_DAO_Rule();
$ruleDao->dedupe_rule_group_id = $rgDao->id;
$ruleDao->delete();
$ruleDao->free();
$substrLenghts = array();
$tables = array();
$daoObj = new CRM_Core_DAO();
$database = $daoObj->database();
for ($count = 0; $count < self::RULES_COUNT; $count++) {
if (empty($values["where_$count"])) {
continue;
}
list($table, $field) = explode('.', CRM_Utils_Array::value("where_$count", $values));
$length = !empty($values["length_$count"]) ? CRM_Utils_Array::value("length_$count", $values) : NULL;
$weight = $values["weight_$count"];
if ($table and $field) {
$ruleDao = new CRM_Dedupe_DAO_Rule();
$ruleDao->dedupe_rule_group_id = $rgDao->id;
$ruleDao->rule_table = $table;
$ruleDao->rule_field = $field;
$ruleDao->rule_length = $length;
$ruleDao->rule_weight = $weight;
$ruleDao->save();
$ruleDao->free();
if (!array_key_exists($table, $tables)) {
$tables[$table] = array();
}
$tables[$table][] = $field;
}
// CRM-6245: we must pass table/field/length triples to the createIndexes() call below
if ($length) {
if (!isset($substrLenghts[$table])) {
$substrLenghts[$table] = array();
}
//CRM-13417 to avoid fatal error "Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys, 1089"
$schemaQuery = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '{$database}' AND
TABLE_NAME = '{$table}' AND COLUMN_NAME = '{$field}';";
$dao = CRM_Core_DAO::executeQuery($schemaQuery);
if ($dao->fetch()) {
// set the length to null for all the fields where prefix length is not supported. eg. int,tinyint,date,enum etc dataTypes.
if ($dao->COLUMN_NAME == $field && !in_array($dao->DATA_TYPE, array(
'char',
'varchar',
'binary',
'varbinary',
'text',
'blob',
))
) {
$length = NULL;
}
elseif ($dao->COLUMN_NAME == $field && !empty($dao->CHARACTER_MAXIMUM_LENGTH) && ($length > $dao->CHARACTER_MAXIMUM_LENGTH)) {
//set the length to CHARACTER_MAXIMUM_LENGTH in case the length provided by the user is greater than the limit
$length = $dao->CHARACTER_MAXIMUM_LENGTH;
}
}
$substrLenghts[$table][$field] = $length;
}
}
// also create an index for this dedupe rule
// CRM-3837
CRM_Utils_Hook::dupeQuery($ruleDao, 'dedupeIndexes', $tables);
CRM_Core_BAO_SchemaHandler::createIndexes($tables, 'dedupe_index', $substrLenghts);
//need to clear cache of deduped contacts
//based on the previous rule
$cacheKey = "merge {$this->_contactType}_{$this->_rgid}_%";
CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey);
CRM_Core_Session::setStatus(ts("The rule '%1' has been saved.", array(1 => $rgDao->title)), ts('Saved'), 'success');
}
}

View file

@ -0,0 +1,313 @@
<?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 to build the form for adding Group.
*/
class CRM_Contact_Form_Domain extends CRM_Core_Form {
/**
* The group id, used when editing a group
*
* @var int
*/
protected $_id;
/**
* The contact_id of domain.
*
* @var int
*/
protected $_contactId;
/**
* Default from email address option value id.
*
* @var int
*/
protected $_fromEmailId = NULL;
/**
* Default location type fields.
*
* @var array
*/
protected $_locationDefaults = array();
/**
* How many locationBlocks should we display?
*
* @var int
* @const
*/
const LOCATION_BLOCKS = 1;
/**
* Explicitly declare the entity api name.
*/
public function getDefaultEntity() {
return 'Domain';
}
/**
* Explicitly declare the form context.
*/
public function getDefaultContext() {
return 'create';
}
public function preProcess() {
CRM_Utils_System::setTitle(ts('Organization Address and Contact Info'));
$breadCrumbPath = CRM_Utils_System::url('civicrm/admin', 'reset=1');
CRM_Utils_System::appendBreadCrumb(ts('Administer CiviCRM'), $breadCrumbPath);
$session = CRM_Core_Session::singleton();
$session->replaceUserContext(CRM_Utils_System::url('civicrm/admin', 'reset=1'));
$this->_id = CRM_Core_Config::domainID();
$this->_action = CRM_Utils_Request::retrieve('action', 'String',
$this, FALSE, 'view'
);
//location blocks.
$location = new CRM_Contact_Form_Location();
$location->preProcess($this);
}
/**
* This virtual function is used to set the default values of.
* various form elements
*
* @return array
* reference to the array of default values
*
*/
public function setDefaultValues() {
$defaults = array();
$params = array();
if (isset($this->_id)) {
$params['id'] = $this->_id;
CRM_Core_BAO_Domain::retrieve($params, $domainDefaults);
$this->_contactId = $domainDefaults['contact_id'];
//get the default domain from email address. fix CRM-3552
$optionValues = array();
$grpParams['name'] = 'from_email_address';
CRM_Core_OptionValue::getValues($grpParams, $optionValues);
foreach ($optionValues as $Id => $value) {
if ($value['is_default'] && $value['is_active']) {
$this->_fromEmailId = $Id;
$list = explode('"', $value['label']);
$domainDefaults['email_name'] = CRM_Utils_Array::value(1, $list);
$domainDefaults['email_address'] = CRM_Utils_Mail::pluckEmailFromHeader($value['label']);
break;
}
}
unset($params['id']);
$locParams = array('contact_id' => $domainDefaults['contact_id']);
$this->_locationDefaults = $defaults = CRM_Core_BAO_Location::getValues($locParams);
$config = CRM_Core_Config::singleton();
if (!isset($defaults['address'][1]['country_id'])) {
$defaults['address'][1]['country_id'] = $config->defaultContactCountry;
}
if (!isset($defaults['address'][1]['state_province_id'])) {
$defaults['address'][1]['state_province_id'] = $config->defaultContactStateProvince;
}
}
$defaults = array_merge($defaults, $domainDefaults);
return $defaults;
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$this->addField('name', array('label' => ts('Organization Name')), TRUE);
$this->addField('description', array('label' => ts('Description'), 'size' => 30));
$this->add('text', 'email_name', ts('FROM Name'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', 'email'), TRUE);
$this->add('text', 'email_address', ts('FROM Email Address'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', 'email'), TRUE);
$this->addRule('email_address', ts('Domain Email Address must use a valid email address format (e.g. \'info@example.org\').'), 'email');
//build location blocks.
CRM_Contact_Form_Location::buildQuickForm($this);
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Save'),
'subName' => 'view',
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
));
if ($this->_action & CRM_Core_Action::VIEW) {
$this->freeze();
}
$this->assign('emailDomain', TRUE);
}
/**
* Add local and global form rules.
*/
public function addRules() {
$this->addFormRule(array('CRM_Contact_Form_Domain', 'formRule'));
}
/**
* Global validation rules for the form.
*
* @param array $fields
* Posted values of the form.
*
* @return array
* list of errors to be posted back to the form
*/
public static function formRule($fields) {
// check for state/country mapping
$errors = CRM_Contact_Form_Edit_Address::formRule($fields, CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullObject);
// $errors === TRUE means no errors from above formRule excution,
// so declaring $errors to array for further processing
if ($errors === TRUE) {
$errors = array();
}
//fix for CRM-3552,
//as we use "fromName"<emailaddresss> format for domain email.
if (strpos($fields['email_name'], '"') !== FALSE) {
$errors['email_name'] = ts('Double quotes are not allow in from name.');
}
// Check for default from email address and organization (domain) name. Force them to change it.
if ($fields['email_address'] == 'info@EXAMPLE.ORG') {
$errors['email_address'] = ts('Please enter a valid default FROM email address for system-generated emails.');
}
if ($fields['name'] == 'Default Domain Name') {
$errors['name'] = ts('Please enter the name of the organization or entity which owns this CiviCRM site.');
}
return empty($errors) ? TRUE : $errors;
}
/**
* Process the form when submitted.
*/
public function postProcess() {
$params = $this->exportValues();
$params['entity_id'] = $this->_id;
$params['entity_table'] = CRM_Core_BAO_Domain::getTableName();
$domain = CRM_Core_BAO_Domain::edit($params, $this->_id);
$defaultLocationType = CRM_Core_BAO_LocationType::getDefault();
if (isset($this->_locationDefaults['address'][1]['location_type_id'])) {
$params['address'][1]['location_type_id'] = $this->_locationDefaults['address'][1]['location_type_id'];
}
else {
$params['address'][1]['location_type_id'] = $defaultLocationType->id;
}
if (isset($this->_locationDefaults['phone'][1]['location_type_id'])) {
$params['phone'][1]['location_type_id'] = $this->_locationDefaults['phone'][1]['location_type_id'];
}
else {
$params['phone'][1]['location_type_id'] = $defaultLocationType->id;
}
if (isset($this->_locationDefaults['email'][1]['location_type_id'])) {
$params['email'][1]['location_type_id'] = $this->_locationDefaults['email'][1]['location_type_id'];
}
else {
$params['email'][1]['location_type_id'] = $defaultLocationType->id;
}
$params += array('contact_id' => $this->_contactId);
$contactParams = array(
'sort_name' => $domain->name,
'display_name' => $domain->name,
'legal_name' => $domain->name,
'organization_name' => $domain->name,
'contact_id' => $this->_contactId,
'contact_type' => 'Organization',
);
if ($this->_contactId) {
$contactParams['contact_sub_type'] = CRM_Contact_BAO_Contact::getContactSubType($this->_contactId);
}
CRM_Contact_BAO_Contact::add($contactParams);
CRM_Core_BAO_Location::create($params, TRUE);
CRM_Core_BAO_Domain::edit($params, $this->_id);
//set domain from email address, CRM-3552
$emailName = '"' . $params['email_name'] . '" <' . $params['email_address'] . '>';
$emailParams = array(
'label' => $emailName,
'description' => $params['description'],
'is_active' => 1,
'is_default' => 1,
);
$groupParams = array('name' => 'from_email_address');
//get the option value wt.
if ($this->_fromEmailId) {
$action = $this->_action;
$emailParams['weight'] = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue', $this->_fromEmailId, 'weight');
}
else {
//add from email address.
$action = CRM_Core_Action::ADD;
$grpId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', 'from_email_address', 'id', 'name');
$fieldValues = array('option_group_id' => $grpId);
$emailParams['weight'] = CRM_Utils_Weight::getDefaultWeight('CRM_Core_DAO_OptionValue', $fieldValues);
}
//reset default within domain.
$emailParams['reset_default_for'] = array('domain_id' => CRM_Core_Config::domainID());
CRM_Core_OptionValue::addOptionValue($emailParams, $groupParams, $action, $this->_fromEmailId);
CRM_Core_Session::setStatus(ts("Domain information for '%1' has been saved.", array(1 => $domain->name)), ts('Saved'), 'success');
$session = CRM_Core_Session::singleton();
$session->replaceUserContext(CRM_Utils_System::url('civicrm/admin', 'reset=1'));
}
}

View file

@ -0,0 +1,442 @@
<?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 used to build address block.
*/
class CRM_Contact_Form_Edit_Address {
/**
* Build form for address input fields.
*
* @param CRM_Core_Form $form
* @param int $addressBlockCount
* The index of the address array (if multiple addresses on a page).
* @param bool $sharing
* False, if we want to skip the address sharing features.
* @param bool $inlineEdit
* True when edit used in inline edit.
*/
public static function buildQuickForm(&$form, $addressBlockCount = NULL, $sharing = TRUE, $inlineEdit = FALSE) {
// passing this via the session is AWFUL. we need to fix this
if (!$addressBlockCount) {
$blockId = ($form->get('Address_Block_Count')) ? $form->get('Address_Block_Count') : 1;
}
else {
$blockId = $addressBlockCount;
}
$config = CRM_Core_Config::singleton();
$countryDefault = $config->defaultContactCountry;
$form->applyFilter('__ALL__', 'trim');
$js = array();
if (!$inlineEdit) {
$js = array('onChange' => 'checkLocation( this.id );', 'placeholder' => NULL);
}
//make location type required for inline edit
$form->addField("address[$blockId][location_type_id]", array('entity' => 'address', 'class' => 'eight', 'option_url' => NULL) + $js, $inlineEdit);
if (!$inlineEdit) {
$js = array('id' => 'Address_' . $blockId . '_IsPrimary', 'onClick' => 'singleSelect( this.id );');
}
$form->addField(
"address[$blockId][is_primary]", array(
'entity' => 'address',
'label' => ts('Primary location for this contact'),
'text' => ts('Primary location for this contact')) + $js);
if (!$inlineEdit) {
$js = array('id' => 'Address_' . $blockId . '_IsBilling', 'onClick' => 'singleSelect( this.id );');
}
$form->addField(
"address[$blockId][is_billing]", array(
'entity' => 'address',
'label' => ts('Billing location for this contact'),
'text' => ts('Billing location for this contact')) + $js);
// hidden element to store master address id
$form->addField("address[$blockId][master_id]", array('entity' => 'address', 'type' => 'hidden'));
$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(
'address_name',
'street_address',
'supplemental_address_1',
'supplemental_address_2',
'supplemental_address_3',
'city',
'postal_code',
'postal_code_suffix',
'country_id',
'state_province_id',
'county_id',
'geo_code_1',
'geo_code_2',
'street_number',
'street_name',
'street_unit',
);
foreach ($elements as $name) {
//Remove id from name, to allow comparison against enabled addressOtions.
$nameWithoutID = strpos($name, '_id') !== FALSE ? substr($name, 0, -3) : $name;
// Skip fields which are not enabled in the address options.
if (empty($addressOptions[$nameWithoutID])) {
$continue = TRUE;
//Don't skip street parsed fields when parsing is enabled.
if (in_array($nameWithoutID, array(
'street_number',
'street_name',
'street_unit',
)) && !empty($addressOptions['street_address_parsing'])
) {
$continue = FALSE;
}
if ($continue) {
continue;
}
}
if ($name == 'address_name') {
$name = 'name';
}
$params = array('entity' => 'address');
if ($name == 'postal_code_suffix') {
$params['label'] = ts('Suffix');
}
$form->addField("address[$blockId][$name]", $params);
}
$entityId = NULL;
if (!empty($form->_values['address']) && !empty($form->_values['address'][$blockId])) {
$entityId = $form->_values['address'][$blockId]['id'];
}
// CRM-11665 geocode override option
$geoCode = FALSE;
if (!empty($config->geocodeMethod)) {
$geoCode = TRUE;
$form->addElement('checkbox',
"address[$blockId][manual_geo_code]",
ts('Override automatic geocoding')
);
}
$form->assign('geoCode', $geoCode);
// Process any address custom data -
$groupTree = CRM_Core_BAO_CustomGroup::getTree('Address', NULL, $entityId);
if (isset($groupTree) && is_array($groupTree)) {
// use simplified formatted groupTree
$groupTree = CRM_Core_BAO_CustomGroup::formatGroupTree($groupTree, 1, $form);
// make sure custom fields are added /w element-name in the format - 'address[$blockId][custom-X]'
foreach ($groupTree as $id => $group) {
foreach ($group['fields'] as $fldId => $field) {
$groupTree[$id]['fields'][$fldId]['element_custom_name'] = $field['element_name'];
$groupTree[$id]['fields'][$fldId]['element_name'] = "address[$blockId][{$field['element_name']}]";
}
}
$defaults = array();
CRM_Core_BAO_CustomGroup::setDefaults($groupTree, $defaults);
// since we change element name for address custom data, we need to format the setdefault values
$addressDefaults = array();
foreach ($defaults as $key => $val) {
if (empty($val)) {
continue;
}
// inorder to set correct defaults for checkbox custom data, we need to converted flat key to array
// this works for all types custom data
$keyValues = explode('[', str_replace(']', '', $key));
$addressDefaults[$keyValues[0]][$keyValues[1]][$keyValues[2]] = $val;
}
$form->setDefaults($addressDefaults);
// we setting the prefix to 'dnc_' below, so that we don't overwrite smarty's grouptree var.
// And we can't set it to 'address_' because we want to set it in a slightly different format.
CRM_Core_BAO_CustomGroup::buildQuickForm($form, $groupTree, FALSE, 'dnc_');
// during contact editing : if no address is filled
// required custom data must not produce 'required' form rule error
// more handling done in formRule func
CRM_Contact_Form_Edit_Address::storeRequiredCustomDataInfo($form, $groupTree);
$template = CRM_Core_Smarty::singleton();
$tplGroupTree = $template->get_template_vars('address_groupTree');
$tplGroupTree = empty($tplGroupTree) ? array() : $tplGroupTree;
$form->assign('address_groupTree', $tplGroupTree + array($blockId => $groupTree));
// unset the temp smarty var that got created
$form->assign('dnc_groupTree', NULL);
}
// address custom data processing ends ..
if ($sharing) {
// shared address
$form->addElement('checkbox', "address[$blockId][use_shared_address]", NULL, ts('Use another contact\'s address'));
// Override the default profile links to add address form
$profileLinks = CRM_Core_BAO_UFGroup::getCreateLinks(array(
'new_individual',
'new_organization',
'new_household',
), 'shared_address');
$form->addEntityRef("address[$blockId][master_contact_id]", ts('Share With'), array('create' => $profileLinks));
}
}
/**
* Check for correct state / country mapping.
*
* @param array $fields
* @param array $files
* @param CRM_Core_Form $self
*
* @return array|bool
* if no errors
*/
public static function formRule($fields, $files = array(), $self = NULL) {
$errors = array();
$customDataRequiredFields = array();
if ($self && property_exists($self, '_addressRequireOmission')) {
$customDataRequiredFields = explode(',', $self->_addressRequireOmission);
}
if (!empty($fields['address']) && is_array($fields['address'])) {
foreach ($fields['address'] as $instance => $addressValues) {
if (CRM_Utils_System::isNull($addressValues)) {
// DETACH 'required' form rule error to
// custom data only if address data not exists upon submission
if (!empty($customDataRequiredFields)) {
foreach ($customDataRequiredFields as $customElementName) {
$elementName = "address[$instance][$customElementName]";
if ($self->getElementError($elementName)) {
// set element error to none
$self->setElementError($elementName, NULL);
}
}
}
continue;
}
// DETACH 'required' form rule error to
// custom data if address data not exists upon submission
// or if master address is selected
if (!empty($customDataRequiredFields) && (!CRM_Core_BAO_Address::dataExists($addressValues) || !empty($addressValues['master_id']))) {
foreach ($customDataRequiredFields as $customElementName) {
$elementName = "address[$instance][$customElementName]";
if ($self->getElementError($elementName)) {
// set element error to none
$self->setElementError($elementName, NULL);
}
}
}
if (!empty($addressValues['use_shared_address']) && empty($addressValues['master_id'])) {
$errors["address[$instance][use_shared_address]"] = ts('Please select valid shared contact or a contact with valid address.');
}
}
}
return empty($errors) ? TRUE : $errors;
}
/**
* Set default values for address block.
*
* @param array $defaults
* Defaults associated array.
* @param CRM_Core_Form $form
* Form object.
*/
public static function setDefaultValues(&$defaults, &$form) {
$addressValues = array();
if (isset($defaults['address']) && is_array($defaults['address']) &&
!CRM_Utils_System::isNull($defaults['address'])
) {
// start of contact shared adddress defaults
$sharedAddresses = array();
$masterAddress = array();
// get contact name of shared contact names
$shareAddressContactNames = CRM_Contact_BAO_Contact_Utils::getAddressShareContactNames($defaults['address']);
foreach ($defaults['address'] as $key => $addressValue) {
if (!empty($addressValue['master_id']) && !$shareAddressContactNames[$addressValue['master_id']]['is_deleted']) {
$master_cid = $shareAddressContactNames[$addressValue['master_id']]['contact_id'];
$sharedAddresses[$key]['shared_address_display'] = array(
'address' => $addressValue['display'],
'name' => $shareAddressContactNames[$addressValue['master_id']]['name'],
'options' => CRM_Core_BAO_Address::getValues(array(
'entity_id' => $master_cid,
'contact_id' => $master_cid,
)),
'master_id' => $addressValue['master_id'],
);
$defaults['address'][$key]['master_contact_id'] = $master_cid;
}
else {
$defaults['address'][$key]['use_shared_address'] = 0;
}
//check if any address is shared by any other contacts
$masterAddress[$key] = CRM_Core_BAO_Address::checkContactSharedAddress($addressValue['id']);
}
$form->assign('sharedAddresses', $sharedAddresses);
$form->assign('masterAddress', $masterAddress);
// end of shared address defaults
// start of parse address functionality
// build street address, CRM-5450.
if ($form->_parseStreetAddress) {
$parseFields = array('street_address', 'street_number', 'street_name', 'street_unit');
foreach ($defaults['address'] as $cnt => & $address) {
$streetAddress = NULL;
foreach (array(
'street_number',
'street_number_suffix',
'street_name',
'street_unit',
) as $fld) {
if (in_array($fld, array(
'street_name',
'street_unit',
))) {
$streetAddress .= ' ';
}
// CRM-17619 - if the street number suffix begins with a number, add a space
$numsuffix = CRM_Utils_Array::value($fld, $address);
if ($fld === 'street_number_suffix' && !empty($numsuffix)) {
if (ctype_digit(substr($numsuffix, 0, 1))) {
$streetAddress .= ' ';
}
}
$streetAddress .= CRM_Utils_Array::value($fld, $address);
}
$streetAddress = trim($streetAddress);
if (!empty($streetAddress)) {
$address['street_address'] = $streetAddress;
}
if (isset($address['street_number'])) {
// CRM-17619 - if the street number suffix begins with a number, add a space
$thesuffix = CRM_Utils_Array::value('street_number_suffix', $address);
if ($thesuffix) {
if (ctype_digit(substr($thesuffix, 0, 1))) {
$address['street_number'] .= " ";
}
}
$address['street_number'] .= $thesuffix;
}
// build array for set default.
foreach ($parseFields as $field) {
$addressValues["{$field}_{$cnt}"] = CRM_Utils_Array::value($field, $address);
}
// don't load fields, use js to populate.
foreach (array('street_number', 'street_name', 'street_unit') as $f) {
if (isset($address[$f])) {
unset($address[$f]);
}
}
}
$form->assign('allAddressFieldValues', json_encode($addressValues));
//hack to handle show/hide address fields.
$parsedAddress = array();
if ($form->_contactId && !empty($_POST['address']) && is_array($_POST['address'])
) {
foreach ($_POST['address'] as $cnt => $values) {
$showField = 'streetAddress';
foreach (array('street_number', 'street_name', 'street_unit') as $fld) {
if (!empty($values[$fld])) {
$showField = 'addressElements';
break;
}
}
$parsedAddress[$cnt] = $showField;
}
}
$form->assign('showHideAddressFields', $parsedAddress);
$form->assign('loadShowHideAddressFields', empty($parsedAddress) ? FALSE : TRUE);
}
// end of parse address functionality
}
}
/**
* Store required custom data info.
*
* @param CRM_Core_Form $form
* @param array $groupTree
*/
public static function storeRequiredCustomDataInfo(&$form, $groupTree) {
if (in_array(CRM_Utils_System::getClassName($form), array('CRM_Contact_Form_Contact', 'CRM_Contact_Form_Inline_Address'))) {
$requireOmission = NULL;
foreach ($groupTree as $csId => $csVal) {
// only process Address entity fields
if ($csVal['extends'] != 'Address') {
continue;
}
foreach ($csVal['fields'] as $cdId => $cdVal) {
if ($cdVal['is_required']) {
$elementName = $cdVal['element_name'];
if (in_array($elementName, $form->_required)) {
// store the omitted rule for a element, to be used later on
$requireOmission .= $cdVal['element_custom_name'] . ',';
}
}
}
}
$form->_addressRequireOmission = rtrim($requireOmission, ',');
}
}
}

View file

@ -0,0 +1,240 @@
<?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
*/
/**
* Form helper class for an Communication Preferences object.
*/
class CRM_Contact_Form_Edit_CommunicationPreferences {
/**
* Greetings.
*
* @var array
*/
static $greetings = array();
/**
* Build the form object elements for Communication Preferences object.
*
* @param CRM_Core_Form $form
* Reference to the form object.
*/
public static function buildQuickForm(&$form) {
// since the pcm - preferred communication method is logically
// grouped hence we'll use groups of HTML_QuickForm
// checkboxes for DO NOT phone, email, mail
// we take labels from SelectValues
$privacy = $commPreff = $commPreference = array();
$privacyOptions = CRM_Core_SelectValues::privacy();
// we add is_opt_out as a separate checkbox below for display and help purposes so remove it here
unset($privacyOptions['is_opt_out']);
foreach ($privacyOptions as $name => $label) {
$privacy[] = $form->createElement('advcheckbox', $name, NULL, $label);
}
$form->addGroup($privacy, 'privacy', ts('Privacy'), '&nbsp;<br/>');
// preferred communication method
$comm = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method', array('loclize' => TRUE));
foreach ($comm as $value => $title) {
$commPreff[] = $form->createElement('advcheckbox', $value, NULL, $title);
}
$form->addField('preferred_communication_method', array('entity' => 'contact', 'type' => 'CheckBoxGroup'));
$form->addField('preferred_language', array('entity' => 'contact'));
if (!empty($privacyOptions)) {
$commPreference['privacy'] = $privacyOptions;
}
if (!empty($comm)) {
$commPreference['preferred_communication_method'] = $comm;
}
//using for display purpose.
$form->assign('commPreference', $commPreference);
$form->addField('preferred_mail_format', array('entity' => 'contact', 'label' => ts('Email Format')));
$form->addField('is_opt_out', array('entity' => 'contact', 'label' => ts('NO BULK EMAILS (User Opt Out)')));
$form->addField('communication_style_id', array('entity' => 'contact', 'type' => 'RadioGroup'));
//check contact type and build filter clause accordingly for greeting types, CRM-4575
$greetings = self::getGreetingFields($form->_contactType);
foreach ($greetings as $greeting => $fields) {
$filter = array(
'contact_type' => $form->_contactType,
'greeting_type' => $greeting,
);
//add addressee in Contact form
$greetingTokens = CRM_Core_PseudoConstant::greeting($filter);
if (!empty($greetingTokens)) {
$form->addElement('select', $fields['field'], $fields['label'],
array(
'' => ts('- select -'),
) + $greetingTokens
);
//custom addressee
$form->addElement('text', $fields['customField'], $fields['customLabel'],
CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Contact', $fields['customField']), $fields['js']
);
}
}
}
/**
* Global form rule.
*
* @param array $fields
* The input form values.
* @param array $files
* The uploaded files if any.
* @param CRM_Contact_Form_Edit_CommunicationPreferences $self
*
* @return bool|array
* true if no errors, else array of errors
*/
public static function formRule($fields, $files, $self) {
//CRM-4575
$greetings = self::getGreetingFields($self->_contactType);
foreach ($greetings as $greeting => $details) {
$customizedValue = CRM_Core_PseudoConstant::getKey('CRM_Contact_BAO_Contact', $details['field'], 'Customized');
if (CRM_Utils_Array::value($details['field'], $fields) == $customizedValue && empty($fields[$details['customField']])) {
$errors[$details['customField']] = ts('Custom %1 is a required field if %1 is of type Customized.',
array(1 => $details['label'])
);
}
}
if (array_key_exists('preferred_mail_format', $fields) && empty($fields['preferred_mail_format'])) {
$errors['preferred_mail_format'] = ts('Please select an email format preferred by this contact.');
}
return empty($errors) ? TRUE : $errors;
}
/**
* Set default values for the form.
*
* @param CRM_Core_Form $form
* @param array $defaults
*/
public static function setDefaultValues(&$form, &$defaults) {
if (!empty($defaults['preferred_language'])) {
$languages = CRM_Contact_BAO_Contact::buildOptions('preferred_language');
$defaults['preferred_language'] = CRM_Utils_Array::key($defaults['preferred_language'], $languages);
}
// CRM-7119: set preferred_language to default if unset
if (empty($defaults['preferred_language'])) {
$config = CRM_Core_Config::singleton();
$defaults['preferred_language'] = $config->lcMessages;
}
if (empty($defaults['communication_style_id'])) {
$defaults['communication_style_id'] = array_pop(CRM_Core_OptionGroup::values('communication_style', TRUE, NULL, NULL, 'AND is_default = 1'));
}
// CRM-17778 -- set preferred_mail_format to default if unset
if (empty($defaults['preferred_mail_format'])) {
$defaults['preferred_mail_format'] = 'Both';
}
else {
$defaults['preferred_mail_format'] = array_search($defaults['preferred_mail_format'], CRM_Core_SelectValues::pmf());
}
//set default from greeting types CRM-4575, CRM-9739
if ($form->_action & CRM_Core_Action::ADD) {
foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
if (empty($defaults[$greeting . '_id'])) {
if ($defaultGreetingTypeId = CRM_Contact_BAO_Contact_Utils::defaultGreeting($form->_contactType, $greeting)
) {
$defaults[$greeting . '_id'] = $defaultGreetingTypeId;
}
}
}
}
else {
foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
$name = "{$greeting}_display";
$form->assign($name, CRM_Utils_Array::value($name, $defaults));
}
}
}
/**
* Set array of greeting fields.
*
* @param string $contactType
*/
public static function getGreetingFields($contactType) {
if (empty(self::$greetings[$contactType])) {
self::$greetings[$contactType] = array();
$js = array(
'onfocus' => "if (!this.value) { this.value='Dear ';} else return false",
'onblur' => "if ( this.value == 'Dear') { this.value='';} else return false",
);
self::$greetings[$contactType] = array(
'addressee' => array(
'field' => 'addressee_id',
'customField' => 'addressee_custom',
'label' => ts('Addressee'),
'customLabel' => ts('Custom Addressee'),
'js' => NULL,
),
'email_greeting' => array(
'field' => 'email_greeting_id',
'customField' => 'email_greeting_custom',
'label' => ts('Email Greeting'),
'customLabel' => ts('Custom Email Greeting'),
'js' => $js,
),
'postal_greeting' => array(
'field' => 'postal_greeting_id',
'customField' => 'postal_greeting_custom',
'label' => ts('Postal Greeting'),
'customLabel' => ts('Custom Postal Greeting'),
'js' => $js,
),
);
}
return self::$greetings[$contactType];
}
}

View file

@ -0,0 +1,108 @@
<?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
*/
/**
* Form helper class for an Demographics object.
*/
class CRM_Contact_Form_Edit_CustomData {
/**
* Build all the data structures needed to build the form.
*
* @param CRM_Core_Form $form
*/
public static function preProcess(&$form) {
$form->_type = CRM_Utils_Request::retrieve('type', 'String');
$form->_subType = CRM_Utils_Request::retrieve('subType', 'String');
//build the custom data as other blocks.
//$form->assign( "addBlock", false );
if ($form->_type) {
$form->_addBlockName = 'CustomData';
$form->assign("addBlock", TRUE);
$form->assign("blockName", $form->_addBlockName);
}
CRM_Custom_Form_CustomData::preProcess($form, NULL, $form->_subType, NULL,
($form->_type) ? $form->_type : $form->_contactType
);
//assign group tree after build.
$form->assign('groupTree', $form->_groupTree);
}
/**
* Build the form object elements for CustomData object.
*
* @param CRM_Core_Form $form
* Reference to the form object.
*/
public static function buildQuickForm(&$form) {
if (!empty($form->_submitValues)) {
if ($customValueCount = CRM_Utils_Array::value('hidden_custom_group_count', $form->_submitValues)) {
if (is_array($customValueCount)) {
if (array_key_exists(0, $customValueCount)) {
unset($customValueCount[0]);
}
$form->_customValueCount = $customValueCount;
$form->assign('customValueCount', $customValueCount);
}
}
}
CRM_Custom_Form_CustomData::buildQuickForm($form);
//build custom data.
$contactSubType = NULL;
if (!empty($_POST["hidden_custom"]) && !empty($_POST['contact_sub_type'])) {
$contactSubType = $_POST['contact_sub_type'];
}
else {
$contactSubType = CRM_Utils_Array::value('contact_sub_type', $form->_values);
}
$form->assign('contactType', $form->_contactType);
$form->assign('contactSubType', $contactSubType);
}
/**
* Set default values for the form. Note that in edit/view mode
* the default values are retrieved from the database
*
*
* @param CRM_Core_Form $form
* @param array $defaults
*/
public static function setDefaultValues(&$form, &$defaults) {
$defaults += CRM_Custom_Form_CustomData::setDefaultValues($form);
}
}

View file

@ -0,0 +1,65 @@
<?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
*/
/**
* Form helper class for an Demographics object.
*/
class CRM_Contact_Form_Edit_Demographics {
/**
* Build the form object elements for Demographics object.
*
* @param CRM_Core_Form $form
* Reference to the form object.
*/
public static function buildQuickForm(&$form) {
$form->addField('gender_id', array('entity' => 'contact', 'type' => 'Radio', 'allowClear' => TRUE));
$form->addField('birth_date', array('entity' => 'contact'), FALSE, FALSE);
$form->addField('is_deceased', array('entity' => 'contact', 'label' => ts('Contact is Deceased'), 'onclick' => "showDeceasedDate()"));
$form->addField('deceased_date', array('entity' => 'contact'), FALSE, FALSE);
}
/**
* Set default values for the form. Note that in edit/view mode
* the default values are retrieved from the database
*
*
* @param CRM_Core_Form $form
* @param array $defaults
*/
public static function setDefaultValues(&$form, &$defaults) {
}
}

View file

@ -0,0 +1,118 @@
<?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
*/
/**
* Form helper class for an Email object.
*/
class CRM_Contact_Form_Edit_Email {
/**
* Build the form object elements for an email object.
*
* @param CRM_Core_Form $form
* Reference to the form object.
* @param int $blockCount
* Block number to build.
* @param bool $blockEdit
* Is it block edit.
*/
public static function buildQuickForm(&$form, $blockCount = NULL, $blockEdit = FALSE) {
// passing this via the session is AWFUL. we need to fix this
if (!$blockCount) {
$blockId = ($form->get('Email_Block_Count')) ? $form->get('Email_Block_Count') : 1;
}
else {
$blockId = $blockCount;
}
$form->applyFilter('__ALL__', 'trim');
//Email box
$form->addField("email[$blockId][email]", array('entity' => 'email'));
$form->addRule("email[$blockId][email]", ts('Email is not valid.'), 'email');
if (isset($form->_contactType) || $blockEdit) {
//Block type
$form->addField("email[$blockId][location_type_id]", array('entity' => 'email', 'placeholder' => NULL, 'class' => 'eight', 'option_url' => NULL));
//TODO: Refactor on_hold field to select.
$multipleBulk = CRM_Core_BAO_Email::isMultipleBulkMail();
//On-hold select
if ($multipleBulk) {
$holdOptions = array(
0 => ts('- select -'),
1 => ts('On Hold Bounce'),
2 => ts('On Hold Opt Out'),
);
$form->addElement('select', "email[$blockId][on_hold]", '', $holdOptions);
}
else {
$form->addField("email[$blockId][on_hold]", array('entity' => 'email', 'type' => 'advcheckbox'));
}
//Bulkmail checkbox
$form->assign('multipleBulk', $multipleBulk);
if ($multipleBulk) {
$js = array('id' => "Email_" . $blockId . "_IsBulkmail");
$form->addElement('advcheckbox', "email[$blockId][is_bulkmail]", NULL, '', $js);
}
else {
$js = array('id' => "Email_" . $blockId . "_IsBulkmail");
if (!$blockEdit) {
$js['onClick'] = 'singleSelect( this.id );';
}
$form->addElement('radio', "email[$blockId][is_bulkmail]", '', '', '1', $js);
}
//is_Primary radio
$js = array('id' => "Email_" . $blockId . "_IsPrimary");
if (!$blockEdit) {
$js['onClick'] = 'singleSelect( this.id );';
}
$form->addElement('radio', "email[$blockId][is_primary]", '', '', '1', $js);
if (CRM_Utils_System::getClassName($form) == 'CRM_Contact_Form_Contact') {
$form->add('textarea', "email[$blockId][signature_text]", ts('Signature (Text)'),
array('rows' => 2, 'cols' => 40)
);
$form->add('wysiwyg', "email[$blockId][signature_html]", ts('Signature (HTML)'),
array('rows' => 2, 'cols' => 40)
);
}
}
}
}

View file

@ -0,0 +1,101 @@
<?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
*/
/**
* Auxiliary class to provide support to the Contact Form class.
*
* Does this by implementing a small set of static methods.
*/
class CRM_Contact_Form_Edit_Household {
/**
* This function provides the HTML form elements that are specific to the Household Contact Type.
*
* @param CRM_Core_Form $form
* Form object.
* @param int $inlineEditMode
* ( 1 for contact summary.
* top bar form and 2 for display name edit )
*/
public static function buildQuickForm(&$form, $inlineEditMode = NULL) {
$form->applyFilter('__ALL__', 'trim');
if (!$inlineEditMode || $inlineEditMode == 1) {
// household_name
$form->addField('household_name');
}
if (!$inlineEditMode || $inlineEditMode == 2) {
// nick_name
$form->addField('nick_name');
$form->addField('contact_source', array('label' => ts('Source')));
}
if (!$inlineEditMode) {
$form->addField('external_identifier', array('label' => ts('External ID')));
$form->addRule('external_identifier',
ts('External ID already exists in Database.'),
'objectExists',
array('CRM_Contact_DAO_Contact', $form->_contactId, 'external_identifier')
);
}
}
/**
* Add rule for household.
*
* @param array $fields
* Array of form values.
* @param array $files
* Unused.
* @param int $contactID
*
* @return array|bool
* $error
*/
public static function formRule($fields, $files, $contactID = NULL) {
$errors = array();
$primaryID = CRM_Contact_Form_Contact::formRule($fields, $errors, $contactID);
// make sure that household name is set
if (empty($fields['household_name'])) {
$errors['household_name'] = 'Household Name should be set.';
}
//check for duplicate - dedupe rules
CRM_Contact_Form_Contact::checkDuplicateContacts($fields, $errors, $contactID, 'Household');
return empty($errors) ? TRUE : $errors;
}
}

View file

@ -0,0 +1,74 @@
<?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
*/
/**
* Form helper class for an IM object.
*/
class CRM_Contact_Form_Edit_IM {
/**
* Build the form object elements for an IM object.
*
* @param CRM_Core_Form $form
* Reference to the form object.
* @param int $blockCount
* Block number to build.
* @param bool $blockEdit
* Is it block edit.
*/
public static function buildQuickForm(&$form, $blockCount = NULL, $blockEdit = FALSE) {
if (!$blockCount) {
$blockId = ($form->get('IM_Block_Count')) ? $form->get('IM_Block_Count') : 1;
}
else {
$blockId = $blockCount;
}
$form->applyFilter('__ALL__', 'trim');
//IM provider select
$form->addField("im[$blockId][provider_id]", array('entity' => 'im', 'class' => 'eight', 'placeholder' => NULL));
//Block type select
$form->addField("im[$blockId][location_type_id]", array('entity' => 'im', 'class' => 'eight', 'placeholder' => NULL, 'option_url' => NULL));
//IM box
$form->addField("im[$blockId][name]", array('entity' => 'im'));
//is_Primary radio
$js = array('id' => 'IM_' . $blockId . '_IsPrimary');
if (!$blockEdit) {
$js['onClick'] = 'singleSelect( this.id );';
}
$form->addElement('radio', "im[$blockId][is_primary]", '', '', '1', $js);
}
}

View file

@ -0,0 +1,145 @@
<?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
*/
/**
* Auxiliary class to provide support to the Contact Form class.
*
* Does this by implementing a small set of static methods.
*/
class CRM_Contact_Form_Edit_Individual {
/**
* This function provides the HTML form elements that are specific to the Individual Contact Type.
*
* @param CRM_Core_Form $form
* Form object.
* @param int $inlineEditMode
* ( 1 for contact summary.
* top bar form and 2 for display name edit )
*/
public static function buildQuickForm(&$form, $inlineEditMode = NULL) {
$form->applyFilter('__ALL__', 'trim');
if (!$inlineEditMode || $inlineEditMode == 1) {
$nameFields = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
'contact_edit_options', TRUE, NULL,
FALSE, 'name', TRUE, 'AND v.filter = 2'
);
// Use names instead of labels to build form.
$nameFields = array_keys($nameFields);
// Fixme: dear god why? these come out in a format that is NOT the name of the fields.
foreach ($nameFields as &$fix) {
$fix = str_replace(' ', '_', strtolower($fix));
if ($fix == 'prefix' || $fix == 'suffix') {
// God, why god?
$fix .= '_id';
}
}
foreach ($nameFields as $name) {
$props = array();
if ($name == 'prefix_id' || $name == 'suffix_id') {
//override prefix/suffix label name as Prefix/Suffix respectively and adjust select size
$props = array('class' => 'eight', 'placeholder' => ' ', 'label' => $name == 'prefix_id' ? ts('Prefix') : ts('Suffix'));
}
$form->addField($name, $props);
}
}
if (!$inlineEditMode || $inlineEditMode == 2) {
// nick_name
$form->addField('nick_name');
// job title
// override the size for UI to look better
$form->addField('job_title', array('size' => '30'));
//Current Employer Element
$props = array(
'api' => array('params' => array('contact_type' => 'Organization')),
'create' => TRUE,
);
$form->addField('employer_id', $props);
$form->addField('contact_source', array('class' => 'big'));
}
if (!$inlineEditMode) {
$checkSimilar = Civi::settings()->get('contact_ajax_check_similar');
if ($checkSimilar == NULL) {
$checkSimilar = 0;
}
$form->assign('checkSimilar', $checkSimilar);
//External Identifier Element
$form->addField('external_identifier', array('label' => 'External ID'));
$form->addRule('external_identifier',
ts('External ID already exists in Database.'),
'objectExists',
array('CRM_Contact_DAO_Contact', $form->_contactId, 'external_identifier')
);
CRM_Core_ShowHideBlocks::links($form, 'demographics', '', '');
}
}
/**
* Global form rule.
*
* @param array $fields
* The input form values.
* @param array $files
* The uploaded files if any.
* @param int $contactID
*
* @return bool
* TRUE if no errors, else array of errors.
*/
public static function formRule($fields, $files, $contactID = NULL) {
$errors = array();
$primaryID = CRM_Contact_Form_Contact::formRule($fields, $errors, $contactID);
// make sure that firstName and lastName or a primary OpenID is set
if (!$primaryID && (empty($fields['first_name']) || empty($fields['last_name']))) {
$errors['_qf_default'] = ts('First Name and Last Name OR an email OR an OpenID in the Primary Location should be set.');
}
//check for duplicate - dedupe rules
CRM_Contact_Form_Contact::checkDuplicateContacts($fields, $errors, $contactID, 'Individual');
return empty($errors) ? TRUE : $errors;
}
}

View file

@ -0,0 +1,75 @@
<?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
*/
/**
* Auxiliary class to provide support for locking (and ignoring locks on) contact records.
*/
class CRM_Contact_Form_Edit_Lock {
/**
* Build the form object.
*
* @param CRM_Core_Form $form
* Form object.
*/
public static function buildQuickForm(&$form) {
$form->addField('modified_date', array('type' => 'hidden', 'id' => 'modified_date', 'label' => ''));
}
/**
* Ensure that modified_date has not changed in the underlying DB.
*
* @param array $fields
* The input form values.
* @param array $files
* The uploaded files if any.
* @param int $contactID
*
* @return bool|array
* true if no errors, else array of errors
*/
public static function formRule($fields, $files, $contactID = NULL) {
$errors = array();
$timestamps = CRM_Contact_BAO_Contact::getTimestamps($contactID);
if ($fields['modified_date'] != $timestamps['modified_date']) {
// Inline buttons generated via JS
$open = sprintf("<span id='update_modified_date' data:latest_modified_date='%s'>", $timestamps['modified_date']);
$close = "</span>";
$errors['modified_date'] = $open . ts('This record was modified by another user!') . $close;
}
return empty($errors) ? TRUE : $errors;
}
}

View file

@ -0,0 +1,46 @@
<?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_Edit_Notes {
/**
* Build form elements.
*
* @param CRM_Core_Form $form
*/
public static function buildQuickForm(&$form) {
$form->applyFilter('__ALL__', 'trim');
$form->addField('subject', array('entity' => 'note', 'size' => '60'));
$form->addField('note', array('entity' => 'note', 'rows' => 3));
}
}

View file

@ -0,0 +1,75 @@
<?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
*/
/**
* Form helper class for an OpenID object.
*/
class CRM_Contact_Form_Edit_OpenID {
/**
* Build the form object elements for an open id object.
*
* @param CRM_Core_Form $form
* Reference to the form object.
* @param int $blockCount
* Block number to build.
* @param bool $blockEdit
* Is it block edit.
*/
public static function buildQuickForm(&$form, $blockCount = NULL, $blockEdit = FALSE) {
if (!$blockCount) {
$blockId = ($form->get('OpenID_Block_Count')) ? $form->get('OpenID_Block_Count') : 1;
}
else {
$blockId = $blockCount;
}
$form->applyFilter('__ALL__', 'trim');
$form->addElement('text', "openid[$blockId][openid]", ts('OpenID'),
CRM_Core_DAO::getAttribute('CRM_Core_DAO_OpenID', 'openid')
);
$form->addRule("openid[$blockId][openid]", ts('OpenID is not a valid URL.'), 'url');
//Block type
$form->addElement('select', "openid[$blockId][location_type_id]", '', CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'));
//is_Primary radio
$js = array('id' => "OpenID_" . $blockId . "_IsPrimary");
if (!$blockEdit) {
$js['onClick'] = 'singleSelect( this.id );';
}
$form->addElement('radio', "openid[$blockId][is_primary]", '', '', '1', $js);
}
}

View file

@ -0,0 +1,103 @@
<?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
*/
/**
* Auxiliary class to provide support to the Contact Form class.
*
* Does this by implementing a small set of static methods.
*/
class CRM_Contact_Form_Edit_Organization {
/**
* This function provides the HTML form elements that are specific to the Organization Contact Type.
*
* @param CRM_Core_Form $form
* Form object.
* @param int $inlineEditMode
* ( 1 for contact summary.
* top bar form and 2 for display name edit )
*/
public static function buildQuickForm(&$form, $inlineEditMode = NULL) {
$form->applyFilter('__ALL__', 'trim');
if (!$inlineEditMode || $inlineEditMode == 1) {
// Organization_name
$form->addField('organization_name');
}
if (!$inlineEditMode || $inlineEditMode == 2) {
// legal_name
$form->addField('legal_name');
// nick_name
$form->addField('nick_name');
// sic_code
$form->addField('sic_code');
$form->addField('contact_source');
}
if (!$inlineEditMode) {
$form->addField('external_identifier', array('label' => ts('External ID')));
$form->addRule('external_identifier',
ts('External ID already exists in Database.'),
'objectExists',
array('CRM_Contact_DAO_Contact', $form->_contactId, 'external_identifier')
);
}
}
/**
* @param $fields
* @param $files
* @param int $contactID
*
* @return array|bool
*/
public static function formRule($fields, $files, $contactID = NULL) {
$errors = array();
$primaryID = CRM_Contact_Form_Contact::formRule($fields, $errors, $contactID);
// make sure that organization name is set
if (empty($fields['organization_name'])) {
$errors['organization_name'] = 'Organization Name should be set.';
}
//check for duplicate - dedupe rules
CRM_Contact_Form_Contact::checkDuplicateContacts($fields, $errors, $contactID, 'Organization');
// add code to make sure that the uniqueness criteria is satisfied
return empty($errors) ? TRUE : $errors;
}
}

View file

@ -0,0 +1,86 @@
<?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
*/
/**
* Form helper class for a phone object.
*/
class CRM_Contact_Form_Edit_Phone {
/**
* Build the form object elements for a phone object.
*
* @param CRM_Core_Form $form
* Reference to the form object.
* @param int $addressBlockCount
* Block number to build.
* @param bool $blockEdit
* Is it block edit.
*/
public static function buildQuickForm(&$form, $addressBlockCount = NULL, $blockEdit = FALSE) {
// passing this via the session is AWFUL. we need to fix this
if (!$addressBlockCount) {
$blockId = ($form->get('Phone_Block_Count')) ? $form->get('Phone_Block_Count') : 1;
}
else {
$blockId = $addressBlockCount;
}
$form->applyFilter('__ALL__', 'trim');
//phone type select
$form->addField("phone[$blockId][phone_type_id]", array(
'entity' => 'phone',
'class' => 'eight',
'placeholder' => NULL,
));
//main phone number with crm_phone class
$form->addField("phone[$blockId][phone]", array('entity' => 'phone', 'class' => 'crm_phone twelve'));
$form->addField("phone[$blockId][phone_ext]", array('entity' => 'phone'));
if (isset($form->_contactType) || $blockEdit) {
//Block type select
$form->addField("phone[$blockId][location_type_id]", array(
'entity' => 'phone',
'class' => 'eight',
'placeholder' => NULL,
'option_url' => NULL,
));
//is_Primary radio
$js = array('id' => 'Phone_' . $blockId . '_IsPrimary', 'onClick' => 'singleSelect( this.id );');
$form->addElement('radio', "phone[$blockId][is_primary]", '', '', '1', $js);
}
// TODO: set this up as a group, we need a valid phone_type_id if we have a phone number
// $form->addRule( "location[$locationId][phone][$locationId][phone]", ts('Phone number is not valid.'), 'phone' );
}
}

View file

@ -0,0 +1,235 @@
<?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_Edit_TagsAndGroups {
/**
* Constant to determine which forms we are generating.
*
* Used by both profile and edit contact
*/
const GROUP = 1, TAG = 2, ALL = 3;
/**
* Build form elements.
*
* @param CRM_Core_Form $form
* The form object that we are operating on.
* @param int $contactId
* Contact id.
* @param int $type
* What components are we interested in.
* @param bool $visibility
* Visibility of the field.
* @param null $isRequired
* @param string $groupName
* If used for building group block.
* @param string $tagName
* If used for building tag block.
* @param string $fieldName
* This is used in batch profile(i.e to build multiple blocks).
*
* @param string $groupElementType
*
*/
public static function buildQuickForm(
&$form,
$contactId = 0,
$type = self::ALL,
$visibility = FALSE,
$isRequired = NULL,
$groupName = 'Group(s)',
$tagName = 'Tag(s)',
$fieldName = NULL,
$groupElementType = 'checkbox'
) {
if (!isset($form->_tagGroup)) {
$form->_tagGroup = array();
}
// NYSS 5670
if (!$contactId && !empty($form->_contactId)) {
$contactId = $form->_contactId;
}
$type = (int) $type;
if ($type & self::GROUP) {
$fName = 'group';
if ($fieldName) {
$fName = $fieldName;
}
$groupID = isset($form->_grid) ? $form->_grid : NULL;
if ($groupID && $visibility) {
$ids = array($groupID => $groupID);
}
else {
if ($visibility) {
$group = CRM_Core_PseudoConstant::allGroup();
}
else {
$group = CRM_Core_PseudoConstant::group();
}
$ids = $group;
}
if ($groupID || !empty($group)) {
$groups = CRM_Contact_BAO_Group::getGroupsHierarchy($ids);
$attributes['skiplabel'] = TRUE;
$elements = array();
$groupsOptions = array();
foreach ($groups as $id => $group) {
// make sure that this group has public visibility
if ($visibility &&
$group['visibility'] == 'User and User Admin Only'
) {
continue;
}
if ($groupElementType == 'select') {
$groupsOptions[$id] = $group['title'];
}
else {
$form->_tagGroup[$fName][$id]['description'] = $group['description'];
$elements[] = &$form->addElement('advcheckbox', $id, NULL, $group['title'], $attributes);
}
}
if ($groupElementType == 'select' && !empty($groupsOptions)) {
$form->add('select', $fName, $groupName, $groupsOptions, FALSE,
array('id' => $fName, 'multiple' => 'multiple', 'class' => 'crm-select2 twenty')
);
$form->assign('groupCount', count($groupsOptions));
}
if ($groupElementType == 'checkbox' && !empty($elements)) {
$form->addGroup($elements, $fName, $groupName, '&nbsp;<br />');
$form->assign('groupCount', count($elements));
if ($isRequired) {
$form->addRule($fName, ts('%1 is a required field.', array(1 => $groupName)), 'required');
}
}
$form->assign('groupElementType', $groupElementType);
}
}
if ($type & self::TAG) {
$tags = CRM_Core_BAO_Tag::getColorTags('civicrm_contact');
if (!empty($tags)) {
$form->add('select2', 'tag', ts('Tag(s)'), $tags, FALSE, array('class' => 'huge', 'placeholder' => ts('- select -'), 'multiple' => TRUE));
}
// build tag widget
$parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_contact');
CRM_Core_Form_Tag::buildQuickForm($form, $parentNames, 'civicrm_contact', $contactId, FALSE, TRUE);
}
$form->assign('tagGroup', $form->_tagGroup);
}
/**
* Set defaults for relevant form elements.
*
* @param int $id
* The contact id.
* @param array $defaults
* The defaults array to store the values in.
* @param int $type
* What components are we interested in.
* @param string $fieldName
* This is used in batch profile(i.e to build multiple blocks).
*
* @param string $groupElementType
*/
public static function setDefaults($id, &$defaults, $type = self::ALL, $fieldName = NULL, $groupElementType = 'checkbox') {
$type = (int ) $type;
if ($type & self::GROUP) {
$fName = 'group';
if ($fieldName) {
$fName = $fieldName;
}
$contactGroup = CRM_Contact_BAO_GroupContact::getContactGroup($id, 'Added', NULL, FALSE, TRUE);
if ($contactGroup) {
foreach ($contactGroup as $group) {
if ($groupElementType == 'select') {
$defaults[$fName][] = $group['group_id'];
}
else {
$defaults[$fName . '[' . $group['group_id'] . ']'] = 1;
}
}
}
}
if ($type & self::TAG) {
$defaults['tag'] = implode(',', CRM_Core_BAO_EntityTag::getTag($id, 'civicrm_contact'));
}
}
/**
* Set default values for the form. Note that in edit/view mode
* the default values are retrieved from the database
*
*
* @param CRM_Core_Form $form
* @param array $defaults
*/
public static function setDefaultValues(&$form, &$defaults) {
$contactEditOptions = $form->get('contactEditOptions');
if ($form->_action & CRM_Core_Action::ADD) {
if (array_key_exists('TagsAndGroups', $contactEditOptions)) {
// set group and tag defaults if any
if ($form->_gid) {
$defaults['group'][$form->_gid] = 1;
}
if ($form->_tid) {
$defaults['tag'][$form->_tid] = 1;
}
}
}
else {
if (array_key_exists('TagsAndGroups', $contactEditOptions)) {
// set the group and tag ids
$groupElementType = 'checkbox';
if (CRM_Utils_System::getClassName($form) == 'CRM_Contact_Form_Contact') {
$groupElementType = 'select';
}
self::setDefaults($form->_contactId, $defaults, self::ALL, NULL, $groupElementType);
}
}
}
}

View file

@ -0,0 +1,66 @@
<?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
*/
/**
* Form helper class for an Website object.
*/
class CRM_Contact_Form_Edit_Website {
/**
* Build the form object elements for an Website object.
*
* @param CRM_Core_Form $form
* Reference to the form object.
* @param int $blockCount
* Block number to build.
*/
public static function buildQuickForm(&$form, $blockCount = NULL) {
if (!$blockCount) {
$blockId = ($form->get('Website_Block_Count')) ? $form->get('Website_Block_Count') : 1;
}
else {
$blockId = $blockCount;
}
$form->applyFilter('__ALL__', 'trim');
//Website type select
$form->addField("website[$blockId][website_type_id]", array('entity' => 'website', 'class' => 'eight'));
//Website box
$form->addField("website[$blockId][url]", array('entity' => 'website'));
$form->addRule("website[$blockId][url]", ts('Enter a valid web address beginning with \'http://\' or \'https://\'.'), 'url');
}
}

View file

@ -0,0 +1,161 @@
<?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 generates form components for groupContact.
*/
class CRM_Contact_Form_GroupContact extends CRM_Core_Form {
/**
* The groupContact id, used when editing the groupContact
*
* @var int
*/
protected $_groupContactId;
/**
* The contact id, used when add/edit groupContact
*
* @var int
*/
protected $_contactId;
/**
* Explicitly declare the entity api name.
*/
public function getDefaultEntity() {
return 'GroupContact';
}
/**
* Explicitly declare the form context.
*/
public function getDefaultContext() {
return 'create';
}
/**
* Pre process form.
*/
public function preProcess() {
$this->_contactId = $this->get('contactId');
$this->_groupContactId = $this->get('groupContactId');
$this->_context = CRM_Utils_Request::retrieve('context', 'String', $this);
}
/**
* Build the form object.
*/
public function buildQuickForm() {
// get the list of all the groups
if ($this->_context == 'user') {
$onlyPublicGroups = CRM_Utils_Request::retrieve('onlyPublicGroups', 'Boolean', $this, FALSE);
$ids = CRM_Core_PseudoConstant::allGroup();
$heirGroups = CRM_Contact_BAO_Group::getGroupsHierarchy($ids);
$allGroups = array();
foreach ($heirGroups as $id => $group) {
// make sure that this group has public visibility
if ($onlyPublicGroups && $group['visibility'] == 'User and User Admin Only') {
continue;
}
$allGroups[$id] = $group;
}
}
else {
$allGroups = CRM_Core_PseudoConstant::group();
}
// Arrange groups into hierarchical listing (child groups follow their parents and have indentation spacing in title)
$groupHierarchy = CRM_Contact_BAO_Group::getGroupsHierarchy($allGroups, NULL, '&nbsp;&nbsp;', TRUE);
// get the list of groups contact is currently in ("Added") or unsubscribed ("Removed").
$currentGroups = CRM_Contact_BAO_GroupContact::getGroupList($this->_contactId);
// Remove current groups from drowdown options ($groupSelect)
if (is_array($currentGroups)) {
// Compare array keys, since the array values (group title) in $groupList may have extra spaces for indenting child groups
$groupSelect = array_diff_key($groupHierarchy, $currentGroups);
}
else {
$groupSelect = $groupHierarchy;
}
$groupSelect = array('' => ts('- select group -')) + $groupSelect;
if (count($groupSelect) > 1) {
$session = CRM_Core_Session::singleton();
// user dashboard
if (strstr($session->readUserContext(), 'user')) {
$msg = ts('Join a Group');
}
else {
$msg = ts('Add to a group');
}
$this->addField('group_id', array('class' => 'crm-action-menu fa-plus', 'placeholder' => $msg, 'options' => $groupSelect));
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Add'),
'isDefault' => TRUE,
),
)
);
}
}
/**
* Post process form.
*/
public function postProcess() {
$contactID = array($this->_contactId);
$groupId = $this->controller->exportValue('GroupContact', 'group_id');
$method = ($this->_context == 'user') ? 'Web' : 'Admin';
$session = CRM_Core_Session::singleton();
$userID = $session->get('userID');
if ($userID == $this->_contactId) {
$method = 'Web';
}
$groupContact = CRM_Contact_BAO_GroupContact::addContactsToGroup($contactID, $groupId, $method);
if ($groupContact && $this->_context != 'user') {
$groups = CRM_Core_PseudoConstant::group();
CRM_Core_Session::setStatus(ts("Contact has been added to '%1'.", array(1 => $groups[$groupId])), ts('Added to Group'), 'success');
}
}
}

View file

@ -0,0 +1,185 @@
<?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
*/
/**
* Parent class for inline contact forms.
*/
abstract class CRM_Contact_Form_Inline extends CRM_Core_Form {
/**
* Id of the contact that is being edited
*/
public $_contactId;
/**
* Type of contact being edited
*/
public $_contactType;
/**
* Sub type of contact being edited
*/
public $_contactSubType;
/**
* Explicitly declare the form context.
*/
public function getDefaultContext() {
return 'create';
}
/**
* Explicitly declare the entity api name.
*/
public function getDefaultEntity() {
return 'Contact';
}
/**
* Common preprocess: fetch contact ID and contact type
*/
public function preProcess() {
$this->_contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE, NULL, $_REQUEST);
$this->assign('contactId', $this->_contactId);
// get contact type and subtype
if (empty($this->_contactType)) {
$contactTypeInfo = CRM_Contact_BAO_Contact::getContactTypes($this->_contactId);
$this->_contactType = $contactTypeInfo[0];
// check if subtype is set
if (isset($contactTypeInfo[1])) {
// unset contact type which is 0th element
unset($contactTypeInfo[0]);
$this->_contactSubType = $contactTypeInfo;
}
}
$this->assign('contactType', $this->_contactType);
$this->setAction(CRM_Core_Action::UPDATE);
}
/**
* Common form elements.
*/
public function buildQuickForm() {
CRM_Contact_Form_Inline_Lock::buildQuickForm($this, $this->_contactId);
$buttons = array(
array(
'type' => 'upload',
'name' => ts('Save'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
);
$this->addButtons($buttons);
}
/**
* Override default cancel action.
*/
public function cancelAction() {
$response = array('status' => 'cancel');
CRM_Utils_JSON::output($response);
}
/**
* Set defaults for the form.
*
* @return array
*/
public function setDefaultValues() {
$defaults = $params = array();
$params['id'] = $this->_contactId;
CRM_Contact_BAO_Contact::getValues($params, $defaults);
return $defaults;
}
/**
* Add entry to log table.
*/
protected function log() {
CRM_Core_BAO_Log::register($this->_contactId,
'civicrm_contact',
$this->_contactId
);
}
/**
* Common function for all inline contact edit forms.
*
* Prepares ajaxResponse
*/
protected function response() {
$this->ajaxResponse = array_merge(
self::renderFooter($this->_contactId),
$this->ajaxResponse,
CRM_Contact_Form_Inline_Lock::getResponse($this->_contactId)
);
// Note: Post hooks will be called by CRM_Core_Form::mainProcess
}
/**
* Render change log footer markup for a contact and supply count.
*
* Needed for refreshing the contact summary screen
*
* @param int $cid
* @param bool $includeCount
* @return array
*/
public static function renderFooter($cid, $includeCount = TRUE) {
// Load change log footer from template.
$smarty = CRM_Core_Smarty::singleton();
$smarty->assign('contactId', $cid);
$smarty->assign('external_identifier', CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'external_identifier'));
$smarty->assign('lastModified', CRM_Core_BAO_Log::lastModified($cid, 'civicrm_contact'));
$viewOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
'contact_view_options', TRUE
);
$smarty->assign('changeLog', $viewOptions['log']);
$ret = array('markup' => $smarty->fetch('CRM/common/contactFooter.tpl'));
if ($includeCount) {
$ret['count'] = CRM_Contact_BAO_Contact::getCountComponent('log', $cid);
}
return array('changeLog' => $ret);
}
}

View file

@ -0,0 +1,190 @@
<?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
*/
/**
* Form helper class for address section.
*/
class CRM_Contact_Form_Inline_Address extends CRM_Contact_Form_Inline {
/**
* Location block no
*/
private $_locBlockNo;
/**
* Do we want to parse street address.
*/
public $_parseStreetAddress;
/**
* Store address values
*/
public $_values;
/**
* Form action
*/
public $_action;
/**
* Address id
*/
public $_addressId;
/**
* Class constructor.
*
* Since we are using same class / code to generate multiple instances
* of address block, we need to generate unique form name for each,
* hence calling parent constructor
*/
public function __construct() {
$locBlockNo = CRM_Utils_Request::retrieve('locno', 'Positive', CRM_Core_DAO::$_nullObject, TRUE, NULL, $_REQUEST);
$name = "Address_{$locBlockNo}";
parent::__construct(NULL, CRM_Core_Action::NONE, 'post', $name);
}
/**
* Call preprocess.
*/
public function preProcess() {
parent::preProcess();
$this->_locBlockNo = CRM_Utils_Request::retrieve('locno', 'Positive', $this, TRUE, NULL, $_REQUEST);
$this->assign('blockId', $this->_locBlockNo);
$addressSequence = CRM_Core_BAO_Address::addressSequence();
$this->assign('addressSequence', $addressSequence);
$this->_values = array();
$this->_addressId = CRM_Utils_Request::retrieve('aid', 'Positive', $this, FALSE, NULL, $_REQUEST);
$this->_action = CRM_Core_Action::ADD;
if ($this->_addressId) {
$params = array('id' => $this->_addressId);
$address = CRM_Core_BAO_Address::getValues($params, FALSE, 'id');
$this->_values['address'][$this->_locBlockNo] = array_pop($address);
$this->_action = CRM_Core_Action::UPDATE;
}
else {
$this->_addressId = 0;
}
$this->assign('action', $this->_action);
$this->assign('addressId', $this->_addressId);
// parse street address, CRM-5450
$this->_parseStreetAddress = $this->get('parseStreetAddress');
if (!isset($this->_parseStreetAddress)) {
$addressOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
'address_options'
);
$this->_parseStreetAddress = FALSE;
if (!empty($addressOptions['street_address']) && !empty($addressOptions['street_address_parsing'])) {
$this->_parseStreetAddress = TRUE;
}
$this->set('parseStreetAddress', $this->_parseStreetAddress);
}
$this->assign('parseStreetAddress', $this->_parseStreetAddress);
}
/**
* Build the form object elements for an address object.
*/
public function buildQuickForm() {
parent::buildQuickForm();
CRM_Contact_Form_Edit_Address::buildQuickForm($this, $this->_locBlockNo, TRUE, TRUE);
$this->addFormRule(array('CRM_Contact_Form_Edit_Address', 'formRule'), $this);
}
/**
* Set defaults for the form.
*
* @return array
*/
public function setDefaultValues() {
$defaults = $this->_values;
$config = CRM_Core_Config::singleton();
//set address block defaults
if (!empty($defaults['address'])) {
CRM_Contact_Form_Edit_Address::setDefaultValues($defaults, $this);
}
else {
// get the default location type
$locationType = CRM_Core_BAO_LocationType::getDefault();
if ($this->_locBlockNo == 1) {
$address['is_primary'] = TRUE;
$address['location_type_id'] = $locationType->id;
}
$address['country_id'] = $config->defaultContactCountry;
$address['state_province_id'] = $config->defaultContactStateProvince;
$defaults['address'][$this->_locBlockNo] = $address;
}
return $defaults;
}
/**
* Process the form.
*/
public function postProcess() {
$params = $this->exportValues();
// Process / save address
$params['contact_id'] = $this->_contactId;
$params['updateBlankLocInfo'] = TRUE;
// process shared contact address.
CRM_Contact_BAO_Contact_Utils::processSharedAddress($params['address']);
if ($this->_parseStreetAddress) {
CRM_Contact_Form_Contact::parseAddress($params);
}
if ($this->_addressId > 0) {
$params['address'][$this->_locBlockNo]['id'] = $this->_addressId;
}
// save address changes
$address = CRM_Core_BAO_Address::create($params, TRUE);
$this->log();
$this->ajaxResponse['addressId'] = $address[0]->id;
$this->response();
}
}

View file

@ -0,0 +1,109 @@
<?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
*/
/**
* Form helper class for communication preferences inline edit section.
*/
class CRM_Contact_Form_Inline_CommunicationPreferences extends CRM_Contact_Form_Inline {
/**
* Build the form object elements for communication preferences.
*/
public function buildQuickForm() {
parent::buildQuickForm();
CRM_Contact_Form_Edit_CommunicationPreferences::buildQuickForm($this);
$this->addFormRule(array('CRM_Contact_Form_Edit_CommunicationPreferences', 'formRule'), $this);
}
/**
* Set defaults for the form.
*
* @return array
*/
public function setDefaultValues() {
$defaults = parent::setDefaultValues();
if (!empty($defaults['preferred_language'])) {
$languages = CRM_Contact_BAO_Contact::buildOptions('preferred_language');
$defaults['preferred_language'] = CRM_Utils_Array::key($defaults['preferred_language'], $languages);
}
// CRM-7119: set preferred_language to default if unset
if (empty($defaults['preferred_language'])) {
$config = CRM_Core_Config::singleton();
$defaults['preferred_language'] = $config->lcMessages;
}
// CRM-19135: where CRM_Core_BAO_Contact::getValues() set label as a default value instead of reserved 'value',
// the code is to ensure we always set default to value instead of label
if (!empty($defaults['preferred_mail_format'])) {
$defaults['preferred_mail_format'] = array_search($defaults['preferred_mail_format'], CRM_Core_SelectValues::pmf());
}
if (empty($defaults['communication_style_id'])) {
$defaults['communication_style_id'] = array_pop(CRM_Core_OptionGroup::values('communication_style', TRUE, NULL, NULL, 'AND is_default = 1'));
}
foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
$name = "{$greeting}_display";
$this->assign($name, CRM_Utils_Array::value($name, $defaults));
}
return $defaults;
}
/**
* Process the form.
*/
public function postProcess() {
$params = $this->exportValues();
// Process / save communication preferences
// this is a chekbox, so mark false if we dont get a POST value
$params['is_opt_out'] = CRM_Utils_Array::value('is_opt_out', $params, FALSE);
$params['contact_type'] = $this->_contactType;
$params['contact_id'] = $this->_contactId;
if (!empty($this->_contactSubType)) {
$params['contact_sub_type'] = $this->_contactSubType;
}
if (!isset($params['preferred_communication_method'])) {
$params['preferred_communication_method'] = 'null';
}
CRM_Contact_BAO_Contact::create($params);
$this->response();
}
}

View file

@ -0,0 +1,89 @@
<?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
*/
/**
* Form helper class for contact info section.
*/
class CRM_Contact_Form_Inline_ContactInfo extends CRM_Contact_Form_Inline {
/**
* Build the form object elements.
*/
public function buildQuickForm() {
parent::buildQuickForm();
// Build contact type specific fields
$class = 'CRM_Contact_Form_Edit_' . $this->_contactType;
$class::buildQuickForm($this, 2);
}
/**
* Set defaults for the form.
*
* @return array
*/
public function setDefaultValues() {
return parent::setDefaultValues();
}
/**
* Process the form.
*/
public function postProcess() {
$params = $this->exportValues();
// Process / save contact info
$params['contact_type'] = $this->_contactType;
$params['contact_id'] = $this->_contactId;
if (!empty($this->_contactSubType)) {
$params['contact_sub_type'] = $this->_contactSubType;
}
CRM_Contact_BAO_Contact::create($params);
// Saving current employer affects relationship tab, and possibly related memberships and contributions
$this->ajaxResponse['updateTabs'] = array(
'#tab_rel' => CRM_Contact_BAO_Contact::getCountComponent('rel', $this->_contactId),
);
if (CRM_Core_Permission::access('CiviContribute')) {
$this->ajaxResponse['updateTabs']['#tab_contribute'] = CRM_Contact_BAO_Contact::getCountComponent('contribution', $this->_contactId);
}
if (CRM_Core_Permission::access('CiviMember')) {
$this->ajaxResponse['updateTabs']['#tab_member'] = CRM_Contact_BAO_Contact::getCountComponent('membership', $this->_contactId);
}
$this->response();
}
}

View file

@ -0,0 +1,94 @@
<?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
*/
/**
* Form helper class for contact name section.
*/
class CRM_Contact_Form_Inline_ContactName extends CRM_Contact_Form_Inline {
/**
* Build the form object elements.
*/
public function buildQuickForm() {
parent::buildQuickForm();
// Build contact type specific fields
$class = 'CRM_Contact_Form_Edit_' . $this->_contactType;
$class::buildQuickForm($this, 1);
$this->addFormRule(array('CRM_Contact_Form_Inline_ContactName', 'formRule'), $this);
}
/**
* Global validation rules for the form.
*
* @param array $fields
* Posted values of the form.
* @param array $errors
* List of errors to be posted back to the form.
* @param CRM_Contact_Form_Inline_ContactName $form
*
* @return array
*/
public static function formRule($fields, $errors, $form) {
if (empty($fields['first_name']) && empty($fields['last_name'])
&& empty($fields['organization_name'])
&& empty($fields['household_name'])) {
$emails = civicrm_api3('Email', 'getcount', array('contact_id' => $form->_contactId));
if (!$emails) {
$errorField = $form->_contactType == 'Individual' ? 'last' : strtolower($form->_contactType);
$errors[$errorField . '_name'] = ts('Contact with no email must have a name.');
}
}
return $errors;
}
/**
* Process the form.
*/
public function postProcess() {
$params = $this->exportValues();
// Process / save contact info
$params['contact_type'] = $this->_contactType;
$params['contact_id'] = $this->_contactId;
if (!empty($this->_contactSubType)) {
$params['contact_sub_type'] = $this->_contactSubType;
}
CRM_Contact_BAO_Contact::create($params);
$this->response();
}
}

View file

@ -0,0 +1,105 @@
<?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
*/
/**
* Form helper class for custom data section.
*/
class CRM_Contact_Form_Inline_CustomData extends CRM_Contact_Form_Inline {
/**
* Custom group id.
*
* @int
*/
public $_groupID;
/**
* Entity type of the table id.
*
* @var string
*/
protected $_entityType;
/**
* Call preprocess.
*/
public function preProcess() {
parent::preProcess();
$this->_groupID = CRM_Utils_Request::retrieve('groupID', 'Positive', $this, TRUE, NULL, $_REQUEST);
$this->assign('customGroupId', $this->_groupID);
$customRecId = CRM_Utils_Request::retrieve('customRecId', 'Positive', $this, FALSE, 1, $_REQUEST);
$cgcount = CRM_Utils_Request::retrieve('cgcount', 'Positive', $this, FALSE, 1, $_REQUEST);
$subType = CRM_Contact_BAO_Contact::getContactSubType($this->_contactId, ',');
CRM_Custom_Form_CustomData::preProcess($this, NULL, $subType, $cgcount,
$this->_contactType, $this->_contactId);
}
/**
* Build the form object elements for custom data.
*/
public function buildQuickForm() {
parent::buildQuickForm();
CRM_Custom_Form_CustomData::buildQuickForm($this);
}
/**
* Set defaults for the form.
*
* @return array
*/
public function setDefaultValues() {
return CRM_Custom_Form_CustomData::setDefaultValues($this);
}
/**
* Process the form.
*/
public function postProcess() {
// Process / save custom data
// Get the form values and groupTree
$params = $this->controller->exportValues($this->_name);
CRM_Core_BAO_CustomValueTable::postProcess($params,
'civicrm_contact',
$this->_contactId,
$this->_entityType
);
$this->log();
CRM_Contact_BAO_GroupContactCache::opportunisticCacheFlush();
$this->response();
}
}

View file

@ -0,0 +1,71 @@
<?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
*/
/**
* Form helper class for demographics section.
*/
class CRM_Contact_Form_Inline_Demographics extends CRM_Contact_Form_Inline {
/**
* Build the form object elements.
*/
public function buildQuickForm() {
parent::buildQuickForm();
CRM_Contact_Form_Edit_Demographics::buildQuickForm($this);
}
/**
* Process the form.
*/
public function postProcess() {
$params = $this->exportValues();
// Process / save demographics
if (empty($params['is_deceased'])) {
$params['is_deceased'] = FALSE;
$params['deceased_date'] = NULL;
}
$params['contact_type'] = 'Individual';
$params['contact_id'] = $this->_contactId;
if (!empty($this->_contactSubType)) {
$params['contact_sub_type'] = $this->_contactSubType;
}
CRM_Contact_BAO_Contact::create($params);
$this->response();
}
}

View file

@ -0,0 +1,204 @@
<?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
*/
/**
* Form helper class for an Email object.
*/
class CRM_Contact_Form_Inline_Email extends CRM_Contact_Form_Inline {
/**
* Email addresses of the contact that is been viewed.
*/
private $_emails = array();
/**
* No of email blocks for inline edit.
*/
private $_blockCount = 6;
/**
* Whether this contact has a first/last/organization/household name
*
* @var bool
*/
public $contactHasName;
/**
* Call preprocess.
*/
public function preProcess() {
parent::preProcess();
//get all the existing email addresses
$email = new CRM_Core_BAO_Email();
$email->contact_id = $this->_contactId;
$this->_emails = CRM_Core_BAO_Block::retrieveBlock($email, NULL);
// Check if this contact has a first/last/organization/household name
if ($this->_contactType == 'Individual') {
$this->contactHasName = (bool) (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'last_name')
|| CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'first_name'));
}
else {
$this->contactHasName = (bool) CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, strtolower($this->_contactType) . '_name');
}
}
/**
* Build the form object elements for an email object.
*/
public function buildQuickForm() {
parent::buildQuickForm();
$totalBlocks = $this->_blockCount;
$actualBlockCount = 1;
if (count($this->_emails) > 1) {
$actualBlockCount = $totalBlocks = count($this->_emails);
if ($totalBlocks < $this->_blockCount) {
$additionalBlocks = $this->_blockCount - $totalBlocks;
$totalBlocks += $additionalBlocks;
}
else {
$actualBlockCount++;
$totalBlocks++;
}
}
$this->assign('actualBlockCount', $actualBlockCount);
$this->assign('totalBlocks', $totalBlocks);
$this->applyFilter('__ALL__', 'trim');
for ($blockId = 1; $blockId < $totalBlocks; $blockId++) {
CRM_Contact_Form_Edit_Email::buildQuickForm($this, $blockId, TRUE);
}
$this->addFormRule(array('CRM_Contact_Form_Inline_Email', 'formRule'), $this);
}
/**
* Global validation rules for the form.
*
* @param array $fields
* Posted values of the form.
* @param array $errors
* List of errors to be posted back to the form.
* @param CRM_Contact_Form_Inline_Email $form
*
* @return array
*/
public static function formRule($fields, $errors, $form) {
$hasData = $hasPrimary = $errors = array();
if (!empty($fields['email']) && is_array($fields['email'])) {
foreach ($fields['email'] as $instance => $blockValues) {
$dataExists = CRM_Contact_Form_Contact::blockDataExists($blockValues);
if ($dataExists) {
$hasData[] = $instance;
if (!empty($blockValues['is_primary'])) {
$hasPrimary[] = $instance;
}
}
}
if (empty($hasPrimary) && !empty($hasData)) {
$errors["email[1][is_primary]"] = ts('One email should be marked as primary.');
}
if (count($hasPrimary) > 1) {
$errors["email[" . array_pop($hasPrimary) . "][is_primary]"] = ts('Only one email can be marked as primary.');
}
}
if (!$hasData && !$form->contactHasName) {
$errors["email[1][email]"] = ts('Contact with no name must have an email.');
}
return $errors;
}
/**
* Set defaults for the form.
*
* @return array
*/
public function setDefaultValues() {
$defaults = array();
if (!empty($this->_emails)) {
foreach ($this->_emails as $id => $value) {
$defaults['email'][$id] = $value;
}
}
else {
// get the default location type
$locationType = CRM_Core_BAO_LocationType::getDefault();
$defaults['email'][1]['location_type_id'] = $locationType->id;
}
return $defaults;
}
/**
* Process the form.
*/
public function postProcess() {
$params = $this->exportValues();
// Process / save emails
$params['contact_id'] = $this->_contactId;
$params['updateBlankLocInfo'] = TRUE;
$params['email']['isIdSet'] = TRUE;
foreach ($this->_emails as $count => $value) {
if (!empty($value['id']) && isset($params['email'][$count])) {
$params['email'][$count]['id'] = $value['id'];
}
}
CRM_Core_BAO_Block::create('email', $params);
// If contact has no name, set primary email as display name
// TODO: This should be handled in the BAO for the benefit of the api, etc.
if (!$this->contactHasName) {
foreach ($params['email'] as $email) {
if ($email['is_primary']) {
CRM_Core_DAO::setFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'display_name', $email['email']);
CRM_Core_DAO::setFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'sort_name', $email['email']);
$this->ajaxResponse['reloadBlocks'] = array('#crm-contactname-content');
break;
}
}
}
$this->log();
$this->response();
}
}

View file

@ -0,0 +1,173 @@
<?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
*/
/**
* Form helper class for an IM object.
*/
class CRM_Contact_Form_Inline_IM extends CRM_Contact_Form_Inline {
/**
* Ims of the contact that is been viewed.
*/
private $_ims = array();
/**
* No of im blocks for inline edit.
*/
private $_blockCount = 6;
/**
* Call preprocess.
*/
public function preProcess() {
parent::preProcess();
//get all the existing ims
$im = new CRM_Core_BAO_IM();
$im->contact_id = $this->_contactId;
$this->_ims = CRM_Core_BAO_Block::retrieveBlock($im, NULL);
}
/**
* Build the form object elements for im object.
*/
public function buildQuickForm() {
parent::buildQuickForm();
$totalBlocks = $this->_blockCount;
$actualBlockCount = 1;
if (count($this->_ims) > 1) {
$actualBlockCount = $totalBlocks = count($this->_ims);
if ($totalBlocks < $this->_blockCount) {
$additionalBlocks = $this->_blockCount - $totalBlocks;
$totalBlocks += $additionalBlocks;
}
else {
$actualBlockCount++;
$totalBlocks++;
}
}
$this->assign('actualBlockCount', $actualBlockCount);
$this->assign('totalBlocks', $totalBlocks);
$this->applyFilter('__ALL__', 'trim');
for ($blockId = 1; $blockId < $totalBlocks; $blockId++) {
CRM_Contact_Form_Edit_IM::buildQuickForm($this, $blockId, TRUE);
}
$this->addFormRule(array('CRM_Contact_Form_Inline_IM', 'formRule'));
}
/**
* Global validation rules for the form.
*
* @param array $fields
* Posted values of the form.
* @param array $errors
* List of errors to be posted back to the form.
*
* @return array
*/
public static function formRule($fields, $errors) {
$hasData = $hasPrimary = $errors = array();
if (!empty($fields['im']) && is_array($fields['im'])) {
foreach ($fields['im'] as $instance => $blockValues) {
$dataExists = CRM_Contact_Form_Contact::blockDataExists($blockValues);
if ($dataExists) {
$hasData[] = $instance;
if (!empty($blockValues['is_primary'])) {
$hasPrimary[] = $instance;
if (!$primaryID && !empty($blockValues['im'])) {
$primaryID = $blockValues['im'];
}
}
}
}
if (empty($hasPrimary) && !empty($hasData)) {
$errors["im[1][is_primary]"] = ts('One IM should be marked as primary.');
}
if (count($hasPrimary) > 1) {
$errors["im[" . array_pop($hasPrimary) . "][is_primary]"] = ts('Only one IM can be marked as primary.');
}
}
return $errors;
}
/**
* Set defaults for the form.
*
* @return array
*/
public function setDefaultValues() {
$defaults = array();
if (!empty($this->_ims)) {
foreach ($this->_ims as $id => $value) {
$defaults['im'][$id] = $value;
}
}
else {
// get the default location type
$locationType = CRM_Core_BAO_LocationType::getDefault();
$defaults['im'][1]['location_type_id'] = $locationType->id;
}
return $defaults;
}
/**
* Process the form.
*/
public function postProcess() {
$params = $this->exportValues();
// Process / save IMs
$params['contact_id'] = $this->_contactId;
$params['updateBlankLocInfo'] = TRUE;
$params['im']['isIdSet'] = TRUE;
foreach ($this->_ims as $count => $value) {
if (!empty($value['id']) && isset($params['im'][$count])) {
$params['im'][$count]['id'] = $value['id'];
}
}
CRM_Core_BAO_Block::create('im', $params);
$this->log();
$this->response();
}
}

View file

@ -0,0 +1,99 @@
<?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
*/
/**
* Auxiliary class to provide support for locking (and ignoring locks on) contact records.
*/
class CRM_Contact_Form_Inline_Lock {
/**
* This function provides the HTML form elements.
*
* @param CRM_Core_Form $form
* Form object.
* @param int $contactID
*/
public static function buildQuickForm(&$form, $contactID) {
// We provide a value for oplock_ts to client, but JS uses it carefully
// -- i.e. when loading the first inline form, JS copies oplock_ts to a
// global value, and that global value is used for future form submissions.
// Any time a form is submitted, the value will be updated. This
// handles cases like:
// - V1:open V1.phone:open V1.email:open V1.email:submit V1.phone:submit
// - V1:open E1:open E1:submit V1.email:open V1.email:submit
// - V1:open V1.email:open E1:open E1:submit V1.email:submit V1:lock
$timestamps = CRM_Contact_BAO_Contact::getTimestamps($contactID);
$form->addElement('hidden', 'oplock_ts', $timestamps['modified_date'], array('id' => 'oplock_ts'));
$form->addFormRule(array('CRM_Contact_Form_Inline_Lock', 'formRule'), $contactID);
}
/**
* Ensure that oplock_ts hasn't changed in the underlying DB.
*
* @param array $fields
* The input form values.
* @param array $files
* The uploaded files if any.
* @param int $contactID
*
* @return bool|array
* true if no errors, else array of errors
*/
public static function formRule($fields, $files, $contactID = NULL) {
$errors = array();
$timestamps = CRM_Contact_BAO_Contact::getTimestamps($contactID);
if ($fields['oplock_ts'] != $timestamps['modified_date']) {
// Inline buttons generated via JS
$open = sprintf("<div class='update_oplock_ts' data:update_oplock_ts='%s'>", $timestamps['modified_date']);
$close = "</div>";
$errors['oplock_ts'] = $open . ts('This record was modified by another user!') . $close;
}
return empty($errors) ? TRUE : $errors;
}
/**
* Return any post-save data.
*
* @param int $contactID
*
* @return array
* extra options to return in JSON
*/
public static function getResponse($contactID) {
$timestamps = CRM_Contact_BAO_Contact::getTimestamps($contactID);
return array('oplock_ts' => $timestamps['modified_date']);
}
}

View file

@ -0,0 +1,173 @@
<?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
*/
/**
* Form helper class for an OpenID object.
*/
class CRM_Contact_Form_Inline_OpenID extends CRM_Contact_Form_Inline {
/**
* Ims of the contact that is been viewed.
*/
private $_openids = array();
/**
* No of openid blocks for inline edit.
*/
private $_blockCount = 6;
/**
* Call preprocess.
*/
public function preProcess() {
parent::preProcess();
//get all the existing openids
$openid = new CRM_Core_BAO_OpenID();
$openid->contact_id = $this->_contactId;
$this->_openids = CRM_Core_BAO_Block::retrieveBlock($openid, NULL);
}
/**
* Build the form object elements for openID object.
*/
public function buildQuickForm() {
parent::buildQuickForm();
$totalBlocks = $this->_blockCount;
$actualBlockCount = 1;
if (count($this->_openids) > 1) {
$actualBlockCount = $totalBlocks = count($this->_openids);
if ($totalBlocks < $this->_blockCount) {
$additionalBlocks = $this->_blockCount - $totalBlocks;
$totalBlocks += $additionalBlocks;
}
else {
$actualBlockCount++;
$totalBlocks++;
}
}
$this->assign('actualBlockCount', $actualBlockCount);
$this->assign('totalBlocks', $totalBlocks);
$this->applyFilter('__ALL__', 'trim');
for ($blockId = 1; $blockId < $totalBlocks; $blockId++) {
CRM_Contact_Form_Edit_OpenID::buildQuickForm($this, $blockId, TRUE);
}
$this->addFormRule(array('CRM_Contact_Form_Inline_OpenID', 'formRule'));
}
/**
* Global validation rules for the form.
*
* @param array $fields
* Posted values of the form.
* @param array $errors
* List of errors to be posted back to the form.
*
* @return array
*/
public static function formRule($fields, $errors) {
$hasData = $hasPrimary = $errors = array();
if (!empty($fields['openid']) && is_array($fields['openid'])) {
foreach ($fields['openid'] as $instance => $blockValues) {
$dataExists = CRM_Contact_Form_Contact::blockDataExists($blockValues);
if ($dataExists) {
$hasData[] = $instance;
if (!empty($blockValues['is_primary'])) {
$hasPrimary[] = $instance;
if (!$primaryID && !empty($blockValues['openid'])) {
$primaryID = $blockValues['openid'];
}
}
}
}
if (empty($hasPrimary) && !empty($hasData)) {
$errors["openid[1][is_primary]"] = ts('One OpenID should be marked as primary.');
}
if (count($hasPrimary) > 1) {
$errors["openid[" . array_pop($hasPrimary) . "][is_primary]"] = ts('Only one OpenID can be marked as primary.');
}
}
return $errors;
}
/**
* Set defaults for the form.
*
* @return array
*/
public function setDefaultValues() {
$defaults = array();
if (!empty($this->_openids)) {
foreach ($this->_openids as $id => $value) {
$defaults['openid'][$id] = $value;
}
}
else {
// get the default location type
$locationType = CRM_Core_BAO_LocationType::getDefault();
$defaults['openid'][1]['location_type_id'] = $locationType->id;
}
return $defaults;
}
/**
* Process the form.
*/
public function postProcess() {
$params = $this->exportValues();
// Process / save openID
$params['contact_id'] = $this->_contactId;
$params['updateBlankLocInfo'] = TRUE;
$params['openid']['isIdSet'] = TRUE;
foreach ($this->_openids as $count => $value) {
if (!empty($value['id']) && isset($params['openid'][$count])) {
$params['openid'][$count]['id'] = $value['id'];
}
}
CRM_Core_BAO_Block::create('openid', $params);
$this->log();
$this->response();
}
}

View file

@ -0,0 +1,174 @@
<?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
*/
/**
* Form helper class for an Phone object.
*/
class CRM_Contact_Form_Inline_Phone extends CRM_Contact_Form_Inline {
/**
* Phones of the contact that is been viewed
*/
private $_phones = array();
/**
* No of phone blocks for inline edit
*/
private $_blockCount = 6;
/**
* Call preprocess.
*/
public function preProcess() {
parent::preProcess();
//get all the existing phones
$phone = new CRM_Core_BAO_Phone();
$phone->contact_id = $this->_contactId;
$this->_phones = CRM_Core_BAO_Block::retrieveBlock($phone, NULL);
}
/**
* Build the form object elements for phone object.
*/
public function buildQuickForm() {
parent::buildQuickForm();
$totalBlocks = $this->_blockCount;
$actualBlockCount = 1;
if (count($this->_phones) > 1) {
$actualBlockCount = $totalBlocks = count($this->_phones);
if ($totalBlocks < $this->_blockCount) {
$additionalBlocks = $this->_blockCount - $totalBlocks;
$totalBlocks += $additionalBlocks;
}
else {
$actualBlockCount++;
$totalBlocks++;
}
}
$this->assign('actualBlockCount', $actualBlockCount);
$this->assign('totalBlocks', $totalBlocks);
$this->applyFilter('__ALL__', 'trim');
for ($blockId = 1; $blockId < $totalBlocks; $blockId++) {
CRM_Contact_Form_Edit_Phone::buildQuickForm($this, $blockId, TRUE);
}
$this->addFormRule(array('CRM_Contact_Form_Inline_Phone', 'formRule'));
}
/**
* Global validation rules for the form.
*
* @param array $fields
* Posted values of the form.
* @param array $errors
* List of errors to be posted back to the form.
*
* @return array
*/
public static function formRule($fields, $errors) {
$hasData = $hasPrimary = $errors = array();
if (!empty($fields['phone']) && is_array($fields['phone'])) {
$primaryID = NULL;
foreach ($fields['phone'] as $instance => $blockValues) {
$dataExists = CRM_Contact_Form_Contact::blockDataExists($blockValues);
if ($dataExists) {
$hasData[] = $instance;
if (!empty($blockValues['is_primary'])) {
$hasPrimary[] = $instance;
if (!$primaryID && !empty($blockValues['phone'])) {
$primaryID = $blockValues['phone'];
}
}
}
}
if (empty($hasPrimary) && !empty($hasData)) {
$errors["phone[1][is_primary]"] = ts('One phone should be marked as primary.');
}
if (count($hasPrimary) > 1) {
$errors["phone[" . array_pop($hasPrimary) . "][is_primary]"] = ts('Only one phone can be marked as primary.');
}
}
return $errors;
}
/**
* Set defaults for the form.
*
* @return array
*/
public function setDefaultValues() {
$defaults = array();
if (!empty($this->_phones)) {
foreach ($this->_phones as $id => $value) {
$defaults['phone'][$id] = $value;
}
}
else {
// get the default location type
$locationType = CRM_Core_BAO_LocationType::getDefault();
$defaults['phone'][1]['location_type_id'] = $locationType->id;
}
return $defaults;
}
/**
* Process the form.
*/
public function postProcess() {
$params = $this->exportValues();
// Process / save phones
$params['contact_id'] = $this->_contactId;
$params['updateBlankLocInfo'] = TRUE;
$params['phone']['isIdSet'] = TRUE;
foreach ($this->_phones as $count => $value) {
if (!empty($value['id']) && isset($params['phone'][$count])) {
$params['phone'][$count]['id'] = $value['id'];
}
}
CRM_Core_BAO_Block::create('phone', $params);
$this->log();
$this->response();
}
}

View file

@ -0,0 +1,131 @@
<?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
*/
/**
* Form helper class for an Website object,
*/
class CRM_Contact_Form_Inline_Website extends CRM_Contact_Form_Inline {
/**
* Websitess of the contact that is been viewed.
*/
private $_websites = array();
/**
* No of website blocks for inline edit.
*/
private $_blockCount = 6;
/**
* Call preprocess.
*/
public function preProcess() {
parent::preProcess();
//get all the existing websites
$params = array('contact_id' => $this->_contactId);
$values = array();
$this->_websites = CRM_Core_BAO_Website::getValues($params, $values);
}
/**
* Build the form object elements for website object.
*/
public function buildQuickForm() {
parent::buildQuickForm();
$totalBlocks = $this->_blockCount;
$actualBlockCount = 1;
if (count($this->_websites) > 1) {
$actualBlockCount = $totalBlocks = count($this->_websites);
if ($totalBlocks < $this->_blockCount) {
$additionalBlocks = $this->_blockCount - $totalBlocks;
$totalBlocks += $additionalBlocks;
}
else {
$actualBlockCount++;
$totalBlocks++;
}
}
$this->assign('actualBlockCount', $actualBlockCount);
$this->assign('totalBlocks', $totalBlocks);
$this->applyFilter('__ALL__', 'trim');
for ($blockId = 1; $blockId < $totalBlocks; $blockId++) {
CRM_Contact_Form_Edit_Website::buildQuickForm($this, $blockId, TRUE);
}
}
/**
* Set defaults for the form.
*
* @return array
*/
public function setDefaultValues() {
$defaults = array();
if (!empty($this->_websites)) {
foreach ($this->_websites as $id => $value) {
$defaults['website'][$id] = $value;
}
}
else {
// set the default website type
$defaults['website'][1]['website_type_id'] = key(CRM_Core_OptionGroup::values('website_type',
FALSE, FALSE, FALSE, ' AND is_default = 1'
));
}
return $defaults;
}
/**
* Process the form.
*/
public function postProcess() {
$params = $this->exportValues();
foreach ($this->_websites as $count => $value) {
if (!empty($value['id']) && isset($params['website'][$count])) {
$params['website'][$count]['id'] = $value['id'];
}
}
// Process / save websites
CRM_Core_BAO_Website::create($params['website'], $this->_contactId, TRUE);
$this->log();
$this->response();
}
}

View file

@ -0,0 +1,117 @@
<?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_Location {
/**
* Set variables up before form is built.
*
* @param CRM_Core_Form $form
*/
public static function preProcess(&$form) {
$form->_addBlockName = CRM_Utils_Request::retrieve('block', 'String');
$additionalblockCount = CRM_Utils_Request::retrieve('count', 'Positive');
$form->assign('addBlock', FALSE);
if ($form->_addBlockName && $additionalblockCount) {
$form->assign('addBlock', TRUE);
$form->assign('blockName', $form->_addBlockName);
$form->assign('blockId', $additionalblockCount);
$form->set($form->_addBlockName . '_Block_Count', $additionalblockCount);
}
if (is_a($form, 'CRM_Event_Form_ManageEvent_Location')
|| is_a($form, 'CRM_Contact_Form_Domain')) {
$form->_blocks = array(
'Address' => ts('Address'),
'Email' => ts('Email'),
'Phone' => ts('Phone'),
);
}
$form->assign('blocks', $form->_blocks);
$form->assign('className', CRM_Utils_System::getClassName($form));
// get address sequence.
if (!$addressSequence = $form->get('addressSequence')) {
$addressSequence = CRM_Core_BAO_Address::addressSequence();
$form->set('addressSequence', $addressSequence);
}
$form->assign('addressSequence', $addressSequence);
}
/**
* Build the form object.
*
* @param CRM_Core_Form $form
*/
public static function buildQuickForm(&$form) {
// required for subsequent AJAX requests.
$ajaxRequestBlocks = array();
$generateAjaxRequest = 0;
//build 1 instance of all blocks, without using ajax ...
foreach ($form->_blocks as $blockName => $label) {
require_once str_replace('_', DIRECTORY_SEPARATOR, 'CRM_Contact_Form_Edit_' . $blockName) . '.php';
$name = strtolower($blockName);
$instances = array(1);
if (!empty($_POST[$name]) && is_array($_POST[$name])) {
$instances = array_keys($_POST[$name]);
}
elseif (property_exists($form, '_values') && !empty($form->_values[$name]) && is_array($form->_values[$name])) {
$instances = array_keys($form->_values[$name]);
}
foreach ($instances as $instance) {
if ($instance == 1) {
$form->assign('addBlock', FALSE);
$form->assign('blockId', $instance);
}
else {
//we are going to build other block instances w/ AJAX
$generateAjaxRequest++;
$ajaxRequestBlocks[$blockName][$instance] = TRUE;
}
$form->set($blockName . '_Block_Count', $instance);
$formName = 'CRM_Contact_Form_Edit_' . $blockName;
$formName::buildQuickForm($form);
}
}
//assign to generate AJAX request for building extra blocks.
$form->assign('generateAjaxRequest', $generateAjaxRequest);
$form->assign('ajaxRequestBlocks', $ajaxRequestBlocks);
}
}

View file

@ -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_Merge.
*/
class CRM_Contact_Form_Merge extends CRM_Core_Form {
// The id of the contact that there's a duplicate for; this one will
// possibly inherit some of $_oid's properties and remain in the system.
var $_cid = NULL;
// The id of the other contact - the duplicate one that will get deleted.
var $_oid = NULL;
var $_contactType = NULL;
/**
* Query limit to be retained in the urls.
*
* @var int
*/
var $limit;
/**
* String for quickform bug handling.
*
* FIXME: QuickForm can't create advcheckboxes with value set to 0 or '0' :(
* see HTML_QuickForm_advcheckbox::setValues() - but patching that doesn't
* help, as QF doesn't put the 0-value elements in exportValues() anyway...
* to side-step this, we use the below UUID as a (re)placeholder
*
* @var string
*/
var $_qfZeroBug = 'e8cddb72-a257-11dc-b9cc-0016d3330ee9';
public function preProcess() {
try {
$this->_cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE);
$this->_oid = CRM_Utils_Request::retrieve('oid', 'Positive', $this, TRUE);
$flip = CRM_Utils_Request::retrieve('flip', 'Positive', $this, FALSE);
$this->_rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE);
$this->_gid = $gid = CRM_Utils_Request::retrieve('gid', 'Positive', $this, FALSE);
$this->_mergeId = CRM_Utils_Request::retrieve('mergeId', 'Positive', $this, FALSE);
$this->limit = CRM_Utils_Request::retrieve('limit', 'Positive', $this, FALSE);
$urlParams = "reset=1&rgid={$this->_rgid}&gid={$this->_gid}&limit=" . $this->limit;
$this->bounceIfInvalid($this->_cid, $this->_oid);
$this->_contactType = civicrm_api3('Contact', 'getvalue', array(
'id' => $this->_cid,
'return' => 'contact_type',
));
$browseUrl = CRM_Utils_System::url('civicrm/contact/dedupefind', $urlParams . '&action=browse');
if (!$this->_rgid) {
// Unset browse URL as we have come from the search screen.
$browseUrl = '';
$this->_rgid = civicrm_api3('RuleGroup', 'getvalue', array(
'contact_type' => $this->_contactType,
'used' => 'Supervised',
'return' => 'id',
));
}
$this->assign('browseUrl', $browseUrl);
if ($browseUrl) {
CRM_Core_Session::singleton()->pushUserContext($browseUrl);
}
$cacheKey = CRM_Dedupe_Merger::getMergeCacheKeyString($this->_rgid, $gid);
$join = CRM_Dedupe_Merger::getJoinOnDedupeTable();
$where = "de.id IS NULL";
$pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, $this->_cid, $this->_oid, $this->_mergeId, $join, $where, $flip);
// get user info of main contact.
$config = CRM_Core_Config::singleton();
CRM_Core_Config::setPermitCacheFlushMode(FALSE);
$mainUfId = CRM_Core_BAO_UFMatch::getUFId($this->_cid);
$mainUser = NULL;
if ($mainUfId) {
// d6 compatible
if ($config->userSystem->is_drupal == '1') {
$mainUser = user_load($mainUfId);
}
elseif ($config->userFramework == 'Joomla') {
$mainUser = JFactory::getUser($mainUfId);
}
$this->assign('mainUfId', $mainUfId);
$this->assign('mainUfName', $mainUser ? $mainUser->name : NULL);
}
$flipUrl = CRM_Utils_System::url('civicrm/contact/merge',
"reset=1&action=update&cid={$this->_oid}&oid={$this->_cid}&rgid={$this->_rgid}&gid={$gid}"
);
if (!$flip) {
$flipUrl .= '&flip=1';
}
$this->assign('flip', $flipUrl);
$this->prev = $this->next = NULL;
foreach (array(
'prev',
'next',
) as $position) {
if (!empty($pos[$position])) {
if ($pos[$position]['id1'] && $pos[$position]['id2']) {
$urlParams .= "&cid={$pos[$position]['id1']}&oid={$pos[$position]['id2']}&mergeId={$pos[$position]['mergeId']}&action=update";
$this->$position = CRM_Utils_System::url('civicrm/contact/merge', $urlParams);
$this->assign($position, $this->$position);
}
}
}
// get user info of other contact.
$otherUfId = CRM_Core_BAO_UFMatch::getUFId($this->_oid);
$otherUser = NULL;
if ($otherUfId) {
// d6 compatible
if ($config->userSystem->is_drupal == '1') {
$otherUser = user_load($otherUfId);
}
elseif ($config->userFramework == 'Joomla') {
$otherUser = JFactory::getUser($otherUfId);
}
$this->assign('otherUfId', $otherUfId);
$this->assign('otherUfName', $otherUser ? $otherUser->name : NULL);
}
$cmsUser = ($mainUfId && $otherUfId) ? TRUE : FALSE;
$this->assign('user', $cmsUser);
$rowsElementsAndInfo = CRM_Dedupe_Merger::getRowsElementsAndInfo($this->_cid, $this->_oid);
$main = $this->_mainDetails = $rowsElementsAndInfo['main_details'];
$other = $this->_otherDetails = $rowsElementsAndInfo['other_details'];
$this->assign('contact_type', $main['contact_type']);
$this->assign('main_name', $main['display_name']);
$this->assign('other_name', $other['display_name']);
$this->assign('main_cid', $main['contact_id']);
$this->assign('other_cid', $other['contact_id']);
$this->assign('rgid', $this->_rgid);
$this->addElement('checkbox', 'toggleSelect', NULL, NULL, array('class' => 'select-rows'));
$this->assign('mainLocBlock', json_encode($rowsElementsAndInfo['main_details']['location_blocks']));
$this->assign('locationBlockInfo', json_encode(CRM_Dedupe_Merger::getLocationBlockInfo()));
$this->assign('rows', $rowsElementsAndInfo['rows']);
// add elements
foreach ($rowsElementsAndInfo['elements'] as $element) {
// We could push this down to the getRowsElementsAndInfo function but it's
// already so overloaded - let's start moving towards doing form-things
// on the form.
if (substr($element[1], 0, 13) === 'move_location') {
$element[4] = array_merge(
(array) CRM_Utils_Array::value(4, $element, array()),
array(
'data-location' => substr($element[1], 14),
'data-is_location' => TRUE,
));
}
if (substr($element[1], 0, 15) === 'location_blocks') {
// @todo We could add some data elements here to make jquery manipulation more straight-forward
// @todo consider enabling if it is an add & defaulting to true.
$element[4] = array_merge((array) CRM_Utils_Array::value(4, $element, array()), array('disabled' => TRUE));
}
$this->addElement($element[0],
$element[1],
array_key_exists('2', $element) ? $element[2] : NULL,
array_key_exists('3', $element) ? $element[3] : NULL,
array_key_exists('4', $element) ? $element[4] : NULL,
array_key_exists('5', $element) ? $element[5] : NULL
);
}
// add related table elements
foreach ($rowsElementsAndInfo['rel_table_elements'] as $relTableElement) {
$element = $this->addElement($relTableElement[0], $relTableElement[1]);
$element->setChecked(TRUE);
}
$this->assign('rel_tables', $rowsElementsAndInfo['rel_tables']);
$this->assign('userContextURL', CRM_Core_Session::singleton()
->readUserContext());
}
catch (CRM_Core_Exception $e) {
CRM_Core_Error::statusBounce(ts($e->getMessage()));
}
}
public function addRules() {
}
public function buildQuickForm() {
CRM_Utils_System::setTitle(ts('Merge %1 contacts', array(1 => $this->_contactType)));
$buttons = array();
$buttons[] = array(
'type' => 'next',
'name' => $this->next ? ts('Merge and go to Next Pair') : ts('Merge'),
'isDefault' => TRUE,
'icon' => $this->next ? 'circle-triangle-e' : 'check',
);
if ($this->next || $this->prev) {
$buttons[] = array(
'type' => 'submit',
'name' => ts('Merge and go to Listing'),
);
$buttons[] = array(
'type' => 'done',
'name' => ts('Merge and View Result'),
'icon' => 'fa-check-circle',
);
}
$buttons[] = array(
'type' => 'cancel',
'name' => ts('Cancel'),
);
$this->addButtons($buttons);
$this->addFormRule(array('CRM_Contact_Form_Merge', 'formRule'), $this);
}
/**
* @param $fields
* @param $files
* @param $self
*
* @return array
*/
public static function formRule($fields, $files, $self) {
$errors = array();
$link = CRM_Utils_System::href(ts('Flip between the original and duplicate contacts.'),
'civicrm/contact/merge',
'reset=1&action=update&cid=' . $self->_oid . '&oid=' . $self->_cid . '&rgid=' . $self->_rgid . '&flip=1'
);
if (CRM_Contact_BAO_Contact::checkDomainContact($self->_oid)) {
$errors['_qf_default'] = ts("The Default Organization contact cannot be merged into another contact record. It is associated with the CiviCRM installation for this domain and contains information used for system functions. If you want to merge these records, you can: %1", array(1 => $link));
}
return $errors;
}
public function postProcess() {
$formValues = $this->exportValues();
$formValues['main_details'] = $this->_mainDetails;
$formValues['other_details'] = $this->_otherDetails;
$migrationData = array('migration_info' => $formValues);
CRM_Utils_Hook::merge('form', $migrationData, $this->_cid, $this->_oid);
CRM_Dedupe_Merger::moveAllBelongings($this->_cid, $this->_oid, $migrationData['migration_info']);
$name = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_cid, 'display_name');
$message = '<ul><li>' . ts('%1 has been updated.', array(1 => $name)) . '</li><li>' . ts('Contact ID %1 has been deleted.', array(1 => $this->_oid)) . '</li></ul>';
CRM_Core_Session::setStatus($message, ts('Contacts Merged'), 'success');
$url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->_cid}");
$urlParams = "reset=1&gid={$this->_gid}&rgid={$this->_rgid}&limit={$this->limit}";
if (!empty($formValues['_qf_Merge_submit'])) {
$urlParams .= "&action=update";
$lisitingURL = CRM_Utils_System::url('civicrm/contact/dedupefind',
$urlParams
);
CRM_Utils_System::redirect($lisitingURL);
}
if (!empty($formValues['_qf_Merge_done'])) {
CRM_Utils_System::redirect($url);
}
if ($this->next && $this->_mergeId) {
$cacheKey = CRM_Dedupe_Merger::getMergeCacheKeyString($this->_rgid, $this->_gid);
$join = CRM_Dedupe_Merger::getJoinOnDedupeTable();
$where = "de.id IS NULL";
$pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, NULL, NULL, $this->_mergeId, $join, $where);
if (!empty($pos) &&
$pos['next']['id1'] &&
$pos['next']['id2']
) {
$urlParams .= "&cid={$pos['next']['id1']}&oid={$pos['next']['id2']}&mergeId={$pos['next']['mergeId']}&action=update";
$url = CRM_Utils_System::url('civicrm/contact/merge', $urlParams);
}
}
CRM_Utils_System::redirect($url);
}
/**
* Bounce if the merge action is invalid.
*
* We don't allow the merge if it is nonsensical, marked as a duplicate
* or outside the user's permission.
*
* @param int $cid
* Contact ID to retain
* @param int $oid
* Contact ID to delete.
*/
public function bounceIfInvalid($cid, $oid) {
if ($cid == $oid) {
CRM_Core_Error::statusBounce(ts('Cannot merge a contact with itself.'));
}
if (!CRM_Dedupe_BAO_Rule::validateContacts($cid, $oid)) {
CRM_Core_Error::statusBounce(ts('The selected pair of contacts are marked as non duplicates. If these records should be merged, you can remove this exception on the <a href="%1">Dedupe Exceptions</a> page.', array(1 => CRM_Utils_System::url('civicrm/dedupe/exception', 'reset=1'))));
}
if (!(CRM_Contact_BAO_Contact_Permission::allow($cid, CRM_Core_Permission::EDIT) &&
CRM_Contact_BAO_Contact_Permission::allow($oid, CRM_Core_Permission::EDIT)
)
) {
CRM_Utils_System::permissionDenied();
}
// ensure that oid is not the current user, if so refuse to do the merge
if (CRM_Core_Session::singleton()->getLoggedInContactID() == $oid) {
$message = ts('The contact record which is linked to the currently logged in user account - \'%1\' - cannot be deleted.',
array(1 => CRM_Core_Session::singleton()->getLoggedInContactDisplayName())
);
CRM_Core_Error::statusBounce($message);
}
}
}

View file

@ -0,0 +1,190 @@
<?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 generates form components generic to all the contact types.
*
* It delegates the work to lower level subclasses and integrates the changes
* back in. It also uses a lot of functionality with the CRM API's, so any change
* made here could potentially affect the API etc. Be careful, be aware, use unit tests.
*/
class CRM_Contact_Form_RelatedContact extends CRM_Core_Form {
/**
* The contact type of the form.
*
* @var string
*/
protected $_contactType;
/**
* The contact id, used when editing the form
*
* @var int
*/
public $_contactId;
/**
* Explicitly declare the form context.
*/
public function getDefaultContext() {
return 'create';
}
/**
* Build all the data structures needed to build the form.
*/
public function preProcess() {
// reset action from the session
$this->_action = CRM_Utils_Request::retrieve('action', 'String',
$this, FALSE, 'update'
);
$this->_contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE);
$rcid = CRM_Utils_Request::retrieve('rcid', 'Positive', $this);
$rcid = $rcid ? "&id={$rcid}" : '';
$session = CRM_Core_Session::singleton();
$session->pushUserContext(CRM_Utils_System::url('civicrm/user', "reset=1{$rcid}"));
if ($this->_contactId) {
$contact = new CRM_Contact_DAO_Contact();
$contact->id = $this->_contactId;
if (!$contact->find(TRUE)) {
CRM_Core_Error::statusBounce(ts('contact does not exist: %1', array(1 => $this->_contactId)));
}
$this->_contactType = $contact->contact_type;
// check for permissions
if (!CRM_Contact_BAO_Contact_Permission::allow($this->_contactId, CRM_Core_Permission::EDIT)) {
CRM_Core_Error::statusBounce(ts('You do not have the necessary permission to edit this contact.'));
}
list($displayName, $contactImage) = CRM_Contact_BAO_Contact::getDisplayAndImage($this->_contactId);
CRM_Utils_System::setTitle($displayName, $contactImage . ' ' . $displayName);
}
else {
CRM_Core_Error::statusBounce(ts('Could not get a contact_id and/or contact_type'));
}
}
/**
* Set default values for the form.
*
* Note that in edit/view mode the default values are retrieved from the
* database
*/
public function setDefaultValues() {
return $this->_defaults;
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$params = array();
$params['id'] = $params['contact_id'] = $this->_contactId;
$contact = CRM_Contact_BAO_Contact::retrieve($params, $this->_defaults);
$countryID = '';
$stateID = '';
if (!empty($this->_defaults['address'][1])) {
$countryID = CRM_Utils_Array::value('country_id',
$this->_defaults['address'][1]
);
$stateID = CRM_Utils_Array::value('state_province_id',
$this->_defaults['address'][1]
);
}
CRM_Contact_BAO_Contact_Utils::buildOnBehalfForm($this,
$this->_contactType,
$countryID,
$stateID,
ts('Contact Information')
);
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Save'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
));
}
/**
* Form submission of new/edit contact is processed.
*/
public function postProcess() {
// store the submitted values in an array
$params = $this->controller->exportValues($this->_name);
$locType = CRM_Core_BAO_LocationType::getDefault();
foreach (array(
'phone',
'email',
'address',
) as $locFld) {
if (!empty($this->_defaults[$locFld]) && $this->_defaults[$locFld][1]['location_type_id']) {
$params[$locFld][1]['is_primary'] = $this->_defaults[$locFld][1]['is_primary'];
$params[$locFld][1]['location_type_id'] = $this->_defaults[$locFld][1]['location_type_id'];
}
else {
$params[$locFld][1]['is_primary'] = 1;
$params[$locFld][1]['location_type_id'] = $locType->id;
}
}
$params['contact_type'] = $this->_contactType;
//CRM-14904
if (isset($this->_defaults['contact_sub_type'])) {
$params['contact_sub_type'] = $this->_defaults['contact_sub_type'];
}
$params['contact_id'] = $this->_contactId;
$contact = CRM_Contact_BAO_Contact::create($params, TRUE);
// set status message.
if ($this->_contactId) {
$message = ts('%1 has been updated.', array(1 => $contact->display_name));
}
else {
$message = ts('%1 has been created.', array(1 => $contact->display_name));
}
CRM_Core_Session::setStatus($message, ts('Contact Saved'), 'success');
}
}

View file

@ -0,0 +1,672 @@
<?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 |
+--------------------------------------------------------------------+
*/
/**
* This class generates form components for relationship.
*/
class CRM_Contact_Form_Relationship extends CRM_Core_Form {
/**
* The relationship id, used when editing the relationship
*
* @var int
*/
public $_relationshipId;
/**
* The contact id, used when add/edit relationship
*
* @var int
*/
public $_contactId;
/**
* This is a string which is either a_b or b_a used to determine the relationship between to contacts
*/
public $_rtype;
/**
* This is a string which is used to determine the relationship between to contacts
*/
public $_rtypeId;
/**
* Display name of contact a
*/
public $_display_name_a;
/**
* Display name of contact b
*/
public $_display_name_b;
/**
* The relationship type id
*
* @var int
*/
public $_relationshipTypeId;
/**
* An array of all relationship names
*
* @var array
*/
public $_allRelationshipNames;
/**
* @var bool
*/
public $_enabled;
/**
* @var bool
*/
public $_isCurrentEmployer;
/**
* @var string
*/
public $_contactType;
/**
* The relationship values if Updating relationship
*/
public $_values;
/**
* Case id if it called from case context
*/
public $_caseId;
/**
* Explicitly declare the form context.
*/
public function getDefaultContext() {
return 'create';
}
/**
* Explicitly declare the entity api name.
*/
public function getDefaultEntity() {
return 'Relationship';
}
public function preProcess() {
$this->_contactId = $this->get('contactId');
$this->_contactType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'contact_type');
$this->_relationshipId = $this->get('id');
$this->_rtype = CRM_Utils_Request::retrieve('rtype', 'String', $this);
$this->_rtypeId = CRM_Utils_Request::retrieve('relTypeId', 'String', $this);
$this->_display_name_a = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'display_name');
$this->assign('display_name_a', $this->_display_name_a);
//get the relationship values.
$this->_values = array();
if ($this->_relationshipId) {
$params = array('id' => $this->_relationshipId);
CRM_Core_DAO::commonRetrieve('CRM_Contact_DAO_Relationship', $params, $this->_values);
}
// Check for permissions
if (in_array($this->_action, array(CRM_Core_Action::ADD, CRM_Core_Action::UPDATE, CRM_Core_Action::DELETE))) {
if (!CRM_Contact_BAO_Contact_Permission::allow($this->_contactId, CRM_Core_Permission::EDIT)
&& !CRM_Contact_BAO_Contact_Permission::allow($this->_values['contact_id_b'], CRM_Core_Permission::EDIT)) {
CRM_Core_Error::statusBounce(ts('You do not have the necessary permission to edit this contact.'));
}
}
// Set page title based on action
switch ($this->_action) {
case CRM_Core_Action::VIEW:
CRM_Utils_System::setTitle(ts('View Relationship for %1', array(1 => $this->_display_name_a)));
break;
case CRM_Core_Action::ADD:
CRM_Utils_System::setTitle(ts('Add Relationship for %1', array(1 => $this->_display_name_a)));
break;
case CRM_Core_Action::UPDATE:
CRM_Utils_System::setTitle(ts('Edit Relationship for %1', array(1 => $this->_display_name_a)));
break;
case CRM_Core_Action::DELETE:
CRM_Utils_System::setTitle(ts('Delete Relationship for %1', array(1 => $this->_display_name_a)));
break;
}
$this->_caseId = CRM_Utils_Request::retrieve('caseID', 'Integer', $this);
if (!$this->_rtypeId) {
$params = CRM_Utils_Request::exportValues();
if (isset($params['relationship_type_id'])) {
$this->_rtypeId = $params['relationship_type_id'];
}
elseif (!empty($this->_values)) {
$this->_rtypeId = $this->_values['relationship_type_id'] . '_' . $this->_rtype;
}
}
//get the relationship type id
$this->_relationshipTypeId = str_replace(array('_a_b', '_b_a'), array('', ''), $this->_rtypeId);
//get the relationship type
if (!$this->_rtype) {
$this->_rtype = str_replace($this->_relationshipTypeId . '_', '', $this->_rtypeId);
}
//need to assign custom data type and subtype to the template - FIXME: explain why
$this->assign('customDataType', 'Relationship');
$this->assign('customDataSubType', $this->_relationshipTypeId);
$this->assign('entityID', $this->_relationshipId);
//use name as it remain constant, CRM-3336
$this->_allRelationshipNames = CRM_Core_PseudoConstant::relationshipType('name');
// Current employer?
if ($this->_action & CRM_Core_Action::UPDATE) {
if ($this->_allRelationshipNames[$this->_relationshipTypeId]["name_a_b"] == 'Employee of') {
$this->_isCurrentEmployer = $this->_values['contact_id_b'] == CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_values['contact_id_a'], 'employer_id');
}
}
// when custom data is included in this page
if (!empty($_POST['hidden_custom'])) {
CRM_Custom_Form_CustomData::preProcess($this, NULL, $this->_relationshipTypeId, 1, 'Relationship', $this->_relationshipId);
CRM_Custom_Form_CustomData::buildQuickForm($this);
CRM_Custom_Form_CustomData::setDefaultValues($this);
}
}
/**
* Set default values for the form.
*/
public function setDefaultValues() {
$defaults = array();
if ($this->_action & CRM_Core_Action::UPDATE) {
if (!empty($this->_values)) {
$defaults['relationship_type_id'] = $this->_rtypeId;
if (!empty($this->_values['start_date'])) {
list($defaults['start_date']) = CRM_Utils_Date::setDateDefaults($this->_values['start_date']);
}
if (!empty($this->_values['end_date'])) {
list($defaults['end_date']) = CRM_Utils_Date::setDateDefaults($this->_values['end_date']);
}
$defaults['description'] = CRM_Utils_Array::value('description', $this->_values);
$defaults['is_active'] = CRM_Utils_Array::value('is_active', $this->_values);
// The javascript on the form will swap these fields if it is a b_a relationship, so we compensate here
$defaults['is_permission_a_b'] = CRM_Utils_Array::value('is_permission_' . $this->_rtype, $this->_values);
$defaults['is_permission_b_a'] = CRM_Utils_Array::value('is_permission_' . strrev($this->_rtype), $this->_values);
$defaults['is_current_employer'] = $this->_isCurrentEmployer;
// Load info about the related contact
$contact = new CRM_Contact_DAO_Contact();
if ($this->_rtype == 'a_b' && $this->_values['contact_id_a'] == $this->_contactId) {
$contact->id = $this->_values['contact_id_b'];
}
else {
$contact->id = $this->_values['contact_id_a'];
}
if ($contact->find(TRUE)) {
$defaults['related_contact_id'] = $contact->id;
$this->_display_name_b = $contact->display_name;
$this->assign('display_name_b', $this->_display_name_b);
}
$noteParams = array(
'entity_id' => $this->_relationshipId,
'entity_table' => 'civicrm_relationship',
'limit' => 1,
'version' => 3,
);
$note = civicrm_api('Note', 'getsingle', $noteParams);
$defaults['note'] = CRM_Utils_Array::value('note', $note);
}
}
else {
$defaults['is_active'] = $defaults['is_current_employer'] = 1;
$defaults['relationship_type_id'] = $this->_rtypeId;
}
$this->_enabled = $defaults['is_active'];
return $defaults;
}
/**
* Add the rules for form.
*/
public function addRules() {
if (!($this->_action & CRM_Core_Action::DELETE)) {
$this->addFormRule(array('CRM_Contact_Form_Relationship', 'dateRule'));
}
}
/**
* Build the form object.
*/
public function buildQuickForm() {
if ($this->_action & CRM_Core_Action::DELETE) {
$this->addButtons(array(
array(
'type' => 'next',
'name' => ts('Delete'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
)
);
return;
}
// Select list
$relationshipList = CRM_Contact_BAO_Relationship::getContactRelationshipType($this->_contactId, $this->_rtype, $this->_relationshipId);
// Metadata needed on clientside
$this->assign('relationshipData', self::getRelationshipTypeMetadata($relationshipList));
foreach ($this->_allRelationshipNames as $id => $vals) {
if ($vals['name_a_b'] === 'Employee of') {
$this->assign('employmentRelationship', $id);
break;
}
}
$this->addField('relationship_type_id', array('options' => array('' => ts('- select -')) + $relationshipList, 'class' => 'huge', 'placeholder' => '- select -'), TRUE);
$label = $this->_action & CRM_Core_Action::ADD ? ts('Contact(s)') : ts('Contact');
$contactField = $this->addField('related_contact_id', array('label' => $label, 'name' => 'contact_id_b', 'multiple' => TRUE, 'create' => TRUE), TRUE);
// This field cannot be updated
if ($this->_action & CRM_Core_Action::UPDATE) {
$contactField->freeze();
}
$this->add('advcheckbox', 'is_current_employer', $this->_contactType == 'Organization' ? ts('Current Employee') : ts('Current Employer'));
$this->addField('start_date', array('label' => ts('Start Date'), 'formatType' => 'searchDate'));
$this->addField('end_date', array('label' => ts('End Date'), 'formatType' => 'searchDate'));
$this->addField('is_active', array('label' => ts('Enabled?'), 'type' => 'advcheckbox'));
$this->addField('is_permission_a_b');
$this->addField('is_permission_b_a');
$this->addField('description', array('label' => ts('Description')));
CRM_Contact_Form_Edit_Notes::buildQuickForm($this);
if ($this->_action & CRM_Core_Action::VIEW) {
$this->addButtons(array(
array(
'type' => 'cancel',
'name' => ts('Done'),
),
));
}
else {
// make this form an upload since we don't know if the custom data injected dynamically is of type file etc.
$this->addButtons(array(
array(
'type' => 'upload',
'name' => ts('Save Relationship'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
));
}
}
/**
* This function is called when the form is submitted and also from unit test.
* @param array $params
*
* @return array
*/
public function submit($params) {
switch ($this->getAction()) {
case CRM_Core_Action::DELETE:
$this->deleteAction($this->_relationshipId);
return array();
case CRM_Core_Action::UPDATE:
return $this->updateAction($params);
default:
return $this->createAction($params);
}
}
/**
* This function is called when the form is submitted.
*/
public function postProcess() {
// Store the submitted values in an array.
$params = $this->controller->exportValues($this->_name);
$values = $this->submit($params);
if (empty($values)) {
return;
}
list ($params, $relationshipIds) = $values;
// if this is called from case view,
//create an activity for case role removal.CRM-4480
// @todo this belongs in the BAO.
if ($this->_caseId) {
CRM_Case_BAO_Case::createCaseRoleActivity($this->_caseId, $relationshipIds, $params['contact_check'], $this->_contactId);
}
// @todo this belongs in the BAO.
$note = !empty($params['note']) ? $params['note'] : '';
$this->saveRelationshipNotes($relationshipIds, $note);
$this->setEmploymentRelationship($params, $relationshipIds);
// Refresh contact tabs which might have been affected
$this->ajaxResponse['updateTabs'] = array(
'#tab_member' => CRM_Contact_BAO_Contact::getCountComponent('membership', $this->_contactId),
'#tab_contribute' => CRM_Contact_BAO_Contact::getCountComponent('contribution', $this->_contactId),
);
}
/**
* Date validation.
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
*
* @return bool|array
* mixed true or array of errors
*/
public static function dateRule($params) {
$errors = array();
// check start and end date
if (!empty($params['start_date']) && !empty($params['end_date'])) {
$start_date = CRM_Utils_Date::format(CRM_Utils_Array::value('start_date', $params));
$end_date = CRM_Utils_Date::format(CRM_Utils_Array::value('end_date', $params));
if ($start_date && $end_date && (int ) $end_date < (int ) $start_date) {
$errors['end_date'] = ts('The relationship end date cannot be prior to the start date.');
}
}
return empty($errors) ? TRUE : $errors;
}
/**
* Set Status message to reflect outcome of the update action.
*
* @param array $outcome
* Outcome of save action - including
* - 'valid' : Number of valid relationships attempted.
* - 'invalid' : Number of invalid relationships attempted.
* - 'duplicate' : Number of duplicate relationships attempted.
* - 'saved' : boolean of whether save was successful
*/
protected function setMessage($outcome) {
if (!empty($outcome['valid']) && empty($outcome['saved'])) {
CRM_Core_Session::setStatus(ts('Relationship created.', array(
'count' => $outcome['valid'],
'plural' => '%count relationships created.',
)), ts('Saved'), 'success');
}
if (!empty($outcome['invalid'])) {
CRM_Core_Session::setStatus(ts('%count relationship record was not created due to an invalid contact type.', array(
'count' => $outcome['invalid'],
'plural' => '%count relationship records were not created due to invalid contact types.',
)), ts('%count invalid relationship record', array(
'count' => $outcome['invalid'],
'plural' => '%count invalid relationship records',
)));
}
if (!empty($outcome['duplicate'])) {
CRM_Core_Session::setStatus(ts('One relationship was not created because it already exists.', array(
'count' => $outcome['duplicate'],
'plural' => '%count relationships were not created because they already exist.',
)), ts('%count duplicate relationship', array(
'count' => $outcome['duplicate'],
'plural' => '%count duplicate relationships',
)));
}
if (!empty($outcome['saved'])) {
CRM_Core_Session::setStatus(ts('Relationship record has been updated.'), ts('Saved'), 'success');
}
}
/**
* @param $relationshipList
* @return array
*/
public static function getRelationshipTypeMetadata($relationshipList) {
$contactTypes = CRM_Contact_BAO_ContactType::contactTypeInfo(TRUE);
$allRelationshipNames = CRM_Core_PseudoConstant::relationshipType('name');
$jsData = array();
// Get just what we need to keep the dom small
$whatWeWant = array_flip(array(
'contact_type_a',
'contact_type_b',
'contact_sub_type_a',
'contact_sub_type_b',
));
foreach ($allRelationshipNames as $id => $vals) {
if (isset($relationshipList["{$id}_a_b"]) || isset($relationshipList["{$id}_b_a"])) {
$jsData[$id] = array_filter(array_intersect_key($allRelationshipNames[$id], $whatWeWant));
// Add user-friendly placeholder
foreach (array('a', 'b') as $x) {
$type = !empty($jsData[$id]["contact_sub_type_$x"]) ? $jsData[$id]["contact_sub_type_$x"] : CRM_Utils_Array::value("contact_type_$x", $jsData[$id]);
$jsData[$id]["placeholder_$x"] = $type ? ts('- select %1 -', array(strtolower($contactTypes[$type]['label']))) : ts('- select contact -');
}
}
}
return $jsData;
}
/**
* Handling 'delete relationship' action
*
* @param int $id
* Relationship ID
*/
private function deleteAction($id) {
CRM_Contact_BAO_Relationship::del($id);
// reload all blocks to reflect this change on the user interface.
$this->ajaxResponse['reloadBlocks'] = array('#crm-contactinfo-content');
}
/**
* Handling updating relationship action
*
* @param array $params
*
* @return array
*/
private function updateAction($params) {
$params = $this->preparePostProcessParameters($params);
$params = $params[0];
try {
civicrm_api3('relationship', 'create', $params);
}
catch (CiviCRM_API3_Exception $e) {
throw new CRM_Core_Exception('Relationship create error ' . $e->getMessage());
}
$this->clearCurrentEmployer($params);
$this->setMessage(array('saved' => TRUE));
return array($params, array($this->_relationshipId));
}
/**
* Handling creating relationship action
*
* @param array $params
*
* @return array
*/
private function createAction($params) {
list($params, $primaryContactLetter) = $this->preparePostProcessParameters($params);
$outcome = CRM_Contact_BAO_Relationship::createMultiple($params, $primaryContactLetter);
$relationshipIds = $outcome['relationship_ids'];
$this->setMessage($outcome);
return array($params, $relationshipIds);
}
/**
* Prepares parameters to be used for create/update actions
*
* @param array $params
*
* @return array
*/
private function preparePostProcessParameters($params) {
$relationshipTypeParts = explode('_', $params['relationship_type_id']);
$params['relationship_type_id'] = $relationshipTypeParts[0];
$params['contact_id_' . $relationshipTypeParts[1]] = $this->_contactId;
if (empty($this->_relationshipId)) {
$params['contact_id_' . $relationshipTypeParts[2]] = explode(',', $params['related_contact_id']);
}
else {
$params['id'] = $this->_relationshipId;
$params['contact_id_' . $relationshipTypeParts[2]] = $params['related_contact_id'];
foreach (array('start_date', 'end_date') as $dateParam) {
if (!empty($params[$dateParam])) {
$params[$dateParam] = CRM_Utils_Date::processDate($params[$dateParam]);
}
}
}
// CRM-14612 - Don't use adv-checkbox as it interferes with the form js
$params['is_permission_a_b'] = CRM_Utils_Array::value('is_permission_a_b', $params, 0);
$params['is_permission_b_a'] = CRM_Utils_Array::value('is_permission_b_a', $params, 0);
return array($params, $relationshipTypeParts[1]);
}
/**
* Updates/Creates relationship notes
*
* @param array $relationshipIds
* @param string $note
*/
private function saveRelationshipNotes($relationshipIds, $note) {
foreach ($relationshipIds as $id) {
$noteParams = array(
'entity_id' => $id,
'entity_table' => 'civicrm_relationship',
);
$existing = civicrm_api3('note', 'get', $noteParams);
if (!empty($existing['id'])) {
$noteParams['id'] = $existing['id'];
}
$action = NULL;
if (!empty($note)) {
$action = 'create';
$noteParams['note'] = $note;
$noteParams['contact_id'] = $this->_contactId;
}
elseif (!empty($noteParams['id'])) {
$action = 'delete';
}
if (!empty($action)) {
civicrm_api3('note', $action, $noteParams);
}
}
}
/**
* Sets current employee/employer relationship
*
* @param $params
* @param array $relationshipIds
*/
private function setEmploymentRelationship($params, $relationshipIds) {
if (
!empty($params['is_current_employer']) &&
$this->_allRelationshipNames[$params['relationship_type_id']]["name_a_b"] == 'Employee of') {
$employerParams = array();
foreach ($relationshipIds as $id) {
// Fixme this is dumb why do we have to look this up again?
$rel = CRM_Contact_BAO_Relationship::getRelationshipByID($id);
$employerParams[$rel->contact_id_a] = $rel->contact_id_b;
}
// @todo this belongs in the BAO.
CRM_Contact_BAO_Contact_Utils::setCurrentEmployer($employerParams);
// Refresh contact summary if in ajax mode
$this->ajaxResponse['reloadBlocks'] = array('#crm-contactinfo-content');
}
}
/**
* Clears the current employer if the relationship type
* get changed, disabled or 'current employer' checkbox get unchecked.
*
* @param $params
*/
private function clearCurrentEmployer($params) {
// @todo this belongs in the BAO.
if ($this->_isCurrentEmployer) {
$relChanged = $params['relationship_type_id'] != $this->_values['relationship_type_id'];
if (!$params['is_active'] || !$params['is_current_employer'] || $relChanged) {
CRM_Contact_BAO_Contact_Utils::clearCurrentEmployer($this->_values['contact_id_a']);
// Refresh contact summary if in ajax mode
$this->ajaxResponse['reloadBlocks'] = array('#crm-contactinfo-content');
}
}
}
}

View file

@ -0,0 +1,890 @@
<?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 extends CRM_Core_Form_Search {
/**
* list of valid contexts.
*
* @var array
*/
static $_validContext = NULL;
/**
* List of values used when we want to display other objects.
*
* @var array
*/
static $_modeValues = NULL;
/**
* The contextMenu.
*
* @var array
*/
protected $_contextMenu;
/**
* The groupId retrieved from the GET vars.
*
* @var int
*/
public $_groupID;
/**
* The Group ID belonging to Add Member to group ID.
* retrieved from the GET vars
*
* @var int
*/
protected $_amtgID;
/**
* The saved search ID retrieved from the GET vars.
*
* @var int
*/
protected $_ssID;
/**
* The group elements.
*
* @var array
*/
public $_group;
public $_groupElement;
/**
* The tag elements.
*
* @var array
*/
public $_tag;
public $_tagElement;
/**
* The params used for search.
*
* @var array
*/
protected $_params;
/**
* The return properties used for search.
*
* @var array
*/
protected $_returnProperties;
/**
* The sort by character.
*
* @var string
*/
protected $_sortByCharacter;
/**
* The profile group id used for display.
*
* @var integer
*/
protected $_ufGroupID;
/**
* Csv - common search values
*
* @var array
*/
static $csv = array('contact_type', 'group', 'tag');
/**
* @var string how to display the results. Should we display as
* contributons, members, cases etc
*/
protected $_componentMode;
/**
* @var string what operator should we use, AND or OR
*/
protected $_operator;
protected $_modeValue;
/**
* Declare entity reference fields as they will need to be converted to using 'IN'.
*
* @var array
*/
protected $entityReferenceFields = array('event_id', 'membership_type_id');
/**
* Name of the selector to use.
*/
static $_selectorName = 'CRM_Contact_Selector';
protected $_customSearchID = NULL;
protected $_customSearchClass = NULL;
protected $_openedPanes = array();
/**
* Explicitly declare the entity api name.
*/
public function getDefaultEntity() {
return 'Contact';
}
/**
* Define the set of valid contexts that the search form operates on.
*
* @return array
* the valid context set and the titles
*/
public static function &validContext() {
if (!(self::$_validContext)) {
self::$_validContext = array(
'smog' => 'Show members of group',
'amtg' => 'Add members to group',
'basic' => 'Basic Search',
'search' => 'Search',
'builder' => 'Search Builder',
'advanced' => 'Advanced Search',
'custom' => 'Custom Search',
);
}
return self::$_validContext;
}
/**
* @param $context
*
* @return bool
*/
public static function isSearchContext($context) {
$searchContext = CRM_Utils_Array::value($context, self::validContext());
return $searchContext ? TRUE : FALSE;
}
public static function setModeValues() {
if (!self::$_modeValues) {
self::$_modeValues = array(
1 => array(
'selectorName' => self::$_selectorName,
'selectorLabel' => ts('Contacts'),
'taskFile' => 'CRM/Contact/Form/Search/ResultTasks.tpl',
'taskContext' => NULL,
'resultFile' => 'CRM/Contact/Form/Selector.tpl',
'resultContext' => NULL,
'taskClassName' => 'CRM_Contact_Task',
),
2 => array(
'selectorName' => 'CRM_Contribute_Selector_Search',
'selectorLabel' => ts('Contributions'),
'taskFile' => 'CRM/common/searchResultTasks.tpl',
'taskContext' => 'Contribution',
'resultFile' => 'CRM/Contribute/Form/Selector.tpl',
'resultContext' => 'Search',
'taskClassName' => 'CRM_Contribute_Task',
),
3 => array(
'selectorName' => 'CRM_Event_Selector_Search',
'selectorLabel' => ts('Event Participants'),
'taskFile' => 'CRM/common/searchResultTasks.tpl',
'taskContext' => NULL,
'resultFile' => 'CRM/Event/Form/Selector.tpl',
'resultContext' => 'Search',
'taskClassName' => 'CRM_Event_Task',
),
4 => array(
'selectorName' => 'CRM_Activity_Selector_Search',
'selectorLabel' => ts('Activities'),
'taskFile' => 'CRM/common/searchResultTasks.tpl',
'taskContext' => NULL,
'resultFile' => 'CRM/Activity/Form/Selector.tpl',
'resultContext' => 'Search',
'taskClassName' => 'CRM_Activity_Task',
),
5 => array(
'selectorName' => 'CRM_Member_Selector_Search',
'selectorLabel' => ts('Memberships'),
'taskFile' => "CRM/common/searchResultTasks.tpl",
'taskContext' => NULL,
'resultFile' => 'CRM/Member/Form/Selector.tpl',
'resultContext' => 'Search',
'taskClassName' => 'CRM_Member_Task',
),
6 => array(
'selectorName' => 'CRM_Case_Selector_Search',
'selectorLabel' => ts('Cases'),
'taskFile' => "CRM/common/searchResultTasks.tpl",
'taskContext' => NULL,
'resultFile' => 'CRM/Case/Form/Selector.tpl',
'resultContext' => 'Search',
'taskClassName' => 'CRM_Case_Task',
),
7 => array(
'selectorName' => self::$_selectorName,
'selectorLabel' => ts('Related Contacts'),
'taskFile' => 'CRM/Contact/Form/Search/ResultTasks.tpl',
'taskContext' => NULL,
'resultFile' => 'CRM/Contact/Form/Selector.tpl',
'resultContext' => NULL,
'taskClassName' => 'CRM_Contact_Task',
),
8 => array(
'selectorName' => 'CRM_Mailing_Selector_Search',
'selectorLabel' => ts('Mailings'),
'taskFile' => "CRM/common/searchResultTasks.tpl",
'taskContext' => NULL,
'resultFile' => 'CRM/Mailing/Form/Selector.tpl',
'resultContext' => 'Search',
'taskClassName' => 'CRM_Mailing_Task',
),
);
}
}
/**
* @param int $mode
*
* @return mixed
*/
public static function getModeValue($mode = 1) {
self::setModeValues();
if (!array_key_exists($mode, self::$_modeValues)) {
$mode = 1;
}
return self::$_modeValues[$mode];
}
/**
* @return array
*/
public static function getModeSelect() {
self::setModeValues();
$select = array();
foreach (self::$_modeValues as $id => & $value) {
$select[$id] = $value['selectorLabel'];
}
// unset contributions or participants if user does not have
// permission on them
if (!CRM_Core_Permission::access('CiviContribute')) {
unset($select['2']);
}
if (!CRM_Core_Permission::access('CiviEvent')) {
unset($select['3']);
}
if (!CRM_Core_Permission::check('view all activities')) {
unset($select['4']);
}
return $select;
}
/**
* Builds the list of tasks or actions that a searcher can perform on a result set.
*
* @return array
*/
public function buildTaskList() {
if ($this->_context !== 'amtg') {
$permission = CRM_Core_Permission::getPermission();
if ($this->_componentMode == 1 || $this->_componentMode == 7) {
$this->_taskList += CRM_Contact_Task::permissionedTaskTitles($permission,
CRM_Utils_Array::value('deleted_contacts', $this->_formValues)
);
}
else {
$className = $this->_modeValue['taskClassName'];
$this->_taskList += $className::permissionedTaskTitles($permission, FALSE);
}
// Only offer the "Update Smart Group" task if a smart group/saved search is already in play
if (isset($this->_ssID) && $permission == CRM_Core_Permission::EDIT) {
$this->_taskList += CRM_Contact_Task::optionalTaskTitle();
}
}
asort($this->_taskList);
return $this->_taskList;
}
/**
* Build the common elements between the search/advanced form.
*/
public function buildQuickForm() {
parent::buildQuickForm();
CRM_Core_Resources::singleton()
// jsTree is needed for tags popup
->addScriptFile('civicrm', 'packages/jquery/plugins/jstree/jquery.jstree.js', 0, 'html-header', FALSE)
->addStyleFile('civicrm', 'packages/jquery/plugins/jstree/themes/default/style.css', 0, 'html-header');
$permission = CRM_Core_Permission::getPermission();
// some tasks.. what do we want to do with the selected contacts ?
$tasks = array();
if ($this->_componentMode == 1 || $this->_componentMode == 7) {
$tasks += CRM_Contact_Task::permissionedTaskTitles($permission,
CRM_Utils_Array::value('deleted_contacts', $this->_formValues)
);
}
else {
$className = $this->_modeValue['taskClassName'];
$tasks += $className::permissionedTaskTitles($permission, FALSE);
}
if (isset($this->_ssID)) {
if ($permission == CRM_Core_Permission::EDIT) {
$tasks = $tasks + CRM_Contact_Task::optionalTaskTitle();
}
$search_custom_id
= CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $this->_ssID, 'search_custom_id');
$savedSearchValues = array(
'id' => $this->_ssID,
'name' => CRM_Contact_BAO_SavedSearch::getName($this->_ssID, 'title'),
'search_custom_id' => $search_custom_id,
);
$this->assign_by_ref('savedSearch', $savedSearchValues);
$this->assign('ssID', $this->_ssID);
}
if ($this->_context === 'smog') {
// CRM-11788, we might want to do this for all of search where force=1
$formQFKey = CRM_Utils_Array::value('qfKey', $this->_formValues);
$getQFKey = CRM_Utils_Array::value('qfKey', $_GET);
$postQFKey = CRM_Utils_Array::value('qfKey', $_POST);
if ($formQFKey && empty($getQFKey) && empty($postQFKey)) {
$url = CRM_Utils_System::makeURL('qfKey') . $formQFKey;
CRM_Utils_System::redirect($url);
}
$permissionForGroup = FALSE;
if (!empty($this->_groupID)) {
// check if user has permission to edit members of this group
$permission = CRM_Contact_BAO_Group::checkPermission($this->_groupID);
if ($permission && in_array(CRM_Core_Permission::EDIT, $permission)) {
$permissionForGroup = TRUE;
}
// check if _groupID exists, it might not if
// we are displaying a hidden group
if (!isset($this->_group[$this->_groupID])) {
$this->_group[$this->_groupID]
= CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $this->_groupID, 'title');
}
// set the group title
$groupValues = array('id' => $this->_groupID, 'title' => $this->_group[$this->_groupID]);
$this->assign_by_ref('group', $groupValues);
// also set ssID if this is a saved search
$ssID = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $this->_groupID, 'saved_search_id');
$this->assign('ssID', $ssID);
//get the saved search mapping id
if ($ssID) {
$this->_ssID = $ssID;
$ssMappingId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $ssID, 'mapping_id');
$this->assign('ssMappingID', $ssMappingId);
}
// Set dynamic page title for 'Show Members of Group'
CRM_Utils_System::setTitle(ts('Contacts in Group: %1', array(1 => $this->_group[$this->_groupID])));
}
$group_contact_status = array();
foreach (CRM_Core_SelectValues::groupContactStatus() as $k => $v) {
if (!empty($k)) {
$group_contact_status[] = $this->createElement('checkbox', $k, NULL, $v);
}
}
$this->addGroup($group_contact_status,
'group_contact_status', ts('Group Status')
);
$this->assign('permissionedForGroup', $permissionForGroup);
}
// add the go button for the action form, note it is of type 'next' rather than of type 'submit'
if ($this->_context === 'amtg') {
// check if _groupID exists, it might not if
// we are displaying a hidden group
if (!isset($this->_group[$this->_amtgID])) {
$this->assign('permissionedForGroup', FALSE);
$this->_group[$this->_amtgID]
= CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $this->_amtgID, 'title');
}
// Set dynamic page title for 'Add Members Group'
CRM_Utils_System::setTitle(ts('Add to Group: %1', array(1 => $this->_group[$this->_amtgID])));
// also set the group title and freeze the action task with Add Members to Group
$groupValues = array('id' => $this->_amtgID, 'title' => $this->_group[$this->_amtgID]);
$this->assign_by_ref('group', $groupValues);
$this->add('submit', $this->_actionButtonName, ts('Add Contacts to %1', array(1 => $this->_group[$this->_amtgID])),
array(
'class' => 'crm-form-submit',
)
);
$this->add('hidden', 'task', CRM_Contact_Task::GROUP_CONTACTS);
$selectedRowsRadio = $this->addElement('radio', 'radio_ts', NULL, '', 'ts_sel', array('checked' => 'checked'));
$allRowsRadio = $this->addElement('radio', 'radio_ts', NULL, '', 'ts_all');
$this->assign('ts_sel_id', $selectedRowsRadio->_attributes['id']);
$this->assign('ts_all_id', $allRowsRadio->_attributes['id']);
}
$selectedContactIds = array();
$qfKeyParam = CRM_Utils_Array::value('qfKey', $this->_formValues);
// We use ajax to handle selections only if the search results component_mode is set to "contacts"
if ($qfKeyParam && ($this->get('component_mode') <= 1 || $this->get('component_mode') == 7)) {
$this->addClass('crm-ajax-selection-form');
$qfKeyParam = "civicrm search {$qfKeyParam}";
$selectedContactIdsArr = CRM_Core_BAO_PrevNextCache::getSelection($qfKeyParam);
$selectedContactIds = array_keys($selectedContactIdsArr[$qfKeyParam]);
}
$this->assign_by_ref('selectedContactIds', $selectedContactIds);
$rows = $this->get('rows');
if (is_array($rows)) {
$this->addRowSelectors($rows);
}
}
/**
* Processing needed for buildForm and later.
*/
public function preProcess() {
// set the various class variables
$this->_group = CRM_Core_PseudoConstant::group();
$this->_tag = CRM_Core_BAO_Tag::getTags();
$this->_done = FALSE;
/*
* we allow the controller to set force/reset externally, useful when we are being
* driven by the wizard framework
*/
$this->_reset = CRM_Utils_Request::retrieve('reset', 'Boolean');
$this->_force = CRM_Utils_Request::retrieve('force', 'Boolean');
$this->_groupID = CRM_Utils_Request::retrieve('gid', 'Positive', $this);
$this->_amtgID = CRM_Utils_Request::retrieve('amtgID', 'Positive', $this);
$this->_ssID = CRM_Utils_Request::retrieve('ssID', 'Positive', $this);
$this->_sortByCharacter = CRM_Utils_Request::retrieve('sortByCharacter', 'String', $this);
$this->_ufGroupID = CRM_Utils_Request::retrieve('id', 'Positive', $this);
$this->_componentMode = CRM_Utils_Request::retrieve('component_mode', 'Positive', $this, FALSE, 1, $_REQUEST);
$this->_operator = CRM_Utils_Request::retrieve('operator', 'String', $this, FALSE, 1, $_REQUEST, 'AND');
/**
* set the button names
*/
$this->_searchButtonName = $this->getButtonName('refresh');
$this->_actionButtonName = $this->getButtonName('next', 'action');
$this->assign('actionButtonName', $this->_actionButtonName);
// if we dont get this from the url, use default if one exsts
$config = CRM_Core_Config::singleton();
if ($this->_ufGroupID == NULL &&
$config->defaultSearchProfileID != NULL
) {
$this->_ufGroupID = $config->defaultSearchProfileID;
}
// assign context to drive the template display, make sure context is valid
$this->_context = CRM_Utils_Request::retrieve('context', 'String', $this, FALSE, 'search');
if (!CRM_Utils_Array::value($this->_context, self::validContext())) {
$this->_context = 'search';
}
$this->set('context', $this->_context);
$this->assign('context', $this->_context);
$this->_modeValue = self::getModeValue($this->_componentMode);
$this->assign($this->_modeValue);
$this->set('selectorName', self::$_selectorName);
// get user submitted values
// get it from controller only if form has been submitted, else preProcess has set this
// $this->controller->isModal( ) returns TRUE if page is
// valid, i.e all the validations are TRUE
if (!empty($_POST) && !$this->controller->isModal()) {
$this->_formValues = $this->controller->exportValues($this->_name);
$this->normalizeFormValues();
$this->_params = CRM_Contact_BAO_Query::convertFormValues($this->_formValues, 0, FALSE, NULL, $this->entityReferenceFields);
$this->_returnProperties = &$this->returnProperties();
// also get the uf group id directly from the post value
$this->_ufGroupID = CRM_Utils_Array::value('uf_group_id', $_POST, $this->_ufGroupID);
$this->_formValues['uf_group_id'] = $this->_ufGroupID;
$this->set('id', $this->_ufGroupID);
// also get the object mode directly from the post value
$this->_componentMode = CRM_Utils_Array::value('component_mode', $_POST, $this->_componentMode);
// also get the operator from the post value if set
$this->_operator = CRM_Utils_Array::value('operator', $_POST, $this->_operator);
$this->_formValues['operator'] = $this->_operator;
$this->set('operator', $this->_operator);
}
else {
$this->_formValues = $this->get('formValues');
$this->_params = CRM_Contact_BAO_Query::convertFormValues($this->_formValues, 0, FALSE, NULL, $this->entityReferenceFields);
$this->_returnProperties = &$this->returnProperties();
if (!empty($this->_ufGroupID)) {
$this->set('id', $this->_ufGroupID);
}
}
if (empty($this->_formValues)) {
//check if group is a smart group (fix for CRM-1255)
if ($this->_groupID) {
if ($ssId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $this->_groupID, 'saved_search_id')) {
$this->_ssID = $ssId;
}
}
// fix for CRM-1907
if (isset($this->_ssID) && $this->_context != 'smog') {
// we only retrieve the saved search values if out current values are null
$this->_formValues = CRM_Contact_BAO_SavedSearch::getFormValues($this->_ssID);
//fix for CRM-1505
if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $this->_ssID, 'mapping_id')) {
$this->_params = CRM_Contact_BAO_SavedSearch::getSearchParams($this->_ssID);
}
else {
$this->_params = CRM_Contact_BAO_Query::convertFormValues($this->_formValues);
}
$this->_returnProperties = &$this->returnProperties();
}
else {
if (isset($this->_ufGroupID)) {
// also set the uf group id if not already present
$this->_formValues['uf_group_id'] = $this->_ufGroupID;
}
if (isset($this->_componentMode)) {
$this->_formValues['component_mode'] = $this->_componentMode;
}
if (isset($this->_operator)) {
$this->_formValues['operator'] = $this->_operator;
}
// FIXME: we should generalise in a way that components could inject url-filters
// just like they build their own form elements
foreach (array(
'mailing_id',
'mailing_delivery_status',
'mailing_open_status',
'mailing_click_status',
'mailing_reply_status',
'mailing_optout',
'mailing_forward',
'mailing_unsubscribe',
'mailing_date_low',
'mailing_date_high',
) as $mailingFilter) {
$type = 'String';
if ($mailingFilter == 'mailing_id' &&
$filterVal = CRM_Utils_Request::retrieve('mailing_id', 'Positive', $this)
) {
$this->_formValues[$mailingFilter] = array($filterVal);
}
elseif ($filterVal = CRM_Utils_Request::retrieve($mailingFilter, $type, $this)) {
$this->_formValues[$mailingFilter] = $filterVal;
}
if ($filterVal) {
$this->_openedPanes['Mailings'] = 1;
$this->_formValues['hidden_CiviMail'] = 1;
}
}
}
}
$this->assign('id',
CRM_Utils_Array::value('uf_group_id', $this->_formValues)
);
$operator = CRM_Utils_Array::value('operator', $this->_formValues, 'AND');
$this->set('queryOperator', $operator);
if ($operator == 'OR') {
$this->assign('operator', ts('OR'));
}
else {
$this->assign('operator', ts('AND'));
}
// show the context menu only when were not searching for deleted contacts; CRM-5673
if (empty($this->_formValues['deleted_contacts'])) {
$menuItems = CRM_Contact_BAO_Contact::contextMenu();
$primaryActions = CRM_Utils_Array::value('primaryActions', $menuItems, array());
$this->_contextMenu = CRM_Utils_Array::value('moreActions', $menuItems, array());
$this->assign('contextMenu', $primaryActions + $this->_contextMenu);
}
if (!isset($this->_componentMode)) {
$this->_componentMode = CRM_Contact_BAO_Query::MODE_CONTACTS;
}
self::setModeValues();
self::$_selectorName = $this->_modeValue['selectorName'];
$setDynamic = FALSE;
if (strpos(self::$_selectorName, 'CRM_Contact_Selector') !== FALSE) {
$selector = new self::$_selectorName(
$this->_customSearchClass,
$this->_formValues,
$this->_params,
$this->_returnProperties,
$this->_action,
FALSE, TRUE,
$this->_context,
$this->_contextMenu
);
$setDynamic = TRUE;
}
else {
$selector = new self::$_selectorName(
$this->_params,
$this->_action,
NULL, FALSE, NULL,
"search", "advanced"
);
}
$selector->setKey($this->controller->_key);
$controller = new CRM_Contact_Selector_Controller($selector,
$this->get(CRM_Utils_Pager::PAGE_ID),
$this->get(CRM_Utils_Sort::SORT_ID),
CRM_Core_Action::VIEW,
$this,
CRM_Core_Selector_Controller::TRANSFER
);
$controller->setEmbedded(TRUE);
$controller->setDynamicAction($setDynamic);
if ($this->_force) {
$this->postProcess();
/*
* Note that we repeat this, since the search creates and stores
* values that potentially change the controller behavior. i.e. things
* like totalCount etc
*/
$sortID = NULL;
if ($this->get(CRM_Utils_Sort::SORT_ID)) {
$sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID),
$this->get(CRM_Utils_Sort::SORT_DIRECTION)
);
}
$controller = new CRM_Contact_Selector_Controller($selector,
$this->get(CRM_Utils_Pager::PAGE_ID),
$sortID,
CRM_Core_Action::VIEW, $this, CRM_Core_Selector_Controller::TRANSFER
);
$controller->setEmbedded(TRUE);
$controller->setDynamicAction($setDynamic);
}
$controller->moveFromSessionToTemplate();
}
/**
* @return array
*/
public function &getFormValues() {
return $this->_formValues;
}
/**
* Common post processing.
*/
public function postProcess() {
/*
* sometime we do a postProcess early on, so we dont need to repeat it
* this will most likely introduce some more bugs :(
*/
if ($this->_done) {
return;
}
$this->_done = TRUE;
//for prev/next pagination
$crmPID = CRM_Utils_Request::retrieve('crmPID', 'Integer');
if (array_key_exists($this->_searchButtonName, $_POST) ||
($this->_force && !$crmPID)
) {
//reset the cache table for new search
$cacheKey = "civicrm search {$this->controller->_key}";
CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey);
}
//get the button name
$buttonName = $this->controller->getButtonName();
if (isset($this->_ufGroupID) && empty($this->_formValues['uf_group_id'])) {
$this->_formValues['uf_group_id'] = $this->_ufGroupID;
}
if (isset($this->_componentMode) && empty($this->_formValues['component_mode'])) {
$this->_formValues['component_mode'] = $this->_componentMode;
}
if (isset($this->_operator) && empty($this->_formValues['operator'])) {
$this->_formValues['operator'] = $this->_operator;
}
if (empty($this->_formValues['qfKey'])) {
$this->_formValues['qfKey'] = $this->controller->_key;
}
if (!CRM_Core_Permission::check('access deleted contacts')) {
unset($this->_formValues['deleted_contacts']);
}
$this->set('type', $this->_action);
$this->set('formValues', $this->_formValues);
$this->set('queryParams', $this->_params);
$this->set('returnProperties', $this->_returnProperties);
if ($buttonName == $this->_actionButtonName) {
// check actionName and if next, then do not repeat a search, since we are going to the next page
// hack, make sure we reset the task values
$stateMachine = $this->controller->getStateMachine();
$formName = $stateMachine->getTaskFormName();
$this->controller->resetPage($formName);
return;
}
else {
$output = CRM_Core_Selector_Controller::SESSION;
// create the selector, controller and run - store results in session
$searchChildGroups = TRUE;
if ($this->get('isAdvanced')) {
$searchChildGroups = FALSE;
}
$setDynamic = FALSE;
if (strpos(self::$_selectorName, 'CRM_Contact_Selector') !== FALSE) {
$selector = new self::$_selectorName(
$this->_customSearchClass,
$this->_formValues,
$this->_params,
$this->_returnProperties,
$this->_action,
FALSE,
$searchChildGroups,
$this->_context,
$this->_contextMenu
);
$setDynamic = TRUE;
}
else {
$selector = new self::$_selectorName(
$this->_params,
$this->_action,
NULL,
FALSE,
NULL,
"search",
"advanced"
);
}
$selector->setKey($this->controller->_key);
// added the sorting character to the form array
$config = CRM_Core_Config::singleton();
// do this only for contact search
if ($setDynamic && $config->includeAlphabeticalPager) {
// Don't recompute if we are just paging/sorting
if ($this->_reset || (empty($_GET['crmPID']) && empty($_GET['crmSID']) && !$this->_sortByCharacter)) {
$aToZBar = CRM_Utils_PagerAToZ::getAToZBar($selector, $this->_sortByCharacter);
$this->set('AToZBar', $aToZBar);
}
}
$sortID = NULL;
if ($this->get(CRM_Utils_Sort::SORT_ID)) {
$sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID),
$this->get(CRM_Utils_Sort::SORT_DIRECTION)
);
}
$controller = new CRM_Contact_Selector_Controller($selector,
$this->get(CRM_Utils_Pager::PAGE_ID),
$sortID,
CRM_Core_Action::VIEW,
$this,
$output
);
$controller->setEmbedded(TRUE);
$controller->setDynamicAction($setDynamic);
$controller->run();
}
}
/**
* @return NULL
*/
public function &returnProperties() {
return CRM_Core_DAO::$_nullObject;
}
/**
* Return a descriptive name for the page, used in wizard header
*
* @return string
*/
public function getTitle() {
return ts('Search');
}
}

View 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'))
);
}
}
}

View 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, '&nbsp;&nbsp;', 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');
}
}

View 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;
}
}

View 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, '&nbsp;&nbsp;', 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);
}
}

View 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;
}
}

View file

@ -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);
}
}

View file

@ -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'));
}
}
}

View file

@ -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);
}
}

View file

@ -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));
}
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

Some files were not shown because too many files have changed in this diff Show more