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

Archiver Bundle Laravel Package

cleentfaar/archiver-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require cleentfaar/archiver-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        Cleentfaar\ArchiverBundle\CLArchiverBundle::class => ['all' => true],
    ];
    
  2. First Use Case Archive a directory to a .zip file:

    use Cleentfaar\ArchiverBundle\Archiver\ArchiverInterface;
    use Symfony\Component\HttpFoundation\Response;
    
    class ArchiveController extends AbstractController
    {
        public function archiveDirectory(ArchiverInterface $archiver): Response
        {
            $archivePath = $archiver->create('zip', '/path/to/source', '/path/to/destination.zip');
            return $this->file($archivePath);
        }
    }
    
  3. Key Classes to Explore

    • ArchiverInterface: Core interface for archiving operations.
    • ArchiverManager: Service for managing multiple archiver formats.
    • Archiver\ZipArchiver: Default implementation for ZIP archives.

Implementation Patterns

Common Workflows

1. Archiving Files/Directories

Use the ArchiverManager to handle different formats dynamically:

// Archive a directory to ZIP
$archiverManager->create('zip', '/source', '/destination.zip');

// Archive a file to TAR.GZ
$archiverManager->create('tar_gz', '/file.txt', '/destination.tar.gz');

2. Streaming Archives for Downloads

Stream archives directly to the browser to avoid memory issues:

public function streamArchive(ArchiverInterface $archiver, string $format, string $source): Response
{
    $response = new Response();
    $response->headers->set('Content-Type', 'application/octet-stream');
    $response->headers->set('Content-Disposition', 'attachment; filename="archive.'.$format.'"');

    $archiver->stream($format, $source, $response->getBody());

    return $response;
}

3. Entity Archiving

Serialize Doctrine entities to JSON/XML and archive them:

use Cleentfaar\ArchiverBundle\Archiver\EntityArchiver;

$entityArchiver = $this->container->get(EntityArchiver::class);
$archivePath = $entityArchiver->archiveEntities(['entity1', 'entity2'], 'zip', '/destination.zip');

4. Custom Archiver Formats

Extend the bundle to support new formats (e.g., RAR):

namespace App\Archiver;

use Cleentfaar\ArchiverBundle\Archiver\ArchiverInterface;

class RarArchiver implements ArchiverInterface
{
    public function create(string $source, string $destination): string
    {
        // Custom RAR logic using a library like `php-rar-php`
    }

    public function stream(string $source, $outputStream): void
    {
        // Stream RAR logic
    }
}

Register the service in config/services.yaml:

services:
    App\Archiver\RarArchiver:
        tags: ['archiver']

Integration Tips

1. Symfony Events

Trigger archiving on entity lifecycle events (e.g., postPersist):

use Doctrine\ORM\Event\LifecycleEventArgs;
use Cleentfaar\ArchiverBundle\Archiver\EntityArchiver;

class ArchiveSubscriber implements EventSubscriber
{
    private $entityArchiver;

    public function __construct(EntityArchiver $entityArchiver)
    {
        $this->entityArchiver = $entityArchiver;
    }

    public function getSubscribedEvents()
    {
        return ['postPersist'];
    }

    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getObject();
        $this->entityArchiver->archiveEntity($entity, 'zip', '/backups/');
    }
}

2. Command-Line Archiving

Create a console command for batch archiving:

namespace App\Command;

use Cleentfaar\ArchiverBundle\Archiver\ArchiverManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class ArchiveCommand extends Command
{
    protected static $defaultName = 'app:archive';

    private $archiverManager;

    public function __construct(ArchiverManager $archiverManager)
    {
        $this->archiverManager = $archiverManager;
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $this->archiverManager->create('zip', '/data', '/backups/data_'.date('Y-m-d').'.zip');
        $output->writeln('Archive created!');
        return Command::SUCCESS;
    }
}

3. Configuration

Customize archiver settings in config/packages/cleentfaar_archiver.yaml:

cleentfaar_archiver:
    default_format: 'zip' # Default archiver format
    formats:
        zip:
            compression_level: 9 # Max compression
            exclude_patterns: ['*.log', 'node_modules/']

Gotchas and Tips

Pitfalls

1. Memory Limits

  • Issue: Large archives may exceed PHP’s memory_limit.
  • Fix: Use stream() instead of create() for large files/directories.
    $archiver->stream('zip', '/large_directory', $response->getBody());
    

2. File Permissions

  • Issue: The bundle may fail silently if it lacks write permissions for the destination.
  • Fix: Verify permissions and use absolute paths:
    $archiver->create('zip', '/source', '/var/www/archives/destination.zip');
    

3. Entity Archiving Quirks

  • Issue: Circular references in entities may cause serialization errors.
  • Fix: Exclude problematic properties or use max_depth in EntityArchiver:
    $archivePath = $entityArchiver->archiveEntities(
        [$entity],
        'zip',
        '/destination.zip',
        ['max_depth' => 2]
    );
    

4. Format-Specific Dependencies

  • Issue: Some formats (e.g., tar_gz) require external binaries (e.g., tar).
  • Fix: Ensure dependencies are installed:
    # For tar_gz support
    sudo apt-get install tar  # Debian/Ubuntu
    
  • Fallback: Use PHP libraries like phpseclib or pclzip for pure-PHP solutions.

Debugging Tips

1. Enable Verbose Logging

Configure Monolog to log archiver events:

# config/packages/monolog.yaml
monolog:
    handlers:
        archiver:
            type: stream
            path: "%kernel.logs_dir%/archiver.log"
            level: debug
            channels: ["archiver"]

Then, in your code:

$this->logger->info('Archiving started', ['format' => $format, 'source' => $source]);

2. Validate Inputs

Sanitize paths to prevent directory traversal:

use Symfony\Component\Filesystem\Filesystem;

$fs = new Filesystem();
$realPath = $fs->makePathAbsolute($source, __DIR__);
if (strpos($realPath, __DIR__.'/../') !== false) {
    throw new \RuntimeException('Invalid path');
}

3. Test with Small Files First

Start with small test files to isolate issues:

// Create a test file
file_put_contents('/tmp/test.txt', 'Hello, Archiver!');
$archivePath = $archiver->create('zip', '/tmp', '/tmp/test.zip');

Extension Points

1. Custom Archiver Tags

Extend the bundle by tagging your own archivers:

# config/services.yaml
services:
    App\Archiver\SevenZipArchiver:
        tags: ['archiver', { alias: '7z' }]

Now use it via:

$archiverManager->create('7z', '/source', '/destination.7z');

2. Pre/Post-Archive Events

Dispatch Symfony events before/after archiving:

use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

$dispatcher->dispatch(new PreArchiveEvent($source, $format));
$archivePath = $archiver->create($format, $source, $destination);
$dispatcher->dispatch(new
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.
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
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle