The rules export explicitly adds the name of the module to the rule categories. See rules.export.inc:
$rule_set['categories'][$module] = $module;
and
$rule['#categories'][$module] = $module;
However, I already categorized my rules with the module name I had in mind to export the rules to with features. Now when exporting those rules, I see in the code:
'#categories' => array(
'0' => 'mymodulename',
'mymodulename' => 'mymodulename'
),
First remark on this is that rules internally stores just a plain array instead of a hash for categories. If the rules export needs to add the module name explicitly, it should also just use the next free array key instead of using the module name as array key.
Second, when enabling the exported module on another site, the same category name appears twice. Also strange things are happening with some rules inside rules sets which are getting duplicated. I guess duplicate categories caused rules from features somehow to get duplicated as well.
I removed both lines of code mentioned above from rules.export.inc and then everything seems to work fine. My suggestion to fix this, is to only add the module name as a category if it's not in the category list yet.
Comments
Comment #1
David Stosik commentedHello,
Same bug here.
How to reproduce: create a rule set, and set its category to "test_category", create a rule inside this rule set, and set its category to the same value, "test_category".
Now, with features, export rules with category "test_category". The code generated contains two instances of the rule defined previously.
Now modify the rule to remove its category "test_category" (or rename it), and then export the feature again : the rule isn't duplicated anymore.
This is because rules_export_items() (rules.export.inc:13) or rules_item_type_invoke() (which is called inside rules_export_items()), when exporting a rule set, export all its rules, wether they have already been exported as standalone rules before, or not. This leads to duplicate entries, when they do.
You can avoid this bug (this IS a bug) by not setting the same category for rule set and the rules it contains (and also not importing two rules categories which coul overlap).
Regards,
David
Comment #2
fagoIndeed. We should just check whether it's already there using in_array(). Perhaps someone wants to tackle that? :)
Comment #3
David Stosik commentedThere's some code ensuring that two rules in the export don't get the same key, by adding a counter.
Function rules_item_rule_export(), rules.export.inc:67
Why is this code here ? Shouldn't it try to avoid duplicates instead ?
Comment #4
fagoWhen exporting multiple rules, the other ones aren't yet in the system. So we have to use a counter to ensure the generated names are unique. Also it successfully avoids duplicate rule names.
Comment #5
David Stosik commentedYeah, but is there a unique id I can find in $export that could tell me if the rule I am exporting is already in there ?
I can't use the key machinename_counter, as we're sure it is unique...
You suggested using in_array() : is this safe to use it with complex structures (arrays, objects) ?
Comment #6
coreyp_1 commentedSubscribing.
Comment #7
fagoI've committed a fix.
Comment #9
kevinwalsh commentedSorry to re-open, but I'm still experiencing this with 6.x-1.3 from September 2nd 2010, every time i run
drush fuit duplicates all the rules again. Most recent dev version is currently August 17th. Should i be using the dev version?Comment #10
kevinwalsh commentedComment #11
dsayswhat commentedI'm also seeing duplicate rules when I export a feature. However, I'm not using rule sets.
In looking at rules.export.inc, I'm seeing that rules are renamed upon export via features - instead of rules_1, on rules.export.inc:75 shows you renaming the rule to be prefixed by the new feature name...foo_1.
My intent is to capture my configuration in code, and continue to work with it on the same site from which it was exported. With other features enabled modules, I can export, use the feature on the current site, and continue to work with a view, panel, imagecache preset, etc and keep updating that same feature via drush to capture further changes.
When I do that with Rules what I end up getting is two of the same rule, distinguished by their names, rules_1 and foo_1. Views, by contrast, doesn't keep two views with different names, instead it changes the existing view so that it indicates it's storage is in code, and notices if you make changes to your view that might need to be exported.
Rules feature integration would be much more consistent ( and useful to me personally ) with the rest of the features ecosystem if it behaved in that same way...is that a goal for Rules under Drupal 6? Can I be of help in some way? I'm not an exportables guru, but I can code.
Comment #12
dsayswhat commentedSorry - I missed #419644: Use CTools to export. It sounds like you don't plan to integrate with ctools exportables in 1.x.
Any chance you'll reconsider that for rules 1.3 or greater? It's been a while since the idea was floated, and it would make Rules enormously helpful in a features-driven environment. Again, if I can be of help, I'd gladly give it a shot, time permitting.
Comment #13
dsayswhat commentedFWIW -
Here's what you can do if you want Rules to behave like some other modules do when exporting to features:
The extra steps make me nervous, but they appear to be working fine now. Changes made to feature-controlled rules show up when exported, etc. Rules just can't clean up after itself without CTools handling exports for it. A little manual help is required.
Comment #14
fagoThis issue is not about duplicated rules - but rule categories. There is another issue for duplicated rules.
Comment #15
mitchell commentedMoving to "Provided Module Integrations" component.