PHP code example of geekcodev / laravel-commercejson

1. Go to this page and download the library: Download geekcodev/laravel-commercejson library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

geekcodev / laravel-commercejson example snippets


// Автоматическая регистрация в boot() методе
$this->loadRoutesFrom(__DIR__.'/routes/api.php');

use GeekCo\CommerceJson\Facades\CommerceJson;

// Получить товары
$products = CommerceJson::products()->getProducts(
    page: 1,
    limit: 100,
    categoryId: 'uuid-here'
);

// Получить заказ
$order = CommerceJson::orders()->getOrder($orderId);

// Создать заказ
$newOrder = CommerceJson::orders()->createOrder($orderData);

// Импортировать предложения (цены и остатки)
CommerceJson::offers()->importOffers($offerImportData);

use GeekCo\CommerceJson\Services\ProductService;
use GeekCo\CommerceJson\Services\OrderService;
use GeekCo\CommerceJson\Http\Client\HttpClientInterface;

class OrderController extends Controller
{
    public function __construct(
        private HttpClientInterface $http,
        private OrderService $orderService
    ) {}

    public function index()
    {
        // Чтение через HTTP API
        $orders = $this->orderService->getOrders(page: 1, limit: 100);
        return view('orders.index', compact('orders'));
    }

    public function store(OrderCreateData $data)
    {
        // Создание через HTTP API + сохранение через CommandBus
        $order = $this->orderService->createOrder($data);
        return response()->json($order);
    }
}

use GeekCo\CommerceJson\Tests\TestCase;
use GeekCo\CommerceJson\Http\Client\HttpClientInterface;
use Mockery;

class ProductServiceTest extends TestCase
{
    protected function setUp(): void
    {
        parent::setUp();
        $this->mockHttp = Mockery::mock(HttpClientInterface::class);
        $this->productService = new ProductService($this->mockHttp, ...);
    }

    /** @test */
    public function get_products_returns_product_list(): void
    {
        $this->mockHttp->shouldReceive('get')
            ->once()
            ->andReturn(new ResponseDto(200, [], $mockResponse, ...));
        
        $products = $this->productService->getProducts(page: 1, limit: 100);
        $this->assertCount(10, $products->products);
    }
}

// Создание тестовых данных
$productData = ProductData::factory()->from([
    'id' => 'uuid-here',
    'name' => 'Test Product',
    'code' => 'TEST-001',
    'is_active' => true,
]);

// В тестах
protected function createProductData(array $attributes = []): ProductData
{
    return ProductData::factory()->from([
        'id' => $this->createTestUuid(),
        'name' => 'Test Product',
        ...$attributes,
    ]);
}

use GeekCo\CommerceJson\Http\Client\HttpClientInterface;

// Внедрение зависимости
public function __construct(
    private HttpClientInterface $http
) {}

// Использование
$response = $this->http->get('/catalog/products', ['page' => 1]);
$data = $response->data; // Массив данных

use GeekCo\CommerceJson\Bus\QueryBusInterface;
use GeekCo\CommerceJson\Commands\UpsertProductCommand;
use GeekCo\CommerceJson\Queries\GetProductQuery;
use Illuminate\Contracts\Bus\Dispatcher;

// Команда (запись) — через Laravel Bus
$command = new UpsertProductCommand($productData);
$product = $this->commandBus->dispatch($command); // Dispatcher

// Запрос (чтение) — через кастомный QueryBus
$query = new GetProductQuery($id);
$product = $this->queryBus->ask($query); // QueryBusInterface

use GeekCo\CommerceJson\Services\ProductService;

public function __construct(
    private ProductService $productService
) {}

// Чтение через HTTP API
$products = $this->productService->getProducts(page: 1, limit: 100);

// Запись через CommandBus
$product = $this->productService->syncProduct($productData);

use GeekCo\CommerceJson\Http\Controllers\ProductController;

// GET /api/commercejson/products
public function index(Request $request): JsonResponse
{
    $query = new GetProductsQuery(limit: 15);
    $products = $this->queryBus->ask($query);
    
    return response()->json(ProductData::collect($products->items()));
}

// POST /api/commercejson/products
public function store(Request $request): JsonResponse
{
    $command = new UpsertProductCommand(ProductData::from($request->all()));
    $product = $this->commandBus->dispatch($command);
    
    return response()->json(ProductData::from($product), 201);
}

use GeekCo\CommerceJson\Http\Client\Exceptions\AuthenticationException;
use GeekCo\CommerceJson\Http\Client\Exceptions\ValidationException;
use GeekCo\CommerceJson\Http\Client\Exceptions\BusinessException;
use GeekCo\CommerceJson\Http\Client\Exceptions\RateLimitException;

try {
    $this->http->post('/orders', $data);
} catch (AuthenticationException $e) {
    // 401, 403
} catch (ValidationException $e) {
    // 400 - $e->errorsAsString()
} catch (BusinessException $e) {
    // 422, 429
}

// Получить товары с пагинацией
$products = $productService->getProducts(
    page: 1,
    limit: 100,
    categoryId: 'uuid',
    isActive: true,
    updatedAfter: new DateTime('2026-01-01')
);

// Получить товар по ID
$product = $productService->getProduct($id);

// Импортировать товары
$result = $productService->importProducts($productsData);

// Деактивировать товар
$productService->deactivateProduct($id);

// Получить заказы
$orders = $orderService->getOrders(
    page: 1,
    limit: 50,
    status: 'new',
    updatedAfter: new DateTime('2026-01-01')
);

