Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 88
0.00% covered (danger)
0.00%
0 / 5
CRAP
n/a
0 / 0
Automattic\Jetpack\Extensions\Premium_Content\register_block
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
6
Automattic\Jetpack\Extensions\Premium_Content\render_block
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
Automattic\Jetpack\Extensions\Premium_Content\render_stripe_nudge
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
Automattic\Jetpack\Extensions\Premium_Content\stripe_nudge
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
Automattic\Jetpack\Extensions\Premium_Content\add_paid_content_post_meta
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2/**
3 * Premium Content Block.
4 *
5 * @package automattic/jetpack
6 */
7
8namespace Automattic\Jetpack\Extensions\Premium_Content;
9
10use Automattic\Jetpack\Blocks;
11use Jetpack_Gutenberg;
12use WP_Post;
13use const Automattic\Jetpack\Extensions\Subscriptions\META_NAME_CONTAINS_PAID_CONTENT;
14
15require_once __DIR__ . '/_inc/access-check.php';
16require_once __DIR__ . '/logged-out-view/logged-out-view.php';
17require_once __DIR__ . '/subscriber-view/subscriber-view.php';
18require_once __DIR__ . '/buttons/buttons.php';
19require_once __DIR__ . '/login-button/login-button.php';
20require_once JETPACK__PLUGIN_DIR . 'extensions/blocks/subscriptions/constants.php';
21
22/**
23 * Registers the block for use in Gutenberg
24 * This is done via an action so that we can disable
25 * registration if we need to.
26 */
27function register_block() {
28
29    require_once JETPACK__PLUGIN_DIR . '/modules/memberships/class-jetpack-memberships.php';
30    if ( \Jetpack_Memberships::should_enable_monetize_blocks_in_editor() ) {
31        Blocks::jetpack_register_block(
32            __DIR__,
33            array(
34                'render_callback'  => __NAMESPACE__ . '\render_block',
35                'provides_context' => array(
36                    'premium-content/planId'  => 'selectedPlanId', // Deprecated.
37                    'premium-content/planIds' => 'selectedPlanIds',
38                    'isPremiumContentChild'   => 'isPremiumContentChild',
39                ),
40            )
41        );
42    }
43
44    register_post_meta(
45        'post',
46        META_NAME_CONTAINS_PAID_CONTENT,
47        array(
48            'show_in_rest'  => true,
49            'single'        => true,
50            'type'          => 'boolean',
51            'auth_callback' => function () {
52                return wp_get_current_user()->has_cap( 'edit_posts' );
53            },
54        )
55    );
56
57    // This ensures Jetpack will sync this post meta to WPCOM.
58    add_filter(
59        'jetpack_sync_post_meta_whitelist',
60        function ( $allowed_meta ) {
61            return array_merge(
62                $allowed_meta,
63                array(
64                    META_NAME_CONTAINS_PAID_CONTENT,
65                )
66            );
67        }
68    );
69
70    add_action( 'wp_after_insert_post', __NAMESPACE__ . '\add_paid_content_post_meta', 99, 2 );
71}
72add_action( 'init', __NAMESPACE__ . '\register_block' );
73add_action( 'template_redirect', __NAMESPACE__ . '\prewarm_premium_content_session_cookie' );
74
75/**
76 * Render callback.
77 *
78 * @param array  $attributes Array containing the block attributes.
79 * @param string $content    String containing the block content.
80 *
81 * @return string
82 */
83function render_block( $attributes, $content ) {
84    if ( ! pre_render_checks() ) {
85        return '';
86    }
87
88    // Render the Stripe nudge when Stripe is unconnected
89    if ( ! membership_checks() ) {
90        $stripe_nudge = render_stripe_nudge();
91        return $stripe_nudge . $content;
92    }
93
94    // We don't use FEATURE_NAME here because styles are not in /container folder.
95    Jetpack_Gutenberg::load_assets_as_required( 'premium-content' );
96    return $content;
97}
98
99/**
100 * Server-side rendering for the stripe connection nudge.
101 *
102 * @return string Final content to render.
103 */
104function render_stripe_nudge() {
105    if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
106        \require_lib( 'memberships' );
107        $blog_id  = get_current_blog_id();
108        $settings = (array) \get_memberships_settings_for_site( $blog_id );
109
110        return stripe_nudge(
111            $settings['connect_url'],
112            __( 'Connect to Stripe to use this block on your site.', 'jetpack' ),
113            __( 'Connect', 'jetpack' )
114        );
115    } else {
116        // On WoA sites, the Stripe connection url is not easily available
117        // server-side, so we redirect them to the post in the editor in order
118        // to connect.
119        return stripe_nudge(
120            get_edit_post_link( get_the_ID() ),
121            __( 'Connect to Stripe in the editor to use this block on your site.', 'jetpack' ),
122            __( 'Edit post', 'jetpack' )
123        );
124    }
125}
126
127/**
128 * Render the stripe nudge.
129 *
130 * @param string $checkout_url Url for the CTA.
131 * @param string $description  Text of the nudge.
132 * @param string $button_text  Text of the button.
133 *
134 * @return string Final content to render.
135 */
136function stripe_nudge( $checkout_url, $description, $button_text ) {
137    require_once JETPACK__PLUGIN_DIR . '_inc/lib/components.php';
138    return \Jetpack_Components::render_frontend_nudge(
139        array(
140            'checkoutUrl' => $checkout_url,
141            'description' => $description,
142            'buttonText'  => $button_text,
143        )
144    );
145}
146
147/**
148 * Add a meta to prevent publication on firehose, ES AI or Reader
149 *
150 * @param int     $post_id Post id.
151 * @param WP_Post $post Post being saved.
152 * @return void
153 */
154function add_paid_content_post_meta( int $post_id, WP_Post $post ) {
155    if ( $post->post_type !== 'post' && $post->post_type !== 'page' ) {
156        return;
157    }
158
159    $contains_paid_content = has_block( 'premium-content/container', $post );
160    if ( $contains_paid_content ) {
161        update_post_meta(
162            $post_id,
163            META_NAME_CONTAINS_PAID_CONTENT,
164            $contains_paid_content
165        );
166    }
167    if ( ! $contains_paid_content ) {
168        delete_post_meta(
169            $post_id,
170            META_NAME_CONTAINS_PAID_CONTENT
171        );
172    }
173}