Skip to content

Commit

Permalink
feature: add get routes for donations
Browse files Browse the repository at this point in the history
  • Loading branch information
glaubersilva committed Jan 28, 2025
1 parent a9ba5df commit e22047b
Show file tree
Hide file tree
Showing 5 changed files with 280 additions and 0 deletions.
91 changes: 91 additions & 0 deletions src/Donations/Controllers/DonationRequestController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

namespace Give\Donations\Controllers;

use Give\Donations\Models\Donation;
use Give\Donations\Repositories\DonationRepository;
use Give\Donations\ValueObjects\DonationMetaKeys;
use Give\Donations\ValueObjects\DonationRoute;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;

/**
* @unreleased
*/
class DonationRequestController
{
/**
* @unreleased
*
* @return WP_Error | WP_REST_Response
*/
public function getDonation(WP_REST_Request $request)
{
$donation = Donation::find($request->get_param('id'));

if ( ! $donation) {
return new WP_Error('donation_not_found', __('Donation not found', 'give'), ['status' => 404]);
}

return new WP_REST_Response($donation->toArray());
}

/**
* @unreleased
*/
public function getDonations(WP_REST_Request $request): WP_REST_Response
{
$campaignId = $request->get_param('campaignId');
$page = $request->get_param('page');
$perPage = $request->get_param('per_page');

$query = give(DonationRepository::class)->prepareQuery();

if ($campaignId) {
$metaKey = DonationMetaKeys::CAMPAIGN_ID;
$query->attachMeta('give_donationmeta', 'ID', 'donation_id', $metaKey)
->where("give_donationmeta_attach_meta_{$metaKey}.meta_value", $campaignId);
}

$query
->limit($perPage)
->offset(($page - 1) * $perPage);

$donations = $query->getAll() ?? [];
$totalDonations = empty($donations) ? 0 : Donation::query()->count();
$totalPages = (int)ceil($totalDonations / $perPage);

$response = rest_ensure_response($donations);
$response->header('X-WP-Total', $totalDonations);
$response->header('X-WP-TotalPages', $totalPages);

$base = add_query_arg(
map_deep($request->get_query_params(), function ($value) {
if (is_bool($value)) {
$value = $value ? 'true' : 'false';
}

return urlencode($value);
}),
rest_url(DonationRoute::DONATIONS)
);

if ($page > 1) {
$prevPage = $page - 1;

if ($prevPage > $totalPages) {
$prevPage = $totalPages;
}

$response->link_header('prev', add_query_arg('page', $prevPage, $base));
}

if ($totalPages > $page) {
$nextPage = $page + 1;
$response->link_header('next', add_query_arg('page', $nextPage, $base));
}

return $response;
}
}
106 changes: 106 additions & 0 deletions src/Donations/Routes/RegisterDonationRoutes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

namespace Give\Donations\Routes;

use Give\Donations\Controllers\DonationRequestController;
use Give\Donations\ValueObjects\DonationRoute;
use WP_REST_Request;
use WP_REST_Server;

/**
* @unreleased
*/
class RegisterDonationRoutes
{
/**
* @var DonationRequestController
*/
protected $donationRequestController;

/**
* @unreleased
*/
public function __construct(DonationRequestController $donationRequestController)
{
$this->donationRequestController = $donationRequestController;
}

/**
* @unreleased
*/
public function __invoke()
{
$this->registerGetDonation();
$this->registerGetDonations();
}

/**
* Get Donation route
*
* @unreleased
*/
public function registerGetDonation()
{
register_rest_route(
DonationRoute::NAMESPACE,
DonationRoute::DONATION,
[
[
'methods' => WP_REST_Server::READABLE,
'callback' => function (WP_REST_Request $request) {
return $this->donationRequestController->getDonation($request);
},
'permission_callback' => function () {
return current_user_can('manage_options');
},
],
'args' => [
'id' => [
'type' => 'integer',
'required' => true,
],
],
]
);
}

/**
* Get Donations route
*
* @unreleased
*/
public function registerGetDonations()
{
register_rest_route(
DonationRoute::NAMESPACE,
DonationRoute::DONATIONS,
[
[
'methods' => WP_REST_Server::READABLE,
'callback' => function (WP_REST_Request $request) {
return $this->donationRequestController->getDonations($request);
},
'permission_callback' => '__return_true',
],
'args' => [
'page' => [
'type' => 'integer',
'default' => 1,
'minimum' => 1,
],
'per_page' => [
'type' => 'integer',
'default' => 30,
'minimum' => 1,
'maximum' => 100,
],
'campaignId' => [
'type' => 'integer',
'required' => false,
'default' => 0,
],
],
]
);
}
}
10 changes: 10 additions & 0 deletions src/Donations/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public function boot()
MoveDonationCommentToDonationMetaTable::class,
UnserializeTitlePrefix::class,
]);

$this->registerRoutes();
}

/**
Expand Down Expand Up @@ -129,4 +131,12 @@ private function addCustomFieldsToDonationDetails()
echo (new DonationDetailsController())->show($donationId);
});
}

/**
* @unreleased
*/
private function registerRoutes()
{
Hooks::addAction('rest_api_init', Routes\RegisterDonationRoutes::class);
}
}
22 changes: 22 additions & 0 deletions src/Donations/ValueObjects/DonationRoute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Give\Donations\ValueObjects;

use Give\Framework\Support\ValueObjects\Enum;

/**
* @unreleased
*
* @method static DonationRoute NAMESPACE()
* @method static DonationRoute DONATION()
* @method static DonationRoute DONATIONS()
* @method bool isNamespace()
* @method bool isDonation()
* @method bool isDonations()
*/
class DonationRoute extends Enum
{
const NAMESPACE = 'give-api/v2';
const DONATION = 'donations/(?P<id>[0-9]+)';
const DONATIONS = 'donations';
}
51 changes: 51 additions & 0 deletions tests/Unit/Donations/Routes/GetDonationsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Unit\Donations\Routes;

use Exception;
use Give\Campaigns\Models\Campaign;
use Give\Donations\Models\Donation;
use Give\Donations\ValueObjects\DonationMetaKeys;
use Give\Donations\ValueObjects\DonationRoute;
use Give\Tests\RestApiTestCase;
use Give\Tests\TestTraits\RefreshDatabase;
use WP_REST_Request;
use WP_REST_Server;

/**
* @unreleased
*/
class GetDonationsTest extends RestApiTestCase
{
use RefreshDatabase;

/**
* @unreleased
*
* @throws Exception
*/
public function testGetDonationsByCampaignId()
{
/** @var Campaign $campaign */
$campaign = Campaign::factory()->create();

/** @var Donation $donation */
$donation = Donation::factory()->create();
give()->payment_meta->update_meta($donation->id, DonationMetaKeys::CAMPAIGN_ID, $campaign->id);

$route = '/' . DonationRoute::NAMESPACE . '/' . DonationRoute::DONATIONS;
$request = new WP_REST_Request(WP_REST_Server::READABLE, $route);
$request->set_query_params(
[
'campaignId' => $campaign->id,
]
);

$response = $this->dispatchRequest($request);
$status = $response->get_status();
$data = $response->get_data();

$this->assertEquals(200, $status);
$this->assertEquals($donation->id, $data[0]->id);
}
}

0 comments on commit e22047b

Please sign in to comment.