Files
ladill-woo-manager/app/Services/Woo/CatalogSyncService.php
T
isaacclad e709de6593
Deploy Ladill Woo Manager / deploy (push) Successful in 35s
Use WooCommerce store currency for product and order money.
Sync currency from the plugin, format product prices and totals with it, and show the store currency on product price fields instead of hard-coding GHS.
2026-07-24 15:38:07 +00:00

129 lines
3.6 KiB
PHP

<?php
namespace App\Services\Woo;
use App\Models\User;
use App\Models\WooStore;
class CatalogSyncService
{
public function __construct(
private PluginClient $client,
private ProductIngestService $products,
private CategoryIngestService $categories,
private SubscriptionService $subscriptions,
) {}
public function syncAll(WooStore $store, ?User $user = null): array
{
$this->syncStoreMeta($store);
return [
'categories' => $this->syncCategories($store),
'products' => $this->syncProducts($store, $user),
];
}
/**
* Pull store-level settings (currency, site name) from the WooCommerce plugin.
*/
public function syncStoreMeta(WooStore $store): void
{
$response = $this->client->get($store, 'store');
if (! is_array($response)) {
return;
}
$this->applyStoreMeta($store, $response);
}
/** @param array<string, mixed> $payload */
public function applyStoreMeta(WooStore $store, array $payload): void
{
$currency = strtoupper(trim((string) ($payload['currency'] ?? '')));
if (preg_match('/^[A-Z]{3}$/', $currency) !== 1) {
return;
}
$meta = is_array($store->metadata) ? $store->metadata : [];
$meta['currency'] = $currency;
$symbol = trim((string) ($payload['currency_symbol'] ?? ''));
if ($symbol !== '') {
$meta['currency_symbol'] = $symbol;
}
$siteName = trim((string) ($payload['site_name'] ?? ''));
$updates = ['metadata' => $meta];
if ($siteName !== '' && (string) $store->site_name !== $siteName) {
$updates['site_name'] = $siteName;
}
$store->forceFill($updates)->save();
$store->refresh();
}
public function syncCategories(WooStore $store): int
{
$response = $this->client->get($store, 'categories', ['per_page' => 100]);
if (! is_array($response)) {
return 0;
}
$items = $response['data'] ?? $response;
if (! is_array($items)) {
return 0;
}
$count = 0;
foreach ($items as $item) {
if (! is_array($item)) {
continue;
}
$this->categories->ingest($store, $item);
$count++;
}
return $count;
}
public function syncProducts(WooStore $store, ?User $user = null): int
{
$response = $this->client->get($store, 'products', ['per_page' => 100]);
if (! is_array($response)) {
return 0;
}
if (isset($response['currency']) || isset($response['currency_symbol'])) {
$this->applyStoreMeta($store, $response);
}
$items = $response['data'] ?? $response;
if (! is_array($items)) {
return 0;
}
// Bare list responses are numeric arrays of products — ignore non-product keys.
if (array_is_list($items) === false && isset($response['data']) === false) {
$items = array_values(array_filter($items, fn ($item) => is_array($item) && isset($item['id'])));
}
$count = 0;
foreach ($items as $item) {
if (! is_array($item)) {
continue;
}
$externalId = (int) ($item['id'] ?? 0);
if ($user && ! $this->subscriptions->canIngestProduct($user, $store, $externalId)) {
continue;
}
$this->products->ingest($store, $item);
$count++;
}
return $count;
}
}