PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 12.1.3
Jetpack – WP Security, Backup, Speed, & Growth v12.1.3
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / extensions / blocks / subscriptions / subscriptions.php
jetpack / extensions / blocks / subscriptions Last commit date
constants.php 3 years ago subscriptions.php 3 years ago
subscriptions.php
783 lines
1 <?php
2 /**
3 * Subscriptions Block.
4 *
5 * @package automattic/jetpack
6 */
7
8 namespace Automattic\Jetpack\Extensions\Subscriptions;
9
10 use Automattic\Jetpack\Blocks;
11 use Automattic\Jetpack\Status;
12 use Jetpack;
13 use Jetpack_Gutenberg;
14 use Jetpack_Memberships;
15 use Jetpack_Subscriptions_Widget;
16
17 require_once __DIR__ . '/constants.php';
18
19 /**
20 * These block defaults should match ./constants.js
21 */
22 const DEFAULT_BORDER_RADIUS_VALUE = 0;
23 const DEFAULT_BORDER_WEIGHT_VALUE = 1;
24 const DEFAULT_FONTSIZE_VALUE = '16px';
25 const DEFAULT_PADDING_VALUE = 15;
26 const DEFAULT_SPACING_VALUE = 10;
27
28 /**
29 * Registers the block for use in Gutenberg
30 * This is done via an action so that we can disable
31 * registration if we need to.
32 */
33 function register_block() {
34 if (
35 ( defined( 'IS_WPCOM' ) && IS_WPCOM )
36 || ( Jetpack::is_connection_ready() && ! ( new Status() )->is_offline_mode() )
37 ) {
38 Blocks::jetpack_register_block(
39 BLOCK_NAME,
40 array(
41 'render_callback' => __NAMESPACE__ . '\render_block',
42 'supports' => array(
43 'spacing' => array(
44 'margin' => true,
45 'padding' => true,
46 ),
47 'align' => array( 'wide', 'full' ),
48 ),
49 )
50 );
51 }
52
53 /*
54 * If the Subscriptions module is not active,
55 * do not make any further changes on the site.
56 */
57 if ( ! Jetpack::is_module_active( 'subscriptions' ) ) {
58 return;
59 }
60
61 /**
62 * Do not proceed if the newsletter feature is not enabled
63 * or if the 'Jetpack_Memberships' class does not exists.
64 */
65 if (
66 /** This filter is documented in class.jetpack-gutenberg.php */
67 ! apply_filters( 'jetpack_subscriptions_newsletter_feature_enabled', false )
68 || ! class_exists( '\Jetpack_Memberships' )
69 ) {
70 return;
71 }
72
73 register_post_meta(
74 'post',
75 META_NAME_FOR_POST_LEVEL_ACCESS_SETTINGS,
76 array(
77 'show_in_rest' => true,
78 'single' => true,
79 'type' => 'string',
80 'auth_callback' => function () {
81 return wp_get_current_user()->has_cap( 'edit_posts' );
82 },
83 )
84 );
85
86 // This ensures Jetpack will sync this post meta to WPCOM.
87 add_filter(
88 'jetpack_sync_post_meta_whitelist',
89 function ( $allowed_meta ) {
90 return array_merge( $allowed_meta, array( META_NAME_FOR_POST_LEVEL_ACCESS_SETTINGS ) );
91 }
92 );
93
94 // Hide the content
95 add_action( 'the_content', __NAMESPACE__ . '\maybe_get_locked_content' );
96
97 // Close comments on the front-end
98 add_filter( 'comments_open', __NAMESPACE__ . '\maybe_close_comments', 10, 2 );
99 add_filter( 'pings_open', __NAMESPACE__ . '\maybe_close_comments', 10, 2 );
100
101 // Hide existing comments
102 add_filter( 'get_comment', __NAMESPACE__ . '\maybe_gate_existing_comments' );
103
104 // Gate the excerpt for a post
105 add_filter( 'get_the_excerpt', __NAMESPACE__ . '\jetpack_filter_excerpt_for_newsletter', 10, 2 );
106 }
107 add_action( 'init', __NAMESPACE__ . '\register_block', 9 );
108
109 /**
110 * Returns true when in a WP.com environment.
111 *
112 * @return boolean
113 */
114 function is_wpcom() {
115 return defined( 'IS_WPCOM' ) && IS_WPCOM;
116 }
117
118 /**
119 * Determine the amount of folks currently subscribed to the blog, splitted out in email_subscribers & social_followers & paid_subscribers
120 *
121 * @return array containing ['value' => ['email_subscribers' => 0, 'paid_subscribers' => 0, 'social_followers' => 0]]
122 */
123 function fetch_subscriber_counts() {
124 $subs_count = 0;
125 if ( is_wpcom() ) {
126 $subs_count = array(
127 'value' => \wpcom_fetch_subs_counts( false ),
128 );
129 } else {
130 $cache_key = 'wpcom_subscribers_totals';
131 $subs_count = get_transient( $cache_key );
132 if ( false === $subs_count || 'failed' === $subs_count['status'] ) {
133 $xml = new \Jetpack_IXR_Client();
134 $xml->query( 'jetpack.fetchSubscriberCounts' );
135
136 if ( $xml->isError() ) { // If we get an error from .com, set the status to failed so that we will try again next time the data is requested.
137 $subs_count = array(
138 'status' => 'failed',
139 'code' => $xml->getErrorCode(),
140 'message' => $xml->getErrorMessage(),
141 'value' => ( isset( $subs_count['value'] ) ) ? $subs_count['value'] : array(
142 'email_subscribers' => 0,
143 'social_followers' => 0,
144 ),
145 );
146 } else {
147 $subs_count = array(
148 'status' => 'success',
149 'value' => $xml->getResponse(),
150 );
151 }
152 set_transient( $cache_key, $subs_count, 3600 ); // Try to cache the result for at least 1 hour.
153 }
154 }
155 return $subs_count;
156 }
157
158 /**
159 * Returns subscriber count based on include_social_followers attribute
160 *
161 * @param bool $include_social_followers Whether to include social followers in the count.
162 * @return int
163 */
164 function get_subscriber_count( $include_social_followers ) {
165 $counts = fetch_subscriber_counts();
166
167 if ( $include_social_followers ) {
168 $subscriber_count = $counts['value']['email_subscribers'] + $counts['value']['social_followers'];
169 } else {
170 $subscriber_count = $counts['value']['email_subscribers'];
171 }
172 return $subscriber_count;
173 }
174
175 /**
176 * Returns true if the block attributes contain a value for the given key.
177 *
178 * @param array $attributes Array containing the block attributes.
179 * @param string $key Block attribute key.
180 *
181 * @return boolean
182 */
183 function has_attribute( $attributes, $key ) {
184 return isset( $attributes[ $key ] ) && $attributes[ $key ] !== 'undefined';
185 }
186
187 /**
188 * Returns the value for the given attribute key, with the option of providing a default fallback value.
189 *
190 * @param array $attributes Array containing the block attributes.
191 * @param string $key Block attribute key.
192 * @param mixed $default Optional fallback value in case the key doesn't exist.
193 *
194 * @return mixed
195 */
196 function get_attribute( $attributes, $key, $default = null ) {
197 return has_attribute( $attributes, $key ) ? $attributes[ $key ] : $default;
198 }
199
200 /**
201 * Mimics getColorClassName, getFontSizeClass and getGradientClass from @wordpress/block-editor js package.
202 *
203 * @param string $setting Setting name.
204 * @param string $value Setting value.
205 *
206 * @return string
207 */
208 function get_setting_class_name( $setting, $value ) {
209 if ( ! $setting || ! $value ) {
210 return '';
211 }
212
213 return sprintf( 'has-%s-%s', $value, $setting );
214 }
215
216 /**
217 * Uses block attributes to generate an array containing the classes for various block elements.
218 * Based on Jetpack_Subscriptions_Widget::do_subscription_form() which the block was originally using.
219 *
220 * @param array $attributes Array containing the block attributes.
221 *
222 * @return array
223 */
224 function get_element_class_names_from_attributes( $attributes ) {
225 $text_color_class = get_setting_class_name( 'color', get_attribute( $attributes, 'textColor' ) );
226 $font_size_class = get_setting_class_name( 'font-size', get_attribute( $attributes, 'fontSize' ) );
227 $border_class = get_setting_class_name( 'border-color', get_attribute( $attributes, 'borderColor' ) );
228
229 $button_background_class = get_setting_class_name( 'background-color', get_attribute( $attributes, 'buttonBackgroundColor' ) );
230 $button_gradient_class = get_setting_class_name( 'gradient-background', get_attribute( $attributes, 'buttonGradient' ) );
231
232 $email_field_background_class = get_setting_class_name( 'background-color', get_attribute( $attributes, 'emailFieldBackgroundColor' ) );
233 $email_field_gradient_class = get_setting_class_name( 'gradient-background', get_attribute( $attributes, 'emailFieldGradient' ) );
234
235 $submit_button_classes = array_filter(
236 array(
237 'wp-block-button__link' => true,
238 'no-border-radius' => 0 === get_attribute( $attributes, 'borderRadius', 0 ),
239 $font_size_class => true,
240 $border_class => true,
241 'has-text-color' => ! empty( $text_color_class ),
242 $text_color_class => true,
243 'has-background' => ! empty( $button_background_class ) || ! empty( $button_gradient_class ),
244 $button_background_class => ! empty( $button_background_class ),
245 $button_gradient_class => ! empty( $button_gradient_class ),
246 )
247 );
248
249 $email_field_classes = array_filter(
250 array(
251 'no-border-radius' => 0 === get_attribute( $attributes, 'borderRadius', 0 ),
252 $font_size_class => true,
253 $border_class => true,
254 $email_field_background_class => true,
255 $email_field_gradient_class => true,
256 )
257 );
258
259 $block_wrapper_classes = array_filter(
260 array(
261 'wp-block-jetpack-subscriptions__supports-newline' => true,
262 'wp-block-jetpack-subscriptions__use-newline' => (bool) get_attribute( $attributes, 'buttonOnNewLine' ),
263 'wp-block-jetpack-subscriptions__show-subs' => (bool) get_attribute( $attributes, 'showSubscribersTotal' ),
264 )
265 );
266
267 return array(
268 'block_wrapper' => join( ' ', array_keys( $block_wrapper_classes ) ),
269 'email_field' => join( ' ', array_keys( $email_field_classes ) ),
270 'submit_button' => join( ' ', array_keys( $submit_button_classes ) ),
271 );
272 }
273
274 /**
275 * Uses block attributes to generate an array containing the styles for various block elements.
276 * Based on Jetpack_Subscriptions_Widget::do_subscription_form() which the block was originally using.
277 *
278 * @param array $attributes Array containing the block attributes.
279 *
280 * @return array
281 */
282 function get_element_styles_from_attributes( $attributes ) {
283 $button_background_style = ! has_attribute( $attributes, 'buttonBackgroundColor' ) && has_attribute( $attributes, 'customButtonGradient' )
284 ? get_attribute( $attributes, 'customButtonGradient' )
285 : get_attribute( $attributes, 'customButtonBackgroundColor' );
286
287 $email_field_styles = '';
288 $submit_button_wrapper_styles = '';
289 $submit_button_styles = '';
290
291 if ( ! empty( $button_background_style ) ) {
292 $submit_button_styles .= sprintf( 'background: %s;', $button_background_style );
293 }
294
295 if ( has_attribute( $attributes, 'customTextColor' ) ) {
296 $submit_button_styles .= sprintf( 'color: %s;', get_attribute( $attributes, 'customTextColor' ) );
297 }
298
299 if ( has_attribute( $attributes, 'buttonWidth' ) ) {
300 $submit_button_wrapper_styles .= sprintf( 'width: %s;', get_attribute( $attributes, 'buttonWidth' ) );
301 $submit_button_wrapper_styles .= 'max-width: 100%;';
302
303 // Account for custom margins on inline forms.
304 $submit_button_styles .= true === get_attribute( $attributes, 'buttonOnNewLine' )
305 ? sprintf( 'width: calc(100%% - %dpx);', get_attribute( $attributes, 'spacing', DEFAULT_SPACING_VALUE ) )
306 : 'width: 100%;';
307 }
308
309 $font_size = get_attribute( $attributes, 'customFontSize', DEFAULT_FONTSIZE_VALUE );
310 $style = sprintf( 'font-size: %s%s;', $font_size, is_numeric( $font_size ) ? 'px' : '' );
311
312 $submit_button_styles .= $style;
313 $email_field_styles .= $style;
314
315 $padding = get_attribute( $attributes, 'padding', DEFAULT_PADDING_VALUE );
316 $style = sprintf( 'padding: %1$dpx %2$dpx %1$dpx %2$dpx;', $padding, round( $padding * 1.5 ) );
317
318 $submit_button_styles .= $style;
319 $email_field_styles .= $style;
320
321 $button_spacing = get_attribute( $attributes, 'spacing', DEFAULT_SPACING_VALUE );
322 if ( true === get_attribute( $attributes, 'buttonOnNewLine' ) ) {
323 $submit_button_styles .= sprintf( 'margin-top: %dpx;', $button_spacing );
324 } else {
325 $submit_button_styles .= 'margin: 0px; '; // Reset Safari's 2px default margin for buttons affecting input and button union
326 $submit_button_styles .= sprintf( 'margin-left: %dpx;', $button_spacing );
327 }
328
329 if ( has_attribute( $attributes, 'borderColor' ) ) {
330 $style = sprintf( 'border-color: %s;', get_attribute( $attributes, 'borderColor', '' ) );
331 $submit_button_styles .= $style;
332 $email_field_styles .= $style;
333 }
334
335 $style = sprintf( 'border-radius: %dpx;', get_attribute( $attributes, 'borderRadius', DEFAULT_BORDER_RADIUS_VALUE ) );
336 $submit_button_styles .= $style;
337 $email_field_styles .= $style;
338
339 $style = sprintf( 'border-width: %dpx;', get_attribute( $attributes, 'borderWeight', DEFAULT_BORDER_WEIGHT_VALUE ) );
340 $submit_button_styles .= $style;
341 $email_field_styles .= $style;
342
343 if ( has_attribute( $attributes, 'customBorderColor' ) ) {
344 $style = sprintf( 'border-color: %s; border-style: solid;', get_attribute( $attributes, 'customBorderColor' ) );
345
346 $submit_button_styles .= $style;
347 $email_field_styles .= $style;
348 }
349
350 return array(
351 'email_field' => $email_field_styles,
352 'submit_button' => $submit_button_styles,
353 'submit_button_wrapper' => $submit_button_wrapper_styles,
354 );
355 }
356
357 /**
358 * Subscriptions block render callback.
359 *
360 * @param array $attributes Array containing the block attributes.
361 *
362 * @return string
363 */
364 function render_block( $attributes ) {
365 // If the Subscriptions module is not active, don't render the block.
366 if ( ! Jetpack::is_module_active( 'subscriptions' ) ) {
367 return '';
368 }
369
370 if ( Jetpack_Gutenberg::is_newsletter_configured() ) {
371 // We only want the sites that have newsletter feature enabled to be graced by this JavaScript and thickbox.
372 Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME, array( 'thickbox' ) );
373 if ( ! wp_style_is( 'enqueued' ) ) {
374 wp_enqueue_style( 'thickbox' );
375 }
376 } else {
377 Jetpack_Gutenberg::load_styles_as_required( FEATURE_NAME );
378 }
379
380 $subscribe_email = '';
381
382 /** This filter is documented in modules/contact-form/grunion-contact-form.php */
383 if ( is_wpcom() || false !== apply_filters( 'jetpack_auto_fill_logged_in_user', false ) ) {
384 $current_user = wp_get_current_user();
385 $subscribe_email = ! empty( $current_user->user_email ) ? $current_user->user_email : '';
386 }
387
388 // The block is using the Jetpack_Subscriptions_Widget backend, hence the need to increase the instance count.
389 ++Jetpack_Subscriptions_Widget::$instance_count;
390
391 $classes = get_element_class_names_from_attributes( $attributes );
392 $styles = get_element_styles_from_attributes( $attributes );
393 $include_social_followers = isset( $attributes['includeSocialFollowers'] ) ? (bool) get_attribute( $attributes, 'includeSocialFollowers' ) : true;
394
395 $data = array(
396 'widget_id' => Jetpack_Subscriptions_Widget::$instance_count,
397 'subscribe_email' => $subscribe_email,
398
399 'wrapper_attributes' => get_block_wrapper_attributes(
400 array(
401 'class' => $classes['block_wrapper'],
402 )
403 ),
404 'subscribe_placeholder' => get_attribute( $attributes, 'subscribePlaceholder', esc_html__( 'Type your email…', 'jetpack' ) ),
405 'submit_button_text' => get_attribute( $attributes, 'submitButtonText', esc_html__( 'Subscribe', 'jetpack' ) ),
406 'success_message' => get_attribute(
407 $attributes,
408 'successMessage',
409 esc_html__( "Success! An email was just sent to confirm your subscription. Please find the email now and click 'Confirm Follow' to start subscribing.", 'jetpack' )
410 ),
411 'show_subscribers_total' => (bool) get_attribute( $attributes, 'showSubscribersTotal' ),
412 'subscribers_total' => get_subscriber_count( $include_social_followers ),
413 'referer' => esc_url_raw(
414 ( is_ssl() ? 'https' : 'http' ) . '://' . ( isset( $_SERVER['HTTP_HOST'] ) ? wp_unslash( $_SERVER['HTTP_HOST'] ) : '' ) .
415 ( isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '' )
416 ),
417 'source' => 'subscribe-block',
418 );
419
420 if ( is_wpcom() ) {
421 return render_wpcom_subscribe_form( $data, $classes, $styles );
422 }
423
424 return render_jetpack_subscribe_form( $data, $classes, $styles );
425 }
426
427 /**
428 * Generates the source parameter to pass to the iframe
429 *
430 * @return string the actual post access level (see projects/plugins/jetpack/extensions/blocks/subscriptions/settings.js for the values).
431 */
432 function get_post_access_level() {
433 if ( ! is_singular() ) {
434 // There is no "actual" current post.
435 return 'everybody';
436 }
437
438 $post_id = get_the_ID();
439 if ( ! $post_id ) {
440 return 'everybody';
441 }
442 $meta = get_post_meta( $post_id, META_NAME_FOR_POST_LEVEL_ACCESS_SETTINGS, true );
443 if ( empty( $meta ) ) {
444 $meta = 'everybody';
445 }
446 return $meta;
447 }
448
449 /**
450 * Renders the WP.com version of the subscriptions block.
451 *
452 * @param array $data Array containing block view data.
453 * @param array $classes Array containing the classes for different block elements.
454 * @param array $styles Array containing the styles for different block elements.
455 *
456 * @return string
457 */
458 function render_wpcom_subscribe_form( $data, $classes, $styles ) {
459 global $current_blog;
460
461 $form_id = 'subscribe-blog' . ( Jetpack_Subscriptions_Widget::$instance_count > 1 ? '-' . Jetpack_Subscriptions_Widget::$instance_count : '' );
462 $url = defined( 'SUBSCRIBE_BLOG_URL' ) ? SUBSCRIBE_BLOG_URL : '';
463
464 ob_start();
465
466 Jetpack_Subscriptions_Widget::render_widget_status_messages(
467 array(
468 'success_message' => $data['success_message'],
469 )
470 );
471
472 $post_access_level = get_post_access_level();
473
474 ?>
475 <div <?php echo wp_kses_data( $data['wrapper_attributes'] ); ?>>
476 <div class="wp-block-jetpack-subscriptions__container">
477 <form
478 action="<?php echo esc_url( $url ); ?>"
479 method="post"
480 accept-charset="utf-8"
481 data-blog="<?php echo esc_attr( get_current_blog_id() ); ?>"
482 data-post_access_level="<?php echo esc_attr( $post_access_level ); ?>"
483 id="<?php echo esc_attr( $form_id ); ?>"
484 >
485 <?php
486 $email_field_id = 'subscribe-field';
487 $email_field_id .= Jetpack_Subscriptions_Widget::$instance_count > 1
488 ? '-' . Jetpack_Subscriptions_Widget::$instance_count
489 : '';
490 $label_field_id = $email_field_id . '-label';
491 ?>
492 <p id="subscribe-email">
493 <label
494 id="<?php echo esc_attr( $label_field_id ); ?>"
495 for="<?php echo esc_attr( $email_field_id ); ?>"
496 class="screen-reader-text"
497 >
498 <?php echo esc_html( $data['subscribe_placeholder'] ); ?>
499 </label>
500
501 <?php
502 printf(
503 '<input
504 required="required"
505 type="email"
506 name="email"
507 %1$s
508 style="%2$s"
509 placeholder="%3$s"
510 value="%4$s"
511 id="%5$s"
512 />',
513 ( ! empty( $classes['email_field'] )
514 ? 'class="' . esc_attr( $classes['email_field'] ) . '"'
515 : ''
516 ),
517 ( ! empty( $styles['email_field'] )
518 ? esc_attr( $styles['email_field'] )
519 : 'width: 95%; padding: 1px 10px'
520 ),
521 esc_attr( $data['subscribe_placeholder'] ),
522 esc_attr( $data['subscribe_email'] ),
523 esc_attr( $email_field_id )
524 );
525 ?>
526 </p>
527
528 <p id="subscribe-submit"
529 <?php if ( ! empty( $styles['submit_button_wrapper'] ) ) : ?>
530 style="<?php echo esc_attr( $styles['submit_button_wrapper'] ); ?>"
531 <?php endif; ?>
532 >
533 <input type="hidden" name="action" value="subscribe"/>
534 <input type="hidden" name="blog_id" value="<?php echo (int) $current_blog->blog_id; ?>"/>
535 <input type="hidden" name="source" value="<?php echo esc_url( $data['referer'] ); ?>"/>
536 <input type="hidden" name="sub-type" value="<?php echo esc_attr( $data['source'] ); ?>"/>
537 <input type="hidden" name="redirect_fragment" value="<?php echo esc_attr( $form_id ); ?>"/>
538 <?php wp_nonce_field( 'blogsub_subscribe_' . $current_blog->blog_id, '_wpnonce', false ); ?>
539 <button type="submit"
540 <?php if ( ! empty( $classes['submit_button'] ) ) : ?>
541 class="<?php echo esc_attr( $classes['submit_button'] ); ?>"
542 <?php endif; ?>
543 <?php if ( ! empty( $styles['submit_button'] ) ) : ?>
544 style="<?php echo esc_attr( $styles['submit_button'] ); ?>"
545 <?php endif; ?>
546 >
547 <?php
548 echo wp_kses(
549 html_entity_decode( $data['submit_button_text'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ),
550 Jetpack_Subscriptions_Widget::$allowed_html_tags_for_submit_button
551 );
552 ?>
553 </button>
554 </p>
555 </form>
556 <?php if ( $data['show_subscribers_total'] && $data['subscribers_total'] ) : ?>
557 <div class="wp-block-jetpack-subscriptions__subscount">
558 <?php
559 /* translators: %s: number of folks following the blog */
560 echo esc_html( sprintf( _n( 'Join %s other follower', 'Join %s other followers', $data['subscribers_total'], 'jetpack' ), number_format_i18n( $data['subscribers_total'] ) ) );
561 ?>
562 </div>
563 <?php endif; ?>
564 </div>
565 </div>
566 <?php
567
568 return ob_get_clean();
569 }
570
571 /**
572 * Renders the Jetpack version of the subscriptions block.
573 *
574 * @param array $data Array containing block view data.
575 * @param array $classes Array containing the classes for different block elements.
576 * @param array $styles Array containing the styles for different block elements.
577 *
578 * @return string
579 */
580 function render_jetpack_subscribe_form( $data, $classes, $styles ) {
581 $form_id = sprintf( 'subscribe-blog-%s', $data['widget_id'] );
582 $subscribe_field_id = apply_filters( 'subscribe_field_id', 'subscribe-field', $data['widget_id'] );
583 ob_start();
584
585 Jetpack_Subscriptions_Widget::render_widget_status_messages(
586 array(
587 'success_message' => $data['success_message'],
588 )
589 );
590
591 $blog_id = \Jetpack_Options::get_option( 'id' );
592 $post_access_level = get_post_access_level();
593
594 ?>
595 <div <?php echo wp_kses_data( $data['wrapper_attributes'] ); ?>>
596 <div class="jetpack_subscription_widget">
597 <div class="wp-block-jetpack-subscriptions__container">
598 <form
599 action="#"
600 method="post"
601 accept-charset="utf-8"
602 data-blog="<?php echo esc_attr( $blog_id ); ?>"
603 data-post_access_level="<?php echo esc_attr( $post_access_level ); ?>"
604 id="<?php echo esc_attr( $form_id ); ?>"
605 >
606 <p id="subscribe-email">
607 <label id="jetpack-subscribe-label"
608 class="screen-reader-text"
609 for="<?php echo esc_attr( $subscribe_field_id . '-' . $data['widget_id'] ); ?>">
610 <?php echo esc_html( $data['subscribe_placeholder'] ); ?>
611 </label>
612 <input type="email" name="email" required="required"
613 <?php if ( ! empty( $classes['email_field'] ) ) : ?>
614 class="<?php echo esc_attr( $classes['email_field'] ); ?> required"
615 <?php endif; ?>
616 <?php if ( ! empty( $styles['email_field'] ) ) : ?>
617 style="<?php echo esc_attr( $styles['email_field'] ); ?>"
618 <?php endif; ?>
619 value="<?php echo esc_attr( $data['subscribe_email'] ); ?>"
620 id="<?php echo esc_attr( $subscribe_field_id . '-' . $data['widget_id'] ); ?>"
621 placeholder="<?php echo esc_attr( $data['subscribe_placeholder'] ); ?>"
622 />
623 </p>
624
625 <p id="subscribe-submit"
626 <?php if ( ! empty( $styles['submit_button_wrapper'] ) ) : ?>
627 style="<?php echo esc_attr( $styles['submit_button_wrapper'] ); ?>"
628 <?php endif; ?>
629 >
630 <input type="hidden" name="action" value="subscribe"/>
631 <input type="hidden" name="blog_id" value="<?php echo (int) $blog_id; ?>"/>
632 <input type="hidden" name="source" value="<?php echo esc_url( $data['referer'] ); ?>"/>
633 <input type="hidden" name="sub-type" value="<?php echo esc_attr( $data['source'] ); ?>"/>
634 <input type="hidden" name="redirect_fragment" value="<?php echo esc_attr( $form_id ); ?>"/>
635 <?php
636 if ( is_user_logged_in() ) {
637 wp_nonce_field( 'blogsub_subscribe_' . get_current_blog_id(), '_wpnonce', false );
638 }
639 ?>
640 <button type="submit"
641 <?php if ( ! empty( $classes['submit_button'] ) ) : ?>
642 class="<?php echo esc_attr( $classes['submit_button'] ); ?>"
643 <?php endif; ?>
644 <?php if ( ! empty( $styles['submit_button'] ) ) : ?>
645 style="<?php echo esc_attr( $styles['submit_button'] ); ?>"
646 <?php endif; ?>
647 name="jetpack_subscriptions_widget"
648 >
649 <?php
650 echo wp_kses(
651 html_entity_decode( $data['submit_button_text'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ),
652 Jetpack_Subscriptions_Widget::$allowed_html_tags_for_submit_button
653 );
654 ?>
655 </button>
656 </p>
657 </form>
658
659 <?php if ( $data['show_subscribers_total'] && $data['subscribers_total'] ) : ?>
660 <div class="wp-block-jetpack-subscriptions__subscount">
661 <?php
662 /* translators: %s: number of folks following the blog */
663 echo esc_html( sprintf( _n( 'Join %s other subscriber', 'Join %s other subscribers', $data['subscribers_total'], 'jetpack' ), number_format_i18n( $data['subscribers_total'] ) ) );
664 ?>
665 </div>
666 <?php endif; ?>
667 </div>
668 </div>
669 </div>
670 <?php
671
672 return ob_get_clean();
673 }
674
675 /**
676 * Filter excerpts looking for subscription data.
677 *
678 * @param string $excerpt The extrapolated excerpt string.
679 * @param \WP_Post $post The current post being processed (in `get_the_excerpt`).
680 *
681 * @return mixed
682 */
683 function jetpack_filter_excerpt_for_newsletter( $excerpt, $post = null ) {
684 // The blogmagazine theme is overriding WP core `get_the_excerpt` filter and only passing the excerpt
685 // TODO: Until this is fixed, return the excerpt without gating. See https://github.com/Automattic/jetpack/pull/28102#issuecomment-1369161116
686 if ( $post && false !== strpos( $post->post_content, '<!-- wp:jetpack/subscriptions -->' ) ) {
687 $excerpt .= sprintf(
688 // translators: %s is the permalink url to the current post.
689 __( "<p><a href='%s'>View post</a> to subscribe to site newsletter.</p>", 'jetpack' ),
690 get_post_permalink()
691 );
692 }
693 return $excerpt;
694 }
695
696 /**
697 * Gate access to posts
698 *
699 * @param string $the_content Post content.
700 *
701 * @return string
702 */
703 function maybe_get_locked_content( $the_content ) {
704 require_once JETPACK__PLUGIN_DIR . 'modules/memberships/class-jetpack-memberships.php';
705
706 if ( Jetpack_Memberships::user_can_view_post() ) {
707 return $the_content;
708 }
709
710 $newsletter_access_level = Jetpack_Memberships::get_newsletter_access_level();
711 return get_locked_content_placeholder_text( $newsletter_access_level );
712 }
713
714 /**
715 * Gate access to comments. We want to close comments on private sites.
716 *
717 * @param bool $default_comments_open Default state of the comments_open filter.
718 * @param int $post_id Current post id.
719 *
720 * @return bool
721 */
722 function maybe_close_comments( $default_comments_open, $post_id ) {
723 if ( ! $default_comments_open || ! $post_id ) {
724 return $default_comments_open;
725 }
726 require_once JETPACK__PLUGIN_DIR . 'modules/memberships/class-jetpack-memberships.php';
727 return Jetpack_Memberships::user_can_view_post();
728 }
729
730 /**
731 * Gate access to exisiting comments
732 *
733 * @param string $comment The comment.
734 *
735 * @return string
736 */
737 function maybe_gate_existing_comments( $comment ) {
738 if ( empty( $comment ) ) {
739 return $comment;
740 }
741
742 require_once JETPACK__PLUGIN_DIR . 'modules/memberships/class-jetpack-memberships.php';
743 if ( Jetpack_Memberships::user_can_view_post() ) {
744 return $comment;
745 }
746 return '';
747 }
748
749 /**
750 * Placeholder text for non-subscribers
751 *
752 * @param string $newsletter_access_level The newsletter access level.
753 * @return string
754 */
755 function get_locked_content_placeholder_text( $newsletter_access_level ) {
756 // Default to subscribers
757 $access_level = __( 'subscribers', 'jetpack' );
758
759 // Only display this text when Stripe is connected and the post is marked for paid subscribers
760 if (
761 $newsletter_access_level === 'paid_subscribers'
762 && ! empty( \Jetpack_Memberships::get_connected_account_id() )
763 ) {
764 $access_level = __( 'paid subscribers', 'jetpack' );
765 }
766
767 return do_blocks(
768 '<!-- wp:group {"style":{"spacing":{"padding":{"top":"var:preset|spacing|80","right":"var:preset|spacing|80","bottom":"var:preset|spacing|80","left":"var:preset|spacing|80"}},"border":{"width":"1px","radius":"4px"}},"borderColor":"primary","layout":{"type":"constrained","contentSize":"400px"}} -->
769 <div class="wp-block-group has-border-color has-primary-border-color" style="border-width:1px;border-radius:4px;padding-top:var(--wp--preset--spacing--80);padding-right:var(--wp--preset--spacing--80);padding-bottom:var(--wp--preset--spacing--80);padding-left:var(--wp--preset--spacing--80)"><!-- wp:heading {"textAlign":"center","style":{"typography":{"fontSize":"24px"},"spacing":{"margin":{"bottom":"var:preset|spacing|60"}}}} -->
770 <h2 class="wp-block-heading has-text-align-center" style="margin-bottom:var(--wp--preset--spacing--60);font-size:24px">' .
771
772 /* translators: Newsletter access. Possible values are "paid newsletters" and "subscribers" */
773 sprintf( esc_html__( 'This post is for %s', 'jetpack' ), $access_level )
774
775 . '</h2>
776 <!-- /wp:heading -->
777
778 <!-- wp:jetpack/subscriptions {"borderRadius":50,"borderColor":"primary","className":"is-style-compact"} /-->
779 </div>
780 <!-- /wp:group -->'
781 );
782 }
783