From ee192bf0730a04c03393f02a7baaab15f36a356f Mon Sep 17 00:00:00 2001 From: Jaap Jansma <jaap@edeveloper.nl> Date: Tue, 28 Apr 2015 13:43:13 +0200 Subject: [PATCH] added delay to civirules actions --- CRM/Civirules/DAO/RuleAction.php | 5 + CRM/Civirules/Delay/Delay.php | 84 ++++++++++++ CRM/Civirules/Delay/Factory.php | 56 ++++++++ CRM/Civirules/Delay/XDays.php | 34 +++++ CRM/Civirules/Delay/XWeekDay.php | 110 ++++++++++++++++ CRM/Civirules/Delay/XWeekDayOfMonth.php | 97 ++++++++++++++ CRM/Civirules/Engine.php | 121 +++++++++++++++++- CRM/Civirules/Form/Rule.php | 6 + CRM/Civirules/Form/RuleAction.php | 31 ++++- CRM/Queue/Queue/Civirules.php | 21 +++ api/v3/CiviRuleAction/Process.mgd.php | 20 +++ api/v3/CiviRuleAction/Process.php | 19 +++ sql/createCiviruleRuleAction.sql | 1 + templates/CRM/Civirules/Delay/XDays.tpl | 3 + templates/CRM/Civirules/Delay/XWeekDay.tpl | 6 + .../CRM/Civirules/Delay/XWeekDayOfMonth.tpl | 6 + templates/CRM/Civirules/Form/RuleAction.tpl | 36 +++++- .../Civirules/Form/RuleBlocks/ActionBlock.tpl | 4 + xml/Menu/civirules.xml | 2 +- 19 files changed, 658 insertions(+), 4 deletions(-) create mode 100644 CRM/Civirules/Delay/Delay.php create mode 100644 CRM/Civirules/Delay/Factory.php create mode 100644 CRM/Civirules/Delay/XDays.php create mode 100644 CRM/Civirules/Delay/XWeekDay.php create mode 100644 CRM/Civirules/Delay/XWeekDayOfMonth.php create mode 100644 CRM/Queue/Queue/Civirules.php create mode 100644 api/v3/CiviRuleAction/Process.mgd.php create mode 100644 api/v3/CiviRuleAction/Process.php create mode 100644 templates/CRM/Civirules/Delay/XDays.tpl create mode 100644 templates/CRM/Civirules/Delay/XWeekDay.tpl create mode 100644 templates/CRM/Civirules/Delay/XWeekDayOfMonth.tpl diff --git a/CRM/Civirules/DAO/RuleAction.php b/CRM/Civirules/DAO/RuleAction.php index 5571ce7..cefa3db 100755 --- a/CRM/Civirules/DAO/RuleAction.php +++ b/CRM/Civirules/DAO/RuleAction.php @@ -46,6 +46,10 @@ class CRM_Civirules_DAO_RuleAction extends CRM_Core_DAO { 'name' => 'action_params', 'type' => CRM_Utils_Type::T_TEXT ), + 'delay' => array( + 'name' => 'delay', + 'type' => CRM_Utils_Type::T_TEXT + ), 'is_active' => array( 'name' => 'is_active', 'type' => CRM_Utils_Type::T_INT, @@ -68,6 +72,7 @@ class CRM_Civirules_DAO_RuleAction extends CRM_Core_DAO { 'rule_id' => 'rule_id', 'action_id' => 'action_id', 'action_params' => 'action_params', + 'delay' => 'delay', 'is_active' => 'is_active' ); } diff --git a/CRM/Civirules/Delay/Delay.php b/CRM/Civirules/Delay/Delay.php new file mode 100644 index 0000000..dcfbf58 --- /dev/null +++ b/CRM/Civirules/Delay/Delay.php @@ -0,0 +1,84 @@ +<?php + +abstract class CRM_Civirules_Delay_Delay { + + /** + * Returns the DateTime to which an action is delayed to + * + * @param DateTime $date + * @return DateTime + */ + abstract public function delayTo(DateTime $date); + + /** + * Add elements to the form + * + * @param \CRM_Core_Form $form + * @return mixed + */ + abstract public function addElements(CRM_Core_Form &$form); + + /** + * Validate the values and set error message in $errors + * + * @param array $values + * @param array $errors + * @return void + */ + abstract public function validate($values, &$errors); + + /** + * Set the values + * + * @param array $values + * @return void + */ + abstract public function setValues($values); + + /** + * Returns an description of the delay + * + * @return string + */ + abstract public function getDescription(); + + /** + * Returns an explanation of the delay + * + * @return string + */ + public function getDelayExplanation() { + return $this->getDescription(); + } + + /** + * Set default values + * + * @param $values + */ + public function setDefaultValues(&$values) { + + } + + /** + * Returns the name of the template + * + * @return string + */ + public function getTemplateFilename() { + return str_replace('_', + DIRECTORY_SEPARATOR, + CRM_Utils_System::getClassName($this) + ) . '.tpl'; + } + + /** + * Returns the name + * + * @return string + */ + public function getName() { + return get_class($this); + } + +} \ No newline at end of file diff --git a/CRM/Civirules/Delay/Factory.php b/CRM/Civirules/Delay/Factory.php new file mode 100644 index 0000000..d86df66 --- /dev/null +++ b/CRM/Civirules/Delay/Factory.php @@ -0,0 +1,56 @@ +<?php + +class CRM_Civirules_Delay_Factory { + + /** + * Get a list with all possible delay classes + * + * @return array + */ + public static function getAllDelayClasses() { + return array( + new CRM_Civirules_Delay_XDays(), + new CRM_Civirules_Delay_XWeekDay(), + new CRM_Civirules_Delay_XWeekDayOfMonth(), + ); + } + + /** + * Returns the delay class for a given name + * + * @param $name + * @return CRM_Civirules_Delay_Delay + * @throws Exception + */ + public static function getDelayClassByName($name) { + foreach(self::getAllDelayClasses() as $class) { + if ($class->getName() == $name) { + return $class; + } + } + + throw new Exception('Could not find delay class for '.$name); + } + + /** + * Returns an option list of possible delays. This list + * can be used in a select list + * + * Each element has a key which correspondents to the name of the class + * and the value to the description of the delay + * + * @return array + */ + public static function getOptionList() { + $classes = self::getAllDelayClasses(); + $options = array(); + foreach($classes as $class) { + if ($class instanceof CRM_Civirules_Delay_Delay) { + $options[$class->getName()] = $class->getDescription(); + } + } + asort($options); + return $options; + } + +} \ No newline at end of file diff --git a/CRM/Civirules/Delay/XDays.php b/CRM/Civirules/Delay/XDays.php new file mode 100644 index 0000000..7e5b446 --- /dev/null +++ b/CRM/Civirules/Delay/XDays.php @@ -0,0 +1,34 @@ +<?php + +class CRM_Civirules_Delay_XDays extends CRM_Civirules_Delay_Delay { + + protected $dayOffset; + + public function delayTo(DateTime $date) { + $date->modify("+ ".$this->dayOffset." days"); + return $date; + } + + public function getDescription() { + return ts('Delay by a number of days'); + } + + public function getDelayExplanation() { + return ts('Delay action by %1 days', array(1 => $this->dayOffset)); + } + + public function addElements(CRM_Core_Form &$form) { + $form->add('text', 'xdays_dayOffset', ts('Days')); + } + + public function validate($values, &$errors) { + if (empty($values['xdays_dayOffset']) || !is_numeric($values['xdays_dayOffset'])) { + $errors['xdays_dayOffset'] = ts('You need to provide a number of days'); + } + } + + public function setValues($values) { + $this->dayOffset = $values['xdays_dayOffset']; + } + +} \ No newline at end of file diff --git a/CRM/Civirules/Delay/XWeekDay.php b/CRM/Civirules/Delay/XWeekDay.php new file mode 100644 index 0000000..82ba3c6 --- /dev/null +++ b/CRM/Civirules/Delay/XWeekDay.php @@ -0,0 +1,110 @@ +<?php + +class CRM_Civirules_Delay_XWeekDay extends CRM_Civirules_Delay_Delay { + + protected $week_offset; + + protected $day; + + protected $time_hour = '9'; + + protected $time_minute = '00'; + + public function delayTo(DateTime $date) { + $d = clone $date; + $d->modify('-30 minutes'); + $mod = $this->day.' of this week'; + $date->modify($mod); + $date->setTime((int) $this->time_hour, (int) $this->time_minute); + if ($date <= $d) { + $date->modify('+1 week'); + $date->modify($mod); + } + $weeknr = $date->format("W"); + switch ($this->week_offset) { + case 'odd': + if(!($weeknr&1)) { + $date->modify('+1 week'); + $date->modify($mod); + } + break; + case 'even': + if($weeknr&1) { + $date->modify('+1 week'); + $date->modify($mod); + } + break; + } + + return $date; + } + + public function getDescription() { + return ts('Day of week'); + } + + public function getDelayExplanation() { + $offsets = $this->getWeekOffset(); + return ts('Delay action to %1 of %2 at %3:%4', + array( + 1 => ts($this->day), + 2 => $offsets[$this->week_offset], + 3 => $this->time_hour, + 4 => $this->time_minute < 10 && strlen($this->time_minute) <= 1 ? '0'.$this->time_minute : $this->time_minute, + )); + } + + public function addElements(CRM_Core_Form &$form) { + $form->add('select', 'XWeekDay_week_offset', ts('Offset'), $this->getWeekOffset()); + $form->add('select', 'XWeekDay_day', ts('Days'), $this->getDays()); + $form->add('text', 'XWeekDay_time_hour', ts('Time (hour)')); + $form->add('text', 'XWeekDay_time_minute', ts('Time (minute)')); + } + + protected function getDays() { + return array( + 'sunday' => ts('Sunday'), + 'monday' => ts('Monday'), + 'tuesday' => ts('Tuesday'), + 'wednesday' => ts('Wednesday'), + 'thursday' => ts('Thursday'), + 'friday' => ts('Friday'), + 'saturday' => ts('Saturday'), + ); + } + + protected function getWeekOffset() { + return array( + 'every' => ts('Every week'), + 'even' => ts('Even weeks'), + 'odd' => ts('Odd weeks'), + ); + } + + public function validate($values, &$errors) { + if (empty($values['XWeekDay_time_hour']) || !is_numeric($values['XWeekDay_time_hour']) || $values['XWeekDay_time_hour'] < 0 || $values['XWeekDay_time_hour'] > 23) { + $errors['XWeekDay_time_hour'] = ts('You need to provide a number between 0 and 23'); + } + if (empty($values['XWeekDay_time_minute']) || !is_numeric($values['XWeekDay_time_minute']) || $values['XWeekDay_time_minute'] < 0 || $values['XWeekDay_time_minute'] > 59) { + $errors['XWeekDay_time_minute'] = ts('You need to provide a number between 0 and 59'); + } + } + + public function setValues($values) { + $this->week_offset = $values['XWeekDay_week_offset']; + $this->day = $values['XWeekDay_day']; + $this->time_hour = $values['XWeekDay_time_hour']; + $this->time_minute = $values['XWeekDay_time_minute']; + } + + /** + * Set default values + * + * @param $values + */ + public function setDefaultValues(&$values) { + $values['XWeekDay_time_hour'] = '9'; + $values['XWeekDay_time_minute'] = '00'; + } + +} \ No newline at end of file diff --git a/CRM/Civirules/Delay/XWeekDayOfMonth.php b/CRM/Civirules/Delay/XWeekDayOfMonth.php new file mode 100644 index 0000000..024b624 --- /dev/null +++ b/CRM/Civirules/Delay/XWeekDayOfMonth.php @@ -0,0 +1,97 @@ +<?php + +class CRM_Civirules_Delay_XWeekDayOfMonth extends CRM_Civirules_Delay_Delay { + + protected $week_offset; + + protected $day; + + protected $time_hour = '9'; + + protected $time_minute = '00'; + + public function delayTo(DateTime $date) { + $d = clone $date; + $d->modify('-30 minutes'); + $mod = $this->week_offset .' '.$this->day.' of this month'; + $date->modify($mod); + $date->setTime((int) $this->time_hour, (int) $this->time_minute); + if ($date <= $d) { + $date->modify('first day of next month'); + $date->modify($mod); + } + + return $date; + } + + public function getDescription() { + return ts('Nth weekday of month'); + } + + public function getDelayExplanation() { + return ts('Delay action to %1 %2 at %3:%4', + array( + 1 => ts($this->week_offset), + 2 => ts($this->day), + 3 => $this->time_hour, + 4 => $this->time_minute < 10 && strlen($this->time_minute) <= 1 ? '0'.$this->time_minute : $this->time_minute, + )); + } + + public function addElements(CRM_Core_Form &$form) { + $form->add('select', 'XWeekDayOfMonth_week_offset', ts('Offset'), $this->getWeekOffset()); + $form->add('select', 'XWeekDayOfMonth_day', ts('Days'), $this->getDays()); + $form->add('text', 'XWeekDayOfMonth_time_hour', ts('Time (hour)')); + $form->add('text', 'XWeekDayOfMonth_time_minute', ts('Time (minute)')); + } + + protected function getDays() { + return array( + 'sunday' => ts('Sunday'), + 'monday' => ts('Monday'), + 'tuesday' => ts('Tuesday'), + 'wednesday' => ts('Wednesday'), + 'thursday' => ts('Thursday'), + 'friday' => ts('Friday'), + 'saturday' => ts('Saturday'), + ); + } + + protected function getWeekOffset() { + return array( + 'first' => ts('First'), + 'second' => ts('Second'), + 'third' => ts('Third'), + 'fourth' => ts('Fourth'), + 'fifth' => ts('Fifth'), + 'last' => ts('Last'), + ); + } + + public function validate($values, &$errors) { + if (empty($values['XWeekDayOfMonth_time_hour']) || !is_numeric($values['XWeekDayOfMonth_time_hour']) || $values['XWeekDayOfMonth_time_hour'] < 0 || $values['XWeekDayOfMonth_time_hour'] > 23) { + $errors['XWeekDayOfMonth_time_hour'] = ts('You need to provide a number between 0 and 23'); + } + if (empty($values['XWeekDayOfMonth_time_minute']) || !is_numeric($values['XWeekDayOfMonth_time_minute']) || $values['XWeekDayOfMonth_time_minute'] < 0 || $values['XWeekDayOfMonth_time_minute'] > 59) { + $errors['XWeekDayOfMonth_time_minute'] = ts('You need to provide a number between 0 and 59'); + } + } + + public function setValues($values) { + $this->week_offset = $values['XWeekDayOfMonth_week_offset']; + $this->day = $values['XWeekDayOfMonth_day']; + $this->time_hour = $values['XWeekDayOfMonth_time_hour']; + $this->time_minute = $values['XWeekDayOfMonth_time_minute']; + } + + /** + * Set default values + * + * @param $values + */ + public function setDefaultValues(&$values) { + $values['XWeekDayOfMonth_time_hour'] = '9'; + $values['XWeekDayOfMonth_time_minute'] = '00'; + } + +} \ No newline at end of file diff --git a/CRM/Civirules/Engine.php b/CRM/Civirules/Engine.php index 6f58330..828a851 100644 --- a/CRM/Civirules/Engine.php +++ b/CRM/Civirules/Engine.php @@ -8,6 +8,8 @@ class CRM_Civirules_Engine { + const QUEUE_NAME = 'org.civicoop.civirules.action'; + /** * Trigger a rule. * @@ -60,7 +62,124 @@ class CRM_Civirules_Engine { } $object->setRuleActionData($ruleAction); - $object->processAction($eventData); + + //determine if the action should be executed with a delay + $delay = self::getActionDelay($ruleAction); + if ($delay instanceof DateTime) { + self::delayAction($delay, $object, $eventData); + } else { + //there is no delay so process action immediatly + $object->processAction($eventData); + } + } + + /** + * Process delayed actions + * + * @param int $maxRunTime + * @return array + */ + public static function processDelayedActions($maxRunTime=30) { + $queue = CRM_Queue_Service::singleton()->create(array( + 'type' => 'Civirules', + 'name' => self::QUEUE_NAME, + 'reset' => false, //do not flush queue upon creation + )); + + $returnValues = array(); + + //retrieve the queue + $runner = new CRM_Queue_Runner(array( + 'title' => ts('Process delayed civirules actions'), //title fo the queue + 'queue' => $queue, //the queue object + 'errorMode'=> CRM_Queue_Runner::ERROR_CONTINUE, //continue on error otherwise the queue will hang + )); + + $stopTime = time() + $maxRunTime; //stop executing next item after 30 seconds + while((time() < $stopTime)) { + $result = $runner->runNext(false); + $returnValues[] = $result; + + if (!$result['is_continue']) { + break; + } + } + + return $returnValues; + } + + /** + * Executes a delayed action + * + * @param \CRM_Queue_TaskContext $ctx + * @param \CRM_Civirules_Action $action + * @param \CRM_Civirules_EventData_EventData $eventData + * @return bool + */ + public static function executeDelayedAction(CRM_Queue_TaskContext $ctx, CRM_Civirules_Action $action, CRM_Civirules_EventData_EventData $eventData) { + $action->processAction($eventData); + return true; + } + + /** + * Save an action into a queue for delayed processing + * + * @param \DateTime $delayTo + * @param \CRM_Civirules_Action $action + * @param \CRM_Civirules_EventData_EventData $eventData + */ + protected static function delayAction(DateTime $delayTo, CRM_Civirules_Action $action, CRM_Civirules_EventData_EventData $eventData) { + $queue = CRM_Queue_Service::singleton()->create(array( + 'type' => 'Civirules', + 'name' => self::QUEUE_NAME, + 'reset' => false, //do not flush queue upon creation + )); + + //create a task with the action and eventData as parameters + $task = new CRM_Queue_Task( + array('CRM_Civirules_Engine', 'executeDelayedAction'), //call back method + array($action, $eventData) //parameters + ); + + //save the task with a delay + $dao = new CRM_Queue_DAO_QueueItem(); + $dao->queue_name = $queue->getName(); + $dao->submit_time = CRM_Utils_Time::getTime('YmdHis'); + $dao->data = serialize($task); + $dao->weight = 0; //weight, normal priority + $dao->release_time = $delayTo->format('YmdHis'); + $dao->save(); + } + + /** + * Returns false when action could not be delayed or return a DateTime + * This DateTime object holds the date and time till when the action should be delayed + * + * The delay is calculated by a seperate delay class. See CRM_Civirules_DelayDelay + * + * @param $ruleAction + * @return bool|\DateTime + */ + protected static function getActionDelay($ruleAction) { + //if the delay is empty the + if (empty($ruleAction['delay'])) { + return false; + } + + $delayClass = unserialize(($ruleAction['delay'])); + if (! ($delayClass instanceof CRM_Civirules_Delay_Delay)) { + return false; + } + + $delayedTo = new DateTime(); + $now = new DateTime(); + $delayedTo = $delayClass->delayTo($delayedTo); + + if ($now >= $delayedTo) { + return false; + } + + return $delayedTo; } /** diff --git a/CRM/Civirules/Form/Rule.php b/CRM/Civirules/Form/Rule.php index 38b251e..6ea4012 100755 --- a/CRM/Civirules/Form/Rule.php +++ b/CRM/Civirules/Form/Rule.php @@ -277,6 +277,12 @@ class CRM_Civirules_Form_Rule extends CRM_Core_Form { $actionClass = CRM_Civirules_BAO_Action::getActionObjectById($ruleAction['action_id']); $actionClass->setRuleActionData($ruleAction); $ruleActions[$ruleActionId]['formattedConditionParams'] = $actionClass->userFriendlyConditionParams(); + + $ruleActions[$ruleActionId]['formattedDelay'] = ''; + if (!empty($ruleAction['delay'])) { + $delayClass = unserialize($ruleAction['delay']); + $ruleActions[$ruleActionId]['formattedDelay'] = $delayClass->getDelayExplanation(); + } } return $ruleActions; } diff --git a/CRM/Civirules/Form/RuleAction.php b/CRM/Civirules/Form/RuleAction.php index e6ab9fc..fef324c 100644 --- a/CRM/Civirules/Form/RuleAction.php +++ b/CRM/Civirules/Form/RuleAction.php @@ -50,8 +50,16 @@ class CRM_Civirules_Form_RuleAction extends CRM_Core_Form { $saveParams = array( 'rule_id' => $this->_submitValues['rule_id'], - 'action_id' => $this->_submitValues['rule_action_select'] + 'action_id' => $this->_submitValues['rule_action_select'], + 'delay' => 'null', ); + + if (!empty($this->_submitValues['delay_select'])) { + $delayClass = CRM_Civirules_Delay_Factory::getDelayClassByName($this->_submitValues['delay_select']); + $delayClass->setValues($this->_submitValues); + $saveParams['delay'] = serialize($delayClass); + } + $ruleAction = CRM_Civirules_BAO_RuleAction::add($saveParams); $session = CRM_Core_Session::singleton(); @@ -78,6 +86,13 @@ class CRM_Civirules_Form_RuleAction extends CRM_Core_Form { asort($actionList); $this->add('select', 'rule_action_select', ts('Select Action'), $actionList); + $delayList = array(' - No Delay - ') + CRM_Civirules_Delay_Factory::getOptionList(); + $this->add('select', 'delay_select', ts('Delay action to'), $delayList); + foreach(CRM_Civirules_Delay_Factory::getAllDelayClasses() as $delay_class) { + $delay_class->addElements($this); + } + $this->assign('delayClasses', CRM_Civirules_Delay_Factory::getAllDelayClasses()); + $this->addButtons(array( array('type' => 'next', 'name' => ts('Save'), 'isDefault' => TRUE,), array('type' => 'cancel', 'name' => ts('Cancel')))); @@ -85,6 +100,11 @@ class CRM_Civirules_Form_RuleAction extends CRM_Core_Form { public function setDefaultValues() { $defaults['rule_id'] = $this->ruleId; + + foreach(CRM_Civirules_Delay_Factory::getAllDelayClasses() as $delay_class) { + $delay_class->setDefaultValues($defaults); + } + return $defaults; } @@ -117,10 +137,19 @@ class CRM_Civirules_Form_RuleAction extends CRM_Core_Form { * @static */ static function validateRuleAction($fields) { + $errors = array(); if (isset($fields['rule_action_select']) && empty($fields['rule_action_select'])) { $errors['rule_action_select'] = ts('Action has to be selected, press CANCEL if you do not want to add an action'); + } + if (!empty($fields['delay_select'])) { + $delayClass = CRM_Civirules_Delay_Factory::getDelayClassByName($fields['delay_select']); + $delayClass->validate($fields, $errors); + } + + if (count($errors)) { return $errors; } + return TRUE; } } diff --git a/CRM/Queue/Queue/Civirules.php b/CRM/Queue/Queue/Civirules.php new file mode 100644 index 0000000..8f2f0a4 --- /dev/null +++ b/CRM/Queue/Queue/Civirules.php @@ -0,0 +1,21 @@ +<?php + +class CRM_Queue_Queue_Civirules extends CRM_Queue_Queue_Sql { + + /** + * Determine number of items remaining in the queue + * + * @return int + */ + function numberOfItems() { + return CRM_Core_DAO::singleValueQuery(" + SELECT count(*) + FROM civicrm_queue_item + WHERE queue_name = %1 + and (release_time is null OR release_time <= curdate()) + ", array( + 1 => array($this->getName(), 'String'), + )); + } + +} \ No newline at end of file diff --git a/api/v3/CiviRuleAction/Process.mgd.php b/api/v3/CiviRuleAction/Process.mgd.php new file mode 100644 index 0000000..8504e47 --- /dev/null +++ b/api/v3/CiviRuleAction/Process.mgd.php @@ -0,0 +1,20 @@ +<?php + +return array ( + 0 => + array ( + 'name' => 'Cron:CiviRuleAction.Process', + 'entity' => 'Job', + 'params' => + array ( + 'version' => 3, + 'name' => 'Process delayed civirule actions', + 'description' => '', + 'run_frequency' => 'Always', + 'api_entity' => 'CiviRuleAction', + 'api_action' => 'Process', + 'parameters' => '', + 'is_active' => '1', + ), + ), +); \ No newline at end of file diff --git a/api/v3/CiviRuleAction/Process.php b/api/v3/CiviRuleAction/Process.php new file mode 100644 index 0000000..7ab8302 --- /dev/null +++ b/api/v3/CiviRuleAction/Process.php @@ -0,0 +1,19 @@ +<?php + +/** + * CiviRuleAction.process API + * + * Process delayed actions + * + * @param array $params + * @return array API result descriptor + * @see civicrm_api3_create_success + * @see civicrm_api3_create_error + * @throws API_Exception + */ +function civicrm_api3_civi_rule_action_process($params) { + $returnValues = CRM_Civirules_Engine::processDelayedActions(60); + + // Spec: civicrm_api3_create_success($values = 1, $params = array(), $entity = NULL, $action = NULL) + return civicrm_api3_create_success($returnValues, $params, 'CiviRuleAction', 'Process'); +} \ No newline at end of file diff --git a/sql/createCiviruleRuleAction.sql b/sql/createCiviruleRuleAction.sql index 85965c0..de8d397 100755 --- a/sql/createCiviruleRuleAction.sql +++ b/sql/createCiviruleRuleAction.sql @@ -3,6 +3,7 @@ CREATE TABLE IF NOT EXISTS civirule_rule_action ( rule_id INT UNSIGNED NULL, action_id INT UNSIGNED NULL, action_params TEXT NULL, + delay TEXT NULL, is_active TINYINT NULL DEFAULT 1, PRIMARY KEY (id), UNIQUE INDEX id_UNIQUE (id ASC), diff --git a/templates/CRM/Civirules/Delay/XDays.tpl b/templates/CRM/Civirules/Delay/XDays.tpl new file mode 100644 index 0000000..d50180d --- /dev/null +++ b/templates/CRM/Civirules/Delay/XDays.tpl @@ -0,0 +1,3 @@ +<div class="label">{$form.xdays_dayOffset.label}</div> +<div class="content">{$form.xdays_dayOffset.html}</div> +<div class="clear"></div> \ No newline at end of file diff --git a/templates/CRM/Civirules/Delay/XWeekDay.tpl b/templates/CRM/Civirules/Delay/XWeekDay.tpl new file mode 100644 index 0000000..3101eec --- /dev/null +++ b/templates/CRM/Civirules/Delay/XWeekDay.tpl @@ -0,0 +1,6 @@ +<div class="label"></div> +<div class="content">{$form.XWeekDay_week_offset.html} {ts}on{/ts} {$form.XWeekDay_day.html} </div> +<div class="clear"></div> +<div class="label">{ts}After{/ts}</div> +<div class="content">{$form.XWeekDay_time_hour.html} : {$form.XWeekDay_time_minute.html}</div> +<div class="clear"></div> \ No newline at end of file diff --git a/templates/CRM/Civirules/Delay/XWeekDayOfMonth.tpl b/templates/CRM/Civirules/Delay/XWeekDayOfMonth.tpl new file mode 100644 index 0000000..e507f50 --- /dev/null +++ b/templates/CRM/Civirules/Delay/XWeekDayOfMonth.tpl @@ -0,0 +1,6 @@ +<div class="label"></div> +<div class="content">{$form.XWeekDayOfMonth_week_offset.html} {$form.XWeekDayOfMonth_day.html}</div> +<div class="clear"></div> +<div class="label">{ts}After{/ts}</div> +<div class="content">{$form.XWeekDayOfMonth_time_hour.html} : {$form.XWeekDayOfMonth_time_minute.html}</div> +<div class="clear"></div> \ No newline at end of file diff --git a/templates/CRM/Civirules/Form/RuleAction.tpl b/templates/CRM/Civirules/Form/RuleAction.tpl index 829a83a..720abcc 100644 --- a/templates/CRM/Civirules/Form/RuleAction.tpl +++ b/templates/CRM/Civirules/Form/RuleAction.tpl @@ -1,12 +1,46 @@ {* block for rule condition data *} <h3>{$ruleActionHeader}</h3> -<div class="crm-block crm-form-block crm-civirule-rule_condition-block"> +<div class="crm-block crm-form-block crm-civirule-rule_action-block"> <div class="crm-section"> <div class="label">{$form.rule_action_select.label}</div> <div class="content">{$form.rule_action_select.html}</div> <div class="clear"></div> </div> </div> +<h3>{ts}Delay action{/ts}</h3> +<div class="crm-block crm-form-block crm-civirule-rule_action_delay-block"> + <div class="crm-section"> + <div class="label">{$form.delay_select.label}</div> + <div class="content">{$form.delay_select.html}</div> + <div class="clear"></div> + </div> + {foreach from=$delayClasses item=delayClass} + <div class="crm-section crm-delay-class" id="{$delayClass->getName()}"> + <div class="label"></div> + <div class="content"><strong>{$delayClass->getDescription()}</strong></div> + <div class="clear"></div> + {include file=$delayClass->getTemplateFilename()} + </div> + {/foreach} +</div> <div class="crm-submit-buttons"> {include file="CRM/common/formButtons.tpl" location="bottom"} </div> + +{literal} +<script type="text/javascript"> +cj(function() { + cj('select#delay_select').change(triggerDelayChange); + + triggerDelayChange(); +}); + +function triggerDelayChange() { + cj('.crm-delay-class').css('display', 'none'); + var val = cj('#delay_select').val(); + if (val) { + cj('#'+val).css('display', 'block'); + } +} +</script> +{/literal} diff --git a/templates/CRM/Civirules/Form/RuleBlocks/ActionBlock.tpl b/templates/CRM/Civirules/Form/RuleBlocks/ActionBlock.tpl index 57cea17..b5ccd9b 100755 --- a/templates/CRM/Civirules/Form/RuleBlocks/ActionBlock.tpl +++ b/templates/CRM/Civirules/Form/RuleBlocks/ActionBlock.tpl @@ -9,6 +9,7 @@ <tr> <th>{ts}Name{/ts}</th> <th>{ts}Extra parameters{/ts}</th> + <th class="nosort"> </th> <th id="nosort"> </th> </tr> </thead> @@ -24,6 +25,9 @@ {else} <td> </td> {/if} + <td> + {$ruleAction.formattedDelay} + </td> <td> <span> {foreach from=$ruleAction.actions item=actionLink} diff --git a/xml/Menu/civirules.xml b/xml/Menu/civirules.xml index 74601b0..d7941b9 100755 --- a/xml/Menu/civirules.xml +++ b/xml/Menu/civirules.xml @@ -44,7 +44,7 @@ </item> <item> <path>civicrm/civirule/form/condition/contributionstatus</path> - <page_callback>CRM_CivirulesConditions_Form_ContributionStatus</page_callback> + <page_callback>CRM_CivirulesConditions_Form_Contribution_Status</page_callback> <title>contribution status</title> <access_arguments>access CiviCRM</access_arguments> </item> -- GitLab