Comparaison des versions

Légende

  • Ces lignes ont été ajoutées. Ce mot a été ajouté.
  • Ces lignes ont été supprimées. Ce mot a été supprimé.
  • Formatting was changed.

...

Warning

...

titleDeprecated page

This wiki page is no longer kept up to date with the project progress. Up to date documentation on CiviRules can be found at http://redmine.civicoop.org/projects/civirules/wiki

This page is work in progress documentation for CiviRules. 

...

  • Create mockups

  • Investigate the core queue mechanism and document it

  • Create the basic framework for the rules extension

  • Create a UI around the framework

  • (API) action for sending e-mail

  • (API) action for sending SMS

  • (API) action for printing PDF Letter

Mockups

In this section several mockups show the desired workflow of a couple of CiviRules.

Initial form from Administer Menu

Initial form shown to user when he/she selects 'CiviRules' from 'Administration' menu

Mockup
NameCiviRule - initial screen
AlignmentLeft
Version20

Manage CiviRule Form

Form shown when a user clicked 'manage' on the initial form or clicked on 'Add CiviRule'. In the latter case there will obviously be no existing Events, Conditions or Actions.

Mockup
NameCiviRule - manage
AlignmentLeft
Version68

Add Event Form

The following form will be shown when the user clicked 'Add event' in the Manage CiviRule form

...

Mockup
NameCiviRule - add Event
AlignmentLeft
Version15

Framework

Below a draft of the API for the framework. This api consist of hooks and functions other extensions could invoke.

  • hook_civicrm_rules_event_types: returns event types to the framework
  • Invoke Event: api to invoke an event in the civicrm rules module
  • hook_civicrm_rules_condition_types: returns condition types to the framework
  • hook_civicrm_rules_action_types: return action types to the frameworks

Interfaces

Add Condition Form

If the user clicks 'Add condition' in the Manage CiviRule form a couple of forms can be presented, depending on what route is followed. The first form will always appear, the others depend on the selection. A couple of tracks are added here without the presumption of being complete

Mockup
NameCIviRule - add condition
AlignmentLeft
Version2

Data comparison form

If the user selected Data comparison and clicked 'Continue'

Mockup
NameCiviRule - add data comparison
AlignmentLeft
Version3

Data value form

If the user typed Contact.total_contributed_amount_this_year and then Clcked 'Continue':

Mockup
NameCiviRule - Condition data value from data comparison
AlignmentLeft
Version6

 

That completes this specific condition, the next step would be to add the action.

Add Action Form

So if the user clicked 'Add action' in the form Manage CiviRule, the following sequence will start:

Mockup
NameCiviRule - add action
AlignmentLeft
Version2

Add contact to group form

In the example 'Add contact to group' has been selected so the next form will show a list of active groups that can be selected, which then completes the action.

Mockup
NameCiviRule - add action add contact to group
AlignmentLeft
Version3

Set data value form sequence

If the user selects 'set data value' he or she will be presented with the next form. Actually, most actions could be done with 'set data value' (or a combination of them) but some shortcuts will be provided with the data selectors.

 

Mockup
NameCiviRule - add action data selector
AlignmentLeft
Version7

In the next form the user gets to enter the actual value. This could be an input field (with relevant replacement patterns if any) or a select list.

Mockup
NameCiviRule - add action data value
AlignmentLeft
Version1

Send PDF letter form

Mockup
NameCiviRule - add action send PDF letter
AlignmentLeft
Version3

Framework

Below a draft of the API for the framework. The framework consists of the following

  • Interfaces
  • Hooks
  • API

Interfaces

Below a more detailed description of the interfaces we are going to use in the framework. The interfaces we have identified are:

  • event definition
  • condition definition
  • action definition

Event definition

The event definition contains a system name (name), a human readable name (label) and a description. Any new event should implements this event definition.

Bloc de code
languagephp
Interfaceinterface CRM_Rules_Interface_EventDefinition {
 
    /**
     * Returns a system name of this event
     * e.g. post_contact
     *
     * @return string
     */
	public function getName();
 
	/**
     * Returns a human and translatable label of the event
     * E.g. 'Before a contact is changed'
     * 
     * @return string
     */
	public function getLabel();
 
    /**
     * Returns the name of the entity e.g. 'Contact', 'Contribution'
     *
     * @return string
     */
	public function getEntity();
 
	/**
     * Returns whether the given event parameters are valid. 
     * If they are not valid the whole rule would probably not be executed
     *
     * @param array $event_parameters
     * @return bool
     */
	public function validateEventParameters($event_parameters);
 
	/**
     * Returns an array which replacement patterns this event provides
     *
     * E.g. a post contribution event provides the Contact and the Contribution contact
     * So the return array looks like:
     * array (
     *  new CRM_Rules_Model_ReplacementPattern('contact', 'CRM_Contact_DAO_Contact'),
     *  new CRM_Rules_Model_ReplacementPattern('soft_credit', 'CRM_Contact_DAO_Contact'),
     *  new CRM_Rules_Model_ReplacementPattern('contribution', 'CRM_Contribution_DAO_Contribution'),
     * )
     * 
     * @return array
     */
	public function getReplacementPatterns();
 
}

Action Definition

The action definition interface consists of  a system name of the action, a human readable label of the action and optional an entity on which the action is performed. An action could be something like add contact to group, or set data value.

Bloc de code
languagephp
interface CRM_Rules_Interface_ActionDefinition {
 
	public function getName();
 
	public function getLabel();
 
	public function getEntity();
 
}

 

Hooks

Below a more detailed description of the hooks

The following hooks are available from this extension. So that you can customize this extension to some extent.

  • hook_civicrm_rules_event_definition
  • hook_civicrm_rules_alter_dataselectors
  • hook_civicrm_rules_action_definition

