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