Completed
Push — branch-6.9 ( 2d29e3...2e30de )
by Jeremy
27:30 queued 19:08
created

Jetpack_Email_Subscribe::parse_shortcode()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 83

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 5
nop 1
dl 0
loc 83
rs 7.4375
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Class Jetpack_Email_Subscribe
4
 * This class encapsulates:
5
 * - a shortcode for subscribing to a MailChimp list.
6
 * - a Gutenberg block for subscribing to a MailChimp list
7
 * Both the shortcode and a block display a simple signup form with an "email" field.
8
 * Submitting it subscribes the user to a MailChimp list selected in the "Sharing" section of Calypso.
9
 * Other Email services and blocks can be implemented as well in the future.
10
 */
11
class Jetpack_Email_Subscribe {
12
13
	private static $shortcode = 'jetpack-email-subscribe';
14
15
	private static $css_classname_prefix = 'jetpack-email-subscribe';
16
17
	private static $option_name = 'jetpack_mailchimp';
18
19
	private static $block_name = 'mailchimp';
20
21
	private static $instance;
22
23
	private static $version = '1.0';
24
25
	private function __construct() {
26
	}
27
28
	/**
29
	 * This follows a classic singleton pattern.
30
	 *
31
	 * @return Jetpack_Email_Subscribe|null
32
	 */
33
	public static function get_instance() {
34
		// Do not load this at all if it's neither a WPCOM or a connected JP site.
35
		if ( ! ( ( defined( 'IS_WPCOM' ) && IS_WPCOM ) || Jetpack::is_active() ) ) {
36
			return null;
37
		}
38
39
		if ( ! self::$instance ) {
40
			self::$instance = new self();
41
			self::$instance->register_init_hook();
42
		}
43
44
		return self::$instance;
45
	}
46
47
	private function register_scripts_and_styles() {
48
		wp_register_script( 'jetpack-email-subscribe', Jetpack::get_file_url_for_environment( '_inc/build/shortcodes/js/jetpack-email-subscribe.min.js', 'modules/shortcodes/js/jetpack-email-subscribe.js' ), array( 'jquery' ), self::$version );
49
		wp_register_style( 'jetpack-email-subscribe', plugins_url( '/css/jetpack-email-subscribe.css', __FILE__ ), array(), self::$version );
50
	}
51
52
	private function register_init_hook() {
53
		add_action( 'init', array( $this, 'init_hook_action' ) );
54
		add_action( 'jetpack_options_whitelist', array( $this, 'filter_whitelisted_options' ), 10, 1 );
55
		add_action( 'jetpack_blocks_to_register', array( $this, 'prevent_jetpack_register_block' ), 10, 1 );
56
	}
57
58
	/**
59
	 * There is a structural problem in Jetpack_Gutenberg class that breaks server-side rendered blocks on WPCOM.
60
	 * The problem stems from register_blocks being called very late. Too late in fact to WP_REST_Block_Renderer_Controller be aware of them.
61
	 * Regular 'register_block_type' call does not register blocks as available from Calypso SDK.
62
	 * I tried registering block twice, both with jetpack_register_block and register_block_type, but that produces a notice.
63
	 * I introduced this callback and 'jetpack_blocks_to_register' filter as a way of dealing with this issue
64
	 * @param $blocks - list of blocks that will be passed to 'register_block_type' call of Jetpack_Gutenberg.
65
	 *
66
	 * @return array
67
	 */
68
	public function prevent_jetpack_register_block( $blocks ) {
69
		return array_filter( $blocks, array( $this, 'filter_out_this_block' ) );
70
	}
71
72
	public function filter_out_this_block( $block_name ) {
73
		return ( $block_name !== self::$block_name );
74
	}
75
76
	public function filter_whitelisted_options( $options ) {
77
		$options[] = self::$option_name;
78
		return $options;
79
	}
80
81
	private function register_shortcode() {
82
		add_shortcode( self::$shortcode, array( $this, 'parse_shortcode' ) );
83
	}
84
85
	private function register_gutenberg_block() {
86
		if ( Jetpack_Gutenberg::is_gutenberg_available() ) {
87
			register_block_type( 'jetpack/' . self::$block_name, array(
88
				'attributes' => array(
89
					'title' => array(
90
						'type' => 'string',
91
					),
92
					'email_placeholder' => array(
93
						'type' => 'string',
94
					),
95
					'submit_label' => array(
96
						'type' => 'string',
97
					),
98
					'consent_text' => array(
99
						'type' => 'string',
100
					),
101
					'processing_label' => array(
102
						'type' => 'string',
103
					),
104
					'success_label' => array(
105
						'type' => 'string',
106
					),
107
					'error_label' => array(
108
						'type' => 'string',
109
					),
110
					'className' => array(
111
						'type' => 'string',
112
					),
113
				),
114
				'style' => 'jetpack-email-subscribe',
115
				'render_callback' => array( $this, 'parse_shortcode' ),
116
			) );
117
			jetpack_register_block( self::$block_name, array(), array( 'available' => true ) );
118
		}
119
	}
120
121
	public function init_hook_action() {
122
		$this->register_scripts_and_styles();
123
		$this->register_shortcode();
124
		$this->register_gutenberg_block();
125
	}
126
127
	private function get_blog_id() {
128
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
129
			return get_current_blog_id();
130
		}
131
132
		return Jetpack_Options::get_option( 'id' );
133
	}
