dataStore->selectCollection(self::COLLECTION_NAME)->find(); $list = []; foreach ($cursor as $entry) { $entry = (new TenantObject())->jsonDeserialize((array)$entry); $list[$entry->getId()] = $entry; } return $list; } public function fetch(string $identifier): ?TenantObject { $entry = $this->dataStore->selectCollection(self::COLLECTION_NAME)->findOne(['identifier' => $identifier]); if (!$entry) { return null; } return (new TenantObject())->jsonDeserialize((array)$entry); } public function fetchByDomain(string $domain): ?TenantObject { $entry = $this->dataStore->selectCollection(self::COLLECTION_NAME)->findOne(['domains' => $domain]); if (!$entry) { return null; } $entity = new TenantObject(); $entity->jsonDeserialize((array)$entry); return $entity; } public function deposit(TenantObject $entry): ?TenantObject { if ($entry->getId()) { return $this->update($entry); } else { return $this->create($entry); } } private function create(TenantObject $entry): ?TenantObject { $result = $this->dataStore->selectCollection(self::COLLECTION_NAME)->insertOne($entry->jsonSerialize()); $entry->setId((string)$result->getInsertedId()); return $entry; } private function update(TenantObject $entry): ?TenantObject { $id = $entry->getId(); if (!$id) { return null; } $this->dataStore->selectCollection(self::COLLECTION_NAME)->updateOne(['_id' => $id], ['$set' => $entry->jsonSerialize()]); return $entry; } public function destroy(TenantObject $entry): void { $id = $entry->getId(); if (!$id) { return; } $this->dataStore->selectCollection(self::COLLECTION_NAME)->deleteOne([ '_id' => $id]); } // ========================================================================= // Settings Operations // ========================================================================= /** * Fetch settings for a tenant, optionally filtered to specific keys. * * @param string $identifier Tenant identifier * @param string[] $keys Optional list of keys to return; empty = all * * @return array */ public function fetchSettings(string $identifier, array $keys = []): array { $entry = $this->dataStore->selectCollection(self::COLLECTION_NAME)->findOne( ['identifier' => $identifier], ['projection' => ['settings' => 1]] ); $settings = (array)($entry['settings'] ?? []); if (empty($keys)) { return $settings; } $result = []; foreach ($keys as $key) { $result[$key] = $settings[$key] ?? null; } return $result; } /** * Merge-update settings for a tenant using atomic $set on sub-fields. * * @param string $identifier Tenant identifier * @param array $settings Key-value pairs to persist */ public function storeSettings(string $identifier, array $settings): bool { $updates = []; foreach ($settings as $key => $value) { $updates["settings.{$key}"] = $value; } $result = $this->dataStore->selectCollection(self::COLLECTION_NAME)->updateOne( ['identifier' => $identifier], ['$set' => $updates] ); return $result->getMatchedCount() > 0; } }