Commit 619c5fa4 authored by jaapjansma's avatar jaapjansma

added action for creating/updating a contact

parent 5e8ab74e
......@@ -202,9 +202,9 @@ abstract class AbstractAction implements \JsonSerializable {
$this->defaultConfiguration = $this->createParameterBag();
foreach($this->getConfigurationSpecification() as $spec) {
if ($spec->getDefaultValue()) {
$this->configuration->set($spec->getName(), $spec->getDefaultValue());
$this->defaultConfiguration->set($spec->getName(), $spec->getDefaultValue());
if ($spec->getDefaultValue() !== null) {
$this->configuration->setParameter($spec->getName(), $spec->getDefaultValue());
$this->defaultConfiguration->setParameter($spec->getName(), $spec->getDefaultValue());
}
}
}
......
<?php
namespace Civi\ActionProvider\Action\Contact;
use \Civi\ActionProvider\Parameter\ParameterBagInterface;
use \Civi\ActionProvider\Parameter\SpecificationBag;
use \Civi\ActionProvider\Parameter\Specification;
use CRM_ActionProvider_ExtensionUtil as E;
/**
* This is a helper class for contact create/update functions.
* The following functions are available in this class:
* - create/update email
* - create/update address
* - create/update phone
*/
class ContactActionUtils {
private static $locationTypes = false;
/**
* Create an address for a contact.
*/
public static function createAddress($contact_id, ParameterBagInterface $parameters, ParameterBagInterface $configuration) {
$existingAddressId = false;
if ($configuration->getParameter('address_update_existing')) {
// Try to find existing address
$existingAddressParams['contact_id'] = $contact_id;
$existingAddressParams['location_type_id'] = $configuration->getParameter('address_location_type');
$existingAddressParams['return'] = 'id';
try {
$existingAddressId = civicrm_api3('Address', 'getvalue', $existingAddressParams);
} catch (\Exception $e) {
// Do nothing
}
}
// Create address
$hasAddressParams = false;
$addressParams = array();
if ($existingAddressId) {
$addressParams['id'] = $existingAddressId;
}
$addressParams['contact_id'] = $contact_id;
$addressParams['location_type_id'] = $configuration->getParameter('address_location_type');
if ($parameters->getParameter('street_address')) {
$addressParams['street_address'] = $parameters->getParameter('street_address');
$hasAddressParams = true;
}
if ($parameters->getParameter('postal_code')) {
$addressParams['postal_code'] = $parameters->getParameter('postal_code');
$hasAddressParams = true;
}
if ($parameters->getParameter('city')) {
$addressParams['city'] = $parameters->getParameter('city');
$hasAddressParams = true;
}
if ($parameters->getParameter('country_id')) {
$addressParams['country_id'] = $parameters->getParameter('country_id');
$hasAddressParams = true;
}
if ($hasAddressParams) {
$result = civicrm_api3('Address', 'create', $addressParams);
return $result['id'];
}
return false;
}
/**
* Update the configuration specification for create address.
*/
public static function createAddressConfigurationSpecification(SpecificationBag $spec) {
$locationTypes = self::getLocationTypes();
reset($locationTypes);
$defaultLocationType = key($locationTypes);
$spec->addSpecification(new Specification('address_location_type', 'Integer', E::ts('Address: Location type'), true, $defaultLocationType, null, $locationTypes, FALSE));
$spec->addSpecification(new Specification('address_update_existing', 'Boolean', E::ts('Address: update existing'), false, 0, null, null, FALSE));
}
/**
* Update the parameter specification for create address.
*/
public static function createAddressParameterSpecification(SpecificationBag $spec) {
$spec->addSpecification(new Specification('street_address', 'String', E::ts('Street and housenumber'), false));
$spec->addSpecification(new Specification('postal_code', 'String', E::ts('Postal code'), false));
$spec->addSpecification(new Specification('city', 'String', E::ts('City'), false));
$spec->addSpecification(new Specification('country_id', 'Integer', E::ts('Country ID'), false));
}
/**
* Create a phone for a contact.
*/
public static function createPhone($contact_id, ParameterBagInterface $parameters, ParameterBagInterface $configuration) {
$existingPhoneId = false;
if ($configuration->getParameter('phone_update_existing')) {
// Try to find existing phone number
$existingPhoneParams['contact_id'] = $contact_id;
$existingPhoneParams['location_type_id'] = $configuration->getParameter('phone_location_type');
$existingPhoneParams['return'] = 'id';
try {
$existingPhoneId = civicrm_api3('Phone', 'getvalue', $existingPhoneParams);
} catch (\Exception $e) {
// Do nothing
}
}
// Create phone
if ($parameters->getParameter('phone')) {
$phoneParams = array();
if ($existingPhoneId) {
$phoneParams['id'] = $existingPhoneId;
}
$phoneParams['contact_id'] = $contact_id;
$phoneParams['location_type_id'] = $configuration->getParameter('phone_location_type');
$phoneParams['phone'] = $parameters->getParameter('phone');
$result = civicrm_api3('Phone', 'create', $phoneParams);
return $result['id'];
}
return false;
}
/**
* Update the configuration specification for create phone.
*/
public static function createPhoneConfigurationSpecification(SpecificationBag $spec) {
$locationTypes = self::getLocationTypes();
reset($locationTypes);
$defaultLocationType = key($locationTypes);
$spec->addSpecification(new Specification('phone_location_type', 'Integer', E::ts('Phone: Location type'), true, $defaultLocationType, null, $locationTypes, FALSE));
$spec->addSpecification(new Specification('phone_update_existing', 'Boolean', E::ts('Phone: update existing'), false, 0, null, null, FALSE));
}
/**
* Update the parameter specification for create phone.
*/
public static function createPhoneParameterSpecification(SpecificationBag $spec) {
$spec->addSpecification(new Specification('phone', 'String', E::ts('Phonenumber'), false));
}
/**
* Create an e-mail address for a contact.
*/
public static function createEmail($contact_id, ParameterBagInterface $parameters, ParameterBagInterface $configuration) {
$existingEmailId = false;
if ($configuration->getParameter('email_update_existing')) {
// Try to find existing email address
$existingEmailParams['contact_id'] = $contact_id;
$existingEmailParams['location_type_id'] = $configuration->getParameter('email_location_type');
$existingEmailParams['return'] = 'id';
try {
$existingEmailId = civicrm_api3('Email', 'getvalue', $existingEmailParams);
} catch (\Exception $e) {
// Do nothing
}
}
// Create email
if ($parameters->getParameter('email')) {
$emailParams = array();
if ($existingEmailId) {
$emailParams['id'] = $existingEmailId;
}
$emailParams['contact_id'] = $contact_id;
$emailParams['location_type_id'] = $configuration->getParameter('email_location_type');
$emailParams['email'] = $parameters->getParameter('email');
$result = civicrm_api3('Email', 'create', $emailParams);
return $result['id'];
}
return false;
}
/**
* Update the configuration specification for create email.
*/
public static function createEmailConfigurationSpecification(SpecificationBag $spec) {
$locationTypes = self::getLocationTypes();
reset($locationTypes);
$defaultLocationType = key($locationTypes);
$spec->addSpecification(new Specification('email_location_type', 'Integer', E::ts('E-mail: Location type'), true, $defaultLocationType, null, $locationTypes, FALSE));
$spec->addSpecification(new Specification('email_update_existing', 'Boolean', E::ts('E-mail: update existing'), false, 0, null, null, FALSE));
}
/**
* Update the parameter specification for create email.
*/
public static function createEmailParameterSpecification(SpecificationBag $spec) {
$spec->addSpecification(new Specification('email', 'String', E::ts('E-mail'), false));
}
private static function getLocationTypes() {
if (!self::$locationTypes) {
self::$locationTypes = array();
$locationTypesApi = civicrm_api3('LocationType', 'get', array('options' => array('limit' => 0)));
foreach($locationTypesApi['values'] as $locationType) {
self::$locationTypes[$locationType['id']] = $locationType['display_name'];
}
}
return self::$locationTypes;
}
}
<?php
namespace Civi\ActionProvider\Action\Contact;
use \Civi\ActionProvider\Action\AbstractAction;
use \Civi\ActionProvider\Parameter\ParameterBagInterface;
use \Civi\ActionProvider\Parameter\SpecificationBag;
use \Civi\ActionProvider\Parameter\Specification;
use CRM_ActionProvider_ExtensionUtil as E;
class CreateUpdateIndividual extends AbstractAction {
/**
* 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) {
// Create contact
if ($parameters->getParameter('contact_id')) {
$params['id'] = $parameters->getParameter('contact_id');
}
$contact_sub_type = $this->configuration->getParameter('contact_sub_type');
$params['contact_type'] = "Individual";
if ($contact_sub_type) {
$params['contact_sub_type'] = $contact_sub_type;
}
$params['first_name'] = $parameters->getParameter('first_name');
$params['last_name'] = $parameters->getParameter('last_name');
if ($parameters->getParameter('middle_name')) {
$params['middle_name'] = $parameters->getParameter('middle_name');
}
$result = civicrm_api3('Contact', 'create', $params);
$contact_id = $result['id'];
$output->setParameter('contact_id', $contact_id);
// Create address
$address_id = ContactActionUtils::createAddress($contact_id, $parameters, $this->configuration);
if ($address_id) {
$output->setParameter('address_id', $address_id);
}
// Create email
$email_id = ContactActionUtils::createEmail($contact_id, $parameters, $this->configuration);
if ($email_id) {
$output->setParameter('email_id', $email_id);
}
// Create phone
$phone_id = ContactActionUtils::createPhone($contact_id, $parameters, $this->configuration);
if ($phone_id) {
$output->setParameter('phone_id', $phone_id);
}
}
/**
* Returns the specification of the configuration options for the actual action.
*
* @return SpecificationBag
*/
public function getConfigurationSpecification() {
$contactSubTypes = array();
$contactSubTypesApi = civicrm_api3('ContactType', 'get', array('parent_id' => 'Individual', 'options' => array('limit' => 0)));
$contactSubTypes[''] = E::ts(' - Select - ');
foreach($contactSubTypesApi['values'] as $contactSubType) {
$contactSubTypes[$contactSubType['name']] = $contactSubType['label'];
}
$spec = new SpecificationBag(array(
new Specification('contact_sub_type', 'String', E::ts('Contact sub type'), false, null, null, $contactSubTypes, FALSE),
));
ContactActionUtils::createAddressConfigurationSpecification($spec);
ContactActionUtils::createEmailConfigurationSpecification($spec);
ContactActionUtils::createPhoneConfigurationSpecification($spec);
return $spec;
}
/**
* Returns the specification of the parameters of the actual action.
*
* @return SpecificationBag
*/
public function getParameterSpecification() {
$contactIdSpec = new Specification('contact_id', 'String', E::ts('Contact ID'), false);
$contactIdSpec->setDescription(E::ts('Leave empty to create a new Individual'));
$spec = new SpecificationBag(array(
$contactIdSpec,
new Specification('first_name', 'String', E::ts('First name'), true),
new Specification('last_name', 'String', E::ts('Last name'), true),
new Specification('middle_name', 'String', E::ts('Middle name'), false),
));
ContactActionUtils::createAddressParameterSpecification($spec);
ContactActionUtils::createEmailParameterSpecification($spec);
ContactActionUtils::createPhoneParameterSpecification($spec);
return $spec;
}
/**
* 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('contact_id', 'Integer', E::ts('Contact ID'), true),
new Specification('address_id', 'Integer', E::ts('Address record ID'), false),
new Specification('email_id', 'Integer', E::ts('Email record ID'), false),
new Specification('phone_id', 'Integer', E::ts('Phone ID'), false),
));
}
/**
* Returns the human readable title of this action
*/
public function getTitle() {
return E::ts('Create or update Individual');
}
/**
* Returns the tags for this action.
*/
public function getTags() {
return array(
AbstractAction::SINGLE_CONTACT_ACTION_TAG,
AbstractAction::DATA_MANIPULATION_TAG,
);
}
}
......@@ -21,7 +21,7 @@ class ParameterBag implements ParameterBagInterface, \IteratorAggregate {
* Tests whether the parameter with the name exists.
*/
public function doesParameterExists($name) {
if (isset($this->parameters[$name])) {
if (isset($this->parameters[$name]) && $this->parameters[$name] != null) {
return true;
}
return false;
......
......@@ -22,14 +22,13 @@ class SpecificationBag implements \IteratorAggregate {
public static function validate(ParameterBagInterface $parameters, SpecificationBag $specification) {
foreach($specification as $spec) {
// First check whether the value is present and should be present.
$value = $parameters->getParameter($spec->getName());
if (isset($value)) {
// Check the type
if (!\CRM_Utils_Type::validate($value, $spec->getDataType(), false)) {
return false;
}
} elseif ($spec->isRequired()) {
return false;
if ($spec->isRequired() && !$parameters->doesParameterExists($spec->getName())) {
return false;
} if($parameters->doesParameterExists($spec->getName())) {
$value = $parameters->getParameter($spec->getName());
if (!\CRM_Utils_Type::validate($value, $spec->getDataType(), false)) {
return false;
}
}
}
return true;
......
......@@ -29,6 +29,7 @@ class Provider {
$actions = array(
new \Civi\ActionProvider\Action\AddToGroup(),
new \Civi\ActionProvider\Action\Contact\ContactDataById(),
new \Civi\ActionProvider\Action\Contact\CreateUpdateIndividual(),
new \Civi\ActionProvider\Action\Contact\FindOrCreateContactByEmail(),
new \Civi\ActionProvider\Action\Event\UpdateParticipantStatus(),
);
......
......@@ -4,7 +4,9 @@
<div ng-if="spec.options"
crm-ui-field="{name: 'spec.name', title: spec.title, required: spec.required}">
<select
style="width: 90%;"
crm-ui-select
ui-options="{allowClear: true}"
name="{{spec.name}}"
ng-model="configuration[spec.name]"
ng-required="spec.required"
......@@ -30,9 +32,8 @@
class="big crm-form-text"
ng-required="spec.required"
/>
<div class="description" ng-if="spec.description" ng-bind-html="spec.description"></div>
</div>
<div class="description" ng-if="spec.description" ng-bind-html="spec.description"></div>
</ng-repeat>
<div ng-if="fields" class="crm-block crm-form-block" ng-form="input_mapper">
......@@ -46,7 +47,7 @@
ui-jq="select2"
ui-options="{allowClear: true}"
ng-model="mapping[spec.name]"
required="spec.required"
ng-required="spec.required"
ng-options="field.name as field.label for field in fields">
<option value=""></option>
</select>
......
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