134
135 View Code Duplication
	private function is_set_up() {
136
		$option = get_option( self::$option_name );
137
		if ( ! $option ) {
138
			return false;
139
		}
140
		$data = json_decode( $option, true );
141
		if ( isset( $data['follower_list_id'], $data['follower_list_id'] ) ) {
142
			return true;
143
		}
144
		return false;
145
	}
146
147
	private function get_site_slug() {
148
		if ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'build_raw_urls' ) ) {
149
			return Jetpack::build_raw_urls( home_url() );
150
		} elseif ( class_exists( 'WPCOM_Masterbar' ) && method_exists( 'WPCOM_Masterbar', 'get_calypso_site_slug' ) ) {
151
			return WPCOM_Masterbar::get_calypso_site_slug( get_current_blog_id() );
152
		}
153
		return '';
154
	}
155
156
	public function parse_shortcode( $attrs ) {
157
		// Lets check if everything is set up.
158
		if (
159
			! $this->is_set_up() &&
160
			current_user_can( 'edit_posts' )
161
		) {
162
			return sprintf(
163
				'<div class="components-placeholder">
164
					<div class="components-placeholder__label">%s</div>
165
					<div class="components-placeholder__instructions">%s</div>
166
					<a class="components-button is-button" href="https://wordpress.com/sharing/%s" target="_blank">%s</a>
167
				</div>',
168
				__( 'MailChimp form', 'jetpack' ),
169
				__( 'You need to connect your MailChimp account and choose a list in order to start collecting Email subscribers.', 'jetpack' ),
170
				$this->get_site_slug(),
171
				__( 'Set up MailChimp form', 'jetpack' )
172
			);
173
		}
174
175
		// We allow for overriding the presentation labels.
176
		$data = shortcode_atts(
177
			array(
178
				'title'             => '',
179
				'email_placeholder' => __( 'Enter your email', 'jetpack' ),
180
				'submit_label'      => __( 'Join My Email List', 'jetpack' ),
181
				'consent_text'      => __( 'By clicking submit, you agree to share your email address with the site owner and MailChimp to receive marketing, updates, and other emails from the site owner. Use the unsubscribe link in those emails to opt out at any time.', 'jetpack' ),
182
				'processing_label'  => __( 'Processing...', 'jetpack' ),
183
				'success_label'     => __( 'Success! You\'ve been added to the list.', 'jetpack' ),
184
				'error_label'       => __( "Oh no! Unfortunately there was an error.\nPlease try reloading this page and adding your email once more.", 'jetpack' ),
185
			),
186
			is_array( $attrs ) ? array_filter( $attrs ) : array()
187
		);
188
189
		// We don't allow users to change these parameters:
190
		$data = array_merge( $data, array(
191
			'blog_id'           => $this->get_blog_id(),
192
			'classname'         => self::$css_classname_prefix,
193
			'dom_id'            => uniqid( self::$css_classname_prefix . '_', false ),
194
		) );
195
196
		if ( ! wp_script_is( 'jetpack-email-subscribe', 'enqueued' ) ) {
197
			wp_enqueue_script( 'jetpack-email-subscribe' );
198
		}
199
200
		if ( ! wp_style_is( 'jetpack-email-subscribe', 'enqueue' ) ) {
201
			wp_enqueue_style( 'jetpack-email-subscribe' );
202
		}
203
204
		wp_add_inline_script(
205
			'jetpack-email-subscribe',
206
			sprintf(
207
				"try{JetpackEmailSubscribe.activate( '%s', '%s', '%s' );}catch(e){}",
208
				esc_js( $data['blog_id'] ),
209
				esc_js( $data['dom_id'] ),
210
				esc_js( $data['classname'] )
211
			)
212
		);
213
214
		return sprintf(
215
			'<div class="%1$s" id="%2$s">
216
				%3$s
217
				<form>
218
					<input type="email" class="%1$s-email" required placeholder="%4$s">
219
					<button type="submit" class="%1$s-submit">%6$s</button>
220
					<label class="%1$s-consent-label">
221
					    <small>%5$s</small>
222
					</label>
223
				</form>
224
				<div class="%1$s-processing">%7$s</div>
225
				<div class="%1$s-success">%8$s</div>
226
				<div class="%1$s-error">%9$s</div>
227
			</div>',
228
			esc_attr( $data['classname'] ),
229
			esc_attr( $data['dom_id'] ),
230
			$data['title'] ? '<h3>' . esc_html( $data['title'] ) . '</h3>' : '',
231
			esc_html( $data['email_placeholder'] ),
232
			esc_html( $data['consent_text'] ),
233
			esc_html( $data['submit_label'] ),
234
			nl2br( esc_html( $data['processing_label'] ) ),
235
			nl2br( esc_html( $data['success_label'] ) ),
236
			nl2br( esc_html( $data['error_label'] ) )
237
		);
238
	}
239
240
}
241
242
Jetpack_Email_Subscribe::get_instance();
243