corollarium / modelarium-medialibrary
整合 Spatie Laravel-media-library 至 Modelarium 和 GraphQL
Requires
- php: >=7.2.0
- corollarium/modelarium: ^0.4
- illuminate/support: ^7.16
- nuwave/lighthouse: ^5.1
- webonyx/graphql-php: ^14.5
Requires (Dev)
- phpstan/phpstan: ^0.12
- phpunit/phpunit: ^8
- thecodingmachine/phpstan-safe-rule: ^1.0
Suggests
- spatie/laravel-medialibrary: The base medialibrary should be installed too.
README
此包将 Spatie 的 Laravel Media Library 集成到 Modelarium,允许使用 LighthousePHP 进行 GraphQL 查询,以轻松访问模型上的媒体。
安装
在您的 Laravel 应用中运行
composer require corollarium/modelarium-medialibrary
快速概述
这是一个针对具有两个不同媒体集合("image" 和 "map")的模型的 Graphql 文件。两者都有额外的字段 "url" 和 "description"。 "Map" 还有一个转换 "thumb",其大小为 150x150(最大,保持宽高比)缩略图。
type Post @migrationSoftDeletes @migrationTimestamps { id: ID! name: String! @modelFillable @renderable( label: "Name" size: "large" itemtype: "name" card: true title: true ) description: Text! @modelFillable @renderable(label: "Description", itemtype: "description") imageUrl: Url @migrationSkip image: LaravelMediaLibraryData @migrationSkip @laravelMediaLibraryData( collection: "image" fields: ["url", "description"] ) map: LaravelMediaLibraryData @migrationSkip @laravelMediaLibraryData( collection: "map" fields: ["url", "description"] conversions: [ { name: "thumb", width: 150, height: 150 } ] ) }
这将在您的模型类上自动生成以下代码
/** * This file was automatically generated by Modelarium on 2020-12-13T18:28:11+00:00 */ namespace App\Models; abstract class BasePost extends \Illuminate\Database\Eloquent\Model implements \Spatie\MediaLibrary\HasMedia { use \Spatie\MediaLibrary\InteractsWithMedia; // ...lots of base stuff... /** * Configures Laravel media-library */ public function registerMediaCollections(): void { $this->addMediaCollection('image'); $this->addMediaCollection('map'); } /** * Returns a collection media from Laravel-MediaLibrary */ public function getMediaImageCollection(): \Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection { return $this->getMedia('image'); } /** * Returns custom fields for the media */ public function getMediaImageCustomFields(): array { return ['url', 'description']; } /** * Returns the media attribute (url) for the image */ public function getImageUrlAttribute(): string { $image = $this->getMediaImageCollection()->first(); if ($image) { return $image->getUrl(); } return ''; } /** * Returns media attribute for the image media with custom fields */ public function getImageAttribute(): array { $image = $this->getMediaImageCollection()->first(); if ($image) { $customFields = []; foreach ($this->getMediaImageCustomFields() as $c) { $customFields[$c] = $image->getCustomProperty($c); } return [ 'url' => $image->getUrl(), 'fields' => json_encode($customFields) ]; } return []; } /** * Configures Laravel media-library conversions */ public function registerMediaConversions(?\Spatie\MediaLibrary\MediaCollections\Models\Media $media = null): void { $this->addMediaConversions('thumb')->width('150')->height('150'); } /** * Returns a collection media from Laravel-MediaLibrary */ public function getMediaMapCollection(): \Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection { return $this->getMedia('map'); } /** * Returns custom fields for the media */ public function getMediaMapCustomFields(): array { return ['url', 'description']; } /** * Returns the media attribute (url) for the map */ public function getMapUrlAttribute(): string { $image = $this->getMediaMapCollection()->first(); if ($image) { return $image->getUrl(); } return ''; } /** * Returns media attribute for the map media with custom fields */ public function getMapAttribute(): array { $image = $this->getMediaMapCollection()->first(); if ($image) { $customFields = []; foreach ($this->getMediaMapCustomFields() as $c) { $customFields[$c] = $image->getCustomProperty($c); } return [ 'url' => $image->getUrl(), 'fields' => json_encode($customFields) ]; } return []; } // ...more stuff here... }
文档
@laravelMediaLibraryData
指令支持以下参数
待办事项
常见问题解答
我需要在我的集合上进行一些自定义转换。
如果指令的基本参数不够,只需在您的模型类中覆盖方法即可
class Post extends BasePost { public function registerMediaConversions(?\Spatie\MediaLibrary\MediaCollections\Models\Media $media = null): void { // do your stuff here } }
我如何在类型中仅获取单个图像的图像 URL?
在您的类型中定义一个 xxxUrl
,其中 xxx
是您的集合名称。它将由模型上的属性方法自动填充。别忘了添加 @migrationSkip
以防止它在迁移中创建。示例
type Post { # ... # this field is filled automatically by the model imageUrl: Url @migrationSkip image: LaravelMediaLibraryData @migrationSkip @laravelMediaLibraryData( collection: "image" singleFile: true fields: ["url", "description"] ) }
您的查询将看起来像这样
query($id: ID!) { post(id: $id) { id # ... other fields imageUrl # this will return the image url } }
我如何在查询中获取完整图像数据?
只需在您的类型中定义 LaravelMediaLibraryData
字段。示例
type Post { image: [LaravelMediaLibraryData!] @migrationSkip @laravelMediaLibraryData( collection: "image" fields: ["url", "description"] ) }
在您的查询中获取字段
query($id: ID!) { post(id: $id) { id # ... other fields image { url # the url, a String fields # a JSON-encoded string with your custom fields if they exist } } }
您也可以轻松地获取第一个
type Post { image: [LaravelMediaLibraryData!] @migrationSkip @laravelMediaLibraryData( collection: "image" fields: ["url", "description"] ) # add this to get the first one: imageFirst: LaravelMediaLibraryData @migrationSkip }
在您的查询中
query($id: ID!) { post(id: $id) { id # ... other fields imageFirst { url # the url, a String fields # a JSON-encoded string with your custom fields if they exist } } }
我想要一个集合中的单个图像,永远不会超过一个。我该如何做?
声明一个 singleFile
集合。注意,这里的返回类型是一个单独的 LaravelMediaLibraryData
,而不是数组
type Post { image: LaravelMediaLibraryData @migrationSkip @laravelMediaLibraryData( collection: "image" singleFile: true fields: ["url", "description"] ) # the [collection]First attribute is also available, so you can mix it with non-singleFile collections: imageFirst: LaravelMediaLibraryData @migrationSkip }
然后正常访问它
query($id: ID!) { post(id: $id) { id # ... other fields image { url # the url, a String fields # a JSON-encoded string with your custom fields if they exist } } }
我如何添加缩略图?
添加一个 conversions
字段。将为每个集合创建两个访问器方法:[CollectionName][ConversionName]HTML
(生成完整的 HTML 标签)和 [CollectionName][ConversionName]Url
(仅 URL)。将它们添加到您的 GraphQL 类型中(并记得 @migrationSkip
它们)以访问它们。示例
type Post { image: LaravelMediaLibraryData @migrationSkip @eagerLoad(name: "media") @laravelMediaLibraryData( collection: "image" conversions: [{ name: "thumb", width: 128, height: 128 }] ) imageThumbHTML: String @migrationSkip @renderable(show: true) imageThumbUrl: Url @migrationSkip @renderable(show: true) }
易于获取
query($id: ID!) { post(id: $id) { id # ... other fields imageThumbUrl } }
我如何在查询中获取响应式图像数据?
添加一个具有 responsive: true
的 conversions
字段。
type Post { image: LaravelMediaLibraryData @migrationSkip @eagerLoad(name: "media") @laravelMediaLibraryData( collection: "image" conversions: [{ name: "thumb", responsive: true}] ) }
待办事项:解释如何获取数据
我如何预加载?
添加一个 @eagerLoad
指令以预加载表并避免 N+1 问题。
type Post { image: LaravelMediaLibraryData @migrationSkip @eagerLoad(name: "media") @laravelMediaLibraryData( collection: "image" fields: ["url", "description"] ) }
赞助商
我们想感谢 Spatie 及其出色的 Spatie 的 Laravel Media Library。
贡献 
欢迎任何贡献。请发送 PR。