The "modify entity values" action has a specific behavior for multiple-value properties (such as "User roles") and fields (any field with cardinality bigger than 1):
It adds an "Add new value(s) to %label, instead of overwriting the existing values." checkbox below the widget, with obvious results.

For this action to be a complete replacement for the old "modify taxonomy" action (#1142062: Port taxonomy term operations to d7 ) we also need a "delete" mode, which will delete the selected values if found in the values of the passed entity.
Of course, this can only work with multi-value fields that have a selection of predefined items (such as product reference fields), can't work for free-entry elements such as textfields.
So the code should be modified, instead of the "Add" checkbox we should have three "mode" radio buttons (replace/add/delete). The delete mode should only be supported for fields with the property_info type of list<$entity_type> (and perhaps list and list, need to check).

There's also a question of how to have this look nice in the UI. Thinking of perhaps having a "Options for field %field_label" fieldset around it.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

blazindrop’s picture

+1

This is a good idea. We could use this for taxonomy terms on nodes. In some cases we may want to remove just an occurrence of a term while *preserving* the others.

Madrugada’s picture

+1

I just ran into this problem. I wanted to delete one taxonomy term on a group of nodes and preserve all other terms.

Happy to see that the issue is here on the queue.

micnap’s picture

+1

Just ran into this problem too.

micnap’s picture

Here's a patch to get things started. The main thing it provides is the code to remove the item(s) from the multidimensional array. The rest is just to get it working for my specific use case (removing taxonomy terms). The checkboxes really need to be turned into radios.

Mickey

micnap’s picture

Ugh. Sloppy patch. Sorry about the extra spaces.

Mickey

el1_1el’s picture

this info may or may not be useful, but i tried the patch on some content taxonomy fields (I did not try straight up bo:tax term as it wouldnt help for my use case - too many vocabs). it did not seem to have any effect on tagged fields, but it partially worked on hierarchical select fields, removing the top level term and leaving its sub-terms.

bojanz’s picture

Status: Active » Needs review

Updating status.

philipz’s picture

#4 gets the job done but it definitely needs more work. The main problem as @micnap said is turning the checkboxes into radios and also adding a new default option for more clarity so this would look something like that:

Choose what to do with selected value(s).
- Overwrite %label with new value(s). (DEFAULT)
- Add new value(s) to %label, instead of overwriting the existing values.
- Remove value(s) from %label. Other existing values will remain.

I'll experiment with it more and let you know.

micnap’s picture

Here's a second attempt. It changes the checkboxes to radios. It still doesn't work for removing heirarchies, just the chosen terms. And I'm not wild about the default automatically overwriting the field with the new values. That seems like it's a disaster waiting to happen. So, it still needs more work but it's start.

philipz’s picture

You used "Add new value(s) to %label, instead of overwriting..." both as default (title) and first radio option. I'm guessing the default and title should be "Overwrite %label with new value(s)."
Moreover I think that Overwrite option should be a radio too with 'overwrite' value. The default option should be set to "append" solving the disaster you mentioned :)
Finally the radios title could be something like 'Choose what to do with selected terms'.

I'll try to find time today to make a patch on top of yours.

micnap’s picture

Good points. Can you give this one a try?

micnap’s picture

Scratch that last patch. It can't default to append the way it is or non taxonomy-reference-term fields don't work. Back to the drawing board...

micnap’s picture

Alright, give this one a spin. Feeling like it's a bit hackish but it seems to be working. Still to be done is add logic to not add a term if it already exists.

philipz’s picture

Testing #13 right now. The radios are looking very good. Applying the path throws some line/space warnings but thats not the most important thing right now ;)
Appending terms works as expected but deleting and overwriting does not as both seem to be appending too. I'll look into the patch more in the morning.

Preventing appending duplicate terms is super important too as it happens often in daily content management.

Thanks for working on this!

micnap’s picture

Thanks for testing philipz. I just applied the patch to a dev version of vbo on a default install of Drupal with stable releases of dependencies and cannot reproduce. Can you share details of the fields and terms that it's not working on? Do you have a heirarchy in your terms? If so, I haven't included support for heirarchies, just top level terms.

micnap’s picture

Ah. I see. If you have any heirarchy in your terms at all, the "Delete value(s). Other existing values will remain" doesn't work at all, not even for the top level terms. Oops.

micnap’s picture

Ok, hope this one's the ticket. Give it a try. Duplicate terms get appended still. Didn't work on that yet. But the delete and overwrite should fully work - for heirarchical vocabs too. Whitespace issues should be fixed too. And it can be applied from within the vbo module instead of the root of the site so no path issues.

philipz’s picture

I've updated vbo to latest dev and patch #17 applies cleanly.
Unfortunately still overwriting and deleting terms keeps adding (and adding as duplicates) selected terms. My terms is default Tags vocabulary with no hierarchy.

micnap’s picture

