oro/marketing
Oro marketing package bundles marketing-related features for Oro applications, providing integrations intended for OroCommerce, OroCRM, and OroPlatform projects. Install via Composer and extend your app with Oro’s marketing-specific bundles.
Install the Package
Add to composer.json:
"require": {
"oro/marketing": "^6.0"
}
Run composer update oro/marketing.
Set Up Database Import the Doctrine schema via:
php bin/console doctrine:schema:update --force
(Note: Requires Doctrine ORM; use a bridge like php-di or laravel-bundle for Laravel compatibility.)
Register Bundles
In config/app.php, add:
Oro\Bundle\CampaignBundle\CampaignBundle::class,
Oro\Bundle\MarketingListBundle\MarketingListBundle::class,
// Other Oro bundles as needed
First Use Case: Create a Marketing List
Use the MarketingList entity via Eloquent (if mapped) or Doctrine:
use Oro\Bundle\MarketingListBundle\Entity\MarketingList;
$marketingList = new MarketingList();
$marketingList->setName('High-Value Customers');
$entityManager->persist($marketingList);
$entityManager->flush();
Verify API Endpoints
Check if REST endpoints are accessible (e.g., /api/marketingactivitytypes). If using Laravel routing, proxy or rewrite paths in routes/api.php.
MarketingListProvider to filter contacts dynamically:
$provider = $this->container->get('oro_marketing_list.provider.marketing_list');
$iterator = $provider->getMarketingListEntitiesIterator($marketingListId);
foreach ($iterator as $contact) {
// Send targeted emails or trigger campaigns
}
MarketingListCriteria to add domain-specific filters (e.g., Customer::where('lifetime_value', '>', 1000)).use Oro\Bundle\CampaignBundle\Entity\Campaign;
$campaign = new Campaign();
$campaign->setName('Summer Sale 2024');
$campaign->setDescription('Promote summer collection');
$entityManager->persist($campaign);
CampaignStatistic to log events (e.g., clicks, conversions):
$statistic = new \Oro\Bundle\CampaignBundle\Entity\CampaignStatistic();
$statistic->setCampaign($campaign);
$statistic->setType('click');
$statistic->setValue(1);
$entityManager->persist($statistic);
/api/marketinglists/{id}/items):
// Example: Fetch marketing list items via HTTP client
$response = Http::get("/api/marketinglists/{id}/items");
$items = $response->json();
CampaignEventListener to trigger external actions (e.g., Slack notifications on campaign completion).campaign.send):
// In a service provider
$this->app->booting(function () {
$dispatcher = $this->app->make('event_dispatcher');
$dispatcher->addListener('campaign.send', function ($event) {
// Custom logic (e.g., log to analytics)
});
});
marketing.list.updated) for decoupled workflows.php-di to adapt Symfony services:
$container->set(\Oro\Bundle\MarketingListBundle\Provider\MarketingListProvider::class, function () {
return new \Oro\Bundle\MarketingListBundle\Provider\MarketingListProvider(
$this->get('doctrine.orm.entity_manager')
);
});
trait DoctrineToEloquentAdapter {
public static function resolveEntityManager() {
return app('doctrine')->getManager();
}
}
AppServiceProvider:
public function register() {
$this->app->tag(
\Oro\Bundle\MarketingListBundle\Twig\Extension\MarketingListExtension::class,
'twig.extension'
);
}
Symfony Dependency Hell:
EventDispatcher, PropertyAccess). Laravel’s equivalents may not map 1:1.symfony/event-dispatcher and symfony/property-access as Composer dependencies, then bridge them in a service provider.Doctrine ORM Lock-In:
class MarketingListRepository {
public function findByCriteria($criteria) {
return $this->entityManager->createQueryBuilder()
->from('OroMarketingListBundle:MarketingList', 'ml')
->where('ml.name = :name')
->setParameter('name', $criteria['name'])
->getQuery()
->getResult();
}
}
Breaking API Path Changes:
/api/matypes → /api/marketingactivitytypes). Old paths return 404.oro/marketing:6.0.0) and handle deprecations proactively.Twig Template Conflicts:
@vite or @asset directives may break.resources/views/oro/ and replace Symfony-specific tags.Event Dispatcher Mismatch:
EventDispatcher and Laravel’s Illuminate\Events\Dispatcher are incompatible.class OroEventDispatcher {
public function dispatch($event, $listener = null) {
return app('events')->dispatch($event);
}
}
Enable Doctrine Logging:
Add to config/services.yaml (Symfony) or Laravel’s config/doctrine.php:
doctrine:
dbal:
logging: true
profiler: true
View logs in storage/logs/doctrine.log.
Check Event Listeners: Dump registered listeners to debug event flow:
$dispatcher = $this->app->make('event_dispatcher');
foreach ($dispatcher->getListeners() as $event => $listeners) {
dump($event, $listeners);
}
Validate Entity States:
Use Oro’s StateMachine to debug workflow transitions:
$stateMachine = $this->container->get('oro_marketing_list.state_machine.marketing_list');
$stateMachine->apply($marketingList, 'publish');
Custom Marketing List Criteria:
Extend MarketingListCriteria to add domain logic:
class CustomMarketingListCriteria extends MarketingListCriteria {
public function addCustomFilter($field, $value) {
$this->getParameters()->add('custom.' . $field, $value);
}
}
Campaign Workflow Extensions: Add custom transitions to Oro’s state machines:
# config/oro/marketing_list.yml
oro_marketing_list:
state_machine:
marketing_list:
transitions:
archive:
from: [published]
to: archived
guard: [is_archivable]
API Resource Customization: Override REST controllers to add fields or filters:
class CustomMarketingListController extends \Oro\Bundle\MarketingListBundle\Controller\Api\Rest\MarketingListController {
public function cgetAction($id) {
$this->get('oro_api.get_data')->setFields(['name', 'custom_field']);
return parent::cgetAction($id);
}
}
Data Importers/Exporters:
How can I help you explore Laravel packages today?