Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Update Campaign Donation Query #7630

Merged
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions give.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
* - The GiveWP Team
*/

use Give\Campaigns\Repositories\CampaignRepository;
use Give\Container\Container;
use Give\DonationForms\ServiceProvider as DonationFormsServiceProvider;
use Give\DonationForms\V2\Repositories\DonationFormsRepository;
Expand Down Expand Up @@ -132,6 +133,7 @@
* @property-read DonorRepositoryProxy $donors
* @property-read SubscriptionRepository $subscriptions
* @property-read DonationFormsRepository $donationForms
* @property-read CampaignRepository $campaigns
* @property-read Profile $donorDashboard
* @property-read TabsRegister $donorDashboardTabs
* @property-read Give_Recurring_DB_Subscription_Meta $subscription_meta
Expand Down
8 changes: 2 additions & 6 deletions src/Campaigns/CampaignDonationQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,8 @@ public function __construct(Campaign $campaign)
$this->where('paymentMode.meta_value', give_is_test_mode() ? 'test' : 'live');

// Include only forms associated with the Campaign.
$this->joinDonationMeta(DonationMetaKeys::FORM_ID, 'formId');
$this->join(function (JoinQueryBuilder $builder) {
$builder->leftJoin('give_campaign_forms', 'campaign_forms')
->on('campaign_forms.form_id', 'formId.meta_value');
});
$this->where('campaign_forms.campaign_id', $campaign->id);
$this->joinDonationMeta(DonationMetaKeys::CAMPAIGN_ID, 'campaignId');
$this->where('campaignId.meta_value', $campaign->id);
}

/**
Expand Down
92 changes: 92 additions & 0 deletions src/Campaigns/Migrations/Donations/AddCampaignId.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace Give\Campaigns\Migrations\Donations;

use Give\Donations\ValueObjects\DonationMetaKeys;
use Give\Framework\Database\DB;
use Give\Framework\Database\Exceptions\DatabaseQueryException;
use Give\Framework\Migrations\Contracts\Migration;
use Give\Framework\Migrations\Exceptions\DatabaseMigrationException;

/**
* @unreleased
*/
class AddCampaignId extends Migration
{
/**
* @inheritDoc
*/
public static function id(): string
{
return 'add_campaign_id_to_donations';
}

/**
* @inheritDoc
*/
public static function title(): string
{
return 'Add campaign id to donations';
}

/**
* @inheritdoc
*/
public static function timestamp(): string
{
return strtotime('2024-11-22 00:00:00');
}

/**
* @inheritDoc
* @throws DatabaseMigrationException
*/
public function run()
alaca marked this conversation as resolved.
Show resolved Hide resolved
{
$relationships = [];

try {
$data = DB::table('give_campaign_forms')
->select('campaign_id', 'form_id')
->getAll();

foreach ($data as $relationship) {
$relationships[$relationship->campaign_id][] = $relationship->form_id;
}

$donations = DB::table('posts')
->select('ID')
->attachMeta(
'give_donationmeta',
'ID',
'donation_id',
[DonationMetaKeys::FORM_ID(), 'formId']
)
->where('post_type', 'give_payment')
->getAll();

$donationMeta = [];

foreach ($donations as $donation) {
foreach ($relationships as $campaignId => $formIds) {
if (in_array($donation->formId, $formIds)) {
$donationMeta[] = [
'donation_id' => $donation->ID,
'meta_key' => DonationMetaKeys::CAMPAIGN_ID,
'meta_value' => $campaignId,
];

break;
}
}
}

if ( ! empty($donationMeta)) {
DB::table('give_donationmeta')
->insert($donationMeta, ['%d', '%s', '%d']);
}
} catch (DatabaseQueryException $exception) {
throw new DatabaseMigrationException("An error occurred while adding campaign ID to the donation meta table", 0, $exception);
}
}
}
9 changes: 4 additions & 5 deletions src/Campaigns/Migrations/RevenueTable/AddCampaignID.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Give\Campaigns\Migrations\RevenueTable;