// Создать заказ
$order = $orderService->createOrder($orderCreateData);

// Обновить статус заказа
$orderService->updateOrderStatus($orderId, 'confirmed');

// Экспортировать новые заказы
$exported = $orderService->exportOrders(limit: 50);

use GeekCo\CommerceJson\Events\ProductsImported;
use GeekCo\CommerceJson\Events\OrderImported;
use GeekCo\CommerceJson\Events\SyncCompleted;

Event::listen(ProductsImported::class, function ($event) {
    Log::info("Импортировано {$event->importedCount} товаров");
});

Event::listen(OrderImported::class, function ($event) {
    // Обработка нового заказа
});

Event::listen(SyncCompleted::class, function ($event) {
    Log::info("Синхронизация завершена за {$event->durationSeconds}с");
});

// config/commercejson.php
return [
    'base_url' => env('COMMERCEJSON_BASE_URL'),
    
    'auth' => [
        'type' => env('COMMERCEJSON_AUTH_TYPE', 'bearer'),
        'token' => env('COMMERCEJSON_AUTH_TOKEN'),
    ],

    'timeout' => env('COMMERCEJSON_TIMEOUT', 30),
    'retry_attempts' => env('COMMERCEJSON_RETRY_ATTEMPTS', 3),

    'exchange' => [
        'mode' => env('COMMERCEJSON_EXCHANGE_MODE', 'auto'),
        'batch_size' => [
            'products' => 100,
            'offers' => 200,
            'orders' => 50,
        ],
        'queue' => [
            'enabled' => env('COMMERCEJSON_QUEUE_ENABLED', true),
            'connection' => env('COMMERCEJSON_QUEUE_CONNECTION', 'redis'),
        ],
    ],

    'sync' => [
        'schedule' => env('COMMERCEJSON_SYNC_SCHEDULE', '0 * * * *'),
        'incremental' => [
            'enabled' => env('COMMERCEJSON_INCREMENTAL_SYNC', true),
        ],
    ],

    'logging' => [
        'enabled' => env('COMMERCEJSON_LOGGING', true),
        'channel' => env('COMMERCEJSON_LOG_CHANNEL', 'stack'),
    ],
];

protected function schedule(Schedule $schedule): void
{
    // Ежечасная инкрементальная синхронизация
    $schedule->command('commercejson:sync --incremental')
        ->hourly();

    // Еженедельная полная синхронизация
    $schedule->command('commercejson:sync --full')
        ->weeklyOn(0, '2:00');
}

use GeekCo\CommerceJson\Http\Client\Exceptions\AuthenticationException;
use GeekCo\CommerceJson\Http\Client\Exceptions\ValidationException;
use GeekCo\CommerceJson\Http\Client\Exceptions\BusinessException;
use GeekCo\CommerceJson\Http\Client\Exceptions\RateLimitException;
use GeekCo\CommerceJson\Http\Client\Exceptions\ConnectionException;

try {
    $order = CommerceJson::orders()->createOrder($data);
} catch (AuthenticationException $e) {
    // 401, 403 - Неверные учётные данные
    Log::error('Ошибка авторизации: ' . $e->getMessage());
} catch (ValidationException $e) {
    // 400 - Ошибка валидации
    Log::error('Валидация: ' . $e->errorsAsString());
    foreach ($e->errors() as $error) {
        Log::error($error);
    }
} catch (BusinessException $e) {
    // 422, 429 - Бизнес-ошибка или rate limit
    Log::error('Бизнес-ошибка [' . $e->getCode() . ']: ' . $e->getMessage());
} catch (RateLimitException $e) {
    // 429 - Превышен лимит запросов
    $retryAfter = $e->retryAfter(); // секунд до повторной попытки
    $retryAt = $e->retryAt();       // DateTime для повторной попытки
    Log::warning("Превышен лимит запросов. Повтор через {$retryAfter}с");
} catch (ConnectionException $e) {
    // Ошибка соединения
    Log::error('Ошибка соединения: ' . $e->getMessage());
}

use GeekCo\CommerceJson\Exceptions\SyncException;

try {
    CommerceJson::syncFull();
} catch (SyncException $e) {
    Log::error('Синхронизация [' . $e->getSyncType() . ']: ' . $e->getMessage());
    $lastSync = $e->getLastSyncTime(); // DateTime последней успешной синхронизации
}

use GeekCo\CommerceJson\Jobs\Import\ImportProductsJob;
use GeekCo\CommerceJson\Jobs\Import\ImportOrdersJob;
use GeekCo\CommerceJson\Jobs\Sync\SyncFullJob;

// Импорт товаров асинхронно
ImportProductsJob::dispatch(
    page: 1,
    limit: 100,
    updatedAfter: now()->subHour()
);

// Цепочка заданий
ImportProductsJob::dispatch()->chain([
    new ImportOrdersJob(),
    new \GeekCo\CommerceJson\Jobs\Export\ExportOrdersJob(),
]);

// Полная синхронизация
SyncFullJob::dispatch();
bash
# Публикация конфигурации
php artisan vendor:publish --tag=commercejson-config

# Публикация миграций
php artisan vendor:publish --tag=commercejson-migrations

# Запуск миграций
php artisan migrate
bash
# Синхронизация изменений за последний час
php artisan commercejson:sync --incremental

# Синхронизация изменений с указанной даты
php artisan commercejson:sync --incremental --since=2026-01-01T00:00:00Z