Hi, 

I feel like I've done a lot of searching around and there's a lot of answers out there using hook_menu_alter, themes, overriding a service, but this is none of the above. The function that I'm trying to tweak is the execute function in views_bulk_edit contributed module in:

/src/Form/BulkEditFormTrait.php 

<?php

namespace Drupal\views_bulk_edit\Form;

.
.
.

 /**
   * {@inheritdoc}
   */
  public function execute($entity = NULL) {
    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
    $type_id = $entity->getEntityTypeId();
    $bundle = $entity->bundle();
    $result = $this->t('No values changed');

    // Load the edit revision for safe editing.
    $entity = $this->entityRepository->getActive($type_id, $entity->id());

    if (isset($this->configuration[$type_id][$bundle])) {
      $values = $this->configuration[$type_id][$bundle]['values'];
      $change_method = $this->configuration[$type_id][$bundle]['change_method'];

      /******INSERTED CODE*************/
      $token_service = \Drupal::token();
      /******INSERTED CODE*************/
    
      foreach ($values as $field => $value) {
        //token replace
        $entityType = $entity->getEntityType()->getLabel()->render();

         /******INSERTED CODE*************/
        $value[0]['value'] = $token_service->replace($value[0]['value'], array($entityType => $entity));
        /******INSERTED CODE*************/

.
.
.

The "INSERTED CODE" comments are the new code. Basically, I'm trying to add token functionality to the views_bulk_edit module.

How do I override this function in my own custom module? 

Thanks in advance!

Comments

jaypan’s picture

In this situation, I would check whether VBO provides a (post-) execute hook, and then perform your actions there. If no such hook exists, then you can add a submit handler to the form, in a form_alter hook, and then perform your actions there.

An alternative would be to create a new trait, and 'extend' the original trait, override any forms using the trait, and add your own, which would be more of an OOP paradigm, but less of a Drupal paradigm.

Contact me to contract me for D7 -> D10/11 migrations.

kevinwlu’s picture

Hi Jaypan,

Really appreciate the suggestions. 

Option 1: I might be mistaken, but I don't see a post execute hook. 

Option 2: This is what I'm trying now (use a form_alter hook), my custom module's name is coh_user:

/**
 * Implements hook_form_FORM_ID_alter().
 * 
 * to edit "bulk_edit_form" (views_bulk_edit module)
 */

 function coh_user_form_bulk_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  // alters bulk_edit_form submitForm function

  $form['actions']['submit']['#submit'][] = 'coh_user_bulk_edit_form_submit';
}

/**
* Custom submit handler for coh_user_form_bulk_edit_form_alter
*/
function coh_user_bulk_edit_form_submit(&$form, FormStateInterface $form_state) {
  \Drupal::logger('FORM2')->notice('TEST TEST');

}

This seems to work in terms of replacing the default "submitForm" function (shown below)

So from the looks of it, all I need to do is replicate everything the original submitForm is doing, except add in the minor edit I did in the "execute" function (shown in my original post). 

However, I have trouble replicating the views_bulk_edit's original "submitForm" function in my custom module because all the functions and variables that are "$this->..." (shown below) are non-static functions and variables, so as far as I know, these can only be used or accessed with an instantiated object of "BulkEditForm".

//BulkEditForm.php

public function submitForm(array &$form, FormStateInterface $form_state) {

    $this->submitConfigurationForm($form, $form_state);

    foreach ($this->getBulkEditEntityData() as $entity_type_id => $bundle_entities) {
      foreach ($bundle_entities as $bundle => $entities) {

        $entities = $this->entityTypeManager->getStorage($entity_type_id)
          ->loadMultiple(array_keys($entities));
        foreach ($entities as $entity) {

    //THIS IS THE EXECUTE FUNCTION THAT I EDITED BEFORE
          $this->execute($entity);
    //THIS IS THE EXECUTE FUNCTION THAT I EDITED BEFORE
        }
      }
    }

    $this->clearBulkEditEntityData();
  }

And so when I try to copy the code over, I cannot call these functions / variables shown above:

  • submitConfigurationForm() 
  • getBulkEditEntityData()
  • $entityTypeManager

Now, I wish there was someway to fetch the instantiated object of BulkEditForm, but (if i'm correct) it seems that the the hook_form_FORM_ID_alter() function is called before the BulkEditForm object is constructed. 

 The constructor for BulkEditForm is as below; however, I don't know where I can find all these parameters (entityTypeManager, entityRepository, etc.) to pass in to construct it from my custom module. 

/**
   * BulkEditForm constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity type manager.
   * @param \Drupal\Core\Entity\EntityRepositoryInterface $entityRepository
   *   The entity repository service.
   * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
   *   Temp store service.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   * @param \Drupal\Core\Session\AccountInterface $currentUser
   *   The current user.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundleInfo
   *   Bundle info object.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
   *   The entity field manager service.
   */
public function __construct(EntityTypeManagerInterface $entityTypeManager, EntityRepositoryInterface $entityRepository, PrivateTempStoreFactory $temp_store_factory, TimeInterface $time, AccountInterface $currentUser, EntityTypeBundleInfoInterface $bundleInfo, EntityFieldManagerInterface $entityFieldManager) {
    $this->entityTypeManager = $entityTypeManager;
    $this->entityRepository = $entityRepository;
    $this->tempStore = $temp_store_factory->get('entity_edit_multiple');
    $this->time = $time;
    $this->currentUser = $currentUser;
    $this->bundleInfo = $bundleInfo;
    $this->entityFieldManager = $entityFieldManager;
  }

I might be going down the wrong rabbit hole. Feel free to offer any re-direction. 

Option 3:  create a new trait, and 'extend' the original trait, override any forms using the trait, and add your own.

I would like to try this, but how do I go about overriding the original form in my custom module to use my new trait instead of the old one? 

Many thanks!