use Give\Framework\Database\DB;
use Give\Framework\Database\Exceptions\DatabaseQueryException;
use Give\Framework\Migrations\Contracts\Migration;
use Give\Framework\Migrations\Exceptions\DatabaseMigrationException;
Expand Down Expand Up @@ -41,17 +42,15 @@ public static function timestamp(): string
*/
public function run()
{
global $wpdb;

$table = $wpdb->give_revenue;
$table = DB::prefix('give_revenue');

$sql = "
ALTER TABLE $table
ADD COLUMN campaign_id INT UNSIGNED NOT NULL DEFAULT '0'
ADD COLUMN campaign_id INT UNSIGNED NULL
";

try {
$wpdb->query($sql);
DB::query($sql);
} catch (DatabaseQueryException $exception) {
throw new DatabaseMigrationException("An error occurred while updating the $table table", 0, $exception);
}
Expand Down
15 changes: 13 additions & 2 deletions src/Campaigns/Repositories/CampaignRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,22 @@ public function getById(int $id)
* Get Campaign by Form ID
*/
public function getByFormId(int $formId)
{
return $this->queryByFormId($formId)->get();
}

/**
* @unreleased
*
* @param int $formId
*
* @return ModelQueryBuilder<Campaign>
*/
public function queryByFormId(int $formId): ModelQueryBuilder
{
return $this->prepareQuery()
->leftJoin('give_campaign_forms', 'campaigns.id', 'forms.campaign_id', 'forms')
->where('forms.form_id', $formId)
->get();
->where('forms.form_id', $formId);
}

/**
Expand Down
10 changes: 7 additions & 3 deletions src/Campaigns/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
use Give\Campaigns\Actions\CreateDefaultCampaignForm;
use Give\Campaigns\Actions\DeleteCampaignPage;
use Give\Campaigns\Actions\FormInheritsCampaignGoal;
use Give\Campaigns\Migrations\Donations\AddCampaignId as DonationsAddCampaignId;
use Give\Campaigns\Migrations\MigrateFormsToCampaignForms;
use Give\Campaigns\Migrations\P2P\SetCampaignType;
use Give\Campaigns\Migrations\RevenueTable\AddCampaignID;
use Give\Campaigns\Migrations\RevenueTable\AddCampaignID as RevenueTableAddCampaignID;
use Give\Campaigns\Migrations\RevenueTable\AddIndexes;
use Give\Campaigns\Migrations\RevenueTable\AssociateDonationsToCampaign;
use Give\Campaigns\Migrations\Tables\CreateCampaignFormsTable;
use Give\Campaigns\Migrations\Tables\CreateCampaignsTable;
use Give\Campaigns\Repositories\CampaignRepository;
use Give\DonationForms\V2\DonationFormsAdminPage;
use Give\Framework\Migrations\MigrationsRegister;
use Give\Helpers\Hooks;
Expand All @@ -29,6 +31,7 @@ class ServiceProvider implements ServiceProviderInterface
*/
public function register(): void
{
give()->singleton('campaigns', CampaignRepository::class);
$this->registerTableNames();
}

Expand Down Expand Up @@ -71,9 +74,10 @@ private function registerMigrations(): void
SetCampaignType::class,
CreateCampaignFormsTable::class,
MigrateFormsToCampaignForms::class,
AddCampaignID::class,
RevenueTableAddCampaignID::class,
AssociateDonationsToCampaign::class,
AddIndexes::class
AddIndexes::class,
DonationsAddCampaignId::class
]
);
}
Expand Down
13 changes: 13 additions & 0 deletions src/Donations/Models/Donation.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Give\Donations\Models;

use DateTime;
use Give\Campaigns\Models\Campaign;
use Give\Donations\DataTransferObjects\DonationQueryData;
use Give\Donations\Factories\DonationFactory;
use Give\Donations\Properties\BillingAddress;
Expand Down Expand Up @@ -55,6 +56,7 @@
* @property string $levelId
* @property string $gatewayTransactionId
* @property Donor $donor
* @property Campaign $campaign
* @property Subscription $subscription
* @property DonationNote[] $notes
* @property string $company
Expand Down Expand Up @@ -99,6 +101,7 @@ class Donation extends Model implements ModelCrud, ModelHasFactory
* @inheritdoc
*/
protected $relationships = [
'campaign' => Relationship::BELONGS_TO,
'donor' => Relationship::BELONGS_TO,
'subscription' => Relationship::BELONGS_TO,
'notes' => Relationship::HAS_MANY,
Expand Down Expand Up @@ -184,6 +187,16 @@ public function subscription(): ModelQueryBuilder
return give()->subscriptions->queryByDonationId($this->id);
}

