<?php
/*
+--------------------------------------------------------------------+
- | CiviCRM version 4.3 |
+ | CiviCRM version 4.4 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2013 |
+--------------------------------------------------------------------+
}
else {
// check for duplicate relationship
-
+ // @todo this code doesn't cope well with updates - causes e-Notices.
+ // API has a lot of code to work around
+ // this but should review this code & remove the extra handling from the api
+ // it seems doubtful any of this is relevant if the contact fields & relationship
+ // type fields are not set
if (
self::checkDuplicateRelationship(
$params,
* @access public
* @static
*/
- static function add(&$params, &$ids, $contactId) {
- if (CRM_Utils_Array::value('relationship', $ids)) {
- CRM_Utils_Hook::pre('edit', 'Relationship', $ids['relationship'], $params);
- }
- else {
- CRM_Utils_Hook::pre('create', 'Relationship', NULL, $params);
+ static function add(&$params, $ids = array(), $contactId = NULL) {
+ $relationshipId =
+ CRM_Utils_Array::value('relationship', $ids, CRM_Utils_Array::value('id', $params));
+
+ $hook = 'create';
+ if($relationshipId) {
+ $hook = 'edit';
}
+ //@todo hook are called from create and add - remove one
+ CRM_Utils_Hook::pre($hook , 'Relationship', $relationshipId, $params);
$relationshipTypes = CRM_Utils_Array::value('relationship_type_id', $params);
- // expolode the string with _ to get the relationship type id and to know which contact has to be inserted in
+ // explode the string with _ to get the relationship type id
+ // and to know which contact has to be inserted in
// contact_id_a and which one in contact_id_b
list($type, $first, $second) = explode('_', $relationshipTypes);
${'contact_' . $first} = CRM_Utils_Array::value('contact', $ids);
${'contact_' . $second} = $contactId;
- //check if the relationship type is Head of Household then update the household's primary contact with this contact.
+ // check if the relationship type is Head of Household then update the
+ // household's primary contact with this contact.
if ($type == 6) {
CRM_Contact_BAO_Household::updatePrimaryContact($contact_b, $contact_a);
}
$relationship = new CRM_Contact_BAO_Relationship();
+ //@todo this code needs to be updated for the possibility that not all fields are set
+ // (update)
$relationship->contact_id_b = $contact_b;
$relationship->contact_id_a = $contact_a;
$relationship->relationship_type_id = $type;
- $relationship->id = CRM_Utils_Array::value('relationship', $ids);
+ $relationship->id = $relationshipId;
$dateFields = array('end_date', 'start_date');
$relationship->$defaultField = $params[$defaultField];
}
}
- elseif(empty($relationship->id)){
+ elseif(!$relationshipId){
$relationship->$defaultField = $defaultValue;
}
}
$relationship->free();
- if (CRM_Utils_Array::value('relationship', $ids)) {
- CRM_Utils_Hook::post('edit', 'Relationship', $relationship->id, $relationship);
- }
- else {
- CRM_Utils_Hook::post('create', 'Relationship', $relationship->id, $relationship);
- }
+ CRM_Utils_Hook::post($hook, 'Relationship', $relationshipId, $relationship);
return $relationship;
}
//to delete relationship between household and individual \
//or between individual and orgnization
if (($action & CRM_Core_Action::DISABLE) || ($action & CRM_Core_Action::DELETE)) {
- if ($relationship->relationship_type_id == 4 || $relationship->relationship_type_id == 7) {
- $sharedContact = new CRM_Contact_DAO_Contact();
- $sharedContact->id = $relationship->contact_id_a;
- $sharedContact->find(TRUE);
-
- if ($relationship->relationship_type_id == 4 && $relationship->contact_id_b == $sharedContact->employer_id) {
- CRM_Contact_BAO_Contact_Utils::clearCurrentEmployer($relationship->contact_id_a);
+ $relTypes = CRM_Utils_Array::index(array('name_a_b'), CRM_Core_PseudoConstant::relationshipType('name'));
+ if ($relationship->relationship_type_id == $relTypes['Employee of']['id'] ||
+ $relationship->relationship_type_id == $relTypes['Household Member of']['id']) {
+ $sharedContact = new CRM_Contact_DAO_Contact();
+ $sharedContact->id = $relationship->contact_id_a;
+ $sharedContact->find(TRUE);
+
+ if ($relationship->relationship_type_id == 4 && $relationship->contact_id_b == $sharedContact->employer_id) {
+ CRM_Contact_BAO_Contact_Utils::clearCurrentEmployer($relationship->contact_id_a);
+ }
}
}
- }
return $relationship;
}
$relationshipTypeId = CRM_Utils_Array::value('relationship_type_id', $params);
list($type, $first, $second) = explode('_', $relationshipTypeId);
- $queryString = " SELECT id
- FROM civicrm_relationship
- WHERE relationship_type_id = " . CRM_Utils_Type::escape($type, 'Integer');
+ $queryString = "
+SELECT id
+FROM civicrm_relationship
+WHERE relationship_type_id = " . CRM_Utils_Type::escape($type, 'Integer');
/*
- * CRM-11792 - date fields from API are in ISO format, but this function supports date arrays
- * BAO has increasingly standardised to ISO format so I believe this function should support
- * ISO rather than make API format it - however, need to support array format for now to avoid breakage
+ * CRM-11792 - date fields from API are in ISO format, but this function
+ * supports date arrays BAO has increasingly standardised to ISO format
+ * so I believe this function should support ISO rather than make API
+ * format it - however, need to support array format for now to avoid breakage
* @ time of writing this function is called from Relationship::create (twice)
* CRM_BAO_Contact_Utils::clearCurrentEmployer (seemingly without dates)
* CRM_Contact_Form_Task_AddToOrganization::postProcess &
foreach ($dateFields as $dateField){
if(array_key_exists($dateField, $params)) {
if (empty($params[$dateField]) || $params[$dateField] == 'null'){
- //this is most likely coming from an api call & probably loaded from the DB to deal with some of the
- //other myriad of excessive checks still in place both in the api & the create functions
+ //this is most likely coming from an api call & probably loaded
+ // from the DB to deal with some of the
+ // other myriad of excessive checks still in place both in
+ // the api & the create functions
$queryString .= " AND $dateField IS NULL";
continue;
}
elseif (is_array($params[$dateField])){
- $queryString .= " AND $dateField = " . CRM_Utils_Type::escape(CRM_Utils_Date::format($params[$dateField]), 'Date');
+ $queryString .= " AND $dateField = " .
+ CRM_Utils_Type::escape(CRM_Utils_Date::format($params[$dateField]), 'Date');
}
- else{
- $queryString .= " AND $dateField = " . CRM_Utils_Type::escape($params[$dateField], 'Date');
+ else {
+ $queryString .= " AND $dateField = " .
+ CRM_Utils_Type::escape($params[$dateField], 'Date');
}
}
}
* @static
*/
static function setIsActive($id, $is_active) {
- CRM_Core_DAO::setFieldValue('CRM_Contact_DAO_Relationship', $id, 'is_active', $is_active);
-
- // call hook
+ // as both the create & add functions have a bunch of logic in them that
+ // doesn't seem to cope with a normal update we will call the api which
+ // has tested handling for this
+ // however, a longer term solution would be to simplify the add, create & api functions
+ // to be more standard. It is debatable @ that point whether it's better to call the BAO
+ // direct as the api is more tested.
+ civicrm_api3('relationship', 'create', array('id' => $id, 'is_active' => $is_active));
+
+ // call (undocumented possibly deprecated) hook
CRM_Utils_Hook::enableDisable('CRM_Contact_BAO_Relationship', $id, $is_active);
return TRUE;
* @param int $count get the no of relationships
* $param int $relationshipId relationship id
* @param string $direction the direction we are interested in a_b or b_a
+ * @param array $params array of extra values including relationship_type_id per api spec
*
* return string the query for this diretion
* @static
* @access public
*/
- static function makeURLClause($contactId, $status, $numRelationship, $count, $relationshipId, $direction) {
+ static function makeURLClause($contactId, $status, $numRelationship, $count, $relationshipId, $direction, $params = array()) {
$select = $from = $where = '';
$select = '( ';
// CRM-6181
$where .= ' AND civicrm_contact.is_deleted = 0';
-
+ if(!empty($params['membership_type_id']) && empty($params['relationship_type_id'])) {
+ $where .= self::membershipTypeToRelationshipTypes($params, $direction);
+ }
+ if(!empty($params['relationship_type_id'])) {
+ if(is_array($params['relationship_type_id'])) {
+ $where .= " AND " . CRM_Core_DAO::createSQLFilter('relationship_type_id', $params['relationship_type_id'], 'Integer');
+ }
+ else {
+ $where .= ' AND relationship_type_id = ' . CRM_Utils_Type::escape($params['relationship_type_id'], 'Positive');
+ }
+ }
if ($direction == 'a_b') {
$where .= ' ) UNION ';
}
* $param array $links the list of links to display
* $param int $permissionMask the permission mask to be applied for the actions
* $param boolean $permissionedContact to return only permissioned Contact
- *
+ * $param array $params array of variables consistent with filters supported by the api
* return array $values relationship records
* @static
* @access public
$status = 0, $numRelationship = 0,
$count = 0, $relationshipId = 0,
$links = NULL, $permissionMask = NULL,
- $permissionedContact = FALSE
+ $permissionedContact = FALSE,
+ $params = array()
) {
$values = array();
if (!$contactId && !$relationshipId) {
}
list($select1, $from1, $where1) = self::makeURLClause($contactId, $status, $numRelationship,
- $count, $relationshipId, 'a_b'
+ $count, $relationshipId, 'a_b', $params
);
list($select2, $from2, $where2) = self::makeURLClause($contactId, $status, $numRelationship,
- $count, $relationshipId, 'b_a'
+ $count, $relationshipId, 'b_a', $params
);
$order = $limit = '';
* Helper function to check whether to delete the membership or
* not.
*
+ * @static
+ *
*/
- function isDeleteRelatedMembership($relTypeIds, $contactId, $mainRelatedContactId, $relTypeId, $relIds) {
+ static function isDeleteRelatedMembership($relTypeIds, $contactId, $mainRelatedContactId, $relTypeId, $relIds) {
if (in_array($relTypeId, $relTypeIds)) {
return TRUE;
}
* @return array array of employers.
*
*/
- static function getPermissionedEmployer($contactID, $name = '%') {
- $employers = array();
-
+ static function getPermissionedEmployer($contactID, $name = NULL) {
//get the relationship id
$relTypeId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType',
'Employee of', 'id', 'name_a_b'
);
+ return self::getPermissionedContacts($contactID, $relTypeId, $name);
+ }
+
+
+ /**
+ * Function to return list of permissioned contacts for a given contact and relationship type
+ *
+ * @param $contactID int contact id whose permissioned contacts are to be found.
+ * @param $relTypeId relationship type id
+ * @param $name string
+ *
+ * @static
+ *
+ * @return array of contacts
+ */
+ static function getPermissionedContacts($contactID, $relTypeId, $name = NULL) {
+ $contacts = array();
+
if ($relTypeId) {
$query = "
SELECT cc.id as id, cc.sort_name as name
FROM civicrm_relationship cr, civicrm_contact cc
-WHERE cr.contact_id_a = $contactID AND
-cr.relationship_type_id = $relTypeId AND
-cr.is_permission_a_b = 1 AND
+WHERE
+cr.contact_id_a = %1 AND
+cr.relationship_type_id = %2 AND
+cr.is_permission_a_b = 1 AND
IF(cr.end_date IS NULL, 1, (DATEDIFF( CURDATE( ), cr.end_date ) <= 0)) AND
cr.is_active = 1 AND
-cc.id = cr.contact_id_b AND
-cc.sort_name LIKE '%$name%'";
+cc.id = cr.contact_id_b";
+
+ if (!empty($name)) {
+ $name = CRM_Utils_Type::escape($name, 'String');
+ $query .= "
+AND cc.sort_name LIKE '%$name%'";
+ }
- $nullArray = array();
- $dao = CRM_Core_DAO::executeQuery($query, $nullArray);
+ $args = array(1 => array($contactID, 'Integer'), 2 => array($relTypeId, 'Integer'));
+ $dao = CRM_Core_DAO::executeQuery($query, $args);
while ($dao->fetch()) {
- $employers[$dao->id] = array(
+ $contacts[$dao->id] = array(
'name' => $dao->name,
'value' => $dao->id,
);
}
}
-
- return $employers;
+ return $contacts;
}
static function getValidContactTypeList($relType) {
} else {
$contactTypes = array();
foreach ($contactProfiles as $key => $value) {
- if (strpos($value, $leftType) !== FALSE) {
+ $groupTypes = CRM_Core_BAO_UFGroup::profileGroups($key);
+ if (in_array($leftType, $groupTypes)) {
$contactTypes = array($key => $value);
}
}
}
return TRUE;
}
+
+ /**
+ * Function filters the query by possible relationships for the membership type
+ * It is intended to be called when constructing queries for the api (reciprocal & non-reciprocal)
+ * and to add clauses to limit the return to those relationships which COULD inherit a membership type
+ * (as opposed to those who inherit a particular membership
+ *
+ * @param array $params api input array
+ */
+ static function membershipTypeToRelationshipTypes(&$params, $direction = NULL) {
+ $membershipType = civicrm_api3('membership_type', 'getsingle', array('id' => $params['membership_type_id'], 'return' => 'relationship_type_id, relationship_direction'));
+ $relationshipTypes = $membershipType['relationship_type_id'];
+ if(empty($relationshipTypes)) {
+ return;
+ }
+ // if we don't have any contact data we can only filter on type
+ if(empty($params['contact_id']) && empty($params['contact_id_a']) && empty($params['contact_id_a'])) {
+ $params['relationship_type_id'] = array('IN' => $relationshipTypes);
+ return;
+ }
+ else {
+ $relationshipDirections = (array) $membershipType['relationship_direction'];
+ // if we have contact_id_a OR contact_id_b we can make a call here
+ // if we have contact??
+ foreach ($relationshipDirections as $index => $mtdirection) {
+ if(isset($params['contact_id_a']) && $mtdirection == 'a_b' || $direction == 'a_b') {
+ $types[] = $relationshipTypes[$index];
+ }
+ if(isset($params['contact_id_b']) && $mtdirection == 'b_a' || $direction == 'b_a') {
+ $types[] = $relationshipTypes[$index];
+ }
+ }
+ if(!empty($types)) {
+ $params['relationship_type_id'] = array('IN' => $types);
+ }
+ elseif(!empty($clauses)) {
+ return explode(' OR ', $clauses);
+ }
+ else{
+ // effectively setting it to return no results
+ $params['relationship_type_id'] = 0;
+ }
+ }
+ }
}