Communitygithub.com

dpaguba/shopware-skill

๐Ÿ›๏ธ Comprehensive agent skill for Shopware 6 development: plugins, DAL, Admin (Vue.js), Storefront (Twig/SCSS), themes, APIs, testing

shopware-skill๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

shopware-skill is a Claude Code agent skill that ๐Ÿ›๏ธ Comprehensive agent skill for Shopware 6 development: plugins, DAL, Admin (Vue.js), Storefront (Twig/SCSS), themes, APIs, testing.

์ง€์› ๋Œ€์ƒ~Claude Code~Codex CLI~Cursor
npx skills add dpaguba/shopware-skill

์ฆ๊ฒจ ์‚ฌ์šฉํ•˜๋Š” AI์—๊ฒŒ ๋ฌผ์–ด๋ณด๊ธฐ

์ด ์—์ด์ „ํŠธ ์Šคํ‚ฌ์ด ๋ฏธ๋ฆฌ ๋กœ๋“œ๋œ ์ƒˆ ์ฑ„ํŒ…์„ ์—ฝ๋‹ˆ๋‹ค.

๋ฌธ์„œ

Shopware 6 Development

Core Architecture

Shopware 6 is a PHP/Symfony platform. Clarify which layer is being targeted before generating code:

LayerTechWhere
Core / PHPPHP 8.2+, Symfony 7.4 (SW 6.7) / Symfony 7.0 (SW 6.6)src/ โ€” Services, DAL, Events
StorefrontTwig 3, SCSS, Vanilla JS, Vite dev server (6.7.11+)src/Resources/views/storefront/
AdminVue 3, Pinia, Meteor components (mt-*), Vite buildsrc/Resources/app/administration/
App Systemmanifest.xml (schema 3.0 in 6.7), App ScriptsExternal server or Twig scripts (no PHP needed)

Plugin vs App System: Use Plugin for self-hosted installs needing direct PHP/DB access. Use App System for SaaS/multi-tenant or when targeting the Shopware Store.

Which version is this?

Ask or infer the target version before generating code. The current line is 6.7.13.x; 6.8 is planned for 2027. 6.7 broke a lot of plugin-facing API, so code that is correct for 6.6 is often wrong for 6.7:

TopicSW 6.6SW 6.7
Payment handlerSynchronous/AsynchronousPaymentHandlerInterfaceAbstractPaymentHandler
Admin componentssw-button, sw-card, sw-text-fieldmt-button, mt-card, mt-text-field
Admin stateVuex Shopware.State (deprecated)Pinia Shopware.Store only
Admin buildWebpackVite
EntityExtensiongetDefinitionClass()plus abstract getEntityName()
Plugin custom entitiesentities.xmlremoved, use EntityDefinition
IdsCollectionShopware\Core\Framework\Test\Shopware\Core\Test\Stub\Framework\

Full list in references/migration-6.7.md. When the version is unknown, target 6.7 and mention what differs on 6.6.


Plugin Structure

PluginName/
โ”œโ”€โ”€ composer.json
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ PluginName.php          # Bootstrap class
โ”‚   โ”œโ”€โ”€ Resources/
โ”‚   โ”‚   โ”œโ”€โ”€ config/
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ services.xml    # Symfony DI container
โ”‚   โ”‚   โ”œโ”€โ”€ views/
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ storefront/     # Twig template overrides
โ”‚   โ”‚   โ””โ”€โ”€ app/
โ”‚   โ”‚       โ””โ”€โ”€ administration/ # Vue.js admin extensions
โ”‚   โ””โ”€โ”€ Migration/              # Database migrations
โ””โ”€โ”€ tests/

Plugin Bootstrap

<?php declare(strict_types=1);

namespace VendorName\PluginName;

use Shopware\Core\Framework\Plugin;

class PluginName extends Plugin {}

Only extend install(), activate(), deactivate(), uninstall() when lifecycle actions are needed (e.g., creating payment methods, dropping tables on uninstall).


Five Core Workflows

1. Register a Service (DI)

<!-- services.xml -->
<service id="VendorName\PluginName\Service\MyService">
    <argument type="service" id="product.repository"/>
</service>

Common tags: kernel.event_subscriber, twig.extension, console.command, messenger.message_handler, shopware.entity.definition, shopware.entity.extension, shopware.rule.definition, shopware.payment.method.sync, shopware.payment.method.async, shopware.cms.element.

2. Listen to Events (Subscriber)

class ProductSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return ['product.written' => 'onProductWritten'];
    }

    public function onProductWritten(EntityWrittenEvent $event): void
    {
        foreach ($event->getWriteResults() as $result) {
            $id = $result->getPrimaryKey();
        }
    }
}

3. DAL Read & Write

// Read
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('active', true));
$criteria->addAssociation('manufacturer');
$result = $this->productRepository->search($criteria, $context);

// Write
$this->productRepository->upsert([
    ['id' => $id, 'name' => 'New Name'],
], $context);

4. Override a Storefront Template

