Merge pull request #15784 from civicrm/5.20
[civicrm-core.git] / Civi / Api4 / Action / GetActions.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | CiviCRM version 5 |
6 +--------------------------------------------------------------------+
7 | Copyright CiviCRM LLC (c) 2004-2020 |
8 +--------------------------------------------------------------------+
9 | This file is a part of CiviCRM. |
10 | |
11 | CiviCRM is free software; you can copy, modify, and distribute it |
12 | under the terms of the GNU Affero General Public License |
13 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | |
15 | CiviCRM is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Affero General Public |
21 | License and the CiviCRM Licensing Exception along |
22 | with this program; if not, contact CiviCRM LLC |
23 | at info[AT]civicrm[DOT]org. If you have questions about the |
24 | GNU Affero General Public License or the licensing of CiviCRM, |
25 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
26 +--------------------------------------------------------------------+
27 */
28
29 /**
30 *
31 * @package CRM
32 * @copyright CiviCRM LLC (c) 2004-2020
33 * $Id$
34 *
35 */
36
37
38 namespace Civi\Api4\Action;
39
40 use Civi\API\Exception\NotImplementedException;
41 use Civi\Api4\Generic\BasicGetAction;
42 use Civi\Api4\Utils\ActionUtil;
43 use Civi\Api4\Utils\ReflectionUtils;
44
45 /**
46 * Get actions for an entity with a list of accepted params
47 */
48 class GetActions extends BasicGetAction {
49
50 private $_actions = [];
51
52 private $_actionsToGet;
53
54 protected function getRecords() {
55 $this->_actionsToGet = $this->_itemsToGet('name');
56
57 $entityReflection = new \ReflectionClass('\Civi\Api4\\' . $this->_entityName);
58 foreach ($entityReflection->getMethods(\ReflectionMethod::IS_STATIC | \ReflectionMethod::IS_PUBLIC) as $method) {
59 $actionName = $method->getName();
60 if ($actionName != 'permissions' && $actionName[0] != '_') {
61 $this->loadAction($actionName);
62 }
63 }
64 if (!$this->_actionsToGet || count($this->_actionsToGet) > count($this->_actions)) {
65 // Search for entity-specific actions in extensions
66 foreach (\CRM_Extension_System::singleton()->getMapper()->getActiveModuleFiles() as $ext) {
67 $dir = \CRM_Utils_File::addTrailingSlash(dirname($ext['filePath']));
68 $this->scanDir($dir . 'Civi/Api4/Action/' . $this->_entityName);
69 }
70 // Search for entity-specific actions in core
71 $this->scanDir(\CRM_Utils_File::addTrailingSlash(__DIR__) . $this->_entityName);
72 }
73 ksort($this->_actions);
74 return $this->_actions;
75 }
76
77 /**
78 * @param $dir
79 */
80 private function scanDir($dir) {
81 if (is_dir($dir)) {
82 foreach (glob("$dir/*.php") as $file) {
83 $matches = [];
84 preg_match('/(\w*).php/', $file, $matches);
85 $actionName = array_pop($matches);
86 $actionClass = new \ReflectionClass('\\Civi\\Api4\\Action\\' . $this->_entityName . '\\' . $actionName);
87 if ($actionClass->isInstantiable() && $actionClass->isSubclassOf('\\Civi\\Api4\\Generic\\AbstractAction')) {
88 $this->loadAction(lcfirst($actionName));
89 }
90 }
91 }
92 }
93
94 /**
95 * @param $actionName
96 */
97 private function loadAction($actionName) {
98 try {
99 if (!isset($this->_actions[$actionName]) && (!$this->_actionsToGet || in_array($actionName, $this->_actionsToGet))) {
100 $action = ActionUtil::getAction($this->getEntityName(), $actionName);
101 if (is_object($action)) {
102 $this->_actions[$actionName] = ['name' => $actionName];
103 if ($this->_isFieldSelected('description') || $this->_isFieldSelected('comment')) {
104 $actionReflection = new \ReflectionClass($action);
105 $actionInfo = ReflectionUtils::getCodeDocs($actionReflection);
106 unset($actionInfo['method']);
107 $this->_actions[$actionName] += $actionInfo;
108 }
109 if ($this->_isFieldSelected('params')) {
110 $this->_actions[$actionName]['params'] = $action->getParamInfo();
111 // Language param is only relevant on multilingual sites
112 $languageLimit = (array) \Civi::settings()->get('languageLimit');
113 if (count($languageLimit) < 2) {
114 unset($this->_actions[$actionName]['params']['language']);
115 }
116 elseif (isset($this->_actions[$actionName]['params']['language'])) {
117 $this->_actions[$actionName]['params']['language']['options'] = array_keys($languageLimit);
118 }
119 }
120 }
121 }
122 }
123 catch (NotImplementedException $e) {
124 }
125 }
126
127 public function fields() {
128 return [
129 [
130 'name' => 'name',
131 'data_type' => 'String',
132 ],
133 [
134 'name' => 'description',
135 'data_type' => 'String',
136 ],
137 [
138 'name' => 'comment',
139 'data_type' => 'String',
140 ],
141 [
142 'name' => 'params',
143 'data_type' => 'Array',
144 ],
145 ];
146 }
147
148 }