Skip to content

Commit 897825a

Browse files
authored
Feature: Add trash option to the donors list (#8134)
1 parent 15054fa commit 897825a

File tree

22 files changed

+497
-41
lines changed

22 files changed

+497
-41
lines changed

includes/database/class-give-db-donors.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public function get_columns() {
5858
'user_id' => '%d',
5959
'name' => '%s',
6060
'email' => '%s',
61+
'status' => '%s',
6162
'payment_ids' => '%s',
6263
'purchase_value' => '%f',
6364
'purchase_count' => '%d',
@@ -81,6 +82,7 @@ public function get_column_defaults() {
8182
'user_id' => 0,
8283
'email' => '',
8384
'name' => '',
85+
'status' => 'active',
8486
'payment_ids' => '',
8587
'purchase_value' => 0.00,
8688
'purchase_count' => 0,

src/Donors/Actions/LoadDonorsListTableAssets.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Give\Donors\Actions;
44

55
use Give\Donors\ListTable\DonorsListTable;
6+
use Give\Donors\ValueObjects\DonorStatus;
67
use Give\Framework\Database\DB;
78
use Give\Framework\Support\Facades\Scripts\ScriptAsset;
89
use Give\Helpers\Language;
@@ -14,6 +15,7 @@
1415
class LoadDonorsListTableAssets
1516
{
1617
/**
18+
* @unreleased Add "statuses" property to the localize script
1719
* @unreleased add recurringDonations check to the localize script
1820
* @since 2.27.1 Pass dismissed recommendations to the localize script
1921
* @since 2.20.0
@@ -40,6 +42,7 @@ public function __invoke()
4042
'pluginUrl' => GIVE_PLUGIN_URL,
4143
'dismissedRecommendations' => $this->getDismissedRecommendations(),
4244
'recurringDonationsEnabled' => Utils::isPluginActive('give-recurring/give-recurring.php'),
45+
'statuses' => $this->getStatuses()
4346
]);
4447

4548
wp_enqueue_script($handleName);
@@ -87,6 +90,31 @@ private function getForms(): array
8790
], $options);
8891
}
8992

93+
/**
94+
* @unreleased
95+
*/
96+
private function getStatuses(): array
97+
{
98+
$statuses = [];
99+
100+
foreach(DonorStatus::labels() as $value => $label) {
101+
if ($value !== DonorStatus::ACTIVE) {
102+
$statuses[] = [
103+
'value' => $value,
104+
'text' => $label,
105+
];
106+
}
107+
}
108+
109+
// Make active status default
110+
return array_merge([
111+
[
112+
'value' => DonorStatus::ACTIVE,
113+
'text' => __('Active', 'give'),
114+
],
115+
], $statuses);
116+
}
117+
90118
/**
91119
* Retrieve a list of dismissed recommendations.
92120
*

src/Donors/DataTransferObjects/DonorQueryData.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
use Give\Donors\Models\Donor;
66
use Give\Donors\ValueObjects\DonorAddress;
77
use Give\Donors\ValueObjects\DonorMetaKeys;
8+
use Give\Donors\ValueObjects\DonorStatus;
89
use Give\Framework\Support\Facades\DateTime\Temporal;
910
use Give\Framework\Support\ValueObjects\Money;
1011

1112
/**
1213
* Class DonorObjectData
1314
*
15+
* @unreleased Add "status" property
1416
* @since 4.4.0 Add "avatarId" and "company" properties
1517
* @since 2.19.6
1618
*/
@@ -21,6 +23,10 @@ final class DonorQueryData
2123
* @var int
2224
*/
2325
public $id;
26+
/**
27+
* @var DonorStatus
28+
*/
29+
public $status;
2430
/**
2531
* @var string
2632
*/
@@ -81,6 +87,7 @@ final class DonorQueryData
8187
/**
8288
* Convert data from donor object to Donor Model
8389
*
90+
* @unreleased Add "status" property
8491
* @since 4.4.0 Add "avatarId" and "company" properties
8592
* @since 3.7.0 Add "phone" property
8693
* @since 2.24.0 add $totalAmountDonated and $totalNumberOfDonations
@@ -97,6 +104,7 @@ public static function fromObject($object)
97104
$self->userId = (int)$object->userId;
98105
$self->prefix = $object->{DonorMetaKeys::PREFIX()->getKeyAsCamelCase()};
99106
$self->email = $object->email;
107+
$self->status = new DonorStatus($object->status);
100108
$self->phone = $object->phone;
101109
$self->name = $object->name;
102110
$self->firstName = $object->firstName;

src/Donors/Endpoints/DeleteDonor.php

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -119,23 +119,4 @@ public function handleRequest(WP_REST_Request $request)
119119
'successes' => $successes,
120120
]);
121121
}
122-
123-
124-
/**
125-
* Split string
126-
*
127-
* @since 2.20.0
128-
*
129-
* @param string $ids
130-
*
131-
* @return string[]
132-
*/
133-
protected function splitString($ids)
134-
{
135-
if (strpos($ids, ',')) {
136-
return array_map('trim', explode(',', $ids));
137-
}
138-
139-
return [trim($ids)];
140-
}
141122
}

src/Donors/Endpoints/Endpoint.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,23 @@ public function authorizationStatusCode()
8282

8383
return 401;
8484
}
85+
86+
87+
/**
88+
* Split string
89+
*
90+
* @unreleased
91+
*
92+
* @param string $ids
93+
*
94+
* @return string[]
95+
*/
96+
protected function splitString(string $ids): array
97+
{
98+
if (strpos($ids, ',')) {
99+
return array_map('trim', explode(',', $ids));
100+
}
101+
102+
return [trim($ids)];
103+
}
85104
}

src/Donors/Endpoints/ListDonors.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Give\Donors\ListTable\DonorsListTable;
66
use Give\Donations\ValueObjects\DonationMetaKeys;
7+
use Give\Donors\ValueObjects\DonorStatus;
78
use Give\Framework\Database\DB;
89
use Give\Framework\QueryBuilder\QueryBuilder;
910
use WP_REST_Request;
@@ -72,6 +73,11 @@ public function registerRoute()
7273
'required' => false,
7374
'default' => 0
7475
],
76+
'status' => [
77+
'enum' => [...array_values(DonorStatus::toArray())],
78+
'default' => DonorStatus::ACTIVE,
79+
'required' => false
80+
],
7581
'end' => [
7682
'type' => 'string',
7783
'required' => false,
@@ -189,6 +195,7 @@ public function getTotalDonorsCount(): int
189195
}
190196

