Commit | Line | Data |
---|---|---|
19b53e5b C |
1 | <?php |
2 | ||
380f3545 TO |
3 | /* |
4 | +--------------------------------------------------------------------+ | |
41498ac5 | 5 | | Copyright CiviCRM LLC. All rights reserved. | |
380f3545 | 6 | | | |
41498ac5 TO |
7 | | This work is published under the GNU AGPLv3 license with some | |
8 | | permitted exceptions and without any warranty. For full license | | |
9 | | and copyright information, see https://civicrm.org/licensing | | |
380f3545 TO |
10 | +--------------------------------------------------------------------+ |
11 | */ | |
12 | ||
13 | /** | |
14 | * | |
15 | * @package CRM | |
ca5cec67 | 16 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
380f3545 TO |
17 | * $Id$ |
18 | * | |
19 | */ | |
20 | ||
21 | ||
19b53e5b C |
22 | namespace Civi\Api4\Action; |
23 | ||
24 | use Civi\API\Exception\NotImplementedException; | |
25 | use Civi\Api4\Generic\BasicGetAction; | |
19b53e5b C |
26 | use Civi\Api4\Utils\ReflectionUtils; |
27 | ||
28 | /** | |
fc95d9a5 CW |
29 | * Get all API actions for the $ENTITY entity. |
30 | * | |
31 | * Includes a list of accepted parameters for each action, descriptions and other documentation. | |
19b53e5b C |
32 | */ |
33 | class GetActions extends BasicGetAction { | |
34 | ||
35 | private $_actions = []; | |
36 | ||
37 | private $_actionsToGet; | |
38 | ||
39 | protected function getRecords() { | |
40 | $this->_actionsToGet = $this->_itemsToGet('name'); | |
41 | ||
42 | $entityReflection = new \ReflectionClass('\Civi\Api4\\' . $this->_entityName); | |
43 | foreach ($entityReflection->getMethods(\ReflectionMethod::IS_STATIC | \ReflectionMethod::IS_PUBLIC) as $method) { | |
44 | $actionName = $method->getName(); | |
45 | if ($actionName != 'permissions' && $actionName[0] != '_') { | |
e15f9453 | 46 | $this->loadAction($actionName, $method); |
19b53e5b C |
47 | } |
48 | } | |
49 | if (!$this->_actionsToGet || count($this->_actionsToGet) > count($this->_actions)) { | |
23c2d07c | 50 | // Search for entity-specific actions in extensions |
19b53e5b C |
51 | foreach (\CRM_Extension_System::singleton()->getMapper()->getActiveModuleFiles() as $ext) { |
52 | $dir = \CRM_Utils_File::addTrailingSlash(dirname($ext['filePath'])); | |
53 | $this->scanDir($dir . 'Civi/Api4/Action/' . $this->_entityName); | |
54 | } | |
23c2d07c | 55 | // Search for entity-specific actions in core |
56 | $this->scanDir(\CRM_Utils_File::addTrailingSlash(__DIR__) . $this->_entityName); | |
19b53e5b C |
57 | } |
58 | ksort($this->_actions); | |
59 | return $this->_actions; | |
60 | } | |
61 | ||
62 | /** | |
63 | * @param $dir | |
64 | */ | |
65 | private function scanDir($dir) { | |
66 | if (is_dir($dir)) { | |
67 | foreach (glob("$dir/*.php") as $file) { | |
68 | $matches = []; | |
69 | preg_match('/(\w*).php/', $file, $matches); | |
70 | $actionName = array_pop($matches); | |
71 | $actionClass = new \ReflectionClass('\\Civi\\Api4\\Action\\' . $this->_entityName . '\\' . $actionName); | |
72 | if ($actionClass->isInstantiable() && $actionClass->isSubclassOf('\\Civi\\Api4\\Generic\\AbstractAction')) { | |
73 | $this->loadAction(lcfirst($actionName)); | |
74 | } | |
75 | } | |
76 | } | |
77 | } | |
78 | ||
79 | /** | |
80 | * @param $actionName | |
e15f9453 | 81 | * @param \ReflectionMethod $method |
19b53e5b | 82 | */ |
e15f9453 | 83 | private function loadAction($actionName, $method = NULL) { |
19b53e5b C |
84 | try { |
85 | if (!isset($this->_actions[$actionName]) && (!$this->_actionsToGet || in_array($actionName, $this->_actionsToGet))) { | |
3a8dc228 | 86 | $action = \Civi\API\Request::create($this->getEntityName(), $actionName, ['version' => 4]); |
19b53e5b C |
87 | if (is_object($action)) { |
88 | $this->_actions[$actionName] = ['name' => $actionName]; | |
e15f9453 | 89 | if ($this->_isFieldSelected('description', 'comment', 'see')) { |
e3c6d5ff | 90 | $vars = ['entity' => $this->getEntityName(), 'action' => $actionName]; |
e15f9453 | 91 | // Docblock from action class |
fc95d9a5 | 92 | $actionDocs = ReflectionUtils::getCodeDocs($action->reflect(), NULL, $vars); |
e15f9453 CW |
93 | unset($actionDocs['method']); |
94 | // Docblock from action factory function in entity class. This takes precedence since most action classes are generic. | |
95 | if ($method) { | |
fc95d9a5 CW |
96 | $methodDocs = ReflectionUtils::getCodeDocs($method, 'Method', $vars); |
97 | // Allow method doc to inherit class doc | |
98 | if (strpos($method->getDocComment(), '@inheritDoc') !== FALSE && !empty($methodDocs['comment']) && !empty($actionDocs['comment'])) { | |
99 | $methodDocs['comment'] .= "\n\n" . $actionDocs['comment']; | |
100 | } | |
101 | $actionDocs = array_filter($methodDocs) + $actionDocs; | |
e15f9453 CW |
102 | } |
103 | $this->_actions[$actionName] += $actionDocs; | |
19b53e5b C |
104 | } |
105 | if ($this->_isFieldSelected('params')) { | |
106 | $this->_actions[$actionName]['params'] = $action->getParamInfo(); | |
107 | // Language param is only relevant on multilingual sites | |
108 | $languageLimit = (array) \Civi::settings()->get('languageLimit'); | |
109 | if (count($languageLimit) < 2) { | |
110 | unset($this->_actions[$actionName]['params']['language']); | |
111 | } | |
112 | elseif (isset($this->_actions[$actionName]['params']['language'])) { | |
113 | $this->_actions[$actionName]['params']['language']['options'] = array_keys($languageLimit); | |
114 | } | |
115 | } | |
116 | } | |
117 | } | |
118 | } | |
119 | catch (NotImplementedException $e) { | |
120 | } | |
121 | } | |
122 | ||
123 | public function fields() { | |
124 | return [ | |
125 | [ | |
126 | 'name' => 'name', | |
e15f9453 | 127 | 'description' => 'Action name', |
19b53e5b C |
128 | ], |
129 | [ | |
130 | 'name' => 'description', | |
e15f9453 | 131 | 'description' => 'Description from docblock', |
19b53e5b C |
132 | ], |
133 | [ | |
134 | 'name' => 'comment', | |
e15f9453 CW |
135 | 'description' => 'Comments from docblock', |
136 | ], | |
137 | [ | |
138 | 'name' => 'see', | |
139 | 'data_type' => 'Array', | |
140 | 'description' => 'Any @see annotations from docblock', | |
19b53e5b C |
141 | ], |
142 | [ | |
143 | 'name' => 'params', | |
e15f9453 | 144 | 'description' => 'List of all accepted parameters', |
19b53e5b C |
145 | 'data_type' => 'Array', |
146 | ], | |
147 | ]; | |
148 | } | |
149 | ||
150 | } |