Code Updated on - 01-May-2024
Updated code news latter is reday with many features --
like that -
  1. One user only one time can subscribe.
  2. All subscriber list you can see on dashboard in Subcriber Page
  3. And When You Create any post then this function a mail on every subscriber
  4. You can also send a custom mail by select specific subscribers from dashboard.

Just copy past this code step by step and your news latter is ready--

Put this html in html widget on your page - just copy past :-

<!-- HTML form -->
<form id="subscribe-form">
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" required>
    <button type="submit">Subscribe</button>
</form>

<!-- Display message -->
<div id="subscribe-message"></div>
  

Put this code in your js file or just below the html code -

<script>
// JavaScript AJAX handling
document.getElementById('subscribe-form').addEventListener('submit', function(event) {
    event.preventDefault();
    
    // Get form data
    const formData = new FormData(this);
    
    // Send AJAX request
    const xhr = new XMLHttpRequest();
    xhr.open('POST', '/wp-admin/admin-ajax.php?action=subscribe_action', true);
    xhr.onload = function() {
        if (xhr.status === 200) {
            document.getElementById('subscribe-message').textContent = xhr.responseText;
 console.log(xhr);
        } else {
            console.error('Error:', xhr.statusText);
        }
    };
    xhr.send(formData);
});

</script>


Now create a PHP file in theme root directry - and include it in Functions.php file.

<?php //sknetking

//news latter handler class create new file and include it your functions.php file 
class Subscribers_Handler {
    public function __construct() {
        add_action('wp_ajax_subscribe_action', array($this, 'subscribe_action_callback'));
        add_action('wp_ajax_nopriv_subscribe_action', array($this, 'subscribe_action_callback'));
        add_action('init', array($this, 'create_subscribers_table_if_not_exists'));
        add_action('admin_menu', array($this, 'custom_subscribers_page'));
        add_action('publish_post', array($this, 'send_email_to_subscribers'));
        add_action('admin_post_send_email', array($this, 'process_email_form_submission'));
    }

    public function subscribe_action_callback() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'subscribers';
        $email = $_POST['email'];
        $existing_email = $wpdb->get_var($wpdb->prepare("SELECT email FROM ".$table_name." WHERE email = %s", $email));

        if ($existing_email) {
            echo 'You are already subscribed.';
        } else {
			date_default_timezone_set("Asia/Kolkata");
            $wpdb->insert(
                 $table_name ,
                array(
                    'email' => $email,
					'subscribed_date'=>date("Y-m-d h:i:s a"),
                )
            );
            echo 'Subscribed successfully!';
        }
        wp_die();
    }

  public function create_subscribers_table_if_not_exists() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'subscribers';
    if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
        $charset_collate = $wpdb->get_charset_collate();
        $current_datetime = current_time('mysql');
        $sql = "CREATE TABLE $table_name (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            email varchar(255) NOT NULL,
            subscribed_date varchar(255) NOT NULL DEFAULT '$current_datetime',
            PRIMARY KEY  (id)
        ) $charset_collate;";
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);
    }
}


    public function custom_subscribers_page() {
        add_menu_page('Subscribers', 'Subscribers', 'manage_options', 'custom-subscribers', array($this, 'custom_subscribers_callback'));
    }

    public function custom_subscribers_callback() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'subscribers';
        $subscribers = $wpdb->get_results("SELECT * FROM $table_name", ARRAY_A);
        $this->display_subscribers_table();
         ?>
 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<h2 class="text-center">Send Email to Subscribers</h2>
<form method="post">
    <input type="hidden" name="action" value="send_email">
    <div class="mb-3">
        <label for="selected-subscribers" class="form-label">Select Subscribers:</label>
        <select name="selected-subscribers[]" class="form-select" multiple aria-label="Select Subscribers" size="3" required>
            <?php foreach ($subscribers as $subscriber): ?>
                <option value="<?= $subscriber['email'] ?>"><?= $subscriber['email'] ?></option>
            <?php endforeach; ?>
        </select>
    </div>
    <div class="mb-3">
        <label for="email-subject" class="form-label">Subject:</label>
        <input type="text" name="email-subject" class="form-control" required>
    </div>
    <div class="mb-3">
        <label for="email-message" class="form-label">Message:</label>
        <textarea name="email-message" class="form-control" required></textarea>
    </div>
    <button type="submit" name="send-email" class="btn btn-primary">Send Email</button>
