PHP code example of fedorlabs / sync-forge

1. Go to this page and download the library: Download fedorlabs/sync-forge 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/ */

    

fedorlabs / sync-forge example snippets


$result = $syncForge->for(Product::class)
    ->key(['externalId'])
    ->source($rows)
    ->chunkSize(1000)
    ->deleteMissing(false)
    ->run();

echo $result->inserted;   // new rows
echo $result->updated;    // changed rows
echo $result->deleted;    // deleted rows (zero when deleteMissing is disabled)
echo $result->unchanged;  // skipped (no diff)

SyncForge\SyncForgeBundle::class => ['all' => true],

final class ProductSyncService
{
    public function __construct(private readonly SyncForge $syncForge) {}

    public function sync(iterable $rows): void
    {
        $this->syncForge->for(Product::class)
            ->key(['externalId'])
            ->source($rows)
            ->chunkSize(1000)
            ->deleteMissing(false)
            ->run();
    }
}

function fetchFromApi(HttpClientInterface $client): iterable
{
    $page = 1;
    do {
        $data = $client->request('GET', '/api/products', [
            'query' => ['page' => $page, 'per_page' => 500],
        ])->toArray();

        foreach ($data['items'] as $item) {
            yield [
                'externalId'  => $item['id'],
                'name'        => $item['title'],
                'price'       => (int) round($item['price'] * 100),
            ];
        }

        $page++;
    } while ($data['has_more'] ?? false);
}

$result = $syncForge->for(Product::class)
    ->key(['externalId'])
    ->source(fetchFromApi($client))
    ->chunkSize(500)
    ->deleteMissing(false)
    ->run();

$result = $syncForge->for(StockLevel::class)
    ->key(['sku', 'warehouseCode'])
    ->source($rows)
    ->chunkSize(2000)
    ->run();

$result = $syncForge->for(Price::class)
    ->key(['supplierId', 'sku'])
    ->scope(['supplierId' => 42])
    ->source($rows)
    ->deleteMissing(true)
    ->run();

$result = $syncForge->for(Product::class)
    ->key(['sku'])
    ->source($rows)
    ->setOnInsert(['createdAt' => new DateTimeImmutable(), 'updatedAt' => new DateTimeImmutable(), 'isNew' => false])
    ->touchOnChange('updatedAt')                                  // any change
    ->touchOnChange('priceUpdatedAt', ['price'])                  // only when the price changed
    ->touchOnChange('stockUpdatedAt', ['stock'])
    ->run();

$result = $syncForge->for(Part::class)
    ->key(['sku'])
    ->source($rows)
    ->returnInserted()
    ->run();

foreach ($result->insertedKeys as $row) {
    // ['sku' => 'B-2', 'id' => 17]
}

$result = $syncForge->for(Product::class)
    ->key(['externalId'])
    ->source($rows)
    ->deleteMissing(true)
    ->dryRun(true)
    ->run();

printf("would delete %d rows\n", $result->deleted);

$result = $syncForge->for(Product::class)
    ->key(['externalId'])
    ->source($rows)
    ->continueOnError(true)
    ->run();

if (!$result->isSuccess()) {
    foreach ($result->errors as $error) {
        // $error->type: 'validation' | 'db' | 'pipeline' | 'internal'
        // $error->chunkIndex: which chunk failed (null for delete-missing phase)
        // Log or otherwise handle $error->type and $error->message.
    }
}