Projet

Général

Profil

Paste
Télécharger (12,5 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / media / modules / media_wysiwyg / media_wysiwyg.module @ 2b3c8cc1

1
<?php
2

    
3
/**
4
 * @file
5
 * Primarily Drupal hooks.
6
 */
7

    
8
// Functions for tracking the file usage of [[inline tags]].
9
require_once dirname(__FILE__) . '/includes/media_wysiwyg.file_usage.inc';
10

    
11
// Functions for working with [[inline tags]] and wysiwyg editors.
12
require_once dirname(__FILE__) . '/includes/media_wysiwyg.filter.inc';
13

    
14
// Functions for UUID support to embedded media.
15
require_once dirname(__FILE__) . '/includes/media_wysiwyg.uuid.inc';
16

    
17
/**
18
 * Implements hook_hook_info().
19
 */
20
function media_wysiwyg_hook_info() {
21
  $hooks = array(
22
    'media_wysiwyg_token_to_markup_alter',
23
    'media_wysiwyg_allowed_view_modes_alter',
24
    'media_wysiwyg_format_form_prepare_alter',
25
  );
26

    
27
  return array_fill_keys($hooks, array('group' => 'media_wysiwyg'));
28
}
29

    
30
/**
31
 * Implements hook_menu().
32
 */
33
function media_wysiwyg_menu() {
34
  $items = array();
35

    
36
  $items['media/%file/format-form'] = array(
37
    'title' => 'Style selector',
38
    'description' => 'Choose a format for a piece of media',
39
    'page callback' => 'drupal_get_form',
40
    'page arguments' => array('media_wysiwyg_format_form', 1),
41
    'access callback' => 'media_wysiwyg_access',
42
    'access arguments' => array('view', 1),
43
    'file' => 'includes/media_wysiwyg.pages.inc',
44
    'theme callback' => 'media_dialog_get_theme_name',
45
    'type' => MENU_CALLBACK,
46
  );
47

    
48
  return $items;
49
}
50

    
51
/**
52
 * Implements hook_permission().
53
 */
54
function media_wysiwyg_permission() {
55
  return array(
56
    'use media wysiwyg' => array(
57
      'title' => t('Use Media WYSIWYG in an editor'),
58
      // Marked restrict because the WYSIWYG forms generate image derivatives,
59
      // which could lead to a DoS security vulnerability.
60
      'restrict access' => TRUE,
61
    ),
62
  );
63
}
64

    
65
/**
66
 * Access callback for WYSIWYG Media.
67
 */
68
function media_wysiwyg_access($op, $file = NULL, $account = NULL) {
69
  return user_access('use media wysiwyg', $account) && file_entity_access($op, $file, $account);
70
}
71

    
72
/**
73
 * Implements hook_element_info_alter().
74
 */
75
function media_wysiwyg_element_info_alter(&$types) {
76
  $types['text_format']['#pre_render'][] = 'media_wysiwyg_pre_render_text_format';
77
}
78

    
79
/**
80
 * Builds a map of media tags in the element.
81
 *
82
 * Builds a map of the media tags in an element that are being rendered to their
83
 * rendered HTML. The map is stored in JS, so we can transform them when the
84
 * editor is being displayed.
85
 */
86
function media_wysiwyg_pre_render_text_format($element) {
87
  // filter_process_format() copies properties to the expanded 'value' child
88
  // element.
89
  if (!isset($element['format'])) {
90
    return $element;
91
  }
92

    
93
  $field = &$element['value'];
94
  $settings = array(
95
    'field' => $field['#id'],
96
  );
97

    
98
  if (!isset($field['#value'])) {
99
    return $element;
100
  }
101

    
102
  $tagmap = _media_wysiwyg_generate_tagMap($field['#value']);
103

    
104
  if (isset($tagmap)) {
105
    $element['#attached']['js'][] = array(
106
      'data' => array(
107
        'tagmap' => $tagmap,
108
      ),
109
      'type' => 'setting',
110
    );
111
  }
112

    
113
  // Load the media browser library.
114
  $element['#attached']['library'][] = array('media', 'media_browser');
115
  $element['#attached']['library'][] = array('media', 'media_browser_settings');
116

    
117
  // Add wysiwyg-specific settings.
118
  $settings = array('wysiwyg_allowed_attributes' => variable_get('media_wysiwyg_wysiwyg_allowed_attributes', _media_wysiwyg_wysiwyg_allowed_attributes_default()));
119
  $element['#attached']['js'][] = array(
120
    'data' => array(
121
      'media' => $settings,
122
    ),
123
    'type' => 'setting',
124
  );
125

    
126
  // Add filter handling.
127
  $element['#attached']['js'][] = drupal_get_path('module', 'media_wysiwyg') . '/js/media_wysiwyg.filter.js';
128

    
129
  // Add CKEditor-specific JS.
130
  if (module_exists('ckeditor')) {
131
    $element['#attached']['js'][] = array(
132
      'data' => drupal_get_path('module', 'media_wysiwyg') . '/wysiwyg_plugins/media_ckeditor/library.js',
133
      'type' => 'file',
134
      'scope' => 'footer',
135
      'weight' => -20,
136
    );
137
  }
138

    
139
  return $element;
140
}
141

    
142
/**
143
 * Implements hook_form_FORM_ID_alter().
144
 */
145
function media_wysiwyg_form_wysiwyg_profile_form_alter(&$form, &$form_state) {
146
  // Add warnings if the media filter is disabled for the WYSIWYG's text format.
147
  $form['buttons']['drupal']['media']['#element_validate'][] = 'media_wysiwyg_wysiwyg_button_element_validate';
148
  $form['buttons']['drupal']['media']['#after_build'][] = 'media_wysiwyg_wysiwyg_button_element_validate';
149
  form_load_include($form_state, 'inc', 'media_wysiwyg', 'wysiwyg_plugins/media');
150
}
151

    
152
/**
153
 * Element validate callback for the media WYSIWYG button.
154
 */
155
function media_wysiwyg_wysiwyg_button_element_validate($element, &$form_state) {
156
  if (!empty($element['#value'])) {
157
    $format = filter_format_load($form_state['build_info']['args'][0]->format);
158
    $filters = filter_list_format($format->format);
159
    if (empty($filters['media_filter']->status)) {
160
      form_error($element, t('The <em>Convert Media tags to markup</em> filter must be enabled for the <a href="@format-link">@format format</a> in order to use the Media browser WYSIWYG button.', array(
161
        '@format-link' => url('admin/config/content/formats/' . $format->format, array('query' => array('destination' => $_GET['q']))),
162
        '@format' => $format->name,
163
      )));
164
    }
165
  }
166

    
167
  return $element;
168
}
169

    
170
/**
171
 * Implements hook_form_FORM_ID_alter().
172
 */
173
function media_wysiwyg_form_media_admin_config_browser_alter(&$form, &$form_state) {
174
  $form['wysiwyg'] = array(
175
    '#type' => 'fieldset',
176
    '#title' => t('WYSIWYG configuration'),
177
    '#collapsible' => TRUE,
178
    '#collapsed' => FALSE,
179
  );
180
  $form['wysiwyg']['media_wysiwyg_wysiwyg_browser_plugins'] = array(
181
    '#type' => 'checkboxes',
182
    '#title' => t('Enabled browser plugins'),
183
    '#options' => array(),
184
    '#required' => FALSE,
185
    '#default_value' => variable_get('media_wysiwyg_wysiwyg_browser_plugins', array()),
186
    '#description' => t('If no plugins are selected, they will all be available.'),
187
  );
188

    
189
  $plugins = media_get_browser_plugin_info();
190

    
191
  foreach ($plugins as $key => $plugin) {
192
    $form['wysiwyg']['media_wysiwyg_wysiwyg_browser_plugins']['#options'][$key] = !empty($plugin['title']) ? $plugin['title'] : $key;
193
  }
194

    
195
  $form['wysiwyg']['media_wysiwyg_wysiwyg_upload_directory'] = array(
196
    '#type' => 'textfield',
197
    '#title' => t("File directory for uploaded media"),
198
    '#default_value' => variable_get('media_wysiwyg_wysiwyg_upload_directory', ''),
199
    '#description' => t('Optional subdirectory within the upload destination where files will be stored. Do not include preceding or trailing slashes.'),
200
  );
201

    
202
  if (module_exists('token')) {
203
    $form['wysiwyg']['media_wysiwyg_wysiwyg_upload_directory']['#description'] .= t('This field supports tokens.');
204
    $form['wysiwyg']['tokens'] = array(
205
      '#theme' => 'token_tree',
206
      '#dialog' => TRUE,
207
    );
208
  }
209

    
210
  $form['wysiwyg']['media_wysiwyg_default_render'] = array(
211
    '#type' => 'radios',
212
    '#title' => t('How should file entities be rendered within a text field?'),
213
    '#description' => t("Full file entity rendering is the best choice for most sites. It respects the file entity's display settings specified at admin/structure/file-types. If your site already uses the legacy method, note that changing this option will affect your site's markup. Testing it on a non-production site is recommended."),
214
    '#options' => array(
215
      'file_entity' => 'Full file entity rendering',
216
      'field_attach' => 'Legacy rendering (using field attach)',
217
    ),
218
    '#default_value' => variable_get('media_wysiwyg_default_render', 'file_entity'),
219
  );
220

    
221
  $form['wysiwyg']['media_wysiwyg_wysiwyg_allowed_types'] = array(
222
    '#type' => 'checkboxes',
223
    '#title' => t('Allowed types in WYSIWYG'),
224
    '#options' => file_entity_type_get_names(),
225
    '#default_value' => variable_get('media_wysiwyg_wysiwyg_allowed_types', array('audio', 'image', 'video', 'document')),
226
  );
227

    
228
  $form['#submit'][] = 'media_wysiwyg_admin_config_browser_pre_submit';
229
}
230

    
231
/**
232
 * Manipulate values before form is submitted.
233
 */
234
function media_wysiwyg_admin_config_browser_pre_submit(&$form, &$form_state) {
235
  $wysiwyg_browser_plugins = array_unique(array_values($form_state['values']['media_wysiwyg_wysiwyg_browser_plugins']));
236
  if (empty($wysiwyg_browser_plugins[0])) {
237
    variable_del('media_wysiwyg_wysiwyg_browser_plugins');
238
    unset($form_state['values']['media_wysiwyg_wysiwyg_browser_plugins']);
239
  }
240
}
241

    
242
/**
243
 * Implements hook_filter_info().
244
 */
245
function media_wysiwyg_filter_info() {
246
  $filters['media_filter'] = array(
247
    'title' => t('Convert Media tags to markup'),
248
    'description' => t('This filter will convert [[{type:media... ]] tags into markup. This must be enabled for the Media WYSIWYG integration to work with this input format.'),
249
    'process callback' => 'media_wysiwyg_filter',
250
    'weight' => 2,
251
    // @TODO not implemented
252
    'tips callback' => 'media_filter_tips',
253
  );
254

    
255
  return $filters;
256
}
257

    
258
/**
259
 * Implements hook_wysiwyg_include_directory().
260
 */
261
function media_wysiwyg_wysiwyg_include_directory($type) {
262
  switch ($type) {
263
    case 'plugins':
264
      return 'wysiwyg_plugins';
265

    
266
      break;
267
  }
268
}
269

    
270
/**
271
 * Returns the default set of allowed attributes for use with WYSIWYG.
272
 *
273
 * @return array
274
 *   An array of whitelisted attributes.
275
 */
276
function _media_wysiwyg_wysiwyg_allowed_attributes_default() {
277
  return array(
278
    'alt',
279
    'title',
280
    'height',
281
    'width',
282
    'hspace',
283
    'vspace',
284
    'border',
285
    'align',
286
    'style',
287
    'class',
288
    'id',
289
    'usemap',
290
    'data-picture-group',
291
    'data-picture-align',
292
    'data-picture-mapping',
293
  );
294
}
295

    
296
/**
297
 * Returns a drupal_render() array for just the file portion of a file entity.
298
 *
299
 * Optional custom settings can override how the file is displayed.
300
 */
301
function media_wysiwyg_get_file_without_label($file, $view_mode, $settings = array()) {
302
  $file->override = $settings;
303

    
304
  $element = file_view_file($file, $view_mode);
305

    
306
  // The formatter invoked by file_view_file() can use $file->override to
307
  // customize the returned render array to match the requested settings. To
308
  // support simple formatters that don't do this, set the element attributes to
309
  // what was requested, but not if the formatter applied its own logic for
310
  // element attributes.
311
  if (isset($settings['attributes'])) {
312
    if (empty($element['#attributes'])) {
313
      $element['#attributes'] = $settings['attributes'];
314
    }
315

    
316
    // While this function may be called for any file type, images are a common
317
    // use-case, and image theme functions have their own structure for render
318
    // arrays.
319
    if (isset($element['#theme'])) {
320
      // theme_image() and theme_image_style() require the 'alt' attributes to
321
      // be passed separately from the 'attributes' array. (see
322
      // http://drupal.org/node/999338). Until that's fixed, implement this
323
      // special-case logic. Image formatters using other theme functions are
324
      // responsible for their own 'alt' attribute handling. See
325
      // theme_media_formatter_large_icon() for an example.
326
      if (in_array($element['#theme'], array('image', 'image_style'))) {
327
        if (empty($element['#alt']) && isset($settings['attributes']['alt'])) {
328
          $element['#alt'] = $settings['attributes']['alt'];
329
        }
330
      }
331
      // theme_image_formatter() and any potential replacements, such as
332
      // theme_colorbox_image_formatter(), also require attribute handling.
333
      elseif (strpos($element['#theme'], 'image_formatter') !== FALSE) {
334
        // theme_image_formatter() requires the attributes to be
335
        // set on the item rather than the element itself.
336
        if (empty($element['#item']['attributes'])) {
337
          $element['#item']['attributes'] = $settings['attributes'];
338
        }
339

    
340
        // theme_image_formatter() also requires alt, title, height, and
341
        // width attributes to be set on the item rather than within its
342
        // attributes array.
343
        foreach (array('alt', 'title', 'width', 'height') as $attr) {
344
          if (isset($settings['attributes'][$attr])) {
345
            $element['#item'][$attr] = $settings['attributes'][$attr];
346
          }
347
        }
348
      }
349
    }
350
  }
351

    
352
  return $element;
353
}
354

    
355
/**
356
 * Returns an array containing the names of all fields that perform text filtering.
357
 */
358
function media_wysiwyg_filter_fields_with_text_filtering($entity_type, $entity) {
359
  list($entity_id, $revision_id, $bundle) = entity_extract_ids($entity_type, $entity);
360
  $fields = field_info_instances($entity_type, $bundle);
361

    
362
  // Get all of the fields on this entity that allow text filtering.
363
  $fields_with_text_filtering = array();
364
  foreach ($fields as $field_name => $field) {
365
    if (!empty($field['settings']['text_processing'])) {
366
      $fields_with_text_filtering[] = $field_name;
367
    }
368
  }
369

    
370
  return $fields_with_text_filtering;
371
}