This package is not avail on packagist yet. If you interesting, take a local clone or zip download then try it out.
Laravel package for efficient synchronization between your models and Google Sheets with advanced state tracking and error handling.
- π Sync from Laravel models to Google Sheets. Bidirectional sync is planned to implement
- π¦ Batch processing with memory efficiency
- π― Support for both full and partial syncs
- πΎ Sophisticated state tracking and resume capability
- π Automatic retry mechanism with exponential backoff
- π Detailed sync history and progress tracking
- π¨ Comprehensive notification system
- π Smart token management for Google API
- PHP
>= 8.1
- Laravel
>= 10
- Google API accessible
composer require zuko/syncro-sheet
Publish the configuration and migrations:
php artisan vendor:publish --provider="Zuko\SyncroSheet\LaravelSyncroSheetProvider"
php artisan migrate
- Create a Google Cloud Project
- Enable Google Sheets API
- Create credentials (OAuth 2.0 or Service Account)
- Set up your .env file:
GOOGLE_SHEETS_CLIENT_ID=your-client-id
GOOGLE_SHEETS_CLIENT_SECRET=your-client-secret
GOOGLE_SHEETS_REDIRECT_URI=your-redirect-uri
Or using service account:
GOOGLE_DEVELOPER_KEY=your-service-account-key
GOOGLE_SERVICE_ENABLED=true
As a wrapped around revolution/laravel-google-sheets
. these env vars is taken from config/google.php
If you already set these authorization values. You can leave env untouched.
// config/syncro-sheet.php
return [
'defaults' => [
'batch_size' => 1000,
'timeout' => 600,
'retries' => 3
],
// ... other configurations
];
use Zuko\SyncroSheet\Contracts\SheetSyncable;
class Product extends Model implements SheetSyncable
{
public function getSheetIdentifier(): string
{
return '1234567890-your-google-sheet-id';
}
public function getSheetName(): string
{
return 'Products';
}
public function toSheetRow(): array
{
return [
$this->id,
$this->name,
$this->price,
$this->stock,
$this->updated_at->format('Y-m-d H:i:s')
];
}
public function getBatchSize(): ?int
{
return 500; // Optional, defaults to config value
}
}
use Zuko\SyncroSheet\Services\SyncManager;
// Full sync
$syncManager = app(SyncManager::class);
$syncState = $syncManager->fullSync(Product::class);
// Partial sync
$syncState = $syncManager->partialSync(Product::class, [1, 2, 3]);
Or using facade static call
use SyncroSheet;
// or
use Zuko\SyncroSheet\Facades\SyncroSheet;
// Full sync
$syncState = SyncroSheet::fullSync(Product::class);
// Partial sync
$syncState = SyncroSheet::partialSync(Product::class, [1, 2, 3]);
// Get last sync state
$lastSync = SyncroSheet::getLastSync(Product::class);
# Full sync
php artisan sheet:sync Product
# Partial sync
php artisan sheet:sync Product --ids=1,2,3
use Zuko\SyncroSheet\Services\DataTransformer;
class ProductTransformer extends DataTransformer
{
protected function transformRecord(SheetSyncable $record): array
{
return [
'ID' => $record->id,
'Product Name' => $record->name,
'Price' => number_format($record->price, 2),
'In Stock' => $record->stock > 0 ? 'Yes' : 'No',
'Last Updated' => $record->updated_at->format('Y-m-d H:i:s')
];
}
}
use Zuko\SyncroSheet\Events\SyncEvent;
Event::listen(SyncEvent::SYNC_STARTED, function ($syncState) {
Log::info("Sync started for {$syncState->model_class}");
});
Event::listen(SyncEvent::SYNC_COMPLETED, function ($syncState) {
Log::info("Sync completed: {$syncState->total_processed} records");
});
use Zuko\SyncroSheet\Notifications\BaseNotification;
class CustomSyncNotification extends BaseNotification
{
protected function getMailMessage(): MailMessage
{
return (new MailMessage)
->subject('Custom Sync Notification')
->line('Your custom notification logic here');
}
protected function getSlackMessage(): SlackMessage
{
return (new SlackMessage)
->content('Custom Slack notification');
}
}
use Zuko\SyncroSheet\Services\StateManager;
$stateManager = app(StateManager::class);
// Get last successful sync
$lastSync = $stateManager->getLastSuccessfulSync(Product::class);
// Get sync history
$syncHistory = \Zuko\SyncroSheet\Models\SyncState::where('model_class', Product::class)
->with('entries')
->latest()
->get();
use Zuko\SyncroSheet\Services\ErrorHandler;
try {
$syncManager->fullSync(Product::class);
} catch (GoogleSheetsException $e) {
// Handle Google Sheets specific errors
} catch (SyncException $e) {
// Handle general sync errors
}
- Batch Size: Adjust based on your model's complexity and memory constraints
public function getBatchSize(): int
{
return $this->hasMedia() ? 100 : 1000;
}
- Rate Limiting: Configure based on your Google Sheets API quotas
// config/syncro-sheet.php
'sheets' => [
'rate_limit' => [
'max_requests' => 100,
'per_seconds' => 60
]
]
- Error Handling: Implement custom notification channels
use Zuko\SyncroSheet\Notifications\SyncFailedNotification;
class SlackSyncNotifier extends Notification
{
public function toSlack($notifiable)
{
// Custom Slack notification logic
}
}
Please see CONTRIBUTING.md for details.
The MIT License (MIT). Please see License File for more information.