hook_civicrm_rules_event_definition

This hooks returns an array with definitions for events. An event definition could be for example e.g. a post event or a pre event. An event definition is defined in a class which implements the CRM_Rules_Interface_EventDefinition

Below is an example usage of this hook

Bloc de code
languagephp
function rules_civicrm_rules_event_definition() {
	$events['post_contact'] = new CRM_Rules_Events_PostContact();
	return $events;
}
 
/*
 * To trigger on this event we add this event to post hook
 */
function rules_civicrm_post($op, $objectName, $objectId, $objectRef) {
	$api = civicrm_api3('Rules', 'InvokeEvent', array(
		'event' => 'post_'.$objectName,
        'event_parameters' => array(
           'operation' => $op,
           'entity_id' => $objectId,
           'entity' => $objectName,
           'entity_data'  => $objectRef,
        );
	));
}
 
/*
 * Below is an example of the CRM_Rules_Events_PostContact class
 */
class CRM_Rules_Events_PostContact {
 
	public function getName() {
		return 'post_contact';
	}
 
	public function getLabel() {
		return ts('After updating a contact');
	}
 
	public function getEntity() {
		return 'Contact';
	}
 
	public function validateEventParameters($event_parameters) {
		if ($event_parameters['objectName'] == 'Contact') {
			return true;
		} else {
			return false;
		}
	}
}

hook_civicrm_rules_action_definition

This hooks returns an array with definitions for actions. An action could be something like send e-mail or set data value. Every action is an object which implements the CRM_Rules_Interface_ActionDefinition

Below is an example usage of this hook

Bloc de code
languagephp
function rules_civicrm_rules_action_definition() {
	$actions['set_data_value'] = new CRM_Rules_Actions_SetDataValue();
	$actions['send_email'] = new CRM_Rules_Actions_SendEmail();
	return $actions;
}

hook_civicrm_rules_alter_dataselectors

This hook can be used to alter available data selectors within a replacement pattern. This can be useful to add a data selector for total_contribution_amount_this_year at contact level.

Below is an example implementation of this hook.

Bloc de code
languagephp
function hook_civicrm_rules_alter_dataselectors($dao, &$current_data_selectors) {
	if ($dao == 'CRM_Contact_DAO_Contact') {
		$current_data_selectors['total_contribution_amount_this_year'] = new CRM_Rules_Model_DataSelector(); //the model for data selector is not yet defined.
	}
}

API: InvokeEvent

The API of this extension consist of a call to the extension to trigger events of a certain type. E.g. in the post hook we want trigger the post event for a certain object. 

...

  • event: the name of the event
  • event_parameters: an array with additional parameters for this specific event

Models

The extension uses the follownig models:

  • CRM_Rules_Model_Rule
  • CRM_Rules_Model_ReplacementPattern

Model: CRM_Rules_Model_Rule

The CRM_Rules_Model_Rule holds all the data belonging to a rule, which is the event, the conditions and the actions. Also when an action is scheduled to be executed with an offset the replacement patterns should be working in the future. We don't know yet how to achieve this. 

Bloc de code
languagephp
class CRM_Rules_Model_Rule {
 
	protected $event_name; //loaded from database
 
	protected $conditions; //loaded from database
 
	protected $actions; //loaded from database
 
	protected $event_parameters; //set on triggerEvent
 
	public function setEvent($event_name) {
		$this->event_name = $event;
	}
 
	public function getEvent() {
		return $this->event_name;
	}
 
	...
 
	/**
     * Trigger the event and check the conditions and eventually execute the actions
     *
     * @return void
     */
	public function triggerEvent($event_name, $event_parameters) {
		if ($event_name != $this->event_name) {
			//not a valid event
			return;
		}
 
		$this->event_parameters = $event_parameters;
		if ($this->checkConditions()) {
			$this->doActions();
		}
	}
	
	/**	
	 * Returns true when all condition criteria are met
	 * returns false when one of the condition criteria is not met
     * 
     * @return bool
     */
	protected function checkConditions() {
		//functionality to test conditions
		//returns true when all conditions are met
		//returns false when one condition fails
		foreach($this->conditions as $condition) {
			if ($condition->check($this->event_name, $this->event_parameters, $this) != false) {
				return false;
			}
		}
		return true;
	}
	
	/**
	 * Execute the actions immediatly or schedule them for future execution
     *
     * @return void
     */
	protected function doActions() {
		//execute the actions are schedule them
		foreach($this->actions as $action) {
			//add the action to the action queue of civicrm core
			CRM_Rules_Queue::addToQueue($action, $this->event_name, $this->event_parameters, $this);
		}
	}
 
	/**
     * Returns the data what can be used for the replacement patterns
     * We don't know yet how this is going to work or to look like
     * but we do know we have to have a method for retrieving and storing this data for future action execution
     *
     * @return array|mixed
     */
	public function getDataForReplacementPatterns() {
		//return something...
	}
 
}

Model: CRM_Rules_Model_ReplacementPattern

Bloc de code
languagephp
class CRM_Rules_Model_ReplacementPattern {
 
	protected $dataselector;
 
    protected $dao;
 
    public function __construct($dataselector, $dao) {
		$this->dataselector = $dataselector;
        $this->dao = $dao;
    }
 
	public function getDataSelector() {
		return $this->dataselector;
	}
 
	public function getDao() {
		return $this->dao;
	}
 
	/**
     * Returns an array with sub dataselectors for this dataselector
     * E.g. if this data selector is on Contribution DAO then this will return all contribution dao fields
     * but the selection could also be altered by a hook
     *
     * @return array
     */
	public function getAvailableDataSelectors() {
		//code to return the available sub data selectors
	}
 
}

Data diagram


Creative Commons License
Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution-Share Alike 3.0 United States Licence.