You are here

function _better_statistics_update_fields in Better Statistics 7

Determines whether or not accesslog fields should be altered, and if so, performs any necessary database alterations and re-saves the declared fields to the active store variable.

It is absolutely necessary that this function does all sanity checks because if not, it's possible for our hook_exit() call to insert data into non-existent fields.

This function is also necessary to ensure that our schema alter is always in line with what's actually declared in the database.

4 calls to _better_statistics_update_fields()
better_statistics_disable_fields in ./better_statistics.admin.inc
Disables a list of statistics fields.
better_statistics_enable_fields in ./better_statistics.admin.inc
Enables a list of statistics fields.
better_statistics_flush_caches in ./better_statistics.module
Implements hook_flush_caches().
better_statistics_update_7101 in ./better_statistics.install
Update the list of statistics files to be auto-loaded.

File

./better_statistics.admin.inc, line 421
Admin and config code for the Better Statistics module.

Code

function _better_statistics_update_fields() {

  // Attempt to get all fields, including customizations from other modules.
  $active = variable_get('better_statistics_fields', FALSE);
  $customizations = _better_statistics_get_custom_fields_by_module();

  // Manually include Core statistics' fields.
  $customizations['statistics'] = better_statistics_get_default_fields();
  $available_fields = array();

  // There's no reason for this to run if no custom fields are installed.
  if (!$active) {
    return;
  }

  // Write through updates to the non-schema portions of custom fields; also
  // check for, perform, and write through schema updates.
  foreach ($customizations as $module => $data) {
    foreach ($data as $field => $field_data) {

      // Only check for differences in pre-existing fields in the active store.
      if (isset($active[$field])) {

        // Check that the new callback is callable and write through.
        if (is_callable($field_data['callback'])) {
          $active[$field]['callback'] = $field_data['callback'];
        }

        // Write through Views API changes.
        $active[$field]['views_field'] = $field_data['views_field'];

        // Write through the location of the callback.
        if (isset($field_data['_file'])) {
          $active[$field]['_file'] = $field_data['_file'];
        }

        // Write through BS JS API changes.
        if (isset($field_data['js'])) {
          $active[$field]['js'] = $field_data['js'];
        }

        // Check for updates to the schema.
        if ($active[$field]['schema'] != $field_data['schema']) {
          try {

            // Change the schema.
            db_change_field('accesslog', $field, $field, $field_data['schema']);

            // Write through the change to the active store.
            $active[$field]['schema'] = $field_data['schema'];

            // Log the field change in watchdog.
            watchdog('better statistics', 'Successfully changed field %field in the accesslog.', array(
              '%field' => $field,
            ), WATCHDOG_NOTICE);
          } catch (Exception $e) {
            $module_info = system_get_info('module', $module);
            $message = filter_xss_admin('<em>Error</em>: Failed to update the %field field in the access log. Please make sure you are using the latest version of the @module module.');
            $options = array(
              '%field' => $field,
              '@module' => $module_info['name'],
            );

            // Set a message notifying the user.
            drupal_set_message(t($message, $options), 'error');

            // Log the failed attempt in watchdog and add more details.
            $message .= filter_xss_admin('<br /><br /><strong>Error message:</strong><br />@error');
            $options['@error'] = $e
              ->getMessage();
            watchdog('better statistics', $message, $options, WATCHDOG_ERROR);
          }
        }
      }

      // Save this field as an available field.
      $available_fields[] = $field;
    }
  }

  // Check for fields in the active store that no longer exist.
  foreach ($active as $field => $data) {
    if (!in_array($field, $available_fields)) {
      $message = 'A recent module update has invalidated the %field field in the access log. No data has been removed at this time, but all data in the field will be lost next time Better Statistics settings are updated.';
      $options = array(
        '%field' => $field,
      );
      drupal_set_message(t($message, $options), 'warning');
      watchdog('better statistics', $message, $options, WATCHDOG_WARNING);
    }
  }

  // Save the active store with any changes.
  variable_set('better_statistics_fields', $active);

  // Save off a list of active inc files to be loaded.
  $active_incs = array();
  foreach (_better_statistics_include_handlers() as $module => $api_info) {
    $active_incs[] = $api_info['file_required'];
  }
  variable_set('better_statistics_active_incs', $active_incs);
}