file.inc 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144
  1. <?php
  2. /**
  3. * @file
  4. * API for handling file uploads and server file management.
  5. */
  6. use Drupal\Component\FileSecurity\FileSecurity;
  7. use Drupal\Component\FileSystem\FileSystem as ComponentFileSystem;
  8. use Drupal\Component\Utility\Environment;
  9. use Drupal\Component\Utility\UrlHelper;
  10. use Drupal\Core\File\Exception\FileException;
  11. use Drupal\Core\File\Exception\FileWriteException;
  12. use Drupal\Core\File\FileSystem;
  13. use Drupal\Core\File\FileSystemInterface;
  14. use Drupal\Core\StreamWrapper\StreamWrapperManager;
  15. /**
  16. * Default mode for new directories.
  17. *
  18. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  19. * Use \Drupal\Core\File\FileSystem::CHMOD_DIRECTORY.
  20. *
  21. * @see \Drupal\Core\File\FileSystemInterface::chmod()
  22. * @see https://www.drupal.org/node/2418133
  23. */
  24. const FILE_CHMOD_DIRECTORY = FileSystem::CHMOD_DIRECTORY;
  25. /**
  26. * Default mode for new files.
  27. *
  28. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  29. * Use \Drupal\Core\File\FileSystem::CHMOD_FILE.
  30. *
  31. * @see \Drupal\Core\File\FileSystemInterface::chmod()
  32. * @see https://www.drupal.org/node/2418133
  33. */
  34. const FILE_CHMOD_FILE = FileSystem::CHMOD_FILE;
  35. /**
  36. * @defgroup file File interface
  37. * @{
  38. * Common file handling functions.
  39. */
  40. /**
  41. * Flag used to create a directory if not present.
  42. *
  43. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  44. * Use \Drupal\Core\File\FileSystemInterface::CREATE_DIRECTORY.
  45. */
  46. const FILE_CREATE_DIRECTORY = FileSystemInterface::CREATE_DIRECTORY;
  47. /**
  48. * Flag used to indicate file permissions may be changed.
  49. *
  50. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  51. * Use \Drupal\Core\File\FileSystemInterface::MODIFY_PERMISSIONS.
  52. */
  53. const FILE_MODIFY_PERMISSIONS = FileSystemInterface::MODIFY_PERMISSIONS;
  54. /**
  55. * Flag for dealing with existing files: Appends number until name is unique.
  56. *
  57. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  58. * Use \Drupal\Core\File\FileSystemInterface::EXISTS_RENAME.
  59. */
  60. const FILE_EXISTS_RENAME = FileSystemInterface::EXISTS_RENAME;
  61. /**
  62. * Flag for dealing with existing files: Replace the existing file.
  63. *
  64. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  65. * Use \Drupal\Core\File\FileSystemInterface::EXISTS_REPLACE.
  66. */
  67. const FILE_EXISTS_REPLACE = FileSystemInterface::EXISTS_REPLACE;
  68. /**
  69. * Flag for dealing with existing files: Do nothing and return FALSE.
  70. *
  71. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  72. * Use \Drupal\Core\File\FileSystemInterface::EXISTS_ERROR.
  73. */
  74. const FILE_EXISTS_ERROR = FileSystemInterface::EXISTS_ERROR;
  75. /**
  76. * Indicates that the file is permanent and should not be deleted.
  77. *
  78. * Temporary files older than the system.file.temporary_maximum_age
  79. * configuration value will be, if clean-up not disabled, removed during cron
  80. * runs, but permanent files will not be removed during the file garbage
  81. * collection process.
  82. */
  83. const FILE_STATUS_PERMANENT = 1;
  84. /**
  85. * Returns the scheme of a URI (e.g. a stream).
  86. *
  87. * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
  88. * Drupal\Core\StreamWrapper\StreamWrapperManagerInterface::getScheme()
  89. * instead.
  90. *
  91. * @see https://www.drupal.org/node/3035273
  92. */
  93. function file_uri_scheme($uri) {
  94. @trigger_error('file_uri_scheme() is deprecated in drupal:8.0.0 and will be removed before drupal:9.0.0. Use \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface::getScheme() instead. See https://www.drupal.org/node/3035273', E_USER_DEPRECATED);
  95. return StreamWrapperManager::getScheme($uri);
  96. }
  97. /**
  98. * Checks that the scheme of a stream URI is valid.
  99. *
  100. * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
  101. * Drupal\Core\StreamWrapper\StreamWrapperManagerInterface::isValidScheme()
  102. * instead.
  103. *
  104. * @see https://www.drupal.org/node/3035273
  105. */
  106. function file_stream_wrapper_valid_scheme($scheme) {
  107. @trigger_error('file_stream_wrapper_valid_scheme() is deprecated in drupal:8.0.0 and will be removed before drupal:9.0.0. Use \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface::isValidScheme() instead. See https://www.drupal.org/node/3035273', E_USER_DEPRECATED);
  108. return \Drupal::service('stream_wrapper_manager')->isValidScheme($scheme);
  109. }
  110. /**
  111. * Returns the part of a URI after the schema.
  112. *
  113. * @param string $uri
  114. * A stream, referenced as "scheme://target" or "data:target".
  115. *
  116. * @return string|bool
  117. * A string containing the target (path), or FALSE if none.
  118. * For example, the URI "public://sample/test.txt" would return
  119. * "sample/test.txt".
  120. *
  121. * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
  122. * \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface::getTarget()
  123. * instead.
  124. *
  125. * @see https://www.drupal.org/node/3035273
  126. */
  127. function file_uri_target($uri) {
  128. @trigger_error('file_uri_target() is deprecated in drupal:8.8.0 and will be removed before drupal:9.0.0. Use \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface::getTarget() instead. See https://www.drupal.org/node/3035273', E_USER_DEPRECATED);
  129. return StreamWrapperManager::getTarget($uri);
  130. }
  131. /**
  132. * Gets the default file stream implementation.
  133. *
  134. * @return string
  135. * 'public', 'private' or any other file scheme defined as the default.
  136. *
  137. * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
  138. * \Drupal::config('system.file')->get('default_scheme') instead.
  139. *
  140. * @see https://www.drupal.org/node/3049030
  141. */
  142. function file_default_scheme() {
  143. @trigger_error('file_default_scheme() is deprecated in drupal:8.8.0. It will be removed from drupal:9.0.0. Use \Drupal::config(\'system.file\')->get(\'default_scheme\') instead. See https://www.drupal.org/node/3049030', E_USER_DEPRECATED);
  144. return \Drupal::config('system.file')->get('default_scheme');
  145. }
  146. /**
  147. * Normalizes a URI by making it syntactically correct.
  148. *
  149. * A stream is referenced as "scheme://target".
  150. *
  151. * The following actions are taken:
  152. * - Remove trailing slashes from target
  153. * - Trim erroneous leading slashes from target. e.g. ":///" becomes "://".
  154. *
  155. * @param string $uri
  156. * String reference containing the URI to normalize.
  157. *
  158. * @return string
  159. * The normalized URI.
  160. *
  161. * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
  162. * \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface::normalizeUri()
  163. * instead.
  164. *
  165. * @see https://www.drupal.org/node/3035273
  166. */
  167. function file_stream_wrapper_uri_normalize($uri) {
  168. @trigger_error('file_stream_wrapper_uri_normalize() is deprecated in drupal:8.8.0 and will be removed before drupal:9.0.0. Use \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface::normalizeUri() instead. See https://www.drupal.org/node/3035273', E_USER_DEPRECATED);
  169. return \Drupal::service('stream_wrapper_manager')->normalizeUri($uri);
  170. }
  171. /**
  172. * Creates a web-accessible URL for a stream to an external or local file.
  173. *
  174. * Compatibility: normal paths and stream wrappers.
  175. *
  176. * There are two kinds of local files:
  177. * - "managed files", i.e. those stored by a Drupal-compatible stream wrapper.
  178. * These are files that have either been uploaded by users or were generated
  179. * automatically (for example through CSS aggregation).
  180. * - "shipped files", i.e. those outside of the files directory, which ship as
  181. * part of Drupal core or contributed modules or themes.
  182. *
  183. * @param string $uri
  184. * The URI to a file for which we need an external URL, or the path to a
  185. * shipped file.
  186. *
  187. * @return string
  188. * A string containing a URL that may be used to access the file.
  189. * If the provided string already contains a preceding 'http', 'https', or
  190. * '/', nothing is done and the same string is returned. If a stream wrapper
  191. * could not be found to generate an external URL, then FALSE is returned.
  192. *
  193. * @see https://www.drupal.org/node/515192
  194. * @see file_url_transform_relative()
  195. */
  196. function file_create_url($uri) {
  197. // Allow the URI to be altered, e.g. to serve a file from a CDN or static
  198. // file server.
  199. \Drupal::moduleHandler()->alter('file_url', $uri);
  200. $scheme = StreamWrapperManager::getScheme($uri);
  201. if (!$scheme) {
  202. // Allow for:
  203. // - root-relative URIs (e.g. /foo.jpg in http://example.com/foo.jpg)
  204. // - protocol-relative URIs (e.g. //bar.jpg, which is expanded to
  205. // http://example.com/bar.jpg by the browser when viewing a page over
  206. // HTTP and to https://example.com/bar.jpg when viewing a HTTPS page)
  207. // Both types of relative URIs are characterized by a leading slash, hence
  208. // we can use a single check.
  209. if (mb_substr($uri, 0, 1) == '/') {
  210. return $uri;
  211. }
  212. else {
  213. // If this is not a properly formatted stream, then it is a shipped file.
  214. // Therefore, return the urlencoded URI with the base URL prepended.
  215. $options = UrlHelper::parse($uri);
  216. $path = $GLOBALS['base_url'] . '/' . UrlHelper::encodePath($options['path']);
  217. // Append the query.
  218. if ($options['query']) {
  219. $path .= '?' . UrlHelper::buildQuery($options['query']);
  220. }
  221. // Append fragment.
  222. if ($options['fragment']) {
  223. $path .= '#' . $options['fragment'];
  224. }
  225. return $path;
  226. }
  227. }
  228. elseif ($scheme == 'http' || $scheme == 'https' || $scheme == 'data') {
  229. // Check for HTTP and data URI-encoded URLs so that we don't have to
  230. // implement getExternalUrl() for the HTTP and data schemes.
  231. return $uri;
  232. }
  233. else {
  234. // Attempt to return an external URL using the appropriate wrapper.
  235. if ($wrapper = \Drupal::service('stream_wrapper_manager')->getViaUri($uri)) {
  236. return $wrapper->getExternalUrl();
  237. }
  238. else {
  239. return FALSE;
  240. }
  241. }
  242. }
  243. /**
  244. * Transforms an absolute URL of a local file to a relative URL.
  245. *
  246. * May be useful to prevent problems on multisite set-ups and prevent mixed
  247. * content errors when using HTTPS + HTTP.
  248. *
  249. * @param string $file_url
  250. * A file URL of a local file as generated by file_create_url().
  251. *
  252. * @return string
  253. * If the file URL indeed pointed to a local file and was indeed absolute,
  254. * then the transformed, relative URL to the local file. Otherwise: the
  255. * original value of $file_url.
  256. *
  257. * @see file_create_url()
  258. */
  259. function file_url_transform_relative($file_url) {
  260. // Unfortunately, we pretty much have to duplicate Symfony's
  261. // Request::getHttpHost() method because Request::getPort() may return NULL
  262. // instead of a port number.
  263. $request = \Drupal::request();
  264. $host = $request->getHost();
  265. $scheme = $request->getScheme();
  266. $port = $request->getPort() ?: 80;
  267. if (('http' == $scheme && $port == 80) || ('https' == $scheme && $port == 443)) {
  268. $http_host = $host;
  269. }
  270. else {
  271. $http_host = $host . ':' . $port;
  272. }
  273. return preg_replace('|^https?://' . preg_quote($http_host, '|') . '|', '', $file_url);
  274. }
  275. /**
  276. * Checks that the directory exists and is writable.
  277. *
  278. * Directories need to have execute permissions to be considered a directory by
  279. * FTP servers, etc.
  280. *
  281. * @param $directory
  282. * A string reference containing the name of a directory path or URI. A
  283. * trailing slash will be trimmed from a path.
  284. * @param $options
  285. * A bitmask to indicate if the directory should be created if it does
  286. * not exist (FILE_CREATE_DIRECTORY) or made writable if it is read-only
  287. * (FILE_MODIFY_PERMISSIONS).
  288. *
  289. * @return
  290. * TRUE if the directory exists (or was created) and is writable. FALSE
  291. * otherwise.
  292. *
  293. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  294. * Use \Drupal\Core\File\FileSystemInterface::prepareDirectory().
  295. */
  296. function file_prepare_directory(&$directory, $options = FileSystemInterface::MODIFY_PERMISSIONS) {
  297. @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);
  298. return \Drupal::service('file_system')->prepareDirectory($directory, $options);
  299. }
  300. /**
  301. * Creates a .htaccess file in each Drupal files directory if it is missing.
  302. *
  303. * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
  304. * \Drupal\Core\File\HtaccessWriterInterface::ensure() instead.
  305. *
  306. * @see https://www.drupal.org/node/2940126
  307. */
  308. function file_ensure_htaccess() {
  309. @trigger_error("file_ensure_htaccess() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\HtaccessWriter::ensure() instead. See https://www.drupal.org/node/2940126", E_USER_DEPRECATED);
  310. \Drupal::service('file.htaccess_writer')->ensure();
  311. }
  312. /**
  313. * Creates a .htaccess file in the given directory.
  314. *
  315. * @param string $directory
  316. * The directory.
  317. * @param bool $private
  318. * (Optional) FALSE indicates that $directory should be a web-accessible
  319. * directory. Defaults to TRUE which indicates a private directory.
  320. * @param bool $force_overwrite
  321. * (Optional) Set to TRUE to attempt to overwrite the existing .htaccess file
  322. * if one is already present. Defaults to FALSE.
  323. *
  324. * @return bool
  325. * TRUE when file exists or created successfully, FALSE otherwise.
  326. *
  327. * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
  328. * \Drupal\Component\FileSecurity\FileSecurity::writeHtaccess() instead.
  329. *
  330. * @see https://www.drupal.org/node/2940126
  331. */
  332. function file_save_htaccess($directory, $private = TRUE, $force_overwrite = FALSE) {
  333. @trigger_error('file_save_htaccess() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Component\FileSecurity\FileSecurity::writeHtaccess() instead. See https://www.drupal.org/node/2940126', E_USER_DEPRECATED);
  334. return \Drupal::service('file.htaccess_writer')->write($directory, $private, $force_overwrite);
  335. }
  336. /**
  337. * Returns the standard .htaccess lines that Drupal writes to file directories.
  338. *
  339. * @param bool $private
  340. * (Optional) Set to FALSE to return the .htaccess lines for a web-accessible
  341. * public directory. The default is TRUE, which returns the .htaccess lines
  342. * for a private directory that should not be web-accessible.
  343. *
  344. * @return string
  345. * The desired contents of the .htaccess file.
  346. *
  347. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  348. * Use \Drupal\Component\FileSecurity\FileSecurity::htaccessLines().
  349. *
  350. * @see https://www.drupal.org/node/2418133
  351. */
  352. function file_htaccess_lines($private = TRUE) {
  353. return FileSecurity::htaccessLines($private);
  354. }
  355. /**
  356. * Determines whether the URI has a valid scheme for file API operations.
  357. *
  358. * There must be a scheme and it must be a Drupal-provided scheme like
  359. * 'public', 'private', 'temporary', or an extension provided with
  360. * hook_stream_wrappers().
  361. *
  362. * @param $uri
  363. * The URI to be tested.
  364. *
  365. * @return
  366. * TRUE if the URI is allowed.
  367. *
  368. * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
  369. * \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface::isValidUri()
  370. * instead.
  371. *
  372. * @see https://www.drupal.org/node/3035273
  373. */
  374. function file_valid_uri($uri) {
  375. @trigger_error('file_valid_uri() is deprecated in drupal:8.8.0 and will be removed before drupal:9.0.0. Use \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface::isValidUri() instead. See https://www.drupal.org/node/3035273', E_USER_DEPRECATED);
  376. return \Drupal::service('stream_wrapper_manager')->isValidUri($uri);
  377. }
  378. /**
  379. * Copies a file to a new location without database changes or hook invocation.
  380. *
  381. * This is a powerful function that in many ways performs like an advanced
  382. * version of copy().
  383. * - Checks if $source and $destination are valid and readable/writable.
  384. * - If file already exists in $destination either the call will error out,
  385. * replace the file or rename the file based on the $replace parameter.
  386. * - If the $source and $destination are equal, the behavior depends on the
  387. * $replace parameter. FILE_EXISTS_REPLACE will error out. FILE_EXISTS_RENAME
  388. * will rename the file until the $destination is unique.
  389. * - Works around a PHP bug where copy() does not properly support streams if
  390. * safe_mode or open_basedir are enabled.
  391. * @see https://bugs.php.net/bug.php?id=60456
  392. *
  393. * @param $source
  394. * A string specifying the filepath or URI of the source file.
  395. * @param $destination
  396. * A URI containing the destination that $source should be copied to. The
  397. * URI may be a bare filepath (without a scheme). If this value is omitted,
  398. * Drupal's default files scheme will be used, usually "public://".
  399. * @param $replace
  400. * Replace behavior when the destination file already exists:
  401. * - FILE_EXISTS_REPLACE - Replace the existing file.
  402. * - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
  403. * unique.
  404. * - FILE_EXISTS_ERROR - Do nothing and return FALSE.
  405. *
  406. * @return
  407. * The path to the new file, or FALSE in the event of an error.
  408. *
  409. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  410. * Use \Drupal\Core\File\FileSystemInterface::copy().
  411. *
  412. * @see file_copy()
  413. * @see https://www.drupal.org/node/3006851
  414. */
  415. function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
  416. @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);
  417. try {
  418. $file_system = \Drupal::service('file_system');
  419. // Build a destination URI if necessary.
  420. if (!isset($destination)) {
  421. $destination = file_build_uri($file_system->basename($source));
  422. }
  423. return $file_system->copy($source, $destination, $replace);
  424. }
  425. catch (FileException $e) {
  426. return FALSE;
  427. }
  428. }
  429. /**
  430. * Internal function that prepares the destination for a file_unmanaged_copy or
  431. * file_unmanaged_move operation.
  432. *
  433. * - Checks if $source and $destination are valid and readable/writable.
  434. * - Checks that $source is not equal to $destination; if they are an error
  435. * is reported.
  436. * - If file already exists in $destination either the call will error out,
  437. * replace the file or rename the file based on the $replace parameter.
  438. *
  439. * @param $source
  440. * A string specifying the filepath or URI of the source file.
  441. * @param $destination
  442. * A URI containing the destination that $source should be moved/copied to.
  443. * The URI may be a bare filepath (without a scheme) and in that case the
  444. * default scheme (file://) will be used. If this value is omitted, Drupal's
  445. * default files scheme will be used, usually "public://".
  446. * @param $replace
  447. * Replace behavior when the destination file already exists:
  448. * - FILE_EXISTS_REPLACE - Replace the existing file.
  449. * - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
  450. * unique.
  451. * - FILE_EXISTS_ERROR - Do nothing and return FALSE.
  452. *
  453. * @return
  454. * TRUE, or FALSE in the event of an error.
  455. *
  456. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  457. * Use \Drupal\Core\File\FileSystemInterface::getDestinationFilename() instead.
  458. *
  459. * @see file_unmanaged_copy()
  460. * @see file_unmanaged_move()
  461. * @see https://www.drupal.org/node/3006851
  462. */
  463. function file_unmanaged_prepare($source, &$destination = NULL, $replace = FILE_EXISTS_RENAME) {
  464. @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);
  465. $original_source = $source;
  466. $logger = \Drupal::logger('file');
  467. /** @var \Drupal\Core\File\FileSystemInterface $file_system */
  468. $file_system = \Drupal::service('file_system');
  469. // Assert that the source file actually exists.
  470. if (!file_exists($source)) {
  471. // @todo Replace \Drupal::messenger()->addError() calls with exceptions
  472. // instead.
  473. \Drupal::messenger()->addError(t('The specified file %file could not be moved/copied because no file by that name exists. Please check that you supplied the correct filename.', ['%file' => $original_source]));
  474. if (($realpath = $file_system->realpath($original_source)) !== FALSE) {
  475. $logger->notice('File %file (%realpath) could not be moved/copied because it does not exist.', ['%file' => $original_source, '%realpath' => $realpath]);
  476. }
  477. else {
  478. $logger->notice('File %file could not be moved/copied because it does not exist.', ['%file' => $original_source]);
  479. }
  480. return FALSE;
  481. }
  482. // Build a destination URI if necessary.
  483. if (!isset($destination)) {
  484. $destination = file_build_uri($file_system->basename($source));
  485. }
  486. // Prepare the destination directory.
  487. if (file_prepare_directory($destination)) {
  488. // The destination is already a directory, so append the source basename.
  489. $destination = file_stream_wrapper_uri_normalize($destination . '/' . $file_system->basename($source));
  490. }
  491. else {
  492. // Perhaps $destination is a dir/file?
  493. $dirname = $file_system->dirname($destination);
  494. if (!file_prepare_directory($dirname)) {
  495. // The destination is not valid.
  496. $logger->notice('File %file could not be moved/copied because the destination directory %destination is not configured correctly.', ['%file' => $original_source, '%destination' => $dirname]);
  497. \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]));
  498. return FALSE;
  499. }
  500. }
  501. // Determine whether we can perform this operation based on overwrite rules.
  502. $destination = file_destination($destination, $replace);
  503. if ($destination === FALSE) {
  504. \Drupal::messenger()->addError(t('The file %file could not be moved/copied because a file by that name already exists in the destination directory.', ['%file' => $original_source]));
  505. $logger->notice('File %file could not be moved/copied because a file by that name already exists in the destination directory (%destination)', ['%file' => $original_source, '%destination' => $destination]);
  506. return FALSE;
  507. }
  508. // Assert that the source and destination filenames are not the same.
  509. $real_source = $file_system->realpath($source);
  510. $real_destination = $file_system->realpath($destination);
  511. if ($source == $destination || ($real_source !== FALSE) && ($real_source == $real_destination)) {
  512. \Drupal::messenger()->addError(t('The specified file %file was not moved/copied because it would overwrite itself.', ['%file' => $source]));
  513. $logger->notice('File %file could not be moved/copied because it would overwrite itself.', ['%file' => $source]);
  514. return FALSE;
  515. }
  516. // Make sure the .htaccess files are present.
  517. file_ensure_htaccess();
  518. return TRUE;
  519. }
  520. /**
  521. * Constructs a URI to Drupal's default files location given a relative path.
  522. */
  523. function file_build_uri($path) {
  524. $uri = \Drupal::config('system.file')->get('default_scheme') . '://' . $path;
  525. /** @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager */
  526. $stream_wrapper_manager = \Drupal::service('stream_wrapper_manager');
  527. return $stream_wrapper_manager->normalizeUri($uri);
  528. }
  529. /**
  530. * Determines the destination path for a file.
  531. *
  532. * @param $destination
  533. * A string specifying the desired final URI or filepath.
  534. * @param $replace
  535. * Replace behavior when the destination file already exists.
  536. * - FILE_EXISTS_REPLACE - Replace the existing file.
  537. * - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
  538. * unique.
  539. * - FILE_EXISTS_ERROR - Do nothing and return FALSE.
  540. *
  541. * @return
  542. * The destination filepath, or FALSE if the file already exists
  543. * and FILE_EXISTS_ERROR is specified.
  544. *
  545. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  546. * Use \Drupal\Core\File\FileSystemInterface::getDestinationFilename().
  547. *
  548. * @see https://www.drupal.org/node/3006851
  549. */
  550. function file_destination($destination, $replace) {
  551. @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);
  552. return \Drupal::service('file_system')->getDestinationFilename($destination, $replace);
  553. }
  554. /**
  555. * Moves a file to a new location without database changes or hook invocation.
  556. *
  557. * This is a powerful function that in many ways performs like an advanced
  558. * version of rename().
  559. * - Checks if $source and $destination are valid and readable/writable.
  560. * - Checks that $source is not equal to $destination; if they are an error
  561. * is reported.
  562. * - If file already exists in $destination either the call will error out,
  563. * replace the file or rename the file based on the $replace parameter.
  564. * - Works around a PHP bug where rename() does not properly support streams if
  565. * safe_mode or open_basedir are enabled.
  566. * @see https://bugs.php.net/bug.php?id=60456
  567. *
  568. * @param $source
  569. * A string specifying the filepath or URI of the source file.
  570. * @param $destination
  571. * A URI containing the destination that $source should be moved to. The
  572. * URI may be a bare filepath (without a scheme) and in that case the default
  573. * scheme (file://) will be used. If this value is omitted, Drupal's default
  574. * files scheme will be used, usually "public://".
  575. * @param $replace
  576. * Replace behavior when the destination file already exists:
  577. * - FILE_EXISTS_REPLACE - Replace the existing file.
  578. * - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
  579. * unique.
  580. * - FILE_EXISTS_ERROR - Do nothing and return FALSE.
  581. *
  582. * @return
  583. * The path to the new file, or FALSE in the event of an error.
  584. *
  585. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  586. * Use \Drupal\Core\File\FileSystemInterface::move().
  587. *
  588. * @see file_move()
  589. * @see https://www.drupal.org/node/3006851
  590. */
  591. function file_unmanaged_move($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
  592. @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);
  593. try {
  594. $file_system = \Drupal::service('file_system');
  595. // Build a destination URI if necessary.
  596. if (!isset($destination)) {
  597. $destination = file_build_uri($file_system->basename($source));
  598. }
  599. return $file_system->move($source, $destination, $replace);
  600. }
  601. catch (FileException $e) {
  602. return FALSE;
  603. }
  604. }
  605. /**
  606. * Modifies a filename as needed for security purposes.
  607. *
  608. * Munging a file name prevents unknown file extensions from masking exploit
  609. * files. When web servers such as Apache decide how to process a URL request,
  610. * they use the file extension. If the extension is not recognized, Apache
  611. * skips that extension and uses the previous file extension. For example, if
  612. * the file being requested is exploit.php.pps, and Apache does not recognize
  613. * the '.pps' extension, it treats the file as PHP and executes it. To make
  614. * this file name safe for Apache and prevent it from executing as PHP, the
  615. * .php extension is "munged" into .php_, making the safe file name
  616. * exploit.php_.pps.
  617. *
  618. * Specifically, this function adds an underscore to all extensions that are
  619. * between 2 and 5 characters in length, internal to the file name, and not
  620. * included in $extensions.
  621. *
  622. * Function behavior is also controlled by the configuration
  623. * 'system.file:allow_insecure_uploads'. If it evaluates to TRUE, no alterations
  624. * will be made, if it evaluates to FALSE, the filename is 'munged'. *
  625. * @param $filename
  626. * File name to modify.
  627. * @param $extensions
  628. * A space-separated list of extensions that should not be altered.
  629. * @param $alerts
  630. * If TRUE, \Drupal::messenger()->addStatus() will be called to display
  631. * a message if the file name was changed.
  632. *
  633. * @return string
  634. * The potentially modified $filename.
  635. */
  636. function file_munge_filename($filename, $extensions, $alerts = TRUE) {
  637. $original = $filename;
  638. // Allow potentially insecure uploads for very savvy users and admin
  639. if (!\Drupal::config('system.file')->get('allow_insecure_uploads')) {
  640. // Remove any null bytes. See
  641. // http://php.net/manual/security.filesystem.nullbytes.php
  642. $filename = str_replace(chr(0), '', $filename);
  643. $whitelist = array_unique(explode(' ', strtolower(trim($extensions))));
  644. // Split the filename up by periods. The first part becomes the basename
  645. // the last part the final extension.
  646. $filename_parts = explode('.', $filename);
  647. // Remove file basename.
  648. $new_filename = array_shift($filename_parts);
  649. // Remove final extension.
  650. $final_extension = array_pop($filename_parts);
  651. // Loop through the middle parts of the name and add an underscore to the
  652. // end of each section that could be a file extension but isn't in the list
  653. // of allowed extensions.
  654. foreach ($filename_parts as $filename_part) {
  655. $new_filename .= '.' . $filename_part;
  656. if (!in_array(strtolower($filename_part), $whitelist) && preg_match("/^[a-zA-Z]{2,5}\d?$/", $filename_part)) {
  657. $new_filename .= '_';
  658. }
  659. }
  660. $filename = $new_filename . '.' . $final_extension;
  661. if ($alerts && $original != $filename) {
  662. \Drupal::messenger()->addStatus(t('For security reasons, your upload has been renamed to %filename.', ['%filename' => $filename]));
  663. }
  664. }
  665. return $filename;
  666. }
  667. /**
  668. * Undoes the effect of file_munge_filename().
  669. *
  670. * @param $filename
  671. * String with the filename to be unmunged.
  672. *
  673. * @return
  674. * An unmunged filename string.
  675. */
  676. function file_unmunge_filename($filename) {
  677. return str_replace('_.', '.', $filename);
  678. }
  679. /**
  680. * Creates a full file path from a directory and filename.
  681. *
  682. * If a file with the specified name already exists, an alternative will be
  683. * used.
  684. *
  685. * @param $basename
  686. * String filename
  687. * @param $directory
  688. * String containing the directory or parent URI.
  689. *
  690. * @return
  691. * File path consisting of $directory and a unique filename based off
  692. * of $basename.
  693. *
  694. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  695. * Use \Drupal\Core\File\FileSystemInterface::createFilename().
  696. *
  697. * @see https://www.drupal.org/node/3006851
  698. */
  699. function file_create_filename($basename, $directory) {
  700. @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);
  701. return \Drupal::service('file_system')->createFilename($basename, $directory);
  702. }
  703. /**
  704. * Deletes a file and its database record.
  705. *
  706. * Instead of directly deleting a file, it is strongly recommended to delete
  707. * file usages instead. That will automatically mark the file as temporary and
  708. * remove it during cleanup.
  709. *
  710. * @param $fid
  711. * The file id.
  712. *
  713. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  714. * Use \Drupal\Core\Entity\EntityStorageInterface::delete() instead.
  715. *
  716. * @see file_unmanaged_delete()
  717. * @see \Drupal\file\FileUsage\FileUsageBase::delete()
  718. * @see \Drupal\Core\Entity\EntityStorageInterface::delete()
  719. * @see https://www.drupal.org/node/3021663
  720. */
  721. function file_delete($fid) {
  722. @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);
  723. return file_delete_multiple([$fid]);
  724. }
  725. /**
  726. * Deletes files.
  727. *
  728. * Instead of directly deleting a file, it is strongly recommended to delete
  729. * file usages instead. That will automatically mark the file as temporary and
  730. * remove it during cleanup.
  731. *
  732. * @param $fids
  733. * An array of file ids.
  734. *
  735. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  736. * Use \Drupal\Core\Entity\EntityStorageInterface::delete() instead.
  737. *
  738. * @see file_unmanaged_delete()
  739. * @see \Drupal\file\FileUsage\FileUsageBase::delete()
  740. * @see \Drupal\Core\Entity\EntityStorageInterface::delete()
  741. * @see https://www.drupal.org/node/3021663
  742. */
  743. function file_delete_multiple(array $fids) {
  744. @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);
  745. $storage = \Drupal::entityTypeManager()->getStorage('file');
  746. $entities = $storage->loadMultiple($fids);
  747. $storage->delete($entities);
  748. }
  749. /**
  750. * Deletes a file without database changes or hook invocations.
  751. *
  752. * This function should be used when the file to be deleted does not have an
  753. * entry recorded in the files table.
  754. *
  755. * @param $path
  756. * A string containing a file path or (streamwrapper) URI.
  757. *
  758. * @return
  759. * TRUE for success or path does not exist, or FALSE in the event of an
  760. * error.
  761. *
  762. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  763. * Use \Drupal\Core\File\FileSystemInterface::delete().
  764. *
  765. * @see file_delete()
  766. * @see file_unmanaged_delete_recursive()
  767. * @see https://www.drupal.org/node/3006851
  768. */
  769. function file_unmanaged_delete($path) {
  770. @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);
  771. try {
  772. return \Drupal::service('file_system')->delete($path);
  773. }
  774. catch (FileException $e) {
  775. return FALSE;
  776. }
  777. }
  778. /**
  779. * Deletes all files and directories in the specified filepath recursively.
  780. *
  781. * If the specified path is a directory then the function will call itself
  782. * recursively to process the contents. Once the contents have been removed the
  783. * directory will also be removed.
  784. *
  785. * If the specified path is a file then it will be passed to
  786. * file_unmanaged_delete().
  787. *
  788. * Note that this only deletes visible files with write permission.
  789. *
  790. * @param $path
  791. * A string containing either an URI or a file or directory path.
  792. * @param callable $callback
  793. * (optional) Callback function to run on each file prior to deleting it and
  794. * on each directory prior to traversing it. For example, can be used to
  795. * modify permissions.
  796. *
  797. * @return
  798. * TRUE for success or if path does not exist, FALSE in the event of an
  799. * error.
  800. *
  801. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  802. * Use \Drupal\Core\File\FileSystemInterface::deleteRecursive().
  803. *
  804. * @see file_unmanaged_delete()
  805. * @see https://www.drupal.org/node/3006851
  806. */
  807. function file_unmanaged_delete_recursive($path, $callback = NULL) {
  808. @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);
  809. $callback = is_callable($callback) ? $callback : NULL;
  810. try {
  811. return \Drupal::service('file_system')->deleteRecursive($path, $callback);
  812. }
  813. catch (FileException $e) {
  814. return FALSE;
  815. }
  816. }
  817. /**
  818. * Moves an uploaded file to a new location.
  819. *
  820. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  821. * Use \Drupal\Core\File\FileSystem::moveUploadedFile().
  822. *
  823. * @see https://www.drupal.org/node/2418133
  824. */
  825. function drupal_move_uploaded_file($filename, $uri) {
  826. @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);
  827. return \Drupal::service('file_system')->moveUploadedFile($filename, $uri);
  828. }
  829. /**
  830. * Saves a file to the specified destination without invoking file API.
  831. *
  832. * This function is identical to file_save_data() except the file will not be
  833. * saved to the {file_managed} table and none of the file_* hooks will be
  834. * called.
  835. *
  836. * @param $data
  837. * A string containing the contents of the file.
  838. * @param $destination
  839. * A string containing the destination location. This must be a stream wrapper
  840. * URI. If no value is provided, a randomized name will be generated and the
  841. * file will be saved using Drupal's default files scheme, usually
  842. * "public://".
  843. * @param $replace
  844. * Replace behavior when the destination file already exists:
  845. * - FILE_EXISTS_REPLACE - Replace the existing file.
  846. * - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
  847. * unique.
  848. * - FILE_EXISTS_ERROR - Do nothing and return FALSE.
  849. *
  850. * @return
  851. * A string with the path of the resulting file, or FALSE on error.
  852. *
  853. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  854. * Use \Drupal\Core\File\FileSystemInterface::saveData().
  855. *
  856. * @see file_save_data()
  857. * @see https://www.drupal.org/node/3006851
  858. */
  859. function file_unmanaged_save_data($data, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
  860. @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);
  861. try {
  862. // Build a destination URI if necessary.
  863. if (!isset($destination)) {
  864. $destination = file_default_scheme() . '://';
  865. }
  866. return \Drupal::service('file_system')->saveData($data, $destination, $replace);
  867. }
  868. catch (FileWriteException $e) {
  869. \Drupal::messenger()->addError(t('The file could not be created.'));
  870. return FALSE;
  871. }
  872. catch (FileException $e) {
  873. return FALSE;
  874. }
  875. }
  876. /**
  877. * Finds all files that match a given mask in a given directory.
  878. *
  879. * Directories and files beginning with a dot are excluded; this prevents
  880. * hidden files and directories (such as SVN working directories) from being
  881. * scanned. Use the umask option to skip configuration directories to
  882. * eliminate the possibility of accidentally exposing configuration
  883. * information. Also, you can use the base directory, recurse, and min_depth
  884. * options to improve performance by limiting how much of the filesystem has
  885. * to be traversed.
  886. *
  887. * @param $dir
  888. * The base directory or URI to scan, without trailing slash.
  889. * @param $mask
  890. * The preg_match() regular expression for files to be included.
  891. * @param $options
  892. * An associative array of additional options, with the following elements:
  893. * - 'nomask': The preg_match() regular expression for files to be excluded.
  894. * Defaults to the 'file_scan_ignore_directories' setting.
  895. * - 'callback': The callback function to call for each match. There is no
  896. * default callback.
  897. * - 'recurse': When TRUE, the directory scan will recurse the entire tree
  898. * starting at the provided directory. Defaults to TRUE.
  899. * - 'key': The key to be used for the returned associative array of files.
  900. * Possible values are 'uri', for the file's URI; 'filename', for the
  901. * basename of the file; and 'name' for the name of the file without the
  902. * extension. Defaults to 'uri'.
  903. * - 'min_depth': Minimum depth of directories to return files from. Defaults
  904. * to 0.
  905. * @param $depth
  906. * The current depth of recursion. This parameter is only used internally and
  907. * should not be passed in.
  908. *
  909. * @return
  910. * An associative array (keyed on the chosen key) of objects with 'uri',
  911. * 'filename', and 'name' properties corresponding to the matched files.
  912. *
  913. * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0.
  914. * Use \Drupal\Core\File\FileSystemInterface::scanDirectory() instead.
  915. *
  916. * @see https://www.drupal.org/node/3038437
  917. */
  918. function file_scan_directory($dir, $mask, $options = [], $depth = 0) {
  919. @trigger_error('file_scan_directory() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::scanDirectory() instead. See https://www.drupal.org/node/3038437', E_USER_DEPRECATED);
  920. $files = [];
  921. try {
  922. if (is_dir($dir)) {
  923. $files = \Drupal::service('file_system')->scanDirectory($dir, $mask, $options);
  924. }
  925. }
  926. catch (FileException $e) {
  927. // Ignore and return empty array for BC.
  928. }
  929. return $files;
  930. }
  931. /**
  932. * Determines the maximum file upload size by querying the PHP settings.
  933. *
  934. * @return
  935. * A file size limit in bytes based on the PHP upload_max_filesize and
  936. * post_max_size
  937. *
  938. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  939. * Use \Drupal\Component\Utility\Environment::getUploadMaxSize() instead.
  940. */
  941. function file_upload_max_size() {
  942. @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);
  943. return Environment::getUploadMaxSize();
  944. }
  945. /**
  946. * Sets the permissions on a file or directory.
  947. *
  948. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  949. * Use \Drupal\Core\File\FileSystem::chmod().
  950. *
  951. * @see https://www.drupal.org/node/2418133
  952. */
  953. function drupal_chmod($uri, $mode = NULL) {
  954. @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);
  955. return \Drupal::service('file_system')->chmod($uri, $mode);
  956. }
  957. /**
  958. * Deletes a file.
  959. *
  960. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  961. * Use \Drupal\Core\File\FileSystem::unlink().
  962. *
  963. * @see \Drupal\Core\File\FileSystem::unlink()
  964. * @see https://www.drupal.org/node/2418133
  965. */
  966. function drupal_unlink($uri, $context = NULL) {
  967. @trigger_error('drupal_unlink() is deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::unlink(). See https://www.drupal.org/node/2418133.', E_USER_DEPRECATED);
  968. return \Drupal::service('file_system')->unlink($uri, $context);
  969. }
  970. /**
  971. * Resolves the absolute filepath of a local URI or filepath.
  972. *
  973. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  974. * Use \Drupal\Core\File\FileSystem::realpath().
  975. *
  976. * @see https://www.drupal.org/node/2418133
  977. */
  978. function drupal_realpath($uri) {
  979. @trigger_error('drupal_realpath() is deprecated in drupal:8.0.0 and will be removed in drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::realpath(). See https://www.drupal.org/node/2418133.', E_USER_DEPRECATED);
  980. return \Drupal::service('file_system')->realpath($uri);
  981. }
  982. /**
  983. * Gets the name of the directory from a given path.
  984. *
  985. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  986. * Use \Drupal\Core\File\FileSystem::dirname().
  987. *
  988. * @see https://www.drupal.org/node/2418133
  989. */
  990. function drupal_dirname($uri) {
  991. @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);
  992. return \Drupal::service('file_system')->dirname($uri);
  993. }
  994. /**
  995. * Gets the filename from a given path.
  996. *
  997. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  998. * Use \Drupal\Core\File\FileSystem::basename().
  999. *
  1000. * @see https://www.drupal.org/node/2418133
  1001. */
  1002. function drupal_basename($uri, $suffix = NULL) {
  1003. @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);
  1004. return \Drupal::service('file_system')->basename($uri, $suffix);
  1005. }
  1006. /**
  1007. * Creates a directory, optionally creating missing components in the path to
  1008. * the directory.
  1009. *
  1010. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  1011. * Use \Drupal\Core\File\FileSystem::mkdir().
  1012. *
  1013. * @see https://www.drupal.org/node/2418133
  1014. */
  1015. function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
  1016. @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);
  1017. return \Drupal::service('file_system')->mkdir($uri, $mode, $recursive, $context);
  1018. }
  1019. /**
  1020. * Removes a directory.
  1021. *
  1022. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  1023. * Use \Drupal\Core\File\FileSystem::rmdir().
  1024. *
  1025. * @see https://www.drupal.org/node/2418133
  1026. */
  1027. function drupal_rmdir($uri, $context = NULL) {
  1028. @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);
  1029. return \Drupal::service('file_system')->rmdir($uri, $context);
  1030. }
  1031. /**
  1032. * Creates a file with a unique filename in the specified directory.
  1033. *
  1034. * @deprecated in drupal:8.0.0 and is removed from drupal:9.0.0.
  1035. * Use \Drupal\Core\File\FileSystem::tempnam().
  1036. *
  1037. * @see https://www.drupal.org/node/2418133
  1038. */
  1039. function drupal_tempnam($directory, $prefix) {
  1040. @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);
  1041. return \Drupal::service('file_system')->tempnam($directory, $prefix);
  1042. }
  1043. /**
  1044. * Gets and sets the path of the configured temporary directory.
  1045. *
  1046. * @return mixed|null
  1047. * A string containing the path to the temporary directory.
  1048. *
  1049. * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
  1050. * \Drupal\Core\File\FileSystemInterface::getTempDirectory() instead.
  1051. *
  1052. * @see \Drupal\Core\File\FileSystemInterface::getTempDirectory()
  1053. * @see https://www.drupal.org/node/3039255
  1054. */
  1055. function file_directory_temp() {
  1056. @trigger_error('file_directory_temp() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::getTempDirectory() instead. See https://www.drupal.org/node/3039255', E_USER_DEPRECATED);
  1057. return \Drupal::service('file_system')->getTempDirectory();
  1058. }
  1059. /**
  1060. * Discovers a writable system-appropriate temporary directory.
  1061. *
  1062. * @return mixed
  1063. * A string containing the path to the temporary directory.
  1064. *
  1065. * @deprecated in drupal:8.3.0 and is removed from drupal:9.0.0.
  1066. * Use \Drupal\Component\FileSystem\FileSystem::getOsTemporaryDirectory().
  1067. *
  1068. * @see https://www.drupal.org/node/2418133
  1069. */
  1070. function file_directory_os_temp() {
  1071. @trigger_error('file_directory_os_temp() is deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\Component\FileSystem\FileSystem::getOsTemporaryDirectory() instead. See https://www.drupal.org/node/2418133', E_USER_DEPRECATED);
  1072. return ComponentFileSystem::getOsTemporaryDirectory();
  1073. }
  1074. /**
  1075. * @} End of "defgroup file".
  1076. */