Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 87
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' );
73
74/**
75 * Render callback.
76 *
77 * @param array  $attributes Array containing the block attributes.
78 * @param string $content    String containing the block content.
79 *
80 * @return string
81 */
82function render_block( $attributes, $content ) {
83    if ( ! pre_render_checks() ) {
84        return '';
85    }
86
87    // Render the Stripe nudge when Stripe is unconnected
88    if ( ! membership_checks() ) {
89        $stripe_nudge = render_stripe_nudge();
90        return $stripe_nudge . $content;
91    }
92
93    // We don't use FEATURE_NAME here because styles are not in /container folder.
94    Jetpack_Gutenberg::load_assets_as_required( 'premium-content' );
95    return $content;
96}
97
98/**
99 * Server-side rendering for the stripe connection nudge.
100 *
101 * @return string Final content to render.
102 */
103function render_stripe_nudge() {
104    if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
105        \require_lib( 'memberships' );
106        $blog_id  = get_current_blog_id();
107        $settings = (array) \get_memberships_settings_for_site( $blog_id );
108
109        return stripe_nudge(
110            $settings['connect_url'],
111            __( 'Connect to Stripe to use this block on your site.', 'jetpack' ),
112            __( 'Connect', 'jetpack' )
113        );
114    } else {
115        // On WoA sites, the Stripe connection url is not easily available
116        // server-side, so we redirect them to the post in the editor in order
117        // to connect.
118        return stripe_nudge(
119            get_edit_post_link( get_the_ID() ),
120            __( 'Connect to Stripe in the editor to use this block on your site.', 'jetpack' ),
121            __( 'Edit post', 'jetpack' )
122        );
123    }
124}
125
126/**
127 * Render the stripe nudge.
128 *
129 * @param string $checkout_url Url for the CTA.
130 * @param string $description  Text of the nudge.
131 * @param string $button_text  Text of the button.
132 *
133 * @return string Final content to render.
134 */
135function stripe_nudge( $checkout_url, $description, $button_text ) {
136    require_once JETPACK__PLUGIN_DIR . '_inc/lib/components.php';
137    return \Jetpack_Components::render_frontend_nudge(
138        array(
139            'checkoutUrl' => $checkout_url,
140            'description' => $description,
141            'buttonText'  => $button_text,
142        )
143    );
144}
145
146/**
147 * Add a meta to prevent publication on firehose, ES AI or Reader
148 *
149 * @param int     $post_id Post id.
150 * @param WP_Post $post Post being saved.
151 * @return void
152 */
153function add_paid_content_post_meta( int $post_id, WP_Post $post ) {
154    if ( $post->post_type !== 'post' && $post->post_type !== 'page' ) {
155        return;
156    }
157
158    $contains_paid_content = has_block( 'premium-content/container', $post );
159    if ( $contains_paid_content ) {
160        update_post_meta(
161            $post_id,
162            META_NAME_CONTAINS_PAID_CONTENT,
163            $contains_paid_content
164        );
165    }
166    if ( ! $contains_paid_content ) {
167        delete_post_meta(
168            $post_id,
169            META_NAME_CONTAINS_PAID_CONTENT
170        );
171    }
172}