PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/phpBB/phpbb/mimetype/guesser.php

http://github.com/phpbb/phpbb
PHP | 156 lines | 68 code | 19 blank | 69 comment | 11 complexity | a2438c951ae43f0b5709b949d6a16a4a MD5 | raw file
Possible License(s): GPL-3.0, AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * This file is part of the phpBB Forum Software package.
  5. *
  6. * @copyright (c) phpBB Limited <https://www.phpbb.com>
  7. * @license GNU General Public License, version 2 (GPL-2.0)
  8. *
  9. * For full copyright and license information, please see
  10. * the docs/CREDITS.txt file.
  11. *
  12. */
  13. namespace phpbb\mimetype;
  14. class guesser
  15. {
  16. /**
  17. * @const Default priority for mimetype guessers
  18. */
  19. const PRIORITY_DEFAULT = 0;
  20. /**
  21. * @var array guessers
  22. */
  23. protected $guessers;
  24. /**
  25. * Construct a mimetype guesser object
  26. *
  27. * @param array $mimetype_guessers Mimetype guesser service collection
  28. */
  29. public function __construct($mimetype_guessers)
  30. {
  31. $this->register_guessers($mimetype_guessers);
  32. }
  33. /**
  34. * Register MimeTypeGuessers and sort them by priority
  35. *
  36. * @param array $mimetype_guessers Mimetype guesser service collection
  37. *
  38. * @throws \LogicException If incorrect or not mimetype guessers have
  39. * been supplied to class
  40. */
  41. protected function register_guessers($mimetype_guessers)
  42. {
  43. foreach ($mimetype_guessers as $guesser)
  44. {
  45. $is_supported = (method_exists($guesser, 'is_supported')) ? 'is_supported' : '';
  46. $is_supported = (method_exists($guesser, 'isSupported')) ? 'isSupported' : $is_supported;
  47. if (empty($is_supported))
  48. {
  49. throw new \LogicException('Incorrect mimetype guesser supplied.');
  50. }
  51. if ($guesser->$is_supported())
  52. {
  53. $this->guessers[] = $guesser;
  54. }
  55. }
  56. if (empty($this->guessers))
  57. {
  58. throw new \LogicException('No mimetype guesser supplied.');
  59. }
  60. // Sort guessers by priority
  61. usort($this->guessers, array($this, 'sort_priority'));
  62. }
  63. /**
  64. * Sort the priority of supplied guessers
  65. * This is a compare function for usort. A guesser with higher priority
  66. * should be used first and vice versa. usort() orders the array values
  67. * from low to high depending on what the comparison function returns
  68. * to it. Return value should be smaller than 0 if value a is smaller
  69. * than value b. This has been reversed in the comparison function in
  70. * order to sort the guessers from high to low.
  71. * Method has been set to public in order to allow proper testing.
  72. *
  73. * @param object $guesser_a Mimetype guesser a
  74. * @param object $guesser_b Mimetype guesser b
  75. *
  76. * @return int If both guessers have the same priority 0, bigger
  77. * than 0 if first guesser has lower priority, and lower
  78. * than 0 if first guesser has higher priority
  79. */
  80. public function sort_priority($guesser_a, $guesser_b)
  81. {
  82. $priority_a = (int) (method_exists($guesser_a, 'get_priority')) ? $guesser_a->get_priority() : self::PRIORITY_DEFAULT;
  83. $priority_b = (int) (method_exists($guesser_b, 'get_priority')) ? $guesser_b->get_priority() : self::PRIORITY_DEFAULT;
  84. return $priority_b - $priority_a;
  85. }
  86. /**
  87. * Guess mimetype of supplied file
  88. *
  89. * @param string $file Path to file
  90. * @param string $file_name The real file name
  91. *
  92. * @return string Guess for mimetype of file
  93. */
  94. public function guess($file, $file_name = '')
  95. {
  96. if (!is_file($file))
  97. {
  98. return false;
  99. }
  100. if (!is_readable($file))
  101. {
  102. return false;
  103. }
  104. $mimetype = 'application/octet-stream';
  105. foreach ($this->guessers as $guesser)
  106. {
  107. $mimetype_guess = $guesser->guess($file, $file_name);
  108. $mimetype = $this->choose_mime_type($mimetype, $mimetype_guess);
  109. }
  110. // Return any mimetype if we got a result or the fallback value
  111. return $mimetype;
  112. }
  113. /**
  114. * Choose the best mime type based on the current mime type and the guess
  115. * If a guesser returns nulls or application/octet-stream, we will keep
  116. * the current guess. Guesses with a slash inside them will be favored over
  117. * already existing ones. However, any guess that will pass the first check
  118. * will always overwrite the default application/octet-stream.
  119. *
  120. * @param string $mime_type The current mime type
  121. * @param string $guess The current mime type guess
  122. *
  123. * @return string The best mime type based on current mime type and guess
  124. */
  125. public function choose_mime_type($mime_type, $guess)
  126. {
  127. if ($guess === null || $guess == 'application/octet-stream')
  128. {
  129. return $mime_type;
  130. }
  131. if ($mime_type == 'application/octet-stream' || strpos($guess, '/') !== false)
  132. {
  133. $mime_type = $guess;
  134. }
  135. return $mime_type;
  136. }
  137. }