{# Mirrors original path under views/storefront/ #}
{% sw_extends '@Storefront/storefront/page/product-detail/index.html.twig' %}

{% block page_product_detail_content %}
    <div class="my-banner">Custom content</div>
    {{ parent() }}
{% endblock %}

5. Decorate a Service

<service id="VendorName\PluginName\Decorator\MyDecorator"
         decorates="original.service.id">
    <argument type="service"
              id="VendorName\PluginName\Decorator\MyDecorator.inner"/>
</service>

Karpathy Principles โ€” Clarify Before Coding

Surface these assumptions before generating code:

  • Version? SW 6.5 vs 6.6 (API and Vue component differences exist)
  • Plugin or App System? Plugin = PHP server; App = manifest.xml + external/no server
  • Layer? PHP/Core, Storefront, Admin, or headless/Store API
  • Read or write? Repository search() vs upsert()/create()/update()
  • Entity or extension? New table vs extending existing entity

Write only the minimum code that solves the problem. Shopware's DI and event system handle most complexity.


DAL Quick Reference

// Criteria
$criteria->addFilter(new EqualsFilter('active', true));
$criteria->addFilter(new ContainsFilter('name', 'shirt'));
$criteria->addFilter(new RangeFilter('price', [RangeFilter::GTE => 10]));
$criteria->addAssociation('manufacturer');
$criteria->addSorting(new FieldSorting('name', FieldSorting::ASCENDING));
$criteria->setLimit(25)->setOffset(0);

// Context
$context = Context::createDefaultContext();               // system
// OR inject SalesChannelContext from route / event

// IDs only (faster, no hydration)
$ids = $this->repo->searchIds($criteria, $context)->getIds();

Admin Vue.js Quick Reference

// Register module
Shopware.Module.register('my-module', {
    type: 'plugin',
    routes: { index: { component: 'my-module-index', path: 'index' } },
    navigation: [{ label: 'my-module.title', path: 'my.module.index', icon: 'default-shopping-paper-bag' }],
});

// Override existing component
Shopware.Component.override('sw-product-detail', {
    methods: {
        async saveProduct() {
            await this.$super('saveProduct'); // call original
        },
    },
});

CLI Commands

bin/console plugin:install --activate PluginName
bin/console database:migrate --all PluginName
bin/console cache:clear
bin/console plugin:refresh
bin/build-administration.sh
bin/build-storefront.sh
bin/console theme:compile
php vendor/bin/phpunit --testsuite=unit
vendor/bin/phpstan analyse src --level=8

Additional Resources

Reference Files

Load these when working on specific areas:

  • references/dal.md โ€” DAL: EntityDefinition, Criteria, Aggregations, custom fields, Entity Extensions (extend core entities)
  • references/admin.md โ€” Admin: Vue modules, components, overrides, naming conventions, ACL privileges, filter/inline edit, search config
  • references/storefront.md โ€” Storefront: Twig inheritance, SCSS/theme variables, JavaScript plugins, controllers
  • references/themes.md โ€” Themes: theme.json (config fields, colors, fonts, media), SCSS Bootstrap overrides, theme inheritance, ThemeInterface, CLI commands
  • references/cart.md โ€” Cart: CartDataCollector, CartProcessor, CartValidator + custom errors, discount line items, price manipulation, Tax Provider
  • references/seo-mail.md โ€” SEO: SeoUrlRoute, sitemap URL provider; Mail: custom mail templates (migration + send); Documents (custom PDF types); Order State Machine (transitions, events)
  • references/plugin-structure.md โ€” Full plugin anatomy: services.xml, lifecycle hooks, composer.json, console commands, scheduled tasks
  • references/api.md โ€” Admin API & Store API: CRUD, bulk, filters; context token lifecycle, Cart/Checkout/Account Store API, TypeScript client pattern
  • references/testing.md โ€” PHPUnit unit/integration, StaticEntityRepository, ProductBuilder, Jest, Cypress, assertSame vs assertEquals
  • references/app-system.md โ€” App System: manifest.xml, webhook HMAC verification, registration handshake, App Scripts (Twig-based, no server)
  • references/security.md โ€” Security: route scopes, CSRF protection, input validation, authorization by customer, SQL injection prevention
  • references/integrations.md โ€” Integrations: Payment Handler (AbstractPaymentHandler), shipping costs (cart processor, not a calculator tag), CMS Elements, Rule Builder conditions, Flow Builder events
  • references/performance.md โ€” Performance: HTTP Cache (tags, invalidation), Message Queue (async processing), Elasticsearch/OpenSearch, object cache
  • references/devops.md โ€” DevOps: structured logging, PHPStan, php-cs-fixer, CI/CD, deployment, debugging, media handling, upgrade safety
  • references/migration-6.7.md โ€” 6.6 to 6.7 migration: breaking changes across Core/DAL, Admin, Storefront, cache, API, hosting, plus what 6.7.x added (Vite dev server, Twig UX components, MCP server)
  • references/advanced.md โ€” Advanced: PHP Attributes entities (SW 6.6.3+), Flysystem (public/private file storage), Redis (cache/queue), Rate Limiter (compiler pass + RateLimiter service), Data Indexer, Field Inheritance (variants), In-App Purchases

Examples

Working code examples in examples/:

๊ด€๋ จ ์Šคํ‚ฌ