-
Notifications
You must be signed in to change notification settings - Fork 193
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
Refactor: migrate v2 forms to campaigns and add upgraded forms as campaign not-default forms #7645
base: epic/campaigns
Are you sure you want to change the base?
Changes from all commits
6b39b47
946160b
3c5bd8f
28d1758
281669b
c9aa3d1
b40fa77
d507602
a794469
3ed604a
18a9066
6c86331
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
use Give\Framework\Migrations\Contracts\Migration; | ||
use Give\Framework\Migrations\Exceptions\DatabaseMigrationException; | ||
use Give\Framework\QueryBuilder\JoinQueryBuilder; | ||
use stdClass; | ||
|
||
/** | ||
* @unreleased | ||
|
@@ -38,8 +39,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); | ||
|
@@ -50,7 +51,7 @@ public function run() | |
/** | ||
* @unreleased | ||
*/ | ||
protected function getFormData(): array | ||
protected function getAllFormsData(): array | ||
{ | ||
$query = DB::table('posts', 'forms')->distinct() | ||
->select( | ||
|
@@ -65,9 +66,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) { | ||
|
@@ -77,17 +77,43 @@ 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 `upgraded` 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. | ||
*/ | ||
$upgradedFormsIds = $this->getUpgradedV2FormsIds(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this be refactored to a join of the meta with a "where not"? Or do we need a second query? |
||
if (count($upgradedFormsIds) > 0) { | ||
$query->whereNotIn('forms.ID', $upgradedFormsIds); | ||
} | ||
|
||
// Ensure campaigns will be displayed in the same order on the list table | ||
$query->orderBy('forms.ID'); | ||
|
||
return $query->getAll(); | ||
} | ||
|
||
/** | ||
* @unreleased | ||
*/ | ||
protected function getUpgradedV2FormsIds(): array | ||
{ | ||
$upgradedFormsIds = DB::table('give_formmeta')->select('meta_value')->where('meta_key', | ||
'migratedFormId')->getAll('ARRAY_A'); | ||
|
||
return is_array($upgradedFormsIds) ? array_column($upgradedFormsIds, 'meta_value') : []; | ||
} | ||
|
||
/** | ||
* @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']) | ||
|
@@ -98,7 +124,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(); | ||
} | ||
|
@@ -109,10 +134,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([ | ||
|
@@ -141,7 +167,7 @@ public function createCampaignForForm($formData): void | |
/** | ||
* @param $data | ||
*/ | ||
protected function addUpgradedFormToCampaign($data): void | ||
protected function addUpgradedV2FormToCampaign($data): void | ||
{ | ||
$this->addCampaignFormRelationship($data->migratedFormId, $data->campaignId); | ||
} | ||
|
@@ -154,25 +180,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': | ||
|
@@ -182,4 +209,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'; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
@@ -19,6 +20,8 @@ final class MigrateFormsToCampaignFormsTest extends TestCase | |
|
||
/** | ||
* @unreleased | ||
* | ||
* @throws Exception | ||
*/ | ||
public function testCreatesParentCampaignForDonationForm() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @glaubersilva can you add a new test to cover V2 forms that are not upgraded? |
||
{ | ||
|
@@ -35,6 +38,8 @@ public function testCreatesParentCampaignForDonationForm() | |
|
||
/** | ||
* @unreleased | ||
* | ||
* @throws Exception | ||
*/ | ||
public function testExistingPeerToPeerCampaignFormsAreNotMigrated() | ||
{ | ||
|
@@ -54,24 +59,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() | ||
{ | ||
|
@@ -87,6 +105,8 @@ public function testMigratedFormsAreDefault() | |
|
||
/** | ||
* @unreleased | ||
* | ||
* @throws Exception | ||
*/ | ||
public function testUpgradedFormsAreNotDefault() | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is conflating two different things. We do need to exclude
auto-draft
as a status, but I don't think that relates in any way to a form being "upgraded" (as stated in the comment above).