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/Services/RendererService.php +46 -39 2.3.3 → 2.4.1 View file →
@@ -5,9 +5,8 @@
5 5 use Better_Payment\Lite\Admin\DB;
6 6 use Better_Payment\Lite\Campaign\CampaignStats;
7 7 use Better_Payment\Lite\Campaign\MetaBox;
8 8 use Better_Payment\Lite\Campaign\Templates\TemplateManager;
9 -use Better_Payment\Lite\Campaign\Templates\ProTemplatePreviews;
10 9 use Better_Payment\Lite\Campaign\Support\Money;
11 10 use Better_Payment\Lite\Campaign\Elements\ElementRegistry;
12 11 use Better_Payment\Lite\Campaign\Elements\ProElementPreview;
13 12
@@ -1229,45 +1228,31 @@
1229 1228 * frontend uses; the lightbox scrolls it. A static screenshot cannot do that
1230 1229 * (it is a fixed crop of the top of the page) and drifts from the layout the
1231 1230 * moment a template is redesigned.
1232 1231 *
1233 - * A locked Pro card (ProTemplateCatalog) carries `columns => []` on purpose —
1234 - * the registry never hands a Pro layout to the client, and that is the gate.
1235 - * Its preview comes from `ProTemplatePreviews`, a generated mirror read ONLY
1236 - * here: the document that goes back is rendered HTML, which cannot be applied.
1232 + * Only a template with a layout of its own previews live. A locked Pro card
1233 + * (ProTemplateCatalog, free install only) carries `columns => []`, and Lite
1234 + * ships no copy of Pro's layouts, so it returns '' and the lightbox shows the
1235 + * card's screenshot — the builder does not even request it. With Pro active
1236 + * the same key resolves to Pro's real template and renders like any other.
1237 1237 * Falling through to `default_layout()` instead would advertise Pro's design
1238 - * as a generic one-column campaign.
1238 + * as a generic campaign.
1239 1239 *
1240 - * Returns '' — and the client falls back to the screenshot — only when there
1241 - * is no layout from either source.
1242 - *
1243 1240 * @param string $key Template key from TemplateManager.
1244 1241 * @return string Full HTML document, or '' when the key is unknown or has no layout.
1245 1242 */
1246 1243 public static function build_template_preview_document( string $key ): string {
1247 1244 $templates = TemplateManager::get_all();
1248 - if ( ! isset( $templates[ $key ] ) ) {
1245 + if ( empty( $templates[ $key ]['columns'] ) ) {
1249 1246 return '';
1250 1247 }
1251 1248
1252 1249 $template = $templates[ $key ];
1253 - $columns = $template['columns'] ?? [];
1254 - $layout = $template['layout'] ?? '1-column';
1255 1250
1256 - if ( empty( $columns ) ) {
1257 - $mirror = ProTemplatePreviews::layout( $key );
1258 - if ( empty( $mirror['columns'] ) ) {
1259 - return '';
1260 - }
1261 -
1262 - $columns = $mirror['columns'];
1263 - $layout = $mirror['layout'] ?? $layout;
1264 - }
1265 -
1266 1251 return self::build_preview_document(
1267 1252 [
1268 - 'layout' => $layout,
1269 - 'columns' => $columns,
1253 + 'layout' => $template['layout'] ?? '1-column',
1254 + 'columns' => $template['columns'],
1270 1255 ],
1271 1256 self::template_preview_meta( $key, $template ),
1272 1257 0,
1273 1258 self::template_preview_stats()
@@ -1423,9 +1408,9 @@
1423 1408 // hotspot, an element that cannot be selected or removed.
1424 1409 //
1425 1410 // Show a mock preview instead so the element is visible,
1426 1411 // selectable, and demonstrates what Pro would do with the
1427 - // settings shown (disabled) in the sidebar.
1412 + // upgrade banner shown in the sidebar.
1428 1413 //
1429 1414 // This is the ONLY call site — the public render path has no
1430 1415 // reference to ProElementPreview, and ProElementPreview::render()
1431 1416 // re-checks the preview flag itself. Its data is fabricated;
@@ -1470,8 +1455,16 @@
1470 1455 $extra_link = file_exists( BETTER_PAYMENT_ASSETS_PATH . '/css/fundraising-campaign.min.css' )
1471 1456 ? '<link rel="stylesheet" href="' . esc_url( $fundraising_css ) . '?v=' . $v . '">' . "\n"
1472 1457 : '';
1473 1458
1459 + // Template theme CSS from an add-on — Pro links its themes through
1460 + // `better_payment/campaign/preview_stylesheets`. A free install links no
1461 + // Pro design. See Campaign\CampaignStyles.
1462 + $theme_links = '';
1463 + foreach ( \Better_Payment\Lite\Campaign\CampaignStyles::preview_stylesheets() as $theme_css ) {
1464 + $theme_links .= '<link rel="stylesheet" href="' . esc_url( $theme_css ) . '">' . "\n";
1465 + }
1466 +
1474 1467 return '<!DOCTYPE html>' . "\n"
1475 1468 . '<html>' . "\n"
1476 1469 . '<head>' . "\n"
1477 1470 . '<meta charset="utf-8">' . "\n"
@@ -1477,8 +1470,9 @@
1477 1470 . '<meta charset="utf-8">' . "\n"
1478 1471 . '<meta name="viewport" content="width=device-width, initial-scale=1">' . "\n"
1479 1472 . '<base href="' . esc_url( home_url( '/' ) ) . '">' . "\n"
1480 1473 . '<link rel="stylesheet" href="' . esc_url( $display_css ) . '?v=' . $v . '">' . "\n"
1474 + . $theme_links
1481 1475 . $extra_link
1482 1476 . '<style>' . "\n"
1483 1477 . '*, *::before, *::after { box-sizing: border-box; }' . "\n"
1484 1478 . 'html, body { margin: 0; padding: 0; background: #fff; }' . "\n"
@@ -1516,44 +1510,57 @@
1516 1510 . '</html>';
1517 1511 }
1518 1512
1519 1513 /**
1514 + * Per-request memo for pro_locked_types(). A property rather than a
1515 + * function-local static so tests can reset it.
1516 + *
1517 + * @var array<string, array>|null
1518 + */
1519 + private static $pro_locked_types_cache = null;
1520 +
1521 + /**
1520 1522 * Element types that are Pro-only AND currently locked (Pro inactive).
1521 1523 *
1522 1524 * Returns a map of type => schema (label/icon) for elements that carry the
1523 1525 * `pro` flag in the filtered registry while `better_payment/pro_enabled` is
1524 - * false. When Pro is active these are overridden by the full schema (no `pro`
1525 - * flag) so the map is empty and nothing is locked. Result is cached per
1526 - * request.
1526 + * false. With Pro active the map is empty and nothing is locked. Result is
1527 + * cached per request.
1527 1528 *
1528 1529 * @return array<string, array>
1529 1530 */
1530 1531 private static function pro_locked_types(): array {
1531 - static $cache = null;
1532 -
1533 - if ( null !== $cache ) {
1534 - return $cache;
1532 + if ( null !== self::$pro_locked_types_cache ) {
1533 + return self::$pro_locked_types_cache;
1535 1534 }
1536 1535
1537 - $cache = [];
1536 + self::$pro_locked_types_cache = [];
1538 1537
1539 1538 if ( apply_filters( 'better_payment/pro_enabled', false ) ) {
1540 - return $cache;
1539 + return self::$pro_locked_types_cache;
1541 1540 }
1542 1541
1543 1542 foreach ( ElementRegistry::get_all() as $type => $schema ) {
1544 1543 if ( ! empty( $schema['pro'] ) ) {
1545 - $cache[ $type ] = $schema;
1544 + self::$pro_locked_types_cache[ $type ] = $schema;
1546 1545 }
1547 1546 }
1548 1547
1549 - return $cache;
1548 + return self::$pro_locked_types_cache;
1550 1549 }
1551 1550
1552 1551 /**
1553 - * Editor-only placeholder banner shown in the builder preview for a
1554 - * Pro-locked element (a Pro element left over from when Pro was active).
1555 - * Never emitted on the public frontend.
1552 + * Generic builder-only "PRO" banner for a locked element that has no mock.
1553 + *
1554 + * Lite's own three Pro elements always get a ProElementPreview mock, so this
1555 + * is reached only by some other `pro`-flagged type — a third party's, added
1556 + * through `better_payment/campaign_elements`, or a future Pro element whose
1557 + * mock has not been written. It is lock chrome, not Pro functionality: it
1558 + * renders a label and an upgrade line, nothing of the element itself. Without
1559 + * it the element's canvas wrapper would be empty and zero-height, so the canvas
1560 + * could place no hotspot and the element could not be selected or deleted.
1561 + * Only build_preview_document() calls it, only while Pro is inactive
1562 + * (pro_locked_types() is empty otherwise). Never emitted on the public frontend.
1556 1563 *
1557 1564 * @param array $schema Element schema (label, icon).
1558 1565 * @return string
1559 1566 */