baks-dev/avito-board
Laravel/PHP модуль baks-dev/avito-board для интеграции с Avito: публикация и управление объявлениями, поддержка PHP 8.4+. Устанавливается через Composer, есть PHPUnit-тесты (группа avito-board). Лицензия MIT.
Installation:
composer require baks-dev/avito-board baks-dev/core:^7.4
Verify php artisan package:discover detects the package.
Publish Assets:
php artisan vendor:publish --provider="BaksDev\AvitoBoard\AvitoBoardServiceProvider" --tag="config"
Update config/avito-board.php with your Avito API credentials (client ID, secret, and sandbox mode).
First Integration: Use the facade to fetch ads in a controller:
use BaksDev\AvitoBoard\Facades\AvitoBoard;
public function showAds(Request $request) {
$ads = AvitoBoard::searchAds($request->query('q'), $request->query('category', 'all'));
return view('ads.index', ['ads' => $ads]);
}
Route Setup:
Add routes in routes/web.php:
use Illuminate\Support\Facades\Route;
use BaksDev\AvitoBoard\Http\Controllers\AdController;
Route::get('/ads', [AdController::class, 'index']);
Blade Template:
Render ads in resources/views/ads/index.blade.php:
@foreach($ads as $ad)
<div class="ad-card">
<h3>{{ $ad->title }}</h3>
<p>{{ $ad->price }} ₽</p>
<img src="{{ $ad->imageUrl }}" alt="{{ $ad->title }}">
</div>
@endforeach
Test Locally:
Run the avito-board test group to verify core functionality:
php artisan test --group=avito-board
Ad Listing Management:
$ad = AvitoBoard::createAd([
'title' => 'Laptop for Sale',
'description' => 'Used MacBook Pro...',
'price' => 120000,
'category' => 'notebooks',
'images' => ['url1.jpg', 'url2.jpg'],
]);
$ads = AvitoBoard::getAds('notebooks', 20, 1); // Category, limit, page
Search Functionality:
$results = AvitoBoard::searchAds('laptop', 'notebooks', ['price_max' => 150000]);
$filteredAds = AvitoBoard::filterAds($ads, ['region' => 'moscow', 'price_min' => 100000]);
User Authentication:
$authUrl = AvitoBoard::getAuthUrl(['scope' => 'ads']);
// Redirect user to $authUrl
$user = AvitoBoard::handleAuthCallback($request);
Webhooks (Async Events):
AvitoBoard::onAdStatusChanged(function ($ad) {
// Update local DB or notify users
});
Laravel Service Provider:
Extend the package’s AvitoBoardServiceProvider to bind custom services:
public function register() {
$this->app->singleton('avito.board.cache', function () {
return Cache::store('redis')->rememberForever('avito_ads', function () {
return AvitoBoard::getAds('all');
});
});
}
Eloquent Models: Sync Avito ads with local models:
use BaksDev\AvitoBoard\Models\AvitoAd;
use App\Models\Ad;
$avitoAd = AvitoAd::find($id);
Ad::updateOrCreate(
['avito_id' => $avitoAd->id],
$avitoAd->toArray()
);
Blade Directives: Create custom Blade directives for Avito-specific logic:
Blade::directive('avitoPrice', function ($expression) {
return "<?php echo BaksDev\AvitoBoard\Helpers\Price::format({$expression}); ?>";
});
Usage:
@avitoPrice($ad->price)
Queue Jobs: Offload heavy operations (e.g., ad publishing):
use BaksDev\AvitoBoard\Jobs\PublishAd;
PublishAd::dispatch($adData)->onQueue('avito');
Middleware: Restrict Avito routes:
Route::middleware(['auth', 'avito.auth'])->group(function () {
Route::post('/ads', [AdController::class, 'store']);
});
Events: Subscribe to Avito events:
event(new \BaksDev\AvitoBoard\Events\AdPublished($ad));
| Pattern | Example |
|---|---|
| Repository Pattern | AvitoBoard::repository()->find($id) |
| Strategy Pattern | Swap Avito API client for testing: AvitoBoard::setClient($mockClient) |
| Observer Pattern | AvitoBoard::observe(Ad::class, function ($ad) { ... }) |
| Decorator Pattern | Extend ad data: AvitoBoard::decorateAds($ads, function ($ad) { ... }) |
Symfony-Laravel Conflicts:
EventDispatcher may clash with Laravel’s Events.
Fix: Use Laravel’s Event facade and bind Symfony events via a service provider:
$this->app->bind(
\Symfony\Component\EventDispatcher\EventDispatcherInterface::class,
function () {
return new class extends \Illuminate\Events\Dispatcher {
// Override Symfony-specific methods
};
}
);
Dependency on baks-dev/core:
baks-dev/core:^7.4, which may introduce Laravel incompatibilities.
Fix: Fork the core package or replace dependencies (e.g., use Laravel’s illuminate/support instead of Symfony components).Undocumented API:
if (config('avito-board.enabled')) {
$ads = AvitoBoard::getAds();
} else {
$ads = Cache::get('fallback_ads');
}
Rate Limiting:
throttle middleware and implement exponential backoff:
Route::middleware(['throttle:60,1'])->group(function () {
Route::get('/ads', [AdController::class, 'index']);
});
Caching Quirks:
Cache::rememberForever with a custom cache key:
Cache::rememberForever("avito_ads_{$category}_{$page}", function () use ($category, $page) {
return AvitoBoard::getAds($category, 20, $page);
});
Blade vs. Twig:
tightenco/ziggy.Authentication Flow:
Session and Redirect helpers to handle callbacks:
return Redirect::to(AvitoBoard::handleAuthCallback($request))->with('auth', $user);
Database Migrations:
Schema builder.
Fix: Manually create Eloquent migrations for Avito-related tables.Enable Avito Debug Mode:
config(['avito-board.debug' => true]);
This logs API requests/responses to storage/logs/avito-board.log.
Mock Avito API: Use Laravel’s HTTP client to mock responses:
$mockResponse = ['data' => ['ads' => []]];
AvitoBoard::setClient(Http::fake($mockResponse));
Test Avito Events: Listen for events in tests
How can I help you explore Laravel packages today?