Here is my use case:
1-I use VBO to select some nodes in a view
2-I run a custom action on those nodes
3-In function executeMultiple of my custom action, I populate an array; something like
private array_that_should_be_used_in_the_redirection;
public function executeMultiple(array $objects) {
$results = [];
foreach ($objects as $entity) {
$results[] = $this->execute($entity);
$this->array_that_should_be_used_in_the_redirection[]=...some logic;
}
return $results;
}
Thus my question is: how to redirect to a form after a VBO run.
Knowing that this form must use $this->array_that_should_be_used_in_the_redirection as an argument.
Where I am:
In function executeProcessing (class ViewsBulkOperationsActionProcessor) I found that the finished function is called at the end of the process:
ViewsBulkOperationsBatch::finished(TRUE, $results, []);
But I don't know how/where to override/subclass the ViewsBulkOperationsActionProcessor in order to redirect to a form
(Or maybe there is a better way to achive this)
Comments
Comment #3
graber commentedHi, just made it possible with the above commit.
You do it like this from you action plugin:
Comment #4
graber commentedof course add a the Drupal\Core\Url namespace and conform to standards etc ;)
Comment #5
graber commentedalso this works only if batching is enabled so would be good to have that for non-batch operations as well but that needs a change in a few places. For later if someone will need this.
Comment #6
johnpitcairn commentedI could use a non-batched version.
I don't really want to do much processing in the action apart from assembling a set of URL parameters based on the selected entities, then redirect to a custom controller route that will do most of my processing. I guess I can set my batch size high, but non-batched would be good.
Comment #7
johnpitcairn commentedActually it's likely we will need to batch the processing somewhere anyway, so we might as well do our processing in the action and stash the result in private tempstore for the redirect page controller to pick up. Thanks, this is working well.
Comment #8
dunebl@graber This is so nice you have done this!
Same as John Pitcairn, I had to use the private tempstore to send the results to my redirected form
Here is how I have implemented this feature (for anybody who would like to do the same)... :
1-Add the user.private_tempstore service as dependency injection in my plugin action [not mandatory]
2-Adapt the setContext funtion in my plugin action:
Question: looking at this code, I have the feeling that it could be better to inherit ViewsBulkOperationsActionBase instead of ActionBase... and if yes, maybe this code could be included in ViewsBulkOperationsActionBase
3-Set the redirect url and store the array within executeMultiple
4-And here is the code to create the form (with dependency injection)
5-route definition:
I hope, that this could help someone
Comment #9
johnpitcairn commentedI'm extending ViewsBulkOperationsActionBase.
Note
user.private_tempstoreis deprecated - you should usetempstore.private, which is fully backwards-compatible.Comment #10
dunebl@John Pitcairn: thank you for the hint!
@Graber Maybe I don't understand the goal, but why should we write the setContext method (if extending ViewsBulkOperationsActionBase). I mean why not updating the setContext method in ViewsBulkOperationsActionBase with this line
$this->context['results'] = &$context['results'];?Comment #11
graber commented@DuneBL the same reason why we have interfaces and method and property visibility declarations. If we don't have to give access to something - we don't. At least that's the way I see it, this makes everything more controllable and reduces possible vulnerabilities. I guess some older dev could explain it better ;)
Comment #12
dunebl@Graber ok, I think it goes over my head, but adding this line will not provide any access to the user a of the class. It will only simplify the way he will have to comply with the url redirection... Don't take your time to answer me, as this is not an educated comment. And thank you again!
Comment #13
svendecabooterMy use case might be a bit different, but here is how I solved a redirect from VBO, that does something with the selected entities:
My custom action plugin:
Key element here is the "confirm_form_route_name" property in the annotation, which is the route where we want to redirect to, after having selected entities via VBO.
Then I have a custom form, which in my case is a content entity form where I want to pre-select the entities that were selected via VBO:
[VIEW_NAME] & [DISPLAY_ID] are the View machine name, and the Views display ID / name, where the VBO checkboxes where added.
Comment #14
graber commentedSwitching to fixed, please feel free to reopen if some additional improvements can be made to the API.
Comment #15
graber commentedComment #17
graber commentedPlease check #3207304: Allow to override the batch finished method. for a new API, when this is merged we'll be able to override the entire batch finished callback with redirection in any action class.