Hi,
First off, if people don't want me asking technical questions here just let me know and I'll stop, I've been posting elsewhere without much response.
I realize people are getting ready for the Drupal Summit, but I have a couple of questions about the Rules module if anyone has any spare bandwidth.
I have a content type called Event, which has a begin date and an end date. I'm trying to create a rule so that every time a user saves an Event the rule checks all other events to see if the new Event overlaps with any of the other Events that have been entered into the system.
I've created a view which returns an Event type and which has a bulk operations field (from the View Bulk Operations module).
I've created a rule and in the Actions part of the rule I've loaded the entity objects from the view and created a loop to loop over the retrieved Events.
The first problem I'm having is that I can't access the begin date and end date field of the Event, only fields such as node id. The second problem is that I only see a way of doing very simple comparisons in the conditional part of the rule, nothing like what I want to do (compare two sets of dates to determine an overlap).
Is there a way of doing this in rules that I'm not seeing, is there an alternative to rules I don't know about, or should I take this as an opportunity to learn how to write a custom module?
Thanks, and sorry for the long post.
Cliff
Comments
If you enable the PHP filter
If you enable the PHP filter module (part of core, at least until D8), you can execute custom PHP code for your rule's condition. That's usually not advisable unless you have no other options, simply because if you accidentally write code that triggers a fatal error, you may loose access to your site (or at least part of your site) and then have to manually access the database to correct the code.
Probably a better option is to create a very simple custom module for adding extra validation to your node form. In that module, you would only need to include 2 functions: one for letting your node edit form know that you would like to perform some extra validation on node save, and one that performs that validation. So the first function would use hook_form_FORM_ID_alter(). It would look something like this:
/**
* Implements hook_form_FORM_ID_alter().
*
* MY_MODULE should be replaced with the machine name of your module.
* If the machine name of your content type is NOT 'event', then replace 'event'
* below with your machine name.
*/
function MY_MODULE_form_event_node_form_alter(&$form, &$form_state, $form_id) {
// Define your custom validation callback here.
$form['#validate'][] = 'MY_MODULE_event_node_form_validate';
}
The validation callback, would look something like this:
/**
* Validation callback for event node forms.
*/
function MY_MODULE_event_node_form_validate($form, &$form_state) {
// Validate the values of the submitted form compared to existing events here.
}
In the validation callback, $form_state['values'] is an array that contains all of the submitted values of the new/edited node. You should be able to find the values of your date fields there. Rather than using a view to get all the other event nodes, try performing a simple database query that will return the node ids of all events. Then load those nodes one at a time as you cycle through the results of your query and compare the dates in your form data with the loaded node's dates. If you feel comfortable with the database abstraction layer in Drupal, you could also just query the date fields for all events so you don't have to use up resources performing node_load for each node id.
Then, if you find an overlap in dates, use either:
drupal_set_message(t('Your error message'), 'error');
or better...
form_set_error($form['your_date_field'], t('Your error message'));
The latter should highlight your fields when the form reloads. Hope that's not too much to digest (AND I hope it is correct!).
You don't need a PHP filter,
You don't need a PHP filter, or a custom module for this (other than if you want to streamline some of the date comparisons).
What you need is to create a "Rules Component". To get to the entity field, you need to first load that field by using a condition "Entity has field." The problem is, if you're loading entities from a VBO, you're past the condition stage. So the solution is to go into a loop and execute a rules component that has the condition -- and then you can go ahead and act on it.
I'm not sure if there's a data comparison for two sets of items, so you've got a couple choices:
Cheers,
John Locke
http://www.freelock.com
Thanks for the answers
Thanks for the answers guys!
John, already tried the solution you suggested and in the rules component condition I couldn't get "entity has field" to work (the custom fields for the event doesn't show up in the data selector and typing them in results in an invalid data selector error).
As a control, inside the loop in the actual rule I tried to access the date field of an event and also got the same error, I think Drupal doesn't know that an Event type is being retrieved by the views bulk operation.
There's a thread about it here: https://drupal.org/node/1386746
The only person who got this to work (post #5) also switched from a custom content type to a taxonomy term which I suspect is what actually got it to work.
I think a custom module may be the solution in this case, not necessarily a bad thing as it allows me to dig into an area I know nothing about.