diff --git a/CRM/FormProcessor/BAO/FormProcessorAction.php b/CRM/FormProcessor/BAO/FormProcessorAction.php index 8c192bdcfe42e463a2eafc72ca381d981bc088ed..015df032481390c1a1e7de754440cb7bce05a1f3 100644 --- a/CRM/FormProcessor/BAO/FormProcessorAction.php +++ b/CRM/FormProcessor/BAO/FormProcessorAction.php @@ -31,7 +31,7 @@ class CRM_FormProcessor_BAO_FormProcessorAction extends CRM_FormProcessor_DAO_Fo while ($action->fetch()) { $row = array(); self::storeValues($action, $row); - if (!empty($row['form_processor_id'])) { + if (!empty($row['form_processor_instance_id'])) { $provider = form_processor_get_action_provider(); $action_type = $provider->getActionByName($row['type']); @@ -143,15 +143,15 @@ class CRM_FormProcessor_BAO_FormProcessorAction extends CRM_FormProcessor_DAO_Fo } /** - * Function to delete all actions with a form processor id + * Function to delete all actions with a form processor instance id * - * @param int $formProcessorId + * @param int $formProcessorInstanceId * @access public * @static */ - public static function deleteWithFormProcessorId($formProcessorId) { + public static function deleteWithFormProcessorInstanceId($formProcessorInstanceId) { $action = new CRM_FormProcessor_BAO_FormProcessorAction(); - $action->form_processor_id = $formProcessorId; + $action->form_processor_instance_id = $formProcessorInstanceId; $action->find(FALSE); while ($action->fetch()) { CRM_Utils_Hook::pre('delete', 'FormProcessorAction', $action->id, CRM_Core_DAO::$_nullArray); diff --git a/CRM/FormProcessor/BAO/FormProcessorInput.php b/CRM/FormProcessor/BAO/FormProcessorInput.php index 67702ff8825167c4aa5752e81adb59ad345b4539..0844a98f942f0f6282d8c25da9de6be504786c3c 100644 --- a/CRM/FormProcessor/BAO/FormProcessorInput.php +++ b/CRM/FormProcessor/BAO/FormProcessorInput.php @@ -30,7 +30,7 @@ class CRM_FormProcessor_BAO_FormProcessorInput extends CRM_FormProcessor_DAO_For while ($input->fetch()) { $row = array(); self::storeValues($input, $row); - if (!empty($row['form_processor_id'])) { + if (!empty($row['form_processor_instance_id'])) { $type = \Civi::service('form_processor_type_factory')->getTypeByName($row['type']); if ($type) { $configuration = $type->getDefaultConfiguration(); @@ -47,6 +47,9 @@ class CRM_FormProcessor_BAO_FormProcessorInput extends CRM_FormProcessor_DAO_For $row['type'] = $type; } + + $row['validators'] = array_values(CRM_FormProcessor_BAO_FormProcessorInputValidation::getValues(array('form_processor_input_id' => $input->id))); + $result[$row['id']] = $row; } else { //invalid input because no there is no form processor @@ -128,15 +131,15 @@ class CRM_FormProcessor_BAO_FormProcessorInput extends CRM_FormProcessor_DAO_For } /** - * Function to delete all inputs with a form processor id + * Function to delete all inputs with a form processor instance id * - * @param int $formProcessorId + * @param int $formProcessorInstanceId * @access public * @static */ - public static function deleteWithFormProcessorId($formProcessorId) { + public static function deleteWithFormProcessorInstanceId($formProcessorInstanceId) { $input = new CRM_FormProcessor_BAO_FormProcessorInput(); - $input->form_processor_id = $formProcessorId; + $input->form_processor_instance_id = $formProcessorInstanceId; $input->find(FALSE); while ($input->fetch()) { CRM_Utils_Hook::pre('delete', 'FormProcessorInput', $input->id, CRM_Core_DAO::$_nullArray); diff --git a/CRM/FormProcessor/BAO/FormProcessorInputValidation.php b/CRM/FormProcessor/BAO/FormProcessorInputValidation.php new file mode 100644 index 0000000000000000000000000000000000000000..99ee59198c621c1fecbe043c88b881cab559c68f --- /dev/null +++ b/CRM/FormProcessor/BAO/FormProcessorInputValidation.php @@ -0,0 +1,151 @@ +<?php + +use CRM_FormProcessor_ExtensionUtil as E; + +/** + * @author Jaap Jansma (CiviCooP) <jaap.jansma@civicoop.org> + * @license http://www.gnu.org/licenses/agpl-3.0.html + */ +class CRM_FormProcessor_BAO_FormProcessorInputValidation extends CRM_FormProcessor_DAO_FormProcessorInputValidation { + + /** + * Function to get values + * + * @return array $result found rows with data + * @access public + * @static + */ + public static function getValues($params) { + $result = array(); + $inputValidation = new CRM_FormProcessor_BAO_FormProcessorInputValidation(); + if (!empty($params)) { + $fields = self::fields(); + foreach ($params as $key => $value) { + if (isset($fields[$key])) { + $inputValidation->$key = $value; + } + } + } + $inputValidation->find(); + while ($inputValidation->fetch()) { + $row = array(); + self::storeValues($inputValidation, $row); + if (!empty($row['form_processor_input_id'])) { + $validator = \Civi::service('form_processor_validation_factory')->getValidatorByName($row['validator']); + if ($validator) { + $configuration = $validator->getDefaultConfiguration(); + if (isset($row['configuration']) && is_string($row['configuration'])) { + $row['configuration'] = json_decode($row['configuration'], true); + } + if (empty($row['configuration']) || !is_array($row['configuration'])) { + $row['configuration'] = array(); + } + foreach($row['configuration'] as $name => $value) { + $configuration->set($name, $value); + } + $validator->setConfiguration($configuration); + + $row['validator'] = $validator; + } + $result[$row['id']] = $row; + } else { + //invalid input because no there is no form processor + CRM_FormProcessor_BAO_FormProcessorInputValidation::deleteWithId($row['id']); + } + } + return $result; + } + + /** + * Function to add or update form processor input validation + * + * @param array $params + * @return array $result + * @access public + * @throws Exception when params is empty + * @static + */ + public static function add($params) { + $result = array(); + if (empty($params)) { + throw new Exception('Params can not be empty when adding or updating a form processor input validation'); + } + + if (!empty($params['id'])) { + CRM_Utils_Hook::pre('edit', 'FormProcessorInputValidation', $params['id'], $params); + } + else { + CRM_Utils_Hook::pre('create', 'FormProcessorInputValidation', NULL, $params); + } + + $inputValidation = new CRM_FormProcessor_BAO_FormProcessorInputValidation(); + $fields = self::fields(); + foreach ($params as $key => $value) { + if (isset($fields[$key])) { + $inputValidation->$key = $value; + } + } + if (is_array($inputValidation->configuration)) { + $inputValidation->configuration = json_encode($inputValidation->configuration); + } + $inputValidation->save(); + self::storeValues($inputValidation, $result); + + if (!empty($params['id'])) { + CRM_Utils_Hook::post('edit', 'FormProcessorInputValidation', $inputValidation->id, $inputValidation); + } + else { + CRM_Utils_Hook::post('create', 'FormProcessorInputValidation', $inputValidation->id, $inputValidation); + } + + return $result; + } + + /** + * Function to delete a form processor input with id + * + * @param int $id + * @throws Exception when $id is empty + * @access public + * @static + */ + public static function deleteWithId($id) { + if (empty($id)) { + throw new Exception('id can not be empty when attempting to delete a form processor input validation'); + } + + CRM_Utils_Hook::pre('delete', 'FormProcessorInputValidation', $id, CRM_Core_DAO::$_nullArray); + + $inputValidation = new CRM_FormProcessor_BAO_FormProcessorInputValidation(); + $inputValidation->id = $id; + if ($inputValidation->find(true)) { + $inputValidation->delete(); + } + + CRM_Utils_Hook::post('delete', 'FormProcessorInputValidation', $id, CRM_Core_DAO::$_nullArray); + + return; + } + + /** + * Function to delete all inputs with a form processor input id + * + * @param int $formProcessorInputId + * @access public + * @static + */ + public static function deleteWithFormProcessorInputId($formProcessorInputId) { + $inputValidation = new CRM_FormProcessor_BAO_FormProcessorInputValidation(); + $inputValidation->form_processor_input_id = $formProcessorInputId; + $inputValidation->find(FALSE); + while ($inputValidation->fetch()) { + CRM_Utils_Hook::pre('delete', 'FormProcessorInputValidation', $inputValidation->id, CRM_Core_DAO::$_nullArray); + + $inputValidation->delete(); + + CRM_Utils_Hook::post('delete', 'FormProcessorInputValidation', $inputValidation->id, CRM_Core_DAO::$_nullArray); + } + } + + +} \ No newline at end of file diff --git a/CRM/FormProcessor/BAO/FormProcessor.php b/CRM/FormProcessor/BAO/FormProcessorInstance.php similarity index 55% rename from CRM/FormProcessor/BAO/FormProcessor.php rename to CRM/FormProcessor/BAO/FormProcessorInstance.php index b355b1d771511d9633d5d72de54ed927847d09bd..cdf59a60843f3f005d2a5a4c8840ca558f3a1c09 100644 --- a/CRM/FormProcessor/BAO/FormProcessor.php +++ b/CRM/FormProcessor/BAO/FormProcessorInstance.php @@ -4,7 +4,7 @@ * @license http://www.gnu.org/licenses/agpl-3.0.html */ - class CRM_FormProcessor_BAO_FormProcessor extends CRM_FormProcessor_DAO_FormProcessor { + class CRM_FormProcessor_BAO_FormProcessorInstance extends CRM_FormProcessor_DAO_FormProcessorInstance { /** * Function to get values @@ -15,21 +15,21 @@ */ public static function getValues($params) { $result = array(); - $formProcessor = new CRM_FormProcessor_BAO_FormProcessor(); + $formProcessorInstance = new CRM_FormProcessor_BAO_FormProcessorInstance(); if (!empty($params)) { $fields = self::fields(); foreach ($params as $key => $value) { if (isset($fields[$key])) { - $formProcessor->$key = $value; + $formProcessorInstance->$key = $value; } } } - $formProcessor->find(); - while ($formProcessor->fetch()) { + $formProcessorInstance->find(); + while ($formProcessorInstance->fetch()) { $row = array(); - self::storeValues($formProcessor, $row); - $row['inputs'] = array_values(CRM_FormProcessor_BAO_FormProcessorInput::getValues(array('form_processor_id' => $formProcessor->id))); - $row['actions'] = array_values(CRM_FormProcessor_BAO_FormProcessorAction::getValues(array('form_processor_id' => $formProcessor->id))); + self::storeValues($formProcessorInstance, $row); + $row['inputs'] = array_values(CRM_FormProcessor_BAO_FormProcessorInput::getValues(array('form_processor_instance_id' => $formProcessorInstance->id))); + $row['actions'] = array_values(CRM_FormProcessor_BAO_FormProcessorAction::getValues(array('form_processor_instance_id' => $formProcessorInstance->id))); $result[$row['id']] = $row; } @@ -37,7 +37,7 @@ } /** - * Function to add or update a FormProcessor + * Function to add or update a FormProcessorInstance * * @param array $params * @return array $result @@ -52,39 +52,39 @@ } if (!empty($params['id'])) { - CRM_Utils_Hook::pre('edit', 'FormProcessor', $params['id'], $params); + CRM_Utils_Hook::pre('edit', 'FormProcessorInstance', $params['id'], $params); } else { - CRM_Utils_Hook::pre('create', 'FormProcessor', NULL, $params); + CRM_Utils_Hook::pre('create', 'FormProcessorInstance', NULL, $params); } - $formProcessor = new CRM_FormProcessor_BAO_FormProcessor(); + $formProcessorInstance = new CRM_FormProcessor_BAO_FormProcessorInstance(); $fields = self::fields(); foreach ($params as $key => $value) { if (isset($fields[$key])) { - $formProcessor->$key = $value; + $formProcessorInstance->$key = $value; } } - if (!isset($formProcessor->name) || empty($formProcessor->name)) { - if (isset($formProcessor->title)) { - $formProcessor->name = CRM_FormProcessor_BAO_FormProcessor::buildNameFromLabel($formProcessor->title); + if (!isset($formProcessorInstance->name) || empty($formProcessorInstance->name)) { + if (isset($formProcessorInstance->title)) { + $formProcessorInstance->name = CRM_FormProcessor_BAO_FormProcessorInstance::buildNameFromLabel($formProcessorInstance->title); } } - $formProcessor->save(); - self::storeValues($formProcessor, $result); + $formProcessorInstance->save(); + self::storeValues($formProcessorInstance, $result); if (!empty($params['id'])) { - CRM_Utils_Hook::post('edit', 'FormProcessor', $formProcessor->id, $formProcessor); + CRM_Utils_Hook::post('edit', 'FormProcessorInstance', $formProcessorInstance->id, $formProcessorInstance); } else { - CRM_Utils_Hook::post('create', 'FormProcessor', $formProcessor->id, $formProcessor); + CRM_Utils_Hook::post('create', 'FormProcessorInstance', $formProcessorInstance->id, $formProcessorInstance); } return $result; } /** - * Function to delete a FormProcessor with id + * Function to delete a FormProcessorInstance with id * * @param int $id * @throws Exception when $id is empty @@ -96,18 +96,18 @@ throw new Exception('id can not be empty when attempting to delete a form processor'); } - CRM_Utils_Hook::pre('delete', 'FormProcessor', $id, CRM_Core_DAO::$_nullArray); + CRM_Utils_Hook::pre('delete', 'FormProcessorInstance', $id, CRM_Core_DAO::$_nullArray); // First delete all inputs - CRM_FormProcessor_BAO_FormProcessorInput::deleteWithFormProcessorId($id); + CRM_FormProcessor_BAO_FormProcessorInput::deleteWithFormProcessorInstanceId($id); // And all actions - CRM_FormProcessor_BAO_FormProcessorAction::deleteWithFormProcessorId($id); + CRM_FormProcessor_BAO_FormProcessorAction::deleteWithFormProcessorInstanceId($id); - $rule = new CRM_FormProcessor_BAO_FormProcessor(); - $rule->id = $id; - $rule->delete(); + $formProcessorInstance = new CRM_FormProcessor_BAO_FormProcessorInstance(); + $formProcessorInstance->id = $id; + $formProcessorInstance->delete(); - CRM_Utils_Hook::post('delete', 'FormProcessor', $id, CRM_Core_DAO::$_nullArray); + CRM_Utils_Hook::post('delete', 'FormProcessorInstance', $id, CRM_Core_DAO::$_nullArray); return; } @@ -135,7 +135,7 @@ * @static */ public static function isNameValid($name, $id=null) { - $sql = "SELECT COUNT(*) FROM `civicrm_form_processor` WHERE `name` = %1"; + $sql = "SELECT COUNT(*) FROM `civicrm_form_processor_instance` WHERE `name` = %1"; $params[1] = array($name, 'String'); if ($id) { $sql .= " AND `id` != %2"; diff --git a/CRM/FormProcessor/DAO/FormProcessorAction.php b/CRM/FormProcessor/DAO/FormProcessorAction.php index aeef77ecf525c17f06ea6e53f2d9361fb1314ca3..fedb33547a897a1484ec0d7e5b1e97c9ea385ac5 100644 --- a/CRM/FormProcessor/DAO/FormProcessorAction.php +++ b/CRM/FormProcessor/DAO/FormProcessorAction.php @@ -36,12 +36,12 @@ class CRM_FormProcessor_DAO_FormProcessorAction extends CRM_Core_DAO { 'type' => CRM_Utils_Type::T_INT, 'required' => true ), - 'form_processor_id' => array( - 'name' => 'form_processor_id', + 'form_processor_instance_id' => array( + 'name' => 'form_processor_instance_id', 'title' => E::ts('Form Processor ID'), 'type' => CRM_Utils_Type::T_INT, 'required' => true, - 'FKApiName' => 'FormProcessor', + 'FKApiName' => 'FormProcessorInstance', ), 'weight' => array( 'name' => 'weight', @@ -88,7 +88,7 @@ class CRM_FormProcessor_DAO_FormProcessorAction extends CRM_Core_DAO { if (!(self::$_fieldKeys)) { self::$_fieldKeys = array( 'id' => 'id', - 'form_processor_id' => 'form_processor_id', + 'form_processor_instance_id' => 'form_processor_instance_id', 'weight' => 'weight', 'title' => 'title', 'type' => 'type', diff --git a/CRM/FormProcessor/DAO/FormProcessorInput.php b/CRM/FormProcessor/DAO/FormProcessorInput.php index 8fc23fc1a7aab307b65a28ee4e5f7e2912465e2d..b183c1a8b1faccadaa01d2263b554a3eb9511cfc 100644 --- a/CRM/FormProcessor/DAO/FormProcessorInput.php +++ b/CRM/FormProcessor/DAO/FormProcessorInput.php @@ -36,12 +36,12 @@ class CRM_FormProcessor_DAO_FormProcessorInput extends CRM_Core_DAO { 'type' => CRM_Utils_Type::T_INT, 'required' => true ), - 'form_processor_id' => array( - 'name' => 'form_processor_id', - 'title' => E::ts('Form Processor ID'), + 'form_processor_instance_id' => array( + 'name' => 'form_processor_instance_id', + 'title' => E::ts('Form Processor Instance ID'), 'type' => CRM_Utils_Type::T_INT, 'required' => true, - 'FKApiName' => 'FormProcessor', + 'FKApiName' => 'FormProcessorInstance', ), 'name' => array( 'name' => 'name', @@ -89,7 +89,7 @@ class CRM_FormProcessor_DAO_FormProcessorInput extends CRM_Core_DAO { if (!(self::$_fieldKeys)) { self::$_fieldKeys = array( 'id' => 'id', - 'form_processor_id' => 'form_processor_id', + 'form_processor_instance_id' => 'form_processor_instance_id', 'name' => 'name', 'type' => 'type', 'is_required' => 'is_required', diff --git a/CRM/FormProcessor/DAO/FormProcessorInputValidation.php b/CRM/FormProcessor/DAO/FormProcessorInputValidation.php new file mode 100644 index 0000000000000000000000000000000000000000..21b131ef7193dd4235a7ab293b3620729c38beef --- /dev/null +++ b/CRM/FormProcessor/DAO/FormProcessorInputValidation.php @@ -0,0 +1,104 @@ +<?php + +use CRM_FormProcessor_ExtensionUtil as E; + +/** + * @author Jaap Jansma (CiviCooP) <jaap.jansma@civicoop.org> + * @license http://www.gnu.org/licenses/agpl-3.0.html + */ +class CRM_FormProcessor_DAO_FormProcessorInputValidation extends CRM_Core_DAO { + /** + * static instance to hold the field values + * + * @var array + * @static + */ + static $_fields = null; + static $_export = null; + /** + * empty definition for virtual function + */ + static function getTableName() { + return 'civicrm_form_processor_input_validation'; + } + /** + * returns all the column names of this table + * + * @access public + * @return array + */ + public static function &fields() { + if (!(self::$_fields)) { + self::$_fields = array( + 'id' => array( + 'name' => 'id', + 'title' => E::ts('ID'), + 'type' => CRM_Utils_Type::T_INT, + 'required' => true + ), + 'form_processor_input_id' => array( + 'name' => 'form_processor_input_id', + 'title' => E::ts('Form Processor Input ID'), + 'type' => CRM_Utils_Type::T_INT, + 'required' => true, + 'FKApiName' => 'FormProcessorInput', + ), + 'validator' => array( + 'name' => 'validator', + 'title' => E::ts('Validator'), + 'type' => CRM_Utils_Type::T_STRING, + 'maxlength' => 80, + 'required' => true, + ), + 'configuration' => array( + 'name' => 'configuration', + 'title' => E::ts('Configuration'), + 'type' => CRM_Utils_Type::T_TEXT, + ), + ); + } + return self::$_fields; + } + /** + * Returns an array containing, for each field, the array key used for that + * field in self::$_fields. + * + * @access public + * @return array + */ + public static function &fieldKeys() { + if (!(self::$_fieldKeys)) { + self::$_fieldKeys = array( + 'id' => 'id', + 'form_processor_input_id' => 'form_processor_input_id', + 'validator' => 'validator', + 'configuration' => 'configuration', + ); + } + return self::$_fieldKeys; + } + /** + * returns the list of fields that can be exported + * + * @access public + * return array + * @static + */ + static function &export($prefix = false) + { + if (!(self::$_export)) { + self::$_export = array(); + $fields = self::fields(); + foreach($fields as $name => $field) { + if (CRM_Utils_Array::value('export', $field)) { + if ($prefix) { + self::$_export['form_processor_input'] = & $fields[$name]; + } else { + self::$_export[$name] = & $fields[$name]; + } + } + } + } + return self::$_export; + } +} \ No newline at end of file diff --git a/CRM/FormProcessor/DAO/FormProcessor.php b/CRM/FormProcessor/DAO/FormProcessorInstance.php similarity index 94% rename from CRM/FormProcessor/DAO/FormProcessor.php rename to CRM/FormProcessor/DAO/FormProcessorInstance.php index 4acef1ae6b28ab3c5014650a8758e06b89554cd2..1df1a4fc1f0cee022c5faf60c6a1e0d7100571c5 100644 --- a/CRM/FormProcessor/DAO/FormProcessor.php +++ b/CRM/FormProcessor/DAO/FormProcessorInstance.php @@ -6,7 +6,7 @@ use CRM_FormProcessor_ExtensionUtil as E; * @author Jaap Jansma (CiviCooP) <jaap.jansma@civicoop.org> * @license http://www.gnu.org/licenses/agpl-3.0.html */ -class CRM_FormProcessor_DAO_FormProcessor extends CRM_Core_DAO { +class CRM_FormProcessor_DAO_FormProcessorInstance extends CRM_Core_DAO { /** * static instance to hold the field values * @@ -19,7 +19,7 @@ class CRM_FormProcessor_DAO_FormProcessor extends CRM_Core_DAO { * empty definition for virtual function */ static function getTableName() { - return 'civicrm_form_processor'; + return 'civicrm_form_processor_instance'; } /** * returns all the column names of this table @@ -118,7 +118,7 @@ class CRM_FormProcessor_DAO_FormProcessor extends CRM_Core_DAO { foreach($fields as $name => $field) { if (CRM_Utils_Array::value('export', $field)) { if ($prefix) { - self::$_export['form_processor'] = & $fields[$name]; + self::$_export['form_processor_instance'] = & $fields[$name]; } else { self::$_export[$name] = & $fields[$name]; } diff --git a/Civi/FormProcessor/API/Provider.php b/Civi/FormProcessor/API/Provider.php index e61d20bfc60681c7cae8378d8e76090a0d62d58a..95260d84cb21ac6e8e1b4cf82eb855a05df43080 100644 --- a/Civi/FormProcessor/API/Provider.php +++ b/Civi/FormProcessor/API/Provider.php @@ -48,7 +48,7 @@ $params = $apiRequest['params']; // Find the form processor - $formProcessors = \CRM_FormProcessor_BAO_FormProcessor::getValues(array('name' => $apiRequest['action'])); + $formProcessors = \CRM_FormProcessor_BAO_FormProcessorInstance::getValues(array('name' => $apiRequest['action'])); if (count($formProcessors) != 1) { throw new \API_Exception('Could not find a form processor'); } @@ -96,7 +96,7 @@ */ public function getEntityNames($version) { return array( - 'FormProcessorExecutor' + 'FormProcessor' ); } @@ -109,8 +109,7 @@ */ public function getActionNames($version, $entity) { $params['is_active'] = 1; - $form_processors = \CRM_FormProcessor_BAO_FormProcessor::getValues($params); - $actions = array(); + $form_processors = \CRM_FormProcessor_BAO_FormProcessorInstance::getValues($params); foreach($form_processors as $form_processor) { $actions[] = $form_processor['name']; } diff --git a/Civi/FormProcessor/Validation/AbstractValidator.php b/Civi/FormProcessor/Validation/AbstractValidator.php new file mode 100644 index 0000000000000000000000000000000000000000..8fc6aecadcb16274d9ba42376c21dfb65b406864 --- /dev/null +++ b/Civi/FormProcessor/Validation/AbstractValidator.php @@ -0,0 +1,127 @@ +<?php + +/** + * @author Jaap Jansma (CiviCooP) <jaap.jansma@civicoop.org> + * @license http://www.gnu.org/licenses/agpl-3.0.html + */ + + namespace Civi\FormProcessor\Validation; + + use \Civi\FormProcessor\Config\ConfigurationBag; + use \Civi\FormProcessor\Config\Specification; + use \Civi\FormProcessor\Config\SpecificationBag; + + use CRM_FormProcessor_ExtensionUtil as E; + + abstract class AbstractValidator implements \JsonSerializable { + + /** + * @var ConfigurationBag + */ + protected $configuration; + + /** + * @var ConfigurationBag + */ + protected $defaultConfiguration; + + /** + * Returns the name of the validator. + * + * @return string + */ + abstract public function getName(); + + /** + * Returns the label of the validator. + * + * @return string + */ + abstract public function getLabel(); + + /** + * Validate the input. + * + * @param mixed $input + * @return bool + */ + abstract public function validate($input); + + public function __construct() { + $this->configuration = new ConfigurationBag(); + $this->defaultConfiguration = new ConfigurationBag(); + + foreach($this->getConfigurationSpecification() as $spec) { + if ($spec->getDefaultValue()) { + $this->configuration->set($spec->getName(), $spec->getDefaultValue()); + $this->defaultConfiguration->set($spec->getName(), $spec->getDefaultValue()); + } + } + } + + /** + * Get the configuration specification + * + * @return SpecificationBag + */ + public function getConfigurationSpecification() { + return new SpecificationBag(); + } + + /** + * @return bool; + */ + public function validateConfiguration() { + if ($this->configuration === null) { + return false; + } + return SpecificationBag::validate($this->configuration, $this->getConfigurationSpecification()); + } + + /** + * @return ConfigurationBag + */ + public function getConfiguration() { + return $this->configuration; + } + + /** + * @return ConfigurationBag + */ + public function getDefaultConfiguration() { + return $this->defaultConfiguration; + } + + + /** + * Returns the invalid message. + * + * @return string + */ + public function getInvalidMessage() { + return E::ts('Invalid %1', array(1=>$this->getLabel())); + } + + /** + * @param ConfigurationBag $configuration + */ + public function setConfiguration(ConfigurationBag $configuration) { + $this->configuration = $configuration; + return $this; + } + + public function toArray() { + return array( + 'name' => $this->getName(), + 'label' => $this->getLabel(), + 'invalid_message' => $this->getInvalidMessage(), + 'configuration_spec' => $this->getConfigurationSpecification()->toArray(), + 'configuration' => $this->getConfiguration()->toArray(), + ); + } + + public function jsonSerialize() { + return $this->toArray(); + } + + } diff --git a/Civi/FormProcessor/Validation/EmailValidator.php b/Civi/FormProcessor/Validation/EmailValidator.php new file mode 100644 index 0000000000000000000000000000000000000000..413ac49bff7517bae485763e7971b18dc0127eb3 --- /dev/null +++ b/Civi/FormProcessor/Validation/EmailValidator.php @@ -0,0 +1,42 @@ +<?php + +/** + * @author Jaap Jansma (CiviCooP) <jaap.jansma@civicoop.org> + * @license http://www.gnu.org/licenses/agpl-3.0.html + */ + + namespace Civi\FormProcessor\Validation; + + use \Civi\FormProcessor\Validation\AbstractValidator; + + use CRM_FormProcessor_ExtensionUtil as E; + + class EmailValidator extends AbstractValidator { + + const PATTERN_LOOSE = '/^.+\@\S+\.\S+$/'; + + public function getLabel() { + return E::ts('E-mail'); + } + + /** + * Returns the name of the validator. + * + * @return string + */ + public function getName() { + return 'email'; + } + + /** + * Validate the input. + * + * @param mixed $input + * @return bool + */ + public function validate($input) { + $pattern = EmailValidator::PATTERN_LOOSE; + return preg_match($pattern, $input); + } + + } diff --git a/Civi/FormProcessor/Validation/Factory.php b/Civi/FormProcessor/Validation/Factory.php new file mode 100644 index 0000000000000000000000000000000000000000..90a3d0371b2dc139bdc012a66a650bb71be66801 --- /dev/null +++ b/Civi/FormProcessor/Validation/Factory.php @@ -0,0 +1,69 @@ +<?php + +/** + * @author Jaap Jansma (CiviCooP) <jaap.jansma@civicoop.org> + * @license http://www.gnu.org/licenses/agpl-3.0.html + */ + + namespace Civi\FormProcessor\Validation; + + use \Civi\FormProcessor\Validation\AbstractValidator; + use \Civi\FormProcessor\Validation\EmailValidator; + + use CRM_FormProcessor_ExtensionUtil as E; + + class Factory { + + /** + * @var array<AbstractValidator> + */ + protected $types = array(); + + /** + * @var Factory + */ + private static $singleton; + + private function __construct() { + $this->addValidator(new EmailValidator()); + } + + /** + * @return Factory + */ + public static function singleton(){ + if (!self::$singleton) { + self::$singleton = new Factory(); + } + return self::$singleton; + } + + /** + * Adds a validator + * + * @param AbstractFactory $validator + * @return Factory + */ + public function addValidator(AbstractValidator $validator) { + $this->validators[$validator->getName()] = $validator; + return $this; + } + + /** + * Returns a validator + * + * @param string $name + * The name of the validator. + * @return AbstractValidator + */ + public function getValidatorByName($name) { + return $this->validators[$name]; + } + + /** + * @return array<AbstractValidator> + */ + public function getValidators() { + return $this->validators; + } + } \ No newline at end of file diff --git a/ang/form_processor.ang.php b/ang/form_processor.ang.php index 7507192389eecc71185aa3781571f330e9d985a2..520547d66c3c4130bca23087397e6219036819e3 100644 --- a/ang/form_processor.ang.php +++ b/ang/form_processor.ang.php @@ -12,6 +12,7 @@ return array ( 'crmUi', 'crmUtil', 'ngRoute', + 'ngSanitize', 'dialogService', 'ui.utils', 'action_provider', @@ -33,6 +34,7 @@ return array ( 'settings' => array ( 'inputTypes' => \Civi::service('form_processor_type_factory')->getTypeLabels(), + 'validators' => \Civi::service('form_processor_validation_factory')->getValidators(), 'actionTypes' => $action_provider->getActions(), ), ); diff --git a/ang/form_processor/ActionDialogCtrl.html b/ang/form_processor/ActionDialogCtrl.html index f4af01cf0bb35d05438ed9a8a84feef8974c02ba..59b2caaeef6ff357c558b98a0d3ce309ed0a338d 100644 --- a/ang/form_processor/ActionDialogCtrl.html +++ b/ang/form_processor/ActionDialogCtrl.html @@ -3,7 +3,7 @@ <div class="crm-group"> <div crm-ui-field="{name: 'ActionForm.type', title: ts('Type')}"> - <div>{{model.action.type.title}}</div> + <div>{{action.type.title}}</div> </div> <div crm-ui-field="{name: 'ActionForm.title', title: ts('Title')}"> @@ -11,7 +11,7 @@ crm-ui-id="addActionForm.title" type="text" name="title" - ng-model="model.action.title" + ng-model="action.title" class="big crm-form-text" required autofocus @@ -19,13 +19,13 @@ </div> <crm-ap-action-configuration - configuration="model.action.configuration" - action="model.action.type" + configuration="action.configuration" + action="action.type" fields="model.formProcessor.fields" - mapping="model.action.mapping" + mapping="action.mapping" ></crm-ap-action-configuration> - <button crm-icon="fa-check" ng-click="saveClick()" ng-disabled="addActionForm.$invalid">{{ts('Save and close')}}</button> + <button crm-icon="fa-check" ng-click="saveClick()" ng-disabled="ActionForm.$invalid">{{ts('Save and close')}}</button> <button crm-icon="fa-times" ng-click="cancelClick()">{{ts('Cancel')}}</button> </div> diff --git a/ang/form_processor/ActionDialogCtrl.js b/ang/form_processor/ActionDialogCtrl.js index af3660eea6fa1477f1c223d99f9cda061cfd3946..f56c60a386b53fa904efaad6325ba2a20686527a 100644 --- a/ang/form_processor/ActionDialogCtrl.js +++ b/ang/form_processor/ActionDialogCtrl.js @@ -3,7 +3,10 @@ angular.module('form_processor').controller('ActionDialogCtrl', function InputDialogCtrl($scope, dialogService) { $scope.ts = CRM.ts(null); + $scope.action = angular.copy($scope.model.action); + $scope.saveClick = function() { + $scope.model.action = $scope.action; dialogService.close('ActionDialog', $scope.model); }; diff --git a/ang/form_processor/FormProcessorEditCtrl.html b/ang/form_processor/FormProcessorEditCtrl.html index 9d1298486b1c9605f342c2a96bdd7c2626bf9b77..0d81dbfba4886471f24b37f9617a2d8cf1c6cc6f 100644 --- a/ang/form_processor/FormProcessorEditCtrl.html +++ b/ang/form_processor/FormProcessorEditCtrl.html @@ -8,6 +8,10 @@ Required vars: formProcessor <form name="editFormProcessorForm" unsaved-warning-form> <div class="crm-block crm-form-block crmFormProcessor"> + + <div class="status status-warning" ng-show="editFormProcessorForm.$dirty"> + {{ts('Form processor is not saved')}} + </div> <div ng-include="'~/form_processor/FormProcessorEditCtrl/Details.html'"></div> @@ -16,9 +20,12 @@ Required vars: formProcessor <div ng-include="'~/form_processor/FormProcessorEditCtrl/ActionTable.html'"></div> <div class="crm-submit-buttons"> - <button crm-icon="fa-check" ng-click="editFormProcessorForm.$setPristine(); save()" ng-disabled="editFormProcessorForm.$invalid || !isNameValid"> + <button crm-icon="fa-check" ng-click="save(false);" ng-disabled="editFormProcessorForm.$invalid || !isNameValid"> {{ts('Save')}} </button> + <button crm-icon="fa-check" ng-click="save(true);" ng-disabled="editFormProcessorForm.$invalid || !isNameValid"> + {{ts('Save and go back')}} + </button> <button crm-icon="fa-times" ng-click="editFormProcessorForm.$setPristine(); goto('formProcessors')"> {{ts('Cancel')}} </button> diff --git a/ang/form_processor/FormProcessorEditCtrl.js b/ang/form_processor/FormProcessorEditCtrl.js index 7f48fe74a7264f9cce1885da8466d36d63c98cec..6c47e6db896dace09100fbf7157fc15668f6a9aa 100644 --- a/ang/form_processor/FormProcessorEditCtrl.js +++ b/ang/form_processor/FormProcessorEditCtrl.js @@ -24,7 +24,7 @@ apiCalls: function($route, crmApi) { var reqs = {}; if ($route.current.params.id !== 'new') { - reqs.formProcessor = ['FormProcessor', 'getsingle', { + reqs.formProcessor = ['FormProcessorInstance', 'getsingle', { id: $route.current.params.id }]; } @@ -35,7 +35,7 @@ } ); - angular.module('form_processor').controller('FormProcessorEditCtrl', function($scope, dialogService, crmApi, apiCalls, $q) { + angular.module('form_processor').controller('FormProcessorEditCtrl', function($scope, dialogService, crmApi, apiCalls, $q, $timeout) { var ts = $scope.ts = CRM.ts(null); $scope.formProcessor = apiCalls.formProcessor; @@ -61,7 +61,7 @@ $scope.$watch('formProcessor.name', function(newFormProcessorName, oldFrmProcessorName) { // Watch for changes in the name field - crmApi('FormProcessor', 'validatename', {'name': newFormProcessorName,'id': $scope.formProcessor.id}) + crmApi('FormProcessorInstance', 'validatename', {'name': newFormProcessorName,'id': $scope.formProcessor.id}) .then(function(data) { $scope.isNameValid = false; if (data.is_valid) { @@ -77,12 +77,19 @@ } }, true); + $timeout(function(){ + // The select boxes for input type and action type do not count for the @pristine state of the + // form. + $scope.editFormProcessorForm.formProcessorInputsForm.type.$pristine = false; + $scope.editFormProcessorForm.formProcessorActionsForm.type.$pristine = false; + }); + $scope.isValidName = function(name) { return (!name) || name.match(/^[a-z0-9_]+$/) ? true : false; }; - $scope.save = function() { - var result = crmApi('FormProcessor', 'create', $scope.formProcessor, true); + $scope.save = function(goBack) { + var result = crmApi('FormProcessorInstance', 'create', $scope.formProcessor, true); result.then(function(data) { if (data.is_error === 0 || data.is_error == '0') { $scope.formProcessor.id = data.id; @@ -96,10 +103,25 @@ }); angular.forEach($scope.formProcessor.inputs, function(input, key) { - input.form_processor_id = $scope.formProcessor.id; + if (input.id < 1) { + delete input.id; + } + var type = angular.copy(input.type); + input.form_processor_instance_id = $scope.formProcessor.id; input.configuration = input.type.configuration; input.type = input.type.name; - apiCalls.push(crmApi('FormProcessorInput', 'create', input, true)); + apiCalls.push(crmApi('FormProcessorInput', 'create', input, true).then(function (input_result){ + input.id = input_result['id']; + input.type = type; + angular.forEach(input.validators, function(validator, validator_index){ + validator.form_processor_input_id = input.id; + var validator_type = angular.copy(validator.validator); + validator.validator = validator.validator.name; + crmApi('FormProcessorInputValidation', 'create', validator).then(function (validator_result) { + validator.validator = validator_type; + }); + }); + })); }); angular.forEach($scope.deletedActions, function(action, key) { @@ -115,12 +137,13 @@ if (action.id < 0) { delete action.id; } - action.form_processor_id = $scope.formProcessor.id; + var action_type = angular.copy(action.type); + action.form_processor_instance_id = $scope.formProcessor.id; action.type = action.type.name; action.weight = actionWeight; - console.log(action); apiCalls.push(crmApi('FormProcessorAction', 'create', action, true).then(function(action_result) { action.id = action_result.id; + action.type = action_type; if (old_id < 0) { newActions[old_id] = action.id; } @@ -143,12 +166,20 @@ } }); if (actionChanged) { - crmApi('FormProcessorAction', 'create', action, true); + var action_type = angular.copy(action.type); + action.type = action.type.name; + crmApi('FormProcessorAction', 'create', action, true).then(function(action_result) { + action.type = action_type; + }); } }); }); - window.location.href = '#/formprocessors'; + $scope.editFormProcessorForm.$setPristine(); + + if (goBack) { + window.location.href = '#/formprocessors'; + } } }); }; @@ -159,6 +190,8 @@ $scope.formProcessor.inputs.splice(index, 1); $scope.deletedInputs.push(input); } + + $scope.editFormProcessorForm.$setDirty(); }; // Open a dialog for adding an input @@ -172,6 +205,7 @@ 'name': '', 'is_required': 0, 'default_value': '', + 'validators': [] }; $scope.editInput(input); }; @@ -184,14 +218,17 @@ height: 'auto', title: ts('Edit input') }); + index = $scope.formProcessor.inputs.indexOf(input); var model = { formProcessor: $scope.formProcessor, input: input }; dialogService.open('InputDialog', '~/form_processor/InputDialogCtrl.html', model, options) - .then( - function(data) { - if ($scope.new_id == data.input.id) { + .then(function(data) { + $scope.editFormProcessorForm.$setDirty(); + if (index >= 0) { + $scope.formProcessor.inputs[index] = data.input; + } else if ($scope.new_id == data.input.id) { $scope.formProcessor.inputs.push(data.input); $scope.new_id --; } @@ -204,13 +241,15 @@ $scope.formProcessor.actions.splice(index, 1); $scope.deletedActions.push(action); } + + $scope.editFormProcessorForm.$setDirty(); }; // Open a dialog for adding an action $scope.addAction = function addAction(actionType) { if (!actionType) { return; - } + } var action = { id: $scope.new_id, type: angular.copy(actionType), @@ -231,14 +270,18 @@ }); $scope.updateFields($scope.formProcessor, action); - + index = $scope.formProcessor.inputs.indexOf(action); var model = { formProcessor: $scope.formProcessor, action: action }; dialogService.open('ActionDialog', '~/form_processor/ActionDialogCtrl.html', model, options) .then(function(data) { - if ($scope.new_id == data.action.id) { + $scope.editFormProcessorForm.$setDirty(); + + if (index >= 0) { + $scope.formProcessor.actions[index] = data.action; + } else if ($scope.new_id == data.action.id) { $scope.formProcessor.actions.push(data.action); $scope.new_id --; } diff --git a/ang/form_processor/FormProcessorEditCtrl/Details.html b/ang/form_processor/FormProcessorEditCtrl/Details.html index ae76bf17f69061c1f386f1b4442ee336a9ad857e..f78991df1af0a9be689440a7e2c3b6ac31969c59 100644 --- a/ang/form_processor/FormProcessorEditCtrl/Details.html +++ b/ang/form_processor/FormProcessorEditCtrl/Details.html @@ -23,7 +23,7 @@ <a crm-ui-lock binding="locks.name"></a> <div ng-show="!isValidName(formProcessor.name) || !isNameValid"> - <em>{{ts('WARNING: The form processor name includes deprecated characters or is already in use by another form processor.')}}</em> + <em>{{ts('WARNING: The form processor name includes invalid characters or is already in use by another form processor.')}}</em> </div> <div ng-show="formProcessor.id && !locks.name"> <em>{{ts('WARNING: If any external files or programs reference the old "Name", then they must be updated manually.')}}</em> diff --git a/ang/form_processor/FormProcessorEditCtrl/InputTable.html b/ang/form_processor/FormProcessorEditCtrl/InputTable.html index b7832478e0f916fece475d0251ccfd1099b20112..9a5567c5771d1f8d19508503f37cd6fb5d56dcb6 100644 --- a/ang/form_processor/FormProcessorEditCtrl/InputTable.html +++ b/ang/form_processor/FormProcessorEditCtrl/InputTable.html @@ -11,6 +11,7 @@ Required vars: formProcessor <th>{{ts('Type')}}</th> <th>{{ts('Is required')}}</th> <th>{{ts('Default value')}}</th> + <th>{{ts('Validation')}}</th> <th></th> </tr> </thead> @@ -20,6 +21,13 @@ Required vars: formProcessor <td>{{input.type.label}}</td> <td>{{input.is_required == 1 ? ts('Yes') : ts('No')}}</td> <td>{{input.default_value}}</td> + <td> + <ul> + <li ng-repeat="validator in input.validators | orderBy:'validator.label'"> + {{validator.validator.label}} + </li> + </ul> + </td> <td> <a crm-icon="fa-edit" class="crm-hover-button" ng-click="editInput(input)" title="{{ts('Edit')}}">{{ts('Edit')}}</a> <a crm-icon="fa-trash" class="crm-hover-button" ng-click="removeInput(input)" title="{{ts('Remove')}}">{{ts('Remove')}}</a> diff --git a/ang/form_processor/FormProcessorListCtrl.js b/ang/form_processor/FormProcessorListCtrl.js index 4f09122983acbfa8fe0bf9a421019223d006bde6..066e7d4a4c1e0e1488f80ab8f634985dadff7c82 100644 --- a/ang/form_processor/FormProcessorListCtrl.js +++ b/ang/form_processor/FormProcessorListCtrl.js @@ -9,7 +9,7 @@ // under "resolve". resolve: { formProcessors: function($route, crmApi) { - return crmApi('FormProcessor', 'get', {options: {limit: 0}}); + return crmApi('FormProcessorInstance', 'get', {options: {limit: 0}}); } } }); @@ -22,14 +22,14 @@ $scope.formProcessors = formProcessors.values; $scope.toggleFormProcessor = function (formProcessor) { formProcessor.is_active = (formProcessor.is_active == '1') ? '0' : '1'; - crmApi('FormProcessor', 'create', formProcessor, true) + crmApi('FormProcessorInstance', 'create', formProcessor, true) .catch(function (data) { formProcessor.is_active = (formProcessor.is_active == '1') ? '0' : '1'; // revert $scope.$digest(); }); }; $scope.deleteFormProcessor = function (formProcessor) { - crmApi('FormProcessor', 'delete', {id: formProcessor.id}, { + crmApi('FormProcessorInstance', 'delete', {id: formProcessor.id}, { error: function (data) { CRM.alert(data.error_message, ts('Error'), 'error'); } diff --git a/ang/form_processor/InputDialogCtrl.html b/ang/form_processor/InputDialogCtrl.html index e68e365d9f1aa85dfce17028d6287020e3ac324f..6ca5aef8bc80948d37758e34b94661c812fe6b13 100644 --- a/ang/form_processor/InputDialogCtrl.html +++ b/ang/form_processor/InputDialogCtrl.html @@ -3,7 +3,7 @@ <div class="crm-group"> <div crm-ui-field="{name: 'formProcessorDetailForm.type', title: ts('Type')}"> - <div>{{model.input.type.label}}</div> + <div>{{input.type.label}}</div> </div> <div crm-ui-field="{name: 'InputForm.name', title: ts('Name')}"> @@ -11,7 +11,7 @@ crm-ui-id="InputForm.name" type="text" name="name" - ng-model="model.input.name" + ng-model="input.name" class="big crm-form-text" required autofocus @@ -25,7 +25,7 @@ </div> <div crm-ui-field="{title: ts('Is required?')}"> - <input name="is_required" type="checkbox" ng-model="model.input.is_required" ng-true-value="'1'" ng-false-value="'0'"/> + <input name="is_required" type="checkbox" ng-model="input.is_required" ng-true-value="'1'" ng-false-value="'0'"/> </div> <div crm-ui-field="{name: 'InputForm.default_value', title: ts('Default value')}"> @@ -33,17 +33,47 @@ crm-ui-id="InputForm.default_value" type="text" name="title" - ng-model="model.input.default_value" + ng-model="input.default_value" class="big crm-form-text" /> </div> <crm-form-processor-type-configuration - type=model.input.type + type=input.type ></crm-form-processor-type-configuration> - - <button crm-icon="fa-check" ng-click="saveClick()">{{ts('Save and Close')}}</button> - <button crm-icon="fa-times" ng-click="cancelClick()">{{ts('Cancel')}}</button> + + <div class="crm-block" ng-form="InputForm" crm-ui-id-scope> + <div class="crm-group"> + <h2>{{ts('Validation')}}</h2> + <select + crm-ui-id="InputForm.newValidator" + name="type" + ui-jq="select2" + ui-options="{dropdownAutoWidth : true, allowClear: true}" + ng-model="newValidator" + ng-options="newValidator.label for newValidator in validators"> + <option value="">{{ts('- Select validation -')}}</option> + </select> + <button crm-icon="fa-check" ng-click="addValidator(newValidator)">{{ts('Add validation rule')}}</button> + </div> + </div> + + <div ng-repeat="validator in input.validators | orderBy:'validator.label'" class="crm-block"> + <div class="crm-group"> + <h3>{{validator.validator.label}}</h3> + <p> + <a crm-icon="fa-trash" class="crm-hover-button" ng-click="removeValidator(validator)" title="{{ts('Remove')}}">{{ts('Remove')}}</a> + </p> + <crm-form-processor-validation-configuration validator=validator></crm-form-processor-validation-configuration> + </div> + </div> + + <div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"> + <div class="ui-dialog-buttonset"> + <button crm-icon="fa-check" ng-click="saveClick()" ng-disabled="InputForm.$invalid">{{ts('Save and Close')}}</button> + <button crm-icon="fa-times" ng-click="cancelClick()">{{ts('Cancel')}}</button> + </div> + </div> </div> </div> diff --git a/ang/form_processor/InputDialogCtrl.js b/ang/form_processor/InputDialogCtrl.js index b24ab2b4f070d650cd0199fe4e50158d4114d11f..99c158ccbe8a8004aaa641ded951ed93d6873804 100644 --- a/ang/form_processor/InputDialogCtrl.js +++ b/ang/form_processor/InputDialogCtrl.js @@ -2,9 +2,10 @@ angular.module('form_processor').controller('InputDialogCtrl', function InputDialogCtrl($scope, dialogService) { $scope.ts = CRM.ts(null); - + $scope.input = angular.copy($scope.model.input); $scope.invalidName = false; $scope.nameExists = false; + $scope.validators = CRM.form_processor.validators; $scope.$watch('model.input.name', function(newName, oldName) { $scope.invalidName = newName && !newName.match(/^[a-z0-9_]+$/) ? true : false; @@ -20,13 +21,32 @@ }, true); $scope.saveClick = function() { + $scope.model.input = $scope.input; dialogService.close('InputDialog', $scope.model); }; - $scope.cancelClick = function() { + $scope.cancelClick = function() { dialogService.cancel('InputDialog'); }; + $scope.addValidator = function(newValidator) { + if (!newValidator) { + return; + } + var validator = { + validator: angular.copy(newValidator), + configuration: {} + }; + $scope.input.validators.push(validator); + }; + + $scope.removeValidator = function(validator) { + var index = $scope.input.validators.indexOf(validator); + if (index >= 0) { + $scope.input.validators.splice(index, 1); + } + }; + }); })(angular, CRM.$, CRM._); diff --git a/ang/form_processor/crmFormProcessorValidationConfiguration.html b/ang/form_processor/crmFormProcessorValidationConfiguration.html new file mode 100644 index 0000000000000000000000000000000000000000..47e6a245a0c8668fb8a554ef91397dd573c918d4 --- /dev/null +++ b/ang/form_processor/crmFormProcessorValidationConfiguration.html @@ -0,0 +1,15 @@ +<ng-repeat ng-repeat="spec in validator.configuration_spec"> +<div crm-ui-field="{name: 'spec.name', title: spec.title, required: spec.required}"> + <input + type="text" + name="{{spec.name}}" + ng-model="validator.configuration[spec.name]" + class="big crm-form-text" + ng-required="spec.required" + /> + + <div class="description" ng-if="spec.description" ng-bind-html="spec.description"></div> + +</ng-repeat> + + diff --git a/ang/form_processor/crmFormProcessorValidationConfiguration.js b/ang/form_processor/crmFormProcessorValidationConfiguration.js new file mode 100644 index 0000000000000000000000000000000000000000..d0a6aec80685567103912567fe53c84d85104dd9 --- /dev/null +++ b/ang/form_processor/crmFormProcessorValidationConfiguration.js @@ -0,0 +1,16 @@ +(function(angular, $, _) { + + angular.module('form_processor').directive('crmFormProcessorValidationConfiguration', function() { + return { + restrict: 'E', + scope: { + validator: '=validator', + }, + templateUrl: '~/form_processor/crmFormProcessorValidationConfiguration.html', + link: function($scope, $el, $attr) { + $scope.ts = CRM.ts(null); + } + }; + }); + +})(angular, CRM.$, CRM._); \ No newline at end of file diff --git a/api/v3/FormProcessorAction/Create.php b/api/v3/FormProcessorAction/Create.php index 17abf812afcdc8e146e4af9931b18c85d8131211..7fb16e988f854f1713d7bf6d7ca276535336d457 100644 --- a/api/v3/FormProcessorAction/Create.php +++ b/api/v3/FormProcessorAction/Create.php @@ -16,11 +16,11 @@ function _civicrm_api3_form_processor_action_create_spec(&$spec) { 'type' => CRM_Utils_Type::T_INT, 'api_required' => false ); - $spec['form_processor_id'] = array( - 'title' => E::ts('Form Processor ID'), + $spec['form_processor_instance_id'] = array( + 'title' => E::ts('Form Processor Instance ID'), 'type' => CRM_Utils_Type::T_INT, 'api_required' => true, - 'FKApiName' => 'FormProcessor', + 'FKApiName' => 'FormProcessorInstance', ); $spec['weight'] = array( 'title' => E::ts('Weight'), diff --git a/api/v3/FormProcessorInput/Create.php b/api/v3/FormProcessorInput/Create.php index b568d4f555b6d70b091a708924f3d187ac602a57..920445c53eb849b0d30144054a3a878fe57b9961 100644 --- a/api/v3/FormProcessorInput/Create.php +++ b/api/v3/FormProcessorInput/Create.php @@ -16,11 +16,11 @@ function _civicrm_api3_form_processor_input_create_spec(&$spec) { 'type' => CRM_Utils_Type::T_INT, 'api_required' => false ); - $spec['form_processor_id'] = array( - 'title' => E::ts('Form Processor ID'), + $spec['form_processor_instance_id'] = array( + 'title' => E::ts('Form Processor Instance ID'), 'type' => CRM_Utils_Type::T_INT, 'api_required' => true, - 'FKApiName' => 'FormProcessor', + 'FKApiName' => 'FormProcessorInstance', ); $spec['name'] = array( 'title' => E::ts('Name'), diff --git a/api/v3/FormProcessorInput/Get.php b/api/v3/FormProcessorInput/Get.php index 93ca91bfe1c9f86fc77a674e343bd8e494aeb001..cf71647311518c64b2dcf6b3331a606693d297f9 100644 --- a/api/v3/FormProcessorInput/Get.php +++ b/api/v3/FormProcessorInput/Get.php @@ -12,6 +12,9 @@ function civicrm_api3_form_processor_input_get($params) { $returnValues = CRM_FormProcessor_BAO_FormProcessorInput::getValues($params); foreach($returnValues as $index => $input) { $returnValues[$index]['type'] = $input['type']->toArray(); + foreach($input['validators'] as $key => $validator) { + $returnValues[$index]['validators'][$key]['validator'] = $validator['validator']->toArray(); + } } return civicrm_api3_create_success($returnValues, $params, 'FormProcessorInput', 'Get'); } diff --git a/api/v3/FormProcessorInputValidation/Create.php b/api/v3/FormProcessorInputValidation/Create.php new file mode 100644 index 0000000000000000000000000000000000000000..646babbf916693dac5e132bd834463c3b34a09be --- /dev/null +++ b/api/v3/FormProcessorInputValidation/Create.php @@ -0,0 +1,52 @@ +<?php + +use CRM_FormProcessor_ExtensionUtil as E; + +/** + * FormProcessorInputValidation.Create API specification (optional) + * This is used for documentation and validation. + * + * @param array $spec description of fields supported by this API call + * @return void + * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards + */ +function _civicrm_api3_form_processor_input_validation_create_spec(&$spec) { + $spec['id'] = array( + 'title' => E::ts('ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api_required' => false + ); + $spec['form_processor_input_id'] = array( + 'title' => E::ts('Form Processor Input ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api_required' => true, + 'FKApiName' => 'FormProcessorInput', + ); + $spec['validator'] = array( + 'title' => E::ts('Validator'), + 'type' => CRM_Utils_Type::T_STRING, + 'api_required' => true + ); + $spec['configuration'] = array( + 'title' => E::ts('Configuration'), + 'type' => CRM_Utils_Type::T_TEXT, + 'api_required' => false + ); +} + +/** + * FormProcessorInputValidation.Create API + * + * @param array $params + * @return array API result descriptor + * @see civicrm_api3_create_success + * @see civicrm_api3_create_error + * + * + */ +function civicrm_api3_form_processor_input_validation_create($params) { + $returnValue = CRM_FormProcessor_BAO_FormProcessorInputValidation::add($params); + $returnValues[$returnValue['id']] = $returnValue; + return civicrm_api3_create_success($returnValues, $params, 'FormProcessorInputValidation', 'Create'); +} + diff --git a/api/v3/FormProcessorInputValidation/Delete.php b/api/v3/FormProcessorInputValidation/Delete.php new file mode 100644 index 0000000000000000000000000000000000000000..546a75e0e83450dfcd8515dcdd7b14eced6618d8 --- /dev/null +++ b/api/v3/FormProcessorInputValidation/Delete.php @@ -0,0 +1,37 @@ +<?php + +use CRM_FormProcessor_ExtensionUtil as E; + +/** + * FormProcessorInputValidation.Delete API specification (optional) + * This is used for documentation and validation. + * + * @param array $spec description of fields supported by this API call + * @return void + * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards + */ +function _civicrm_api3_form_processor_input_validation_Delete_spec(&$spec) { + $spec['id'] = array( + 'title' => E::ts('ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api_required' => true + ); +} + +/** + * FormProcessorInputValidation.Delete API + * + * @param array $params + * @return array API result descriptor + * @see civicrm_api3_create_success + * @see civicrm_api3_create_error + * @throws API_Exception + */ +function civicrm_api3_form_processor_input_validation_Delete($params) { + if (!array_key_exists('id', $params) || empty($params['id'])) { + throw new API_Exception('Parameter id is mandatory and can not be empty in ' . __METHOD__, 0010); + } else { + return civicrm_api3_create_success(CRM_FormProcessor_BAO_FormProcessorInputValidation::deleteWithId($params['id']), $params, 'FormProcessorInputValidation', 'Delete'); + } +} + diff --git a/api/v3/FormProcessorInputValidation/Get.php b/api/v3/FormProcessorInputValidation/Get.php new file mode 100644 index 0000000000000000000000000000000000000000..75a8386ad92564fd1cc575754616dff3f7716019 --- /dev/null +++ b/api/v3/FormProcessorInputValidation/Get.php @@ -0,0 +1,33 @@ +<?php +/** + * FormProcessorInputValidation.Get API + * + * @param array $params + * @return array API result descriptor + * @see civicrm_api3_create_success + * @see civicrm_api3_create_error + * @throws API_Exception + */ +function civicrm_api3_form_processor_input_validation_get($params) { + $returnValues = CRM_FormProcessor_BAO_FormProcessorInputValidation::getValues($params); + foreach($returnValues as $index => $input) { + $returnValues[$index]['validator'] = $input['validator']->toArray(); + } + return civicrm_api3_create_success($returnValues, $params, 'FormProcessorInputValidation', 'Get'); +} + +/** + * FormProcessorInputValidation.Get API specification (optional) + * This is used for documentation and validation. + * + * @param array $spec description of fields supported by this API call + * @return void + * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards + */ +function _civicrm_api3_form_processor_input_validation_get_spec(&$spec) { + $fields = CRM_FormProcessor_BAO_FormProcessorInputValidation::fields(); + foreach($fields as $fieldname => $field) { + $spec[$fieldname] = $field; + } +} + diff --git a/api/v3/FormProcessor/Create.php b/api/v3/FormProcessorInstance/Create.php similarity index 86% rename from api/v3/FormProcessor/Create.php rename to api/v3/FormProcessorInstance/Create.php index 181fee3752d9972a8dfe36add83fcf3137d55574..0be79ee3d0782e156903cd80328546cfe0e7ed9e 100644 --- a/api/v3/FormProcessor/Create.php +++ b/api/v3/FormProcessorInstance/Create.php @@ -10,7 +10,7 @@ use CRM_FormProcessor_ExtensionUtil as E; * @return void * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards */ -function _civicrm_api3_form_processor_create_spec(&$spec) { +function _civicrm_api3_form_processor_instance_create_spec(&$spec) { $spec['id'] = array( 'title' => E::ts('ID'), 'type' => CRM_Utils_Type::T_INT, @@ -49,9 +49,9 @@ function _civicrm_api3_form_processor_create_spec(&$spec) { * * */ -function civicrm_api3_form_processor_create($params) { +function civicrm_api3_form_processor_instance_create($params) { if (!isset($params['id']) && empty($params['title'])) { - return civicrm_api3_create_error('Title can not be empty when adding a new FormProcessor'); + return civicrm_api3_create_error('Title can not be empty when adding a new FormProcessorInstance'); } /* @@ -66,8 +66,8 @@ function civicrm_api3_form_processor_create($params) { $params['created_date'] = date('Ymd'); $params['created_user_id'] = $userId; } - $returnValue = CRM_FormProcessor_BAO_FormProcessor::add($params); + $returnValue = CRM_FormProcessor_BAO_FormProcessorInstance::add($params); $returnValues[$returnValue['id']] = $returnValue; - return civicrm_api3_create_success($returnValues, $params, 'FormProcessor', 'Create'); + return civicrm_api3_create_success($returnValues, $params, 'FormProcessorInstance', 'Create'); } diff --git a/api/v3/FormProcessor/Delete.php b/api/v3/FormProcessorInstance/Delete.php similarity index 79% rename from api/v3/FormProcessor/Delete.php rename to api/v3/FormProcessorInstance/Delete.php index ac417589a3a134b537543b1755ef86450b988c12..5b45e17da69e87a3b62ebf14947c4cc640190287 100644 --- a/api/v3/FormProcessor/Delete.php +++ b/api/v3/FormProcessorInstance/Delete.php @@ -10,7 +10,7 @@ use CRM_FormProcessor_ExtensionUtil as E; * @return void * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards */ -function _civicrm_api3_form_processor_Delete_spec(&$spec) { +function _civicrm_api3_form_processor_instance_Delete_spec(&$spec) { $spec['id'] = array( 'title' => E::ts('ID'), 'type' => CRM_Utils_Type::T_INT, @@ -27,11 +27,11 @@ function _civicrm_api3_form_processor_Delete_spec(&$spec) { * @see civicrm_api3_create_error * @throws API_Exception */ -function civicrm_api3_form_processor_Delete($params) { +function civicrm_api3_form_processor_instance_Delete($params) { if (!array_key_exists('id', $params) || empty($params['id'])) { throw new API_Exception('Parameter id is mandatory and can not be empty in ' . __METHOD__, 0010); } else { - return civicrm_api3_create_success(CRM_FormProcessor_BAO_FormProcessor::deleteWithId($params['id']), $params, 'FormProcessor', 'Delete'); + return civicrm_api3_create_success(CRM_FormProcessor_BAO_FormProcessorInstance::deleteWithId($params['id']), $params, 'FormProcessorInstance', 'Delete'); } } diff --git a/api/v3/FormProcessor/Get.php b/api/v3/FormProcessorInstance/Get.php similarity index 66% rename from api/v3/FormProcessor/Get.php rename to api/v3/FormProcessorInstance/Get.php index 589d0b8ab9069fc0f3e5db2fc1b4d9a47db3e33c..2de109f2d2a09ef7dd8e70b05a574d1f9ff770f8 100644 --- a/api/v3/FormProcessor/Get.php +++ b/api/v3/FormProcessorInstance/Get.php @@ -8,17 +8,20 @@ * @see civicrm_api3_create_error * @throws API_Exception */ -function civicrm_api3_form_processor_get($params) { - $returnValues = CRM_FormProcessor_BAO_FormProcessor::getValues($params); +function civicrm_api3_form_processor_instance_get($params) { + $returnValues = CRM_FormProcessor_BAO_FormProcessorInstance::getValues($params); foreach($returnValues as $index => $formProcessor) { foreach($formProcessor['inputs'] as $key => $input) { $returnValues[$index]['inputs'][$key]['type'] = $input['type']->toArray(); + foreach($input['validators'] as $validator_key => $validator) { + $returnValues[$index]['inputs'][$key]['validators'][$validator_key]['validator'] = $validator['validator']->toArray(); + } } foreach($formProcessor['actions'] as $key => $action) { $returnValues[$index]['actions'][$key]['type'] = $action['type']->toArray(); } } - return civicrm_api3_create_success($returnValues, $params, 'FormProcessor', 'Get'); + return civicrm_api3_create_success($returnValues, $params, 'FormProcessorInstance', 'Get'); } /** @@ -29,8 +32,8 @@ function civicrm_api3_form_processor_get($params) { * @return void * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards */ -function _civicrm_api3_form_processor_get_spec(&$spec) { - $fields = CRM_FormProcessor_BAO_FormProcessor::fields(); +function _civicrm_api3_form_processor_instance_get_spec(&$spec) { + $fields = CRM_FormProcessor_BAO_FormProcessorInstance::fields(); foreach($fields as $fieldname => $field) { $spec[$fieldname] = $field; } diff --git a/api/v3/FormProcessor/Validatename.php b/api/v3/FormProcessorInstance/Validatename.php similarity index 84% rename from api/v3/FormProcessor/Validatename.php rename to api/v3/FormProcessorInstance/Validatename.php index f21098d3030f857145ba252f3fa460b31b57964b..69b6a5c4b624c25998f05bd3910d30c7ec815f47 100644 --- a/api/v3/FormProcessor/Validatename.php +++ b/api/v3/FormProcessorInstance/Validatename.php @@ -11,11 +11,11 @@ use CRM_FormProcessor_ExtensionUtil as E; * @see civicrm_api3_create_error * @throws API_Exception */ -function civicrm_api3_form_processor_validatename($params) { +function civicrm_api3_form_processor_instance_validatename($params) { $name = $params['name']; $id = isset($params['id']) ? $params['id'] : null; $returnValues['name'] = $name; - $returnValues['is_valid'] = CRM_FormProcessor_BAO_FormProcessor::isNameValid($name, $id); + $returnValues['is_valid'] = CRM_FormProcessor_BAO_FormProcessorInstance::isNameValid($name, $id); return $returnValues; } @@ -27,7 +27,7 @@ function civicrm_api3_form_processor_validatename($params) { * @return void * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards */ -function _civicrm_api3_form_processor_validatename_spec(&$spec) { +function _civicrm_api3_form_processor_instance_validatename_spec(&$spec) { $spec['id'] = array( 'title' => E::ts('ID'), 'type' => CRM_Utils_Type::T_INT, diff --git a/form_processor.php b/form_processor.php index 838065883a2f974ab42a19bc1653c4f5c861657a..13845c385fe2f41fca5afa2bcb286a8e2acfce34 100644 --- a/form_processor.php +++ b/form_processor.php @@ -14,6 +14,9 @@ use \Symfony\Component\DependencyInjection\Definition; function form_processor_civicrm_container(ContainerBuilder $container) { // Register the TypeFactory $container->setDefinition('form_processor_type_factory', new Definition('Civi\FormProcessor\Type\Factory')); + $validationFactoryDefinition = new Definition('Civi\FormProcessor\Validation\Factory'); + $validationFactoryDefinition->setFactory(array('Civi\FormProcessor\Validation\Factory', 'singleton')); + $container->setDefinition('form_processor_validation_factory', $validationFactoryDefinition); // Register our API Provider. @@ -33,17 +36,21 @@ function form_processor_civicrm_container(ContainerBuilder $container) { * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_alterAPIPermissions/ */ function form_processor_civicrm_alterAPIPermissions($entity, $action, &$params, &$permissions) { - $permissions['form_processor']['get'] = array('administer CiviCRM'); - $permissions['form_processor']['create'] = array('administer CiviCRM'); - $permissions['form_processor']['delete'] = array('administer CiviCRM'); + $permissions['form_processor_instance']['get'] = array('administer CiviCRM'); + $permissions['form_processor_instance']['create'] = array('administer CiviCRM'); + $permissions['form_processor_instance']['delete'] = array('administer CiviCRM'); $permissions['form_processor_input']['get'] = array('administer CiviCRM'); $permissions['form_processor_input']['create'] = array('administer CiviCRM'); $permissions['form_processor_input']['delete'] = array('administer CiviCRM'); - $permissions['form_processor_delete']['get'] = array('administer CiviCRM'); - $permissions['form_processor_delete']['create'] = array('administer CiviCRM'); - $permissions['form_processor_delete']['delete'] = array('administer CiviCRM'); + $permissions['form_processor_input_validation']['get'] = array('administer CiviCRM'); + $permissions['form_processor_input_validation']['create'] = array('administer CiviCRM'); + $permissions['form_processor_input_validation']['delete'] = array('administer CiviCRM'); + + $permissions['form_processor_action']['get'] = array('administer CiviCRM'); + $permissions['form_processor_action']['create'] = array('administer CiviCRM'); + $permissions['form_processor_action']['delete'] = array('administer CiviCRM'); } /** diff --git a/sql/create_civicrm_form_processor.sql b/sql/create_civicrm_form_processor.sql index 97ee8565151d128ed1a912fb77bf7018b5bdc9af..8f0b9be16165f6bd6d1cb6b9183cb5c99401fc83 100644 --- a/sql/create_civicrm_form_processor.sql +++ b/sql/create_civicrm_form_processor.sql @@ -1,4 +1,4 @@ -CREATE TABLE IF NOT EXISTS `civicrm_form_processor` ( +CREATE TABLE IF NOT EXISTS `civicrm_form_processor_instance` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(80) NULL, `title` VARCHAR(128) NULL, @@ -14,19 +14,27 @@ CREATE TABLE IF NOT EXISTS `civicrm_form_processor` ( CREATE TABLE IF NOT EXISTS `civicrm_form_processor_input` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `form_processor_id` INT UNSIGNED NOT NULL, + `form_processor_instance_id` INT UNSIGNED NOT NULL, `name` VARCHAR(80) NOT NULL, `type` VARCHAR(80) NOT NULL, `is_required` TINYINT NULL DEFAULT 0, `default_value` VARCHAR(256) NULL, `configuration` TEXT NULL, PRIMARY KEY (`id`), - UNIQUE INDEX `name_id_UNIQUE` (`id`, `name` ASC) + UNIQUE INDEX `name_id_UNIQUE` (`form_processor_instance_id`, `name` ASC) +) ENGINE = InnoDB; + +CREATE TABLE IF NOT EXISTS `civicrm_form_processor_input_validation` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `form_processor_input_id` INT UNSIGNED NOT NULL, + `validator` VARCHAR(80) NOT NULL, + `configuration` TEXT NULL, + PRIMARY KEY (`id`) ) ENGINE = InnoDB; CREATE TABLE IF NOT EXISTS `civicrm_form_processor_action` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `form_processor_id` INT UNSIGNED NOT NULL, + `form_processor_instance_id` INT UNSIGNED NOT NULL, `weight` INT UNSIGNED NOT NULL, `title` VARCHAR(80) NOT NULL, `type` VARCHAR(80) NOT NULL, diff --git a/sql/uninstall.sql b/sql/uninstall.sql index 084e627b4aa60ae559c885db6e4bd4812501e588..03729442544bc963a77513d70e6d7d39358a9cf4 100644 --- a/sql/uninstall.sql +++ b/sql/uninstall.sql @@ -1,2 +1,4 @@ -DROP TABLE `civicrm_form_processor_input`; -DROP TABLE `civicrm_form_processor`; +DROP TABLE IF EXISTS `civicrm_form_processor_input_validation`; +DROP TABLE IF EXISTS `civicrm_form_processor_input`; +DROP TABLE IF EXISTS `civicrm_form_processor_action`; +DROP TABLE IF EXISTS `civicrm_form_processor_instance`; diff --git a/tests/phpunit/api/v3/ApiPermissionTest.php b/tests/phpunit/api/v3/ApiPermissionTest.php index 85a42404f14b8683a9552255ff7a179c82f4a017..6e98108a75b3bb4a63184cc5e71cb4fc23365ef2 100644 --- a/tests/phpunit/api/v3/ApiPermissionTest.php +++ b/tests/phpunit/api/v3/ApiPermissionTest.php @@ -30,6 +30,8 @@ class Api_v3_ApiPermissionTest extends \PHPUnit_Framework_TestCase implements He protected $formProcessorInputId; + protected $formProcessorInputValidationId; + protected $formProcessorActionId; public function setUpHeadless() { @@ -47,7 +49,7 @@ class Api_v3_ApiPermissionTest extends \PHPUnit_Framework_TestCase implements He $config->userPermissionClass = new \CRM_Core_Permission_UnitTests(); $config->userPermissionClass->permissions = array(); - $formProcessor = new \CRM_FormProcessor_BAO_FormProcessor(); + $formProcessor = new \CRM_FormProcessor_BAO_FormProcessorInstance(); $formProcessor->name = 'name'; $formProcessor->title = 'Title'; $formProcessor->save(); @@ -56,14 +58,20 @@ class Api_v3_ApiPermissionTest extends \PHPUnit_Framework_TestCase implements He $formProcessorInput = new \CRM_FormProcessor_BAO_FormProcessorInput(); $formProcessorInput->name = 'contact_id'; $formProcessorInput->type = 'Integer'; - $formProcessorInput->form_processor_id = $this->formProcessorId; + $formProcessorInput->form_processor_instance_id = $this->formProcessorId; $formProcessorInput->save(); $this->formProcessorInputId = $formProcessorInput->id; + $formProcessorInputValidation = new \CRM_FormProcessor_BAO_FormProcessorInputValidation(); + $formProcessorInputValidation->validator = 'email'; + $formProcessorInputValidation->form_processor_input_id = $this->formProcessorInputId; + $formProcessorInputValidation->save(); + $this->formProcessorInputValidationId = $formProcessorInputValidation->id; + $formProcessorAction = new \CRM_FormProcessor_BAO_FormProcessorAction(); $formProcessorAction->title = 'contact_id'; $formProcessorAction->type = 'AddToGroup'; - $formProcessorAction->form_processor_id = $this->formProcessorId; + $formProcessorAction->form_processor_instance_id = $this->formProcessorId; $formProcessorAction->weight = 0; $formProcessorAction->save(); $this->formProcessorActionId = $formProcessorAction->id; @@ -113,15 +121,15 @@ class Api_v3_ApiPermissionTest extends \PHPUnit_Framework_TestCase implements He public function apiCalls() { return array( - 'FormProcessor.Get' => array( - 'entity' => 'FormProcessor', + 'FormProcessorInstance.Get' => array( + 'entity' => 'FormProcessorInstance', 'action' => 'get', 'params' => array(), 'id_params' => array('id' => 'formProcessorId'), 'expected' => array('count' => 1), ), - 'FormProcessor.Create' => array( - 'entity' => 'FormProcessor', + 'FormProcessorInstance.Create' => array( + 'entity' => 'FormProcessorInstance', 'action' => 'create', 'params' => array( 'title' => 'Test', @@ -130,8 +138,8 @@ class Api_v3_ApiPermissionTest extends \PHPUnit_Framework_TestCase implements He 'id_params' => array('id' => 'formProcessorId'), 'expected' => array('count' => 1), ), - 'FormProcessor.Delete' => array( - 'entity' => 'FormProcessor', + 'FormProcessorInstance.Delete' => array( + 'entity' => 'FormProcessorInstance', 'action' => 'delete', 'params' => array( ), @@ -166,6 +174,33 @@ class Api_v3_ApiPermissionTest extends \PHPUnit_Framework_TestCase implements He 'expected' => array('count' => 0, 'is_error' => 0), ), + // Test for the input validation api + 'FormProcessorInputValidation.Get' => array( + 'entity' => 'FormProcessorInputValidation', + 'action' => 'get', + 'params' => array(), + 'id_params' => array('id' => 'formProcessorInputValidationId'), + 'expected' => array('count' => 1), + ), + 'FormProcessorInputValidation.Create' => array( + 'entity' => 'FormProcessorInputValidation', + 'action' => 'create', + 'params' => array( + 'validator' => 'email', + 'configuration' => array(), + ), + 'id_params' => array('id' => 'formProcessorInputValidationId'), + 'expected' => array('count' => 1), + ), + 'FormProcessorInputValidation.Delete' => array( + 'entity' => 'FormProcessorInputValidation', + 'action' => 'delete', + 'params' => array( + ), + 'id_params' => array('id' => 'formProcessorInputValidationId'), + 'expected' => array('count' => 0, 'is_error' => 0), + ), + // Test for the action api. 'FormProcessorAction.Get' => array( 'entity' => 'FormProcessorAction',