doing_ajax() ) { return; } // Hook the actual rendering of notices add_action( 'current_screen', array( $this, 'hook' ), 20 ); // Add our notice dismissal script tribe_asset( Tribe__Main::instance(), 'tribe-notice-dismiss', 'notice-dismiss.js', array( 'jquery' ), 'admin_enqueue_scripts' ); } /** * This will happen on the `current_screen` and will hook to the correct actions and display the notices * * @return void */ public function hook() { foreach ( $this->notices as $notice ) { if ( $notice->dismiss && $this->has_user_dimissed( $notice->slug ) ) { continue; } if ( !empty( $notice->active_callback ) && is_callable( $notice->active_callback ) && false == call_user_func( $notice->active_callback ) ) { continue; } add_action( $notice->action, $notice->callback, $notice->priority ); } } /** * This will allow the user to Dimiss the Notice using JS. * * We will dismiss the notice without checking to see if the slug was already * registered (via a call to exists()) for the reason that, during a dismiss * ajax request, some valid notices may not have been registered yet. * * @return void */ public function maybe_dismiss() { if ( empty( $_GET[ self::$meta_key ] ) ) { wp_send_json( false ); } $slug = sanitize_title_with_dashes( $_GET[ self::$meta_key ] ); // Send a JSON answer with the status of dimissal wp_send_json( $this->dismiss( $slug ) ); } /** * Allows a Magic to remove the Requirement of creating a callback * * @param string $name Name of the Method used to create the Slug of the Notice * @param array $arguments Which arguments were used, normally empty * * @return string */ public function __call( $name, $arguments ) { // Transform from Method name to Notice number $slug = preg_replace( '/render_/', '', $name, 1 ); if ( ! $this->exists( $slug ) ) { return false; } $notice = $this->get( $slug ); if ( empty( $notice->active_callback ) || ( is_callable( $notice->active_callback ) && true == call_user_func( $notice->active_callback ) ) ) { // Return the rendered HTML return $this->render( $slug, $notice->content ); } return false; } /** * This is a helper to actually print the Message * * @param string $slug The Name of the Notice * @param string $content The content of the notice * @param boolean $return Echo or return the content * @param string|bool $wrap An optional HTML tag to wrap the content. * * @return bool|string */ public function render( $slug, $content = null, $return = false, $wrap = false ) { $notice = $this->get( $slug ); $classes = array( 'tribe-dismiss-notice', 'notice' ); $classes[] = sanitize_html_class( 'notice-' . $notice->type ); $classes[] = sanitize_html_class( 'tribe-notice-' . $notice->slug ); if ( $notice->dismiss ) { $classes[] = 'is-dismissible'; } if ( is_string( $wrap ) ) { $content = sprintf( '<%1$s>' . $content . '', $wrap ); } $html = sprintf( '
%s
', implode( ' ', $classes ), $notice->slug, $content ); if ( ! $return ) { echo $html; } return $html; } /** * This is a helper to print the message surrounded by `p` tags. * * @param string $slug The Name of the Notice * @param string $content The content of the notice * @param boolean $return Echo or return the content * * @return boolean|string */ public function render_paragraph( $slug, $content = null, $return = false ) { return $this->render( $slug, $content, $return, 'p' ); } /** * Checks if a given user has dimissed a given notice. * * @param string $slug The Name of the Notice * @param int|null $user_id The user ID * * @return boolean */ public function has_user_dimissed( $slug, $user_id = null ) { if ( is_null( $user_id ) ) { $user_id = get_current_user_id(); } $dismissed_notices = get_user_meta( $user_id, self::$meta_key ); if ( ! is_array( $dismissed_notices ) ) { return false; } if ( ! in_array( $slug, $dismissed_notices ) ) { return false; } return true; } /** * A Method to actually add the Meta value telling that this notice has been dismissed * * @param string $slug The Name of the Notice * @param int|null $user_id The user ID * * @return boolean */ public function dismiss( $slug, $user_id = null ) { if ( is_null( $user_id ) ) { $user_id = get_current_user_id(); } // If this user has dimissed we don't care either if ( $this->has_user_dimissed( $slug, $user_id ) ) { return true; } return add_user_meta( $user_id, self::$meta_key, $slug, false ); } /** * Removes the User meta holding if a notice was dimissed * * @param string $slug The Name of the Notice * @param int|null $user_id The user ID * * @return boolean */ public function undismiss( $slug, $user_id = null ) { if ( is_null( $user_id ) ) { $user_id = get_current_user_id(); } // If this user has dimissed we don't care either if ( ! $this->has_user_dimissed( $slug, $user_id ) ) { return false; } return delete_user_meta( $user_id, self::$meta_key, $slug ); } /** * Undismisses the specified notice for all users. * * @param string $slug * * @return int */ public function undismiss_for_all( $slug ) { $user_query = new WP_User_Query( array( 'meta_key' => self::$meta_key, 'meta_value' => $slug, ) ); $affected = 0; foreach ( $user_query->get_results() as $user ) { if ( $this->undismiss( $slug, $user->ID ) ) { $affected++; } } return $affected; } /** * Register a Notice and attach a callback to the required action to display it correctly * * @param string $slug Slug to save the notice * @param callable|string $callback A callable Method/Fuction to actually display the notice * @param array $arguments Arguments to Setup a notice * @param callable|null $active_callback An optional callback that should return bool values * to indicate whether the notice should display or not. * * @return stdClass */ public function register( $slug, $callback, $arguments = array(), $active_callback = null ) { // Prevent weird stuff here $slug = sanitize_title_with_dashes( $slug ); $defaults = array( 'callback' => null, 'content' => null, 'action' => 'admin_notices', 'priority' => 10, 'expire' => false, 'dismiss' => false, 'type' => 'error', ); if ( is_callable( $callback ) ) { $defaults['callback'] = $callback; } else { $defaults['callback'] = array( $this, 'render_' . $slug ); $defaults['content'] = $callback; } if ( is_callable( $active_callback ) ) { $defaults['active_callback'] = $active_callback; } // Merge Arguments $notice = (object) wp_parse_args( $arguments, $defaults ); // Enforce this one $notice->slug = $slug; // Clean these $notice->priority = absint( $notice->priority ); $notice->expire = (bool) $notice->expire; $notice->dismiss = (bool) $notice->dismiss; // Set the Notice on the array of notices $this->notices[ $slug ] = $notice; // Return the notice Object because it might be modified return $notice; } public function remove( $slug ) { if ( ! $this->exists( $slug ) ) { return false; } unset( $this->notices[ $slug ] ); return true; } public function get( $slug = null ) { // Prevent weird stuff here $slug = sanitize_title_with_dashes( $slug ); if ( is_null( $slug ) ) { return $this->notices; } if ( ! empty( $this->notices[ $slug ] ) ) { return $this->notices[ $slug ]; } return null; } public function exists( $slug ) { return is_object( $this->get( $slug ) ) ? true : false; } }