media.module

  1. cis7 sites/all/modules/ulmus/media/media.module
  2. cle7 sites/all/modules/ulmus/media/media.module
  3. ecd7 sites/all/modules/ulmus/media/media.module
  4. elmsmedia7 sites/all/modules/ulmus/media/media.module
  5. harmony7 sites/all/modules/ulmus/media/media.module
  6. icor7 sites/all/modules/ulmus/media/media.module
  7. meedjum_blog7 sites/all/modules/ulmus/media/media.module
  8. mooc7 sites/all/modules/ulmus/media/media.module

Media API

The core Media API. See http://drupal.org/project/media for more details.

Functions

Namesort descending Description
media_access Access callback for files. This function is deprecated.
media_admin_paths Implements hook_admin_paths().
media_browser_form_submit Submit handler; direction form submissions in the media browser.
media_ctools_plugin_api Implements hook_ctools_plugin_api().
media_dialog_get_theme_name Theme callback used to identify when we are in a popup dialog.
media_element_info Implements hook_element_info().
media_element_info_alter Implements hook_element_info_alter().
media_element_process Process callback for the media form element.
media_element_validate Validate media form elements.
media_entity_info_alter Implements hook_entity_info_alter().
media_file_default_displays_alter Implements hook_file_default_displays_alter().
media_file_displays_alter Implements hook_file_displays_alter().
media_file_edit_url Return a URL for editing an files.
media_file_list_element_process Process callback for the media_browser element.
media_file_operations Implements hook_file_operations().
media_file_operation_edit_multiple Callback for the edit operation.
media_file_validate_types Check that the media is one of the selected types.
media_filter_info Implements hook_filter_info().
media_forms Implements hook_forms().
media_form_alter Implements hook_form_alter().
media_form_field_ui_field_edit_form_alter Implements hook_form_FIELD_UI_FIELD_EDIT_FORM_alter().
media_form_field_ui_field_settings_form_alter Implements hook_form_FIELD_UI_FIELD_SETTINGS_FORM_alter().
media_form_file_entity_admin_file_alter Implements hook_form_FORM_ID_alter().
media_form_file_entity_edit_alter Implements hook_form_FORM_ID_alter().
media_form_wysiwyg_profile_form_alter Implements hook_form_FORM_ID_alter().
media_get_browser_plugin_info Returns metadata describing Media browser plugins.
media_get_local_stream_wrappers Helper function to get a list of local stream wrappers.
media_get_remote_stream_wrappers Helper function to get a list of remote stream wrappers.
media_get_thumbnail_preview Media thumbnail render function.
media_help Implements hook_help().
media_hook_info Implements hook_hook_info().
media_image_default_styles Implements hook_image_default_styles().
media_library Implements hook_library().
media_load_all_exports Fetches an array of exportables from files.
media_menu Implements hook_menu().
media_menu_local_tasks_alter Implements hook_menu_local_tasks_alter().
media_multi_load Load callback for %media_multi placeholder in menu paths.
media_page_alter Implements hook_page_alter().
media_parse_to_file Parse a URL or embed code and return a file object.
media_parse_to_uri This will parse a url or embedded code into a unique URI.
media_permission Implements hook_permission().
media_recursive_check_plain Utility function to recursively run check_plain on an array.
media_theme Implements hook_theme().
media_views_api Implements hook_views_api().
media_views_default_views Implements hook_views_default_views().
_media_file_entity_access_recursive Access callback for the media-multi form.
_media_get_migratable_file_types Checks if there are any files that belong to disabled or deleted file types.

File

