ノードを保存する前にカスタムフォームで変更されたフィールドを一般的に検出する


12

field_attach_form()を使用して、コンテンツタイプの特定のフィールドをカスタムフォームに追加しています。フォームが送信されると、#validateおよび#submitコールバックからfield_attach_form_validate()およびfield_attach_submit()を呼び出してこれらのフィールドを処理しています。

その時点で、投稿後の準備されたノードオブジェクトを元のノードと比較し、フィールドのいずれかが変更された場合にのみnode_save()を使用します。したがって、最初にを使用して元のノードをロードしますentity_load_unchanged()

残念ながら、元のノードオブジェクトのフィールド配列は、フィールドに変更が加えられていない場合でも、保存を待機している準備済みノードオブジェクトのフィールド配列と一致しないため、単純な "$ old_field == $ new_field 「比較は不可能です。たとえば、元のテキストフィールドは次のように表示されます。

$old_node->field_text['und'][0] = array(
  'value' => 'Test',
  'format' => NULL,
  'safe_value' => 'Test',
);

一方、準備されたノードでは次のように表示されます。

$node->field_text['und'][0] = array(
  'value' => 'Test',
);

「値」キーを比較するだけでよいと思うかもしれませんが、「値」キーを持たない他の要素で構成されたフィールドに遭遇します。例えば、NO「値」キーが存在しないアドレス・フィールドでの見てみましょう対応していない古い、準備ノードの両方のキーがあります。

古いノード

$old_node->field_address['und'][0] = array(
  'country' => 'GB',
  'administrative_area' => 'Test',
  'sub_administrative_area' => NULL,
  'locality' => 'Test',
  'dependent_locality' => NULL,
  'postal_code' => 'Test',
  'thoroughfare' => 'Test',
  'premise' => 'Test',
  'sub_premise' => NULL,
  'organisation_name' => 'Test',
  'name_line' => 'Test',
  'first_name' => NULL,
  'last_name' => NULL,
  'data' => NULL,
);

準備されたノード

$node->field_address['und'][0] = array(
  'element_key' => 'node|page|field_address|und|0',
  'thoroughfare' => 'Test',
  'premise' => 'Test',
  'locality' => 'Test',
  'administrative_area' => 'Test',
  'postal_code' => 'Test',
  'country' => 'GB',
  'organisation_name' => 'Test',
  'name_line' => 'Test',
);

空のフィールドについては、さらに別の矛盾があります。

古いノード

$old_node->field_text = array();

準備されたノード

$node->field_text = array(
  'und' => array(),
);

一般に、フィールドの古い値と新しい値を比較して、変更されたかどうかを検出できますか?
これは単なる不可能ですか?


_field_invoke()「準備された」ノードから完全なフィールド構造を準備し、両方のフィールドをレンダリングして、これらのHTML文字列を単純に比較するために、あなたは遊んだり何か関連することができると思います。ただのアイデア。
kalabro

@kalabroそれは間違いなく行く方法です、しかし、パフォーマンスにとって非常に悪いと感じることは避けられません-一般的にするには、フォーム送信を使用してフィールド情報のすべてのビットを個別にロードする必要があります。または、集計クエリを記述してデータを取得することもできますが、重要なフックが起動しない場合があります。概念的にそれは可能と思われるが、私は実装が非常に複雑になるだろうと思う
クライヴ

@kalabroこの考えはよくわかりません。フィールド構造を準備し、説明したとおりにレンダリングする方法を示すための擬似コードを投稿できますか?
morbiD

回答:


9

これは、ついに、一般的なソリューションとして機能するはずです。すべての入力をしてくれたCliveとmorbiDに感謝します。

ノードの両方のバージョンを次の関数に渡します。そうなる:

  1. 検出されたコンテンツタイプの編集可能なフィールドとその編集可能な列(つまり、カスタムフォームに表示される可能性があるアイテム)をすべて、単一のクエリでデータベースから取得します。

  2. 両方のバージョンで完全に空のフィールドと列を無視します。

  3. 2つのバージョン間で異なる数の値を持つフィールドを変更として扱います。

  4. すべてのフィールド、値、および列を反復処理し、2つのバージョンを比較します。

  5. アイテムが数値である場合は非同一(!=)で、他のアイテムである場合は同一(!==)で比較します。

  6. 検出された最初の変更ですぐにTRUEを返します(1つの変更でノードを再保存する必要があることがわかるので)。

  7. すべての値を比較した後に変更が検出されない場合は、FALSEを返します。

  8. フィールドコレクションを読み込み、スキーマを再帰的に比較し、結果をそれ自体に渡します。これは、ネストされたフィールドコレクションを比較できるようにする必要があります。コードは、フィールドコレクションモジュールに依存しないようにする必要があります。

