track_field_changes.module in Track Field Changes 7
Same filename and directory in other branches
The Track Field Changes module.
File
track_field_changes.moduleView source
<?php
/**
* @file
* The Track Field Changes module.
*/
define('TRACK_FIELD_CHANGES_ADMIN_PATH', 'admin/config/system/track_field_changes');
/**
* Implements hook_permission().
*/
function track_field_changes_permission() {
return array(
'administer track field changes' => array(
'title' => t('Administer Track Field Changes'),
'description' => t('Enable or disable field tracking'),
),
);
}
/**
* Implements hook_help().
*/
function track_field_changes_help($path, $arg) {
switch ($path) {
case TRACK_FIELD_CHANGES_ADMIN_PATH:
$output = '<p>' . t('This page lists all the <em>fields audited</em> that are currently defined on this system.') . '</p>';
return $output;
}
}
/**
* Implements hook_menu().
*/
function track_field_changes_menu() {
$items[TRACK_FIELD_CHANGES_ADMIN_PATH] = array(
'title' => 'Field Track Changes',
'description' => 'Enable and disable which content type and fields need to be audited.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'track_field_changes_admin_settings',
),
'access arguments' => array(
'administer track field changes',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'track_field_changes.admin.inc',
);
return $items;
}
/**
* Implements hook_node_insert().
*/
function track_field_changes_node_insert($node) {
// Each node type which are audited.
$node_types = variable_get('track_field_changes_node_types', array());
// If content type is audited.
if (in_array($node->type, $node_types)) {
// Basic or/and advanced audit.
$basic_audit = variable_get('track_field_changes_basic_new_' . $node->type, FALSE);
// Get log.
$log = isset($node->track_field_changes) ? $node->track_field_changes : '';
if ($basic_audit) {
track_field_changes_insert_db($node->nid, 'log', '', '', 'bn', $log);
}
}
}
/**
* Implements hook_node_update().
*/
function track_field_changes_node_update($node) {
// Each node type which are audited.
$node_types = variable_get('track_field_changes_node_types', array());
// If content type is audited.
if (in_array($node->type, $node_types)) {
// Basic or/and Advanced audit.
$basic_audit = variable_get('track_field_changes_basic_revision_' . $node->type, FALSE);
$fields_audit = variable_get('track_field_changes_track_revision_fields_' . $node->type, FALSE);
// Get log.
$log = isset($node->track_field_changes) ? $node->track_field_changes : '';
if ($basic_audit) {
track_field_changes_insert_db($node->nid, 'log', '', '', 'br', $log);
}
if ($fields_audit) {
$selected_fields = track_field_changes_get_selected_field($node->type);
// Clone ?
$newnode = $node;
$originalnode = $node->original;
foreach ($selected_fields as $field_name) {
if ($field_name == 'title') {
$field_info_type = 'title';
$newfield = $newnode->title;
$originalfield = $originalnode->title;
}
else {
$field_info = field_info_field($field_name);
$field_info_type = $field_info['type'];
$language = field_language('node', $newnode, $field_name);
$newfield = field_get_items('node', $newnode, $field_name, $language);
$language = field_language('node', $originalnode, $field_name);
$originalfield = field_get_items('node', $originalnode, $field_name, $language);
}
if (!track_field_changes_compare_field($field_info_type, $originalfield, $newfield)) {
$field_before = array();
$field_before['field_name'] = $field_name;
$field_before['value'] = $originalfield;
$field_after = array();
$field_after['field_name'] = $field_name;
$field_after['value'] = $newfield;
if ($field_info_type == 'file') {
for ($i = 0; $i < count($field_after['value'][LANGUAGE_NONE]); $i++) {
$file = file_load($field_after['value'][LANGUAGE_NONE][$i][fid]);
$field_after['value'][LANGUAGE_NONE][$i]['filename'] = $file->filename;
$field_after['value'][LANGUAGE_NONE][$i]['uri'] = $file->uri;
$field_after['value'][LANGUAGE_NONE][$i]['filemime'] = $file->filemime;
$field_after['value'][LANGUAGE_NONE][$i]['filesize'] = $file->filesize;
$field_after['value'][LANGUAGE_NONE][$i]['status'] = $file->status;
$field_after['value'][LANGUAGE_NONE][$i]['timestamp'] = $file->timestamp;
}
}
track_field_changes_insert_db($node->nid, $field_name, serialize($field_before), serialize($field_after), 'fr', $log);
}
}
}
}
}
/**
* Implements hook_node_delete().
*/
function track_field_changes_node_delete($node) {
db_delete('track_field_changes_audit')
->condition('nid', $node->nid)
->execute();
}
/**
* Implements hook_views_api().
*/
function track_field_changes_views_api() {
return array(
'api' => 2.0,
'path' => drupal_get_path('module', 'track_field_changes') . '/views',
);
}
/**
* Get select field for a bundle.
*
* @param $bundle
*/
function track_field_changes_get_selected_field($bundle) {
$track_field_changess = db_select('track_field_changes', 'a')
->fields('a')
->condition('bundle', $bundle)
->execute()
->fetchCol();
$options = array();
foreach ($track_field_changess as $track_field_changes) {
$options[$track_field_changes] = $track_field_changes;
}
return $options;
}
/**
* Compare two fields.
*
* return FALSE if different
* return TRUE if egal
*/
function track_field_changes_compare_field($field_info_type, $old_field, $new_field) {
if ($field_info_type == 'title') {
return $old_field == $new_field;
}
else {
if ($old_field == NULL && empty($new_field)) {
return TRUE;
}
if ($new_field == NULL && empty($old_field)) {
return TRUE;
}
if ($new_field == NULL && $old_field == NULL) {
return TRUE;
}
if (empty($new_field) && empty($old_field)) {
return TRUE;
}
if (count($new_field) != count($old_field)) {
return FALSE;
}
switch ($field_info_type) {
case 'datestamp':
case 'datetime':
case 'date':
for ($i = 0; $i < count($new_field); $i++) {
if ($old_field[$i]['value'] != $new_field[$i]['value']) {
return FALSE;
}
}
return TRUE;
break;
case 'tablefield':
case 'text_long':
case 'list_text':
case 'list_boolean':
case 'text_with_summary':
case 'number_decimal':
case 'number_float':
case 'text':
for ($i = 0; $i < count($new_field); $i++) {
if ($old_field[$i]['value'] != $new_field[$i]['value']) {
return FALSE;
}
if (isset($old_field[$i]['value2']) && $old_field[$i]['value2'] != $new_field[$i]['value2']) {
return FALSE;
}
}
return TRUE;
case 'email':
for ($i = 0; $i < count($new_field); $i++) {
if ($old_field[$i]['email'] != $new_field[$i]['email']) {
return FALSE;
}
}
return TRUE;
case 'link_field':
for ($i = 0; $i < count($new_field); $i++) {
if (empty($old_field) || empty($new_field)) {
return FALSE;
//if they are both empty, that case is handled at the beginning of this function
}
// not all link fields have a title, i.e. static title
if (array_key_exists('title', $old_field[$i]) && array_key_exists('title', $new_field[$i])) {
if ($old_field[$i]['title'] != $new_field[$i]['title']) {
return FALSE;
}
}
}
for ($i = 0; $i < count($new_field); $i++) {
if ($old_field[$i]['url'] != $new_field[$i]['url']) {
return FALSE;
}
}
return TRUE;
case 'image':
case 'file':
for ($i = 0; $i < count($new_field); $i++) {
if ($old_field[$i]['fid'] != $new_field[$i]['fid']) {
return FALSE;
}
}
return TRUE;
case 'geofield':
for ($i = 0; $i < count($new_field); $i++) {
if ($old_field[$i]['wkt'] != $new_field[$i]['wkt']) {
return FALSE;
}
}
return TRUE;
case 'entityreference':
for ($i = 0; $i < count($new_field); $i++) {
if ($old_field[$i]['target_id'] != $new_field[$i]['target_id']) {
return FALSE;
}
}
return TRUE;
case 'taxonomy_term_reference':
if (sizeof($old_field) != sizeof($new_field)) {
return FALSE;
}
foreach ($old_field as $key => $value) {
if ($old_field[$key]['tid'] != $new_field[$key]['tid']) {
return FALSE;
}
}
return TRUE;
case 'list_integer':
case 'list_float':
case 'number_integer':
case 'user_reference':
return $old_field == $new_field;
case 'addressfield':
for ($i = 0; $i < count($new_field); $i++) {
//do a compare of each part of address field
// first get a list of the address parts
$address_items = array_keys($new_field[$i]);
// use $new_field in case something has change in the address definition
foreach ($address_items as $address_item) {
if ($address_item != 'data') {
if (empty($new_field[$i][$address_item])) {
if (array_key_exists($address_item, $old_field[$i])) {
if (!empty($old_field[$i][$address_item])) {
return FALSE;
}
}
else {
return FALSE;
}
}
else {
if (empty($old_field[$i][$address_item])) {
return FALSE;
}
else {
if ($old_field[$i][$address_item] != $new_field[$i][$address_item]) {
return FALSE;
}
}
}
}
}
}
// if we made it this far, no changes
return TRUE;
default:
return TRUE;
}
}
}
/**
* Compare if one field is empty.
*
* return FALSE if not empty
* return TRUE if empty
*/
function track_field_changes_is_empty($field_info_type, $field) {
if ($field_info_type == 'title') {
return $field == '';
}
else {
switch ($field_info_type) {
case 'datestamp':
case 'datetime':
case 'date':
return empty($field);
case 'tablefield':
case 'text_long':
case 'list_text':
case 'list_boolean':
case 'text_with_summary':
case 'number_decimal':
case 'number_float':
case 'text':
case 'entityreference':
$field = $field[LANGUAGE_NONE];
return empty($field);
case 'email':
return FALSE;
case 'link_field':
return FALSE;
case 'image':
case 'file':
$field = $field[LANGUAGE_NONE];
return empty($field);
case 'taxonomy_term_reference':
case 'list_integer':
case 'list_float':
case 'number_integer':
case 'user_reference':
case 'geofield':
return $field == '';
default:
return FALSE;
}
}
}
function track_field_changes_insert_db($nid, $field_name, $old_field, $new_field, $type, $log) {
global $user;
$track_field_changes_disable_multiple = variable_get('track_field_changes_disable_multiple', array());
if ($track_field_changes_disable_multiple['checked'] === "checked") {
$result = db_select('track_field_changes_audit', 't')
->fields('t')
->condition('nid', $nid, '=')
->execute()
->fetchAssoc();
if ($result['nid'] == $nid) {
db_update('track_field_changes_audit')
->fields(array(
'nid' => $nid,
'timestamp' => REQUEST_TIME,
'uid' => $user->uid,
'field_name' => $field_name,
'before_value_text' => $old_field,
'after_value_text' => $new_field,
'type' => $type,
'log' => $log,
))
->condition('nid', $nid, '=')
->execute();
}
else {
db_insert('track_field_changes_audit')
->fields(array(
'nid' => $nid,
'timestamp' => REQUEST_TIME,
'uid' => $user->uid,
'field_name' => $field_name,
'before_value_text' => $old_field,
'after_value_text' => $new_field,
'type' => $type,
'log' => $log,
))
->execute();
}
}
else {
db_insert('track_field_changes_audit')
->fields(array(
'nid' => $nid,
'timestamp' => REQUEST_TIME,
'uid' => $user->uid,
'field_name' => $field_name,
'before_value_text' => $old_field,
'after_value_text' => $new_field,
'type' => $type,
'log' => $log,
))
->execute();
}
}
/**
* Implement hook_form_alter().
* (cant use hook_form_FORM_ID_alter(). here as the form ID changes from node to node)
*/
function track_field_changes_form_alter(&$form, $form_state, $form_id) {
// If we're editing a node...
if (!empty($form['#node_edit_form'])) {
$node_types = variable_get('track_field_changes_node_types', array());
// And the show field is enabled for this node type.
$enable_log = variable_get('track_field_changes_enable_log_' . $form['type']['#value'], FALSE);
if (in_array($form['type']['#value'], $node_types) && $enable_log) {
$log = !$form['nid']['#value'] ? 'New ' . $form['type']['#value'] : '';
$form['track_field_changes'] = array(
'#type' => 'fieldset',
'#title' => t('Track Field Information'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'additional_settings',
'#weight' => 35,
);
$form['track_field_changes']['track_field_changes'] = array(
'#type' => 'textarea',
'#title' => t('Track field log message'),
'#rows' => 4,
'#default_value' => !empty($node->track_field_changes) ? $node->track_field_changes : $log,
'#description' => t('Provide an explanation of the changes you are making.'),
'#maxlength' => 256,
);
}
}
}
/**
* Implement hook_form_FORM_ID_alter().
*/
function track_field_changes_form_user_profile_form_alter(&$form, $form_state) {
// @todo
}
/**
* Implement hook_form_FORM_ID_alter().
*/
function track_field_changes_form_taxonomy_form_term_alter(&$form, $form_state) {
// @todo
}
/**
* This hook is called right before the execute process. The query is
* now fully built, but it has not yet been run through db_rewrite_sql.
*
* Adding output to the view can be accomplished by placing text on
* $view->attachment_before and $view->attachment_after.
*/
function track_field_changes_views_pre_execute(&$view) {
// @todo
}
Functions
Constants
Name | Description |
---|---|
TRACK_FIELD_CHANGES_ADMIN_PATH | @file The Track Field Changes module. |