191197
/**
198+
* @unreleased Add "status" where condition
192199
* @since 2.24.0 Replace Query Builder with Donors model
193200
* @since 2.21.0
194201
*
@@ -202,6 +209,7 @@ private function getWhereConditions(QueryBuilder $query): QueryBuilder
202209
$start = $this->request->get_param('start');
203210
$end = $this->request->get_param('end');
204211
$campaignId = $this->request->get_param('campaignId');
212+
$status = $this->request->get_param('status');
205213

206214
if ($search) {
207215
if (ctype_digit($search)) {
@@ -238,6 +246,9 @@ private function getWhereConditions(QueryBuilder $query): QueryBuilder
238246
});
239247
}
240248

249+
250+
$query->where('status', $status);
251+
241252
return $query;
242253
}
243254
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
namespace Give\Donors\Endpoints;
4+
5+
use Exception;
6+
use Give\Donors\Models\Donor;
7+
use Give\Donors\ValueObjects\DonorStatus;
8+
use WP_Error;
9+
use WP_REST_Request;
10+
use WP_REST_Response;
11+
12+
/**
13+
* @unreleased
14+
*/
15+
class UpdateStatus extends Endpoint
16+
{
17+
/**
18+
* @var string
19+
*/
20+
protected $endpoint = 'admin/donors/status';
21+
22+
/**
23+
* @inheritDoc
24+
*/
25+
public function registerRoute()
26+
{
27+
register_rest_route(
28+
'give-api/v2',
29+
$this->endpoint,
30+
[
31+
[
32+
'methods' => 'POST',
33+
'callback' => [$this, 'handleRequest'],
34+
'permission_callback' => [$this, 'permissionsCheck'],
35+
],
36+
'args' => [
37+
'ids' => [
38+
'type' => 'string',
39+
'required' => true,
40+
'validate_callback' => function ($ids) {
41+
foreach ($this->splitString($ids) as $id) {
42+
if ( ! $this->validateInt($id)) {
43+
return false;
44+
}
45+
}
46+
47+
return true;
48+
},
49+
],
50+
'status' => [
51+
'enum' => [...array_values(DonorStatus::toArray())],
52+
'required' => true,
53+
],
54+
],
55+
]
56+
);
57+
}
58+
59+
/**
60+
* @inheritDoc
61+
*/
62+
public function permissionsCheck()
63+
{
64+
if (current_user_can('manage_options') || current_user_can('edit_give_payments')) {
65+
return true;
66+
}
67+
68+
return new WP_Error(
69+
'rest_forbidden',
70+
esc_html__('You don\'t have permission to update Donors status', 'give'),
71+
['status' => $this->authorizationStatusCode()]
72+
);
73+
}
74+
75+
/**
76+
* @unreleased
77+
*/
78+
public function handleRequest(WP_REST_Request $request): WP_REST_Response
79+
{
80+
$ids = array_map('intval', $this->splitString($request->get_param('ids')));
81+
$status = $request->get_param('status');
82+
$errors = $successes = [];
83+
84+
foreach ($ids as $id) {
85+
try {
86+
/**
87+
* Fires before updating donor status.
88+
*
89+
* @param int $id The ID of the donor.
90+
* @param bool $status Confirm Donor related donations deletion.
91+
*/
92+
do_action('give_pre_donor_status_update', $id, $status);
93+
$donor = Donor::find($id);
94+
$donorStatus = new DonorStatus($status);
95+
$donor->status = $donorStatus;
96+
$donor->save();
97+
$successes[] = $id;
98+
} catch (Exception $e) {
99+
$errors[] = $id;
100+
}
101+
}
102+
103+
return new WP_REST_Response([
104+
'errors' => $errors,
105+
'successes' => $successes,
106+
]);
107+
}
108+
}

