Dismiss.php
165 lines
| 1 | <?php |
| 2 | |
| 3 | namespace PriyoMukul\WPNotice; |
| 4 | |
| 5 | use PriyoMukul\WPNotice\Utils\Base; |
| 6 | use PriyoMukul\WPNotice\Utils\Helper; |
| 7 | |
| 8 | #[\AllowDynamicProperties] |
| 9 | class Dismiss extends Base { |
| 10 | use Helper; |
| 11 | |
| 12 | private $id; |
| 13 | private $scope = 'user'; |
| 14 | |
| 15 | /** |
| 16 | * @var Notices |
| 17 | */ |
| 18 | private $app; |
| 19 | private $hook; |
| 20 | |
| 21 | public function __construct( $id, $options, $app ) { |
| 22 | $this->id = $id; |
| 23 | $this->app = $app; |
| 24 | |
| 25 | if ( ! empty( $options ) ) { |
| 26 | foreach ( $options as $key => $_value ) { |
| 27 | $this->{$key} = $_value; |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | $this->hook = $this->app->app . '_wpnotice_dismiss_notice'; |
| 32 | |
| 33 | add_action( 'wp_ajax_' . $this->hook, [ $this, 'ajax_maybe_dismiss_notice' ] ); |
| 34 | } |
| 35 | |
| 36 | /** |
| 37 | * Print the script for dismissing the notice. |
| 38 | * |
| 39 | * @access public |
| 40 | * @return void |
| 41 | * @since 1.0 |
| 42 | */ |
| 43 | public function print_script() { |
| 44 | $nonce = wp_create_nonce( 'wpnotice_dismiss_notice_' . $this->id ); |
| 45 | $_id = '#wpnotice-' . esc_attr( $this->app->app ) . '-' . esc_attr( $this->id ); |
| 46 | ?> |
| 47 | <script> |
| 48 | window.addEventListener('load', function () { |
| 49 | var dismissBtn = document.querySelector('<?php echo $_id ?> .notice-dismiss'); |
| 50 | var extraDismissBtn = document.querySelectorAll('<?php echo $_id ?> .dismiss-btn'); |
| 51 | |
| 52 | function wpNoticeDismissFunc(event) { |
| 53 | event.preventDefault(); |
| 54 | |
| 55 | var httpRequest = new XMLHttpRequest(), |
| 56 | postData = '', |
| 57 | dismiss = event.target.dataset?.hasOwnProperty('dismiss') && event.target.dataset.dismiss || false, |
| 58 | later = event.target.dataset?.hasOwnProperty('later') && event.target.dataset.later || false; |
| 59 | |
| 60 | if (dismiss || later) { |
| 61 | jQuery(event.target.offsetParent).slideUp(200); |
| 62 | } |
| 63 | |
| 64 | // Data has to be formatted as a string here. |
| 65 | postData += 'id=<?php echo esc_attr( rawurlencode( $this->id ) ); ?>'; |
| 66 | postData += '&action=<?php echo esc_attr( $this->hook ); ?>'; |
| 67 | if (dismiss) { |
| 68 | postData += '&dismiss=' + dismiss; |
| 69 | } |
| 70 | if (later) { |
| 71 | postData += '&later=' + later; |
| 72 | } |
| 73 | |
| 74 | postData += '&nonce=<?php echo esc_html( $nonce ); ?>'; |
| 75 | |
| 76 | httpRequest.open('POST', '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>'); |
| 77 | httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); |
| 78 | httpRequest.send(postData); |
| 79 | } |
| 80 | |
| 81 | // Add an event listener to the dismiss button. |
| 82 | dismissBtn && dismissBtn.addEventListener('click', wpNoticeDismissFunc); |
| 83 | if (extraDismissBtn.length > 0) { |
| 84 | extraDismissBtn.forEach(btn => btn.addEventListener('click', wpNoticeDismissFunc)) |
| 85 | } |
| 86 | }); |
| 87 | </script> |
| 88 | <?php |
| 89 | } |
| 90 | |
| 91 | |
| 92 | /** |
| 93 | * Run check to see if we need to dismiss the notice. |
| 94 | * If all tests are successful then call the dismiss_notice() method. |
| 95 | * |
| 96 | * @access public |
| 97 | * @return void |
| 98 | * @since 1.0 |
| 99 | */ |
| 100 | public function ajax_maybe_dismiss_notice() { |
| 101 | // Sanity check: Early exit if we're not on a _dismiss_notice action. |
| 102 | if ( ! isset( $_POST['action'] ) || $this->hook !== $_POST['action'] ) { |
| 103 | return; |
| 104 | } |
| 105 | |
| 106 | // Sanity check: Early exit if the ID of the notice is not the one from this object. |
| 107 | if ( ! isset( $_POST['id'] ) || $this->id !== $_POST['id'] ) { |
| 108 | return; |
| 109 | } |
| 110 | |
| 111 | // Security check: Make sure nonce is OK. |
| 112 | check_ajax_referer( 'wpnotice_dismiss_notice_' . $this->id, 'nonce', true ); |
| 113 | |
| 114 | if ( isset( $_POST['later'] ) ) { |
| 115 | $_recurrence = intval( $this->recurrence ) || 15; |
| 116 | $_queue = $this->app->storage()->get(); |
| 117 | |
| 118 | $_queue[ $this->id ]['start'] = $this->strtotime( "+$_recurrence days" ); |
| 119 | $_queue[ $this->id ]['expire'] = $this->strtotime( "+" . ( $_recurrence + 3 ) . " days" ); |
| 120 | $this->app->storage()->save( $_queue ); |
| 121 | |
| 122 | return; |
| 123 | } |
| 124 | |
| 125 | // If we got this far, we need to dismiss the notice. |
| 126 | $this->dismiss_notice(); |
| 127 | } |
| 128 | |
| 129 | /** |
| 130 | * Actually dismisses the notice. |
| 131 | * |
| 132 | * @access private |
| 133 | * @return bool |
| 134 | * @since 1.0 |
| 135 | */ |
| 136 | public function dismiss_notice() { |
| 137 | if ( ! defined( 'WPNOTICE_EXPIRED_TIME' ) ) { |
| 138 | define( 'WPNOTICE_EXPIRED_TIME', HOUR_IN_SECONDS * 10 ); |
| 139 | } |
| 140 | |
| 141 | set_transient( 'wpnotice_priority_time_expired', true, time() + WPNOTICE_EXPIRED_TIME ); |
| 142 | |
| 143 | if ( 'user' === $this->scope ) { |
| 144 | return $this->app->storage()->save_meta( $this->id ); |
| 145 | } |
| 146 | |
| 147 | $_key = $this->app->app . '_' . $this->id . '_notice_dismissed'; |
| 148 | |
| 149 | return $this->app->storage()->save( $_key ); |
| 150 | } |
| 151 | |
| 152 | /** |
| 153 | * Check if is dismissed or not |
| 154 | * @return boolean |
| 155 | */ |
| 156 | public function is_dismissed() { |
| 157 | if ( 'user' === $this->scope ) { |
| 158 | return $this->app->storage()->get_meta( $this->id ); |
| 159 | } |
| 160 | |
| 161 | $_key = $this->app->app . '_' . $this->id . '_notice_dismissed'; |
| 162 | |
| 163 | return $this->app->storage()->get( $_key ); |
| 164 | } |
| 165 | } |