<?php
/*
+--------------------------------------------------------------------+
- | CiviCRM version 4.4 |
+ | CiviCRM version 4.6 |
+--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2013 |
+ | Copyright CiviCRM LLC (c) 2004-2015 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
-*/
+ */
namespace Civi\API;
use Civi\API\Event\AuthorizeEvent;
use Civi\API\Provider\ProviderInterface;
/**
- *
* @package Civi
- * @copyright CiviCRM LLC (c) 2004-2013
+ * @copyright CiviCRM LLC (c) 2004-2015
*/
-
class Kernel {
/**
protected $apiProviders;
/**
- * @param $dispatcher
+ * @param \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
+ * The event dispatcher which receives kernel events.
* @param array $apiProviders
+ * Array of ProviderInterface.
*/
- function __construct($dispatcher, $apiProviders = array()) {
+ public function __construct($dispatcher, $apiProviders = array()) {
$this->apiProviders = $apiProviders;
$this->dispatcher = $dispatcher;
}
/**
* @param string $entity
- * type of entities to deal with
+ * Type of entities to deal with.
* @param string $action
- * create, get, delete or some special action name.
+ * Create, get, delete or some special action name.
* @param array $params
- * array to be passed to function
- * @param null $extra
+ * Array to be passed to API function.
+ * @param mixed $extra
+ * Who knows.
*
* @return array|int
*/
return $this->formatResult($apiRequest, $apiResponse);
}
catch (\Exception $e) {
- $this->dispatcher->dispatch(Events::EXCEPTION, new ExceptionEvent($e, $apiProvider, $apiRequest));
+ $this->dispatcher->dispatch(Events::EXCEPTION, new ExceptionEvent($e, $apiProvider, $apiRequest, $this));
if ($e instanceof \PEAR_Exception) {
$err = $this->formatPearException($e, $apiRequest);
- } elseif ($e instanceof \API_Exception) {
+ }
+ elseif ($e instanceof \API_Exception) {
$err = $this->formatApiException($e, $apiRequest);
- } else {
+ }
+ else {
$err = $this->formatException($e, $apiRequest);
}
}
}
+ /**
+ * Determine if a hypothetical API call would be authorized.
+ *
+ * @param string $entity
+ * Type of entities to deal with.
+ * @param string $action
+ * Create, get, delete or some special action name.
+ * @param array $params
+ * Array to be passed to function.
+ * @param mixed $extra
+ * Who knows.
+ * @return bool
+ * TRUE if authorization would succeed.
+ * @throws \Exception
+ */
+ public function runAuthorize($entity, $action, $params, $extra = NULL) {
+ $apiProvider = NULL;
+ $apiRequest = Request::create($entity, $action, $params, $extra);
+
+ try {
+ $this->boot();
+ list($apiProvider, $apiRequest) = $this->resolve($apiRequest);
+ $this->authorize($apiProvider, $apiRequest);
+ return TRUE;
+ }
+ catch (\Civi\API\Exception\UnauthorizedException $e) {
+ return FALSE;
+ }
+ }
+
+ /**
+ * Bootstrap - Load basic dependencies.
+ */
public function boot() {
- require_once ('api/v3/utils.php');
+ require_once 'api/v3/utils.php';
require_once 'api/Exception.php';
_civicrm_api3_initialize();
}
* Determine which, if any, service will execute the API request.
*
* @param array $apiRequest
+ * The full description of the API request.
* @throws Exception\NotImplementedException
* @return array
+ * Array(0 => ProviderInterface, 1 => array).
*/
public function resolve($apiRequest) {
/** @var ResolveEvent $resolveEvent */
- $resolveEvent = $this->dispatcher->dispatch(Events::RESOLVE, new ResolveEvent($apiRequest));
+ $resolveEvent = $this->dispatcher->dispatch(Events::RESOLVE, new ResolveEvent($apiRequest, $this));
$apiRequest = $resolveEvent->getApiRequest();
if (!$resolveEvent->getApiProvider()) {
throw new \Civi\API\Exception\NotImplementedException("API (" . $apiRequest['entity'] . ", " . $apiRequest['action'] . ") does not exist (join the API team and implement it!)");
* Determine if the API request is allowed (under current policy)
*
* @param ProviderInterface $apiProvider
+ * The API provider responsible for executing the request.
* @param array $apiRequest
+ * The full description of the API request.
* @throws Exception\UnauthorizedException
*/
public function authorize($apiProvider, $apiRequest) {
/** @var AuthorizeEvent $event */
- $event = $this->dispatcher->dispatch(Events::AUTHORIZE, new AuthorizeEvent($apiProvider, $apiRequest));
+ $event = $this->dispatcher->dispatch(Events::AUTHORIZE, new AuthorizeEvent($apiProvider, $apiRequest, $this));
if (!$event->isAuthorized()) {
throw new \Civi\API\Exception\UnauthorizedException("Authorization failed");
}
* Allow third-party code to manipulate the API request before execution.
*
* @param ProviderInterface $apiProvider
+ * The API provider responsible for executing the request.
* @param array $apiRequest
+ * The full description of the API request.
* @return mixed
*/
public function prepare($apiProvider, $apiRequest) {
/** @var PrepareEvent $event */
- $event = $this->dispatcher->dispatch(Events::PREPARE, new PrepareEvent($apiProvider, $apiRequest));
+ $event = $this->dispatcher->dispatch(Events::PREPARE, new PrepareEvent($apiProvider, $apiRequest, $this));
return $event->getApiRequest();
}
* Allow third-party code to manipulate the API response after execution.
*
* @param ProviderInterface $apiProvider
+ * The API provider responsible for executing the request.
* @param array $apiRequest
+ * The full description of the API request.
* @param array $result
+ * The response to return to the client.
* @return mixed
*/
public function respond($apiProvider, $apiRequest, $result) {
/** @var RespondEvent $event */
- $event = $this->dispatcher->dispatch(Events::RESPOND, new RespondEvent($apiProvider, $apiRequest, $result));
+ $event = $this->dispatcher->dispatch(Events::RESPOND, new RespondEvent($apiProvider, $apiRequest, $result, $this));
return $event->getResponse();
}
/**
* @param int $version
- * @return array<string>
+ * API version.
+ * @return array
+ * Array<string>.
*/
public function getEntityNames($version) {
// Question: Would it better to eliminate $this->apiProviders and just use $this->dispatcher?
/**
* @param int $version
+ * API version.
* @param string $entity
- * @return array<string>
+ * API entity.
+ * @return array
+ * Array<string>
*/
public function getActionNames($version, $entity) {
// Question: Would it better to eliminate $this->apiProviders and just use $this->dispatcher?
/**
* @param \Exception $e
+ * An unhandled exception.
* @param array $apiRequest
- * @return array (API response)
+ * The full description of the API request.
+ * @return array
+ * API response.
*/
public function formatException($e, $apiRequest) {
$data = array();
/**
* @param \API_Exception $e
+ * An unhandled exception.
* @param array $apiRequest
- * @return array (API response)
+ * The full description of the API request.
+ * @return array
+ * (API response)
*/
public function formatApiException($e, $apiRequest) {
$data = $e->getExtraParams();
/**
* @param \PEAR_Exception $e
+ * An unhandled exception.
* @param array $apiRequest
- * @return array (API response)
+ * The full description of the API request.
+ * @return array
+ * API response.
*/
public function formatPearException($e, $apiRequest) {
$data = array();
/**
* @param string $msg
+ * Descriptive error message.
* @param array $data
+ * Error data.
* @param array $apiRequest
- * @param mixed $code doesn't appear to be used
+ * The full description of the API request.
+ * @param mixed $code
+ * Doesn't appear to be used.
*
* @throws \API_Exception
- * @return array <type>
+ * @return array
+ * Array<type>.
*/
- function createError($msg, $data, $apiRequest, $code = NULL) {
+ public function createError($msg, $data, $apiRequest, $code = NULL) {
// FIXME what to do with $code?
if ($msg == 'DB Error: constraint violation' || substr($msg, 0, 9) == 'DB Error:' || $msg == 'DB Error: already exists') {
try {
$fields = _civicrm_api3_api_getfields($apiRequest);
_civicrm_api3_validate_fields($apiRequest['entity'], $apiRequest['action'], $apiRequest['params'], $fields, TRUE);
- } catch (\Exception $e) {
+ }
+ catch (\Exception $e) {
$msg = $e->getMessage();
}
}
/**
* @param array $apiRequest
+ * The full description of the API request.
* @param array $result
+ * The response to return to the client.
* @return mixed
*/
public function formatResult($apiRequest, $result) {
/**
* @param array $apiProviders
+ * Array<ProviderInterface>.
* @return Kernel
*/
public function setApiProviders($apiProviders) {
/**
* @param ProviderInterface $apiProvider
+ * The API provider responsible for executing the request.
* @return Kernel
*/
public function registerApiProvider($apiProvider) {
/**
* @param \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
+ * The event dispatcher which receives kernel events.
* @return Kernel
*/
public function setDispatcher($dispatcher) {
$this->dispatcher = $dispatcher;
return $this;
}
+
}