Skip to content
This repository was archived by the owner on Sep 23, 2025. It is now read-only.
Merged
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
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
"v6.5.8.2",
"6.5.x",
"v6.6.0.3",
"v6.6.8.1",
"trunk"
]
php: ["8.2"]
Expand Down Expand Up @@ -70,4 +71,4 @@ jobs:
with:
files: ./clover.xml
root_dir: ${{ github.workspace }}/custom/plugins/${{ env.PLUGIN_NAME }}
working-directory: ${{ github.workspace }}/custom/plugins/${{ env.PLUGIN_NAME }}
working-directory: ${{ github.workspace }}/custom/plugins/${{ env.PLUGIN_NAME }}
5 changes: 5 additions & 0 deletions CHANGELOG_en-GB.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 3.4.0

* Feat: (for Shopware >= 6.6.8.0) Add support for writeBatch.
With this you can use storage for theme and asset with more speed. Instead of 2,5 hours it now takes 30 seconds for assets on storage with SSD with demo shop.

# 3.3.3

* Fix: correct config message for Shopware >6.6.3.0
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ https://github.com/FriendsOfShopware/FroshPlatformBunnycdnMediaStorage/releases/

## Recommendations and warnings

- Don't store theme or asset files on external storage if possible. Due to some improvements in shopware with 6.5 and 6.6 there are created many files. This is the reason why this would slow down theme compilation and asset installation significantly.
- Before Shopware 6.6.8.0 and plugin version 3.4.0: Don't store theme or asset files on external storage. Due to some improvements in shopware with 6.5 and 6.6 there are created many files. This is the reason why this would slow down theme compilation and asset installation significantly.
- Utilize storage zones with SSDs as they are significantly faster than standard option (means HDDs), with up to 80x faster upload speeds in our tests.

## Suggestions
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
],
"require": {
"shopware/core": "~6.5.3||~6.6.0",
"platformcommunity/flysystem-bunnycdn": "^3.3.4",
"platformcommunity/flysystem-bunnycdn": "^3.3.5",
"league/flysystem-path-prefixing": "^3.10.3",
"ajgl/flysystem-replicate": "^2.2",
"tinect/flysystem-garbage": "^1.0"
Expand Down
12 changes: 11 additions & 1 deletion src/Adapter/BunnyCdnFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use League\Flysystem\Local\LocalFilesystemAdapter;
use League\Flysystem\PathPrefixing\PathPrefixedAdapter;
use Shopware\Core\Framework\Adapter\Filesystem\Adapter\AdapterFactoryInterface;
use Shopware\Core\Framework\Adapter\Filesystem\Plugin\WriteBatchInterface;
use Tinect\Flysystem\Garbage\GarbageFilesystemAdapter;

class BunnyCdnFactory implements AdapterFactoryInterface
Expand All @@ -19,7 +20,7 @@ public function create(array $config): FilesystemAdapter
$adapterConfig = new AdapterConfig();
$adapterConfig->assign($config);

$adapter = new Shopware6BunnyCdnAdapter($adapterConfig);
$adapter = $this->getBasicAdapter($adapterConfig);

if (!empty($adapterConfig->isUseGarbage())) {
$adapter = new GarbageFilesystemAdapter($adapter);
Expand All @@ -36,6 +37,15 @@ public function create(array $config): FilesystemAdapter
return $adapter;
}

private function getBasicAdapter(AdapterConfig $adapterConfig): FilesystemAdapter
{
if (\interface_exists(WriteBatchInterface::class)) {
return new Shopware6BunnyCdnWriteBatchAdapter($adapterConfig);
}

return new Shopware6BunnyCdnAdapter($adapterConfig);
}

public function getType(): string
{
return 'bunnycdn';
Expand Down
70 changes: 70 additions & 0 deletions src/Adapter/Shopware6BunnyCdnWriteBatchAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php declare(strict_types=1);

namespace Frosh\BunnycdnMediaStorage\Adapter;

use League\Flysystem\Config;
use PlatformCommunity\Flysystem\BunnyCDN\WriteBatchFile;
use Shopware\Core\Framework\Adapter\Filesystem\Plugin\CopyBatchInput;
use Shopware\Core\Framework\Adapter\Filesystem\Plugin\WriteBatchInterface;

if (!\interface_exists(WriteBatchInterface::class)) {
class Shopware6BunnyCdnWriteBatchAdapter extends Shopware6BunnyCdnAdapter
{}
} else {
class Shopware6BunnyCdnWriteBatchAdapter extends Shopware6BunnyCdnAdapter implements WriteBatchInterface
{
public function writeBatch(CopyBatchInput|array|Config ...$input): void
{
$files = [];
$config = new Config();

foreach ($input as $data) {
if ($data instanceof CopyBatchInput) {
// migrate CopyBatchInput of Shopware to WriteBatchFile
foreach ($data->getTargetFiles() as $targetFile) {
$sourceFile = $data->getSourceFile();

if (\is_string($sourceFile)) {
$files[] = new WriteBatchFile($sourceFile, $targetFile);

continue;
}

$metaData = stream_get_meta_data($sourceFile);
if (empty($metaData['uri'])) {
throw new \InvalidArgumentException('Cannot get source file path from stream.');
}

$sourcePath = $metaData['uri'];

$files[] = new WriteBatchFile($sourcePath, $targetFile);
}

continue;
}

if ($data instanceof Config) {
$config = $data;

continue;
}

if (\is_array($data)) {
foreach ($data as $item) {
if (!$item instanceof WriteBatchFile) {
throw new \InvalidArgumentException('Each value of array must be a WriteBatchFile object.');
}

$files[] = $item;
}
}
}

if (empty($files)) {
return;
}

parent::writeBatch($files, $config);
}
}
}
15 changes: 15 additions & 0 deletions tests/unit/Adapter/BunnyCdnFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
use Ajgl\Flysystem\Replicate\ReplicateFilesystemAdapter;
use Frosh\BunnycdnMediaStorage\Adapter\BunnyCdnFactory;
use Frosh\BunnycdnMediaStorage\Adapter\Shopware6BunnyCdnAdapter;
use Frosh\BunnycdnMediaStorage\Adapter\Shopware6BunnyCdnWriteBatchAdapter;
use League\Flysystem\PathPrefixing\PathPrefixedAdapter;
use PHPUnit\Framework\TestCase;
use Shopware\Core\Framework\Adapter\Filesystem\Plugin\WriteBatchInterface;
use Tinect\Flysystem\Garbage\GarbageFilesystemAdapter;

class BunnyCdnFactoryTest extends TestCase
Expand Down Expand Up @@ -47,6 +49,19 @@ public function testFactoryCreatesReplicateFilesystemAdapter(): void
static::assertInstanceOf(ReplicateFilesystemAdapter::class, $adapter);
}

public function testFactoryCreatesWriteBatchAdapter(): void
{
if (!\interface_exists(WriteBatchInterface::class)) {
static::markTestSkipped('WriteBatchInterface not found');
}

$factory = new BunnyCdnFactory();
$config = ['endpoint' => 'https://storage.bunnycdn.com', 'apiKey' => 'a', 'storageName' => 'a', 'useGarbage' => false];
$adapter = $factory->create($config);

static::assertInstanceOf(WriteBatchInterface::class, $adapter);
}

public function testFactoryReturnsBunnycdnType(): void
{
$factory = new BunnyCdnFactory();
Expand Down
Loading