Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ibexa Dataflow Bundle Laravel Package

code-rhapsodie/ibexa-dataflow-bundle

Integrates Code Rhapsodie Dataflow Bundle into Ibexa 4.0+ to manage content imports from external sources. Provides a backoffice UI to create and schedule dataflow processes (one-off or recurring) with per-type options.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Steps to Begin
1. **Installation**:
   ```bash
   composer require code-rhapsodie/ibexa-dataflow-bundle

Add bundles to config/bundles.php in the correct order:

CodeRhapsodie\DataflowBundle\CodeRhapsodieDataflowBundle::class => ['all' => true],
CodeRhapsodie\IbexaDataflowBundle\CodeRhapsodieIbexaDataflowBundle::class => ['all' => true],

Import routing:

# config/routing/ibexa_dataflow.yaml
_cr.ibexa_dataflow:
  resource: '@CodeRhapsodieIbexaDataflowBundle/Resources/config/routing.yaml'
  1. Database Setup: Follow Dataflow Bundle's schema update guide.

  2. Queue Configuration: Configure the job runner as per Dataflow Bundle's Queue section.

  3. First Dataflow: Define a DataflowType (see Dataflow Bundle docs). Example minimal DataflowType:

    use CodeRhapsodie\IbexaDataflowBundle\Writer\ContentWriter;
    use CodeRhapsodie\DataflowBundle\DataflowType\AbstractDataflowType;
    
    class MyDataflowType extends AbstractDataflowType
    {
        public function __construct(private ContentWriter $contentWriter) {}
    
        protected function buildDataflow(DataflowBuilder $builder, array $options): void
        {
            $builder->addWriter($this->contentWriter);
        }
    }
    

    Tag it as a service:

    services:
        App\Dataflow\MyDataflowType:
            tags:
                - { name: coderhapsodie.dataflow.type }
    
  4. Access UI: Navigate to Admin > Ibexa Dataflow in the Ibexa backoffice to create schedules.


Implementation Patterns

Core Workflow: Data Import/Export

  1. Define DataflowType: Extend AbstractDataflowType and implement buildDataflow() to chain readers, steps, and writers. Example:

    protected function buildDataflow(DataflowBuilder $builder, array $options): void
    {
        $builder
            ->addReader(new CsvReader($options['file_path']))
            ->addStep($this->contentStructureFactory->createStep($options['content_type']))
            ->addWriter($this->contentWriter);
    }
    
  2. Content Processing: Use ContentWriter to handle Ibexa content creation/updates. Transform data into ContentCreateStructure or ContentUpdateStructure:

    $builder->addStep(function ($data) {
        return $this->contentStructureFactory->transform(
            $data,
            'remote-id-' . $data['id'],
            'eng-GB',
            'article',
            42 // Parent location ID
        );
    });
    
  3. Scheduled Jobs:

    • Recurring: Set frequency (e.g., +1 day) and first run time in the UI.
    • One-shot: Define a single execution time via the "Oneshot" tab.
  4. Filtering: Use NotModifiedContentFilter to skip unchanged updates:

    $builder->addStep($this->notModifiedContentFilter);
    
  5. Error Handling: Log exceptions via setLogger() on writers/filters:

    $this->contentWriter->setLogger($this->logger);
    

Integration Tips

  1. Environment-Specific Config: Store parent location IDs or sensitive options in .env.local:

    DATAFLOW_PARENT_LOCATION_ID=42
    
  2. Custom Field Types: Extend AbstractFieldComparator for unsupported field types (e.g., ibexa_matrix):

    class MatrixFieldComparator extends AbstractFieldComparator
    {
        protected function compareValues(Value $currentValue, Value $newValue): bool
        {
            return $currentValue->value === $newValue->value;
        }
    }
    

    Register as a service:

    services:
        App\FieldComparator\MatrixFieldComparator:
            tags:
                - { name: coderhapsodie.ibexa_dataflow.field_comparator, fieldType: 'ibexa_matrix' }
    
  3. UI Customization: Override templates in templates/bundles/coderhapsodieibexadataflow/ to modify the admin UI.

  4. Testing: Mock ContentWriter and ContentStructureFactory in unit tests:

    $this->contentWriter->expects($this->once())
        ->method('write')
        ->with($this->isInstanceOf(ContentCreateStructure::class));
    
  5. Performance:

    • Batch large imports by chunking data in readers.
    • Use MODE_UPDATE_ONLY to avoid redundant checks for existing content.

Gotchas and Tips

Pitfalls

  1. Bundle Loading Order: Critical: CodeRhapsodieDataflowBundle must load before CodeRhapsodieIbexaDataflowBundle. Misordering causes service registration failures.

  2. Siteaccess Flag: Use --siteaccess (not --connection) for Dataflow commands:

    php bin/console code-rhapsodie:dataflow:run my_dataflow --siteaccess=admin
    

    Exception: dump-schema uses --connection.

  3. Remote ID Conflicts: Ensure remoteId in ContentStructureFactory::transform() is unique. Duplicate IDs cause overwrites or errors.

  4. Field Type Mismatches: NotModifiedContentFilter skips unsupported field types. Log warnings if relying on this filter:

    if (!$this->notModifiedContentFilter->supports($fieldType)) {
        $this->logger->warning('Unsupported field type: ', [$fieldType]);
    }
    
  5. Queue Stuck Jobs: Failed jobs may linger in the queue. Clear them manually:

    php bin/console doctrine:query:sql "DELETE FROM dataflow_job WHERE status = 'failed' AND created_at < NOW() - INTERVAL '1 day'"
    
  6. Parent Location ID: Hardcoding IDs breaks across environments. Use parameters.yaml:

    parameters:
        dataflow.parent_location.article: '%env(ARTICLE_PARENT_LOCATION_ID)%'
    

Debugging Tips

  1. Enable Debug Mode: Add to config/packages/dev/monolog.yaml:

    handlers:
        dataflow:
            type: stream
            path: "%kernel.logs_dir%/dataflow.log"
            level: debug
    
  2. Log Dataflow Steps: Inject LoggerInterface and log data at each step:

    $builder->addStep(function ($data) use ($logger) {
        $logger->debug('Processing data', ['data' => $data]);
        // ...
    });
    
  3. Dry Runs: Test dataflows without writing to Ibexa by mocking ContentWriter:

    $writer = $this->createMock(ContentWriter::class);
    $writer->method('write')->willReturnCallback(function ($structure) {
        $this->logger->info('Would write:', [$structure->getRemoteId()]);
    });
    
  4. Schema Validation: Validate YAML options in the UI with a custom validator:

    use Symfony\Component\Validator\Constraints as Assert;
    
    $constraints = new Assert\Collection([
        'options' => new Assert\All([
            new Assert\Type('array'),
            new Assert\NotBlank(),
        ]),
    ]);
    
  5. UI Refresh: Clear cache after adding new DataflowType services:

    php bin/console cache:clear
    

Extension Points

  1. Custom Writers: Extend AbstractWriter to support non-content operations (e.g., taxonomy imports):

    class TaxonomyWriter extends AbstractWriter
    {
        protected function process($data): void
        {
            // Custom logic
        }
    }
    
  2. Dynamic Options: Fetch options from external sources (e.g., API) in buildDataflow():

    $options = $this->optionFetcher->fetch($options['source']);
    
  3. Pre/Post Hooks: Add hooks via Symfony events (e.g., dataflow.job.start):

    services:
        App\EventListener\DataflowHookListener:
            tags:
                - { name: kernel.event_listener, event: dataflow.job.start, method: onJobStart }
    
  4. UI Extensions: Override Twig templates or add JavaScript via asset bundles:

    // assets/dataflow.js
    document.addEventListener('DOMContentLoaded',
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
cadot.eu/make
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky