Skip to content
Snippets Groups Projects
Commit 0053bc0d authored by jaapjansma's avatar jaapjansma
Browse files

added form for conditions

parent de7e17b2
Branches
Tags
No related merge requests found
Showing
with 360 additions and 249 deletions
......@@ -131,4 +131,40 @@ class CRM_Civirules_BAO_Condition extends CRM_Civirules_DAO_Condition {
$condition->find(true);
return $condition->label;
}
/**
* Get the condition class for this condition
*
* @param $condition_id
* @param bool $abort if true this function will throw an exception if class could not be instanciated
* @return CRM_Civirules_Condition
* @throws Exception if abort is set to true and class does not exist or is not valid
*/
public static function getConditionObjectById($condition_id, $abort=true) {
$condition = new CRM_Civirules_BAO_Condition();
$condition->id = $condition_id;
if (!$condition->find(true)) {
if ($abort) {
throw new Exception('Could not find condition');
}
return false;
}
$class_name = $condition->class_name;
if (!class_exists($class_name)) {
if ($abort) {
throw new Exception('Condition class ' . $class_name . ' does not exist');
}
return false;
}
$object = new $class_name();
if (!$object instanceof CRM_Civirules_Condition) {
if ($abort) {
throw new Exception('Condition class ' . $class_name . ' is not a subclass of CRM_Civirules_Condition');
}
return false;
}
return $object;
}
}
\ No newline at end of file
......@@ -128,4 +128,5 @@ class CRM_Civirules_BAO_RuleCondition extends CRM_Civirules_DAO_RuleCondition {
self::deleteWithId($ruleCondition->id);
}
}
}
\ No newline at end of file
<?php
abstract class CRM_Civirules_Condition {
protected $ruleCondition = array();
public function setRuleConditionData($ruleCondition) {
$this->ruleCondition = array();
if (is_array($ruleCondition)) {
$this->ruleCondition = $ruleCondition;
}
}
/**
* This function returns true or false when an condition is valid or not
*
* @param CRM_Civirules_EventData_EventData $eventData
* @return bool
*/
public abstract function isConditionValid(CRM_Civirules_EventData_EventData $eventData);
/**
* Returns a redirect url to extra data input from the user after adding a condition
*
* Return false if you do not need extra data input
*
* @param int $ruleConditionId
* @return bool|string
*/
abstract public function getExtraDataInputUrl($ruleConditionId);
/**
* Retruns a user friendly text explaining the condition params
* e.g. 'Older than 65'
*
* @return string
*/
public function userFriendlyConditionParams() {
return '';
}
}
\ No newline at end of file
<?php
abstract class CRM_Civirules_Conditions_Condition {
private $ruleConditionId = false;
private $ruleCondition = false;
protected function __construct($ruleConditionId=false) {
$this->ruleConditionId = $ruleConditionId;
$this->ruleCondition = false;
if ($this->getRuleConditionId()) {
$ruleCondition = new CRM_Civirules_BAO_RuleCondition();
$ruleCondition->id = $this->getRuleConditionId();
if ($ruleCondition->find(true)) {
$ruleConditionData = array();
CRM_Core_DAO::storeValues($ruleCondition, $ruleConditionData);
$this->ruleCondition = $ruleConditionData;
}
}
}
/**
* This function returns true or false when an condition is valid or not
*
* @param CRM_Civirules_EventData_EventData $eventData
* @return bool
*/
public abstract function isConditionValid(CRM_Civirules_EventData_EventData $eventData);
/**
* Returns wether this condition has an extra input form
*
* If your condition contains a form override this method and return a CRM_Civirules_Conditions_Form_Form
* If your condition does not have/need an extra input form then return this method should return false
*
* @return bool|CRM_Civirules_Conditions_Form_Form
*/
public function getForm() {
return false;
}
/**
* Returns the extra condition data
*
* @return array
*/
public function getConditionData() {
return array();
}
/*
* Transforms condition data so that it could be stored in the database
*
* @param array $data
* @return string
*/
public function transformConditionData($data=array()) {
return '';
}
/**
* Returns the Id of the current condition, or false if not set
*
* @return int
*/
public function getRuleConditionId() {
return $this->ruleConditionId;
}
/**
* Returns the rule condition or false when not set
*
* @return array|bool
*/
public function getRuleCondition() {
return $this->ruleCondition;
}
}
\ No newline at end of file
<?php
abstract class CRM_Civirules_Conditions_Form_Form {
protected $condition;
public function __construct(CRM_Civirules_Conditions_Condition $condition) {
$this->condition = $condition;
}
/**
* You can use this function to add elements to a form
*
* @param CRM_Core_Form $form
* @return void
*/
abstract public function buildForm(CRM_Core_Form &$form);
/**
* You can use this function to set default values
*
* @param CRM_Core_Form $form
* @param array $defaultValues
* @return array
*/
abstract public function defaultValues(CRM_Core_Form &$form, $defaultValues);
/**
* You can use this to post process the form
*
* This function should return a string with the options ready for saving into the database
*
* @param CRM_Core_Form $form
* @param array $submittedValues
* @return string
*/
abstract public function postProcess(CRM_Core_Form &$form, $submittedValues);
}
\ No newline at end of file
<?php
class CRM_Civirules_Conditions_Form_ValueComparison extends CRM_Civirules_Conditions_Form_Form {
/**
* You can use this function to add elements to a form
*
* @param CRM_Core_Form $form
* @return void
*/
public function buildForm(CRM_Core_Form &$form) {
$form->addSelect('operator', ts('Operator'), array(
'=' => ts('equals'),
'!=' => ts('not equals'),
'>' => ts('greater than'),
'<' => ts('less than'),
'>=' => ts('greater than or equals'),
'<=' => ts('less than or equals'),
), true);
$this->add('text', 'value', ts('Compare value'), true);
}
/**
* You can use this function to set default values
*
* @param CRM_Core_Form $form
* @return array
*/
public function defaultValues(CRM_Core_Form &$form, $defaultValues) {
$data = $this->condition->getConditionData();
if (!empty($data['operator'])) {
$defaultValues['operator'] = $data['operator'];
}
if (!empty($data['value'])) {
$defaultValues['value'] = $data['value'];
}
return $defaultValues;
}
/**
* You can use this to post process the form
*
* This function should return a string with the options ready for saving into the database
*
* @param CRM_Core_Form $form
* @param array $submittedValues
* @return string
*/
public function postProcess(CRM_Core_Form &$form, $submittedValues) {
$data['operator'] = $submittedValues['operator'];
$data['value'] = $submittedValues['values'];
return $this->condition->transformConditionData($data);
}
}
\ No newline at end of file
......@@ -55,7 +55,7 @@ class CRM_Civirules_Engine {
);
$ruleConditions = CRM_Civirules_BAO_RuleCondition::getValues($conditionParams);
foreach ($ruleConditions as $ruleConditionId => $ruleCondition) {
$isConditionValid = self::checkCondition($conditionParams['condition_id'], $eventData);
$isConditionValid = self::checkCondition($ruleCondition, $eventData);
if ($firstCondition) {
$isValid = $isConditionValid ? true : false;
$firstCondition = false;
......@@ -78,24 +78,13 @@ class CRM_Civirules_Engine {
return $isValid;
}
protected static function checkCondition($condition_id, CRM_Civirules_EventData_EventData $eventData) {
$condition = new CRM_Civirules_BAO_Condition();
$condition->id = $condition_id;
if (!$condition->find(true)) {
protected static function checkCondition($ruleCondition, CRM_Civirules_EventData_EventData $eventData) {
$condition = CRM_Civirules_BAO_Condition::getConditionObjectById($ruleCondition['condition_id'], false);
if (!$condition) {
return false;
}
$class_name = $condition->class_name;
if (!class_exists($class_name)) {
return false;
}
$object = new $class_name();
if (!$object instanceof CRM_Civirules_Conditions_Condition) {
return false;
}
$isValid = $object->isConditionValid($eventData);
$condition->setRuleConditionData($ruleCondition);
$isValid = $condition->isConditionValid($eventData);
return $isValid ? true : false;
}
......
......@@ -250,6 +250,10 @@ class CRM_Civirules_Form_Rule extends CRM_Core_Form {
$ruleConditions[$ruleConditionId]['name'] =
CRM_Civirules_BAO_Condition::getConditionLabelWithId($ruleCondition['condition_id']);
$ruleConditions[$ruleConditionId]['actions'] = $this->setRuleConditionActions($ruleConditionId);
$conditionClass = CRM_Civirules_BAO_Condition::getConditionObjectById($ruleCondition['condition_id']);
$conditionClass->setRuleConditionData($ruleCondition);
$ruleConditions[$ruleConditionId]['formattedConditionParams'] = $conditionClass->userFriendlyConditionParams();
}
return $ruleConditions;
}
......
......@@ -47,8 +47,14 @@ class CRM_Civirules_Form_RuleCondition extends CRM_Core_Form {
if (isset($this->_submitValues['rule_condition_link_select'])) {
$saveParams['condition_link'] = $this->_submitValues['rule_condition_link_select'];
}
CRM_Civirules_BAO_RuleCondition::add($saveParams);
$redirectUrl = CRM_Utils_System::url('civicrm/civirule/form/rule', 'action=update&id='.$this->_submitValues['rule_id'], TRUE);
$ruleCondition = CRM_Civirules_BAO_RuleCondition::add($saveParams);
$condition = CRM_Civirules_BAO_Condition::getConditionObjectById($ruleCondition['condition_id'], true);
$redirectUrl = $condition->getExtraDataInputUrl($ruleCondition['id']);
if (empty($redirectUrl)) {
$redirectUrl = CRM_Utils_System::url('civicrm/civirule/form/rule', 'action=update&id=' . $this->_submitValues['rule_id'], TRUE);
}
$session->setStatus('Condition added to CiviRule '.CRM_Civirules_BAO_Rule::getRuleLabelWithId($this->_submitValues['rule_id']),
'Condition added', 'success');
CRM_Utils_System::redirect($redirectUrl);
......
<?php
class CRM_Civirules_Conditions_AgeComparison extends CRM_Civirules_Conditions_DataComparison {
class CRM_CivirulesConditions_AgeComparison extends CRM_CivirulesConditions_Generic_ValueComparison {
/**
* Returns value of the field
*
* @parameter CRM_Civirules_EventData_EventData $eventData
* @param CRM_Civirules_EventData_EventData $eventData
* @return mixed
*/
protected function getFieldValue(CRM_Civirules_EventData_EventData $eventData) {
......@@ -17,27 +17,36 @@ class CRM_Civirules_Conditions_AgeComparison extends CRM_Civirules_Conditions_Da
}
/**
* Returns the value for the data comparison
* @return mixed
*/
protected function getComparisonValue() {
throw new exception('return age value');
}
/**
* Returns an operator for comparison
*
* Valid operators are:
* - equal: =
* - not equal: !=
* - greater than: >
* - lesser than: <
* - greater than or equal: >=
* - lesser than or equal: <=
* Retruns a user friendly text explaining the condition params
* e.g. 'Older than 65'
*
* @return an operator for comparison
* @return string
*/
protected function getOperator() {
throw new exception('return operator');
public function userFriendlyConditionParams() {
switch ($this->getOperator()) {
case '=':
$label = 'Age is %1';
break;
case '>':
$label = 'Age is older than %1';
break;
case '<':
$label = 'Age is younger than %1';
break;
case '>=':
$label = 'Age is %1 or older than %1';
break;
case '<=':
$label = 'Age is %1 or younger than %1';
break;
case '!=':
$label = 'Age is not %1';
break;
default:
return '';
break;
}
return ts($label, array(1 => $this->getValue()));
}
}
\ No newline at end of file
<?php
class CRM_Civirules_Conditions_BirthdayChanged extends CRM_Civirules_Conditions_FieldChanged {
class CRM_CivirulesConditions_BirthdayChanged extends CRM_CivirulesConditions_Generic_FieldChanged {
/**
* Returns name of entity
*
* @return string
*/
protected function getEntity() {
return 'contact';
}
/**
* Returns name of the field
* @return string
*/
protected function getField() {
return 'birth_date';
}
/**
* This function could be overridden in subclasses to
* transform field data to a certain type
*
* E.g. a date field could be transformed to a DataTime object so that
* the comparison is easier
*
* @param $fieldData
* @return mixed
*/
protected function transformFieldData($fieldData) {
return new DateTime($fieldData);
}
......
<?php
class CRM_CivirulesConditions_Form_ValueComparison extends CRM_Core_Form {
protected $ruleConditionId = false;
function preProcess() {
$this->ruleConditionId = CRM_Utils_Request::retrieve('rule_condition_id', 'Integer');
parent::preProcess();
}
function buildQuickForm() {
$this->setFormTitle();
$this->add('select', 'operator', ts('Operator'), array(
'=' => ts('Is equal to'),
'!=' => ts('Is not equal to'),
'>' => ts('Is greater than'),
'<' => ts('Is less than'),
'>=' => ts('Is greater than or equal to'),
'<=' => ts('Is less than or equal to'),
), true);
$this->add('text', 'value', ts('Compare value'), true);
$this->addButtons(array(
array('type' => 'next', 'name' => ts('Save'), 'isDefault' => TRUE,),
array('type' => 'cancel', 'name' => ts('Cancel'))));
}
public function setDefaultValues() {
$data = array();
$defaultValues = array();
$ruleCondition = new CRM_Civirules_BAO_RuleCondition();
if ($ruleCondition->find(true)) {
$data = CRM_Civirules_Utils_Parameters::convertFromMultiline($ruleCondition->condition_params);
}
if (!empty($data['operator'])) {
$defaultValues['operator'] = $data['operator'];
}
if (!empty($data['value'])) {
$defaultValues['value'] = $data['value'];
}
return $defaultValues;
}
public function postProcess() {
$rule_id = 0;
$ruleCondition = new CRM_Civirules_BAO_RuleCondition();
$condition_label = '';
if ($ruleCondition->find(true)) {
$rule_id = $ruleCondition->rule_id;
$condition = new CRM_Civirules_BAO_Condition();
$condition->id = $ruleCondition->condition_id;
if ($condition->find(true)) {
$condition_label = $condition->label;
}
}
$data['operator'] = $this->_submitValues['operator'];
$data['value'] = $this->_submitValues['values'];
$saveParams = array(
'id' => $this->ruleConditionId,
'condition_params' => CRM_Civirules_Utils_Parameters::convertToMultiline($data),
);
CRM_Civirules_BAO_RuleCondition::add($saveParams);
$session = CRM_Core_Session::singleton();
$session->setStatus('Condition '.$condition_label.' parameters updated to CiviRule '.CRM_Civirules_BAO_Rule::getRuleLabelWithId($rule_id),
'Condition parameters updated', 'success');
$redirectUrl = CRM_Utils_System::url('civicrm/civirule/form/rule', 'action=update&id='.$rule_id, TRUE);
CRM_Utils_System::redirect($redirectUrl); }
protected function setFormTitle() {
$condition_label = '';
$ruleCondition = new CRM_Civirules_BAO_RuleCondition();
if ($ruleCondition->find(true)) {
$condition = new CRM_Civirules_BAO_Condition();
$condition->id = $ruleCondition->condition_id;
if ($condition->find(true)) {
$condition_label = $condition->label;
}
}
$title = 'CiviRules Edit Condition parameters';
$this->assign('ruleConditionHeader', 'Edit Condition '.$condition_label.' of CiviRule '.CRM_Civirules_BAO_Rule::getRuleLabelWithId($ruleCondition->rule_id));
CRM_Utils_System::setTitle($title);
}
}
\ No newline at end of file
<?php
abstract class CRM_Civirules_Conditions_FieldChanged extends CRM_Civirules_Conditions_Condition {
abstract class CRM_CivirulesConditions_Generic_FieldChanged extends CRM_Civirules_Condition {
/**
* Returns name of entity
......@@ -38,6 +38,32 @@ abstract class CRM_Civirules_Conditions_FieldChanged extends CRM_Civirules_Condi
return true;
}
/**
* This function could be overridden in subclasses to
* transform field data to a certain type
*
* E.g. a date field could be transformed to a DataTime object so that
* the comparison is easier
*
* @param $fieldData
* @return mixed
*/
protected function transformFieldData($fieldData) {
return $fieldData;
}
/**
* Returns a redirect url to extra data input from the user after adding a condition
*
* Return false if you do not need extra data input
*
* @param int $ruleConditionId
* @return bool|string
*/
public function getExtraDataInputUrl($ruleConditionId) {
return false;
}
protected function getFieldData(CRM_Civirules_EventData_EventData $eventData) {
$entity = $this->getEntity();
$data = $eventData->getEntityData($entity);
......@@ -61,18 +87,4 @@ abstract class CRM_Civirules_Conditions_FieldChanged extends CRM_Civirules_Condi
}
return null;
}
/**
* This function could be overridden in subclasses to
* transform field data to a certain type
*
* E.g. a date field could be transformed to a DataTime object so that
* the comparison is easier
*
* @param $fieldData
* @return mixed
*/
protected function transformFieldData($fieldData) {
return $fieldData;
}
}
\ No newline at end of file
<?php
abstract class CRM_Civirules_Conditions_DataComparison extends CRM_Civirules_Conditions_Condition {
abstract class CRM_CivirulesConditions_Generic_ValueComparison extends CRM_Civirules_Condition {
private $condition_params = array();
public function setRuleConditionData($ruleCondition) {
parent::setRuleConditionData($ruleCondition);
$this->condition_params = array();
if (!empty($this->ruleCondition['condition_params'])) {
$this->condition_params = CRM_Civirules_Utils_Parameters::convertFromMultiline($this->ruleCondition['condition_params']);
}
}
/**
* Returns value of the field
*
* @parameter CRM_Civirules_EventData_EventData $eventData
* @param CRM_Civirules_EventData_EventData $eventData
* @return mixed
*/
abstract protected function getFieldValue(CRM_Civirules_EventData_EventData $eventData);
......@@ -14,7 +24,9 @@ abstract class CRM_Civirules_Conditions_DataComparison extends CRM_Civirules_Con
* Returns the value for the data comparison
* @return mixed
*/
abstract protected function getComparisonValue();
protected function getComparisonValue() {
return (!empty($this->condition_params['value']) ? $this->condition_params['value'] : '');
}
/**
* Returns an operator for comparison
......@@ -29,7 +41,9 @@ abstract class CRM_Civirules_Conditions_DataComparison extends CRM_Civirules_Con
*
* @return an operator for comparison
*/
abstract protected function getOperator();
protected function getOperator() {
return (!empty($this->condition_params['operator']) ? $this->condition_params['operator'] : '');
}
public function isConditionValid(CRM_Civirules_EventData_EventData $eventData) {
$value = $this->getFieldValue($eventData);
......@@ -66,48 +80,25 @@ abstract class CRM_Civirules_Conditions_DataComparison extends CRM_Civirules_Con
}
/**
* Returns wether this condition has an extra input form
* Returns a redirect url to extra data input from the user after adding a condition
*
* If your condition contains a form override this method and return a CRM_Civirules_Conditions_Form_Form
* If your condition does not have/need an extra input form then return this method should return false
* Return false if you do not need extra data input
*
* @return bool|CRM_Civirules_Conditions_Form_Form
* @param int $ruleConditionId
* @return bool|string
*/
public function getForm() {
return new CRM_Civirules_Conditions_Form_ValueComparison($this);
public function getExtraDataInputUrl($ruleConditionId) {
return CRM_Utils_System::url('civicrm/civirule/form/condition/datacomparison/', 'rule_condition_id='.$ruleConditionId);
}
/**
* Returns the extra condition data
*
* @return array
*/
public function getConditionData() {
$return = array(
'operator' => '=',
'value' => '',
);
$ruleCondition = $this->getRuleCondition();
if (is_array($ruleCondition)) {
$data = CRM_Civirules_Utils_Parameters::convertFromMultiline($ruleCondition['data']);
if (!empty($data['operator'])) {
$return['operator'] = $data['operator'];
}
if (!empty($data['value'])) {
$return['value'] = $data['value'];
}
}
return $return;
}
/*
* Transforms condition data so that it could be stored in the database
* Retruns a user friendly text explaining the condition params
* e.g. 'Older than 65'
*
* @param array $data
* @return string
*/
public function transformConditionData($data=array()) {
return CRM_Civirules_Utils_Parameters::convertToMultiline($data);
public function userFriendlyConditionParams() {
return htmlentities(($this->getOperator())).' '.htmlentities($this->getComparisonValue());
}
}
\ No newline at end of file
......@@ -17,7 +17,12 @@
{foreach from=$ruleConditions key=ruleConditionIid item=ruleCondition}
<tr class={$row_class}>
<td>{$ruleCondition.condition_link}</td>
<td>{$ruleCondition.name}</td>
<td>
{$ruleCondition.name}
{if !empty($ruleCondition.formattedConditionParams)}
<br /><span>{$ruleCondition.formattedConditionParams}</span>
{/if}
</td>
<td>
<span>
{foreach from=$ruleCondition.actions item=action_link}
......
<h3>{$ruleConditionHeader}</h3>
<div class="crm-block crm-form-block crm-civirule-rule_condition-block-value-comparison">
<div class="crm-section">
<div class="label">{$form.operator.label}</div>
<div class="content">{$form.operator.html}</div>
<div class="clear"></div>
</div>
<div class="crm-section">
<div class="label">{$form.value.label}</div>
<div class="content">{$form.value.html}</div>
<div class="clear"></div>
</div>
</div>
<div class="crm-submit-buttons">
{include file="CRM/common/formButtons.tpl" location="bottom"}
</div>
\ No newline at end of file
......@@ -24,4 +24,10 @@
<title>RuleAction</title>
<access_arguments>access CiviCRM</access_arguments>
</item>
<item>
<path>civicrm/civirule/form/condition/datacomparison</path>
<page_callback>CRM_CivirulesConditions_Form_ValueComparison</page_callback>
<title>Value comparison</title>
<access_arguments>access CiviCRM</access_arguments>
</item>
</menu>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment