Login

Source code - My Date - Module Listing

my_date.module

<?php
 
/**
 * Implements hook_field_info().
 */
function my_date_field_info() {
  return array(
      'my_date' => array(
          'label' => t('My Date Field'),
          'description' => t('Timestamp Value'),
          'default_widget' => 'my_date_widget',
          'default_formatter' => 'my_date_calendar_formatter',
      ),
      'use_today' => array(
          'label' => t('Use Today\'s Date'),
          'description' => t('Setting Value'),
          'default_widget' => 'my_date_widget',
          'default_formatter' => 'my_date_calendar_formatter',
      ),
  );
}
 
/**
 * Implements hook_field_formatter_info().
 */
function my_date_field_formatter_info() {
  return array(
      'my_date_calendar_formatter' => array(
          'label' => t('My Date Calendar Formatter'),
          'field types' => array('my_date'),
          'settings' => array(
              'container' => array(
              'float' => 'right',
              'class' => '',
              'inline_style' => '',),
           ),
      ),
      'my_date_detailed_formatter' => array(
          'label' => t('My Date Detailed Formater'),
          'field types' => array('my_date'),
          'settings' => array(
              'container' => array(
                'float' => 'right',
                'class' => '',
                'inline_style' => '',
                 array('background' =>
                   array('image' => ''),
                 ),
               ),
              'date_part' => array(
                  'show_month' => TRUE,
                  'show_day' => TRUE,
                  'show_year' => TRUE,
                  'inline_style_month' => '',
                  'inline_style_day' => '',
                  'inline_style_year' => ''),
              ),
          ),
      );
}
 
/**
 * Implements hook_field_widget_info().
 */
function my_date_field_widget_info() {
  return array(
      'my_date_text_select' => array(
          'label' => t('Text/JQuery DatePicker'),
          'field types' => array('my_date'),
      ),
  );
}
 
 
/**
 * Implements hook_field_formatter_view().
 */
function my_date_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
 
  $element = array();
 
  $container = '<div ';
  $style = 'float:right;margin-left:4px;';
 
  if ($display['settings']['container']['float'] == 'right') {
    $style = 'float:right;margin-left:4px;';
  } else {
    $style = 'float:left;margin-right:4px;';
  }
 
  if($display['settings']['container']['background']['image'] != 'none') {
      $back_ground_image = $GLOBALS['base_path'] . drupal_get_path('module', 'my_date') . '/images/' . $display['settings']['container']['background']['image'].'-sky.png';
      $style .= 'background:url(\'' .$back_ground_image . '\');';
  }
 
  if (!empty($display['settings']['container']['inline_style'])) {
    $style .= $display['settings']['container']['inline_style'];
  }
 
  if (!empty($display['settings']['container']['class'])) {
    $container .= 'class="' . $display['settings']['container']['class'] . '" ';
  }
 
  $field_name = $instance['field_name'];
  $field_id = str_replace('_', '-', $instance['field_name']) . $delta;
 
 
  switch ($display['type']) {
    case 'my_date_calendar_formatter':
      foreach ($items as $delta => $item) {
        if ($item['my_date']) {
 
          $date_string = my_date_field_to_string_format($item['my_date']);
 
          $js = '(function($){$(function() { $("#' . $field_id . '").datepicker({defaultDate:"' . $date_string . '", minDate: "' . $date_string . '", maxDate: "' . $date_string . '"}); })})(jQuery);';
 
          $element[$delta]['#markup'] = $container . 'id="' . $field_id . '" style="' . $style . '"></div>';
          $element['#attached']['library'][] = array('system', 'ui.datepicker');
          $element['#attached']['js'][] = array('data' => $js, 'type' => 'inline');
        }
      }
      break;
 
    case 'my_date_detailed_formatter':
      foreach ($items as $delta => $item) {
        if ($item['my_date']) {
          $date_value = getdate($item['my_date']);
          $settings = $display['settings'];
 
          $output = $container . 'id="' . $field_id . '" style="' . $style . '" align="center">';
          if ($display['settings']['date_part']['show_month']) {
            $output .= '<div style="'. $settings['date_part']['inline_style_month'] .'">' . $date_value['month'] . '</div>';
          }
          if ($display['settings']['date_part']['show_day']) {
            $output .= '<div style="'. $settings['date_part']['inline_style_day'] .'">' . $date_value['mday'] . '</div>';
          }
          if ($display['settings']['date_part']['show_year']) {
            $output .= '<div style="'.$settings['date_part']['inline_style_year'].'">' . $date_value['year'] . '</div>';
          }
          $output .= '</div>';
          $element[$delta]['#markup'] = $output;
        }
      }
      break;
  }
  return $element;
}
 
