PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.1
16.3-a.1 16.2 16.2-beta 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 All 503 releases
jetpack / extensions / blocks / subscriptions / class-jetpack-subscription-site.php

class-jetpack-subscription-site.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-a.1, at extensions/blocks/subscriptions/class-jetpack-subscription-site.php

334 lines 9.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Adds support for Jetpack Subscription Site feature.
4 *
5 * @package automattic/jetpack
6 * @since 13.2
7 */
8
9 namespace Automattic\Jetpack\Extensions\Subscriptions;
10
11 use Jetpack_Memberships;
12 use WP_Block_Template;
13 use WP_Post;
14
15 /**
16 * Jetpack_Subscription_Site class.
17 */
18 class Jetpack_Subscription_Site {
19 /**
20 * Jetpack_Subscription_Site singleton instance.
21 *
22 * @var Jetpack_Subscription_Site|null
23 */
24 private static $instance;
25
26 /**
27 * Jetpack_Subscription_Site instance init.
28 */
29 public static function init() {
30 if ( self::$instance === null ) {
31 self::$instance = new Jetpack_Subscription_Site();
32 }
33
34 return self::$instance;
35 }
36
37 /**
38 * Handles Subscribe block placements.
39 *
40 * @return void
41 */
42 public function handle_subscribe_block_placements() {
43 $this->handle_subscribe_block_post_end_placement();
44 $this->handle_subscribe_block_navigation_placement();
45 }
46
47 /**
48 * Returns true if current user can view the post.
49 *
50 * @return bool
51 */
52 protected function user_can_view_post() {
53 if ( ! class_exists( 'Jetpack_Memberships' ) ) {
54 return true;
55 }
56
57 return Jetpack_Memberships::user_can_view_post();
58 }
59
60 /**
61 * Returns post end placement hooked block attributes.
62 *
63 * @param array $default_attrs Deafult attributes.
64 * @param array $anchor_block The anchor block, in parsed block array format.
65 *
66 * @return array
67 */
68 protected function get_post_end_placement_block_attributes( $default_attrs, $anchor_block ) {
69 if ( ! empty( $anchor_block['attrs']['layout']['type'] ) ) {
70 return array_merge(
71 $default_attrs,
72 array(
73 'layout' => array(
74 'type' => $anchor_block['attrs']['layout']['type'],
75 ),
76 )
77 );
78 }
79
80 if ( ! empty( $anchor_block['attrs']['layout']['inherit'] ) ) {
81 return array_merge(
82 $default_attrs,
83 array(
84 'layout' => array(
85 'inherit' => $anchor_block['attrs']['layout']['inherit'],
86 ),
87 )
88 );
89 }
90
91 return $default_attrs;
92 }
93
94 /**
95 * Returns true if context is recognized as a header element.
96 *
97 * @param WP_Block_Template|WP_Post|array $context The block template, template part, or pattern the anchor block belongs to.
98 *
99 * @return bool
100 */
101 protected function is_header_context( $context ) {
102 if ( $context instanceof WP_Post && $context->post_type === 'wp_navigation' ) {
103 return true;
104 }
105
106 if ( $context instanceof WP_Block_Template && $context->area === 'header' ) {
107 return true;
108 }
109
110 return false;
111 }
112
113 /**
114 * Returns true if context is recognized as a single post element.
115 *
116 * @param WP_Block_Template|WP_Post|array $context The block template, template part, or pattern the anchor block belongs to.
117 *
118 * @return bool
119 */
120 protected function is_single_post_context( $context ) {
121 /**
122 * Some themes are not returning a WP_Block_Template. In that case, we need to check with is_singular function.
123 */
124 if ( is_array( $context ) ) {
125 return is_singular( 'post' );
126 }
127
128 return $context instanceof WP_Block_Template && $context->slug === 'single';
129 }
130
131 /**
132 * Handles Subscription block navigation placement.
133 *
134 * @return void
135 */
136 protected function handle_subscribe_block_navigation_placement() {
137 $is_enabled = get_option( 'jetpack_subscriptions_subscribe_navigation_enabled', false );
138 if ( ! $is_enabled ) {
139 return;
140 }
141
142 if ( ! wp_is_block_theme() ) { // TODO Fallback for classic themes.
143 return;
144 }
145
146 add_filter(
147 'hooked_block_types',
148 function ( $hooked_blocks, $relative_position, $anchor_block, $context ) {
149 if (
150 $anchor_block === 'core/navigation' &&
151 $relative_position === 'last_child' &&
152 self::is_header_context( $context )
153 ) {
154 $hooked_blocks[] = 'jetpack/subscriptions';
155 }
156
157 return $hooked_blocks;
158 },
159 10,
160 4
161 );
162
163 add_filter(
164 'hooked_block_jetpack/subscriptions',
165 function ( $hooked_block, $hooked_block_type, $relative_position, $anchor_block ) {
166 $is_navigation_anchor_block = isset( $anchor_block['blockName'] ) && $anchor_block['blockName'] === 'core/navigation';
167
168 if ( $is_navigation_anchor_block ) {
169 $class_name = ( ! empty( $hooked_block['attrs'] ) && ! empty( $hooked_block['attrs']['className'] ) )
170 ? $hooked_block['attrs']['className'] . ' is-style-button'
171 : 'is-style-button';
172
173 $hooked_block['attrs']['className'] = $class_name;
174 $hooked_block['attrs']['appSource'] = 'subscribe-block-navigation';
175 }
176
177 return $hooked_block;
178 },
179 10,
180 4
181 );
182 }
183
184 /**
185 * Handles Subscribe block placement at the end of each post.
186 *
187 * @return void
188 */
189 protected function handle_subscribe_block_post_end_placement() {
190 $subscribe_post_end_enabled = get_option( 'jetpack_subscriptions_subscribe_post_end_enabled', false );
191 if ( ! $subscribe_post_end_enabled ) {
192 return;
193 }
194
195 if ( ! wp_is_block_theme() ) { // Fallback for classic themes.
196 add_filter(
197 'the_content',
198 function ( $content ) {
199 // Check if we're inside the main loop in a single Post.
200 if (
201 is_single() &&
202 in_the_loop() &&
203 is_main_query() &&
204 $this->user_can_view_post()
205 ) {
206 // translators: %s is the name of the site.
207 $discover_more_from_text = sprintf( __( 'Discover more from %s', 'jetpack' ), get_bloginfo( 'name' ) );
208 $subscribe_text = __( 'Subscribe to get the latest posts sent to your email.', 'jetpack' );
209
210 return $content . do_blocks(
211 <<<HTML
212 <!-- wp:group {"style":{"spacing":{"padding":{"top":"0px","bottom":"0px","left":"0px","right":"0px"},"margin":{"top":"32px","bottom":"32px"}},"border":{"width":"0px","style":"none"}},"className":"has-border-color","layout":{"type":"default"}} -->
213 <div class="wp-block-group has-border-color" style="border-style:none;border-width:0px;margin-top:32px;margin-bottom:32px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px">
214 <!-- wp:separator {"style":{"spacing":{"margin":{"bottom":"24px"}}},"className":"is-style-wide"} -->
215 <hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-bottom:24px"/>
216 <!-- /wp:separator -->
217
218 <!-- wp:heading {"textAlign":"center","level":3,"style":{"layout":{"selfStretch":"fit","flexSize":null},"spacing":{"margin":{"top":"4px","bottom":"10px"}}}} -->
219 <h3 class="wp-block-heading has-text-align-center" style="margin-top:4px;margin-bottom:10px">$discover_more_from_text</h3>
220 <!-- /wp:heading -->
221
222 <!-- wp:paragraph {"align":"center","style":{"typography":{"fontSize":"15px"},"spacing":{"margin":{"top":"10px","bottom":"10px"}}}} -->
223 <p class="has-text-align-center" style="margin-top:10px;margin-bottom:10px;font-size:15px">$subscribe_text</p>
224 <!-- /wp:paragraph -->
225
226 <!-- wp:group {"layout":{"type":"constrained","contentSize":"480px"}} -->
227 <div class="wp-block-group">
228 <!-- wp:jetpack/subscriptions {"appSource":"subscribe-block-post-end"} /-->
229 </div>
230 <!-- /wp:group -->
231 </div>
232 <!-- /wp:group -->
233 HTML
234 );
235 }
236
237 return $content;
238 },
239 100, // To insert it after the sharing blocks.
240 1
241 );
242
243 return;
244 }
245
246 add_filter(
247 'hooked_block_types',
248 function ( $hooked_blocks, $relative_position, $anchor_block, $context ) {
249 if (
250 $anchor_block === 'core/post-content' &&
251 $relative_position === 'after' &&
252 self::is_single_post_context( $context ) &&
253 $this->user_can_view_post()
254 ) {
255 $hooked_blocks[] = 'jetpack/subscriptions';
256 }
257
258 return $hooked_blocks;
259 },
260 10,
261 4
262 );
263
264 add_filter(
265 'hooked_block_jetpack/subscriptions',
266 function ( $hooked_block, $hooked_block_type, $relative_position, $anchor_block ) {
267 $is_post_content_anchor_block = isset( $anchor_block['blockName'] ) && $anchor_block['blockName'] === 'core/post-content';
268 if ( $is_post_content_anchor_block && ( $relative_position === 'after' || $relative_position === 'before' ) ) {
269 $attrs = $this->get_post_end_placement_block_attributes(
270 array(
271 'style' => array(
272 'spacing' => array(
273 'margin' => array(
274 'top' => '48px',
275 'bottom' => '48px',
276 ),
277 'padding' => array(
278 'top' => '5px',
279 'bottom' => '5px',
280 ),
281 ),
282 ),
283 ),
284 $anchor_block
285 );
286
287 // translators: %s is the name of the site.
288 $discover_more_from_text = sprintf( __( 'Discover more from %s', 'jetpack' ), get_bloginfo( 'name' ) );
289 $subscribe_text = __( 'Subscribe to get the latest posts sent to your email.', 'jetpack' );
290 $inner_content_begin = <<<HTML
291 <div class="wp-block-group" style="margin-top:48px;margin-bottom:48px;padding-top:5px;padding-bottom:5px">
292 <!-- wp:separator {"style":{"spacing":{"margin":{"bottom":"36px"}}},"className":"is-style-wide"} -->
293 <hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-bottom:36px"/>
294 <!-- /wp:separator -->
295
296 <!-- wp:heading {"textAlign":"center","level":3,"style":{"layout":{"selfStretch":"fit","flexSize":null},"spacing":{"margin":{"top":"4px","bottom":"10px"}}}} -->
297 <h3 class="wp-block-heading has-text-align-center" style="margin-top:4px;margin-bottom:10px">$discover_more_from_text</h3>
298 <!-- /wp:heading -->
299
300 <!-- wp:paragraph {"align":"center","style":{"typography":{"fontSize":"15px"},"spacing":{"margin":{"top":"4px","bottom":"0px"}}}} -->
301 <p class="has-text-align-center" style="margin-top:4px;margin-bottom:0px;font-size:15px">$subscribe_text</p>
302 <!-- /wp:paragraph -->
303
304 <!-- wp:group {"layout":{"type":"constrained","contentSize":"480px"}} -->
305 <div class="wp-block-group">
306 HTML;
307 $inner_content_end = <<<'HTML'
308 </div>
309 <!-- /wp:group -->
310 </div>
311 HTML;
312
313 $hooked_block['attrs']['appSource'] = 'subscribe-block-post-end';
314
315 return array(
316 'blockName' => 'core/group',
317 'attrs' => $attrs,
318 'innerBlocks' => array( $hooked_block ),
319 'innerContent' => array(
320 $inner_content_begin,
321 null,
322 $inner_content_end,
323 ),
324 );
325 }
326
327 return $hooked_block;
328 },
329 10,
330 4
331 );
332 }
333 }
334