Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions database/migrations/2024_03_07_100000_create_asset_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ public function up()
$table->char('extension', 10)->index();
$table->string('path')->index();
$table->jsonb('meta')->nullable();

$table->integer('duration')->nullable()->default(null);
$table->integer('height')->nullable()->default(null);
$table->integer('last_modified');
$table->string('mime_type');
$table->integer('size')->index();
$table->integer('width')->nullable()->default(null);

$table->timestamps();

$table->unique(['container', 'folder', 'basename']);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Arr;
use Statamic\Eloquent\Assets\AssetModel;
use Statamic\Eloquent\Database\BaseMigration as Migration;

return new class extends Migration {
public function up()
{
if (Schema::hasColumn($this->prefix('assets_meta', 'size')) {
return;
}

Schema::table($this->prefix('assets_meta'), function (Blueprint $table) {
$table->integer('duration')->nullable()->default(null);
$table->integer('height')->nullable()->default(null);
$table->integer('last_modified')->default(0);
$table->string('mime_type')->default('');
$table->integer('size')->default(0)->index();
$table->integer('width')->nullable()->default(null);
});

AssetModel::query()
->lazy()
->each(function ($model) {
$meta = $model->meta;

$model->duration = Arr::pull($meta, 'duration', null);
$model->height = Arr::pull($meta, 'height', null);
$model->last_modified = Arr::pull($meta, 'last_modified', time());
$model->mime_type = Arr::pull($meta, 'mime_type', '');
$model->size = Arr::pull($meta, 'size', 0);
$model->width = Arr::pull($meta, 'height', null);

$model->meta = $meta['data'];
$model->saveQuietly();
});
}

public function down()
{
if (! Schema::hasColumn($this->prefix('assets_meta', 'size')) {
return;
}

AssetModel::query()
->lazy()
->each(function ($model) {
$meta = $model->meta;

$meta['duration'] = $model->duration;
$meta['height'] = $model->height;
$meta['last_modified'] = $model->last_modified;
$meta['mime_type'] = $model->mime_type;
$meta['size'] = $model->size;
$meta['width'] = $model->width;

$model->meta = $meta;

$model->saveQuietly();
});

Schema::table($this->prefix('assets_meta'), function (Blueprint $table) {
$table->dropColumn(['duration', 'height', 'last_modified', 'mime_type', 'size', 'width']);
});
}
};
41 changes: 37 additions & 4 deletions src/Assets/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,20 @@ public function syncOriginal()

public static function fromModel(Model $model)
{
$meta = ['data' => $model->meta];
$meta['duration'] = $model->duration;
$meta['height'] = $model->height;
$meta['last_modified'] = $model->last_modified;
$meta['mime_type'] = $model->mime_type;
$meta['size'] = $model->size;
$meta['width'] = $model->width;

$meta = Arr::removeNullValues($meta);

$asset = (new static)
->container($model->container)
->path(Str::replace('//', '/', $model->folder.'/'.$model->basename))
->hydrateMeta($model->meta)
->hydrateMeta($meta)
->syncOriginal()
->model($model);

Expand Down Expand Up @@ -62,8 +72,17 @@ public function meta($key = null)
return $meta;
}

if ($meta = $this->model()?->meta) {
return $meta;
if ($this->model()?->meta) {
$model = $this->model();
$meta = ['data' => $model->meta];
$meta['duration'] = $model->duration;
$meta['height'] = $model->height;
$meta['last_modified'] = $model->last_modified;
$meta['mime_type'] = $model->mime_type;
$meta['size'] = $model->size;
$meta['width'] = $model->width;

return Arr::removeNullValues($meta);
}

$meta = $this->generateMeta();
Expand Down Expand Up @@ -122,6 +141,13 @@ public function writeMeta($meta)
return;
}

$model->meta = $meta['data'];
$model->duration = $meta['duration'] ?? null;
$model->height = $meta['height'] ?? null;
$model->last_modified = $meta['last_modified'] ?? time();
$model->mime_type = $meta['mime_type'] ?? '';
$model->size = $meta['size'] ?? 0;
$model->width = $meta['width'] ?? null;
$model->save();

$this->model($model);
Expand Down Expand Up @@ -153,12 +179,19 @@ public static function makeModelFromContract(AssetContract $source, $meta = [])
}

$model->fill([
'meta' => $meta,
'meta' => $meta['data'],
'filename' => $source->filename(),
'extension' => $extension,
'path' => $source->path(),
'folder' => $source->folder(),
'basename' => $source->basename(),

'duration' => $source->duration(),
'height' => $source->height(),
'last_modified' => $source->lastModified()?->timestamp ?? time(),
'mime_type' => $source->mimeType(),
'size' => $source->size(),
'width' => $source->width(),
]);

// Set initial timestamps.
Expand Down
10 changes: 2 additions & 8 deletions src/Assets/AssetQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,13 @@
class AssetQueryBuilder extends EloquentQueryBuilder implements QueryBuilder
{
const COLUMNS = [
'id', 'container', 'folder', 'basename', 'filename', 'extension', 'path', 'created_at', 'updated_at',
];

const META_COLUMNS = [
'size', 'width', 'height', 'duration', 'mime_type', 'last_modified',
'id', 'container', 'folder', 'basename', 'filename', 'extension', 'path', 'size', 'width', 'height', 'duration', 'mime_type', 'last_modified', 'created_at', 'updated_at',
];

protected function column($column)
{
if (in_array($column, self::META_COLUMNS)) {
if (! in_array($column, self::COLUMNS)) {
$column = 'meta->'.$column;
} elseif (! in_array($column, self::COLUMNS)) {
$column = 'meta->data->'.$column;
}

return $column;
Expand Down
27 changes: 27 additions & 0 deletions src/Updates/AddMetaColumnsToAssetsTable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Statamic\Eloquent\Updates;

use Illuminate\Support\Facades\Schema;
use Statamic\UpdateScripts\UpdateScript;

class AddMetaColumnsToAssetsTable extends UpdateScript
{
public function shouldUpdate($newVersion, $oldVersion)
{
$assetsTable = config('statamic.eloquent-driver.table_prefix', '').'assets';

return Schema::hasTable($assetsTable) && ! Schema::hasColumn($assetsTable, 'size');
}

public function update()
{
$source = __DIR__.'/../../database/migrations/updates/add_meta_columns_to_assets_table.php.stub';
$dest = database_path('migrations/'.date('Y_m_d_His').'_add_meta_columns_to_assets_table.php');

$this->files->copy($source, $dest);

$this->console()->info('Migration created');
$this->console()->comment('Remember to run `php artisan migrate` to apply it to your database.');
}
}
21 changes: 13 additions & 8 deletions tests/Assets/AssetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ public function it_loads_from_asset_model()
'basename' => 'test.jpg',
'filename' => 'test',
'extension' => 'jpg',
'meta' => ['width' => 100, 'height' => 100, 'data' => ['focus' => '50-50-1']],
'meta' => ['focus' => '50-50-1'],
'width' => 100,
'height' => 100,
]);

$asset = (new Asset)->fromModel($model);
Expand All @@ -83,7 +85,7 @@ public function it_loads_from_asset_model()
$this->assertSame('test.jpg', $asset->basename());
$this->assertSame('test', $asset->filename());
$this->assertSame('jpg', $asset->extension());
$this->assertSame(['width' => 100, 'height' => 100, 'data' => ['focus' => '50-50-1']], $asset->meta());
$this->assertSame(['data' => ['focus' => '50-50-1'], 'height' => 100, 'width' => 100], $asset->meta());
}

#[Test]
Expand All @@ -96,7 +98,12 @@ public function it_loads_from_an_existing_model_outside_the_query_builder()
'basename' => 'test.jpg',
'filename' => 'test',
'extension' => 'jpg',
'meta' => ['width' => 100, 'height' => 100, 'data' => ['focus' => '50-50-1']],
'meta' => ['focus' => '50-50-1'],
'width' => 100,
'height' => 100,
'last_modified' => $lastModified = time(),
'mime_type' => 'image/jpeg',
'size' => 1000,
]);

