Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
41 / 41
guesser
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
5 / 5
20
100.00% covered (success)
100.00%
41 / 41
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 register_guessers
100.00% covered (success)
100.00%
1 / 1
7
100.00% covered (success)
100.00%
16 / 16
 sort_priority
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
3 / 3
 guess
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
12 / 12
 choose_mime_type
100.00% covered (success)
100.00%
1 / 1
5
100.00% covered (success)
100.00%
8 / 8
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\mimetype;
class guesser
{
    /**
    * @const Default priority for mimetype guessers
    */
    const PRIORITY_DEFAULT = 0;
    /**
    * @var array guessers
    */
    protected $guessers;
    /**
    * Construct a mimetype guesser object
    *
    * @param array $mimetype_guessers Mimetype guesser service collection
    */
    public function __construct($mimetype_guessers)
    {
        $this->register_guessers($mimetype_guessers);
    }
    /**
    * Register MimeTypeGuessers and sort them by priority
    *
    * @param array $mimetype_guessers Mimetype guesser service collection
    *
    * @throws \LogicException If incorrect or not mimetype guessers have
    *            been supplied to class
    */
    protected function register_guessers($mimetype_guessers)
    {
        foreach ($mimetype_guessers as $guesser)
        {
            $is_supported = (method_exists($guesser, 'is_supported')) ? 'is_supported' : '';
            $is_supported = (method_exists($guesser, 'isSupported')) ? 'isSupported' : $is_supported;
            if (empty($is_supported))
            {
                throw new \LogicException('Incorrect mimetype guesser supplied.');
            }
            if ($guesser->$is_supported())
            {
                $this->guessers[] = $guesser;
            }
        }
        if (empty($this->guessers))
        {
            throw new \LogicException('No mimetype guesser supplied.');
        }
        // Sort guessers by priority
        usort($this->guessers, array($this, 'sort_priority'));
    }
    /**
    * Sort the priority of supplied guessers
    * This is a compare function for usort. A guesser with higher priority
    * should be used first and vice versa. usort() orders the array values
    * from low to high depending on what the comparison function returns
    * to it. Return value should be smaller than 0 if value a is smaller
    * than value b. This has been reversed in the comparision function in
    * order to sort the guessers from high to low.
    * Method has been set to public in order to allow proper testing.
    *
    * @param object $guesser_a Mimetype guesser a
    * @param object $guesser_b Mimetype guesser b
    *
    * @return int     If both guessers have the same priority 0, bigger
    *        than 0 if first guesser has lower priority, and lower
    *        than 0 if first guesser has higher priority
    */
    public function sort_priority($guesser_a, $guesser_b)
    {
        $priority_a = (int) (method_exists($guesser_a, 'get_priority')) ? $guesser_a->get_priority() : self::PRIORITY_DEFAULT;
        $priority_b = (int) (method_exists($guesser_b, 'get_priority')) ? $guesser_b->get_priority() : self::PRIORITY_DEFAULT;
        return $priority_b - $priority_a;
    }
    /**
    * Guess mimetype of supplied file
    *
    * @param string $file Path to file
    * @param string $file_name The real file name
    *
    * @return string Guess for mimetype of file
    */
    public function guess($file, $file_name = '')
    {
        if (!is_file($file))
        {
            return false;
        }
        if (!is_readable($file))
        {
            return false;
        }
        $mimetype = 'application/octet-stream';
        foreach ($this->guessers as $guesser)
        {
            $mimetype_guess = $guesser->guess($file, $file_name);
            $mimetype = $this->choose_mime_type($mimetype, $mimetype_guess);
        }
        // Return any mimetype if we got a result or the fallback value
        return $mimetype;
    }
    /**
     * Choose the best mime type based on the current mime type and the guess
     * If a guesser returns nulls or application/octet-stream, we will keep
     * the current guess. Guesses with a slash inside them will be favored over
     * already existing ones. However, any guess that will pass the first check
     * will always overwrite the default application/octet-stream.
     *
     * @param    string    $mime_type    The current mime type
     * @param    string    $guess        The current mime type guess
     *
     * @return string The best mime type based on current mime type and guess
     */
    public function choose_mime_type($mime_type, $guess)
    {
        if ($guess === null || $guess == 'application/octet-stream')
        {
            return $mime_type;
        }
        if ($mime_type == 'application/octet-stream' || strpos($guess, '/') !== false)
        {
            $mime_type = $guess;
        }
        return $mime_type;
    }
}