APIv4 - Delete unused OptionList trait
[civicrm-core.git] / Civi / Api4 / Action / GetActions.php
CommitLineData
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
19b53e5b
C
13namespace Civi\Api4\Action;
14
15use Civi\API\Exception\NotImplementedException;
16use Civi\Api4\Generic\BasicGetAction;
26258982 17use Civi\Api4\Utils\CoreUtil;
19b53e5b
C
18use Civi\Api4\Utils\ReflectionUtils;
19
20/**
fc95d9a5
CW
21 * Get all API actions for the $ENTITY entity.
22 *
23 * Includes a list of accepted parameters for each action, descriptions and other documentation.
19b53e5b
C
24 */
25class GetActions extends BasicGetAction {
26
27 private $_actions = [];
28
29 private $_actionsToGet;
30
31 protected function getRecords() {
32 $this->_actionsToGet = $this->_itemsToGet('name');
33
26258982
CW
34 $className = CoreUtil::getApiClass($this->_entityName);
35 $entityReflection = new \ReflectionClass($className);
19b53e5b
C
36 foreach ($entityReflection->getMethods(\ReflectionMethod::IS_STATIC | \ReflectionMethod::IS_PUBLIC) as $method) {
37 $actionName = $method->getName();
449c4e6b 38 if ($actionName != 'permissions' && $actionName != 'getInfo' && $actionName[0] != '_') {
e15f9453 39 $this->loadAction($actionName, $method);
19b53e5b
C
40 }
41 }
42 if (!$this->_actionsToGet || count($this->_actionsToGet) > count($this->_actions)) {
23c2d07c 43 // Search for entity-specific actions in extensions
26258982 44 $nameSpace = str_replace('Civi\Api4\\', 'Civi\Api4\Action\\', $className);
19b53e5b
C
45 foreach (\CRM_Extension_System::singleton()->getMapper()->getActiveModuleFiles() as $ext) {
46 $dir = \CRM_Utils_File::addTrailingSlash(dirname($ext['filePath']));
26258982 47 $this->scanDir($dir, $nameSpace);
19b53e5b 48 }
23c2d07c 49 // Search for entity-specific actions in core
26258982
CW
50 global $civicrm_root;
51 $this->scanDir(\CRM_Utils_File::addTrailingSlash($civicrm_root), $nameSpace);
19b53e5b
C
52 }
53 ksort($this->_actions);
54 return $this->_actions;
55 }
56
57 /**
26258982
CW
58 * @param string $dir
59 * @param string $nameSpace
19b53e5b 60 */
26258982
CW
61 private function scanDir($dir, $nameSpace) {
62 $dir .= str_replace('\\', '/', $nameSpace);
19b53e5b
C
63 if (is_dir($dir)) {
64 foreach (glob("$dir/*.php") as $file) {
26258982
CW
65 $actionName = basename($file, '.php');
66 $actionClass = new \ReflectionClass($nameSpace . '\\' . $actionName);
a62d97f3 67 if ($actionClass->isInstantiable() && $actionClass->isSubclassOf('\Civi\Api4\Generic\AbstractAction')) {
19b53e5b
C
68 $this->loadAction(lcfirst($actionName));
69 }
70 }
71 }
72 }
73
74 /**
75 * @param $actionName
e15f9453 76 * @param \ReflectionMethod $method
19b53e5b 77 */
e15f9453 78 private function loadAction($actionName, $method = NULL) {
19b53e5b
C
79 try {
80 if (!isset($this->_actions[$actionName]) && (!$this->_actionsToGet || in_array($actionName, $this->_actionsToGet))) {
3a8dc228 81 $action = \Civi\API\Request::create($this->getEntityName(), $actionName, ['version' => 4]);
399eff1a 82 if (is_object($action) && (!$this->checkPermissions || $action->isAuthorized(\CRM_Core_Session::singleton()->getLoggedInContactID()))) {
19b53e5b 83 $this->_actions[$actionName] = ['name' => $actionName];
e15f9453 84 if ($this->_isFieldSelected('description', 'comment', 'see')) {
e3c6d5ff 85 $vars = ['entity' => $this->getEntityName(), 'action' => $actionName];
e15f9453 86 // Docblock from action class
fc95d9a5 87 $actionDocs = ReflectionUtils::getCodeDocs($action->reflect(), NULL, $vars);
e15f9453
CW
88 unset($actionDocs['method']);
89 // Docblock from action factory function in entity class. This takes precedence since most action classes are generic.
90 if ($method) {
fc95d9a5
CW
91 $methodDocs = ReflectionUtils::getCodeDocs($method, 'Method', $vars);
92 // Allow method doc to inherit class doc
93 if (strpos($method->getDocComment(), '@inheritDoc') !== FALSE && !empty($methodDocs['comment']) && !empty($actionDocs['comment'])) {
94 $methodDocs['comment'] .= "\n\n" . $actionDocs['comment'];
95 }
96 $actionDocs = array_filter($methodDocs) + $actionDocs;
e15f9453
CW
97 }
98 $this->_actions[$actionName] += $actionDocs;
19b53e5b
C
99 }
100 if ($this->_isFieldSelected('params')) {
101 $this->_actions[$actionName]['params'] = $action->getParamInfo();
102 // Language param is only relevant on multilingual sites
103 $languageLimit = (array) \Civi::settings()->get('languageLimit');
104 if (count($languageLimit) < 2) {
105 unset($this->_actions[$actionName]['params']['language']);
106 }
107 elseif (isset($this->_actions[$actionName]['params']['language'])) {
108 $this->_actions[$actionName]['params']['language']['options'] = array_keys($languageLimit);
109 }
110 }
111 }
112 }
113 }
114 catch (NotImplementedException $e) {
115 }
116 }
117
118 public function fields() {
119 return [
120 [
121 'name' => 'name',
e15f9453 122 'description' => 'Action name',
19b53e5b
C
123 ],
124 [
125 'name' => 'description',
e15f9453 126 'description' => 'Description from docblock',
19b53e5b
C
127 ],
128 [
129 'name' => 'comment',
e15f9453
CW
130 'description' => 'Comments from docblock',
131 ],
132 [
133 'name' => 'see',
134 'data_type' => 'Array',
135 'description' => 'Any @see annotations from docblock',
19b53e5b
C
136 ],
137 [
138 'name' => 'params',
e15f9453 139 'description' => 'List of all accepted parameters',
19b53e5b
C
140 'data_type' => 'Array',
141 ],
142 ];
143 }
144
145}