Загальне виявлення змінених полів у спеціальній формі до збереження вузла


12

Я додаю певні поля з типу вмісту у власну форму за допомогою field_attach_form (). Після надсилання форми я обробляю ці поля, зателефонувавши field_attach_form_validate () та field_attach_submit () з #validate та #submit callback.

У цей момент я хочу порівняти підготовлений об'єкт після подання, який готується до вихідного вузла, і потурбувати його лише для 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',
);

Ви можете подумати просто порівняти ключ "значення", але тоді ви натрапите на поля, що складаються з інших елементів, у яких немає клавіш "значення". Наприклад, давайте подивимось на адресне поле, де немає клавіші 'value', а в старих та підготовлених вузлах є ключі, які не мають аналогів.

Старий вузол

$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. Трактуйте поле, яке має різну кількість значень між двома версіями, як зміну.

  4. Ітерайте через кожне поле, значення та стовпець та порівняйте дві версії.

  5. Порівняйте елементи не тотожно (! =), Якщо вони чисельні та однакові (! ==), якщо вони є чимось іншим.

  6. Негайно поверніть TRUE при першій виявленій зміні (оскільки однієї зміни достатньо, щоб знати, що нам потрібно зберегти вузол).

  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;
  }
}

EDIT (30.07.2013) Збільшена підтримка збору полів. Додана підтримка полів з кількома значеннями.

EDIT (31.07.2015) Додана версія функції, яка повертає, які поля були змінені, і, наприклад, використовуйте регістр.


Це чудово, я вважаю, що це має бути в якомусь модулі api, який розробники можуть використовувати.
Джелле

3

Ось ще один, простіший підхід, який дозволяє уникнути складних порівнянь вартості сервера і може працювати в будь-якій формі:

  1. Використовуйте jQuery, щоб визначити, чи змінилися значення форми
  2. Встановіть приховане значення елемента, щоб вказати, що форма змінилася.
  3. Перевірте сторону сервера прихованих значень елементів та обробіть, як потрібно.

Ви можете використовувати плагін для брудної форми jQuery, наприклад https://github.com/codedance/jquery.AreYouSure

Хоча інші, які дозволяють вам слухати форму, змінили / забруднили статус, також працюватимуть.

Додайте слухача, щоб встановити значення прихованого елемента форми:

Встановіть для прихованого елемента форми значення за замовчуванням "змінено", щоб зберегти за замовчуванням для тих користувачів, у яких відключений 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.behaviors.formUp updated у файлі misc / form.js ядра drupal. Ще одна річ, що слід зазначити, що з тим, як працюють деякі редактори wysiwyg та їх друпальські модулі, виявлення зміненого значення не завжди є таким прямим, як це має бути.
рубін

Так, встановлення за замовчуванням значення "змінено" для прихованого елемента дозволить зберегти за замовчуванням для тих небагатьох користувачів без включених 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 (), але не розумів, що ти можеш передати $ node як 2-й параметр. Однак я тільки протестував ваш приклад код вище, і, на жаль, хоча повернуті структури масиву однакові, значення не є. Подивіться на цей рекурсивний масив_diff_assoc () для адресного поля, з яким я тестую: i.imgur.com/LUDPu1R.jpg
morbiD

Я бачу, що array_diff_assoc, але чи встигнете ви дати два рази в хвилину як drupal_get_form? Можливо, це обійдеться.
Григорій Капустін

0

Ось метод, що використовує гачку_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_поперед. Мені не важливо поля значень поля, які знаходяться в $ node_before і не знаходяться в $ node, я вважаю, що вони залишаються однаковими.


Можливо, мені чогось не вистачає, але чи не вважає прив'язку_node_presave () означає, що node_save () викликано? Ми намагаємось уникати виклику node_save (), якщо жодні поля не були змінені.
morbiD

Правда, цей гачок називається всередині node_save (). Але ви все одно можете скасувати збереження, зателефонувавши на drupal_goto () всередині mymodule_node_presave ().
dxvargas

2
@hiphip Це дійсно не дуже гарна ідея, ви залишите вузол збереження в непослідовному стані, якщо перенаправитеся посередині нього
Клайв

0

Це лише якийсь код, який я спільно зв'язав. Вся заслуга повинна бути надана @eclecto за виконання всіх робіт з ніг. Це лише (аналогічно неперевірений) варіант, який безпосередньо забирає об'єкти вузла, трохи зменшує звернення до БД та піклується про мовні переговори.

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
Ви змусили мене думати по одній лінії з моєю новою версією. Я навіть включив перевірку на відповідність типу вузла.
Ерік Н

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'].


Я щойно перевірив функцію _fields_changed () на свіжому встановленні Drupal 7.41 і збереження вузла з field_collection дає мені це $ old_field і $ new_field . Мені здається, ви могли б викликати _fields_changed () з параметрами $ old_entity та $ new_entity неправильно (або ви випадково десь поміняли імена змінних у своєму коді).
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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.