Skip to content

Feature/shopware 145 add plugin logic #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes from 5 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
Empty file added .env.test
Empty file.
46 changes: 46 additions & 0 deletions .github/workflows/apply-coding-standard.app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Apply Coding Standard

on:
push:
branches:
- main
paths:
- 'src/**'

permissions:
contents: write
pull-requests: write

jobs:
php-coding-standard:
name: 'Apply PHP Coding Standard'
runs-on: ubuntu-latest
steps:
- name: 'Checkout Code'
uses: actions/checkout@v4

- name: 'Composer install'
uses: netlogix/actions/.github/actions/composer-install@main
with:
php-version: '8.2'
github_token: ${{ secrets.COMPOSER_AUTH }}

- name: 'ECS PHP Code'
shell: bash
run: composer lint-fix

- name: 'Create pull-request'
uses: peter-evans/create-pull-request@v7
with:
commit-message: "[automated] Apply Coding Standard"
branch: 'automated-apply-coding-standards'
title: '[automated] Apply Coding Standard'
labels: 'automated'
delete-branch: true
token: ${{ secrets.GITHUB_TOKEN }}

- name: 'Enable Pull Request Merge when ready'
if: steps.cpr.outputs.pull-request-operation == 'created'
run: gh pr merge --auto "${{ steps.cpr.outputs.pull-request-number }}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53 changes: 53 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Tests

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build-platform:
name: 'Test'
runs-on: ubuntu-latest

steps:
- name: 'Checkout Code'
uses: actions/checkout@v3

- uses: netlogix/actions/.github/actions/composer-install@main
with:
php-version: '8.2'
coverage: 'xdebug3'
args: '--prefer-dist --no-progress --no-interaction --optimize-autoloader'
github_token: ${{ secrets.COMPOSER_AUTH }}

- name: 'Run Unit Tests'
shell: bash
env:
XDEBUG_MODE: 'coverage'
run: vendor/bin/phpunit --coverage-clover Build/Artifacts/Reports/Unit/clover.xml

- name: 'Generate Unit Test Code Coverage Summary Report'
uses: saschanowak/CloverCodeCoverageSummary@0.3.1
with:
filename: Build/Artifacts/Reports/Unit/clover.xml

- name: 'Add Unit Test Code Coverage to file'
shell: bash
run: |
echo '## Code Coverage Summery for unit tests' >> code-coverage-merged.md
cat code-coverage-summary.md >> code-coverage-merged.md

echo '## Code Coverage for unit tests' >> $GITHUB_STEP_SUMMARY
cat code-coverage-summary.md >> $GITHUB_STEP_SUMMARY
cat code-coverage-details.md >> $GITHUB_STEP_SUMMARY

- name: 'Add Code Coverage as PR Comment'
uses: marocchino/sticky-pull-request-comment@v2
if: github.event_name == 'pull_request'
with:
recreate: true
path: code-coverage-merged.md
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/src/Resources/app/storefront/dist/
/.phpunit.result.cache
/.phpunit.cache
/vendor/
composer.lock
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ composer require netlogix/nlxShopwreImageProxy

Use the image proxy `darthsim/imgproxy` in your docker-compose file to quickly and easily resize images.

Define IMAGE_PROXY_HOST in your .env file to set the image proxy host.

For signing URLs you have to define the following environment variables:
- IMGPROXY_KEY: hex-encoded key
- IMGPROXY_SALT: hex-encoded salt
Expand Down
40 changes: 40 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "netlogix/nlxshopwareimageproxy",
"version": "v1.0.0",
"description": "Plugin to allow shopware to authenticate and support image proxy",
"type": "shopware-platform-plugin",
"license": "MIT",
"autoload": {
"psr-4": {
"nlxShopwareImageProxy\\": "src/"
}
},
"require": {
"shopware/core": "dev-trunk"
},
"require-dev": {
"php": ">= 8.2",
"phpunit/phpunit": "^12.0",
"netlogix/coding-guidelines-php": "^1.0"
},
"conflict": {
"shopware/core": "<6.7.0"
},
"scripts": {
"lint": "ecs check",
"lint-fix": "ecs check --fix",
"unit": "vendor/bin/phpunit tests/Unit"
},
"extra": {
"shopware-plugin-class": "nlxShopwareImageProxy\\nlxShopwareImageProxy",
"label": {
"de-DE": "Bilder Proxy Unterstützung",
"en-GB": "Image proxy support"
}
},
"config": {
"allow-plugins": {
"symfony/runtime": true
}
}
}
16 changes: 16 additions & 0 deletions ecs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

use Netlogix\CodingGuidelines\Php\DefaultPhp;
use Symplify\EasyCodingStandard\Config\ECSConfig;

return static function (ECSConfig $ecsConfig): void {
(new DefaultPhp())->configure($ecsConfig);

$ecsConfig->paths(
[
__DIR__ . '/src',
]
);
};
38 changes: 38 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>

<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
cacheDirectory=".phpunit.cache"
executionOrder="random"
requireCoverageMetadata="true"
beStrictAboutCoverageMetadata="true"
beStrictAboutOutputDuringTests="true"
displayDetailsOnPhpunitDeprecations="true"
failOnPhpunitDeprecation="true"
failOnRisky="true"
failOnWarning="true">

