This project is not covered by Drupal’s security advisory policy.

Adds a secondary form for creating a Rules configuration (e.g. component, non-abstract action containers) the proper way, e.g. with additional arguments. This is a developer module used by Rules-related modules, and is not required unless a module indicates this as a requirement.

See #1681510: Add plugin factory to UI for more general efforts to incorporate factory UI into Rules.

Problem

When creating a new component, Rules UI automatically assumes there is no argument to use other than the plugin name to initialize a new Rules configuration. However, this is not applicable for plugins that require additional information to initialize properly (e.g. run MyRulesPlugin::setUp() with the right options). This is not an issue with RulesAbstractPlugin, though largely because it cannot be initialized as a component.

Solution

With Rules Factory UI, you could create form elements for the factory to be able to properly create an instance of the desired plugin.

  1. Create a new class that extends RulesFactoryUI and implement the abstract methods:
    • factoryForm(): Set up form elements. The $options argument contains an 'init' flag, which will be TRUE if the configuration has been set up, at which point the form elements should be disabled.
    • factoryFormValidate(): (Optional) Validate factory form submission. RulesFactoryUI provides a blank implementation, but you can override this to validate form values.
    • factoryFormSubmit(): Process factory form submission, i.e. create the plugin instance. Store the instance in $form_state['rules_factory_created'] to mark the factory workflow complete.
  2. Add the class as a Faces extender in hook_rules_plugin_info() for the RulesFactoryUIInterface class.

RulesPluginUIInterface implementations for embedded plugins should take care not to add visible form elements apart from the 'submit' button—that is, until the plugins have been initialized. By default, RulesPluginUI adds a 'submit' button labeled "Continue" and empty (invisible) elements to a form, given the plugin does not return parameters or variables.

API change in 7.x-1.0-beta1

From 7.x-1.0-beta1 onwards, the factoryFormSubmit() method should save the created element in $form_state['rules_factory_created'] instead of $form_state['rules_config']. This change is to allow for flexibility in dealing with other types of Rules configuration than components (in case "rules_config" conflicts with any plugin form).

Remarks

Note: Due to the way PHP magic methods work, transparently invoking the factoryForm() on an extended Rules plugin will not pass the form by reference. If you want to access factoryForm() seamlessly you will need to implement into your plugin something similar to RulesAbstractPlugin::form() (see example below). Rules Factory UI uses the __call() method for ease of extension.

Note #2: Rules Factory UI does not have a dependency on Rules UI. It is meant to be used as an API extension, so a module using a factory UI should not be forced to enable Rules UI. Any module that actually requires Rules UI to work (e.g. tests) should include a dependency on Rules UI for itself.

Example

myexample.module file:

/**
 * Implements hook_rules_plugin_info().
 */
function myexample_rules_plugin_info() {
  return array(
    'my_rules_plugin' => array(
      'label' => t('My Rules Plugin'),
      'class' => 'MyRulesPlugin',
      'component' => TRUE,
      'embeddable' => FALSE,
      'extenders' => array(
        'RulesPluginUIInterface' => array(
          'class' => 'RulesPluginUI',
        ),
        'RulesFactoryUIInterface' => array(
          'class' => 'MyRulesFactoryUI',
        ),
      ),
    ),
  );
}

/**
 * Example plugin that uses $foo to set up.
 */
class MyRulesPlugin extends RulesPlugin {
  protected $itemName = 'my_rules_plugin';
  protected $foo;

  /**
   * Constructs the plugin with $foo.
   */
  public function __construct($foo = NULL) {
    $this->foo = $foo;
    $this->setUp();
  }

  /**
   * Sets up the plugin.
   */
  protected function setUp() {
    parent::setUp();

    // Use $this->foo to set up.
    if (isset($this->foo)) {
      // ...
    }
  }

  /**
   * Extends factory form using arguments by reference.
   */
  public function factoryForm(&$form, &$form_state, $options) {
    $this->__call('factoryForm', array(&$form, &$form_state, $options));
  }

  /**
   * Extends factory form validate using arguments by reference.
   */
  public function factoryFormValidate(&$form, &$form_state, $options) {
    $this->__call('factoryFormValidate', array(&$form, &$form_state, $options));
  }

  /**
   * Extends factory form submit using arguments by reference.
   */
  public function factoryFormSubmit(&$form, &$form_state, $options) {
    $this->__call('factoryFormSubmit', array(&$form, &$form_state, $options));
  }

  // Insert other methods here, such as componentVariables().
}

/**
 * Factory UI for the example class.
 */
class MyRulesFactoryUI extends RulesFactoryUI {
  /**
   * Adds a text field for 'foo'.
   */
  public function factoryForm(&$form, &$form_state, $options = array()) {
    $form['foo'] = array(
      '#type' => 'textfield',
      '#title' => t('Foo'),
      '#default_value' => isset($form_state['values']['foo']) ? $form_state['values']['foo'] : '',
      '#required' => TRUE,
      '#disabled' => !empty($options['init']),
    );
  }

  /**
   * Creates an instance of MyRulesPlugin.
   */
  public function factoryFormSubmit(&$form, &$form_state, $options = array()) {
    $foo = $form_state['values']['foo'];
    $form_state['rules_factory_created'] = new MyRulesPlugin($foo);
  }
}

Project information

  • caution Minimally maintained
    Maintainers monitor issues, but fast responses are not guaranteed.
  • caution No further development
    No longer developed by its maintainers.
  • Module categories: Automation
  • chart icon6 sites report using this module
  • Created by zhangtaihao on , updated
  • shield alertThis project is not covered by the security advisory policy.
    Use at your own risk! It may have publicly disclosed vulnerabilities.

Releases