comparison core/includes/file.inc @ 5:12f9dff5fda9 tip

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:34:47 +0100
parents a9cd425dd02b
children
comparison
equal deleted inserted replaced
4:a9cd425dd02b 5:12f9dff5fda9
4 * @file 4 * @file
5 * API for handling file uploads and server file management. 5 * API for handling file uploads and server file management.
6 */ 6 */
7 7
8 use Drupal\Component\FileSystem\FileSystem as ComponentFileSystem; 8 use Drupal\Component\FileSystem\FileSystem as ComponentFileSystem;
9 use Drupal\Component\PhpStorage\FileStorage;
10 use Drupal\Component\Utility\Environment;
9 use Drupal\Component\Utility\UrlHelper; 11 use Drupal\Component\Utility\UrlHelper;
10 use Drupal\Component\PhpStorage\FileStorage; 12 use Drupal\Core\File\Exception\FileException;
11 use Drupal\Component\Utility\Bytes; 13 use Drupal\Core\File\Exception\FileWriteException;
12 use Drupal\Core\File\FileSystem; 14 use Drupal\Core\File\FileSystem;
15 use Drupal\Core\File\FileSystemInterface;
13 use Drupal\Core\Site\Settings; 16 use Drupal\Core\Site\Settings;
17 use Drupal\Core\StreamWrapper\PrivateStream;
14 use Drupal\Core\StreamWrapper\PublicStream; 18 use Drupal\Core\StreamWrapper\PublicStream;
15 use Drupal\Core\StreamWrapper\PrivateStream; 19
16 20 /**
17 /** 21 * Default mode for new directories.
18 * Default mode for new directories. See drupal_chmod().
19 * 22 *
20 * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. 23 * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
21 * Use \Drupal\Core\File\FileSystem::CHMOD_DIRECTORY. 24 * Use \Drupal\Core\File\FileSystem::CHMOD_DIRECTORY.
22 * 25 *
26 * @see \Drupal\Core\File\FileSystemInterface::chmod()
23 * @see https://www.drupal.org/node/2418133 27 * @see https://www.drupal.org/node/2418133
24 */ 28 */
25 const FILE_CHMOD_DIRECTORY = FileSystem::CHMOD_DIRECTORY; 29 const FILE_CHMOD_DIRECTORY = FileSystem::CHMOD_DIRECTORY;
26 30
27 /** 31 /**
28 * Default mode for new files. See drupal_chmod(). 32 * Default mode for new files.
29 * 33 *
30 * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. 34 * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
31 * Use \Drupal\Core\File\FileSystem::CHMOD_FILE. 35 * Use \Drupal\Core\File\FileSystem::CHMOD_FILE.
32 * 36 *
37 * @see \Drupal\Core\File\FileSystemInterface::chmod()
33 * @see https://www.drupal.org/node/2418133 38 * @see https://www.drupal.org/node/2418133
34 */ 39 */
35 const FILE_CHMOD_FILE = FileSystem::CHMOD_FILE; 40 const FILE_CHMOD_FILE = FileSystem::CHMOD_FILE;
36 41
37 /** 42 /**
39 * @{ 44 * @{
40 * Common file handling functions. 45 * Common file handling functions.
41 */ 46 */
42 47
43 /** 48 /**
44 * Flag used by file_prepare_directory() -- create directory if not present. 49 * Flag used to create a directory if not present.
45 */ 50 *
46 const FILE_CREATE_DIRECTORY = 1; 51 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
47 52 * Use \Drupal\Core\File\FileSystemInterface::CREATE_DIRECTORY.
48 /** 53 */
49 * Flag used by file_prepare_directory() -- file permissions may be changed. 54 const FILE_CREATE_DIRECTORY = FileSystemInterface::CREATE_DIRECTORY;
50 */ 55
51 const FILE_MODIFY_PERMISSIONS = 2; 56 /**
57 * Flag used to indicate file permissions may be changed.
58 *
59 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
60 * Use \Drupal\Core\File\FileSystemInterface::MODIFY_PERMISSIONS.
61 */
62 const FILE_MODIFY_PERMISSIONS = FileSystemInterface::MODIFY_PERMISSIONS;
52 63
53 /** 64 /**
54 * Flag for dealing with existing files: Appends number until name is unique. 65 * Flag for dealing with existing files: Appends number until name is unique.
55 */ 66 *
56 const FILE_EXISTS_RENAME = 0; 67 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
68 * Use \Drupal\Core\File\FileSystemInterface::EXISTS_RENAME.
69 */
70 const FILE_EXISTS_RENAME = FileSystemInterface::EXISTS_RENAME;
57 71
58 /** 72 /**
59 * Flag for dealing with existing files: Replace the existing file. 73 * Flag for dealing with existing files: Replace the existing file.
60 */ 74 *
61 const FILE_EXISTS_REPLACE = 1; 75 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
76 * Use \Drupal\Core\File\FileSystemInterface::EXISTS_REPLACE.
77 */
78 const FILE_EXISTS_REPLACE = FileSystemInterface::EXISTS_REPLACE;
62 79
63 /** 80 /**
64 * Flag for dealing with existing files: Do nothing and return FALSE. 81 * Flag for dealing with existing files: Do nothing and return FALSE.
65 */ 82 *
66 const FILE_EXISTS_ERROR = 2; 83 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
84 * Use \Drupal\Core\File\FileSystemInterface::EXISTS_ERROR.
85 */
86 const FILE_EXISTS_ERROR = FileSystemInterface::EXISTS_ERROR;
67 87
68 /** 88 /**
69 * Indicates that the file is permanent and should not be deleted. 89 * Indicates that the file is permanent and should not be deleted.
70 * 90 *
71 * Temporary files older than the system.file.temporary_maximum_age 91 * Temporary files older than the system.file.temporary_maximum_age
286 * (FILE_MODIFY_PERMISSIONS). 306 * (FILE_MODIFY_PERMISSIONS).
287 * 307 *
288 * @return 308 * @return
289 * TRUE if the directory exists (or was created) and is writable. FALSE 309 * TRUE if the directory exists (or was created) and is writable. FALSE
290 * otherwise. 310 * otherwise.
291 */ 311 *
292 function file_prepare_directory(&$directory, $options = FILE_MODIFY_PERMISSIONS) { 312 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
293 if (!file_stream_wrapper_valid_scheme(\Drupal::service('file_system')->uriScheme($directory))) { 313 * Use \Drupal\Core\File\FileSystemInterface::prepareDirectory().
294 // Only trim if we're not dealing with a stream. 314 */
295 $directory = rtrim($directory, '/\\'); 315 function file_prepare_directory(&$directory, $options = FileSystemInterface::MODIFY_PERMISSIONS) {
296 } 316 @trigger_error('file_prepare_directory() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::prepareDirectory(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
297 317 return \Drupal::service('file_system')->prepareDirectory($directory, $options);
298 // Check if directory exists.
299 if (!is_dir($directory)) {
300 // Let mkdir() recursively create directories and use the default directory
301 // permissions.
302 if ($options & FILE_CREATE_DIRECTORY) {
303 return @drupal_mkdir($directory, NULL, TRUE);
304 }
305 return FALSE;
306 }
307 // The directory exists, so check to see if it is writable.
308 $writable = is_writable($directory);
309 if (!$writable && ($options & FILE_MODIFY_PERMISSIONS)) {
310 return drupal_chmod($directory);
311 }
312
313 return $writable;
314 } 318 }
315 319
316 /** 320 /**
317 * Creates a .htaccess file in each Drupal files directory if it is missing. 321 * Creates a .htaccess file in each Drupal files directory if it is missing.
318 */ 322 */
368 } 372 }
369 $htaccess_lines = FileStorage::htaccessLines($private); 373 $htaccess_lines = FileStorage::htaccessLines($private);
370 374
371 // Write the .htaccess file. 375 // Write the .htaccess file.
372 if (file_exists($directory) && is_writable($directory) && file_put_contents($htaccess_path, $htaccess_lines)) { 376 if (file_exists($directory) && is_writable($directory) && file_put_contents($htaccess_path, $htaccess_lines)) {
373 return drupal_chmod($htaccess_path, 0444); 377 return \Drupal::service('file_system')->chmod($htaccess_path, 0444);
374 } 378 }
375 else { 379 else {
376 $variables = ['%directory' => $directory, '@htaccess' => $htaccess_lines]; 380 $variables = ['%directory' => $directory, '@htaccess' => $htaccess_lines];
377 \Drupal::logger('security')->error("Security warning: Couldn't write .htaccess file. Please create a .htaccess file in your %directory directory which contains the following lines: <pre><code>@htaccess</code></pre>", $variables); 381 \Drupal::logger('security')->error("Security warning: Couldn't write .htaccess file. Please create a .htaccess file in your %directory directory which contains the following lines: <pre><code>@htaccess</code></pre>", $variables);
378 return FALSE; 382 return FALSE;
450 * - FILE_EXISTS_ERROR - Do nothing and return FALSE. 454 * - FILE_EXISTS_ERROR - Do nothing and return FALSE.
451 * 455 *
452 * @return 456 * @return
453 * The path to the new file, or FALSE in the event of an error. 457 * The path to the new file, or FALSE in the event of an error.
454 * 458 *
459 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
460 * Use \Drupal\Core\File\FileSystemInterface::copy().
461 *
455 * @see file_copy() 462 * @see file_copy()
463 * @see https://www.drupal.org/node/3006851
456 */ 464 */
457 function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) { 465 function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
458 if (!file_unmanaged_prepare($source, $destination, $replace)) { 466 @trigger_error('file_unmanaged_copy() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::copy(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
467 try {
468 $file_system = \Drupal::service('file_system');
469
470 // Build a destination URI if necessary.
471 if (!isset($destination)) {
472 $destination = file_build_uri($file_system->basename($source));
473 }
474 return $file_system->copy($source, $destination, $replace);
475 }
476 catch (FileException $e) {
459 return FALSE; 477 return FALSE;
460 } 478 }
461 // Attempt to resolve the URIs. This is necessary in certain configurations
462 // (see above).
463 $file_system = \Drupal::service('file_system');
464 $real_source = $file_system->realpath($source) ?: $source;
465 $real_destination = $file_system->realpath($destination) ?: $destination;
466 // Perform the copy operation.
467 if (!@copy($real_source, $real_destination)) {
468 \Drupal::logger('file')->error('The specified file %file could not be copied to %destination.', ['%file' => $source, '%destination' => $destination]);
469 return FALSE;
470 }
471 // Set the permissions on the new file.
472 drupal_chmod($destination);
473 return $destination;
474 } 479 }
475 480
476 /** 481 /**
477 * Internal function that prepares the destination for a file_unmanaged_copy or 482 * Internal function that prepares the destination for a file_unmanaged_copy or
478 * file_unmanaged_move operation. 483 * file_unmanaged_move operation.
498 * - FILE_EXISTS_ERROR - Do nothing and return FALSE. 503 * - FILE_EXISTS_ERROR - Do nothing and return FALSE.
499 * 504 *
500 * @return 505 * @return
501 * TRUE, or FALSE in the event of an error. 506 * TRUE, or FALSE in the event of an error.
502 * 507 *
508 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
509 * Use \Drupal\Core\File\FileSystemInterface::getDestinationFilename() instead.
510 *
503 * @see file_unmanaged_copy() 511 * @see file_unmanaged_copy()
504 * @see file_unmanaged_move() 512 * @see file_unmanaged_move()
513 * @see https://www.drupal.org/node/3006851
505 */ 514 */
506 function file_unmanaged_prepare($source, &$destination = NULL, $replace = FILE_EXISTS_RENAME) { 515 function file_unmanaged_prepare($source, &$destination = NULL, $replace = FILE_EXISTS_RENAME) {
516 @trigger_error('file_unmanaged_prepare() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::getDestinationFilename() instead. See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
507 $original_source = $source; 517 $original_source = $source;
508 $logger = \Drupal::logger('file'); 518 $logger = \Drupal::logger('file');
519 /** @var \Drupal\Core\File\FileSystemInterface $file_system */
509 $file_system = \Drupal::service('file_system'); 520 $file_system = \Drupal::service('file_system');
510 521
511 // Assert that the source file actually exists. 522 // Assert that the source file actually exists.
512 if (!file_exists($source)) { 523 if (!file_exists($source)) {
513 // @todo Replace \Drupal::messenger()->addError() calls with exceptions 524 // @todo Replace \Drupal::messenger()->addError() calls with exceptions
522 return FALSE; 533 return FALSE;
523 } 534 }
524 535
525 // Build a destination URI if necessary. 536 // Build a destination URI if necessary.
526 if (!isset($destination)) { 537 if (!isset($destination)) {
527 $destination = file_build_uri(drupal_basename($source)); 538 $destination = file_build_uri($file_system->basename($source));
528 } 539 }
529 540
530 // Prepare the destination directory. 541 // Prepare the destination directory.
531 if (file_prepare_directory($destination)) { 542 if (file_prepare_directory($destination)) {
532 // The destination is already a directory, so append the source basename. 543 // The destination is already a directory, so append the source basename.
533 $destination = file_stream_wrapper_uri_normalize($destination . '/' . drupal_basename($source)); 544 $destination = file_stream_wrapper_uri_normalize($destination . '/' . $file_system->basename($source));
534 } 545 }
535 else { 546 else {
536 // Perhaps $destination is a dir/file? 547 // Perhaps $destination is a dir/file?
537 $dirname = drupal_dirname($destination); 548 $dirname = $file_system->dirname($destination);
538 if (!file_prepare_directory($dirname)) { 549 if (!file_prepare_directory($dirname)) {
539 // The destination is not valid. 550 // The destination is not valid.
540 $logger->notice('File %file could not be moved/copied because the destination directory %destination is not configured correctly.', ['%file' => $original_source, '%destination' => $dirname]); 551 $logger->notice('File %file could not be moved/copied because the destination directory %destination is not configured correctly.', ['%file' => $original_source, '%destination' => $dirname]);
541 \Drupal::messenger()->addError(t('The specified file %file could not be moved/copied because the destination directory is not properly configured. This may be caused by a problem with file or directory permissions. More information is available in the system log.', ['%file' => $original_source])); 552 \Drupal::messenger()->addError(t('The specified file %file could not be moved/copied because the destination directory is not properly configured. This may be caused by a problem with file or directory permissions. More information is available in the system log.', ['%file' => $original_source]));
542 return FALSE; 553 return FALSE;
585 * - FILE_EXISTS_ERROR - Do nothing and return FALSE. 596 * - FILE_EXISTS_ERROR - Do nothing and return FALSE.
586 * 597 *
587 * @return 598 * @return
588 * The destination filepath, or FALSE if the file already exists 599 * The destination filepath, or FALSE if the file already exists
589 * and FILE_EXISTS_ERROR is specified. 600 * and FILE_EXISTS_ERROR is specified.
601 *
602 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
603 * Use \Drupal\Core\File\FileSystemInterface::getDestinationFilename().
604 *
605 * @see https://www.drupal.org/node/3006851
590 */ 606 */
591 function file_destination($destination, $replace) { 607 function file_destination($destination, $replace) {
592 if (file_exists($destination)) { 608 @trigger_error('file_destination() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::getDestinationFilename(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
593 switch ($replace) { 609 return \Drupal::service('file_system')->getDestinationFilename($destination, $replace);
594 case FILE_EXISTS_REPLACE:
595 // Do nothing here, we want to overwrite the existing file.
596 break;
597
598 case FILE_EXISTS_RENAME:
599 $basename = drupal_basename($destination);
600 $directory = drupal_dirname($destination);
601 $destination = file_create_filename($basename, $directory);
602 break;
603
604 case FILE_EXISTS_ERROR:
605 // Error reporting handled by calling function.
606 return FALSE;
607 }
608 }
609 return $destination;
610 } 610 }
611 611
612 /** 612 /**
613 * Moves a file to a new location without database changes or hook invocation. 613 * Moves a file to a new location without database changes or hook invocation.
614 * 614 *
638 * - FILE_EXISTS_ERROR - Do nothing and return FALSE. 638 * - FILE_EXISTS_ERROR - Do nothing and return FALSE.
639 * 639 *
640 * @return 640 * @return
641 * The path to the new file, or FALSE in the event of an error. 641 * The path to the new file, or FALSE in the event of an error.
642 * 642 *
643 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
644 * Use \Drupal\Core\File\FileSystemInterface::move().
645 *
643 * @see file_move() 646 * @see file_move()
647 * @see https://www.drupal.org/node/3006851
644 */ 648 */
645 function file_unmanaged_move($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) { 649 function file_unmanaged_move($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
646 if (!file_unmanaged_prepare($source, $destination, $replace)) { 650 @trigger_error('file_unmanaged_move() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::move(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
651 try {
652 $file_system = \Drupal::service('file_system');
653
654 // Build a destination URI if necessary.
655 if (!isset($destination)) {
656 $destination = file_build_uri($file_system->basename($source));
657 }
658 return $file_system->move($source, $destination, $replace);
659 }
660 catch (FileException $e) {
647 return FALSE; 661 return FALSE;
648 } 662 }
649 // Ensure compatibility with Windows.
650 // @see drupal_unlink()
651 if ((substr(PHP_OS, 0, 3) == 'WIN') && (!file_stream_wrapper_valid_scheme(file_uri_scheme($source)))) {
652 chmod($source, 0600);
653 }
654 // Attempt to resolve the URIs. This is necessary in certain configurations
655 // (see above) and can also permit fast moves across local schemes.
656 $file_system = \Drupal::service('file_system');
657 $real_source = $file_system->realpath($source) ?: $source;
658 $real_destination = $file_system->realpath($destination) ?: $destination;
659 // Perform the move operation.
660 if (!@rename($real_source, $real_destination)) {
661 // Fall back to slow copy and unlink procedure. This is necessary for
662 // renames across schemes that are not local, or where rename() has not been
663 // implemented. It's not necessary to use drupal_unlink() as the Windows
664 // issue has already been resolved above.
665 if (!@copy($real_source, $real_destination) || !@unlink($real_source)) {
666 \Drupal::logger('file')->error('The specified file %file could not be moved to %destination.', ['%file' => $source, '%destination' => $destination]);
667 return FALSE;
668 }
669 }
670 // Set the permissions on the new file.
671 drupal_chmod($destination);
672 return $destination;
673 } 663 }
674 664
675 /** 665 /**
676 * Modifies a filename as needed for security purposes. 666 * Modifies a filename as needed for security purposes.
677 * 667 *
766 * String containing the directory or parent URI. 756 * String containing the directory or parent URI.
767 * 757 *
768 * @return 758 * @return
769 * File path consisting of $directory and a unique filename based off 759 * File path consisting of $directory and a unique filename based off
770 * of $basename. 760 * of $basename.
761 *
762 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
763 * Use \Drupal\Core\File\FileSystemInterface::createFilename().
764 *
765 * @see https://www.drupal.org/node/3006851
771 */ 766 */
772 function file_create_filename($basename, $directory) { 767 function file_create_filename($basename, $directory) {
773 // Strip control characters (ASCII value < 32). Though these are allowed in 768 @trigger_error('file_create_filename() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::createFilename(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
774 // some filesystems, not many applications handle them well. 769 return \Drupal::service('file_system')->createFilename($basename, $directory);
775 $basename = preg_replace('/[\x00-\x1F]/u', '_', $basename);
776 if (substr(PHP_OS, 0, 3) == 'WIN') {
777 // These characters are not allowed in Windows filenames
778 $basename = str_replace([':', '*', '?', '"', '<', '>', '|'], '_', $basename);
779 }
780
781 // A URI or path may already have a trailing slash or look like "public://".
782 if (substr($directory, -1) == '/') {
783 $separator = '';
784 }
785 else {
786 $separator = '/';
787 }
788
789 $destination = $directory . $separator . $basename;
790
791 if (file_exists($destination)) {
792 // Destination file already exists, generate an alternative.
793 $pos = strrpos($basename, '.');
794 if ($pos !== FALSE) {
795 $name = substr($basename, 0, $pos);
796 $ext = substr($basename, $pos);
797 }
798 else {
799 $name = $basename;
800 $ext = '';
801 }
802
803 $counter = 0;
804 do {
805 $destination = $directory . $separator . $name . '_' . $counter++ . $ext;
806 } while (file_exists($destination));
807 }
808
809 return $destination;
810 } 770 }
811 771
812 /** 772 /**
813 * Deletes a file and its database record. 773 * Deletes a file and its database record.
814 * 774 *
817 * remove it during cleanup. 777 * remove it during cleanup.
818 * 778 *
819 * @param $fid 779 * @param $fid
820 * The file id. 780 * The file id.
821 * 781 *
782 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
783 * Use \Drupal\Core\Entity\EntityStorageInterface::delete() instead.
784 *
822 * @see file_unmanaged_delete() 785 * @see file_unmanaged_delete()
823 * @see \Drupal\file\FileUsage\FileUsageBase::delete() 786 * @see \Drupal\file\FileUsage\FileUsageBase::delete()
787 * @see \Drupal\Core\Entity\EntityStorageInterface::delete()
788 * @see https://www.drupal.org/node/3021663
824 */ 789 */
825 function file_delete($fid) { 790 function file_delete($fid) {
791 @trigger_error('file_delete() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\EntityStorageInterface::delete() instead. See https://www.drupal.org/node/3021663.', E_USER_DEPRECATED);
826 return file_delete_multiple([$fid]); 792 return file_delete_multiple([$fid]);
827 } 793 }
828 794
829 /** 795 /**
830 * Deletes files. 796 * Deletes files.
831 * 797 *
832 * Instead of directly deleting a file, it is strongly recommended to delete 798 * Instead of directly deleting a file, it is strongly recommended to delete
833 * file usages instead. That will automatically mark the file as temporary and 799 * file usages instead. That will automatically mark the file as temporary and
834 * remove it during cleanup. 800 * remove it during cleanup.
835 * 801 *
836 * @param $fid 802 * @param $fids
837 * The file id. 803 * An array of file ids.
804 *
805 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
806 * Use \Drupal\Core\Entity\EntityStorageInterface::delete() instead.
838 * 807 *
839 * @see file_unmanaged_delete() 808 * @see file_unmanaged_delete()
840 * @see \Drupal\file\FileUsage\FileUsageBase::delete() 809 * @see \Drupal\file\FileUsage\FileUsageBase::delete()
810 * @see \Drupal\Core\Entity\EntityStorageInterface::delete()
811 * @see https://www.drupal.org/node/3021663
841 */ 812 */
842 function file_delete_multiple(array $fids) { 813 function file_delete_multiple(array $fids) {
843 entity_delete_multiple('file', $fids); 814 @trigger_error('file_delete_multiple() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\EntityStorageInterface::delete() instead. See https://www.drupal.org/node/3021663.', E_USER_DEPRECATED);
815 $storage = \Drupal::entityTypeManager()->getStorage('file');
816 $entities = $storage->loadMultiple($fids);
817 $storage->delete($entities);
844 } 818 }
845 819
846 /** 820 /**
847 * Deletes a file without database changes or hook invocations. 821 * Deletes a file without database changes or hook invocations.
848 * 822 *
854 * 828 *
855 * @return 829 * @return
856 * TRUE for success or path does not exist, or FALSE in the event of an 830 * TRUE for success or path does not exist, or FALSE in the event of an
857 * error. 831 * error.
858 * 832 *
833 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
834 * Use \Drupal\Core\File\FileSystemInterface::delete().
835 *
859 * @see file_delete() 836 * @see file_delete()
860 * @see file_unmanaged_delete_recursive() 837 * @see file_unmanaged_delete_recursive()
838 * @see https://www.drupal.org/node/3006851
861 */ 839 */
862 function file_unmanaged_delete($path) { 840 function file_unmanaged_delete($path) {
863 if (is_file($path)) { 841 @trigger_error('file_unmanaged_delete() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::delete(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
864 return drupal_unlink($path); 842 try {
865 } 843 return \Drupal::service('file_system')->delete($path);
866 $logger = \Drupal::logger('file'); 844 }
867 if (is_dir($path)) { 845 catch (FileException $e) {
868 $logger->error('%path is a directory and cannot be removed using file_unmanaged_delete().', ['%path' => $path]);
869 return FALSE; 846 return FALSE;
870 } 847 }
871 // Return TRUE for non-existent file, but log that nothing was actually
872 // deleted, as the current state is the intended result.
873 if (!file_exists($path)) {
874 $logger->notice('The file %path was not deleted because it does not exist.', ['%path' => $path]);
875 return TRUE;
876 }
877 // We cannot handle anything other than files and directories. Log an error
878 // for everything else (sockets, symbolic links, etc).
879 $logger->error('The file %path is not of a recognized type so it was not deleted.', ['%path' => $path]);
880 return FALSE;
881 } 848 }
882 849
883 /** 850 /**
884 * Deletes all files and directories in the specified filepath recursively. 851 * Deletes all files and directories in the specified filepath recursively.
885 * 852 *
901 * 868 *
902 * @return 869 * @return
903 * TRUE for success or if path does not exist, FALSE in the event of an 870 * TRUE for success or if path does not exist, FALSE in the event of an
904 * error. 871 * error.
905 * 872 *
873 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
874 * Use \Drupal\Core\File\FileSystemInterface::deleteRecursive().
875 *
906 * @see file_unmanaged_delete() 876 * @see file_unmanaged_delete()
877 * @see https://www.drupal.org/node/3006851
907 */ 878 */
908 function file_unmanaged_delete_recursive($path, $callback = NULL) { 879 function file_unmanaged_delete_recursive($path, $callback = NULL) {
909 if (isset($callback)) { 880 @trigger_error('file_unmanaged_delete_recursive() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::deleteRecursive(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
910 call_user_func($callback, $path); 881 $callback = is_callable($callback) ? $callback : NULL;
911 } 882 try {
912 if (is_dir($path)) { 883 return \Drupal::service('file_system')->deleteRecursive($path, $callback);
913 $dir = dir($path); 884 }
914 while (($entry = $dir->read()) !== FALSE) { 885 catch (FileException $e) {
915 if ($entry == '.' || $entry == '..') { 886 return FALSE;
916 continue; 887 }
917 }
918 $entry_path = $path . '/' . $entry;
919 file_unmanaged_delete_recursive($entry_path, $callback);
920 }
921 $dir->close();
922
923 return drupal_rmdir($path);
924 }
925 return file_unmanaged_delete($path);
926 } 888 }
927 889
928 /** 890 /**
929 * Moves an uploaded file to a new location. 891 * Moves an uploaded file to a new location.
930 * 892 *
932 * Use \Drupal\Core\File\FileSystem::moveUploadedFile(). 894 * Use \Drupal\Core\File\FileSystem::moveUploadedFile().
933 * 895 *
934 * @see https://www.drupal.org/node/2418133 896 * @see https://www.drupal.org/node/2418133
935 */ 897 */
936 function drupal_move_uploaded_file($filename, $uri) { 898 function drupal_move_uploaded_file($filename, $uri) {
899 @trigger_error('drupal_move_uploaded_file() is deprecated in Drupal 8.0.x-dev and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::moveUploadedFile(). See https://www.drupal.org/node/2418133.', E_USER_DEPRECATED);
937 return \Drupal::service('file_system')->moveUploadedFile($filename, $uri); 900 return \Drupal::service('file_system')->moveUploadedFile($filename, $uri);
938 } 901 }
939 902
940 /** 903 /**
941 * Saves a file to the specified destination without invoking file API. 904 * Saves a file to the specified destination without invoking file API.
959 * - FILE_EXISTS_ERROR - Do nothing and return FALSE. 922 * - FILE_EXISTS_ERROR - Do nothing and return FALSE.
960 * 923 *
961 * @return 924 * @return
962 * A string with the path of the resulting file, or FALSE on error. 925 * A string with the path of the resulting file, or FALSE on error.
963 * 926 *
927 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
928 * Use \Drupal\Core\File\FileSystemInterface::saveData().
929 *
964 * @see file_save_data() 930 * @see file_save_data()
931 * @see https://www.drupal.org/node/3006851
965 */ 932 */
966 function file_unmanaged_save_data($data, $destination = NULL, $replace = FILE_EXISTS_RENAME) { 933 function file_unmanaged_save_data($data, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
967 // Write the data to a temporary file. 934 @trigger_error('file_unmanaged_save_data() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::saveData(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
968 $temp_name = drupal_tempnam('temporary://', 'file'); 935 try {
969 if (file_put_contents($temp_name, $data) === FALSE) { 936 // Build a destination URI if necessary.
937 if (!isset($destination)) {
938 $destination = file_default_scheme() . '://';
939 }
940 return \Drupal::service('file_system')->saveData($data, $destination, $replace);
941 }
942 catch (FileWriteException $e) {
970 \Drupal::messenger()->addError(t('The file could not be created.')); 943 \Drupal::messenger()->addError(t('The file could not be created.'));
971 return FALSE; 944 return FALSE;
972 } 945 }
973 946 catch (FileException $e) {
974 // Move the file to its final destination. 947 return FALSE;
975 return file_unmanaged_move($temp_name, $destination, $replace); 948 }
976 } 949 }
977 950
978 /** 951 /**
979 * Finds all files that match a given mask in a given directory. 952 * Finds all files that match a given mask in a given directory.
980 * 953 *
1091 * Determines the maximum file upload size by querying the PHP settings. 1064 * Determines the maximum file upload size by querying the PHP settings.
1092 * 1065 *
1093 * @return 1066 * @return
1094 * A file size limit in bytes based on the PHP upload_max_filesize and 1067 * A file size limit in bytes based on the PHP upload_max_filesize and
1095 * post_max_size 1068 * post_max_size
1069 *
1070 * @deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0.
1071 * Use \Drupal\Component\Utility\Environment::getUploadMaxSize() instead.
1096 */ 1072 */
1097 function file_upload_max_size() { 1073 function file_upload_max_size() {
1098 static $max_size = -1; 1074 @trigger_error('file_upload_max_size() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Component\Utility\Environment::getUploadMaxSize() instead. See https://www.drupal.org/node/3000058.', E_USER_DEPRECATED);
1099 1075 return Environment::getUploadMaxSize();
1100 if ($max_size < 0) {
1101 // Start with post_max_size.
1102 $max_size = Bytes::toInt(ini_get('post_max_size'));
1103
1104 // If upload_max_size is less, then reduce. Except if upload_max_size is
1105 // zero, which indicates no limit.
1106 $upload_max = Bytes::toInt(ini_get('upload_max_filesize'));
1107 if ($upload_max > 0 && $upload_max < $max_size) {
1108 $max_size = $upload_max;
1109 }
1110 }
1111 return $max_size;
1112 } 1076 }
1113 1077
1114 /** 1078 /**
1115 * Sets the permissions on a file or directory. 1079 * Sets the permissions on a file or directory.
1116 * 1080 *
1117 * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. 1081 * @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
1118 * Use \Drupal\Core\File\FileSystem::chmod(). 1082 * Use \Drupal\Core\File\FileSystem::chmod().
1119 * 1083 *
1120 * @see https://www.drupal.org/node/2418133 1084 * @see https://www.drupal.org/node/2418133
1121 */ 1085 */
1122 function drupal_chmod($uri, $mode = NULL) { 1086 function drupal_chmod($uri, $mode = NULL) {
1087 @trigger_error('drupal_chmod() is deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::chmod(). See https://www.drupal.org/node/2418133.', E_USER_DEPRECATED);
1123 return \Drupal::service('file_system')->chmod($uri, $mode); 1088 return \Drupal::service('file_system')->chmod($uri, $mode);
1124 } 1089 }
1125 1090
1126 /** 1091 /**
1127 * Deletes a file. 1092 * Deletes a file.
1148 } 1113 }
1149 1114
1150 /** 1115 /**
1151 * Gets the name of the directory from a given path. 1116 * Gets the name of the directory from a given path.
1152 * 1117 *
1153 * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. 1118 * @deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0.
1154 * Use \Drupal\Core\File\FileSystem::dirname(). 1119 * Use \Drupal\Core\File\FileSystem::dirname().
1155 * 1120 *
1156 * @see https://www.drupal.org/node/2418133 1121 * @see https://www.drupal.org/node/2418133
1157 */ 1122 */
1158 function drupal_dirname($uri) { 1123 function drupal_dirname($uri) {
1124 @trigger_error('drupal_dirname() is deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::dirname(). See https://www.drupal.org/node/2418133.', E_USER_DEPRECATED);
1159 return \Drupal::service('file_system')->dirname($uri); 1125 return \Drupal::service('file_system')->dirname($uri);
1160 } 1126 }
1161 1127
1162 /** 1128 /**
1163 * Gets the filename from a given path. 1129 * Gets the filename from a given path.
1164 * 1130 *
1165 * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. 1131 * @deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0.
1166 * Use \Drupal\Core\File\FileSystem::basename(). 1132 * Use \Drupal\Core\File\FileSystem::basename().
1167 * 1133 *
1168 * @see https://www.drupal.org/node/2418133 1134 * @see https://www.drupal.org/node/2418133
1169 */ 1135 */
1170 function drupal_basename($uri, $suffix = NULL) { 1136 function drupal_basename($uri, $suffix = NULL) {
1137 @trigger_error('drupal_basename() is deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::basename(). See https://www.drupal.org/node/2418133.', E_USER_DEPRECATED);
1171 return \Drupal::service('file_system')->basename($uri, $suffix); 1138 return \Drupal::service('file_system')->basename($uri, $suffix);
1172 } 1139 }
1173 1140
1174 /** 1141 /**
1175 * Creates a directory, optionally creating missing components in the path to 1142 * Creates a directory, optionally creating missing components in the path to
1176 * the directory. 1143 * the directory.
1177 * 1144 *
1178 * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. 1145 * @deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0.
1179 * Use \Drupal\Core\File\FileSystem::mkdir(). 1146 * Use \Drupal\Core\File\FileSystem::mkdir().
1180 * 1147 *
1181 * @see https://www.drupal.org/node/2418133 1148 * @see https://www.drupal.org/node/2418133
1182 */ 1149 */
1183 function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) { 1150 function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
1151 @trigger_error('drupal_mkdir() is deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::mkdir(). See https://www.drupal.org/node/2418133.', E_USER_DEPRECATED);
1184 return \Drupal::service('file_system')->mkdir($uri, $mode, $recursive, $context); 1152 return \Drupal::service('file_system')->mkdir($uri, $mode, $recursive, $context);
1185 } 1153 }
1186 1154
1187 /** 1155 /**
1188 * Removes a directory. 1156 * Removes a directory.
1189 * 1157 *
1190 * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. 1158 * @deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0.
1191 * Use \Drupal\Core\File\FileSystem::rmdir(). 1159 * Use \Drupal\Core\File\FileSystem::rmdir().
1192 * 1160 *
1193 * @see https://www.drupal.org/node/2418133 1161 * @see https://www.drupal.org/node/2418133
1194 */ 1162 */
1195 function drupal_rmdir($uri, $context = NULL) { 1163 function drupal_rmdir($uri, $context = NULL) {
1164 @trigger_error('drupal_rmdir() is deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::rmdir(). See https://www.drupal.org/node/2418133.', E_USER_DEPRECATED);
1196 return \Drupal::service('file_system')->rmdir($uri, $context); 1165 return \Drupal::service('file_system')->rmdir($uri, $context);
1197 } 1166 }
1198 1167
1199 /** 1168 /**
1200 * Creates a file with a unique filename in the specified directory. 1169 * Creates a file with a unique filename in the specified directory.
1201 * 1170 *
1202 * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0. 1171 * @deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0.
1203 * Use \Drupal\Core\File\FileSystem::tempnam(). 1172 * Use \Drupal\Core\File\FileSystem::tempnam().
1204 * 1173 *
1205 * @see https://www.drupal.org/node/2418133 1174 * @see https://www.drupal.org/node/2418133
1206 */ 1175 */
1207 function drupal_tempnam($directory, $prefix) { 1176 function drupal_tempnam($directory, $prefix) {
1177 @trigger_error('tempnam() is deprecated in Drupal 8.0.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::tempnam(). See https://www.drupal.org/node/2418133.', E_USER_DEPRECATED);
1208 return \Drupal::service('file_system')->tempnam($directory, $prefix); 1178 return \Drupal::service('file_system')->tempnam($directory, $prefix);
1209 } 1179 }
1210 1180
1211 /** 1181 /**
1212 * Gets and sets the path of the configured temporary directory. 1182 * Gets and sets the path of the configured temporary directory.