corollarium/modelarium-medialibrary 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

corollarium/modelarium-medialibrary

Composer 安装命令:

composer require corollarium/modelarium-medialibrary

包简介

Integrates Spatie Laravel-media-library with Modelarium and GraphQL

README 文档

README

Latest Stable Version Total Downloads License

This package integrates Spatie's Laravel Media Library to Modelarium, allowing GraphQL queries with LighthousePHP to easily access media on models.

Installing

On your Laravel app run:

composer require corollarium/modelarium-medialibrary

Quick overview

This a Graphql file for a model with two different media collections, "image" and "map". Both have extra fields, "url" and "description". "Map" also has a conversion "thumb" with 150x150 (max, maintaining aspect ratio) thumbnails.

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 will automatically generate roughly the following code on your model class:

/** 
 * 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...
}

Documentation

The @laravelMediaLibraryData directive supports the following arguments:

TODO

FAQ

I need some custom conversion on my collection.

If the basic arguments on the directive are not enough, just override the method on your model class:

class Post extends BasePost 
{
    public function registerMediaConversions(?\Spatie\MediaLibrary\MediaCollections\Models\Media $media = null): void
    {
        // do your stuff here
    }
}

How do I get only the image url for a single image in my type?

Define a xxxUrl on your type, where xxx is your collection name. which is filled automatically by the attribute method on the model. Don't forget to add @migrationSkip so it won't be created in the migration. Example:

type Post { 
    # ...

    # this field is filled automatically by the model
    imageUrl: Url @migrationSkip

    image: LaravelMediaLibraryData
        @migrationSkip
        @laravelMediaLibraryData(
            collection: "image"
            singleFile: true
            fields: ["url", "description"]
        )
}

your query will look like this:

query($id: ID!) {
    post(id: $id) {
        id

        # ... other fields

        imageUrl # this will return the image url
    }
}

How do I get the full image data in a query?

Just define the LaravelMediaLibraryData field in your type. Example:

type Post { 
    image: [LaravelMediaLibraryData!]
        @migrationSkip
        @laravelMediaLibraryData(
            collection: "image"
            fields: ["url", "description"]
        )
}

On your query, fetch the field

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
        }
    }
}

You can easily access only the first one too:

type Post { 
    image: [LaravelMediaLibraryData!]
        @migrationSkip
        @laravelMediaLibraryData(
            collection: "image"
            fields: ["url", "description"]
        )
    
    # add this to get the first one:
    imageFirst: LaravelMediaLibraryData @migrationSkip
}

In your query:

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
        }
    }
}

I want a single image in the collection, never more than one. How do I do that?

Declare a singleFile collection. Notice that the return type here is a single LaravelMediaLibraryData, not an array:

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

}

Then access it normally:

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
        }
    }
}

How do I add thumbnails?

Add a conversions field. Two accessor methods will be created on your model for each collection: [CollectionName][ConversionName]HTML (which generates the full HTML tag) and [CollectionName][ConversionName]Url (just the URL). Add them to your GraphQL type (and remember to @migrationSkip them) to access them. Example:

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)

}

Easy to fetch:

query($id: ID!) {
    post(id: $id) {
        id

        # ... other fields

        imageThumbUrl
    }
}

How do I get the responsive image data in a query?

Add a conversions field with responsive: true.

type Post { 
    image: LaravelMediaLibraryData
        @migrationSkip
        @eagerLoad(name: "media")
        @laravelMediaLibraryData(
            collection: "image"
            conversions: [{ name: "thumb",  responsive: true}]
        )
}

TODO: explain how to get data

How do I eager load?

Add an @eagerLoad directive to eager load the table and avoid a N+1 problem.

type Post { 
    image: LaravelMediaLibraryData
        @migrationSkip
        @eagerLoad(name: "media")
        @laravelMediaLibraryData(
            collection: "image"
            fields: ["url", "description"]
        )
}

Sponsors

Corollarium

We want to thanks to Spatie for its wonderful Spatie's Laravel Media Library.

Contributing contributions welcome

Any contributions are welcome. Please send a PR.

corollarium/modelarium-medialibrary 适用场景与选型建议

corollarium/modelarium-medialibrary 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 15 次下载、GitHub Stars 达 0, 最近一次更新时间为 2020 年 12 月 27 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「media」 「web」 「laravel」 「graphql」 「modelarium」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 corollarium/modelarium-medialibrary 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 corollarium/modelarium-medialibrary 我们能提供哪些服务?
定制开发 / 二次开发

基于 corollarium/modelarium-medialibrary 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 15
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2020-12-27