diff --git a/CRM/Civirules/Delay/XWeekDay.php b/CRM/Civirules/Delay/XWeekDay.php index 5f7ea10125a6c9d60b9779ed1e7adfa073245e39..643e374526cc57ffe8cbfb7914ba1565a53f0e28 100644 --- a/CRM/Civirules/Delay/XWeekDay.php +++ b/CRM/Civirules/Delay/XWeekDay.php @@ -13,7 +13,7 @@ class CRM_Civirules_Delay_XWeekDay extends CRM_Civirules_Delay_Delay { public function delayTo(DateTime $date) { $d = clone $date; $d->modify('-30 minutes'); - $mod = $this->day.' of this week'; + $mod = $this->day.' this week'; $date->modify($mod); $date->setTime((int) $this->time_hour, (int) $this->time_minute); if ($date <= $d) { diff --git a/CRM/Civirules/Utils/PreData.php b/CRM/Civirules/Utils/PreData.php index 61cad9273ac4f0d60e3f5d8e2c197ba322645d6a..1a78a1ed75e0f7f950fd9e4cc488ec1af67943f0 100644 --- a/CRM/Civirules/Utils/PreData.php +++ b/CRM/Civirules/Utils/PreData.php @@ -22,7 +22,8 @@ class CRM_Civirules_Utils_PreData { * */ public static function pre($op, $objectName, $objectId, $params) { - if ($op != 'edit') { + $nonPreEntities = array('GroupContact', 'EntityTag'); + if ($op != 'edit' || in_array($objectName, $nonPreEntities)) { return; } diff --git a/CRM/CivirulesActions/Contribution/Form/ThankYouDate.php b/CRM/CivirulesActions/Contribution/Form/ThankYouDate.php new file mode 100644 index 0000000000000000000000000000000000000000..5483b3fc2c1551ebbfedc997575e0a1f1c1f9201 --- /dev/null +++ b/CRM/CivirulesActions/Contribution/Form/ThankYouDate.php @@ -0,0 +1,76 @@ +<?php +/** + * Class for CiviRules Contribution Thank You Date Form + * + * @author Erik Hommel (CiviCooP) <erik.hommel@civicoop.org> + * @license AGPL-3.0 + */ + +class CRM_CivirulesActions_Contribution_Form_ThankYouDate extends CRM_CivirulesActions_Form_Form { + + /** + * Overridden parent method to build the form + * + * @access public + */ + public function buildQuickForm() { + $this->add('hidden', 'rule_action_id'); + $radioOptions = array('Date of Action Execution', 'xxx days after Action Execution', 'Specific Date'); + $this->addRadio('thank_you_radio', ts('Thank You Date will be set to : '), $radioOptions); + $this->add('text', 'number_of_days', ts('Number of Days after Action Execution')); + $this->addDate('thank_you_date', ts('Thank You Date'), FALSE, array('formatType' => 'custom')); + $this->addButtons(array( + array('type' => 'next', 'name' => ts('Save'), 'isDefault' => TRUE,), + array('type' => 'cancel', 'name' => ts('Cancel')))); + } + + /** + * Overridden parent method to set default values + * + * @return array $defaultValues + * @access public + */ + public function setDefaultValues() { + $defaultValues = parent::setDefaultValues(); + $defaultValues['rule_action_id'] = $this->ruleActionId; + if (!empty($this->ruleAction->action_params)) { + $data = unserialize($this->ruleAction->action_params); + } + if (!empty($data['number_of_days'])) { + $defaultValues['number_of_days'] = $data['number_of_days']; + } + if (empty($data['thank_you_radio'])) { + $defaultValues['thank_you_radio'] = 0; + } else { + $defaultValues['thank_you_radio'] = $data['thank_you_radio']; + } + if (empty($data['thank_you_date'])) { + list($defaultValues['thank_you_date']) = CRM_Utils_Date::setDateDefaults(date('Y-m-d')); + } else { + list($defaultValues['thank_you_date']) = CRM_Utils_Date::setDateDefaults($data['thank_you_date']); + } + return $defaultValues; + } + + /** + * Overridden parent method to process form data after submitting + * + * @access public + */ + public function postProcess() { + $data['thank_you_radio'] = $this->_submitValues['thank_you_radio']; + if ($this->_submitValues['thank_you_radio'] == 2) { + $data['thank_you_date'] = $this->_submitValues['thank_you_date']; + } else { + $data['thank_you_date'] = null; + } + if ($this->_submitValues['thank_you_radio'] == 1) { + $data['number_of_days'] = $this->_submitValues['number_of_days']; + } else { + $data['number_of_days'] = 0; + } + $this->ruleAction->action_params = serialize($data); + $this->ruleAction->save(); + parent::postProcess(); + } +} \ No newline at end of file diff --git a/CRM/CivirulesActions/Contribution/ThankYouDate.mgd.php b/CRM/CivirulesActions/Contribution/ThankYouDate.mgd.php new file mode 100644 index 0000000000000000000000000000000000000000..87549c445654907358c3ad276a2250ac0d6a25a6 --- /dev/null +++ b/CRM/CivirulesActions/Contribution/ThankYouDate.mgd.php @@ -0,0 +1,17 @@ +<?php + +return array ( + 0 => + array ( + 'name' => 'Civirules:Action.ThankYouDate', + 'entity' => 'CiviRuleAction', + 'params' => + array ( + 'version' => 3, + 'name' => 'ThankYouDate', + 'label' => 'Set Thank You Date for Contribution', + 'class_name' => 'CRM_CivirulesActions_Contribution_ThankYouDate', + 'is_active' => 1 + ), + ), +); \ No newline at end of file diff --git a/CRM/CivirulesActions/Contribution/ThankYouDate.php b/CRM/CivirulesActions/Contribution/ThankYouDate.php new file mode 100644 index 0000000000000000000000000000000000000000..516cb3ebd7f8520a43baff9b6a6dd382d6875d8c --- /dev/null +++ b/CRM/CivirulesActions/Contribution/ThankYouDate.php @@ -0,0 +1,84 @@ +<?php +/** + * Class for CiviRules Set Thank You Date for Contribution Action + * + * @author Erik Hommel (CiviCooP) <erik.hommel@civicoop.org> + * @license AGPL-3.0 + */ +class CRM_CivirulesActions_Contribution_ThankYouDate extends CRM_Civirules_Action { + /** + * Method processAction to execute the action + * + * @param CRM_Civirules_EventData_EventData $eventData + * @access public + * + */ + public function processAction(CRM_Civirules_EventData_EventData $eventData) { + $contribution = $eventData->getEntityData('Contribution'); + $actionParams = $this->getActionParameters(); + switch ($actionParams['thank_you_radio']) { + case 1: + if (!empty($actionParams['number_of_days'])) { + $thankYouDate = new DateTime(); + $thankYouDate->modify('+'.$actionParams['number_of_days']. ' day'); + } + break; + case 2: + $thankYouDate = new DateTime($actionParams['thank_you_date']); + break; + default: + $thankYouDate = new DateTime(); + break; + } + $params = array( + 'id' => $contribution['id'], + 'thankyou_date' => $thankYouDate->format('Ymd') + ); + try { + civicrm_api3('Contribution', 'Create', $params); + } catch (CiviCRM_API3_Exception $ex) {} + } + + /** + * 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 + * @access public + */ + public function getExtraDataInputUrl($ruleActionId) { + return CRM_Utils_System::url('civicrm/civirule/form/action/contribution/thankyoudate', 'rule_action_id='.$ruleActionId); + } + + /** + * Returns a user friendly text explaining the condition params + * e.g. 'Older than 65' + * + * @return string + * @access public + */ + public function userFriendlyConditionParams() { + $return = ""; + $dateString = ""; + $params = $this->getActionParameters(); + if (isset($params['thank_you_radio'])) { + switch ($params['thank_you_radio']) { + case 0: + $dateString = "date action executes"; + break; + case 1: + $dateString = $params['number_of_days']." days after action executes"; + break; + case 2: + $dateString = date('d M Y', strtotime($params['thank_you_date'])); + break; + } + } + if (!empty($dateString)) { + $return = 'Thank You Date for Contribution will be set to : ' . $dateString; + } + return $return; + } +} \ No newline at end of file diff --git a/CRM/CivirulesActions/GroupContact/Remove.php b/CRM/CivirulesActions/GroupContact/Remove.php index d0551bafa05319101bbedf2d8bcd96e4719d1124..e6a303db7d5e33c177ec8344ed9e62e3ee427030 100644 --- a/CRM/CivirulesActions/GroupContact/Remove.php +++ b/CRM/CivirulesActions/GroupContact/Remove.php @@ -21,4 +21,35 @@ class CRM_CivirulesActions_GroupContact_Remove extends CRM_CivirulesActions_Grou return 'delete'; } + /** + * Process the action + * + * @param CRM_Civirules_EventData_EventData $eventData + * @access public + */ + public function processAction(CRM_Civirules_EventData_EventData $eventData) { + $entity = $this->getApiEntity(); + $action = $this->getApiAction(); + $contactId = $eventData->getContactId(); + + $action_params = $this->getActionParameters(); + $group_ids = array(); + if (!empty($action_params['group_id'])) { + $group_ids = array($action_params['group_id']); + } elseif (!empty($action_params['group_ids']) && is_array($action_params['group_ids'])) { + $group_ids = $action_params['group_ids']; + } + foreach($group_ids as $group_id) { + if (CRM_CivirulesConditions_Utils_GroupContact::isContactInGroup($contactId, $group_id)) { + $params = array(); + $params['group_id'] = $group_id; + + //alter parameters by subclass + $params = $this->alterApiParameters($params, $eventData); + + //execute the action + $this->executeApiAction($entity, $action, $params); + } + } + } } \ No newline at end of file diff --git a/CRM/CivirulesConditions/Contact/InGroup.php b/CRM/CivirulesConditions/Contact/InGroup.php index 65d50a7b5515a6641b4e22ec24d6026758965624..abd71b38ae21112dea216c5dd75f763456361225 100644 --- a/CRM/CivirulesConditions/Contact/InGroup.php +++ b/CRM/CivirulesConditions/Contact/InGroup.php @@ -52,7 +52,7 @@ class CRM_CivirulesConditions_Contact_InGroup extends CRM_Civirules_Condition { protected function contactIsNotMemberOfGroup($contact_id, $group_ids) { $isValid = true; foreach($group_ids as $gid) { - if (CRM_Contact_BAO_GroupContact::isContactInGroup($contact_id, $gid)) { + if (CRM_CivirulesConditions_Utils_GroupContact::isContactInGroup($contact_id, $gid)) { $isValid = false; break; } @@ -63,7 +63,7 @@ class CRM_CivirulesConditions_Contact_InGroup extends CRM_Civirules_Condition { protected function contactIsMemberOfOneGroup($contact_id, $group_ids) { $isValid = false; foreach($group_ids as $gid) { - if (CRM_Contact_BAO_GroupContact::isContactInGroup($contact_id, $gid)) { + if (CRM_CivirulesConditions_Utils_GroupContact::isContactInGroup($contact_id, $gid)) { $isValid = true; break; } @@ -74,7 +74,7 @@ class CRM_CivirulesConditions_Contact_InGroup extends CRM_Civirules_Condition { protected function contactIsMemberOfAllGroups($contact_id, $group_ids) { $isValid = 0; foreach($group_ids as $gid) { - if (CRM_Contact_BAO_GroupContact::isContactInGroup($contact_id, $gid)) { + if (CRM_CivirulesConditions_Utils_GroupContact::isContactInGroup($contact_id, $gid)) { $isValid++; } } diff --git a/CRM/CivirulesConditions/Contribution/DonorIsRecurring.php b/CRM/CivirulesConditions/Contribution/DonorIsRecurring.php index 28fe007528bb0a02a0d4e5c5c2328b40c78bbeb0..4c167b312cb1bf879c530001766ac23644f3b25e 100644 --- a/CRM/CivirulesConditions/Contribution/DonorIsRecurring.php +++ b/CRM/CivirulesConditions/Contribution/DonorIsRecurring.php @@ -34,19 +34,38 @@ class CRM_CivirulesConditions_Contribution_DonorIsRecurring extends CRM_Civirule * @access public */ public function isConditionValid(CRM_Civirules_EventData_EventData $eventData) { - $isConditionValid = FALSE; $contactId = $eventData->getContactId(); + $donorHasAny = FALSE; $recurringParams = array( 'contact_id' => $contactId, 'is_test' => 0); try { $foundRecurring = civicrm_api3('ContributionRecur', 'Get', $recurringParams); foreach ($foundRecurring['values'] as $recurring) { - if (CRM_Civirules_Utils::endDateLaterThanToday($recurring['end_date']) == TRUE) { + if (CRM_Civirules_Utils::endDateLaterThanToday($recurring['end_date']) == TRUE || !isset($recurring['end_date'])) { + $donorHasAny = TRUE; + } + } + if ($donorHasAny) { + if ($this->conditionParams['has_recurring']) { + $isConditionValid = TRUE; + } else { + $isConditionValid = FALSE; + } + } else { + if ($this->conditionParams['has_recurring']) { + $isConditionValid = FALSE; + } else { $isConditionValid = TRUE; } } - } catch (CiviCRM_API3_Exception $ex) {} + } catch (CiviCRM_API3_Exception $ex) { + if ($this->conditionParams['has_recurring']) { + $isConditionValid = FALSE; + } else { + $isConditionValid = TRUE; + } + } return $isConditionValid; } diff --git a/CRM/CivirulesConditions/FieldValueComparison.php b/CRM/CivirulesConditions/FieldValueComparison.php index a8b8c0246f30973be103b0b4370f12d39cc1a629..6099917f65505e30446a52bf4e3d167ad459096f 100644 --- a/CRM/CivirulesConditions/FieldValueComparison.php +++ b/CRM/CivirulesConditions/FieldValueComparison.php @@ -37,7 +37,7 @@ class CRM_CivirulesConditions_FieldValueComparison extends CRM_CivirulesConditio } protected function normalizeValue($value) { - if (value === null) { + if ($value === null) { return null; } diff --git a/CRM/CivirulesConditions/Utils/GroupContact.php b/CRM/CivirulesConditions/Utils/GroupContact.php new file mode 100644 index 0000000000000000000000000000000000000000..fc8b2dd67323abc38828500395c41f8edf7e9d2e --- /dev/null +++ b/CRM/CivirulesConditions/Utils/GroupContact.php @@ -0,0 +1,35 @@ +<?php + +class CRM_CivirulesConditions_Utils_GroupContact { + + /** + * Checks wether a contact is a member of a group + * + * This function is a copy of CRM_Contact_BAO_GroupContact::isContactInGroup but with + * a change so that the group contact cache won't be rebuild. Which somehow resulted + * in a deadlock + * + * @param $contact_id + * @param $group_id + * @return bool + */ + public static function isContactInGroup($contact_id, $group_id) { + if (!CRM_Utils_Rule::positiveInteger($contact_id) || + !CRM_Utils_Rule::positiveInteger($group_id) + ) { + return FALSE; + } + + $params = array( + array('group', 'IN', array($group_id => 1), 0, 0), + array('contact_id', '=', $contact_id, 0, 0), + ); + list($contacts, $_) = CRM_Contact_BAO_Query::apiQuery($params, array('contact_id'), null, null, 0, 1, false, false, true); + + if (!empty($contacts)) { + return TRUE; + } + return FALSE; + } + +} \ No newline at end of file diff --git a/CRM/CivirulesConditions/Utils/Period.php b/CRM/CivirulesConditions/Utils/Period.php index b6e85598c668a3eb6bfc4d7f3a1518fe69ec955d..f6fc8f50039b031d6942a2734303dcffa992aed9 100644 --- a/CRM/CivirulesConditions/Utils/Period.php +++ b/CRM/CivirulesConditions/Utils/Period.php @@ -252,7 +252,7 @@ class CRM_CivirulesConditions_Utils_Period { */ public static function convertPeriodToStartDate($condition_params) { $period = $condition_params['period']; - $replaceParameters = $condition_params['replaceParameters']; + $replaceParameters = isset($condition_params['replaceParameters']) ? $condition_params['replaceParameters'] : array(); $date = new DateTime(); switch ($period) { case 'this month': @@ -317,7 +317,7 @@ class CRM_CivirulesConditions_Utils_Period { */ public static function convertPeriodToEndDate($condition_params) { $period = $condition_params['period']; - $replaceParameters = $condition_params['replaceParameters']; + $replaceParameters = isset($condition_params['replaceParameters']) ? $condition_params['replaceParameters'] : array(); $date = new DateTime(); switch ($period) { case 'this month': diff --git a/CRM/Queue/Queue/Civirules.php b/CRM/Queue/Queue/Civirules.php index 8f2f0a4eac5112534f01782fd642e6eb678f1730..a96b28a89aeab7c0beb31d3c100d8398613b3f05 100644 --- a/CRM/Queue/Queue/Civirules.php +++ b/CRM/Queue/Queue/Civirules.php @@ -12,10 +12,94 @@ class CRM_Queue_Queue_Civirules extends CRM_Queue_Queue_Sql { SELECT count(*) FROM civicrm_queue_item WHERE queue_name = %1 - and (release_time is null OR release_time <= curdate()) + and (release_time is null OR release_time <= NOW()) ", array( 1 => array($this->getName(), 'String'), )); } + /** + * Get the next item + * + * @param $lease_time seconds + * + * @return object with key 'data' that matches the inputted data + */ + function claimItem($lease_time = 3600) { + $sql = " + SELECT id, queue_name, submit_time, release_time, data + FROM civicrm_queue_item + WHERE queue_name = %1 + and (release_time is null OR release_time <= NOW()) + ORDER BY weight ASC, release_time ASC, id ASC + LIMIT 1 + "; + $params = array( + 1 => array($this->getName(), 'String'), + ); + $dao = CRM_Core_DAO::executeQuery($sql, $params, TRUE, 'CRM_Queue_DAO_QueueItem'); + if (is_a($dao, 'DB_Error')) { + // FIXME - Adding code to allow tests to pass + CRM_Core_Error::fatal(); + } + + if ($dao->fetch()) { + $nowEpoch = CRM_Utils_Time::getTimeRaw(); + if ($dao->release_time === NULL || strtotime($dao->release_time) < $nowEpoch) { + CRM_Core_DAO::executeQuery("UPDATE civicrm_queue_item SET release_time = %1 WHERE id = %2", array( + '1' => array(date('YmdHis', $nowEpoch + $lease_time), 'String'), + '2' => array($dao->id, 'Integer'), + )); + // work-around: inconsistent date-formatting causes unintentional breakage + # $dao->submit_time = date('YmdHis', strtotime($dao->submit_time)); + # $dao->release_time = date('YmdHis', $nowEpoch + $lease_time); + # $dao->save(); + $dao->data = unserialize($dao->data); + return $dao; + } + else { + CRM_Core_Error::debug_var('not ready for release', $dao); + return FALSE; + } + } + else { + CRM_Core_Error::debug_var('no items found'); + return FALSE; + } + } + + /** + * Get the next item, even if there's an active lease + * + * @param $lease_time seconds + * + * @return object with key 'data' that matches the inputted data + */ + function stealItem($lease_time = 3600) { + $sql = " + SELECT id, queue_name, submit_time, release_time, data + FROM civicrm_queue_item + WHERE queue_name = %1 + ORDER BY weight ASC, release_time ASC, id ASC + LIMIT 1 + "; + $params = array( + 1 => array($this->getName(), 'String'), + ); + $dao = CRM_Core_DAO::executeQuery($sql, $params, TRUE, 'CRM_Queue_DAO_QueueItem'); + if ($dao->fetch()) { + $nowEpoch = CRM_Utils_Time::getTimeRaw(); + CRM_Core_DAO::executeQuery("UPDATE civicrm_queue_item SET release_time = %1 WHERE id = %2", array( + '1' => array(date('YmdHis', $nowEpoch + $lease_time), 'String'), + '2' => array($dao->id, 'Integer'), + )); + $dao->data = unserialize($dao->data); + return $dao; + } + else { + CRM_Core_Error::debug_var('no items found'); + return FALSE; + } + } + } \ No newline at end of file diff --git a/api/v3/Civirules/Cron.php b/api/v3/Civirules/Cron.php index 645ac74effaa9185d96985431b417b6f7360aad7..7854fa0147ac8b0823be8f4dd35e8818c400f1ae 100644 --- a/api/v3/Civirules/Cron.php +++ b/api/v3/Civirules/Cron.php @@ -24,6 +24,9 @@ function _civicrm_api3_civirules_cron_spec(&$spec) { function civicrm_api3_civirules_cron($params) { $returnValues = array(); + //prevent from crashing with a max execution time error + set_time_limit(0); + $rules = CRM_Civirules_BAO_Rule::findRulesForCron(); foreach($rules as $rule) { $return = $rule->process(); diff --git a/info.xml b/info.xml index 449f5ad66a84b92ae66be0eefa020594771795f3..3424fff9fd954c5bd29690073f7c5cf6dc8caed2 100755 --- a/info.xml +++ b/info.xml @@ -16,7 +16,7 @@ </maintainer> <releaseDate>2015-01-13</releaseDate> <version>1.0</version> - <develStage>beta</develStage> + <develStage>stable</develStage> <compatibility> <ver>4.4</ver> </compatibility> diff --git a/templates/CRM/CivirulesActions/Contribution/Form/ThankYouDate.tpl b/templates/CRM/CivirulesActions/Contribution/Form/ThankYouDate.tpl new file mode 100644 index 0000000000000000000000000000000000000000..6b5045889f40fc332197472f4f35cb6a150e2ff5 --- /dev/null +++ b/templates/CRM/CivirulesActions/Contribution/Form/ThankYouDate.tpl @@ -0,0 +1,53 @@ +<h3>{$ruleActionHeader}</h3> +<div class="crm-block crm-form-block crm-civirule-rule_action-block-contribution-thank-you-date"> + <div id="thank-you-radio-block" class="crm-section"> + <div class="label">{$form.thank_you_radio.label}</div> + <div class="content">{$form.thank_you_radio.html}</div> + <div class="clear"></div> + </div> + <div id="number_of_days-block" class="crm-section"> + <div class="label">{$form.number_of_days.label}</div> + <div class="content">{$form.number_of_days.html}</div> + <div class="clear"></div> + </div> + <div id ="thank_you_date-block" class="crm-section"> + <div class="label">{$form.thank_you_date.label}</div> + <div class="content">{include file="CRM/common/jcalendar.tpl" elementName=thank_you_date}</div> + <div class="clear"></div> + </div> +</div> +<div class="crm-submit-buttons"> + {include file="CRM/common/formButtons.tpl" location="bottom"} +</div> +{literal} + <script type="text/javascript"> + cj(function($) { + $("input[type=radio][checked]").each(function() { + if ($('#CIVICRM_QFID_0_thank_you_radio').prop('checked')) { + $('#number_of_days-block').hide(); + $('#thank_you_date-block').hide(); + } + if ($('#CIVICRM_QFID_1_thank_you_radio').prop('checked')) { + $('#number_of_days-block').show(); + $('#thank_you_date-block').hide(); + } + if ($('#CIVICRM_QFID_2_thank_you_radio').prop('checked')) { + $('#number_of_days-block').hide(); + $('#thank_you_date-block').show(); + } + }); + $('#CIVICRM_QFID_0_thank_you_radio').click(function() { + $('#number_of_days-block').hide(); + $('#thank_you_date-block').hide(); + }) + $('#CIVICRM_QFID_1_thank_you_radio').click(function() { + $('#number_of_days-block').show(); + $('#thank_you_date-block').hide(); + }) + $('#CIVICRM_QFID_2_thank_you_radio').click(function() { + $('#number_of_days-block').hide(); + $('#thank_you_date-block').show(); + }) + }); + </script> +{/literal} \ No newline at end of file diff --git a/xml/Menu/civirules.xml b/xml/Menu/civirules.xml index 29c792a62836bfdbe17b6635690183053cea6944..0dd0bd1bc7d9ca4ef047c1696f0bd03f7fbbb50e 100755 --- a/xml/Menu/civirules.xml +++ b/xml/Menu/civirules.xml @@ -5,149 +5,181 @@ <page_callback>CRM_Civirules_Page_Rule</page_callback> <title>Rule</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/rule</path> <page_callback>CRM_Civirules_Form_Rule</page_callback> <title>Rule</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/rule_condition</path> <page_callback>CRM_Civirules_Form_RuleCondition</page_callback> <title>RuleCondition</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/rule_action</path> <page_callback>CRM_Civirules_Form_RuleAction</page_callback> <title>RuleAction</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer 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> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> - <path>civicrm/civirule/form/condition/fieldvaluecomparison</path> - <page_callback>CRM_CivirulesConditions_Form_FieldValueComparison</page_callback> - <title>Value comparison</title> - <access_arguments>access CiviCRM</access_arguments> + <path>civicrm/civirule/form/condition/fieldvaluecomparison</path> + <page_callback>CRM_CivirulesConditions_Form_FieldValueComparison</page_callback> + <title>Value comparison</title> + <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> - <path>civicrm/civirule/form/condition/groupcontact/groupid</path> - <page_callback>CRM_CivirulesConditions_Form_GroupContact_GroupId</page_callback> - <title>Group Id</title> - <access_arguments>access CiviCRM</access_arguments> + <path>civicrm/civirule/form/condition/groupcontact/groupid</path> + <page_callback>CRM_CivirulesConditions_Form_GroupContact_GroupId</page_callback> + <title>Group Id</title> + <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> - <path>civicrm/civirule/form/condition/contributionstatus</path> - <page_callback>CRM_CivirulesConditions_Form_Contribution_Status</page_callback> - <title>contribution status</title> - <access_arguments>access CiviCRM</access_arguments> + <path>civicrm/civirule/form/condition/contributionstatus</path> + <page_callback>CRM_CivirulesConditions_Form_Contribution_Status</page_callback> + <title>contribution status</title> + <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/contribution_totalcontributedamount</path> <page_callback>CRM_CivirulesConditions_Form_Contribution_TotalContributedAmount</page_callback> <title>Total contributed amount</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/contribution_financialtype</path> <page_callback>CRM_CivirulesConditions_Form_Contribution_FinancialType</page_callback> <title>financial type</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/contribution_distinctcontributingday</path> <page_callback>CRM_CivirulesConditions_Form_Contribution_DistinctContributingDay</page_callback> <title>distinct contributing days</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/contribution_countrecurring</path> <page_callback>CRM_CivirulesConditions_Form_Contribution_CountRecurring</page_callback> <title>recurring contribution collections</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/contribution_donorisrecurring</path> <page_callback>CRM_CivirulesConditions_Form_Contribution_DonorIsRecurring</page_callback> <title>donor has recurring contributions</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/contribution_recurringenddate</path> <page_callback>CRM_CivirulesConditions_Form_Contribution_RecurringEndDate</page_callback> <title>end date recurring contribution</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/contribution_specificamount</path> <page_callback>CRM_CivirulesConditions_Form_Contribution_SpecificAmount</page_callback> <title>specific amount count</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/contact_ingroup</path> <page_callback>CRM_CivirulesConditions_Form_Contact_InGroup</page_callback> <title>In Group</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/contact_hastag</path> <page_callback>CRM_CivirulesConditions_Form_Contact_HasTag</page_callback> <title>Has Tag</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/contribution_paidby</path> <page_callback>CRM_CivirulesConditions_Form_Contribution_PaidBy</page_callback> <title>paid by</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/action/groupcontact</path> <page_callback>CRM_CivirulesActions_GroupContact_Form_GroupId</page_callback> <title>Group contact</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> + </item> + <item> + <path>civicrm/civirule/form/action/contribution/thankyoudate</path> + <page_callback>CRM_CivirulesActions_Contribution_Form_ThankYouDate</page_callback> + <title>Contribution Thank You Date</title> + <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/event/groupmembership</path> <page_callback>CRM_CivirulesCronEvent_Form_GroupMembership</page_callback> <title>Group membership</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/action/tag</path> <page_callback>CRM_CivirulesActions_Tag_Form_TagId</page_callback> <title>Tag</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/action/contact/subtype</path> <page_callback>CRM_CivirulesActions_Contact_Form_Subtype</page_callback> <title>Set contact subtype</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/action/activity</path> <page_callback>CRM_CivirulesActions_Activity_Form_Activity</page_callback> <title>Activity</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/activity_type</path> <page_callback>CRM_CivirulesConditions_Form_Activity_Type</page_callback> <title>Activity Type</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> <item> <path>civicrm/civirule/form/condition/activity_contact_record_type</path> <page_callback>CRM_CivirulesConditions_Form_Activity_RecordType</page_callback> <title>Activity Contact Record Type</title> <access_arguments>access CiviCRM</access_arguments> + <access_arguments>administer CiviCRM</access_arguments> </item> </menu>