array( 'alert_id' => 10702, 'old_value_name' => 'OldSEOTitle', 'new_value_name' => 'NewSEOTitle', ), 'rank_math_description' => array( 'alert_id' => 10703, 'old_value_name' => 'old_desc', 'new_value_name' => 'new_desc', ), 'rank_math_focus_keyword' => array( 'alert_id' => 10704, 'old_value_name' => 'old_keywords', 'new_value_name' => 'new_keywords', ), 'rank_math_pillar_content' => array( 'alert_id' => 10705, 'old_value_name' => 'old_status', 'new_value_name' => 'new_status', 'event_type' => true, ), 'rank_math_robots' => array( 'alert_id' => null, 'old_value_name' => 'old_status', 'new_value_name' => 'new_status', 'event_type' => true, 'supported_vals' => array( 'nofollow' => array( 'alert_id' => 10707, ), 'noimageindex' => array( 'alert_id' => 10708, ), 'noarchive' => array( 'alert_id' => 10709, ), 'nosnippet' => array( 'alert_id' => 10710, ), 'index' => array( 'alert_id' => 10706, ), ), ), 'rank_math_advanced_robots' => array( 'alert_id' => null, 'old_value_name' => 'old_status', 'new_value_name' => 'new_status', 'event_type' => true, 'supported_vals' => array( 'max-snippet' => array( 'alert_id' => 10711, ), 'max-video-preview' => array( 'alert_id' => 10712, ), 'max-image-preview' => array( 'alert_id' => 10713, ), ), 'extract_vals' => true, ), 'rank_math_canonical_url' => array( 'alert_id' => 10714, 'old_value_name' => 'OldCanonicalUrl', 'new_value_name' => 'NewCanonicalUrl', ), ); /** * Class cache for the type of the event. * * @var bool * * @since 5.4.0 */ private static $add_event = null; /** * Stores the old values of the metadata, so the can be present in the alert, if the update is successful. * * @var array * * @since 5.4.0 */ private static $old_vals = array(); /** * Hook events related to sensor. * * @since 5.4.0 */ public static function init() { if ( Rank_Math_Helper::is_rank_math_active() ) { \add_action( 'rank_math/module_changed', array( __CLASS__, 'module_change' ), 10, 2 ); \add_filter( 'update_post_metadata', array( __CLASS__, 'store_old_values' ), 10, 5 ); \add_filter( 'delete_post_metadata', array( __CLASS__, 'store_old_values_delete' ), 10, 5 ); \add_action( 'updated_post_meta', array( __CLASS__, 'post_meta_updated' ), 10, 4 ); \add_action( 'added_post_meta', array( __CLASS__, 'post_meta_added' ), 10, 4 ); \add_action( 'deleted_post_meta', array( __CLASS__, 'post_meta_updated' ), 10, 4 ); } } /** * Loads all the plugin dependencies early. * * @return void * * @since 5.4.0 */ public static function early_init() { \add_filter( 'wsal_event_objects', array( Rank_Math_Helper::class, 'wsal_rank_math_add_custom_event_objects' ), 10, 2 ); } /** * Triggers when module status changes * * @param string $module - The name of the module. * @param string $state - The state of the module. * * @return void * * @since 5.4.0 */ public static function module_change( $module, $state ) { Alert_Manager::trigger_event( 10701, array( 'ModuleName' => $module, 'state' => $state, 'EventType' => ( 'on' === $state ) ? 'activated' : 'deactivated', ) ); } /** * Fires immediately after updating metadata of a specific type. * * @param int $meta_id ID of updated metadata entry. * @param int $object_id ID of the object metadata is for. * @param string $meta_key Metadata key. * @param mixed $_meta_value Metadata value. Serialized if non-scalar. * * @since 5.4.0 */ public static function post_meta_updated( $meta_id, $object_id, $meta_key, $_meta_value ) { if ( ! ( isset( self::SUPPORTED_META_KEYS[ $meta_key ] ) ) ) { return; } else { self::store_event( $meta_id, $object_id, $meta_key, $_meta_value ); } } /** * Fires immediately after updating metadata of a specific type. * * @param int $meta_id ID of updated metadata entry. * @param int $object_id ID of the object metadata is for. * @param string $meta_key Metadata key. * @param mixed $_meta_value Metadata value. Serialized if non-scalar. * * @since 5.4.0 */ public static function post_meta_added( $meta_id, $object_id, $meta_key, $_meta_value ) { self::$add_event = true; self::post_meta_updated( $meta_id, $object_id, $meta_key, $_meta_value ); } /** * Stores the old value of the metadata before deleting it. * * @param null|bool $check Whether to allow deleting metadata for the given type. * @param int $object_id ID of the object metadata is for. * @param string $meta_key Metadata key. * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. * @param bool $delete_all Whether to delete the matching metadata entries * for all objects, ignoring the specified $object_id. * Default false. * * @return null|bool * * @since 5.4.0 * @since 5.6.1 - Fixed void return type: now returns $check to preserve the filter chain. */ public static function store_old_values_delete( $check, $object_id, $meta_key, $meta_value, $delete_all ) { if ( ! ( isset( self::SUPPORTED_META_KEYS[ $meta_key ] ) ) ) { return $check; } self::store_old_values( $check, $object_id, $meta_key, $meta_value, $meta_value ); return $check; } /** * Stores the old value of the metadata before updating it. * * @param null|bool $check Whether to allow updating metadata for the given type. * @param int $object_id ID of the object metadata is for. * @param string $meta_key Metadata key. * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. * @param mixed $prev_value Optional. Previous value to check before updating. * If specified, only update existing metadata entries with * this value. Otherwise, update all entries. * * @return null|bool * * @since 5.4.0 * @since 5.6.1 - Fixed void return type: now returns $check to preserve the filter chain. */ public static function store_old_values( $check, $object_id, $meta_key, $meta_value, $prev_value ) { if ( ! ( isset( self::SUPPORTED_META_KEYS[ $meta_key ] ) ) ) { return $check; } if ( empty( $prev_value ) ) { $prev_value = \get_metadata_raw( 'post', $object_id, $meta_key, false ); if ( \is_array( $prev_value ) && count( $prev_value ) === 1 ) { $prev_value = $prev_value[0]; } } self::$old_vals[ $meta_key ] = $prev_value; return $check; } /** * Fires focus_keyword metadata changes. * * @param int $meta_id ID of updated metadata entry. * @param int $object_id ID of the object metadata is for. * @param string $meta_key Metadata key. * @param mixed $_meta_value Metadata value. Serialized if non-scalar. * * @since 5.4.0 */ private static function store_event( $meta_id, $object_id, $meta_key, $_meta_value ) { if ( ! ( isset( self::SUPPORTED_META_KEYS[ $meta_key ] ) ) ) { return; } $alert_id = self::SUPPORTED_META_KEYS[ $meta_key ]['alert_id']; $post = \get_post( $object_id ); $old_value = self::$old_vals[ $meta_key ] ?? ''; $alert_vals = array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, 'PostDate' => $post->post_date, 'PostUrl' => \get_permalink( $post->ID ), 'EditorLinkPost' => \get_edit_post_link( $post->ID ), ); if ( isset( self::SUPPORTED_META_KEYS[ $meta_key ]['supported_vals'] ) && \is_array( self::SUPPORTED_META_KEYS[ $meta_key ]['supported_vals'] ) ) { foreach ( self::SUPPORTED_META_KEYS[ $meta_key ]['supported_vals'] as $key => $val ) { $alert_id = $val['alert_id']; if ( ! \is_array( $old_value ) ) { $old_value = array( $old_value ); } if ( ! \is_array( $_meta_value ) ) { $_meta_value = array( $_meta_value ); } if ( \in_array( $key, $_meta_value, true ) || isset( $_meta_value[ $key ] ) ) { // If it is associative array - extract the value. if ( isset( self::SUPPORTED_META_KEYS[ $meta_key ]['extract_vals'] ) && self::SUPPORTED_META_KEYS[ $meta_key ]['extract_vals'] && isset( $_meta_value[ $key ] ) ) { $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['new_value_name'] ] = $_meta_value[ $key ]; } else { $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['new_value_name'] ] = 'on'; } } else { $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['new_value_name'] ] = 'off'; } if ( \in_array( $key, $old_value, true ) || isset( $old_value[ $key ] ) ) { if ( isset( self::SUPPORTED_META_KEYS[ $meta_key ]['extract_vals'] ) && self::SUPPORTED_META_KEYS[ $meta_key ]['extract_vals'] && isset( $old_value[ $key ] ) ) { $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['old_value_name'] ] = $old_value[ $key ]; } else { $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['old_value_name'] ] = 'on'; } } elseif ( self::$add_event ) { $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['old_value_name'] ] = null; } else { $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['old_value_name'] ] = 'off'; } if ( $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['old_value_name'] ] !== $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['new_value_name'] ] ) { if ( isset( self::SUPPORTED_META_KEYS[ $meta_key ]['event_type'] ) && self::SUPPORTED_META_KEYS[ $meta_key ]['event_type'] ) { if ( isset( self::SUPPORTED_META_KEYS[ $meta_key ]['extract_vals'] ) && self::SUPPORTED_META_KEYS[ $meta_key ]['extract_vals'] ) { if ( isset( $old_value[ $key ] ) && isset( $_meta_value[ $key ] ) ) { $alert_vals['EventType'] = 'modified'; } else { $alert_vals['EventType'] = ( 'off' !== $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['new_value_name'] ] ) ? 'enabled' : 'disabled'; } } else { $alert_vals['EventType'] = ( Settings_Helper::string_to_bool( $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['new_value_name'] ] ) ) ? 'enabled' : 'disabled'; } } Alert_Manager::trigger_event( $alert_id, $alert_vals ); } } } else { $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['old_value_name'] ] = $old_value; $alert_vals[ self::SUPPORTED_META_KEYS[ $meta_key ]['new_value_name'] ] = $_meta_value; if ( isset( self::SUPPORTED_META_KEYS[ $meta_key ]['event_type'] ) && self::SUPPORTED_META_KEYS[ $meta_key ]['event_type'] ) { $alert_vals['EventType'] = ( Settings_Helper::string_to_bool( $_meta_value ) ) ? 'enabled' : 'disabled'; } Alert_Manager::trigger_event( $alert_id, $alert_vals ); } } } }