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