TRUE, 'select' => ['options', 'name'], 'where' => [['name', 'IN', ['visibility', 'group_type']]]]); // Don't show n-to-many joins in Explorer $entityLinks = (array) civicrm_api4('Entity', 'getLinks', [], ['entity' => 'links']); foreach ($entityLinks as $entity => $links) { $entityLinks[$entity] = array_filter($links, function($link) { return $link['joinType'] != Joinable::JOIN_TYPE_ONE_TO_MANY; }); } $vars = [ 'operators' => \CRM_Core_DAO::acceptedSQLOperators(), 'basePath' => Civi::resources()->getUrl('civicrm'), 'schema' => (array) \Civi\Api4\Entity::get()->setChain(['fields' => ['$name', 'getFields']])->execute(), 'links' => $entityLinks, 'docs' => \Civi\Api4\Utils\ReflectionUtils::parseDocBlock($apiDoc->getDocComment()), 'functions' => self::getSqlFunctions(), 'groupOptions' => array_column((array) $groupOptions, 'options', 'name'), ]; Civi::resources() ->addVars('api4', $vars) ->addPermissions(['access debug output', 'edit groups', 'administer reserved groups']) ->addScriptFile('civicrm', 'js/load-bootstrap.js') ->addScriptFile('civicrm', 'bower_components/js-yaml/dist/js-yaml.min.js') ->addScriptFile('civicrm', 'bower_components/marked/marked.min.js') ->addScriptFile('civicrm', 'bower_components/google-code-prettify/bin/prettify.min.js') ->addStyleFile('civicrm', 'bower_components/google-code-prettify/bin/prettify.min.css'); $loader = new Civi\Angular\AngularLoader(); $loader->setModules(['api4Explorer']); $loader->setPageName('civicrm/api4'); $loader->useApp([ 'defaultRoute' => '/explorer', ]); $loader->load(); parent::run(); } /** * Gets info about all available sql functions * @return array */ public static function getSqlFunctions() { $fns = []; foreach (glob(Civi::paths()->getPath('[civicrm.root]/Civi/Api4/Query/SqlFunction*.php')) as $file) { $matches = []; if (preg_match('/(SqlFunction[A-Z_]+)\.php$/', $file, $matches)) { $className = '\Civi\Api4\Query\\' . $matches[1]; if (is_subclass_of($className, '\Civi\Api4\Query\SqlFunction')) { $fns[] = [ 'name' => $className::getName(), 'title' => $className::getTitle(), 'params' => $className::getParams(), 'category' => $className::getCategory(), ]; } } } return $fns; } }