/**
 * Helper function. Provides float options to formatters. 
 * 
 * @return array
 */
 
function my_date_field_float_options() {
  return array(
      'left' => t('Left'),
      'right' => t('Right'),
  );
}
 
/**
 * Help function. Provides background image options to formatters. 
 * 
 * @return array
 */
function my_date_field_image_options() {
 
  $image_base_url = $GLOBALS['base_path'] . drupal_get_path('module', 'my_date') . '/images/';
  $attributes = array('style' => 'margin-top:10px;float:right;');
 
  $red_image = theme('image', array('path' => $image_base_url.'red-sky.png', 'alt' => 'red sky', 'title' => 'red sky', 'width'=>'25px', 'height' =>'25px', 'attributes' => $attributes));
  $blue_image = theme('image', array('path' => $image_base_url . 'blue-sky.png', 'alt' => 'red sky', 'title' => 'red sky','width'=>'25px', 'height' =>'25px', 'attributes' => $attributes));
  $green_image = theme('image', array('path' => $image_base_url . 'green-sky.png', 'alt' => 'red sky', 'title' => 'red sky','width' => '25px', 'height' => '25px', 'attributes' => $attributes));  
 
 
  return array(
      'none' => t('None'),
      'red' =>  $red_image,
      'blue' =>  $blue_image,
      'green' => $green_image,
  );
}
 
/**
 *  Implements hook_field_formatter_settings_form()
 */
