1

Using Rules I would like to check the values of some fields.

I have a content type 'A' which has a custom field called 'address'. All nodes of content type 'A' are imported through Feeds.

I would like to create a rule where each node that is imported is checked, to verify if the value of field 'address' is equal to the value of field 'address' on any of my other nodes of type A.

I have read about 'Entity has field' as a Rules Condition. However I understand that this only checks several fields in the same node, while I want to check one field against all other nodes.

How can I accomplish this with Rules or any other method?

  • even if you could it in Rules (which I don't think you can), it would be much slower than writing a custom module to handle this – Geoff Jun 1 '15 at 11:27
  • Would a custom module be better then a custom rule? – Byron Jun 2 '15 at 23:08
  • that really depends on how good you are at writing either :) I don't think from a practical stand point either is 'better', a stand-alone module isn't reliant on Rules, but a custom Rule might be easier to write - efficiency really depends on your coding skill – Geoff Jun 2 '15 at 23:41
  • @Pierre.Vriens Nope. A comment is just that, a comment based on what I knew at the time. Going back to make sure every piece of content is correct based on current information is pointless and indicative of severe OCD. Besides, I don't say it isn't possible, I just didn't think it was, hence a comment, and not an answer. It's still a valid comment. – Geoff Feb 15 '18 at 14:02
  • @Geoff OK, good enough. Based on that, and combined with my answer to this question, it seems that we disagree then, since I think (actually I'm sure) you can ... even already from when this question was posted. – Pierre.Vriens Feb 15 '18 at 14:32
0

You can make this work by using Rules in combination with the Views Bulk Operations module, as further detailed below.

In what follows, I'm assuming that the machine name of your field is field_address (change to whatever fits).

Step 1 - Create a VBO view

Use the Views Bulk Operations (VBO) module to create a view of all relevant nodes, in which you should:

  1. Add a VBO field to it.
  2. Add a contextual filter for the field_address field for which you want to check that its value is unique. Make sure to correctly configure this contextual filter, similar to what is mentioned in this answer to "How to have a field that counts the nodes submitted by the current user?" (credits to Niall Murphy, merci!).

Include a field like nid for each node (no need for any other fields). Just make sure you get exactly 1 row for each node you want to take into consideration.

Here is an export of such VBO view:

$view = new view();
$view->name = 'relevant_nodes';
$view->description = 'Produce a list of node ids that satisfy a specific filter';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Relevant nodes';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Relevant nodes';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '10';
$handler->display->display_options['style_plugin'] = 'table';
$handler->display->display_options['style_options']['columns'] = array(
  'title' => 'title',
);
$handler->display->display_options['style_options']['default'] = '-1';
$handler->display->display_options['style_options']['info'] = array(
  'title' => array(
    'sortable' => 0,
    'default_sort_order' => 'asc',
    'align' => '',
    'separator' => '',
    'empty_column' => 0,
  ),
);
/* Field: Content: Nid */
$handler->display->display_options['fields']['nid']['id'] = 'nid';
$handler->display->display_options['fields']['nid']['table'] = 'node';
$handler->display->display_options['fields']['nid']['field'] = 'nid';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Field: Content: Address */
$handler->display->display_options['fields']['field_address']['id'] = 'field_address';
$handler->display->display_options['fields']['field_address']['table'] = 'field_data_field_address';
$handler->display->display_options['fields']['field_address']['field'] = 'field_address';
/* Field: Bulk operations: Content */
$handler->display->display_options['fields']['views_bulk_operations']['id'] = 'views_bulk_operations';
$handler->display->display_options['fields']['views_bulk_operations']['table'] = 'node';
$handler->display->display_options['fields']['views_bulk_operations']['field'] = 'views_bulk_operations';
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['display_type'] = '0';
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['enable_select_all_pages'] = 1;
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['row_clickable'] = 1;
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['force_single'] = 0;
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['entity_load_capacity'] = '10';
/* Contextual filter: Content: Address (field_address) */
$handler->display->display_options['arguments']['field_address_value']['id'] = 'field_address_value';
$handler->display->display_options['arguments']['field_address_value']['table'] = 'field_data_field_address';
$handler->display->display_options['arguments']['field_address_value']['field'] = 'field_address_value';
$handler->display->display_options['arguments']['field_address_value']['default_action'] = 'default';
$handler->display->display_options['arguments']['field_address_value']['default_argument_type'] = 'raw';
$handler->display->display_options['arguments']['field_address_value']['default_argument_options']['index'] = '0';
$handler->display->display_options['arguments']['field_address_value']['summary']['number_of_records'] = '0';
$handler->display->display_options['arguments']['field_address_value']['summary']['format'] = 'default_summary';
$handler->display->display_options['arguments']['field_address_value']['summary_options']['items_per_page'] = '25';
$handler->display->display_options['arguments']['field_address_value']['limit'] = '0';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
  'article' => 'article',
);

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['path'] = 'relevant-nodes';

Step 2 - Create a Rule

Create a rule like so:

  • Rules Event: something like "Before saving content of type Article" seems most appropriate, though you can use any variation that fits.

  • Rules Condition: "Check number of results returned by a VBO view". And select the VBO view created in the previous step. In doing so, you will be asked to "specify arguments to pass to the view, one per line. You may use token replacement patterns.". The token to be entered there is node:field-address. If the number of results is 1 or more, then you know the value already exists. So within Minimum number of results you should enter the value 1.

  • Rules Action: this is pretty much up to your own imagination (your question doesn't specify what should happen ...). For example if the Rules Condition is TRUE, you could use "Set a data value", to set the value of that field to whatever fits. Maybe also display an appropriate message, such as (when trying to set the value to HomeIsWhereMyStellaIs):

    The value "HomeIsWhereMyStellaIs" has already been used in at least 1 other node ...

Here is an export of a Rule that does (without such "Set a value" though) what is described above (if you have the Rules UI enabled, and a field with the machine name field_address, you should be able to just import this rule):

{ "rules_prevent_multiple_nodes_with_same_field_value" : {
    "LABEL" : "Prevent multiple nodes with same field value",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "views_bulk_operations", "rules" ],
    "ON" : { "node_presave--article" : { "bundle" : "article" } },
    "IF" : [
      { "views_bulk_operations_condition_result_count" : {
          "view" : "relevant_nodes|page",
          "args" : [ "node:field-address" ],
          "minimum" : "1"
        }
      }
    ],
    "DO" : [
      { "drupal_message" : {
          "message" : "The value \u0022[node:field-address]\u0022 has already been used in at least 1 other node ...",
          "type" : "error"
        }
      }
    ]
  }
}

Note that my Rules Event is limited to "Article" (change to whatever fits), and replace (prior to trying to import this rule) the machine name of field_address to whatever other machine name your field.

Done!

PS: I'm assuming this is about D7.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.