cleentfaar/tissue-clamav-adapter
Laravel adapter for Tissue that integrates ClamAV scanning into your file upload/validation flow. Provides a simple bridge to run antivirus checks on uploaded files and handle infected results within your application.
Installation Add the package via Composer:
composer require cleentfaar/tissue-clamav-adapter
Publish the config (if needed):
php artisan vendor:publish --provider="Cleentfaar\TissueClamavAdapter\TissueClamavAdapterServiceProvider"
Basic Configuration
Ensure ClamAV is installed and running on your system. Configure the adapter in config/tissue-clamav-adapter.php:
'clamav' => [
'socket' => '/var/run/clamav/clamav.socket', // Default socket path
'timeout' => 30, // Timeout in seconds
],
First Use Case: Scanning a File Integrate with Laravel Filesystem or Tissue:
use Cleentfaar\TissueClamavAdapter\ClamavAdapter;
use Tissue\File;
$adapter = app(ClamavAdapter::class);
$file = new File(storage_path('app/example.pdf'));
$result = $adapter->scan($file);
if ($result->isClean()) {
// File is safe
} else {
// File contains malware
foreach ($result->getErrors() as $error) {
log::error("ClamAV scan error: " . $error);
}
}
Pre-Processing
Use Laravel’s HandleUploadedFile or a custom request handler to process uploads before storage:
use Illuminate\Http\Request;
use Cleentfaar\TissueClamavAdapter\ClamavAdapter;
public function store(Request $request)
{
$request->validate(['file' => 'required|file']);
$file = $request->file('file');
$adapter = app(ClamavAdapter::class);
$scanResult = $adapter->scan($file);
if (!$scanResult->isClean()) {
throw new \Exception("Malware detected!");
}
$path = $file->store('uploads');
// Proceed with storage...
}
Batch Scanning For bulk operations (e.g., migrating old files), use Laravel Queues:
use Illuminate\Support\Facades\Bus;
Bus::batch([
new ScanFileJob($file1),
new ScanFileJob($file2),
])->then(function (Batch $batch) {
// Handle results
})->dispatch();
Integration with Tissue
Use Tissue’s File class for consistent handling:
use Tissue\File;
use Tissue\Storage\Filesystem;
$storage = new Filesystem(storage_path('app'));
$file = $storage->get('example.pdf');
$adapter->scan($file);
\Log::info('ClamAV scan', ['file' => $file->path(), 'clean' => $result->isClean()]);
spatie/laravel-virus-scanner) if ClamAV fails.ClamAV Not Running
Connection refused or timeouts.clamd) is running:
sudo systemctl status clamav-daemon
clamscan --bell -r /path/to/files
Socket vs. TCP
'clamav' => [
'host' => '127.0.0.1',
'port' => 3310,
],
Large Files
timeout in config or chunk the file:
$adapter->setChunkSize(1024 * 1024); // 1MB chunks
False Positives
config/tissue-clamav-adapter.php:
'exclusions' => [
'*.jpg',
'*.png',
'vendor/**',
],
Enable Verbose Logging
Add to config/tissue-clamav-adapter.php:
'debug' => env('CLAMAV_DEBUG', false),
Check Laravel logs for raw ClamAV output.
Test with Known Malware
Use EICAR test file (https://www.eicar.org/download-anti-malware-testfile/) to verify setup:
file_put_contents('eicar.com', file_get_contents('https://www.eicar.org/download-anti-malware-testfile/'));
$result = $adapter->scan(new File('eicar.com'));
// Should return errors
Custom Error Handling
Override the adapter’s handleScanResult method to customize responses:
$adapter->setErrorHandler(function ($errors) {
throw new \RuntimeException("Scan failed: " . implode(', ', $errors));
});
Async Scanning
Use Laravel’s dispatchSync for synchronous scans or dispatch for async:
$adapter->scan($file)->dispatchSync();
Multi-Scanner Setup
Combine with other Tissue adapters (e.g., spatie/laravel-virus-scanner) for redundancy:
$results = [
$adapter1->scan($file),
$adapter2->scan($file),
];
$allClean = collect($results)->every(fn ($r) => $r->isClean());
How can I help you explore Laravel packages today?