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

Document Manipulation Bundle Laravel Package

ddeboer/document-manipulation-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle Add to composer.json:

    "require": {
        "ddeboer/document-manipulation-bundle": "^1.0"
    }
    

    Run composer update and enable the bundle in config/bundles.php:

    return [
        // ...
        Ddeboer\DocumentManipulationBundle\DdeboerDocumentManipulationBundle::class => ['all' => true],
    ];
    
  2. Configure Required Services For LiveDocx (Word):

    • Register the ZendService repository in composer.json (as per README).
    • Add credentials to config/packages/ddeboer_document_manipulation.yaml:
      ddeboer_document_manipulation:
          livedocx:
              username: "%env(LIVE_DOCX_USERNAME)%"
              password: "%env(LIVE_DOCX_PASSWORD)%"
              wsdl: "%env(LIVE_DOCX_WSDL)%"  # Optional for premium
      

    For PDF (pdftk):

    • Install pdftk via system package manager (e.g., apt-get install pdftk).
    • Configure in config/packages/ddeboer_document_manipulation.yaml:
      ddeboer_document_manipulation:
          pdftk_path: "/usr/bin/pdftk"  # Path to pdftk binary
      
  3. First Use Case: Mail Merge Inject the LiveDocxManipulator service and merge a template:

    use Ddeboer\DocumentManipulationBundle\Service\LiveDocxManipulator;
    
    class InvoiceController extends AbstractController {
        public function generate(LiveDocxManipulator $manipulator) {
            $data = ['client' => 'John Doe', 'amount' => 100.00];
            $templatePath = $this->getParameter('kernel.project_dir').'/templates/invoice.docx';
            $outputPath = $this->getParameter('kernel.project_dir').'/uploads/invoice_'.uniqid().'.docx';
    
            $manipulator->merge($templatePath, $data, $outputPath);
            return $this->json(['success' => true, 'path' => $outputPath]);
        }
    }
    

Implementation Patterns

Common Workflows

1. Dynamic Document Generation

  • Template-Based Merging: Use LiveDocxManipulator for Word documents with placeholders (e.g., {client_name}).
    $manipulator->merge(
        $templatePath,
        ['client_name' => 'Acme Corp', 'date' => now()->format('Y-m-d')],
        $outputPath
    );
    
  • PDF Concatenation: Combine multiple PDFs into one using PdfManipulator:
    $pdfManipulator = $this->container->get('ddeboer_document_manipulation.pdf_manipulator');
    $pdfManipulator->concatenate(
        [$pdf1Path, $pdf2Path],
        $outputPath
    );
    

2. Batch Processing

  • Loop through records and generate documents:
    foreach ($invoices as $invoice) {
        $outputPath = $this->generateOutputPath($invoice->id);
        $manipulator->merge($template, $invoice->toArray(), $outputPath);
        $this->queueEmailAttachment($outputPath, $invoice->email);
    }
    

3. Integration with Storage Systems

  • Store generated files in S3 or local storage:
    use League\Flysystem\Filesystem;
    
    $filesystem = new Filesystem($adapter);
    $manipulator->merge($template, $data, $tempPath);
    $filesystem->put('invoices/invoice_'.$invoiceId.'.docx', file_get_contents($tempPath));
    unlink($tempPath); // Cleanup
    

4. Error Handling

  • Wrap operations in try-catch blocks:
    try {
        $manipulator->merge($template, $data, $outputPath);
    } catch (\Exception $e) {
        $this->logger->error('Document merge failed', ['error' => $e->getMessage()]);
        throw new \RuntimeException('Failed to generate document', 0, $e);
    }
    

Integration Tips

Laravel-Specific Adjustments

  1. Service Container Access: Use dependency injection or resolve services manually:

    $manipulator = app('ddeboer_document_manipulation.live_docx_manipulator');
    
  2. Configuration Overrides: Override bundle config in config/packages/override/ddeboer_document_manipulation.yaml:

    ddeboer_document_manipulation:
        pdftk_path: "%env(PDFTK_PATH)%"
        livedocx:
            timeout: 30  # Override default timeout
    
  3. Event Listeners: Trigger actions post-generation (e.g., send email):

    // config/services.yaml
    App\Listener\DocumentGeneratedListener:
        tags:
            - { name: kernel.event_listener, event: app.document_generated, method: onDocumentGenerated }
    

Gotchas and Tips

Pitfalls

  1. LiveDocx API Limits:

    • Free accounts have rate limits (e.g., 100 requests/day). Monitor usage or upgrade to premium.
    • Solution: Cache merged documents or implement retry logic with exponential backoff.
  2. pdftk Dependencies:

    • pdftk requires Java on some systems. Ensure it’s installed and in PATH.
    • Debugging: Test pdftk manually first:
      pdftk input1.pdf input2.pdf cat output combined.pdf
      
  3. File Permissions:

    • Ensure the web server user (e.g., www-data) has write permissions for output directories.
    • Fix: Set umask in your deployment script or use a dedicated uploads directory:
      chmod -R 775 /path/to/uploads
      
  4. Template Placeholder Syntax:

    • LiveDocx uses double curly braces ({{placeholder}}). Avoid conflicts with Twig templates by escaping or using unique prefixes (e.g., {{docx_client_name}}).
  5. Memory Limits:

    • Merging large Word/PDF files may hit PHP’s memory_limit. Increase it temporarily:
      ini_set('memory_limit', '512M');
      

Debugging Tips

  1. Enable Verbose Logging: Configure Monolog to log bundle operations:

    # config/packages/monolog.yaml
    monolog:
        handlers:
            document_manipulation:
                type: stream
                path: "%kernel.logs_dir%/document_manipulation.log"
                level: debug
                channels: ["ddeboer_document_manipulation"]
    
  2. Check LiveDocx Responses: Inspect raw API responses for errors:

    try {
        $manipulator->merge($template, $data, $outputPath);
    } catch (\ZendService\LiveDocx\Exception $e) {
        \Log::error('LiveDocx Error', [
            'code' => $e->getCode(),
            'message' => $e->getMessage(),
            'raw_response' => $e->getRawResponse()
        ]);
    }
    
  3. Validate Input Files: Ensure templates are valid before merging:

    if (!file_exists($templatePath) || !is_readable($templatePath)) {
        throw new \InvalidArgumentException("Template file not found or unreadable");
    }
    

Extension Points

  1. Custom Manipulators: Extend the bundle by creating your own manipulator class:

    use Ddeboer\DocumentManipulationBundle\Service\AbstractManipulator;
    
    class CustomPdfManipulator extends AbstractManipulator {
        public function watermark($inputPath, $outputPath, $watermarkText) {
            // Implement custom logic (e.g., using Imagick)
        }
    }
    

    Register it as a service:

    services:
        App\Service\CustomPdfManipulator:
            tags: ['ddeboer_document_manipulation.manipulator']
    
  2. Pre/Post-Processing Hooks: Use Symfony events to intercept document operations:

    // src/EventListener/DocumentEventListener.php
    class DocumentEventListener {
        public function onDocumentMerge(DocumentMergeEvent $event) {
            // Modify $event->getData() or $event->getOutputPath()
        }
    }
    

    Dispatch events in the bundle’s manipulator classes (requires patching or extending).

  3. Alternative Backends: Replace LiveDocx with PhpWord or **DocRapt

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.
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager