From 0298287b6bd08a4c10a7a59b93ed4ce0df8097b5 Mon Sep 17 00:00:00 2001 From: eileenmcnaughton Date: Mon, 10 Aug 2015 08:41:17 +0000 Subject: [PATCH] CRM-16036 fixes to make all tess pass with new internalsx wq! --- api/v3/Activity.php | 21 ++++- api/v3/Dashboard.php | 1 + api/v3/Event.php | 4 +- api/v3/WordReplacement.php | 1 + api/v3/utils.php | 85 ++++++++++++++++--- tests/phpunit/api/v3/MembershipTest.php | 4 +- .../phpunit/api/v3/SyntaxConformanceTest.php | 9 +- 7 files changed, 106 insertions(+), 19 deletions(-) diff --git a/api/v3/Activity.php b/api/v3/Activity.php index cd6f3bbee1..6fcbafdc88 100644 --- a/api/v3/Activity.php +++ b/api/v3/Activity.php @@ -242,7 +242,25 @@ function civicrm_api3_activity_get($params) { } } else { - $activities = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE, 'Activity'); + $extraSql = array(); + $options = civicrm_api3('ActivityContact', 'getoptions', array('field' => 'record_type_id')); + $options = $options['values']; + $activityContactOptions = array( + 'target_contact_id' => array_search('Activity Targets', $options), + 'source_contact_id' => array_search('Activity Source', $options), + 'assignee_contact_id' => array_search('Activity Assignees', $options), + ); + foreach ($activityContactOptions as $activityContactName => $activityContactValue) { + if (!empty($params[$activityContactName])) { + $extraSql['join'][] = array( + 'activity_' . $activityContactName => ' + LEFT JOIN civicrm_activity_contact ac ON a.id = ac.activity_id AND ac.record_type_id = ' . $activityContactValue, + ); + // Note that if we later need to change the int to an array we would need sql escaping. + $extraSql['where'] = array('activity_' . $activityContactName => 'ac.contact_id = ' . (int) $params[$activityContactName]); + } + } + $activities = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE, 'Activity', $extraSql); } $options = _civicrm_api3_get_options_from_params($params, FALSE, 'Activity', 'get'); if ($options['is_count']) { @@ -280,6 +298,7 @@ function _civicrm_api3_activity_get_formatResult($params, $activities) { $returns[$returnkey] = $v; } } + $returns['source_contact_id'] = 1; foreach ($returns as $n => $v) { switch ($n) { diff --git a/api/v3/Dashboard.php b/api/v3/Dashboard.php index c29b660401..9ab5dcbdb5 100644 --- a/api/v3/Dashboard.php +++ b/api/v3/Dashboard.php @@ -72,6 +72,7 @@ function _civicrm_api3_dashboard_create_spec(&$params) { * @return array */ function civicrm_api3_dashboard_get($params) { + // NEVER COPY THIS. No idea why a newish api would not use basic_get. $bao = new CRM_Core_BAO_Dashboard(); _civicrm_api3_dao_set_filter($bao, $params, TRUE); $dashlets = _civicrm_api3_dao_to_array($bao, $params, TRUE, 'Dashboard'); diff --git a/api/v3/Event.php b/api/v3/Event.php index d303979b4f..0407881d93 100644 --- a/api/v3/Event.php +++ b/api/v3/Event.php @@ -132,6 +132,9 @@ function civicrm_api3_event_get($params) { $events = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE, 'Event', $extraSql, TRUE); $options = _civicrm_api3_get_options_from_params($params); + if ($options['is_count']) { + return civicrm_api3_create_success($events, $params, 'Event', 'get'); + } foreach ($events as $id => $event) { if (!empty($params['return.is_full'])) { _civicrm_api3_event_getisfull($events, $id); @@ -139,7 +142,6 @@ function civicrm_api3_event_get($params) { _civicrm_api3_event_get_legacy_support_42($events, $id); if (!empty($options['return'])) { $events[$id]['price_set_id'] = CRM_Price_BAO_PriceSet::getFor('civicrm_event', $id); - print_r($events); } } diff --git a/api/v3/WordReplacement.php b/api/v3/WordReplacement.php index 8ac602784a..62002c16e6 100644 --- a/api/v3/WordReplacement.php +++ b/api/v3/WordReplacement.php @@ -43,6 +43,7 @@ * @throws \API_Exception */ function civicrm_api3_word_replacement_get($params) { + // NEVER COPY THIS. No idea why a newish api would not use basic_get. $bao = new CRM_Core_BAO_WordReplacement(); _civicrm_api3_dao_set_filter($bao, $params, TRUE); $wordReplacements = _civicrm_api3_dao_to_array($bao, $params, TRUE, 'WordReplacement'); diff --git a/api/v3/utils.php b/api/v3/utils.php index 16a3fd7e83..30bdcac6e0 100644 --- a/api/v3/utils.php +++ b/api/v3/utils.php @@ -480,6 +480,7 @@ function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFiel $entity = _civicrm_api_get_entity_name_from_dao($dao); $custom_fields = _civicrm_api3_custom_fields_for_entity($entity); $options = _civicrm_api3_get_options_from_params($params); + // Unset $params['options'] if they are api parameters (not options as a fieldname). if (!empty($params['options']) && is_array($params['options'])&& array_intersect(array_keys($params['options']), array_keys($options))) { unset ($params['options']); @@ -487,8 +488,14 @@ function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFiel $entity_field_names = _civicrm_api3_field_names(_civicrm_api3_build_fields_array($dao)); $custom_field_names = array(); + $uniqueAliases = array(); $getFieldsResult = civicrm_api3($entity, 'getfields', array('action' => 'get')); $getFieldsResult = $getFieldsResult['values']; + foreach ($getFieldsResult as $getFieldKey => $getFieldSpec) { + $uniqueAliases[$getFieldKey] = $getFieldSpec['name']; + $uniqueAliases[$getFieldSpec['name']] = $getFieldSpec['name']; + } + // $select_fields maps column names to the field names of the result // values. $select_fields = array(); @@ -504,12 +511,13 @@ function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFiel // populate $select_fields $return_all_fields = (empty($options['return']) || !is_array($options['return'])); + $return = $return_all_fields ? array_fill_keys($entity_field_names, 1) : $options['return']; // default fields - foreach ($entity_field_names as $field_name) { - if ($return_all_fields || !empty($options['return'][$field_name])) { + foreach (array_keys($return) as $field_name) { + if (!empty($uniqueAliases[$field_name]) && substr($field_name, 0, 7) != 'custom_') { // 'a.' is an alias for the entity table. - $select_fields["a.$field_name"] = $field_name; + $select_fields["a.{$uniqueAliases[$field_name]}"] = $uniqueAliases[$field_name]; } } @@ -553,10 +561,52 @@ function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFiel // populate $where_clauses foreach ($params as $key => $value) { $type = 'String'; + $table_name = NULL; + $column_name = NULL; + + if (substr($key, 0, 7) == 'filter.') { + // Legacy support for old filter syntax per the test contract. + // (Convert the style to the later one & then deal with them). + $filterArray = explode('.', $key); + $value = array($filterArray[1] => $value); + $key = 'filters'; + } + + // Legacy support for 'filter's construct. + if ($key == 'filters') { + foreach ($value as $filterKey => $filterValue) { + if (substr($filterKey, -4, 4) == 'high') { + $key = substr($filterKey, 0, -5); + $value = array('<=' => $filterValue); + } + + if (substr($filterKey, -3, 3) == 'low') { + $key = substr($filterKey, 0, -4); + $value = array('>=' => $filterValue); + } + + if ($filterKey == 'is_current' || $filterKey == 'isCurrent') { + // Is current is almost worth creating as a 'sql filter' in the DAO function since several entities have the + // concept. + $todayStart = date('Ymd000000', strtotime('now')); + $todayEnd = date('Ymd235959', strtotime('now')); + $query->where(array("(a.start_date <= '$todayStart' OR a.start_date IS NULL) AND (a.end_date >= '$todayEnd' OR + a.end_date IS NULL) + AND a.is_active = 1 + ")); + } + } + } + if (array_key_exists($key, $getFieldsResult)) { $type = $getFieldsResult[$key]['type']; $key = $getFieldsResult[$key]['name']; } + if ($key == _civicrm_api_get_entity_name_from_camel($entity) . '_id') { + // The test contract enforces support of (eg) mailing_group_id if the entity is MailingGroup. + $type = 'int'; + $key = 'id'; + } if (in_array($key, $entity_field_names)) { $table_name = 'a'; $column_name = $key; @@ -571,7 +621,7 @@ function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFiel } // I don't know why I had to specifically exclude 0 as a key - wouldn't the others have caught it? // We normally silently ignore null values passed in - if people want IS_NULL they can use acceptedSqlOperator syntax. - if ((!in_array($key, $entity_field_names) && !in_array($key, $custom_field_names)) || empty($key) || is_null($value)) { + if ((!$table_name) || empty($key) || is_null($value)) { // No valid filter field. This might be a chained call or something. // Just ignore this for the $where_clause. continue; @@ -649,9 +699,18 @@ function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFiel )); } }; - if (!empty($extraMysql['where'])) { - foreach ($extraMysql['where'] as $extraWhere) { - $query->where($extraWhere); + if (!empty($extraMysql)) { + foreach ($extraMysql as $type => $extraClauses) { + foreach ($extraClauses as $clauseKey => $clause) { + if ($type == 'join') { + foreach ($clause as $joinName => $join) { + $query->$type($joinName, $join); + } + } + else { + $query->$type($clause); + } + } } } @@ -662,7 +721,7 @@ function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFiel $words = preg_split("/[\s]+/", $sort_option); if (count($words) > 0 && in_array($words[0], array_values($select_fields))) { $tmp = $words[0]; - if (strtoupper($words[1]) == 'DESC') { + if (!empty($words[1]) && strtoupper($words[1]) == 'DESC') { $tmp .= " DESC"; } $sort_fields[] = $tmp; @@ -688,7 +747,7 @@ function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFiel } $result_entities[$result_dao->id] = array(); foreach ($select_fields as $column => $alias) { - if (property_exists($result_dao, $alias)) { + if (property_exists($result_dao, $alias) && $result_dao->$alias != NULL) { $result_entities[$result_dao->id][$alias] = $result_dao->$alias; } // Backward compatibility on fields names. @@ -696,10 +755,6 @@ function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFiel $result_entities[$result_dao->id][$getFieldsResult['values'][$column]['uniqueName']] = $result_dao->$alias; } foreach ($getFieldsResult as $returnName => $spec) { - $castToInt = FALSE; - if (!empty($spec['type']) && $spec['type'] == CRM_Utils_Type::T_INT) { - $castToInt = TRUE; - } if (empty($result_entities[$result_dao->id][$returnName]) && !empty($result_entities[$result_dao->id][$spec['name']])) { $result_entities[$result_dao->id][$returnName] = $result_entities[$result_dao->id][$spec['name']]; } @@ -935,6 +990,8 @@ function _civicrm_api3_get_query_object($params, $mode, $entity) { /** * Function transfers the filters being passed into the DAO onto the params object. * + * @deprecated DAO based retrieval is being phased out. + * * @param CRM_Core_DAO $dao * @param array $params * @param bool $unique @@ -1246,6 +1303,8 @@ function _civicrm_api3_get_unique_name_array(&$bao) { /** * Converts an DAO object to an array. * + * @deprecated - DAO based retrieval is being phased out. + * * @param CRM_Core_DAO $dao * Object to convert. * @param array $params diff --git a/tests/phpunit/api/v3/MembershipTest.php b/tests/phpunit/api/v3/MembershipTest.php index e31e2dc753..26d9d0ee3f 100644 --- a/tests/phpunit/api/v3/MembershipTest.php +++ b/tests/phpunit/api/v3/MembershipTest.php @@ -596,13 +596,13 @@ class api_v3_MembershipTest extends CiviUnitTestCase { } /** - * We are checking for no enotices + only id & end_date returned + * We are checking for no e-notices + only id & end_date returned */ public function testMembershipGetWithReturn() { $this->contactMembershipCreate($this->_params); $result = $this->callAPISuccess('membership', 'get', array('return' => 'end_date')); foreach ($result['values'] as $membership) { - $this->assertEquals(array('id', 'end_date'), array_keys($membership)); + $this->assertEquals(array('end_date', 'membership_end_date', 'id'), array_keys($membership)); } } ///////////////// civicrm_membership_create methods diff --git a/tests/phpunit/api/v3/SyntaxConformanceTest.php b/tests/phpunit/api/v3/SyntaxConformanceTest.php index ae4aa2d859..70627208a7 100644 --- a/tests/phpunit/api/v3/SyntaxConformanceTest.php +++ b/tests/phpunit/api/v3/SyntaxConformanceTest.php @@ -1187,9 +1187,9 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { $entity[$fieldName] = (string) $entity2['id']; } else { - $uniqueName = CRM_Utils_Array::value('uniqueName', $specs); + $uniqueName = CRM_Utils_Array::value('uniqueName', $specs, $fieldName); if (!empty($entity[$fieldName])) { - $resetFKTo = array($fieldName => $entity[$fieldName]); + $resetFKTo = array($fieldName => $entity[$fieldName], $uniqueName => $entity[$fieldName]); } $entity[$fieldName] = (string) empty($entity2[$field]) ? CRM_Utils_Array::value($uniqueName, $entity2) : $entity2[$field]; //todo - there isn't always something set here - & our checking on unset values is limited @@ -1248,6 +1248,10 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { $entity['contribution_type_id'] = $updateParams['financial_type_id']; } + if (!empty($specs['uniqueName'])) { + $entity[$specs['uniqueName']] = $entity[$specs['name']]; + } + $update = $this->callAPISuccess($entityName, 'create', $updateParams); $checkParams = array( 'id' => $entity['id'], @@ -1260,6 +1264,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { ); $checkEntity = $this->callAPISuccess($entityName, 'getsingle', $checkParams); + $this->assertAPIArrayComparison($entity, $checkEntity, array(), "checking if $fieldName was correctly updated\n" . print_r(array( 'update-params' => $updateParams, 'update-result' => $update, -- 2.25.1