Commit 92bc85a3 authored by jaapjansma's avatar jaapjansma

Added create participant action and updated action provider on the go.

parent 619c5fa4
......@@ -62,11 +62,14 @@ class ContactDataById extends AbstractAction {
continue;
}
$type = \CRM_Utils_Type::typeToString($field['type']);
if (empty($type)) {
continue;
}
switch ($type) {
case 'Int':
$type = 'Integer';
break;
}
}
$fieldSpec = new Specification(
$field['name'],
$type,
......
<?php
namespace Civi\ActionProvider\Action\Event;
use \Civi\ActionProvider\Action\AbstractAction;
use \Civi\ActionProvider\Parameter\ParameterBagInterface;
use \Civi\ActionProvider\Parameter\SpecificationBag;
use \Civi\ActionProvider\Parameter\Specification;
use \Civi\ActionProvider\Parameter\OptionGroupSpecification;
use \Civi\ActionProvider\Utils\CustomField;
use CRM_ActionProvider_ExtensionUtil as E;
class CreateOrUpdateParticipant extends AbstractAction {
/**
* Returns the human readable title of this action
*/
public function getTitle() {
return E::ts('Register contact for an event');
}
/**
* Returns the specification of the configuration options for the actual action.
*
* @return SpecificationBag
*/
public function getConfigurationSpecification() {
return new SpecificationBag(array(
new Specification('status_id', 'Integer', E::ts('Status'), true, null, 'ParticipantStatusType', null, FALSE),
new OptionGroupSpecification('role_id', 'participant_role', E::ts('Role'), true, null, FALSE),
new Specification('update_existing', 'Boolean', E::ts('Update existing event registration'), false, 0, null, null, FALSE),
new Specification('source', 'String', E::ts('Source'), false, null, null, null, FALSE),
));
}
/**
* Returns the specification of the configuration options for the actual action.
*
* @return SpecificationBag
*/
public function getParameterSpecification() {
$specs = new SpecificationBag(array(
/**
* The parameters given to the Specification object are:
* @param string $name
* @param string $dataType
* @param string $title
* @param bool $required
* @param mixed $defaultValue
* @param string|null $fkEntity
* @param array $options
* @param bool $multiple
*/
new Specification('event_id', 'Integer', E::ts('Event ID'), true, null, null, null, FALSE),
new Specification('contact_id', 'Integer', E::ts('Contact ID'), true, null, null, null, FALSE),
new Specification('campaign_id', 'Integer', E::ts('Campaign ID'), false, null, null, null, FALSE),
));
$customGroups = civicrm_api3('CustomGroup', 'get', array('extends' => 'Participant', 'is_active' => 1, 'options' => array('limit' => 0)));
foreach($customGroups['values'] as $customGroup) {
$customFields = civicrm_api3('CustomField', 'get', array('custom_group_id' => $customGroup['id'], 'is_active' => 1, 'options' => array('limit' => 0)));
foreach($customFields['values'] as $customField) {
$spec = CustomField::getSpecFromCustomField($customField, $customGroup['title'].': ', false);
if ($spec) {
$specs->addSpecification($spec);
}
}
}
return $specs;
}
/**
* Returns the specification of the output parameters of this action.
*
* This function could be overriden by child classes.
*
* @return SpecificationBag
*/
public function getOutputSpecification() {
return new SpecificationBag(array(
new Specification('id', 'Integer', E::ts('Participant record ID')),
));
}
/**
* Run the action
*
* @param ParameterInterface $parameters
* The parameters to this action.
* @param ParameterBagInterface $output
* The parameters this action can send back
* @return void
*/
protected function doAction(ParameterBagInterface $parameters, ParameterBagInterface $output) {
// Get the contact and the event.
$contact_id = $parameters->getParameter('contact_id');
$event_id = $parameters->getParameter('event_id');
$role_id = $this->configuration->getParameter('role_id');
$status_id = $this->configuration->getParameter('status_id');
$participant_id = false;
if ($this->configuration->getParameter('update_existing')) {
// Find the participant record for this contact and event.
// This assumes that the contact has already been registered for the event.
$participant_id = \CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_participant WHERE is_test = '0' AND contact_id = %1 AND event_id = %2 and role_id = %3 ORDER BY id DESC LIMIT 1", array(
1 => array($contact_id, 'Integer'),
2 => array($event_id, 'Integer'),
3 => array($role_id, 'Integer')
));
}
// Create or Update the participant record through an API call.
try {
$participantParams = array();
if ($participant_id) {
$participantParams['id'] = $participant_id;
}
$participantParams['event_id'] = $event_id;
$participantParams['status_id'] = $status_id;
$participantParams['role_id'] = $role_id;
$participantParams['contact_id'] = $contact_id;
if ($this->configuration->doesParameterExists('source')) {
$participantParams['source'] = $this->configuration->getParameter('source');
}
if ($parameters->getParameter('campaign_id')) {
$participantParams['campaign_id'] = $parameters->getParameter('campaign_id');
}
foreach($this->getParameterSpecification() as $spec) {
if (stripos($spec->getName(), 'custom_')!==0) {
continue;
}
if ($parameters->getParameter($spec->getName())) {
$participantParams[$spec->getName()] = $parameters->getParameter($spec->getName());
}
}
$result = civicrm_api3('Participant', 'create', $participantParams);
$output->setParameter('id', $result['id']);
} catch (Exception $e) {
throw new \Civi\ActionProvider\Exception\ExecutionException(E::ts('Could not update or create a participant record'));
}
}
/**
* Returns the tags for this action.
*/
public function getTags() {
return array(
AbstractAction::SINGLE_CONTACT_ACTION_TAG,
AbstractAction::DATA_MANIPULATION_TAG,
);
}
}
\ No newline at end of file
<?php
namespace Civi\ActionProvider\Parameter;
use CRM_ActionProvider_ExtensionUtil as E;
class OptionGroupSpecification extends Specification {
protected $option_group_id;
/**
* @param string $name
* @param string $dataType
* @param string $title
* @param bool $required
* @param mixed $defaultValue
* @param string|null $fkEntity
* @param array $options
* @param bool $multiple
*/
public function __construct($name, $option_group_id, $title='', $required = false, $defaultValue = null, $multiple = false) {
$this->setName($name);
$this->setDataType('String');
$this->setTitle($title);
$this->setRequired($required);
$this->setDefaultValue($defaultValue);
$this->setMultiple($multiple);
$this->setOptionGroupId($option_group_id);
}
/**
* Set the option group id.
*
* @param string
* @return Specification
*/
public function setOptionGroupId($option_group_id) {
$this->option_group_id = $option_group_id;
return $this;
}
public function getOptionGroupId() {
return $this->option_group_id;
}
/**
* @return array
*/
public function getOptions() {
$options = array();
$optionsApi = civicrm_api3('OptionValue', 'get', array('option_group_id' => $this->option_group_id, 'options' => array('limit' => 0)));
foreach($optionsApi['values'] as $optionValue) {
$options[$optionValue['value']] = $optionValue['label'];
}
return $options;
}
/**
* @param array $options
*
* @return $this
*/
public function setOptions($options) {
// Do nothing
return $this;
}
/**
* @param $option
*/
public function addOption($option) {
// Do nothing.
}
}
......@@ -248,9 +248,19 @@ class Specification {
public function toArray() {
$ret = array();
foreach (get_object_vars($this) as $key => $val) {
$key = strtolower(preg_replace('/(?=[A-Z])/', '_$0', $key));
$ret[$key] = $val;
foreach (get_class_methods($this) as $method) {
$var = false;
if (stripos($method, 'get') === 0) {
$var = lcfirst(substr($method, 3));
} elseif (stripos($method, 'is') === 0) {
$var = lcfirst(substr($method, 2));
}
if (!$var) {
continue;
}
$key = strtolower(preg_replace('/(?=[A-Z])/', '_$0', $var));
$ret[$key] = $this->$method();
}
return $ret;
}
......
......@@ -98,7 +98,7 @@ class SpecificationBag implements \IteratorAggregate {
public function toArray() {
$return = array();
foreach($this->parameterSpecifications as $spec) {
$return[] = $spec->toArray();
$return[] = $spec->toArray();
}
return $return;
}
......
......@@ -32,6 +32,7 @@ class Provider {
new \Civi\ActionProvider\Action\Contact\CreateUpdateIndividual(),
new \Civi\ActionProvider\Action\Contact\FindOrCreateContactByEmail(),
new \Civi\ActionProvider\Action\Event\UpdateParticipantStatus(),
new \Civi\ActionProvider\Action\Event\CreateOrUpdateParticipant(),
);
foreach($actions as $action) {
......
<?php
namespace Civi\ActionProvider\Utils;
use \Civi\ActionProvider\Parameter\Specification;
use \Civi\ActionProvider\Parameter\OptionGroupSpecification;
use CRM_ActionProvider_ExtensionUtil as E;
/**
* Helper class to add a configuration specification from custom field
*/
class CustomField {
/**
* Gets the data type of the custom field.
*/
public static function getTypeForCustomField($field) {
$type = $field['data_type'];
switch ($type) {
case 'Int':
case 'ContactReference':
$type = 'Integer';
break;
case 'File':
$type = null;
break;
}
return $type;
}
/**
* Converts a specifcation object to a custom field.
*
* @param array
* The custom field data
* @param string
* @param bool
* When this param is true then the required state is taken over from the custom field.
* Other wise the field is not required.
* @return Specification|null
*/
public static function getSpecFromCustomField($customField, $titlePrefix='', $useRequiredFromCustomField=false) {
$name = 'custom_'.$customField['id'];
$type = self::getTypeForCustomField($customField);
$title = trim($titlePrefix.$customField['label']);
$is_required = $customField['is_required'] && $useRequiredFromCustomField ? true : false;
$multiple = false;
$default = null;
if (isset($customField['option_group_id']) && $customField['option_group_id']) {
return new OptionGroupSpecification($name, $customField['option_group_id'], $title, $is_required, $default, $multiple);
} elseif($type) {
return new Specification($name, $type, $title, $is_required, $default, null, array(), $multiple);
}
return null;
}
}
......@@ -2,10 +2,11 @@
<ng-repeat ng-repeat="spec in action.configuration_spec">
<div ng-if="spec.options"
crm-ui-field="{name: 'spec.name', title: spec.title, required: spec.required}">
crm-ui-field="{name: spec.name, title: spec.title, required: spec.required}">
<select
style="width: 90%;"
crm-ui-select
crm-ui-id="{{spec.name}}"
ui-options="{allowClear: true}"
name="{{spec.name}}"
ng-model="configuration[spec.name]"
......@@ -15,18 +16,20 @@
</select>
</div>
<div ng-if="spec.fk_entity"
crm-ui-field="{name: 'spec.name', title: spec.title, required: spec.required}">
crm-ui-field="{name: spec.name, title: spec.title, required: spec.required}">
<input
crm-entityref="{entity: spec.fk_entity, select: {allowClear: true, placeholder: spec.title}}"
name="{{spec.name}}"
crm-ui-id="{{spec.name}}"
ng-model="configuration[spec.name]"
ng-required="spec.required"
/>
</div>
<div ng-if="!spec.options && !spec.fk_entity"
crm-ui-field="{name: 'spec.name', title: spec.title, required: spec.required}">
crm-ui-field="{name: spec.name, title: spec.title, required: spec.required}">
<input
type="text"
crm-ui-id="{{spec.name}}"
name="{{spec.name}}"
ng-model="configuration[spec.name]"
class="big crm-form-text"
......@@ -39,7 +42,7 @@
<div ng-if="fields" class="crm-block crm-form-block" ng-form="input_mapper">
<h3>{{ts('Parameter Mapping')}}</h3>
<ng-repeat ng-repeat="spec in action.parameter_spec">
<div crm-ui-field="{name: spec.name, title: spec.title, required: spec.required}">
<div crm-ui-field="{name: 'input_mapper.'+spec.name, title: spec.title, required: spec.required}">
<select
style="width: 90%;"
crm-ui-id="input_mapper.{{spec.name}}"
......
......@@ -13,6 +13,7 @@
},
link: function($scope, $el, $attr) {
$scope.ts = CRM.ts(null);
console.log($scope.action.parameter_spec);
}
};
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment