You are here

cck_table.module in CCK Table Field 7

Same filename and directory in other branches
  1. 8 cck_table.module
  2. 5 cck_table.module
  3. 6 cck_table.module

Defines a field type that outputs data in a table.

File

cck_table.module
View source
<?php

define('CCK_TABLE_ENFORCE_MISALIGN_COL', TRUE);
define('CCK_TABLE_DEFAULT_ROWS', 5);
define('CCK_TABLE_DEFAULT_SEPARATOR', '|');

/**
 *  Module version 5 create by rszrama
 *  sponser by Wombats http://www.bywombats.com
 *  Module coverted to 6 then to 7 by iStryker
 *  Sponser by Themes 24/7  http://www.themes247.com
 *  & Stryker Enteprise http://www.strykerenterprise.com
 */

/**
 * @file
 * Defines a field type that outputs data in a table.
 */

/**
 * Implements of hook_field_info().
 */
function cck_table_field_info() {
  return array(
    'table' => array(
      'label' => t('Table'),
      'description' => t('Defines a textarea field that outputs data in a table'),
      'settings' => array(
        'rows' => CCK_TABLE_DEFAULT_ROWS,
        'enforce_misalign_col' => CCK_TABLE_ENFORCE_MISALIGN_COL,
        'separator' => CCK_TABLE_DEFAULT_SEPARATOR,
      ),
      'default_widget' => 'text_textarea',
      'default_formatter' => 'without_header',
    ),
  );
}

/**
 * Implements of hook_field_widget_info().
 */
function cck_table_field_widget_info() {
  return array(
    'cck_table_textarea' => array(
      'label' => t('Textarea'),
      'field types' => array(
        'table',
      ),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
        'default value' => FIELD_BEHAVIOR_NONE,
      ),
      'settings' => array(
        'rows' => CCK_TABLE_DEFAULT_ROWS,
        'enforce_misalign_col' => CCK_TABLE_ENFORCE_MISALIGN_COL,
        'separator' => CCK_TABLE_DEFAULT_SEPARATOR,
      ),
    ),
  );
}

/**
 * Implements of hook_field_formatter_info().
 */
function cck_table_field_formatter_info() {
  return array(
    'first_row_header' => array(
      'label' => t('First Row will be the table header'),
      'multiple values' => FIELD_BEHAVIOR_DEFAULT,
      'field types' => array(
        'table',
      ),
    ),
    'without_header' => array(
      'label' => t('Without a table header'),
      'multiple values' => FIELD_BEHAVIOR_DEFAULT,
      'field types' => array(
        'table',
      ),
    ),
  );
}

/**
 * Implements of hook_field_is_empty().
 */
function cck_table_field_is_empty($item, $field) {
  if (empty($item['table'])) {
    return TRUE;
  }
  return FALSE;
}

/**
 * Implements of hook_field_formatter_view().
 */
function cck_table_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  $settings = $display['settings'];
  $formatter = $display['type'];
  switch ($formatter) {
    case 'first_row_header':
      $header_type = TRUE;
      break;
    case 'without_header':
      $header_type = FALSE;
      break;
  }
  foreach ($items as $delta => $item) {
    if (!empty($item['table'])) {
      $header = array();
      $rows = array();
      $lines = explode("\n", $item['table']);
      $lines = array_map('trim', $lines);
      $lines = array_filter($lines, 'strlen');
      foreach ($lines as $line) {
        $cells = explode($instance['widget']['settings']['separator'], $line);
        if (empty($header) && count($lines) > 1 && $header_type) {
          $header = $cells;
        }
        else {
          $rows[] = $cells;
        }
      }
      if (count($rows) > 0) {
        $attributes = array();
        if (!empty($field['css_id'])) {
          $attributes['id'] = $instance['widget']['settings']['css_id'] . '-' . $instanc['id'];
        }
        if (!empty($field['css_class'])) {
          $attributes['class'] = $instance['widget']['settings']['css_class'];
        }
      }
      $element[$delta] = array(
        '#theme' => 'table',
        '#header' => $header,
        '#rows' => $rows,
        '#attributes' => $attributes,
      );
    }
  }
  return $element;
}

/**
 * Implements of hook_field_widget_settings_form().
 */
