
Oro Bundle
- 4 installs
- 2 repo stars
- Updated July 22, 2026
- netresearch/orocommerce-skill
Helps with ai & agent building tasks.
About
oro-bundle is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- oro-bundle
- AI & Agent Building
- AI-coding skill
Oro Bundle by the numbers
- 4 all-time installs (skills.sh)
- +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #13,348 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/netresearch/orocommerce-skill --skill oro-bundleAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 2 |
| Last updated | July 22, 2026 |
| Repository | netresearch/orocommerce-skill ↗ |
What it does
Helps with ai & agent building tasks.
Files
OroCommerce v6.1 Bundle Development
Bundle Directory Structure
src/Acme/Bundle/DemoBundle/
├── AcmeDemoBundle.php
├── DependencyInjection/
│ └── AcmeDemoExtension.php
├── Resources/
│ ├── config/
│ │ ├── oro/
│ │ │ └── bundles.yml
│ │ ├── services.yml
│ │ ├── navigation.yml
│ │ └── system_configuration.yml
│ ├── translations/
│ │ └── messages.en.yml
│ └── views/
├── Entity/
├── EventListener/
├── Command/
└── Migrations/
└── Data/
└── ORM/Bundle Class
<?php
namespace Acme\Bundle\DemoBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AcmeDemoBundle extends Bundle
{
public function getPath(): string
{
return __DIR__;
}
}The getPath() method in v6.1 replaces legacy container-relative path logic, enabling the kernel to locate bundle resources automatically.
DependencyInjection Extension
<?php
namespace Acme\Bundle\DemoBundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader;
class AcmeDemoExtension extends Extension
{
#[\Override]
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new Loader\YamlFileLoader(
$container,
new FileLocator(__DIR__ . '/../Resources/config')
);
$loader->load('services.yml');
}
#[\Override]
public function getAlias(): string
{
return 'acme_demo';
}
}Use #[\Override] attributes (standard in v6.1) — they catch method signature mismatches at compile time.
Bundle Registration
Register in Resources/config/oro/bundles.yml:
bundles:
- { name: Acme\Bundle\DemoBundle\AcmeDemoBundle }Priority: Lower loads first. Omit priority (defaults to 0) for custom bundles unless you need to override config from a specific Oro bundle.
Service Configuration
services:
acme_demo.my_service:
class: Acme\Bundle\DemoBundle\Service\MyService
public: false
acme_demo.event_listener.my_listener:
class: Acme\Bundle\DemoBundle\EventListener\MyListener
tags:
- { name: kernel.event_listener, event: kernel.request, method: onRequest }
arguments:
- '@logger'Tags trigger compiler passes that register listeners, commands, and API endpoints. Verify with debug:container acme_demo.
See bundle-patterns.md for service decoration, compiler passes, event listeners, navigation menus, system configuration, and translations.
Post-Installation Commands
php bin/console cache:clear
php bin/console debug:container acme_demo # Verify services registeredCache clear is critical — changes to bundles.yml, services.yml, or navigation.yml take effect only after clearing.
Key Pitfalls
1. Missing cache clear: Bundle config changes (services, navigation, system config) are invisible until cache:clear runs. This is the most common "it doesn't work" cause. 2. Wrong extension alias: The DI extension alias must match the bundle name convention (acme_demo for AcmeDemoBundle). A mismatch silently skips your services.yml loading. 3. Priority ordering confusion: In bundles.yml, lower priority loads first (opposite of processor priority). Most custom bundles should omit priority entirely.
See Also
- bundle-patterns.md — System config, navigation, translations, compiler passes, event listeners, service decoration
- v6.1.md — v6.1 specifics, migration checklist, and environment notes
- v7.0.md — v7.0 changes (placeholder)
Bundle Configuration Patterns (v6.1)
Detailed configuration examples for OroCommerce bundle development. See the main SKILL.md for core concepts and quick-start patterns.
System Configuration
Add admin settings via Resources/config/system_configuration.yml:
system_configuration:
groups:
acme_demo_settings:
title: acme_demo.system_config.group_label
icon: fa-cog
children:
- acme_demo_connection_settings
fields:
demo_enabled:
data_type: boolean
type: Oro\Bundle\ConfigBundle\Form\Type\ConfigCheckbox
priority: 10
ui_only: true
demo_timeout:
data_type: integer
type: Symfony\Component\Form\Extension\Core\Type\IntegerType
options:
constraints:
- Range:
min: 1
max: 60
tree:
system_configuration:
platform:
integrations:
children:
- acme_demo_settingsSettings are accessible at /admin/config/system and retrieved via ConfigProvider:
$apiKey = $this->configProvider->get('demo_api_key');Navigation Menu Configuration
Create Resources/config/navigation.yml to add menu items:
oro_navigation_elements:
acme_demo_menu:
type: group
label: acme_demo.navigation.main_menu
show_non_authorized: false
children:
acme_demo_list:
type: item
route: acme_demo_index
label: acme_demo.navigation.demo_listReference the menu in your Twig template with {{ oro_menu_render('acme_demo_menu') }}. Translation keys are resolved during rendering.
Translation Files
Create Resources/translations/messages.en.yml:
acme_demo:
navigation:
main_menu: 'Demo Module'
demo_list: 'Demo Items'
system_config:
group_label: 'Demo Settings'
entity:
class_label: 'Demo'
class_plural_label: 'Demos'
id.label: 'ID'
name.label: 'Name'Oro auto-discovers .yml translation files in Resources/translations/. For other languages, use messages.fr.yml, messages.de.yml, etc.
Service Decoration
Wrap an existing service without modifying its definition:
# In your services.yml
acme_demo.decorated_service:
class: Acme\Bundle\DemoBundle\Service\EnhancedProductService
decorates: oro_product.service.product_service
decoration_inner_name: oro_product.service.product_service.inner
arguments:
- '@oro_product.service.product_service.inner'Decoration is safer than dependency injection modification — it preserves the original service for other consumers.
Compiler Passes
Collect tagged services into a registry using a compiler pass:
namespace Acme\Bundle\DemoBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class RegisterHandlersPass implements CompilerPassInterface
{
#[\Override]
public function process(ContainerBuilder $container): void
{
if (!$container->hasDefinition('acme_demo.handler_registry')) {
return;
}
$registry = $container->getDefinition('acme_demo.handler_registry');
foreach ($container->findTaggedServiceIds('acme_demo.handler') as $id => $tags) {
$registry->addMethodCall('addHandler', [new Reference($id)]);
}
}
}Register the pass in your bundle class's build() method:
public function build(ContainerBuilder $container): void
{
parent::build($container);
$container->addCompilerPass(new RegisterHandlersPass());
}Event Listeners
Use standard Doctrine lifecycle events for entity change hooks:
namespace Acme\Bundle\DemoBundle\EventListener;
use Doctrine\ORM\Event\PostPersistEventArgs;
use Doctrine\ORM\Event\PostUpdateEventArgs;
class DocumentChangeListener
{
public function postPersist(PostPersistEventArgs $args): void
{
$entity = $args->getObject();
if (!$entity instanceof Document) {
return;
}
// React to new entity creation
}
public function postUpdate(PostUpdateEventArgs $args): void
{
$entity = $args->getObject();
if (!$entity instanceof Document) {
return;
}
// React to entity update
}
}Register with the doctrine.event_listener tag:
Acme\Bundle\DemoBundle\EventListener\DocumentChangeListener:
tags:
- { name: doctrine.event_listener, event: postPersist }
- { name: doctrine.event_listener, event: postUpdate }Bundle Development — v6.1 Notes
Key Environment
- PHP 8.1+ required; 8.2+ recommended
- Symfony 6.x base (6.2+ for full attribute support)
- PostgreSQL primary; MySQL reduced to legacy compatibility mode
Changes from Earlier Versions
- PHP 8 attributes replace docblock annotations (annotations deprecated)
getPath()method on Bundle class replaces legacygetNamespace()path resolution- Auto-discovery of console commands and subscribers
- PSR-4 auto-wiring enabled by default in
config/services.yaml - Service tags must be explicitly defined in bundle's
services.yml
Important Constraints
- Entity metadata attributes are read at runtime (no caching unlike old annotations)
- Attribute parsing is slightly heavier than cached annotations — monitor memory in large projects
Migration Checklist: v6.0 to v6.1
- [ ] Replace all
@annotations with#[...]attributes - [ ] Add
getPath()method to Bundle classes - [ ] Update
services.ymlto use explicit tag definitions - [ ] Test with PostgreSQL (if not already)
- [ ] Run
cache:clearto rebuild service container - [ ] Verify
php bin/console debug:containershows all expected services
Bundle Development — v7.0 Notes
v7.0 is not yet released. This file will be updated when v7.0 stabilizes.
Expected Changes
- TBD