oveleon/product-installer
Laravel package to install products/modules via a simple installer workflow. Helps automate setup steps like publishing assets, running migrations, and seeding data, so new product features can be added and deployed with minimal manual effort.
Installation
composer require oveleon/product-installer
Ensure your project uses Contao 4.x or Contao 5.5+ (Turbo) (verified compatibility) and PHP 8.1+.
Basic Setup
config/bundles.php:
return [
// ...
Oveleon\ProductInstallerBundle\ProductInstallerBundle::class => ['all' => true],
];
php bin/contao-console oveleon:product-installer:install
First Use Case Create a simple product installer command to deploy a demo product:
use Oveleon\ProductInstallerBundle\Installer\ProductInstallerInterface;
class DemoProductInstaller implements ProductInstallerInterface
{
public function install(array $options): bool
{
// Example: Install a product with predefined settings
$product = new ProductModel();
$product->name = $options['name'] ?? 'Demo Product';
$product->save();
return true;
}
}
Register it in config/packages/oveleon_product_installer.yaml:
services:
App\Installer\DemoProductInstaller:
tags: ['oveleon.product_installer']
Product Installation
Use the ProductInstaller service to orchestrate installations:
$installer = $this->container->get('oveleon.product_installer');
$installer->install('demo_product', ['name' => 'My Product']);
Dependency Management Define dependencies between installers (e.g., a theme must be installed before a product):
# config/packages/oveleon_product_installer.yaml
oveleon_product_installer:
installers:
demo_theme:
depends_on: ['base_theme']
Post-Install Hooks Extend functionality with events:
use Oveleon\ProductInstallerBundle\Event\PostInstallEvent;
$dispatcher->addListener(PostInstallEvent::class, function (PostInstallEvent $event) {
if ($event->getProductName() === 'demo_product') {
// Custom logic after installation
}
});
CLI Integration Create custom commands for user-friendly installations:
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class InstallDemoProductCommand extends Command
{
protected function execute(InputInterface $input, OutputInterface $output): int
{
$installer = $this->getContainer()->get('oveleon.product_installer');
$success = $installer->install('demo_product');
$output->writeln($success ? 'Product installed!' : 'Installation failed.');
return $success ? Command::SUCCESS : Command::FAILURE;
}
}
Configuration Overrides Override default installer options via YAML:
oveleon_product_installer:
installers:
demo_product:
options:
name: 'Custom Product Name'
price: 99.99
Contao Version Mismatch
composer.json or README.md. For Contao 5.5+, ensure oveleon/product-installer is explicitly listed in composer.json under require.Missing Database Tables
php bin/contao-console doctrine:migrations:migrate
PreInstallEvent to validate the database schema.Circular Dependencies
A depends on B and B depends on A).Permission Issues
web/).sudo or adjust file permissions:
chmod -R 775 web/
Event Dispatching Order
PreInstallEvent and PostInstallEvent fire in a specific order. Misplacing logic (e.g., modifying data in PreInstallEvent but reading it in PostInstallEvent) can cause inconsistencies.$dispatcher->addListener(PostInstallEvent::class, function (PostInstallEvent $event) {
error_log('PostInstallEvent fired for: ' . $event->getProductName());
});
Dry Runs Simulate installations without changes:
$installer->dryRun('demo_product', ['name' => 'Test']);
Rollback Support
Implement ProductInstallerInterface::rollback() to undo installations:
public function rollback(array $options): bool
{
$product = ProductModel::findByName($options['name']);
if ($product) {
$product->delete();
return true;
}
return false;
}
Localization Support multilingual products by extending the installer:
public function install(array $options): bool
{
$product = new ProductModel();
$product->name = $options['name'];
$product->save();
// Add translations (works for Contao 4.x/5.5+)
$tlProduct = new TLProduct();
$tlProduct->pid = $product->id;
$tlProduct->language = 'en';
$tlProduct->title = $options['title_en'];
$tlProduct->save();
return true;
}
Logging
Enable verbose logging in config/packages/oveleon_product_installer.yaml:
oveleon_product_installer:
debug: true
Testing
Use the ProductInstallerTestCase base class for unit tests:
use Oveleon\ProductInstallerBundle\Test\ProductInstallerTestCase;
class DemoProductInstallerTest extends ProductInstallerTestCase
{
public function testInstallation()
{
$installer = $this->getInstaller('demo_product');
$this->assertTrue($installer->install([]));
}
}
Performance Batch database operations for large installations:
public function install(array $options): bool
{
DB::beginTransaction();
try {
// Bulk insert products (works for Contao 4.x/5.5+)
ProductModel::insert($options['products']);
DB::commit();
return true;
} catch (\Exception $e) {
DB::rollBack();
return false;
}
}
Contao 5.5+ (Turbo) Specifics
symfony/* packages are compatible with Symfony 6+ if using Contao 5.5+.public function __construct(private ProductInstallerInterface $installer)
{
}
src/Command/ and ensure they extend Contao\CoreBundle\Command\ContaoCommand:
use Contao\CoreBundle\Command\ContaoCommand;
class InstallDemoProductCommand extends ContaoCommand
{
// ...
}
config/packages/ or config/bundles.php differently. Verify the correct path for your setup.How can I help you explore Laravel packages today?