created_at = current_time( 'mysql' ); } /** * Get table name. * * @return string */ public static function tableName() { return 'anycomment_email_queue'; } /** * @return wpdb */ public static function db() { global $wpdb; return $wpdb; } /** * Get latest * @return AnyCommentEmailQueue|null|object */ public static function getNewest() { $tableName = static::tableName(); $sql = "SELECT * FROM `$tableName` ORDER BY `id` DESC LIMIT 1"; return static::db()->get_row( $sql ); } /** * Get fresh comments which were not notified about yet. * * @return WC_Comments[]|null WC_Comments[] on success, NULL on failure. */ public static function grabToAdd() { $wpdb = static::db(); $commentsTable = $wpdb->comments; $usersTable = $wpdb->users; $latestEmailQueue = static::getNewest(); $latestDate = $latestEmailQueue->created_at; /** * Select * - list of replies to parent comment * - make sure user has email * - make sure user did not reply to his own comment * - and comment date is after the latest reply sent */ $sql = "SELECT `comments`.*, `users`.`ID` AS parent_user_ID FROM `$commentsTable` `comments` INNER JOIN `$commentsTable` `innerComment` ON `innerComment`.`comment_ID` = `comments`.`comment_parent` INNER JOIN `$usersTable` `users` ON `users`.`ID` = `innerComment`.`user_ID` WHERE `comments`.`comment_parent` != 0 AND `users`.`user_email` != '' AND `comments`.`user_ID` != `innerComment`.`user_ID` AND `comments`.`comment_date` > '$latestDate'"; return $wpdb->get_results( $sql ); } /** * Grab emails to be sent. * * @return null|AnyCommentEmailQueue[] */ public static function grabRepliesToSend() { $usersTable = static::db()->users; $tableName = static::tableName(); $sql = "SELECT `emails`.*, `users`.`user_email` AS notify_email FROM `$tableName` `emails` LEFT JOIN `$usersTable` `users` ON `emails`.`user_ID` = `users`.`ID` WHERE `emails`.`sent_at` = '0000-00-00 00:00:00'"; return static::db()->get_results( $sql ); } /** * Check whether specified email ID was already sent or not. * * @param int $email_id Email ID to check for. * * @return bool */ public static function isSent( $email_id ) { if ( empty( $email_id ) || ! is_numeric( $email_id ) ) { return false; } $tableName = static::tableName(); $query = static::db()->prepare( "SELECT `id`, `sent_at` FROM `$tableName` WHERE `id`=%d LIMIT 1", [ $email_id ] ); /** * @var $model AnyCommentEmailQueue|null */ $model = static::db()->get_row( $query ); if ( empty( $model ) ) { return false; } if ( $model->sent_at === '0000-00-00 00:00:00' ) { return false; } return true; } /** * Mark email as sent. * * Notice: when email is already sent, method will return true. * * @param int $email_id Email to be updated. * * @return bool */ public static function markAsSent( $email_id ) { if ( empty( $email_id ) || ! is_numeric( $email_id ) ) { return false; } if ( static::isSent( $email_id ) ) { return true; } $isUpdated = static::db()->update( static::tableName(), [ 'sent_at' => current_time( 'mysql' ) ], [ 'ID' => $email_id ] ); return $isUpdated !== false; } /** * Add specified comment as reply if applicable. * Method will check: * - whether specified comment is child comment * - not a reply to the same user * - make sure parent user has email (some socials do not provide email in the API) * * @param WP_Comment $comment Instance of comment model. * * @return AnyCommentEmailQueue|bool|int */ public static function addAsReply( $comment ) { if ( ! $comment instanceof WP_Comment || (int) $comment->comment_parent === 0 ) { return false; } $db = static::db(); $usersTable = $db->users; $commentsTable = $db->comments; $query = "SELECT `comments`.*, `users`.`ID` AS parent_user_ID FROM `$commentsTable` `comments` LEFT JOIN `$commentsTable` `innerComment` ON `innerComment`.`comment_ID` = `comments`.`comment_parent` LEFT JOIN `$usersTable` `users` ON `users`.`ID` = `innerComment`.`user_ID` WHERE `comments`.`comment_parent` != 0 AND `users`.`user_email` != '' AND `comments`.`user_ID` != `innerComment`.`user_ID` AND `comments`.`comment_ID`=%d"; $result = static::db()->get_row( static::db()->prepare( $query, [ $comment->comment_ID ] ) ); if ( empty( $result ) || ! $result ) { return false; } $email = new self(); $email->user_ID = $result->parent_user_ID; $email->post_ID = $comment->comment_post_ID; $email->comment_ID = $comment->comment_ID; $email->content = AnyCommentEmailQueue::generateReplyEmail( $email ); // todo: add some logging $isAdded = AnyCommentEmailQueue::add( $email ); return $isAdded; } public static function addAsAdminNotification( $comment ) { if ( ! $comment instanceof WP_Comment ) { return false; } $db = static::db(); $usersTable = $db->users; $commentsTable = $db->comments; $adminEmail = get_option( 'new_admin_email' ); $query = "SELECT `comments`.* FROM `$commentsTable` `comments` LEFT JOIN `$usersTable` `users` ON `users`.`ID` = `comments`.`user_ID` WHERE `users`.`user_email` != %s AND `comments`.`comment_ID`=%d"; $result = static::db()->get_row( static::db()->prepare( $query, [ $adminEmail, $comment->comment_ID ] ) ); if ( empty( $result ) || ! $result ) { return false; } $user = get_user_by( 'email', $adminEmail ); if(!$user instanceof WP_User) { return false; } $email = new self(); $email->user_ID = $user->ID; $email->post_ID = $comment->comment_post_ID; $email->comment_ID = $comment->comment_ID; $email->content = AnyCommentEmailQueue::generateAdminEmail( $email ); // todo: add some logging $isAdded = AnyCommentEmailQueue::add( $email ); return $isAdded; } /** * Add new email to queue. * * @param AnyCommentEmailQueue $email * @param string $returnOnSuccess What to return on success. * - ID - will return new record ID * - OBJECT - will return email queue * * @return bool|int|AnyCommentEmailQueue */ public static function add( $email, $returnOnSuccess = 'ID' ) { if ( ! $email instanceof AnyCommentEmailQueue ) { return false; } if ( ! isset( $email->ip ) ) { $email->ip = isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : null; } if ( ! isset( $email->user_agent ) ) { $email->user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : null; } if ( ! isset( $email->ip ) ) { $email->ip = isset( $_SERVER['SERVER_ADDR'] ) ? $_SERVER['SERVER_ADDR'] : null; } if ( ! isset( $email->created_at ) ) { $email->created_at = current_time( 'mysql' ); } global $wpdb; unset( $email->ID ); $tableName = static::tableName(); $count = $wpdb->insert( $tableName, (array) $email ); if ( $count !== false && $count > 0 ) { $lastId = $wpdb->insert_id; if ( empty( $lastId ) ) { return false; } $email->ID = $lastId; if ( $returnOnSuccess === 'ID' ) { return $lastId; } elseif ( $returnOnSuccess === 'OBJECT' ) { return $email; } return true; } return false; } /** * Prepare email body. * * @param AnyCommentEmailQueue $email * * @return string HTML formatted content of email. */ public static function generateReplyEmail( $email ) { $comment = get_comment( $email->comment_ID ); $post = get_post( $email->post_ID ); $cleanPermalink = get_permalink( $post ); $commentLink = sprintf( '%s#comment-%s', $cleanPermalink, $comment->comment_ID ); $body = '
' . sprintf( __( 'New reply was posted in %s', 'anycomment' ), get_option( 'siteurl' ), get_option( 'blogname' ) ) . '
'; if ( $post !== null ) { $body .= '' . sprintf( __( 'For post %s', 'anycomment' ), $cleanPermalink, $post->post_title ) . '
'; } if ( $comment !== null ) { $body .= '' . __( 'Reply', 'anycomment' ) . '
'; return $body; } /** * Generate email template to send notification to admin. * * @param AnyCommentEmailQueue $email * * @return string * todo: need rewrite as duplicate code of email template above, for now good enought */ public static function generateAdminEmail( $email ) { $comment = get_comment( $email->comment_ID ); $post = get_post( $email->post_ID ); $cleanPermalink = get_permalink( $post ); $commentLink = sprintf( '%s#comment-%s', $cleanPermalink, $comment->comment_ID ); $body = '' . sprintf( __( 'New comment posted in %s', 'anycomment' ), get_option( 'siteurl' ), get_option( 'blogname' ) ) . '
'; if ( $post !== null ) { $body .= '' . sprintf( __( 'For post %s', 'anycomment' ), $cleanPermalink, $post->post_title ) . '
'; } if ( $comment !== null ) { $body .= '