/** * Process the activities. * * @param array $params * Associated array of the submitted values. * * @throws CRM_Core_Exception * * @return CRM_Activity_BAO_Activity|null|object */ public static function create(&$params) { // check required params if (!self::dataExists($params)) { throw new CRM_Core_Exception('Not enough data to create activity object'); } $activity = new CRM_Activity_DAO_Activity(); if (isset($params['id']) && empty($params['id'])) { unset($params['id']); } if (empty($params['status_id']) && empty($params['activity_status_id']) && empty($params['id'])) { if (isset($params['activity_date_time']) && strcmp($params['activity_date_time'], CRM_Utils_Date::processDate(date('Ymd')) == -1)) { $params['status_id'] = 2; } else { $params['status_id'] = 1; } } // Set priority to Normal for Auto-populated activities (for Cases) if (CRM_Utils_Array::value('priority_id', $params) === NULL && !CRM_Utils_Array::value('id', $params)) { $priority = CRM_Core_PseudoConstant::get('CRM_Activity_DAO_Activity', 'priority_id'); $params['priority_id'] = array_search('Normal', $priority); } if (!empty($params['target_contact_id']) && is_array($params['target_contact_id'])) { $params['target_contact_id'] = array_unique($params['target_contact_id']); } if (!empty($params['assignee_contact_id']) && is_array($params['assignee_contact_id'])) { $params['assignee_contact_id'] = array_unique($params['assignee_contact_id']); } // CRM-9137 if (!empty($params['id'])) { CRM_Utils_Hook::pre('edit', 'Activity', $activity->id, $params); } else { CRM_Utils_Hook::pre('create', 'Activity', NULL, $params); } $activity->copyValues($params); if (isset($params['case_id'])) { // CRM-8708, preserve case ID even though it's not part of the SQL model $activity->case_id = $params['case_id']; } elseif (is_numeric($activity->id)) { // CRM-8708, preserve case ID even though it's not part of the SQL model $activity->case_id = CRM_Case_BAO_Case::getCaseIdByActivityId($activity->id); } // start transaction $transaction = new CRM_Core_Transaction(); $result = $activity->save(); if (is_a($result, 'CRM_Core_Error')) { $transaction->rollback(); return $result; } $activityId = $activity->id; $activityContacts = CRM_Core_OptionGroup::values('activity_contacts', FALSE, FALSE, FALSE, NULL, 'name'); $sourceID = CRM_Utils_Array::key('Activity Source', $activityContacts); $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts); $targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts); if (isset($params['source_contact_id'])) { $acParams = array('activity_id' => $activityId, 'contact_id' => $params['source_contact_id'], 'record_type_id' => $sourceID); self::deleteActivityContact($activityId, $sourceID); CRM_Activity_BAO_ActivityContact::create($acParams); } // check and attach and files as needed CRM_Core_BAO_File::processAttachment($params, 'civicrm_activity', $activityId); // attempt to save activity assignment $resultAssignment = NULL; if (!empty($params['assignee_contact_id'])) { $assignmentParams = array('activity_id' => $activityId); if (is_array($params['assignee_contact_id'])) { if (CRM_Utils_Array::value('deleteActivityAssignment', $params, TRUE)) { // first delete existing assignments if any self::deleteActivityContact($activityId, $assigneeID); } $values = array(); foreach ($params['assignee_contact_id'] as $acID) { if ($acID) { $values[] = "( {$activityId}, {$acID}, {$assigneeID} )"; } } while (!empty($values)) { $input = array_splice($values, 0, CRM_Core_DAO::BULK_INSERT_COUNT); $str = implode(',', $input); $sql = "INSERT IGNORE INTO civicrm_activity_contact ( activity_id, contact_id, record_type_id ) VALUES {$str};"; CRM_Core_DAO::executeQuery($sql); } } else { $assignmentParams['contact_id'] = $params['assignee_contact_id']; $assignmentParams['record_type_id'] = $assigneeID; if (!empty($params['id'])) { $assignment = new CRM_Activity_BAO_ActivityContact(); $assignment->activity_id = $activityId; $assignment->record_type_id = $assigneeID; $assignment->find(TRUE); if ($assignment->contact_id != $params['assignee_contact_id']) { $assignmentParams['id'] = $assignment->id; $resultAssignment = CRM_Activity_BAO_ActivityContact::create($assignmentParams); } } else { $resultAssignment = CRM_Activity_BAO_ActivityContact::create($assignmentParams); } } } else { if (CRM_Utils_Array::value('deleteActivityAssignment', $params, TRUE)) { self::deleteActivityContact($activityId, $assigneeID); } } if (is_a($resultAssignment, 'CRM_Core_Error')) { $transaction->rollback(); return $resultAssignment; } // attempt to save activity targets $resultTarget = NULL; if (!empty($params['target_contact_id'])) { $targetParams = array('activity_id' => $activityId); $resultTarget = array(); if (is_array($params['target_contact_id'])) { if (CRM_Utils_Array::value('deleteActivityTarget', $params, TRUE)) { // first delete existing targets if any self::deleteActivityContact($activityId, $targetID); } $values = array(); foreach ($params['target_contact_id'] as $tid) { if ($tid) { $values[] = "( {$activityId}, {$tid}, {$targetID} )"; } } while (!empty($values)) { $input = array_splice($values, 0, CRM_Core_DAO::BULK_INSERT_COUNT); $str = implode(',', $input); $sql = "INSERT IGNORE INTO civicrm_activity_contact ( activity_id, contact_id, record_type_id ) VALUES {$str};"; CRM_Core_DAO::executeQuery($sql); } } else { $targetParams['contact_id'] = $params['target_contact_id']; $targetParams['record_type_id'] = $targetID; if (!empty($params['id'])) { $target = new CRM_Activity_BAO_ActivityContact(); $target->activity_id = $activityId; $target->record_type_id = $targetID; $target->find(TRUE); if ($target->contact_id != $params['target_contact_id']) { $targetParams['id'] = $target->id; $resultTarget = CRM_Activity_BAO_ActivityContact::create($targetParams); } } else { $resultTarget = CRM_Activity_BAO_ActivityContact::create($targetParams); } } } else { if (CRM_Utils_Array::value('deleteActivityTarget', $params, TRUE)) { self::deleteActivityContact($activityId, $targetID); } } // write to changelog before transaction is committed/rolled // back (and prepare status to display) if (!empty($params['id'])) { $logMsg = "Activity (id: {$result->id} ) updated with "; } else { $logMsg = "Activity created for "; } $msgs = array(); if (isset($params['source_contact_id'])) { $msgs[] = "source={$params['source_contact_id']}"; } if (!empty($params['target_contact_id'])) { if (is_array($params['target_contact_id']) && !CRM_Utils_array::crmIsEmptyArray($params['target_contact_id'])) { $msgs[] = "target=" . implode(',', $params['target_contact_id']); // take only first target // will be used for recently viewed display $t = array_slice($params['target_contact_id'], 0, 1); $recentContactId = $t[0]; } elseif (isset($params['target_contact_id']) && !is_array($params['target_contact_id'])) { $msgs[] = "target={$params['target_contact_id']}"; // will be used for recently viewed display $recentContactId = $params['target_contact_id']; } } else { // at worst, take source for recently viewed display $recentContactId = CRM_Utils_Array::value('source_contact_id', $params); } if (isset($params['assignee_contact_id'])) { if (is_array($params['assignee_contact_id'])) { $msgs[] = "assignee=" . implode(',', $params['assignee_contact_id']); } else { $msgs[] = "assignee={$params['assignee_contact_id']}"; } } $logMsg .= implode(', ', $msgs); self::logActivityAction($result, $logMsg); if (!empty($params['custom']) && is_array($params['custom'])) { CRM_Core_BAO_CustomValueTable::store($params['custom'], 'civicrm_activity', $result->id); } $transaction->commit(); if (empty($params['skipRecentView'])) { $recentOther = array(); if (!empty($params['case_id'])) { $caseContactID = CRM_Core_DAO::getFieldValue('CRM_Case_DAO_CaseContact', $params['case_id'], 'contact_id', 'case_id'); $url = CRM_Utils_System::url('civicrm/case/activity/view', "reset=1&aid={$activity->id}&cid={$caseContactID}&caseID={$params['case_id']}&context=home"); } else { $q = "action=view&reset=1&id={$activity->id}&atype={$activity->activity_type_id}&cid=" . CRM_Utils_Array::value('source_contact_id', $params) . "&context=home"; if ($activity->activity_type_id != CRM_Core_OptionGroup::getValue('activity_type', 'Email', 'name')) { $url = CRM_Utils_System::url('civicrm/activity', $q); if ($activity->activity_type_id == CRM_Core_OptionGroup::getValue('activity_type', 'Print PDF Letter', 'name')) { $recentOther['editUrl'] = CRM_Utils_System::url('civicrm/activity/pdf/add', "action=update&reset=1&id={$activity->id}&atype={$activity->activity_type_id}&cid={$params['source_contact_id']}&context=home"); } else { $recentOther['editUrl'] = CRM_Utils_System::url('civicrm/activity/add', "action=update&reset=1&id={$activity->id}&atype={$activity->activity_type_id}&cid=" . CRM_Utils_Array::value('source_contact_id', $params) . "&context=home"); } if (CRM_Core_Permission::check("delete activities")) { $recentOther['deleteUrl'] = CRM_Utils_System::url('civicrm/activity', "action=delete&reset=1&id={$activity->id}&atype={$activity->activity_type_id}&cid=" . CRM_Utils_Array::value('source_contact_id', $params) . "&context=home"); } } else { $url = CRM_Utils_System::url('civicrm/activity/view', $q); if (CRM_Core_Permission::check('delete activities')) { $recentOther['deleteUrl'] = CRM_Utils_System::url('civicrm/activity', "action=delete&reset=1&id={$activity->id}&atype={$activity->activity_type_id}&cid=" . CRM_Utils_Array::value('source_contact_id', $params) . "&context=home"); } } } if (!isset($activity->parent_id)) { $recentContactDisplay = CRM_Contact_BAO_Contact::displayName($recentContactId); // add the recently created Activity $activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, TRUE); $activitySubject = CRM_Core_DAO::getFieldValue('CRM_Activity_DAO_Activity', $activity->id, 'subject'); $title = ""; if (isset($activitySubject)) { $title = $activitySubject . ' - '; } $title = $title . $recentContactDisplay; if (!empty($activityTypes[$activity->activity_type_id])) { $title .= ' (' . $activityTypes[$activity->activity_type_id] . ')'; } CRM_Utils_Recent::add($title, $url, $activity->id, 'Activity', $recentContactId, $recentContactDisplay, $recentOther); } } // reset the group contact cache since smart groups might be affected due to this CRM_Contact_BAO_GroupContactCache::remove(); if (!empty($params['id'])) { CRM_Utils_Hook::post('edit', 'Activity', $activity->id, $activity); } else { CRM_Utils_Hook::post('create', 'Activity', $activity->id, $activity); } // if the subject contains a ‘[case #…]’ string, file that activity on the related case (CRM-5916) $matches = array(); if (preg_match('/\\[case #([0-9a-h]{7})\\]/', CRM_Utils_Array::value('subject', $params), $matches)) { $key = CRM_Core_DAO::escapeString(CIVICRM_SITE_KEY); $hash = $matches[1]; $query = "SELECT id FROM civicrm_case WHERE SUBSTR(SHA1(CONCAT('{$key}', id)), 1, 7) = '{$hash}'"; $caseParams = array('activity_id' => $activity->id, 'case_id' => CRM_Core_DAO::singleValueQuery($query)); if ($caseParams['case_id']) { CRM_Case_BAO_Case::processCaseActivity($caseParams); } else { self::logActivityAction($activity, "unknown case hash encountered: {$hash}"); } } return $result; }
/** * Get details of a particular case, or search for cases, depending on params * * Please provide one (and only one) of the four get/search parameters: * * @param array( 'id' => if set, will get all available info about a case, including contacts and activities * * // if no case_id provided, this function will use one of the following search parameters: * 'client_id' => finds all cases with a specific client * 'activity_id' => returns the case containing a specific activity * 'contact_id' => finds all cases associated with a contact (in any role, not just client) * * {@getfields case_get} * * @return (get mode, case_id provided): Array with case details, case roles, case activity ids, (search mode, case_id not provided): Array of cases found * @access public * @todo Erik Hommel 16 dec 2010 check if all DB fields are returned */ function civicrm_api3_case_get($params) { $options = _civicrm_api3_get_options_from_params($params); //search by client if (!empty($params['contact_id'])) { $ids = array(); foreach ((array) $params['contact_id'] as $cid) { if (is_numeric($cid)) { $ids = array_merge($ids, CRM_Case_BAO_Case::retrieveCaseIdsByContactId($cid, TRUE)); } } $cases = array(); foreach ($ids as $id) { if ($case = _civicrm_api3_case_read($id, $options)) { $cases[$id] = $case; } } return civicrm_api3_create_success($cases, $params, 'case', 'get'); } //search by activity if (!empty($params['activity_id'])) { if (!is_numeric($params['activity_id'])) { return civicrm_api3_create_error('Invalid parameter: activity_id. Must provide a numeric value.'); } $caseId = CRM_Case_BAO_Case::getCaseIdByActivityId($params['activity_id']); if (!$caseId) { return civicrm_api3_create_success(array(), $params, 'case', 'get'); } $case = array($caseId => _civicrm_api3_case_read($caseId, $options)); return civicrm_api3_create_success($case, $params, 'case', 'get'); } //search by contacts if ($contact = CRM_Utils_Array::value('contact_id', $params)) { if (!is_numeric($contact)) { return civicrm_api3_create_error('Invalid parameter: contact_id. Must provide a numeric value.'); } $sql = "\nSELECT DISTINCT case_id\n FROM civicrm_relationship\n WHERE (contact_id_a = {$contact}\n OR contact_id_b = {$contact})\n AND case_id IS NOT NULL"; $dao =& CRM_Core_DAO::executeQuery($sql); $cases = array(); while ($dao->fetch()) { $cases[$dao->case_id] = _civicrm_api3_case_read($dao->case_id, $options); } return civicrm_api3_create_success($cases, $params, 'case', 'get'); } // For historic reasons we always return these when an id is provided $caseId = CRM_Utils_Array::value('id', $params); if ($caseId) { $options['return'] = array('contacts' => 1, 'activities' => 1); } $foundcases = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, TRUE, 'Case'); $cases = array(); foreach ($foundcases['values'] as $foundcase) { if ($case = _civicrm_api3_case_read($foundcase['id'], $options)) { $cases[$foundcase['id']] = $case; } } return civicrm_api3_create_success($cases, $params, 'case', 'get'); }
/** * Get details of a particular case, or search for cases, depending on params * * Please provide one (and only one) of the four get/search parameters: * * @param array( 'case_id' => if set, will get all available info about a case, including contacts and activities * * // if no case_id provided, this function will use one of the following search parameters: * 'client_id' => finds all cases with a specific client * 'activity_id' => returns the case containing a specific activity * 'contact_id' => finds all cases associated with a contact (in any role, not just client) * * {@getfields case_get} * * @return (get mode, case_id provided): Array with case details, case roles, case activity ids, (search mode, case_id not provided): Array of cases found * @access public * @todo Eileen McNaughton 13 Oct 2011 No unit test * @todo Erik Hommel 16 dec 2010 check if all DB fields are returned */ function civicrm_api3_case_get($params) { // Get mode if (!($caseId = CRM_Utils_Array::value('id', $params))) { $caseId = CRM_Utils_Array::value('case_id', $params); } if ($caseId) { // Validate param if (!is_numeric($caseId)) { return civicrm_api3_create_error('Invalid parameter: case_id. Must provide a numeric value.'); } $case = _civicrm_api3_case_read($caseId); if ($case) { //get case contacts $contacts = CRM_Case_BAO_Case::getcontactNames($caseId); $relations = CRM_Case_BAO_Case::getRelatedContacts($caseId); $case['contacts'] = array_merge($contacts, $relations); //get case activities $query = "SELECT activity_id FROM civicrm_case_activity WHERE case_id = {$caseId}"; $dao = CRM_Core_DAO::executeQuery($query); $case['activities'] = array(); while ($dao->fetch()) { $case['activities'][] = $dao->activity_id; } $cases = array($caseId => $case); return civicrm_api3_create_success($cases); } else { return civicrm_api3_create_success(array()); } } //search by client if ($client = CRM_Utils_Array::value('client_id', $params)) { $ids = array(); foreach ((array) $client as $cid) { if (is_numeric($cid)) { $ids = array_merge($ids, CRM_Case_BAO_Case::retrieveCaseIdsByContactId($cid, TRUE)); } } if (empty($ids)) { return civicrm_api3_create_success(array()); } $cases = array(); foreach ($ids as $id) { $cases[$id] = _civicrm_api3_case_read($id); } return civicrm_api3_create_success($cases); } //search by activity if ($act = CRM_Utils_Array::value('activity_id', $params)) { if (!is_numeric($act)) { return civicrm_api3_create_error('Invalid parameter: activity_id. Must provide a numeric value.'); } $caseId = CRM_Case_BAO_Case::getCaseIdByActivityId($act); if (!$caseId) { return civicrm_api3_create_success(array()); } $case = array($caseId => _civicrm_api3_case_read($caseId)); return civicrm_api3_create_success($case); } //search by contacts if ($contact = CRM_Utils_Array::value('contact_id', $params)) { if (!is_numeric($contact)) { return civicrm_api3_create_error('Invalid parameter: contact_id. Must provide a numeric value.'); } $sql = "\nSELECT DISTINCT case_id\n FROM civicrm_relationship\n WHERE (contact_id_a = {$contact}\n OR contact_id_b = {$contact})\n AND case_id IS NOT NULL"; $dao =& CRM_Core_DAO::executeQuery($sql); $cases = array(); while ($dao->fetch()) { $cases[$dao->case_id] = _civicrm_api3_case_read($dao->case_id); } return civicrm_api3_create_success($cases); } return civicrm_api3_create_error('Missing required parameter. Must provide case_id, client_id, activity_id, or contact_id.'); }