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
|
|||||||
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) { |
||||||
36 | $file->delete(); |
||||||
37 | } |
||||||
38 | } |
||||||
39 | |||||||
40 | function actionClear() |
||||||
0 ignored issues
–
show
|
|||||||
41 | { |
||||||
42 | $countDeleted = $countOk = 0; |
||||||
43 | $module = Yii::$app->getModule('files'); |
||||||
44 | $path1 = $module->storageFullPath; |
||||||
45 | foreach (scandir($path1) as $folder1) { |
||||||
0 ignored issues
–
show
It seems like
$path1 can also be of type null and object ; however, parameter $directory of scandir() 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
![]() |
|||||||
46 | $path2 = $path1 . '/' . $folder1; |
||||||
0 ignored issues
–
show
Are you sure
$path1 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
![]() |
|||||||
47 | if ($this->checkFolderItem($folder1)) { |
||||||
48 | continue; |
||||||
49 | } |
||||||
50 | foreach (scandir($path2) as $folder2) { |
||||||
51 | $path3 = $path2 . '/' . $folder2; |
||||||
52 | if ($this->checkFolderItem($folder2)) { |
||||||
53 | continue; |
||||||
54 | }; |
||||||
55 | foreach (scandir($path3) as $filename) { |
||||||
56 | $path4 = $path3 . '/' . $filename; |
||||||
57 | if ($this->checkFolderItem($filename)) { |
||||||
58 | continue; |
||||||
59 | }; |
||||||
60 | $dbFileName = "/{$folder1}/{$folder2}/{$filename}"; |
||||||
61 | if (is_file($path4)) { |
||||||
62 | $this->stdout($path4 . "..."); |
||||||
63 | if (File::find()->where(['filename' => $dbFileName])->count() === 0) { |
||||||
64 | $this->stdout('no' . PHP_EOL, Console::FG_RED); |
||||||
65 | unlink($path4); |
||||||
66 | $countDeleted++; |
||||||
67 | } else { |
||||||
68 | $this->stdout('ok' . PHP_EOL, Console::FG_GREEN); |
||||||
69 | $countOk++; |
||||||
70 | } |
||||||
71 | } |
||||||
72 | } |
||||||
73 | } |
||||||
74 | } |
||||||
75 | $this->stdout('Deleted: ' . $countDeleted . PHP_EOL, Console::FG_YELLOW); |
||||||
76 | $this->stdout('Ok: ' . $countOk . PHP_EOL, Console::FG_GREEN); |
||||||
77 | } |
||||||
78 | |||||||
79 | private function checkFolderItem($string) |
||||||
80 | { |
||||||
81 | $ignoreItems = ['.', '..', '.gitignore', 'summerfiles']; |
||||||
82 | if (in_array($string, $ignoreItems)) { |
||||||
83 | return true; |
||||||
84 | } |
||||||
85 | return false; |
||||||
86 | } |
||||||
87 | |||||||
88 | |||||||
89 | /** |
||||||
90 | * Run `./yii files/console/clean-cache` to remove all generated images and previews |
||||||
91 | */ |
||||||
92 | function actionCleanCache() |
||||||
0 ignored issues
–
show
|
|||||||
93 | { |
||||||
94 | $module = Yii::$app->getModule('files'); |
||||||
95 | $commands = []; |
||||||
96 | $commands[] = "find {$module->storageFullPath} -regextype egrep -regex \".+/.{32}_.*\" -exec rm -rf {} \;"; |
||||||
97 | $commands[] = "find {$module->cacheFullPath} -regextype egrep -regex \".+/.{32}_.*\" -exec rm -rf {} \;"; |
||||||
98 | $commands[] = "find {$module->storageFullPath} -regextype egrep -regex \".+/.{32}\..{3,4}\.jpg\" -exec rm -rf {} \;"; |
||||||
99 | $commands[] = "find {$module->cacheFullPath} -regextype egrep -regex \".+/.{32}\..{3,4}\.jpg\" -exec rm -rf {} \;"; |
||||||
100 | |||||||
101 | array_map(function ($command) { |
||||||
102 | exec($command); |
||||||
103 | }, $commands); |
||||||
104 | |||||||
105 | } |
||||||
106 | |||||||
107 | /** |
||||||
108 | * Run `./yii files/console/convert` to proccess one video file from queue with ffmpeg |
||||||
109 | * @return bool|int |
||||||
110 | */ |
||||||
111 | function actionConvert() |
||||||
0 ignored issues
–
show
|
|||||||
112 | { |
||||||
113 | $ffmpeg = Yii::$app->getModule('files')->ffmpeg; |
||||||
114 | |||||||
115 | if (!file_exists($ffmpeg)) |
||||||
0 ignored issues
–
show
It seems like
$ffmpeg can also be of type null and 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
![]() |
|||||||
116 | return $this->stdout("ffmpeg is not found: {$ffmpeg}" . PHP_EOL, Console::FG_RED); |
||||||
117 | |||||||
118 | if (!is_executable($ffmpeg)) |
||||||
0 ignored issues
–
show
It seems like
$ffmpeg can also be of type null and 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
![]() |
|||||||
119 | return $this->stdout("ffmpeg is not executable: {$ffmpeg}" . PHP_EOL, Console::FG_RED); |
||||||
120 | |||||||
121 | $file = File::find() |
||||||
122 | ->where(['type' => FileType::VIDEO, 'video_status' => VideoStatus::QUEUE]) |
||||||
123 | ->andWhere(['!=', 'object_id', 0]) |
||||||
124 | ->one(); |
||||||
125 | |||||||
126 | if (!$file) |
||||||
127 | return $this->stdout("Convert queue is empty" . PHP_EOL, Console::FG_GREEN); |
||||||
128 | |||||||
129 | if (!file_exists($file->rootPath)) |
||||||
0 ignored issues
–
show
It seems like
$file->rootPath can also be of type null ; 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
![]() |
|||||||
130 | return $this->stdout("Source file is not found: {$file->rootPath}" . PHP_EOL, Console::FG_RED); |
||||||
131 | |||||||
132 | |||||||
133 | $file->video_status = VideoStatus::CONVERTING; |
||||||
134 | $file->save(); |
||||||
135 | $width = $this->getVideoWidth($file->class, $file->field); |
||||||
136 | $height = $this->getVideoHeight($file->class, $file->field); |
||||||
137 | $newFileName = $file->filename . ".mp4"; |
||||||
138 | $newFilePath = $file->rootPath . ".mp4"; |
||||||
139 | $command = Yii::$app->getModule('files')->ffmpeg . " -i {$file->rootPath} -vf scale={$width}:{$height} -threads 4 {$newFilePath}"; |
||||||
0 ignored issues
–
show
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
![]() |
|||||||
140 | echo $command . PHP_EOL; |
||||||
141 | exec($command, |
||||||
142 | $outout, $result); |
||||||
143 | if ($result == 0) { |
||||||
144 | @unlink($file->rootPath); |
||||||
0 ignored issues
–
show
It seems like
$file->rootPath can also be of type null ; however, parameter $filename of unlink() 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
![]() 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
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.');
}
![]() |
|||||||
145 | $file->filename = $newFileName; |
||||||
146 | $file->content_type = 'video/mp4'; |
||||||
147 | $file->video_status = VideoStatus::READY; |
||||||
148 | } else { |
||||||
149 | $file->video_status = VideoStatus::QUEUE; |
||||||
150 | } |
||||||
151 | $file->save(); |
||||||
152 | |||||||
153 | return $this->stdout("File converted: {$file->rootPath}" . PHP_EOL, Console::FG_GREEN); |
||||||
154 | } |
||||||
155 | |||||||
156 | protected |
||||||
157 | function getVideoWidth($classname, $field) |
||||||
158 | { |
||||||
159 | /** @var ActiveRecord $ownerClassObject */ |
||||||
160 | $ownerClassObject = new $classname; |
||||||
161 | return $ownerClassObject->getBehavior('files')->attributes[$field]['videoWidth'] ?? 1280; |
||||||
162 | } |
||||||
163 | |||||||
164 | protected |
||||||
165 | function getVideoHeight($classname, $field) |
||||||
166 | { |
||||||
167 | /** @var ActiveRecord $ownerClassObject */ |
||||||
168 | $ownerClassObject = new $classname; |
||||||
169 | return $ownerClassObject->getBehavior('files')->attributes[$field]['videoHeight'] ?? -1; |
||||||
170 | } |
||||||
171 | |||||||
172 | |||||||
173 | } |
||||||
174 |
Adding explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.