* @return string
*/
public function run() {
- CRM_Utils_System::setTitle(ts('API explorer and generator'));
+ CRM_Utils_System::setTitle('CiviCRM API');
CRM_Core_Resources::singleton()
->addScriptFile('civicrm', 'templates/CRM/Admin/Page/APIExplorer.js')
->addScriptUrl('//cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js', 99)
->addStyleUrl('//cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css', 99);
+
$this->assign('operators', CRM_Core_DAO::acceptedSQLOperators());
+
+ // List example directories
+ global $civicrm_root;
+ $examples = array();
+ foreach (scandir($civicrm_root . 'api/v3/examples') as $item) {
+ if ($item && strpos($item, '.') === FALSE) {
+ $examples[] = $item;
+ }
+ }
+ $this->assign('examples', $examples);
+
return parent::run();
}
return 'civicrm/api/explorer';
}
+ /**
+ * AJAX callback to fetch examples
+ */
+ public static function getExampleFile() {
+ global $civicrm_root;
+ if (!empty($_GET['entity']) && strpos($_GET['entity'], '.') === FALSE) {
+ $examples = array();
+ foreach (scandir($civicrm_root . 'api/v3/examples/' . $_GET['entity']) as $item) {
+ $item = str_replace('.php', '', $item);
+ if ($item && strpos($item, '.') === FALSE) {
+ $examples[] = array('key' => $item, 'value' => $item);
+ }
+ }
+ CRM_Utils_JSON::output($examples);
+ }
+ if (!empty($_GET['file']) && strpos($_GET['file'], '.') === FALSE) {
+ $fileName = $civicrm_root . 'api/v3/examples/' . $_GET['file'] . '.php';
+ if (file_exists($fileName)) {
+ echo file_get_contents($fileName);
+ }
+ else {
+ echo "Not found.";
+ }
+ CRM_Utils_System::civiExit();
+ }
+ }
+
}
(function($, _, undefined) {
+ "use strict";
+ /* jshint validthis: true */
var
entity,
action,
});
}
+ /**
+ * Fetch list of example files for a given entity
+ */
+ function getExamples() {
+ CRM.utils.setOptions($('#example-action').prop('disabled', true).addClass('loading'), []);
+ $.getJSON(CRM.url('civicrm/ajax/apiexample', {entity: $(this).val()}))
+ .done(function(result) {
+ CRM.utils.setOptions($('#example-action').prop('disabled', false).removeClass('loading'), result);
+ });
+ }
+
+ /**
+ * Fetch and display an example file
+ */
+ function getExample() {
+ var
+ entity = $('#example-entity').val(),
+ action = $('#example-action').val();
+ if (entity && action) {
+ $('#example-result').block();
+ $.get(CRM.url('civicrm/ajax/apiexample', {file: entity + '/' + action}))
+ .done(function(result) {
+ $('#example-result').unblock().addClass('prettyprint').removeClass('prettyprinted').text(result);
+ prettyPrint();
+ });
+ } else {
+ $('#example-result').text($('#example-result').attr('title'));
+ }
+ }
+
$(document).ready(function() {
- $('#api-entity').crmSelect2({
+ // Set up tabs - bind active tab to document hash because... it's cool?
+ document.location.hash = document.location.hash || 'explorer';
+ $('#mainTabContainer')
+ .tabs({
+ active: $(document.location.hash + '-tab').index() - 1
+ })
+ .on('tabsactivate', function(e, ui) {
+ if (ui.newPanel) {
+ document.location.hash = ui.newPanel.attr('id').replace('-tab', '');
+ }
+ });
+
+ // Initialize widgets
+ $('#api-entity, #example-entity').crmSelect2({
// Add strikethough class to selection to indicate deprecated apis
formatSelection: function(option) {
return $(option.element).hasClass('strikethrough') ? '<span class="strikethrough">' + option.text + '</span>' : option.text;
buildParams();
})
.on('change', 'select.api-chain-entity', getChainedAction);
+ $('#example-entity').on('change', getExamples);
+ $('#example-action').on('change', getExample);
$('#api-params-add').on('click', function(e) {
e.preventDefault();
addField();
*}
<style>
{literal}
- #api-explorer pre {
+ #mainTabContainer {
+ background: transparent;
+ border: 0 none;
+ }
+ #mainTabContainer pre {
line-height: 1.3em;
font-size: 11px;
margin: 0;
border: 0 none;
}
- pre#api-result {
+ #mainTabContainer ul.ui-tabs-nav {
+ font-size: 1.1em;
+ margin-bottom: .6em;
+ }
+ pre#api-result,
+ pre#example-result {
padding:1em;
max-height: 50em;
border: 1px solid lightgrey;
+ margin-top: 1em;
+ overflow: auto;
}
#api-params-table th:first-child,
#api-params-table td:first-child {
#api-params .red-icon {
margin-top: .5em;
}
- #api-explorer label {
+ #mainTabContainer label {
display: inline;
font-weight: bold;
}
{/literal}
</style>
-<form id="api-explorer">
- <label for="api-entity">{ts}Entity{/ts}:</label>
- <select class="crm-form-select" id="api-entity" name="entity">
- <option value="" selected="selected">{ts}Choose{/ts}...</option>
- {crmAPI entity="Entity" action="get" var="entities" version=3}
- {foreach from=$entities.values item=entity}
- <option value="{$entity}" {if !empty($entities.deprecated) && in_array($entity, $entities.deprecated)}class="strikethrough"{/if}>
- {$entity}
- </option>
- {/foreach}
- </select>
-
- <label for="api-action">{ts}Action{/ts}:</label>
- <input class="crm-form-text" id="api-action" name="action" value="get">
-
+<div id="mainTabContainer">
+ <ul>
+ <li class="ui-corner-all"><a href="#explorer-tab">{ts}Explorer{/ts}</a></li>
+ <li class="ui-corner-all"><a href="#examples-tab">{ts}Examples{/ts}</a></li>
+ </ul>
- <label for="debug-checkbox" title="{ts}Display debug output with results.{/ts}">
- <input type="checkbox" class="crm-form-checkbox api-param-checkbox api-input" id="debug-checkbox" name="debug" value="1" >debug
- </label>
- |
+ <div id="explorer-tab">
- <label for="sequential-checkbox" title="{ts}Sequential is more compact format, well-suited for json and smarty.{/ts}">
- <input type="checkbox" class="crm-form-checkbox api-param-checkbox api-input" id="sequential-checkbox" name="sequential" checked="checked" value="1">sequential
- </label>
+ <form id="api-explorer">
+ <label for="api-entity">{ts}Entity{/ts}:</label>
+ <select class="crm-form-select big required" id="api-entity" name="entity">
+ <option value="" selected="selected">{ts}Choose{/ts}...</option>
+ {crmAPI entity="Entity" action="get" var="entities" version=3}
+ {foreach from=$entities.values item=entity}
+ <option value="{$entity}" {if !empty($entities.deprecated) && in_array($entity, $entities.deprecated)}class="strikethrough"{/if}>
+ {$entity}
+ </option>
+ {/foreach}
+ </select>
+
+ <label for="api-action">{ts}Action{/ts}:</label>
+ <input class="crm-form-text" id="api-action" name="action" value="get">
+
- <table id="api-params-table">
- <thead style="display: none;">
- <tr>
- <th>{ts}Name{/ts} {help id='param-name'}</th>
- <th>{ts}Operator{/ts} {help id='param-op'}</th>
- <th>{ts}Value{/ts} {help id='param-value'}</th>
- </tr>
- </thead>
- <tbody id="api-params"></tbody>
- </table>
- <div id="api-param-buttons" style="display: none;">
- <a href="#" class="crm-hover-button" id="api-params-add"><span class="icon ui-icon-plus"></span>{ts}Add Parameter{/ts}</a>
- <a href="#" class="crm-hover-button" id="api-option-add"><span class="icon ui-icon-gear"></span>{ts}Add Option{/ts}</a>
- <a href="#" class="crm-hover-button" id="api-chain-add"><span class="icon ui-icon-link"></span>{ts}Chain API Call{/ts}</a>
- </div>
- <div id="api-generated-wraper">
- <table id="api-generated" border=1>
- <caption>{ts}Code{/ts}</caption>
- <tr><td>Rest</td><td><pre class="prettyprint" id="api-rest"></pre></td></tr>
- <tr><td>Smarty</td><td><pre class="prettyprint linenums" id="api-smarty" title='smarty syntax (for get actions)'></pre></td></tr>
- <tr><td>Php</td><td><pre class="prettyprint linenums" id="api-php" title='php syntax'></pre></td></tr>
- <tr><td>Javascript</td><td><pre class="prettyprint linenums" id="api-json" title='javascript syntax'></pre></td></tr>
- {if $config->userSystem->is_drupal}
- <tr><td>Drush</td><td><pre class="prettyprint" id="api-drush" title='drush syntax'></pre></td></tr>
- {/if}
- {if $config->userSystem->is_wordpress}
- <tr><td>WP-CLI</td><td><pre class="prettyprint" id="api-wpcli" title='wp-cli syntax'></pre></td></tr>
- {/if}
- </table>
- </div>
- <div class="crm-submit-buttons">
- <span class="crm-button crm-icon-button">
- <span class="crm-button-icon ui-icon-check"> </span> <input type="submit" value="{ts}Execute{/ts}" class="crm-form-submit" accesskey="S" title="{ts}Execute API call and display results{/ts}"/>
- </span>
- </div>
+ <label for="debug-checkbox" title="{ts}Display debug output with results.{/ts}">
+ <input type="checkbox" class="crm-form-checkbox api-param-checkbox api-input" id="debug-checkbox" name="debug" value="1" >debug
+ </label>
+ |
+
+ <label for="sequential-checkbox" title="{ts}Sequential is more compact format, well-suited for json and smarty.{/ts}">
+ <input type="checkbox" class="crm-form-checkbox api-param-checkbox api-input" id="sequential-checkbox" name="sequential" checked="checked" value="1">sequential
+ </label>
+
+ <table id="api-params-table">
+ <thead style="display: none;">
+ <tr>
+ <th>{ts}Name{/ts} {help id='param-name'}</th>
+ <th>{ts}Operator{/ts} {help id='param-op'}</th>
+ <th>{ts}Value{/ts} {help id='param-value'}</th>
+ </tr>
+ </thead>
+ <tbody id="api-params"></tbody>
+ </table>
+ <div id="api-param-buttons" style="display: none;">
+ <a href="#" class="crm-hover-button" id="api-params-add"><span class="icon ui-icon-plus"></span>{ts}Add Parameter{/ts}</a>
+ <a href="#" class="crm-hover-button" id="api-option-add"><span class="icon ui-icon-gear"></span>{ts}Add Option{/ts}</a>
+ <a href="#" class="crm-hover-button" id="api-chain-add"><span class="icon ui-icon-link"></span>{ts}Chain API Call{/ts}</a>
+ </div>
+ <div id="api-generated-wraper">
+ <table id="api-generated" border=1>
+ <caption>{ts}Code{/ts}</caption>
+ <tr><td>Rest</td><td><pre class="prettyprint" id="api-rest"></pre></td></tr>
+ <tr><td>Smarty</td><td><pre class="prettyprint linenums" id="api-smarty" title='smarty syntax (for get actions)'></pre></td></tr>
+ <tr><td>Php</td><td><pre class="prettyprint linenums" id="api-php" title='php syntax'></pre></td></tr>
+ <tr><td>Javascript</td><td><pre class="prettyprint linenums" id="api-json" title='javascript syntax'></pre></td></tr>
+ {if $config->userSystem->is_drupal}
+ <tr><td>Drush</td><td><pre class="prettyprint" id="api-drush" title='drush syntax'></pre></td></tr>
+ {/if}
+ {if $config->userSystem->is_wordpress}
+ <tr><td>WP-CLI</td><td><pre class="prettyprint" id="api-wpcli" title='wp-cli syntax'></pre></td></tr>
+ {/if}
+ </table>
+ </div>
+ <div class="crm-submit-buttons">
+ <span class="crm-button crm-icon-button">
+ <span class="crm-button-icon ui-icon-check"> </span> <input type="submit" value="{ts}Execute{/ts}" class="crm-form-submit" accesskey="S" title="{ts}Execute API call and display results{/ts}"/>
+ </span>
+ </div>
<pre id="api-result" class="linenums">
-{ts}The result of api calls are displayed in this area.{/ts}
+{ts}Results are displayed here.{/ts}
+</pre>
+ </form>
+ </div>
+
+ <div id="examples-tab">
+ <form id="api-examples">
+ <label for="example-entity">{ts}Entity{/ts}:</label>
+ <select class="crm-form-select big required" id="example-entity" name="entity">
+ <option value="" selected="selected">{ts}Choose{/ts}...</option>
+ {foreach from=$examples item=entity}
+ <option value="{$entity}" {if !empty($entities.deprecated) && in_array($entity, $entities.deprecated)}class="strikethrough"{/if}>
+ {$entity}
+ </option>
+ {/foreach}
+ </select>
+
+ <label for="example-action">{ts}Example{/ts}:</label>
+ <select class="crm-form-select big crm-select2" id="example-action" name="action">
+ <option value="" selected="selected">{ts}Choose{/ts}...</option>
+ </select>
+<pre id="example-result" class="linenums lang-php" title="{ts escape='html'}Results are displayed here.{/ts}">
+{ts}Results are displayed here.{/ts}
</pre>
-</form>
+ </form>
+ </div>
+</div>
{strip}
<script type="text/template" id="api-param-tpl">