CRM-13244 Extend reminders functionality to cover additional entities and include more tokens

    Details

    • Documentation Required?:
      Developer Doc
    • Funding Source:
      Core Team Funds

      Description

      Sometimes, you need to use the handy schedule reminders to send out emails containing additional info, currently not made available in the core code. The idea is to make this open and extensible. In addition, this aims at enabling reminders for other types of entities in CiviCRM.

      This change introduces a new hook (mod Utils/Hook.php) and refactors the ActionSchedule to allow different types of additional tokens to be added before the email message is composed :

      • tokens you can add directly, regardless of the context of the reminder
      • tokens depending on data you prefer to include in the original data query
      • tokens you may want to add based on data returned by the current query.

      Example of a hook which does this:

      function mymodule_civicrm_getReminderTokens($mapping, $op, &$more) {
        $ent = $mapping->entity;
        CRM_Core_Session::setStatus('Mymodule's getReminderTokens hook is called !');
        if ($mapping->entity == 'civicrm_membership') {
          switch ($op) {
            case 'pre' :
              //
              // one way of adding tokens is adding them directly to the tokens array
              // mind: use a prefix !
              //
              $more->tokens = array(
                  'membership.boo' => 'Boo !',
                  'mydomain.burp' => 'Scuze me !',
              );
      
              // 
              // it is possible to amend the selection query, for instance to add 
              // a custom field
              // mind: you need to take a look at BAO/ActionSchedule.php to unerstand how to join these !
              //
              $more->extraJoins[] = 'INNER JOIN civicrm_value_testing_custom_4 cmt ON cmt.entity_id = reminder.entity_id';
              $more->extraFields['widgetizement']   = 'cmt.widgetizement_7 as widgetizement';
      
              break;
      
            case 'post' :
              //
              // in the post hook, we can access the resulting dao, and once again
              // add tokens based on any of this info
              //
              $dao = $more->dao;
              $joined = strtotime($dao->join_date);
              $more->tokens[ 'membership.mydate' ] = date('d_m_YY',$joined);
      
              break;
          }
        }
      }
      

      — Open issues —

      Currently, you can only work on existing entities. I am working on a fix to ActionSchedule:getSelection* to include that into the hook as well, so the UI automatically picks up the additional action_mappings (to be installed with the module/extension) and drive the UI accordingly. Nonetheless, this extension is useful without the changes to this method.

        Attachments

          Activity

          [CRM-13244] Extend reminders functionality to cover additional entities and include more tokens
          Tim Otten added a comment - - edited

          I've been working on refactoring/breaking-apart CRM_Core_BAO_ActionSchedule. It's taken forever... and a day... but I think there's finally enough abstractions/separations between the scheduled-reminder (generic core) and the scheduled-reminder (entity-specific mappings) that one can add new mappings in an almostnotmindboggling way.

          The process has required a lot of analysis and careful modification to some gargantuan functions. I believe that I've got this organized into ~2 layers now:

          1. Build Recipients: This process takes a schedule-rule and the current time then generates a concrete list of recipients.This responsibility has been moved to \Civi\ActionSchedule\RecipientBuilder (which handles the generic/core parts) and the \Civi\ActionSchedule\MappingInterface (which handles the entity-specific parts). There's more discussion in the class docs.

          2. Send mailings: Given that we've scheduled a message for a particular person,
          This requires loading relational data from the DB (for use with mail-merge tokens) and formatting/inserting the data. This responsibility has been broken up into a generic core (CRM_Core_BAO_ActionSchedule::sendMailings and TokenProcessor) and entity-specific bits (CRM_Activity_Tokens, etc).

          The next remaining tasks:

          a. It should be possible for an extension/module to implement "hook_civicrm_container" and register new mappings and new token handlers (which follow the general structure of the above examples). I'll need to do this for an example entity (preferably one I understand).

          b. Assess how well the new entity works in the admin UI. This might require more refactoring in the form code - but we'll have to see.

          c. Update schema. `civicrm_action_schedule.mapping_id` should allow alphanumerics (so that new mapping types can be registered by name). `civicrm_action_mapping` should be dropped from the schema.

          Tim Otten added a comment -
          Tim Otten added a comment -

          We've merged the work into 4.7 (master; PR #6687).

          Eileen McNaughton added a comment -

          Tim this is merged to master but fix-version is 4.6.

          I'm assuming you don't see any backport as feasible?

          Tim Otten added a comment -

          No feedback... guess it's perfect...

          Joanne Chester added a comment -

          Hi Tim,

          I am adding scheduled reminders for contributions to the documentation. However, there don't seem to be any contribution tokens available for the email.

          Most of the above is way too technical for me, but was https://github.com/totten/civicrm-core/blob/4.6-sched-ref/CRM/Contribute/Tokens.php meant to be part of the PR for this issue as it doesn't seem to have been included.

          Tim Otten added a comment - - edited

          That file should already be included – https://github.com/civicrm/civicrm-core/blob/master/CRM/Contribute/Tokens.php (Note: When I first followed the link, I tried hacking the URL to change 4.6-sched-ref to master, and the file didn't show up. That's because I was looking at the totten fork of master... which is ancient. Generally, one shouldn't trust "master" on random personal forks.)

          The issue may be in the UI (rather than the token-processing) – e.g. the UI does not display the token an option in the dropdown, but it should still accept the token anyway. Internally, there is a list of tokens - but it needs to be plugged into the UI. For now, you'd have to type in the token (e.g. "contribution.status").

          To verify that contribution tokens are rendered, I updated a test: https://github.com/civicrm/civicrm-core/pull/7974

          Joanne Chester added a comment -

          Thanks Tim, it didn't occur to me that the processing capability would be there but the tokens just weren't listed. I think I can fix that myself.

            People

            • Assignee:
              Frank J. Gómez
              Reporter:
              Paul Delbar

              Dates

              • Created:
                Updated:
                Resolved: