file_entity.file_api.inc

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

API extensions of Drupal core's file.inc.

Functions

Namesort descending Description
file_build_content Builds a structured array representing the file's content.
file_delete_multiple Delete multiple files.
file_displays Returns an array of displays to use for a file type in a given view mode.
file_displays_load Returns an array of {file_display} objects for the file type and view mode.
file_display_new Creates a new {file_display} object.
file_display_save Saves a {file_display} object to the database.
file_get_type Determines file type for a given file.
file_info_cache_clear Clears caches that are related to file entity.
file_info_formatter_types Returns information about file formatters from hook_file_formatter_info().
file_type_delete Deletes a file type from the database.
file_type_disable Disable a file type.
file_type_enable Enable a file type.
file_type_get_disabled_types Returns an array of disabled file types.
file_type_get_enabled_types Returns an array of enabled file types.
file_type_is_disabled Returns TRUE if a file type is disabled, FALSE otherwise.
file_type_is_enabled Returns TRUE if a file type is enabled, FALSE otherwise.
file_type_load Load a file type configuration object.
file_type_load_all Load all file type configuration objects.
file_type_load_multiple Load multiple file type configuration objects.
file_type_save Updates an existing file type or creates a new one.
file_uri_to_object Returns a file object which can be passed to file_save().
file_view Generate an array for rendering the given file.
file_view_file Generate an array for rendering just the file portion of a file entity.
file_view_multiple Construct a drupal_render() style array from an array of loaded files.
_file_entity_sort_weight_label User sort function to sort by weight, then label/name.
_file_sort_array_by_weight Sorts an array by weight.

Constants

Namesort descending Description
FILE_TYPE_NONE The {file_managed}.type value when the file type has not yet been determined.

File

