Skip to content

Commit

Permalink
Refactor: migrate v2 forms to campaigns and add upgraded forms as cam…
Browse files Browse the repository at this point in the history
…paign not-default forms (#7645)
  • Loading branch information
glaubersilva authored Dec 23, 2024
1 parent a26e2f6 commit 7dd1436
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 28 deletions.
159 changes: 143 additions & 16 deletions src/Campaigns/Migrations/MigrateFormsToCampaignForms.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Give\Framework\Migrations\Contracts\Migration;
use Give\Framework\Migrations\Exceptions\DatabaseMigrationException;
use Give\Framework\QueryBuilder\JoinQueryBuilder;
use Give\Framework\QueryBuilder\QueryBuilder;
use stdClass;

/**
* @unreleased
Expand Down Expand Up @@ -38,8 +40,8 @@ public function run()
{
DB::transaction(function() {
try {
array_map([$this, 'createCampaignForForm'], $this->getFormData());
array_map([$this, 'addUpgradedFormToCampaign'], $this->getUpgradedFormData());
array_map([$this, 'createCampaignForForm'], $this->getAllFormsData());
array_map([$this, 'addUpgradedV2FormToCampaign'], $this->getUpgradedV2FormsData());
} catch (DatabaseQueryException $exception) {
DB::rollback();
throw new DatabaseMigrationException('An error occurred while creating initial campaigns', 0, $exception);
Expand All @@ -50,7 +52,7 @@ public function run()
/**
* @unreleased
*/
protected function getFormData(): array
protected function getAllFormsData(): array
{
$query = DB::table('posts', 'forms')->distinct()
->select(
Expand All @@ -65,9 +67,8 @@ protected function getFormData(): array
->join(function (JoinQueryBuilder $builder) {
$builder
->leftJoin('give_formmeta', 'formmeta')
->on('formmeta.form_id', 'forms.ID');
})
->where('formmeta.meta_key', 'formBuilderSettings');
->on('formmeta.form_id', 'forms.ID')->joinRaw("AND formmeta.meta_key = 'formBuilderSettings'");
});

// Exclude forms already associated with a campaign (ie Peer-to-peer).
$query->join(function (JoinQueryBuilder $builder) {
Expand All @@ -77,8 +78,25 @@ protected function getFormData(): array
})
->whereIsNull('campaigns.id');

// Exclude forms with an `upgraded` status, which are archived.
$query->where('forms.post_status', 'upgraded', '!=');
/**
* Exclude forms with an "auto-draft" status, which are WP revisions.
*
* @see https://wordpress.org/documentation/article/post-status/#auto-draft
*/
$query->where('forms.post_status', 'auto-draft', '!=');

/**
* Excluded upgraded V2 forms as their corresponding V3 version will be used to create the campaign - later the V2 form will be added to the proper campaign as a non-default form through the addUpgradedV2FormToCampaign() method.
*/
$query->whereNotIn('forms.ID', function (QueryBuilder $builder) {
$builder
->select('meta_value')
->from('give_formmeta')
->where('meta_key', 'migratedFormId');
});

// Ensure campaigns will be displayed in the same order on the list table
$query->orderBy('forms.ID');

return $query->getAll();
}
Expand All @@ -87,7 +105,7 @@ protected function getFormData(): array
* @unreleased
* @return array [{formId, campaignId, migratedFormId}]
*/
protected function getUpgradedFormData(): array
protected function getUpgradedV2FormsData(): array
{
return DB::table('posts', 'forms')
->select(['forms.ID', 'formId'], ['campaign_forms.campaign_id', 'campaignId'])
Expand All @@ -98,7 +116,6 @@ protected function getUpgradedFormData(): array
->on('campaign_forms.form_id', 'forms.ID');
})
->where('forms.post_type', 'give_forms')
->where('forms.post_status', 'publish')
->whereIsNotNull('give_formmeta_attach_meta_migratedFormId.meta_value')
->getAll();
}
Expand All @@ -109,10 +126,11 @@ protected function getUpgradedFormData(): array
public function createCampaignForForm($formData): void
{
$formId = $formData->id;
$formTitle = $formData->title;
$formStatus = $formData->status;
$formTitle = $formData->title;
$formCreatedAt = $formData->createdAt;
$formSettings = json_decode($formData->settings);
$isV3Form = ! is_null($formData->settings);
$formSettings = $isV3Form ? json_decode($formData->settings) : $this->getV2FormSettings($formId);

DB::table('give_campaigns')
->insert([
Expand Down Expand Up @@ -141,7 +159,7 @@ public function createCampaignForForm($formData): void
/**
* @param $data
*/
protected function addUpgradedFormToCampaign($data): void
protected function addUpgradedV2FormToCampaign($data): void
{
$this->addCampaignFormRelationship($data->migratedFormId, $data->campaignId);
}
Expand All @@ -154,25 +172,26 @@ protected function addCampaignFormRelationship($formId, $campaignId)
DB::table('give_campaign_forms')
->insert([
'form_id' => $formId,
'campaign_id' => $campaignId
'campaign_id' => $campaignId,
]);
}

/**
* @unreleased
*/
public function mapFormToCampaignStatus(string $status): string
protected function mapFormToCampaignStatus(string $status): string
{
switch ($status) {

case 'pending':
return 'pending';

case 'draft':
case 'upgraded': // Some V3 forms can have the 'upgraded' status after being migrated from a V2 form
return 'draft';

case 'trash':
return 'inactive';
return 'archived';

case 'publish':
case 'private':
Expand All @@ -182,4 +201,112 @@ public function mapFormToCampaignStatus(string $status): string
return 'inactive';
}
}

/**
* @unreleased
*/
protected function getV2FormSettings(int $formId): stdClass
{
$template = give_get_meta($formId, '_give_form_template', true);
$templateSettings = give_get_meta($formId, "_give_{$template}_form_template_settings", true);
$templateSettings = is_array($templateSettings) ? $templateSettings : [];

return (object)[
'formExcerpt' => get_the_excerpt($formId),
'description' => $this->getV2FormDescription($templateSettings),
'designSettingsLogoUrl' => '',
'designSettingsImageUrl' => $this->getV2FormFeaturedImage($templateSettings, $formId),
'primaryColor' => $this->getV2FormPrimaryColor($templateSettings),
'secondaryColor' => '',
'goalAmount' => $this->getV2FormGoalAmount($formId),
'goalType' => $this->getV2FormGoalType($formId),
'goalStartDate' => '',
'goalEndDate' => '',
];
}

/**
* @unreleased
*/
protected function getV2FormFeaturedImage(array $templateSettings, int $formId): string
{
if ( ! empty($templateSettings['introduction']['image'])) {
// Sequoia Template (Multi-Step)
$featuredImage = $templateSettings['introduction']['image'];
} elseif ( ! empty($templateSettings['visual_appearance']['header_background_image'])) {
// Classic Template - it doesn't use the featured image from the WP default setting as a fallback
$featuredImage = $templateSettings['visual_appearance']['header_background_image'];
} elseif ( ! isset($templateSettings['visual_appearance']['header_background_image'])) {
// Legacy Template or Sequoia Template without the ['introduction']['image'] setting
$featuredImage = get_the_post_thumbnail_url($formId, 'full');
} else {
$featuredImage = '';
}

return $featuredImage;
}

/**
* @unreleased
*/
protected function getV2FormDescription(array $templateSettings): string
{
if ( ! empty($templateSettings['introduction']['description'])) {
// Sequoia Template (Multi-Step)
$description = $templateSettings['introduction']['description'];
} elseif ( ! empty($templateSettings['visual_appearance']['description'])) {
// Classic Template
$description = $templateSettings['visual_appearance']['description'];
} else {
$description = '';
}

return $description;
}

/**
* @unreleased
*/
protected function getV2FormPrimaryColor(array $templateSettings): string
{
if ( ! empty($templateSettings['introduction']['primary_color'])) {
// Sequoia Template (Multi-Step)
$primaryColor = $templateSettings['introduction']['primary_color'];
} elseif ( ! empty($templateSettings['visual_appearance']['primary_color'])) {
// Classic Template
$primaryColor = $templateSettings['visual_appearance']['primary_color'];
} else {
$primaryColor = '';
}

return $primaryColor;
}

/**
* @unreleased
*/
protected function getV2FormGoalAmount(int $formId)
{
return give_get_form_goal($formId);
}

/**
* @unreleased
*/
protected function getV2FormGoalType(int $formId): string
{
$onlyRecurringEnabled = filter_var(give_get_meta($formId, '_give_recurring_goal_format', true),
FILTER_VALIDATE_BOOLEAN);

switch (give_get_form_goal_format($formId)) {
case 'donors':
return $onlyRecurringEnabled ? 'donorsFromSubscriptions' : 'donors';
case 'donation':
return $onlyRecurringEnabled ? 'subscriptions' : 'donations';
case 'amount':
case 'percentage':
default:
return $onlyRecurringEnabled ? 'amountFromSubscriptions' : 'amount';
}
}
}
5 changes: 3 additions & 2 deletions src/FormMigration/Controllers/MigrationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ public function __invoke(DonationForm $formV2)

// Associate upgraded form to a campaign
$campaignRepository = give(CampaignRepository::class);
$campaign = $campaignRepository->getByFormId($payload->formV2->id);
$campaignRepository->addCampaignForm($campaign, $payload->formV3->id);
if ($campaign = $campaignRepository->getByFormId($payload->formV2->id)) {
$campaignRepository->addCampaignForm($campaign, $payload->formV3->id);
}

Log::info(esc_html__('Form migrated from v2 to v3.', 'give'), $this->debugContext);
});
Expand Down
11 changes: 5 additions & 6 deletions src/FormMigration/Controllers/TransferController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

