AGH Strategies - Alice Frumin, Andrew Hunt, Eli Lisseck
Agileware - Alok Patel, Francis Whittle, Justin Freeman
Andrew Thompson
+applicado
Australian Greens - Seamus Lee
-CiviDesk - Yashodha Chaku
-CompuCorp - Michael Devery, Mukesh Ram, Omar Abu Hussein, René Olivo, Vinu
- Varshith Sekar
-Coop SymbioTIC - Samuel Vanhove
+Bastien Ho
+Blackfly Solutions - Alan Dixon
+Caltha - Tomasz Pietrzkowski
+CEDC - Laryn Kragt Bakker
+Chris Burgess
+CiviCoop - Jaap Jansma
+CiviDesk - Sunil Pawar, Yashodha Chaku
+CompuCorp - Camilo Rodriguez, Davi Alexandre, Debarshi Bhaumik, Michael Devery,
+ Mukesh Ram, Omar Abu Hussein, René Olivo, Vinu Varshith Sekar
+Coop SymbioTIC - Mathieu Lutfy, Samuel Vanhove
Davis Media Access - Darrick Servis
+Electronic Frontier Foundation - Mark Burdett
Fuzion - Jitendra Purohit
Ginkgo Street Labs - Frank Gómez
+Hossein Amin
JMA Consulting - Monish Deb
+Johan Vervloet
John Kingsnorth
Joinery - Allen Shaw
+Kanzu Code - Carl Andrew Lema
Kompetenzzentrum Technik-Diversity-Chancengleichheit - Niels Heinemann
Left Join Labs - Sean Madsen
Lighthouse Design and Consulting - Brian Shaughnessy
Naomi Rosenberg
Olivier Tétard
Oxfam Germany - Thomas Schüttler, Yuliyana Liyana
+Pradeep Nayak
Progressive Technology Project - Jamie McClelland
+Romain Thouvenin
+Squiffle Consulting - Aidan Saunders
Systopia - Björn Endres
Tadpole Collective - Kevin Cristiano
Third Sector Design - Michael McAndrew
+Tom Bloor
Wikimedia Foundation - Eileen McNaughton
+Wildsight - Lars Sanders-Green
+Will Long
************************************************
Key Contributors and Sponsors for 4.7
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
// note this also resets any ACL cache
$staticGroupIDs = array();
$cachedGroupIDs = array();
while ($dao->fetch()) {
- // currently operation is restrcited to VIEW/EDIT
+ // currently operation is restricted to VIEW/EDIT
if ($dao->where_clause) {
if ($dao->select_tables) {
$tmpTables = array();
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_ACL_DAO_EntityRole', $id, 'is_active', $is_active);
CRM_Core_Session::setStatus("", ts('Wordpress Access Control Updated'), "success");
- // rebuild the menus to comply with the new permisssions/capabilites
+ // rebuild the menus to comply with the new permissions/capabilites
CRM_Core_Invoke::rebuildMenuAndCaches();
CRM_Utils_System::redirect('admin.php?page=CiviCRM&q=civicrm/admin/access&reset=1');
continue;
}
- $isBulkActivity = (!$bulkActivityTypeID || ($bulkActivityTypeID != $activity['activity_type_id']));
+ $isBulkActivity = (!$bulkActivityTypeID || ($bulkActivityTypeID === $activity['activity_type_id']));
foreach ($mappingParams as $apiKey => $expectedName) {
if (in_array($apiKey, array('assignee_contact_name', 'target_contact_name'))) {
$activities[$id][$expectedName] = CRM_Utils_Array::value($apiKey, $activity, array());
}
// Get contact activities.
- $activities = CRM_Activity_BAO_Activity::deprecatedGetActivities($params);
+ $activities = CRM_Activity_BAO_Activity::getActivities($params);
// Add total.
$params['total'] = CRM_Activity_BAO_Activity::deprecatedGetActivitiesCount($params);
}
elseif (isset($values['target_contact_counter']) && $values['target_contact_counter']) {
$activity['target_contact_name'] = '';
- foreach ($values['target_contact_name'] as $tcID => $tcName) {
- $targetTypeImage = "";
- $targetLink = CRM_Utils_System::href($tcName, 'civicrm/contact/view', "reset=1&cid={$tcID}");
- if ($showContactOverlay) {
- $targetTypeImage = CRM_Contact_BAO_Contact_Utils::getImage(
- CRM_Contact_BAO_Contact::getContactType($tcID),
- FALSE,
- $tcID);
- $activity['target_contact_name'] .= "<div>$targetTypeImage $targetLink";
- }
- else {
- $activity['target_contact_name'] .= $targetLink;
- }
+ $firstTargetName = reset($values['target_contact_name']);
+ $firstTargetContactID = key($values['target_contact_name']);
+
+ $targetLink = CRM_Utils_System::href($firstTargetName, 'civicrm/contact/view', "reset=1&cid={$firstTargetContactID}");
+ if ($showContactOverlay) {
+ $targetTypeImage = CRM_Contact_BAO_Contact_Utils::getImage(
+ CRM_Contact_BAO_Contact::getContactType($firstTargetContactID),
+ FALSE,
+ $firstTargetContactID);
+ $activity['target_contact_name'] .= "<div>$targetTypeImage $targetLink";
+ }
+ else {
+ $activity['target_contact_name'] .= $targetLink;
}
if ($extraCount = $values['target_contact_counter'] - 1) {
$mainActivity->activity_date_time = $actDateTime;
// Make sure this is current revision.
$mainActivity->is_current_revision = TRUE;
- // Drop all relations.
- $mainActivity->parent_id = $mainActivity->original_id = NULL;
+ $mainActivity->original_id = $otherActivity->id;
+ $otherActivity->is_current_revision = FALSE;
$mainActivity->save();
$mainActivityId = $mainActivity->id;
1 => $params['caseID'],
)) . ' ' . $otherActivity->subject;
}
- $otherActivity->activity_date_time = $actDateTime;
$otherActivity->save();
$caseActivity->free();
'sort' => $sort,
);
$config = CRM_Core_Config::singleton();
- $rows = CRM_Activity_BAO_Activity::deprecatedGetActivities($params);
+ $rows = CRM_Activity_BAO_Activity::getActivities($params);
if (empty($rows)) {
return $rows;
$optionValue = CRM_Core_OptionValue::addOptionValue($params, $this->_gName, $this->_action, $this->_id);
- // CRM-11516
- if (!empty($params['financial_account_id'])) {
- $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Asset Account is' "));
- $params = array(
- 'entity_table' => 'civicrm_option_value',
- 'entity_id' => $optionValue->id,
- 'account_relationship' => $relationTypeId,
- 'financial_account_id' => $params['financial_account_id'],
- );
- CRM_Financial_BAO_FinancialTypeAccount::add($params);
- }
-
CRM_Core_Session::setStatus(ts('The %1 \'%2\' has been saved.', array(
1 => $this->_gLabel,
2 => $optionValue->label,
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
- *
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_PrintLabel', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return CRM_Campaign_DAO_Campaign|null
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Campaign_DAO_Campaign', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Campaign_DAO_Survey', $id, 'is_active', $is_active);
if (!$crmPID) {
$cacheKey = "civicrm search {$this->_key}";
- CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey, 'civicrm_contact');
+ Civi::service('prevnext')->deleteItem(NULL, $cacheKey, 'civicrm_contact');
$sql = $this->_query->searchQuery(0, 0, $sort,
FALSE, FALSE,
$casesList[$key]['activity_list'] = sprintf('<a title="%s" class="crm-expand-row" href="%s"></a>',
ts('Activities'),
- CRM_Utils_System::url('civicrm/case/details', array('caseid' => $case['case_id'], 'cid' => $case['contact_id'], 'type' => $type))
+ CRM_Utils_System::url('civicrm/case/details', array('caseId' => $case['case_id'], 'cid' => $case['contact_id'], 'type' => $type))
);
$phone = empty($case['phone']) ? '' : '<br /><span class="description">' . $case['phone'] . '</span>';
}
if (self::checkPermission($actId, 'edit', $case['activity_type_id'], $userID)) {
$casesList[$key]['date'] .= sprintf('<a class="action-item crm-hover-button" href="%s" title="%s"><i class="crm-i fa-pencil"></i></a>',
- CRM_Utils_System::url('civicrm/case/activity', array('reset' => 1, 'cid' => $case['contact_id'], 'caseid' => $case['case_id'], 'action' => 'update')),
+ CRM_Utils_System::url('civicrm/case/activity', array('reset' => 1, 'cid' => $case['contact_id'], 'caseid' => $case['case_id'], 'action' => 'update', 'id' => $actId)),
ts('Edit activity')
);
}
*
* @param null $context
* @param int $userID
- * @param null $type
+ * @param null $type (deprecated)
*
* @return array
* Array of case activities
*
*/
public static function getCaseActivity($caseID, &$params, $contactID, $context = NULL, $userID = NULL, $type = NULL) {
- $values = array();
-
$activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate');
$assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts);
$sourceID = CRM_Utils_Array::key('Activity Source', $activityContacts);
CRM_Activity_BAO_Activity::getStatusesByType(CRM_Activity_BAO_Activity::CANCELLED)
);
- $contactViewUrl = CRM_Utils_System::url("civicrm/contact/view", "reset=1&cid=", FALSE, NULL, FALSE);
- $hasViewContact = CRM_Core_Permission::giveMeAllACLs();
-
if (!$userID) {
$session = CRM_Core_Session::singleton();
$userID = $session->get('userID');
continue;
}
- $caseActivity['DT_RowId'] = $caseActivityId;
+ $caseActivities[$caseActivityId]['DT_RowId'] = $caseActivityId;
//Add classes to the row, via DataTables syntax
- $caseActivity['DT_RowClass'] = "crm-entity status-id-$dao->status";
+ $caseActivities[$caseActivityId]['DT_RowClass'] = "crm-entity status-id-$dao->status";
if (CRM_Utils_Array::crmInArray($dao->status, $compStatusValues)) {
- $caseActivity['DT_RowClass'] .= " status-completed";
+ $caseActivities[$caseActivityId]['DT_RowClass'] .= " status-completed";
}
else {
if (CRM_Utils_Date::overdue($dao->display_date)) {
- $caseActivity['DT_RowClass'] .= " status-overdue";
+ $caseActivities[$caseActivityId]['DT_RowClass'] .= " status-overdue";
}
else {
- $caseActivity['DT_RowClass'] .= " status-scheduled";
+ $caseActivities[$caseActivityId]['DT_RowClass'] .= " status-scheduled";
}
}
if (!empty($dao->priority)) {
if ($dao->priority == CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'priority_id', 'Urgent')) {
- $caseActivity['DT_RowClass'] .= " priority-urgent ";
+ $caseActivities[$caseActivityId]['DT_RowClass'] .= " priority-urgent ";
}
elseif ($dao->priority == CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'priority_id', 'Low')) {
- $caseActivity['DT_RowClass'] .= " priority-low ";
+ $caseActivities[$caseActivityId]['DT_RowClass'] .= " priority-low ";
}
}
//Add data to the row for inline editing, via DataTable syntax
- $caseActivity['DT_RowAttr'] = array();
- $caseActivity['DT_RowAttr']['data-entity'] = 'activity';
- $caseActivity['DT_RowAttr']['data-id'] = $caseActivityId;
+ $caseActivities[$caseActivityId]['DT_RowAttr'] = array();
+ $caseActivities[$caseActivityId]['DT_RowAttr']['data-entity'] = 'activity';
+ $caseActivities[$caseActivityId]['DT_RowAttr']['data-id'] = $caseActivityId;
//Activity Date and Time
- $caseActivity['activity_date_time'] = CRM_Utils_Date::customFormat($dao->display_date);
+ $caseActivities[$caseActivityId]['activity_date_time'] = CRM_Utils_Date::customFormat($dao->display_date);
//Activity Subject
- $caseActivity['subject'] = $dao->subject;
+ $caseActivities[$caseActivityId]['subject'] = $dao->subject;
//Activity Type
- $caseActivity['type'] = (!empty($activityTypes[$dao->type]['icon']) ? '<span class="crm-i ' . $activityTypes[$dao->type]['icon'] . '"></span> ' : '')
+ $caseActivities[$caseActivityId]['type'] = (!empty($activityTypes[$dao->type]['icon']) ? '<span class="crm-i ' . $activityTypes[$dao->type]['icon'] . '"></span> ' : '')
. $activityTypes[$dao->type]['label'];
- //Activity Target (With)
- $targetContact = '';
- if (isset($dao->target_contact_id)) {
- $targetContact = $dao->target_contact_name;
- if ($hasViewContact) {
- $targetContact = '<a href="' . $contactViewUrl . $dao->target_contact_id . '">' . $dao->target_contact_name . '</a>';
+ // Activity Target (With Contact) (There can be more than one)
+ $targetContact = self::formatContactLink($dao->target_contact_id, $dao->target_contact_name);
+ if (empty($caseActivities[$caseActivityId]['target_contact_name'])) {
+ $caseActivities[$caseActivityId]['target_contact_name'] = $targetContact;
+ }
+ else {
+ if (strpos($caseActivities[$caseActivityId]['target_contact_name'], $targetContact) === FALSE) {
+ $caseActivities[$caseActivityId]['target_contact_name'] .= '; ' . $targetContact;
}
}
- $caseActivity['target_contact_name'] = $targetContact;
- //Activity Source Contact (Reporter)
- $sourceContact = $dao->source_contact_name;
- if ($hasViewContact) {
- $sourceContact = '<a href="' . $contactViewUrl . $dao->source_contact_id . '">' . $dao->source_contact_name . '</a>';
- }
- $caseActivity['source_contact_name'] = $sourceContact;
+ // Activity Source Contact (Reporter) (There can only be one)
+ $sourceContact = self::formatContactLink($dao->source_contact_id, $dao->source_contact_name);
+ $caseActivities[$caseActivityId]['source_contact_name'] = $sourceContact;
- //Activity Assignee. CRM-4485.
- $assigneeContact = '';
- if (isset($dao->assignee_contact_id)) {
- $assigneeContact = $dao->assignee_contact_name;
- if ($hasViewContact) {
- $assigneeContact = '<a href="' . $contactViewUrl . $dao->assignee_contact_id . '">' . $dao->assignee_contact_name . '</a>';
+ // Activity Assignee (There can be more than one)
+ $assigneeContact = self::formatContactLink($dao->assignee_contact_id, $dao->assignee_contact_name);
+ if (empty($caseActivities[$caseActivityId]['assignee_contact_name'])) {
+ $caseActivities[$caseActivityId]['assignee_contact_name'] = $assigneeContact;
+ }
+ else {
+ if (strpos($caseActivities[$caseActivityId]['assignee_contact_name'], $assigneeContact) === FALSE) {
+ $caseActivities[$caseActivityId]['assignee_contact_name'] .= '; ' . $assigneeContact;
}
}
- $caseActivity['assignee_contact_name'] = $assigneeContact;
//Activity Status
- $caseActivity['status_id'] = $activityStatuses[$dao->status];
+ $caseActivities[$caseActivityId]['status_id'] = $activityStatuses[$dao->status];
// FIXME: Why are we not using CRM_Core_Action for these links? This is too much manual work and likely to get out-of-sync with core markup.
$url = "";
}
elseif (!$caseDeleted) {
$url = ' <a ' . $css . ' href="' . $restoreUrl . $additionalUrl . '">' . ts('Restore') . '</a>';
- $caseActivity['status_id'] = $caseActivity['status_id'] . '<br /> (deleted)';
+ $caseActivities[$caseActivityId]['status_id'] = $caseActivities[$caseActivityId]['status_id'] . '<br /> (deleted)';
}
//check for operations.
// if there are file attachments we will return how many and, if only one, add a link to it
if (!empty($dao->attachment_ids)) {
$attachmentIDs = array_unique(explode(',', $dao->attachment_ids));
- $caseActivity['no_attachments'] = count($attachmentIDs);
+ $caseActivities[$caseActivityId]['no_attachments'] = count($attachmentIDs);
$url .= implode(' ', CRM_Core_BAO_File::paperIconAttachment('civicrm_activity', $caseActivityId));
}
- $caseActivity['links'] = $url;
-
- array_push($caseActivities, $caseActivity);
+ $caseActivities[$caseActivityId]['links'] = $url;
}
$dao->free();
$caseActivitiesDT = array();
- $caseActivitiesDT['data'] = $caseActivities;
+ $caseActivitiesDT['data'] = array_values($caseActivities);
$caseActivitiesDT['recordsTotal'] = $caseCount;
$caseActivitiesDT['recordsFiltered'] = $caseCount;
return $caseActivitiesDT;
}
+ /**
+ * Helper function to generate a formatted contact link/name for display in the Case activities tab
+ *
+ * @param $contactId
+ * @param $contactName
+ *
+ * @return string
+ */
+ private static function formatContactLink($contactId, $contactName) {
+ if (empty($contactId)) {
+ return NULL;
+ }
+
+ $hasViewContact = CRM_Contact_BAO_Contact_Permission::allow($contactId);
+
+ if ($hasViewContact) {
+ $contactViewUrl = CRM_Utils_System::url("civicrm/contact/view", "reset=1&cid={$contactId}");
+ return "<a href=\"{$contactViewUrl}\">" . $contactName . "</a>";
+ }
+ else {
+ return $contactName;
+ }
+ }
+
/**
* Get Case Related Contacts.
*
$atArray,
$this->_currentUserId
);
- $activities = array_keys($activities);
- $activities = $activities[0];
+ $activityId = CRM_Utils_Array::first(array_keys($activities['data']));
$editUrl = CRM_Utils_System::url('civicrm/case/activity',
- "reset=1&cid={$this->_currentlyViewedContactId}&caseid={$caseId}&action=update&id={$activities}"
+ "reset=1&cid={$this->_currentlyViewedContactId}&caseid={$caseId}&action=update&id={$activityId}"
);
}
CRM_Core_Error::statusBounce(ts("You can not add another '%1' activity to this case. %2",
CRM_Utils_Recent::delContact($id);
self::updateContactCache($id, empty($restore));
- // delete any dupe cache entry
+ // delete any prevnext/dupe cache entry
+ // These two calls are redundant in default deployments, but they're
+ // meaningful if "prevnext" is memory-backed.
+ Civi::service('prevnext')->deleteItem($id);
CRM_Core_BAO_PrevNextCache::deleteItem($id);
$transaction->commit();
return;
}
if ($isEmptyPrevNextTable) {
+ // These two calls are redundant in default deployments, but they're
+ // meaningful if "prevnext" is memory-backed.
+ Civi::service('prevnext')->deleteItem();
CRM_Core_BAO_PrevNextCache::deleteItem();
}
// clear acl cache if any.
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
$params = array('id' => $id);
* @param bool $isActive
* Value we want to set the is_active field.
*
- * @return CRM_Core_DAO|null
- * DAO object on success, NULL otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $isActive) {
return CRM_Core_DAO::setFieldValue('CRM_Contact_DAO_Group', $id, 'is_active', $isActive);
$this->_qill[$grouping][] = "$field[title] $op \"$value\"";
}
elseif ($name === 'email_greeting') {
+ CRM_Core_Error::deprecatedFunctionWarning('pass in email_greeting_id or email_greeting_display');
$filterCondition = array('greeting_type' => 'email_greeting');
$this->optionValueQuery(
$name, $op, $value, $grouping,
);
}
elseif ($name === 'postal_greeting') {
+ CRM_Core_Error::deprecatedFunctionWarning('pass in postal_greeting_id or postal_greeting_display');
$filterCondition = array('greeting_type' => 'postal_greeting');
$this->optionValueQuery(
$name, $op, $value, $grouping,
);
}
elseif ($name === 'addressee') {
+ CRM_Core_Error::deprecatedFunctionWarning('pass in addressee_id or addressee_display');
$filterCondition = array('greeting_type' => 'addressee');
$this->optionValueQuery(
$name, $op, $value, $grouping,
}
}
else {
- // LOWER roughly translates to 'hurt my database without deriving any benefit' See CRM-19811.
- $wc = self::caseImportant($op) ? "LOWER({$field['where']})" : "{$field['where']}";
+ CRM_Core_Error::deprecatedFunctionWarning('pass $ids to this method');
+ $wc = "{$field['where']}";
}
if (in_array($name, $pseudoFields)) {
if (!in_array($name, array('gender_id', 'prefix_id', 'suffix_id', 'communication_style_id'))) {
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Contact_DAO_RelationshipType', $id, 'is_active', $is_active);
) {
//reset the cache table for new search
$cacheKey = "civicrm search {$this->controller->_key}";
- CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey);
+ Civi::service('prevnext')->deleteItem(NULL, $cacheKey);
}
//get the button name
}
$form->_emails = $fromEmailValues;
+ $defaults = array();
$form->_fromEmails = $fromEmailValues;
+ if (!Civi::settings()->get('allow_mail_from_logged_in_contact')) {
+ $defaults['from_email_address'] = current(CRM_Core_BAO_Domain::getNameAndEmail(FALSE, TRUE));
+ }
if (is_numeric(key($form->_fromEmails))) {
// Add signature
$defaultEmail = civicrm_api3('email', 'getsingle', array('id' => key($form->_fromEmails)));
if (!empty($defaultEmail['signature_text'])) {
$defaults['text_message'] = "\n\n--\n" . $defaultEmail['signature_text'];
}
- $form->setDefaults($defaults);
}
+ $form->setDefaults($defaults);
}
/**
'nextPrevError' => 0,
);
if ($qfKey) {
- $pos = CRM_Core_BAO_PrevNextCache::getPositions("civicrm search $qfKey",
+ $pos = Civi::service('prevnext')->getPositions("civicrm search $qfKey",
$this->_contactId,
$this->_contactId
);
// check for current != previous to ensure cache is not reset if paging is done without changing
// sort criteria
if (!$pageNum || (!empty($currentSortID) && $currentSortID != $previousSortID)) {
- CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey, 'civicrm_contact');
+ Civi::service('prevnext')->deleteItem(NULL, $cacheKey, 'civicrm_contact');
// this means it's fresh search, so set pageNum=1
if (!$pageNum) {
$pageNum = 1;
$sortByCharacter = CRM_Utils_Request::retrieve('sortByCharacter', 'String');
//for text field pagination selection save
- $countRow = CRM_Core_BAO_PrevNextCache::getCount($cacheKey, NULL, "entity_table = 'civicrm_contact'");
+ $countRow = Civi::service('prevnext')->getCount($cacheKey);
// $sortByCharacter triggers a refresh in the prevNext cache
if ($sortByCharacter && $sortByCharacter != 'all') {
$cacheKey .= "_alphabet";
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_ContributionPage', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Premium', $id, 'premiums_active ', $is_active);
*
*/
class CRM_Contribute_Form_AbstractEditPayment extends CRM_Contact_Form_Task {
+
+ use CRM_Financial_Form_SalesTaxTrait;
+
public $_mode;
public $_action;
* Get all the recurring contribution information and assign to the template
*/
private function addRecurringContributionsBlock() {
- $activeContributions = $this->getActiveRecurringContributions();
- $inactiveRecurringContributions = $this->getInactiveRecurringContributions();
+ list($activeContributions, $activeContributionsCount) = $this->getActiveRecurringContributions();
+ list($inactiveRecurringContributions, $inactiveContributionsCount) = $this->getInactiveRecurringContributions();
if (!empty($activeContributions) || !empty($inactiveRecurringContributions)) {
// assign vars to templates
$this->assign('action', $this->_action);
$this->assign('activeRecurRows', $activeContributions);
+ $this->assign('contributionRecurCount', $activeContributionsCount + $inactiveContributionsCount);
$this->assign('inactiveRecurRows', $inactiveRecurringContributions);
$this->assign('recur', TRUE);
}
$contributionRecurResult = civicrm_api3('ContributionRecur', 'get', array(
'contact_id' => $this->_contactId,
'contribution_status_id' => array('NOT IN' => CRM_Contribute_BAO_ContributionRecur::getInactiveStatuses()),
- 'options' => array('limit' => 0, 'sort' => 'start_date ASC'),
+ 'options' => ['limit' => 0, 'sort' => 'is_test, start_date DESC'],
));
$recurContributions = CRM_Utils_Array::value('values', $contributionRecurResult);
}
$contributionRecurResult = civicrm_api3('ContributionRecur', 'get', array(
'contact_id' => $this->_contactId,
'contribution_status_id' => array('IN' => CRM_Contribute_BAO_ContributionRecur::getInactiveStatuses()),
- 'options' => array('limit' => 0, 'sort' => 'start_date ASC'),
+ 'options' => ['limit' => 0, 'sort' => 'is_test, start_date DESC'],
));
$recurContributions = CRM_Utils_Array::value('values', $contributionRecurResult);
}
* @return mixed
*/
private function buildRecurringContributionsArray($recurContributions) {
+ $liveRecurringContributionCount = 0;
foreach ($recurContributions as $recurId => $recurDetail) {
$action = array_sum(array_keys($this->recurLinks($recurId)));
// no action allowed if it's not active
$recurContributions[$recurId]['is_active'] = (!CRM_Contribute_BAO_Contribution::isContributionStatusNegative($recurDetail['contribution_status_id']));
+ if (empty($recurDetail['is_test'])) {
+ $liveRecurringContributionCount++;
+ }
+
// Get the name of the payment processor
if (!empty($recurDetail['payment_processor_id'])) {
$recurContributions[$recurId]['payment_processor'] = CRM_Financial_BAO_PaymentProcessor::getPaymentProcessorName($recurDetail['payment_processor_id']);
}
}
- return $recurContributions;
+ return [$recurContributions, $liveRecurringContributionCount];
}
/**
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_ActionSchedule', $id, 'is_active', $is_active);
$argString = "CRM_CT_{$group}_{$path}_{$componentID}";
if (!array_key_exists($argString, self::$_cache)) {
$cache = CRM_Utils_Cache::singleton();
- self::$_cache[$argString] = $cache->get(self::cleanKey($argString));
+ $cleanKey = self::cleanKey($argString);
+ self::$_cache[$argString] = $cache->get($cleanKey);
if (!self::$_cache[$argString]) {
$table = self::getTableName();
$where = self::whereCache($group, $path, $componentID);
$data = $rawData ? self::decode($rawData) : NULL;
self::$_cache[$argString] = $data;
- $cache->set(self::cleanKey($argString), self::$_cache[$argString]);
+ $cache->set($cleanKey, self::$_cache[$argString]);
}
}
return self::$_cache[$argString];
$argString = "CRM_CT_CI_{$group}_{$componentID}";
if (!array_key_exists($argString, self::$_cache)) {
$cache = CRM_Utils_Cache::singleton();
- self::$_cache[$argString] = $cache->get(self::cleanKey($argString));
+ $cleanKey = self::cleanKey($argString);
+ self::$_cache[$argString] = $cache->get($cleanKey);
if (!self::$_cache[$argString]) {
$table = self::getTableName();
$where = self::whereCache($group, NULL, $componentID);
$dao->free();
self::$_cache[$argString] = $result;
- $cache->set(self::cleanKey($argString), self::$_cache[$argString]);
+ $cache->set($cleanKey, self::$_cache[$argString]);
}
}
return $escape . md5($key);
}
- $r = preg_replace_callback(';[^A-Za-z0-9_\. ];', function($m) use ($escape) {
+ $r = preg_replace_callback(';[^A-Za-z0-9_\.];', function($m) use ($escape) {
return $escape . dechex(ord($m[0]));
}, $key);
$urlVar = 'task';
}
- if ($isUpgrade && CRM_Core_DAO::checkFieldExists('civicrm_domain', 'config_backend')) {
+ if ($isUpgrade && CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_domain', 'config_backend')) {
$domain->selectAdd('config_backend');
}
else {
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
// reset the cache
'extends' => $dao->extends,
);
+ if (!empty($params['id'])) {
+ $cvParam['id'] = $params['id'];
+ }
+
if ($cvParam['type'] == 'File') {
$cvParam['file_id'] = $fieldValue['value'];
}
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
- *
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_Job', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
- *
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_LocationType', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, NULL otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_MessageTemplate', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return CRM_Core_DAO_Navigation|NULL
- * DAO object on success, NULL otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_Navigation', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_OptionGroup', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_OptionValue', $id, 'is_active', $is_active);
$optionValue->id = $id;
$optionValue->save();
CRM_Core_PseudoConstant::flush();
+
+ // Create relationship for payment intrument options
+ if (!empty($params['financial_account_id'])) {
+ $optionName = civicrm_api3('OptionGroup', 'getvalue', [
+ 'return' => 'name',
+ 'id' => $params['option_group_id'],
+ ]);
+ // Only create relationship for payment intrument options
+ if ($optionName == 'payment_instrument') {
+ $relationTypeId = civicrm_api3('OptionValue', 'getvalue', [
+ 'return' => 'value',
+ 'option_group_id' => 'account_relationship',
+ 'name' => 'Asset Account is',
+ ]);
+ $params = [
+ 'entity_table' => 'civicrm_option_value',
+ 'entity_id' => $optionValue->id,
+ 'account_relationship' => $relationTypeId,
+ 'financial_account_id' => $params['financial_account_id'],
+ ];
+ CRM_Financial_BAO_FinancialTypeAccount::add($params);
+ }
+ }
return $optionValue;
}
*
* @param string $tableName
* @param string $columnName
+ * @param bool $i18nRewrite
+ * Whether to rewrite the query on multilingual setups.
*
* @return bool
*/
- public static function checkIfFieldExists($tableName, $columnName) {
- $result = CRM_Core_DAO::executeQuery(
- "SHOW COLUMNS FROM $tableName LIKE %1",
- array(1 => array($columnName, 'String'))
- );
- if ($result->fetch()) {
- return TRUE;
- }
- return FALSE;
+ public static function checkIfFieldExists($tableName, $columnName, $i18nRewrite = TRUE) {
+ $query = "SHOW COLUMNS FROM $tableName LIKE '%1'";
+ $dao = CRM_Core_DAO::executeQuery($query, [1 => [$columnName, 'Alphanumeric']], TRUE, NULL, FALSE, $i18nRewrite);
+ $result = $dao->fetch() ? TRUE : FALSE;
+ $dao->free();
+ return $result;
}
/**
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
//check if custom data profile field is disabled
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * CRM_Core_DAO_UFGroup object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $id, 'is_active', $is_active);
public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission::VIEW, $returnFields = NULL) {
$selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
- if (CRM_Core_DAO::checkFieldExists('civicrm_uf_group', 'description')) {
+ if (CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_uf_group', 'description')) {
// CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
$selectFields[] = 'description';
}
- if (CRM_Core_DAO::checkFieldExists('civicrm_uf_group', 'frontend_title')) {
+ if (CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_uf_group', 'frontend_title')) {
$selectFields[] = 'frontend_title';
}
/**
* Check if there is a given column in a specific table.
*
+ * @deprecated
+ * @see CRM_Core_BAO_SchemaHandler::checkIfFieldExists
+ *
* @param string $tableName
* @param string $columnName
* @param bool $i18nRewrite
* true if exists, else false
*/
public static function checkFieldExists($tableName, $columnName, $i18nRewrite = TRUE) {
- $query = "
-SHOW COLUMNS
-FROM $tableName
-LIKE %1
-";
- $params = array(1 => array($columnName, 'String'));
- $dao = CRM_Core_DAO::executeQuery($query, $params, TRUE, NULL, FALSE, $i18nRewrite);
- $result = $dao->fetch() ? TRUE : FALSE;
- $dao->free();
- return $result;
+ return CRM_Core_BAO_SchemaHandler::checkIfFieldExists($tableName, $columnName, $i18nRewrite);
}
/**
/**
* Modify indices to account for localization options.
*
- * @param CRM_Core_DAO $class DAO class
+ * @param string $class DAO class
* @param array $originalIndices index definitions before localization
*
* @return array
*
* Generated from xml/schema/CRM/Core/Phone.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:661faad4886dd1a40784d465b906f447)
+ * (GenCodeChecksum:22802e5d7d8dfce93626004aaf6cd2e2)
*/
/**
'type' => CRM_Utils_Type::T_INT,
'title' => ts('Phone Type'),
'description' => 'Which type of phone does this number belongs.',
+ 'export' => TRUE,
+ 'where' => 'civicrm_phone.phone_type_id',
+ 'headerPattern' => '',
+ 'dataPattern' => '',
'table_name' => 'civicrm_phone',
'entity' => 'Phone',
'bao' => 'CRM_Core_BAO_Phone',
return $this->addEntityRef($name, $label, $props, $required);
case 'Password':
+ $props['size'] = isset($props['size']) ? $props['size'] : 60;
return $this->add('password', $name, $label, $props, $required);
// Check datatypes of fields
// add new columns
foreach ($hash as $column => $type) {
// CRM-7854: skip existing columns
- if (CRM_Core_DAO::checkFieldExists($table, "{$column}_{$locale}", FALSE)) {
+ if (CRM_Core_BAO_SchemaHandler::checkIfFieldExists($table, "{$column}_{$locale}", FALSE)) {
continue;
}
$queries[] = "ALTER TABLE {$table} ADD {$column}_{$locale} {$type}";
$menu->find(TRUE);
if (!CRM_Core_Config::isUpgradeMode() ||
- CRM_Core_DAO::checkFieldExists('civicrm_menu', 'module_data', FALSE)
+ CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_menu', 'module_data', FALSE)
) {
// Move unrecognized fields to $module_data.
$module_data = array();
*/
public function getSelection($cacheKey, $action = 'get');
+ /**
+ * Get the previous and next keys.
+ *
+ * @param string $cacheKey
+ * @param int $id1
+ * @param int $id2
+ *
+ * @return array
+ */
+ public function getPositions($cacheKey, $id1, $id2);
+
+ /**
+ * Delete an item from the prevnext cache table based on the entity.
+ *
+ * @param int $id
+ * @param string $cacheKey
+ * @param string $entityTable
+ */
+ public function deleteItem($id = NULL, $cacheKey = NULL, $entityTable = 'civicrm_contact');
+
+ /**
+ * Get count of matching rows.
+ *
+ * @param string $cacheKey
+ * @return int
+ */
+ public function getCount($cacheKey);
+
}
}
}
+ /**
+ * Get the previous and next keys.
+ *
+ * @param string $cacheKey
+ * @param int $id1
+ * @param int $id2
+ *
+ * NOTE: I don't really get why there are two ID columns, but we'll
+ * keep passing them through as a matter of safe-refactoring.
+ *
+ * @return array
+ */
+ public function getPositions($cacheKey, $id1, $id2) {
+ return CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, $id1, $id2);
+ }
+
+ /**
+ * Delete an item from the prevnext cache table based on the entity.
+ *
+ * @param int $id
+ * @param string $cacheKey
+ * @param string $entityTable
+ */
+ public function deleteItem($id = NULL, $cacheKey = NULL, $entityTable = 'civicrm_contact') {
+ CRM_Core_BAO_PrevNextCache::deleteItem($id, $cacheKey, $entityTable);
+ }
+
+ /**
+ * Get count of matching rows.
+ *
+ * @param string $cacheKey
+ * @return int
+ */
+ public function getCount($cacheKey) {
+ return CRM_Core_BAO_PrevNextCache::getCount($cacheKey, NULL, "entity_table = 'civicrm_contact'");
+ }
+
}
"bower_components/datatables/media/css/jquery.dataTables.min.css",
"bower_components/jquery-validation/dist/jquery.validate.min.js",
"packages/jquery/plugins/jquery.ui.datepicker.validation.min.js",
+ "js/crm.datepicker.js",
"js/Common.js",
"js/crm.ajax.js",
"js/wysiwyg/crm.wysiwyg.js",
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Event_DAO_Event', $id, 'is_active', $is_active);
$returnMessages = array();
- $participantRole = CRM_Event_PseudoConstant::participantRole();
$pendingStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Pending'");
$expiredStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Negative'");
$waitingStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Waiting'");
$expiredParticipantCount = $waitingConfirmCount = $waitingApprovalCount = 0;
//get all participant who's status in class pending and waiting
- $query = "SELECT * FROM civicrm_participant WHERE status_id IN {$statusIds} ORDER BY register_date";
-
$query = "
SELECT participant.id,
participant.contact_id,
}
}
$this->assign('totalTaxAmount', $totalTaxAmount);
- $this->assign('taxTerm', CRM_Utils_Array::value('tax_term', $invoiceSettings));
+ $this->assign('taxTerm', $this->getSalesTaxTerm());
$this->assign('dataArray', $dataArray);
}
if (!empty($additionalParticipantDetails)) {
$processor = new CRM_Export_BAO_ExportProcessor($exportMode, $fields, $queryOperator);
$returnProperties = array();
- $selectedPaymentFields = FALSE;
- // @todo - this variable is overwritten later - it should be wholly definable in the processor fn.
- $paymentTableId = $processor->getPaymentTableID();
$phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id');
// Warning - this imProviders var is used in a somewhat fragile way - don't rename it
if ($fieldName == 'event_id') {
$returnProperties['event_id'] = 1;
}
- elseif (
- $exportMode == CRM_Export_Form_Select::EVENT_EXPORT &&
- array_key_exists($fieldName, self::componentPaymentFields())
- ) {
- $selectedPaymentFields = TRUE;
- $paymentTableId = 'participant_id';
- $returnProperties[$fieldName] = 1;
- }
else {
$returnProperties[$fieldName] = 1;
}
else {
$returnProperties = $processor->getDefaultReturnProperties();
}
+ // @todo - we are working towards this being entirely a property of the processor
+ $processor->setReturnProperties($returnProperties);
+ $paymentTableId = $processor->getPaymentTableID();
if ($mergeSameAddress) {
//make sure the addressee fields are selected
$addPaymentHeader = FALSE;
$paymentDetails = array();
- if ($processor->isExportPaymentFields() || $selectedPaymentFields) {
+ if ($processor->isExportPaymentFields()) {
// get payment related in for event and members
$paymentDetails = CRM_Contribute_BAO_Contribution::getContributionDetails($exportMode, $ids);
//get all payment headers.
// If we haven't selected specific payment fields, load in all the
// payment headers.
- if (!$selectedPaymentFields) {
+ if (!$processor->isExportSpecifiedPaymentFields()) {
$paymentHeaders = self::componentPaymentFields();
if (!empty($paymentDetails)) {
$addPaymentHeader = TRUE;
// for CRM-3157 purposes
$i18n = CRM_Core_I18n::singleton();
- list($outputColumns, $headerRows, $sqlColumns, $metadata) = self::getExportStructureArrays($returnProperties, $processor, $relationQuery, $selectedPaymentFields);
+ list($outputColumns, $headerRows, $sqlColumns, $metadata) = self::getExportStructureArrays($returnProperties, $processor);
$limitReached = FALSE;
while (!$limitReached) {
self::fetchRelationshipDetails($relDAO, $value, $field, $row);
}
else {
- $row[$field] = self::getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $selectedPaymentFields, $paymentDetails, $paymentTableId);
+ $row[$field] = self::getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $paymentDetails, $processor);
}
}
// data will already be in $row. Otherwise, add payment related
// information, if appropriate.
if ($addPaymentHeader) {
- if (!$selectedPaymentFields) {
+ if (!$processor->isExportSpecifiedPaymentFields()) {
if ($processor->isExportPaymentFields()) {
$paymentData = CRM_Utils_Array::value($row[$paymentTableId], $paymentDetails);
if (!is_array($paymentData) || empty($paymentData)) {
}
else {
// return tableName and sqlColumns in test context
- return array($exportTempTable, $sqlColumns);
+ return array($exportTempTable, $sqlColumns, $headerRows);
}
// delete the export temp table and component table
if (substr($field, -4) == '_a_b' || substr($field, -4) == '_b_a') {
return;
}
- $queryFields = $processor->getQueryFields();
-
- $fieldName = CRM_Utils_String::munge(strtolower($field), '_', 64);
- if ($fieldName == 'id') {
- $fieldName = 'civicrm_primary_id';
- }
-
- // early exit for master_id, CRM-12100
- // in the DB it is an ID, but in the export, we retrive the display_name of the master record
- // also for current_employer, CRM-16939
- if ($fieldName == 'master_id' || $fieldName == 'current_employer') {
- $sqlColumns[$fieldName] = "$fieldName varchar(128)";
- return;
- }
- if (substr($fieldName, -11) == 'campaign_id') {
- // CRM-14398
- $sqlColumns[$fieldName] = "$fieldName varchar(128)";
- return;
- }
-
- $lookUp = array('prefix_id', 'suffix_id');
- // set the sql columns
- if (isset($queryFields[$field]['type'])) {
- switch ($queryFields[$field]['type']) {
- case CRM_Utils_Type::T_INT:
- case CRM_Utils_Type::T_BOOLEAN:
- if (in_array($field, $lookUp)) {
- $sqlColumns[$fieldName] = "$fieldName varchar(255)";
- }
- else {
- $sqlColumns[$fieldName] = "$fieldName varchar(16)";
- }
- break;
-
- case CRM_Utils_Type::T_STRING:
- if (isset($queryFields[$field]['maxlength'])) {
- $sqlColumns[$fieldName] = "$fieldName varchar({$queryFields[$field]['maxlength']})";
- }
- else {
- $sqlColumns[$fieldName] = "$fieldName varchar(255)";
- }
- break;
-
- case CRM_Utils_Type::T_TEXT:
- case CRM_Utils_Type::T_LONGTEXT:
- case CRM_Utils_Type::T_BLOB:
- case CRM_Utils_Type::T_MEDIUMBLOB:
- $sqlColumns[$fieldName] = "$fieldName longtext";
- break;
-
- case CRM_Utils_Type::T_FLOAT:
- case CRM_Utils_Type::T_ENUM:
- case CRM_Utils_Type::T_DATE:
- case CRM_Utils_Type::T_TIME:
- case CRM_Utils_Type::T_TIMESTAMP:
- case CRM_Utils_Type::T_MONEY:
- case CRM_Utils_Type::T_EMAIL:
- case CRM_Utils_Type::T_URL:
- case CRM_Utils_Type::T_CCNUM:
- default:
- $sqlColumns[$fieldName] = "$fieldName varchar(32)";
- break;
- }
- }
- else {
- if (substr($fieldName, -3, 3) == '_id') {
- $sqlColumns[$fieldName] = "$fieldName varchar(255)";
- }
- elseif (substr($fieldName, -5, 5) == '_note') {
- $sqlColumns[$fieldName] = "$fieldName text";
- }
- else {
- $changeFields = array(
- 'groups',
- 'tags',
- 'notes',
- );
-
- if (in_array($fieldName, $changeFields)) {
- $sqlColumns[$fieldName] = "$fieldName text";
- }
- else {
- // set the sql columns for custom data
- if (isset($queryFields[$field]['data_type'])) {
-
- switch ($queryFields[$field]['data_type']) {
- case 'String':
- // May be option labels, which could be up to 512 characters
- $length = max(512, CRM_Utils_Array::value('text_length', $queryFields[$field]));
- $sqlColumns[$fieldName] = "$fieldName varchar($length)";
- break;
-
- case 'Country':
- case 'StateProvince':
- case 'Link':
- $sqlColumns[$fieldName] = "$fieldName varchar(255)";
- break;
-
- case 'Memo':
- $sqlColumns[$fieldName] = "$fieldName text";
- break;
-
- default:
- $sqlColumns[$fieldName] = "$fieldName varchar(255)";
- break;
- }
- }
- else {
- $sqlColumns[$fieldName] = "$fieldName text";
- }
- }
- }
- }
+ $sqlColumns[$processor->getMungedFieldName($field)] = $processor->getSqlColumnDefinition($field);
}
/**
* @param $details
* @param $sqlColumns
*/
- public static function writeDetailsToTable($tableName, &$details, &$sqlColumns) {
+ public static function writeDetailsToTable($tableName, $details, $sqlColumns) {
if (empty($details)) {
return;
}
$sqlClause = array();
- foreach ($details as $dontCare => $row) {
+ foreach ($details as $row) {
$id++;
$valueString = array($id);
- foreach ($row as $dontCare => $value) {
+ foreach ($row as $value) {
if (empty($value)) {
$valueString[] = "''";
}
*
* @return string
*/
- public static function createTempTable(&$sqlColumns) {
+ public static function createTempTable($sqlColumns) {
//creating a temporary table for the search result that need be exported
$exportTempTable = CRM_Utils_SQL_TempTable::build()->setDurable()->setCategory('export')->getName();
* Columns to go in the temp table.
* @param \CRM_Export_BAO_ExportProcessor $processor
* @param array|string $value
- * @param array $phoneTypes
- * @param array $imProviders
- * @param string $relationQuery
- * @param array $selectedPaymentFields
+ *
* @return array
*/
- public static function setHeaderRows($field, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery, $selectedPaymentFields) {
+ public static function setHeaderRows($field, $headerRows, $sqlColumns, $processor, $value) {
$queryFields = $processor->getQueryFields();
- // Split campaign into 2 fields for id and title
- if (substr($field, -14) == 'campaign_title') {
- $headerRows[] = ts('Campaign Title');
- }
- elseif (substr($field, -11) == 'campaign_id') {
+ if (substr($field, -11) == 'campaign_id') {
+ // @todo - set this correctly in the xml rather than here.
$headerRows[] = ts('Campaign ID');
}
elseif (isset($queryFields[$field]['title'])) {
$headerRows[] = $queryFields[$field]['title'];
}
- elseif ($field == 'phone_type_id') {
- $headerRows[] = ts('Phone Type');
- }
elseif ($field == 'provider_id') {
+ // @todo - set this correctly in the xml rather than here.
$headerRows[] = ts('IM Service Provider');
}
elseif ($processor->isRelationshipTypeKey($field)) {
foreach ($value as $relationField => $relationValue) {
// below block is same as primary block (duplicate)
- if (isset($relationQuery[$field]->_fields[$relationField]['title'])) {
- if ($relationQuery[$field]->_fields[$relationField]['name'] == 'name') {
+ if (isset($queryFields[$relationField]['title'])) {
+ if ($queryFields[$relationField]['name'] == 'name') {
$headerName = $field . '-' . $relationField;
}
else {
$headerName = $field . '-' . 'current_employer';
}
else {
- $headerName = $field . '-' . $relationQuery[$field]->_fields[$relationField]['name'];
+ $headerName = $field . '-' . $queryFields[$relationField]['name'];
}
}
foreach (array_keys($val) as $fld) {
$type = explode('-', $fld);
- $hdr = "{$ltype}-" . $relationQuery[$field]->_fields[$type[0]]['title'];
+ $hdr = "{$ltype}-" . $queryFields[$type[0]]['title'];
if (!empty($type[1])) {
if (CRM_Utils_Array::value(0, $type) == 'phone') {
- $hdr .= "-" . CRM_Utils_Array::value($type[1], $phoneTypes);
+ $hdr .= "-" . CRM_Core_PseudoConstant::getLabel('CRM_Core_BAO_Phone', 'phone_type_id', $type[1]);
}
elseif (CRM_Utils_Array::value(0, $type) == 'im') {
- $hdr .= "-" . CRM_Utils_Array::value($type[1], $imProviders);
+ $hdr .= "-" . CRM_Core_PseudoConstant::getLabel('CRM_Core_BAO_IM', 'provider_id', $type[1]);
}
}
$headerName = $field . '-' . $hdr;
}
self::manipulateHeaderRows($headerRows);
}
- elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) {
+ elseif ($processor->isExportPaymentFields() && array_key_exists($field, self::componentPaymentFields())) {
$headerRows[] = CRM_Utils_Array::value($field, self::componentPaymentFields());
}
else {
*
* @param array $returnProperties
* @param \CRM_Export_BAO_ExportProcessor $processor
- * @param string $relationQuery
- * @param array $selectedPaymentFields
+ *
* @return array
* - outputColumns Array of columns to be exported. The values don't matter but the key must match the
* alias for the field generated by BAO_Query object.
* - b) this code is old & outdated. Submit your answers to circular bin or better
* yet find a way to comment them for posterity.
*/
- public static function getExportStructureArrays($returnProperties, $processor, $relationQuery, $selectedPaymentFields) {
+ public static function getExportStructureArrays($returnProperties, $processor) {
$metadata = $headerRows = $outputColumns = $sqlColumns = array();
$phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id');
$imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id');
-
$queryFields = $processor->getQueryFields();
foreach ($returnProperties as $key => $value) {
if ($key != 'location' || !is_array($value)) {
$outputColumns[$key] = $value;
- list($headerRows, $sqlColumns) = self::setHeaderRows($key, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery, $selectedPaymentFields);
+ list($headerRows, $sqlColumns) = self::setHeaderRows($key, $headerRows, $sqlColumns, $processor, $value);
}
else {
foreach ($value as $locationType => $locationFields) {
$metadata[$daoFieldName]['pseudoconstant']['var'] = 'imProviders';
}
self::sqlColumnDefn($processor, $sqlColumns, $outputFieldName);
- list($headerRows, $sqlColumns) = self::setHeaderRows($outputFieldName, $headerRows, $sqlColumns, $processor, $value, $phoneTypes, $imProviders, $relationQuery, $selectedPaymentFields);
+ list($headerRows, $sqlColumns) = self::setHeaderRows($outputFieldName, $headerRows, $sqlColumns, $processor, $value);
if ($actualDBFieldName == 'country' || $actualDBFieldName == 'world_region') {
$metadata[$daoFieldName] = array('context' => 'country');
}
* @param $fieldValue
* @param $i18n
* @param $metadata
- * @param $selectedPaymentFields
* @param $paymentDetails
- * @param string $paymentTableId
+ *
+ * @param \CRM_Export_BAO_ExportProcessor $processor
+ *
* @return string
*/
- protected static function getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $selectedPaymentFields, $paymentDetails, $paymentTableId) {
+ protected static function getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $paymentDetails, $processor) {
if ($field == 'id') {
return $iterationDAO->contact_id;
}
}
}
- elseif ($selectedPaymentFields && array_key_exists($field, self::componentPaymentFields())) {
+ elseif ($processor->isExportSpecifiedPaymentFields() && array_key_exists($field, self::componentPaymentFields())) {
+ $paymentTableId = $processor->getPaymentTableID();
$paymentData = CRM_Utils_Array::value($iterationDAO->$paymentTableId, $paymentDetails);
$payFieldMapper = array(
'componentPaymentField_total_amount' => 'total_amount',
*/
protected $relationshipReturnProperties = [];
+ /**
+ * @var array
+ */
+ protected $returnProperties = [];
+
/**
* CRM_Export_BAO_ExportProcessor constructor.
*
$this->requestedFields = $requestedFields;
}
+
+ /**
+ * @return array
+ */
+ public function getReturnProperties() {
+ return $this->returnProperties;
+ }
+
+ /**
+ * @param array $returnProperties
+ */
+ public function setReturnProperties($returnProperties) {
+ $this->returnProperties = $returnProperties;
+ }
+
/**
* @return array
*/
])) {
return TRUE;
}
+ elseif ($this->isExportSpecifiedPaymentFields()) {
+ return TRUE;
+ }
return FALSE;
}
+ /**
+ * Has specific payment fields been requested (as opposed to via all fields).
+ *
+ * If specific fields have been requested then they get added at various points.
+ *
+ * @return bool
+ */
+ public function isExportSpecifiedPaymentFields() {
+ if ($this->getRequestedFields() !== NULL && $this->hasRequestedComponentPaymentFields()) {
+ return TRUE;
+ }
+ }
+
/**
* Get the name of the id field in the table that connects contributions to the export entity.
*/
];
return isset($mapping[$this->getQueryMode()]) ? $mapping[$this->getQueryMode()] : '';
}
+ elseif ($this->hasRequestedComponentPaymentFields()) {
+ return 'participant_id';
+ }
+ return FALSE;
+ }
+
+ /**
+ * Have component payment fields been requested.
+ *
+ * @return bool
+ */
+ protected function hasRequestedComponentPaymentFields() {
+ if ($this->getQueryMode() === CRM_Contact_BAO_Query::MODE_EVENT) {
+ $participantPaymentFields = array_intersect_key($this->getComponentPaymentFields(), $this->getReturnProperties());
+ if (!empty($participantPaymentFields)) {
+ return TRUE;
+ }
+ }
return FALSE;
}
+ /**
+ * Get fields that indicate payment fields have been requested for a component.
+ *
+ * @return array
+ */
+ protected function getComponentPaymentFields() {
+ return [
+ 'componentPaymentField_total_amount' => ts('Total Amount'),
+ 'componentPaymentField_contribution_status' => ts('Contribution Status'),
+ 'componentPaymentField_received_date' => ts('Date Received'),
+ 'componentPaymentField_payment_instrument' => ts('Payment Method'),
+ 'componentPaymentField_transaction_id' => ts('Transaction ID'),
+ ];
+ }
+
/**
* Get the default properties when not specified.
*
];
}
+ /**
+ * Get the sql column definition for the given field.
+ *
+ * @param $field
+ *
+ * @return mixed
+ */
+ public function getSqlColumnDefinition($field) {
+ $fieldName = $this->getMungedFieldName($field);
+
+ // early exit for master_id, CRM-12100
+ // in the DB it is an ID, but in the export, we retrive the display_name of the master record
+ // also for current_employer, CRM-16939
+ if ($fieldName == 'master_id' || $fieldName == 'current_employer') {
+ return "$fieldName varchar(128)";
+ }
+
+ if (substr($fieldName, -11) == 'campaign_id') {
+ // CRM-14398
+ return "$fieldName varchar(128)";
+ }
+
+ $queryFields = $this->getQueryFields();
+ $lookUp = ['prefix_id', 'suffix_id'];
+ // set the sql columns
+ if (isset($queryFields[$field]['type'])) {
+ switch ($queryFields[$field]['type']) {
+ case CRM_Utils_Type::T_INT:
+ case CRM_Utils_Type::T_BOOLEAN:
+ if (in_array($field, $lookUp)) {
+ return "$fieldName varchar(255)";
+ }
+ else {
+ return "$fieldName varchar(16)";
+ }
+
+ case CRM_Utils_Type::T_STRING:
+ if (isset($queryFields[$field]['maxlength'])) {
+ return "$fieldName varchar({$queryFields[$field]['maxlength']})";
+ }
+ else {
+ return "$fieldName varchar(255)";
+ }
+
+ case CRM_Utils_Type::T_TEXT:
+ case CRM_Utils_Type::T_LONGTEXT:
+ case CRM_Utils_Type::T_BLOB:
+ case CRM_Utils_Type::T_MEDIUMBLOB:
+ return "$fieldName longtext";
+
+ case CRM_Utils_Type::T_FLOAT:
+ case CRM_Utils_Type::T_ENUM:
+ case CRM_Utils_Type::T_DATE:
+ case CRM_Utils_Type::T_TIME:
+ case CRM_Utils_Type::T_TIMESTAMP:
+ case CRM_Utils_Type::T_MONEY:
+ case CRM_Utils_Type::T_EMAIL:
+ case CRM_Utils_Type::T_URL:
+ case CRM_Utils_Type::T_CCNUM:
+ default:
+ return "$fieldName varchar(32)";
+ }
+ }
+ else {
+ if (substr($fieldName, -3, 3) == '_id') {
+ return "$fieldName varchar(255)";
+ }
+ elseif (substr($fieldName, -5, 5) == '_note') {
+ return "$fieldName text";
+ }
+ else {
+ $changeFields = [
+ 'groups',
+ 'tags',
+ 'notes',
+ ];
+
+ if (in_array($fieldName, $changeFields)) {
+ return "$fieldName text";
+ }
+ else {
+ // set the sql columns for custom data
+ if (isset($queryFields[$field]['data_type'])) {
+
+ switch ($queryFields[$field]['data_type']) {
+ case 'String':
+ // May be option labels, which could be up to 512 characters
+ $length = max(512, CRM_Utils_Array::value('text_length', $queryFields[$field]));
+ return "$fieldName varchar($length)";
+
+ case 'Country':
+ case 'StateProvince':
+ case 'Link':
+ return "$fieldName varchar(255)";
+
+ case 'Memo':
+ return "$fieldName text";
+
+ default:
+ return "$fieldName varchar(255)";
+ }
+ }
+ else {
+ return "$fieldName text";
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the munged field name.
+ *
+ * @param string $field
+ * @return string
+ */
+ public function getMungedFieldName($field) {
+ $fieldName = CRM_Utils_String::munge(strtolower($field), '_', 64);
+ if ($fieldName == 'id') {
+ $fieldName = 'civicrm_primary_id';
+ }
+ return $fieldName;
+ }
+
}
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return CRM_Core_DAO|null
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Financial_DAO_FinancialAccount', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return CRM_Financial_DAO_PaymentProcessor|null
- * DAO object on success, null otherwise
- *
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Financial_DAO_PaymentProcessor', $id, 'is_active', $is_active);
*/
public static function getAllPaymentProcessors($mode = 'all', $reset = FALSE, $isCurrentDomainOnly = TRUE) {
- $cacheKey = 'CRM_Financial_BAO_Payment_Processor_' . $mode . '_' . CRM_Core_Config::domainID();
+ $cacheKey = 'CRM_Financial_BAO_Payment_Processor_' . $mode . '_' . $isCurrentDomainOnly . '_' . CRM_Core_Config::domainID();
if (!$reset) {
$processors = CRM_Utils_Cache::singleton()->get($cacheKey);
if (!empty($processors)) {
public static function getPaymentProcessors($capabilities = array(), $ids = FALSE) {
$testProcessors = in_array('TestMode', $capabilities) ? self::getAllPaymentProcessors('test') : array();
if (is_array($ids)) {
- $processors = self::getAllPaymentProcessors('all', TRUE, FALSE);
+ $processors = self::getAllPaymentProcessors('all', FALSE, FALSE);
}
else {
- $processors = self::getAllPaymentProcessors('all', TRUE);
+ $processors = self::getAllPaymentProcessors('all');
}
if (in_array('TestMode', $capabilities) && is_array($ids)) {
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
- *
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Financial_DAO_PaymentProcessorType', $id, 'is_active', $is_active);
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.7 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2018 |
+ +--------------------------------------------------------------------+
+ | 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-2018
+ */
+
+trait CRM_Financial_Form_SalesTaxTrait {
+
+ /**
+ * Assign the sales tax term to the template.
+ */
+ public function assignSalesTaxTermToTemplate() {
+ $this->assign('taxTerm', $this->getSalesTaxTerm());
+ }
+
+ /**
+ * Assign sales tax rates to the template.
+ */
+ public function assignSalesTaxRates() {
+ $this->assign('taxRates', json_encode(CRM_Core_PseudoConstant::getTaxRates()));
+ }
+
+ /**
+ * Return the string to be assigned to the template for sales tax - e.g GST, VAT.
+ *
+ * @return string
+ */
+ public function getSalesTaxTerm() {
+ $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
+ $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
+ if (!$invoicing) {
+ return '';
+ }
+ return CRM_Utils_Array::value('tax_term', $invoiceSettings);
+ }
+
+ /**
+ * Assign information to the template required for sales tax purposes.
+ */
+ public function assignSalesTaxMetadataToTemplate() {
+ $this->assignSalesTaxRates();
+ $this->assignSalesTaxTermToTemplate();
+ }
+
+ /**
+ * Get sales tax rates.
+ *
+ * @return array
+ */
+ public function getTaxRatesForFinancialTypes() {
+ return CRM_Core_PseudoConstant::getTaxRates();
+ }
+
+ /**
+ * @param int $financialTypeID
+ *
+ * @return string
+ */
+ public function getTaxRateForFinancialType($financialTypeID) {
+ return CRM_Utils_Array::value($financialTypeID, $this->getTaxRatesForFinancialTypes());
+ }
+
+}
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Mailing_DAO_Component', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Member_DAO_MembershipStatus', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Member_DAO_MembershipType', $id, 'is_active', $is_active);
*
* Generated from xml/schema/CRM/Member/MembershipType.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:51b478b01b1ef20a54b1039ccc29d0ab)
+ * (GenCodeChecksum:b36330fa029a5c1467441e89b7c45c63)
*/
/**
'entity' => 'MembershipType',
'bao' => 'CRM_Member_BAO_MembershipType',
'localizable' => 0,
+ 'html' => [
+ 'type' => 'Radio',
+ ],
'pseudoconstant' => [
'callback' => 'CRM_Core_SelectValues::memberAutoRenew',
]
* Build the form object.
*/
public function buildQuickForm() {
+ $this->assignSalesTaxMetadataToTemplate();
$this->addPaymentProcessorSelect(TRUE, FALSE, TRUE);
CRM_Core_Payment_Form::buildPaymentForm($this, $this->_paymentProcessor, FALSE, TRUE, $this->getDefaultPaymentInstrumentId());
*/
public function buildQuickForm() {
- $this->assign('taxRates', json_encode(CRM_Core_PseudoConstant::getTaxRates()));
-
$this->assign('currency', CRM_Core_Config::singleton()->defaultCurrencySymbol);
- $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
- $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
- if (isset($invoicing)) {
- $this->assign('taxTerm', CRM_Utils_Array::value('tax_term', $invoiceSettings));
- }
+
// build price set form.
$buildPriceSet = FALSE;
if ($this->_priceSetId || !empty($_POST['price_set_id'])) {
}
if ($taxAmount) {
$this->assign('totalTaxAmount', $totalTaxAmount);
- $this->assign('taxTerm', CRM_Utils_Array::value('tax_term', $invoiceSettings));
+ // Not sure why would need this on Submit.... unless it's being used when sending mails in which case this is the wrong place
+ $this->assign('taxTerm', $this->getSalesTaxTerm());
}
$this->assign('dataArray', $dataArray);
}
}
//CRM-16950
- $taxRates = CRM_Core_PseudoConstant::getTaxRates();
- $taxRate = CRM_Utils_Array::value($this->allMembershipTypeDetails[$defaults['membership_type_id']]['financial_type_id'], $taxRates);
-
- $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
+ $taxRate = $this->getTaxRateForFinancialType($this->allMembershipTypeDetails[$defaults['membership_type_id']]['financial_type_id']);
// auto renew options if enabled for the membership
$options = CRM_Core_SelectValues::memberAutoRenew();
//CRM-16950
$taxAmount = NULL;
$totalAmount = CRM_Utils_Array::value('minimum_fee', $values);
- if (CRM_Utils_Array::value($values['financial_type_id'], $taxRates)) {
+ // @todo - feels a bug - we use taxRate from the form default rather than from the specified type?!?
+ if ($this->getTaxRateForFinancialType($values['financial_type_id'])) {
$taxAmount = ($taxRate / 100) * CRM_Utils_Array::value('minimum_fee', $values);
$totalAmount = $totalAmount + $taxAmount;
}
'financial_type_id' => CRM_Utils_Array::value('financial_type_id', $values),
'total_amount' => CRM_Utils_Money::format($totalAmount, NULL, '%a'),
'total_amount_numeric' => $totalAmount,
- 'tax_message' => $taxAmount ? ts("Includes %1 amount of %2", array(1 => CRM_Utils_Array::value('tax_term', $invoiceSettings), 2 => CRM_Utils_Money::format($taxAmount))) : $taxAmount,
+ 'tax_message' => $taxAmount ? ts("Includes %1 amount of %2", array(1 => $this->getSalesTaxTerm(), 2 => CRM_Utils_Money::format($taxAmount))) : $taxAmount,
);
if (!empty($values['auto_renew'])) {
* Set entity fields to be assigned to the form.
*/
protected function setEntityFields() {
- // TODO: Add fields here per CRM/Admin/Form/RelationshipType.php.
- // ... It's not as easy because MembershipType has multiple conditional fields/javascript etc.
- $this->entityFields = [];
+ $this->entityFields = [
+ 'name' => [
+ 'required' => 'TRUE',
+ 'name' => 'name',
+ 'description' => ts("e.g. 'Student', 'Senior', 'Honor Society'..."),
+ ],
+ 'description' => [
+ 'name' => 'description',
+ 'description' => ts("Description of this membership type for internal use. May include eligibility, benefits, terms, etc."),
+ ],
+ 'member_of_contact_id' => [
+ 'name' => 'member_of_contact_id',
+ 'description' => ts("Members assigned this membership type belong to which organization (e.g. this is for membership in 'Save the Whales - Northwest Chapter'). NOTE: This organization/group/chapter must exist as a CiviCRM Organization type contact."),
+ ],
+ 'minimum_fee' => [
+ 'name' => 'minimum_fee',
+ 'description' => ts('Minimum fee required for this membership type. For free/complimentary memberships - set minimum fee to zero (0). NOTE: When using CiviCRM to process sales taxes this should be the tax exclusive amount.'),
+ 'formatter' => 'crmMoney',
+ ],
+ 'financial_type_id' => [
+ 'name' => 'financial_type_id',
+ 'description' => ts('Select the financial type assigned to fees for this membership type (for example \'Membership Fees\'). This is required for all membership types - including free or complimentary memberships.'),
+ ],
+ 'auto_renew' => [
+ 'name' => 'auto_renew',
+ 'options' => CRM_Core_SelectValues::memberAutoRenew(),
+ 'place_holder' => ts('You will need to select and configure a supported payment processor (currently Authorize.Net, PayPal Pro, or PayPal Website Standard) in order to offer automatically renewing memberships.'),
+ ],
+ 'duration_interval' => [
+ 'name' => 'duration_interval',
+ ],
+ 'duration_unit' => [
+ 'name' => 'duration_unit',
+ 'description' => ts('Duration of this membership (e.g. 30 days, 2 months, 5 years, 1 lifetime)'),
+ ],
+ 'period_type' => [
+ 'name' => 'period_type',
+ 'description' => ts("Select 'rolling' if membership periods begin at date of signup. Select 'fixed' if membership periods begin on a set calendar date."),
+ 'help' => ['id' => 'period-type', 'file' => "CRM/Member/Page/MembershipType.hlp"],
+ ],
+ 'fixed_period_start_day' => [
+ 'name' => 'fixed_period_start_day',
+ 'description' => ts("Month and day on which a <strong>fixed</strong> period membership or subscription begins. Example: A fixed period membership with Start Day set to Jan 01 means that membership periods would be 1/1/06 - 12/31/06 for anyone signing up during 2006."),
+ ],
+ 'fixed_period_rollover_day' => [
+ 'name' => 'fixed_period_rollover_day',
+ 'description' => ts('Membership signups on or after this date cover the following calendar year as well. Example: If the rollover day is November 30, membership period for signups during December will cover the following year.'),
+ ],
+ 'relationship_type_id' => [
+ 'name' => 'relationship_type_id',
+ ],
+ 'max_related' => [
+ 'name' => 'max_related',
+ 'description' => ts('Maximum number of related memberships (leave blank for unlimited).'),
+ ],
+ 'visibility' => [
+ 'name' => 'visibility',
+ 'description' => ts("Can this membership type be used for self-service signups ('Public'), or is it only for CiviCRM users with 'Edit Contributions' permission ('Admin')."),
+ ],
+ 'weight' => [
+ 'name' => 'weight',
+ ],
+ 'is_active' => [
+ 'name' => 'is_active',
+ ],
+ ];
+
+ if (!CRM_Financial_BAO_PaymentProcessor::hasPaymentProcessorSupporting(array('Recurring'))) {
+ $this->entityFields['auto_renew']['not-auto-addable'] = TRUE;
+ $this->entityFields['auto_renew']['documentation_link'] = ['page' => 'user/contributions/payment-processors'];
+ }
}
/**
if ($this->_action & CRM_Core_Action::DELETE) {
return;
}
-
- $this->applyFilter('__ALL__', 'trim');
- $this->addField('name', [], TRUE);
- $this->addField('description');
- $this->addField('minimum_fee');
- $this->addField('duration_unit', [], TRUE);
- $this->addField('period_type', [], TRUE);
- $this->addField('is_active');
- $this->addField('weight');
- $this->addField('max_related');
+ // This is a temporary variable as we work towards moving over towards using the EntityField.tpl.
+ // Fields in this array have been tested & in the tpl have been switched over to metadata.
+ // Note this kinda 'works from the top' - ie. once we hit a field that needs some thought we need
+ // to stop & make that one work.
+ $this->assign('tpl_standardised_fields', ['name', 'description', 'member_of_contact_id', 'minimum_fee']);
$this->addRule('name', ts('A membership type with this name already exists. Please select another name.'),
'objectExists', array('CRM_Member_DAO_MembershipType', $this->_id)
);
$this->addRule('minimum_fee', ts('Please enter a monetary value for the Minimum Fee.'), 'money');
- $this->add('text', 'duration_interval', ts('Duration Interval'),
- CRM_Core_DAO::getAttribute('CRM_Member_DAO_MembershipType', 'duration_interval')
- );
-
$props = array('api' => array('params' => array('contact_type' => 'Organization')));
$this->addEntityRef('member_of_contact_id', ts('Membership Organization'), $props, TRUE);
* Campaign page id.
*
* @param bool $is_active
- * @return null
+ *
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setDisable($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_PCP_DAO_PCP', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise.
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceField', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
- *
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceFieldValue', $id, 'is_active', $is_active);
* Id of the database record.
* @param $isActive
*
- * @internal param bool $is_active value we want to set the is_active field
- *
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $isActive) {
return CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceSet', $id, 'is_active', $isActive);
* @param bool $isQuickConfig we want to set the is_quick_config field.
* Value we want to set the is_quick_config field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsQuickConfig($id, $isQuickConfig) {
return CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceSet', $id, 'is_quick_config', $isQuickConfig);
/**
* The recommended PHP version.
*/
- const RECOMMENDED_PHP_VER = '7.0';
+ const RECOMMENDED_PHP_VER = '7.1';
/**
* The previous recommended PHP version.
*/
- const MIN_RECOMMENDED_PHP_VER = '5.6';
+ const MIN_RECOMMENDED_PHP_VER = '7.0';
/**
* The minimum PHP version required to install Civi.
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 5 |
+ +--------------------------------------------------------------------+
+ | 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. |
+ | |
+ | 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 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 |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * Upgrade logic for FiveSix */
+class CRM_Upgrade_Incremental_php_FiveSix extends CRM_Upgrade_Incremental_Base {
+
+ /**
+ * Compute any messages which should be displayed beforeupgrade.
+ *
+ * Note: This function is called iteratively for each upcoming
+ * revision to the database.
+ *
+ * @param string $preUpgradeMessage
+ * @param string $rev
+ * a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'.
+ * @param null $currentVer
+ */
+ public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
+ // Example: Generate a pre-upgrade message.
+ // if ($rev == '5.12.34') {
+ // $preUpgradeMessage .= '<p>' . ts('A new permission has been added called %1 This Permission is now used to control access to the Manage Tags screen', array(1 => 'manage tags')) . '</p>';
+ // }
+ }
+
+ /**
+ * Compute any messages which should be displayed after upgrade.
+ *
+ * @param string $postUpgradeMessage
+ * alterable.
+ * @param string $rev
+ * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
+ */
+ public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
+ // Example: Generate a post-upgrade message.
+ // if ($rev == '5.12.34') {
+ // $postUpgradeMessage .= '<br /><br />' . ts("By default, CiviCRM now disables the ability to import directly from SQL. To use this feature, you must explicitly grant permission 'import SQL datasource'.");
+ // }
+ }
+
+ /*
+ * Important! All upgrade functions MUST add a 'runSql' task.
+ * Uncomment and use the following template for a new upgrade version
+ * (change the x in the function name):
+ */
+
+ // /**
+ // * Upgrade function.
+ // *
+ // * @param string $rev
+ // */
+ // public function upgrade_5_0_x($rev) {
+ // $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
+ // $this->addTask('Do the foo change', 'taskFoo', ...);
+ // // Additional tasks here...
+ // // Note: do not use ts() in the addTask description because it adds unnecessary strings to transifex.
+ // // The above is an exception because 'Upgrade DB to %1: SQL' is generic & reusable.
+ // }
+
+ // public static function taskFoo(CRM_Queue_TaskContext $ctx, ...) {
+ // return TRUE;
+ // }
+
+}
* @return bool
*/
public static function addMailingTemplateType() {
- if (!CRM_Core_DAO::checkFieldExists('civicrm_mailing', 'template_type', FALSE)) {
+ if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_mailing', 'template_type', FALSE)) {
CRM_Core_DAO::executeQuery('
ALTER TABLE civicrm_mailing
ADD COLUMN `template_type` varchar(64) NOT NULL DEFAULT \'traditional\' COMMENT \'The language/processing system used for email templates.\',
*/
public function upgrade_4_3_alpha2($rev) {
//CRM-11847
- $isColumnPresent = CRM_Core_DAO::checkFieldExists('civicrm_dedupe_rule_group', 'is_default');
+ $isColumnPresent = CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_dedupe_rule_group', 'is_default');
if ($isColumnPresent) {
CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_dedupe_rule_group DROP COLUMN is_default');
}
// CRM-12002
if (
CRM_Core_DAO::checkTableExists('log_civicrm_line_item') &&
- CRM_Core_DAO::checkFieldExists('log_civicrm_line_item', 'label')
+ CRM_Core_BAO_SchemaHandler::checkIfFieldExists('log_civicrm_line_item', 'label')
) {
CRM_Core_DAO::executeQuery('ALTER TABLE `log_civicrm_line_item` CHANGE `label` `label` VARCHAR(255) NULL DEFAULT NULL');
}
// CRM-12205
if (
CRM_Core_DAO::checkTableExists('log_civicrm_financial_trxn') &&
- CRM_Core_DAO::checkFieldExists('log_civicrm_financial_trxn', 'trxn_id')
+ CRM_Core_BAO_SchemaHandler::checkIfFieldExists('log_civicrm_financial_trxn', 'trxn_id')
) {
CRM_Core_DAO::executeQuery('ALTER TABLE `log_civicrm_financial_trxn` CHANGE `trxn_id` `trxn_id` VARCHAR(255) NULL DEFAULT NULL');
}
// CRM-12367 - add this column to single lingual sites only
$upgrade = new CRM_Upgrade_Form();
if (!$upgrade->multilingual &&
- !CRM_Core_DAO::checkFieldExists('civicrm_premiums', 'premiums_nothankyou_label')
+ !CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_premiums', 'premiums_nothankyou_label')
) {
$query = "
ALTER TABLE civicrm_premiums
}
}
// check if column contact_id is present or not in civicrm_financial_account
- $fieldExists = CRM_Core_DAO::checkFieldExists('civicrm_financial_account', 'contact_id', FALSE);
+ $fieldExists = CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_financial_account', 'contact_id', FALSE);
if (!$fieldExists) {
$query = "
ALTER TABLE civicrm_financial_account
--- /dev/null
+{* file to handle db changes in 5.5.beta1 during upgrade *}
--- /dev/null
+{* file to handle db changes in 5.6.alpha1 during upgrade *}
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Field', $id, 'is_active', $is_active);
* @param bool $is_active
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
- *
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_FieldValue', $id, 'is_active', $is_active);
* @param bool $isActive
* Value we want to set the is_active field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsActive($id, $isActive) {
return CRM_Core_DAO::setFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set', $id, 'is_active', $isActive);
* @param bool $isQuickConfig we want to set the is_quick_config field.
* Value we want to set the is_quick_config field.
*
- * @return Object
- * DAO object on success, null otherwise
+ * @return bool
+ * true if we found and updated the object, else false
*/
public static function setIsQuickConfig($id, $isQuickConfig) {
return CRM_Core_DAO::setFieldValue('CRM_Upgrade_Snapshot_V4p2_Price_DAO_Set', $id, 'is_quick_config', $isQuickConfig);
* @param array $params
* Array with keys:
* - name: string, unique symbolic name.
+ * For a naming convention, use `snake_case` or `CamelCase` to maximize
+ * portability/cleanliness. Any other punctuation or whitespace
+ * should function correctly, but it can be harder to inspect/debug.
* - type: array|string, list of acceptable cache types, in order of preference.
* - prefetch: bool, whether to prefetch all data in cache (if possible).
* @return CRM_Utils_Cache_Interface
public static function create($params = array()) {
$types = (array) $params['type'];
+ if (!empty($params['name'])) {
+ $params['name'] = CRM_Core_BAO_Cache::cleanKey($params['name']);
+ }
+
foreach ($types as $type) {
switch ($type) {
case '*memory*':
elseif (version_compare($phpVersion, CRM_Upgrade_Incremental_General::MIN_INSTALL_PHP_VER) >= 0) {
$messages[] = new CRM_Utils_Check_Message(
__FUNCTION__,
- ts('This system uses PHP version %1. This meets the minimum requirements for CiviCRM to function but is not recommended. At least PHP version %2 is recommended; the preferrred version is %3.',
+ ts('This system uses PHP version %1. This meets the minimum requirements for CiviCRM to function but is not recommended. At least PHP version %2 is recommended; the preferred version is %3.',
array(
1 => $phpVersion,
2 => CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER,
// or extend a base class. While we identify and implement a geocoding
// abstraction library (rather than continue to roll our own), we settle for
// this check.
- if (!method_exists($provider, 'format')) {
+ if (!method_exists($provider, 'format') && $provider !== FALSE) {
Civi::log()->error('Configured geocoder is invalid, must provide a format method', ['geocode_class' => $provider]);
$provider = FALSE;
}
// flush out all cache entries so we can reload new data
// a bit aggressive, but livable for now
CRM_Utils_Cache::singleton()->flush();
- if (Civi\Core\Container::isContainerBooted()) {
+
+ // Traditionally, systems running on memory-backed caches were quite
+ // zealous about destroying *all* memory-backed caches during a flush().
+ // These flushes simulate that legacy behavior. However, they should probably
+ // be removed at some point.
+ $localDrivers = ['CRM_Utils_Cache_Arraycache', 'CRM_Utils_Cache_NoCache'];
+ if (Civi\Core\Container::isContainerBooted()
+ && !in_array(get_class(CRM_Utils_Cache::singleton()), $localDrivers)) {
Civi::cache('settings')->flush();
Civi::cache('js_strings')->flush();
Civi::cache('community_messages')->flush();
define('JDEBUG', FALSE);
}
+ // Set timezone for Joomla on Cron
+ $config = JFactory::getConfig();
+ $timezone = $config->get('offset');
+ if ($timezone) {
+ date_default_timezone_set($timezone);
+ CRM_Core_Config::singleton()->userSystem->setMySQLTimeZone();
+ }
+
// CRM-14281 Joomla wasn't available during bootstrap, so hook_civicrm_config never executes.
$config = CRM_Core_Config::singleton();
CRM_Utils_Hook::config($config);
$isUpgradeMode = \CRM_Core_Config::isUpgradeMode();
- if ($isUpgradeMode && empty($this->contactId) && \CRM_Core_DAO::checkFieldExists('civicrm_domain', 'config_backend', FALSE)) {
+ if ($isUpgradeMode && empty($this->contactId) && \CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_domain', 'config_backend', FALSE)) {
$config_backend = \CRM_Core_DAO::singleValueQuery('SELECT config_backend FROM civicrm_domain WHERE id = %1',
array(1 => array($this->domainId, 'Positive')));
$oldSettings = \CRM_Upgrade_Incremental_php_FourSeven::convertBackendToSettings($this->domainId, $config_backend);
if (!isset(\Civi::$statics[__CLASS__]['upgradeMode'])) {
\Civi::$statics[__CLASS__]['upgradeMode'] = \CRM_Core_Config::isUpgradeMode();
}
- if (\Civi::$statics[__CLASS__]['upgradeMode'] && \CRM_Core_DAO::checkFieldExists('civicrm_setting', 'group_name')) {
+ if (\Civi::$statics[__CLASS__]['upgradeMode'] && \CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_setting', 'group_name')) {
$dao->group_name = 'placeholder';
}
if (\CRM_Core_Config::isUpgradeMode() && isset($trigger['upgrade_check'])) {
$uc = $trigger['upgrade_check'];
- if (!\CRM_Core_DAO::checkFieldExists($uc['table'], $uc['column'])
+ if (!\CRM_Core_BAO_SchemaHandler::checkIfFieldExists($uc['table'], $uc['column'])
) {
continue;
}
// In the past, this was a version-based check, but checkFieldExists()
// seems more robust.
if (\CRM_Core_Config::isUpgradeMode()) {
- if (!\CRM_Core_DAO::checkFieldExists($this->getTableName(),
+ if (!\CRM_Core_BAO_SchemaHandler::checkIfFieldExists($this->getTableName(),
$this->getCreatedDate())
) {
return;
'debug' => 1,
);
$result = $this->civicrm_api($entity, 'getvalue', $params);
+ if (is_array($result) && (!empty($result['is_error']) || isset($result['values']))) {
+ throw new \Exception('Invalid getvalue result' . print_r($result, TRUE));
+ }
if ($type) {
if ($type == 'integer') {
// api seems to return integers as strings
// less randomly.
\CRM_Utils_Hook::tokenValues($contactArray,
(array) $contactId,
- empty($row->context['mailingJob']) ? NULL : $row->context['mailingJob']->id,
+ empty($row->context['mailingJobId']) ? NULL : $row->context['mailingJobId'],
$messageTokens,
$row->context['controller']
);
Installing the latest developmental code requires some [special steps](http://wiki.civicrm.org/confluence/display/CRMDOC/Contributing+to+CiviCRM+using+GitHub).
-Report all issues to CiviCRM via JIRA:
-https://issues.civicrm.org
+Report all issues to CiviCRM via GitLab:
+https://lab.civicrm.org
value = fmt.decode($route.current.params[options.param]);
}
else {
- value = _.isObject(options.default) ? angular.extend({}, options.default) : options.default;
+ value = _.cloneDeep(options.default);
ignorable[options.param] = fmt.encode(options.default);
}
$parse(options.expr).assign(_scope, value);
if (!empty(substr($id, 7))) {
$returnVal = substr($id, 7);
}
- foreach ((array) $returnVal as $value) {
+ if (!is_array($returnVal)) {
+ $returnVal = explode(',', $returnVal);
+ }
+ foreach ($returnVal as $value) {
list($c, $i) = CRM_Utils_System::explode('_', $value, 2);
if ($c == 'custom' && is_numeric($i)) {
$names['custom_' . $i] = 'custom_' . $i;
$params['payment_processor_type_id']['api.required'] = 1;
$params['is_default']['api.default'] = 0;
$params['is_test']['api.default'] = 0;
+ $params['domain_id']['api.default'] = CRM_Core_Config::domainID();
}
/**
$params['class_name']['api.required'] = 1;
$params['is_active']['api.default'] = 1;
$params['is_recur']['api.default'] = FALSE;
- // FIXME bool support // $params['is_recur']['api.required'] = 1;
$params['name']['api.required'] = 1;
$params['title']['api.required'] = 1;
$params['payment_instrument_id']['api.default'] = 'Credit Card';
"require": {
"dompdf/dompdf" : "0.8.*",
"electrolinux/phpquery": "^0.9.6",
- "symfony/config": "^2.6.13 || ~3.0",
- "symfony/dependency-injection": "^2.6.13 || ~3.0",
- "symfony/event-dispatcher": "^2.6.13 || ~3.0",
- "symfony/filesystem": "^2.6.13 || ~3.0",
- "symfony/process": "^2.6.13 || ~3.0",
+ "symfony/config": "^2.8.44 || ~3.0",
+ "symfony/polyfill-iconv": "~1.0",
+ "symfony/dependency-injection": "^2.8.44 || ~3.0",
+ "symfony/event-dispatcher": "^2.8.44 || ~3.0",
+ "symfony/filesystem": "^2.8.44 || ~3.0",
+ "symfony/process": "^2.8.44 || ~3.0",
"psr/log": "~1.0.0",
- "symfony/finder": "^2.6.13 || ~3.0",
+ "symfony/finder": "^2.8.44 || ~3.0",
"tecnickcom/tcpdf" : "6.2.*",
"totten/ca-config": "~17.05",
"zetacomponents/base": "1.7.*",
{
"_readme": [
"This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "233f9c457d9e7d49a6d96c356e1035f1",
+ "content-hash": "38f5450ab72f881008f5cd10bb588b6f",
"packages": [
{
"name": "civicrm/civicrm-cxn-rpc",
"extra": {
"branch-alias": {
"dev-develop": "0.7-dev"
+ },
+ "patches_applied": {
+ "Fix Fatal error: Uncaught Dompdf Exception: No block-level parent found.": "tools/scripts/composer/patches/dompdf_no_block_level_parent_fix.patch"
}
},
"autoload": {
"pear/auth_sasl": "Install optionally via your project's composer.json"
},
"type": "library",
+ "extra": {
+ "patches_applied": {
+ "CRM-8744 Display CiviCRM Specific error message": "tools/scripts/composer/patches/net-smtp-patch.patch",
+ "Fix PHP7 Compliance": "tools/scripts/composer/patches/net-smtp-php7-patch.patch",
+ "Fix Pass by reference issues": "tools/scripts/composer/patches/net-smtp-ref-patch.patch",
+ "Fix TLS support issue in PHP5.6": "tools/scripts/composer/patches/net-smtp-tls-patch.patch"
+ }
+ },
"autoload": {
"psr-0": {
"Net": "./"
},
{
"name": "symfony/config",
- "version": "v2.6.13",
- "target-dir": "Symfony/Component/Config",
+ "version": "v2.8.44",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "0ca496cbe208fc37c4cf3415ebb3056e0963115b"
+ "reference": "06c0be4cdd8363f3ec8d592c9a4d1b981d5052af"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/0ca496cbe208fc37c4cf3415ebb3056e0963115b",
- "reference": "0ca496cbe208fc37c4cf3415ebb3056e0963115b",
+ "url": "https://api.github.com/repos/symfony/config/zipball/06c0be4cdd8363f3ec8d592c9a4d1b981d5052af",
+ "reference": "06c0be4cdd8363f3ec8d592c9a4d1b981d5052af",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
- "symfony/filesystem": "~2.3"
+ "php": ">=5.3.9",
+ "symfony/filesystem": "~2.3|~3.0.0",
+ "symfony/polyfill-ctype": "~1.8"
},
"require-dev": {
- "symfony/phpunit-bridge": "~2.7"
+ "symfony/yaml": "~2.7|~3.0.0"
+ },
+ "suggest": {
+ "symfony/yaml": "To use the yaml reference dumper"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.6-dev"
+ "dev-master": "2.8-dev"
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Config\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
- "time": "2015-07-08T05:59:48+00:00"
+ "time": "2018-07-26T11:13:39+00:00"
},
{
"name": "symfony/dependency-injection",
- "version": "v2.6.13",
- "target-dir": "Symfony/Component/DependencyInjection",
+ "version": "v2.8.44",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
- "reference": "d9fe6837d74aed11e5ee741cd6b6dfe45e0af78e"
+ "reference": "ad2446d39d11c3daaa7f147d957941a187e47357"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d9fe6837d74aed11e5ee741cd6b6dfe45e0af78e",
- "reference": "d9fe6837d74aed11e5ee741cd6b6dfe45e0af78e",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ad2446d39d11c3daaa7f147d957941a187e47357",
+ "reference": "ad2446d39d11c3daaa7f147d957941a187e47357",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=5.3.9"
},
"conflict": {
"symfony/expression-language": "<2.6"
},
"require-dev": {
- "symfony/config": "~2.2",
- "symfony/expression-language": "~2.6",
- "symfony/phpunit-bridge": "~2.7",
- "symfony/yaml": "~2.1"
+ "symfony/config": "~2.2|~3.0.0",
+ "symfony/expression-language": "~2.6|~3.0.0",
+ "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7"
},
"suggest": {
"symfony/config": "",
+ "symfony/expression-language": "For using expressions in service container configuration",
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.6-dev"
+ "dev-master": "2.8-dev"
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\DependencyInjection\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
- "time": "2015-07-22T10:08:40+00:00"
+ "time": "2018-07-26T11:13:39+00:00"
},
{
"name": "symfony/event-dispatcher",
- "version": "v2.6.13",
- "target-dir": "Symfony/Component/EventDispatcher",
+ "version": "v2.8.44",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02"
+ "reference": "84ae343f39947aa084426ed1138bb96bf94d1f12"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/672593bc4b0043a0acf91903bb75a1c82d8f2e02",
- "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/84ae343f39947aa084426ed1138bb96bf94d1f12",
+ "reference": "84ae343f39947aa084426ed1138bb96bf94d1f12",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=5.3.9"
},
"require-dev": {
"psr/log": "~1.0",
- "symfony/config": "~2.0,>=2.0.5",
- "symfony/dependency-injection": "~2.6",
- "symfony/expression-language": "~2.6",
- "symfony/phpunit-bridge": "~2.7",
- "symfony/stopwatch": "~2.3"
+ "symfony/config": "^2.0.5|~3.0.0",
+ "symfony/dependency-injection": "~2.6|~3.0.0",
+ "symfony/expression-language": "~2.6|~3.0.0",
+ "symfony/stopwatch": "~2.3|~3.0.0"
},
"suggest": {
"symfony/dependency-injection": "",
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.6-dev"
+ "dev-master": "2.8-dev"
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\EventDispatcher\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2015-05-02T15:18:45+00:00"
+ "time": "2018-07-26T09:03:18+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v2.6.13",
- "target-dir": "Symfony/Component/Filesystem",
+ "version": "v2.8.44",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "823c035b1a5c13a4924e324d016eb07e70f94735"
+ "reference": "2d6a4deccdfa2e4e9f113138b93457b2d0886c15"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/823c035b1a5c13a4924e324d016eb07e70f94735",
- "reference": "823c035b1a5c13a4924e324d016eb07e70f94735",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/2d6a4deccdfa2e4e9f113138b93457b2d0886c15",
+ "reference": "2d6a4deccdfa2e4e9f113138b93457b2d0886c15",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7"
+ "php": ">=5.3.9",
+ "symfony/polyfill-ctype": "~1.8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.6-dev"
+ "dev-master": "2.8-dev"
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Filesystem\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2015-07-08T05:59:48+00:00"
+ "time": "2018-07-26T11:13:39+00:00"
},
{
"name": "symfony/finder",
- "version": "v2.6.13",
- "target-dir": "Symfony/Component/Finder",
+ "version": "v2.8.44",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "203a10f928ae30176deeba33512999233181dd28"
+ "reference": "f0de0b51913eb2caab7dfed6413b87e14fca780e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/203a10f928ae30176deeba33512999233181dd28",
- "reference": "203a10f928ae30176deeba33512999233181dd28",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/f0de0b51913eb2caab7dfed6413b87e14fca780e",
+ "reference": "f0de0b51913eb2caab7dfed6413b87e14fca780e",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7"
+ "php": ">=5.3.9"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.6-dev"
+ "dev-master": "2.8-dev"
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Finder\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2015-07-09T16:02:48+00:00"
+ "time": "2018-07-26T11:13:39+00:00"
},
{
- "name": "symfony/process",
- "version": "v2.6.13",
- "target-dir": "Symfony/Component/Process",
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.8.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/process.git",
- "reference": "57f1e88bb5dafa449b83f9f265b11d52d517b3e9"
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/57f1e88bb5dafa449b83f9f265b11d52d517b3e9",
- "reference": "57f1e88bb5dafa449b83f9f265b11d52d517b3e9",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae",
+ "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7"
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ },
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "time": "2018-04-30T19:57:29+00:00"
+ },
+ {
+ "name": "symfony/polyfill-iconv",
+ "version": "v1.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-iconv.git",
+ "reference": "bcc0cd69185b8a5d8b4a5400c489ed3333bf9bb2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/bcc0cd69185b8a5d8b4a5400c489ed3333bf9bb2",
+ "reference": "bcc0cd69185b8a5d8b4a5400c489ed3333bf9bb2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-iconv": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.6-dev"
+ "dev-master": "1.9-dev"
}
},
"autoload": {
- "psr-0": {
- "Symfony\\Component\\Process\\": ""
+ "psr-4": {
+ "Symfony\\Polyfill\\Iconv\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
+ ],
+ "description": "Symfony polyfill for the Iconv extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "iconv",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2018-08-06T14:22:27+00:00"
+ },
+ {
+ "name": "symfony/process",
+ "version": "v2.8.44",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/process.git",
+ "reference": "cc83afdb5ac99147806b3bb65a3ff1227664f596"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/process/zipball/cc83afdb5ac99147806b3bb65a3ff1227664f596",
+ "reference": "cc83afdb5ac99147806b3bb65a3ff1227664f596",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Process\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2015-06-30T16:10:16+00:00"
+ "time": "2018-07-26T11:13:39+00:00"
},
{
"name": "tecnickcom/tcpdf",
- name : Matthias Bärnthaler
jira : baerm
+- github : baernm
+
+- github : bastienho
+ name : Bastien Ho
+
- github : bhahumanists
name : Andrew West
organization: British Humanist Association
organization: Jvillage Network
jira : dinalondon
+- name : Lizz Trudeau
+ organization: Drupal Association
+ jira : drupal_lizz
+
- github : dsnopek
name : David Snopek
organization: myDropWizard
organization: AGH Strategies
jira : hollyhanks
+- name : Hugo do Carmo
+ jira : hugo.carmo
+
- name : Anthony Colombo
organization: DreamSpace
jira : Hunabku
organization: Coop SymbioTIC
jira : mlutfy
-- name : Michal Mach
+- github : michau
+ name : Michal Mach
+ organization: Caltha
jira : mover
+- github : MikeyMJCO
+ name : Mikey O'Toole
+ organization: MJCO
+ jira : MikeyMJCO
+
- github : mmauroy
name : Matthias de Mauroy
organization: CYIM
organization: Botanical Society of America
jira : robbrandt
+- github : robfenwickuk
+ name : Robin Fenwick
+
- name : Robert Lang
jira : rjlang
- github : scardinius
name : Tomasz Pietrzkowski
- organization: We Move Europe/Caltha
+ organization: Caltha
jira : scardinius
- github : seamuslee001
return combined;
}
- function copyAttributes($source, $target, attributes) {
+ CRM.utils.copyAttributes = function ($source, $target, attributes) {
_.each(attributes, function(name) {
if ($source.attr(name) !== undefined) {
$target.attr(name, $source.attr(name));
}
});
- }
-
- /**
- * @see http://wiki.civicrm.org/confluence/display/CRMDOC/crmDatepicker
- */
- $.fn.crmDatepicker = function(options) {
- return $(this).each(function() {
- if ($(this).is('.crm-form-date-wrapper .crm-hidden-date')) {
- // Already initialized - destroy
- $(this)
- .off('.crmDatepicker')
- .css('display', '')
- .removeClass('crm-hidden-date')
- .siblings().remove();
- $(this).unwrap();
- }
- if (options === 'destroy') {
- return;
- }
- var
- $dataField = $(this).wrap('<span class="crm-form-date-wrapper" />'),
- settings = _.cloneDeep(options || {}),
- $dateField = $(),
- $timeField = $(),
- $clearLink = $(),
- hasDatepicker = settings.date !== false && settings.date !== 'yy',
- type = hasDatepicker ? 'text' : 'number';
-
- if (settings.allowClear !== undefined ? settings.allowClear : !$dataField.is('.required, [required]')) {
- $clearLink = $('<a class="crm-hover-button crm-clear-link" title="'+ _.escape(ts('Clear')) +'"><i class="crm-i fa-times"></i></a>')
- .insertAfter($dataField);
- }
- if (settings.time !== false) {
- $timeField = $('<input>').insertAfter($dataField);
- copyAttributes($dataField, $timeField, ['class', 'disabled']);
- $timeField
- .addClass('crm-form-text crm-form-time')
- .attr('placeholder', $dataField.attr('time-placeholder') === undefined ? ts('Time') : $dataField.attr('time-placeholder'))
- .attr('aria-label', $dataField.attr('time-placeholder') === undefined ? ts('Time') : $dataField.attr('time-placeholder'))
- .change(updateDataField)
- .timeEntry({
- spinnerImage: '',
- show24Hours: settings.time === true || settings.time === undefined ? CRM.config.timeIs24Hr : settings.time == '24'
- });
- }
- if (settings.date !== false) {
- // Render "number" field for year-only format, calendar popup for all other formats
- $dateField = $('<input type="' + type + '">').insertAfter($dataField);
- copyAttributes($dataField, $dateField, ['placeholder', 'style', 'class', 'disabled', 'aria-label']);
- $dateField.addClass('crm-form-' + type);
- if (hasDatepicker) {
- settings.minDate = settings.minDate ? CRM.utils.makeDate(settings.minDate) : null;
- settings.maxDate = settings.maxDate ? CRM.utils.makeDate(settings.maxDate) : null;
- settings.dateFormat = typeof settings.date === 'string' ? settings.date : CRM.config.dateInputFormat;
- settings.changeMonth = _.includes(settings.dateFormat, 'm');
- settings.changeYear = _.includes(settings.dateFormat, 'y');
- if (!settings.yearRange && settings.minDate !== null && settings.maxDate !== null) {
- settings.yearRange = '' + CRM.utils.formatDate(settings.minDate, 'yy') + ':' + CRM.utils.formatDate(settings.maxDate, 'yy');
- }
- $dateField.addClass('crm-form-date').datepicker(settings);
- } else {
- $dateField.attr('min', settings.minDate ? CRM.utils.formatDate(settings.minDate, 'yy') : '1000');
- $dateField.attr('max', settings.maxDate ? CRM.utils.formatDate(settings.maxDate, 'yy') : '4000');
- }
- $dateField.change(updateDataField);
- }
- // Rudimentary validation. TODO: Roll into use of jQUery validate and ui.datepicker.validation
- function isValidDate() {
- // FIXME: parseDate doesn't work with incomplete date formats; skip validation if no month, day or year in format
- var lowerFormat = settings.dateFormat.toLowerCase();
- if (lowerFormat.indexOf('y') < 0 || lowerFormat.indexOf('m') < 0 || !dateHasDay()) {
- return true;
- }
- try {
- $.datepicker.parseDate(settings.dateFormat, $dateField.val());
- return true;
- } catch (e) {
- return false;
- }
- }
-
- /**
- * Does the date format contain the day.
- *
- * @returns {boolean}
- */
- function dateHasDay() {
- var lowerFormat = settings.dateFormat.toLowerCase();
- if (lowerFormat.indexOf('d') < 0) {
- return false;
- }
- return true;
- }
- function updateInputFields(e, context) {
- var val = $dataField.val(),
- time = null;
- if (context !== 'userInput' && context !== 'crmClear') {
- if (hasDatepicker) {
- $dateField.datepicker('setDate', _.includes(val, '-') ? $.datepicker.parseDate('yy-mm-dd', val) : null);
- } else if ($dateField.length) {
- $dateField.val(val.slice(0, 4));
- }
- if ($timeField.length) {
- if (val.length === 8) {
- time = val;
- } else if (val.length === 19) {
- time = val.split(' ')[1];
- }
- $timeField.timeEntry('setTime', time);
- }
- }
- $clearLink.css('visibility', val ? 'visible' : 'hidden');
- }
- function updateDataField(e, context) {
- // The crmClear event wipes all the field values anyway, so no need to respond
- if (context !== 'crmClear') {
- var val = '';
- if ($dateField.val()) {
- if (hasDatepicker && isValidDate() && dateHasDay()) {
- val = $.datepicker.formatDate('yy-mm-dd', $dateField.datepicker('getDate'));
- $dateField.removeClass('crm-error');
- } else if (!hasDatepicker) {
- val = $dateField.val() + '-01-01';
- }
- else if (!dateHasDay()) {
- // This would be a Year-month date (yyyy-mm)
- // it could be argued it should not use a datepicker....
- val = $dateField.val() + '-01';
- } else {
- $dateField.addClass('crm-error');
- }
- }
- if ($timeField.val()) {
- val += (val ? ' ' : '') + $timeField.timeEntry('getTime').toTimeString().substr(0, 8);
- }
- $dataField.val(val).trigger('change', ['userInput']);
- }
- }
- $dataField.hide().addClass('crm-hidden-date').on('change.crmDatepicker', updateInputFields);
- updateInputFields();
- });
};
CRM.utils.formatSelect2Result = function (row) {
--- /dev/null
+(function($, CRM, _) {
+ "use strict";
+
+ /**
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/crmDatepicker
+ */
+ $.fn.crmDatepicker = function(options) {
+ return $(this).each(function() {
+ if ($(this).is('.crm-form-date-wrapper .crm-hidden-date')) {
+ // Already initialized - destroy
+ $(this)
+ .off('.crmDatepicker')
+ .css('display', '')
+ .removeClass('crm-hidden-date')
+ .siblings().remove();
+ $(this).unwrap();
+ }
+ if (options === 'destroy') {
+ return;
+ }
+ var
+ $dataField = $(this).wrap('<span class="crm-form-date-wrapper" />'),
+ settings = CRM._.cloneDeep(options || {}),
+ $dateField = $(),
+ $timeField = $(),
+ $clearLink = $(),
+ hasDatepicker = settings.date !== false && settings.date !== 'yy',
+ type = hasDatepicker ? 'text' : 'number';
+
+ if (settings.allowClear !== undefined ? settings.allowClear : !$dataField.is('.required, [required]')) {
+ $clearLink = $('<a class="crm-hover-button crm-clear-link" title="'+ CRM._.escape(ts('Clear')) +'"><i class="crm-i fa-times"></i></a>')
+ .insertAfter($dataField);
+ }
+ if (settings.time !== false) {
+ $timeField = $('<input>').insertAfter($dataField);
+ CRM.utils.copyAttributes($dataField, $timeField, ['class', 'disabled']);
+ $timeField
+ .addClass('crm-form-text crm-form-time')
+ .attr('placeholder', $dataField.attr('time-placeholder') === undefined ? ts('Time') : $dataField.attr('time-placeholder'))
+ .attr('aria-label', $dataField.attr('time-placeholder') === undefined ? ts('Time') : $dataField.attr('time-placeholder'))
+ .change(updateDataField)
+ .timeEntry({
+ spinnerImage: '',
+ show24Hours: settings.time === true || settings.time === undefined ? CRM.config.timeIs24Hr : settings.time == '24'
+ });
+ }
+ if (settings.date !== false) {
+ // Render "number" field for year-only format, calendar popup for all other formats
+ $dateField = $('<input type="' + type + '">').insertAfter($dataField);
+ CRM.utils.copyAttributes($dataField, $dateField, ['placeholder', 'style', 'class', 'disabled', 'aria-label']);
+ $dateField.addClass('crm-form-' + type);
+ if (hasDatepicker) {
+ settings.minDate = settings.minDate ? CRM.utils.makeDate(settings.minDate) : null;
+ settings.maxDate = settings.maxDate ? CRM.utils.makeDate(settings.maxDate) : null;
+ settings.dateFormat = typeof settings.date === 'string' ? settings.date : CRM.config.dateInputFormat;
+ settings.changeMonth = CRM._.includes(settings.dateFormat, 'm');
+ settings.changeYear = CRM._.includes(settings.dateFormat, 'y');
+ if (!settings.yearRange && settings.minDate !== null && settings.maxDate !== null) {
+ settings.yearRange = '' + CRM.utils.formatDate(settings.minDate, 'yy') + ':' + CRM.utils.formatDate(settings.maxDate, 'yy');
+ }
+ $dateField.addClass('crm-form-date').datepicker(settings);
+ } else {
+ $dateField.attr('min', settings.minDate ? CRM.utils.formatDate(settings.minDate, 'yy') : '1000');
+ $dateField.attr('max', settings.maxDate ? CRM.utils.formatDate(settings.maxDate, 'yy') : '4000');
+ }
+ $dateField.change(updateDataField);
+ }
+ // Rudimentary validation. TODO: Roll into use of jQUery validate and ui.datepicker.validation
+ function isValidDate() {
+ // FIXME: parseDate doesn't work with incomplete date formats; skip validation if no month, day or year in format
+ var lowerFormat = settings.dateFormat.toLowerCase();
+ if (lowerFormat.indexOf('y') < 0 || lowerFormat.indexOf('m') < 0 || !dateHasDay()) {
+ return true;
+ }
+ try {
+ $.datepicker.parseDate(settings.dateFormat, $dateField.val());
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+
+ /**
+ * Does the date format contain the day.
+ *
+ * @returns {boolean}
+ */
+ function dateHasDay() {
+ var lowerFormat = settings.dateFormat.toLowerCase();
+ if (lowerFormat.indexOf('d') < 0) {
+ return false;
+ }
+ return true;
+ }
+ function updateInputFields(e, context) {
+ var val = $dataField.val(),
+ time = null;
+ if (context !== 'userInput' && context !== 'crmClear') {
+ if (hasDatepicker) {
+ $dateField.datepicker('setDate', CRM._.includes(val, '-') ? $.datepicker.parseDate('yy-mm-dd', val) : null);
+ } else if ($dateField.length) {
+ $dateField.val(val.slice(0, 4));
+ }
+ if ($timeField.length) {
+ if (val.length === 8) {
+ time = val;
+ } else if (val.length === 19) {
+ time = val.split(' ')[1];
+ }
+ $timeField.timeEntry('setTime', time);
+ }
+ }
+ $clearLink.css('visibility', val ? 'visible' : 'hidden');
+ }
+ function updateDataField(e, context) {
+ // The crmClear event wipes all the field values anyway, so no need to respond
+ if (context !== 'crmClear') {
+ var val = '';
+ if ($dateField.val()) {
+ if (hasDatepicker && isValidDate() && dateHasDay()) {
+ val = $.datepicker.formatDate('yy-mm-dd', $dateField.datepicker('getDate'));
+ $dateField.removeClass('crm-error');
+ } else if (!hasDatepicker) {
+ val = $dateField.val() + '-01-01';
+ }
+ else if (!dateHasDay()) {
+ // This would be a Year-month date (yyyy-mm)
+ // it could be argued it should not use a datepicker....
+ val = $dateField.val() + '-01';
+ } else {
+ $dateField.addClass('crm-error');
+ }
+ }
+ if ($timeField.val()) {
+ val += (val ? ' ' : '') + $timeField.timeEntry('getTime').toTimeString().substr(0, 8);
+ }
+ $dataField.val(val).trigger('change', ['userInput']);
+ }
+ }
+ $dataField.hide().addClass('crm-hidden-date').on('change.crmDatepicker', updateInputFields);
+ updateInputFields();
+ });
+ };
+})(jQuery, CRM, CRM._);
'bower_components/jquery-validation/dist/jquery.validate.min.js',
'packages/jquery/plugins/jquery.timeentry.js',
'js/Common.js',
+ 'js/crm.datepicker.js',
'bower_components/angular/angular.js',
'js/crm.angular.js',
angularTempFile,
* https://github.com/civicrm/civicrm-joomla
* https://github.com/civicrm/civicrm-wordpress
+## CiviCRM 5.4.0
+
+Released August 1, 2018
+
+- **[Synopsis](release-notes/5.4.0.md#synopsis)**
+- **[Features](release-notes/5.4.0.md#features)**
+- **[Bugs resolved](release-notes/5.4.0.md#bugs)**
+- **[Miscellany](release-notes/5.4.0.md#misc)**
+- **[Credits](release-notes/5.4.0.md#credits)**
+- **[Feedback](release-notes/5.4.0.md#feedback)**
+
+## CiviCRM 5.3.2
+
+Released July 25, 2018
+
+- **[Synopsis](release-notes/5.3.2.md#synopsis)**
+- **[Bugs resolved](release-notes/5.3.2.md#bugs)**
+- **[Credits](release-notes/5.3.2.md#credits)**
+- **[Feedback](release-notes/5.3.2.md#feedback)**
+
+## CiviCRM 5.3.1
+
+Released July 18, 2018
+
+- **[Security advisories](release-notes/5.3.1.md#security)**
+- **[Features](release-notes/5.3.1.md#features)**
+- **[Bugs resolved](release-notes/5.3.1.md#bugs)**
+- **[Miscellany](release-notes/5.3.1.md#misc)**
+- **[Credits](release-notes/5.3.1.md#credits)**
+
## CiviCRM 5.3.0
Released July 3, 2018
--- /dev/null
+# CiviCRM 5.4.0
+
+Released August 1, 2018
+
+- **[Synopsis](#synopsis)**
+- **[Features](#features)**
+- **[Bugs resolved](#bugs)**
+- **[Miscellany](#misc)**
+- **[Credits](#credits)**
+- **[Feedback](#feedback)**
+
+## <a name="synopsis"></a>Synopsis
+
+| *Does this version...?* | |
+|:--------------------------------------------------------------- |:-------:|
+| Fix security vulnerabilities? | no |
+| **Change the database schema?** | **yes** |
+| **Alter the API?** | **yes** |
+| **Require attention to configuration options?** | **yes** |
+| **Fix problems installing or upgrading to a previous version?** | **yes** |
+| **Introduce features?** | **yes** |
+| **Fix bugs?** | **yes** |
+
+## <a name="features"></a>Features
+
+### Core CiviCRM
+
+- **[CRM-20430](https://issues.civicrm.org/jira/browse/CRM-20430) A permission
+ 'save Report Criteria'
+ ([12107](https://github.com/civicrm/civicrm-core/pull/12107))**
+
+ Permission to edit the criteria for saved reports is now separate from the
+ permission to access and preview modifications of report criteria. This will
+ prevent non-privileged users from modifying the criteria of an organization's
+ standard reports. However when upgrading, site administrators will need to
+ grant the Save Report Criteria permission to roles that need that capability.
+
+- **[dev/core#174](https://lab.civicrm.org/dev/core/issues/174) Consistently use
+ swappable cache interfaces
+ ([12321](https://github.com/civicrm/civicrm-core/pull/12321),
+ [12322](https://github.com/civicrm/civicrm-core/pull/12322),
+ [12323](https://github.com/civicrm/civicrm-core/pull/12323),
+ [12330](https://github.com/civicrm/civicrm-core/pull/12330),
+ [12331](https://github.com/civicrm/civicrm-core/pull/12331),
+ [12336](https://github.com/civicrm/civicrm-core/pull/12336),
+ [12342](https://github.com/civicrm/civicrm-core/pull/12342),
+ [12348](https://github.com/civicrm/civicrm-core/pull/12348),
+ [12354](https://github.com/civicrm/civicrm-core/pull/12354),
+ [12362](https://github.com/civicrm/civicrm-core/pull/12362),
+ [12368](https://github.com/civicrm/civicrm-core/pull/12368),
+ [12376](https://github.com/civicrm/civicrm-core/pull/12376),
+ [12378](https://github.com/civicrm/civicrm-core/pull/12378),
+ [12379](https://github.com/civicrm/civicrm-core/pull/12379),
+ [12380](https://github.com/civicrm/civicrm-core/pull/12380),
+ [12381](https://github.com/civicrm/civicrm-core/pull/12381),
+ [12389](https://github.com/civicrm/civicrm-core/pull/12389), and
+ [215](https://github.com/civicrm/civicrm-packages/pull/215))**
+
+ Sites using Redis or Memcache for caches and sessions will now use those
+ facilities exclusively rather than retaining the `civicrm_cache` table as
+ a backstop. This improves performance for these sites, especially those
+ using multiple MySQL servers.
+
+ As a precaution, Redis or Memcache administrators with very active sites
+ may wish to double-check that they have ample capacity for their caches and
+ sessions.
+
+ For developers, the `CRM_Utils_Cache` APIs now support expiration/TTL
+ times and [PSR-16 CacheInterface](https://www.php-fig.org/psr/psr-16/).
+ The Civi implementation is slightly more permissive than the PSR-16
+ specification; for full compliance, enable `CIVICRM_PSR16_STRICT`.
+
+- **[CRM-21574](https://issues.civicrm.org/jira/browse/CRM-21574) Allow to
+ disable sending of email from source contact for tell a friend on pcp
+ ([12355](https://github.com/civicrm/civicrm-core/pull/12355)) (preliminary
+ work)**
+
+ Emails from the "tell a friend" feature are sent as if they are from the
+ donor's address. This can cause delivery failures as the site may not be a
+ valid source for the donor's email domain. Changes here are preliminary
+ cleanup.
+
+- **[dev/core#32](https://lab.civicrm.org/dev/core/issues/32) Add option to
+ disable cancel button on a profile form
+ ([11883](https://github.com/civicrm/civicrm-core/pull/11883))**
+
+ The Cancel button is now optional on profile forms.
+
+- **[CRM-21392](https://issues.civicrm.org/jira/browse/CRM-21392) Allow viewing
+ groups/smartgroups as as other entities (eg. memberships, events)
+ ([11241](https://github.com/civicrm/civicrm-core/pull/11241))**
+
+ The Find Groups page now has a similar "View Results As" feature as the
+ Advanced Search: you can choose to view memberships, events, activities, etc.
+ of group subscribers rather than the contacts themselves.
+
+- **[CRM-21622](https://issues.civicrm.org/jira/browse/CRM-21622) Make the Add
+ Parent Groups on Group Settings be a multiselect
+ ([11481](https://github.com/civicrm/civicrm-core/pull/11481))**
+
+ The New Group form now allows you to set multiple parent groups for a single
+ group.
+
+- **[CRM-21460](https://issues.civicrm.org/jira/browse/CRM-21460) Programmatic
+ access to job execution status
+ ([11337](https://github.com/civicrm/civicrm-core/pull/11337))**
+
+ Extension developers can implement two new hooks, `hook_civicrm_preJob` and
+ `hook_civicrm_postJob`, which are invoked before and after executing a
+ scheduled job.
+
+- **Change default for `CIVICRM_CONTAINER_CACHE` to simplify admin/developer
+ experience ([12426](https://github.com/civicrm/civicrm-core/pull/12426))**
+
+- **[dev/core#223](https://lab.civicrm.org/dev/core/issues/223) Expose prefix
+ and suffix in reports
+ ([12394](https://github.com/civicrm/civicrm-core/pull/12394))**
+
+ Individuals' prefix and suffix fields are now available as columns and filters
+ among the contact fields in most reports.
+
+- **[dev/core#101](https://lab.civicrm.org/dev/core/issues/101) Allow further
+ customization of search form in hooks
+ ([12078](https://github.com/civicrm/civicrm-core/pull/12078))**
+
+ Fields are no longer explicitly included in the search form template since
+ that makes it hard to add or remove fields. Instead, the fields are listed in
+ template variables, and the template iterates over the list to render the
+ field elements.
+
+- **[dev/core#183](https://lab.civicrm.org/dev/core/issues/183) Temporary tables
+ should follow consistent naming convention
+ ([12311](https://github.com/civicrm/civicrm-core/pull/12311)) (partially
+ completed)**
+
+ This moves towards naming temporary tables--both true temporary tables in
+ MySQL and regular tables created for temporary use--in a consistent manner in
+ order to help database administrators employ replication policies based upon
+ table names.
+
+- **[dev/core#144](https://lab.civicrm.org/dev/core/issues/144)
+ `getCustomFieldID` switch to API, add caching, add full string return option
+ ([12218](https://github.com/civicrm/civicrm-core/pull/12218) and
+ [12283](https://github.com/civicrm/civicrm-core/pull/12283))**
+
+ The function to retrieve a custom field ID now relies upon APIv3 rather than
+ an *ad hoc* SQL query. It also contains an option to return the ID preceded
+ by `custom_`. Finally, the function caches the result and attempts to return
+ the cached value rather than looking it up each time.
+
+- **[dev/core#47](https://lab.civicrm.org/dev/core/issues/47) Add "clone"
+ functionality to scheduled jobs
+ ([11945](https://github.com/civicrm/civicrm-core/pull/11945))**
+
+ Scheduled jobs can now be copied, including their parameters, both from the
+ Scheduled Jobs page and through a new `Job.clone` API method.
+
+### CiviCase
+
+- **[dev/core#107](https://lab.civicrm.org/dev/core/issues/107) After creating a
+ new case, the assignee for each activity must be selected manually
+ ([11998](https://github.com/civicrm/civicrm-core/pull/11998))**
+
+ You can now select the default assignee for each activity in the standard
+ timeline for a case type. This may be defined according to a relationship
+ with the client, a single specific contact, or the contact who created the
+ case.
+
+- **CiviCase, added reference of activities from different timelines.
+ ([12236](https://github.com/civicrm/civicrm-core/pull/12236))**
+
+ From an activity on a case timeline, you can now reference any activity
+ available to the case--not just those on that case timeline.
+
+### CiviContribute
+
+- **Add support for hidden fields in general (and 'token' specifically) on the
+ payment form. ([12332](https://github.com/civicrm/civicrm-core/pull/12332)
+ and [12391](https://github.com/civicrm/civicrm-core/pull/12391))**
+
+ A new authorization token field is added to the payment form to support
+ token-based payment processors.
+
+- **[CRM-21808](https://issues.civicrm.org/jira/browse/CRM-21808) Install custom
+ group for Contribution or ContributioRecur subtypes based on XML file
+ ([11726](https://github.com/civicrm/civicrm-core/pull/11726))**
+
+ Extensions created custom data sets for contributions can now specify the
+ custom data to apply only to a single financial type.
+
+- **(dev/core/50) and
+ [dev/core#195](https://lab.civicrm.org/dev/core/issues/195) Add Separate
+ Sub-tabs for Contributions and Recurring Contributions
+ ([11956](https://github.com/civicrm/civicrm-core/pull/11956) and
+ [12345](https://github.com/civicrm/civicrm-core/pull/12345))**
+
+ The Contributions tab on a contact now contains two sub-tabs--one for single
+ contributions, and the other for recurring contribution series--instead of
+ displaying one after the other.
+
+- **[dev/core#96](https://lab.civicrm.org/dev/core/issues/96) Expose source
+ column in booking report
+ ([12374](https://github.com/civicrm/civicrm-core/pull/12374))**
+
+ The contribution Source field is now available as a column and filter on the
+ Bookkeeping Transactions report.
+
+- **Use html5 color input for contribution page widget
+ ([12339](https://github.com/civicrm/civicrm-core/pull/12339))**
+
+### CiviMail
+
+- **[dev/mail#1](https://lab.civicrm.org/dev/mail/issues/1) Add pause/resume
+ functionality to civicrm bulk mailing.
+ ([11803](https://github.com/civicrm/civicrm-core/pull/11803) and
+ [12284](https://github.com/civicrm/civicrm-core/pull/12284))**
+
+ A CiviMail mailing that is scheduled or in progress can now be paused in order
+ to allow an urgent message to go out first.
+
+- **Add in bootstrap button classes to CiviMail interface
+ ([12013](https://github.com/civicrm/civicrm-core/pull/12013) and
+ [12338](https://github.com/civicrm/civicrm-core/pull/12338))**
+
+ This allows the interfaces to be themed more easily by Bootstrap-based themes.
+
+## <a name="bugs"></a>Bugs resolved
+
+### Core CiviCRM
+
+- **[dev/core#222](https://lab.civicrm.org/dev/core/issues/222) Importing
+ contacts with dedupe rule does not use the rule
+ ([12393](https://github.com/civicrm/civicrm-core/pull/12393))**
+
+- **[dev/core#284](https://lab.civicrm.org/dev/core/issues/284) Aggressive cache
+ clearing significantly increases test time
+ ([12590](https://github.com/civicrm/civicrm-core/pull/12590))**
+
+ Settings, compiled Javascript, extension, and other caches are now only
+ flushed along with the `default` CiviCRM cache if an external cache like Redis or
+ Memcache is in use. (This reproduces the `5.3` behavior.)
+
+- **[dev/core#279](https://lab.civicrm.org/dev/core/issues/279) When Merging two
+ contacts, Flip between original and duplicate link not working in WordPress
+ ([12568](https://github.com/civicrm/civicrm-core/pull/12568))**
+
+- **Handle 'Check for Matching Contact(s)' button with ajax
+ ([12552](https://github.com/civicrm/civicrm-core/pull/12552))**
+
+ This resolves a bug where the "Check for Matching Contact(s)" button would not
+ work if AJAX Deduping is enabled.
+
+- **[dev/core#131](https://lab.civicrm.org/dev/core/issues/131) Add in missing
+ UK shire Monmouthshire
+ ([12538](https://github.com/civicrm/civicrm-core/pull/12538)) (follow-up on
+ previous work)**
+
+ Many individual sites had manually added the county of Monmouthshire in Wales
+ to the `civicrm_state_province` table, and upgrading to 5.3.0, which added the
+ missing record, would cause them a database error.
+
+- **[dev/core#258](https://lab.civicrm.org/dev/core/issues/258) Possible
+ unreleased regression - message template update altered customised template
+ ([12492](https://github.com/civicrm/civicrm-core/pull/12492))**
+
+- **[dev/core#249](https://lab.civicrm.org/dev/core/issues/249) Contact Export
+ fails in 5.4 when trying to export using the All radio button
+ ([12447](https://github.com/civicrm/civicrm-core/pull/12447))**
+
+- **[dev/core#234](https://lab.civicrm.org/dev/core/issues/234) Upgrade Steps in
+ 5.3.alpha1 may not have been run
+ ([12419](https://github.com/civicrm/civicrm-core/pull/12419),
+ [12420](https://github.com/civicrm/civicrm-core/pull/12420), and
+ [12425](https://github.com/civicrm/civicrm-core/pull/12425))**
+
+- **[dev/core#155](https://lab.civicrm.org/dev/core/issues/155) Improvements and
+ bugfixes to Option Groups UI
+ ([12233](https://github.com/civicrm/civicrm-core/pull/12233) and
+ [12411](https://github.com/civicrm/civicrm-core/pull/12411))**
+
+ The Option Groups page now displays whether each option group is reserved or
+ enabled. In addition, sites using sample data no longer have the sample
+ custom fields reserved.
+
+- **[CRM-20184](https://issues.civicrm.org/jira/browse/CRM-20184) Some System
+ Workflow templates still miss {contact.email_greeting}
+ ([12296](https://github.com/civicrm/civicrm-core/pull/12296))**
+
+ This makes receipt templates more consistent in using the contact's email
+ greeting when sent to individuals.
+
+- **[dev/core#41](https://lab.civicrm.org/dev/core/issues/41) Search Builder:
+ Not empty with date or integer custom fields gives a sql warning
+ ([12351](https://github.com/civicrm/civicrm-core/pull/12351) and
+ [12363](https://github.com/civicrm/civicrm-core/pull/12363))**
+
+- **Make all form tasks inherit from `CRM_Core_Form_Task`
+ ([12318](https://github.com/civicrm/civicrm-core/pull/12318))**
+
+ This addresses some export problems caused by tasks lacking certain properties
+ because their classes did not extend `CRM_Core_Form_Task`.
+
+- **[dev/core#178](https://lab.civicrm.org/dev/core/issues/178) Redis driver -
+ Error messages are invisible
+ ([12303](https://github.com/civicrm/civicrm-core/pull/12303))**
+
+ The log now contains error messages passed from Redis.
+
+- **[dev/core#180](https://lab.civicrm.org/dev/core/issues/180) Deleting custom
+ values and custom_hook parameter `$entity_id` empty
+ ([12309](https://github.com/civicrm/civicrm-core/pull/12309))**
+
+ The ID of the affected entity is now passed to `hook_civicrm_custom` when a
+ value is deleted from a custom field.
+
+- **Fix access to scheduled reminders for admins without event access
+ ([11733](https://github.com/civicrm/civicrm-core/pull/11733))**
+
+ Users with Administer CiviCRM permission but lacking Manage Events permission
+ would get an error when trying to create a non-event scheduled reminder.
+
+- **Only treat a request as a get request (and hence use GET) if it starts with
+ get ([12308](https://github.com/civicrm/civicrm-core/pull/12308))**
+
+- **[dev/core#179](https://lab.civicrm.org/dev/core/issues/179) Redis driver -
+ Allow anonymous connections
+ ([12304](https://github.com/civicrm/civicrm-core/pull/12304))**
+
+ Redis no longer attempts to authenticate when no password is set, such as on
+ local development environments.
+
+- **[dev/core#177](https://lab.civicrm.org/dev/core/issues/177) Redis driver -
+ Reports incorrect value for cache-miss
+ ([12302](https://github.com/civicrm/civicrm-core/pull/12302))**
+
+ When a cache key is undefined, Redis now returns `NULL` rather than `FALSE`.
+
+- **[dev/core#175](https://lab.civicrm.org/dev/core/issues/175) Smart group
+ involving relationship type filter display incorrect results.
+ ([12301](https://github.com/civicrm/civicrm-core/pull/12301))**
+
+- **Make Send SMS permission independent of Edit Contact permission
+ ([12067](https://github.com/civicrm/civicrm-core/pull/12067))**
+
+ You no longer need the permission to edit a contact (in addition to the Send
+ SMS permission) to send the contact a SMS message.
+
+- **[dev/core#134](https://lab.civicrm.org/dev/core/issues/134) Search Builder
+ broken filter for Source Contact ID
+ ([12181](https://github.com/civicrm/civicrm-core/pull/12181))**
+
+- **[dev/core#140](https://lab.civicrm.org/dev/core/issues/140) add missing
+ pseudoconstant for `option_group_id` in CustomField.xml
+ ([12195](https://github.com/civicrm/civicrm-core/pull/12195))**
+
+ Extensions creating custom fields can now refer to option groups by name
+ rather than ID.
+
+- **[dev/accessiblity#3](https://lab.civicrm.org/dev/accessibility/issues/3) Add
+ aria-label (and label?) to form elements missing them
+ ([12209](https://github.com/civicrm/civicrm-core/pull/12209) and
+ [213](https://github.com/civicrm/civicrm-packages/pull/213)) (partial work)**
+
+ Besides adding `aria-label` attributes to sub-elements of the Quickform
+ date field, event info pages no longer wrap basic information labels in
+ `<label>` tags.
+
+- **[CRM-20711](https://issues.civicrm.org/jira/browse/CRM-20711) Error - DB
+ Constraint Violation - GroupContact, get API
+ ([12408](https://github.com/civicrm/civicrm-core/pull/12408))**
+
+ This adds the `location_id` field to the `civicrm_group_contact` table on
+ older sites that lack it.
+
+- **[dev/core#152](https://lab.civicrm.org/dev/core/issues/152) -
+ AdvMulti-Select cleanup
+ ([531](https://github.com/civicrm/civicrm-drupal/pull/531)) (follow-up work)**
+
+ This removes a couple of references to the now-removed "Advanced Multi-select"
+ custom field type
+
+- **Upgrade Mime_mail to fix issues with PHP7.2
+ ([205](https://github.com/civicrm/civicrm-packages/pull/205))**
+
+- **Apply fixes to have DB package support PHP7.2
+ ([207](https://github.com/civicrm/civicrm-packages/pull/207))**
+
+- **[dev/core#117](https://lab.civicrm.org/dev/core/issues/117) Remove usage of
+ `each()` This is deprecated in php7.2
+ ([211](https://github.com/civicrm/civicrm-packages/pull/211)) (follow-up
+ work)**
+
+- **Declare Subparts as array in mimePart to support PHP7.2
+ ([210](https://github.com/civicrm/civicrm-packages/pull/210))**
+
+- **[CRM-19798](https://issues.civicrm.org/jira/browse/CRM-19798) Memory leak in
+ API3 EntityTag get operations
+ ([12276](https://github.com/civicrm/civicrm-core/pull/12276))**
+
+### CiviCase
+
+- **Fix regression on case export from recent export fix
+ ([12588](https://github.com/civicrm/civicrm-core/pull/12588))**
+
+ This resolves undefined property PHP notices when exporting cases.
+
+- **[dev/core#24](https://lab.civicrm.org/dev/core/issues/24) Passing an array
+ for contact_id/client_id to Case.Create API when updating an existing case
+ causes case to be "reassigned"
+ ([11830](https://github.com/civicrm/civicrm-core/pull/11830))**
+
+- **[CRM-21815](https://issues.civicrm.org/jira/browse/CRM-21815) On re-opening
+ a civicase - Case Coordinator (and other roles) are not reinstated
+ ([11736](https://github.com/civicrm/civicrm-core/pull/11736))**
+
+- **[dev/core#165](https://lab.civicrm.org/dev/core/issues/165) Bad link in
+ civicrm/case/activity/view breadcrumb
+ ([12279](https://github.com/civicrm/civicrm-core/pull/12279))**
+
+### CiviContribute
+
+- **[CRM-21637](https://issues.civicrm.org/jira/browse/CRM-21637) Search
+ Criteria for Card Type ID and Card Number not respected in Batch
+ ([11495](https://github.com/civicrm/civicrm-core/pull/11495))**
+
+ The card type and card number filters for financial transactions in the
+ accounting batch interface now work as expected.
+
+- **[CRM-21854](https://issues.civicrm.org/jira/browse/CRM-21854) Contribution
+ start date and end dates are not respected
+ ([11881](https://github.com/civicrm/civicrm-core/pull/11881) and
+ [12504](https://github.com/civicrm/civicrm-core/pull/12504))**
+
+- **[dev/core#264](https://lab.civicrm.org/dev/core/issues/264) Fatal Error on
+ editing Financial Transaction
+ ([12502](https://github.com/civicrm/civicrm-core/pull/12502))**
+
+- **[dev/core#220](https://lab.civicrm.org/dev/core/issues/220) State
+ province/country doesn't show properly in the report
+ ([12390](https://github.com/civicrm/civicrm-core/pull/12390))**
+
+ This resolves a bug in the Contribution History by Relationship report where
+ strange values would appear for the State/Province and Country fields.
+
+- **[dev/core#202](https://lab.civicrm.org/dev/core/issues/202) Empty row under
+ currency drop down
+ ([12356](https://github.com/civicrm/civicrm-core/pull/12356))**
+
+ A warning now appears when a site has a disabled currency that is set as
+ default.
+
+- **[dev/core#88](https://lab.civicrm.org/dev/core/issues/88) Make sure
+ `financial_type_id` is set when a contribution is created
+ ([11907](https://github.com/civicrm/civicrm-core/pull/11907))**
+
+ This resolves a bug where the financial type would not be set on a one-time
+ contribution made through a contribution page.
+
+- **[dev/core#170](https://lab.civicrm.org/dev/core/issues/170) contribution
+ detail report errors when soft credits column is exposed
+ ([12281](https://github.com/civicrm/civicrm-core/pull/12281) and
+ [12282](https://github.com/civicrm/civicrm-core/pull/12282))**
+
+- **Fix e-notice, remove legacy code pattern
+ ([12298](https://github.com/civicrm/civicrm-core/pull/12298))**
+
+ This resolves a PHP notice when printing contribution receipts in bulk.
+
+- **[dev/core#56](https://lab.civicrm.org/dev/core/issues/56) Cancel Recurring
+ Contribution activity should have a source record id
+ ([11964](https://github.com/civicrm/civicrm-core/pull/11964))**
+
+ The activity created when cancelling a recurring contribution now has the
+ recurring contribution ID as the `source_record_id`.
+
+- **[dev/financial#14](https://lab.civicrm.org/dev/financial/issues/14) PayPal
+ Express recurring payment causes warning messages
+ ([12091](https://github.com/civicrm/civicrm-core/pull/12091))**
+
+- **[CRM-20697](https://issues.civicrm.org/jira/browse/CRM-20697) Online pay now
+ anomalies (contribution transfer to new contact)
+ ([11578](https://github.com/civicrm/civicrm-core/pull/11578))**
+
+ The Pay Now form now uses contact ID and checksum to validate the
+ contribution's contact to avoid creating new contacts when an anonymous
+ visitor fulfills a pending contribution.
+
+### CiviEvent
+
+- **[dev/core#272](https://lab.civicrm.org/dev/core/issues/272) Fatal Error
+ (Regression) on PCP pages associated with Events
+ ([12533](https://github.com/civicrm/civicrm-core/pull/12533))**
+
+- **[dev/core#124](https://lab.civicrm.org/dev/core/issues/124) Registration
+ approval issues ([12160](https://github.com/civicrm/civicrm-core/pull/12160)
+ and [12417](https://github.com/civicrm/civicrm-core/pull/12417))**
+
+ This resolves a PHP warning and some confusing aspects of handling event
+ registration approvals.
+
+### CiviGrant
+
+- **[dev/core#187](https://lab.civicrm.org/dev/core/issues/187) Fix typo in
+ `CRM_Grant_Form_Task` that prevents retrieving session key from URL
+ ([12317](https://github.com/civicrm/civicrm-core/pull/12317))**
+
+### CiviMail
+
+- **[dev/core#133](https://lab.civicrm.org/dev/core/issues/133) Reply-to field
+ with empty string get saved in DB as `NULL`
+ ([12176](https://github.com/civicrm/civicrm-core/pull/12176))**
+
+- **[CRM-20320](https://issues.civicrm.org/jira/browse/CRM-20320) Error in PEAR
+ SMTP causes mailing job to fail when an error occurs during one connection
+ ([11840](https://github.com/civicrm/civicrm-core/pull/11840))**
+
+ CiviMail will now disconnect the SMTP connection when a connection error is
+ detected and record the group of messages as not delivered. This allows it to
+ reconnect later and send the messages.
+
+- **[CRM-17753](https://issues.civicrm.org/jira/browse/CRM-17753) Newsletter
+ confirmation emails shouldn't use do-not-reply@yourdomain.org
+ ([12270](https://github.com/civicrm/civicrm-core/pull/12270)) (preliminary
+ work)**
+
+- **[CRM-21779](https://issues.civicrm.org/jira/browse/CRM-21779) Civimail
+ allows adding current draft mailing recipients to recipients field
+ ([11724](https://github.com/civicrm/civicrm-core/pull/11724))**
+
+### CiviMember
+
+- **[dev/membership#4](https://lab.civicrm.org/dev/membership/issues/4) Admin
+ Membership type is displayed on Public contribution page.
+ ([12178](https://github.com/civicrm/civicrm-core/pull/12178))**
+
+- **[dev/core#276](https://lab.civicrm.org/dev/core/issues/276) Undefined index:
+ is_override on submit credit card membership
+ ([12563](https://github.com/civicrm/civicrm-core/pull/12563))**
+
+- **[dev/core#151](https://lab.civicrm.org/dev/core/issues/151) Action to Update
+ Recurring Contributions From Membership View is Never Shown
+ ([12228](https://github.com/civicrm/civicrm-core/pull/12228))**
+
+ The table to view recurring contributions on a membership now displays the
+ Edit action where appropriate.
+
+- **[CRM-21682](https://issues.civicrm.org/jira/browse/CRM-21682) Automatic
+ membership renewal fixes
+ ([12313](https://github.com/civicrm/civicrm-core/pull/12313) and
+ [12314](https://github.com/civicrm/civicrm-core/pull/12314)) (preliminary
+ work)**
+
+- **[CRM-21177](https://issues.civicrm.org/jira/browse/CRM-21177) Wrong interval
+ of recurring payment for auto-renewing membership
+ ([12289](https://github.com/civicrm/civicrm-core/pull/12289)) (preliminary
+ work)**
+
+### Joomla Integration
+
+- **[dev/joomla#1](https://lab.civicrm.org/dev/joomla/issues/1) CiviEvent menu
+ listing showing old events
+ ([46](https://github.com/civicrm/civicrm-joomla/pull/46))**
+
+### WordPress Integration
+
+- **[dev/wordpress#1](https://lab.civicrm.org/dev/wordpress/issues/1)
+ CiviCRM-WordPress - Gutenberg Compatibility: Do not parse shortcodes in REST
+ context ([130](https://github.com/civicrm/civicrm-wordpress/pull/130))**
+
+- **[CRM-21565](https://issues.civicrm.org/jira/browse/CRM-21565) Change mkdir
+ to use correct and more secure mode numbers
+ ([120](https://github.com/civicrm/civicrm-wordpress/pull/120))**
+
+## <a name="misc"></a>Miscellany
+
+- **(NFC) Convert files to use linux line endings not windows
+ ([12531](https://github.com/civicrm/civicrm-core/pull/12531))**
+
+- **Move DAO function to DAO class, call it from Merge class
+ ([12340](https://github.com/civicrm/civicrm-core/pull/12340))**
+
+- **NFC code cleanup for AuthNet, Paypal, PaypalPro IPNs
+ ([12386](https://github.com/civicrm/civicrm-core/pull/12386))**
+
+- **[dev/core#203](https://lab.civicrm.org/dev/core/issues/203) Cruft code in
+ `CRM_Core_BAO_OptionGroup::add()`
+ ([12357](https://github.com/civicrm/civicrm-core/pull/12357))**
+
+- **Remove unused instances of usedTable
+ ([12341](https://github.com/civicrm/civicrm-core/pull/12341) and
+ [12349](https://github.com/civicrm/civicrm-core/pull/12349))**
+
+- **(NFC) CiviUnitTestCase - Fix edge-case for mis-reported error
+ ([12347](https://github.com/civicrm/civicrm-core/pull/12347))**
+
+- **NFC Code cleanup to core task class
+ ([12316](https://github.com/civicrm/civicrm-core/pull/12316))**
+
+- **[NFC] Stop passing no-longer-part-of-signature variable
+ ([12329](https://github.com/civicrm/civicrm-core/pull/12329))**
+
+- **Fix typo in api explorer sample code
+ ([12324](https://github.com/civicrm/civicrm-core/pull/12324))**
+
+- **Remove unused code variable
+ ([12299](https://github.com/civicrm/civicrm-core/pull/12299))**
+
+- **Confirm & lock in group.get handling of is_active
+ ([12295](https://github.com/civicrm/civicrm-core/pull/12295))**
+
+- **Remove unused function getRecuringTransactionStatus from PayflowPro c…
+ ([12294](https://github.com/civicrm/civicrm-core/pull/12294))**
+
+- **Add upgrade function for message templates that does not involve copying the
+ whole template ([12224](https://github.com/civicrm/civicrm-core/pull/12224))**
+
+- **Function extraction BAO_Export class
+ ([12288](https://github.com/civicrm/civicrm-core/pull/12288))**
+
+- **Partial refactor of completeMembershipFromContribution
+ ([12271](https://github.com/civicrm/civicrm-core/pull/12271))**
+
+- **[NFC] Fix line endings (Jenkins where were you)
+ ([12280](https://github.com/civicrm/civicrm-core/pull/12280))**
+
+- **Towards fixing household merge export, extract function, add test, fix prev
+ ([12272](https://github.com/civicrm/civicrm-core/pull/12272))**
+
+- **Standardise line endings away from windows line endings to linux
+ ([212](https://github.com/civicrm/civicrm-packages/pull/212))**
+
+## <a name="credits"></a>Credits
+
+This release was developed by the following code authors:
+
+AGH Strategies - Alice Frumin, Andrew Hunt; Agileware - Alok Patel; Australian
+Greens - Seamus Lee; Bastien Ho; Caltha - Tomasz Pietrzkowski; CiviCoop - Jaap
+Jansma; CiviCRM - Coleman Watts, Tim Otten; CiviDesk - Yashodha Chaku; CompuCorp -
+Camilo Rodriguez, Michael Devery, René Olivo, Vinu Varshith Sekar; Electronic
+Frontier Foundation - Mark Burdett; Fuzion - Jitendra Purohit; Ginkgo Street
+Labs - Frank Gómez; JMA Consulting - Monish Deb; Johan Vervloet; John
+Kingsnorth; Kanzu Code - Carl Andrew Lema; Left Join Labs - Sean Madsen; MJW
+Consulting - Matthew Wire; Pradeep Nayak; Romain Thouvenin; Squiffle Consulting -
+Aidan Saunders; Tadpole Collective - Kevin Cristiano; Third Sector Design -
+Michael McAndrew; Tom Bloor; Wikimedia Foundation - Eileen McNaughton
+
+Most authors also reviewed code for this release; in addition, the following
+reviewers contributed their comments:
+
+Agileware - Justin Freeman; baernm; Blackfly Solutions - Alan Dixon; Bob
+Silvern; Borislav Zlatanov; Caltha - Michal Mach; cartbar; Christian Wach;
+Circle Interactive - Dave Jenkins; CiviCoop - Erik Hommel; Community Builders -
+Andrew Perry; CompuCorp - Guanhuan Chen, Omar Abu Hussein; Coop SymbioTIC -
+Mathieu Lutfy; Drupal Association - Lizz Trudeau; Evan Chute; Forest CRM
+Consulting - Tamar Meir; Freeform Solutions - Herb van den Dool; Ginkgo Street
+Labs - Dan O'Brien; Hugo do Carmo; JMA Consulting - Joe Murray; Lemniscus - Noah
+Miller; Lighthouse Design and Consulting - Brian Shaughnessy; Megaphone
+Technology Consulting - Jon Goldberg; MJCO - Mikey O'Toole; Oxfam Germany -
+Thomas Schüttler; Richard van Oosterhout; Robin Fenwick; Semper IT - Karin
+Gerritsen; Stephen Palmstrom; Tech To The People - Xavier Dutoit; Timbsoft
+Technologies - Tunbola Ogunwande
+
+## <a name="feedback"></a>Feedback
+
+These release notes are edited by Andrew Hunt. If you'd like to provide
+feedback on them, please log in to https://chat.civicrm.org/civicrm and contact
+`@agh1`.
LOCK TABLES `civicrm_domain` WRITE;
/*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */;
-INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'5.5.alpha1',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
+INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'5.6.alpha1',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
/*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */;
UNLOCK TABLES;
<table class="form-layout-compressed">
{foreach from=$caseRoles.client item=client}
<tr class="crm-case-caseview-display_name">
- <td class="label-left bold" style="padding: 0px; border: none;">{$client.display_name}</td>
+ <td class="label-left bold" style="padding: 0px; border: none;">
+ <a href="{crmURL p='civicrm/contact/view' q="action=view&reset=1&cid=`$client.contact_id`"}" title="{ts}View contact record{/ts}">{$client.display_name}</a>
+ </td>
</tr>
{if $client.phone}
<tr class="crm-case-caseview-phone">
</li>
<li id="tab_recurring" class="crm-tab-button ui-corner-all ui-tabs-tab ui-corner-top ui-state-default ui-tab">
<a href="#recurring-subtab" title="{ts}Recurring Contributions{/ts}">
- {ts}Recurring Contributions{/ts} <em>{$activeRecurRows|@count}</em>
+ {ts}Recurring Contributions{/ts} <em>{$contributionRecurCount}</em>
</a>
</li>
</ul>
</td>
<td>{if $form.$fieldName.html}{if $fieldSpec.formatter === 'crmMoney'}{$form.$fieldName.html|crmMoney}{else}{$form.$fieldName.html}{/if}{else}{$fieldSpec.place_holder}{/if}<br />
{if $fieldSpec.description}<span class="description">{$fieldSpec.description}</span>{/if}
+ {if $fieldSpec.documentation_link}{docURL page=$fieldSpec.documentation_link.page}{/if}
</td>
{/if}
<div class="form-item" id="membership_type_form">
<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div>
<table class="form-layout-compressed">
- <tr class="crm-membership-type-form-block-name">
- <td class="label">{$form.name.label} {if $action == 2}{include file='CRM/Core/I18n/Dialog.tpl' table='civicrm_membership_type' field='name' id=$membershipTypeId}{/if}
- </td>
- <td>{$form.name.html}<br />
- <span class="description">{ts}e.g. 'Student', 'Senior', 'Honor Society'...{/ts}</span>
- </td>
- </tr>
- <tr class="crm-membership-type-form-block-description">
- <td class="label">{$form.description.label} {if $action == 2}{include file='CRM/Core/I18n/Dialog.tpl' table='civicrm_membership_type' field='description' id=$membershipTypeId}{/if}
- </td>
- <td>{$form.description.html}<br />
- <span class="description">{ts}Description of this membership type for internal use. May include eligibility, benefits, terms, etc.{/ts}</span>
- </td>
- </tr>
-
- <tr class="crm-membership-type-form-block-member_org">
- <td class="label">{$form.member_of_contact_id.label}</td>
- <td>{$form.member_of_contact_id.html}<br />
- <span class="description">{ts}Members assigned this membership type belong to which organization (e.g. this is for membership in 'Save the Whales - Northwest Chapter'). NOTE: This organization/group/chapter must exist as a CiviCRM Organization type contact.{/ts}</span>
- </td>
- </tr>
-
- <tr class="crm-membership-type-form-block-minimum_fee">
- <td class="label">{$form.minimum_fee.label}</td>
- <td>{$form.minimum_fee.html|crmMoney}<br />
- <span class="description">{ts}Minimum fee required for this membership type. For free/complimentary memberships - set minimum fee to zero (0). NOTE: When using CiviCRM to process sales taxes this should be the tax exclusive amount.{/ts}</span>
- </td>
- </tr>
+ {foreach from=$tpl_standardised_fields item=fieldName}
+ {assign var=fieldSpec value=$entityFields.$fieldName}
+ <tr class="crm-{$entityInClassFormat}-form-block-{$fieldName}">
+ {include file="CRM/Core/Form/Field.tpl"}
+ </tr>
+ {/foreach}
<tr class="crm-membership-type-form-block-financial_type_id">
<td class="label">{$form.financial_type_id.label}</td>
<td>{$form.financial_type_id.html}<br />
public function getCleanKeyExamples() {
$es = [];
- $es[] = ['hello_world and other.planets', 'hello_world and other.planets']; // allowed chars
+ $es[] = ['hello_world and/other.planets', 'hello_world-20and-2fother.planets']; // allowed chars
$es[] = ['hello/world+-#@{}', 'hello-2fworld-2b-2d-23-40-7b-7d']; // escaped chars
- $es[] = ['123456789 123456789 123456789 123456789 123456789 123456789 123', '123456789 123456789 123456789 123456789 123456789 123456789 123']; // long but allowed
- $es[] = ['123456789 123456789 123456789 123456789 123456789 123456789 1234', '-2a008e182a4dcd1a78f405f30119e5f2']; // too long, md5 fallback
- $es[] = ['123456789 /23456789 +23456789 -23456789 123456789 123456789', '-1b6baab5961431ed443ab321f5dfa0fb']; // too long, md5 fallback
+ $es[] = ["LF-\nTAB-\tCR-\remojiskull💀", 'LF-2d-aTAB-2d-9CR-2d-demojiskull-f0-9f-92-80']; // short with emoji
+ $es[] = ["LF-\nTAB-\tCR-\remojibomb💣emojiskull💀", '-5d9324e052f6e10240dce5029c5e8525']; // long with emoji
+ $es[] = ['123456789 123456789 123456789 123456789 123456789 123', '123456789-20123456789-20123456789-20123456789-20123456789-20123']; // spaces are escaped
+ $es[] = ['123456789_123456789_123456789_123456789_123456789_123456789_123', '123456789_123456789_123456789_123456789_123456789_123456789_123']; // long but allowed
+ $es[] = ['123456789_123456789_123456789_123456789_123456789_123456789_1234', '-e02b981aff954fdcc9a81c25f5ec9681']; // too long, md5 fallback
+ $es[] = ['123456789-/23456789-+23456789--23456789_123456789_123456789', '-43b6dec1026187ae6f6a8fe4d56ab22e']; // too long, md5 fallback
return $es;
}
$this->assertEquals($params["custom_{$customField['id']}_-1"], $result["custom_{$customField['id']}_1"]);
$this->assertEquals($params['entityID'], $result['entityID']);
+ $updateParams = array(
+ 'id' => 1,
+ 'entityID' => $contactID,
+ "custom_{$customField['id']}" => 2,
+ );
+ CRM_Core_BAO_CustomValueTable::setValues($updateParams);
+
+ $criteria = array(
+ 'id' => 1,
+ 'entityID' => $contactID,
+ );
+ $result = CRM_Core_BAO_CustomValueTable::getValues($criteria);
+ $this->assertEquals(2, $result["custom_{$customField['id']}_1"]);
+
$this->customFieldDelete($customField['id']);
$this->customGroupDelete($customGroup['id']);
$this->contactDelete($contactID);
*/
public function testHardLocks() {
$hardLocks = array(
- 'symfony/config' => '/^v2\.6\./',
- 'symfony/dependency-injection' => '/^v2\.6\./',
- 'symfony/event-dispatcher' => '/^v2\.6\./',
- 'symfony/filesystem' => '/^v2\.6\./',
- 'symfony/finder' => '/^v2\.6\./',
- 'symfony/process' => '/^v2\.6\./',
+ 'symfony/config' => '/^v2\.8\./',
+ 'symfony/dependency-injection' => '/^v2\.8\./',
+ 'symfony/event-dispatcher' => '/^v2\.8\./',
+ 'symfony/filesystem' => '/^v2\.8\./',
+ 'symfony/finder' => '/^v2\.8\./',
+ 'symfony/process' => '/^v2\.8\./',
);
$lockFile = Civi::paths()->getPath('[civicrm.root]/composer.lock');
* @param $selectedFields
* @param int $id
*
+ * @param int $exportMode
+ *
* @return array
*/
- protected function doExport($selectedFields, $id) {
+ protected function doExport($selectedFields, $id, $exportMode = CRM_Export_Form_Select::CONTACT_EXPORT) {
list($tableName, $sqlColumns) = CRM_Export_BAO_Export::exportComponents(
TRUE,
array($id),
NULL,
$selectedFields,
NULL,
- CRM_Export_Form_Select::CONTACT_EXPORT,
+ $exportMode,
"contact_a.id IN ({$id})",
NULL,
FALSE,
/**
* Test the column definition when 'all' fields defined.
*
- * @param $exportMode
- * @param $expected
+ * @param int $exportMode
+ * @param array $expected
+ * @param array $expectedHeaders
*
* @dataProvider getSqlColumnsOutput
*/
- public function testGetSQLColumns($exportMode, $expected) {
+ public function testGetSQLColumnsAndHeaders($exportMode, $expected, $expectedHeaders) {
$this->ensureComponentIsEnabled($exportMode);
// We need some data so that we can get to the end of the export
// function. Hopefully one day that won't be required to get metadata info out.
)
);
$this->assertEquals($expected, $result[1]);
+ $this->assertEquals($expectedHeaders, $result[2]);
+ }
+
+ /**
+ * Test exported with fields to output specified.
+ *
+ * @dataProvider getAllSpecifiableReturnFields
+ *
+ * @param int $exportMode
+ * @param array $selectedFields
+ * @param array $expected
+ */
+ public function testExportSpecifyFields($exportMode, $selectedFields, $expected) {
+ $this->ensureComponentIsEnabled($exportMode);
+ $this->setUpContributionExportData();
+ list($tableName, $sqlColumns) = $this->doExport($selectedFields, $this->contactIDs[1], $exportMode);
+ $this->assertEquals($expected, $sqlColumns);
+ }
+
+ /**
+ * Test export fields when no payment fields to be exported.
+ */
+ public function textExportParticipantSpecifyFieldsNoPayment() {
+ $selectedFields = $this->getAllSpecifiableParticipantReturnFields();
+ foreach ($selectedFields as $index => $field) {
+ if (substr($field[1], 0, 22) === 'componentPaymentField_') {
+ unset ($selectedFields[$index]);
+ }
+ }
+
+ $expected = $this->getAllSpecifiableParticipantReturnFields();
+ foreach ($expected as $index => $field) {
+ if (substr($index, 0, 22) === 'componentPaymentField_') {
+ unset ($expected[$index]);
+ }
+ }
+
+ list($tableName, $sqlColumns) = $this->doExport($selectedFields, $this->contactIDs[1], CRM_Export_Form_Select::EVENT_EXPORT);
+ $this->assertEquals($expected, $sqlColumns);
+ }
+ /**
+ * Get all return fields (@todo - still being built up.
+ *
+ * @return array
+ */
+ public function getAllSpecifiableReturnFields() {
+ return [
+ [
+ CRM_Export_Form_Select::EVENT_EXPORT,
+ $this->getAllSpecifiableParticipantReturnFields(),
+ $this->getAllSpecifiableParticipantReturnColumns(),
+ ],
+ ];
+ }
+
+ /**
+ * Get expected return column output for participant mode return all columns.
+ *
+ * @return array
+ */
+ public function getAllSpecifiableParticipantReturnColumns() {
+ return [
+ 'participant_campaign_id' => 'participant_campaign_id varchar(128)',
+ 'participant_contact_id' => 'participant_contact_id varchar(16)',
+ 'componentpaymentfield_contribution_status' => 'componentpaymentfield_contribution_status text',
+ 'currency' => 'currency varchar(3)',
+ 'componentpaymentfield_received_date' => 'componentpaymentfield_received_date text',
+ 'default_role_id' => 'default_role_id varchar(16)',
+ 'participant_discount_name' => 'participant_discount_name varchar(16)',
+ 'event_id' => 'event_id varchar(16)',
+ 'event_end_date' => 'event_end_date varchar(32)',
+ 'event_start_date' => 'event_start_date varchar(32)',
+ 'template_title' => 'template_title varchar(255)',
+ 'event_title' => 'event_title varchar(255)',
+ 'participant_fee_amount' => 'participant_fee_amount varchar(32)',
+ 'participant_fee_currency' => 'participant_fee_currency varchar(3)',
+ 'fee_label' => 'fee_label varchar(255)',
+ 'participant_fee_level' => 'participant_fee_level longtext',
+ 'participant_is_pay_later' => 'participant_is_pay_later varchar(16)',
+ 'participant_id' => 'participant_id varchar(16)',
+ 'participant_note' => 'participant_note text',
+ 'participant_role_id' => 'participant_role_id varchar(128)',
+ 'participant_role' => 'participant_role varchar(255)',
+ 'participant_source' => 'participant_source varchar(128)',
+ 'participant_status_id' => 'participant_status_id varchar(16)',
+ 'participant_status' => 'participant_status varchar(255)',
+ 'participant_register_date' => 'participant_register_date varchar(32)',
+ 'participant_registered_by_id' => 'participant_registered_by_id varchar(16)',
+ 'participant_is_test' => 'participant_is_test varchar(16)',
+ 'componentpaymentfield_total_amount' => 'componentpaymentfield_total_amount text',
+ 'componentpaymentfield_transaction_id' => 'componentpaymentfield_transaction_id varchar(255)',
+ 'transferred_to_contact_id' => 'transferred_to_contact_id varchar(16)',
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function getAllSpecifiableParticipantReturnFields() {
+ return [
+ 0 =>
+ [
+ 0 => 'Participant',
+ 1 => '',
+ ],
+ 1 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_campaign_id',
+ ],
+ 2 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_contact_id',
+ ],
+ 3 =>
+ [
+ 0 => 'Participant',
+ 1 => 'componentPaymentField_contribution_status',
+ ],
+ 4 =>
+ [
+ 0 => 'Participant',
+ 1 => 'currency',
+ ],
+ 5 =>
+ [
+ 0 => 'Participant',
+ 1 => 'componentPaymentField_received_date',
+ ],
+ 6 =>
+ [
+ 0 => 'Participant',
+ 1 => 'default_role_id',
+ ],
+ 7 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_discount_name',
+ ],
+ 8 =>
+ [
+ 0 => 'Participant',
+ 1 => 'event_id',
+ ],
+ 9 =>
+ [
+ 0 => 'Participant',
+ 1 => 'event_end_date',
+ ],
+ 10 =>
+ [
+ 0 => 'Participant',
+ 1 => 'event_start_date',
+ ],
+ 11 =>
+ [
+ 0 => 'Participant',
+ 1 => 'template_title',
+ ],
+ 12 =>
+ [
+ 0 => 'Participant',
+ 1 => 'event_title',
+ ],
+ 13 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_fee_amount',
+ ],
+ 14 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_fee_currency',
+ ],
+ 15 =>
+ [
+ 0 => 'Participant',
+ 1 => 'fee_label',
+ ],
+ 16 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_fee_level',
+ ],
+ 17 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_is_pay_later',
+ ],
+ 18 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_id',
+ ],
+ 19 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_note',
+ ],
+ 20 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_role_id',
+ ],
+ 21 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_role',
+ ],
+ 22 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_source',
+ ],
+ 23 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_status_id',
+ ],
+ 24 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_status',
+ ],
+ 25 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_status',
+ ],
+ 26 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_register_date',
+ ],
+ 27 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_registered_by_id',
+ ],
+ 28 =>
+ [
+ 0 => 'Participant',
+ 1 => 'participant_is_test',
+ ],
+ 29 =>
+ [
+ 0 => 'Participant',
+ 1 => 'componentPaymentField_total_amount',
+ ],
+ 30 =>
+ [
+ 0 => 'Participant',
+ 1 => 'componentPaymentField_transaction_id',
+ ],
+ 31 =>
+ [
+ 0 => 'Participant',
+ 1 => 'transferred_to_contact_id',
+ ],
+ ];
}
/**
[
'anything that will then be defaulting ton contact',
$this->getBasicSqlColumnDefinition(TRUE),
+ $this->getBasicHeaderDefinition(TRUE),
],
[
CRM_Export_Form_Select::ACTIVITY_EXPORT,
array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getActivitySqlColumns()),
+ array_merge($this->getBasicHeaderDefinition(FALSE), $this->getActivityHeaderDefinition()),
],
[
CRM_Export_Form_Select::CASE_EXPORT,
array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getCaseSqlColumns()),
+ array_merge($this->getBasicHeaderDefinition(FALSE), $this->getCaseHeaderDefinition()),
],
[
CRM_Export_Form_Select::CONTRIBUTE_EXPORT,
array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getContributionSqlColumns()),
+ array_merge($this->getBasicHeaderDefinition(FALSE), $this->getContributeHeaderDefinition()),
],
[
CRM_Export_Form_Select::EVENT_EXPORT,
array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getParticipantSqlColumns()),
+ array_merge($this->getBasicHeaderDefinition(FALSE), $this->getParticipantHeaderDefinition()),
],
[
CRM_Export_Form_Select::MEMBER_EXPORT,
array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getMembershipSqlColumns()),
+ array_merge($this->getBasicHeaderDefinition(FALSE), $this->getMemberHeaderDefinition()),
],
[
CRM_Export_Form_Select::PLEDGE_EXPORT,
array_merge($this->getBasicSqlColumnDefinition(FALSE), $this->getPledgeSqlColumns()),
+ array_merge($this->getBasicHeaderDefinition(FALSE), $this->getPledgeHeaderDefinition()),
],
];
}
+ /**
+ * Get the header definition for exports.
+ *
+ * @param bool $isContactExport
+ *
+ * @return array
+ */
+ protected function getBasicHeaderDefinition($isContactExport) {
+ $headers = [
+ 0 => 'Contact ID',
+ 1 => 'Contact Type',
+ 2 => 'Contact Subtype',
+ 3 => 'Do Not Email',
+ 4 => 'Do Not Phone',
+ 5 => 'Do Not Mail',
+ 6 => 'Do Not Sms',
+ 7 => 'Do Not Trade',
+ 8 => 'No Bulk Emails (User Opt Out)',
+ 9 => 'Legal Identifier',
+ 10 => 'External Identifier',
+ 11 => 'Sort Name',
+ 12 => 'Display Name',
+ 13 => 'Nickname',
+ 14 => 'Legal Name',
+ 15 => 'Image Url',
+ 16 => 'Preferred Communication Method',
+ 17 => 'Preferred Language',
+ 18 => 'Preferred Mail Format',
+ 19 => 'Contact Hash',
+ 20 => 'Contact Source',
+ 21 => 'First Name',
+ 22 => 'Middle Name',
+ 23 => 'Last Name',
+ 24 => 'Individual Prefix',
+ 25 => 'Individual Suffix',
+ 26 => 'Formal Title',
+ 27 => 'Communication Style',
+ 28 => 'Email Greeting ID',
+ 29 => 'Postal Greeting ID',
+ 30 => 'Addressee ID',
+ 31 => 'Job Title',
+ 32 => 'Gender',
+ 33 => 'Birth Date',
+ 34 => 'Deceased',
+ 35 => 'Deceased Date',
+ 36 => 'Household Name',
+ 37 => 'Organization Name',
+ 38 => 'Sic Code',
+ 39 => 'Unique ID (OpenID)',
+ 40 => 'Current Employer ID',
+ 41 => 'Contact is in Trash',
+ 42 => 'Created Date',
+ 43 => 'Modified Date',
+ 44 => 'Addressee',
+ 45 => 'Email Greeting',
+ 46 => 'Postal Greeting',
+ 47 => 'Current Employer',
+ 48 => 'Location Type',
+ 49 => 'Street Address',
+ 50 => 'Street Number',
+ 51 => 'Street Number Suffix',
+ 52 => 'Street Name',
+ 53 => 'Street Unit',
+ 54 => 'Supplemental Address 1',
+ 55 => 'Supplemental Address 2',
+ 56 => 'Supplemental Address 3',
+ 57 => 'City',
+ 58 => 'Postal Code Suffix',
+ 59 => 'Postal Code',
+ 60 => 'Latitude',
+ 61 => 'Longitude',
+ 62 => 'Address Name',
+ 63 => 'Master Address Belongs To',
+ 64 => 'County',
+ 65 => 'State',
+ 66 => 'Country',
+ 67 => 'Phone',
+ 68 => 'Phone Extension',
+ 69 => 'Phone Type',
+ 70 => 'Email',
+ 71 => 'On Hold',
+ 72 => 'Use for Bulk Mail',
+ 73 => 'Signature Text',
+ 74 => 'Signature Html',
+ 75 => 'IM Provider',
+ 76 => 'IM Screen Name',
+ 77 => 'OpenID',
+ 78 => 'World Region',
+ 79 => 'Website',
+ 80 => 'Group(s)',
+ 81 => 'Tag(s)',
+ 82 => 'Note(s)',
+ 83 => 'IM Service Provider',
+ ];
+ if (!$isContactExport) {
+ unset($headers[80]);
+ unset($headers[81]);
+ unset($headers[82]);
+ }
+ return $headers;
+ }
+
+ /**
+ * Get the definition for activity headers.
+ *
+ * @return array
+ */
+ protected function getActivityHeaderDefinition() {
+ return [
+ 81 => 'Activity ID',
+ 82 => 'Activity Type',
+ 83 => 'Activity Type ID',
+ 84 => 'Subject',
+ 85 => 'Activity Date',
+ 86 => 'Duration',
+ 87 => 'Location',
+ 88 => 'Details',
+ 89 => 'Activity Status',
+ 90 => 'Activity Priority',
+ 91 => 'Source Contact',
+ 92 => 'source_record_id',
+ 93 => 'Test',
+ 94 => 'Campaign ID',
+ 95 => 'result',
+ 96 => 'Engagement Index',
+ 97 => 'parent_id',
+ ];
+ }
+
+ /**
+ * Get the definition for case headers.
+ *
+ * @return array
+ */
+ protected function getCaseHeaderDefinition() {
+ return [
+ 81 => 'contact_id',
+ 82 => 'Case ID',
+ 83 => 'case_activity_subject',
+ 84 => 'Case Subject',
+ 85 => 'Case Status',
+ 86 => 'Case Type',
+ 87 => 'Role in Case',
+ 88 => 'Case is in the Trash',
+ 89 => 'case_recent_activity_date',
+ 90 => 'case_recent_activity_type',
+ 91 => 'case_scheduled_activity_date',
+ 92 => 'Case Start Date',
+ 93 => 'Case End Date',
+ 94 => 'case_source_contact_id',
+ 95 => 'case_activity_status',
+ 96 => 'case_activity_duration',
+ 97 => 'case_activity_medium_id',
+ 98 => 'case_activity_details',
+ 99 => 'case_activity_is_auto',
+ ];
+ }
+
+ /**
+ * Get the definition for contribute headers.
+ *
+ * @return array
+ */
+ protected function getContributeHeaderDefinition() {
+ return [
+ 81 => 'Financial Type',
+ 82 => 'Contribution Source',
+ 83 => 'Date Received',
+ 84 => 'Thank-you Date',
+ 85 => 'Cancel Date',
+ 86 => 'Total Amount',
+ 87 => 'Accounting Code',
+ 88 => 'payment_instrument',
+ 89 => 'Payment Method ID',
+ 90 => 'Check Number',
+ 91 => 'Non-deductible Amount',
+ 92 => 'Fee Amount',
+ 93 => 'Net Amount',
+ 94 => 'Transaction ID',
+ 95 => 'Invoice Reference',
+ 96 => 'Invoice Number',
+ 97 => 'Currency',
+ 98 => 'Cancel Reason',
+ 99 => 'Receipt Date',
+ 100 => 'Product Name',
+ 101 => 'SKU',
+ 102 => 'Product Option',
+ 103 => 'Fulfilled Date',
+ 104 => 'Start date for premium',
+ 105 => 'End date for premium',
+ 106 => 'Test',
+ 107 => 'Is Pay Later',
+ 108 => 'contribution_status',
+ 109 => 'Recurring Contribution ID',
+ 110 => 'Amount Label',
+ 111 => 'Contribution Note',
+ 112 => 'Batch Name',
+ 113 => 'Campaign Title',
+ 114 => 'Campaign ID',
+ 115 => 'Premium',
+ 116 => 'Soft Credit For',
+ 117 => 'Soft Credit Amount',
+ 118 => 'Soft Credit Type',
+ 119 => 'Soft Credit For Contact ID',
+ 120 => 'Soft Credit For Contribution ID',
+ ];
+ }
+
+ /**
+ * Get the definition for event headers.
+ *
+ * @return array
+ */
+ protected function getParticipantHeaderDefinition() {
+ return [
+ 81 => 'Event',
+ 82 => 'Event Title',
+ 83 => 'Event Start Date',
+ 84 => 'Event End Date',
+ 85 => 'Event Type',
+ 86 => 'Participant ID',
+ 87 => 'Participant Status',
+ 88 => 'Participant Status Id',
+ 89 => 'Participant Role',
+ 90 => 'Participant Role Id',
+ 91 => 'Participant Note',
+ 92 => 'Register date',
+ 93 => 'Participant Source',
+ 94 => 'Fee level',
+ 95 => 'Test',
+ 96 => 'Is Pay Later',
+ 97 => 'Fee Amount',
+ 98 => 'Discount Name',
+ 99 => 'Fee Currency',
+ 100 => 'Registered By ID',
+ 101 => 'Campaign ID',
+ ];
+ }
+
+ /**
+ * Get the definition for member headers.
+ *
+ * @return array
+ */
+ protected function getMemberHeaderDefinition() {
+ return [
+ 81 => 'Membership Type',
+ 82 => 'Test',
+ 83 => 'Is Pay Later',
+ 84 => 'Member Since',
+ 85 => 'Membership Start Date',
+ 86 => 'Membership Expiration Date',
+ 87 => 'Source',
+ 88 => 'Membership Status',
+ 89 => 'Membership ID',
+ 90 => 'Primary Member ID',
+ 91 => 'max_related',
+ 92 => 'membership_recur_id',
+ 93 => 'Campaign ID',
+ 94 => 'member_is_override',
+ 95 => 'member_auto_renew',
+ ];
+ }
+
+ /**
+ * Get the definition for pledge headers.
+ *
+ * @return array
+ */
+ protected function getPledgeHeaderDefinition() {
+ return [
+ 81 => 'Pledge ID',
+ 82 => 'Total Pledged',
+ 83 => 'Total Paid',
+ 84 => 'Pledge Made',
+ 85 => 'pledge_start_date',
+ 86 => 'Next Payment Date',
+ 87 => 'Next Payment Amount',
+ 88 => 'Pledge Status',
+ 89 => 'Test',
+ 90 => 'Pledge Contribution Page Id',
+ 91 => 'pledge_financial_type',
+ 92 => 'Pledge Frequency Interval',
+ 93 => 'Pledge Frequency Unit',
+ 94 => 'pledge_currency',
+ 95 => 'Campaign ID',
+ 96 => 'Balance Amount',
+ 97 => 'Payment ID',
+ 98 => 'Scheduled Amount',
+ 99 => 'Scheduled Date',
+ 100 => 'Paid Amount',
+ 101 => 'Paid Date',
+ 102 => 'Last Reminder',
+ 103 => 'Reminders Sent',
+ 104 => 'Pledge Payment Status',
+ ];
+ }
+
/**
* Get the column definition for exports.
*
'country' => 'country varchar(64)',
'phone' => 'phone varchar(32)',
'phone_ext' => 'phone_ext varchar(16)',
+ 'phone_type_id' => 'phone_type_id varchar(16)',
'email' => 'email varchar(254)',
'on_hold' => 'on_hold varchar(16)',
'is_bulkmail' => 'is_bulkmail varchar(16)',
'groups' => 'groups text',
'tags' => 'tags text',
'notes' => 'notes text',
- 'phone_type_id' => 'phone_type_id varchar(255)',
'provider_id' => 'provider_id varchar(255)',
];
if (!$isContactExport) {
'openid' => 'openid varchar(255)',
'world_region' => 'world_region varchar(128)',
'url' => 'url varchar(128)',
- 'phone_type_id' => 'phone_type_id varchar(255)',
+ 'phone_type_id' => 'phone_type_id varchar(16)',
'provider_id' => 'provider_id varchar(255)',
'financial_type' => 'financial_type varchar(64)',
'contribution_source' => 'contribution_source varchar(255)',
}
/**
- * CRM-21656: Test the submit function of the membership form if Sale Tax is enabled.
- * Check that the tax rate isn't reapplied to line item's unit price and total amount
+ * CRM-21656: Test the submit function of the membership form if Sales Tax is enabled.
+ * This test simulates what happens when one hits Edit on a Contribution that has both LineItems and Sales Tax components
+ * Without making any Edits -> check that the LineItem data remain the same
+ * In addition (a data-integrity check) -> check that the LineItem data add up to the data at the Contribution level
*/
- public function testLineItemAmountOnSaleTax() {
+ public function testLineItemAmountOnSalesTax() {
$this->enableTaxAndInvoicing();
$this->relationForFinancialTypeWithFinancialAccount(2);
$form = $this->getForm();
$this->createLoggedInUser();
$priceSet = $this->callAPISuccess('PriceSet', 'Get', array("extends" => "CiviMember"));
$form->set('priceSetId', $priceSet['id']);
+ // we are simulating the creation of a Price Set in Administer -> CiviContribute -> Manage Price Sets so set is_quick_config = 0
+ $this->callAPISuccess('PriceSet', 'Create', array("id" => $priceSet['id'], 'is_quick_config' => 0));
// clean the price options static variable to repopulate the options, in order to fetch tax information
\Civi::$statics['CRM_Price_BAO_PriceField']['priceOptions'] = NULL;
CRM_Price_BAO_PriceSet::buildPriceSet($form);
),
CRM_Core_Action::UPDATE);
- // ensure that the line-item values got unaffected
+ // ensure that the LineItem data remain the same
$lineItem = $this->callAPISuccessGetSingle('LineItem', array('entity_id' => $membership['id'], 'entity_table' => 'civicrm_membership'));
$this->assertEquals(1, $lineItem['qty']);
- $this->assertEquals(5.00, $lineItem['tax_amount']); // ensure that tax amount is not changed
+ $this->assertEquals(50.00, $lineItem['unit_price']);
+ $this->assertEquals(50.00, $lineItem['line_total']);
+ $this->assertEquals(5.00, $lineItem['tax_amount']);
+
+ // ensure that the LineItem data add up to the data at the Contribution level
+ $contribution = $this->callAPISuccessGetSingle('Contribution',
+ array(
+ 'contribution_id' => 1,
+ 'return' => array('tax_amount', 'total_amount'),
+ )
+ );
+ $this->assertEquals($contribution['total_amount'], $lineItem['line_total'] + $lineItem['tax_amount']);
+ $this->assertEquals($contribution['tax_amount'], $lineItem['tax_amount']);
// reset the price options static variable so not leave any dummy data, that might hamper other unit tests
\Civi::$statics['CRM_Price_BAO_PriceField']['priceOptions'] = NULL;
}
+ /**
+ * Creates a multi-valued custom field set and creates a contact with mutliple values for it.
+ *
+ * @return array
+ */
+ private function _testGetCustomValueMultiple() {
+ $fieldIDs = $this->CustomGroupMultipleCreateWithFields();
+ $customFieldValues = [];
+ foreach ($fieldIDs['custom_field_id'] as $id) {
+ $customFieldValues["custom_{$id}"] = "field_{$id}_value_1";
+ }
+ $this->assertNotEmpty($customFieldValues);
+ $contactParams = [
+ 'first_name' => 'Jane',
+ 'last_name' => 'Doe',
+ 'contact_type' => 'Individual',
+ ];
+ $contact = $this->callAPISuccess('Contact', 'create', array_merge($contactParams, $customFieldValues));
+ foreach ($fieldIDs['custom_field_id'] as $id) {
+ $customFieldValues["custom_{$id}"] = "field_{$id}_value_2";
+ }
+ $result = $this->callAPISuccess('Contact', 'create', array_merge(['id' => $contact['id']], $customFieldValues));
+ return [
+ $contact['id'],
+ $customFieldValues,
+ ];
+ }
+
+ /**
+ * Test that specific custom values can be retrieved while using return with comma separated values as genererated by the api explorer.
+ * ['return' => 'custom_1,custom_2']
+ */
+ public function testGetCustomValueReturnMultipleApiExplorer() {
+ list($cid, $customFieldValues) = $this->_testGetCustomValueMultiple();
+ $result = $this->callAPISuccess('CustomValue', 'get', [
+ 'return' => implode(',', array_keys($customFieldValues)),
+ 'entity_id' => $cid,
+ ]);
+ $this->assertEquals(count($customFieldValues), $result['count']);
+ }
+
+ /**
+ * Test that specific custom values can be retrieved while using return with array style syntax.
+ * ['return => ['custom_1', 'custom_2']]
+ */
+ public function testGetCustomValueReturnMultipleArray() {
+ list($cid, $customFieldValues) = $this->_testGetCustomValueMultiple();
+ $result = $this->callAPISuccess('CustomValue', 'get', [
+ 'return' => array_keys($customFieldValues),
+ 'entity_id' => $cid,
+ ]);
+ $this->assertEquals(count($customFieldValues), $result['count']);
+ }
+
+ /**
+ * Test that specific custom values can be retrieved while using a list of return parameters.
+ * [['return.custom_1' => '1'], ['return.custom_2' => '1']]
+ */
+ public function testGetCustomValueReturnMultipleList() {
+ list($cid, $customFieldValues) = $this->_testGetCustomValueMultiple();
+ $returnArray = [];
+ foreach ($customFieldValues as $field => $value) {
+ $returnArray["return.{$field}"] = 1;
+ }
+ $result = $this->callAPISuccess('CustomValue', 'get', array_merge($returnArray, ['entity_id' => $cid]));
+ $this->assertEquals(count($customFieldValues), $result['count']);
+ }
+
}
'civicrm_activity_source_record_id' => NULL,
'civicrm_activity_activity_type_id' => 'Meeting',
'civicrm_activity_activity_subject' => 'Very secret meeting',
- 'civicrm_activity_activity_date_time' => '2018-07-16 03:42:32',
+ 'civicrm_activity_activity_date_time' => date('Y-m-d 23:59:58', strtotime('now')),
'civicrm_activity_status_id' => 'Scheduled',
'civicrm_activity_duration' => '120',
'civicrm_activity_location' => 'Pennsylvania',
'civicrm_contact_contact_source_link' => '/index.php?q=civicrm/contact/view&reset=1&cid=' . $this->contactIDs[2],
'civicrm_contact_contact_source_hover' => 'View Contact Summary for this Contact',
'civicrm_activity_activity_type_id_hover' => 'View Activity Record',
- 'class' => 'status-overdue',
];
$row = $rows[0];
// This link is not relative - skip for now
$this->callAPISuccess('Activity', 'create', [
'subject' => 'Very secret meeting',
- 'activity_date_time' => '2018-07-16 03:42:32',
+ 'activity_date_time' => date('Y-m-d 23:59:58', strtotime('now')),
'duration' => 120,
'location' => 'Pennsylvania',
'details' => 'a test activity',
<name>phone_type_id</name>
<title>Phone Type</title>
<type>int unsigned</type>
+ <export>true</export>
<comment>Which type of phone does this number belongs.</comment>
<pseudoconstant>
<optionGroupName>phone_type</optionGroupName>
<name>auto_renew</name>
<type>boolean</type>
<default>0</default>
+ <html>
+ <type>Radio</type>
+ </html>
<pseudoconstant>
<callback>CRM_Core_SelectValues::memberAutoRenew</callback>
</pseudoconstant>
<?xml version="1.0" encoding="iso-8859-1" ?>
<version>
- <version_no>5.5.alpha1</version_no>
+ <version_no>5.6.alpha1</version_no>
</version>