Merge pull request #18720 from artfulrobot/artfulrobot-core-issue-1428
[civicrm-core.git] / Civi / Api4 / Action / Entity / Get.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
6 | |
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 |
10 +--------------------------------------------------------------------+
11 */
12
13 /**
14 *
15 * @package CRM
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
17 */
18
19
20 namespace Civi\Api4\Action\Entity;
21
22 use Civi\Api4\CustomGroup;
23
24 /**
25 * Get the names & docblocks of all APIv4 entities.
26 *
27 * Scans for api entities in core + enabled extensions.
28 *
29 * Also includes pseudo-entities from multi-record custom groups by default.
30 *
31 * @method $this setIncludeCustom(bool $value)
32 * @method bool getIncludeCustom()
33 */
34 class Get extends \Civi\Api4\Generic\BasicGetAction {
35
36 /**
37 * Include custom-field-based pseudo-entities?
38 *
39 * @var bool
40 */
41 protected $includeCustom = TRUE;
42
43 /**
44 * Scan all api directories to discover entities
45 */
46 protected function getRecords() {
47 $entities = [];
48 $toGet = $this->_itemsToGet('name');
49 $locations = array_merge([\Civi::paths()->getPath('[civicrm.root]/Civi.php')],
50 array_column(\CRM_Extension_System::singleton()->getMapper()->getActiveModuleFiles(), 'filePath')
51 );
52 foreach ($locations as $location) {
53 $dir = \CRM_Utils_File::addTrailingSlash(dirname($location)) . 'Civi/Api4';
54 if (is_dir($dir)) {
55 foreach (glob("$dir/*.php") as $file) {
56 $matches = [];
57 preg_match('/(\w*)\.php$/', $file, $matches);
58 $entity = '\Civi\Api4\\' . $matches[1];
59 if (
60 (!$toGet || in_array($matches[1], $toGet))
61 && is_a($entity, '\Civi\Api4\Generic\AbstractEntity', TRUE)
62 ) {
63 $info = $entity::getInfo();
64 $entities[$info['name']] = $info;
65 }
66 }
67 }
68 }
69
70 // Fetch custom entities unless we've already fetched everything requested
71 if ($this->includeCustom && (!$toGet || array_diff($toGet, array_keys($entities)))) {
72 $this->addCustomEntities($entities);
73 }
74
75 ksort($entities);
76 return $entities;
77 }
78
79 /**
80 * Add custom-field pseudo-entities
81 *
82 * @param $entities
83 * @throws \API_Exception
84 */
85 private function addCustomEntities(&$entities) {
86 $customEntities = CustomGroup::get()
87 ->addWhere('is_multiple', '=', 1)
88 ->addWhere('is_active', '=', 1)
89 ->setSelect(['name', 'title', 'help_pre', 'help_post', 'extends', 'icon'])
90 ->setCheckPermissions(FALSE)
91 ->execute();
92 foreach ($customEntities as $customEntity) {
93 $fieldName = 'Custom_' . $customEntity['name'];
94 $entities[$fieldName] = [
95 'name' => $fieldName,
96 'title' => $customEntity['title'],
97 'description' => 'Custom group - extends ' . $customEntity['extends'],
98 'see' => [
99 'https://docs.civicrm.org/user/en/latest/organising-your-data/creating-custom-fields/#multiple-record-fieldsets',
100 '\\Civi\\Api4\\CustomGroup',
101 ],
102 'icon' => $customEntity['icon'],
103 ];
104 if (!empty($customEntity['help_pre'])) {
105 $entities[$fieldName]['comment'] = $this->plainTextify($customEntity['help_pre']);
106 }
107 if (!empty($customEntity['help_post'])) {
108 $pre = empty($entities[$fieldName]['comment']) ? '' : $entities[$fieldName]['comment'] . "\n\n";
109 $entities[$fieldName]['comment'] = $pre . $this->plainTextify($customEntity['help_post']);
110 }
111 }
112 }
113
114 /**
115 * Convert html to plain text.
116 *
117 * @param $input
118 * @return mixed
119 */
120 private function plainTextify($input) {
121 return html_entity_decode(strip_tags($input), ENT_QUOTES | ENT_HTML5, 'UTF-8');
122 }
123
124 }