From a14e9d0882bc313f0c7822d04b33eb0d885997e4 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 9 Oct 2014 22:52:14 -0400 Subject: [PATCH] CRM-15417 - Display deprecation notices in api output and api explorer --- Civi/API/Provider/ReflectionProvider.php | 8 +- api/v3/ActivityType.php | 15 ++-- api/v3/Case.php | 13 ++- api/v3/Constant.php | 100 +++++++++++++---------- api/v3/Contact.php | 10 ++- api/v3/Entity.php | 17 ++++ api/v3/Generic.php | 2 +- api/v3/Generic/Getactions.php | 2 +- api/v3/GroupContact.php | 12 +++ api/v3/Mailing.php | 8 ++ api/v3/MailingGroup.php | 10 ++- api/v3/Profile.php | 11 +++ api/v3/SurveyRespondant.php | 8 ++ api/v3/utils.php | 36 +++++++- templates/CRM/Admin/Page/APIExplorer.js | 44 ++++++++-- templates/CRM/Admin/Page/APIExplorer.tpl | 6 +- 16 files changed, 231 insertions(+), 71 deletions(-) diff --git a/Civi/API/Provider/ReflectionProvider.php b/Civi/API/Provider/ReflectionProvider.php index 676458faea..24ec10d2f8 100644 --- a/Civi/API/Provider/ReflectionProvider.php +++ b/Civi/API/Provider/ReflectionProvider.php @@ -63,7 +63,9 @@ class ReflectionProvider implements EventSubscriberInterface, ProviderInterface public function __construct($apiKernel) { $this->apiKernel = $apiKernel; $this->actions = array( + // FIXME: We really need to deal with the api's lack of uniformity wrt case (Entity or entity) 'Entity' => array('get', 'getactions'), + 'entity' => array('get', 'getactions'), '*' => array('getactions'), // 'getfields' ); } @@ -99,12 +101,12 @@ class ReflectionProvider implements EventSubscriberInterface, ProviderInterface * {inheritdoc} */ public function invoke($apiRequest) { - if ($apiRequest['entity'] == 'Entity' && $apiRequest['action'] == 'get') { - return civicrm_api3_create_success($this->apiKernel->getEntityNames($apiRequest['version'])); + if (strtolower($apiRequest['entity']) == 'entity' && $apiRequest['action'] == 'get') { + return civicrm_api3_create_success($this->apiKernel->getEntityNames($apiRequest['version']), $apiRequest['params'], 'entity', 'get'); } switch ($apiRequest['action']) { case 'getactions': - return civicrm_api3_create_success($this->apiKernel->getActionNames($apiRequest['version'], $apiRequest['entity'])); + return civicrm_api3_create_success($this->apiKernel->getActionNames($apiRequest['version'], $apiRequest['entity']), $apiRequest['params'], $apiRequest['entity'], $apiRequest['action']); // case 'getfields': // return $this->doGetFields($apiRequest); default: diff --git a/api/v3/ActivityType.php b/api/v3/ActivityType.php index 8a9328777e..2805c9b65d 100644 --- a/api/v3/ActivityType.php +++ b/api/v3/ActivityType.php @@ -26,10 +26,7 @@ */ /** - * Definition of the ActivityType part of the CRM API. - * More detailed documentation can be found - * {@link http://objectledge.org/confluence/display/CRM/CRM+v1.0+Public+APIs - * here} + * @deprecated * * @package CiviCRM_APIv3 * @subpackage API_Activity @@ -39,6 +36,14 @@ * */ +/** + * @deprecated api notice + * @return string to indicate this entire api entity is deprecated + */ +function _civicrm_api3_activity_type_deprecation() { + return 'The activity_type api is deprecated. Please use the option_value api instead.'; +} + /** * Function to retrieve activity types * @@ -66,7 +71,7 @@ function civicrm_api3_activity_type_get($params) { * * @access public * - * @deprecated - we will introduce OptionValue Create - plse consider helping with this if not done + * @deprecated - use option_value create */ function civicrm_api3_activity_type_create($params) { diff --git a/api/v3/Case.php b/api/v3/Case.php index 3f1f55acea..d76b1afa24 100644 --- a/api/v3/Case.php +++ b/api/v3/Case.php @@ -273,7 +273,18 @@ SELECT DISTINCT case_id * @return array */ function civicrm_api3_case_activity_create($params) { - return civicrm_api3_activity_create($params); + require_once "api/v3/Activity.php"; + return civicrm_api3_activity_create($params) + array( + 'deprecated' => CRM_Utils_Array::value('activity_create', _civicrm_api3_case_deprecation()), + ); +} + +/** + * @deprecated api notice + * @return array of deprecated actions + */ +function _civicrm_api3_case_deprecation() { + return array('activity_create' => 'Case api "activity_create" action is deprecated. Use the activity api instead.'); } /** diff --git a/api/v3/Constant.php b/api/v3/Constant.php index 93fcfcb68f..f242307ebc 100644 --- a/api/v3/Constant.php +++ b/api/v3/Constant.php @@ -36,6 +36,14 @@ * @version $Id: Constant.php 30171 2010-10-14 09:11:27Z mover $ */ +/** + * @deprecated api notice + * @return string to indicate this entire api entity is deprecated + */ +function _civicrm_api3_constant_deprecation() { + return 'The constant api is deprecated as of CiviCRM 4.4. Please use the getoptions api action instead.'; +} + /** * @deprecated as of CiviCRM 4.4. * It's recommended to use the api getoptions action instead @@ -117,12 +125,12 @@ function civicrm_api3_constant_get($params) { //@TODO XAV take out the param the COOKIE, Entity, Action and so there are only the "real param" in it //$values = call_user_func_array( array( $className, $name ), $params ); } - return civicrm_api3_create_success($values, $params); + return civicrm_api3_create_success($values, $params, 'constant'); } else{ $values = call_user_func(array('CRM_Utils_PseudoConstant', 'getConstant'), $name); if(!empty($values)){ - return civicrm_api3_create_success($values, $params); + return civicrm_api3_create_success($values, $params, 'constant'); } } return civicrm_api3_create_error('Unknown civicrm constant or method not callable'); @@ -132,53 +140,55 @@ function civicrm_api3_constant_get($params) { * @param $params */ function _civicrm_api3_constant_get_spec(&$params) { - + $options = array( + 'activityStatus', + 'activityType', + 'addressee', + 'allGroup', + 'country', + 'countryIsoCode', + 'county', + 'currencyCode', + 'currencySymbols', + 'customGroup', + 'emailGreeting', + 'fromEmailAddress', + 'gender', + 'group', + 'groupIterator', + 'honor', + 'IMProvider', + 'individualPrefix', + 'individualSuffix', + 'locationType', + 'locationVcardName', + 'mailProtocol', + 'mappingTypes', + 'paymentInstrument', + 'paymentProcessor', + 'paymentProcessorType', + 'pcm', + 'phoneType', + 'postalGreeting', + 'priority', + 'relationshipType', + 'stateProvince', + 'stateProvinceAbbreviation', + 'stateProvinceForCountry', + 'staticGroup', + 'tag', + 'tasks', + 'ufGroup', + 'visibility', + 'worldRegion', + 'wysiwygEditor', + ); $params = (array ('name' => array( 'title' => 'Constant Name', + 'name' => 'name', 'api.required' => 1, - 'options' => - 'activityStatus', - 'activityType', - 'addressee', - 'allGroup', - 'country', - 'countryIsoCode', - 'county', - 'currencyCode', - 'currencySymbols', - 'customGroup', - 'emailGreeting', - 'fromEmailAddress', - 'gender', - 'group', - 'groupIterator', - 'honor', - 'IMProvider', - 'individualPrefix', - 'individualSuffix', - 'locationType', - 'locationVcardName', - 'mailProtocol', - 'mappingTypes', - 'paymentInstrument', - 'paymentProcessor', - 'paymentProcessorType', - 'pcm', - 'phoneType', - 'postalGreeting', - 'priority', - 'relationshipType', - 'stateProvince', - 'stateProvinceAbbreviation', - 'stateProvinceForCountry', - 'staticGroup', - 'tag', - 'tasks', - 'ufGroup', - 'visibility', - 'worldRegion', - 'wysiwygEditor', + 'options' => array_combine($options, $options) )) ); } diff --git a/api/v3/Contact.php b/api/v3/Contact.php index bd8656691d..e287cb21e3 100644 --- a/api/v3/Contact.php +++ b/api/v3/Contact.php @@ -835,7 +835,15 @@ LIMIT 0, {$limit} } } - return civicrm_api3_create_success($contactList, $params); + return civicrm_api3_create_success($contactList, $params, 'contact', 'getquick'); +} + +/** + * @deprecated api notice + * @return array of deprecated actions + */ +function _civicrm_api3_contact_deprecation() { + return array('getquick' => 'The "getquick" action is deprecated in favor of "getlist".'); } /** diff --git a/api/v3/Entity.php b/api/v3/Entity.php index e0c30dbf80..204dd3ae01 100644 --- a/api/v3/Entity.php +++ b/api/v3/Entity.php @@ -1,5 +1,22 @@ get('magic_function_provider'); $actions = $mfp->getActionNames($apiRequest['version'], $apiRequest['entity']); - return civicrm_api3_create_success($actions); + return civicrm_api3_create_success($actions, $apiRequest['params'], $apiRequest['entity'], 'getactions'); } diff --git a/api/v3/GroupContact.php b/api/v3/GroupContact.php index aa64298807..83282fde0e 100644 --- a/api/v3/GroupContact.php +++ b/api/v3/GroupContact.php @@ -236,3 +236,15 @@ function civicrm_api3_group_contact_update_status($params) { return TRUE; } +/** + * @deprecated api notice + * @return array of deprecated actions + */ +function _civicrm_api3_group_contact_deprecation() { + return array( + 'delete' => 'GroupContact "delete" action is deprecated in favor of "create".', + 'pending' => 'GroupContact "pending" action is deprecated in favor of "create".', + 'update_status' => 'GroupContact "update_status" action is deprecated in favor of "create".', + ); +} + diff --git a/api/v3/Mailing.php b/api/v3/Mailing.php index 62bac6e308..74f7d8fc9e 100644 --- a/api/v3/Mailing.php +++ b/api/v3/Mailing.php @@ -145,6 +145,14 @@ function civicrm_api3_mailing_event_confirm($params) { return civicrm_api('mailing_event_confirm', 'create', $params); } +/** + * @deprecated api notice + * @return array of deprecated actions + */ +function _civicrm_api3_mailing_deprecation() { + return array('event_confirm' => 'Mailing api "event_confirm" action is deprecated. Use the mailing_event_confirm api instead.'); +} + /** * Handle a reply event * diff --git a/api/v3/MailingGroup.php b/api/v3/MailingGroup.php index c042a393cf..490a793649 100644 --- a/api/v3/MailingGroup.php +++ b/api/v3/MailingGroup.php @@ -37,6 +37,14 @@ * */ +/** + * @deprecated api notice + * @return string to indicate this entire api entity is deprecated + */ +function _civicrm_api3_mailing_group_deprecation() { + return 'The mailing_group api is deprecated. Use the mailing_event apis instead.'; +} + /** * Handle an unsubscribe event * @deprecated @@ -108,6 +116,6 @@ function civicrm_api3_mailing_group_getfields($params) { unset($field['pseudoconstant']); } - return civicrm_api3_create_success($fields); + return civicrm_api3_create_success($fields, $params, 'mailing_group'); } diff --git a/api/v3/Profile.php b/api/v3/Profile.php index 04eb431457..7553d0765f 100644 --- a/api/v3/Profile.php +++ b/api/v3/Profile.php @@ -732,3 +732,14 @@ function _civicrm_api3_profile_appendaliases($values, $entity) { } return $values; } + +/** + * @deprecated api notice + * @return array of deprecated actions + */ +function _civicrm_api3_profile_deprecation() { + return array( + 'set' => 'Profile api "set" action is deprecated in favor of "submit".', + 'apply' => 'Profile api "apply" action is deprecated in favor of "submit".', + ); +} diff --git a/api/v3/SurveyRespondant.php b/api/v3/SurveyRespondant.php index b81ca55af5..381a6dd1fa 100644 --- a/api/v3/SurveyRespondant.php +++ b/api/v3/SurveyRespondant.php @@ -33,6 +33,14 @@ * @subpackage API_Survey */ +/** + * @deprecated api notice + * @return string to indicate this entire api entity is deprecated + */ +function _civicrm_api3_survey_respondant_deprecation() { + return 'The survey_respondant api is not currently supported.'; +} + /** * Get the list of signatories * diff --git a/api/v3/utils.php b/api/v3/utils.php index 37d232a6e8..4ad728ec49 100644 --- a/api/v3/utils.php +++ b/api/v3/utils.php @@ -164,7 +164,7 @@ function civicrm_api3_create_success($values = 1, $params = array(), $entity = N $result = array(); $result['is_error'] = 0; //lets set the ['id'] field if it's not set & we know what the entity is - if (is_array($values) && !empty($entity)) { + if (is_array($values) && !empty($entity) && $action != 'getfields') { foreach ($values as $key => $item) { if (empty($item['id']) && !empty($item[$entity . "_id"])) { $values[$key]['id'] = $item[$entity . "_id"]; @@ -233,11 +233,27 @@ function civicrm_api3_create_success($values = 1, $params = array(), $entity = N } if(!empty($params['options']['metadata'])) { // we've made metadata an array but only supporting 'fields' atm - if(in_array('fields', (array) $params['options']['metadata'])) { + if(in_array('fields', (array) $params['options']['metadata']) && $action !== 'getfields') { $fields = civicrm_api3($entity, 'getfields', array('action' => substr($action, 0, 3) == 'get' ? 'get' : 'create')); $result['metadata']['fields'] = $fields['values']; } } + // Report deprecations + $deprecated = _civicrm_api3_deprecation_check($entity, $result); + // Always report "update" action as deprecated + if (!is_string($deprecated) && ($action == 'getactions' || $action == 'update')) { + $deprecated = ((array) $deprecated) + array('update' => 'The "update" action is deprecated. Use "create" with an id instead.'); + } + if ($deprecated) { + // Metadata-level deprecations or wholesale entity deprecations + if ($entity == 'entity' || $action == 'getactions' || is_string($deprecated)) { + $result['deprecated'] = $deprecated; + } + // Action-specific deprecations + elseif (!empty($deprecated[$action])) { + $result['deprecated'] = $deprecated[$action]; + } + } return array_merge($result, $extraReturnValues); } @@ -1954,3 +1970,19 @@ function _civicrm_api3_api_resolve_alias($entity, $fieldName) { } return FALSE; } + +/** + * @param string $entity + * @param array $result + */ +function _civicrm_api3_deprecation_check($entity, $result = array()) { + $apiFile = 'api/v3/' . _civicrm_api_get_camel_name($entity) . '.php'; + if (CRM_Utils_File::isIncludable($apiFile)) { + require_once $apiFile; + } + $entity = _civicrm_api_get_entity_name_from_camel($entity); + $fnName = "_civicrm_api3_{$entity}_deprecation"; + if (function_exists($fnName)) { + return $fnName($result); + } +} diff --git a/templates/CRM/Admin/Page/APIExplorer.js b/templates/CRM/Admin/Page/APIExplorer.js index 729d7c6d4e..39ec4f6e6a 100644 --- a/templates/CRM/Admin/Page/APIExplorer.js +++ b/templates/CRM/Admin/Page/APIExplorer.js @@ -2,7 +2,7 @@ var entity, action, - actions = ['get'], + actions = {values: ['get']}, fields = [], getFieldData = {}, options = {}, @@ -77,7 +77,7 @@ /** * Fetch fields for entity+action */ - function getFields() { + function getFields(changedElement) { var required = []; fields = []; options = getFieldData = {}; @@ -108,6 +108,9 @@ } } }); + if ($(changedElement).is('#api-entity') && data.deprecated) { + CRM.alert(data.deprecated, entity + ' Deprecated'); + } showFields(required); if (action === 'get' || action === 'getsingle') { showReturn(); @@ -130,15 +133,22 @@ if (entity) { $('#api-action').addClass('loading'); CRM.api3(entity, 'getactions').done(function(data) { - actions = data.values || ['get']; + actions = data; populateActions(); }); } else { - actions = ['get']; + actions = {values: ['get']}; populateActions(); } } + function renderAction(option) { + if (actions.deprecated && actions.deprecated[option.id]) { + return '' + option.text + ''; + } + return option.text; + } + /** * Called after getActions to populate action list * @param el @@ -146,11 +156,19 @@ function populateActions(el) { var val = $('#api-action').val(); $('#api-action').removeClass('loading').select2({ - data: _.transform(actions, function(ret, item) {ret.push({text: item, id: item})}) + data: _.transform(actions.values, function(ret, item) {ret.push({text: item, id: item})}), + formatSelection: renderAction, + formatResult: renderAction }); // If previously selected action is not available, set it to 'get' if possible - if (_.indexOf(actions, val) < 0) { - $('#api-action').select2('val', _.indexOf(actions, 'get') < 0 ? actions[0] : 'get', true); + if (_.indexOf(actions.values, val) < 0) { + $('#api-action').select2('val', _.indexOf(actions.values, 'get') < 0 ? actions.values[0] : 'get', true); + } + } + + function onChangeAction(action) { + if (actions.deprecated && actions.deprecated[action]) { + CRM.alert(actions.deprecated[action], action + ' deprecated'); } } @@ -449,17 +467,25 @@ } $(document).ready(function() { + $('#api-entity').crmSelect2({ + // Add strikethough class to selection to indicate deprecated apis + formatSelection: function(option) { + return $(option.element).hasClass('strikethrough') ? '' + option.text + '' : option.text; + } + }); $('form#api-explorer') .on('change', '#api-entity, #api-action', function() { entity = $('#api-entity').val(); + action = $('#api-action').val(); if ($(this).is('#api-entity')) { getActions(); + } else { + onChangeAction(action); } - action = $('#api-action').val(); if (entity && action) { $('#api-params').html(''); $('#api-params-table thead').show(); - getFields(); + getFields(this); buildParams(); } else { $('#api-params, #api-generated pre').empty(); diff --git a/templates/CRM/Admin/Page/APIExplorer.tpl b/templates/CRM/Admin/Page/APIExplorer.tpl index 6fbf0306d6..35630105d8 100644 --- a/templates/CRM/Admin/Page/APIExplorer.tpl +++ b/templates/CRM/Admin/Page/APIExplorer.tpl @@ -85,11 +85,13 @@
- {crmAPI entity="Entity" action="get" var="entities" version=3} {foreach from=$entities.values item=entity} - + {/foreach}    -- 2.25.1