Commit | Line | Data |
---|---|---|
19b53e5b C |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
41498ac5 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
19b53e5b | 5 | | | |
41498ac5 TO |
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 | | |
19b53e5b C |
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 | } |