From 72d6c17a547444815a76e30037703c4b33870452 Mon Sep 17 00:00:00 2001 From: Jon Waldstein Date: Tue, 14 Jan 2025 14:07:33 -0500 Subject: [PATCH] feature: add json encoding and get method --- .../Listeners/StoreCustomFields.php | 6 +- .../Repositories/DonationMetaRepository.php | 44 ++++++++++++-- .../Repositories/DonorMetaRepository.php | 45 +++++++++++++-- .../GenerateConfirmationPageReceipt.php | 8 +-- src/Framework/Support/Facades/Str.php | 23 ++++++++ .../TestDonationMetaRepository.php | 57 +++++++++++++++++-- .../Repositories/TestDonorMetaRepository.php | 51 ++++++++++++++++- 7 files changed, 212 insertions(+), 22 deletions(-) diff --git a/src/DonationForms/Listeners/StoreCustomFields.php b/src/DonationForms/Listeners/StoreCustomFields.php index c2cf7c26ab..a60fdf85fa 100644 --- a/src/DonationForms/Listeners/StoreCustomFields.php +++ b/src/DonationForms/Listeners/StoreCustomFields.php @@ -79,19 +79,21 @@ protected function handleFileUpload(File $field): ?array } /** + * @unreleased replace update_meta with meta repository * @since 3.0.0 */ protected function storeAsDonorMeta(int $donorId, string $metaKey, $value): void { - give()->donor_meta->update_meta($donorId, $metaKey, $value); + give()->donors->meta->upsert($donorId, $metaKey, $value); } /** + * @unreleased replace update_meta with meta repository * @since 3.0.0 */ protected function storeAsDonationMeta(int $donationId, string $metaKey, $value): void { - give()->payment_meta->update_meta($donationId, $metaKey, $value); + give()->donations->meta->upsert($donationId, $metaKey, $value); } /** diff --git a/src/Donations/Repositories/DonationMetaRepository.php b/src/Donations/Repositories/DonationMetaRepository.php index 4eaf3228bf..fd4f0c7020 100644 --- a/src/Donations/Repositories/DonationMetaRepository.php +++ b/src/Donations/Repositories/DonationMetaRepository.php @@ -3,26 +3,52 @@ namespace Give\Donations\Repositories; use Give\Framework\Database\DB; +use Give\Framework\QueryBuilder\QueryBuilder; +use Give\Framework\Support\Facades\Str; /** * @unreleased */ class DonationMetaRepository { - /** * @unreleased + * @return mixed|null */ - public function upsert(int $donationId, string $metaKey, $metaValue): void + public function get(int $donationId, string $metaKey) { - $queryBuilder = DB::table("give_donationmeta"); - - $query = $queryBuilder + $query = $this->prepareQuery() ->where("donation_id", $donationId) ->where("meta_key", $metaKey) ->get(); if (!$query) { + return null; + } + + $value = $query->meta_value; + + if (Str::isJson($value)) { + return json_decode($value, false); + } + + return $value; + } + + /** + * @unreleased + */ + public function upsert(int $donationId, string $metaKey, $metaValue): void + { + if (is_array($metaValue) || is_object($metaValue)) { + $metaValue = json_encode($metaValue); + } + + $exists = $this->get($donationId, $metaKey); + + $queryBuilder = $this->prepareQuery(); + + if (!$exists) { $queryBuilder->insert([ "donation_id" => $donationId, "meta_key" => $metaKey, @@ -35,4 +61,12 @@ public function upsert(int $donationId, string $metaKey, $metaValue): void ->update(["meta_value" => $metaValue]); } } + + /** + * @unreleased + */ + public function prepareQuery(): QueryBuilder + { + return DB::table("give_donationmeta"); + } } diff --git a/src/Donors/Repositories/DonorMetaRepository.php b/src/Donors/Repositories/DonorMetaRepository.php index c810762b54..79ac209f6d 100644 --- a/src/Donors/Repositories/DonorMetaRepository.php +++ b/src/Donors/Repositories/DonorMetaRepository.php @@ -3,26 +3,53 @@ namespace Give\Donors\Repositories; use Give\Framework\Database\DB; +use Give\Framework\QueryBuilder\QueryBuilder; +use Give\Framework\Support\Facades\Str; /** * @unreleased */ class DonorMetaRepository { - /** * @unreleased + * + * @return mixed|null */ - public function upsert(int $donorId, string $metaKey, $metaValue): void + public function get(int $donorId, string $metaKey) { - $queryBuilder = DB::table("give_donormeta"); - - $query = $queryBuilder + $query = $this->prepareQuery() ->where("donor_id", $donorId) ->where("meta_key", $metaKey) ->get(); if (!$query) { + return null; + } + + $value = $query->meta_value; + + if (Str::isJson($value)) { + return json_decode($value, false); + } + + return $value; + } + + /** + * @unreleased + */ + public function upsert(int $donorId, string $metaKey, $metaValue): void + { + if (is_array($metaValue) || is_object($metaValue)) { + $metaValue = json_encode($metaValue); + } + + $exists = $this->get($donorId, $metaKey); + + $queryBuilder = $this->prepareQuery(); + + if (!$exists) { $queryBuilder->insert([ "donor_id" => $donorId, "meta_key" => $metaKey, @@ -35,4 +62,12 @@ public function upsert(int $donorId, string $metaKey, $metaValue): void ->update(["meta_value" => $metaValue]); } } + + /** + * @unreleased + */ + public function prepareQuery(): QueryBuilder + { + return DB::table("give_donormeta"); + } } diff --git a/src/Framework/Receipts/Actions/GenerateConfirmationPageReceipt.php b/src/Framework/Receipts/Actions/GenerateConfirmationPageReceipt.php index 268f7245bc..09fdc71f08 100644 --- a/src/Framework/Receipts/Actions/GenerateConfirmationPageReceipt.php +++ b/src/Framework/Receipts/Actions/GenerateConfirmationPageReceipt.php @@ -33,6 +33,7 @@ public function __invoke(DonationReceipt $receipt): DonationReceipt } /** + * @unreleased replace get_meta with meta repositories * @since 3.4.0 updated to check for metaKey first and then fallback to name * @since 3.3.0 updated conditional to check for scopes and added support for retrieving values programmatically with Fields API * @since 3.0.0 @@ -70,17 +71,16 @@ protected function getCustomFields(Donation $donation): array continue; } - $value = give()->donor_meta->get_meta( + $value = give()->donors->meta->get( $donation->donor->id, - $field->getMetaKey() ?? $field->getName(), - true + $field->getMetaKey() ?? $field->getName() ); } elseif ($field->getScope()->isDonation()) { if (!metadata_exists('donation', $donation->id, $field->getMetaKey() ?? $field->getName())) { continue; } - $value = give()->payment_meta->get_meta($donation->id, $field->getMetaKey() ?? $field->getName(), true); + $value = give()->donations->meta->get($donation->id, $field->getMetaKey() ?? $field->getName()); } else { $value = null; } diff --git a/src/Framework/Support/Facades/Str.php b/src/Framework/Support/Facades/Str.php index c0adbedf33..d6425f2627 100644 --- a/src/Framework/Support/Facades/Str.php +++ b/src/Framework/Support/Facades/Str.php @@ -2,6 +2,8 @@ namespace Give\Framework\Support\Facades; +use JsonException; + use function sanitize_title; class Str @@ -816,4 +818,25 @@ public static function flushCache() static::$camelCache = []; static::$studlyCache = []; } + + /** + * @unreleased + * + * Determine if a given value is valid JSON. + * + * @param mixed $value + * @return bool + */ + public static function isJson($value): bool + { + if (!is_string($value)) { + return false; + } + + if (function_exists('json_validate')) { + return json_validate($value); + } + + return !is_null(json_decode($value, true)); + } } diff --git a/tests/Unit/Donations/Repositories/TestDonationMetaRepository.php b/tests/Unit/Donations/Repositories/TestDonationMetaRepository.php index 194ac6e300..f233c72602 100644 --- a/tests/Unit/Donations/Repositories/TestDonationMetaRepository.php +++ b/tests/Unit/Donations/Repositories/TestDonationMetaRepository.php @@ -45,17 +45,31 @@ public function testUpsertShouldInsertNewMeta(): void { $donation = Donation::factory()->create(); $repository = new DonationMetaRepository(); - $repository->upsert($donation->id, 'test_key', 'test_value'); + $repository->upsert($donation->id, 'test_key_string', 'Test Value'); + $repository->upsert($donation->id, 'test_key_array', ['Test Value']); + $repository->upsert($donation->id, 'test_key_int', 1); - $meta = DB::table('give_donationmeta') + $meta1 = DB::table('give_donationmeta') ->where('donation_id', $donation->id) - ->where('meta_key', 'test_key') + ->where('meta_key', 'test_key_string') ->get() ->meta_value; - $this->assertEquals('test_value', $meta); + $meta2 = DB::table('give_donationmeta') + ->where('donation_id', $donation->id) + ->where('meta_key', 'test_key_array') + ->get() + ->meta_value; + $meta3 = DB::table('give_donationmeta') + ->where('donation_id', $donation->id) + ->where('meta_key', 'test_key_int') + ->get() + ->meta_value; + $this->assertEquals('Test Value', $meta1); + $this->assertEquals(['Test Value'], json_decode($meta2, false)); + $this->assertEquals(1, $meta3); } /** @@ -84,4 +98,39 @@ public function testUpsertShouldUpdateExistingMeta(): void $this->assertEquals('Test Value Two', $meta); } + + /** + * @unreleased + * @throws Exception + */ + public function testGetShouldReturnNullIfMetaDoesNotExist(): void + { + $donation = Donation::factory()->create(); + $repository = new DonationMetaRepository(); + + $meta = $repository->get($donation->id, 'test_key'); + + $this->assertNull($meta); + } + + /** + * @unreleased + * @throws Exception + */ + public function testGetShouldReturnMetaValueIfExists(): void + { + $donation = Donation::factory()->create(); + $repository = new DonationMetaRepository(); + + DB::table('give_donationmeta') + ->insert([ + 'donation_id' => $donation->id, + 'meta_key' => 'test_key', + 'meta_value' => 'Test Value', + ]); + + $meta = $repository->get($donation->id, 'test_key'); + + $this->assertEquals('Test Value', $meta); + } } diff --git a/tests/Unit/Donors/Repositories/TestDonorMetaRepository.php b/tests/Unit/Donors/Repositories/TestDonorMetaRepository.php index 088ceca619..ded81cd14b 100644 --- a/tests/Unit/Donors/Repositories/TestDonorMetaRepository.php +++ b/tests/Unit/Donors/Repositories/TestDonorMetaRepository.php @@ -27,14 +27,30 @@ public function testUpsertMetaShouldInsertNewMeta(): void $donor = Donor::factory()->create(); $repository = new DonorMetaRepository(); $repository->upsert($donor->id, 'test_key', 'test_value'); + $repository->upsert($donor->id, 'test_key_array', ['Test Value']); + $repository->upsert($donor->id, 'test_key_int', 1); - $meta = DB::table('give_donormeta') + $meta1 = DB::table('give_donormeta') ->where('donor_id', $donor->id) ->where('meta_key', 'test_key') ->get() ->meta_value; - $this->assertEquals('test_value', $meta); + $meta2 = DB::table('give_donormeta') + ->where('donor_id', $donor->id) + ->where('meta_key', 'test_key_array') + ->get() + ->meta_value; + + $meta3 = DB::table('give_donormeta') + ->where('donor_id', $donor->id) + ->where('meta_key', 'test_key_int') + ->get() + ->meta_value; + + $this->assertEquals('test_value', $meta1); + $this->assertEquals(['Test Value'], json_decode($meta2, true)); + $this->assertEquals(1, $meta3); } /** @@ -84,4 +100,35 @@ public function testUpsertMetaShouldUpdateExistingMeta(): void $this->assertEquals('Test Value Two', $meta); } + /** + * @unreleased + */ + public function testGetShouldReturnNullIfMetaDoesNotExist(): void + { + $donor = Donor::factory()->create(); + $repository = new DonorMetaRepository(); + + $meta = $repository->get($donor->id, 'test_key'); + + $this->assertNull($meta); + } + + /** + * @unreleased + */ + public function testGetShouldReturnMetaValueIfExists(): void + { + $donor = Donor::factory()->create(); + $repository = new DonorMetaRepository(); + + DB::table('give_donormeta') + ->insert([ + 'donor_id' => $donor->id, + 'meta_key' => 'test_key', + 'meta_value' => 'Test Value', + ]); + + $meta = $repository->get($donor->id, 'test_key'); + $this->assertEquals('Test Value', $meta); + } }