Commit 35070aff authored by MikeyMJCO's avatar MikeyMJCO
Browse files

Merge branch 'master' into 'MikeyMJCO-master-patch-52249'

# Conflicts:
#   docs/sign-up-newsletter-wordpress.md
parents 195979a8 333ca3de
Version 1.7 (not yet released)
Version 1.17 (not yet released)
============
Version 1.16
============
* Fixed issue with titles of default inputs on the tryout form.
* Allow re-ordering of actions !20
Version 1.15
============
* Fixed issue with default data drop down.
Version 1.14
============
* Possible to delete imported form processors (unless those are in an extension).
Version 1.13.2
============
* Fixed issue with mailing group type and multiple.
Version 1.13.1
============
* Fixed issue with mailing group type and multiple.
Version 1.13
============
* Fixed bug with MailingGroupType.
Version 1.12
============
* Added import functionality to the manage form processors screen. Also improved importing/exporting.
Version 1.11
============
* Support names as well as values on State/Province input
* Fixed issue with formatting of output when trying a form processor.
* Added Multiple to Custom Options Type.
Version 1.10
===========
* Fixed #9 Error in the default value
Fixed issue with output handler decide what to send.
Version 1.9
===========
* Support deleting conditions from actions.
* Fixed issue #15 Errors on import from extensions
* Added File URL Type
Version 1.8
===========
* Fixed issue when output handler is not set breaking the whole form processor.
* Implemented Grouped Parameter Specification (requires Action Provider version 1.20 or newer).
Version 1.7
===========
* Fixed notice in FormProcessor->invokeFormProcessor
* Fixed #9 Error in the default value
* Fixed #11 Errors in DateType validation
* Added try out functionality.
* Added Min/Max validators.
* Now passing input type to input validators.
* Added Date validator.
Version 1.6
===========
......
......@@ -113,7 +113,13 @@ class CRM_FormProcessor_BAO_FormProcessorAction extends CRM_FormProcessor_DAO_Fo
$action->mapping = json_encode($action->mapping);
}
if (is_array($action->condition_configuration)) {
$action->condition_configuration = json_encode($action->condition_configuration);
// Delete condition if set to "No condition".
if ($action->condition_configuration['name']) {
$action->condition_configuration = json_encode($action->condition_configuration);
}
else {
$action->condition_configuration = '';
}
}
if (is_array($action->delay_configuration)) {
$action->delay_configuration = json_encode($action->delay_configuration);
......
......@@ -34,23 +34,25 @@
$row['actions'] = array_values(CRM_FormProcessor_BAO_FormProcessorAction::getValues(array('form_processor_instance_id' => $formProcessorInstance->id)));
$row['default_data_inputs'] = array_values(CRM_FormProcessor_BAO_FormProcessorDefaultDataInput::getValues(array('form_processor_instance_id' => $formProcessorInstance->id)));
$row['default_data_actions'] = array_values(CRM_FormProcessor_BAO_FormProcessorDefaultDataAction::getValues(array('form_processor_instance_id' => $formProcessorInstance->id)));
if (isset($row['output_handler_configuration']) && is_string($row['output_handler_configuration'])) {
$row['output_handler_configuration'] = json_decode($row['output_handler_configuration'], true);
}
if (empty($row['output_handler_configuration']) || !is_array($row['output_handler_configuration'])) {
$row['output_handler_configuration'] = array();
}
$handler = \Civi::service('form_processor_output_handler_factory')->getHandlerByName($row['output_handler']);
if ($handler) {
$configuration = $handler->getDefaultConfiguration();
if (isset($row['output_handler_configuration']) && is_string($row['output_handler_configuration'])) {
$row['output_handler_configuration'] = json_decode($row['output_handler_configuration'], true);
}
if (empty($row['output_handler_configuration']) || !is_array($row['output_handler_configuration'])) {
$row['output_handler_configuration'] = array();
}
foreach($row['output_handler_configuration'] as $name => $value) {
$configuration->set($name, $value);
}
$handler->setConfiguration($configuration);
$row['output_handler'] = $handler;
}
$handler = null;
if ($row['output_handler']) {
$handler = \Civi::service('form_processor_output_handler_factory')->getHandlerByName($row['output_handler']);
if ($handler) {
$configuration = $handler->getDefaultConfiguration();
foreach ($row['output_handler_configuration'] as $name => $value) {
$configuration->set($name, $value);
}
$handler->setConfiguration($configuration);
$row['output_handler'] = $handler;
}
}
if (isset($row['default_data_output_configuration']) && is_string($row['default_data_output_configuration'])) {
$row['default_data_output_configuration'] = json_decode($row['default_data_output_configuration'], true);
......@@ -145,7 +147,12 @@
$formProcessorInstance = new CRM_FormProcessor_BAO_FormProcessorInstance();
$formProcessorInstance->id = $id;
$formProcessorInstance->delete();
if ($formProcessorInstance->find(TRUE)) {
if (!empty($formProcessorInstance->source_file)) {
\Civi\FormProcessor\Exporter\ExportToJson::deleteUploadedFile($formProcessorInstance->source_file);
}
$formProcessorInstance->delete();
}
CRM_Utils_Hook::post('delete', 'FormProcessorInstance', $id, CRM_Core_DAO::$_nullArray);
......
<?php
/**
* @author Jaap Jansma <jaap.jansma@civicoop.org>
* @license AGPL-3.0
*/
use CRM_FormProcessor_ExtensionUtil as E;
class CRM_FormProcessor_Form_Export extends CRM_Core_Form {
private $formProcessorId;
private $dataProcessor;
/**
* @var \Civi\DataProcessor\ProcessorType\AbstractProcessorType
*/
private $dataProcessorClass;
private $currentUrl;
/**
* Function to perform processing before displaying form (overrides parent function)
*
* @access public
*/
function preProcess() {
$this->formProcessorId = CRM_Utils_Request::retrieve('id', 'Integer');
if ($this->_action == CRM_Core_Action::EXPORT) {
$exporter = new \Civi\FormProcessor\Exporter\ExportToJson();
$data = (array) $exporter->export($this->formProcessorId);
$file_download_name = $data['name'].'.json';
$mime_type = 'application/json';
$buffer = json_encode($data, JSON_PRETTY_PRINT);
CRM_Utils_System::download(
$file_download_name,
$mime_type,
$buffer,
NULL,
TRUE,
'download'
);
}
}
}
<?php
/**
* @author Jaap Jansma <jaap.jansma@civicoop.org>
* @license AGPL-3.0
*/
use CRM_FormProcessor_ExtensionUtil as E;
class CRM_FormProcessor_Form_Import extends CRM_Core_Form {
/**
* Function to perform processing before displaying form (overrides parent function)
*
* @access public
*/
function preProcess() {
parent::preProcess();
}
public function buildQuickForm() {
$this->add('file', 'uploadFile', E::ts('Import Form Processor File'), 'size=30 maxlength=255', TRUE);
$this->addButtons(array(
array('type' => 'next', 'name' => E::ts('Import'), 'isDefault' => TRUE,),
array('type' => 'cancel', 'name' => E::ts('Cancel'))
));
}
public function postProcess() {
$values = $this->getSubmitValues(True);
// Check for JSON extension required
$filetype = $values['uploadFile']['type'];
$redirectUrl = CRM_Utils_System::url('civicrm/admin/automation/formprocessor/#/formprocessors');
if($filetype != 'application/json'){
CRM_Core_Session::setStatus(E::ts('Imported file should be a json file'), '', 'error');
} else {
$config = CRM_Core_Config::singleton();
$uniqID = md5(uniqid(rand(), TRUE));
$filename = $values['uploadFile']['name'].'.'.$uniqID;
$directoryName = $config->customFileUploadDir . 'FormProcessor';
CRM_Utils_File::createDir($directoryName);
CRM_Utils_File::restrictAccess($directoryName.DIRECTORY_SEPARATOR, TRUE);
if (!rename($values['uploadFile']['tmp_name'], $directoryName . DIRECTORY_SEPARATOR . $filename)) {
CRM_Core_Error::statusBounce(ts('Could not move custom file to custom upload directory'));
}
$result = civicrm_api3('FormProcessorInstance', 'import', ['file' => $filename]);
CRM_Core_Session::setStatus(E::ts('Imported form processor'), '', 'success');
}
CRM_Utils_System::redirect($redirectUrl);
}
}
<?php
/**
* @author Jaap Jansma <jaap.jansma@civicoop.org>
* @license AGPL-3.0
*/
use CRM_FormProcessor_ExtensionUtil as E;
class CRM_FormProcessor_Form_RunFormProcessor extends CRM_Core_Form {
protected $defaultFields = [];
protected $fields = [];
protected $formProcessorName;
/**
* Preprocess form.
*
* This is called before buildForm. Any pre-processing that
* needs to be done for buildForm should be done here.
*
* This is a virtual function and should be redefined if needed.
*/
public function preProcess() {
parent::preProcess(); // TODO: Change the autogenerated stub
$this->formProcessorName = CRM_Utils_Request::retrieve('_qf_formProcessorName', 'String', $this, TRUE);
}
/**
* This virtual function is used to build the form.
*
* It replaces the buildForm associated with QuickForm_Page. This allows us
* to put preProcess in front of the actual form building routine
*/
public function buildQuickForm() {
$this->add('hidden', '_qf_formProcessorName');
$this->setDefaults(['_qf_formProcessorName' => $this->formProcessorName]);
$formProcessor = civicrm_api3('FormProcessorInstance', 'getsingle', ['name' => $this->formProcessorName]);
$defaultFields = civicrm_api3('FormProcessorDefaults', 'getfields', ['api_action' => $this->formProcessorName]);
$this->defaultFields = $defaultFields['values'];
$defaultFieldNames = [];
foreach($this->defaultFields as $field) {
$attributes = [
'style' => 'min-width:250px',
'class' => 'huge'
];
if (isset($field['options']) && is_array($field['options'])) {
$attributes['class'] .= ' crm-select2';
$attributes['placeholder'] = E::ts('- select -');
if ($field['formprocessor.is_multiple']) {
$attributes['multiple'] = 'multiple';
}
$this->add('select', $this->formProcessorName . '_default_' . $field['name'], $field['title'], $field['options'], $field['api.required'], $attributes);
} else {
$this->add('text', $this->formProcessorName . '_default_' . $field['name'], $field['title'], $attributes, $field['api.required']);
}
$defaultFieldNames[] = $this->formProcessorName.'_default_'.$field['name'];
}
$this->assign('enableDefault', $formProcessor['enable_default_data']);
$this->assign('defaultFieldNames', $defaultFieldNames);
$fields = civicrm_api3('FormProcessor', 'getfields', ['api_action' => $this->formProcessorName]);
$this->fields = $fields['values'];
$fieldNames = [];
foreach($this->fields as $field) {
$attributes = [
'style' => 'min-width:250px',
'class' => 'huge'
];
if (isset($field['options']) && is_array($field['options'])) {
$attributes['class'] .= ' crm-select2';
$attributes['placeholder'] = E::ts('- select -');
if ($field['formprocessor.is_multiple']) {
$attributes['multiple'] = 'multiple';
}
$this->add('select', $field['name'], $field['title'], $field['options'], $field['api.required'], $attributes);
} else {
$this->add('text', $field['name'], $field['title'], $attributes, $field['api.required']);
}
$fieldNames[] = $field['name'];
}
$this->assign('fieldNames', $fieldNames);
$this->addButtons([
[
'type' => 'refresh',
'name' => E::ts('Load'),
'isDefault' => FALSE,
],
[
'type' => 'submit',
'name' => E::ts('Submit'),
'isDefault' => FALSE,
],
]);
if (isset($this->_submitValues['_qf_RunFormProcessor_refresh']) && $this->_submitValues['_qf_RunFormProcessor_refresh'] == E::ts('Load')) {
$this->loadDefaultData($this->formProcessorName);
}
}
protected function loadDefaultData($formProcessorName) {
$defaultParams = [];
foreach($this->defaultFields as $field) {
$submitFieldName = $formProcessorName.'_default_'.$field['name'];
if (isset($this->_submitValues[$submitFieldName])) {
$defaultParams[$field['name']] = $this->_submitValues[$submitFieldName];
}
}
$defaultParams['version'] = 3;
$default = civicrm_api('FormProcessorDefaults', $formProcessorName, $defaultParams);
if (!isset($default['is_error']) || !$default['is_error']) {
$this->setDefaults($default);
foreach($default as $k=>$v) {
$idx = $this->_elementIndex[$k];
$this->_elements[$idx]->setValue($v);
}
} else {
CRM_Core_Session::setStatus($default['error_message']);
$this->clearForm();
}
}
protected function clearForm() {
foreach($this->fields as $field) {
$idx = $this->_elementIndex[$field['name']];
$this->_elements[$idx]->setValue('');
}
}
/**
* Performs the server side validation.
*
* @return bool
* true if no error found
* @throws HTML_QuickForm_Error
* @since 1.0
*/
public function validate() {
$return = parent::validate(); // TODO: Change the autogenerated stub
if (isset($this->_submitValues['_qf_RunFormProcessor_refresh']) && $this->_submitValues['_qf_RunFormProcessor_refresh'] == E::ts('Load')) {
foreach($this->fields as $field) {
if (isset($this->_errors[$field['name']])) {
unset($this->_errors[$field['name']]);
}
}
} elseif (isset($this->_submitValues['_qf_RunFormProcessor_submit']) && $this->_submitValues['_qf_RunFormProcessor_submit'] == E::ts('Submit')) {
foreach($this->defaultFields as $field) {
$submitFieldName = $this->formProcessorName.'_default_'.$field['name'];
if (isset($this->_errors[$submitFieldName])) {
unset($this->_errors[$submitFieldName]);
}
}
}
return (0 == count($this->_errors));
}
/**
* Called after the form is validated.
*
* Any processing of form state etc should be done in this function.
* Typically all processing associated with a form should be done
* here and relevant state should be stored in the session
*
* This is a virtual function and should be redefined if needed
*/
public function postProcess() {
if (isset($this->_submitValues['_qf_RunFormProcessor_submit']) && $this->_submitValues['_qf_RunFormProcessor_submit'] == E::ts('Submit') && !count($this->_errors)) {
$params = [];
foreach($this->fields as $field) {
$submitFieldName = $field['name'];
if (isset($this->_submitValues[$submitFieldName])) {
$params[$field['name']] = $this->_submitValues[$submitFieldName];
}
}
$params['version'] = 3;
$result = civicrm_api('FormProcessor', $this->formProcessorName, $params);
$this->assign('result_json', json_encode($result, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
if (!isset($result['is_error']) || !$result['is_error']) {
$this->clearForm();
}
}
}
}
......@@ -53,7 +53,10 @@ class CRM_FormProcessor_Upgrader extends CRM_FormProcessor_Upgrader_Base {
}*/
public function uninstall() {
$this->executeSqlFile('sql/uninstall.sql');
$config = \CRM_Core_Config::singleton();
$directoryName = $config->customFileUploadDir . 'FormProcessor';
\CRM_Utils_File::cleanDir($directoryName, TRUE);
$this->executeSqlFile('sql/uninstall.sql');
}
/**
......@@ -92,7 +95,7 @@ class CRM_FormProcessor_Upgrader extends CRM_FormProcessor_Upgrader_Base {
$manager = CRM_Extension_System::singleton()->getManager();
$dependencies = array(
['action-provider', '1.9']
['action-provider', '1.20']
);
$unmet = array();
......
......@@ -100,7 +100,7 @@
}
$field = array(
'name' => $input['name'],
'title' => $input['name'],
'title' => $input['title'],
'description' => '',
'type' => $input['type']->getCrmType(),
'api.required' => $input['is_required'],
......@@ -109,6 +109,7 @@
);
if ($input['type'] instanceof OptionListInterface) {
$field['options'] = $input['type']->getOptions($apiParams);
$field['formprocessor.is_multiple'] = $input['type']->isMultiple(); // We add our own spec here, as an option for is multiple does not exists.
}
// Set a default value
if (isset($input['default_value']) && $input['default_value'] != '') {
......@@ -239,13 +240,14 @@
// Check the validations on the input.
if (isset($params[$input['name']]) && $params[$input['name']] != "") {
foreach ($input['validators'] as $validator) {
if (!$validator['validator']->validate($params[$input['name']])) {
if (!$validator['validator']->validate($params[$input['name']], $inputType)) {
throw new \API_Exception($validator['validator']->getInvalidMessage() . ' (Parameter ' . $input['name'] . ')');
}
}
}
$dataBag->setInputData($objInput, $inputType->normalizeValue($params[$objInput->name]));
if (isset($params[$objInput->name])) {
$dataBag->setInputData($objInput, $inputType->normalizeValue($params[$input['name']]));
}
}
// Execute the actions
......
......@@ -53,7 +53,7 @@ class FormProcessorDefaults extends FormProcessor implements API_ProviderInterfa
foreach ($formProcessor['default_data_inputs'] as $input) {
$field = array(
'name' => $input['name'],
'title' => $input['name'],
'title' => !empty($input['title']) ? $input['title'] : $input['name'],
'description' => '',
'type' => $input['type']->getCrmType(),
'api.required' => $input['is_required'],
......@@ -62,6 +62,7 @@ class FormProcessorDefaults extends FormProcessor implements API_ProviderInterfa
);
if ($input['type'] instanceof OptionListInterface) {
$field['options'] = $input['type']->getOptions($apiParams);
$field['formprocessor.is_multiple'] = $input['type']->isMultiple(); // We add our own spec here, as an option for is multiple does not exists.
}
// Set a default value
if (isset($input['default_value']) && $input['default_value'] != '') {
......@@ -138,13 +139,13 @@ class FormProcessorDefaults extends FormProcessor implements API_ProviderInterfa
// Check the validations on the input.
if (isset($params[$input['name']]) && $params[$input['name']] != "") {
foreach ($input['validators'] as $validator) {
if (!$validator['validator']->validate($params[$input['name']])) {
if (!$validator['validator']->validate($params[$input['name']], $inputType)) {
throw new \API_Exception($validator['validator']->getInvalidMessage() . ' (Parameter ' . $input['name'] . ')');
}
}
}
$dataBag->setInputData($objInput, $inputType->normalizeValue($params[$objInput->name]));
$dataBag->setInputData($objInput, $inputType->normalizeValue($params[$input['name']]));
}
// Execute the actions
......
......@@ -115,7 +115,7 @@ class DataBag {
if ($input) {
return $this->inputData[$input->id];
}
} elseif ($splitted_alias[0] == 'action') {
} elseif ($splitted_alias[0] == 'action' && isset($this->actionData[$splitted_alias[1]][$splitted_alias[2]])) {
return $this->actionData[$splitted_alias[1]][$splitted_alias[2]];
}
return null;
......
......@@ -3,10 +3,10 @@
namespace Civi\FormProcessor\Exporter;
class ExportToJson {
/**
* Exports a form processor to json.
*
*
* @param int $form_processor_id
* The form processor.
* @return string
......@@ -21,19 +21,21 @@ class ExportToJson {
unset($form_processor['modified_date']);
unset($form_processor['status']);
unset($form_processor['source_file']);
unset($form_processor['try_out_url']);
unset($form_processor['export_url']);
$form_processor['output_handler'] = $form_processor['output_handler']['name'];
foreach($form_processor['inputs'] as $key => $input) {
unset($form_processor['inputs'][$key]['id']);
unset($form_processor['inputs'][$key]['form_processor_instance_id']);
$form_processor['inputs'][$key]['type'] = $input['type']['name'];
foreach($input['validators'] as $validator_key => $validator) {
unset($form_processor['inputs'][$key]['validators'][$validator_key]['id']);
unset($form_processor['inputs'][$key]['validators'][$validator_key]['entity']);
unset($form_processor['inputs'][$key]['validators'][$validator_key]['entity_id']);
unset($form_processor['inputs'][$key]['validators'][$validator_key]['entity_id']);
$form_processor['inputs'][$key]['validators'][$validator_key]['validator'] = $validator['validator']['name'];
}
}
......@@ -45,17 +47,17 @@ class ExportToJson {
unset($form_processor['actions'][$key]['condition_configuration']['title']);
}
}
foreach($form_processor['default_data_inputs'] as $key => $input) {
unset($form_processor['default_data_inputs'][$key]['id']);
unset($form_processor['default_data_inputs'][$key]['form_processor_instance_id']);
$form_processor['default_data_inputs'][$key]['type'] = $input['type']['name'];
foreach($input['validators'] as $validator_key => $validator) {
unset($form_processor['default_data_inputs'][$key]['validators'][$validator_key]['id']);
unset($form_processor['default_data_inputs'][$key]['validators'][$validator_key]['entity']);