Completed
Push — master ( 6e202e...693518 )
by Evgenii
02:47
created

ConsoleController::getVideoWidth()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 2
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: floor12
5
 * Date: 27.06.2016
6
 * Time: 8:32
7
 */
8
9
namespace floor12\files\controllers;
10
11
12
use floor12\files\models\File;
13
use floor12\files\models\FileType;
14
use floor12\files\models\VideoStatus;
15
use Throwable;
16
use Yii;
17
use yii\console\Controller;
18
use yii\db\ActiveRecord;
19
use yii\db\StaleObjectException;
20
use yii\helpers\Console;
21
22
class ConsoleController extends Controller
23
{
24
25
    /**
26
     * Run `./yii files/console/clean` to remove all unlinked files more then 6 hours
27
     *
28
     * @throws Throwable
29
     * @throws StaleObjectException
30
     */
31
    function actionClean()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
32
    {
33
        $time = strtotime('- 6 hours');
34
        $files = File::find()->where(['object_id' => '0'])->andWhere(['<', 'created', $time])->all();
35
        if ($files) foreach ($files as $file) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $files of type yii\db\ActiveRecordInterface[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
36
            $file->delete();
37
        }
38
    }
39
40
    /**
41
     * Run `./yii files/console/clean-cache` to remove all generated images and previews
42
     */
43
    function actionCleanCache()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
44
    {
45
        $module = Yii::$app->getModule('files');
46
        $commands = [];
47
        $commands[] = "find {$module->storageFullPath}  -regextype egrep -regex \".+/.{32}_.*\"  -exec rm -rf {} \;";
48
        $commands[] = "find {$module->cacheFullPath}  -regextype egrep -regex \".+/.{32}_.*\" -exec rm -rf {} \;";
49
        $commands[] = "find {$module->storageFullPath}  -regextype egrep -regex \".+/.{32}\..{3,4}\.jpg\" -exec rm -rf {} \;";
50
        $commands[] = "find {$module->cacheFullPath}  -regextype egrep -regex \".+/.{32}\..{3,4}\.jpg\" -exec rm -rf {} \;";
51
52
        array_map(function ($command) {
53
            exec($command);
54
        }, $commands);
55
56
    }
57
58
    /**
59
     * Run `./yii files/console/convert` to proccess one video file from queue with ffmpeg
60
     * @return bool|int
61
     */
62
    function actionConvert()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
63
    {
64
        $ffmpeg = Yii::$app->getModule('files')->ffmpeg;
65
66
        if (!file_exists($ffmpeg))
0 ignored issues
show
Bug introduced by
It seems like $ffmpeg can also be of type object; however, parameter $filename of file_exists() 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

66
        if (!file_exists(/** @scrutinizer ignore-type */ $ffmpeg))
Loading history...
67
            return $this->stdout("ffmpeg is not found: {$ffmpeg}" . PHP_EOL, Console::FG_RED);
68
69
        if (!is_executable($ffmpeg))
0 ignored issues
show
Bug introduced by
It seems like $ffmpeg can also be of type object; however, parameter $filename of is_executable() 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

69
        if (!is_executable(/** @scrutinizer ignore-type */ $ffmpeg))
Loading history...
70
            return $this->stdout("ffmpeg is not executable: {$ffmpeg}" . PHP_EOL, Console::FG_RED);
71
72
        $file = File::find()
73
            ->where(['type' => FileType::VIDEO, 'video_status' => VideoStatus::QUEUE])
74
            ->andWhere(['!=', 'object_id', 0])
75
            ->one();
76
77
        if (!$file)
78
            return $this->stdout("Convert queue is empty" . PHP_EOL, Console::FG_GREEN);
79
80
        if (!file_exists($file->rootPath))
81
            return $this->stdout("Source file is not found: {$file->rootPath}" . PHP_EOL, Console::FG_RED);
82
83
84
        $file->video_status = VideoStatus::CONVERTING;
85
        $file->save();
86
        $width = $this->getVideoWidth($file->class, $file->field);
87
        $height = $this->getVideoHeight($file->class, $file->field);
88
        $newFileName = $file->filename . ".mp4";
89
        $newFilePath = $file->rootPath . ".mp4";
90
        $command = Yii::$app->getModule('files')->ffmpeg . " -i {$file->rootPath} -vf scale={$width}:{$height} -threads 4 {$newFilePath}";
0 ignored issues
show
Bug introduced by
Are you sure Yii::app->getModule('files')->ffmpeg of type mixed|null|object can be used in concatenation? ( Ignorable by Annotation )

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

90
        $command = /** @scrutinizer ignore-type */ Yii::$app->getModule('files')->ffmpeg . " -i {$file->rootPath} -vf scale={$width}:{$height} -threads 4 {$newFilePath}";
Loading history...
91
        echo $command . PHP_EOL;
92
        exec($command,
93
            $outout, $result);
94
        if ($result == 0) {
95
            @unlink($file->rootPath);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

95
            /** @scrutinizer ignore-unhandled */ @unlink($file->rootPath);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
96
            $file->filename = $newFileName;
97
            $file->video_status = VideoStatus::READY;
98
        } else {
99
            $file->video_status = VideoStatus::QUEUE;
100
        }
101
        $file->save();
102
103
        return $this->stdout("File converted: {$file->rootPath}" . PHP_EOL, Console::FG_GREEN);
104
    }
105
106
    protected function getVideoWidth($classname, $field)
107
    {
108
        /** @var ActiveRecord $ownerClassObject */
109
        $ownerClassObject = new $classname;
110
        return $ownerClassObject->getBehavior('files')->attributes[$field]['videoWidth'] ?? 1280;
111
    }
112
113
    protected function getVideoHeight($classname, $field)
114
    {
115
        /** @var ActiveRecord $ownerClassObject */
116
        $ownerClassObject = new $classname;
117
        return $ownerClassObject->getBehavior('files')->attributes[$field]['videoHeight'] ?? -1;
118
    }
119
120
121
}
122