Completed
Push — master ( deca00...5388ff )
by Sam
24s
created

TestAssetStore::getOriginalFilename()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Assets\Tests\Storage\AssetStoreTest;
4
5
use League\Flysystem\Adapter\Local;
6
use League\Flysystem\AdapterInterface;
7
use League\Flysystem\Filesystem;
8
use SilverStripe\Assets\Filesystem as SSFilesystem;
9
use SilverStripe\Assets\Flysystem\FlysystemAssetStore;
10
use SilverStripe\Assets\Flysystem\ProtectedAssetAdapter;
11
use SilverStripe\Assets\Flysystem\PublicAssetAdapter;
12
use SilverStripe\Assets\Storage\AssetContainer;
13
use SilverStripe\Assets\Flysystem\GeneratedAssetHandler;
14
use SilverStripe\Assets\Storage\DBFile;
15
use SilverStripe\Assets\File;
16
use SilverStripe\Assets\Folder;
17
use SilverStripe\Control\Director;
18
use SilverStripe\Core\Injector\Injector;
19
use SilverStripe\View\Requirements;
20
21
/**
22
 * Allows you to mock a backend store in a custom directory beneath assets.
23
 */
24
class TestAssetStore extends FlysystemAssetStore
25
{
26
    /**
27
     * Enable disclosure of secure assets
28
     *
29
     * @config
30
     * @var    int
31
     */
32
    private static $denied_response_code = 403;
33
34
    /**
35
     * Set to true|false to override all isSeekableStream calls
36
     *
37
     * @var null|bool
38
     */
39
    public static $seekable_override = null;
40
41
    /**
42
     * Base dir of current file
43
     *
44
     * @var string
45
     */
46
    public static $basedir = null;
47
48
    /**
49
     * Set this store as the new asset backend
50
     *
51
     * @param string $basedir Basedir to store assets, which will be placed beneath 'assets' folder
52
     */
53
    public static function activate($basedir)
54
    {
55
        // Assign this as the new store
56
        $publicAdapter = new PublicAssetAdapter(ASSETS_PATH . '/' . $basedir);
57
        $publicFilesystem = new Filesystem(
58
            $publicAdapter,
59
            [
60
            'visibility' => AdapterInterface::VISIBILITY_PUBLIC
61
            ]
62
        );
63
        $protectedAdapter = new ProtectedAssetAdapter(ASSETS_PATH . '/' . $basedir . '/.protected');
64
        $protectedFilesystem = new Filesystem(
65
            $protectedAdapter,
66
            [
67
            'visibility' => AdapterInterface::VISIBILITY_PRIVATE
68
            ]
69
        );
70
71
        $backend = new TestAssetStore();
72
        $backend->setPublicFilesystem($publicFilesystem);
73
        $backend->setProtectedFilesystem($protectedFilesystem);
74
        Injector::inst()->registerService($backend, 'AssetStore');
75
76
        // Assign flysystem backend to generated asset handler at the same time
77
        $generated = new GeneratedAssetHandler();
78
        $generated->setFilesystem($publicFilesystem);
79
        Injector::inst()->registerService($generated, 'GeneratedAssetHandler');
80
        Requirements::backend()->setAssetHandler($generated);
81
82
        // Disable legacy and set defaults
83
        FlysystemAssetStore::config()->set('legacy_filenames', false);
84
        Director::config()->set('alternate_base_url', '/');
85
        DBFile::config()->set('force_resample', false);
86
        File::config()->set('force_resample', false);
87
        self::reset();
88
        self::$basedir = $basedir;
89
90
        // Ensure basedir exists
91
        SSFilesystem::makeFolder(self::base_path());
92
    }
93
94
    /**
95
     * Get absolute path to basedir
96
     *
97
     * @return string
98
     */
99
    public static function base_path()
100
    {
101
        if (!self::$basedir) {
102
            return null;
103
        }
104
        return ASSETS_PATH . '/' . self::$basedir;
105
    }
106
107
    /**
108
     * Reset defaults for this store
109
     */
110
    public static function reset()
111
    {
112
        // Remove all files in this store
113
        if (self::$basedir) {
114
            $path = self::base_path();
115
            if (file_exists($path)) {
116
                SSFilesystem::removeFolder($path);
117
            }
118
        }
119
        self::$seekable_override = null;
120
        self::$basedir = null;
121
    }
122
123
    /**
124
     * Helper method to get local filesystem path for this file
125
     *
126
     * @param  AssetContainer $asset
127
     * @return string
128
     */
129
    public static function getLocalPath(AssetContainer $asset)
130
    {
131
        if ($asset instanceof Folder) {
132
            return self::base_path() . '/' . $asset->getFilename();
133
        }
134
        if ($asset instanceof File) {
135
            $asset = $asset->File;
136
        }
137
        // Extract filesystem used to store this object
138
        /** @var TestAssetStore $assetStore */
139
        $assetStore = Injector::inst()->get('AssetStore');
140
        $fileID = $assetStore->getFileID($asset->Filename, $asset->Hash, $asset->Variant);
0 ignored issues
show
Bug introduced by
Accessing Filename on the interface SilverStripe\Assets\Storage\AssetContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
Accessing Hash on the interface SilverStripe\Assets\Storage\AssetContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
Accessing Variant on the interface SilverStripe\Assets\Storage\AssetContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
141
        $filesystem = $assetStore->getProtectedFilesystem();
142
        if (!$filesystem->has($fileID)) {
143
            $filesystem = $assetStore->getPublicFilesystem();
144
        }
145
        /** @var Local $adapter */
146
        $adapter = $filesystem->getAdapter();
147
        return $adapter->applyPathPrefix($fileID);
148
    }
149
150
    public function cleanFilename($filename)
151
    {
152
        return parent::cleanFilename($filename);
153
    }
154
155
    public function getFileID($filename, $hash, $variant = null)
156
    {
157
        return parent::getFileID($filename, $hash, $variant);
158
    }
159
160
161
    public function getOriginalFilename($fileID)
162
    {
163
        return parent::getOriginalFilename($fileID);
164
    }
165
166
    public function removeVariant($fileID)
167
    {
168
        return parent::removeVariant($fileID);
169
    }
170
171
    public function getDefaultConflictResolution($variant)
172
    {
173
        return parent::getDefaultConflictResolution($variant);
174
    }
175
176
    protected function isSeekableStream($stream)
177
    {
178
        if (isset(self::$seekable_override)) {
179
            return self::$seekable_override;
180
        }
181
        return parent::isSeekableStream($stream);
182
    }
183
}
184