var
entity,
action,
+ actions = ['get'],
fields = [],
options = {},
params = {},
+ smartyStub,
fieldTpl = _.template($('#api-param-tpl').html()),
+ optionsTpl = _.template($('#api-options-tpl').html()),
+ returnTpl = _.template($('#api-return-tpl').html()),
chainTpl = _.template($('#api-chain-tpl').html());
+ /**
+ * Call prettyPrint function if it successfully loaded from the cdn
+ */
function prettyPrint() {
if (window.prettyPrint) {
window.prettyPrint();
}
}
+ /**
+ * Add a "fields" row
+ * @param name
+ */
function addField(name) {
$('#api-params').append($(fieldTpl({name: name || ''})));
var $row = $('tr:last-child', '#api-params');
- $('.api-param-name', $row).crmSelect2({data: fields}).change();
+ $('.api-param-name', $row).crmSelect2({
+ data: fields.concat({id: '-', text: ts('Other') + '...'})
+ }).change();
}
+ /**
+ * Add a new "options" row
+ * @param name
+ */
+ function addOptionField(name) {
+ if ($('.api-options-row', '#api-params').length) {
+ $('.api-options-row:last', '#api-params').after($(optionsTpl({})));
+ } else {
+ $('#api-params').append($(optionsTpl({})));
+ }
+ var $row = $('.api-options-row:last', '#api-params');
+ $('.api-option-name', $row).crmSelect2({data: [
+ {id: 'limit', text: 'limit'},
+ {id: 'offset', text: 'offset'},
+ {id: 'sort', text: 'sort'},
+ {id: 'metadata', text: 'metadata'},
+ {id: '-', text: ts('Other') + '...'}
+ ]});
+ }
+
+ /**
+ * Add an "api chain" row
+ */
function addChainField() {
$('#api-params').append($(chainTpl({})));
var $row = $('tr:last-child', '#api-params');
$('.api-chain-entity', $row).crmSelect2({
formatSelection: function(item) {
return '<span class="icon ui-icon-link"></span> API ' + item.text;
- }
+ },
+ placeholder: '<span class="icon ui-icon-link"></span> ' + ts('Entity'),
+ escapeMarkup: function(m) {return m}
});
}
+ /**
+ * Fetch fields for entity+action
+ */
function getFields() {
var required = [];
fields = [];
}
});
showFields(required);
+ if (action === 'get' || action === 'getsingle') {
+ showReturn();
+ }
});
}
- function showFields(required) {
- fields.push({
- id: '-',
- text: ts('Other') + '...'
+ /**
+ * For "get" actions show the "return" options
+ */
+ function showReturn() {
+ $('#api-params').prepend($(returnTpl({})));
+ console.log($(returnTpl({})));
+ $('#api-return-value').crmSelect2({data: fields, multiple: true});
+ }
+
+ /**
+ * Fetch actions for entity
+ */
+ function getActions() {
+ if (entity) {
+ CRM.api3(entity, 'getactions').done(function(data) {
+ // Ensure 'get' is always an action
+ actions = _.union(['get'], data.values);
+ populateActions();
+ });
+ } else {
+ actions = ['get'];
+ populateActions();
+ }
+ }
+
+ /**
+ * Called after getActions to populate action list
+ * @param el
+ */
+ function populateActions(el) {
+ $('#api-action').select2({
+ data: _.transform(actions, function(ret, item) {ret.push({text: item, id: item})})
});
+ }
+
+ /**
+ * Called after getfields to show buttons and required fields
+ * @param required
+ */
+ function showFields(required) {
$('#api-params').empty();
$('#api-param-buttons').show();
if (required.length) {
}
}
+ /**
+ * Add/remove option list for selected field's pseudoconstant
+ */
function toggleOptions() {
var name = $(this).val(),
$valField = $(this).closest('tr').find('.api-param-value');
else if ($valField.data('select2')) {
$valField.select2('destroy');
}
- if (name === '-') {
- $(this).select2('destroy');
- $(this).val('').focus();
- }
}
/**
var ret = '';
if ($.isPlainObject(val)) {
$.each(val, function(k, v) {
- ret += (ret ? ',' : '') + "'" + k + "' => " + phpFormat(v);
+ ret += (ret ? ', ' : '') + "'" + k + "' => " + phpFormat(v);
});
return 'array(' + ret + ')';
}
*/
function smartyFormat(js, key) {
if (js.indexOf('[') > -1 || js.indexOf('{') > -1) {
+ smartyStub = true;
return '$' + key.replace(/[. -]/g, '_');
}
return js;
}
+ /**
+ * Create the params array from user input
+ * @param e
+ */
function buildParams(e) {
params = {};
$('.api-param-checkbox:checked').each(function() {
params[this.name] = 1;
});
- $('input.api-param-value').each(function() {
+ $('input.api-param-value, input.api-option-value').each(function() {
var $row = $(this).closest('tr'),
val = evaluate($(this).val(), $(this).is('.select2-offscreen')),
name = $('input.api-param-name', $row).val(),
op = $('select.api-param-op', $row).val() || '=';
+
+ // Ignore blank values for the return field
+ if ($(this).is('#api-return-value') && !val) {
+ return;
+ }
// Special syntax for api chaining
if (!name && $('select.api-chain-entity', $row).val()) {
name = 'api.' + $('select.api-chain-entity', $row).val() + '.' + $('select.api-chain-action', $row).val();
}
+ // Special handling for options
+ if ($(this).is('.api-option-value')) {
+ op = $('input.api-option-name', $row).val();
+ if (op) {
+ name = 'options';
+ }
+ }
if (name && val !== undefined) {
- params[name] = op === '=' ? val : {};
+ params[name] = op === '=' ? val : (params[name] || {});
if (op !== '=') {
params[name][op] = val;
}
if (!$(el).hasClass('crm-error')) {
$(el)
.addClass('crm-error')
+ .css('width', '82%')
.attr('title', ts('Syntax error'))
.before('<div class="icon red-icon ui-icon-alert"/>');
}
$(el)
.removeClass('crm-error')
.attr('title', '')
+ .css('width', '85%')
.siblings('.ui-icon-alert').remove();
}
json: "CRM.api3('" + entity + "', '" + action + "'",
rest: CRM.config.resourceBase + "extern/rest.php?entity=" + entity + "&action=" + action + "&json=" + JSON.stringify(params) + "&api_key=yoursitekey&key=yourkey"
};
+ smartyStub = false;
$.each(params, function(key, value) {
var js = JSON.stringify(value);
if (!i++) {
}
q.php += " '" + key + "' => " + phpFormat(value) + ",\n";
q.json += " \"" + key + '": ' + js;
- // FIXME: How to deal with complex values in smarty?
q.smarty += ' ' + key + '=' + smartyFormat(js, key);
});
if (i) {
q.smarty += "}\n{foreach from=$result.values item=" + entity.toLowerCase() + "}\n {$" + entity.toLowerCase() + ".some_field}\n{/foreach}";
if (action.indexOf('get') < 0) {
q.smarty = '{* Smarty API only works with get actions *}';
+ } else if (smartyStub) {
+ q.smarty = "{* Smarty does not have a syntax for array literals; assign complex variables on the server *}\n" + q.smarty;
}
$.each(q, function(type, val) {
$('#api-' + type).removeClass('prettyprinted').text(val);
function submit(e) {
e.preventDefault();
if (!entity || !action) {
- alert(ts('Select an entity & action.'));
+ alert(ts('Select an entity.'));
return;
}
if (action.indexOf('get') < 0) {
type: action.indexOf('get') < 0 ? 'POST' : 'GET',
dataType: 'text'
}).done(function(text) {
- $('#api-result').addClass('prettyprint linenums').removeClass('prettyprinted').text(text);
+ $('#api-result').addClass('prettyprint').removeClass('prettyprinted').text(text);
prettyPrint();
});
}
$('form#api-explorer')
.on('change', '#api-entity, #api-action', function() {
entity = $('#api-entity').val();
+ if ($(this).is('#api-entity')) {
+ $('#api-action').select2('val', 'get');
+ getActions();
+ }
action = $('#api-action').val();
if (entity && action) {
$('#api-params').html('<tr><td colspan="4" class="crm-loading-element"></td></tr>');
$('#api-param-buttons, #api-params-table thead').hide();
}
})
- .on('change keyup', 'input.api-param-checkbox, input.api-param-value, input.api-param-name, #api-params select', buildParams)
+ .on('change keyup', 'input.api-input, #api-params select', buildParams)
.on('submit', submit);
$('#api-params')
.on('change', '.api-param-name', toggleOptions)
+ .on('change', '.api-param-name, .api-option-name', function() {
+ if ($(this).val() === '-') {
+ $(this).select2('destroy');
+ $(this).val('').focus();
+ }
+ })
.on('click', '.api-param-remove', function(e) {
e.preventDefault();
$(this).closest('tr').remove();
e.preventDefault();
addField();
});
+ $('#api-option-add').on('click', function(e) {
+ e.preventDefault();
+ addOptionField();
+ });
$('#api-chain-add').on('click', function(e) {
e.preventDefault();
addChainField();