get_action_keys() as $key ) { $key_underscore = self::_key( $key ); add_action( 'wp_ajax_' . $this->action_string( $key ), array( $this, 'action_' . $key_underscore ) ); } } /** * Get necessary action keys, which will be used to create wp_ajax hooks. * * @return array */ private function get_action_keys() { return array( 'notification-visibility', ); } /** * Creates an array of all of the necessary actions. * * @return array */ private function get_ajax_actions() { $actions = array(); foreach ( $this->get_action_keys() as $key ) { $actions[ self::_key( $key ) ] = array( 'action' => $this->action_string( $key ), 'security' => wp_create_nonce( $this->nonce_string( $key ) ), ); } return $actions; } /** * Enqueue scripts */ public function enqueue() { if ( $this->is_screen( array( 'toplevel_page_ad-commander' ) ) ) { wp_enqueue_script( 'jquery' ); $handle = Util::ns( 'notifications' ); wp_register_script( $handle, AdCommander::assets_url() . 'js/notifications.js', array( 'jquery', ), AdCommander::version(), array( 'in_footer' => true ) ); wp_enqueue_script( $handle ); Util::enqueue_script_data( $handle, array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'actions' => $this->get_ajax_actions(), ) ); } } /** * Toggle visibility. */ public function action_notification_visibility() { $action = 'notification-visibility'; check_ajax_referer( $this->nonce_string( $action ), 'security' ); if ( ! current_user_can( AdCommander::capability() ) ) { wp_die(); } $hidden = Options::instance()->get( 'notifications_hidden', null, array() ); $notification_key = isset( $_REQUEST['notification_key'] ) ? sanitize_key( $_REQUEST['notification_key'] ) : false; if ( ! $notification_key ) { wp_die(); } if ( in_array( $notification_key, $hidden ) ) { $hide = false; $hidden = array_filter( $hidden, fn( $value ) => $value !== $notification_key ); } else { $hide = true; $hidden[] = $notification_key; } Options::instance()->update( 'notifications_hidden', $hidden, true ); $this->hidden_notifications = $hidden; wp_send_json_success( array( 'action' => $action, 'hide' => ( $hide ) ? 1 : 0, ) ); wp_die(); } public function run_tests() { $this->notifications = array(); $this->hidden_notifications = Options::instance()->get( 'notifications_hidden', null, array() ); $tests = array( 'caching', 'consent', 'custom_css_failure', 'bots', 'adsense_alerts', 'lazy' ); foreach ( $tests as $test ) { try { $func = 'test_' . $test; if ( method_exists( $this, $func ) ) { $result = $this->$func(); if ( ! $result ) { continue; } if ( ! is_array( $result ) ) { $this->notifications[ $test ] = $result; } else { foreach ( $result as $r ) { if ( ! is_array( $r ) ) { $this->notifications[ $test ] = $result; break; } else { $this->notifications[ $test . '_' . $r['id'] ] = array( 'title' => $r['title'], 'text' => $r['text'], ); } } } } } catch ( \Exception $e ) { continue; } } /** * Remove any unneccessary (old) hidden notification keys. */ $filtered_hidden = array_filter( $this->hidden_notifications, fn( $value ) => in_array( $value, array_keys( $this->notifications ) ) ); if ( $filtered_hidden !== $this->hidden_notifications ) { $this->hidden_notifications = $filtered_hidden; Options::instance()->update( 'notifications_hidden', $this->hidden_notifications, true ); } } /** * Count active notifications. * * @return int */ public function count() { $this->run_tests(); if ( ! $this->notifications || count( $this->notifications ) <= 0 ) { return 0; } return count( array_filter( $this->notifications, fn ( $notification ) => ! in_array( $notification, $this->hidden_notifications ), ARRAY_FILTER_USE_KEY ) ); } /** * Build list of notifications. */ public function build() { $this->run_tests(); /** * Move ignored notifications to the end. */ uksort( $this->notifications, function ( $a, $b ) { return in_array( $a, $this->hidden_notifications ) <=> in_array( $b, $this->hidden_notifications ); } ); } /** * Display notifications. * * @return string The notification content. */ public function display() { $this->build(); if ( empty( $this->notifications ) ) { return esc_html__( 'Everything looks good! You do not have any notifications at this time.', 'ad-commander' ); } $visible_content = ''; $hidden_content = ''; foreach ( $this->notifications as $key => $text ) { $notification = $this->notification( ( isset( $text['text'] ) ) ? $text['text'] : $text, $key, ( isset( $text['title'] ) ) ? $text['title'] : '', ( isset( $text['button'] ) ) ? $text['button'] : '' ); if ( in_array( $key, $this->hidden_notifications ) ) { $hidden_content .= $notification; } else { $visible_content .= $notification; } } if ( $hidden_content ) { /* translators: %d: The number of hidden notifications */ $button_text = sprintf( esc_html__( 'Hidden notifications (%d)', 'ad-commander' ), count( $this->hidden_notifications ) ); $hidden_content = '
' . sprintf( esc_html__( 'If you feel any of these notifications were received in error, please ignore or %1$scontact support%2$s.', 'ad-commander' ), '', '' ) . '
'; return $content; } /** * Create an individual notification. * * @param string $text The text to display inside a notification. * @param string $key The key of the notification. * @param string $title The notification title text. * @param string $button The button text. * * @return string */ private function notification( $text, $key, $title = '', $button = '' ) { $classes = 'adcmdr-notification adcmdr-notice-error'; $icon = 'visibility'; if ( in_array( $key, $this->hidden_notifications ) ) { $classes .= ' adcmdr-ignored'; $icon = 'hidden'; } if ( $title ) { $title = '' . esc_html( $title ) . '