Skip to content

Commit

Permalink
CRM-17867 - Api kernel refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
colemanw committed Feb 9, 2016
1 parent 93e1f1e commit 9485b89
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 69 deletions.
46 changes: 25 additions & 21 deletions Civi/API/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -159,39 +152,50 @@ 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);
$this->authorize($apiProvider, $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);
}
}

/**
* @param $apiRequest
* @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);
}
}
}

/**
Expand Down
65 changes: 19 additions & 46 deletions Civi/API/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

}
4 changes: 2 additions & 2 deletions api/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand All @@ -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);
}
Expand Down

0 comments on commit 9485b89

Please sign in to comment.