このコードにバグやタイプミスがあるかどうかを教えてください。

/*
 * Pass both versions of the node to this function. Returns TRUE if it detects any changes and FALSE if not.
 * Pass field collections as an array keyed by field collection ID.
 *
 * @param object $old_entity
 *   The original (stored in the database) node object.
 *   This function may also pass itself a FieldCollectionItemEntity object to compare field collections.
 * @param object $new_entity
 *   The prepared node object for comparison.
 *   This function may also pass itself a FieldCollectionItemEntity object to compare field collections.
 */
function _fields_changed($old_entity, $new_entity) {
  // Check for node or field collection.
  $entity_is_field_collection = (get_class($old_entity) == 'FieldCollectionItemEntity');

  $bundle = ($entity_is_field_collection ? $old_entity->field_name : $old_entity->type);

  // Sanity check. Exit and throw an error if the content types don't match.
  if($bundle !== ($entity_is_field_collection ? $new_entity->field_name : $new_entity->type)) {
    drupal_set_message('Content type mismatch. Unable to save changes.', 'error');
    return FALSE;
  }

  // Get field info.
  $field_read_params = array(
    'entity_type' => ($entity_is_field_collection ? 'field_collection_item' : 'node'),
    'bundle' => $bundle
  );
  $fields_info = field_read_fields($field_read_params);

  foreach($fields_info as $field_name => $field_info) {
    $old_field = $old_entity->$field_name;
    $new_field = $new_entity->$field_name;

    // Check the number of values for each field, or if they are populated at all.
    $old_field_count = (isset($old_field[LANGUAGE_NONE]) ? count($old_field[LANGUAGE_NONE]) : 0);
    $new_field_count = (isset($new_field[LANGUAGE_NONE]) ? count($new_field[LANGUAGE_NONE]) : 0);

    if ($old_field_count != $new_field_count) {
      // The two versions have a different number of values. Something has changed.
      return TRUE;
    } elseif ($old_field_count > 0 && $new_field_count > 0) {
      // Both versions have an equal number of values. Time to compare.

      // See if this field is a field collection.
      if ($field_info['type'] == 'field_collection') {

        foreach ($new_field[LANGUAGE_NONE] as $delta => $values) {
          $old_field_collection = entity_load_unchanged('field_collection_item', $values['entity']->item_id);
          $new_field_collection = $values['entity'];

          if (_fields_changed($old_field_collection, $new_field_collection)) {
            return TRUE;
          }
        }
        unset($delta, $values);

      } else {
        foreach($old_field[LANGUAGE_NONE] as $delta => $value) {
          foreach($field_info['columns'] as $field_column_name => $field_column_info) {
            $old_value = $old_field[LANGUAGE_NONE][$delta][$field_column_name];
            $new_value = $new_field[LANGUAGE_NONE][$delta][$field_column_name];
            $field_column_type = $field_column_info['type'];

            // As with the overall field, exit if one version has a value and the other doesn't.
            if (isset($old_value) != isset($new_value)) {
              return TRUE;
            } elseif (isset($old_value) && isset($new_value)) {
              // The column stores numeric data so compare values non-identically.
              if (in_array($field_column_type, array('int', 'float', 'numeric'))) {
                if ($new_value != $old_value) {
                  return TRUE;
                }
              }
              // The column stores non-numeric data so compare values identically,
              elseif ($new_value !== $old_value) {
                return TRUE;
              }
            } else {
              // Included for clarity. Both values are empty so there was obviously no change.
            }
          } 
          unset($field_column_name, $field_column_info);
        }
        unset($delta, $value);
      }
    } else {
      // Included for clarity. Both values are empty so there was obviously no change.
    }
  }
  unset($field_name, $field_info);
  // End of field comparison loop.

  // We didn't find any changes. Don't resave the node.
  return FALSE;
}

どのフィールドが変更されたかを知りたい場合があります。それを知るために、このバージョンの関数を使用できます:

