Mercurial > defr > drupal > scald > mee
diff mee.module @ 0:548f63d8a41b
Blam, simple MEE cck field type.
| author | David Eads <eads@chicagotech.org> |
|---|---|
| date | Tue, 10 Mar 2009 13:44:50 -0500 |
| parents | |
| children | 3d3d533f9eff |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mee.module Tue Mar 10 13:44:50 2009 -0500 @@ -0,0 +1,330 @@ +<?php +// $Id; +/** + * @file + * Defines a special textarea, with drag and drop media driven by Scald and + * dnd.module when rich text editing is enabled on the textarea via the + * WYSIWYG API. + */ + +/** + * Implementation of hook_theme(). + */ +function mee_theme() { + $theme = array( + 'mee_textarea' => array( + 'arguments' => array('element' => NULL), + ), + 'mee_formatter_default' => array( + 'arguments' => array('element' => NULL), + ), + ); + // @TODO enable! + //foreach (scald_contexts() as $context) { + // $theme['mee_formatter_'. $context] = array( + // 'arguments' => array('element' => NULL), + // 'function' => 'theme_mee_context_formatter', + // ); + //} + return $theme; +} + +/** + * Implementation of hook_field_info(). + */ +function mee_field_info() { + return array( + 'multimedia_editorial_element' => array( + 'label' => t('Multimedia Editorial Element (MEE)'), + 'description' => t('MEE combines Scald, WYSIWYG, and DnD to create a multimedia enabled text field.'), + ), + ); +} + +/** + * Implementation of hook_field_settings(). + */ +function mee_field_settings($op, $field) { + switch ($op) { + case 'form': + $form = array(); + $options = array(0 => t('Plain text'), 1 => t('Filtered text (user selects input format)')); + $form['mee_processing'] = array( + '#type' => 'radios', + '#title' => t('Text processing'), + '#default_value' => is_numeric($field['mee_processing']) ? $field['mee_processing'] : 1, + '#options' => $options, + '#description' => t('Filtered text, with a WYSIWYG editor defined on one or more input formats, is strongly recommended.'), + ); + // @TODO Ask Drupal about available libraries + $form['mee_dnd_callback_url'] = array( + '#type' => 'textfield', + '#title' => t('Library callback URL'), + '#default_value' => url($field['mee_dnd_callback_url']) ? $field['mee_dnd_callback_url'] : '', + '#description' => t('The absolute URL or relative path of a callback URL that provides proper JSON to the drag and drop library.'), + ); + return $form; + + case 'save': + return array('mee_processing', 'mee_dnd_callback_url'); + + case 'database columns': + $columns['value'] = array('type' => 'text', 'size' => 'big', 'not null' => FALSE, 'sortable' => TRUE); + $columns['dnd_callback_url'] = array('type' => 'text', 'size' => 'small', 'not null' => FALSE); + if (!empty($field['mee_processing'])) { + $columns['format'] = array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE); + } + return $columns; + + case 'views data': + return content_views_field_views_data($field); + } +} + +/** + * Implementation of hook_field(). + */ +function mee_field($op, &$node, $field, &$items, $teaser, $page) { + switch ($op) { + case 'sanitize': + foreach ($items as $delta => $item) { + if (!empty($field['mee_processing'])) { + $check = is_null($node) || (isset($node->build_mode) && $node->build_mode == NODE_BUILD_PREVIEW); + $text = isset($item['value']) ? check_markup($item['value'], $item['format'], $check) : ''; + } + else { + $text = check_plain($item['value']); + } + $items[$delta]['safe'] = $text; + } + } +} + +/** + * Implementation of hook_content_is_empty(). + */ +function mee_content_is_empty($item, $field) { + if (empty($item['value']) && (string)$item['value'] !== '0') { + return TRUE; + } + return FALSE; +} + +/** + * Implementation of hook_field_formatter_info(). + */ +function mee_field_formatter_info() { + $formatters = array( + 'default' => array( + 'label' => t('Filtered text'), + 'field types' => array('multimedia_editorial_element'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + 'plain' => array( + 'label' => t('Plain text'), + 'field types' => array('multimedia_editorial_element'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + ); + //@TODO generate context processor based field formatters + //foreach (scald_contexts() as $context) { + // $formatters[$context] = array( + // 'label' => t('Scald context processor: @context', array('@context' => $context), + // 'field types' => 'mee', + // ); + //} + return $formatters; +} + +function theme_mee_formatter_default($element) { + return $element['#item']['safe']; +} + +/** + * Theme function for 'plain' text field formatter. + */ +function theme_mee_formatter_plain($element) { + return strip_tags($element['#item']['safe']); +} + +function theme_mee_context_formatter($element) { + return 'foo'; +} + +/** + * Implementation of hook_widget_info(). + */ +function mee_widget_info() { + return array( + 'mee_textarea' => array( + 'label' => t('MEE Textarea'), + 'field types' => array('multimedia_editorial_element'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + ); +} + +/** + * Implementation of FAPI hook_elements(). + * + * Any FAPI callbacks needed for individual widgets can be declared here, + * and the element will be passed to those callbacks for processing. + * + * Drupal will automatically theme the element using a theme with + * the same name as the hook_elements key. + */ +function mee_elements() { + return array( + 'mee_textarea' => array( + '#input' => TRUE, + '#columns' => array('value', 'format'), '#delta' => 0, + '#process' => array('mee_textarea_process', 'dnd_process_textarea'), + '#filter_value' => FILTER_FORMAT_DEFAULT, + ), + ); +} + +/** + * Implementation of hook_widget_settings(). + */ +function mee_widget_settings($op, $widget) { + switch ($op) { + case 'form': + $form = array(); + $rows = (isset($widget['rows']) && is_numeric($widget['rows'])) ? $widget['rows'] : 5; + $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60; + $form['rows'] = array( + '#type' => 'textfield', + '#title' => t('Rows'), + '#default_value' => $rows, + '#element_validate' => array('_mee_widget_settings_row_validate'), + '#required' => TRUE, + ); + $form['size'] = array('#type' => 'hidden', '#value' => $size); + return $form; + + case 'save': + return array('rows', 'size'); + } +} + +function _mee_widget_settings_row_validate($element, &$form_state) { + $value = $form_state['values']['rows']; + if (!is_numeric($value) || intval($value) != $value || $value <= 0) { + form_error($element, t('"Rows" must be a positive integer.')); + } +} + +function _mee_widget_settings_size_validate($element, &$form_state) { + $value = $form_state['values']['size']; + if (!is_numeric($value) || intval($value) != $value || $value <= 0) { + form_error($element, t('"Size" must be a positive integer.')); + } +} + +/** + * Implementation of hook_widget(). + * + * Attach a single form element to the form. It will be built out and + * validated in the callback(s) listed in hook_elements. We build it + * out in the callbacks rather than here in hook_widget so it can be + * plugged into any module that can provide it with valid + * $field information. + * + * Content module will set the weight, field name and delta values + * for each form element. This is a change from earlier CCK versions + * where the widget managed its own multiple values. + * + * If there are multiple values for this field, the content module will + * call this function as many times as needed. + * + * @param $form + * the entire form array, $form['#node'] holds node information + * @param $form_state + * the form_state, $form_state['values'][$field['field_name']] + * holds the field's form values. + * @param $field + * the field array + * @param $items + * array of default values for this field + * @param $delta + * the order of this item in the array of subelements (0, 1, 2, etc) + * + * @return + * the form item for a single element for this field + */ +function mee_widget(&$form, &$form_state, $field, $items, $delta = 0) { + $element = array( + '#type' => $field['widget']['type'], + '#default_value' => isset($items[$delta]) ? $items[$delta] : '', + ); + return $element; +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + * The $fields array is in $form['#field_info'][$element['#field_name']]. + */ +function mee_textarea_process($element, $edit, $form_state, $form) { + drupal_add_css(drupal_get_path('module', 'mee') .'/css/mee.css'); + + $field = $form['#field_info'][$element['#field_name']]; + $field_key = $element['#columns'][0]; + $element[$field_key] = array( + '#type' => 'textarea', + '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL, + '#rows' => !empty($field['widget']['rows']) ? $field['widget']['rows'] : 10, + '#weight' => 0, + // The following values were set by the content module and need + // to be passed down to the nested element. + '#title' => $element['#title'], + '#description' => $element['#description'], + '#required' => $element['#required'], + '#field_name' => $element['#field_name'], + '#type_name' => $element['#type_name'], + '#delta' => $element['#delta'], + '#columns' => $element['#columns'], + '#prefix' => '<div class="mee-wrap-editor-library">', + '#suffix' => '</div>', + '#dnd-enabled' => TRUE, + '#dnd-settings' => array( + 'drop_selector' => '#'. $element['#id'] .' .drop', + 'url' => $field['mee_dnd_callback_url'], + ), + ); + + if (!empty($field['mee_processing'])) { + $filter_key = (count($element['#columns']) == 2) ? $element['#columns'][1] : 'format'; + $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : FILTER_FORMAT_DEFAULT; + $parents = array_merge($element['#parents'] , array($filter_key)); + $element[$filter_key] = filter_form($format, 1, $parents); + } + + // Used so that hook_field('validate') knows where to flag an error. + $element['_error_element'] = array( + '#type' => 'value', + '#value' => implode('][', array_merge($element['#parents'], array($field_key))), + ); + + + return $element; +} + +/** + * FAPI theme for an individual text elements. + * + * The textfield or textarea is already rendered by the + * textfield or textarea themes and the html output + * lives in $element['#children']. Override this theme to + * make custom changes to the output. + * + * $element['#field_name'] contains the field name + * $element['#delta] is the position of this element in the group + */ +function theme_mee_textarea($element) { + return $element['#children']; +}
