Skip to content

Instantly share code, notes, and snippets.

@sauron
Created May 26, 2021 11:48
Show Gist options
  • Save sauron/bc713a18779207e5386ad7e83c292a3a to your computer and use it in GitHub Desktop.
Save sauron/bc713a18779207e5386ad7e83c292a3a to your computer and use it in GitHub Desktop.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class UpdateCrops extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'twill:update-crops
{moduleName : The name of the module to update, or the FQCN of the model if you did not setup morphmaps}
{roleName : The name of the image role to update}
{cropName : The name of the image crop to update}
{newRatio : The new ratio to apply, which can be provided as a string fraction or a number}
{originCropName? : The name of the image crop which will be used as base}'
;
// php artisan twill:update-crops "App\Models\Destination" cover listing "4/5" desktop
/**
* The console command description.
*
* @var string
*/
protected $description = 'Smartly update existing crops in database given a new ratio';
/**
* Execute the console command.
*
* @return integer
*/
public function handle(): int
{
$this->info("Updating crops");
$arguments = $this->arguments();
$model = $this->getModelClass($arguments['moduleName']);
if (isset($arguments['originCropName'])) {
$mediables = DB::table(config('twill.mediables_table'))
->where('mediable_type', $model)
->where('role', $arguments['roleName'])
->where('crop', $arguments['originCropName'])
->get();
$this->info("Create new crops based on {$arguments['originCropName']}");
foreach ($mediables as $item) {
$crops = $this->getExistingCrops($item, $arguments['cropName']);
if ($crops->count() === 0) {
DB::table(config('twill.mediables_table'))->insert([
'mediable_id' => $item->mediable_id,
'mediable_type' => $item->mediable_type,
'media_id' => $item->media_id,
'crop_x' => $item->crop_x,
'crop_y' => $item->crop_y,
'crop_w' => $item->crop_w,
'crop_h' => $item->crop_h,
'role' => $arguments['roleName'],
'crop' => $arguments['cropName'],
'ratio' => $arguments['cropName'],
'lqip_data' => $item->lqip_data,
'metadatas' => $item->metadatas,
'locale' => $item->locale,
]);
}
}
}
$mediables = DB::table(config('twill.mediables_table'))
->where('mediable_type', $model)
->where('role', $arguments['roleName'])
->where('crop', $arguments['cropName'])
->get();
$this->info("Found {$mediables->count()} mediables to update.");
if (strpos($arguments['newRatio'], '/')) {
$fractions = explode('/', $arguments['newRatio']);
$newRatio = $fractions[0] / $fractions[1];
} else {
$newRatio = $arguments['newRatio'];
}
if ($mediables->count() === 0) {
$this->info("Aborted.");
return 1;
}
$this->info("Updating mediables.");
$mediables->each(function ($crop) use ($newRatio) {
$image = DB::table(config('twill.medias_table'))
->where('id', $crop->media_id)
->first();
if ($newRatio < 1) {
$newCropW = min($image->height * $newRatio, $image->width);
$newCropH = $newCropW / $newRatio;
} else {
$newCropH = min($image->width / $newRatio, $image->height);
$newCropW = $newCropH * $newRatio;
}
$currentFocalPointX = ($crop->crop_w / 2 + $crop->crop_x) / $image->width;
$currentFocalPointY = ($crop->crop_h / 2 + $crop->crop_y) / $image->height;
if ($currentFocalPointX > 0.5) {
$newCropX = $image->width - $newCropW;
} else {
$newCropX = 0;
}
if ($currentFocalPointY > 0.5) {
$newCropY = $image->height - $newCropH;
} else {
$newCropY = 0;
}
DB::table(config('twill.mediables_table'))->where('id', $crop->id)->update([
'crop_x' => $newCropX,
'crop_y' => $newCropY,
'crop_w' => $newCropW,
'crop_h' => $newCropH,
]);
});
return 0;
}
private function getModelClass($moduleName): string
{
if (class_exists($moduleName)) {
return $moduleName;
}
$this->error('Providing module name is not yet supported');
die;
}
/**
* @param $item
* @param $cropName
* @return \Illuminate\Support\Collection
*/
private function getExistingCrops($item, $cropName): \Illuminate\Support\Collection
{
$found = DB::table(config('twill.mediables_table'))->where([
'mediable_id' => $item->mediable_id,
'mediable_type' => $item->mediable_type,
'media_id' => $item->media_id,
'crop' => $cropName,
'ratio' => $cropName,
'locale' => $item->locale,
])->get()
;
return $found;
}
}
@Dmi3yy
Copy link

Dmi3yy commented May 28, 2021

run php artisan twill:update-crops "App\Models\Service" cover mobile "1" mobile
https://tppr.me/JKvSS

In model:

public $mediasParams = [
        'cover' => [
            'mobile' => [
                [
                    'name' => 'mobile',
                    'ratio' => 1,
                ],
            ],
        ],
    ];

but in admin panel still see
https://tppr.me/Dx861

and after click
https://tppr.me/C7TZ0

@sauron
Copy link
Author

sauron commented May 28, 2021

@Dmi3yy Try running
php artisan twill:update-crops "App\Models\Service" cover mobile "1"
The last parameter is used for when you already have a crop and added a new one.

@Dmi3yy
Copy link

Dmi3yy commented May 28, 2021

@sauron
Copy link
Author

sauron commented May 28, 2021

@Dmi3yy so when you click on the Cropping tool you see only the one that is on the Model, but in the Form you see the previously generated right?

In that case we might need to change the Command, because it is not deleting all crops but just updating/adding the new ones.

If you take a look at the command, it is not reading from the Model, but basing the update on the role and crop given as parameter.

I've made a quick command to delete existing crops.

https://gist.github.com/sauron/bcffa9f44eda6c414d71829c3d4d6b20

It is dangerous, and I only tested with a few scenarios.

Be cautious!
I'll try to create one based on the params given in the model, but can't promise it'll be ready soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment