Mercurial > defr > drupal > scald > mee
comparison 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 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:548f63d8a41b |
|---|---|
| 1 <?php | |
| 2 // $Id; | |
| 3 /** | |
| 4 * @file | |
| 5 * Defines a special textarea, with drag and drop media driven by Scald and | |
| 6 * dnd.module when rich text editing is enabled on the textarea via the | |
| 7 * WYSIWYG API. | |
| 8 */ | |
| 9 | |
| 10 /** | |
| 11 * Implementation of hook_theme(). | |
| 12 */ | |
| 13 function mee_theme() { | |
| 14 $theme = array( | |
| 15 'mee_textarea' => array( | |
| 16 'arguments' => array('element' => NULL), | |
| 17 ), | |
| 18 'mee_formatter_default' => array( | |
| 19 'arguments' => array('element' => NULL), | |
| 20 ), | |
| 21 ); | |
| 22 // @TODO enable! | |
| 23 //foreach (scald_contexts() as $context) { | |
| 24 // $theme['mee_formatter_'. $context] = array( | |
| 25 // 'arguments' => array('element' => NULL), | |
| 26 // 'function' => 'theme_mee_context_formatter', | |
| 27 // ); | |
| 28 //} | |
| 29 return $theme; | |
| 30 } | |
| 31 | |
| 32 /** | |
| 33 * Implementation of hook_field_info(). | |
| 34 */ | |
| 35 function mee_field_info() { | |
| 36 return array( | |
| 37 'multimedia_editorial_element' => array( | |
| 38 'label' => t('Multimedia Editorial Element (MEE)'), | |
| 39 'description' => t('MEE combines Scald, WYSIWYG, and DnD to create a multimedia enabled text field.'), | |
| 40 ), | |
| 41 ); | |
| 42 } | |
| 43 | |
| 44 /** | |
| 45 * Implementation of hook_field_settings(). | |
| 46 */ | |
| 47 function mee_field_settings($op, $field) { | |
| 48 switch ($op) { | |
| 49 case 'form': | |
| 50 $form = array(); | |
| 51 $options = array(0 => t('Plain text'), 1 => t('Filtered text (user selects input format)')); | |
| 52 $form['mee_processing'] = array( | |
| 53 '#type' => 'radios', | |
| 54 '#title' => t('Text processing'), | |
| 55 '#default_value' => is_numeric($field['mee_processing']) ? $field['mee_processing'] : 1, | |
| 56 '#options' => $options, | |
| 57 '#description' => t('Filtered text, with a WYSIWYG editor defined on one or more input formats, is strongly recommended.'), | |
| 58 ); | |
| 59 // @TODO Ask Drupal about available libraries | |
| 60 $form['mee_dnd_callback_url'] = array( | |
| 61 '#type' => 'textfield', | |
| 62 '#title' => t('Library callback URL'), | |
| 63 '#default_value' => url($field['mee_dnd_callback_url']) ? $field['mee_dnd_callback_url'] : '', | |
| 64 '#description' => t('The absolute URL or relative path of a callback URL that provides proper JSON to the drag and drop library.'), | |
| 65 ); | |
| 66 return $form; | |
| 67 | |
| 68 case 'save': | |
| 69 return array('mee_processing', 'mee_dnd_callback_url'); | |
| 70 | |
| 71 case 'database columns': | |
| 72 $columns['value'] = array('type' => 'text', 'size' => 'big', 'not null' => FALSE, 'sortable' => TRUE); | |
| 73 $columns['dnd_callback_url'] = array('type' => 'text', 'size' => 'small', 'not null' => FALSE); | |
| 74 if (!empty($field['mee_processing'])) { | |
| 75 $columns['format'] = array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE); | |
| 76 } | |
| 77 return $columns; | |
| 78 | |
| 79 case 'views data': | |
| 80 return content_views_field_views_data($field); | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 /** | |
| 85 * Implementation of hook_field(). | |
| 86 */ | |
| 87 function mee_field($op, &$node, $field, &$items, $teaser, $page) { | |
| 88 switch ($op) { | |
| 89 case 'sanitize': | |
| 90 foreach ($items as $delta => $item) { | |
| 91 if (!empty($field['mee_processing'])) { | |
| 92 $check = is_null($node) || (isset($node->build_mode) && $node->build_mode == NODE_BUILD_PREVIEW); | |
| 93 $text = isset($item['value']) ? check_markup($item['value'], $item['format'], $check) : ''; | |
| 94 } | |
| 95 else { | |
| 96 $text = check_plain($item['value']); | |
| 97 } | |
| 98 $items[$delta]['safe'] = $text; | |
| 99 } | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 /** | |
| 104 * Implementation of hook_content_is_empty(). | |
| 105 */ | |
| 106 function mee_content_is_empty($item, $field) { | |
| 107 if (empty($item['value']) && (string)$item['value'] !== '0') { | |
| 108 return TRUE; | |
| 109 } | |
| 110 return FALSE; | |
| 111 } | |
| 112 | |
| 113 /** | |
| 114 * Implementation of hook_field_formatter_info(). | |
| 115 */ | |
| 116 function mee_field_formatter_info() { | |
| 117 $formatters = array( | |
| 118 'default' => array( | |
| 119 'label' => t('Filtered text'), | |
| 120 'field types' => array('multimedia_editorial_element'), | |
| 121 'multiple values' => CONTENT_HANDLE_CORE, | |
| 122 ), | |
| 123 'plain' => array( | |
| 124 'label' => t('Plain text'), | |
| 125 'field types' => array('multimedia_editorial_element'), | |
| 126 'multiple values' => CONTENT_HANDLE_CORE, | |
| 127 ), | |
| 128 ); | |
| 129 //@TODO generate context processor based field formatters | |
| 130 //foreach (scald_contexts() as $context) { | |
| 131 // $formatters[$context] = array( | |
| 132 // 'label' => t('Scald context processor: @context', array('@context' => $context), | |
| 133 // 'field types' => 'mee', | |
| 134 // ); | |
| 135 //} | |
| 136 return $formatters; | |
| 137 } | |
| 138 | |
| 139 function theme_mee_formatter_default($element) { | |
| 140 return $element['#item']['safe']; | |
| 141 } | |
| 142 | |
| 143 /** | |
| 144 * Theme function for 'plain' text field formatter. | |
| 145 */ | |
| 146 function theme_mee_formatter_plain($element) { | |
| 147 return strip_tags($element['#item']['safe']); | |
| 148 } | |
| 149 | |
| 150 function theme_mee_context_formatter($element) { | |
| 151 return 'foo'; | |
| 152 } | |
| 153 | |
| 154 /** | |
| 155 * Implementation of hook_widget_info(). | |
| 156 */ | |
| 157 function mee_widget_info() { | |
| 158 return array( | |
| 159 'mee_textarea' => array( | |
| 160 'label' => t('MEE Textarea'), | |
| 161 'field types' => array('multimedia_editorial_element'), | |
| 162 'multiple values' => CONTENT_HANDLE_CORE, | |
| 163 ), | |
| 164 ); | |
| 165 } | |
| 166 | |
| 167 /** | |
| 168 * Implementation of FAPI hook_elements(). | |
| 169 * | |
| 170 * Any FAPI callbacks needed for individual widgets can be declared here, | |
| 171 * and the element will be passed to those callbacks for processing. | |
| 172 * | |
| 173 * Drupal will automatically theme the element using a theme with | |
| 174 * the same name as the hook_elements key. | |
| 175 */ | |
| 176 function mee_elements() { | |
| 177 return array( | |
| 178 'mee_textarea' => array( | |
| 179 '#input' => TRUE, | |
| 180 '#columns' => array('value', 'format'), '#delta' => 0, | |
| 181 '#process' => array('mee_textarea_process', 'dnd_process_textarea'), | |
| 182 '#filter_value' => FILTER_FORMAT_DEFAULT, | |
| 183 ), | |
| 184 ); | |
| 185 } | |
| 186 | |
| 187 /** | |
| 188 * Implementation of hook_widget_settings(). | |
| 189 */ | |
| 190 function mee_widget_settings($op, $widget) { | |
| 191 switch ($op) { | |
| 192 case 'form': | |
| 193 $form = array(); | |
| 194 $rows = (isset($widget['rows']) && is_numeric($widget['rows'])) ? $widget['rows'] : 5; | |
| 195 $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60; | |
| 196 $form['rows'] = array( | |
| 197 '#type' => 'textfield', | |
| 198 '#title' => t('Rows'), | |
| 199 '#default_value' => $rows, | |
| 200 '#element_validate' => array('_mee_widget_settings_row_validate'), | |
| 201 '#required' => TRUE, | |
| 202 ); | |
| 203 $form['size'] = array('#type' => 'hidden', '#value' => $size); | |
| 204 return $form; | |
| 205 | |
| 206 case 'save': | |
| 207 return array('rows', 'size'); | |
| 208 } | |
| 209 } | |
| 210 | |
| 211 function _mee_widget_settings_row_validate($element, &$form_state) { | |
| 212 $value = $form_state['values']['rows']; | |
| 213 if (!is_numeric($value) || intval($value) != $value || $value <= 0) { | |
| 214 form_error($element, t('"Rows" must be a positive integer.')); | |
| 215 } | |
| 216 } | |
| 217 | |
| 218 function _mee_widget_settings_size_validate($element, &$form_state) { | |
| 219 $value = $form_state['values']['size']; | |
| 220 if (!is_numeric($value) || intval($value) != $value || $value <= 0) { | |
| 221 form_error($element, t('"Size" must be a positive integer.')); | |
| 222 } | |
| 223 } | |
| 224 | |
| 225 /** | |
| 226 * Implementation of hook_widget(). | |
| 227 * | |
| 228 * Attach a single form element to the form. It will be built out and | |
| 229 * validated in the callback(s) listed in hook_elements. We build it | |
| 230 * out in the callbacks rather than here in hook_widget so it can be | |
| 231 * plugged into any module that can provide it with valid | |
| 232 * $field information. | |
| 233 * | |
| 234 * Content module will set the weight, field name and delta values | |
| 235 * for each form element. This is a change from earlier CCK versions | |
| 236 * where the widget managed its own multiple values. | |
| 237 * | |
| 238 * If there are multiple values for this field, the content module will | |
| 239 * call this function as many times as needed. | |
| 240 * | |
| 241 * @param $form | |
| 242 * the entire form array, $form['#node'] holds node information | |
| 243 * @param $form_state | |
| 244 * the form_state, $form_state['values'][$field['field_name']] | |
| 245 * holds the field's form values. | |
| 246 * @param $field | |
| 247 * the field array | |
| 248 * @param $items | |
| 249 * array of default values for this field | |
| 250 * @param $delta | |
| 251 * the order of this item in the array of subelements (0, 1, 2, etc) | |
| 252 * | |
| 253 * @return | |
| 254 * the form item for a single element for this field | |
| 255 */ | |
| 256 function mee_widget(&$form, &$form_state, $field, $items, $delta = 0) { | |
| 257 $element = array( | |
| 258 '#type' => $field['widget']['type'], | |
| 259 '#default_value' => isset($items[$delta]) ? $items[$delta] : '', | |
| 260 ); | |
| 261 return $element; | |
| 262 } | |
| 263 | |
| 264 /** | |
| 265 * Process an individual element. | |
| 266 * | |
| 267 * Build the form element. When creating a form using FAPI #process, | |
| 268 * note that $element['#value'] is already set. | |
| 269 * | |
| 270 * The $fields array is in $form['#field_info'][$element['#field_name']]. | |
| 271 */ | |
| 272 function mee_textarea_process($element, $edit, $form_state, $form) { | |
| 273 drupal_add_css(drupal_get_path('module', 'mee') .'/css/mee.css'); | |
| 274 | |
| 275 $field = $form['#field_info'][$element['#field_name']]; | |
| 276 $field_key = $element['#columns'][0]; | |
| 277 $element[$field_key] = array( | |
| 278 '#type' => 'textarea', | |
| 279 '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL, | |
| 280 '#rows' => !empty($field['widget']['rows']) ? $field['widget']['rows'] : 10, | |
| 281 '#weight' => 0, | |
| 282 // The following values were set by the content module and need | |
| 283 // to be passed down to the nested element. | |
| 284 '#title' => $element['#title'], | |
| 285 '#description' => $element['#description'], | |
| 286 '#required' => $element['#required'], | |
| 287 '#field_name' => $element['#field_name'], | |
| 288 '#type_name' => $element['#type_name'], | |
| 289 '#delta' => $element['#delta'], | |
| 290 '#columns' => $element['#columns'], | |
| 291 '#prefix' => '<div class="mee-wrap-editor-library">', | |
| 292 '#suffix' => '</div>', | |
| 293 '#dnd-enabled' => TRUE, | |
| 294 '#dnd-settings' => array( | |
| 295 'drop_selector' => '#'. $element['#id'] .' .drop', | |
| 296 'url' => $field['mee_dnd_callback_url'], | |
| 297 ), | |
| 298 ); | |
| 299 | |
| 300 if (!empty($field['mee_processing'])) { | |
| 301 $filter_key = (count($element['#columns']) == 2) ? $element['#columns'][1] : 'format'; | |
| 302 $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : FILTER_FORMAT_DEFAULT; | |
| 303 $parents = array_merge($element['#parents'] , array($filter_key)); | |
| 304 $element[$filter_key] = filter_form($format, 1, $parents); | |
| 305 } | |
| 306 | |
| 307 // Used so that hook_field('validate') knows where to flag an error. | |
| 308 $element['_error_element'] = array( | |
| 309 '#type' => 'value', | |
| 310 '#value' => implode('][', array_merge($element['#parents'], array($field_key))), | |
| 311 ); | |
| 312 | |
| 313 | |
| 314 return $element; | |
| 315 } | |
| 316 | |
| 317 /** | |
| 318 * FAPI theme for an individual text elements. | |
| 319 * | |
| 320 * The textfield or textarea is already rendered by the | |
| 321 * textfield or textarea themes and the html output | |
| 322 * lives in $element['#children']. Override this theme to | |
| 323 * make custom changes to the output. | |
| 324 * | |
| 325 * $element['#field_name'] contains the field name | |
| 326 * $element['#delta] is the position of this element in the group | |
| 327 */ | |
| 328 function theme_mee_textarea($element) { | |
| 329 return $element['#children']; | |
| 330 } |
