Files

374 lines
12 KiB
PHP

<?php
/**
* Custom Sensors for Rank Math
* Class file for alert manager.
*
* @since 5.4.0
*
* @package Wsal
*/
declare(strict_types=1);
namespace WSAL\WP_Sensors;
use WSAL\Controllers\Alert_Manager;
use WSAL\Helpers\Settings_Helper;
use WSAL\WP_Sensors\Helpers\Rank_Math_Helper;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( '\WSAL\Plugin_Sensors\Rank_Math_Sensor' ) ) {
/**
* Custom sensor for Rank Math plugin.
*
* @since 5.4.0
*/
class Rank_Math_Sensor {
public const SUPPORTED_META_KEYS = array(
'rank_math_title' => 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
);
}
}
}
}