Drupal 7 - Defining rules within a module using PHP

It took a while to figure out with all information I could easily find relating to the Rules module using the UI to define rules.

But you can define some default rules within your module by using the function MODULE_NAME_default_rules_configuration() which sits within a file called MODULE_NAME.rules_defaults.inc in your module folder.

Creating your rule

I still find the easiest way to initially set up the rule is to use the Rules UI interface. You can code directly but you are much more likely to make mistakes than if you are just copying our some exported text from the Rules interface.

Exporting your rule

Within the rules UI you can see all the rules including the rule you have created.

rules_ui.png

I am going to use on of the Drupal Commerce rules as an example. So click the Export link next to the rule you wish to set up within your module.

rules-export.png

Adding the export code to your module

In your MODULE_NAME.rules_defaults.inc file, you should have the following set up as the very basic code.

<?php
function MODULE_NAME_default_rules_configuration() {
  
$configs = array();
  return 
$configs;
}
?>

Note that you will need to change MODULE_NAME to your actual module name and the closing ?> tag should not be at the end of your file, that is something that the syntax highlighter adds on automatically.

To have the rule process from the exported code we need to run it through the function rules_import(). This will change the export code in to a usable format for the Rules module. This then needs to be added to the $configs array.

<?php
function MODULE_NAME_default_rules_configuration() {
  
$configs = array();
  
$rule '{ "commerce_checkout_order_email" : {
    "LABEL" : "Send an order notification e-mail",
    "PLUGIN" : "reaction rule",
    "WEIGHT" : "4",
    "REQUIRES" : [ "rules", "commerce_checkout" ],
    "ON" : [ "commerce_checkout_complete" ],
    "DO" : [
      { "mail" : {
          "to" : [ "commerce-order:mail" ],
          "subject" : "Order [commerce-order:order-number] at [site:name]",
          "message" : "Thanks for your order [commerce-order:order-number] at [site:name].\n\nIf this is your first order with us, you will receive a separate e-mail with login instructions. You can view your order history with us at any time by logging into our website at:\n\n[site:login-url]\n\nYou can find the status of your current order at:\n\n[commerce-order:customer-url]\n\nPlease contact us if you have any questions about your order.",
          "from" : ""
        }
      }
    ]
  }
}'
;
  
$configs['commerce_checkout_order_email'] = rules_import($rule);
  return 
$configs;
}
?>

You can define multiple rules through this function and you also have the luxury of being able to programmatically define rules based on other aspects of the site (such as rule per user role or content type, an example being setting up different pricing groups per user role in Drupal Commerce).

If you are actively adding your rule in a development site, you will need to run cron before the rule appears within Rules UI. The same goes for any changes you make to the rule in code.

Comments

Hi James, thank you kindly for posting this exmaple, it has helped me out massively.

I have been able to import rules via module when using the UI to create them and then using the export output.

I am however having issues with importing some php eval action, the code works fine in a UI created rule, but fails to import via the module, if i change the rules code to require() my script now placed in a file, then it will import fine, but then has issues with running the script, as if $node is no longer defined when the rule is triggered.

Any advice you might be able to give would be appreciated.

Thanks again.

Regards
Delphium

Best thing to do would be to open up the rules file with an IDE with syntax highlighting and make sure the PHP eval isn't breaking anything.

Thank you very much for this