Issues (245)

src/controllers/FileController.php (1 issue)

Labels
Severity
1
<?php
2
/**
3
 * SEOmatic plugin for Craft CMS
4
 *
5
 * A turnkey SEO implementation for Craft CMS that is comprehensive, powerful,
6
 * and flexible
7
 *
8
 * @link      https://nystudio107.com
9
 * @copyright Copyright (c) 2017 nystudio107
10
 */
11
12
namespace nystudio107\seomatic\controllers;
13
14
use Craft;
15
use craft\helpers\FileHelper;
16
use craft\web\Controller;
17
use nystudio107\seomatic\helpers\UrlHelper;
18
use nystudio107\seomatic\Seomatic;
19
use yii\web\HttpException;
20
use yii\web\NotFoundHttpException;
21
use yii\web\Response;
22
use yii\web\ServerErrorHttpException;
23
24
/**
25
 * @author    nystudio107
26
 * @package   Seomatic
27
 * @since     3.0.0
28
 */
29
class FileController extends Controller
30
{
31
    // Properties
32
    // =========================================================================
33
34
    /**
35
     * @inheritdoc
36
     */
37
    protected array|bool|int $allowAnonymous = [
38
        'seo-file-link',
39
    ];
40
41
    // Public Methods
42
    // =========================================================================
43
44
    /**
45
     * @inheritDoc
46
     */
47
    public function beforeAction($action): bool
48
    {
49
        if (!Seomatic::$settings->enableSeoFileLinkEndpoint) {
50
            $this->allowAnonymous = false;
51
        }
52
53
        return parent::beforeAction($action);
54
    }
55
56
    /**
57
     * Allow setting the X-Robots-Tag and Link headers on static files as per:
58
     * https://moz.com/blog/how-to-advanced-relcanonical-http-headers
59
     *
60
     * @param        $url
61
     * @param string $robots
62
     * @param string $canonical
63
     * @param bool $inline
64
     * @param string $fileName
65
     *
66
     * @return Response|\yii\console\Response
67
     * @throws HttpException
68
     * @throws NotFoundHttpException
69
     */
70
    public function actionSeoFileLink($url, $robots = '', $canonical = '', $inline = true, $fileName = '')
71
    {
72
        $url = base64_decode($url);
73
        $robots = base64_decode($robots);
74
        $canonical = base64_decode($canonical);
75
        $url = UrlHelper::absoluteUrlWithProtocol($url);
76
        $contents = file_get_contents($url);
77
        $response = Craft::$app->getResponse();
78
        if ($contents) {
79
            // Add the X-Robots-Tag header
80
            if (!empty($robots)) {
81
                $headerValue = $robots;
82
                $response->headers->add('X-Robots-Tag', $headerValue);
83
            }
84
            // Add the Link header
85
            if (!empty($canonical)) {
86
                $headerValue = '<' . $canonical . '>; rel="canonical"';
87
                $response->headers->add('Link', $headerValue);
88
            }
89
            // Ensure the file type is allowed
90
            // ref: https://craftcms.com/docs/3.x/config/config-settings.html#allowedfileextensions
91
            $allowedExtensions = Craft::$app->getConfig()->getGeneral()->allowedFileExtensions;
92
            if (($ext = pathinfo($fileName, PATHINFO_EXTENSION)) !== '') {
93
                $ext = strtolower($ext);
0 ignored issues
show
It seems like $ext can also be of type array; however, parameter $string of strtolower() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

93
                $ext = strtolower(/** @scrutinizer ignore-type */ $ext);
Loading history...
94
            }
95
            if ($ext === '' || $ext === 'svg' || !in_array($ext, $allowedExtensions, true)) {
96
                throw new ServerErrorHttpException(Craft::t('seomatic', 'File format not allowed.'));
97
            }
98
            // Send the file as a stream, so it can exist anywhere
99
            $response->sendContentAsFile(
100
                $contents,
101
                $fileName,
102
                [
103
                    'inline' => $inline,
104
                    'mimeType' => FileHelper::getMimeTypeByExtension($fileName),
105
                ]
106
            );
107
        } else {
108
            throw new NotFoundHttpException(Craft::t('seomatic', 'File not found.'));
109
        }
110
111
        return $response;
112
    }
113
}
114