Can't update $value in PULL_ENTITY_VALUE event subscriber

Created on 5 May 2023, over 1 year ago
Updated 20 May 2024, 7 months ago

Problem/Motivation

I'm confused about how to change $value in a PULL_ENTITY_VALUE event subscriber. The SalesforcePullEntityValueEvent class constructor passes &$value by reference, but its contents are immediately copied to the protected $entityValue property. How am I supposed to update the $value?

This doesn't work without patching SalesforcePullEntityValueEvent.php:

class MySalesforceSubscriber implements EventSubscriberInterface {

  public function onSalesforcePullEntityValue(SalesforcePullEntityValueEvent $event) {
    $value = &$event->getEntityValue();
    if (is_null($value) {
      $value = 42;
    }
  }

  public static function getSubscribedEvents() {
    return [
      SalesforceEvents::PULL_ENTITY_VALUE => ['onSalesforcePullEntityValue'],
    ];
  }
}
πŸ’¬ Support request
Status

Active

Version

5.0

Component

salesforce_mapping.module

Created by

πŸ‡ΊπŸ‡ΈUnited States audiomason

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @audiomason
  • πŸ‡ΊπŸ‡ΈUnited States audiomason

    added patch

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 9.5.x + Environment: PHP 8.0 & MySQL 5.7 (--ignore-platform-reqs)
    last update over 1 year ago
    79 pass
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update over 1 year ago
    79 pass
  • πŸ‡ΊπŸ‡¦Ukraine knyshuk.vova

    @audiomason, nice job for finding such an issue. I have some adjustments for your patch.

    It's better to use a setter method setEntityValue(), which indicates that change is intentional and controlled, rather than getting the reference of the value and change it directly.

      public function __construct(&$value, SalesforceMappingFieldPluginInterface $fieldPlugin, MappedObjectInterface $mappedObject) {
        $this->entityValue = &$value;
        // rest of code...
      }
    
      /**
       * Setter for entity value.
       *
       * @param mixed $value
       *   The value to be assigned.
       */
      public function setEntityValue($value) {
        $this->entityValue = $value;
      }
    
  • πŸ‡ΊπŸ‡¦Ukraine knyshuk.vova

    added patch according to above comment

  • I was having the same problem, but found the way to do this without a patch.

    class MySalesforceSubscriber implements EventSubscriberInterface {
    
      public function onSalesforcePullEntityValue(SalesforcePullEntityValueEvent $event) {
        $value = $event->getEntityValue();
        if (is_null($value->getValue())) {
          $value->setValue(42);
        }
      }
    
      public static function getSubscribedEvents() {
        return [
          SalesforceEvents::PULL_ENTITY_VALUE => ['onSalesforcePullEntityValue'],
        ];
      }
    }
    

    You need to use setValue() and you don't need to pass by reference.

    This is not clear, an example added to SalesforceExampleSubscriber would be helpful.
    Also, should the pass by reference be removed from the __construct in SalesforcePullEntityValueEvent.php? As far as I can tell it does nothing.

  • πŸ‡ΊπŸ‡¦Ukraine knyshuk.vova

    Confirm that solution from #5resolves the issue.

    I agree that the example should be added to SalesforceExampleSubscriber

Production build 0.71.5 2024