diff --git a/includes/Dispatcher.php b/includes/Dispatcher.php index 65b70b9..87620af 100644 --- a/includes/Dispatcher.php +++ b/includes/Dispatcher.php @@ -7,6 +7,7 @@ use Texty\Models\SmsStat; use WeDevs\WPKit\DataLayer\DataLayerFactory; use Texty\Gateways\GatewayInterface; +use WP_Comment; /** * Dispatcher Class @@ -76,6 +77,14 @@ public function user_register( $user_id ) { * @return void */ public function new_comment( $comment_id ) { + // The comment may have been deleted, trashed, or flagged as spam + // (e.g. by an anti-spam plugin hooked on `comment_post`) before this + // runs. Bail so we don't render and bill an SMS for a comment that no + // longer exists. + if ( ! get_comment( $comment_id ) instanceof WP_Comment ) { + return; + } + $class = texty()->notifications()->get( 'comment' ); $notifier = new $class(); diff --git a/includes/Notifications/WP/Comment.php b/includes/Notifications/WP/Comment.php index 8fcb91d..fc0fad6 100644 --- a/includes/Notifications/WP/Comment.php +++ b/includes/Notifications/WP/Comment.php @@ -3,6 +3,7 @@ namespace Texty\Notifications\WP; use Texty\Notifications\Notification; +use WP_Comment; class Comment extends Notification { @@ -52,9 +53,23 @@ public function get_message() { $comment = get_comment( $this->comment_id ); + // The comment can vanish between the `comment_post` hook and the send + // (deleted, trashed, or spam). Bail to the global-key pass instead of + // dereferencing null and rendering an empty-bodied message. + if ( ! $comment instanceof WP_Comment ) { + return $this->replace_global_keys( $message ); + } + foreach ( $this->replacement_keys() as $search => $value ) { - $value = ( $search === 'post_url' ) ? get_permalink( $comment->comment_post_ID ) : $comment->$value; - $message = str_replace( '{' . $search . '}', $value, $message ); + // `post_url` has no comment property; everything else reads off the + // comment via WP_Comment's magic getter (e.g. `post_title` proxies + // to the post). Coerce to string so a missing value never reaches + // str_replace as null (deprecated since PHP 8.1). + $replacement = ( 'post_url' === $search ) + ? (string) get_permalink( $comment->comment_post_ID ) + : (string) ( $comment->$value ?? '' ); + + $message = str_replace( '{' . $search . '}', $replacement, $message ); } $message = $this->replace_global_keys( $message );