sites/all/modules/ulmus/media/media.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * Media API
  5. *
  6. * The core Media API.
  7. * See http://drupal.org/project/media for more details.
  8. */
  9. /* ***************************************** */
  10. /* INCLUDES */
  11. /* ***************************************** */
  12. // Code relating to using media as a field.
  13. require_once dirname(__FILE__) . '/includes/media.fields.inc';
  14. // Functions for working with [[inline tags]] and wysiwyg editors.
  15. require_once dirname(__FILE__) . '/includes/media.filter.inc';
  16. /* ***************************************** */
  17. /* Hook Implementations */
  18. /* ***************************************** */
  19. /**
  20. * Implements hook_hook_info().
  21. */
  22. function media_hook_info() {
  23. $hooks = array(
  24. 'media_parse',
  25. 'media_browser_plugin_info',
  26. 'media_browser_plugin_info_alter',
  27. 'media_browser_plugins_alter',
  28. 'media_browser_params_alter',
  29. 'media_wysiwyg_allowed_view_modes_alter',
  30. 'media_format_form_prepare_alter',
  31. 'media_token_to_markup_alter',
  32. 'query_media_browser_alter',
  33. );
  34. return array_fill_keys($hooks, array('group' => 'media'));
  35. }
  36. /**
  37. * Implements hook_help().
  38. */
  39. function media_help($path, $arg) {
  40. switch ($path) {
  41. case 'admin/help#media':
  42. $output = '';
  43. $output .= '<h3>' . t('About') . '</h3>';
  44. $output .= '<p>' . t('The Media module is a File Browser to the Internet, media provides a framework for managing files and multimedia assets, regardless of whether they are hosted on your own site or a 3rd party site. It replaces the Drupal core upload field with a unified User Interface where editors and administrators can upload, manage, and reuse files and multimedia assets. Media module also provides rich integration with WYSIWYG module to let content creators access media assets in rich text editor. Javascript is required to use the Media module. For more information check <a href="@media_faq">Media Module page</a>', array('@media_faq' => 'http://drupal.org/project/media')) . '.</p>';
  45. $output .= '<h3>' . t('Uses') . '</h3>';
  46. $output .= '<dl>';
  47. $output .= '<dt>' . t('Media Repository') . '</dt>';
  48. $output .= '<dd>' . t('Media module allows you to maintain a <a href="@mediarepo">media asset repository</a> where in you can add, remove, reuse your media assets. You can add the media file using upload form or from a url and also do bulk operations on the media assets.', array('@mediarepo' => url('admin/content/media'))) . '</dd>';
  49. $output .= '<dt>' . t('Attaching media assets to content types') . '</dt>';
  50. $output .= '<dd>' . t('Media assets can be attached to content types as fields. To add a media field to a <a href="@content-type">content type</a>, go to the content type\'s <em>manage fields</em> page, and add a new field of type <em>Multimedia Asset</em>.', array('@content-type' => url('admin/structure/types'))) . '</dd>';
  51. $output .= '<dt>' . t('Using media assets in WYSIWYG') . '</dt>';
  52. $output .= '<dd>' . t('Media module provides rich integration with WYSIWYG editors, using Media Browser plugin you can select media asset from library to add to the rich text editor moreover you can add media asset from the media browser itself using either upload method or add from url method. To configure media with WYSIWYG you need two steps of configuration:');
  53. $output .= '<ul><li>' . t('Enable WYSIWYG plugin on your desired <a href="@wysiwyg-profile">WYSIWYG profile</a>. Please note that you will need to have <a href="@wysiwyg">WYSIWYG</a> module enabled.', array('@wysiwyg-profile' => url('admin/config/content/wysiwyg'), '@wysiwyg' => 'http://drupal.org/project/wysiwyg')) . '</li>';
  54. $output .= '<li>' . t('Enable the <em>Convert Media tags to markup</em> filter on the <a href="@input-format">Input format</a> you are using with the WYSIWYG profile.', array('@input-format' => url('admin/config/content/formats'))) . '</li></ul></dd>';
  55. return $output;
  56. }
  57. }
  58. /**
  59. * Implements hook_entity_info_alter().
  60. */
  61. function media_entity_info_alter(&$entity_info) {
  62. // For sites that updated from Media 1.x, continue to provide these deprecated
  63. // view modes.
  64. // @see http://drupal.org/node/1051090
  65. if (variable_get('media__show_deprecated_view_modes', FALSE)) {
  66. $entity_info['file']['view modes'] += array(
  67. 'media_link' => array(
  68. 'label' => t('Link'),
  69. 'custom settings' => TRUE,
  70. ),
  71. 'media_original' => array(
  72. 'label' => t('Original'),
  73. 'custom settings' => TRUE,
  74. ),
  75. );
  76. }
  77. if (module_exists('entity_translation')) {
  78. $entity_info['file']['translation']['entity_translation']['class'] = 'MediaEntityTranslationHandler';
  79. $entity_info['file']['translation']['entity_translation']['path schemes']['media'] = array('edit path' => 'media/%file/edit/%ctools_js');
  80. }
  81. }
  82. /**
  83. * Access callback for files. This function is deprecated.
  84. *
  85. * @todo Completely remove this function in favor of file_entity_access after
  86. * a few releases, to ensure rest of contib catches up.
  87. */
  88. function media_access($op, $account = NULL) {
  89. return user_access('administer files', $account);
  90. }
  91. /**
  92. * Implements hook_menu().
  93. */
  94. function media_menu() {
  95. // For managing different types of media and the fields associated with them.
  96. $items['admin/config/media/browser'] = array(
  97. 'title' => 'Media browser settings',
  98. 'description' => 'Configure the behavior and display of the media browser.',
  99. 'page callback' => 'drupal_get_form',
  100. 'page arguments' => array('media_admin_config_browser'),
  101. 'access arguments' => array('administer media browser'),
  102. 'file' => 'includes/media.admin.inc',
  103. );
  104. // Administrative screens for managing media.
  105. $items['admin/content/file/thumbnails'] = array(
  106. 'title' => 'Thumbnails',
  107. 'description' => 'Manage files used on your site.',
  108. 'page callback' => 'drupal_get_form',
  109. 'page arguments' => array('file_entity_admin_file'),
  110. 'access arguments' => array('administer files'),
  111. 'type' => MENU_LOCAL_TASK,
  112. 'file' => 'file_entity.admin.inc',
  113. 'file path' => drupal_get_path('module', 'file_entity'),
  114. 'weight' => 10,
  115. );
  116. // Used to import files from a local filesystem into Drupal.
  117. $items['admin/content/file/import'] = array(
  118. 'title' => 'Import files',
  119. 'description' => 'Import files into your media library.',
  120. 'page callback' => 'drupal_get_form',
  121. 'page arguments' => array('media_import'),
  122. 'access arguments' => array('import media'),
  123. 'type' => MENU_LOCAL_ACTION,
  124. 'file' => 'includes/media.admin.inc',
  125. 'weight' => 10,
  126. );
  127. $items['admin/content/file/thumbnails/import'] = $items['admin/content/file/import'];
  128. $items['media/browser'] = array(
  129. 'title' => 'Media browser',
  130. 'description' => 'Media Browser for picking media and uploading new media',
  131. 'page callback' => 'media_browser',
  132. 'access callback' => 'file_entity_access',
  133. 'access arguments' => array('create'),
  134. 'type' => MENU_CALLBACK,
  135. 'file' => 'includes/media.browser.inc',
  136. 'theme callback' => 'media_dialog_get_theme_name',
  137. );
  138. // A testbed to try out the media browser with different launch commands.
  139. $items['media/browser/testbed'] = array(
  140. 'title' => 'Media Browser test',
  141. 'description' => 'Make it easier to test media browser',
  142. 'page callback' => 'drupal_get_form',
  143. 'page arguments' => array('media_browser_testbed'),
  144. 'access arguments' => array('administer files'),
  145. 'type' => MENU_CALLBACK,
  146. 'file' => 'includes/media.browser.inc',
  147. );
  148. $items['media/%file/format-form'] = array(
  149. 'title' => 'Style selector',
  150. 'description' => 'Choose a format for a piece of media',
  151. 'page callback' => 'drupal_get_form',
  152. 'page arguments' => array('media_format_form', 1),
  153. 'access callback' => 'file_entity_access',
  154. 'access arguments' => array('view', 1),
  155. 'file' => 'includes/media.filter.inc',
  156. 'theme callback' => 'media_dialog_get_theme_name',
  157. 'type' => MENU_CALLBACK,
  158. );
  159. if (module_exists('multiform')) {
  160. // @todo Investigate passing file IDs in query string rather than a menu
  161. // argument and then deprecate media_multi_load().
  162. $items['admin/content/file/edit-multiple/%media_multi'] = array(
  163. 'title' => 'Edit multiple files',
  164. 'page callback' => 'media_file_page_edit_multiple',
  165. 'page arguments' => array(4),
  166. 'access callback' => '_media_file_entity_access_recursive',
  167. 'access arguments' => array(4, 'update'),
  168. 'file' => 'includes/media.pages.inc',
  169. );
  170. }
  171. // We could re-use the file/%file/edit path for the modal callback, but
  172. // it is just easier to use our own namespace here.
  173. $items['media/%file/edit/%ctools_js'] = array(
  174. 'title' => 'Edit',
  175. 'page callback' => 'drupal_get_form',
  176. 'page arguments' => array('media_file_edit_modal', 1, 3),
  177. 'access callback' => 'file_entity_access',
  178. 'access arguments' => array('update', 1),
  179. 'file' => 'includes/media.pages.inc',
  180. 'type' => MENU_CALLBACK,
  181. );
  182. // Upgrade interface for old file types.
  183. $items['admin/structure/file-types/upgrade'] = array(
  184. 'title' => 'Upgrade types',
  185. 'page callback' => 'drupal_get_form',
  186. 'page arguments' => array('media_upgrade_file_types'),
  187. 'access arguments' => array('administer file types'),
  188. 'file' => 'includes/media.pages.inc',
  189. 'type' => MENU_CALLBACK,
  190. );
  191. $items['admin/structure/file-types/upgrade/confirm'] = array(
  192. 'title' => 'Upgrade types',
  193. 'page callback' => 'drupal_get_form',
  194. 'page arguments' => array('media_upgrade_file_types_confirm'),
  195. 'access arguments' => array('administer file types'),
  196. 'file' => 'includes/media.pages.inc',
  197. 'type' => MENU_CALLBACK,
  198. );
  199. return $items;
  200. }
  201. /**
  202. * Implements hook_menu_local_tasks_alter().
  203. */
  204. function media_menu_local_tasks_alter(&$data, $router_item, $root_path) {
  205. // Add action link to 'file/add' on 'admin/content/file/thumbnails' page.
  206. if ($root_path == 'admin/content/file/thumbnails') {
  207. $item = menu_get_item('file/add');
  208. if (!empty($item['access'])) {
  209. $data['actions']['output'][] = array(
  210. '#theme' => 'menu_local_action',
  211. '#link' => $item,
  212. '#weight' => $item['weight'],
  213. );
  214. }
  215. }
  216. }
  217. /**
  218. * Implements hook_admin_paths().
  219. */
  220. function media_admin_paths() {
  221. $paths['media/*/edit/*'] = TRUE;
  222. // If the media browser theme is set to the admin theme, ensure it gets set
  223. // as an admin path as well.
  224. $dialog_theme = variable_get('media__dialog_theme', '');
  225. if (empty($dialog_theme) || $dialog_theme == variable_get('admin_theme')) {
  226. $paths['media/browser'] = TRUE;
  227. $paths['media/browser/*'] = TRUE;
  228. }
  229. return $paths;
  230. }
  231. /**
  232. * Implements hook_permission().
  233. */
  234. function media_permission() {
  235. return array(
  236. 'administer media browser' => array(
  237. 'title' => t('Administer media browser'),
  238. 'description' => t('Access media browser settings.'),
  239. ),
  240. 'import media' => array(
  241. 'title' => t('Import media files from the local filesystem'),
  242. 'description' => t('Simple file importer'),
  243. ),
  244. );
  245. }
  246. /**
  247. * Implements hook_theme().
  248. */
  249. function media_theme() {
  250. return array(
  251. // The default media file list form element.
  252. 'media_file_list' => array(
  253. 'variables' => array('element' => NULL),
  254. ),
  255. // A preview of the uploaded file.
  256. 'media_thumbnail' => array(
  257. 'render element' => 'element',
  258. 'file' => 'includes/media.theme.inc',
  259. ),
  260. // Dialog page.
  261. 'media_dialog_page' => array(
  262. 'render element' => 'page',
  263. 'template' => 'templates/media-dialog-page',
  264. 'file' => 'includes/media.theme.inc',
  265. ),
  266. // Media form API element type.
  267. 'media_element' => array(
  268. 'render element' => 'element',
  269. 'file' => 'includes/media.theme.inc',
  270. ),
  271. // Display a file as a large icon.
  272. 'media_formatter_large_icon' => array(
  273. 'variables' => array('file' => NULL, 'attributes' => array(), 'style_name' => 'media_thumbnail'),
  274. 'file' => 'includes/media.theme.inc',
  275. ),
  276. );
  277. }
  278. /**
  279. * Implements hook_image_default_styles().
  280. */
  281. function media_image_default_styles() {
  282. $styles = array();
  283. $styles['media_thumbnail'] = array(
  284. 'label' => 'Media thumbnail (100x100)',
  285. 'effects' => array(
  286. array(
  287. 'name' => 'image_scale_and_crop',
  288. 'data' => array('width' => 100, 'height' => 100),
  289. 'weight' => 0,
  290. ),
  291. ),
  292. );
  293. return $styles;
  294. }
  295. /**
  296. * Implements hook_page_alter().
  297. *
  298. * This is used to use our alternate template when ?render=media-popup is passed
  299. * in the URL.
  300. */
  301. function media_page_alter(&$page) {
  302. if (isset($_GET['render']) && $_GET['render'] == 'media-popup') {
  303. $page['#theme'] = 'media_dialog_page';
  304. // Disable administration modules from adding output to the popup.
  305. // @see http://drupal.org/node/914786
  306. module_invoke_all('suppress', TRUE);
  307. foreach (element_children($page) as $key) {
  308. if ($key != 'content') {
  309. unset($page[$key]);
  310. }
  311. }
  312. }
  313. // Check if there are file types that need migration and display a message
  314. // to user if so.
  315. $menu = menu_get_item();
  316. if (variable_get('media__display_types_migration_mess', TRUE) && $menu['path'] == 'admin/structure/file-types') {
  317. if ($migratable_types = _media_get_migratable_file_types()) {
  318. drupal_set_message(t('There are disabled/deleted file types that can be migrated to their new alternatives. Visit <a href="!url">migration page</a> to get more information.', array('!url' => url('admin/structure/file-types/upgrade'))));
  319. }
  320. }
  321. }
  322. /**
  323. * Implements hook_element_info_alter().
  324. */
  325. function media_element_info_alter(&$types) {
  326. $types['text_format']['#pre_render'][] = 'media_pre_render_text_format';
  327. }
  328. /**
  329. * Implements hook_file_operations().
  330. */
  331. function media_file_operations() {
  332. $operations = array();
  333. // If the multiform module is not installed, do not show this option.
  334. if (module_exists('multiform')) {
  335. $operations['edit_multiple'] = array(
  336. 'label' => t('Edit selected files'),
  337. 'callback' => 'media_file_operation_edit_multiple',
  338. );
  339. }
  340. return $operations;
  341. }
  342. /**
  343. * Return a URL for editing an files.
  344. *
  345. * Works with an array of fids or a single fid.
  346. *
  347. * @param mixed $fids
  348. * An array of file IDs or a single file ID.
  349. */
  350. function media_file_edit_url($fids) {
  351. if (!is_array($fids)) {
  352. $fids = array($fids);
  353. }
  354. if (count($fids) > 1) {
  355. return 'admin/content/file/edit-multiple/' . implode(' ', $fids);
  356. }
  357. else {
  358. return 'file/' . reset($fids) . '/edit';
  359. }
  360. }
  361. /**
  362. * Callback for the edit operation.
  363. *
  364. * Redirects the user to the edit multiple files page.
  365. *
  366. * @param array $fids
  367. * An array of file IDs.
  368. *
  369. * @see media_file_page_edit_multiple()
  370. */
  371. function media_file_operation_edit_multiple($fids) {
  372. // The thumbnail browser returns TRUE/FALSE for each item, so use array keys.
  373. $fids = array_keys(array_filter($fids));
  374. drupal_goto(media_file_edit_url($fids), array('query' => drupal_get_destination()));
  375. }
  376. /**
  377. * Implements hook_forms().
  378. */
  379. function media_forms($form_id, $args) {
  380. $forms = array();
  381. // To support the multiedit form, each form has to have a unique ID.
  382. // So we name all the forms media_edit_N where the first requested form is
  383. // media_edit_0, 2nd is media_edit_1, etc.
  384. module_load_include('inc', 'file_entity', 'file_entity.pages');
  385. if ($form_id != 'media_edit' && (strpos($form_id, 'media_edit') === 0)) {
  386. $forms[$form_id] = array(
  387. 'callback' => 'file_entity_edit',
  388. );
  389. }
  390. return $forms;
  391. }
  392. /**
  393. * Implements hook_form_FIELD_UI_FIELD_SETTINGS_FORM_alter().
  394. *
  395. * @todo: Respect field settings in 7.x-2.x and handle them in the media widget
  396. * UI.
  397. */
  398. function media_form_field_ui_field_settings_form_alter(&$form, &$form_state) {
  399. // On file fields that use the media widget we need remove specific fields.
  400. if ($form['field']['type']['#value'] == 'file') {
  401. $fields = field_info_instances($form['#entity_type'], $form['#bundle']);
  402. if ($fields[$form['field']['field_name']['#value']]['widget']['type'] == 'media_generic') {
  403. $form['field']['settings']['display_field']['#access'] = FALSE;
  404. $form['field']['settings']['display_default']['#access'] = FALSE;
  405. }
  406. }
  407. }
  408. /**
  409. * Implements hook_form_FIELD_UI_FIELD_EDIT_FORM_alter().
  410. *
  411. * @todo: Respect field settings in 7.x-2.x and handle them in the media widget
  412. * UI.
  413. */
  414. function media_form_field_ui_field_edit_form_alter(&$form, &$form_state) {
  415. // On file fields that use the media widget we need remove specific fields.
  416. if ($form['#field']['type'] == 'file' && $form['instance']['widget']['type']['#value'] == 'media_generic') {
  417. $form['field']['settings']['display_field']['#access'] = FALSE;
  418. $form['field']['settings']['display_default']['#access'] = FALSE;
  419. $form['instance']['settings']['description_field']['#access'] = FALSE;
  420. $form['instance']['settings']['file_extensions']['#title'] = t('Allowed file extensions for uploaded files');
  421. $form['instance']['settings']['file_extensions']['#maxlength'] = 255;
  422. }
  423. // On image fields using the media widget we remove the alt/title fields.
  424. if ($form['#field']['type'] == 'image' && $form['instance']['widget']['type']['#value'] == 'media_generic') {
  425. $form['instance']['settings']['alt_field']['#access'] = FALSE;
  426. $form['instance']['settings']['title_field']['#access'] = FALSE;
  427. $form['instance']['settings']['file_extensions']['#title'] = t('Allowed file extensions for uploaded files');
  428. // Do not increase maxlength of file extensions for image fields, since
  429. // presumably they will not need a long list of extensions.
  430. }
  431. if ($form['#instance']['entity_type'] == 'file') {
  432. $form['instance']['settings']['wysiwyg_override'] = array(
  433. '#type' => 'checkbox',
  434. '#title' => t('Override in WYSIWYG'),
  435. '#description' => t('If checked, then this field may be overridden in the WYSIWYG editor.'),
  436. '#default_value' => isset($form['#instance']['settings']['wysiwyg_override']) ? $form['#instance']['settings']['wysiwyg_override'] : TRUE,
  437. );
  438. }
  439. }
  440. /**
  441. * Implements hook_form_FORM_ID_alter().
  442. */
  443. function media_form_file_entity_edit_alter(&$form, &$form_state) {
  444. // Make adjustments to the file edit form when used in a CTools modal.
  445. if (!empty($form_state['ajax'])) {
  446. // Remove the preview and the delete button.
  447. $form['preview']['#access'] = FALSE;
  448. $form['actions']['delete']['#access'] = FALSE;
  449. // Convert the cancel link to a button which triggers a modal close.
  450. $form['actions']['cancel']['#attributes']['class'][] = 'button';
  451. $form['actions']['cancel']['#attributes']['class'][] = 'button-no';
  452. $form['actions']['cancel']['#attributes']['class'][] = 'ctools-close-modal';
  453. }
  454. }
  455. /**
  456. * Implements hook_form_alter().
  457. */
  458. function media_form_alter(&$form, &$form_state, $form_id) {
  459. // If we're in the media browser, set the #media_browser key to true
  460. // so that if an ajax request gets sent to a different path, the form
  461. // still uses the media_browser_form_submit callback.
  462. if (current_path() == 'media/browser' && $form_id != 'views_exposed_form') {
  463. $form_state['#media_browser'] = TRUE;
  464. }
  465. // If the #media_browser key isset and is true we are using the browser
  466. // popup, so add the media_browser submit handler.
  467. if (!empty($form_state['#media_browser'])) {
  468. $form['#submit'][] = 'media_browser_form_submit';
  469. }
  470. }
  471. /**
  472. * Submit handler; direction form submissions in the media browser.
  473. */
  474. function media_browser_form_submit($form, &$form_state) {
  475. $url = NULL;
  476. $parameters = array();
  477. // Single upload.
  478. if (!empty($form_state['file'])) {
  479. $file = $form_state['file'];
  480. $url = 'media/browser';
  481. $parameters = array('query' => array('render' => 'media-popup', 'fid' => $file->fid));
  482. }
  483. // Multi upload.
  484. if (!empty($form_state['files'])) {
  485. $files = $form_state['files'];
  486. $url = 'media/browser';
  487. $parameters = array('query' => array('render' => 'media-popup', 'fid' => array_keys($files)));
  488. }
  489. // If $url is set, we had some sort of upload, so redirect the form.
  490. if (!empty($url)) {
  491. $form_state['redirect'] = array($url, $parameters);
  492. }
  493. }
  494. /**
  495. * Implements hook_form_FORM_ID_alter().
  496. */
  497. function media_form_wysiwyg_profile_form_alter(&$form, &$form_state) {
  498. // Add warnings if the media filter is disabled for the WYSIWYG's text format.
  499. $form['buttons']['drupal']['media']['#element_validate'][] = 'media_wysiwyg_button_element_validate';
  500. $form['buttons']['drupal']['media']['#after_build'][] = 'media_wysiwyg_button_element_validate';
  501. form_load_include($form_state, 'inc', 'media', 'wysiwyg_plugins/media');
  502. }
  503. /**
  504. * Access callback for the media-multi form.
  505. *
  506. * @param $files
  507. * An array of files being editing on the multiform.
  508. * @param $op
  509. * A string containing the operation requested, such as 'update'.
  510. * @return
  511. * TRUE if the current user has access to edit all of the files, otherwise FALSE.
  512. */
  513. function _media_file_entity_access_recursive($files, $op) {
  514. // Check that the current user can access each file.
  515. if (!empty($files)) {
  516. foreach ($files as $file) {
  517. if (!file_entity_access($op, $file)) {
  518. return FALSE;
  519. }
  520. }
  521. return TRUE;
  522. }
  523. return FALSE;
  524. }
  525. /* ***************************************** */
  526. /* API FUNCTIONS */
  527. /* ***************************************** */
  528. /**
  529. * Load callback for %media_multi placeholder in menu paths.
  530. *
  531. * @param string $fids
  532. * Separated by space (e.g., "3 6 12 99"). This often appears as "+" within
  533. * URLs (e.g., "3+6+12+99"), but Drupal automatically decodes paths when
  534. * intializing $_GET['q'].
  535. *
  536. * @return array
  537. * An array of corresponding file entities.
  538. */
  539. function media_multi_load($fids) {
  540. return file_load_multiple(explode(' ', $fids));
  541. }
  542. /* ***************************************** */
  543. /* Callbacks */
  544. /* ***************************************** */
  545. /**
  546. * Process callback for the media_browser element.
  547. */
  548. function media_file_list_element_process($element, $edit, $form_state, $form) {
  549. $element['list'] = array(
  550. '#type' => 'select',
  551. '#options' => $element['#options'],
  552. '#size' => variable_get('media__file_list_size', 10),
  553. );
  554. return $element;
  555. }
  556. /**
  557. * Implements hook_library().
  558. */
  559. function media_library() {
  560. $path = drupal_get_path('module', 'media');
  561. $info = system_get_info('module', 'media');
  562. $common = array(
  563. 'website' => 'http://drupal.org/project/media',
  564. 'version' => !empty($info['version']) ? $info['version'] : '7.x-2.x',
  565. );
  566. // Contains libraries common to other media modules.
  567. $libraries['media_base'] = array(
  568. 'title' => 'Media base',
  569. 'js' => array(
  570. $path . '/js/media.core.js' => array('group' => JS_LIBRARY, 'weight' => -5),
  571. $path . '/js/util/json2.js' => array('group' => JS_LIBRARY),
  572. $path . '/js/util/ba-debug.min.js' => array('group' => JS_LIBRARY),
  573. ),
  574. 'css' => array(
  575. $path . '/css/media.css',
  576. ),
  577. );
  578. // Includes resources needed to launch the media browser. Should be included
  579. // on pages where the media browser needs to be launched from.
  580. $libraries['media_browser'] = array(
  581. 'title' => 'Media Browser popup libraries',
  582. 'js' => array(
  583. $path . '/js/media.popups.js' => array('group' => JS_DEFAULT),
  584. ),
  585. 'dependencies' => array(
  586. array('system', 'ui.resizable'),
  587. array('system', 'ui.draggable'),
  588. array('system', 'ui.dialog'),
  589. array('media', 'media_base'),
  590. ),
  591. );
  592. // Resources needed in the media browser itself.
  593. $libraries['media_browser_page'] = array(
  594. 'title' => 'Media browser',
  595. 'js' => array(
  596. $path . '/js/media.browser.js' => array('group' => JS_DEFAULT),
  597. ),
  598. 'dependencies' => array(
  599. array('system', 'ui.tabs'),
  600. array('system', 'ui.draggable'),
  601. array('system', 'ui.dialog'),
  602. array('media', 'media_base'),
  603. ),
  604. );
  605. foreach ($libraries as &$library) {
  606. $library += $common;
  607. }
  608. return $libraries;
  609. }
  610. /**
  611. * Theme callback used to identify when we are in a popup dialog.
  612. *
  613. * Generally the default theme will look terrible in the media browser. This
  614. * will default to the administration theme, unless set otherwise.
  615. */
  616. function media_dialog_get_theme_name() {
  617. return variable_get('media__dialog_theme', variable_get('admin_theme'));
  618. }
  619. /**
  620. * This will parse a url or embedded code into a unique URI.
  621. *
  622. * The function will call all modules implementing hook_media_parse($url),
  623. * which should return either a string containing a parsed URI or NULL.
  624. *
  625. * @NOTE The implementing modules may throw an error, which will not be caught
  626. * here; it's up to the calling function to catch any thrown errors.
  627. *
  628. * @NOTE In emfield, we originally also accepted an array of regex patterns
  629. * to match against. However, that module used a registration for providers,
  630. * and simply stored the match in the database keyed to the provider object.
  631. * However, other than the stream wrappers, there is currently no formal
  632. * registration for media handling. Additionally, few, if any, stream wrappers
  633. * will choose to store a straight match from the parsed URL directly into
  634. * the URI. Thus, we leave both the matching and the final URI result to the
  635. * implementing module in this implementation.
  636. *
  637. * An alternative might be to do the regex pattern matching here, and pass a
  638. * successful match back to the implementing module. However, that would
  639. * require either an overloaded function or a new hook, which seems like more
  640. * overhead than it's worth at this point.
  641. *
  642. * @TODO Once hook_module_implements_alter() is in core (see the issue at
  643. * http://drupal.org/node/692950) we may want to implement media_media_parse()
  644. * to ensure we were passed a valid URL, rather than an unsupported or
  645. * malformed embed code that wasn't caught earlier. It will needed to be
  646. * weighted so it's called after all other streams have a go, as the fallback,
  647. * and will need to throw an error.
  648. *
  649. * @param string $url
  650. * The original URL or embed code to parse.
  651. *
  652. * @return string
  653. * The unique URI for the file, based on its stream wrapper, or NULL.
  654. *
  655. * @see media_parse_to_file()
  656. * @see media_add_from_url_validate()
  657. */
  658. function media_parse_to_uri($url) {
  659. // Trim any whitespace before parsing.
  660. $url = trim($url);
  661. foreach (module_implements('media_parse') as $module) {
  662. $success = module_invoke($module, 'media_parse', $url);
  663. if (isset($success)) {
  664. return $success;
  665. }
  666. }
  667. }
  668. /**
  669. * Parse a URL or embed code and return a file object.
  670. *
  671. * If a remote stream doesn't claim the parsed URL in media_parse_to_uri(),
  672. * then we'll copy the file locally.
  673. *
  674. * @NOTE The implementing modules may throw an error, which will not be caught
  675. * here; it's up to the calling function to catch any thrown errors.
  676. *
  677. * @see media_parse_to_uri()
  678. * @see media_add_from_url_submit()
  679. */
  680. function media_parse_to_file($url) {
  681. try {
  682. $uri = media_parse_to_uri($url);
  683. }
  684. catch (Exception $e) {
  685. // Pass the error along.
  686. throw $e;
  687. return;
  688. }
  689. if (isset($uri)) {
  690. // Attempt to load an existing file from the unique URI.
  691. $select = db_select('file_managed', 'f')
  692. ->extend('PagerDefault')
  693. ->fields('f', array('fid'))
  694. ->condition('uri', $uri);
  695. $fid = $select->execute()->fetchCol();
  696. if (!empty($fid)) {
  697. $file = file_load(array_pop($fid));
  698. return $file;
  699. }
  700. }
  701. if (isset($uri)) {
  702. // The URL was successfully parsed to a URI, but does not yet have an
  703. // associated file: save it!
  704. $file = file_uri_to_object($uri);
  705. file_save($file);
  706. }
  707. else {
  708. // The URL wasn't parsed. We'll try to save a remote file.
  709. // Copy to temporary first.
  710. $source_uri = file_stream_wrapper_uri_normalize('temporary://' . basename($url));
  711. if (!@copy(@$url, $source_uri)) {
  712. throw new Exception('Unable to add file ' . $url);
  713. return;
  714. }
  715. $source_file = file_uri_to_object($source_uri);
  716. $scheme = variable_get('file_default_scheme', 'public') . '://';
  717. $uri = file_stream_wrapper_uri_normalize($scheme . $source_file->filename);
  718. // Now to its new home.
  719. $file = file_move($source_file, $uri, FILE_EXISTS_RENAME);
  720. }
  721. return $file;
  722. }
  723. /**
  724. * Utility function to recursively run check_plain on an array.
  725. *
  726. * @todo There is probably something in core I am not aware of that does this.
  727. */
  728. function media_recursive_check_plain(&$value, $key) {
  729. $value = check_plain($value);
  730. }
  731. /**
  732. * Implements hook_element_info().
  733. */
  734. function media_element_info() {
  735. $types = array();
  736. $types['media'] = array(
  737. '#input' => TRUE,
  738. '#process' => array('media_element_process'),
  739. // '#value_callback' => 'media_element_value',
  740. '#element_validate' => array('media_element_validate'),
  741. '#theme_wrappers' => array('container'),
  742. '#progress_indicator' => 'throbber',
  743. '#extended' => FALSE,
  744. '#required' => FALSE,
  745. '#media_options' => array(
  746. 'global' => array(
  747. // Example: array('image', 'audio');
  748. 'types' => array(),
  749. // Example: array('http', 'ftp', 'flickr');
  750. 'schemes' => array(),
  751. ),
  752. ),
  753. '#attributes' => array(
  754. 'class' => array('media-widget', 'form-item'),
  755. ),
  756. '#attached' => array(
  757. 'library' => array(
  758. array('media', 'media_browser'),
  759. ),
  760. ),
  761. );
  762. return $types;
  763. }
  764. /**
  765. * Process callback for the media form element.
  766. */
  767. function media_element_process(&$element, &$form_state, $form) {
  768. $fid = isset($element['#value']['fid']) ? $element['#value']['fid'] : 0;
  769. $file = $fid ? file_load($fid) : FALSE;
  770. // Add the CTools modal JavaScript for the edit button if necessary.
  771. ctools_include('modal');
  772. ctools_include('ajax');
  773. ctools_modal_add_js();
  774. // Set some default element properties.
  775. $element['#file'] = $file;
  776. $element['title'] = array(
  777. '#type' => 'item',
  778. '#title' => $element['#title'],
  779. '#description' => $element['#description'],
  780. '#required' => $element['#required'],
  781. '#weight' => -100,
  782. );
  783. if (isset($element['#title_display'])) {
  784. $element['title']['#title_display'] = $element['#title_display'];
  785. }
  786. // @todo This should load from the JS in case of a failed form submission.
  787. $element['preview'] = array(
  788. '#prefix' => '<div class="preview launcher">',
  789. '#suffix' => '</div>',
  790. '#weight' => 0,
  791. 'content' => $file ? media_get_thumbnail_preview($file) : array(),
  792. );
  793. // @todo: Perhaps this language logic should be handled by JS since the state
  794. // changes on client side after choosing an item.
  795. $element['select'] = array(
  796. '#type' => 'link',
  797. '#href' => '',
  798. '#title' => t('Select'),
  799. '#attributes' => array('class' => array('button', 'launcher')),
  800. '#options' => array('fragment' => FALSE, 'external' => TRUE),
  801. '#weight' => 10,
  802. );
  803. // @todo Figure out how to update the preview image after the Edit modal is
  804. // closed.
  805. $element['edit'] = array(
  806. '#type' => 'link',
  807. '#href' => 'media/' . $fid . '/edit/nojs',
  808. '#title' => t('Edit'),
  809. '#attributes' => array(
  810. 'class' => array(
  811. // Required for CTools modal to work.
  812. 'ctools-use-modal', 'use-ajax',
  813. 'ctools-modal-media-file-edit', 'button', 'edit',
  814. ),
  815. ),
  816. '#weight' => 20,
  817. '#access' => $file ? file_entity_access('update', $file) : TRUE, // only do perm check for existing files
  818. );
  819. $element['remove'] = array(
  820. '#type' => 'link',
  821. '#href' => '',
  822. '#title' => t('Remove'),
  823. '#attributes' => array('class' => array('button', 'remove')),
  824. '#options' => array('fragment' => FALSE, 'external' => TRUE),
  825. '#weight' => 30,
  826. );
  827. $element['fid'] = array(
  828. '#type' => 'hidden',
  829. '#value' => $fid,
  830. '#attributes' => array('class' => array('fid')),
  831. '#weight' => 100,
  832. );
  833. // Media browser attach code.
  834. $element['#attached']['js'][] = drupal_get_path('module', 'media') . '/js/media.js';
  835. $setting = array();
  836. $setting['media']['elements'][$element['#id']] = $element['#media_options'];
  837. $element['#attached']['js'][] = array(
  838. 'type' => 'setting',
  839. 'data' => $setting,
  840. );
  841. // @todo: Might need to think about this. All settings would likely apply to
  842. // all media in a multi-value, but what about passing the existing fid?
  843. module_load_include('inc', 'media', 'includes/media.browser');
  844. media_attach_browser_js($element);
  845. return $element;
  846. // @todo: make this work for file and image fields.
  847. }
  848. /**
  849. * Validate media form elements.
  850. *
  851. * The file type is validated during the upload process, but this is necessary
  852. * necessary in order to respect the #required property.
  853. */
  854. function media_element_validate(&$element, &$form_state) {
  855. if ($element['#required']) {
  856. $has_value = FALSE;
  857. $widget_parents = $element['#array_parents'];
  858. array_pop($widget_parents);
  859. $items = drupal_array_get_nested_value($form_state['values'], $widget_parents);
  860. foreach ($items as $value) {
  861. if (is_array($value) && !empty($value['fid'])) {
  862. $has_value = TRUE;
  863. }
  864. }
  865. if (!$has_value) {
  866. form_error($element, t('%element_title is required.', array('%element_title' => $element['#title'])));
  867. }
  868. }
  869. }
  870. /**
  871. * Implements hook_filter_info().
  872. */
  873. function media_filter_info() {
  874. $filters['media_filter'] = array(
  875. 'title' => t('Convert Media tags to markup'),
  876. 'description' => t('This filter will convert [[{type:media... ]] tags into markup.'),
  877. 'process callback' => 'media_filter',
  878. 'weight' => 2,
  879. // @TODO not implemented
  880. 'tips callback' => 'media_filter_tips',
  881. );
  882. // If the WYSIWYG module is enabled, add additional help.
  883. if (module_exists('wysiwyg')) {
  884. $filters['media_filter']['description'] .= ' ' . t('This must be enabled for the Media WYSIWYG integration to work with this input format.');
  885. }
  886. return $filters;
  887. }
  888. /**
  889. * Media thumbnail render function.
  890. *
  891. * Returns a renderable array with the necessary classes to support a media
  892. * thumbnail. Also provides default fallback images if no image is available.
  893. *
  894. * @param object $file
  895. * A Drupal file object.
  896. *
  897. * @return array
  898. * Renderable array.
  899. */
  900. function media_get_thumbnail_preview($file, $link = NULL) {
  901. // If a file has an invalid type, allow file_view_file() to work.
  902. if (!file_type_is_enabled($file->type)) {
  903. $file->type = file_get_type($file);
  904. }
  905. // @todo should CSS be attached to the form element here?
  906. // $element['#attached']['css'][] = drupal_get_path('module', 'media') . '/css/media.css';
  907. drupal_add_css(drupal_get_path('module', 'media') . '/css/media.css');
  908. $preview = file_view_file($file, 'preview');
  909. $preview['#show_names'] = TRUE;
  910. $preview['#add_link'] = $link;
  911. $preview['#theme_wrappers'][] = 'media_thumbnail';
  912. return $preview;
  913. }
  914. /**
  915. * Check that the media is one of the selected types.
  916. *
  917. * @param object $file
  918. * A Drupal file object.
  919. * @param array $types
  920. * An array of media type names
  921. *
  922. * @return array
  923. * If the file type is not allowed, it will contain an error message.
  924. *
  925. * @see hook_file_validate()
  926. */
  927. function media_file_validate_types(stdClass $file, $types) {
  928. $errors = array();
  929. if (!in_array(file_get_type($file), $types)) {
  930. $errors[] = t('Only the following types of files are allowed to be uploaded: %types-allowed', array('%types-allowed' => implode(', ', $types)));
  931. }
  932. return $errors;
  933. }
  934. /**
  935. * Implements hook_file_displays_alter().
  936. */
  937. function media_file_displays_alter(&$displays, $file, $view_mode) {
  938. if ($view_mode == 'preview' && empty($displays)) {
  939. // We re in the media browser and this file has no formatters enabled.
  940. // Instead of letting it go through theme_file_link(), pass it through
  941. // theme_media_formatter_large_icon() to get our cool file icon instead.
  942. $displays['file_field_media_large_icon'] = array(
  943. 'weight' => 0,
  944. 'status' => 1,
  945. 'settings' => NULL,
  946. );
  947. }
  948. // Override the fields of the file when requested by the WYSIWYG.
  949. if (isset($file->override) && isset($file->override['fields'])) {
  950. $instance = field_info_instances('file', $file->type);
  951. foreach ($file->override['fields'] as $field_name => $value) {
  952. if (!isset($instance[$field_name]['settings']) || !isset($instance[$field_name]['settings']['wysiwyg_override']) || $instance[$field_name]['settings']['wysiwyg_override']) {
  953. $file->{$field_name} = $value;}
  954. }
  955. }
  956. }
  957. /**
  958. * Implements hook_file_default_displays_alter().
  959. */
  960. function media_file_default_displays_alter(&$file_displays) {
  961. // Image previews should be displayed using the media image style.
  962. if (isset($file_displays['image__preview__file_field_image'])) {
  963. $file_displays['image__preview__file_field_image']->settings['image_style'] = 'media_thumbnail';
  964. }
  965. // Video previews should be displayed using a large filetype icon.
  966. if (isset($file_displays['video__preview__file_field_file_default'])) {
  967. $file_displays['video__preview__file_field_file_default']->status = FALSE;
  968. }
  969. $file_display = new stdClass();
  970. $file_display->api_version = 1;
  971. $file_display->name = 'video__preview__file_field_media_large_icon';
  972. $file_display->weight = 50;
  973. $file_display->status = TRUE;
  974. $file_display->settings = '';
  975. $file_displays['video__preview__file_field_media_large_icon'] = $file_display;
  976. // Audio previews should be displayed using a large filetype icon.
  977. if (isset($file_displays['audio__preview__file_field_file_default'])) {
  978. $file_displays['audio__preview__file_field_file_default']->status = FALSE;
  979. }
  980. $file_display = new stdClass();
  981. $file_display->api_version = 1;
  982. $file_display->name = 'audio__preview__file_field_media_large_icon';
  983. $file_display->weight = 50;
  984. $file_display->status = TRUE;
  985. $file_display->settings = '';
  986. $file_displays['audio__preview__file_field_media_large_icon'] = $file_display;
  987. // Document previews should be displayed using a large filetype icon.
  988. if (isset($file_displays['document__preview__file_field_file_default'])) {
  989. $file_displays['document__preview__file_field_file_default']->status = FALSE;
  990. }
  991. $file_display = new stdClass();
  992. $file_display->api_version = 1;
  993. $file_display->name = 'document__preview__file_field_media_large_icon';
  994. $file_display->weight = 50;
  995. $file_display->status = TRUE;
  996. $file_display->settings = '';
  997. $file_displays['document__preview__file_field_media_large_icon'] = $file_display;
  998. }
  999. /**
  1000. * Implements hook_ctools_plugin_api().
  1001. *
  1002. * Lets CTools know which plugin APIs are implemented by Media module.
  1003. */
  1004. function media_ctools_plugin_api($module, $api) {
  1005. if ($module == 'file_entity' && $api == 'file_default_displays') {
  1006. return array(
  1007. 'version' => 1,
  1008. );
  1009. }
  1010. }
  1011. /**
  1012. * Implements hook_form_FORM_ID_alter().
  1013. *
  1014. * This alter enhances the default admin/content/file page, addding JS and CSS.
  1015. * It also makes modifications to the thumbnail view by replacing the existing
  1016. * checkboxes and table with thumbnails.
  1017. */
  1018. function media_form_file_entity_admin_file_alter(&$form, $form_state) {
  1019. if (!empty($form_state['values']['operation'])) {
  1020. // The form is being rebuilt because an operation requiring confirmation
  1021. // We don't want to be messing with it in this case.
  1022. return;
  1023. }
  1024. // Add the "Add file" local action, and notify users if they have files
  1025. // selected and they try to switch between the "Thumbnail" and "List" local
  1026. // tasks.
  1027. $path = drupal_get_path('module', 'media');
  1028. require_once $path . '/includes/media.browser.inc';
  1029. $form['#attributes']['class'][] = 'file-entity-admin-file-form';
  1030. $form['#attached']['js'][] = $path . '/js/media.admin.js';
  1031. $form['#attached']['css'][] = $path . '/css/media.css';
  1032. media_attach_browser_js($form);
  1033. // By default, this form contains a table select element called "files". For
  1034. // the 'thumbnails' tab, Media generates a thumbnail for each file and
  1035. // replaces the tableselect with a grid of thumbnails.
  1036. if (arg(3) == 'thumbnails') {
  1037. if (empty($form['admin']['files'])) {
  1038. // Display empty text if there are no files.
  1039. $form['admin']['files'] = array(
  1040. '#markup' => '<p>' . $form['files']['#empty'] . '</p>',
  1041. );
  1042. }
  1043. else {
  1044. $files = file_load_multiple(array_keys($form['admin']['files']['#options']));
  1045. $form['admin']['files'] = array(
  1046. '#tree' => TRUE,
  1047. '#prefix' => '<div class="media-display-thumbnails media-clear clearfix"><ul id="media-browser-library-list" class="media-list-thumbnails">',
  1048. '#suffix' => '</ul></div>',
  1049. );
  1050. foreach ($files as $file) {
  1051. $preview = media_get_thumbnail_preview($file, TRUE);
  1052. $form['admin']['files'][$file->fid] = array(
  1053. '#type' => 'checkbox',
  1054. '#title' => '',
  1055. '#prefix' => '<li>' . drupal_render($preview),
  1056. '#suffix' => '</li>',
  1057. );
  1058. }
  1059. }
  1060. }
  1061. }
  1062. /**
  1063. * Implements hook_views_api().
  1064. */
  1065. function media_views_api() {
  1066. return array(
  1067. 'api' => 3,
  1068. 'path' => drupal_get_path('module', 'media'),
  1069. );
  1070. }
  1071. /**
  1072. * Implements hook_views_default_views().
  1073. */
  1074. function media_views_default_views() {
  1075. return media_load_all_exports('media', 'views', 'view.inc', 'view');
  1076. }
  1077. /**
  1078. * Fetches an array of exportables from files.
  1079. *
  1080. * @param string $module
  1081. * The module invoking this request. (Can be called by other modules.)
  1082. * @param string $directory
  1083. * The subdirectory in the custom module.
  1084. * @param string $extension
  1085. * The file extension.
  1086. * @param string $name
  1087. * The name of the variable found in each file. Defaults to the same as
  1088. * $extension.
  1089. *
  1090. * @return array
  1091. * Array of $name objects.
  1092. */
  1093. function media_load_all_exports($module, $directory, $extension, $name = NULL) {
  1094. if (!$name) {
  1095. $name = $extension;
  1096. }
  1097. $return = array();
  1098. // Find all the files in the directory with the correct extension.
  1099. $files = file_scan_directory(drupal_get_path('module', $module) . "/$directory", "/.$extension/");
  1100. foreach ($files as $path => $file) {
  1101. require $path;
  1102. if (isset($$name)) {
  1103. $return[$$name->name] = $$name;
  1104. }
  1105. }
  1106. return $return;
  1107. }
  1108. /**
  1109. * Returns metadata describing Media browser plugins.
  1110. *
  1111. * @see hook_media_browser_plugin_info()
  1112. * @see hook_media_browser_plugin_info_alter()
  1113. */
  1114. function media_get_browser_plugin_info() {
  1115. $info = &drupal_static(__FUNCTION__);
  1116. if (!isset($info)) {
  1117. $cid = 'media:browser:plugin:info:' . $GLOBALS['language']->language;
  1118. if ($cache = cache_get($cid)) {
  1119. $info = $cache->data;
  1120. }
  1121. else {
  1122. $info = module_invoke_all('media_browser_plugin_info');
  1123. drupal_alter('media_browser_plugin_info', $info);
  1124. cache_set($cid, $info);
  1125. }
  1126. }
  1127. return $info;
  1128. }
  1129. /**
  1130. * Helper function to get a list of local stream wrappers.
  1131. */
  1132. function media_get_local_stream_wrappers() {
  1133. return file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL_NORMAL);
  1134. }
  1135. /**
  1136. * Helper function to get a list of remote stream wrappers.
  1137. */
  1138. function media_get_remote_stream_wrappers() {
  1139. $wrappers = file_get_stream_wrappers();
  1140. $wrappers = array_diff_key($wrappers, file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL_NORMAL));
  1141. $wrappers = array_diff_key($wrappers, file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL_HIDDEN));
  1142. return $wrappers;
  1143. }
  1144. /**
  1145. * Checks if there are any files that belong to disabled or deleted file
  1146. * types.
  1147. *
  1148. * @return Array of file types (machine names) that are candidates for
  1149. * migration.
  1150. */
  1151. function _media_get_migratable_file_types() {
  1152. $query = db_select('file_managed', 'f')
  1153. ->fields('f', array('type'))
  1154. ->distinct();
  1155. $types = $query->execute()->fetchCol();
  1156. $enabled_types = array();
  1157. foreach (file_type_get_enabled_types() as $type) {
  1158. $enabled_types[] = $type->type;
  1159. }
  1160. return array_diff($types, $enabled_types);
  1161. }
Error | ELMSLN API

Error

×

Error message

  • Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/elmsln_community/api.elmsln.org/includes/common.inc:2791) in drupal_send_headers() (line 1499 of /var/www/html/elmsln_community/api.elmsln.org/includes/bootstrap.inc).
  • Error: Call to undefined function apc_delete() in DrupalAPCCache->clear() (line 289 of /var/www/html/elmsln_community/api.elmsln.org/sites/all/modules/apc/drupal_apc_cache.inc).
The website encountered an unexpected error. Please try again later.