champs-libres/wopi-lib
Laravel-friendly PHP library to integrate WOPI (Web Application Open Platform Interface) with Office Online/Collabora. Provides helpers to implement WOPI endpoints, token handling, file access, and callbacks so you can view/edit documents from your app.
Installation
composer require champs-libres/wopi-lib
Add the service provider to config/app.php (if using Laravel):
ChampsLibres\WopiLib\WopiLibServiceProvider::class,
Basic Configuration Publish the config file:
php artisan vendor:publish --provider="ChampsLibres\WopiLib\WopiLibServiceProvider" --tag="wopi-config"
Update config/wopi.php with your WOPI endpoint details (e.g., host, scheme, baseUrl).
First Use Case: File Check Create a controller to handle WOPI requests:
use ChampsLibres\WopiLib\Wopi;
class WopiController extends Controller
{
public function checkFile(Request $request)
{
$wopi = new Wopi(config('wopi'));
$response = $wopi->checkFile($request->all());
return response()->json($response);
}
}
Routing
Define a route for WOPI requests (e.g., /wopi/checkfile):
Route::post('/wopi/checkfile', [WopiController::class, 'checkFile']);
WOPI Endpoint Handling
Use the Wopi facade or class to handle standard WOPI actions:
$wopi = new Wopi(config('wopi'));
// Check file
$checkResponse = $wopi->checkFile($request->all());
// Lock file
$lockResponse = $wopi->lockFile($request->all());
// Get file info
$fileInfo = $wopi->getFileInfo($request->all());
Middleware for Authentication Secure WOPI endpoints with middleware (e.g., API token validation):
Route::middleware(['auth:wopi'])->post('/wopi/{action}', [WopiController::class, 'handleAction']);
Create a custom middleware to validate WOPI headers (e.g., Authorization, X-WOPI-Override).
Integration with Storage Extend the library to work with Laravel’s filesystem or custom storage:
$wopi->setStorage(new LaravelFilesystemAdapter(storage_path('app/wopi')));
Async Processing Offload heavy operations (e.g., file conversion) to queues:
dispatch(new ProcessWopiFile($request->all()))->onQueue('wopi');
Custom Actions Extend the library to support non-standard WOPI actions:
class CustomWopiAction extends \ChampsLibres\WopiLib\Actions\BaseAction
{
public function execute(array $params)
{
// Custom logic
return ['success' => true, 'data' => []];
}
}
Register the action in config/wopi.php:
'actions' => [
'custom' => \App\Actions\CustomWopiAction::class,
],
CORS and Headers Configure CORS for WOPI clients (e.g., Office Online):
Header::set('Access-Control-Allow-Origin', '*');
Header::set('Access-Control-Allow-Methods', 'POST, OPTIONS');
Logging and Monitoring Log WOPI requests/responses for debugging:
$wopi->setLogger(new SingleChannelAdapter([
new StreamHandler(storage_path('logs/wopi.log'), Logger::DEBUG),
]));
Testing Mock WOPI responses in tests:
$wopi = new Wopi(config('wopi'));
$wopi->setHttpClient(new MockHttpClient());
CSRF and Security
VerifyCsrfToken middleware:
protected $except = [
'/wopi/*',
];
X-WOPI-Override headers to prevent CSRF attacks.File Locking Conflicts
wopi->lockFile() with exclusive mode for critical operations.URL and BasePath Issues
FileUrl and BaseFileUrl. Use Laravel’s url() helper:
'BaseFileUrl' => url('/wopi/files/'),
Timeouts
max_execution_time or use Laravel’s queue:work --timeout=3600.Case Sensitivity
checkfile, lock) are case-sensitive. Stick to lowercase in routes and config.Enable Verbose Logging
Set the logger to DEBUG in config/wopi.php:
'log_level' => \Monolog\Logger::DEBUG,
Validate WOPI Headers
Use dd($request->header()) to inspect incoming WOPI headers (e.g., Authorization, X-WOPI-Override).
Test with WOPI Client Use Office Online or OnlyOffice to test integration. Example WOPI request:
POST /wopi/checkfile HTTP/1.1
Host: yourdomain.com
Authorization: Basic base64credentials
X-WOPI-Override: YOUR_OVERRIDE
Check WOPI Spec Compliance Validate responses against the WOPI 2.0 spec. Example required fields:
{
"UserId": "user@example.com",
"Access": "edit",
"BaseFileUrl": "https://yourdomain.com/wopi/files/",
"FileUrl": "https://yourdomain.com/wopi/files/123.docx",
"Expires": "2025-12-31T23:59:59Z"
}
Custom Storage Adapters
Implement ChampsLibres\WopiLib\Contracts\StorageAdapter for S3, Database, etc.:
class S3StorageAdapter implements StorageAdapter
{
public function read($fileId) { /* ... */ }
public function write($fileId, $content) { /* ... */ }
// ...
}
Override HTTP Client Replace the default Guzzle client for custom behavior (e.g., retries):
$wopi->setHttpClient(new CustomHttpClient());
Hook into Actions
Extend BaseAction to modify responses:
$wopi->extendAction('checkfile', function ($response) {
$response['CustomField'] = 'value';
return $response;
});
Add Metadata Extend file info responses with custom metadata:
$wopi->setFileInfoTransformer(function ($file) {
return array_merge($file->toArray(), [
'custom_metadata' => ['key' => 'value'],
]);
});
How can I help you explore Laravel packages today?