Hmmm...I'm at a loss. I just tried it in another new default install of D7.22 with entity 1.1, ctools 1.3, views 3.7, and vbo 7.x-3.1+2-dev and deleting and overwriting worked. I tried both with heirarchies and just top level terms using the default Tags vocab in article content type. I must be missing something but I can't reproduce to figure out what it is. Help!

philipz’s picture

Sorry I had no time recently to test this more. I've updated all the modules to use the same as you wrote but the terms still can't be overwritten nor deleted.
I'm testing this on drupal 7.19 so that may be a problem too. As soon as I update it and debug a little I'll let you know what happens in my installation.

philipz’s picture

Finally I've updated my Drupal but still the problem remains. I've debugged a little and I think I know what's happening.
The problem is I have multiple taxonomy fields on my content type. When I select the one I want to delete terms from the dpm of $context['operations'] shows ['append'] contains all the taxonomy fields except the one selected to be deleted which sits in ['delete'] as it should.

Now I'm not sure if those not selected term fields are supposed to be in the ['append'] operation and the if condition needs to be changed OR the terms that were not selected should not be in $context['operation'] array at all.

philipz’s picture

Here's patch from #17 with changed operation condition. Basically instead of checking just if

isset($context['operations']['append']['bundle_' . $bundle_name])

it checks if the selected field is in selected operation in $context like this

in_array($key, $context['operations']['append']['bundle_' . $bundle_name])

Works for append, delete and overwrite.

micnap’s picture

Aha! Multiple taxonomy fields. Yay! Thanks for figuring it out!

Yuri’s picture

The patch in #22 is not working any more..any updates?

philipz’s picture

Component: Core » Actions
Issue summary: View changes
FileSize
6.65 KB

Here's a re-roll. Tested with VBO 3.2 which is currently newer than dev.

anrikun’s picture

Here is an improved patch:
- cleaner code
- should work with most multiple fields (not tested on all types though)

anrikun’s picture

anrikun’s picture

Minor change: removed points from option texts.

anrikun’s picture

BarisW’s picture

Status: Needs review » Reviewed & tested by the community

Wow, thanks for this. Patch works great, and now I can finally remove references to nodes instead of replacing/adding them.

Please commit ;)

ikeigenwijs’s picture

Pleas commit, still applies cleanly to current dev

wickwood’s picture

Patch #29 applied cleanly for me as well and everything worked. Thanks to everyone who worked on this!

Rustan’s picture

Patch #29 works fine for me as well.

adrien.felipe’s picture

Great patch #29. Works nicely, thanks.

whthat’s picture

Awesome feature addition, works great!

joseph.olstad’s picture

+RTBC,

Great work everyone!

I was going to write my own hook_alter for this essential functionality until I found this patch.

This is required in order to remove entity references or term references to fields, without this I was going to make a 'None' term because if nothing is entered nothing happens and previously there were no options for "remove". Then I thought about writing a hook_alter to do this, then I found this patch which does everything that is required.

Thanks ! Please commit!

anrikun’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
6.26 KB

Too bad the patch was not included in latest release 7.x-3.4.
Anyway, here's a patch rerolled for latest dev.

joelpittet’s picture

Status: Needs review » Needs work

Not sure I'm ready to add features to VBO that are not minor but this patch needs some clean-up for coding standards and explanation/documentation around some of the code like unset($item); line spuriously added.

joseph.olstad’s picture

How about make a 7.x-4.x branch, put this in, then we run 'coder review' for coding standards and make the changes, then maybe tag a 7.x-4.0-alpha1 release. as for isset($item) , appears that $item wasn't being used at all, and there's a second token replace, so removed the useless one.

See new patch and interdiff.

joseph.olstad’s picture

Status: Needs work » Needs review
SocialNicheGuru’s picture

Status: Needs review » Needs work

patch -p1 < vbo_modify_action_remove_option_prevent_duplicates-1421656-39.patch
patching file actions/modify.action.inc
Hunk #2 FAILED at 47.
1 out of 8 hunks FAILED -- saving rejects to file actions/modify.action.inc.rej
$ more actions/modify.action.inc.rej
--- actions/modify.action.inc
+++ actions/modify.action.inc
@@ -47,20 +48,19 @@
// already been figured out if this field is translatable or not and
// applied the appropriate language code to the field.
$language = key($pseudo_entity->{$key});
- // Replace any tokens that might exist in the field columns.
- foreach ($pseudo_entity->{$key}[$language] as $delta => &$item) {
- foreach ($item as $column => $value) {
- if (is_string($value)) {
- $item[$column] = token_replace($value, array($context['entity_type'] => $entity), array('sanitize' => FAL
SE));
- }
- }
- }

