Passed
Push — v1 ( 58f920...59b7b1 )
by Andrew
15:42 queued 08:34
created

DefaultController::beforeAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
/**
3
 * Transcoder plugin for Craft CMS 3.x
4
 *
5
 * Transcode videos to various formats, and provide thumbnails of the video
6
 *
7
 * @link      https://nystudio107.com
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @copyright tag
Loading history...
8
 * @copyright Copyright (c) 2017 nystudio107
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
9
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
10
11
namespace nystudio107\transcoder\controllers;
12
13
use nystudio107\transcoder\Transcoder;
14
15
use Craft;
16
use craft\errors\AssetDisallowedExtensionException;
17
use craft\helpers\Json as JsonHelper;
18
use craft\helpers\Path as PathHelper;
19
use craft\web\Controller;
20
use yii\web\BadRequestHttpException;
21
22
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
23
 * @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...
Coding Style introduced by
Tag value for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
24
 * @package   Transcode
0 ignored issues
show
Coding Style introduced by
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
25
 * @since     1.0.0
0 ignored issues
show
Coding Style introduced by
The tag in position 3 should be the @author tag
Loading history...
Coding Style introduced by
Tag value for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
26
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
27
class DefaultController extends Controller
28
{
29
30
    // Protected Properties
31
    // =========================================================================
32
33
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
34
     * @var    bool|array Allows anonymous access to this controller's actions.
35
     *         The actions must be in 'kebab-case'
36
     * @access protected
37
     */
38
    protected $allowAnonymous = [
39
        'download-file',
40
        'progress',
41
    ];
42
43
    // Public Methods
44
    // =========================================================================
45
46
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $action should have a doc-comment as per coding-style.
Loading history...
47
     * @inheritDoc
48
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
49
    public function beforeAction($action)
50
    {
51
        if (!Transcoder::$settings->enableDownloadFileEndpoint) {
52
            $this->allowAnonymous = false;
53
        }
54
55
        return parent::beforeAction($action);
56
    }
57
58
    /**
59
     * Force the download of a given $url.  We do it this way to prevent people
60
     * from downloading things that are outside of the server root.
61
     *
62
     * @param $url
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
63
     *
64
     * @throws \yii\base\ExitException
65
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
66
    public function actionDownloadFile($url)
67
    {
68
        $filePath = parse_url($url, PHP_URL_PATH);
69
        // Remove any relative paths
70
        if (!PathHelper::ensurePathIsContained($filePath)) {
71
            throw new BadRequestHttpException('Invalid resource path: ' . $filePath);
72
        }
73
        // Only work for `allowedFileExtensions` file extensions
74
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
75
        $allowedExtensions = Craft::$app->getConfig()->getGeneral()->allowedFileExtensions;
76
        if (!in_array($extension, $allowedExtensions, true)) {
77
            throw new AssetDisallowedExtensionException("File “{$filePath}” cannot be downloaded because “{$extension}” is not allowed.");
78
        }
79
80
        $filePath = $_SERVER['DOCUMENT_ROOT'].$filePath;
81
        Craft::$app->getResponse()->sendFile(
82
            $filePath,
83
            null,
84
            ['inline' => false]
85
        );
86
        Craft::$app->end();
87
    }
88
89
    /**
90
     * Return a JSON-encoded array providing the progress of the transcoding:
91
     *
92
     * 'filename' => the name of the file
93
     * 'duration' => the duration of the video/audio stream
94
     * 'time' => the time of the current encoding
95
     * 'progress' => a percentage indicating how much of the encoding is done
96
     *
97
     * @param $filename
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
98
     *
99
     * @return mixed
100
     */
101
    public function actionProgress($filename)
102
    {
103
        $result = [];
104
        $progressFile = sys_get_temp_dir().DIRECTORY_SEPARATOR.$filename.'.progress';
105
        if (file_exists($progressFile)) {
106
            $content = @file_get_contents($progressFile);
107
            if ($content) {
108
                // get duration of source
109
                preg_match('/Duration: (.*?), start:/', $content, $matches);
110
                if (\count($matches) > 0) {
111
                    $rawDuration = $matches[1];
112
113
                    // rawDuration is in 00:00:00.00 format. This converts it to seconds.
114
                    $ar = array_reverse(explode(':', $rawDuration));
115
                    $duration = (float)$ar[0];
116
                    if (!empty($ar[1])) {
117
                        $duration += (int)$ar[1] * 60;
118
                    }
119
                    if (!empty($ar[2])) {
120
                        $duration += (int)$ar[2] * 60 * 60;
121
                    }
122
                } else {
123
                    $duration = 'unknown'; // with GIF as input, duration is unknown
124
                }
125
126
                // Get the time in the file that is already encoded
127
                preg_match_all('/time=(.*?) bitrate/', $content, $matches);
128
                $rawTime = array_pop($matches);
129
130
                // this is needed if there is more than one match
131
                if (\is_array($rawTime)) {
132
                    $rawTime = array_pop($rawTime);
133
                }
134
135
                //rawTime is in 00:00:00.00 format. This converts it to seconds.
136
                $ar = array_reverse(explode(':', $rawTime));
137
                $time = (float)$ar[0];
138
                if (!empty($ar[1])) {
139
                    $time += (int)$ar[1] * 60;
140
                }
141
                if (!empty($ar[2])) {
142
                    $time += (int)$ar[2] * 60 * 60;
143
                }
144
145
                //calculate the progress
146
                if ($duration !== 'unknown') {
147
                    $progress = round(($time / $duration) * 100);
148
                } else {
149
                    $progress = 'unknown';
150
                }
151
152
                // return results
153
                if ($progress !== 'unknown' && $progress < 100) {
154
                    $result = [
155
                        'filename' => $filename,
156
                        'duration' => $duration,
157
                        'time' => $time,
158
                        'progress' => $progress,
159
                    ];
160
                } elseif ($progress === 'unknown') {
161
                    $result = [
162
                        'filename' => $filename,
163
                        'duration' => 'unknown',
164
                        'time' => $time,
165
                        'progress' => 'unknown',
166
                        'message' => 'encoding GIF, can\'t determine duration',
167
                    ];
168
                }
169
            }
170
        }
171
172
        return JsonHelper::encode($result);
173
    }
174
}
175