Skip to content
Snippets Groups Projects
Commit 4dbe5217 authored by Erik Hommel's avatar Erik Hommel
Browse files
parents 6c2ce314 35e282d5
No related branches found
No related tags found
No related merge requests found
Showing
with 410 additions and 61 deletions
<?php
abstract class CRM_Civirules_Action_Action {
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
......@@ -17,20 +32,19 @@ abstract class CRM_Civirules_Action_Action {
/**
* 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);
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->executeAction($entity, $action, $params);
$this->executeApiAction($entity, $action, $params);
}
/**
......@@ -42,18 +56,43 @@ abstract class CRM_Civirules_Action_Action {
* @param $action
* @param $parameters
*/
protected function executeAction($entity, $action, $parameters) {
protected function executeApiAction($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);
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 '';
}
......
......@@ -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;
}
}
......@@ -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
......@@ -39,6 +39,15 @@ abstract class CRM_Civirules_Condition {
return '';
}
/**
* Returns an array with required entity names
*
* @return array
*/
public function requiredEntities() {
return array();
}
}
\ No newline at end of file
......@@ -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',
......
......@@ -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) {
......
......@@ -25,21 +25,32 @@ class CRM_Civirules_Event_EditEntity {
}
public static function post( $op, $objectName, $objectId, &$objectRef ) {
if ($op != 'edit') {
if ($op != 'edit' && $op != 'create' && $op != 'delete' && $op != 'trash' && $op != 'restore') {
return;
}
$entity = self::convertObjectNameToEntity($objectName);
//set data
$data = array();
CRM_Core_DAO::storeValues($objectRef, $data);
if (is_object($objectRef)) {
CRM_Core_DAO::storeValues($objectRef, $data);
} elseif (is_array($objectRef)) {
$data = $objectRef;
}
$entity = self::convertObjectNameToEntity($objectName);
$oldData = self::getPreData($entity, $objectId);
if ($op == 'edit') {
//set also original data with an edit event
$oldData = self::getPreData($entity, $objectId);
$eventData = new CRM_Civirules_EventData_Edit($entity, $objectId, $data, $oldData);
} else {
$eventData = new CRM_Civirules_EventData_Post($entity, $objectId, $data);
}
$rules = CRM_Civirules_BAO_Rule::findRulesByObjectnameAndAction($objectName, $op);
//find matching rules for this objectName and op
$rules = CRM_Civirules_BAO_Rule::findRulesByObjectNameAndOp($objectName, $op);
foreach($rules as $rule) {
$eventData = new CRM_Civirules_EventData_Edit($entity, $objectId, $data, $oldData);
CRM_Civirules_Engine::triggerRule($eventData, $rule['rule_id'], $rule['event_id']);
CRM_Civirules_Engine::triggerRule(clone $eventData, $rule['rule_id'], $rule['event_id']);
}
}
......@@ -54,7 +65,7 @@ class CRM_Civirules_Event_EditEntity {
return array();
}
protected static function convertObjectNameToEntity($objectName) {
public static function convertObjectNameToEntity($objectName) {
$entity = $objectName;
switch($objectName) {
case 'Individual':
......
......@@ -165,7 +165,7 @@ class CRM_Civirules_Form_Rule extends CRM_Core_Form {
$this->add('checkbox', 'rule_is_active', ts('Enabled'));
$this->add('text', 'rule_created_date', ts('Created Date'));
$this->add('text', 'rule_created_contact', ts('Created By'));
$eventList = array_merge(array(' - select - '), CRM_Civirules_Utils::buildEventList());
$eventList = array(' - select - ') + CRM_Civirules_Utils::buildEventList();
asort($eventList);
$this->add('select', 'rule_event_select', ts('Select Event'), $eventList);
if ($this->_action == CRM_Core_Action::UPDATE) {
......@@ -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;
}
......@@ -343,7 +347,10 @@ class CRM_Civirules_Form_Rule extends CRM_Core_Form {
'id' => $this->ruleId,
'event_id' => $formValues['rule_event_select']
);
CRM_Civirules_BAO_Rule::add($ruleParams);
var_dump($this->_submitValues);
var_dump($ruleParams);
$result = CRM_Civirules_BAO_Rule::add($ruleParams);
var_dump($result); exit();
}
}
}
......@@ -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);
}
......@@ -66,7 +74,7 @@ class CRM_Civirules_Form_RuleAction extends CRM_Core_Form {
*/
protected function createFormElements() {
$this->add('hidden', 'rule_id');
$actionList = array_merge(array(' - select - '), CRM_Civirules_Utils::buildActionList());
$actionList = array(' - select - ') + CRM_Civirules_Utils::buildActionList();
asort($actionList);
$this->add('select', 'rule_action_select', ts('Select Action'), $actionList);
......
......@@ -81,7 +81,7 @@ class CRM_Civirules_Form_RuleCondition extends CRM_Core_Form {
*/
$linkList = array('AND' => 'AND', 'OR' =>'OR');
$this->add('select', 'rule_condition_link_select', ts('Select Link Operator'), $linkList);
$conditionList = array_merge(array(' - select - '), CRM_Civirules_Utils::buildConditionList());
$conditionList = array(' - select - ') + CRM_Civirules_Utils::buildConditionList();
asort($conditionList);
$this->add('select', 'rule_condition_select', ts('Select Condition'), $conditionList);
......@@ -113,6 +113,39 @@ class CRM_Civirules_Form_RuleCondition extends CRM_Core_Form {
*/
public function addRules() {
$this->addFormRule(array('CRM_Civirules_Form_RuleCondition', 'validateRuleCondition'));
$this->addFormRule(array('CRM_Civirules_Form_RuleCondition', 'validateConditionEntities'));
}
/**
* @param $fields
*/
static function validateConditionEntities($fields) {
$conditionClass = CRM_Civirules_BAO_Condition::getConditionObjectById($fields['rule_condition_select'], false);
if (!$conditionClass) {
$errors['rule_condition_select'] = ts('Not a valid condition, condition class is missing');
return $errors;
}
$requiredEntities = $conditionClass->requiredEntities();
$rule = new CRM_Civirules_BAO_Rule();
$rule->id = $fields['rule_id'];
$rule->find(true);
$event = new CRM_Civirules_BAO_Event();
$event->id = $rule->event_id;
$event->find(true);
$eventEntities = array('contact');
$eventEntities[] = $event->object_name;
if (CRM_Civirules_Event_EditEntity::convertObjectNameToEntity($event->object_name) != $event->object_name) {
$eventEntities[] = CRM_Civirules_Event_EditEntity::convertObjectNameToEntity($event->object_name);
}
foreach($requiredEntities as $entity) {
if (!in_array(strtolower($entity), $eventEntities)) {
$errors['rule_condition_select'] = ts('This condition is not available with event %1', array(1 => $event->label));
return $errors;
}
}
return true;
}
/**
......
<?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
<?php
class CRM_Civirules_Action_GroupContact extends CRM_Civirules_Action_Action {
class CRM_CivirulesActions_GroupContact extends CRM_Civirules_Action {
/**
* Returns an array with parameters used for processing an action
......@@ -15,4 +15,31 @@ class CRM_Civirules_Action_GroupContact extends CRM_Civirules_Action_Action {
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
......@@ -50,4 +50,13 @@ class CRM_CivirulesConditions_AgeComparison extends CRM_CivirulesConditions_Gene
return ts($label, array(1 => $this->getComparisonValue()));
}
/**
* Returns an array with required entity names
*
* @return array
*/
public function requiredEntities() {
return array('contact');
}
}
\ No newline at end of file
......@@ -87,4 +87,13 @@ abstract class CRM_CivirulesConditions_Generic_FieldChanged extends CRM_Civirule
}
return null;
}
/**
* Returns an array with required entity names
*
* @return array
*/
public function requiredEntities() {
return array($this->getEntity());
}
}
\ No newline at end of file
......@@ -19,6 +19,7 @@ class CRM_CivirulesConditions_PrimaryEmailChanged extends CRM_CivirulesCondition
return 'email';
}
public function isConditionValid(CRM_Civirules_EventData_EventData $eventData) {
$isValid = parent::isConditionValid($eventData);
if ($isValid) {
......
......@@ -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),
......
......@@ -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),
......
......@@ -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>&nbsp;</td>
{/if}
......
<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
......@@ -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>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment