Skip to content

Commit 3b9769e

Browse files
author
riccardodallavia
committed
wip
1 parent 13a77fe commit 3b9769e

26 files changed

+576
-110
lines changed

README.md

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,6 @@ You can install the package via composer:
1616
composer require maize-tech/laravel-prunable-fields
1717
```
1818

19-
You can publish the config file with:
20-
21-
```bash
22-
php artisan vendor:publish --tag="prunable-fields-config"
23-
```
24-
25-
This is the contents of the published config file:
26-
27-
```php
28-
return [
29-
];
30-
```
31-
3219
## Usage
3320

3421
```php

composer.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717
],
1818
"require": {
1919
"php": "^8.0",
20-
"spatie/laravel-package-tools": "^1.9.2",
21-
"illuminate/contracts": "^9.0"
20+
"illuminate/console": "^9.0",
21+
"illuminate/database": "^9.0",
22+
"illuminate/events": "^9.0",
23+
"illuminate/support": "^9.0",
24+
"spatie/laravel-package-tools": "^1.9.2"
2225
},
2326
"require-dev": {
2427
"friendsofphp/php-cs-fixer": "^3.8",
@@ -57,10 +60,7 @@
5760
"laravel": {
5861
"providers": [
5962
"Maize\\PrunableFields\\PrunableFieldsServiceProvider"
60-
],
61-
"aliases": {
62-
"PrunableFields": "Maize\\PrunableFields\\Facades\\PrunableFields"
63-
}
63+
]
6464
}
6565
},
6666
"minimum-stability": "dev",

config/prunable-fields.php

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Maize\PrunableFields\Database\Factories;
4+
5+
use Illuminate\Database\Eloquent\Factories\Factory;
6+
use Maize\PrunableFields\Tests\Models\MassPrunableUser;
7+
8+
class MassPrunableUserFactory extends Factory
9+
{
10+
protected $model = MassPrunableUser::class;
11+
12+
public function definition()
13+
{
14+
return [
15+
'first_name' => $this->faker->firstName,
16+
'last_name' => $this->faker->lastName,
17+
'email' => $this->faker->email,
18+
];
19+
}
20+
}

database/factories/ModelFactory.php

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Maize\PrunableFields\Database\Factories;
4+
5+
use Illuminate\Database\Eloquent\Factories\Factory;
6+
use Maize\PrunableFields\Tests\Models\PrunableUser;
7+
8+
class PrunableUserFactory extends Factory
9+
{
10+
protected $model = PrunableUser::class;
11+
12+
public function definition()
13+
{
14+
return [
15+
'first_name' => $this->faker->firstName,
16+
'last_name' => $this->faker->lastName,
17+
'email' => $this->faker->email,
18+
];
19+
}
20+
}

database/migrations/create_prunable_fields_table.php.stub

Lines changed: 0 additions & 19 deletions
This file was deleted.

resources/views/.gitkeep

Whitespace-only changes.

src/Commands/PrunableFieldsCommand.php

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?php
2+
3+
namespace Maize\PrunableFields\Commands;
4+
5+
use Illuminate\Console\Command;
6+
use Illuminate\Database\Eloquent\SoftDeletes;
7+
use Illuminate\Support\Collection;
8+
use Illuminate\Support\Facades\Event;
9+
use Illuminate\Support\Str;
10+
use InvalidArgumentException;
11+
use Maize\PrunableFields\Events\ModelsFieldsPruned;
12+
use Maize\PrunableFields\MassPrunableFields;
13+
use Maize\PrunableFields\PrunableFields;
14+
use Symfony\Component\Finder\Finder;
15+
16+
class PruneFieldsCommand extends Command
17+
{
18+
protected $signature = 'model:prune-fields
19+
{--model=* : Class names of the models to be pruned}
20+
{--chunk=1000 : The number of models to retrieve per chunk of models to be pruned}
21+
{--pretend : Display the number of prunable records found instead of pruning them}';
22+
23+
public $description = 'Prune model fields that are no longer needed';
24+
25+
public function handle(): void
26+
{
27+
$models = $this->models();
28+
29+
if ($models->isEmpty()) {
30+
$this->info('No prunable models found.');
31+
32+
return;
33+
}
34+
35+
if ($this->option('pretend')) {
36+
$models->each(fn ($model) => $this->pretendToPrune($model));
37+
38+
return;
39+
}
40+
41+
Event::listen(ModelsFieldsPruned::class, function ($event) {
42+
$this->info("{$event->count} [{$event->model}] records have been pruned.");
43+
});
44+
45+
$models->each(function ($model) {
46+
$instance = new $model();
47+
48+
$chunkSize = property_exists($instance, 'prunableFieldsChunkSize')
49+
? $instance->prunableFieldsChunkSize
50+
: $this->option('chunk');
51+
52+
$total = $this->isPrunable($model)
53+
? $instance->pruneAllFields($chunkSize)
54+
: 0;
55+
56+
if ($total === 0) {
57+
$this->info("No prunable [$model] records found.");
58+
}
59+
});
60+
61+
Event::forget(ModelsFieldsPruned::class);
62+
}
63+
64+
protected function models(): Collection
65+
{
66+
if (! empty($models = $this->option('model'))) {
67+
return collect($models)
68+
->filter(fn ($model) => class_exists($model))
69+
->values();
70+
}
71+
72+
$except = $this->option('except');
73+
74+
if (! empty($models) && ! empty($except)) {
75+
throw new InvalidArgumentException('The --models and --except options cannot be combined.');
76+
}
77+
78+
return collect((new Finder())->in($this->getDefaultPath())->files()->name('*.php'))
79+
->map(function ($model) {
80+
$namespace = $this->laravel->getNamespace();
81+
82+
return $namespace.str_replace(
83+
['/', '.php'],
84+
['\\', ''],
85+
Str::after($model->getRealPath(), realpath(app_path()).DIRECTORY_SEPARATOR)
86+
);
87+
})
88+
->when(! empty($except), function ($models) use ($except) {
89+
return $models->reject(fn ($model) => in_array($model, $except));
90+
})
91+
->filter(fn ($model) => $this->isPrunable($model))
92+
->filter(fn ($model) => class_exists($model))
93+
->values();
94+
}
95+
96+
protected function isPrunable(string $model): bool
97+
{
98+
$uses = class_uses_recursive($model);
99+
100+
return in_array(PrunableFields::class, $uses) || in_array(MassPrunableFields::class, $uses);
101+
}
102+
103+
protected function pretendToPrune(string $model): void
104+
{
105+
$instance = new $model();
106+
107+
$count = $instance
108+
->prunableFields()
109+
->when(
110+
in_array(SoftDeletes::class, class_uses_recursive(get_class($instance))),
111+
fn ($query) => $query->withTrashed()
112+
)
113+
->count();
114+
115+
if ($count === 0) {
116+
$this->info("No prunable [$model] records found.");
117+
} else {
118+
$this->info("{$count} [{$model}] records will be pruned.");
119+
}
120+
}
121+
}

0 commit comments

Comments
 (0)