Installation
Run composer require biplane/yandex-direct-bundle and enable the bundle in AppKernel.php:
new Biplane\Bundle\YandexDirectBundle\BiplaneYandexDirectBundle(),
Basic Configuration
Add minimal required config in config/packages/biplane_yandex_direct.yaml:
biplane_yandex_direct:
locale: ru
user:
access_token: "%env(YANDEX_DIRECT_ACCESS_TOKEN)%"
First Use Case Inject the client service in a controller/service and fetch campaigns:
use Biplane\Bundle\YandexDirectBundle\Client\ClientInterface;
class CampaignController extends AbstractController
{
public function __construct(private ClientInterface $client) {}
public function index()
{
$campaigns = $this->client->campaign()->getList();
return $this->json($campaigns);
}
}
Service Injection Use dependency injection for all Yandex Direct operations:
// Controller
public function __construct(
private ClientInterface $client,
private CampaignService $campaignService
) {}
// Service
public function syncCampaigns()
{
$campaigns = $this->client->campaign()->getList();
$this->campaignService->process($campaigns);
}
Command-Line Operations Create custom commands for bulk operations:
use Biplane\Bundle\YandexDirectBundle\Client\ClientInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class SyncCampaignsCommand extends Command
{
protected static $defaultName = 'yandex:campaign:sync';
public function __construct(private ClientInterface $client) {}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$campaigns = $this->client->campaign()->getList();
// Process campaigns...
return Command::SUCCESS;
}
}
Event-Driven Sync Use Symfony events to trigger syncs after entity changes:
// In a subscriber
public function onCampaignUpdated(CampaignUpdatedEvent $event)
{
$this->client->campaign()->update($event->getCampaign()->toArray());
}
Environment Variables
Store sensitive tokens in .env:
YANDEX_DIRECT_ACCESS_TOKEN=your_token_here
YANDEX_DIRECT_MASTER_TOKEN=your_master_token_here
Reference them in config:
user:
access_token: "%env(YANDEX_DIRECT_ACCESS_TOKEN)%"
master_token: "%env(YANDEX_DIRECT_MASTER_TOKEN)%"
Caching Responses Cache API responses to reduce calls:
$cache = $this->container->get('cache.app');
$key = 'yandex_campaigns_' . $campaignId;
if (!$cache->has($key)) {
$campaign = $this->client->campaign()->get($campaignId);
$cache->set($key, $campaign, 3600);
}
Error Handling Centralize error handling with a decorator:
class YandexDirectClientDecorator implements ClientInterface
{
public function __construct(private ClientInterface $client, private LoggerInterface $logger) {}
public function campaign()
{
return new CampaignDecorator($this->client->campaign(), $this->logger);
}
}
Token Management
master_token. Omitting it will cause silent failures.401 Unauthorized errors.Locale Limitations
ru, en, and ua are supported. Using other locales will throw exceptions.Dump Listener Overhead
dump_listener with dump: all logs every API call, which can bloat logs. Use only-fail for debugging.Rate Limiting
use Symfony\Component\Stopwatch\Stopwatch;
$stopwatch = new Stopwatch();
$event = $stopwatch->start('yandex_api_call');
try {
$response = $this->client->campaign()->getList();
} catch (RateLimitExceededException $e) {
$event->stop();
$duration = $event->getDuration();
sleep(max(1, $duration * 1.5)); // Backoff
retry();
}
Enable API Dumps
Configure in config/packages/biplane_yandex_direct.yaml:
dump_listener:
enabled: true
dump: only-fail
Dumps are saved to %kernel.cache_dir%/api_dumps with timestamps.
Logging Use Monolog to log API interactions:
# config/packages/monolog.yaml
handlers:
yandex_direct:
type: stream
path: "%kernel.logs_dir%/yandex_direct.log"
level: debug
channels: ["yandex_direct"]
Common Errors
InvalidArgumentException: Validate access_token and login are set if using master_token.RuntimeException with "Invalid locale": Ensure locale is one of ru, en, or ua.Custom API Clients Extend the base client to add domain-specific methods:
class CustomCampaignClient extends AbstractCampaignClient
{
public function getActiveCampaigns(): array
{
$campaigns = $this->getList();
return array_filter($campaigns, fn($c) => $c['Status'] === 'Active');
}
}
Event Dispatching Dispatch custom events for API responses:
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class YandexDirectClientDecorator implements ClientInterface
{
public function __construct(
private ClientInterface $client,
private EventDispatcherInterface $dispatcher
) {}
public function campaign()
{
return new CampaignDecorator(
$this->client->campaign(),
$this->dispatcher
);
}
}
Middleware for Requests Add middleware to modify requests/responses:
use Biplane\YandexDirect\Client\Middleware\MiddlewareInterface;
class LoggingMiddleware implements MiddlewareInterface
{
public function __invoke(callable $next, RequestInterface $request)
{
$this->logger->info('Yandex Direct Request', ['data' => $request->getData()]);
$response = $next($request);
$this->logger->info('Yandex Direct Response', ['data' => $response->getData()]);
return $response;
}
}
Register it in services:
services:
Biplane\YandexDirect\Client\ClientInterface:
class: Biplane\Bundle\YandexDirectBundle\Client\YandexDirectClient
arguments:
- '@Biplane\YandexDirect\Client\MiddlewareStack'
calls:
- [addMiddleware, ['@app.yandex_direct.logging_middleware']]
How can I help you explore Laravel packages today?