/**
* @unreleased
*
* @return ModelQueryBuilder<Campaign>
*/
public function campaign(): ModelQueryBuilder
{
return give()->campaigns->queryByFormId($this->formId);
}

/**
* @since 2.19.6
*
Expand Down
4 changes: 4 additions & 0 deletions src/Donations/Repositories/DonationRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,10 @@ private function getCoreDonationMetaForDatabase(Donation $donation): array
DonationMetaKeys::ANONYMOUS => (int)$donation->anonymous
];

if ($campaign = $donation->campaign) {
$meta[DonationMetaKeys::CAMPAIGN_ID] = $campaign->id;
}

if ($donation->feeAmountRecovered !== null) {
$meta[DonationMetaKeys::FEE_AMOUNT_RECOVERED] = $donation->feeAmountRecovered->formatToDecimal();
}
Expand Down
2 changes: 2 additions & 0 deletions src/Donations/ValueObjects/DonationMetaKeys.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* @since 2.19.6
*
* @method static DonationMetaKeys AMOUNT()
* @method static DonationMetaKeys CAMPAIGN_ID()
* @method static DonationMetaKeys CURRENCY()
* @method static DonationMetaKeys GATEWAY()
* @method static DonationMetaKeys DONOR_ID()
Expand Down Expand Up @@ -47,6 +48,7 @@ class DonationMetaKeys extends Enum
use EnumInteractsWithQueryBuilder;

const AMOUNT = '_give_payment_total';
const CAMPAIGN_ID = '_give_campaign_id';
const BASE_AMOUNT = '_give_cs_base_amount';
const CURRENCY = '_give_payment_currency';
const EXCHANGE_RATE = '_give_cs_exchange_rate';
Expand Down
7 changes: 7 additions & 0 deletions src/Framework/QueryBuilder/Concerns/CRUD.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ trait CRUD
/**
* @see https://developer.wordpress.org/reference/classes/wpdb/insert/
*
* @unreleased Add support for inserting multiple rows at once
* @since 2.19.0
*
* @param array|string $format
Expand All @@ -22,6 +23,12 @@ trait CRUD
*/
public function insert($data, $format = null)
{
if (array_is_list($data)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alaca Do we have a polyfill for this somewhere? This is a PHP 8.1 function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JasonTheAdams Yeah. I installed and am using the stellarwp/arrays package now.

return DB::query(
$this->getInsertIntoSQL($data, $format)
);
}

return DB::insert(
$this->getTable(),
$data,
Expand Down
55 changes: 55 additions & 0 deletions src/Framework/QueryBuilder/Concerns/InsertInto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Give\Framework\QueryBuilder\Concerns;

use Give\Framework\Database\DB;

/**
* @unreleased
*/
trait InsertInto
{
/**
* @unreleased
*/
public function getInsertIntoSQL($data, $format): string
{
$sql = 'INSERT INTO ' . $this->getTable()
. sprintf(' (%s) ', implode(',', array_keys($data[0])))
. 'VALUES ';

foreach ($data as $row) {
$sql .= DB::prepare(
sprintf('(%s),', implode(',', $format ?? $this->getInsertIntoRowValuesFormat($row))),
$row
);
}

return rtrim($sql, ',');
}

/**
* Get values format used by DB::prepare()
*
* @unreleased
*
* @param array $data
*
* @return array
*/
private function getInsertIntoRowValuesFormat(array $data): array
{
return array_map(function ($value) {
if (is_int($value)) {
return '%d';
}

if (is_float($value)) {
return '%f';
}

return '%s';
}, $data);
}

}
2 changes: 2 additions & 0 deletions src/Framework/QueryBuilder/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Give\Framework\QueryBuilder\Concerns\FromClause;
use Give\Framework\QueryBuilder\Concerns\GroupByStatement;
use Give\Framework\QueryBuilder\Concerns\HavingClause;
use Give\Framework\QueryBuilder\Concerns\InsertInto;
use Give\Framework\QueryBuilder\Concerns\JoinClause;
use Give\Framework\QueryBuilder\Concerns\LimitStatement;
use Give\Framework\QueryBuilder\Concerns\MetaQuery;
Expand Down Expand Up @@ -36,6 +37,7 @@ class QueryBuilder
use TablePrefix;
use UnionOperator;
use WhereClause;
use InsertInto;

/**
* @return string
Expand Down
Loading
Loading