diff --git a/Civi/API/Kernel.php b/Civi/API/Kernel.php index 596fdada7266..4b88edddaf7a 100644 --- a/Civi/API/Kernel.php +++ b/Civi/API/Kernel.php @@ -86,15 +86,8 @@ public function run($entity, $action, $params, $extra = NULL) { * @throws \API_Exception */ public function runSafe($entity, $action, $params, $extra = NULL) { - // TODO Define alternative calling convention makes it easier to construct $apiRequest - // without the ambiguity of "data" vs "options" $apiRequest = Request::create($entity, $action, $params, $extra); - /** - * @var $apiProvider \Civi\API\Provider\ProviderInterface|NULL - */ - $apiProvider = NULL; - try { $apiResponse = $this->runRequest($apiRequest); return $this->formatResult($apiRequest, $apiResponse); @@ -159,9 +152,7 @@ public function runAuthorize($entity, $action, $params, $extra = NULL) { * @throws \Civi\API\Exception\UnauthorizedException */ public function runRequest($apiRequest) { - $this->validate($apiRequest); - - $this->boot(); + $this->boot($apiRequest); $errorScope = \CRM_Core_TemporaryErrorScope::useException(); list($apiProvider, $apiRequest) = $this->resolve($apiRequest); @@ -169,17 +160,35 @@ public function runRequest($apiRequest) { $apiRequest = $this->prepare($apiProvider, $apiRequest); $result = $apiProvider->invoke($apiRequest); - $apiResponse = $this->respond($apiProvider, $apiRequest, $result); - return $apiResponse; + return $this->respond($apiProvider, $apiRequest, $result); } /** - * Bootstrap - Load basic dependencies. + * Bootstrap - Load basic dependencies and sanity-check inputs. + * + * @param \Civi\API\V4\Action|array $apiRequest + * @throws \API_Exception */ - public function boot() { - require_once 'api/v3/utils.php'; + public function boot($apiRequest) { require_once 'api/Exception.php'; - _civicrm_api3_initialize(); + + if (!is_array($apiRequest['params'])) { + throw new \API_Exception('Input variable `params` is not an array', 2000); + } + switch ($apiRequest['version']) { + case 2: + case 3: + require_once 'api/v3/utils.php'; + _civicrm_api3_initialize(); + break; + + case 4: + // nothing to do + break; + + default: + throw new \API_Exception('Unknown api version', 2000); + } } /** @@ -187,11 +196,6 @@ public function boot() { * @throws \API_Exception */ protected function validate($apiRequest) { - if ($apiRequest['version'] === 3) { - if (!is_array($apiRequest['params'])) { - throw new \API_Exception('Input variable `params` is not an array', 2000); - } - } } /** diff --git a/Civi/API/Request.php b/Civi/API/Request.php index 361ac5a8a588..f30962d1a735 100644 --- a/Civi/API/Request.php +++ b/Civi/API/Request.php @@ -59,83 +59,56 @@ class Request { * - chains: unspecified derived from params [v4-only] */ public static function create($entity, $action, $params, $extra = NULL) { - $version = self::parseVersion($params); - + $version = \CRM_Utils_Array::value('version', $params); switch ($version) { - case 2: - case 3: - $apiRequest = array(); // new \Civi\API\Request(); + default: + $apiRequest = array(); $apiRequest['id'] = self::$nextId++; - $apiRequest['version'] = $version; + $apiRequest['version'] = (int) $version; $apiRequest['params'] = $params; $apiRequest['extra'] = $extra; $apiRequest['fields'] = NULL; - - $apiRequest['entity'] = $entity = self::normalizeEntityName($entity, $apiRequest['version']); - $apiRequest['action'] = $action = self::normalizeActionName($action, $apiRequest['version']); - + $apiRequest['entity'] = self::normalizeEntityName($entity, $apiRequest['version']); + $apiRequest['action'] = self::normalizeActionName($action, $apiRequest['version']); return $apiRequest; case 4: $apiCall = call_user_func(array("Civi\\Api4\\$entity", $action)); + $apiRequest['id'] = self::$nextId++; unset($params['version']); foreach ($params as $name => $param) { $setter = 'set' . ucfirst($name); $apiCall->$setter($param); } return $apiCall; - - default: } } /** - * Normalize/validate entity and action names + * Normalize entity to be CamelCase. + * + * APIv1-v3 munges entity/action names, and accepts any mixture of case and underscores. * * @param string $entity * @param int $version * @return string - * @throws \API_Exception */ public static function normalizeEntityName($entity, $version) { - if ($version <= 3) { - // APIv1-v3 munges entity/action names, and accepts any mixture of case and underscores. - // We normalize entity to be CamelCase. - return \CRM_Utils_String::convertStringToCamel(\CRM_Utils_String::munge($entity)); - } - else { - throw new \API_Exception("Unknown api version"); - } - } - - public static function normalizeActionName($action, $version) { - if ($version <= 3) { - // APIv1-v3 munges entity/action names, and accepts any mixture of case and underscores. - // We normalize action to be lowercase. - return strtolower(\CRM_Utils_String::munge($action)); - } - else { - throw new \API_Exception("Unknown api version"); - } + return \CRM_Utils_String::convertStringToCamel(\CRM_Utils_String::munge($entity)); } /** - * We must be sure that every request uses only one version of the API. + * Normalize api action name to be lowercase. * - * @param array $params - * API parameters. - * @return int + * APIv1-v3 munges entity/action names, and accepts any mixture of case and underscores. + * + * @param $action + * @param $version + * @return string */ - protected static function parseVersion($params) { - $desired_version = empty($params['version']) ? NULL : (int) $params['version']; - if (isset($desired_version) && is_int($desired_version)) { - return $desired_version; - } - else { - // we will set the default to version 3 as soon as we find that it works. - return 3; - } + public static function normalizeActionName($action, $version) { + return strtolower(\CRM_Utils_String::munge($action)); } } diff --git a/api/api.php b/api/api.php index 24afbb226219..1e45a143e628 100644 --- a/api/api.php +++ b/api/api.php @@ -20,7 +20,7 @@ * @return array|int */ function civicrm_api($entity, $action, $params, $extra = NULL) { - return \Civi::service('civi_api_kernel')->run($entity, $action, $params, $extra); + return \Civi::service('civi_api_kernel')->runSafe($entity, $action, $params, $extra); } /** @@ -40,7 +40,7 @@ function civicrm_api($entity, $action, $params, $extra = NULL) { */ function civicrm_api3($entity, $action, $params = array()) { $params['version'] = 3; - $result = \Civi::service('civi_api_kernel')->run($entity, $action, $params); + $result = \Civi::service('civi_api_kernel')->runSafe($entity, $action, $params); if (is_array($result) && !empty($result['is_error'])) { throw new CiviCRM_API3_Exception($result['error_message'], CRM_Utils_Array::value('error_code', $result, 'undefined'), $result); }