Annotate DAO files with COMPONENT, exclude disabled components' entities from APIv4...
[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 use Civi\Api4\Service\Schema\Joinable\CustomGroupJoinable;
24
25 /**
26 * Get the names & docblocks of all APIv4 entities.
27 *
28 * Scans for api entities in core, enabled components & enabled extensions.
29 *
30 * Also includes pseudo-entities from multi-record custom groups by default.
31 *
32 * @method $this setIncludeCustom(bool $value)
33 * @method bool getIncludeCustom()
34 */
35 class 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 = [];
49 $toGet = $this->_itemsToGet('name');
50 $locations = array_merge([\Civi::paths()->getPath('[civicrm.root]/Civi.php')],
51 array_column(\CRM_Extension_System::singleton()->getMapper()->getActiveModuleFiles(), 'filePath')
52 );
53 $enabledComponents = array_keys(\CRM_Core_Component::getEnabledComponents());
54 foreach ($locations as $location) {
55 $dir = \CRM_Utils_File::addTrailingSlash(dirname($location)) . 'Civi/Api4';
56 if (is_dir($dir)) {
57 foreach (glob("$dir/*.php") as $file) {
58 $matches = [];
59 preg_match('/(\w*)\.php$/', $file, $matches);
60 $entity = '\Civi\Api4\\' . $matches[1];
61 if (
62 (!$toGet || in_array($matches[1], $toGet))
63 && is_a($entity, '\Civi\Api4\Generic\AbstractEntity', TRUE)
64 ) {
65 $info = $entity::getInfo();
66 // Only include DAO entities from enabled components
67 if (empty($info['dao']) || !defined($info['dao'] . '::COMPONENT') || in_array(constant($info['dao'] . '::COMPONENT'), $enabledComponents)) {
68 $entities[$info['name']] = $info;
69 }
70 }
71 }
72 }
73 }
74
75 // Fetch custom entities unless we've already fetched everything requested
76 if ($this->includeCustom && (!$toGet || array_diff($toGet, array_keys($entities)))) {
77 $this->addCustomEntities($entities);
78 }
79
80 ksort($entities);
81 return $entities;
82 }
83
84 /**
85 * Add custom-field pseudo-entities
86 *
87 * @param $entities
88 * @throws \API_Exception
89 */
90 private function addCustomEntities(&$entities) {
91 $customEntities = CustomGroup::get()
92 ->addWhere('is_multiple', '=', 1)
93 ->addWhere('is_active', '=', 1)
94 ->setSelect(['name', 'title', 'help_pre', 'help_post', 'extends', 'icon'])
95 ->setCheckPermissions(FALSE)
96 ->execute();
97 foreach ($customEntities as $customEntity) {
98 $fieldName = 'Custom_' . $customEntity['name'];
99 $baseEntity = '\Civi\Api4\\' . CustomGroupJoinable::getEntityFromExtends($customEntity['extends']);
100 $entities[$fieldName] = [
101 'name' => $fieldName,
102 'title' => $customEntity['title'],
103 'title_plural' => $customEntity['title'],
104 'description' => ts('Custom group for %1', [1 => $baseEntity::getInfo()['title_plural']]),
105 'see' => [
106 'https://docs.civicrm.org/user/en/latest/organising-your-data/creating-custom-fields/#multiple-record-fieldsets',
107 '\\Civi\\Api4\\CustomGroup',
108 ],
109 'icon' => $customEntity['icon'],
110 ];
111 if (!empty($customEntity['help_pre'])) {
112 $entities[$fieldName]['comment'] = $this->plainTextify($customEntity['help_pre']);
113 }
114 if (!empty($customEntity['help_post'])) {
115 $pre = empty($entities[$fieldName]['comment']) ? '' : $entities[$fieldName]['comment'] . "\n\n";
116 $entities[$fieldName]['comment'] = $pre . $this->plainTextify($customEntity['help_post']);
117 }
118 }
119 }
120
121 /**
122 * Convert html to plain text.
123 *
124 * @param $input
125 * @return mixed
126 */
127 private function plainTextify($input) {
128 return html_entity_decode(strip_tags($input), ENT_QUOTES | ENT_HTML5, 'UTF-8');
129 }
130
131 }