Skip to content

Commit

Permalink
improved maintenance controller d3files/clean-files
Browse files Browse the repository at this point in the history
Signed-off-by: uldisn <[email protected]>
  • Loading branch information
uldisn committed Jun 28, 2022
1 parent 1d82fc3 commit 26d6711
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 55 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,14 +365,14 @@ D3filesModel::createCopy($fileModelId, Users::class, $model->id);
### Maintenance commands

Soft deletes files (sets deleted=1)
For model dektrium\user\models\User remove from database model dektrium\user\models\User oldest as 12 months files
For model dektrium\user\models\User soft delete from database for model dektrium\user\models\User oldest as 12 months files with extension xml
```bash
yii d3files/remove-older-than 'dektrium\user\models\User' 12
yii d3files/clean-files/remove-older-than 'dektrium\user\models\User' 12 '%.xml'
```

Deletes files and corresponding records in database which have deleted=1
```bash
yii d3files/remove-files 'dektrium\user\models\User'
yii d3files/clean-files/remove-files 'dektrium\user\models\User'
```

Deletes model files from filesystem with out refence in database
Expand All @@ -386,4 +386,5 @@ yii d3files/clean-files/unused-files 'poker\poker\models\PkPlaygroundFixes'
- 0.9.3 (May 29, 2017) - auto creating upload directories
- 0.9.4 (Nov 16, 2017) - added parameter controllerRoute
- 0.9.13 (Jul 2, 2018) - added action column
- 0.9.93 (febr 10, 2022) - added maint
- 0.9.93 (febr 10, 2022) - added controller d3files/clean-files for maintenance
- 0.9.97 (jun 28, 2022) - improved maintanance controller d3files/clean-files
133 changes: 86 additions & 47 deletions controllers/CleanFilesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
use d3yii2\d3files\models\D3filesModel;
use d3yii2\d3files\components\FileHandler;
use d3system\commands\D3CommandController;
use yii\helpers\VarDumper;
use d3yii2\d3files\models\D3filesModelName;
use DateInterval;
use DateTime;
use yii\console\ExitCode;

