Weave 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

Avito Products Laravel Package

baks-dev/avito-products

Avito product module for BaksDev: install via Composer, run grouped PHPUnit tests, and manage Avito catalog products within your Laravel/PHP application. Requires PHP 8.4+, MIT licensed.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle from the BaksDev platform, not a Laravel package. composer require gets the code onto disk; it does not make it boot in a Laravel app. The README is a single install line, so your first real step is reading the source:

composer require baks-dev/avito-products
composer show baks-dev/avito-products      # read the requires block first
ls vendor/baks-dev/avito-products/src      # Bundle class, DI config, entities, DTOs, repositories
cat vendor/baks-dev/avito-products/composer.json

Look in this order:

  1. src/*Bundle.php (or *Extension.php) — what gets registered and what services are exposed.
  2. src/Resources/config/ — Symfony DI service definitions; this is your de-facto API map (class names, constructor dependencies, tags).
  3. src/Entity/ and src/DTO/ — the data shapes for an Avito product.
  4. src/Repository/, src/Client/, src/Message/ (whichever exist) — where the actual Avito API/DB interaction lives.
  5. tests/ — the only executable documentation in the repo; run it in a checkout of the package, not in your Laravel app:
git clone https://github.com/baks-dev/avito-products && cd avito-products
composer install
php bin/phpunit --group=avito-products

Prerequisites you must verify before committing: PHP 8.4+ (so Laravel 11/12, not Laravel 10), baks-dev/core:^7.x, and whatever Doctrine/Symfony components the module drags in. If composer why-not laravel/framework shows conflicts, stop here.

First use case: do not try to wire the bundle into Laravel's container. Instead pick the integration mode up front:

  • Mode A (recommended if you need the BaksDev domain logic): run the bundle inside a small Symfony/BaksDev service that talks to Avito, and have Laravel consume it over HTTP or a queue.
  • Mode B: reuse only the framework-agnostic pieces (DTOs, value objects, mappers) and wrap them in a Laravel service provider.
  • Mode C (usually right for a Laravel app): skip the package, talk to Avito's official API with Laravel's Http client, and use this repo's src/ purely as a reference for payload shapes and edge cases.

A concrete first milestone: take one Avito product payload from tests/, define a matching Eloquent model/migration, and get a queued sync job running against Avito's sandbox — regardless of which mode you chose. That validates auth and payload shape before you invest in bridging.

Implementation Patterns

Mode A — service isolation (cleanest fit). Keep the Symfony stack out of your Laravel app entirely:

// Laravel side: a thin client around your BaksDev service
class AvitoBridge
{
    public function __construct(private Http $http) {}

    public function product(int $avitoId): array
    {
        return $this->http->baseUrl(config('services.avito_bridge.url'))
            ->withToken(config('services.avito_bridge.token'))
            ->get("/products/{$avitoId}")
            ->throw()
            ->json();
    }
}

Wrap calls in a queued job so a slow Avito response never blocks a request.

Mode B — provider bridge for framework-free pieces. If the DTOs/mappers are plain PHP classes, bind them yourself:

// app/Providers/AvitoProductsServiceProvider.php
public function register(): void
{
    $this->app->bind(
        \BaksDev\AvitoProducts\Product\ProductMapper::class, // confirm the real FQCN in src/
        fn () => new \BaksDev\AvitoProducts\Product\ProductMapper()
    );
}

public function boot(): void
{
    // Do NOT call $this->loadMigrationsFrom(...) on Doctrine entities.
    // Mirror Avito product fields into your own Eloquent migration instead.
}

Then translate the package DTO into your model:

$dto = app(ProductMapper::class)->map($avitoPayload);

Product::updateOrCreate(
    ['avito_id' => $dto->getId()],
    ['title' => $dto->getTitle(), 'price' => $dto->getPrice(), 'status' => $dto->getStatus()],
);

Mode C — HTTP-native client. If the package adds no logic beyond request/response shapes, mirror it:

class AvitoClient
{
    public function __construct(private Http $http) {}

    public function products(array $filters = []): array
    {
        return $this->http->baseUrl('https://api.avito.ru')
            ->withToken(Cache::remember('avito_token', 3500, fn () => $this->token()))
            ->get('/autoload/v2/items', $filters)
            ->throw()
            ->json('resources', []);
    }
}

Sync workflow (all modes).

  1. Scheduled command (every N minutes) dispatches SyncAvitoProducts to a queue.
  2. Job pages through listings, maps each item to a local row, dispatches SyncAvitoProduct per ID.
  3. Per-item job fetches details and updates the row; failures go to failed_jobs with the raw Avito error.
  4. Store the raw Avito payload in a json column for debugging — you will need it when field mappings drift.

Configuration. There is no Laravel vendor:publish tag here. Put credentials in .env and expose them through config/services.php, then map to whatever Symfony parameters the bundle expects (AVITO_CLIENT_ID, AVITO_CLIENT_SECRET) only in the isolated service:

// config/services.php
'avito' => [
    'client_id'     => env('AVITO_CLIENT_ID'),
    'client_secret' => env('AVITO_CLIENT_SECRET'),
    'account_id'    => env('AVITO_ACCOUNT_ID'),
],

Testing. Use the package's tests/ as a behaviour spec even if you never run the bundle — copy representative payloads into your own fixtures and assert your mapper handles them. Mock the HTTP boundary, not the package:

Http::fake(['api.avito.ru/*' => Http::response(['resources' => []], 200)]);

Gotchas and Tips

  • The README is not documentation. It is one install line. Everything else in this assessment came from the repo layout and the Symfony ecosystem, not from published methods — treat any AvitoProducts::products() style pseudo-API you have seen elsewhere as unverified until you grep the actual src/.
  • No Laravel auto-discovery. Laravel looks for extra.laravel in composer.json; a Symfony bundle declares extra.symfony (flex recipe). The package will be installed and completely inert in a Laravel app. There is no facade, no publish tag, no Eloquent trait.
  • baks-dev/core is a platform, not a helper library. It will pull Doctrine and Symfony components. Check composer why-not before installing and expect psr/*, symfony/*, and Doctrine version constraints to be the flashpoints.
  • Doctrine vs Eloquent. The entities are Doctrine-mapped. Do not point Doctrine at your Laravel schema, and do not loadMigrationsFrom() Doctrine metadata. Mirror the fields into Eloquent tables and treat the entities purely as a field reference.
  • PHP 8.4 floor. Fine on Laravel 11/12; a hard block on Laravel 10 and older CI images. If your Docker base image is 8.3, composer install fails before you see any code.
  • Release cadence is fast, notes are empty. 7.4.9 through 7.4.15 landed within weeks, each release body is just v7.4.x. Pin an exact version ("baks-dev/avito-products": "7.4.15") and diff src/ between bumps; there is no changelog to rely on.
  • Zero community. 1 star, 0 dependents, no issues to search. When something breaks you are reading code. The MIT license means forking is a legitimate option — keep your integration behind one adapter interface so a fork or a full replacement is a one-file change.
  • Auth and rate limits are Avito's, not the package's. Avito uses OAuth client credentials with short-lived tokens and per-minute quotas. Cache the token, add a throttle middleware or RateLimiter::for('avito'), and handle 429 by releasing the job back onto the queue with delay rather than sleep() in a worker.
  • Debugging in Laravel. You get no Symfony profiler. Log the outbound request, status, and body (redact tokens) in a Http::withMiddleware() tap or a global client macro; without it a mapping failure is invisible.
  • Extension points are interfaces in src/. Prefer decorating an interface (bind your class in a Laravel provider) over editing vendor code. If the class you need to change is final or has a hardcoded client, that is your signal to switch to Mode C.
  • Field mapping drift is the recurring bug. Avito payloads nest price, location, and seller data with inconsistent nullability. Always keep the raw JSON column so you can re-derive mappings without re-fetching from Avito.
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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route