首页 > 解决方案 > How to override the existing method of an existing class, FlysystemAssetStore that is part of the framework in SilverStripe

问题描述

I am working on a SilverStripe project, in my project, I need to change the behavior of a class that is part of the SilverStripe framework. The class I need to modify is SilverStripe\Assets\Flysystem\FlysystemAssetStore. For example, I am now trying to modify the exists method of the class. I tried using two options Injector and Extension. Both did not work.

The first option I tried is using the Injector. This is what I did.

First, I created a class called, CustomFlysystemAssetStore.

Then I added the following code to the mysite.yml

SilverStripe\Assets\Flysystem\FlysystemAssetStore:
    class: CustomFlysystemAssetStore

I declared the public function called exists in the CustomFlysystemAssetStore class to override the existing behavior. But it did not work. The new method within the new class was not executed at all.

The second option I tried is using the Extension. This is what I did.

First, I created a class called CustomFlysystemAssetStore that is extending the DataExtension class.

Then, I added the following code snippet into the mysite.yml.

SilverStripe\Assets\Flysystem\FlysystemAssetStore:
  extensions:
    - CustomFlysystemAssetStore

Then I declared a public method in the new class called exists to see if the new method is called.

Unfortunately, the second approach did not work either. How can I override the methods of the SilverStripe\Assets\Flysystem\FlysystemAssetStore class that is part of the framework?

This is my assets.yml file

---
Name: silverstripes3-flysystem
Only:
  envvarset: AWS_BUCKET_NAME
After:
  - '#assetsflysystem'
---
SilverStripe\Core\Injector\Injector:
  Aws\S3\S3Client:
    constructor:
      configuration:
        region: '`AWS_REGION`'
        version: latest
  League\Flysystem\Adapter\Local:
    class: League\Flysystem\Adapter\Local
    constructor:
      root: '`TEMP_PATH`'

  SilverStripe\S3\Adapter\PublicAdapter:
    constructor:
      s3Client: '%$Aws\S3\S3Client'
      bucket: '`AWS_BUCKET_NAME`'
      prefix: '`AWS_PUBLIC_BUCKET_PREFIX`'
  League\Flysystem\Cached\Storage\Memory.public:
    class: League\Flysystem\Cached\Storage\Memory
  League\Flysystem\Cached\Storage\Adapter.public:
    class: League\Flysystem\Cached\Storage\Adapter
    constructor:
      adapter: '%$League\Flysystem\Adapter\Local'
      file: 's3metadata/public'
      expire: 259200
  SilverStripe\Assets\Flysystem\PublicAdapter:
    class: SilverStripe\S3\Adapter\PublicCachedAdapter
    constructor:
      adapter: '%$SilverStripe\S3\Adapter\PublicAdapter'
      cache: '%$League\Flysystem\Cached\Storage\Adapter.public'

  SilverStripe\S3\Adapter\ProtectedAdapter:
    constructor:
      s3Client: '%$Aws\S3\S3Client'
      bucket: '`AWS_BUCKET_NAME`'
      prefix: '`AWS_PROTECTED_BUCKET_PREFIX`'
  League\Flysystem\Cached\Storage\Adapter.protected:
    class: League\Flysystem\Cached\Storage\Adapter
    constructor:
      adapter: '%$League\Flysystem\Adapter\Local'
      file: 's3metadata/protected'
      expire: 259200
  SilverStripe\Assets\Flysystem\ProtectedAdapter:
    class: SilverStripe\S3\Adapter\ProtectedCachedAdapter
    constructor:
      adapter: '%$SilverStripe\S3\Adapter\ProtectedAdapter'
      cache: '%$League\Flysystem\Cached\Storage\Adapter.protected'
#---
Name: silverstripes3-assetscore
Only:
  envvarset: AWS_BUCKET_NAME
After:
  - '#assetscore'
---
SilverStripe\Core\Injector\Injector:
  SilverStripe\Assets\Storage\AssetStore:
    class: CustomFlysystemAssetStore

标签: silverstripesilverstripe-4

解决方案


在 Silverstripe 4.5 中,我们可以扩展FlysystemAssetStore和定义我们自己的exists方法。

首先我们在项目中创建一个CustomFlysystemAssetStore.php文件:

app/src/CustomFlysystemAssetStore.php

use SilverStripe\Assets\Flysystem\FlysystemAssetStore;

class CustomFlysystemAssetStore extends FlysystemAssetStore {

    public function exists($filename, $hash, $variant = null)
    {
        // Custom logic goes here
        // ...

        // Fallback to the parent exists function
        return parent::exists($filename, $hash, $variant);
    }
}

然后我们将其设置为AssetStore我们希望系统通过 yml 配置文件使用的值。我们创建一个assets.yml文件:

app/_config/assets.yml

---
Name: app-assetscore
After:
  - '#assetscore'
---

SilverStripe\Core\Injector\Injector:
  SilverStripe\Assets\Storage\AssetStore:
    class: CustomFlysystemAssetStore

推荐阅读