/*
 * Pass both versions of the node to this function. Returns an array of
 * fields that were changed or an empty array if none were changed.
 * Pass field collections as an array keyed by field collection ID.
 *
 * @param object $old_entity
 *   The original (stored in the database) node object.
 *   This function may also pass itself a FieldCollectionItemEntity object to compare field collections.
 * @param object $new_entity
 *   The prepared node object for comparison.
 *   This function may also pass itself a FieldCollectionItemEntity object to compare field collections.
 */
function _fields_changed($old_entity, $new_entity) {
  // Check for node or field collection.
  $entity_is_field_collection = (get_class($old_entity) == 'FieldCollectionItemEntity');

  $bundle = ($entity_is_field_collection ? $old_entity->field_name : $old_entity->type);

  // Sanity check. Exit and throw an error if the content types don't match.
  if ($bundle !== ($entity_is_field_collection ? $new_entity->field_name : $new_entity->type)) {
    drupal_set_message('Content type mismatch. Unable to save changes.', 'error');
    return FALSE;
  }

  // Get field info.
  $field_read_params = array(
    'entity_type' => ($entity_is_field_collection ? 'field_collection_item' : 'node'),
    'bundle' => $bundle
  );
  $fields_info = field_read_fields($field_read_params);

  $fields_changed = array();

  foreach ($fields_info as $field_name => $field_info) {
    $old_field = $old_entity->$field_name;
    $new_field = $new_entity->$field_name;

    // Check the number of values for each field, or if they are populated at all.
    $old_field_count = (isset($old_field[LANGUAGE_NONE]) ? count($old_field[LANGUAGE_NONE]) : 0);
    $new_field_count = (isset($new_field[LANGUAGE_NONE]) ? count($new_field[LANGUAGE_NONE]) : 0);

    if ($old_field_count != $new_field_count) {
      // The two versions have a different number of values. Something has changed.
      $fields_changed[] = $field_name;
    }
    elseif ($old_field_count > 0 && $new_field_count > 0) {
      // Both versions have an equal number of values. Time to compare.

      // See if this field is a field collection.
      if ($field_info['type'] == 'field_collection') {

        foreach ($new_field[LANGUAGE_NONE] as $delta => $values) {
          $old_field_collection = entity_load_unchanged('field_collection_item', $values['entity']->item_id);
          $new_field_collection = $values['entity'];

          $fields_changed = array_merge($fields_changed, _fields_changed($old_field_collection, $new_field_collection));
        }
        unset($delta, $values);

      }
      else {
        foreach ($old_field[LANGUAGE_NONE] as $delta => $value) {
          foreach ($field_info['columns'] as $field_column_name => $field_column_info) {
            $old_value = $old_field[LANGUAGE_NONE][$delta][$field_column_name];
            $new_value = $new_field[LANGUAGE_NONE][$delta][$field_column_name];
            $field_column_type = $field_column_info['type'];

            // As with the overall field, exit if one version has a value and the other doesn't.
            if (isset($old_value) != isset($new_value)) {
              $fields_changed[] = $old_field;
            }
            elseif (isset($old_value) && isset($new_value)) {
              // The column stores numeric data so compare values non-identically.
              if (in_array($field_column_type, array(
                'int',
                'float',
                'numeric'
              ))) {
                if ($new_value != $old_value) {
                  $fields_changed[] = $field_name;
                }
              }
              // The column stores non-numeric data so compare values identically,
              elseif ($new_value !== $old_value) {
                $fields_changed[] = $field_name;
              }
            }
            else {
              // Included for clarity. Both values are empty so there was obviously no change.
            }
          }
          unset($field_column_name, $field_column_info);
        }
        unset($delta, $value);
      }
    }
    else {
      // Included for clarity. Both values are empty so there was obviously no change.
    }
  }
  unset($field_name, $field_info);
  // End of field comparison loop.

  return $fields_changed;
}

ノードの特定のフィールドを変更しても、そのノードの「変更された」タイムスタンプが更新されないようにしたい場合があります。これは次のように実装できます。

/**
 * Implements hook_node_presave().
 */
function mymodule_node_presave($node) {
  $fields_changed = _fields_changed($node->original, $node);
  $no_update_timestamp_fields = array('field_subject', 'field_keywords');
  if (!empty($fields_changed) &&
    empty(array_diff($fields_changed, $no_update_timestamp_fields))) {
    // Don't change the $node->changed timestamp if one of the fields has
    // been changed that should not affect the timestamp.
    $node->changed = $node->original->changed;
  }
}

