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
|
}
|