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/Campaign/Elements/ProElementPreview.php +89 -34 2.3.4 → 2.4.1 View file →
@@ -11,11 +11,17 @@
11 11 * for sites without Better Payment Pro.
12 12 *
13 13 * Replaces the old flat "PRO" banner. A banner told a free user nothing about
14 14 * what the element does; this paints a realistic approximation so they can see
15 - * the widget, watch it react to the (disabled) controls beside it, and judge
16 - * whether Pro is worth buying.
15 + * the widget and judge whether Pro is worth buying.
17 16 *
17 + * A free install registers only a lock stub for these elements
18 + * ({@see ProElementStubs}: no schema, no default settings), so a freshly dropped
19 + * element reaches here with `[]` settings and every mock must look complete from
20 + * built-in sample content alone. Settings that ARE present — a campaign built
21 + * while Pro was active — are still honoured, so a downgraded campaign shows the
22 + * author's own configuration.
23 + *
18 24 * ── The one rule that matters ────────────────────────────────────────────────
19 25 * **This NEVER renders on the public frontend.** Every method here fabricates
20 26 * data — invented donor names, invented amounts. On a live fundraising page that
21 27 * is not a cosmetic bug, it is a lie about who gave money. Two independent gates
@@ -174,9 +180,11 @@
174 180 $show_amount = ! isset( $settings['show_amount'] ) || $settings['show_amount'];
175 181 $show_avatar = ! isset( $settings['show_avatar'] ) || $settings['show_avatar'];
176 182 $show_date = ! isset( $settings['show_date'] ) || $settings['show_date'];
177 183
178 - $headline = isset( $settings['headline'] ) ? (string) $settings['headline'] : '';
184 + // Unset (a stub-registered element) takes the sample heading; an emptied
185 + // heading stays empty.
186 + $headline = isset( $settings['headline'] ) ? (string) $settings['headline'] : __( 'Recent Donors', 'better-payment' );
179 187 $accent = self::safe_color( isset( $settings['accent_color'] ) ? $settings['accent_color'] : '' );
180 188
181 189 $donors = array_slice( self::sample_donors(), 0, $limit );
182 190
@@ -251,10 +259,12 @@
251 259 return (string) ob_get_clean();
252 260 }
253 261
254 262 /**
255 - * The FAQ mock renders the author's OWN items, not invented ones — the
256 - * questions are already in the saved settings and are not Pro data. Only the
263 + * The FAQ mock renders the author's OWN items when the saved settings carry
264 + * any (a campaign built while Pro was active) — those questions are not Pro
265 + * data. Otherwise it shows {@see self::sample_faq_items()}: placeholder copy
266 + * that describes the widget and states nothing about the campaign. Only the
257 267 * accordion's interactivity is missing, so every item is shown open.
258 268 *
259 269 * @param array $settings
260 270 * @return string
@@ -259,14 +269,18 @@
259 269 * @param array $settings
260 270 * @return string
261 271 */
262 272 private static function faq( array $settings ): string {
263 - $heading = isset( $settings['heading'] ) ? (string) $settings['heading'] : '';
273 + $heading = isset( $settings['heading'] ) ? (string) $settings['heading'] : __( 'Frequently Asked Questions', 'better-payment' );
264 274 $accent = self::safe_color( isset( $settings['accent_color'] ) ? $settings['accent_color'] : '' );
265 275
266 276 $items = ( isset( $settings['items'] ) && is_array( $settings['items'] ) ) ? $settings['items'] : [];
267 277 $items = array_slice( $items, 0, 30 );
268 278
279 + if ( ! self::has_faq_content( $items ) ) {
280 + $items = self::sample_faq_items();
281 + }
282 +
269 283 ob_start();
270 284 ?>
271 285 <div>
272 286 <?php if ( '' !== $heading ) : ?>
@@ -274,41 +288,82 @@
274 288 <?php echo esc_html( $heading ); ?>
275 289 </h4>
276 290 <?php endif; ?>
277 291
278 - <?php if ( empty( $items ) ) : ?>
279 - <p style="margin:0;font-size:12px;color:#787c82;">
280 - <?php esc_html_e( 'No questions added yet.', 'better-payment' ); ?>
281 - </p>
282 - <?php else : ?>
283 - <div style="display:flex;flex-direction:column;gap:8px;">
284 - <?php foreach ( $items as $item ) :
285 - $question = isset( $item['question'] ) ? (string) $item['question'] : '';
286 - $answer = isset( $item['answer'] ) ? (string) $item['answer'] : '';
292 + <div style="display:flex;flex-direction:column;gap:8px;">
293 + <?php foreach ( $items as $item ) :
294 + $question = isset( $item['question'] ) ? (string) $item['question'] : '';
295 + $answer = isset( $item['answer'] ) ? (string) $item['answer'] : '';
287 296
288 - if ( '' === $question && '' === $answer ) {
289 - continue;
290 - }
291 - ?>
292 - <div style="border:1px solid #f0f0f1;border-radius:6px;padding:10px 12px;">
293 - <div style="display:flex;align-items:flex-start;gap:8px;">
294 - <span style="flex:0 0 auto;color:<?php echo esc_attr( $accent ); ?>;font-weight:700;line-height:1.4;">+</span>
295 - <span style="flex:1 1 auto;font-size:13px;font-weight:600;color:#1a1a2e;line-height:1.4;">
296 - <?php echo esc_html( $question ); ?>
297 - </span>
298 - </div>
299 - <?php if ( '' !== $answer ) : ?>
300 - <p style="margin:6px 0 0 18px;font-size:12px;line-height:1.6;color:#50575e;">
301 - <?php echo esc_html( $answer ); ?>
302 - </p>
303 - <?php endif; ?>
297 + if ( '' === $question && '' === $answer ) {
298 + continue;
299 + }
300 + ?>
301 + <div style="border:1px solid #f0f0f1;border-radius:6px;padding:10px 12px;">
302 + <div style="display:flex;align-items:flex-start;gap:8px;">
303 + <span style="flex:0 0 auto;color:<?php echo esc_attr( $accent ); ?>;font-weight:700;line-height:1.4;">+</span>
304 + <span style="flex:1 1 auto;font-size:13px;font-weight:600;color:#1a1a2e;line-height:1.4;">
305 + <?php echo esc_html( $question ); ?>
306 + </span>
304 307 </div>
305 - <?php endforeach; ?>
306 - </div>
307 - <?php endif; ?>
308 + <?php if ( '' !== $answer ) : ?>
309 + <p style="margin:6px 0 0 18px;font-size:12px;line-height:1.6;color:#50575e;">
310 + <?php echo esc_html( $answer ); ?>
311 + </p>
312 + <?php endif; ?>
313 + </div>
314 + <?php endforeach; ?>
315 + </div>
308 316 </div>
309 317 <?php
310 318 return (string) ob_get_clean();
319 + }
320 +
321 + /**
322 + * Whether any FAQ row carries a question or an answer.
323 + *
324 + * @param array $items Saved FAQ rows.
325 + * @return bool
326 + */
327 + private static function has_faq_content( array $items ): bool {
328 + foreach ( $items as $item ) {
329 + if ( ! is_array( $item ) ) {
330 + continue;
331 + }
332 + $question = isset( $item['question'] ) ? (string) $item['question'] : '';
333 + $answer = isset( $item['answer'] ) ? (string) $item['answer'] : '';
334 + if ( '' !== $question || '' !== $answer ) {
335 + return true;
336 + }
337 + }
338 +
339 + return false;
340 + }
341 +
342 + /**
343 + * Sample FAQ rows for a mock with no saved questions.
344 + *
345 + * The questions are the generic ones any donor asks; the answers describe the
346 + * widget, not the campaign, so nothing here can be read as a claim about how a
347 + * real campaign spends its money.
348 + *
349 + * @return array<int, array<string, string>>
350 + */
351 + private static function sample_faq_items(): array {
352 + return [
353 + [
354 + 'question' => __( 'How will my donation be used?', 'better-payment' ),
355 + 'answer' => __( 'Your own answer appears here. Add the questions donors ask most, each with a short, direct answer.', 'better-payment' ),
356 + ],
357 + [
358 + 'question' => __( 'Is my payment secure?', 'better-payment' ),
359 + 'answer' => __( 'Sample answer. Each question opens and closes on your live campaign.', 'better-payment' ),
360 + ],
361 + [
362 + 'question' => __( 'Can I donate any amount?', 'better-payment' ),
363 + 'answer' => __( 'Sample answer. Add, remove and reorder questions as your campaign needs.', 'better-payment' ),
364 + ],
365 + ];
311 366 }
312 367
313 368 /**
314 369 * A poster frame, never a real embed.