core->assets->load( 'src/vue/standalone/wp-notices/main.js' ); } /** * Registers an API field with notices. * * @since 4.2.3 * * @return void */ public function registerApiField() { foreach ( aioseo()->helpers->getPublicPostTypes( true ) as $postType ) { register_rest_field( $postType, 'aioseo_notices', [ 'get_callback' => [ $this, 'apiGetNotices' ] ] ); } } /** * API field callback. * * @since 4.2.3 * * @return array Notices array */ public function apiGetNotices() { $notices = $this->getNoticesInContext(); // Notices show only one time. $this->removeNotices( $notices ); return $notices; } /** * Get all notices. * * @since 4.2.3 * * @return array Notices array */ public function getNotices() { if ( empty( $this->notices ) ) { $this->notices = (array) aioseo()->core->cache->get( $this->cacheKey ); } return ! empty( $this->notices ) ? $this->notices : []; } /** * Get all notices in the current context. * * @since 4.2.6 * * @return array Notices array */ public function getNoticesInContext() { $contextNotices = $this->getNotices(); foreach ( $contextNotices as $key => $notice ) { if ( empty( $notice['allowedContexts'] ) ) { continue; } $allowed = false; foreach ( $notice['allowedContexts'] as $allowedContext ) { if ( $this->isAllowedContext( $allowedContext ) ) { $allowed = true; break; } } if ( ! $allowed ) { unset( $contextNotices[ $key ] ); } } return $contextNotices; } /** * Test if we are in the current context. * * @since 4.2.6 * * @param string $context The context to test. (posts) * @return bool Is the required context. */ private function isAllowedContext( $context ) { switch ( $context ) { case 'posts': return aioseo()->helpers->isScreenPostList() || aioseo()->helpers->isScreenPostEdit() || aioseo()->helpers->isAjaxCronRestRequest(); } return false; } /** * Finds a notice by message. * * @since 4.2.3 * * @param string $message The message string. * @param string $type The message type. * @return void|array The found notice. */ public function getNotice( $message, $type = '' ) { $notices = $this->getNotices(); foreach ( $notices as $notice ) { if ( $notice['options']['id'] === $this->getNoticeId( $message, $type ) ) { return $notice; } } } /** * Generates a notice id. * * @since 4.2.3 * * @param string $message The message string. * @param string $type The message type. * @return string The notice id. */ public function getNoticeId( $message, $type = '' ) { return md5( $message . $type ); } /** * Clear notices. * * @since 4.2.3 * * @return void */ public function clearNotices() { $this->notices = []; $this->updateCache(); } /** * Remove certain notices. * * @since 4.2.6 * * @param array $notices A list of notices to remove. * @return void */ public function removeNotices( $notices ) { foreach ( array_keys( $notices ) as $noticeKey ) { unset( $this->notices[ $noticeKey ] ); } $this->updateCache(); } /** * Adds a notice. * * @since 4.2.3 * * @param string $message The message. * @param string $status The message status [success, info, warning, error] * @param array $options Options for the message. https://developer.wordpress.org/block-editor/reference-guides/data/data-core-notices/#createnotice * @param array $allowedContexts The contexts where this notice will show. * @return void */ public function addNotice( $message, $status = 'warning', $options = [], $allowedContexts = [] ) { $type = ! empty( $options['type'] ) ? $options['type'] : ''; $foundNotice = $this->getNotice( $message, $type ); if ( empty( $message ) || ! empty( $foundNotice ) ) { return; } $notice = [ 'message' => $message, 'status' => $status, 'options' => wp_parse_args( $options, [ 'id' => $this->getNoticeId( $message, $type ), 'isDismissible' => true ] ), 'allowedContexts' => $allowedContexts ]; $this->notices[] = $notice; $this->updateCache(); } /** * Show notices on classic editor. * * @since 4.2.3 * * @return void */ public function adminNotices() { // Double check we're actually in the admin before outputting anything. if ( ! is_admin() ) { return; } $notices = $this->getNoticesInContext(); $notices = array_filter( $notices, function( $notice ) { return is_array( $notice ); } ); foreach ( $notices as $notice ) { // Hide snackbar notices on classic editor. if ( ! empty( $notice['options']['type'] ) && 'snackbar' === $notice['options']['type'] ) { continue; } $status = ! empty( $notice['status'] ) ? $notice['status'] : 'warning'; $class = ! empty( $notice['options']['class'] ) ? $notice['options']['class'] : ''; ?>