use Give\Campaigns\Repositories\CampaignRepository;
use Give\DonationForms\V2\Models\DonationForm;
use Give\DonationForms\ValueObjects\DonationFormStatus;
use Give\FormMigration\Actions\GetMigratedFormId;
use Give\FormMigration\Actions\TransferDonations;
use Give\FormMigration\Actions\TransferFormUrl;
use Give\FormMigration\DataTransferObjects\TransferOptions;
use Give\Framework\Database\DB;
use Give\Framework\QueryBuilder\QueryBuilder;
use WP_REST_Request;
use WP_REST_Response;

Expand Down Expand Up @@ -38,11 +36,12 @@ public function __invoke(DonationForm $formV2, TransferOptions $options)

// Promote upgraded form to default form
$campaignRepository = give(CampaignRepository::class);
$campaign = $campaignRepository->getByFormId($formV2->id);
$defaultForm = $campaign->defaultForm();
if ($campaign = $campaignRepository->getByFormId($formV2->id)) {
$defaultForm = $campaign->defaultForm();

if ($defaultForm->id === $formV2->id) {
$campaignRepository->updateDefaultCampaignForm($campaign, $v3FormId);
if ($defaultForm->id === $formV2->id) {
$campaignRepository->updateDefaultCampaignForm($campaign, $v3FormId);
}
}

if($options->shouldDelete()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Give\Tests\Unit\Campaigns\Migrations;

use Exception;
use Give\Campaigns\Migrations\MigrateFormsToCampaignForms;
use Give\Campaigns\Models\Campaign;
use Give\DonationForms\Models\DonationForm;
Expand All @@ -19,6 +20,8 @@ final class MigrateFormsToCampaignFormsTest extends TestCase

/**
* @unreleased
*
* @throws Exception
*/
public function testCreatesParentCampaignForDonationForm()
{
Expand All @@ -35,6 +38,33 @@ public function testCreatesParentCampaignForDonationForm()

/**
* @unreleased
*
* @throws Exception
*/
public function testCreatesParentCampaignForOptionBasedDonationForm()
{
$formId = $this->factory()->post->create(
[
'post_title' => 'Test Form',
'post_type' => 'give_forms',
'post_status' => 'publish',
]
);

$migration = new MigrateFormsToCampaignForms();

$migration->run();

$relationship = DB::table('give_campaign_forms')->where('form_id', $formId)->get();

$this->assertNotNull(Campaign::find($relationship->campaign_id));
$this->assertEquals($formId, $relationship->form_id);
}

/**
* @unreleased
*
* @throws Exception
*/
public function testExistingPeerToPeerCampaignFormsAreNotMigrated()
{
Expand All @@ -54,24 +84,37 @@ public function testExistingPeerToPeerCampaignFormsAreNotMigrated()

/**
* @unreleased
*
* @throws Exception
*/
public function testUpgradedFormsAreNotMigrated()
{
$form = DonationForm::factory()->create([
$upgradedForm = DonationForm::factory()->create([
'status' => DonationFormStatus::UPGRADED(),
]);

$newForm = DonationForm::factory()->create([
'status' => DonationFormStatus::PUBLISHED(),
]);

Give()->form_meta->update_meta($newForm->id, 'migratedFormId', $upgradedForm->id);


$migration = new MigrateFormsToCampaignForms();
$migration->run();

$relationship = DB::table('give_campaign_forms')->where('form_id', $form->id)->get();
$campaign = Campaign::findByFormId($upgradedForm->id);

$this->assertNull($relationship);
$this->assertEquals(0, DB::table('give_campaigns')->count());
$this->assertNotNull($campaign);
$this->assertEquals(0, DB::table('give_campaigns')->where('form_id', $upgradedForm->id)->count());
$this->assertEquals(1, DB::table('give_campaigns')->where('form_id', $newForm->id)->count());
$this->assertEquals(2, DB::table('give_campaign_forms')->where('campaign_id', $campaign->id)->count());
}

/**
* @unreleased
*
* @throws Exception
*/
public function testMigratedFormsAreDefault()
{
Expand All @@ -87,6 +130,8 @@ public function testMigratedFormsAreDefault()

/**
* @unreleased
*
* @throws Exception
*/
public function testUpgradedFormsAreNotDefault()
{
Expand Down

0 comments on commit 7dd1436

Please sign in to comment.