function cck_table_field_widget_settings_form($field, $instance) {
  $form = array();
  $form['rows'] = array(
    '#type' => 'textfield',
    '#title' => t('Number of Rows'),
    '#default_value' => isset($instance['widget']['settings']['rows']) ? $instance['widget']['settings']['rows'] : CCK_TABLE_DEFAULT_ROWS,
    '#required' => TRUE,
    '#element_validate' => array(
      '_element_validate_integer_positive',
    ),
  );
  $form['separator'] = array(
    '#type' => 'textfield',
    '#title' => t('Separator'),
    '#description' => t('Separator to use to distinguish cells in a row'),
    '#default_value' => isset($instance['widget']['settings']['separator']) ? $instance['widget']['settings']['separator'] : CCK_TABLE_DEFAULT_SEPARATOR,
    '#size' => 5,
    '#required' => TRUE,
  );
  $form['enforce_misalign_col'] = array(
    '#type' => 'checkbox',
    '#title' => 'Enforce Mis-Align Column',
    '#default_value' => isset($instance['widget']['settings']['enforce_misalign_col']) ? $instance['widget']['settings']['enforce_misalign_col'] : CCK_TABLE_ENFORCE_MISALIGN_COL,
    '#description' => 'If Enabled, each row must have the same number of columns or an error will be thrown.',
  );
  $form['css_id'] = array(
    '#type' => 'textfield',
    '#title' => t('CSS ID'),
    '#description' => t('Specify an ID to be assigned to the table element.') . '<br />' . t('The node ID will be appended to keep the ID unique.'),
    '#default_value' => isset($instance['widget']['settings']['css_id']) ? $instance['widget']['settings']['css_id'] : '',
    '#field_suffix' => '-##',
  );
  $form['css_class'] = array(
    '#type' => 'textfield',
    '#title' => t('CSS Class'),
    '#description' => t('Specify a class to be added to the table element.'),
    '#default_value' => isset($instance['widget']['settings']['css_class']) ? $instance['widget']['settings']['css_class'] : '',
  );
  return $form;
}

/**
 * Implements hook_field_widget_form().
 */
function cck_table_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $base) {

  // it suggest I use += to avoid overwriting incoming $element & $element as parameter instead of $base
  // if I do this it throws error of undefined operand type
  // if I do this then I cannot put in default help
  if (!empty($instance['description'])) {
    $description = t($instance['description']);
  }
  else {
    $description = t(_cck_table_default_help_text($instance['display']['default']['type'], $instance['widget']['settings']['enforce_misalign_col']));
  }
  $element = $base;
  $element['table'] = array(
    '#type' => 'textarea',
    '#title' => check_plain($element['#title']),
    '#default_value' => isset($items[$delta]['table']) ? $items[$delta]['table'] : NULL,
    '#rows' => $instance['widget']['settings']['rows'],
    '#description' => $description,
  );
  return $element;
}

/**
 * Implements hook_field_validate().
 *
 * Possible error codes:
 * - %name: mis-align number of columns.
 */
function cck_table_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
  foreach ($items as $delta => $item) {
    if ($instance['widget']['settings']['enforce_misalign_col']) {
      if (is_array($items)) {
        $error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
        if (is_array($item) && isset($item['_error_element'])) {
          unset($item['_error_element']);
        }
        if ($item['table'] != '') {
          $lines = explode("\n", $item['table']);
          $lines = array_map('trim', $lines);
          $lines = array_filter($lines, 'strlen');
          foreach ($lines as $line) {
            if (!isset($cell_count)) {
              $cell_count = count(explode('|', $line));
            }
            elseif ($cell_count != count(explode('|', $line))) {
              form_set_error($error_element, t('%name: mis-align number of columns.', array(
                '%name' => t($instance['label']),
              )));
              break;
            }
          }
        }
      }
    }
  }
}

/*
 * Custom function that maybe call by cck_table_field_widget_form
 * @param $display
 * The type of display the full view is set to
 */
function _cck_table_default_help_text($display, $enforce_misalign_col) {
  switch ($display) {
    case 'first_row_header':
      $current_display = "Currently the first row is the header to this table.";
      break;
    case 'without_header':
      $current_display = "Currently there is no header to this table.";
      break;
  }
  $default_description = "Enter table cell data separated by |, one row per line. {$current_display}";
  if ($enforce_misalign_col) {
    $default_description .= " All rows must have the same number of columns.";
  }
  return $default_description;
}

/**
 * Implements hook_field_widget_error().
 */
function cck_table_field_widget_error($element, $error, $form, &$form_state) {
  form_error($element['value'], $error['message']);
}

/**
 * Implements hook_content_migrate_instance_alter().
 *
 * D6-D7 upgrade
 * fixes new formatter names
 */
function cck_table_content_migrate_instance_alter(&$instance_value, &$field_value) {
  if ($field_value['module'] == 'cck_table') {
    foreach ($instance_value['display'] as $context => $settings) {
      if (in_array($instance_value['display'][$context]['type'], array(
        'first_row_header',
        'without_header',
      ))) {
        $instance_value['display'][$context]['type'] = 'cck_table_' . $instance_value['display'][$context]['type'];
      }
    }
  }
}