unit test for case audit
[civicrm-core.git] / Civi / Api4 / Provider / ActionObjectProvider.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 namespace Civi\Api4\Provider;
13
14 use Civi\API\Event\ResolveEvent;
15 use Civi\API\Provider\ProviderInterface;
16 use Civi\Api4\Generic\AbstractAction;
17 use Civi\API\Events;
18 use Civi\Api4\Utils\ReflectionUtils;
19 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
20
21 /**
22 * Accept $apiRequests based on \Civi\API\Action
23 */
24 class ActionObjectProvider implements EventSubscriberInterface, ProviderInterface {
25
26 /**
27 * @return array
28 */
29 public static function getSubscribedEvents() {
30 // Using a high priority allows adhoc implementations
31 // to override standard implementations -- which is
32 // handy for testing/mocking.
33 return [
34 Events::RESOLVE => [
35 ['onApiResolve', Events::W_EARLY],
36 ],
37 ];
38 }
39
40 /**
41 * @param \Civi\API\Event\ResolveEvent $event
42 * API resolution event.
43 */
44 public function onApiResolve(ResolveEvent $event) {
45 $apiRequest = $event->getApiRequest();
46 if ($apiRequest instanceof AbstractAction) {
47 $event->setApiRequest($apiRequest);
48 $event->setApiProvider($this);
49 $event->stopPropagation();
50 }
51 }
52
53 /**
54 * @inheritDoc
55 *
56 * @param \Civi\Api4\Generic\AbstractAction $action
57 *
58 * @return \Civi\Api4\Generic\Result
59 */
60 public function invoke($action) {
61 // Load result class based on @return annotation in the execute() method.
62 $reflection = new \ReflectionClass($action);
63 $doc = ReflectionUtils::getCodeDocs($reflection->getMethod('execute'), 'Method');
64 $resultClass = \CRM_Utils_Array::value('return', $doc, '\\Civi\\Api4\\Generic\\Result');
65 $result = new $resultClass();
66 $result->action = $action->getActionName();
67 $result->entity = $action->getEntityName();
68 $action->_run($result);
69 $this->handleChains($action, $result);
70 return $result;
71 }
72
73 /**
74 * Run each chained action once per row
75 *
76 * @param \Civi\Api4\Generic\AbstractAction $action
77 * @param \Civi\Api4\Generic\Result $result
78 */
79 protected function handleChains($action, $result) {
80 foreach ($action->getChain() as $name => $request) {
81 $request += [NULL, NULL, [], NULL];
82 $request[2]['checkPermissions'] = $action->getCheckPermissions();
83 foreach ($result as &$row) {
84 $row[$name] = $this->runChain($request, $row);
85 }
86 }
87 }
88
89 /**
90 * Run a chained action
91 *
92 * @param $request
93 * @param $row
94 * @return array|\Civi\Api4\Generic\Result|null
95 * @throws \API_Exception
96 */
97 protected function runChain($request, $row) {
98 list($entity, $action, $params, $index) = $request;
99 // Swap out variables in $entity, $action & $params
100 $this->resolveChainLinks($entity, $row);
101 $this->resolveChainLinks($action, $row);
102 $this->resolveChainLinks($params, $row);
103 return (array) civicrm_api4($entity, $action, $params, $index);
104 }
105
106 /**
107 * Swap out variable names
108 *
109 * @param mixed $val
110 * @param array $result
111 */
112 protected function resolveChainLinks(&$val, $result) {
113 if (is_array($val)) {
114 foreach ($val as &$v) {
115 $this->resolveChainLinks($v, $result);
116 }
117 }
118 elseif (is_string($val) && strlen($val) > 1 && substr($val, 0, 1) === '$') {
119 $val = \CRM_Utils_Array::pathGet($result, explode('.', substr($val, 1)));
120 }
121 }
122
123 /**
124 * @inheritDoc
125 * @param int $version
126 * @return array
127 */
128 public function getEntityNames($version) {
129 /** FIXME */
130 return [];
131 }
132
133 /**
134 * @inheritDoc
135 * @param int $version
136 * @param string $entity
137 * @return array
138 */
139 public function getActionNames($version, $entity) {
140 /** FIXME Civi\API\V4\Action\GetActions */
141 return [];
142 }
143
144 }