</form>
<?php 
		if(isset($_POST['send-email'])){
			$subscriber= $_POST['selected-subscribers'];
			$subject = $_POST['email-subject'];
			$message = $_POST['email-message'];
			
			 $send_mail = wp_mail($subscriber, $subject, $message);
				if($send_mail)
				echo "Mail Sent Successfully!";
				else 
				echo "Mail not sending please configer SMTP!";
		  }
}
    public function display_subscribers_table() {
    	$test_list_table = new TT_Example_List_Table();
	// Fetch, prepare, sort, and filter our data.
	    $test_list_table->prepare_items();
		$test_list_table->display();
}


    public function send_email_to_subscribers($post_id) {
        if (wp_is_post_revision($post_id)) return;

        global $wpdb;
        $table_name = $wpdb->prefix . 'subscribers';
        $subscribers = $wpdb->get_col("SELECT email FROM $table_name");

        $post_title = get_the_title($post_id);
        $post_link = get_permalink($post_id);
        $subject = 'New Post: ' . $post_title;
        $message = 'A new post has been published: ' . $post_title . ' - ' . $post_link;

        foreach ($subscribers as $subscriber) {
            wp_mail($subscriber, $subject, $message);
        }
    }

    public function process_email_form_submission() {
        if (isset($_POST['send-email'])) {
            $selected_subscribers = $_POST['selected-subscribers'];
            $subject = $_POST['email-subject'];
            $message = $_POST['email-message'];

            foreach ($selected_subscribers as $subscriber) {
                wp_mail($subscriber, $subject, $message);
            }
        }
    }
}

$subscribers_handler = new Subscribers_Handler();

if ( ! class_exists( 'WP_List_Table' ) ) {
	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}
class TT_Example_List_Table extends WP_List_Table {
		
	public function __construct() {
		// Set parent defaults.
		parent::__construct( array(
			'singular' => 'subscriber',     // Singular name of the listed records.
			'plural'   => 'subscribers',    // Plural name of the listed records.
			'ajax'     => false,       // Does this table support ajax?
		) );
	}
	
	public function get_columns() {
		$columns = array(
			'cb'       => '<input type="checkbox" />', // Render a checkbox instead of text.
			'email'    => _x( 'Email', 'Column label', 'wp-list-table-example' ),
			'date'   => _x( 'Date', 'Column label', 'wp-list-table-example' ),
			'action' => _x( 'Action', 'Column label', 'wp-list-table-example' ),
		);

		return $columns;
	}

	
	protected function get_sortable_columns() {
		$sortable_columns = array(
			'email'    => array( 'email', false ),
			'date'   => array( 'date', false ),
			'action' => array( 'action', false ),
		);

		return $sortable_columns;
	}

	
	protected function column_default( $item, $column_name ) {
		switch ( $column_name ) {
			case 'date':
			case 'action':
				return $item[ $column_name ];
			default:
				return print_r( $item, true ); // Show the whole array for troubleshooting purposes.
		}
	}

	
	protected function column_cb( $item ) {
		return sprintf(
			'<input type="checkbox" name="%1$s[]" value="%2$s" />',
			$this->_args['singular'],  // Let's simply repurpose the table's singular label ("subscriber").
			$item['ID']                // The value of the checkbox should be the record's ID.
		);
	}

