hash_wrapper.module

Tracking 7.x-1.x branch
  1. drupal
    1. 7 contributions/hash_wrapper/hash_wrapper.module

Classes

NameDescription
HashStreamWrapper

Functions & methods

NameDescription
hash_wrapper_stream_wrappersImplements hook_stream_wrappers().

File

View source
  1. <?php
  2. /**
  3. * Implements hook_stream_wrappers().
  4. */
  5. function hash_wrapper_stream_wrappers() {
  6. return array(
  7. 'hash' => array(
  8. 'name' => t('Hashed files'),
  9. 'class' => 'HashStreamWrapper',
  10. 'description' => t('Hashed local files served by the webserver.'),
  11. 'type' => STREAM_WRAPPERS_LOCAL_NORMAL,
  12. ),
  13. );
  14. }
  15. class HashStreamWrapper extends DrupalPublicStreamWrapper {
  16. /**
  17. * Return the local filesystem path.
  18. *
  19. * Minimally modified DrupalPublicStreamWrapper::getLocalPath to call
  20. * $this->uriTarget() instead of file_uri_target().
  21. *
  22. * @param $uri
  23. * Optional URI, supplied when doing a move or rename.
  24. */
  25. protected function getLocalPath($uri = NULL) {
  26. if (!isset($uri)) {
  27. $uri = $this->uri;
  28. }
  29. $basedir = $this->getDirectoryPath();
  30. $path = $basedir . '/' . $this->uriTarget($uri, $basedir);
  31. $realpath = realpath($path);
  32. if (!$realpath) {
  33. // This file does not yet exist.
  34. $realpath = realpath(dirname($path)) . '/' . basename($path);
  35. }
  36. $directory = realpath($basedir);
  37. if (!$realpath || !$directory || strpos($realpath, $directory) !== 0) {
  38. return FALSE;
  39. }
  40. return $realpath;
  41. }
  42. /**
  43. * Overrides getExternalUrl().
  44. *
  45. * Minimally modified DrupalPublicStreamWrapper::getExternalUrl() to call
  46. * $this->uriTarget() instead of file_uri_target().
  47. *
  48. * Return the HTML URI of a public file.
  49. */
  50. function getExternalUrl() {
  51. $basedir = self::getDirectoryPath();
  52. $path = str_replace('\\', '/', self::uriTarget($this->uri, $basedir));
  53. return $GLOBALS['base_url'] . "/$basedir/$path";
  54. }
  55. /**
  56. * Support for mkdir().
  57. *
  58. * Minimall modified DrupalPublicStreamWrapper::mkdir() to call
  59. * $this->uriTarget() instead of file_uri_target().
  60. *
  61. * @param $uri
  62. * A string containing the URI to the directory to create.
  63. * @param $mode
  64. * Permission flags - see mkdir().
  65. * @param $options
  66. * A bit mask of STREAM_REPORT_ERRORS and STREAM_MKDIR_RECURSIVE.
  67. * @return
  68. * TRUE if directory was successfully created.
  69. * @see http://php.net/manual/en/streamwrapper.mkdir.php
  70. */
  71. public function mkdir($uri, $mode, $options) {
  72. $this->uri = $uri;
  73. $recursive = (bool)($options & STREAM_MKDIR_RECURSIVE);
  74. if ($recursive) {
  75. // $this->getLocalPath() fails if $uri has multiple levels of directories
  76. // that do not yet exist.
  77. $basedir = $this->getDirectoryPath();
  78. $localpath = $basedir . '/' . $this->uriTarget($uri, $basedir);
  79. }
  80. else {
  81. $localpath = $this->getLocalPath($uri);
  82. }
  83. if ($options & STREAM_REPORT_ERRORS) {
  84. return mkdir($localpath, $mode, $recursive);
  85. }
  86. else {
  87. return @mkdir($localpath, $mode, $recursive);
  88. }
  89. }
  90. /**
  91. * Returns the target of a URI (e.g. a stream).
  92. *
  93. * @param $uri
  94. * A stream, referenced as "scheme://target".
  95. * @return
  96. * A string containing the target (path), or FALSE if none.
  97. * For example, the URI "public://sample/test.txt" would return
  98. * "sample/test.txt".
  99. */
  100. function uriTarget($uri, $basedir) {
  101. $filepath = file_uri_target($uri);
  102. // If all we got is hash://directory or even just hash:// then we can't
  103. // really continue.
  104. if (!$filepath || strpos($filepath, '.') === FALSE) {
  105. return $filepath;
  106. }
  107. $directory = dirname($filepath);
  108. $dir_parts = explode('/', $directory);
  109. if (count($dir_parts) >= 2 && strlen(array_pop($dir_parts)) == 2 && strlen(array_pop($dir_parts)) == 2) {
  110. return $filepath;
  111. }
  112. $file_parts = explode('.', $filepath);
  113. $count = count($file_parts);
  114. $extension = ($count > 1) ? '.' . array_pop($file_parts) : '';
  115. $basedir .= "/$directory";
  116. // Remove styles/$style/hash path before generating the hash.
  117. $filepath = preg_replace('/styles\/.+\/hash\//', '', $filepath);
  118. $target = md5($filepath) . $extension;
  119. $level1 = "$target[0]$target[1]";
  120. $level2 = "$target[2]$target[3]";
  121. if (!is_dir("$basedir/$level1/$level2")) {
  122. drupal_mkdir("$basedir/$level1/$level2", NULL, TRUE);
  123. }
  124. return "$directory/$level1/$level2/$target";
  125. }
  126. }