function my_date_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  $format = $instance['display'][$view_mode];
  $settings = $format['settings'];
  $type = $format['type'];
 
  $element = array();
 
  $element['container'] = array(
    '#type' => 'fieldset',
    '#title' => t('Container Attributes'),
  );
 
  $element['container']['float'] = array(
      '#title' => t('Float'),
      '#type' => 'select',
      '#options' => my_date_field_float_options(),
      '#default_value' => isset($settings['container']['float']) ? $settings['container']['float'] : 'right',
  );
 
  $element['container']['class'] = array(
      '#title' => t('Class(es)'),
      '#type' => 'textfield',
      '#size' => 15,
      '#default_value' => !empty($settings['container']['class']) ? $settings['container']['class'] : '',
      '#required' => false,
  );
 
  $element['container']['inline_style'] = array(
      '#title' => t('Inline Style'),
      '#type' => 'textfield',
      '#default_value' => !empty($settings['container']['inline_style']) ? $settings['container']['inline_style'] : '',
      '#required' => false,
  );
 
  if ($type == 'my_date_detailed_formatter') {
 
    $field_name = $instance['field_name'];
 
    $element['container']['background'] = array(
      '#type' => 'fieldset',
      '#attributes' => array('style' =>'float:right;margin-left:4px;'),
      '#weight' => -20,
    );
 
    $element['container']['background']['image'] = array(
        '#type' => 'radios',
        '#title' => 'Choose Background Image',
        '#default_value' => $settings['container']['background']['image'],
        '#options' => my_date_field_image_options(),
    );
 
    $element['date_part'] = array(
        '#type' => 'fieldset',
        '#title' => t('Date Part Attributes'),
    );
 
    $element['date_part']['show_month'] = array(
        '#type' => 'checkbox',
        '#title' => 'Use Month',
        '#default_value' => isset($settings['date_part']['show_month']) ? TRUE : FALSE,
    );
 
    $element_name = 'fields[' . $field_name . '][settings_edit_form][settings][date_part][show_month]';
    $element['date_part']['inline_style_month'] = array(
        '#type' => 'textfield',
        '#title' => 'Inline Style Month',
        '#default_value' => $settings['date_part']['inline_style_month'],
        '#states' => array('visible' => 
            array(':input[name="' . $element_name . '"]' => 
                array('checked' => TRUE),
            )
        ),
    );
 
    $element['date_part']['show_day'] = array(
        '#type' => 'checkbox',
        '#title' => 'Use Day',
        '#default_value' => $settings['date_part']['show_day'] ? TRUE : FALSE,
    );
 
    $element_name = 'fields[' . $field_name . '][settings_edit_form][settings][date_part][show_day]';
    $element['date_part']['inline_style_day'] = array(
        '#type' => 'textfield',
        '#title' => 'Inline Style Day',
        '#default_value' => $settings['date_part']['inline_style_day'],
        '#states' => array('visible' => 
            array(':input[name="' . $element_name . '"]' => 
                array('checked' => TRUE),
            )
        ),
    );
 
    $element['date_part']['show_year'] = array(
        '#type' => 'checkbox',
        '#title' => 'Use Year',
        '#default_value' => $settings['date_part']['show_year'] ? TRUE : FALSE,
        '#states' => 
          array('visible' => 
              array(':input[name="' . $element_name . '"]' => 
                  array('checked' => TRUE),
              )
         ),
    );
 
    $element_name = 'fields[' . $field_name . '][settings_edit_form][settings][date_part][show_year]';
    $element['date_part']['inline_style_year'] = array(
        '#type' => 'textfield',
        '#title' => 'Inline Style Year',
        '#default_value' => $settings['date_part']['inline_style_year'],
        '#states' => array('visible' => 
            array(':input[name="' . $element_name . '"]' => 
                array('checked' => TRUE),
            )
        ),
    );
  }
 
  return $element;
}
 
/**
 *  Implements hook_field_formatter_settings_summary()
 */
function my_date_field_formatter_settings_summary($field, $instance, $view_mode) {
  $format = $instance['display'][$view_mode];
  $settings = $format['settings'];
 
  $summary = '';
 
  $styles = my_date_field_float_options();
  $summary = t('Float') . ': ' . $styles[$settings['container']['float']] . ', ';
 
  $class_summary = t('Class: ');
  $class_summary .= empty($settings['container']['class']) ? t('None') : $settings['container']['class'] . ', ';
  $summary .= $class_summary;
 
  $inline_summary = t(' Inline Style:');
  $inline_summary .= empty($settings['container']['inline_style']) ? t('None') : $settings['container']['inline_style'];
  $summary .= $inline_summary;
 
 
  if ('my_date_detailed_formatter' == $format['type']) {
 
    $show_month = isset($settings['date_part']['show_month']) ? TRUE : FALSE;
    $show_day = isset($settings['date_part']['show_day']) ? TRUE : FALSE;
    $show_year = isset($settings['date_part']['show_year']) ? TRUE : FALSE;
 
    $date_part_summary = 'Date Parts : ';
    $date_part_summary .= $show_month ? 'Month-' : '';
    $date_part_summary .= $show_day ? 'Day' : '';
    $date_part_summary .= $show_year ? '-Year' : '';
    $summary = $date_part_summary . ' ' . $summary;
  }
 
  return $summary;
}
 
/**
 * Implements hook_field_widget_form().
 */
