Commit c022ded7 authored by ErikHommel's avatar ErikHommel

Merge branch 'master' of lab.civicrm.org:extensions/form-processor

parents 653a5998 1fb9fb2b
......@@ -220,6 +220,8 @@
// Validate the parameters.
foreach($formProcessor['inputs'] as $input) {
$inputType = $input['type'];
unset($input['type']);
$objInput = new \CRM_FormProcessor_BAO_FormProcessorInput();
$objInput->copyValues($input);
......@@ -231,7 +233,7 @@
if ($input['is_required'] && !isset($params[$input['name']])) {
throw new \API_Exception('Parameter '.$input['name'].' is required');
}
if (isset($params[$input['name']]) && !empty($params[$input['name']]) && !$input['type']->validateValue($params[$input['name']], $params)) {
if (isset($params[$input['name']]) && !empty($params[$input['name']]) && !$inputType->validateValue($params[$input['name']], $params)) {
throw new \API_Exception('Parameter '.$input['name'].' is invalid');
}
// Check the validations on the input.
......@@ -243,7 +245,7 @@
}
}
$dataBag->setInputData($objInput, $input['type']->normalizeValue($params[$objInput->name]));
$dataBag->setInputData($objInput, $inputType->normalizeValue($params[$objInput->name]));
}
// Execute the actions
......@@ -272,7 +274,7 @@
$actionClass->setCondition($condition);
// Check whether the action should be delayed
if ($action['delay']) {
if (isset($action['delay']) && $action['delay']) {
$delayClass = $delayedActionFactory->getHandlerByName($action['delay']);
$configuration = $delayClass->getDefaultConfiguration();
if (is_array($action['delay_configuration'])) {
......
......@@ -119,6 +119,8 @@ class FormProcessorDefaults extends FormProcessor implements API_ProviderInterfa
// Validate the parameters.
foreach ($formProcessor['default_data_inputs'] as $input) {
$inputType = $input['type'];
unset($input['type']);
$objInput = new \CRM_FormProcessor_BAO_FormProcessorDefaultDataInput();
$objInput->copyValues($input);
......@@ -130,7 +132,7 @@ class FormProcessorDefaults extends FormProcessor implements API_ProviderInterfa
if ($input['is_required'] && !isset($params[$input['name']])) {
throw new \API_Exception('Parameter ' . $input['name'] . ' is required');
}
if (isset($params[$input['name']]) && !empty($params[$input['name']]) && !$input['type']->validateValue($params[$input['name']], $params)) {
if (isset($params[$input['name']]) && !empty($params[$input['name']]) && !$inputType->validateValue($params[$input['name']], $params)) {
throw new \API_Exception('Parameter ' . $input['name'] . ' is invalid');
}
// Check the validations on the input.
......@@ -142,7 +144,7 @@ class FormProcessorDefaults extends FormProcessor implements API_ProviderInterfa
}
}
$dataBag->setInputData($objInput, $input['type']->normalizeValue($params[$objInput->name]));
$dataBag->setInputData($objInput, $inputType->normalizeValue($params[$objInput->name]));
}
// Execute the actions
......
......@@ -17,7 +17,7 @@
/**
* @var array<AbstractValidator>
*/
protected $types = array();
protected $validators = array();
/**
* @var Factory
......
......@@ -147,9 +147,9 @@
input.type = type;
if (input.deletedValidators) {
angular.forEach(input.deletedValidators, function (validator, validator_index) {
if (validator.id) {
crmApi('FormProcessorValidator', 'delete', {'id': id});
angular.forEach(input.deletedValidators, function (deletedValidator, validator_index) {
if (deletedValidator.id) {
crmApi('FormProcessorValidation', 'delete', {'id': deletedValidator.id});
}
});
}
......
......@@ -67,10 +67,10 @@
ui-jq="select2"
ui-options="{dropdownAutoWidth : true, allowClear: true}"
ng-model="newValidator"
ng-options="newValidator.label for newValidator in validators">
ng-options="validator.label for validator in validators track by validator.name">
<option value="">{{ts('- Select validation -')}}</option>
</select>
<button crm-icon="fa-plus" ng-click="addValidator(newValidator)">{{ts('Add validation rule')}}</button>
<button crm-icon="fa-plus" ng-click="addValidator(newValidator);">{{ts('Add validation rule')}}</button>
</div>
</div>
</div>
......
(function(angular, $, _) {
function getValidators($scope) {
var validators = []
for(var validator_name in CRM.form_processor.validators) {
var validator = CRM.form_processor.validators[validator_name];
var exists = false;
for (var i = 0; i < $scope.input.validators.length; i++) {
if ($scope.input.validators[i].validator.name == validator.name) {
exists = true;
break;
}
}
if (!exists) {
validators.push(validator);
}
}
return validators;
}
angular.module('form_processor').controller('InputDialogCtrl', function InputDialogCtrl($scope, dialogService, crmApi) {
$scope.ts = CRM.ts(null);
$scope.input = angular.copy($scope.model.input);
$scope.locks = {name: true};
$scope.isNameValid = false;
$scope.validators = CRM.form_processor.validators;
$scope.validators = getValidators($scope);
$scope.newValidator = null;
if (!$scope.input.deletedValidators) {
$scope.input.deletedValidators = [];
}
......@@ -46,7 +65,7 @@
$scope.saveClick = function() {
for(var i=0; i<$scope.input.validators.length; i++) {
$scope.input.validators[i].configuration = {}
$scope.input.validators[i].configuration = {};
for (var key in $scope.input.validators[i].validator.configuration) {
$scope.input.validators[i].configuration[key] = $scope.input.validators[i].validator.configuration[key];
}
......@@ -63,11 +82,18 @@
if (!newValidator) {
return;
}
var validator = {
validator: angular.copy(newValidator),
configuration: angular.copy(newValidator.configuration_spec.default_configuration)
};
$scope.input.validators.push(validator);
for (var i=0; i < $scope.input.validators.length; i++) {
if ($scope.input.validators[i].validator.name == newValidator.name) {
return;
}
}
var validator = {
validator: angular.copy(newValidator),
configuration: angular.copy(newValidator.configuration_spec.default_configuration)
};
$scope.input.validators.push(validator);
$scope.validators = getValidators($scope);
return;
};
$scope.removeValidator = function(validator) {
......@@ -75,6 +101,7 @@
if (index >= 0) {
$scope.input.deletedValidators.push(validator);
$scope.input.validators.splice(index, 1);
$scope.validators = getValidators($scope);
}
};
......
......@@ -28,8 +28,9 @@ The basic concepts of the **Form Processor** are explained on:
In this guide you will also find an example to set up forms with the **Form Processor** without coding and an example how to develop your own *actions* and *retrieval criteria*, as well as an introduction on how to create your own:
- [How to create a basic form to sign up for a newsletter](sign-up-newsletter.md)
- [How to create a form for your email preferences](email-preferences.md)
- [How to create a basic form to sign up for a newsletter (Drupal 7 website)](sign-up-newsletter.md)
- [How to create a basic form to sign up for a newsletter (Wordpress website)](sign-up-newsletter-wordpress.md)
- [How to create a form for your email preferences (Drupal 7 website)](email-preferences.md)
The latter How To will give you an example of how to develop your own actions!
......
# Example of a basic form to sign up for a newsletter from a Wordpress website
This example details how to create a form on my public wordpress website where a visitor can enter *first name, last name and email* and click to sign up for our monhtly newsletter.
The **Form Processor** extension will make sure this is processed in the CiviCRM backend.
The public website is on another server than CiviCRM and I am using Wordpress on my public website example.
## Defining the form processor
The general information for my form processor looks like this:
![Form Processor General](/images/newsletter-general-fp.png)
On my form processor I will accept 3 inputs: first name, last name and email.
The email will be validated (is it a valid email?).
![Form Processor Inputs](/images/newsletter-inputs-fp.png)
Once the form is sent from the public website I would like the following to happen:
* check if we already have a contact with the email entered and if so, use that contact
* if there is no contact with the email yet, create a new contact with the email, first and last name from the form
* add the found or created contact to our newsletter group
So here is what the actions look like:
![Form Processor Actions](/images/newsletter-actions-fp.png)
The action to find or create the contact has been specified so:
![Action to Find or Create Contact](/images/newsletter-find-action.png)
Finally in the action to add the contact to the group I have selected the group the contact should be added to and specified that the contact ID found in the find action should be used.
![Action to Add to Group](/images/newsletter-group-action.png)
## Testing the form processor with the api explorer
Once I have specified my form processor I can test if it works as I would expect.
The form processor generates an API action for the API entity FormProcessor so I can use the API Explorer (Support>Developer>Api Explorer v3) to test if it works.
In this case this is what I will enter:
![Test with API Explorer](/images/newsletter-api-test.png)
And if I then click on **Execute** it should actually add or find the contact and add him/her to the newsletter group.
## Defining the form in Wordpress
I now need to design a form on my public website that communicates with my form processor. In this example I use Wordpress.
### Contact Form 7 CiviCRM Integration
To be able to communicate with a CiviCRM installation on another server the **Contact Form 7 CiviCRM integration** plugin is installed, and I have also installed the **Contact Form 7** plugin. (see the [Requirements](requirements.md) section):
![CiviMRF modules](/images/newsletter-wp-plugins.png)
Once I have installed the Contact Form 7 plugins I can specify how to connect to CiviCRM under Settings and then CiviCRM settings:
![CiviMRF Profile Menu](/images/newsletter-wp-civicrm-settings.png).
In this settings screen I specify the URL to the REST interface of CiviCRM and added the site and API keys.
The URL is broken down in two parts: first is the hostname including http or https, the
second part is the link to the rest.php in your civicrm installation.
!!! Note "Site and API keys"
(for background information check [System Administrator Guide on Site Key][sitekey] and [StackExchange on API key][apikey]).
### Creating the form with Contact Form 7
I am now going to create my form in Wordpress by clicking *Contact*, then *Add new*. I then create my form in a big textarea.
The contact form 7 plugin works in this way that you design your form describing it in text.
The text to design my form looks like this:
![New empty form](/images/newsletter-wp-contact-form-design.png)
Make sure that your fields have the same name as the name defined in the form processor. The field is defined between
brackets `[]` after that the type of the field is specified. And an asterix `*` indicates that this field is required.
Then a space and the name of the field.
Press save and if there are any errors on the *Mail* tab correct those by clicking on the *Mail* tab. You can also
disable the e-mail by setting the following under additional settings:
![Additional settings](/images/newsletter-wp-contact-form-additional-settings.png)
Now click on the *CiviCRM* tab and you will see the following:
![CiviCRM Settings](/images/newsletter-wp-contact-form-civicrm.png)
In this screen you specify to which API you want to send your form to. With the form processor the Entity is always _FormProcessor_
and the action is the *name* of your form processor.
### Add the form a page
In the top of the form you see the short code which you can use to display the form on a page:
![shortcode](images/newsletter-wp-contact-form-shortcode.png)
Copy this short code.
It is time to create a page and paste our short code:
![page](images/newsletter-wp-new-page.png)
Save the page.
### The end result of the form
After we have saved the page our form looks like this. I did not apply any styling or theming in my wordpress installation:
![Resulting form](/images/newsletter-wp-form.png)
## Result!
If I now enter data in my form as you can see here:
![Form for John Doe](/images/newsletter-wp-jd-form.png)
The result in CiviCRM will be that a contact is created and he is added to the newsletter group:
![CiviCRM John Doe](/images/newsletter-wp-jd-civi1.png)
![CiviCRM John Doe](/images/newsletter-wp-jd-civi2.png)
[sitekey]:https://docs.civicrm.org/sysadmin/en/latest/setup/site-key/
[apikey]:https://civicrm.stackexchange.com/questions/31092/where-is-the-api-key
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