PluginProbe
Whols – Wholesale Prices and B2B Store Solution for WooCommerce / trunk
Whols – Wholesale Prices and B2B Store Solution for WooCommerce vtrunk
2.4.12 2.4.11 trunk 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 All 55 releases
whols / includes / Admin / Notice_Handler.php

Notice_Handler.php in Whols – Wholesale Prices and B2B Store Solution for WooCommerce trunk, at includes/Admin/Notice_Handler.php

492 lines 17.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Whols\Admin;
3
4 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
5
6 if ( ! class_exists( 'Notice_Handler' ) ){
7 class Notice_Handler{
8
9 /**
10 * [$instance]
11 * @var null
12 */
13 private static $instance = null;
14
15 /**
16 * All Notices
17 *
18 * @var array
19 */
20 private static $notices = [];
21
22 /**
23 * [instance]
24 * @return [Notice_Handler]
25 */
26 public static function instance(){
27 if( is_null( self::$instance ) ){
28 self::$instance = new self();
29 }
30 return self::$instance;
31 }
32
33 /**
34 * [__construct]
35 */
36 public function __construct(){
37 add_action( 'admin_notices', [ $this, 'show_admin_notices' ] );
38 add_action( 'admin_footer', [ $this, 'enqueue_scripts' ], 999 );
39 add_action( 'wp_ajax_whols_notices', [ $this, 'ajax_dismiss' ] );
40 }
41
42 /**
43 * Ajax Action for Notice dismiss
44 *
45 * @return void
46 */
47 public function ajax_dismiss() {
48
49 $nonce = !empty( $_POST['notice_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['notice_nonce'] ) ) : '';
50 $notice_id = isset( $_POST['noticeid'] ) ? sanitize_key( $_POST['noticeid'] ) : '';
51 $alreadydid = isset( $_POST['alreadydid'] ) ? sanitize_key( $_POST['alreadydid'] ) : '';
52 $expire_time = isset( $_POST['expiretime'] ) ? sanitize_text_field( wp_unslash( $_POST['expiretime'] ) ) : '';
53 $close_by = isset( $_POST['closeby'] ) ? sanitize_key( $_POST['closeby'] ) : '';
54 $notice = $this->get_notice_by_id( $notice_id );
55 $capability = isset( $notice['capability'] ) ? $notice['capability'] : 'manage_options';
56
57 // User Capability check
58 if ( ! apply_filters( 'whols_notice_user_cap_check', current_user_can( $capability ) ) ) {
59 $error_message = [
60 'message' => __('You are not authorized.', 'whols')
61 ];
62 wp_send_json_error( $error_message );
63 }
64
65 // Nonce verification check
66 if( !wp_verify_nonce( $nonce, 'whols_notices_nonce') ) {
67 $error_message = [
68 'message' => __('Are you cheating?', 'whols')
69 ];
70 wp_send_json_error( $error_message );
71 }
72
73 if ( ! empty( $notice_id ) && (strpos( $notice_id, 'whols-notice' ) !== false) ) {
74
75 if( !empty( $alreadydid ) ) {
76 update_option( $notice_id , true );
77 }else{
78 if ( 'user' === $close_by ) {
79 update_user_meta( get_current_user_id(), $notice_id, true );
80 } else {
81 set_transient( $notice_id, true, $expire_time );
82 }
83 }
84
85 wp_send_json_success();
86 }
87
88 wp_send_json_error();
89 }
90
91 /**
92 * Script
93 *
94 * @return void
95 */
96 public function enqueue_scripts() {
97
98 $styles = ".whols-admin-notice {
99 width: 100%;
100 box-sizing: border-box;
101 }
102
103 .whols-admin-notice.promo-banner {
104 position: relative;
105 padding: 12px !important;
106 border: 1px solid #c3c4c7;
107 }
108 .whols-admin-notice.promo-banner a {
109 display: flex;
110 }
111 .whols-admin-notice.promo-banner img {
112 width: 100%;
113 }
114 .whols-admin-notice.promo-banner *:empty:not(img) {
115 display: none;
116 }
117 .whols-admin-notice.promo-banner .notice-dismiss {
118 top: -10px;
119 right: -10px;
120 background-color: white;
121 padding: 2px;
122 border-radius: 50px;
123 border: 1px solid #ddd;
124 }
125
126 .toplevel_page_whols-admin #whols-notice-id-halloween-notice {
127 padding-right: 0;
128 display: block;
129 margin: 20px;
130 }
131 .whols-admin-notice.notice img, .whols-review-notice-wrap img{
132 width: 100%;
133 }
134
135 #whols-notice-id-halloween-notice {
136 padding: 12px;
137 border-left-width: 1px;
138 }
139 #whols-notice-id-halloween-notice .notice-dismiss {
140 top: -10px;
141 right: -10px;
142 background-color: white;
143 padding: 2px;
144 border-radius: 50px;
145 border: 1px solid #ddd;
146 }
147 .whols-review-notice-wrap{
148 border-left-color: #2271b1 !important;
149 display: flex;
150 justify-content: left;
151 align-items: center;
152 padding: 10px 0;
153 }
154 .whols-review-notice-content {
155 margin-left: 15px;
156 }
157 .whols-review-notice-action {
158 display: flex;
159 align-items: center;
160 padding-top: 10px;
161 }
162 .whols-review-notice-action span.dashicons {
163 font-size: 1.4em;
164 padding-left: 10px;
165 }
166 .whols-review-notice-action a {
167 padding-left: 5px;
168 text-decoration: none;
169 }
170 .whols-review-notice-content h3 {
171 margin: 0;
172 }";
173
174 $scripts = "jQuery(document).ready( function($) {
175 $( '.whols-admin-notice.is-dismissible' ).on( 'click', '.notice-dismiss,.whols-notice-close', function(e) {
176 e.preventDefault();
177 let noticeWrap = $( this ).parents( '.whols-admin-notice' ),
178 noticeId = noticeWrap.attr( 'id' ) || '',
179 expireTime = noticeWrap.attr( 'expire-time' ) || '',
180 closeBy = noticeWrap.attr( 'close-by' ) || '',
181 alreadyDid = $( this ).attr('data-already-did') || '',
182 noticeNonce = '".esc_html( wp_create_nonce( 'whols_notices_nonce' ) )."';
183
184 noticeWrap.css('opacity','0.5');
185
186 $.ajax({
187 url: ajaxurl,
188 type: 'POST',
189 data: {
190 action : 'whols_notices',
191 noticeid: noticeId,
192 closeby : closeBy,
193 expiretime : expireTime,
194 alreadydid : alreadyDid,
195 notice_nonce: noticeNonce
196 },
197 success: function( response ) {
198 noticeWrap.css('display','none');
199 },
200 complete: function( response ){
201 noticeWrap.css('display','none');
202 }
203 });
204
205 });
206 });";
207
208 printf( '<style>%s</style>', $styles ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
209 printf( '<script>%s</script>', $scripts ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
210 }
211
212 /**
213 * Set Notices
214 *
215 * @param array $args
216 * @return void
217 */
218 public static function set_notice( $args = [] ) {
219 self::$notices[] = $args;
220 }
221
222 /**
223 * Sort Notices
224 *
225 * @param [type] $notice_a
226 * @param [type] $notice_b
227 */
228 public function sort_notices($notice_a, $notice_b){
229 if ( ! isset( $notice_a['priority'] ) ) {
230 $notice_a['priority'] = 1;
231 }
232 if ( ! isset( $notice_b['priority'] ) ) {
233 $notice_b['priority'] = 1;
234 }
235
236 if ( $notice_a['priority'] == $notice_b['priority'] ) {
237 return 0;
238 }
239 return ( $notice_a['priority'] < $notice_b['priority'] ) ? -1 : 1;
240 }
241
242 /**
243 * Get all notices
244 */
245 private function get_notices() {
246 usort( self::$notices, [ $this, 'sort_notices' ] );
247 return self::$notices;
248 }
249
250 /**
251 * Get Notices By id
252 * @param [type] $notice_id
253 */
254 private function get_notice_by_id( $notice_id ) {
255 if ( empty( $notice_id ) ) {
256 return [];
257 }
258
259 $notices = $this->get_notices();
260 $notice = wp_list_filter( $notices, [ 'id' => $notice_id ] );
261
262 return ! empty( $notice ) ? $notice[0] : [];
263 }
264
265 /**
266 * Notice Prepare For Display
267 *
268 * @param [type] $notice_data
269 */
270 private function prepare_notice( $notice_data ){
271 $defaults = [
272 'id' => '',
273 'type' => 'info', // Notice type. Default 'info' Expected [info, warning, notice, error]
274 'dismissible' => false,
275 'close_by' => 'user', // Default 'user' Expected [user, transient]
276 'expire_time' => WEEK_IN_SECONDS,
277 'display_after' => false,
278 'is_show' => true,
279 'data' => '',
280 'message' => '',
281 'message_type' => 'text', // Message Type. Default 'text' Expected [html, text]
282 'button' => [],
283 'banner' => [],
284 'priority' => 1,
285 'dismissible_btn'=> '',
286 'capability' => 'manage_options'
287 ];
288 $notice = wp_parse_args( $notice_data, $defaults );
289
290 $classes = [ 'whols-admin-notice' ];
291
292 if ( isset( $notice['type'] ) ) {
293 $classes[] = 'notice-' . $notice['type'];
294 if( $notice['type'] !== 'custom'){
295 $classes[] = 'notice';
296 }else{
297 $notice['dismissible_btn'] = '<button type="button" class="notice-dismiss"><span class="screen-reader-text">'.esc_html__('Dismiss this notice.','whols').'</span></button>';
298 }
299 }
300
301 if( !empty( $notice['banner'] ) ){
302 $classes[] = 'promo-banner';
303 }
304
305 // If notice is dismissible then add "is-dismissible" class.
306 if ( true === $notice['dismissible'] ) {
307 $classes[] = 'is-dismissible';
308 $notice['data'] = ' expire-time=' . esc_attr( $notice['expire_time'] ) . ' ';
309 }
310
311 $notice['id'] = 'whols-notice-id-' . $notice['id'];
312 $notice['classes'] = implode( ' ', $classes );
313 $notice['data'] .= ' close-by=' . esc_attr( $notice['close_by'] ) . ' ';
314
315 // Hide Screen
316 $current_screen = get_current_screen();
317
318 $hide_screen = ['plugins','plugin-install','update','update-core','shoplentor_page_whols_templates'];
319
320 // Check If do not Pass is_show from Notice Argument
321 if( in_array( $current_screen->id, $hide_screen) ){
322 $notice['is_show'] = array_key_exists( 'is_show', $notice_data ) ? $notice_data['is_show'] : false;
323 }
324
325 return $notice;
326
327 }
328
329 /**
330 * Show Admin Notices
331 *
332 * @return void
333 */
334 public function show_admin_notices(){
335 global $current_screen;
336
337 if( $current_screen->id === 'update' ){
338 return;
339 }
340
341 $notices_displayed_count = 0;
342 $notices = $this->get_notices();
343
344 foreach ( $notices as $notice ) {
345
346 // Only Show one notice at a time.
347 if ( $notices_displayed_count > 0 ) {
348 break;
349 }
350
351 $notice = self::instance()->prepare_notice( $notice );
352
353 if ( isset( $notice['is_show'] ) && current_user_can( $notice['capability'] ) ) {
354 if ( true === $notice['is_show'] ) {
355 if ( self::is_expired( $notice ) ) {
356 self::html( $notice );
357 ++$notices_displayed_count;
358 }
359 }
360 }
361
362 }
363
364 }
365
366 /**
367 * Add Notices
368 *
369 * @param [type] $notice
370 * @return void
371 */
372 public static function add_notice( $notice_data ) {
373
374 $notice = self::instance()->prepare_notice( $notice_data );
375
376 // Check Notice visible condition.
377 if ( isset( $notice['is_show'] ) && current_user_can( $notice['capability'] ) ) {
378 if ( true === $notice['is_show'] ) {
379 if ( self::is_expired( $notice ) ) {
380 self::html( $notice );
381 }
382 }
383 }
384
385 }
386
387 /**
388 * Gerenare Notice HTML
389 *
390 * @param array $notice_arg
391 * @return void
392 */
393 public static function html( $notice_arg = [] ){
394 ?>
395 <div id="<?php echo esc_attr( $notice_arg['id'] ); ?>" class="<?php echo esc_attr( $notice_arg['classes'] ); ?>" <?php self::render_attribute($notice_arg['data']); ?>>
396 <?php
397 // Notice Image
398 if( !empty( $notice_arg['banner'] ) ){
399 printf( '<a href="%1$s" target="_blank">%2$s</a>', esc_url( $notice_arg['banner']['url'] ), $notice_arg['banner']['image'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
400 }
401
402 // Notice Message
403 if( $notice_arg['message_type'] === 'text'){
404 printf('<p>%1$s</p>', $notice_arg['message'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
405 }else{
406 echo wp_kses_post( $notice_arg['message'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
407 }
408
409 // If notice type custom and dismissible true
410 if ( true === $notice_arg['dismissible'] ) {
411 printf('%1$s', $notice_arg['dismissible_btn'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
412 }
413
414 // Notice Action Button
415 if( !empty( $notice_arg['button'] ) ){
416 printf('<p><a href="%1$s" class="button-primary">%2$s</a></p>', esc_url( $notice_arg['button']['url'] ), esc_html( $notice_arg['button']['text'] ) );
417 }
418 ?>
419 </div>
420 <?php
421 }
422
423 /**
424 * Data Attribute Render
425 *
426 * @param [type] $data
427 * @return void
428 */
429 public static function render_attribute( $data ){
430 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
431 echo $data;
432 }
433
434 /**
435 * Check Notice Show Expirity
436 *
437 * @param [type] $notice
438 */
439 private static function is_expired( $notice ) {
440 if( isset( $notice['display_after'] ) && false !== $notice['display_after'] ){
441
442 // Check if already did : rated / something else
443 if ( get_option( $notice['id'], false ) ) {
444 return false;
445 }
446
447 $transient = get_transient( $notice['id'] );
448
449 if( false === $transient ){
450
451 $expired = get_user_meta( get_current_user_id(), $notice['id'], true );
452
453 if ( 'notice_delayed' !== $expired && true !== $expired ) {
454 set_transient( $notice['id'], 'notice_delayed', $notice['display_after'] );
455 update_user_meta( get_current_user_id(), $notice['id'], 'notice_delayed' );
456
457 return false;
458 }
459
460 // Verify the user meta status to determine if the current user notice has been dismissed or if the delay has been completed.
461 $user_meta = get_user_meta( get_current_user_id(), $notice['id'], true );
462
463 if ( empty( $user_meta ) || 'notice_delayed' === $user_meta ) {
464 return true;
465 }
466
467 }
468
469 return false;
470
471 }else{
472 if ( 'user' === $notice['close_by'] ) {
473 $expired = get_user_meta( get_current_user_id(), $notice['id'], true );
474 } elseif ( 'transient' === $notice['close_by'] ) {
475 $expired = get_transient( $notice['id'] );
476 }
477
478 if ( false === $expired || empty( $expired ) ) {
479 return true;
480 }else{
481 return false;
482 }
483 }
484
485 }
486
487 }
488
489 // Call instance
490 Notice_Handler::instance();
491
492 }