class CleanFilesController extends D3CommandController
{
Expand All @@ -16,53 +19,81 @@ class CleanFilesController extends D3CommandController
* soft deletes all the file models older than date provided
* older than number of months
*
* @param $modelName
* @param $months
* @throws \Throwable
*
* @param string $modelName
* @param int $months
* @param string|null $sqlLikeFileName
* @return int
* @throws \Exception
*/
public function actionRemoveOlderThan($modelName, $months): int
public function actionRemoveOlderThan(string $modelName, int $months, string $sqlLikeFileName = null): int
{
$date = date('Y-m-d', strtotime('-'.$months.' month'));

$oldFiles = D3filesModel::find()
->innerJoin('d3files', '`d3files`.`id` = `d3files_model`.`d3files_id`')
->innerJoin(['d3files_model_name', '`d3file_model_name`.id = `d3files_model`.`model_name_id'])
->where(['`d3files_model_name`.`name`' => $modelName ])
->andWhere(['deleted' => 0])
->andWhere(['<', '`add_datetime`', $date ])
->all()
;

$this->stdout('Deleting ' . count($oldFiles) . ' files.');

foreach ($oldFiles as $file) {

$file->deleted = 1;
$file->save();
$date = new DateTime();
$date->sub(new DateInterval('P' . $months . 'M'));
$this->out('Clrear oldest ' . $date->format('Y-m-d H:i:s'));
$modelMN = new D3filesModelName();
if (!$modelNameId = $modelMN->getByName($modelName, false)) {
$this->out('Ilegal model name: ' . $modelName);
}
$i = 1;
$count = 1;
while ($count > 0) {
$activeQuery = D3filesModel::find()
->select('d3files_model.id')
->innerJoin('d3files', '`d3files`.`id` = `d3files_model`.`d3files_id`')
->where([
'`d3files_model`.`model_name_id`' => $modelNameId,
'd3files_model.deleted' => 0
])
->andWhere(['<', '`add_datetime`', $date->format('Y-m-d H:i:s')])
->orderBy(['`add_datetime`' => SORT_ASC])
->limit(100);

if ($sqlLikeFileName) {
$activeQuery->andWhere('d3files.file_name like \'' . $sqlLikeFileName . '\'');
}
$oldFilesId = $activeQuery
->column();

$count = count($oldFilesId);
$this->out('FilesId: ' . implode(',', $oldFilesId));
$this->out('Deleting ' . $count . ' files.');
D3filesModel::updateAll(
['deleted' => 1],
['id' => $oldFilesId]
);
if ($i++ > 30) {
break;
}

return 0;
sleep(1);
}
return ExitCode::OK;
}

/**
* deletes all files saved under the model name
* with value "deleted = 1"
*
* @param $modelName
* @param string $modelName
* @return int
* @throws \ReflectionException
* @throws \Throwable
* @throws \yii\db\StaleObjectException
*/
public function actionRemoveFiles($modelName)
public function actionRemoveFiles(string $modelName): int
{
$modelMN = new D3filesModelName();
if (!$modelNameId = $modelMN->getByName($modelName, false)) {
$this->out('Illegal model name: ' . $modelName);
}
$deletedFiles = D3filesModel::find()
->where(['deleted' => 1])
->where([
'deleted' => 1,
'`d3files_model`.`model_name_id`' => $modelNameId
])
->limit(1000)
->all();

$this->stdout('Deleting ' . count($deletedFiles) . ' file models.');
$this->out('Deleting ' . count($deletedFiles) . ' file models.');

foreach ($deletedFiles as $fileModel) {

Expand All @@ -81,19 +112,16 @@ public function actionRemoveFiles($modelName)
$fileModel->delete();

if (!$usedModel = D3filesModel::findOne(['d3files_id' => $file->id])) {

$this->out('Delete file ' . $fileModel->d3files_id . ' - ' . $file->file_name);
$file->delete();

if (file_exists($filePath)) {
unlink($filePath);
}
} else {
$this->stdout('Can\'t delete file ' . $file->file_name . ', in use with model: '. $usedModel->id);
$this->out('Can\'t delete file ' . $file->file_name . ', in use with model: '. $usedModel->id);
}

}

return 0;
return ExitCode::OK;
}

/**
Expand All @@ -103,12 +131,17 @@ public function actionRemoveFiles($modelName)
*/
public function actionUnusedFiles(string $modelName): int
{

$modelMN = new D3filesModelName();
if (!$modelNameId = $modelMN->getByName($modelName, false)) {
$this->out('Illegal model name: ' . $modelName);
}

$dirPath = FileHandler::getUploadDirPath($modelName);
$handle = opendir($dirPath);

$i = 0;
if ($handle) {
$i = 1;
while (($entry = readdir($handle)) !== FALSE) {
while (($entry = readdir($handle)) !== false) {
if ($entry ==='.') {
continue;
}
Expand All @@ -117,25 +150,31 @@ public function actionUnusedFiles(string $modelName): int
}
$i++;
$this->out($entry);
$fileName = pathinfo($entry, PATHINFO_FILENAME);
if (!preg_match('#^\d+$#',$fileName)) {
$this->out(' ilegal file name');
$d3FilesId = pathinfo($entry, PATHINFO_FILENAME);
if (!preg_match('#^\d+$#', $d3FilesId)) {
$this->out(' ilegal $d3FilesId: ' . $d3FilesId);
continue;
}
if (D3files::findOne($fileName)) {
if (D3files::find()
->innerJoin('d3files_model', 'd3files_model.d3files_id = d3files.id')
->where([
'd3files.id' => $d3FilesId,
'`d3files_model`.`model_name_id`' => $modelNameId
])
->exists()
) {
//$this->out(' Izmanto');
continue;
}
$this->out(' unused');
if (!unlink($dirPath . '/' . $entry)){
if (!unlink($dirPath . '/' . $entry)) {
$this->out(' Error: can not unlink');
continue;
}
$this->out(' unlinked');
}
}

return 0;
$this->out('Deleted ' . $i . ' files');
return ExitCode::OK;
}

}
}
7 changes: 3 additions & 4 deletions models/D3filesModelName.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function attributeLabels()
*/
public function getD3filesModels()
{
return $this->hasMany(D3filesModel::className(), ['model_name_id' => 'id']);
return $this->hasMany(D3filesModel::class, ['model_name_id' => 'id']);
}

/**
Expand All @@ -59,11 +59,11 @@ public function getD3filesModels()
*
* @return integer model name id
*/
public function getByName($name, $addIfNotSet)
public function getByName(string $name, bool $addIfNotSet)
{
$model = self::find()
->select('id')
->where(['name' => $name])
->where(['name' => trim($name)])
->one();

if ($model) {
Expand All @@ -79,6 +79,5 @@ public function getByName($name, $addIfNotSet)
$newModel->save();

return $newModel->id;

}
}

0 comments on commit 26d6711

Please sign in to comment.