From bf1074f35f99e1f1548791fba171d5865e8743c4 Mon Sep 17 00:00:00 2001 From: Jaap Jansma <jaap@edeveloper.nl> Date: Wed, 11 Mar 2015 15:15:23 +0100 Subject: [PATCH] created form for action parameters --- CRM/Civirules/Action.php | 100 ++++++++++++++++++ CRM/Civirules/Action/Action.php | 61 ----------- CRM/Civirules/Action/GroupContact.php | 18 ---- CRM/Civirules/BAO/Action.php | 46 +++++++- CRM/Civirules/BAO/RuleAction.php | 19 ---- CRM/Civirules/DAO/RuleAction.php | 2 +- CRM/Civirules/Engine.php | 38 +++---- CRM/Civirules/Form/Rule.php | 4 + CRM/Civirules/Form/RuleAction.php | 14 ++- CRM/CivirulesActions/Form/GroupContact.php | 79 ++++++++++++++ CRM/CivirulesActions/GroupContact.php | 45 ++++++++ sql/createCiviruleRuleAction.sql | 2 +- sql/createCiviruleRuleCondition.sql | 2 +- .../Civirules/Form/RuleBlocks/ActionBlock.tpl | 4 +- .../CivirulesActions/Form/GroupContact.tpl | 11 ++ xml/Menu/civirules.xml | 6 ++ 16 files changed, 323 insertions(+), 128 deletions(-) create mode 100644 CRM/Civirules/Action.php delete mode 100644 CRM/Civirules/Action/Action.php delete mode 100644 CRM/Civirules/Action/GroupContact.php create mode 100644 CRM/CivirulesActions/Form/GroupContact.php create mode 100644 CRM/CivirulesActions/GroupContact.php create mode 100644 templates/CRM/CivirulesActions/Form/GroupContact.tpl diff --git a/CRM/Civirules/Action.php b/CRM/Civirules/Action.php new file mode 100644 index 0000000..eeddf31 --- /dev/null +++ b/CRM/Civirules/Action.php @@ -0,0 +1,100 @@ +<?php + +abstract class CRM_Civirules_Action { + + protected $ruleAction = array(); + + protected $action = array(); + + public function setRuleActionData($ruleAction) { + $this->ruleAction = array(); + if (is_array($ruleAction)) { + $this->ruleAction = $ruleAction; + } + } + + public function setActionData($action) { + $this->action = $action; + } + + /** + * Returns an array with parameters used for processing an action + * + * @param array $parameters + * @param CRM_Civirules_EventData_EventData $eventData + * @return array + */ + protected function alterApiParameters($parameters, CRM_Civirules_EventData_EventData $eventData) { + //this function could be overridden in subclasses to alter parameters to meet certain criteraia + return $parameters; + } + + /** + * Process the action + * + * @param CRM_Civirules_EventData_EventData $eventData + */ + public function processAction(CRM_Civirules_EventData_EventData $eventData) { + $entity = $this->action['api_entity']; + $action = $this->action['api_action']; + + $params = $this->getActionParameters(); + + //alter parameters by subclass + $params = $this->alterApiParameters($params, $eventData); + + //execute the action + $this->executeApiAction($entity, $action, $params); + } + + /** + * Executes the action + * + * This function could be overriden if needed + * + * @param $entity + * @param $action + * @param $parameters + */ + protected function executeApiAction($entity, $action, $parameters) { + civicrm_api3($entity, $action, $parameters); + } + + /** + * Convert parameters to an array of parameters + * + * @return array + */ + protected function getActionParameters() { + $params = array(); + if (!empty($this->ruleAction['action_params'])) { + $params = unserialize($this->ruleAction['action_params']); + } + return $params; + } + + /** + * Returns a redirect url to extra data input from the user after adding a action + * + * Return false if you do not need extra data input + * + * @param int $ruleActionId + * @return bool|string + */ + public function getExtraDataInputUrl($ruleActionId) { + return false; + } + + /** + * 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 diff --git a/CRM/Civirules/Action/Action.php b/CRM/Civirules/Action/Action.php deleted file mode 100644 index bf296ba..0000000 --- a/CRM/Civirules/Action/Action.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php - -abstract class CRM_Civirules_Action_Action { - - /** - * Returns an array with parameters used for processing an action - * - * @param array $parameters - * @param CRM_Civirules_EventData_EventData $eventData - * @return array - */ - protected function alterApiParameters($parameters, CRM_Civirules_EventData_EventData $eventData) { - //this function could be overridden in subclasses to alter parameters to meet certain criteraia - return $parameters; - } - - /** - * Process the action - * - * @param $rule_action_id - * @param $entity - * @param $action - * @param $parameters - * @param CRM_Civirules_EventData_EventData $eventData - */ - public function processAction($rule_action_id, $entity, $action, $parameters, CRM_Civirules_EventData_EventData $eventData) { - $params = $this->convertParameters($parameters); - - //alter parameters by subclass - $params = $this->alterApiParameters($params, $eventData); - - //execute the action - $this->executeAction($entity, $action, $params); - } - - /** - * Executes the action - * - * This function could be overriden if needed - * - * @param $entity - * @param $action - * @param $parameters - */ - protected function executeAction($entity, $action, $parameters) { - civicrm_api3($entity, $action, $parameters); - } - - /** - * Convert parameters to an array of parameters - * - * @param $action_parameters - * @return array - */ - protected function convertParameters($action_parameters) { - return CRM_Civirules_Utils_Parameters::convertFromMultiline($action_parameters); - } - - - -} \ No newline at end of file diff --git a/CRM/Civirules/Action/GroupContact.php b/CRM/Civirules/Action/GroupContact.php deleted file mode 100644 index e251cf8..0000000 --- a/CRM/Civirules/Action/GroupContact.php +++ /dev/null @@ -1,18 +0,0 @@ -<?php - -class CRM_Civirules_Action_GroupContact extends CRM_Civirules_Action_Action { - - /** - * Returns an array with parameters used for processing an action - * - * @param array $parameters - * @param CRM_Civirules_EventData_EventData $eventData - * @return array - */ - protected function alterApiParameters($parameters, CRM_Civirules_EventData_EventData $eventData) { - //this function could be overridden in subclasses to alter parameters to meet certain criteraia - $parameters['contact_id'] = $eventData->getContactId(); - return $parameters; - } - -} \ No newline at end of file diff --git a/CRM/Civirules/BAO/Action.php b/CRM/Civirules/BAO/Action.php index bfd0db5..06f4860 100755 --- a/CRM/Civirules/BAO/Action.php +++ b/CRM/Civirules/BAO/Action.php @@ -129,4 +129,48 @@ class CRM_Civirules_BAO_Action extends CRM_Civirules_DAO_Action { $action->id = $actionId; $action->find(true); return $action->label; - }} + } + + /** + * Get the action class for this condition + * + * @param $actionId + * @param bool $abort if true this function will throw an exception if class could not be instanciated + * @return CRM_Civirules_Action + * @throws Exception if abort is set to true and class does not exist or is not valid + */ + public static function getActionObjectById($actionId, $abort=true) { + $action = new CRM_Civirules_BAO_Action(); + $action->id = $actionId; + if (!$action->find(true)) { + if ($abort) { + throw new Exception('CiviRule could not find action'); + } + return false; + } + + $className = $action->class_name; + if (!class_exists($className)) { + if ($abort) { + + throw new Exception('CiviRule action class "' . $className . '" does not exist'); + } + return false; + } + + $object = new $className(); + if (!$object instanceof CRM_Civirules_Action) { + if ($abort) { + throw new Exception('CiviRule action class "' . $className . '" is not a subclass of CRM_Civirules_Action'); + } + return false; + } + + $actionData = array(); + CRM_Core_DAO::storeValues($action, $actionData); + $object->setActionData($actionData); + + return $object; + } + +} diff --git a/CRM/Civirules/BAO/RuleAction.php b/CRM/Civirules/BAO/RuleAction.php index c5f562e..1af1a71 100755 --- a/CRM/Civirules/BAO/RuleAction.php +++ b/CRM/Civirules/BAO/RuleAction.php @@ -129,23 +129,4 @@ class CRM_Civirules_BAO_RuleAction extends CRM_Civirules_DAO_RuleAction { } } - public static function getRuleActions($rule_id) { - $sql = "SELECT `ra`.`id`, a.`api_entity`, a.`api_action`, a.`class_name`, ra.`action_params` - FROM `civirule_action` `a` - INNER JOIN `civirule_rule_action` `ra` ON `a`.`id` = `ra`.`action_id` - WHERE `ra`.`rule_id` = %1"; - $params[1] = array($rule_id, 'Integer'); - $return = array(); - $dao = CRM_COre_DAO::executeQuery($sql, $params); - while($dao->fetch()) { - $return[$dao->id] = array( - 'rule_action_id' => $dao->id, - 'api_entity' => $dao->api_entity, - 'api_action' => $dao->api_action, - 'api_parameters' => $dao->action_params, - 'class_name' => $dao->class_name - ); - } - return $return; - } } \ No newline at end of file diff --git a/CRM/Civirules/DAO/RuleAction.php b/CRM/Civirules/DAO/RuleAction.php index 2c8ef05..5571ce7 100755 --- a/CRM/Civirules/DAO/RuleAction.php +++ b/CRM/Civirules/DAO/RuleAction.php @@ -44,7 +44,7 @@ class CRM_Civirules_DAO_RuleAction extends CRM_Core_DAO { ), 'action_params' => array( 'name' => 'action_params', - 'type' => CRM_Utils_Type::T_BLOB + 'type' => CRM_Utils_Type::T_TEXT ), 'is_active' => array( 'name' => 'is_active', diff --git a/CRM/Civirules/Engine.php b/CRM/Civirules/Engine.php index 4d7e6f8..4c432ff 100644 --- a/CRM/Civirules/Engine.php +++ b/CRM/Civirules/Engine.php @@ -8,42 +8,38 @@ class CRM_Civirules_Engine { * The trigger will check the conditions and if conditions are valid then the actions are executed * * @param CRM_Civirules_EventData_EventData $eventData - * @param $rule_id + * @param $ruleId + * @param $eventId */ - public static function triggerRule(CRM_Civirules_EventData_EventData $eventData, $rule_id, $event_id) { - $eventData->setEventId($event_id); - $eventData->setRuleId($rule_id); + public static function triggerRule(CRM_Civirules_EventData_EventData $eventData, $ruleId, $eventId) { + $eventData->setEventId($eventId); + $eventData->setRuleId($ruleId); - $isRuleValid = self::areConditionsValid($eventData, $rule_id); + $isRuleValid = self::areConditionsValid($eventData, $ruleId); if ($isRuleValid) { - self::executeActions($eventData, $rule_id); + self::executeActions($eventData, $ruleId); } } - protected static function executeActions(CRM_Civirules_EventData_EventData $eventData, $rule_id) { - $ruleActions = CRM_Civirules_BAO_RuleAction::getRuleActions($rule_id); - foreach($ruleActions as $ruleAction) { + protected static function executeActions(CRM_Civirules_EventData_EventData $eventData, $ruleId) { + $actionParams = array( + 'rule_id' => $ruleId + ); + $ruleActions = CRM_Civirules_BAO_RuleAction::getValues($actionParams); + foreach ($ruleActions as $ruleAction) { self::executeAction($eventData, $ruleAction); } } protected static function executeAction(CRM_Civirules_EventData_EventData $eventData, $ruleAction) { - $className = $ruleAction['class_name']; - if (!class_exists($className)) { - return; - } - - $object = new $className(); - if (!$object instanceof CRM_Civirules_Action_Action) { + $object = CRM_Civirules_BAO_Action::getActionObjectById($ruleAction['action_id'], true); + if (!$object) { return; } - $rule_action_id = $ruleAction['rule_action_id']; - $entity = $ruleAction['api_entity']; - $action = $ruleAction['api_action']; - $parameters = $ruleAction['api_parameters']; - $object->processAction($rule_action_id, $entity, $action, $parameters, $eventData); + $object->setRuleActionData($ruleAction); + $object->processAction($eventData); } protected static function areConditionsValid(CRM_Civirules_EventData_EventData $eventData, $rule_id) { diff --git a/CRM/Civirules/Form/Rule.php b/CRM/Civirules/Form/Rule.php index 7c61acf..ebef293 100755 --- a/CRM/Civirules/Form/Rule.php +++ b/CRM/Civirules/Form/Rule.php @@ -273,6 +273,10 @@ class CRM_Civirules_Form_Rule extends CRM_Core_Form { $ruleActions[$ruleActionId]['label'] = CRM_Civirules_BAO_Action::getActionLabelWithId($ruleAction['action_id']); $ruleActions[$ruleActionId]['actions'] = $this->setRuleActionActions($ruleActionId); + + $actionClass = CRM_Civirules_BAO_Action::getActionObjectById($ruleAction['action_id']); + $actionClass->setRuleActionData($ruleAction); + $ruleActions[$ruleActionId]['formattedConditionParams'] = $actionClass->userFriendlyConditionParams(); } return $ruleActions; } diff --git a/CRM/Civirules/Form/RuleAction.php b/CRM/Civirules/Form/RuleAction.php index 6e4efd4..894ad6f 100644 --- a/CRM/Civirules/Form/RuleAction.php +++ b/CRM/Civirules/Form/RuleAction.php @@ -47,15 +47,23 @@ class CRM_Civirules_Form_RuleAction extends CRM_Core_Form { * @access public */ function postProcess() { - $session = CRM_Core_Session::singleton(); + $saveParams = array( 'rule_id' => $this->_submitValues['rule_id'], 'action_id' => $this->_submitValues['rule_action_select'] ); - CRM_Civirules_BAO_RuleAction::add($saveParams); - $redirectUrl = CRM_Utils_System::url('civicrm/civirule/form/rule', 'action=update&id='.$this->_submitValues['rule_id'], TRUE); + $ruleAction = CRM_Civirules_BAO_RuleAction::add($saveParams); + + $session = CRM_Core_Session::singleton(); $session->setStatus('Action added to CiviRule '.CRM_Civirules_BAO_Rule::getRuleLabelWithId($this->_submitValues['rule_id']), 'Action added', 'success'); + + $action = CRM_Civirules_BAO_Action::getActionObjectById($ruleAction['action_id'], true); + $redirectUrl = $action->getExtraDataInputUrl($ruleAction['id']); + if (empty($redirectUrl)) { + $redirectUrl = CRM_Utils_System::url('civicrm/civirule/form/rule', 'action=update&id=' . $this->_submitValues['rule_id'], TRUE); + } + CRM_Utils_System::redirect($redirectUrl); } diff --git a/CRM/CivirulesActions/Form/GroupContact.php b/CRM/CivirulesActions/Form/GroupContact.php new file mode 100644 index 0000000..756bf5c --- /dev/null +++ b/CRM/CivirulesActions/Form/GroupContact.php @@ -0,0 +1,79 @@ +<?php + +class CRM_CivirulesActions_Form_GroupContact extends CRM_Core_Form { + + protected $ruleActionId = false; + + protected $ruleAction; + + protected $action; + + function preProcess() { + $this->ruleActionId = CRM_Utils_Request::retrieve('rule_action_id', 'Integer'); + + $this->ruleAction = new CRM_Civirules_BAO_RuleAction(); + $this->action = new CRM_Civirules_BAO_Action(); + $this->ruleAction->id = $this->ruleActionId; + if ($this->ruleAction->find(true)) { + $this->action->id = $this->ruleAction->action_id; + if (!$this->action->find(true)) { + throw new Exception('CiviRules Could not find action with id '.$this->ruleAction->action_id); + } + } else { + throw new Exception('CiviRules Could not find rule action with id '.$this->ruleActionId); + } + + parent::preProcess(); + } + + protected function getGroups() { + return array('' => ts('-- please select --')) + CRM_Contact_BAO_GroupContact::getGroupList(); + } + + function buildQuickForm() { + $this->setFormTitle(); + + $this->add('hidden', 'rule_action_id'); + + $this->add('select', 'group_id', ts('Group'), $this->getGroups(), 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(); + $defaultValues['rule_action_id'] = $this->ruleActionId; + if (!empty($this->ruleAction->action_params)) { + $data = unserialize($this->ruleCondition->action_params); + } + if (!empty($data['group_id'])) { + $defaultValues['group_id'] = $data['group_id']; + } + return $defaultValues; + } + + public function postProcess() { + $data['group_id'] = $this->_submitValues['group_id']; + + $ruleAction = new CRM_Civirules_BAO_RuleAction(); + $ruleAction->id = $this->ruleActionId; + $ruleAction->action_params = serialize($data); + $ruleAction->save(); + + $session = CRM_Core_Session::singleton(); + $session->setStatus('Action '.$this->action->label.' parameters updated to CiviRule '.CRM_Civirules_BAO_Rule::getRuleLabelWithId($this->ruleAction->rule_id), + 'Action parameters updated', 'success'); + + $redirectUrl = CRM_Utils_System::url('civicrm/civirule/form/rule', 'action=update&id='.$this->ruleAction->rule_id, TRUE); + CRM_Utils_System::redirect($redirectUrl); } + + protected function setFormTitle() { + $title = 'CiviRules Edit Action parameters'; + $this->assign('ruleActionHeader', 'Edit action '.$this->action->label.' of CiviRule '.CRM_Civirules_BAO_Rule::getRuleLabelWithId($this->ruleAction->rule_id)); + CRM_Utils_System::setTitle($title); + } + +} \ No newline at end of file diff --git a/CRM/CivirulesActions/GroupContact.php b/CRM/CivirulesActions/GroupContact.php new file mode 100644 index 0000000..992b38f --- /dev/null +++ b/CRM/CivirulesActions/GroupContact.php @@ -0,0 +1,45 @@ +<?php + +class CRM_CivirulesActions_GroupContact extends CRM_Civirules_Action { + + /** + * Returns an array with parameters used for processing an action + * + * @param array $parameters + * @param CRM_Civirules_EventData_EventData $eventData + * @return array + */ + protected function alterApiParameters($parameters, CRM_Civirules_EventData_EventData $eventData) { + //this function could be overridden in subclasses to alter parameters to meet certain criteraia + $parameters['contact_id'] = $eventData->getContactId(); + return $parameters; + } + + /** + * Returns a redirect url to extra data input from the user after adding a action + * + * Return false if you do not need extra data input + * + * @param int $ruleActionId + * @return bool|string + */ + public function getExtraDataInputUrl($ruleActionId) { + return CRM_Utils_System::url('civicrm/civirule/form/action/groupcontact', 'rule_action_id='.$ruleActionId); + } + + /** + * Retruns a user friendly text explaining the condition params + * e.g. 'Older than 65' + * + * @return string + */ + public function userFriendlyConditionParams() { + $params = $this->getActionParameters(); + if (!empty($params['group_id'])) { + $group = civicrm_api3('Group', 'getvalue', array('return' => 'title', 'id' => $params['group_id'])); + return ts('Add contact to group %1', array(1 => $group)); + } + return ''; + } + +} \ No newline at end of file diff --git a/sql/createCiviruleRuleAction.sql b/sql/createCiviruleRuleAction.sql index 5b3ed7f..f869c12 100755 --- a/sql/createCiviruleRuleAction.sql +++ b/sql/createCiviruleRuleAction.sql @@ -2,7 +2,7 @@ CREATE TABLE IF NOT EXISTS civirule_rule_action ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, rule_id INT UNSIGNED NULL, action_id INT UNSIGNED NULL, - action_params BLOB NULL, + action_params TEXT NULL, is_active TINYINT NULL DEFAULT 1, UNIQUE INDEX id_UNIQUE (id ASC), INDEX fk_ra_rule_idx (rule_id ASC), diff --git a/sql/createCiviruleRuleCondition.sql b/sql/createCiviruleRuleCondition.sql index 4d5965b..2e546e5 100755 --- a/sql/createCiviruleRuleCondition.sql +++ b/sql/createCiviruleRuleCondition.sql @@ -3,7 +3,7 @@ CREATE TABLE IF NOT EXISTS civirule_rule_condition ( rule_id INT UNSIGNED NULL, condition_link VARCHAR(3) NULL, condition_id INT UNSIGNED NULL, - condition_params TEXT, + condition_params TEXT NULL, is_active TINYINT NULL DEFAULT 1, PRIMARY KEY (id), UNIQUE INDEX id_UNIQUE (id ASC), diff --git a/templates/CRM/Civirules/Form/RuleBlocks/ActionBlock.tpl b/templates/CRM/Civirules/Form/RuleBlocks/ActionBlock.tpl index 10b57d9..57cea17 100755 --- a/templates/CRM/Civirules/Form/RuleBlocks/ActionBlock.tpl +++ b/templates/CRM/Civirules/Form/RuleBlocks/ActionBlock.tpl @@ -19,8 +19,8 @@ <tr id="row_{$rowNumber}" class={$rowClass}> <td hidden="1" id="ruleActionId">{$ruleAction.id}</td> <td>{$ruleAction.label}</td> - {if !empty($ruleAction.action_params)} - <td>{$ruleAction.action_params}</td> + {if !empty($ruleAction.formattedConditionParams)} + <td>{$ruleAction.formattedConditionParams}</td> {else} <td> </td> {/if} diff --git a/templates/CRM/CivirulesActions/Form/GroupContact.tpl b/templates/CRM/CivirulesActions/Form/GroupContact.tpl new file mode 100644 index 0000000..80ad325 --- /dev/null +++ b/templates/CRM/CivirulesActions/Form/GroupContact.tpl @@ -0,0 +1,11 @@ +<h3>{$ruleActionHeader}</h3> +<div class="crm-block crm-form-block crm-civirule-rule_action-block-group-contact"> + <div class="crm-section"> + <div class="label">{$form.group_id.label}</div> + <div class="content">{$form.group_id.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 diff --git a/xml/Menu/civirules.xml b/xml/Menu/civirules.xml index 8815e6b..32cf78d 100755 --- a/xml/Menu/civirules.xml +++ b/xml/Menu/civirules.xml @@ -30,4 +30,10 @@ <title>Value comparison</title> <access_arguments>access CiviCRM</access_arguments> </item> + <item> + <path>civicrm/civirule/form/action/groupcontact</path> + <page_callback>CRM_CivirulesActions_Form_GroupContact</page_callback> + <title>Group contact</title> + <access_arguments>access CiviCRM</access_arguments> + </item> </menu> -- GitLab