Projet

Général

Profil

Paste
Télécharger (9,71 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / media / modules / media_internet / media_internet.module @ ca0757b9

1
<?php
2

    
3
/**
4
 * Implements hook_hook_info().
5
 */
6
function media_internet_hook_info() {
7
  $hooks = array(
8
    'media_internet_providers',
9
  );
10

    
11
  return array_fill_keys($hooks, array('group' => 'media'));
12
}
13

    
14
/**
15
 * Implements hook_menu().
16
 */
17
function media_internet_menu() {
18
  $items['file/add/web'] = array(
19
    'title' => 'Web',
20
    'description' => 'Add internet files to your media library.',
21
    'page callback' => 'drupal_get_form',
22
    'page arguments' => array('media_internet_add_upload'),
23
    'access callback' => 'media_internet_access',
24
    'type' => MENU_LOCAL_TASK,
25
    'file' => 'file_entity.pages.inc',
26
    'file path' => drupal_get_path('module', 'file_entity'),
27
  );
28

    
29
  return $items;
30
}
31

    
32
/**
33
 * Access callback for the media_internet media browser plugin.
34
 */
35
function media_internet_access($account = NULL) {
36
  return user_access('administer files', $account) || user_access('add media from remote sources', $account);
37
}
38

    
39
/**
40
 * Implement hook_permission().
41
 */
42
function media_internet_permission() {
43
  return array(
44
    'add media from remote sources' => array(
45
      'title' => t('Add media from remote services'),
46
      'description' => t('Add media from remote sources such as other websites, YouTube, etc'),
47
    ),
48
  );
49
}
50

    
51
/**
52
 * Implements hook_theme().
53
 */
54
function media_internet_theme() {
55
  return array(
56
    // media_internet.pages.inc.
57
    'media_internet_embed_help' => array(
58
      'variables' => array('description' => NULL, 'supported_providers' => NULL),
59
    ),
60
  );
61
}
62

    
63
/**
64
 * Gets the list of providers.
65
 *
66
 * A "Provider" is a bit of meta-data like a title and a logo and a class which
67
 * can handle saving remote files.  Each provider is able to parse an embed code or URL
68
 * and store it as a file object in file_managed.
69
 */
70
function media_internet_get_providers() {
71
  $providers = &drupal_static(__FUNCTION__);
72

    
73
  if (!isset($providers)) {
74
    $cid = 'media:internet:providers';
75
    if ($cache = cache_get($cid)) {
76
      $providers = $cache->data;
77
    }
78
    else {
79
      $providers = array();
80
      foreach (module_implements('media_internet_providers') as $module) {
81
        foreach (module_invoke($module, 'media_internet_providers') as $key => $provider) {
82
          // Store the module here too for convinience.
83
          $providers[$key] = $provider;
84
          $providers[$key]['module'] = $module;
85
          if (!isset($providers[$key]['weight'])) {
86
            $providers[$key]['weight'] = 0;
87
          }
88
        }
89
      }
90
      uasort($providers, 'drupal_sort_weight');
91
      cache_set($cid, $providers);
92
    }
93
  }
94

    
95
  return $providers;
96
}
97

    
98
/**
99
 * Finds the appropriate provider for a given URL or embed_string
100
 *
101
 * Each provider has a claim() method which it uses to tell media_internet
102
 * that it should handle this input.  We cycle through all providers to find
103
 * the right one.
104
 *
105
 * @todo: Make this into a normal hook or something because we have to instantiate
106
 * each class to test and that's not right.
107
 */
108
function media_internet_get_provider($embed_string) {
109
  foreach (media_internet_get_providers() as $class_name => $nothing) {
110
    $p = new $class_name($embed_string);
111
    if ($p->claim($embed_string)) {
112
      return $p;
113
    }
114
  }
115
  throw new MediaInternetNoHandlerException(t('Unable to handle the provided embed string or URL.'));
116
}
117

    
118
/**
119
 * Returns HTML for help text based on supported internet media providers.
120
 *
121
 * @param $variables
122
 *   An associative array containing:
123
 *   - description: The normal description for this field, specified by the
124
 *     user.
125
 *   - supported_providers: A string of supported providers.
126
 *
127
 * @ingroup themeable
128
 */
129
function theme_media_internet_embed_help($variables) {
130
  $description = $variables['description'];
131
  $supported_providers = $variables['supported_providers'];
132

    
133
  $descriptions = array();
134

    
135
  if (strlen($description)) {
136
    $descriptions[] = $description;
137
  }
138
  if (!empty($supported_providers)) {
139
    $descriptions[] = t('Supported internet media providers: !providers.', array('!providers' => '<strong>' . $supported_providers . '</strong>'));
140
  }
141

    
142
  return implode('<br />', $descriptions);
143
}
144

    
145
/**
146
 * Implements hook_forms().
147
 */
148
function media_internet_forms($form_id, $args) {
149
  $forms = array();
150

    
151
  // Create a copy of the upload wizard form for internet media.
152
  if ($form_id == 'media_internet_add_upload') {
153
    $forms[$form_id] = array(
154
      'callback' => 'file_entity_add_upload',
155
    );
156
  }
157

    
158
  return $forms;
159
}
160

    
161
/**
162
 * Implements hook_form_FORM_ID_alter().
163
 */
164
function media_internet_form_file_entity_add_upload_alter(&$form, &$form_state, $form_id) {
165
  $step = $form['#step'];
166
  $options = $form['#options'];
167

    
168
  // Swap the upload field for an embed field when on the first step of the web
169
  // tab.
170
  if ($form_id == 'media_internet_add_upload' && $step == 1) {
171
    unset($form['upload']);
172

    
173
    $form['embed_code'] = array(
174
      '#type' => 'textfield',
175
      '#title' => t('File URL'),
176
      '#description' => t('Enter a URL to a file.'),
177
      '#attributes' => array('class' => array('media-add-from-url')),
178
      // There is no standard specifying a maximum length for a URL. Internet
179
      // Explorer supports up to 2083 (http://support.microsoft.com/kb/208427)
180
      // so we assume publicly available media URLs are within this limit.
181
      '#maxlength' => 2083,
182
      '#required' => TRUE,
183
      '#default_value' => isset($form_state['storage']['embed_code']) ? $form_state['storage']['embed_code'] : NULL,
184
    );
185

    
186
    // Create an array to hold potential Internet media providers.
187
    $providers = array();
188

    
189
    // Determine if there are any visible providers.
190
    foreach (media_internet_get_providers() as $key => $provider) {
191
      if (empty($provider['hidden']) || $provider['hidden'] != TRUE) {
192
        $providers[] = check_plain($provider['title']);
193
      }
194
    }
195

    
196
    $form['#providers'] = $providers;
197

    
198
    // Notify the user of any available providers.
199
    if ($providers) {
200
      // If any providers are enabled it is assumed that some kind of embed is supported.
201
      $form['embed_code']['#title'] = t('File URL or media resource');
202
      $form['embed_code']['#description'] = t('Enter a URL to a file or media resource. Many media providers also support identifying media via the embed code used to embed the media into external websites.');
203

    
204
      $form['embed_code']['#description'] = theme('media_internet_embed_help', array('description' => $form['embed_code']['#description'], 'supported_providers' => implode(' ', $providers)));
205
    }
206

    
207
    $form['#validators'] = array();
208

    
209
    if (!empty($options['types'])) {
210
      $form['#validators']['media_file_validate_types'] = array($options['types']);
211
    }
212

    
213
    // Add validation and submission handlers to the form and ensure that they
214
    // run first.
215
    array_unshift($form['#validate'], 'media_internet_add_validate');
216
    array_unshift($form['#submit'], 'media_internet_add_submit');
217
  }
218
}
219

    
220
/**
221
 * Allow stream wrappers to have their chance at validation.
222
 *
223
 * Any module that implements hook_media_parse will have an
224
 * opportunity to validate this.
225
 *
226
 * @see media_parse_to_uri()
227
 */
228
function media_internet_add_validate($form, &$form_state) {
229
  // Supporting providers can now claim this input. It might be a URL, but it
230
  // might be an embed code as well.
231
  $embed_code = $form_state['values']['embed_code'];
232

    
233
  try {
234
    $provider = media_internet_get_provider($embed_code);
235
    $provider->validate();
236
  }
237
  catch (MediaInternetNoHandlerException $e) {
238
    form_set_error('embed_code', $e->getMessage());
239
    return;
240
  }
241
  catch (MediaInternetValidationException $e) {
242
    form_set_error('embed_code', $e->getMessage());
243
    return;
244
  }
245

    
246
  $validators = $form['#validators'];
247
  $file = $provider->getFileObject();
248

    
249
  if ($validators) {
250
    try {
251
      $file = $provider->getFileObject();
252
    }
253
    catch (Exception $e) {
254
      form_set_error('embed_code', $e->getMessage());
255
      return;
256
    }
257

    
258
    // Check for errors. @see media_add_upload_validate calls file_save_upload().
259
    // this code is ripped from file_save_upload because we just want the validation part.
260
    // Call the validation functions specified by this function's caller.
261
    $errors = file_validate($file, $validators);
262

    
263
    if (!empty($errors)) {
264
      $message = t('%url could not be added.', array('%url' => $embed_code));
265
      if (count($errors) > 1) {
266
        $message .= theme('item_list', array('items' => $errors));
267
      }
268
      else {
269
        $message .= ' ' . array_pop($errors);
270
      }
271
      form_set_error('embed_code', $message);
272
      return FALSE;
273
    }
274
  }
275

    
276
  // @TODO: Validate that if we have no $uri that this is a valid file to
277
  // save. For instance, we may only be interested in images, and it would
278
  // be helpful to let the user know they passed the HTML page containing
279
  // the image accidentally. That would also save us from saving the file
280
  // in the submit step.
281

    
282
  // This is kinda a hack of the same.
283

    
284
  // This should use the file_validate routines that the upload form users.
285
  // We need to fix the media_parse_to_file routine to allow for a validation.
286
}
287

    
288
/**
289
 * Upload a file from a URL.
290
 *
291
 * This will copy a file from a remote location and store it locally.
292
 *
293
 * @see media_parse_to_uri()
294
 * @see media_parse_to_file()
295
 */
296
function media_internet_add_submit($form, &$form_state) {
297
  $embed_code = $form_state['values']['embed_code'];
298

    
299
  try {
300
    // Save the remote file
301
    $provider = media_internet_get_provider($embed_code);
302
    // Providers decide if they need to save locally or somewhere else.
303
    // This method returns a file object
304
    $file = $provider->save();
305
  }
306
  catch (Exception $e) {
307
    form_set_error('embed_code', $e->getMessage());
308
    return;
309
  }
310

    
311
  if (!$file->fid) {
312
    form_set_error('embed_code', t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $embed_code)));
313
    return;
314
  }
315
  else {
316
    $form_state['storage']['upload'] = $file->fid;
317
  }
318
}