<php>
<ini name="display_errors" value="1" />
<ini name="error_reporting" value="-1" />
<server name="APP_ENV" value="test" force="true" />
<server name="SHELL_VERBOSITY" value="-1" />
</php>

<testsuites>
<testsuite name="unit">
<directory>./tests/Unit/</directory>
</testsuite>
</testsuites>

<coverage ignoreDeprecatedCodeUnits="true"
disableCodeCoverageIgnore="true">
</coverage>

<source>
<include>
<directory >src</directory>
</include>
</source>
</phpunit>
20 changes: 20 additions & 0 deletions src/DTO/ImageProxyOptionDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

/*
* Created by netlogix GmbH & Co. KG
*
* @copyright netlogix GmbH & Co. KG
*/

namespace nlxShopwareImageProxy\DTO;

class ImageProxyOptionDTO
{
public function __construct(
public readonly string $width,
public readonly string $height,
) {
}
}
31 changes: 31 additions & 0 deletions src/Decorators/MediaUrlGeneratorDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

/*
* Created by netlogix GmbH & Co. KG
*
* @copyright netlogix GmbH & Co. KG
*/

namespace nlxShopwareImageProxy\Decorators;

use nlxShopwareImageProxy\Services\UrlGeneratorInterface;
use Shopware\Core\Content\Media\Core\Application\AbstractMediaUrlGenerator;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;

#[AsDecorator(decorates: AbstractMediaUrlGenerator::class)]
class MediaUrlGeneratorDecorator extends AbstractMediaUrlGenerator
{
public function __construct(
private readonly UrlGeneratorInterface $urlGenerator
) {
}

public function generate(array $paths): array
{
return array_map(function ($value) {
return $this->urlGenerator->generateUrl($value->path);
}, $paths);
}
}
45 changes: 45 additions & 0 deletions src/Services/UrlGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

/*
* Created by netlogix GmbH & Co. KG
*
* @copyright netlogix GmbH & Co. KG
*/

namespace nlxShopwareImageProxy\Services;

use nlxShopwareImageProxy\DTO\ImageProxyOptionDTO;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

class UrlGenerator implements UrlGeneratorInterface
{
public function __construct(
#[Autowire(env: 'default::string:IMGPROXY_KEY')]
private ?string $imgProxySecret,
#[Autowire(env: 'default::string:IMGPROXY_SALT')]
private ?string $imgProxySalt,
#[Autowire(env: 'default::string:IMAGE_PROXY_HOST')]
private ?string $imageProxyHost,
) {
$this->imgProxySecret = pack("H*", $imgProxySecret);
$this->imgProxySalt = pack("H*", $imgProxySalt);
}

public function generateUrl(string $imagePath, ?ImageProxyOptionDTO $imageProxyOption = null): string
{
$mediaPath = 'local://' . $imagePath;
$path = rtrim(strtr(base64_encode($mediaPath), '+/', '-_'), '=');

if ($imageProxyOption !== null) {
$path = sprintf('resize:fit:%s:%s:no:0/%s', $imageProxyOption->width, $imageProxyOption->height, $path);
}

$sha256 = hash_hmac('sha256', $this->imgProxySalt . '/' . $path, $this->imgProxySecret, true);
$sha256Encoded = base64_encode($sha256);
$signature = str_replace(["+", "/", "="], ["-", "_", ""], $sha256Encoded);

return sprintf('%s/%s/%s', $this->imageProxyHost, $signature, $path);
}
}
18 changes: 18 additions & 0 deletions src/Services/UrlGeneratorInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

/*
* Created by netlogix GmbH & Co. KG
*
* @copyright netlogix GmbH & Co. KG
*/

namespace nlxShopwareImageProxy\Services;

use nlxShopwareImageProxy\DTO\ImageProxyOptionDTO;

interface UrlGeneratorInterface
{
public function generateUrl(string $imagePath, ?ImageProxyOptionDTO $imageProxyOption = null): string;
}
35 changes: 35 additions & 0 deletions src/Subscriber/RemoteThumbnailUrlExtensionSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

/*
* Created by netlogix GmbH & Co. KG
*
* @copyright netlogix GmbH & Co. KG
*/

namespace nlxShopwareImageProxy\Subscriber;

use nlxShopwareImageProxy\DTO\ImageProxyOptionDTO;
use nlxShopwareImageProxy\Services\UrlGeneratorInterface;
use Shopware\Core\Content\Media\Extension\ResolveRemoteThumbnailUrlExtension;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

#[AsEventListener(ResolveRemoteThumbnailUrlExtension::NAME . '.pre')]
class RemoteThumbnailUrlExtensionSubscriber
{
public function __construct(
private readonly UrlGeneratorInterface $urlGenerator,
) {
}

public function __invoke(ResolveRemoteThumbnailUrlExtension $extension): void
{
$extension->stopPropagation();

$extension->result = $this->urlGenerator->generateUrl(
$extension->mediaPath,
new ImageProxyOptionDTO(width: $extension->width, height: $extension->height),
);
}
}
17 changes: 17 additions & 0 deletions src/nlxShopwareImageProxy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

/*
* Created by netlogix GmbH & Co. KG
*
* @copyright netlogix GmbH & Co. KG
*/

namespace nlxShopwareImageProxy;

use Shopware\Core\Framework\Plugin;

class nlxShopwareImageProxy extends Plugin
{
}
Loading
Loading