function my_date_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
 
  $field_name = $field['field_name'];
 
  // are we working with a field setting form or a content form
  $is_settings_form_type = isset($form['type']['#type']) ? FALSE : TRUE;
 
  // A couple of default values we'll populate below
  $val = NULL;
  $use_today = NULL;
 
  switch ($instance['widget']['type']) {
 
    case 'my_date_text_select':
      if (isset($form_state['input'][$field_name][$langcode][$delta]['select_date'])) {
        $display_values = _process_display_my_date_widget($form_state, $field, $items, $delta, $is_settings_form_type);
 
        $val = $display_values['date_value'];
        $use_today = $display_values['use_today'];
      } else {
 
        $form_input_values = _process_user_input_my_date_widget($items, $delta, $is_settings_form_type);
        $val = $form_input_values['date_value'];
        $use_today = $form_input_values['use_today'];
      }
 
      $states = array();
      if ($is_settings_form_type) {
        $check_box_name = $field_name . '[' . $langcode . '][' . $delta . '][use_today]';
        $states = array('visible' => array(':input[name="' . $check_box_name . '"]' => array('checked' => FALSE),));
      }
 
      $element['my_date'] = array(
          '#type' => 'textfield',
          '#title' => $element['#title'],
          '#description' => $element['#description'],
          '#default_value' => $val,
          '#required' => $element['#required'],
          '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
          '#delta' => $delta,
          '#states' => $states,
          '#element_validate' => array('my_date_str_to_date_validate'),
          '#field_name' => $field_name,
      );
 
 
      $field_name_trimmed = substr($field_name, 6);
      $field_id = '#edit-field-' . $field_name_trimmed . '-' . $langcode . '-' . $delta . '-my-date';
      // replace underscores with dashes
      $field_id = str_replace('_', '-', $field_id);
      $js = '(function($){$(function() { $("' . $field_id . '").datepicker(); })})(jQuery);';
      $element['select_date']['#attached']['library'][] = array('system', 'ui.datepicker');
      $element['select_date']['#attached']['js'][] = array('data' => $js, 'type' => 'inline');
 
      if ($is_settings_form_type) {
 
        $element['use_today'] = array(
            '#type' => 'checkbox',
            '#title' => t('Use Today\'s Date'),
            '#return_value' => TRUE,
            '#default_value' => (boolean) $use_today,
        );
      } else {
        // we need to pass this value as a hidden element
        $element['use_today'] = array(
            '#type' => 'hidden',
            '#value' => $use_today,
        );
      }
      break;
  }
 
  return $element;
}
 
/**
 * Formats a value into a date string.
 * 
 * @param type $val
 * @return string
 *  a string formatted as a date.
 */
function my_date_field_to_string_format($val = NULL) {
 
  $formatted_value = NULL;
  // this must come first before is_numerirc
  if (is_string($val)) {
    $formatted_value = $val;
  }
  if (empty($val)) {
    $formatted_value = format_date(time(), 'custom', 'n/d/Y');
  }
 
  if (is_numeric($val)) {
    $formatted_value = format_date($val, 'custom', 'n/d/Y');
  }
 
  return $formatted_value;
}
 
/**
 * Implements hook_field_widget_error().
 */
function my_date_widget_error($element, $error, $form, &$form_state) {
  switch ($error['error']) {
    case 'my_date_invalid':
      form_error($element, $error['message']);
 
      break;
  }
}
 
/**
 * Implements hook_field_is_empty().
 */
function my_date_field_is_empty($item, $field) {
  if (empty($item['my_date'])) {
    return true;
  }
}
 
/**
 * Converts a validates a date string to a time stamp.
 * 
 * In addition, this function sets the form to correct timestamp value
 * so that the field api service stores the correct value. 
 * 
 * If $element does not contain a valid date string this method sets
 * a form error. 
 * 
 * We use the drupal api methods 
 * drupal_array_get_nested_value() and drupal_array_set_nested_value()
 * to get the date string form the deeply nested form_state array and 
 * the set the corresponding timestamp value (again back in to the deeply
 * nested form_state structure).
 *
 *
 * @param type $element
 * @param type $form_state
 *  
 */
function my_date_str_to_date_validate($element, &$form_state) {
 
  try {
 
    $date_string = drupal_array_get_nested_value($form_state['values'], $element['#parents']);
    $timestamp = my_date_field_convert_to_timestamp($date_string);
    drupal_array_set_nested_value($form_state['values'], $element['#parents'], $timestamp, TRUE);
  } catch (Exception $e) {
    form_error($element, $e->getMessage());
  }
}
 