	protected function column_email( $item ) {
		$page = wp_unslash( $_REQUEST['page'] ); // WPCS: Input var ok.

		// Build edit row action.
		$edit_query_args = array(
			'page'   => $page,
			'action' => 'edit',
			'subscriber'  => $item['ID'],
		);

		$actions['edit'] = sprintf(
			'<a href="%1$s">%2$s</a>',
			esc_url( wp_nonce_url( add_query_arg( $edit_query_args, 'admin.php' ), 'editsubscriber_' . $item['ID'] ) ),
			_x( 'Edit', 'List table row action', 'wp-list-table-example' )
		);

		// Build delete row action.
		$delete_query_args = array(
			'page'   => $page,
			'action' => 'delete',
			'subscriber'  => $item['ID'],
		);

		$actions['delete'] = sprintf(
			'<a href="%1$s">%2$s</a>',
			esc_url( wp_nonce_url( add_query_arg( $delete_query_args, 'admin.php' ), 'deletesubscriber_' . $item['ID'] ) ),
			_x( 'Delete', 'List table row action', 'wp-list-table-example' )
		);

		// Return the email contents.
		return sprintf( '%1$s <span style="color:silver;">(id:%2$s)</span>%3$s',
			$item['email'],
			$item['ID'],
			$this->row_actions( $actions )
		);
	}

	
	protected function get_bulk_actions() {
		$actions = array(
			'delete' => _x( 'Delete', 'List table bulk action', 'wp-list-table-example' ),
		);

		return $actions;
	}

	
	protected function process_bulk_action() {
		// Detect when a bulk action is being triggered.
		if ( 'delete' === $this->current_action() ) {
			wp_die( 'Items deleted (or they would be if we had items to delete)!' );
		}
	}

	function prepare_items() {
		global $wpdb; //This is used only if making any database queries


		$per_page = 10;

		
		$columns  = $this->get_columns();
		$hidden   = array();
		$sortable = $this->get_sortable_columns();

		
		$this->_column_headers = array( $columns, $hidden, $sortable );

				$this->process_bulk_action();

		
		$data = array();
		 $table_name = $wpdb->prefix . 'subscribers';
        $subscribers = $wpdb->get_results("SELECT * FROM $table_name", ARRAY_A);
		foreach ($subscribers as $subscriber) {
    	$temp_array = array(
			'ID'       =>  $subscriber['id'] ,
			'email'    =>$subscriber['email'] ,
			'date'   =>  $subscriber['subscribed_date'] ,
			'action' => '<a href="?page=custom-subscribers&action=delete&subscriber_id=' . $subscriber['id'] . '">Delete</a>',
		     );  
			array_push($data,$temp_array);
		 }
		
		usort( $data, array( $this, 'usort_reorder' ) );

				$current_page = $this->get_pagenum();

				$total_items = count( $data );

				$data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page );

				$this->items = $data;

				$this->set_pagination_args( array(
			'total_items' => $total_items,                     // WE have to calculate the total number of items.
			'per_page'    => $per_page,                        // WE have to determine how many items to show on a page.
			'total_pages' => ceil( $total_items / $per_page ), // WE have to calculate the total number of pages.
		) );
	}

	protected function usort_reorder( $a, $b ) {
		// If no sort, default to email.
		$orderby = ! empty( $_REQUEST['orderby'] ) ? wp_unslash( $_REQUEST['orderby'] ) : 'email'; // WPCS: Input var ok.

		// If no order, default to asc.
		$order = ! empty( $_REQUEST['order'] ) ? wp_unslash( $_REQUEST['order'] ) : 'asc'; // WPCS: Input var ok.

		// Determine sort order.
		$result = strcmp( $a[ $orderby ], $b[ $orderby ] );

		return ( 'asc' === $order ) ? $result : - $result;
	}
}



Now your news latter is reday with many featuresc--
like that -

  1. One user only one time can subscribe.
  2. All subscriber list you can see on dashboard in Subcriber Page
  3. And When You Create any post then this function a mail on every subscriber
  4. You can also send a custom mail by select specific subscribers from dashboard.

Must need to know -- top-10-most-use-full-wordpress-plugins Note - If you like this post then please share & comment a nice line. Tags - how to add newsletter in wordpress elementor,how to add newsletters to wordpress,how to add newsletter in wordpress 2021,add newsletter form in wordpress website,wordpress newsletter plugins,wordpress add newsletter to site,how to add subscribe newsletter form in elementor,wordpress what newsletter tools to use,best newsletter plugins,how to add email subscription to wordpress,add email form in wordpress,wordpress plugins for newsletters,