src/Donors/Factories/DonorFactory.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
namespace Give\Donors\Factories;
44

55
use Give\Donors\ValueObjects\DonorAddress;
6+
use Give\Donors\ValueObjects\DonorStatus;
67
use Give\Framework\Models\Factories\ModelFactory;
78
use Give\Framework\Support\ValueObjects\Money;
89

910
class DonorFactory extends ModelFactory
1011
{
1112
/**
13+
* @unreleased Add "status" property
1214
* @since 4.4.0 Add "company", "avatarId", "additionalEmails", and "addresses" properties
1315
* @since 3.7.0 Add "phone" property
1416
* @since 2.19.6
@@ -44,6 +46,7 @@ public function definition(): array
4446
'lastName' => $lastName,
4547
'prefix' => $this->faker->randomElement(give_get_option('title_prefixes', array_values(give_get_default_title_prefixes()))),
4648
'name' => trim("$firstName $lastName"),
49+
'status' => new DonorStatus(DonorStatus::ACTIVE),
4750
'email' => $this->faker->email,
4851
'phone' => $this->faker->phoneNumber,
4952
'company' => $this->faker->company,
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace Give\Donors\Migrations;
4+
5+
use Give\Donors\ValueObjects\DonorStatus;
6+
use Give\Framework\Database\DB;
7+
use Give\Framework\Migrations\Contracts\Migration;
8+
use Give\Framework\Migrations\Exceptions\DatabaseMigrationException;
9+
10+
/**
11+
* @unreleased
12+
*/
13+
class AddStatusColumn extends Migration
14+
{
15+
/**
16+
* @inheritDoc
17+
*/
18+
public static function id(): string
19+
{
20+
return 'add_status_column_to_donors_table';
21+
}
22+
23+
/**
24+
* @inheritDoc
25+
*/
26+
public static function title(): string
27+
{
28+
return 'Add status column to the give_donors table';
29+
}
30+
31+
/**
32+
* @inheritdoc
33+
*/
34+
public static function timestamp(): string
35+
{
36+
return strtotime('2025-10-07 00:00:00');
37+
}
38+
39+
/**
40+
* @inheritDoc
41+
* @throws DatabaseMigrationException
42+
*/
43+
public function run()
44+
{
45+
$table = DB::prefix('give_donors');
46+
$defaultStatus = DonorStatus::ACTIVE;
47+
48+
$columnAdded = maybe_add_column($table, 'status', "ALTER TABLE $table ADD COLUMN status VARCHAR(12) NOT NULL DEFAULT '$defaultStatus'");
49+
50+
if ( ! $columnAdded) {
51+
throw new DatabaseMigrationException("An error occurred while updating the $table table");
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)