it-swarm.com.de

Wie werden alle Felder abgerufen, die beim Speichern der Entität geändert wurden (Formular senden)?

Ich versuche einen effizienten Weg zu finden, um die Feldnamen/-werte zu erhalten, die aktualisiert wurden. Es ähnelt dem, was das Diff-Modul zum Berechnen von Änderungen auf einem Knoten tut, ist jedoch nicht so detailliert. Ich möchte nur sehen, welche Felder aktualisiert wurden, wenn ein Benutzer eine Entität speichert. Beispielsweise kann ein Benutzer den Titel nicht ändern, aber den Text ändern. Ich möchte eine API-Funktion erstellen, die das zurückgibt. so etwas wie dieser Pseudocode:

// possibly on presave or form submit. 
function my_module_entity_presave() {
    // Return only the fields values that are not similar to the original node: 
    $modified = $entity->getModifiedFields();
}

und die Methode könnte so etwas wie dieser Psudo-Code sein:

public function getModifiedFields() {
  $original = $this->originalFieldsValues();
  $new = $this->newFieldValues();
  // compare original with new
  // finally return only modified fields name values.
  $modified = ['title' => 'new value', 'body' => 'new value' ...];
  return $modified 
}
2
awm

Wenn Sie sich im Presave-Hook befinden, hat das aktualisierte Objekt $node$node->original, Dies ist der Knoten, bevor Änderungen vorgenommen wurden.

Knoten haben auch eine $node->toArray() -Methode, die das Objekt in ein mehrdimensionales assoziatives Array reduziert.

Also das

array_keys(DiffArray::diffAssocRecursive($node->toArray(), $node->original->toArray())

sollte

  1. Nehmen Sie die $node Und $node->original Und konvertieren Sie sie in Arrays.
  2. Führen Sie die beiden Arrays durch eine der Hilfsklassen Drupal), die Unterschiede in mehrdimensionalen assoziativen Arrays erzeugen.
  3. Geben Sie die Tasten der obersten Ebene zurück. Aufgrund der Art und Weise, wie Knoten erstellt werden, sind dies alle geänderten Eigenschafts- und Feldnamen.
3
mpdonadio

Hier ist ein Auszug aus einer Methode, mit der ich feststelle, ob sich eine Entität geändert hat. Ich habe es ein wenig angepasst, um die Namen für Sie zurückzugeben. Möglicherweise müssen Sie es stärker an Ihre spezifischen Bedürfnisse anpassen.

mymodule> src> GaryFunctions.php

<?php

/**
 * File for holding helper functions user by Gary
 */


namespace Drupal\mymodule;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Entity\Entity\EntityViewDisplay;

class GaryFunctions {

  /**
   * Check if entity field content has changed
   * @param  EntityInterface $entity     The entity being saved
   * @return array                    A list of changed field names
   */
  public function entityHasChanged(EntityInterface $entity) {
    $changed_fields = [];
    if (!$entity->original) {
      return $changed_fields;
    }
    $field_names = $this->getFieldList($entity->bundle(), $entity->getEntityTypeId());
    foreach($field_names as $key => $field_name) {
      if($entity->hasField($field_name) && $field_name != 'field_comments' && !$entity->get($field_name)->equals($entity->original->get($field_name))){
        $changed_fields[] = $field_name;
        // $entity->get($field_name)->getValue();
      }
    }
     return $changed_fields;
  }


  /**
   * Get list of field names from bundle
   * @param  string $bundle Bundle name
   * @return array         Array of field names
   */
  public function getFieldList($bundle, $entity_type_id) {
    $fields_by_weight = [];
    $bundle_fields = \Drupal::entityTypeManager()
      ->getStorage('entity_view_display')
      ->load($entity_type_id . '.' . $bundle . '.' . 'default')
      ->getComponents();

    foreach ($bundle_fields as $name => $options) {
      $fields_by_weight[] = $name;
    }
    return $fields_by_weight;
  }

}

mymodule> mymodule.module

<?php

use Drupal\Core\Entity\EntityInterface;
use Drupal\mymodule\GaryFunctions;

function mymodule_entity_presave(EntityInterface $entity) {
  $helper = new GaryFunctions;

  switch ($entity->bundle()){

    case 'projects':
      $changed_fields = $helper->entityHasChanged($entity);
      if (!empty($changed_fields)) {
        print_r($changed_fields);
      } else {
        print 'didnt change';
      }
    break;

    default:
    break;
  }

}
2
Matt Campbell

Sie können $node->original Verwenden, es gibt Zugriff auf die ursprünglichen Knotenwerte. Nehmen wir also an, dass das Feld, das Sie überprüfen möchten, foo_field Ist:

function myModule_node_presave($node) {
  if ($node->getType() == 'my_content_type') {
    if ($node->original->foo_field != $node->foo_field) {
      // Do what you want here.
    }
  }
}
0
MiharbKH