$model->save();
Expand All @@ -109,7 +116,7 @@ public function it_loads_from_an_existing_model_outside_the_query_builder()
$this->assertSame('test.jpg', $asset->basename());
$this->assertSame('test', $asset->filename());
$this->assertSame('jpg', $asset->extension());
$this->assertSame(['width' => 100, 'height' => 100, 'data' => ['focus' => '50-50-1']], $asset->meta());
$this->assertSame(['data' => ['focus' => '50-50-1'], 'height' => 100, 'last_modified' => $lastModified, 'mime_type' => 'image/jpeg', 'size' => 1000, 'width' => 100], $asset->meta());
}

#[Test]
Expand Down Expand Up @@ -168,11 +175,9 @@ public function making_and_saving_an_asset_creates_a_new_model()
{
$this->assertCount(6, AssetModel::all());

Storage::disk('test')->put('f.jpg', '');
Storage::disk('test')->put('test.jpg', '');

$asset = Facades\Asset::make()->container('test')->path('test.jpg');
$this->assertCount(6, AssetModel::all());

$asset->save();

$this->assertInstanceOf(AssetModel::class, $asset->model());
Expand All @@ -199,7 +204,7 @@ public function moving_an_asset_updates_the_same_model()
$this->assertSame($model->basename, $asset->basename());
$this->assertSame($model->filename, $asset->filename());
$this->assertSame($model->extension, $asset->extension());
$this->assertSame($model->meta, $asset->meta());
$this->assertSame($model->meta, $asset->meta()['data']);
$this->assertSame($modelId, $asset->model()->getKey());
}

Expand Down