function my_date_field_convert_to_timestamp($val) {
 
  $date_picked_array = date_parse($val);
  if ($date_picked_array['error_count'] > 0) {
    throw new Exception(t('Invalid Date Value: @val', array('@val' => $val)));
  }
  $time_value = mktime(0, 0, 0, $date_picked_array['month'], $date_picked_array['day'], $date_picked_array['year']);
 
  return $time_value;
}
 
/**
 * Private helper function.
 * 
 * After the user has submitted a form, the form is submitted back to the 
 * widget form constructor(my_date_field_widget_form()).This method
 * simply gaurantees that the widget connstructor doesn't over write the user's 
 * input before the submit handlers are called. 
 * 
 * The widget contructor is used in a couple differemt scenarios. This method
 * hides some of the details required by the various scenarios. For example,
 * are we configuring default valus for an attached instances. Or are we displaying
 * the widget to an end user who is simply selecting a content date. 
 * 
 * @param array $form_state
 * @param array $field
 * @param array $items
 * @param int $delta
 * @param boolean $is_settings_form_type
 * @return array
 *    the date value and whether we should default to today. 
 */
function _process_display_my_date_widget($form_state, $field, $items, $delta, $is_settings_form_type = FALSE) {
 
  $field_name = $field['field_name'];
  $field_type = $field['type'];
  $val = 0;
  $use_today = 0;
 
  $val = $form_state['input'][$field_name][$langcode][$delta]['select_date'];
 
  if ($is_settings_form_type) {    
    // if this a attachment setting form set the defaults
 
    $use_today = empty($form_state['input'][$field_name][$langcode][$delta]['use_today']) ? FALSE : TRUE;
 
    if ($use_today) {
      $val = my_date_field_to_string_format(time());
    }
  } else {
    $use_today = $form_state['input'][$field_name][$langcode][$delta]['use_today'];
  }
 
  return array('date_value' => $val, 'use_today' => $use_today);
}
 
 
/**
 * Private helper function. 
 * 
 * Used by the widget constructor (my_date_field_widget_form()). 
 * Takes care of populating the form elements, for form display, 
 * prior to user input.
 * 
 * The widget constructor is called during several different scenariois.
 * For example we could be attaching and configuring the widget to a content type. 
 * We set the defaults. If the content type setting uses this field many times, I.E.
 * has a cardinality of more than one. We use the default settings in the first cardinaliry instance.
 * 
 * The widget constructor is also called when the attached content is being edited.
 * 
 * This method simply poplutes the form elemets according the various scenario/use cases
 * mentioned above.
 * 
 * 
 * @param array $items
 * @param int $delta
 * @param boolean $is_settings_form_type
 * @return array 
 *  the date value and whether we should default to today.
 */
 
function _process_user_input_my_date_widget($items, $delta, $is_settings_form_type = FALSE) {
 
  $timestamp_value = isset($items[$delta]['my_date']) ? $items[$delta]['my_date'] : $items[0]['my_date'];
  $datestring_value = my_date_field_to_string_format($timestamp_value);
 
  if (!$is_settings_form_type) {
    // The widget constructor is being called for adding or updating content The entity (e.g. node)
    // that this field is attached to is being edited. .
 
    // we have 2 cases 1)  we have just one element
    // 2) cardinality is more than one -- the default is set for the whole set
 
    $use_today = FALSE;
 
    if (isset($items[$delta]['use_today'])) {
      $use_today = $items[$delta]['use_today'];
    } else {
      // this is where cardinality is more than one -- just use the setting stored in element/delta 0
      $use_today = $items[0]['use_today'];
    }
 
    if ($use_today) {
      $datestring_value = my_date_field_to_string_format(time());
    }
  }
 
  if ($is_settings_form_type) {
    // The widget constructor is be called during instance setting dialog.
    $use_today = $items[$delta]['use_today'];
  }
 
  return array('date_value' => $datestring_value, 'use_today' => $use_today);
}