-
Notifications
You must be signed in to change notification settings - Fork 1
/
ComingSoon.php
381 lines (315 loc) · 11.9 KB
/
ComingSoon.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
<?php
namespace NewfoldLabs\WP\Module\ComingSoon;
use NewfoldLabs\WP\ModuleLoader\Container;
use function NewfoldLabs\WP\ModuleLoader\container;
/**
* This class adds a coming soon page functionality.
**/
#[\AllowDynamicProperties]
class ComingSoon {
/**
* Register functionality using WordPress Actions.
*
* @param Container $container the container from the module loader
*/
public function __construct( Container $container ) {
$this->container = $container;
// setup args
$defaults = array(
'admin_screen_id' => container()->plugin()->id,
'admin_app_url' => \admin_url( 'admin.php?page=newfold' ),
'admin_notice_text' => __( 'Your site has Coming Soon mode active.', 'newfold-module-coming-soon' ),
'template_page_title' => __( 'Coming Soon!', 'newfold-module-coming-soon' ),
'template_styles' => false,
'template_content' => false,
'template_h1' => __( 'Coming Soon!', 'newfold-module-coming-soon' ),
'template_h2' => __( 'A New WordPress Site!', 'newfold-module-coming-soon' ),
'template_login_btn' => false,
'template_p' => __( 'Be the first to know when we launch, enter your email address and we will let you know when we go live and any future website updates we have.', 'newfold-module-coming-soon' ),
'template_msg_success' => __( 'Thank you, please check your email to confirm your subscription.', 'newfold-module-coming-soon' ),
'template_msg_active' => __( 'Your email address is already subscribed to this website. Stay tuned to your inbox for our updates or try a different email address.', 'newfold-module-coming-soon' ),
'template_msg_invalid' => __( 'There was an error with your submission and you were not subscribed. Please try again with a valid email address.', 'newfold-module-coming-soon' ),
'template_email_label' => __( 'Email', 'newfold-module-coming-soon' ),
'template_email_ph' => __( 'Enter your email address', 'newfold-module-coming-soon' ),
'template_subscribe' => __( 'Subscribe', 'newfold-module-coming-soon' ),
'template_footer_t' => __( 'Is this your website? Log in to WordPress to launch your site.', 'newfold-module-coming-soon' ),
);
$this->args = wp_parse_args( $container->has( 'comingsoon' ) ? $container['comingsoon'] : array(), $defaults );
if ( false !== $this->args['template_styles'] && isset( $container['plugin'] ) ) {
// add plugin version to plugin styles file for cache busting
$this->args['template_styles'] = $this->args['template_styles'] . '?v=' . container()->plugin()->version;
}
new WooCommerceOptionsSync();
// set up all actions
\add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
\add_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
\add_action( 'newfold/onboarding/completed', array( $this, 'handle_onboarding_completed' ) );
\add_action( 'admin_notices', array( $this, 'notice_display' ) );
\add_action( 'template_redirect', array( $this, 'maybe_load_template' ) );
\add_action( 'wp_ajax_newfold_coming_soon_subscribe', array( $this, 'coming_soon_subscribe' ) );
\add_action( 'wp_ajax_nopriv_newfold_coming_soon_subscribe', array( $this, 'coming_soon_subscribe' ) );
\add_action( 'plugins_loaded', array( $this, 'coming_soon_prevent_emails' ) );
\add_filter( 'default_option_nfd_coming_soon', array( $this, 'filter_coming_soon_fallback' ) );
\add_action( 'update_option_nfd_coming_soon', array( $this, 'on_update_nfd_coming_soon' ), 10, 2 );
\add_action( 'update_option_mm_coming_soon', array( $this, 'on_update_mm_coming_soon' ), 10, 2 );
\add_filter( 'jetpack_is_under_construction_plugin', array( $this, 'filter_jetpack_is_under_construction' ) );
new AdminBarSiteStatusBadge( $container );
new SitePreviewWarning();
new PrePublishModal();
}
/**
* When the coming soon state is updated, make sure we trigger actions and update the legacy option value.
*
* @param mixed $old_value
* @param mixed $value
*
* @return mixed
*/
public function on_update_nfd_coming_soon( $old_value, $value ) {
// Ensure the value is a boolean.
$value = wp_validate_boolean( $value );
// Trigger any actions associated with the coming soon state.
$this->conditionally_trigger_coming_soon_action_hooks( $value );
// When the database value changes for the new value, make sure we update the legacy value.
remove_filter( 'update_option_mm_coming_soon', array( $this, 'on_update_mm_coming_soon' ) );
update_option( 'mm_coming_soon', $value );
add_filter( 'update_option_mm_coming_soon', array( $this, 'on_update_mm_coming_soon' ), 10, 2 );
return $value;
}
/**
* When the coming soon state is updated, make sure we trigger actions and update the new option value.
*
* @param mixed $old_value
* @param mixed $value
*
* @return mixed
*/
public function on_update_mm_coming_soon( $old_value, $value ) {
// Ensure the value is a boolean.
$value = wp_validate_boolean( $value );
// Trigger any actions associated with the coming soon state.
$this->conditionally_trigger_coming_soon_action_hooks( $value );
// When the database value changes for the legacy value, make sure we update the new value.
remove_filter( 'update_option_nfd_coming_soon', array( $this, 'on_update_nfd_coming_soon' ) );
update_option( 'nfd_coming_soon', $value );
add_filter( 'update_option_nfd_coming_soon', array( $this, 'on_update_nfd_coming_soon' ), 10, 2 );
return $value;
}
/**
* Conditionally trigger coming soon actions.
*
* The data module only starts listening for events after the init hook.
* - If the init hook has run, we trigger the action immediately.
* - If the init hook has not run, we add a callback to the init hook to trigger the action.
*
* @param bool $isEnabled
*
* @return void
*/
public function conditionally_trigger_coming_soon_action_hooks( bool $isEnabled ) {
if ( ! did_action( 'init' ) ) {
add_action( 'init', function () use ( $isEnabled ) {
$this->conditionally_trigger_coming_soon_action_hooks( $isEnabled );
}, 99 );
return;
}
if ( $isEnabled ) {
$this->trigger_enabled_action_hook();
} else {
$this->trigger_disabled_action_hook();
}
}
/**
* Trigger the enabled action hook.
*
* @return void
*/
public function trigger_enabled_action_hook() {
if ( ! did_action( 'newfold/coming-soon/enabled' ) ) {
do_action( 'newfold/coming-soon/enabled' );
}
}
/**
* Trigger the disabled action hook.
*
* @return void
*/
public function trigger_disabled_action_hook() {
if ( ! did_action( 'newfold/coming-soon/disabled' ) ) {
do_action( 'newfold/coming-soon/disabled' );
}
}
/**
* If nfd_coming_soon is not defined, set it to the value of mm_coming_soon.
*
* @return bool
*/
public function filter_coming_soon_fallback() {
return wp_validate_boolean( get_option( 'mm_coming_soon', false ) );
}
/**
* Enqueue admin scripts.
*/
public function enqueue_admin_scripts() {
$assetsDir = container()->plugin()->url . 'vendor/newfold-labs/wp-module-coming-soon/static/js/';
wp_enqueue_script(
'newfold-coming-soon-api',
$assetsDir . 'coming-soon.js',
array( 'wp-api-fetch', 'nfd-runtime' ),
container()->plugin()->version,
true
);
}
/**
* Register the coming soon route.
*/
public function rest_api_init() {
new API\ComingSoon();
}
/**
* Handle the onboarding complete action.
* When the onboarding is complete, disable the coming soon page if the user has not opted in.
*
* @return void
*/
public function handle_onboarding_completed() {
$coming_soon_service = container()->get( 'comingSoon' );
$coming_soon_last_changed = $coming_soon_service->get_last_changed_timestamp();
if ( ! $coming_soon_last_changed ) {
$coming_soon_service->disable();
}
}
/**
* Display coming soon notice.
*/
public function notice_display() {
$screen = get_current_screen();
$allowed_notice_html = array(
// formatting
'strong' => array(),
'em' => array(),
// and links
'a' => array(
'href' => array(),
'title' => array(),
),
);
if (
isComingSoonActive() && // coming soon is active
false === strpos( $screen->id, $this->args['admin_screen_id'] ) && // not on our app screen
current_user_can( 'manage_options' ) // current user can manage options
) {
?>
<div class='notice notice-warning'>
<p><?php echo wp_kses( $this->args['admin_notice_text'], $allowed_notice_html ); ?></p>
</div>
<?php
}
}
/**
* Load the coming soon page, if necessary.
*/
public function maybe_load_template() {
if ( ! is_user_logged_in() || ( isset( $_SERVER['QUERY_STRING'] ) && 'preview=coming_soon' === $_SERVER['QUERY_STRING'] ) ) {
if ( isComingSoonActive() ) {
self::coming_soon_content( $this->args );
die();
}
}
}
/**
* Render the coming soon page.
*
* @param array $args the args from container and defaults to pass to the template
*/
public static function coming_soon_content( $args ) {
$coming_soon_template = __DIR__ . '/template/index.php';
load_template( $coming_soon_template, true, $args );
}
/**
* Handle the AJAX subscribe action.
*/
public function coming_soon_subscribe() {
$response = array();
$a_response = array();
$email = sanitize_email( wp_unslash( $_POST['email'] ) );
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['nonce'] ), 'newfold_coming_soon_subscribe_nonce' ) ) {
$a_response['message'] = __( 'Gotcha!', 'newfold-module-coming-soon' );
$a_response['status'] = 'nonce_failure';
} else {
if ( ! is_email( $email ) ) {
$a_response['message'] = __( 'Please provide a valid email address', 'newfold-module-coming-soon' );
$a_response['status'] = 'invalid_email';
} else {
// Initialize JetPack_Subscriptions
$jetpack = \Jetpack_Subscriptions::init();
// ensure jetpack subscribe is callable, bail if not.
if ( ! is_callable( array( $jetpack, 'subscribe' ) ) ) {
$a_response['message'] = __( 'Jetpack encountered an error with the subscription', 'newfold-module-coming-soon' );
$a_response['status'] = 'jetpack-error';
wp_send_json( $a_response );
exit;
}
// Get JetPack response and subscribe email if response is true
$response = $jetpack->subscribe(
$email,
0,
false,
// See Jetpack subscribe `extra_data` attribute
array(
'server_data' => jetpack_subscriptions_cherry_pick_server_data(),
)
);
if ( isset( $response[0]->errors ) ) {
$error_text = array_keys( $response[0]->errors );
$error_text = $error_text[0];
$a_response['message'] = __( 'There was an error with the subscription', 'newfold-module-coming-soon' );
$a_response['status'] = $error_text;
} else {
$a_response['message'] = __( 'Subscription successful', 'newfold-module-coming-soon' );
$a_response['status'] = 'success';
}
}
wp_send_json( $a_response );
exit;
}
}
/**
* When the coming soon module is enabled, add a filter to override Jetpack to prevent emails from being sent.
*/
public function coming_soon_prevent_emails() {
if ( isComingSoonActive() ) {
add_filter(
'jetpack_subscriptions_exclude_all_categories_except',
__CLASS__ . '\\coming_soon_prevent_emails_return_array'
);
}
}
/**
* Prevent emails from being sent.
*
* @return string[]
* @see coming_soon_prevent_emails
*
*/
public function coming_soon_prevent_emails_return_array() {
return array(
'please-for-the-love-of-all-things-do-not-exist',
);
}
/**
* Filter Jetpack's is_under_construction_plugin to return true if the coming soon module is active.
*
* @see https://github.com/Automattic/jetpack/blob/trunk/projects/plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php#L1149-L1184
*
* @param bool $value
*
* @return bool
*/
public function filter_jetpack_is_under_construction( $value ) {
if ( isComingSoonActive() ) {
return true;
}
return $value;
}
}