編集(2013年7月30日フィールドコレクションのサポートを強化しました。複数の値を持つフィールドのサポートが追加されました。

編集(2015年7月31日)変更されフィールドと使用例の例を返す関数のバージョンが追加されました。


これは素晴らしいことです。これは、開発者が使用するための何らかのAPIモジュールにあるべきだと思います。
Jelle

3

複雑なサーバー側の値の比較を回避し、任意の形式で機能する別のよりシンプルなアプローチを次に示します。

  1. jQueryを使用して、フォームの値が変更されたかどうかを検出します
  2. 非表示の要素値を設定して、フォームが変更されたことを示します。
  3. 非表示要素の値をサーバー側で確認し、必要に応じて処理します。

次のようなjQueryダーティフォームプラグインを使用できます。 https://github.com/codedance/jquery.AreYouSure。

フォームの変更/ダーティステータスを聞くことができる他のユーザーも動作しますが。

リスナーを追加して、非表示のフォーム要素の値を設定します。

非表示のフォーム要素をデフォルト値の「changed」に設定して、javascriptが無効(〜2%)のユーザー向けにデフォルトで保存します。

例えば:

// Clear initial state for js-enabled user
$('input#hidden-indicator').val('')
// Add changed listener
$('#my-form').areYouSure({
    change: function() {
      // Set hidden element value
      if ($(this).hasClass('dirty')) {
        $('input#hidden-indicator').val('changed');
      } else {
        $('input#hidden-indicator').val('');
      }
    }
 });

その後、非表示要素の値を確認できます

if ($form_state['values']['hidden_indicator'] == 'changed') { /* node_save($node) */ }

フォームで検証/送信ハンドラー。


2
素敵なソリューションですが、明らかにjsのないユーザーもいます。また、drupalコアのmisc / form.jsファイルでDrupal.behaviors.formUpdatedを確認してください。注意すべきもう1つの点は、一部のwysiwygエディターとそのdrupalモジュールの動作では、変更された値を検出することは必ずしも簡単ではないことです。
ルービー

はい、非表示要素に「変更」のデフォルト値を設定すると、jsが有効になっていない少数のユーザーのデフォルトで、わずかな割合で保存されます。興味深いノートについてはDrupal.behaviors.formUpdated、おそらくval()、専用のプラグインは、実際の変更フォームの値を検出で優れているのに対し、(例えばイベントをクリック含みます)、それは価値なしでトリガするように見えるものの、実際に変更することとしてリンクすることができます。
デビッドトーマス

0

これが完璧かどうかはわかりませんが、ノードオブジェクトの代わりにフォームを比較することで、逆に考えないでください。か?

厳密にノード形式であるかどうかはわかりませんが、とにかく古いノードと新しいノードでフォームをレンダリングできます:

module_load_include('inc', 'node', 'node.pages');
node_object_prepare($new_node);
$new_form = drupal_get_form($new_node->node_type . '_node_form', $new_node);
node_object_prepare($old_node);
$old_form = drupal_get_form($old_node->node_type . '_node_form', $old_node);

フォームを比較...

良いトラックになることを願っています...教えてください。


すでにdrupal_get_form()を調べていましたが、2番目のパラメーターとして$ nodeを渡すことができるとは思いませんでした。ただし、上記のサンプルコードをテストしましたが、残念ながら、返される配列構造は同じですが、値は同じではありません。i.imgur.com/LUDPu1R.jpg
morbiD

array_diff_assocが表示されますが、両方のdrupal_get_formのdpmを提供する時間がありますか?これを回避する方法があるかもしれません。
グレゴリーカプスティン

0

次に、hook_node_presave($ node)を使用するメソッドを示します。これは単なるモックアップです。役立つと思う場合は、テストして、ニーズに合わせて改善してください。

  /**
   * Implements hook_node_presave().
   *
   * Look for changes in node fields, before they are saved
   */
  function mymodule_node_presave($node) {

    $changes = array();

    $node_before = node_load($node->nid);

    $fields = field_info_instances('node', $node->type);
    foreach (array_keys($fields) as $field_name) {

      $val_before = field_get_items('node', $node_before, $field_name);
      $val = field_get_items('node', $node, $field_name);

      if ($val_before != $val) {

        //if new field values has more instances then old one, it has changed
        if (count($val) != count($val_before)) {
          $changes[] = $field_name;
        } else {
          //cycle throught 1 or multiple field value instances
          foreach ($val as $k_i => $val_i) {
            if (is_array($val_i)) {
              foreach ($val_i as $k => $v) {
                if (isset($val_before[$k_i][$k]) && $val_before[$k_i][$k] != $val[$k_i][$k]) {
                  $changes[] = $field_name;
                }
              }
            }
          }
        }
      }
    }
    dpm($changes);
  }

各フィールド値について、$ nodeで定義されているインスタンスは$ node_beforeで定義され、等しい必要があると思います。$ node_beforeにあり、$ nodeにないフィールド値のフィールドは気にしません、それらは同じままであると思います。


たぶん私は何かを見逃していますが、hook_node_presave()はnode_save()が呼び出されたことを意味しませんか?フィールドが変更されていない場合、node_save()を呼び出さないようにします。
morbiD

確かに、このフックはnode_save()内で呼び出されます。ただし、mymodule_node_presave()内でdrupal_goto()を呼び出すことにより、保存をキャンセルできます。
dxvargas

2
あなたはそれの真ん中にリダイレクトする場合は、一貫性のない状態で保存ノードを残しておきます、それは本当に良いアイデアではありません@hiphip
クライヴ

0

これは、私が一緒にまとめたコードの一部です。すべての脚の仕事をするために、すべてのクレジットは@eclectoに送らなければなりません。これは(同様にテストされていない)バリエーションで、ノードオブジェクトを直接取得し、DBヒットを少し減らし、言語ネゴシエーションを処理します。

function _node_fields_have_changed($old_node, $new_node) {
  // @TODO Sanity checks (e.g. node types match).

  // Get the fields attached to the node type.
  $params = array('entity_type' => 'node', 'bundle' => $old_node->type);
  foreach (field_read_fields($params) as $field) {
    // Get the field data for both nodes.
    $old_field_data = field_get_items('node', $old_node, $field['field_name']);
    $new_field_data = field_get_items('node', $new_node, $field['field_name']);

    // If the field existed on the old node, but not the new, it's changed.
    if ($old_field_data && !$new_field_data) {
      return TRUE;
    }
    // Ditto but in reverse.
    elseif ($new_field_data && !$old_field_data) {
      return TRUE;
    }

    foreach ($field['columns'] as $column_name => $column) {
      // If there's data in both columns we need an equality check.
      if (isset($old_field_data[$column_name]) && isset($new_field_data[$column_name])) {
        // Equality checking based on column type.
        if (in_array($column['type'], array('int', 'float', 'numeric')) && $old_field_data[$column_name] != $new_field_data[$column_name]) {
          return TRUE;
        }
        elseif ($old_field_data[$column_name] !== $new_field_data[$column_name]) {
          return TRUE;
        }
      }
      // Otherwise, if there's data for one column but not the other,
      // something changed.
      elseif (isset($old_field_data[$column_name]) || isset($new_field_data[$column_name])) {
        return TRUE;
      }
    } 
  }

  return FALSE;
}

1
あなたは私の新しいバージョンと同じ線に沿って考えさせられました。ノードタイプの健全性チェックも含めました。
エリックN

0

提供された答えは素晴らしく、私を助けましたが、私が修正しなければならなかった何かがあります。

// See if this field is a field collection.
if ($field_info['type'] == 'field_collection') {
  foreach ($old_field[LANGUAGE_NONE] as $delta => $values) {
    $old_field_collection = entity_load_unchanged('field_collection_item', $values['entity']->item_id);
    $new_field_collection = $values['entity'];

    $fields_changed = array_merge($fields_changed, erplain_api_fields_changed($old_field_collection, $new_field_collection));
  }
  unset($delta, $values);
}

foreach()ループ、私はから変更しなければならなかった$new_field$old_field。これが新しいバージョンのDrupalなのか自分のコードだけなのかはわかりません(別のコードが原因の可能性があります)が、アクセスできません$new_field['entity']


新しいDrupal 7.41インストールで_fields_changed()関数をテストし、field_collectionでノードを保存すると、この$ old_fieldと$ new_fieldが得られます。$ old_entityパラメーターと$ new_entityパラメーターを指定して_fields_changed()を間違った方法で呼び出している(またはコードのどこかで誤って変数名を交換している)可能性があります。
morbiD

0

投稿をありがとう、本当に時間を節約できました。たくさんの警告を修正し、関数が出力していることに気付きました。

/*
 * Pass both versions of the node to this function. Returns an array of
 * fields that were changed or an empty array if none were changed.
 * Pass field collections as an array keyed by field collection ID.
 *
 * @param object $old_entity
 *   The original (stored in the database) node object.
 *   This function may also pass itself a FieldCollectionItemEntity object to compare field collections.
 * @param object $new_entity
 *   The prepared node object for comparison.
 *   This function may also pass itself a FieldCollectionItemEntity object to compare field collections.
 */
function _fields_changed($old_entity, $new_entity) {
  $fields_changed = array();

  // Check for node or field collection.
  if (is_object($old_entity)) {
    $entity_is_field_collection = (get_class($old_entity) == 'FieldCollectionItemEntity');
    $bundle = !empty($entity_is_field_collection) ? $old_entity->field_name : $old_entity->type;
  }

  // Sanity check. Exit and throw an error if the content types don't match.
  if (is_object($new_entity)) {
    if ($bundle !== (!empty($entity_is_field_collection) ? $new_entity->field_name : $new_entity->type)) {
      drupal_set_message('Content type mismatch. Unable to save changes.', 'error');
      return FALSE;
    }
  }

  // Get field info.
  $field_read_params = array(
    'entity_type' => !empty($entity_is_field_collection) ? 'field_collection_item' : 'node',
  );

  if (!empty($bundle)) {
    $field_read_params['bundle'] = $bundle;
  }

  $fields_info = field_read_fields($field_read_params);

  foreach ($fields_info as $field_name => $field_info) {
    $old_field = isset($old_entity->$field_name) ? $old_entity->$field_name : NULL;
    $new_field = isset($new_entity->$field_name) ? $new_entity->$field_name : NULL;

    // Check the number of values for each field, or if they are populated at all.
    $old_field_count = (isset($old_field[LANGUAGE_NONE]) ? count($old_field[LANGUAGE_NONE]) : 0);
    $new_field_count = (isset($new_field[LANGUAGE_NONE]) ? count($new_field[LANGUAGE_NONE]) : 0);

    if ($old_field_count != $new_field_count) {
      // The two versions have a different number of values. Something has changed.
      $fields_changed[] = $field_name;
    }
    elseif ($old_field_count > 0 && $new_field_count > 0) {
      // Both versions have an equal number of values. Time to compare.

      // See if this field is a field collection.
      if ($field_info['type'] == 'field_collection') {

        foreach ($new_field[LANGUAGE_NONE] as $delta => $values) {
          $old_field_collection = NULL;
          if (!empty($values['entity']->item_id)) {
            $old_field_collection = entity_load_unchanged('field_collection_item', $values['entity']->item_id);
          }

          $new_field_collection = NULL;
          if (isset($values['entity'])) {
            $new_field_collection = $values['entity'];
          }

          $fields_changed = array_merge($fields_changed, _fields_changed($old_field_collection, $new_field_collection));
        }
        unset($delta, $values);

      }
      else {
        foreach ($old_field[LANGUAGE_NONE] as $delta => $value) {
          foreach ($field_info['columns'] as $field_column_name => $field_column_info) {
            $old_value = isset($old_field[LANGUAGE_NONE][$delta][$field_column_name]) ? $old_field[LANGUAGE_NONE][$delta][$field_column_name] : NULL;
            $new_value = isset($new_field[LANGUAGE_NONE][$delta][$field_column_name]) ? $new_field[LANGUAGE_NONE][$delta][$field_column_name] : NULL;
            $field_column_type = $field_column_info['type'];

            // As with the overall field, exit if one version has a value and the other doesn't.
            if (isset($old_value) != isset($new_value)) {
              $fields_changed[] = $old_field;
            }
            elseif (isset($old_value) && isset($new_value)) {
              // The column stores numeric data so compare values non-identically.
              if (in_array($field_column_type, array(
                'int',
                'float',
                'numeric'
              ))) {
                if ($new_value != $old_value) {
                  $fields_changed[] = $field_name;
                }
              }
              // The column stores non-numeric data so compare values identically,
              elseif ($new_value !== $old_value) {
                $fields_changed[] = $field_name;
              }
            }
            else {
              // Included for clarity. Both values are empty so there was obviously no change.
            }
          }
          unset($field_column_name, $field_column_info);
        }
        unset($delta, $value);
      }
    }
    else {
      // Included for clarity. Both values are empty so there was obviously no change.
    }
  }
  unset($field_name, $field_info);
  // End of field comparison loop.

  return $fields_changed;
}

このコードが元の質問にどのように答えるかを説明してください(一部のコードを投稿するだけでは、ここの規則に準拠していません)。
Pierre.Vriens
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.