if (in_array($key, $context['append']['bundle_' . $bundle_name]) && !empty($entity->$key)) {
- $entity->{$key}[$language] = array_merge($entity->{$key}[$language], $pseudo_entity->{$key}[$language]);
+ // Append the new items while preventing duplicates. We perform the
+ // comparison between existing and new field items on their first
+ // columns only.
+ $field_info = field_info_field($key);
+ $value_key = key($field_info['columns']);
+ $items = _views_bulk_operations_modify_action_normalize_items($entity->{$key}[$language], $value_key);
+ $pseudo_items = _views_bulk_operations_modify_action_normalize_items($pseudo_entity->{$key}[$language], $val
ue_key);
+ $diff = array_diff($pseudo_items, $items);
+ $entity->{$key}[$language] = array_values(array_merge($entity->{$key}[$language], array_intersect_key($pseud
o_entity->{$key}[$language], $diff)));

// Check if we breached cardinality, and notify the user.
- $field_info = field_info_field($key);
$field_count = count($entity->{$key}[$language]);
if ($field_info['cardinality'] != FIELD_CARDINALITY_UNLIMITED && $field_count > $field_info['cardinality']) {
$entity_label = entity_label($context['entity_type'], $entity);

ikeigenwijs’s picture

I rerolled the patch in #39

the source of the problem is for people with other versions than the current dev.

current dev has:

       if (in_array($key, $context['append']['bundle_' . $bundle_name]) && !empty($entity->{$key})) {

old patch looked for:

       if (in_array($key, $context['append']['bundle_' . $bundle_name]) && !empty($entity->$key)) {
ikeigenwijs’s picture

On a side note

In our use case we want regular user to be able to add terms but not delete or overwrite.
We fixed this in code in this issue
https://www.drupal.org/node/2046653

The nicer solution would be to allow the site builder to choose in the view setup which options that would be available for the user to select.
It would be nice if this could be integrated

In our use case:
Permission on the field itself is not a solution.
The regular user can add, delete, modify tags on a per node basis, so permissions are granted.
The regular user can add only using vbo (protection for changes beyond there intention or comprehension)
Only curaters can use the more dangerous delete and overwrite on vbo site wide scale.

ikeigenwijs’s picture

Status: Needs work » Needs review
jannis’s picture

RTBC +1, #42 applies cleanly to v7.x-3.x-dev and works as advertised. this would be a useful addition to the module

izmeez’s picture

Status: Needs review » Reviewed & tested by the community

Patch in #42 applies cleanly to 7.x-3.x-dev (2018-05-17) and has had one RTBC in comment #45

ikeigenwijs’s picture

yes pleas, we use it for over 3 years on a large site on a daily basis more than 1000 node edits a day.

izmeez’s picture

Patch in #42 still applies without difficulty to latest 7.x-3.x-dev (2019-05-16).

Chris Matthews’s picture

rickharington’s picture

Very weird. I assume something was added to the modify.action.inc on 7.x-3.x-dev on 2019/05/17 because when I apply the patch from #42 I get the following;

ParseError: syntax error, unexpected 'elseif' (T_ELSEIF) in module_load_include() (line 72 of /usr/www/users/relecpaxes/admin.relecart.com/sites/all/modules/views_bulk_operations-7_x-3_5_zip_0/views_bulk_operations/actions/modify.action.inc).

Even though @izmeez said they applied the patch cleanly on the 2019-05-16.
"Patch in #42 still applies without difficulty to latest 7.x-3.x-dev (2019-05-16)."

I do see that the latest release date on dev was 2019/05/17

Any help on how I can fix this patch would be super helpful.

izmeez’s picture

@rickharington are you having trouble applying the patch to 7.x-3.5 or to 7.x-3.x-dev?

The patch is meant to apply to the latest dev so it is ready for commit.

It looks like there were 3 commits since the 3.5 release 2018-05-08 https://git.drupalcode.org/project/views_bulk_operations/commits/7.x-3.x

The patch is 2 years old, maybe the maintainer(s) will consider a commit.

rickharington’s picture

@izmeez I tried to apply to both 7.x-3.5 and to 7.x-3.x-dev and both gave the error below;

ParseError: syntax error, unexpected 'elseif' (T_ELSEIF) in module_load_include() (line 72 of /usr/www/users/relecpaxes/admin.relecart.com/sites/all/modules/views_bulk_operations-7_x-3_5_zip_0/views_bulk_operations/actions/modify.action.inc).

I see that Issue #2973282 did make an adjustment to modify.action.inc but shouldn't have had an impact on the ELSEIF

https://git.drupalcode.org/project/views_bulk_operations/commit/dd52428b...

Would be great if this could be committed.

rickharington’s picture

I was an absolute idiot. Obviously messed up the manual patch. Patched through terminal everything is working perfectly on #42 applied to latest dev. Apologies for all the comments. Thanks everyone.

ikeigenwijs’s picture

Patch in #42 still applies without difficulty to latest 7.x-3.x-dev (16-08-2020).

Did not make it in 3.6 so patching everything again.

paintingguy’s picture

Hi, I'm trying to do this on Drupal 9 VBO. I can easily add bulk terms to nodes but cannot remove ones in bulk that I do not want. Is there an action that I can add to do this somehow?

Thank you for any help.

Graber’s picture

@paintingguy, VBO 8.x+ doesn't have that, it's separated in Views Bulk Edit module. You can create an issue there.