sites/all/modules/ulmus/file_entity/file_entity.file_api.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * API extensions of Drupal core's file.inc.
  5. */
  6. /**
  7. * The {file_managed}.type value when the file type has not yet been determined.
  8. */
  9. define('FILE_TYPE_NONE', 'undefined');
  10. /**
  11. * Returns information about file formatters from hook_file_formatter_info().
  12. *
  13. * @param string $formatter_type
  14. * (optional) A file formatter type name. If ommitted, all file formatter
  15. * will be returned.
  16. *
  17. * @return string|array
  18. * Either a file formatter description, as provided by
  19. * hook_file_formatter_info(), or an array of all existing file formatters,
  20. * keyed by formatter type name.
  21. */
  22. function file_info_formatter_types($formatter_type = NULL) {
  23. $info = &drupal_static(__FUNCTION__);
  24. if (!isset($info)) {
  25. $info = module_invoke_all('file_formatter_info');
  26. drupal_alter('file_formatter_info', $info);
  27. uasort($info, '_file_entity_sort_weight_label');
  28. }
  29. if ($formatter_type) {
  30. if (isset($info[$formatter_type])) {
  31. return $info[$formatter_type];
  32. }
  33. }
  34. else {
  35. return $info;
  36. }
  37. }
  38. /**
  39. * Clears caches that are related to file entity.
  40. *
  41. * Clears all cached configuration related to file types, formatters, and
  42. * display settings.
  43. */
  44. function file_info_cache_clear() {
  45. // Clear the CTools managed caches.
  46. ctools_include('export');
  47. ctools_export_load_object_reset('file_type');
  48. ctools_export_load_object_reset('file_display');
  49. // Clear the formatter type cache, managed by file_info_formatter_types().
  50. drupal_static_reset('file_info_formatter_types');
  51. // Clear file type caches.
  52. drupal_static_reset('file_type_get_names');
  53. }
  54. /**
  55. * Construct a drupal_render() style array from an array of loaded files.
  56. *
  57. * @param array $files
  58. * An array of files as returned by file_load_multiple().
  59. * @param string $view_mode
  60. * View mode.
  61. * @param int $weight
  62. * An integer representing the weight of the first file in the list.
  63. * @param string $langcode
  64. * A string indicating the language field values are to be shown in. If no
  65. * language is provided the current content language is used.
  66. *
  67. * @return array
  68. * An array in the format expected by drupal_render().
  69. */
  70. function file_view_multiple($files, $view_mode = 'full', $weight = 0, $langcode = NULL) {
  71. if (empty($files)) {
  72. return array();
  73. }
  74. field_attach_prepare_view('file', $files, $view_mode, $langcode);
  75. entity_prepare_view('file', $files, $langcode);
  76. $build = array();
  77. foreach ($files as $file) {
  78. $build['files'][$file->fid] = file_view($file, $view_mode, $langcode);
  79. $build['files'][$file->fid]['#weight'] = $weight;
  80. $weight++;
  81. }
  82. $build['files']['#sorted'] = TRUE;
  83. return $build;
  84. }
  85. /**
  86. * Generate an array for rendering the given file.
  87. *
  88. * @param object $file
  89. * A file object.
  90. * @param string $view_mode
  91. * View mode.
  92. * @param string $langcode
  93. * (optional) A language code to use for rendering. Defaults to the global
  94. * content language of the current request.
  95. *
  96. * @return array
  97. * An array as expected by drupal_render().
  98. */
  99. function file_view($file, $view_mode = 'full', $langcode = NULL) {
  100. if (!isset($langcode)) {
  101. $langcode = $GLOBALS['language_content']->language;
  102. }
  103. // Populate $file->content with a render() array.
  104. file_build_content($file, $view_mode, $langcode);
  105. $build = $file->content;
  106. // We don't need duplicate rendering info in $file->content.
  107. unset($file->content);
  108. $build += array(
  109. '#theme' => 'file_entity',
  110. '#file' => $file,
  111. '#view_mode' => $view_mode,
  112. '#language' => $langcode,
  113. );
  114. // Add contextual links for this file, except when the file is already being
  115. // displayed on its own page. Modules may alter this behavior (for example,
  116. // to restrict contextual links to certain view modes) by implementing
  117. // hook_file_view_alter().
  118. if (!empty($file->fid) && !($view_mode == 'full' && file_entity_is_page($file))) {
  119. $build['#contextual_links']['file'] = array('file', array($file->fid));
  120. }
  121. // Allow modules to modify the structured file.
  122. $type = 'file';
  123. drupal_alter(array('file_view', 'entity_view'), $build, $type);
  124. return $build;
  125. }
  126. /**
  127. * Builds a structured array representing the file's content.
  128. *
  129. * @param object $file
  130. * A file object.
  131. * @param string $view_mode
  132. * View mode, e.g. 'default', 'full', etc.
  133. * @param string $langcode
  134. * (optional) A language code to use for rendering. Defaults to the global
  135. * content language of the current request.
  136. */
  137. function file_build_content($file, $view_mode = 'full', $langcode = NULL) {
  138. if (!isset($langcode)) {
  139. $langcode = $GLOBALS['language_content']->language;
  140. }
  141. // Remove previously built content, if exists.
  142. $file->content = array();
  143. // Build the actual file display.
  144. // @todo Figure out how to clean this crap up.
  145. $file->content['file'] = file_view_file($file, $view_mode, $langcode);
  146. if (isset($file->content['file'])) {
  147. if (isset($file->content['file']['#theme']) && $file->content['file']['#theme'] != 'file_link') {
  148. unset($file->content['file']['#file']);
  149. }
  150. unset($file->content['file']['#view_mode']);
  151. unset($file->content['file']['#language']);
  152. }
  153. else {
  154. unset($file->content['file']);
  155. }
  156. // Build fields content.
  157. // In case of a multiple view, file_view_multiple() already ran the
  158. // 'prepare_view' step. An internal flag prevents the operation from running
  159. // twice.
  160. field_attach_prepare_view('file', array($file->fid => $file), $view_mode, $langcode);
  161. entity_prepare_view('file', array($file->fid => $file), $langcode);
  162. $file->content += field_attach_view('file', $file, $view_mode, $langcode);
  163. $links = array();
  164. $file->content['links'] = array(
  165. '#theme' => 'links__file',
  166. '#pre_render' => array('drupal_pre_render_links'),
  167. '#attributes' => array('class' => array('links', 'inline')),
  168. );
  169. $file->content['links']['file'] = array(
  170. '#theme' => 'links__file__file',
  171. '#links' => $links,
  172. '#attributes' => array('class' => array('links', 'inline')),
  173. );
  174. // Allow modules to make their own additions to the file.
  175. module_invoke_all('file_view', $file, $view_mode, $langcode);
  176. module_invoke_all('entity_view', $file, 'file', $view_mode, $langcode);
  177. }
  178. /**
  179. * Generate an array for rendering just the file portion of a file entity.
  180. *
  181. * @param object $file
  182. * A file object.
  183. * @param string|array $displays
  184. * Can be either:
  185. * - the name of a view mode;
  186. * - or an array of custom display settings, as returned by file_displays().
  187. * @param string $langcode
  188. * (optional) A language code to use for rendering. Defaults to the global
  189. * content language of the current request.
  190. *
  191. * @return array
  192. * An array as expected by drupal_render().
  193. */
  194. function file_view_file($file, $displays = 'full', $langcode = NULL) {
  195. if (!isset($langcode)) {
  196. $langcode = $GLOBALS['language_content']->language;
  197. }
  198. // Prepare incoming display specifications.
  199. if (is_string($displays)) {
  200. $view_mode = $displays;
  201. $displays = file_displays($file->type, $view_mode);
  202. }
  203. else {
  204. $view_mode = '_custom_display';
  205. }
  206. drupal_alter('file_displays', $displays, $file, $view_mode);
  207. _file_sort_array_by_weight($displays);
  208. // Attempt to display the file with each of the possible displays. Stop after
  209. // the first successful one. See file_displays() for details.
  210. $element = NULL;
  211. foreach ($displays as $formatter_type => $display) {
  212. if (!empty($display['status'])) {
  213. $formatter_info = file_info_formatter_types($formatter_type);
  214. // Under normal circumstances, the UI prevents enabling formatters for
  215. // incompatible MIME types. In case this was somehow circumvented (for
  216. // example, a module updated its formatter definition without updating
  217. // existing display settings), perform an extra check here.
  218. if (isset($formatter_info['mime types'])) {
  219. if (!file_entity_match_mimetypes($formatter_info['mime types'], $file->filemime)) {
  220. continue;
  221. }
  222. }
  223. if (isset($formatter_info['view callback']) && ($function = $formatter_info['view callback']) && function_exists($function)) {
  224. $display['type'] = $formatter_type;
  225. if (!empty($formatter_info['default settings'])) {
  226. if (empty($display['settings'])) {
  227. $display['settings'] = array();
  228. }
  229. $display['settings'] += $formatter_info['default settings'];
  230. }
  231. $element = $function($file, $display, $langcode);
  232. if (isset($element)) {
  233. break;
  234. }
  235. }
  236. }
  237. }
  238. // As a last resort, fall back to showing a link to the file.
  239. if (!isset($element)) {
  240. $element = array(
  241. '#theme' => 'file_link',
  242. '#file' => $file,
  243. );
  244. }
  245. // Add defaults and return the element.
  246. $element += array(
  247. '#file' => $file,
  248. '#view_mode' => $view_mode,
  249. '#language' => $langcode,
  250. );
  251. return $element;
  252. }
  253. /**
  254. * @defgroup file_displays File displays API
  255. * @{
  256. * Functions to load and save information about file displays.
  257. */
  258. /**
  259. * Returns an array of displays to use for a file type in a given view mode.
  260. *
  261. * It is common for a site to be configured with broadly defined file types
  262. * (e.g., 'video'), and to have different files of this type require different
  263. * displays (for example, the code required to display a YouTube video is
  264. * different than the code required to display a local QuickTime video).
  265. * Therefore, the site administrator can configure multiple displays for a given
  266. * file type. This function returns all of the displays that the administrator
  267. * enabled for the given file type in the given view mode. file_view_file() then
  268. * invokes each of these, and passes the specific file to display. Each display
  269. * implementation can inspect the file, and either return a render array (if it
  270. * is capable of displaying the file), or return nothing (if it is incapable of
  271. * displaying the file). The first render array returned is the one used.
  272. *
  273. * @param string $file_type
  274. * The type of file.
  275. * @param string $view_mode
  276. * The view mode.
  277. *
  278. * @return array
  279. * An array keyed by the formatter type name. Each item in the array contains
  280. * the following key/value pairs:
  281. * - status: Whether this display is enabled. If not TRUE, file_view_file()
  282. * skips over it.
  283. * - weight: An integer that determines the order of precedence within the
  284. * returned array. The lowest weight display capable of displaying the file
  285. * is used.
  286. * - settings: An array of key/value pairs specific to the formatter type. See
  287. * hook_file_formatter_info() for details.
  288. *
  289. * @see hook_file_formatter_info()
  290. * @see file_view_file()
  291. */
  292. function file_displays($file_type, $view_mode) {
  293. $cache = &drupal_static(__FUNCTION__, array());
  294. // If the requested view mode isn't configured to use a custom display for its
  295. // fields, then don't use a custom display for its file either.
  296. if ($view_mode != 'default') {
  297. $view_mode_settings = field_view_mode_settings('file', $file_type);
  298. $view_mode = !empty($view_mode_settings[$view_mode]['custom_settings']) ? $view_mode : 'default';
  299. }
  300. if (!isset($cache[$file_type][$view_mode])) {
  301. // Load the display configurations for the file type and view mode. If none
  302. // exist for the view mode, use the default view mode.
  303. $displays = file_displays_load($file_type, $view_mode, TRUE);
  304. if (empty($displays) && $view_mode != 'default') {
  305. $cache[$file_type][$view_mode] = file_displays($file_type, 'default');
  306. }
  307. else {
  308. // Convert the display objects to arrays and remove unnecessary keys.
  309. foreach ($displays as $formatter_name => $display) {
  310. $displays[$formatter_name] = array_intersect_key((array) $display, drupal_map_assoc(array('status', 'weight', 'settings')));
  311. }
  312. $cache[$file_type][$view_mode] = $displays;
  313. }
  314. }
  315. return $cache[$file_type][$view_mode];
  316. }
  317. /**
  318. * Returns an array of {file_display} objects for the file type and view mode.
  319. */
  320. function file_displays_load($file_type, $view_mode, $key_by_formatter_name = FALSE) {
  321. ctools_include('export');
  322. $display_names = array();
  323. $prefix = $file_type . '__' . $view_mode . '__';
  324. foreach (array_keys(file_info_formatter_types()) as $formatter_name) {
  325. $display_names[] = $prefix . $formatter_name;
  326. }
  327. $displays = ctools_export_load_object('file_display', 'names', $display_names);
  328. if ($key_by_formatter_name) {
  329. $prefix_length = strlen($prefix);
  330. $rekeyed_displays = array();
  331. foreach ($displays as $name => $display) {
  332. $rekeyed_displays[substr($name, $prefix_length)] = $display;
  333. }
  334. $displays = $rekeyed_displays;
  335. }
  336. return $displays;
  337. }
  338. /**
  339. * Saves a {file_display} object to the database.
  340. */
  341. function file_display_save($display) {
  342. ctools_include('export');
  343. ctools_export_crud_save('file_display', $display);
  344. file_info_cache_clear();
  345. }
  346. /**
  347. * Creates a new {file_display} object.
  348. */
  349. function file_display_new($file_type, $view_mode, $formatter_name) {
  350. ctools_include('export');
  351. $display = ctools_export_crud_new('file_display');
  352. file_info_cache_clear();
  353. $display->name = implode('__', array($file_type, $view_mode, $formatter_name));
  354. return $display;
  355. }
  356. /**
  357. * @} End of "defgroup file_displays".
  358. */
  359. /**
  360. * @defgroup file_types File types API
  361. * @{
  362. * Functions to load and save information about file types.
  363. */
  364. /**
  365. * Load a file type configuration object.
  366. *
  367. * @param string $name
  368. * The file type machine name to load.
  369. *
  370. * @return object
  371. * The file type object, or FALSE if it does not exist.
  372. */
  373. function file_type_load($name) {
  374. ctools_include('export');
  375. $type = ctools_export_crud_load('file_type', $name);
  376. return isset($type) ? $type : FALSE;
  377. }
  378. /**
  379. * Load multiple file type configuration objects.
  380. *
  381. * @param array $names
  382. * An array of file type machine names to load.
  383. *
  384. * @return array
  385. * An array of file type objects, keyed by machine name.
  386. */
  387. function file_type_load_multiple(array $names) {
  388. ctools_include('export');
  389. return ctools_export_crud_load_multiple('file_type', $names);
  390. }
  391. /**
  392. * Load all file type configuration objects.
  393. *
  394. * This includes all enabled and disabled file types.
  395. *
  396. * @param bool $reset
  397. * If TRUE, the static cache of all file types will be flushed prior to
  398. * loading. This can be important on listing pages where file types might
  399. * have changed on the page load.
  400. *
  401. * @return array
  402. * An array of file type objects, keyed by machine name.
  403. *
  404. * @see file_type_get_enabled_types()
  405. * @see file_type_get_disabled_types()
  406. */
  407. function file_type_load_all($reset = FALSE) {
  408. ctools_include('export');
  409. return ctools_export_crud_load_all('file_type', $reset);
  410. }
  411. /**
  412. * Returns an array of enabled file types.
  413. */
  414. function file_type_get_enabled_types() {
  415. $types = file_type_load_all();
  416. return array_filter($types, 'file_type_is_enabled');
  417. }
  418. /**
  419. * Returns an array of disabled file types.
  420. */
  421. function file_type_get_disabled_types() {
  422. $types = file_type_load_all();
  423. return array_filter($types, 'file_type_is_disabled');
  424. }
  425. /**
  426. * Returns TRUE if a file type is enabled, FALSE otherwise.
  427. */
  428. function file_type_is_enabled($type) {
  429. return empty($type->disabled);
  430. }
  431. /**
  432. * Returns TRUE if a file type is disabled, FALSE otherwise.
  433. */
  434. function file_type_is_disabled($type) {
  435. return !empty($type->disabled);
  436. }
  437. /**
  438. * Updates an existing file type or creates a new one.
  439. *
  440. * This function can be called on its own, or via the CTools exportables
  441. * 'save callback' for {file_type} objects.
  442. */
  443. function file_type_save($type) {
  444. // Get the old type object, so we now can issue the correct insert/update
  445. // queries.
  446. if (!empty($type->old_type) && $type->old_type != $type->type) {
  447. $rename_bundle = TRUE;
  448. $old_type = file_type_load($type->old_type);
  449. }
  450. else {
  451. $rename_bundle = FALSE;
  452. $old_type = file_type_load($type->type);
  453. }
  454. // The type and label fields are required, but description is optional.
  455. if (!isset($type->description)) {
  456. $type->description = '';
  457. }
  458. $fields = array(
  459. 'type' => $type->type,
  460. 'label' => $type->label,
  461. 'description' => $type->description,
  462. 'mimetypes' => serialize($type->mimetypes),
  463. );
  464. // Update an existing type object, whether with a modified 'type' property or
  465. // not.
  466. if ($old_type) {
  467. if ($old_type->export_type & EXPORT_IN_DATABASE) {
  468. db_update('file_type')
  469. ->fields($fields)
  470. ->condition('type', $old_type->type)
  471. ->execute();
  472. }
  473. else {
  474. db_insert('file_type')
  475. ->fields($fields)
  476. ->execute();
  477. }
  478. if ($rename_bundle) {
  479. field_attach_rename_bundle('file', $old_type->type, $type->type);
  480. }
  481. module_invoke_all('file_type_update', $type);
  482. $status = SAVED_UPDATED;
  483. }
  484. // Insert a new type object.
  485. else {
  486. db_insert('file_type')
  487. ->fields($fields)
  488. ->execute();
  489. field_attach_create_bundle('file', $type->type);
  490. module_invoke_all('file_type_insert', $type);
  491. $status = SAVED_NEW;
  492. }
  493. // Clear the necessary caches.
  494. file_info_cache_clear();
  495. // Ensure the type has the correct export_type in case the $type parameter
  496. // continues to be used by the calling function after this function completes.
  497. if (empty($type->export_type)) {
  498. $type->export_type = 0;
  499. }
  500. $type->export_type |= EXPORT_IN_DATABASE;
  501. return $status;
  502. }
  503. /**
  504. * Deletes a file type from the database.
  505. *
  506. * This function can be called on its own, or via the CTools exportables
  507. * 'delete callback' for {file_type} objects.
  508. *
  509. * @param object|string $type
  510. * Either a loaded file type object or the machine-name of the type.
  511. */
  512. function file_type_delete($type) {
  513. $type = is_string($type) ? file_type_load($type) : $type;
  514. db_delete('file_type')
  515. ->condition('type', $type->type)
  516. ->execute();
  517. // Remove this type from CToolS status variable.
  518. $status = variable_get('default_file_type', array());
  519. unset($status[$type->type]);
  520. variable_set('default_file_type', $status);
  521. file_info_cache_clear();
  522. // After deleting from the database, check if the type still exists as a
  523. // code-provided default type. If not, consider the type fully deleted and
  524. // invoke the needed hooks.
  525. if (!file_type_load($type->type)) {
  526. field_attach_delete_bundle('file', $type->type);
  527. module_invoke_all('file_type_delete', $type);
  528. }
  529. }
  530. /**
  531. * Enable a file type.
  532. *
  533. * @param string $type
  534. * Type of the file_type to disable
  535. */
  536. function file_type_enable($type) {
  537. ctools_include('export');
  538. ctools_export_crud_enable('file_type', $type);
  539. }
  540. /**
  541. * Disable a file type.
  542. *
  543. * @param string $type
  544. * Type of the file_type to disable
  545. */
  546. function file_type_disable($type) {
  547. ctools_include('export');
  548. ctools_export_crud_disable('file_type', $type);
  549. }
  550. /**
  551. * Determines file type for a given file.
  552. *
  553. * @param object $file
  554. * File object.
  555. *
  556. * @return string
  557. * Machine name of file type that should be used for given file.
  558. */
  559. function file_get_type($file) {
  560. $types = module_invoke_all('file_type', $file);
  561. drupal_alter('file_type', $types, $file);
  562. return empty($types) ? NULL : reset($types);
  563. }
  564. /**
  565. * @} End of "defgroup file_types".
  566. */
  567. /**
  568. * Sorts an array by weight.
  569. *
  570. * Helper function to sort an array by the value of each item's 'weight' key,
  571. * while preserving relative order of items that have equal weight.
  572. */
  573. function _file_sort_array_by_weight(&$a) {
  574. $i = 0;
  575. foreach ($a as $key => $item) {
  576. if (!isset($a[$key]['weight'])) {
  577. $a[$key]['weight'] = 0;
  578. }
  579. $original_weight[$key] = $a[$key]['weight'];
  580. $a[$key]['weight'] += $i / 1000;
  581. $i++;
  582. }
  583. uasort($a, 'drupal_sort_weight');
  584. foreach ($a as $key => $item) {
  585. $a[$key]['weight'] = $original_weight[$key];
  586. }
  587. }
  588. /**
  589. * User sort function to sort by weight, then label/name.
  590. */
  591. function _file_entity_sort_weight_label($a, $b) {
  592. $a_weight = isset($a['weight']) ? $a['weight'] : 0;
  593. $b_weight = isset($b['weight']) ? $b['weight'] : 0;
  594. if ($a_weight == $b_weight) {
  595. $a_label = isset($a['label']) ? $a['label'] : '';
  596. $b_label = isset($b['label']) ? $b['label'] : '';
  597. return strcasecmp($a_label, $b_label);
  598. }
  599. else {
  600. return $a_weight < $b_weight ? -1 : 1;
  601. }
  602. }
  603. /**
  604. * Returns a file object which can be passed to file_save().
  605. *
  606. * @param string $uri
  607. * A string containing the URI, path, or filename.
  608. * @param bool $use_existing
  609. * (Optional) If TRUE and there's an existing file in the {file_managed}
  610. * table with the passed in URI, then that file object is returned.
  611. * Otherwise, a new file object is returned. Default is TRUE.
  612. *
  613. * @return object|bool
  614. * A file object, or FALSE on error.
  615. *
  616. * @todo This should probably be named
  617. * file_load_by_uri($uri, $create_if_not_exists).
  618. * @todo Remove this function when http://drupal.org/node/685818 is fixed.
  619. */
  620. function file_uri_to_object($uri, $use_existing = TRUE) {
  621. $file = FALSE;
  622. $uri = file_stream_wrapper_uri_normalize($uri);
  623. if ($use_existing) {
  624. // We should always attempt to re-use a file if possible.
  625. $files = entity_load('file', FALSE, array('uri' => $uri));
  626. $file = !empty($files) ? reset($files) : FALSE;
  627. }
  628. if (empty($file)) {
  629. $file = new stdClass();
  630. $file->uid = $GLOBALS['user']->uid;
  631. $file->filename = drupal_basename($uri);
  632. $file->uri = $uri;
  633. $file->filemime = file_get_mimetype($uri);
  634. // This is gagged because some uris will not support it.
  635. $file->filesize = @filesize($uri);
  636. $file->timestamp = REQUEST_TIME;
  637. $file->status = FILE_STATUS_PERMANENT;
  638. }
  639. return $file;
  640. }
  641. /**
  642. * Delete multiple files.
  643. *
  644. * Unlike core's file_delete(), this function does not care about file usage
  645. * or skip on invalid URIs. Just deletes the damn file like it should.
  646. *
  647. * @param array $fids
  648. * An array of file IDs.
  649. */
  650. function file_delete_multiple(array $fids) {
  651. $transaction = db_transaction();
  652. if (!empty($fids) && $files = file_load_multiple($fids)) {
  653. try {
  654. foreach ($files as $fid => $file) {
  655. module_invoke_all('file_delete', $file);
  656. module_invoke_all('entity_delete', $file, 'file');
  657. // Skip calling field_attach_delete as file_entity_file_delete()
  658. // does this.
  659. // field_attach_delete('file', $file);
  660. // Remove this file from the search index if needed.
  661. // This code is implemented in file_entity module rather than in search
  662. // module, because node module is implementing search module's API,
  663. // not the other way around.
  664. if (module_exists('search')) {
  665. search_reindex($fid, 'file');
  666. }
  667. // Make sure the file is deleted before removing its row from the
  668. // database, so UIs can still find the file in the database.
  669. if (file_valid_uri($file->uri)) {
  670. file_unmanaged_delete($file->uri);
  671. }
  672. }
  673. db_delete('file_managed')
  674. ->condition('fid', $fids, 'IN')
  675. ->execute();
  676. db_delete('file_usage')
  677. ->condition('fid', $fids, 'IN')
  678. ->execute();
  679. }
  680. catch (Exception $e) {
  681. $transaction->rollback();
  682. watchdog_exception('file', $e);
  683. throw $e;
  684. }
  685. // Clear the page and block and file_load_multiple caches.
  686. entity_get_controller('file')->resetCache();
  687. }
  688. }