PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.1.2
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.1.2
3.3.0 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 trunk 1.0.4 1.1.0 1.1.0.1 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 All 162 releases
cartflows / libraries / nps-survey / classes / nps-survey-script.php

nps-survey-script.php in CartFlows – Funnel Builder & Checkout Plugin for WooCommerce 3.1.2, at libraries/nps-survey/classes/nps-survey-script.php

514 lines 13.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * NPS Survey Script
4 * File to handle behaviour and content of NPS popup`
5 *
6 * @package {{package}}
7 */
8
9 // Prevent multiple inclusions of this file.
10 if ( defined( 'NPS_SURVEY_SCRIPT_LOADED' ) ) {
11 return;
12 }
13 define( 'NPS_SURVEY_SCRIPT_LOADED', true );
14
15 /**
16 * Nps_Survey
17 */
18 class Nps_Survey {
19 /**
20 * Instance
21 *
22 * @access private
23 * @var object Class Instance.
24 * @since 1.0.0
25 */
26 private static $instance = null;
27
28 /**
29 * Constructor.
30 *
31 * @since 1.0.0
32 */
33 public function __construct() {
34 add_action( 'rest_api_init', array( $this, 'register_route' ) );
35 }
36
37 /**
38 * Initiator
39 *
40 * @since 1.0.0
41 * @return object initialized object of class.
42 */
43 public static function get_instance() {
44 if ( null === self::$instance ) {
45 self::$instance = new self();
46 }
47 return self::$instance;
48 }
49
50 /**
51 * Render NPS Survey.
52 *
53 * @param string $id ID of the root element, should start with nps-survey- .
54 * @param array<mixed> $vars Variables to be passed to the NPS.
55 * @since 1.0.0
56 * @return void
57 */
58 public static function show_nps_notice( string $id, array $vars = [] ): void {
59
60 if ( ! isset( $vars['plugin_slug'] ) || ! is_string( $vars['plugin_slug'] ) ) {
61 return;
62 }
63
64 $plugin_slug = $vars['plugin_slug'];
65 $display_after = is_int( $vars['display_after'] ) ? $vars['display_after'] : 0;
66
67 if ( ! self::is_show_nps_survey_form( $plugin_slug, $display_after ) ) {
68 return;
69 }
70
71 $show_on_screen = ! empty( $vars['show_on_screens'] ) && is_array( $vars['show_on_screens'] ) ? $vars['show_on_screens'] : [ 'dashboard' ];
72
73 if ( ! function_exists( 'get_current_screen' ) ) {
74 require_once ABSPATH . '/wp-admin/includes/screen.php';
75 }
76 $current_screen = get_current_screen();
77
78 if ( $current_screen instanceof WP_Screen && ! in_array( $current_screen->id, $show_on_screen, true ) ) {
79 return;
80 }
81 // Loading script here to confirm if the screen is allowed or not.
82 self::editor_load_scripts( $show_on_screen );
83
84 ?><div data-id="<?php echo esc_attr( $id ); ?>" class="nps-survey-root" data-vars="<?php echo esc_attr( strval( wp_json_encode( $vars ) ) ); ?>"></div>
85 <?php
86 }
87
88 /**
89 * Generate and return the Google fonts url.
90 *
91 * @since 1.0.2
92 * @return string
93 */
94 public static function google_fonts_url() {
95
96 $font_families = array(
97 'Figtree:400,500,600,700',
98 );
99
100 $query_args = array(
101 'family' => rawurlencode( implode( '|', $font_families ) ),
102 'subset' => rawurlencode( 'latin,latin-ext' ),
103 );
104
105 return add_query_arg( $query_args, '//fonts.googleapis.com/css' );
106 }
107
108 /**
109 * Load script.
110 *
111 * @param array<string> $show_on_screens An array of screen IDs where the scripts should be loaded.
112 * @since 1.0.0
113 * @return void
114 */
115 public static function editor_load_scripts( $show_on_screens ): void {
116
117 if ( ! is_admin() ) {
118 return;
119 }
120
121 $screen = get_current_screen();
122 $screen_id = $screen ? $screen->id : '';
123
124 if ( ! in_array( $screen_id, $show_on_screens, true ) ) {
125 return;
126 }
127
128 $handle = 'nps-survey-script';
129 $build_path = NPS_SURVEY_DIR . 'dist/';
130 $default_build_url = NPS_SURVEY_URL . 'dist/';
131
132 // Use a filter to allow $build_url to be modified externally.
133 $build_url = apply_filters( 'nps_survey_build_url', $default_build_url );
134 $script_asset_path = $build_path . 'main.asset.php';
135
136 $script_info = file_exists( $script_asset_path )
137 ? include $script_asset_path
138 : array(
139 'dependencies' => array(),
140 'version' => NPS_SURVEY_VER,
141 );
142
143 $script_dep = array_merge( $script_info['dependencies'], array( 'jquery' ) );
144
145 wp_enqueue_script(
146 $handle,
147 $build_url . 'main.js',
148 $script_dep,
149 $script_info['version'],
150 true
151 );
152
153 $data = apply_filters(
154 'nps_survey_vars',
155 [
156 'ajaxurl' => esc_url( admin_url( 'admin-ajax.php' ) ),
157 '_ajax_nonce' => wp_create_nonce( 'nps-survey' ),
158 'rest_api_nonce' => current_user_can( 'manage_options' ) ? wp_create_nonce( 'wp_rest' ) : '',
159 ]
160 );
161
162 // Add localize JS.
163 wp_localize_script(
164 'nps-survey-script',
165 'npsSurvey',
166 $data
167 );
168
169 wp_enqueue_style( 'nps-survey-style', $build_url . '/style-main.css', array(), NPS_SURVEY_VER );
170 wp_style_add_data( 'nps-survey-style', 'rtl', 'replace' );
171 wp_enqueue_style( 'nps-survey-google-fonts', self::google_fonts_url(), array(), 'all' );
172 }
173
174 /**
175 * Load all the required files in the importer.
176 *
177 * @since 1.0.0
178 * @return void
179 */
180 public static function register_route(): void {
181
182 register_rest_route(
183 self::get_api_namespace(),
184 '/rating/',
185 array(
186 array(
187 'methods' => \WP_REST_Server::CREATABLE,
188 'callback' => array( self::class, 'submit_rating' ),
189 'permission_callback' => array( self::class, 'get_item_permissions_check' ),
190 'args' => array(),
191 ),
192 )
193 );
194
195 register_rest_route(
196 self::get_api_namespace(),
197 '/dismiss-nps-survey/',
198 array(
199 array(
200 'methods' => \WP_REST_Server::CREATABLE,
201 'callback' => array( self::class, 'dismiss_nps_survey_panel' ),
202 'permission_callback' => array( self::class, 'get_item_permissions_check' ),
203 'args' => array(),
204 ),
205 )
206 );
207 }
208
209 /**
210 * Get the API URL.
211 *
212 * @since 1.0.0
213 *
214 * @return string
215 */
216 public static function get_api_domain() {
217 return trailingslashit( defined( 'NPS_SURVEY_REMOTE_URL' ) ? NPS_SURVEY_REMOTE_URL : apply_filters( 'nps_survey_api_domain', 'https://metrics.brainstormforce.com/' ) );
218 }
219
220 /**
221 * Get api namespace
222 *
223 * @since 1.0.0
224 * @return string
225 */
226 public static function get_api_namespace() {
227 return 'nps-survey/v1';
228 }
229
230 /**
231 * Get API headers
232 *
233 * @since 1.0.0
234 * @return array<string, string>
235 */
236 public static function get_api_headers() {
237 return array(
238 'Content-Type' => 'application/json',
239 'Accept' => 'application/json',
240 );
241 }
242
243 /**
244 * Check whether a given request has permission to read notes.
245 *
246 * @param object $request WP_REST_Request Full details about the request.
247 * @return object|bool
248 */
249 public static function get_item_permissions_check( $request ) {
250
251 if ( ! current_user_can( 'manage_options' ) ) {
252 return new \WP_Error(
253 'gt_rest_cannot_access',
254 __( 'Sorry, you are not allowed to do that.', 'nps-survey' ),
255 array( 'status' => rest_authorization_required_code() )
256 );
257 }
258 return true;
259 }
260
261 /**
262 * Submit Ratings.
263 *
264 * @param \WP_REST_Request $request Request object.
265 * @return void
266 * @phpstan-ignore-next-line
267 */
268 public static function submit_rating( $request ) {
269
270 $nonce = $request->get_header( 'X-WP-Nonce' );
271
272 // Verify the nonce.
273 if ( ! wp_verify_nonce( sanitize_text_field( (string) $nonce ), 'wp_rest' ) ) {
274 wp_send_json_error(
275 array(
276 'data' => __( 'Nonce verification failed.', 'nps-survey' ),
277 'status' => false,
278
279 )
280 );
281 }
282
283 $current_user = wp_get_current_user();
284
285 /**
286 * Filter the post data.
287 * This can be used to modify the post data before sending it to the API.
288 *
289 * @param array<mixed> $post_data Post data.
290 * @return array<mixed>
291 */
292 $post_data = apply_filters(
293 'nps_survey_post_data',
294 array(
295 'rating' => ! empty( $request['rating'] ) ? sanitize_text_field( strval( $request['rating'] ) ) : '',
296 'comment' => ! empty( $request['comment'] ) ? sanitize_text_field( strval( $request['comment'] ) ) : '',
297 'email' => $current_user->user_email,
298 'first_name' => $current_user->first_name ?? $current_user->display_name,
299 'last_name' => $current_user->last_name ?? '',
300 'source' => ! empty( $request['plugin_slug'] ) ? sanitize_text_field( strval( $request['plugin_slug'] ) ) : '',
301 'plugin_slug' => ! empty( $request['plugin_slug'] ) ? sanitize_text_field( strval( $request['plugin_slug'] ) ) : '',
302 )
303 );
304
305 /**
306 * Filter the API endpoint.
307 *
308 * @param string $api_endpoint API endpoint.
309 * @param array<mixed> $post_data Post data.
310 *
311 * @return string
312 */
313 $api_endpoint = apply_filters(
314 'nps_survey_api_endpoint',
315 self::get_api_domain() . 'wp-json/bsf-metrics-server/v1/nps-survey/',
316 $post_data // Pass the post data to the filter, so that the endpoint can be modified based on the data.
317 );
318
319 $post_data_in_json = wp_json_encode( $post_data );
320 $request_args = array(
321 'body' => $post_data_in_json ? $post_data_in_json : '',
322 'headers' => self::get_api_headers(),
323 'timeout' => 60,
324 );
325
326 $response = wp_safe_remote_post( $api_endpoint, $request_args );
327
328 if ( is_wp_error( $response ) ) {
329 // There was an error in the request.
330 wp_send_json_error(
331 array(
332 'data' => 'Failed ' . $response->get_error_message(),
333 'status' => false,
334
335 )
336 );
337 }
338
339 $response_code = wp_remote_retrieve_response_code( $response );
340
341 if ( 200 === $response_code ) {
342
343 $nps_form_status = array(
344 'dismiss_count' => 0,
345 'dismiss_permanently' => true,
346 'dismiss_step' => '',
347 );
348
349 update_option( self::get_nps_id( strval( $request['plugin_slug'] ) ), $nps_form_status, false );
350
351 wp_send_json_success(
352 array(
353 'status' => true,
354 )
355 );
356
357 } else {
358 wp_send_json_error(
359 array(
360 'status' => false,
361
362 )
363 );
364 }
365 }
366
367 /**
368 * Dismiss NPS Survey.
369 *
370 * @param \WP_REST_Request $request Request object.
371 * @return void
372 * @phpstan-ignore-next-line
373 */
374 public static function dismiss_nps_survey_panel( $request ) {
375
376 $nonce = $request->get_header( 'X-WP-Nonce' );
377
378 // Verify the nonce.
379 if ( ! wp_verify_nonce( sanitize_text_field( (string) $nonce ), 'wp_rest' ) ) {
380 wp_send_json_error(
381 array(
382 'data' => __( 'Nonce verification failed.', 'nps-survey' ),
383 'status' => false,
384
385 )
386 );
387 }
388
389 $nps_form_status = self::get_nps_survey_dismiss_status( strval( $request['plugin_slug'] ) );
390
391 // Add dismiss timespan.
392 $nps_form_status['dismiss_timespan'] = $request['dismiss_timespan'];
393
394 // Add dismiss date.
395 $nps_form_status['dismiss_time'] = time();
396
397 // Update dismiss count.
398 $nps_form_status['dismiss_count'] += 1;
399 $nps_form_status['dismiss_step'] = $request['current_step'];
400
401 // Dismiss Permanantly.
402 if ( $nps_form_status['dismiss_count'] >= 2 ) {
403 $nps_form_status['dismiss_permanently'] = true;
404 }
405
406 update_option( self::get_nps_id( strval( $request['plugin_slug'] ) ), $nps_form_status );
407
408 wp_send_json_success(
409 array(
410 'status' => true,
411 )
412 );
413 }
414
415 /**
416 * Get dismiss status of NPS Survey.
417 *
418 * @param string $plugin_slug slug of unique NPS Survey.
419 * @return array<string, mixed>
420 */
421 public static function get_nps_survey_dismiss_status( string $plugin_slug ) {
422
423 $default_status = get_option(
424 self::get_nps_id( $plugin_slug ),
425 array(
426 'dismiss_count' => 0,
427 'dismiss_permanently' => false,
428 'dismiss_step' => '',
429 'dismiss_time' => '',
430 'dismiss_timespan' => null,
431 'first_render_time' => null,
432 )
433 );
434
435 if ( ! is_array( $default_status ) ) {
436 return array();
437 }
438
439 return array(
440 'dismiss_count' => ! empty( $default_status['dismiss_count'] ) ? $default_status['dismiss_count'] : 0,
441 'dismiss_permanently' => ! empty( $default_status['dismiss_permanently'] ) ? $default_status['dismiss_permanently'] : false,
442 'dismiss_step' => ! empty( $default_status['dismiss_step'] ) ? $default_status['dismiss_step'] : '',
443 'dismiss_time' => ! empty( $default_status['dismiss_time'] ) ? $default_status['dismiss_time'] : '',
444 'dismiss_timespan' => ! empty( $default_status['dismiss_timespan'] ) ? $default_status['dismiss_timespan'] : null,
445 'first_render_time' => ! empty( $default_status['first_render_time'] ) ? $default_status['first_render_time'] : null,
446 );
447 }
448
449 /**
450 * Show status of NPS Survey.
451 *
452 * @param string $plugin_slug slug of unique NPS Survey.
453 * @param int $display_after number of days after which NPS Survey should be displayed.
454 * @return bool
455 */
456 public static function is_show_nps_survey_form( string $plugin_slug, int $display_after ) {
457
458 $current_time = time();
459 $status = self::get_nps_survey_dismiss_status( $plugin_slug );
460
461 if ( $status['dismiss_permanently'] ) {
462 return false;
463 }
464
465 $first_render_time = $status['first_render_time'];
466
467 if ( 0 !== $display_after ) {
468 if ( null === $first_render_time ) {
469 $status['first_render_time'] = $current_time;
470 update_option( self::get_nps_id( $plugin_slug ), $status );
471 $status = self::get_nps_survey_dismiss_status( $plugin_slug );
472 return false;
473 }
474 if ( $display_after + $first_render_time > $current_time ) {
475 return false;
476 }
477 }
478
479 // Retrieve the stored date time stamp from wp_options.
480 $stored_date_timestamp = $status['dismiss_time'];
481 $dismiss_timespan = $status['dismiss_timespan'];
482
483 if ( $stored_date_timestamp ) {
484
485 $current_time = time();
486
487 // time difference of current time and the time user dismissed the nps.
488 $time_difference = $current_time - $stored_date_timestamp;
489
490 // Check if two weeks have passed.
491 if ( $time_difference <= $dismiss_timespan ) {
492 return false;
493 }
494 }
495
496 return true;
497 }
498
499 /**
500 * Get NPS Dismiss Option Name.
501 *
502 * @param string $plugin_slug Plugin name.
503 * @return string
504 */
505 public static function get_nps_id( $plugin_slug ) {
506 return 'nps-survey-' . $plugin_slug;
507 }
508 }
509
510 /**
511 * Kicking this off by calling 'get_instance()' method
512 */
513 Nps_Survey::get_instance();
514