Skip to content

Commit

Permalink
Refactor: Update Forms to Campaigns migration (#7532)
Browse files Browse the repository at this point in the history
  • Loading branch information
kjohnson authored Sep 12, 2024
1 parent 979c5c0 commit aa54987
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 40 deletions.
161 changes: 122 additions & 39 deletions src/Campaigns/Migrations/MigrateFormsToCampaignForms.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@

namespace Give\Campaigns\Migrations;

use DateTime;
use Give\Campaigns\Models\Campaign;
use Give\Campaigns\ValueObjects\CampaignStatus;
use Give\Campaigns\ValueObjects\CampaignType;
use Give\DonationForms\Models\DonationForm;
use Give\DonationForms\ValueObjects\DonationFormStatus;
use Give\Framework\Database\DB;
use Give\Framework\Database\Exceptions\DatabaseQueryException;
use Give\Framework\Migrations\Contracts\Migration;
use Give\Framework\Migrations\Exceptions\DatabaseMigrationException;
use Give\Framework\QueryBuilder\JoinQueryBuilder;

/**
* @unreleased
Expand All @@ -29,66 +26,152 @@ public static function id(): string
*/
public static function timestamp(): int
{
return strtotime('2024-08-21');
return strtotime('2024-08-26 00:00:01');
}

/**
* @unreleased
* @inheritDoc
* @throws \Exception
*/
public function run()
{
foreach(DonationForm::query()->getAll() ?? [] as $form) {
$this->createParentCampaignForDonationForm($form);
}
DB::transaction(function() {
try {
array_map([$this, 'createCampaignForForm'], $this->getFormData());
array_map([$this, 'addUpgradedFormToCampaign'], $this->getUpgradedFormData());
} catch (DatabaseQueryException $exception) {
DB::rollback();
throw new DatabaseMigrationException('An error occurred while creating initial campaigns', 0, $exception);
}
});
}

/**
* @unreleased
*/
protected function getFormData(): array
{
$query = DB::table('posts', 'forms')
->select(
['forms.ID', 'id'],
['forms.post_title', 'title'],
['forms.post_status', 'status'],
['forms.post_date', 'createdAt']
)
->where('forms.post_type', 'give_forms');

$query->select(['formmeta.meta_value', 'settings'])
->join(function (JoinQueryBuilder $builder) {
$builder
->leftJoin('give_formmeta', 'formmeta')
->on('formmeta.form_id', 'forms.ID');
})
->where('formmeta.meta_key', 'formBuilderSettings');

// Exclude forms already associated with a campaign (ie Peer-to-peer).
$query->join(function (JoinQueryBuilder $builder) {
$builder
->leftJoin('give_campaigns', 'campaigns')
->on('campaigns.form_id', 'forms.ID');
})
->whereIsNull('campaigns.id');

// Exclude forms with an `upgraded` status, which are archived.
$query->where('forms.post_status', 'upgraded', '!=');

return $query->getAll();
}

/**
* @unreleased
* @return array [{formId, campaignId, migratedFormId}]
*/
public function createParentCampaignForDonationForm(DonationForm $form)
protected function getUpgradedFormData(): array
{
$campaign = Campaign::create([
'type' => CampaignType::CORE(),
'title' => $form->title,
'shortDescription' => $form->settings->formExcerpt,
'longDescription' => $form->settings->description,
'logo' => $form->settings->designSettingsLogoUrl,
'image' => $form->settings->designSettingsImageUrl,
'primaryColor' => $form->settings->primaryColor,
'secondaryColor' => $form->settings->secondaryColor,
'goal' => (int) $form->settings->goalAmount,
'status' => $this->mapFormStatusToCampaignStatus($form->status),
'startDate' => new DateTime($form->settings->goalStartDate),
'endDate' => new DateTime($form->settings->goalEndDate),
]);
return DB::table('posts', 'forms')
->select(['forms.ID', 'formId'], ['campaign_forms.campaign_id', 'campaignId'])
->attachMeta('give_formmeta', 'ID', 'form_id', 'migratedFormId')
->join(function (JoinQueryBuilder $builder) {
$builder
->rightJoin('give_campaign_forms', 'campaign_forms')
->on('campaign_forms.form_id', 'forms.ID');
})
->where('forms.post_type', 'give_forms')
->whereIsNotNull('give_formmeta_attach_meta_migratedFormId.meta_value')
->getAll();
}

/**
* @unreleased
*/
public function createCampaignForForm($formData): void
{
$formId = $formData->id;
$formTitle = $formData->title;
$formStatus = $formData->status;
$formCreatedAt = $formData->createdAt;
$formSettings = json_decode($formData->settings);

$campaignId = DB::table('give_campaigns')
->insert([
'campaign_type' => 'core',
'campaign_title' => $formTitle,
'status' => $this->mapFormToCampaignStatus($formStatus),
'short_desc' => $formSettings->formExcerpt,
'long_desc' => $formSettings->description,
'campaign_logo' => $formSettings->designSettingsLogoUrl,
'campaign_image' => $formSettings->designSettingsImageUrl,
'primary_color' => $formSettings->primaryColor,
'secondary_color' => $formSettings->secondaryColor,
'campaign_goal' => $formSettings->goalAmount,
'start_date' => $formSettings->goalStartDate,
'end_date' => $formSettings->goalEndDate,
'date_created' => $formCreatedAt,
]);

DB::table('give_campaign_forms')
->insert([
'form_id' => $form->id,
'campaign_id' => $campaign->id,
'form_id' => $formId,
'campaign_id' => $campaignId,
'is_default' => true,
]);
}

/**
/**
* @param $data
*/
protected function addUpgradedFormToCampaign($data): void
{
DB::table('give_campaign_forms')
->insert([
'form_id' => $data->migratedFormId,
'campaign_id' => $data->campaignId,
]);
}

/**
* @unreleased
*/
public function mapFormStatusToCampaignStatus(DonationFormStatus $status)
public function mapFormToCampaignStatus(string $status): string
{
switch ($status) {
case DonationFormStatus::PUBLISHED():
case DonationFormStatus::UPGRADED(): // TODO: How do we handle upgraded, non-upgraded forms?
case DonationFormStatus::PRIVATE(): // TODO: How do we handle Private forms?
return CampaignStatus::ACTIVE();

case DonationFormStatus::PENDING():
return CampaignStatus::PENDING();
case 'pending':
return 'pending';

case 'draft':
return 'draft';

case 'trash':
return 'inactive';

case DonationFormStatus::DRAFT():
return CampaignStatus::DRAFT();
case 'publish':
case 'private':
return 'active';

case DonationFormStatus::TRASH():
return CampaignStatus::INACTIVE();
default: // TODO: How do we handle an unknown form status?
return 'inactive';
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public function run(): void
$sql = "CREATE TABLE $table (
campaign_id INT UNSIGNED NOT NULL,
form_id INT UNSIGNED NOT NULL,
is_default BOOLEAN NOT NULL DEFAULT 0,
KEY form_id (form_id),
KEY campaign_id (campaign_id),
PRIMARY KEY (campaign_id, form_id)
Expand Down
10 changes: 10 additions & 0 deletions src/Campaigns/Models/Campaign.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ class Campaign extends Model implements ModelCrud, ModelHasFactory
'createdAt' => DateTime::class,
];

/**
* @unreleased
*/
public function form(): DonationForm
{
return $this->forms()
->where('campaign_forms.is_default', true)
->get();
}

/**
* @unreleased
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Give\Campaigns\Migrations\MigrateFormsToCampaignForms;
use Give\Campaigns\Models\Campaign;
use Give\DonationForms\Models\DonationForm;
use Give\DonationForms\ValueObjects\DonationFormStatus;
use Give\Framework\Database\DB;
use Give\Tests\TestCase;
use Give\Tests\TestTraits\RefreshDatabase;
Expand All @@ -24,11 +25,82 @@ public function testCreatesParentCampaignForDonationForm()
$form = DonationForm::factory()->create();
$migration = new MigrateFormsToCampaignForms();

$migration->createParentCampaignForDonationForm($form);
$migration->run();

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

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

/**
* @unreleased
*/
public function testExistingPeerToPeerCampaignFormsAreNotMigrated()
{
$form = DonationForm::factory()->create();
DB::table('give_campaigns')->insert([
'form_id' => $form->id,
]);

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

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

$this->assertNull($relationship);
$this->assertEquals(1, DB::table('give_campaigns')->count());
}

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

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

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

$this->assertNull($relationship);
$this->assertEquals(0, DB::table('give_campaigns')->count());
}

/**
* @unreleased
*/
public function testMigratedFormsAreDefault()
{
$form = DonationForm::factory()->create();

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

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

$this->assertEquals(1, $relationship->is_default);
}

/**
* @unreleased
*/
public function testUpgradedFormsAreNotDefault()
{
$form1 = DonationForm::factory()->create([
'status' => DonationFormStatus::UPGRADED(),
]);
$form2 = DonationForm::factory()->create();
give_update_meta($form2->id, 'migratedFormId', $form1->id);

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

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

$this->assertEquals(0, $relationship->is_default);
}
}
16 changes: 16 additions & 0 deletions tests/Unit/Campaigns/Models/CampaignModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,20 @@ public function testCampaignHasManyForms()

$this->assertEquals(2, $campaign->forms()->count());
}

/**
* @unreleased
*/
public function testCampaignHasDefaultForm()
{
$campaign = Campaign::factory()->create();
$form1 = DonationForm::factory()->create();
$form2 = DonationForm::factory()->create();

$db = DB::table('give_campaign_forms');
$db->insert(['form_id' => $form1->id, 'campaign_id' => $campaign->id, 'is_default' => 1]);
$db->insert(['form_id' => $form2->id, 'campaign_id' => $campaign->id]);

$this->assertEquals($form1->id, $campaign->form()->id);
}
}

0 comments on commit aa54987

Please sign in to comment.