PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 12.0.3
Jetpack – WP Security, Backup, Speed, & Growth v12.0.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
754 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 if ( ! Jetpack_Gutenberg::is_newsletter_enabled() ) {
62 return; // Stop here if the Newsletter feature is not enabled.
63 }
64
65 register_post_meta(
66 'post',
67 META_NAME_FOR_POST_LEVEL_ACCESS_SETTINGS,
68 array(
69 'show_in_rest' => true,
70 'single' => true,
71 'type' => 'string',
72 'auth_callback' => function () {
73 return wp_get_current_user()->has_cap( 'edit_posts' );
74 },
75 )
76 );
77
78 // This ensures Jetpack will sync this post meta to WPCOM.
79 add_filter(
80 'jetpack_sync_post_meta_whitelist',
81 function ( $allowed_meta ) {
82 return array_merge( $allowed_meta, array( META_NAME_FOR_POST_LEVEL_ACCESS_SETTINGS ) );
83 }
84 );
85
86 // Hide the content
87 add_action( 'the_content', __NAMESPACE__ . '\maybe_get_locked_content' );
88
89 // Close comments on the front-end
90 add_filter( 'comments_open', __NAMESPACE__ . '\maybe_close_comments', 10, 2 );
91 add_filter( 'pings_open', __NAMESPACE__ . '\maybe_close_comments', 10, 2 );
92
93 // Hide existing comments
94 add_filter( 'get_comment', __NAMESPACE__ . '\maybe_gate_existing_comments' );
95
96 // Gate the excerpt for a post
97 add_filter( 'get_the_excerpt', __NAMESPACE__ . '\jetpack_filter_excerpt_for_newsletter', 10, 2 );
98 }
99 add_action( 'init', __NAMESPACE__ . '\register_block', 9 );
100
101 /**
102 * Returns true when in a WP.com environment.
103 *
104 * @return boolean
105 */
106 function is_wpcom() {
107 return defined( 'IS_WPCOM' ) && IS_WPCOM;
108 }
109
110 /**
111 * Determine the amount of folks currently subscribed to the blog, splitted out in email_subscribers & social_followers
112 *
113 * @return array containing ['value' => ['email_subscribers' => 0, 'social_followers' => 0]]
114 */
115 function fetch_subscriber_counts() {
116 $subs_count = 0;
117 if ( is_wpcom() ) {
118 $subs_count = array(
119 'value' => array(
120 'email_subscribers' => \wpcom_subs_total_for_blog(),
121 'social_followers' => \wpcom_social_followers_total_for_blog(),
122 ),
123 );
124 } else {
125 $cache_key = 'wpcom_subscribers_totals';
126 $subs_count = get_transient( $cache_key );
127 if ( false === $subs_count || 'failed' === $subs_count['status'] ) {
128 $xml = new \Jetpack_IXR_Client();
129 $xml->query( 'jetpack.fetchSubscriberCounts' );
130
131 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.
132 $subs_count = array(
133 'status' => 'failed',
134 'code' => $xml->getErrorCode(),
135 'message' => $xml->getErrorMessage(),
136 'value' => ( isset( $subs_count['value'] ) ) ? $subs_count['value'] : array(
137 'email_subscribers' => 0,
138 'social_followers' => 0,
139 ),
140 );
141 } else {
142 $subs_count = array(
143 'status' => 'success',
144 'value' => $xml->getResponse(),
145 );
146 }
147 set_transient( $cache_key, $subs_count, 3600 ); // Try to cache the result for at least 1 hour.
148 }
149 }
150 return $subs_count;
151 }
152
153 /**
154 * Returns subscriber count based on include_social_followers attribute
155 *
156 * @param bool $include_social_followers Whether to include social followers in the count.
157 * @return int
158 */
159 function get_subscriber_count( $include_social_followers ) {
160 $counts = fetch_subscriber_counts();
161
162 if ( $include_social_followers ) {
163 $subscriber_count = $counts['value']['email_subscribers'] + $counts['value']['social_followers'];
164 } else {
165 $subscriber_count = $counts['value']['email_subscribers'];
166 }
167 return $subscriber_count;
168 }
169
170 /**
171 * Returns true if the block attributes contain a value for the given key.
172 *
173 * @param array $attributes Array containing the block attributes.
174 * @param string $key Block attribute key.
175 *
176 * @return boolean
177 */
178 function has_attribute( $attributes, $key ) {
179 return isset( $attributes[ $key ] ) && $attributes[ $key ] !== 'undefined';
180 }
181
182 /**
183 * Returns the value for the given attribute key, with the option of providing a default fallback value.
184 *
185 * @param array $attributes Array containing the block attributes.
186 * @param string $key Block attribute key.
187 * @param mixed $default Optional fallback value in case the key doesn't exist.
188 *
189 * @return mixed
190 */
191 function get_attribute( $attributes, $key, $default = null ) {
192 return has_attribute( $attributes, $key ) ? $attributes[ $key ] : $default;
193 }
194
195 /**
196 * Mimics getColorClassName, getFontSizeClass and getGradientClass from @wordpress/block-editor js package.
197 *
198 * @param string $setting Setting name.
199 * @param string $value Setting value.
200 *
201 * @return string
202 */
203 function get_setting_class_name( $setting, $value ) {
204 if ( ! $setting || ! $value ) {
205 return '';
206 }
207
208 return sprintf( 'has-%s-%s', $value, $setting );
209 }
210
211 /**
212 * Uses block attributes to generate an array containing the classes for various block elements.
213 * Based on Jetpack_Subscriptions_Widget::do_subscription_form() which the block was originally using.
214 *
215 * @param array $attributes Array containing the block attributes.
216 *
217 * @return array
218 */
219 function get_element_class_names_from_attributes( $attributes ) {
220 $text_color_class = get_setting_class_name( 'color', get_attribute( $attributes, 'textColor' ) );
221 $font_size_class = get_setting_class_name( 'font-size', get_attribute( $attributes, 'fontSize' ) );
222 $border_class = get_setting_class_name( 'border-color', get_attribute( $attributes, 'borderColor' ) );
223
224 $button_background_class = get_setting_class_name( 'background-color', get_attribute( $attributes, 'buttonBackgroundColor' ) );
225 $button_gradient_class = get_setting_class_name( 'gradient-background', get_attribute( $attributes, 'buttonGradient' ) );
226
227 $email_field_background_class = get_setting_class_name( 'background-color', get_attribute( $attributes, 'emailFieldBackgroundColor' ) );
228 $email_field_gradient_class = get_setting_class_name( 'gradient-background', get_attribute( $attributes, 'emailFieldGradient' ) );
229
230 $submit_button_classes = array_filter(
231 array(
232 'wp-block-button__link' => true,
233 'no-border-radius' => 0 === get_attribute( $attributes, 'borderRadius', 0 ),
234 $font_size_class => true,
235 $border_class => true,
236 'has-text-color' => ! empty( $text_color_class ),
237 $text_color_class => true,
238 'has-background' => ! empty( $button_background_class ) || ! empty( $button_gradient_class ),
239 $button_background_class => ! empty( $button_background_class ),
240 $button_gradient_class => ! empty( $button_gradient_class ),
241 )
242 );
243
244 $email_field_classes = array_filter(
245 array(
246 'no-border-radius' => 0 === get_attribute( $attributes, 'borderRadius', 0 ),
247 $font_size_class => true,
248 $border_class => true,
249 $email_field_background_class => true,
250 $email_field_gradient_class => true,
251 )
252 );
253
254 $block_wrapper_classes = array_filter(
255 array(
256 'wp-block-jetpack-subscriptions__supports-newline' => true,
257 'wp-block-jetpack-subscriptions__use-newline' => (bool) get_attribute( $attributes, 'buttonOnNewLine' ),
258 'wp-block-jetpack-subscriptions__show-subs' => (bool) get_attribute( $attributes, 'showSubscribersTotal' ),
259 )
260 );
261
262 return array(
263 'block_wrapper' => join( ' ', array_keys( $block_wrapper_classes ) ),
264 'email_field' => join( ' ', array_keys( $email_field_classes ) ),
265 'submit_button' => join( ' ', array_keys( $submit_button_classes ) ),
266 );
267 }
268
269 /**
270 * Uses block attributes to generate an array containing the styles for various block elements.
271 * Based on Jetpack_Subscriptions_Widget::do_subscription_form() which the block was originally using.
272 *
273 * @param array $attributes Array containing the block attributes.
274 *
275 * @return array
276 */
277 function get_element_styles_from_attributes( $attributes ) {
278 $button_background_style = ! has_attribute( $attributes, 'buttonBackgroundColor' ) && has_attribute( $attributes, 'customButtonGradient' )
279 ? get_attribute( $attributes, 'customButtonGradient' )
280 : get_attribute( $attributes, 'customButtonBackgroundColor' );
281
282 $email_field_styles = '';
283 $submit_button_wrapper_styles = '';
284 $submit_button_styles = '';
285
286 if ( ! empty( $button_background_style ) ) {
287 $submit_button_styles .= sprintf( 'background: %s;', $button_background_style );
288 }
289
290 if ( has_attribute( $attributes, 'customTextColor' ) ) {
291 $submit_button_styles .= sprintf( 'color: %s;', get_attribute( $attributes, 'customTextColor' ) );
292 }
293
294 if ( has_attribute( $attributes, 'buttonWidth' ) ) {
295 $submit_button_wrapper_styles .= sprintf( 'width: %s;', get_attribute( $attributes, 'buttonWidth' ) );
296 $submit_button_wrapper_styles .= 'max-width: 100%;';
297
298 // Account for custom margins on inline forms.
299 $submit_button_styles .= true === get_attribute( $attributes, 'buttonOnNewLine' )
300 ? sprintf( 'width: calc(100%% - %dpx);', get_attribute( $attributes, 'spacing', DEFAULT_SPACING_VALUE ) )
301 : 'width: 100%;';
302 }
303
304 $font_size = get_attribute( $attributes, 'customFontSize', DEFAULT_FONTSIZE_VALUE );
305 $style = sprintf( 'font-size: %s%s;', $font_size, is_numeric( $font_size ) ? 'px' : '' );
306
307 $submit_button_styles .= $style;
308 $email_field_styles .= $style;
309
310 $padding = get_attribute( $attributes, 'padding', DEFAULT_PADDING_VALUE );
311 $style = sprintf( 'padding: %1$dpx %2$dpx %1$dpx %2$dpx;', $padding, round( $padding * 1.5 ) );
312
313 $submit_button_styles .= $style;
314 $email_field_styles .= $style;
315
316 $button_spacing = get_attribute( $attributes, 'spacing', DEFAULT_SPACING_VALUE );
317 if ( true === get_attribute( $attributes, 'buttonOnNewLine' ) ) {
318 $submit_button_styles .= sprintf( 'margin-top: %dpx;', $button_spacing );
319 } else {
320 $submit_button_styles .= 'margin: 0px; '; // Reset Safari's 2px default margin for buttons affecting input and button union
321 $submit_button_styles .= sprintf( 'margin-left: %dpx;', $button_spacing );
322 }
323
324 if ( has_attribute( $attributes, 'borderColor' ) ) {
325 $style = sprintf( 'border-color: %s;', get_attribute( $attributes, 'borderColor', '' ) );
326 $submit_button_styles .= $style;
327 $email_field_styles .= $style;
328 }
329
330 $style = sprintf( 'border-radius: %dpx;', get_attribute( $attributes, 'borderRadius', DEFAULT_BORDER_RADIUS_VALUE ) );
331 $submit_button_styles .= $style;
332 $email_field_styles .= $style;
333
334 $style = sprintf( 'border-width: %dpx;', get_attribute( $attributes, 'borderWeight', DEFAULT_BORDER_WEIGHT_VALUE ) );
335 $submit_button_styles .= $style;
336 $email_field_styles .= $style;
337
338 if ( has_attribute( $attributes, 'customBorderColor' ) ) {
339 $style = sprintf( 'border-color: %s; border-style: solid;', get_attribute( $attributes, 'customBorderColor' ) );
340
341 $submit_button_styles .= $style;
342 $email_field_styles .= $style;
343 }
344
345 return array(
346 'email_field' => $email_field_styles,
347 'submit_button' => $submit_button_styles,
348 'submit_button_wrapper' => $submit_button_wrapper_styles,
349 );
350 }
351
352 /**
353 * Subscriptions block render callback.
354 *
355 * @param array $attributes Array containing the block attributes.
356 *
357 * @return string
358 */
359 function render_block( $attributes ) {
360 // If the Subscriptions module is not active, don't render the block.
361 if ( ! Jetpack::is_module_active( 'subscriptions' ) ) {
362 return '';
363 }
364
365 if ( Jetpack_Gutenberg::is_newsletter_enabled() ) {
366 // We only want the sites that have newsletter feature enabled to be graced by this JavaScript and thickbox.
367 Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME, array( 'thickbox' ) );
368 if ( ! wp_style_is( 'enqueued' ) ) {
369 wp_enqueue_style( 'thickbox' );
370 }
371 } else {
372 Jetpack_Gutenberg::load_styles_as_required( FEATURE_NAME );
373 }
374
375 $subscribe_email = '';
376
377 /** This filter is documented in modules/contact-form/grunion-contact-form.php */
378 if ( is_wpcom() || false !== apply_filters( 'jetpack_auto_fill_logged_in_user', false ) ) {
379 $current_user = wp_get_current_user();
380 $subscribe_email = ! empty( $current_user->user_email ) ? $current_user->user_email : '';
381 }
382
383 // The block is using the Jetpack_Subscriptions_Widget backend, hence the need to increase the instance count.
384 ++Jetpack_Subscriptions_Widget::$instance_count;
385
386 $classes = get_element_class_names_from_attributes( $attributes );
387 $styles = get_element_styles_from_attributes( $attributes );
388 $include_social_followers = isset( $attributes['includeSocialFollowers'] ) ? (bool) get_attribute( $attributes, 'includeSocialFollowers' ) : true;
389
390 $data = array(
391 'widget_id' => Jetpack_Subscriptions_Widget::$instance_count,
392 'subscribe_email' => $subscribe_email,
393
394 'wrapper_attributes' => get_block_wrapper_attributes(
395 array(
396 'class' => $classes['block_wrapper'],
397 )
398 ),
399 'subscribe_placeholder' => get_attribute( $attributes, 'subscribePlaceholder', esc_html__( 'Type your email…', 'jetpack' ) ),
400 'submit_button_text' => get_attribute( $attributes, 'submitButtonText', esc_html__( 'Subscribe', 'jetpack' ) ),
401 'success_message' => get_attribute(
402 $attributes,
403 'successMessage',
404 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' )
405 ),
406 'show_subscribers_total' => (bool) get_attribute( $attributes, 'showSubscribersTotal' ),
407 'subscribers_total' => get_subscriber_count( $include_social_followers ),
408 'referer' => esc_url_raw(
409 ( is_ssl() ? 'https' : 'http' ) . '://' . ( isset( $_SERVER['HTTP_HOST'] ) ? wp_unslash( $_SERVER['HTTP_HOST'] ) : '' ) .
410 ( isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '' )
411 ),
412 'source' => 'subscribe-block',
413 );
414
415 if ( is_wpcom() ) {
416 return render_wpcom_subscribe_form( $data, $classes, $styles );
417 }
418
419 return render_jetpack_subscribe_form( $data, $classes, $styles );
420 }
421
422 /**
423 * Generates the source parameter to pass to the iframe
424 *
425 * @return string the actual post access level (see projects/plugins/jetpack/extensions/blocks/subscriptions/settings.js for the values).
426 */
427 function get_post_access_level() {
428 $post_id = get_the_ID();
429 if ( ! $post_id ) {
430 return 'everybody';
431 }
432 $meta = get_post_meta( $post_id, META_NAME_FOR_POST_LEVEL_ACCESS_SETTINGS, true );
433 if ( empty( $meta ) ) {
434 $meta = 'everybody';
435 }
436 return $meta;
437 }
438
439 /**
440 * Renders the WP.com version of the subscriptions block.
441 *
442 * @param array $data Array containing block view data.
443 * @param array $classes Array containing the classes for different block elements.
444 * @param array $styles Array containing the styles for different block elements.
445 *
446 * @return string
447 */
448 function render_wpcom_subscribe_form( $data, $classes, $styles ) {
449 global $current_blog;
450
451 $form_id = 'subscribe-blog' . ( Jetpack_Subscriptions_Widget::$instance_count > 1 ? '-' . Jetpack_Subscriptions_Widget::$instance_count : '' );
452 $url = defined( 'SUBSCRIBE_BLOG_URL' ) ? SUBSCRIBE_BLOG_URL : '';
453
454 ob_start();
455
456 Jetpack_Subscriptions_Widget::render_widget_status_messages(
457 array(
458 'success_message' => $data['success_message'],
459 )
460 );
461
462 $post_access_level = get_post_access_level();
463
464 ?>
465 <div <?php echo wp_kses_data( $data['wrapper_attributes'] ); ?>>
466 <div class="wp-block-jetpack-subscriptions__container">
467 <form
468 action="<?php echo esc_url( $url ); ?>"
469 method="post"
470 accept-charset="utf-8"
471 data-blog="<?php echo esc_attr( get_current_blog_id() ); ?>"
472 data-post_access_level="<?php echo esc_attr( $post_access_level ); ?>"
473 id="<?php echo esc_attr( $form_id ); ?>"
474 >
475 <?php
476 $email_field_id = 'subscribe-field';
477 $email_field_id .= Jetpack_Subscriptions_Widget::$instance_count > 1
478 ? '-' . Jetpack_Subscriptions_Widget::$instance_count
479 : '';
480 $label_field_id = $email_field_id . '-label';
481 ?>
482 <p id="subscribe-email">
483 <label
484 id="<?php echo esc_attr( $label_field_id ); ?>"
485 for="<?php echo esc_attr( $email_field_id ); ?>"
486 class="screen-reader-text"
487 >
488 <?php echo esc_html( $data['subscribe_placeholder'] ); ?>
489 </label>
490
491 <?php
492 printf(
493 '<input
494 required="required"
495 type="email"
496 name="email"
497 %1$s
498 style="%2$s"
499 placeholder="%3$s"
500 value="%4$s"
501 id="%5$s"
502 />',
503 ( ! empty( $classes['email_field'] )
504 ? 'class="' . esc_attr( $classes['email_field'] ) . '"'
505 : ''
506 ),
507 ( ! empty( $styles['email_field'] )
508 ? esc_attr( $styles['email_field'] )
509 : 'width: 95%; padding: 1px 10px'
510 ),
511 esc_attr( $data['subscribe_placeholder'] ),
512 esc_attr( $data['subscribe_email'] ),
513 esc_attr( $email_field_id )
514 );
515 ?>
516 </p>
517
518 <p id="subscribe-submit"
519 <?php if ( ! empty( $styles['submit_button_wrapper'] ) ) : ?>
520 style="<?php echo esc_attr( $styles['submit_button_wrapper'] ); ?>"
521 <?php endif; ?>
522 >
523 <input type="hidden" name="action" value="subscribe"/>
524 <input type="hidden" name="blog_id" value="<?php echo (int) $current_blog->blog_id; ?>"/>
525 <input type="hidden" name="source" value="<?php echo esc_url( $data['referer'] ); ?>"/>
526 <input type="hidden" name="sub-type" value="<?php echo esc_attr( $data['source'] ); ?>"/>
527 <input type="hidden" name="redirect_fragment" value="<?php echo esc_attr( $form_id ); ?>"/>
528 <?php wp_nonce_field( 'blogsub_subscribe_' . $current_blog->blog_id, '_wpnonce', false ); ?>
529 <button type="submit"
530 <?php if ( ! empty( $classes['submit_button'] ) ) : ?>
531 class="<?php echo esc_attr( $classes['submit_button'] ); ?>"
532 <?php endif; ?>
533 <?php if ( ! empty( $styles['submit_button'] ) ) : ?>
534 style="<?php echo esc_attr( $styles['submit_button'] ); ?>"
535 <?php endif; ?>
536 >
537 <?php
538 echo wp_kses(
539 html_entity_decode( $data['submit_button_text'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ),
540 Jetpack_Subscriptions_Widget::$allowed_html_tags_for_submit_button
541 );
542 ?>
543 </button>
544 </p>
545 </form>
546 <?php if ( $data['show_subscribers_total'] && $data['subscribers_total'] ) : ?>
547 <div class="wp-block-jetpack-subscriptions__subscount">
548 <?php
549 /* translators: %s: number of folks following the blog */
550 echo esc_html( sprintf( _n( 'Join %s other follower', 'Join %s other followers', $data['subscribers_total'], 'jetpack' ), number_format_i18n( $data['subscribers_total'] ) ) );
551 ?>
552 </div>
553 <?php endif; ?>
554 </div>
555 </div>
556 <?php
557
558 return ob_get_clean();
559 }
560
561 /**
562 * Renders the Jetpack version of the subscriptions block.
563 *
564 * @param array $data Array containing block view data.
565 * @param array $classes Array containing the classes for different block elements.
566 * @param array $styles Array containing the styles for different block elements.
567 *
568 * @return string
569 */
570 function render_jetpack_subscribe_form( $data, $classes, $styles ) {
571 $form_id = sprintf( 'subscribe-blog-%s', $data['widget_id'] );
572 $subscribe_field_id = apply_filters( 'subscribe_field_id', 'subscribe-field', $data['widget_id'] );
573 ob_start();
574
575 Jetpack_Subscriptions_Widget::render_widget_status_messages(
576 array(
577 'success_message' => $data['success_message'],
578 )
579 );
580
581 $blog_id = \Jetpack_Options::get_option( 'id' );
582 $post_access_level = get_post_access_level();
583
584 ?>
585 <div <?php echo wp_kses_data( $data['wrapper_attributes'] ); ?>>
586 <div class="jetpack_subscription_widget">
587 <div class="wp-block-jetpack-subscriptions__container">
588 <form
589 action="#"
590 method="post"
591 accept-charset="utf-8"
592 data-blog="<?php echo esc_attr( $blog_id ); ?>"
593 data-post_access_level="<?php echo esc_attr( $post_access_level ); ?>"
594 id="<?php echo esc_attr( $form_id ); ?>"
595 >
596 <p id="subscribe-email">
597 <label id="jetpack-subscribe-label"
598 class="screen-reader-text"
599 for="<?php echo esc_attr( $subscribe_field_id . '-' . $data['widget_id'] ); ?>">
600 <?php echo esc_html( $data['subscribe_placeholder'] ); ?>
601 </label>
602 <input type="email" name="email" required="required"
603 <?php if ( ! empty( $classes['email_field'] ) ) : ?>
604 class="<?php echo esc_attr( $classes['email_field'] ); ?> required"
605 <?php endif; ?>
606 <?php if ( ! empty( $styles['email_field'] ) ) : ?>
607 style="<?php echo esc_attr( $styles['email_field'] ); ?>"
608 <?php endif; ?>
609 value="<?php echo esc_attr( $data['subscribe_email'] ); ?>"
610 id="<?php echo esc_attr( $subscribe_field_id . '-' . $data['widget_id'] ); ?>"
611 placeholder="<?php echo esc_attr( $data['subscribe_placeholder'] ); ?>"
612 />
613 </p>
614
615 <p id="subscribe-submit"
616 <?php if ( ! empty( $styles['submit_button_wrapper'] ) ) : ?>
617 style="<?php echo esc_attr( $styles['submit_button_wrapper'] ); ?>"
618 <?php endif; ?>
619 >
620 <input type="hidden" name="action" value="subscribe"/>
621 <input type="hidden" name="blog_id" value="<?php echo (int) $blog_id; ?>"/>
622 <input type="hidden" name="source" value="<?php echo esc_url( $data['referer'] ); ?>"/>
623 <input type="hidden" name="sub-type" value="<?php echo esc_attr( $data['source'] ); ?>"/>
624 <input type="hidden" name="redirect_fragment" value="<?php echo esc_attr( $form_id ); ?>"/>
625 <?php
626 if ( is_user_logged_in() ) {
627 wp_nonce_field( 'blogsub_subscribe_' . get_current_blog_id(), '_wpnonce', false );
628 }
629 ?>
630 <button type="submit"
631 <?php if ( ! empty( $classes['submit_button'] ) ) : ?>
632 class="<?php echo esc_attr( $classes['submit_button'] ); ?>"
633 <?php endif; ?>
634 <?php if ( ! empty( $styles['submit_button'] ) ) : ?>
635 style="<?php echo esc_attr( $styles['submit_button'] ); ?>"
636 <?php endif; ?>
637 name="jetpack_subscriptions_widget"
638 >
639 <?php
640 echo wp_kses(
641 html_entity_decode( $data['submit_button_text'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ),
642 Jetpack_Subscriptions_Widget::$allowed_html_tags_for_submit_button
643 );
644 ?>
645 </button>
646 </p>
647 </form>
648
649 <?php if ( $data['show_subscribers_total'] && $data['subscribers_total'] ) : ?>
650 <div class="wp-block-jetpack-subscriptions__subscount">
651 <?php
652 /* translators: %s: number of folks following the blog */
653 echo esc_html( sprintf( _n( 'Join %s other subscriber', 'Join %s other subscribers', $data['subscribers_total'], 'jetpack' ), number_format_i18n( $data['subscribers_total'] ) ) );
654 ?>
655 </div>
656 <?php endif; ?>
657 </div>
658 </div>
659 </div>
660 <?php
661
662 return ob_get_clean();
663 }
664
665 /**
666 * Filter excerpts looking for subscription data.
667 *
668 * @param string $excerpt The extrapolated excerpt string.
669 * @param \WP_Post $post The current post being processed (in `get_the_excerpt`).
670 *
671 * @return mixed
672 */
673 function jetpack_filter_excerpt_for_newsletter( $excerpt, $post = null ) {
674 // The blogmagazine theme is overriding WP core `get_the_excerpt` filter and only passing the excerpt
675 // TODO: Until this is fixed, return the excerpt without gating. See https://github.com/Automattic/jetpack/pull/28102#issuecomment-1369161116
676 if ( $post && false !== strpos( $post->post_content, '<!-- wp:jetpack/subscriptions -->' ) ) {
677 $excerpt .= sprintf(
678 // translators: %s is the permalink url to the current post.
679 __( "<p><a href='%s'>View post</a> to subscribe to site newsletter.</p>", 'jetpack' ),
680 get_post_permalink()
681 );
682 }
683 return $excerpt;
684 }
685
686 /**
687 * Gate access to posts
688 *
689 * @param string $the_content Post content.
690 *
691 * @return string
692 */
693 function maybe_get_locked_content( $the_content ) {
694 require_once JETPACK__PLUGIN_DIR . 'modules/memberships/class-jetpack-memberships.php';
695
696 if ( Jetpack_Memberships::user_can_view_post() ) {
697 return $the_content;
698 }
699 return get_locked_content_placeholder_text();
700 }
701
702 /**
703 * Gate access to comments. We want to close comments on private sites.
704 *
705 * @param bool $default_comments_open Default state of the comments_open filter.
706 * @param int $post_id Current post id.
707 *
708 * @return bool
709 */
710 function maybe_close_comments( $default_comments_open, $post_id ) {
711 if ( ! $default_comments_open || ! $post_id ) {
712 return $default_comments_open;
713 }
714 require_once JETPACK__PLUGIN_DIR . 'modules/memberships/class-jetpack-memberships.php';
715 return Jetpack_Memberships::user_can_view_post();
716 }
717
718 /**
719 * Gate access to exisiting comments
720 *
721 * @param string $comment The comment.
722 *
723 * @return string
724 */
725 function maybe_gate_existing_comments( $comment ) {
726 if ( empty( $comment ) ) {
727 return $comment;
728 }
729
730 require_once JETPACK__PLUGIN_DIR . 'modules/memberships/class-jetpack-memberships.php';
731 if ( Jetpack_Memberships::user_can_view_post() ) {
732 return $comment;
733 }
734 return '';
735 }
736
737 /**
738 * Placeholder text for non-subscribers
739 *
740 * @return string
741 */
742 function get_locked_content_placeholder_text() {
743 return do_blocks(
744 '<!-- 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"}} -->
745 <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"}}}} -->
746 <h2 class="wp-block-heading has-text-align-center" style="margin-bottom:var(--wp--preset--spacing--60);font-size:24px">' . esc_html__( 'This post is for paid subscribers', 'jetpack' ) . '</h2>
747 <!-- /wp:heading -->
748
749 <!-- wp:jetpack/subscriptions {"borderRadius":50,"borderColor":"primary","className":"is-style-compact"} /-->
750 </div>
751 <!-- /wp:group -->'
752 );
753 }
754