PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.0.0
GiveWP – Donation Plugin and Fundraising Platform v4.0.0
4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / Campaigns / Migrations / MigrateFormsToCampaignForms.php
give / src / Campaigns / Migrations Last commit date
Donations 1 year ago P2P 1 year ago RevenueTable 1 year ago Tables 1 year ago MigrateFormsToCampaignForms.php 1 year ago
MigrateFormsToCampaignForms.php
327 lines
1 <?php
2
3 namespace Give\Campaigns\Migrations;
4
5 use Give\Framework\Database\DB;
6 use Give\Framework\Database\Exceptions\DatabaseQueryException;
7 use Give\Framework\Migrations\Contracts\Migration;
8 use Give\Framework\Migrations\Exceptions\DatabaseMigrationException;
9 use Give\Framework\QueryBuilder\JoinQueryBuilder;
10 use Give\Framework\QueryBuilder\QueryBuilder;
11 use stdClass;
12
13 /**
14 * @since 4.0.0
15 */
16 class MigrateFormsToCampaignForms extends Migration
17 {
18 /**
19 * @inheritDoc
20 */
21 public static function id(): string
22 {
23 return 'migrate_forms_to_campaign_forms';
24 }
25
26 /**
27 * @inheritDoc
28 */
29 public static function timestamp(): int
30 {
31 return strtotime('2024-08-26 00:00:02');
32 }
33
34 /**
35 * @since 4.0.0
36 * @inheritDoc
37 * @throws \Exception
38 */
39 public function run()
40 {
41 DB::transaction(function() {
42 try {
43 array_map([$this, 'createCampaignForForm'], $this->getAllFormsData());
44 array_map([$this, 'addUpgradedV2FormToCampaign'], $this->getUpgradedV2FormsData());
45 } catch (DatabaseQueryException $exception) {
46 DB::rollback();
47 throw new DatabaseMigrationException('An error occurred while creating initial campaigns', 0, $exception);
48 }
49 });
50 }
51
52 /**
53 * @since 4.0.0
54 */
55 protected function getAllFormsData(): array
56 {
57 $query = DB::table('posts', 'forms')->distinct()
58 ->select(
59 ['forms.ID', 'id'],
60 ['forms.post_title', 'title'],
61 ['forms.post_name', 'name'], // unique slug
62 ['forms.post_status', 'status'],
63 ['forms.post_date', 'createdAt']
64 )
65 ->where('forms.post_type', 'give_forms');
66
67 $query->select(['formmeta.meta_value', 'settings'])
68 ->join(function (JoinQueryBuilder $builder) {
69 $builder
70 ->leftJoin('give_formmeta', 'formmeta')
71 ->on('formmeta.form_id', 'forms.ID')->joinRaw("AND formmeta.meta_key = 'formBuilderSettings'");
72 });
73
74 // Exclude forms already associated with a campaign (ie Peer-to-peer).
75 $query->join(function (JoinQueryBuilder $builder) {
76 $builder
77 ->leftJoin('give_campaigns', 'campaigns')
78 ->on('campaigns.form_id', 'forms.ID');
79 })
80 ->whereIsNull('campaigns.id');
81
82 /**
83 * Exclude forms with an "auto-draft" status, which are WP revisions.
84 *
85 * @see https://wordpress.org/documentation/article/post-status/#auto-draft
86 */
87 $query->where('forms.post_status', 'auto-draft', '!=');
88
89 /**
90 * 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.
91 */
92 $query->whereNotIn('forms.ID', function (QueryBuilder $builder) {
93 $builder
94 ->select('meta_value')
95 ->from('give_formmeta')
96 ->where('meta_key', 'migratedFormId');
97 });
98
99 // Ensure campaigns will be displayed in the same order on the list table
100 $query->orderBy('forms.ID');
101
102 $results = $query->getAll();
103
104 if (!$results) {
105 return [];
106 }
107
108 return $results;
109 }
110
111 /**
112 * @since 4.0.0
113 * @return array [{formId, campaignId, migratedFormId}]
114 */
115 protected function getUpgradedV2FormsData(): array
116 {
117 $results = DB::table('posts', 'forms')
118 ->select(['forms.ID', 'formId'], ['campaign_forms.campaign_id', 'campaignId'])
119 ->attachMeta('give_formmeta', 'ID', 'form_id', 'migratedFormId')
120 ->join(function (JoinQueryBuilder $builder) {
121 $builder
122 ->rightJoin('give_campaign_forms', 'campaign_forms')
123 ->on('campaign_forms.form_id', 'forms.ID');
124 })
125 ->where('forms.post_type', 'give_forms')
126 ->whereIsNotNull('give_formmeta_attach_meta_migratedFormId.meta_value')
127 ->getAll();
128
129 if (!$results) {
130 return [];
131 }
132
133 return $results;
134 }
135
136 /**
137 * @since 4.0.0
138 */
139 public function createCampaignForForm($formData): void
140 {
141 $formId = $formData->id;
142 $formStatus = $formData->status;
143 $formName = $formData->name;
144 $formTitle = $formData->title;
145 $formCreatedAt = $formData->createdAt;
146 $isV3Form = ! is_null($formData->settings);
147 $formSettings = $isV3Form ? json_decode($formData->settings) : $this->getV2FormSettings($formId);
148
149 DB::table('give_campaigns')
150 ->insert([
151 'form_id' => $formId,
152 'campaign_type' => 'core',
153 'campaign_title' => $formTitle,
154 'status' => $this->mapFormToCampaignStatus($formStatus),
155 'short_desc' => $formSettings->formExcerpt,
156 'long_desc' => $formSettings->description,
157 'campaign_logo' => $formSettings->designSettingsLogoUrl,
158 'campaign_image' => $formSettings->designSettingsImageUrl,
159 'primary_color' => $formSettings->primaryColor,
160 'secondary_color' => $formSettings->secondaryColor,
161 'campaign_goal' => $formSettings->goalAmount,
162 'goal_type' => $formSettings->goalType,
163 'start_date' => $formCreatedAt,
164 'end_date' => null,
165 'date_created' => $formCreatedAt,
166 ]);
167
168 $campaignId = DB::last_insert_id();
169
170 $this->addCampaignFormRelationship($formId, $campaignId);
171 }
172
173 /**
174 * @param $data
175 */
176 protected function addUpgradedV2FormToCampaign($data): void
177 {
178 $this->addCampaignFormRelationship($data->migratedFormId, $data->campaignId);
179 }
180
181 /**
182 * @since 4.0.0
183 */
184 protected function addCampaignFormRelationship($formId, $campaignId)
185 {
186 DB::table('give_campaign_forms')
187 ->insert([
188 'form_id' => $formId,
189 'campaign_id' => $campaignId,
190 ]);
191 }
192
193 /**
194 * @since 4.0.0
195 */
196 protected function mapFormToCampaignStatus(string $status): string
197 {
198 switch ($status) {
199
200 case 'pending':
201 return 'pending';
202
203 case 'draft':
204 case 'upgraded': // Some V3 forms can have the 'upgraded' status after being migrated from a V2 form
205 return 'draft';
206
207 case 'trash':
208 return 'archived';
209
210 case 'publish':
211 case 'private':
212 return 'active';
213
214 default: // TODO: How do we handle an unknown form status?
215 return 'inactive';
216 }
217 }
218
219 /**
220 * @since 4.0.0
221 */
222 protected function getV2FormSettings(int $formId): stdClass
223 {
224 $template = give_get_meta($formId, '_give_form_template', true);
225 $templateSettings = give_get_meta($formId, "_give_{$template}_form_template_settings", true);
226 $templateSettings = is_array($templateSettings) ? $templateSettings : [];
227
228 return (object)[
229 'formExcerpt' => get_the_excerpt($formId),
230 'description' => $this->getV2FormDescription($templateSettings),
231 'designSettingsLogoUrl' => '',
232 'designSettingsImageUrl' => $this->getV2FormFeaturedImage($templateSettings, $formId),
233 'primaryColor' => $this->getV2FormPrimaryColor($templateSettings),
234 'secondaryColor' => '',
235 'goalAmount' => $this->getV2FormGoalAmount($formId),
236 'goalType' => $this->getV2FormGoalType($formId),
237 'goalStartDate' => '',
238 'goalEndDate' => '',
239 ];
240 }
241
242 /**
243 * @since 4.0.0
244 */
245 protected function getV2FormFeaturedImage(array $templateSettings, int $formId): string
246 {
247 if ( ! empty($templateSettings['introduction']['image'])) {
248 // Sequoia Template (Multi-Step)
249 $featuredImage = $templateSettings['introduction']['image'];
250 } elseif ( ! empty($templateSettings['visual_appearance']['header_background_image'])) {
251 // Classic Template - it doesn't use the featured image from the WP default setting as a fallback
252 $featuredImage = $templateSettings['visual_appearance']['header_background_image'];
253 } elseif ( ! isset($templateSettings['visual_appearance']['header_background_image'])) {
254 // Legacy Template or Sequoia Template without the ['introduction']['image'] setting
255 $featuredImage = get_the_post_thumbnail_url($formId, 'full');
256 } else {
257 $featuredImage = '';
258 }
259
260 return $featuredImage;
261 }
262
263 /**
264 * @since 4.0.0
265 */
266 protected function getV2FormDescription(array $templateSettings): string
267 {
268 if ( ! empty($templateSettings['introduction']['description'])) {
269 // Sequoia Template (Multi-Step)
270 $description = $templateSettings['introduction']['description'];
271 } elseif ( ! empty($templateSettings['visual_appearance']['description'])) {
272 // Classic Template
273 $description = $templateSettings['visual_appearance']['description'];
274 } else {
275 $description = '';
276 }
277
278 return $description;
279 }
280
281 /**
282 * @since 4.0.0
283 */
284 protected function getV2FormPrimaryColor(array $templateSettings): string
285 {
286 if ( ! empty($templateSettings['introduction']['primary_color'])) {
287 // Sequoia Template (Multi-Step)
288 $primaryColor = $templateSettings['introduction']['primary_color'];
289 } elseif ( ! empty($templateSettings['visual_appearance']['primary_color'])) {
290 // Classic Template
291 $primaryColor = $templateSettings['visual_appearance']['primary_color'];
292 } else {
293 $primaryColor = '';
294 }
295
296 return $primaryColor;
297 }
298
299 /**
300 * @since 4.0.0
301 */
302 protected function getV2FormGoalAmount(int $formId)
303 {
304 return give_get_form_goal($formId);
305 }
306
307 /**
308 * @since 4.0.0
309 */
310 protected function getV2FormGoalType(int $formId): string
311 {
312 $onlyRecurringEnabled = filter_var(give_get_meta($formId, '_give_recurring_goal_format', true),
313 FILTER_VALIDATE_BOOLEAN);
314
315 switch (give_get_form_goal_format($formId)) {
316 case 'donors':
317 return $onlyRecurringEnabled ? 'donorsFromSubscriptions' : 'donors';
318 case 'donation':
319 return $onlyRecurringEnabled ? 'subscriptions' : 'donations';
320 case 'amount':
321 case 'percentage':
322 default:
323 return $onlyRecurringEnabled ? 'amountFromSubscriptions' : 'amount';
324 }
325 }
326 }
327