Passed
Push — develop ( c078e7...5f2cdc )
by Andrew
10:35
created

FileController   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 32
c 1
b 0
f 0
dl 0
loc 83
ccs 0
cts 43
cp 0
rs 10
wmc 9

2 Methods

Rating   Name   Duplication   Size   Complexity  
A beforeAction() 0 7 2
B actionSeoFileLink() 0 42 7
1
<?php
2
/**
3
 * SEOmatic plugin for Craft CMS 3.x
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 nystudio107\seomatic\helpers\UrlHelper;
15
use nystudio107\seomatic\Seomatic;
16
17
use Craft;
18
use craft\elements\Asset;
19
use craft\helpers\FileHelper;
20
use craft\helpers\Assets as AssetsHelper;
21
use craft\web\Controller;
22
23
use yii\web\NotFoundHttpException;
24
use yii\web\HttpException;
25
use yii\web\Response;
26
use yii\web\ServerErrorHttpException;
27
28
/**
29
 * @author    nystudio107
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
30
 * @package   Seomatic
31
 * @since     3.0.0
32
 */
33
class FileController extends Controller
34
{
35
    // Properties
36
    // =========================================================================
37
38
    /**
39
     * @inheritdoc
40
     */
41
    protected $allowAnonymous = [
42
        'seo-file-link',
43
    ];
44
45
    // Public Methods
46
    // =========================================================================
47
48
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $action should have a doc-comment as per coding-style.
Loading history...
49
     * @inheritDoc
50
     */
51
    public function beforeAction($action)
52
    {
53
        if (!Seomatic::$settings->enableSeoFileLinkEndpoint) {
54
            $this->allowAnonymous = false;
55
        }
56
57
        return parent::beforeAction($action);
58
    }
59
60
    /**
61
     * Allow setting the X-Robots-Tag and Link headers on static files as per:
62
     * https://moz.com/blog/how-to-advanced-relcanonical-http-headers
63
     *
64
     * @param        $url
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
65
     * @param string $robots
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
66
     * @param string $canonical
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
67
     * @param bool   $inline
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
68
     * @param string $fileName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
69
     *
70
     * @return Response|\yii\console\Response
71
     * @throws HttpException
72
     * @throws NotFoundHttpException
73
     */
74
    public function actionSeoFileLink($url, $robots = '', $canonical = '', $inline = true, $fileName = '')
75
    {
76
        $url = base64_decode($url);
77
        $robots = base64_decode($robots);
78
        $canonical = base64_decode($canonical);
79
        $url = UrlHelper::absoluteUrlWithProtocol($url);
80
        $contents = file_get_contents($url);
81
        $response = Craft::$app->getResponse();
82
        if ($contents) {
83
            // Add the X-Robots-Tag header
84
            if (!empty($robots)) {
85
                $headerValue = $robots;
86
                $response->headers->add('X-Robots-Tag', $headerValue);
87
            }
88
            // Add the Link header
89
            if (!empty($canonical)) {
90
                $headerValue = '<'.$canonical.'>; rel="canonical"';
91
                $response->headers->add('Link', $headerValue);
92
            }
93
            // Ensure the file type is allowed
94
            // ref: https://craftcms.com/docs/3.x/config/config-settings.html#allowedfileextensions
95
            $allowedExtensions = Craft::$app->getConfig()->getGeneral()->allowedFileExtensions;
96
            if (($ext = pathinfo($fileName, PATHINFO_EXTENSION)) !== '') {
97
                $ext = strtolower($ext);
0 ignored issues
show
Bug introduced by
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

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