namespace PatreonSync\Service; use PatreonSync\Core\Content\PatreonLink\PatreonLinkRepository; use Shopware\Core\Framework\Context; use Symfony\Component\HttpClient\HttpClient; class PatreonSyncService { private PatreonLinkRepository $linkRepo; public function __construct(PatreonLinkRepository $linkRepo) { $this->linkRepo = $linkRepo; } public function syncCustomer(string $customerId, array $patreonData, Context $context): void { $liveData = $this->fetchLivePatreonData($patreonData['access_token']); $link = $this->linkRepo->getByCustomerId($customerId, $context); $payload = [ 'id' => $link ? $link->getId() : null, 'customerId' => $customerId, 'patreonUserId' => $liveData['user_id'], 'accessToken' => $patreonData['access_token'], 'refreshToken' => $patreonData['refresh_token'], 'currentTier' => $liveData['tier'], 'lastSyncedAt' => (new \DateTime())->format('Y-m-d H:i:s'), ]; $this->linkRepo->upsert([$payload], $context); $groupName = $this->mapTierToGroup($liveData['tier']); $groupId = $this->getGroupIdForTier($liveData['tier'], $context); if ($groupId) { $this->container->get('customer.repository')->update([[ 'id' => $customerId, 'groupId' => $groupId, ]], $context); } $customerRepo = $this->container->get('customer.repository'); $customerRepo->update([[ 'id' => $customerId, 'groupId' => $this->getGroupIdByName($groupName, $context), ]], $context); } private function fetchLivePatreonData(string $accessToken): array { $client = HttpClient::create(); $response = $client->request('GET', 'https://www.patreon.com/api/oauth2/v2/identity?include=memberships.tier', [ 'headers' => [ 'Authorization' => 'Bearer ' . $accessToken, ], ]); $data = $response->toArray(); return [ 'user_id' => $data['data']['id'], 'tier' => $data['included'][0]['attributes']['tier']['title'] ?? 'unknown', ]; } private function getGroupIdForTier(string $tier, Context $context): ?string { $repo = $this->container->get('patreon_tier_mapping.repository'); $criteria = new Criteria(); $criteria->addFilter(new EqualsFilter('patreonTier', $tier)); $result = $repo->search($criteria, $context)->first(); return $result?->getCustomerGroupId(); } private function getGroupIdByName(string $name, Context $context): ?string { $groupRepo = $this->container->get('customer_group.repository'); $criteria = new Criteria(); $criteria->addFilter(new EqualsFilter('name', $name)); return $groupRepo->searchIds($criteria, $context)->firstId(); } }