floor12 /
yii2-module-files
| 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
Loading history...
|
|||||||
| 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
Loading history...
|
|||||||
| 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
Loading history...
|
|||||||
| 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
Loading history...
|
|||||||
| 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
Loading history...
|
|||||||
| 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
Loading history...
|
|||||||
| 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
Loading history...
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.');
}
Loading history...
|
|||||||
| 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.