PluginProbe
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More / 2.4.1
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More v2.4.1
2.4.1 2.4.0 2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.2 2.2.1 2.2.0 2.1.2 2.1.1 trunk 0.0.1 0.0.2 0.0.3 0.0.4 0.0.5 0.0.6 0.0.7 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 All 68 releases
← All changes | includes/AI/Layout/LayoutLibrary.php +30 -72 2.3.0 → 2.4.1 View file →
@@ -1,10 +1,8 @@
1 1 <?php
2 2
3 3 namespace Better_Payment\Lite\AI\Layout;
4 4
5 -use Better_Payment\Lite\AI\Schema\CampaignSchema;
6 -
7 5 if ( ! defined( 'ABSPATH' ) ) {
8 6 exit;
9 7 }
10 8
@@ -32,19 +30,15 @@
32 30 * 'weight' => int, // selection weight
33 31 * 'tags' => array<string>, // campaign categories it suits
34 32 * 'preset' => '1-column'|'2-column'|'3-column'|'split',
35 33 * 'columns' => [ [ 'id','label','width','role',
36 - * 'suggested' => [element types],
37 - * 'pro' => [Pro element types] ], ... ],
34 + * 'suggested' => [element types] ], ... ],
38 35 * ]
39 36 *
40 - * `pro` names the Pro widgets that genuinely belong in that column — appended to
41 - * `suggested` only when Pro is active ({@see self::suggested_for()}). Without it,
42 - * a paying install generated pages made entirely of free widgets: the schema
43 - * listed the Pro elements but nothing ever proposed *where* one should go, and
44 - * the model builds from the design direction, not from the type list. Placement
45 - * is per-column on purpose — a Donors Wall belongs beside the donation ask, an
46 - * FAQ belongs under the story, and a video belongs in the hero.
37 + * Blueprints name free element types only. They used to carry a per-column `pro`
38 + * list of Pro widgets, read by a `suggested_for()` helper — but generation stopped
39 + * prescribing a blueprint, nothing called it any more, and Pro-widget placement
40 + * is proposed to a Pro install by CampaignGenerator::pro_elements_instruction().
47 41 *
48 42 * @see \Better_Payment\Lite\AI\Services\CampaignGenerator Consumer.
49 43 */
50 44 class LayoutLibrary {
@@ -102,10 +96,10 @@
102 96 'weight' => 3,
103 97 'tags' => [ 'general', 'medical', 'community', 'nonprofit' ],
104 98 'preset' => '2-column',
105 99 'columns' => [
106 - [ 'id' => 'main', 'label' => 'Main Content', 'width' => '64%', 'role' => 'Hero title, image and the campaign story, ending with the progress bar', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description', 'progress_bar' ], 'pro' => [ 'video', 'faq' ] ],
107 - [ 'id' => 'sidebar', 'label' => 'Sidebar', 'width' => '36%', 'role' => 'Donation actions and quick stats', 'suggested' => [ 'donation_form', 'donate_amount', 'campaign_summary', 'social_sharing' ], 'pro' => [ 'donors_wall' ] ],
100 + [ 'id' => 'main', 'label' => 'Main Content', 'width' => '64%', 'role' => 'Hero title, image and the campaign story, ending with the progress bar', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description', 'progress_bar' ] ],
101 + [ 'id' => 'sidebar', 'label' => 'Sidebar', 'width' => '36%', 'role' => 'Donation actions and quick stats', 'suggested' => [ 'donation_form', 'donate_amount', 'campaign_summary', 'social_sharing' ] ],
108 102 ],
109 103 ],
110 104 [
111 105 'key' => 'donate-first',
@@ -113,10 +107,10 @@
113 107 'weight' => 2,
114 108 'tags' => [ 'emergency', 'medical', 'nonprofit' ],
115 109 'preset' => '2-column',
116 110 'columns' => [
117 - [ 'id' => 'action', 'label' => 'Donate', 'width' => '42%', 'role' => 'Prominent donation panel with amounts, progress and summary', 'suggested' => [ 'donate_amount', 'donation_form', 'progress_bar', 'campaign_summary' ], 'pro' => [ 'donors_wall' ] ],
118 - [ 'id' => 'story', 'label' => 'Story', 'width' => '58%', 'role' => 'Title, image, story and organizer', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description', 'organizer' ], 'pro' => [ 'video', 'faq' ] ],
111 + [ 'id' => 'action', 'label' => 'Donate', 'width' => '42%', 'role' => 'Prominent donation panel with amounts, progress and summary', 'suggested' => [ 'donate_amount', 'donation_form', 'progress_bar', 'campaign_summary' ] ],
112 + [ 'id' => 'story', 'label' => 'Story', 'width' => '58%', 'role' => 'Title, image, story and organizer', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description', 'organizer' ] ],
119 113 ],
120 114 ],
121 115 [
122 116 'key' => 'full-story',
@@ -124,9 +118,9 @@
124 118 'weight' => 2,
125 119 'tags' => [ 'memorial', 'community', 'nonprofit', 'general' ],
126 120 'preset' => '1-column',
127 121 'columns' => [
128 - [ 'id' => 'main', 'label' => 'Main Content', 'width' => '100%', 'role' => 'A single vertical narrative: hero, story, progress, then the donation ask and organizer', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description', 'progress_bar', 'donate_amount', 'donation_form', 'organizer', 'social_sharing' ], 'pro' => [ 'video', 'faq', 'donors_wall' ] ],
122 + [ 'id' => 'main', 'label' => 'Main Content', 'width' => '100%', 'role' => 'A single vertical narrative: hero, story, progress, then the donation ask and organizer', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description', 'progress_bar', 'donate_amount', 'donation_form', 'organizer', 'social_sharing' ] ],
129 123 ],
130 124 ],
131 125 [
132 126 'key' => 'hero-split',
@@ -134,11 +128,11 @@
134 128 'weight' => 3,
135 129 'tags' => [ 'event', 'community', 'general', 'creative' ],
136 130 'preset' => 'split',
137 131 'columns' => [
138 - [ 'id' => 'hero', 'label' => 'Hero', 'width' => '100%', 'role' => 'Full-width hero: title and a strong image', 'suggested' => [ 'campaign_title', 'photo' ], 'pro' => [ 'video' ] ],
139 - [ 'id' => 'story', 'label' => 'Story', 'width' => '50%', 'role' => 'The story, progress and organizer', 'suggested' => [ 'campaign_description', 'progress_bar', 'organizer' ], 'pro' => [ 'faq' ] ],
140 - [ 'id' => 'donate', 'label' => 'Donate', 'width' => '50%', 'role' => 'Summary and the donation ask', 'suggested' => [ 'campaign_summary', 'donate_amount', 'donation_form', 'social_sharing' ], 'pro' => [ 'donors_wall' ] ],
132 + [ 'id' => 'hero', 'label' => 'Hero', 'width' => '100%', 'role' => 'Full-width hero: title and a strong image', 'suggested' => [ 'campaign_title', 'photo' ] ],
133 + [ 'id' => 'story', 'label' => 'Story', 'width' => '50%', 'role' => 'The story, progress and organizer', 'suggested' => [ 'campaign_description', 'progress_bar', 'organizer' ] ],
134 + [ 'id' => 'donate', 'label' => 'Donate', 'width' => '50%', 'role' => 'Summary and the donation ask', 'suggested' => [ 'campaign_summary', 'donate_amount', 'donation_form', 'social_sharing' ] ],
141 135 ],
142 136 ],
143 137 [
144 138 'key' => 'impact-split',
@@ -146,11 +140,11 @@
146 140 'weight' => 2,
147 141 'tags' => [ 'nonprofit', 'medical', 'education', 'community' ],
148 142 'preset' => 'split',
149 143 'columns' => [
150 - [ 'id' => 'intro', 'label' => 'Intro', 'width' => '100%', 'role' => 'Full-width title and a concise mission statement', 'suggested' => [ 'campaign_title', 'campaign_description' ], 'pro' => [ 'video' ] ],
151 - [ 'id' => 'impact', 'label' => 'Impact', 'width' => '50%', 'role' => 'Visual impact: image, summary stats and progress', 'suggested' => [ 'photo', 'campaign_summary', 'progress_bar' ], 'pro' => [ 'faq' ] ],
152 - [ 'id' => 'donate', 'label' => 'Donate', 'width' => '50%', 'role' => 'Donation amounts, the form and sharing', 'suggested' => [ 'donate_amount', 'donation_form', 'social_sharing' ], 'pro' => [ 'donors_wall' ] ],
144 + [ 'id' => 'intro', 'label' => 'Intro', 'width' => '100%', 'role' => 'Full-width title and a concise mission statement', 'suggested' => [ 'campaign_title', 'campaign_description' ] ],
145 + [ 'id' => 'impact', 'label' => 'Impact', 'width' => '50%', 'role' => 'Visual impact: image, summary stats and progress', 'suggested' => [ 'photo', 'campaign_summary', 'progress_bar' ] ],
146 + [ 'id' => 'donate', 'label' => 'Donate', 'width' => '50%', 'role' => 'Donation amounts, the form and sharing', 'suggested' => [ 'donate_amount', 'donation_form', 'social_sharing' ] ],
153 147 ],
154 148 ],
155 149 [
156 150 'key' => 'minimal',
@@ -168,11 +162,11 @@
168 162 'weight' => 1,
169 163 'tags' => [ 'creative', 'community', 'nonprofit', 'event' ],
170 164 'preset' => '3-column',
171 165 'columns' => [
172 - [ 'id' => 'story', 'label' => 'Story', 'width' => '38%', 'role' => 'Title and the story', 'suggested' => [ 'campaign_title', 'campaign_description' ], 'pro' => [ 'faq' ] ],
173 - [ 'id' => 'visual', 'label' => 'Visual', 'width' => '32%', 'role' => 'Image and progress', 'suggested' => [ 'photo', 'progress_bar' ], 'pro' => [ 'video' ] ],
174 - [ 'id' => 'action', 'label' => 'Action', 'width' => '30%', 'role' => 'Amounts and the donation form', 'suggested' => [ 'donate_amount', 'donation_form', 'social_sharing' ], 'pro' => [ 'donors_wall' ] ],
166 + [ 'id' => 'story', 'label' => 'Story', 'width' => '38%', 'role' => 'Title and the story', 'suggested' => [ 'campaign_title', 'campaign_description' ] ],
167 + [ 'id' => 'visual', 'label' => 'Visual', 'width' => '32%', 'role' => 'Image and progress', 'suggested' => [ 'photo', 'progress_bar' ] ],
168 + [ 'id' => 'action', 'label' => 'Action', 'width' => '30%', 'role' => 'Amounts and the donation form', 'suggested' => [ 'donate_amount', 'donation_form', 'social_sharing' ] ],
175 169 ],
176 170 ],
177 171 [
178 172 'key' => 'organizer-led',
@@ -180,10 +174,10 @@
180 174 'weight' => 1,
181 175 'tags' => [ 'nonprofit', 'community', 'memorial' ],
182 176 'preset' => '2-column',
183 177 'columns' => [
184 - [ 'id' => 'profile', 'label' => 'Organizer', 'width' => '36%', 'role' => 'Who is running this: organizer card, summary and links', 'suggested' => [ 'organizer', 'campaign_summary', 'social_links' ], 'pro' => [ 'donors_wall' ] ],
185 - [ 'id' => 'main', 'label' => 'Main Content', 'width' => '64%', 'role' => 'Title, image, story, progress and the donation ask', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description', 'progress_bar', 'donation_form' ], 'pro' => [ 'video', 'faq' ] ],
178 + [ 'id' => 'profile', 'label' => 'Organizer', 'width' => '36%', 'role' => 'Who is running this: organizer card, summary and links', 'suggested' => [ 'organizer', 'campaign_summary', 'social_links' ] ],
179 + [ 'id' => 'main', 'label' => 'Main Content', 'width' => '64%', 'role' => 'Title, image, story, progress and the donation ask', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description', 'progress_bar', 'donation_form' ] ],
186 180 ],
187 181 ],
188 182 [
189 183 'key' => 'gallery-story',
@@ -191,9 +185,9 @@
191 185 'weight' => 1,
192 186 'tags' => [ 'event', 'creative', 'community', 'animal' ],
193 187 'preset' => '1-column',
194 188 'columns' => [
195 - [ 'id' => 'main', 'label' => 'Main Content', 'width' => '100%', 'role' => 'An image-rich narrative: title, image, story, a second image, progress, then donate and share', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description', 'photo', 'progress_bar', 'donation_form', 'social_sharing' ], 'pro' => [ 'video', 'donors_wall', 'faq' ] ],
189 + [ 'id' => 'main', 'label' => 'Main Content', 'width' => '100%', 'role' => 'An image-rich narrative: title, image, story, a second image, progress, then donate and share', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description', 'photo', 'progress_bar', 'donation_form', 'social_sharing' ] ],
196 190 ],
197 191 ],
198 192 [
199 193 'key' => 'urgent-emergency',
@@ -201,10 +195,10 @@
201 195 'weight' => 2,
202 196 'tags' => [ 'emergency', 'medical', 'animal' ],
203 197 'preset' => '2-column',
204 198 'columns' => [
205 - [ 'id' => 'main', 'label' => 'Main Content', 'width' => '58%', 'role' => 'An urgent title, the situation, live progress and an image', 'suggested' => [ 'campaign_title', 'campaign_description', 'progress_bar', 'photo' ], 'pro' => [ 'video' ] ],
206 - [ 'id' => 'sidebar', 'label' => 'Sidebar', 'width' => '42%', 'role' => 'Immediate donation ask with amounts and summary', 'suggested' => [ 'donate_amount', 'donation_form', 'campaign_summary', 'social_sharing' ], 'pro' => [ 'donors_wall' ] ],
199 + [ 'id' => 'main', 'label' => 'Main Content', 'width' => '58%', 'role' => 'An urgent title, the situation, live progress and an image', 'suggested' => [ 'campaign_title', 'campaign_description', 'progress_bar', 'photo' ] ],
200 + [ 'id' => 'sidebar', 'label' => 'Sidebar', 'width' => '42%', 'role' => 'Immediate donation ask with amounts and summary', 'suggested' => [ 'donate_amount', 'donation_form', 'campaign_summary', 'social_sharing' ] ],
207 201 ],
208 202 ],
209 203 [
210 204 'key' => 'balanced',
@@ -212,10 +206,10 @@
212 206 'weight' => 1,
213 207 'tags' => [ 'general', 'education', 'community', 'creative' ],
214 208 'preset' => '2-column',
215 209 'columns' => [
216 - [ 'id' => 'left', 'label' => 'Left', 'width' => '50%', 'role' => 'Title, image and the story', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description' ], 'pro' => [ 'video', 'faq' ] ],
217 - [ 'id' => 'right', 'label' => 'Right', 'width' => '50%', 'role' => 'Progress, amounts, the form and summary', 'suggested' => [ 'progress_bar', 'donate_amount', 'donation_form', 'campaign_summary' ], 'pro' => [ 'donors_wall' ] ],
210 + [ 'id' => 'left', 'label' => 'Left', 'width' => '50%', 'role' => 'Title, image and the story', 'suggested' => [ 'campaign_title', 'photo', 'campaign_description' ] ],
211 + [ 'id' => 'right', 'label' => 'Right', 'width' => '50%', 'role' => 'Progress, amounts, the form and summary', 'suggested' => [ 'progress_bar', 'donate_amount', 'donation_form', 'campaign_summary' ] ],
218 212 ],
219 213 ],
220 214 [
221 215 'key' => 'progress-hero-split',
@@ -223,11 +217,11 @@
223 217 'weight' => 1,
224 218 'tags' => [ 'medical', 'emergency', 'education', 'general' ],
225 219 'preset' => 'split',
226 220 'columns' => [
227 - [ 'id' => 'hero', 'label' => 'Hero', 'width' => '100%', 'role' => 'Full-width title with the progress bar right up top', 'suggested' => [ 'campaign_title', 'progress_bar' ], 'pro' => [ 'video' ] ],
228 - [ 'id' => 'story', 'label' => 'Story', 'width' => '50%', 'role' => 'Image and the story', 'suggested' => [ 'photo', 'campaign_description' ], 'pro' => [ 'faq' ] ],
229 - [ 'id' => 'donate', 'label' => 'Donate', 'width' => '50%', 'role' => 'Amounts, the form and summary', 'suggested' => [ 'donate_amount', 'donation_form', 'campaign_summary', 'social_sharing' ], 'pro' => [ 'donors_wall' ] ],
221 + [ 'id' => 'hero', 'label' => 'Hero', 'width' => '100%', 'role' => 'Full-width title with the progress bar right up top', 'suggested' => [ 'campaign_title', 'progress_bar' ] ],
222 + [ 'id' => 'story', 'label' => 'Story', 'width' => '50%', 'role' => 'Image and the story', 'suggested' => [ 'photo', 'campaign_description' ] ],
223 + [ 'id' => 'donate', 'label' => 'Donate', 'width' => '50%', 'role' => 'Amounts, the form and summary', 'suggested' => [ 'donate_amount', 'donation_form', 'campaign_summary', 'social_sharing' ] ],
230 224 ],
231 225 ],
232 226 ];
233 227 }
@@ -333,46 +327,10 @@
333 327 return [ 'primary' => $chosen['primary'], 'mood' => $chosen['mood'] ];
334 328 }
335 329
336 330 /**
337 - * The element types to suggest for one blueprint column.
338 - *
339 - * The column's free `suggested` list, plus its `pro` list when Pro is active.
340 - * Pro types are appended rather than interleaved so the free composition stays
341 - * the backbone of the page and the Pro widgets read as additions to it — a
342 - * campaign whose donation column is all Donors Wall and no donate button is a
343 - * worse page, not a more premium one.
344 - *
345 - * `$pro_enabled` is the authority on entitlement — this method does not
346 - * re-read the filter, so the caller's answer and this one can never disagree.
347 - * The only extra check is registration: a `pro` entry naming a type no longer
348 - * in the registry (a blueprint added through the filter, say) must not be
349 - * named to the model as something it may use.
350 - *
351 - * @param array $column A blueprint column.
352 - * @param bool $pro_enabled Whether Pro is active.
353 - * @return array<int, string>
354 - */
355 - public static function suggested_for( array $column, bool $pro_enabled ): array {
356 - $suggested = array_values( (array) ( $column['suggested'] ?? [] ) );
357 -
358 - if ( ! $pro_enabled ) {
359 - return $suggested;
360 - }
361 -
362 - foreach ( (array) ( $column['pro'] ?? [] ) as $type ) {
363 - $type = (string) $type;
364 - if ( '' !== $type && CampaignSchema::is_element_type( $type ) && ! in_array( $type, $suggested, true ) ) {
365 - $suggested[] = $type;
366 - }
367 - }
368 -
369 - return $suggested;
370 - }
371 -
372 - /**
373 331 * The trusted column structure for enforcement — only id/label/width (the
374 - * role/suggested/pro hints are for the prompt, not the stored layout).
332 + * role/suggested hints are for the prompt, not the stored layout).
375 333 *
376 334 * @param array $blueprint
377 335 * @return array{preset: string, columns: array}
378 336 */