Issues (306)

src/controllers/DefaultController.php (25 issues)

1
<?php
2
/**
3
 * Transcoder plugin for Craft CMS
4
 *
5
 * Transcode videos to various formats, and provide thumbnails of the video
6
 *
7
 * @link      https://nystudio107.com
0 ignored issues
show
The tag in position 1 should be the @copyright tag
Loading history...
8
 * @copyright Copyright (c) 2017 nystudio107
0 ignored issues
show
@copyright tag must contain a year and the name of the copyright holder
Loading history...
9
 */
0 ignored issues
show
PHP version not specified
Loading history...
Missing @category tag in file comment
Loading history...
Missing @package tag in file comment
Loading history...
Missing @author tag in file comment
Loading history...
Missing @license tag in file comment
Loading history...
10
11
namespace nystudio107\transcoder\controllers;
12
13
use Craft;
14
use craft\errors\AssetDisallowedExtensionException;
15
use craft\helpers\Json as JsonHelper;
16
use craft\helpers\Path as PathHelper;
17
use craft\web\Controller;
18
use nystudio107\transcoder\Transcoder;
19
use yii\web\BadRequestHttpException;
20
21
/**
0 ignored issues
show
Missing short description in doc comment
Loading history...
22
 * @author    nystudio107
0 ignored issues
show
The tag in position 1 should be the @package tag
Loading history...
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
Tag value for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
23
 * @package   Transcode
0 ignored issues
show
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
24
 * @since     1.0.0
0 ignored issues
show
The tag in position 3 should be the @author tag
Loading history...
Tag value for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
25
 */
0 ignored issues
show
Missing @category tag in class comment
Loading history...
Missing @license tag in class comment
Loading history...
Missing @link tag in class comment
Loading history...
26
class DefaultController extends Controller
27
{
28
29
    // Protected Properties
30
    // =========================================================================
31
32
    /**
0 ignored issues
show
Missing short description in doc comment
Loading history...
33
     * @var    bool|array Allows anonymous access to this controller's actions.
34
     *         The actions must be in 'kebab-case'
35
     * @access protected
36
     */
37
    protected $allowAnonymous = [
38
        'download-file',
39
        'progress',
40
    ];
41
42
    // Public Methods
43
    // =========================================================================
44
45
    /**
0 ignored issues
show
Missing short description in doc comment
Loading history...
Parameter $action should have a doc-comment as per coding-style.
Loading history...
46
     * @inheritDoc
47
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
48
    public function beforeAction($action)
49
    {
50
        if (!Transcoder::$settings->enableDownloadFileEndpoint) {
51
            $this->allowAnonymous = false;
52
        }
53
54
        return parent::beforeAction($action);
55
    }
56
57
    /**
58
     * Force the download of a given $url.  We do it this way to prevent people
59
     * from downloading things that are outside of the server root.
60
     *
61
     * @param $url
0 ignored issues
show
Missing parameter comment
Loading history...
62
     *
63
     * @throws \yii\base\ExitException
64
     */
0 ignored issues
show
Missing @return tag in function comment
Loading history...
65
    public function actionDownloadFile($url)
66
    {
67
        $filePath = parse_url($url, PHP_URL_PATH);
68
        // Remove any relative paths
69
        if (!PathHelper::ensurePathIsContained($filePath)) {
70
            throw new BadRequestHttpException('Invalid resource path: ' . $filePath);
71
        }
72
        // Only work for `allowedFileExtensions` file extensions
73
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
0 ignored issues
show
It seems like pathinfo($filePath, nyst...ers\PATHINFO_EXTENSION) 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

73
        $extension = strtolower(/** @scrutinizer ignore-type */ pathinfo($filePath, PATHINFO_EXTENSION));
Loading history...
74
        $allowedExtensions = Craft::$app->getConfig()->getGeneral()->allowedFileExtensions;
75
        if (!in_array($extension, $allowedExtensions, true)) {
76
            throw new AssetDisallowedExtensionException("File “{$filePath}” cannot be downloaded because “{$extension}” is not allowed.");
77
        }
78
79
        $filePath = $_SERVER['DOCUMENT_ROOT'] . $filePath;
80
        Craft::$app->getResponse()->sendFile(
81
            $filePath,
82
            null,
83
            ['inline' => false]
84
        );
85
        Craft::$app->end();
86
    }
87
88
    /**
89
     * Return a JSON-encoded array providing the progress of the transcoding:
90
     *
91
     * 'filename' => the name of the file
92
     * 'duration' => the duration of the video/audio stream
93
     * 'time' => the time of the current encoding
94
     * 'progress' => a percentage indicating how much of the encoding is done
95
     *
96
     * @param $filename
0 ignored issues
show
Missing parameter comment
Loading history...
97
     *
98
     * @return mixed
99
     */
100
    public function actionProgress($filename)
101
    {
102
        $result = [];
103
        $progressFile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $filename . '.progress';
104
        if (file_exists($progressFile)) {
105
            $content = @file_get_contents($progressFile);
106
            if ($content) {
107
                // get duration of source
108
                preg_match('/Duration: (.*?), start:/', $content, $matches);
109
                if (\count($matches) > 0) {
110
                    $rawDuration = $matches[1];
111
112
                    // rawDuration is in 00:00:00.00 format. This converts it to seconds.
113
                    $ar = array_reverse(explode(':', $rawDuration));
114
                    $duration = (float)$ar[0];
115
                    if (!empty($ar[1])) {
116
                        $duration += (int)$ar[1] * 60;
117
                    }
118
                    if (!empty($ar[2])) {
119
                        $duration += (int)$ar[2] * 60 * 60;
120
                    }
121
                } else {
122
                    $duration = 'unknown'; // with GIF as input, duration is unknown
123
                }
124
125
                // Get the time in the file that is already encoded
126
                preg_match_all('/time=(.*?) bitrate/', $content, $matches);
127
                $rawTime = array_pop($matches);
128
129
                // this is needed if there is more than one match
130
                if (\is_array($rawTime)) {
131
                    $rawTime = array_pop($rawTime);
132
                }
133
134
                //rawTime is in 00:00:00.00 format. This converts it to seconds.
135
                $ar = array_reverse(explode(':', $rawTime));
136
                $time = (float)$ar[0];
137
                if (!empty($ar[1])) {
138
                    $time += (int)$ar[1] * 60;
139
                }
140
                if (!empty($ar[2])) {
141
                    $time += (int)$ar[2] * 60 * 60;
142
                }
143
144
                //calculate the progress
145
                if ($duration !== 'unknown') {
146
                    $progress = round(($time / $duration) * 100);
147
                } else {
148
                    $progress = 'unknown';
149
                }
150
151
                // return results
152
                if ($progress !== 'unknown' && $progress < 100) {
153
                    $result = [
154
                        'filename' => $filename,
155
                        'duration' => $duration,
156
                        'time' => $time,
157
                        'progress' => $progress,
158
                    ];
159
                } elseif ($progress === 'unknown') {
160
                    $result = [
161
                        'filename' => $filename,
162
                        'duration' => 'unknown',
163
                        'time' => $time,
164
                        'progress' => 'unknown',
165
                        'message' => 'encoding GIF, can\'t determine duration',
166
                    ];
167
                }
168
            }
169
        }
170
171
        return JsonHelper::encode($result);
172
    }
173
}
174