<commit_before><?php
/**
 * @author <NAME> <<EMAIL>>
 * @copyright 2012 <NAME>
 * @see https://www.elabftw.net Official website
 * @license AGPL-3.0
 * @package elabftw
 */
declare(strict_types=1);

namespace Elabftw\Services;

use Elabftw\Elabftw\Tools;
use Elabftw\Exceptions\FilesystemErrorException;
use Elabftw\Exceptions\ImproperActionException;
use Exception;
use function extension_loaded;
use function file_exists;
use function filesize;
use finfo;
use Gmagick;
use Imagick;
use function in_array;
use function is_readable;
use function substr;

/**
 * Create a thumbnail from a file
 */
final class MakeThumbnail
{
    /** @var int BIG_FILE_THRESHOLD size of a file in bytes above which we don't process it (5 Mb) */
    private const BIG_FILE_THRESHOLD = 5000000;

    /** @var int WIDTH the width for the thumbnail */
    private const WIDTH = 100;

    /**
     * Do some sane white-listing. In theory, gmagick handles almost all image formats,
     * but the processing of rarely used formats may be less tested/stable or may have security issues
     * when adding new mime types take care of ambiguities:
     * e.g. image/eps may be a valid application/postscript; image/bmp may also be image/x-bmp or
     * image/x-ms-bmp
     * @var array ALLOWED_MIMES
     */
    private const ALLOWED_MIMES = array(
        'image/png',
        'image/jpeg',
        'image/gif',
        'image/tiff',
        'image/x-eps',
        'image/svg+xml',
        'application/pdf',
        'application/postscript',
    );

    private string $filePath;

    private string $thumbPath;

    private string $mime;

    /**
     * This class has no public method. Just instance it with a filePath and it creates the thumbnail if needed.
     *
     * @param string $filePath the full path to the file
     */
    public function __construct(string $filePath)
    {
        $this->filePath = $filePath;
        // get mime type of the file
        $finfo = new finfo(FILEINFO_MIME_TYPE);
        $mime = $finfo->file($this->filePath);
        if ($mime === false) {
            throw new ImproperActionException('Cannot detect the file type for thumbnail!');
        }
        $this->mime = $mime;
        $this->thumbPath = $this->filePath . '_th.jpg';
    }

    /**
     * Create a jpg thumbnail from images of type jpeg, png, gif, tiff, eps and pdf.
     *
     * @param bool $force force regeneration of thumbnail even if file exist (useful if upload was replaced)
     * @return void
     */
    public function makeThumb($force = false): void
    {
        if (is_readable($this->filePath) === false) {
            throw new FilesystemErrorException('File not found! (' . substr($this->filePath, 0, 42) . '…)');
        }

        // do nothing for big files
        if (filesize($this->filePath) > self::BIG_FILE_THRESHOLD) {
            return;
        }

        // don't bother if the thumbnail exists already
        if (file_exists($this->thumbPath) && $force === false) {
            return;
        }

        // verify mime type
        if (!in_array($this->mime, self::ALLOWED_MIMES, true)) {
            return;
        }

        // if pdf or postscript, generate thumbnail using the first page (index 0) do the same for postscript files
        // sometimes eps images will be identified as application/postscript as well, but thumbnail generation still
        // works in those cases
        if ($this->mime === 'application/pdf' || $this->mime === 'application/postscript') {
            $this->filePath .= '[0]';
        }

        // try with imagick first
        if (extension_loaded('imagick')) {
            $this->useImagick();

        // try with gmagick
        // FIXME at the moment there is a bug with only png files on thumbnail generation, so use GD for png
        } elseif (extension_loaded('gmagick') && Tools::getExt($this->filePath) !== 'png') {<commit_msg>move file check upstream in makethumbnail<commit_after><?php
/**
 * @author <NAME> <<EMAIL>>
 * @copyright 2012 <NAME>
 * @see https://www.elabftw.net Official website
 * @license AGPL-3.0
 * @package elabftw
 */
declare(strict_types=1);

namespace Elabftw\Services;

use Elabftw\Elabftw\Tools;
use Elabftw\Exceptions\FilesystemErrorException;
use Elabftw\Exceptions\ImproperActionException;
use Exception;
use function extension_loaded;
use function file_exists;
use function filesize;
use finfo;
use Gmagick;
use Imagick;
use function in_array;
use function is_readable;
use function substr;

/**
 * Create a thumbnail from a file
 */
final class MakeThumbnail
{
    /** @var int BIG_FILE_THRESHOLD size of a file in bytes above which we don't process it (5 Mb) */
    private const BIG_FILE_THRESHOLD = 5000000;

    /** @var int WIDTH the width for the thumbnail */
    private const WIDTH = 100;

    /**
     * Do some sane white-listing. In theory, gmagick handles almost all image formats,
     * but the processing of rarely used formats may be less tested/stable or may have security issues
     * when adding new mime types take care of ambiguities:
     * e.g. image/eps may be a valid application/postscript; image/bmp may also be image/x-bmp or
     * image/x-ms-bmp
     * @var array ALLOWED_MIMES
     */
    private const ALLOWED_MIMES = array(
        'image/png',
        'image/jpeg',
        'image/gif',
        'image/tiff',
        'image/x-eps',
        'image/svg+xml',
        'application/pdf',
        'application/postscript',
    );

    private string $filePath;

    private string $thumbPath;

    private string $mime;

    public function __construct(string $filePath)
    {
        $this->filePath = $filePath;
        // make sure we can read the file
        if (is_readable($this->filePath) === false) {
            throw new FilesystemErrorException('File not found! (' . substr($this->filePath, 0, 42) . '…)');
        }
        // get mime type of the file
        $finfo = new finfo(FILEINFO_MIME_TYPE);
        $mime = $finfo->file($this->filePath);
        if ($mime === false) {
            throw new ImproperActionException('Cannot detect the file type for thumbnail!');
        }
        $this->mime = $mime;
        $this->thumbPath = $this->filePath . '_th.jpg';
    }

    /**
     * Create a jpg thumbnail from images of type jpeg, png, gif, tiff, eps and pdf.
     *
     * @param bool $force force regeneration of thumbnail even if file exist (useful if upload was replaced)
     */
    public function makeThumb($force = false): void
    {
        // do nothing for big files
        if (filesize($this->filePath) > self::BIG_FILE_THRESHOLD) {
            return;
        }

        // don't bother if the thumbnail exists already
        if (file_exists($this->thumbPath) && $force === false) {
            return;
        }

        // verify mime type
        if (!in_array($this->mime, self::ALLOWED_MIMES, true)) {
            return;
        }

        // if pdf or postscript, generate thumbnail using the first page (index 0) do the same for postscript files
        // sometimes eps images will be identified as application/postscript as well, but thumbnail generation still
        // works in those cases
        if ($this->mime === 'application/pdf' || $this->mime === 'application/postscript') {
            $this->filePath .= '[0]';
        }

        // try with imagick first
        if (extension_loaded('imagick')) {
            $this->useImagick();

        // try with gmagick
        // FIXME at the moment there is a bug with only png files on thumbnail generation, so use GD for png
        } elseif (extension_loaded('gmagick') && Tools::getExt($this->filePath) !== 'png') {
{'fraction_non_alphanumeric': 0.11003659174072138, 'fraction_numerical': 0.0060115002613695765, 'mean_word_length': 2.491332116788321, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 45, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4601960', 'n_tokens_mistral': 2352, 'n_tokens_neox': 2242, 'n_words': 752}