Ajax registration for WordPress Newsletter plugin

There are some forum posts about customizing ajax registration of Newsletter plugin but these solutions aren’t complete (for example activation emails aren’t supported). Here you can find my code with instructions.

I work on a child theme. It’s easier to tweak your template if update won’t delete your changes… I suggest reading this first, after that you can generate your theme using this simple tool.

Now back to the business… Copy the content of the four files pasted on my gist to your (child) template files and install Newsletter plugin.

Files you’ll need to edit or create:

  • style.css – add form styles, tweak it to your needs.
  • main.js – add ajax support for your form.
  • functions.php – add vars needed by ajax form and ajax hook to register new subscriber.
  • newsletterForm.php – create this file in your template directory, use <?php get_template_part( ‘newsletterForm’ ); ?> to include it in your selected place.

My template with all files:

Download on Github.

Source code:

&lt;?php
/** @constant string THEME_NAME **/
define( &#39;THEME_NAME&#39;, get_option(&#39;stylesheet&#39;) );

/**
* Custom script
*/
function my_scripts_method() {
wp_enqueue_script(
&#39;custom-script&#39;,
get_stylesheet_directory_uri() . &#39;/js/main.js&#39;,
array( &#39;jquery&#39; ),
&#39;1.2&#39;
);

if ( !is_admin() ) {
/** */
wp_localize_script( &#39;custom-script&#39;, &#39;ajax&#39;, array(
&#39;url&#39; =&gt; admin_url( &#39;admin-ajax.php&#39; ),
&#39;ajax_nonce&#39; =&gt; wp_create_nonce( &#39;noncy_nonce&#39; ),
&#39;assets_url&#39; =&gt; get_stylesheet_directory_uri(),
) );
}
}
add_action( &#39;wp_enqueue_scripts&#39;, &#39;my_scripts_method&#39; );

/**
* Ajax newsletter
*
* @url http://www.thenewsletterplugin.com/forums/topic/ajax-subscription
*/
function realhero_ajax_subscribe() {
check_ajax_referer( &#39;noncy_nonce&#39;, &#39;nonce&#39; );
$data = urldecode( $_POST[&#39;data&#39;] );

if ( !empty( $data ) ) :
$data_array = explode( &quot;&amp;&quot;, $data );
$fields = [];
foreach ( $data_array as $array ) :
$array = explode( &quot;=&quot;, $array );
$fields[ $array[0] ] = $array[1];
endforeach;
endif;

if ( !empty( $fields ) ) :
global $wpdb;

// check if already exists

/** @var int $count **/
$count = $wpdb-&gt;get_var( $wpdb-&gt;prepare(&quot;SELECT COUNT(*) FROM {$wpdb-&gt;prefix}newsletter WHERE email = %s&quot;, $fields[&#39;ne&#39;] ) );

if( $count &gt; 0 ) {
$output = array(
&#39;status&#39; =&gt; &#39;error&#39;,
&#39;msg&#39; =&gt; __( &#39;Already in a database.&#39;, THEME_NAME )
);
} elseif( !defined( &#39;NEWSLETTER_VERSION&#39; ) ) {
$output = array(
&#39;status&#39; =&gt; &#39;error&#39;,
&#39;msg&#39; =&gt; __( &#39;Please install &amp; activate newsletter plugin.&#39;, THEME_NAME )
);
} else {
/**
* Generate token
*/

/** @var string $token */
$token = wp_generate_password( rand( 10, 50 ), false );

$wpdb-&gt;insert( $wpdb-&gt;prefix . &#39;newsletter&#39;, array(
&#39;email&#39; =&gt; $fields[&#39;ne&#39;],
&#39;status&#39; =&gt; $fields[&#39;na&#39;],
&#39;http_referer&#39; =&gt; $fields[&#39;nhr&#39;],
&#39;token&#39; =&gt; $token,
)
);

$opts = get_option(&#39;newsletter&#39;);

$opt_in = (int) $opts[&#39;noconfirmation&#39;];

// This means that double opt in is enabled
// so we need to send activation e-mail
if ($opt_in == 0) {
$newsletter = Newsletter::instance();
$user = NewsletterUsers::instance()-&gt;get_user( $wpdb-&gt;insert_id );

NewsletterSubscription::instance()-&gt;mail($user-&gt;email, $newsletter-&gt;replace($opts[&#39;confirmation_subject&#39;], $user), $newsletter-&gt;replace($opts[&#39;confirmation_message&#39;], $user));
}

$output = array(
&#39;status&#39; =&gt; &#39;success&#39;,
&#39;msg&#39; =&gt; __( &#39;Thank you!&#39;, THEME_NAME )
);
}

else :
$output = array(
&#39;status&#39; =&gt; &#39;error&#39;,
&#39;msg&#39; =&gt; __( &#39;An Error occurred. Please try again later.&#39;, THEME_NAME )
);
endif;

wp_send_json( $output );
}
add_action( &#39;wp_ajax_realhero_subscribe&#39;, &#39;realhero_ajax_subscribe&#39; );
add_action( &#39;wp_ajax_nopriv_realhero_subscribe&#39;, &#39;realhero_ajax_subscribe&#39; );

File: main.js
————-

function validateEmail(email) {
var re = /^(([^&lt;&gt;()[\]\\.,;:\s@\&quot;]+(\.[^&lt;&gt;()[\]\\.,;:\s@\&quot;]+)*)|(\&quot;.+\&quot;))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
};

jQuery(function($){
// now you can use jQuery code here with $ shortcut formatting
// this executes immediately – before the page finishes loading

/**
* Newsletter support
*/
$(&#39;#newsletter&#39;)
.attr(&#39;novalidate&#39;, true)
.each( function() {
var $this = $(this),
$input = $this.find( &#39;input[name=&quot;ne&quot;]&#39;),
$noti = $input.prev(),
$submit = $this.find( &#39;input[type=&quot;submit&quot;]&#39;),
showNoti = function(txt) {
var $msg = $noti.clone();

$noti.before($msg);
$noti.remove();

$msg.text( txt ).addClass(&#39;vaporize&#39;).attr(&#39;aria-hidden&#39;, &#39;false&#39;);
},
success = function() {
$this
.fadeOut(&#39;slow&#39;, function() {
$this.replaceWith( &#39;&lt;p class=&quot;appear-nicely dynamic-msg&quot;&gt;Thank you!&lt;/p&gt;&#39; );
});
};

// Submit handler
$this.submit( function(e) {
var serializedData = $this.serialize();

$noti = $input.prev();

console.log( &#39;INFO: Form submit.&#39; );

e.preventDefault();

// validate
if( validateEmail( $input.val() ) ) {
var data = {};

// Prepare ajax data
data = {
action: &#39;realhero_subscribe&#39;,
nonce: ajax.ajax_nonce,
data: serializedData
}

// send ajax request
$.ajax({
method: &quot;POST&quot;,
url: ajax.url,
data: data,
beforeSend: function() {
$input.prop( &#39;disabled&#39;, true );
$submit.val(&#39;Wait&#39;).prop( &#39;disabled&#39;, true );
},
success: function( data ) {

if( data.status == &#39;success&#39; ) {
success();
console.log( &#39;INFO: OK!&#39; );
} else {
$input.prop( &#39;disabled&#39;, false );
$submit.val(&#39;Submit&#39;).prop( &#39;disabled&#39;, false );

showNoti( data.msg );
console.log( &#39;INFO: Bad response.&#39; );
}
}
});

console.log( &#39;INFO: Email ok.&#39; );
} else {
showNoti( &#39;Enter valid e-mail address!&#39; );
};
});
});

});

File: newsletterForm.php
————————

&lt;aside id=&quot;newsletter-form&quot;&gt;
&lt;div&gt;
&lt;h1 class=&quot;widget-title&quot;&gt;Newsletter&lt;/h1&gt;
&lt;div class=&quot;widget&quot;&gt;
&lt;p&gt;Be upddated!&lt;/p&gt;
&lt;/div&gt;&lt;!–
–&gt;&lt;div class=&quot;widget&quot;&gt;
&lt;form id=&quot;newsletter&quot; role=&quot;form&quot; method=&quot;get&quot; class=&quot;search-form&quot; action=&quot;http://domain.com/&quot;&gt;
&lt;label&gt;
&lt;span class=&quot;screen-reader-text&quot;&gt;E-mail:&lt;/span&gt;
&lt;span class=&quot;notification&quot; aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;
&lt;input class=&quot;email-field&quot; placeholder=&quot;Type your e-mail&quot; value=&quot;&quot; name=&quot;ne&quot; type=&quot;email&quot;&gt;
&lt;/label&gt;
&lt;input type=&quot;hidden&quot; name=&quot;na&quot; value=&quot;S&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;nhr&quot; value=&quot;&lt;?php echo get_bloginfo( &#39;url&#39; ) ?&gt;&quot;&gt;
&lt;input class=&quot;email-submit&quot; value=&quot;Submit&quot; type=&quot;submit&quot;&gt;
&lt;/form&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/aside&gt;&lt;!– #newsletter-form –&gt;

File: style.css
—————

/**
* Newsletter form
*/
@keyframes appear-nicely {

0% {
opacity: 0;

}

100% {
opacity: 1;
}
}

.appear-nicely {
animation: appear-nicely 2s forwards ease-out;
}

#wolontariat #newsletter-form {
background-color: #24282d;
padding: 32px 40px;
margin-left: -40px;
box-sizing: content-box;
width: 100%;
color: White;
text-align: center;
position: relative;
}
#wolontariat #newsletter-form &gt; div {
max-width: 1000px;
margin: 0 auto;
}
#wolontariat #newsletter-form h1 {
color: White;
}
#wolontariat #newsletter-form .widget {
float: none;
width: 100%;
display: inline-block;
margin: 0 0;
padding: 16px;
box-sizing: border-box;
vertical-align: middle;
}
#wolontariat #newsletter-form .widget p img {
vertical-align: middle;
}
#wolontariat #newsletter-form .widget .disclaimer {
padding: 0 0;
margin: 10px 0 0 0;
font-size: .625rem;
}
#wolontariat #newsletter-form .email-submit {
min-width: 100%;
margin-top: 16px;
}

@keyframes vaporize {
0% {
opacity: 1;

}
100% {
opacity: 0;
top: -80px;
}
}

#wolontariat #newsletter-form .notification[aria-hidden=&quot;true&quot;] {
display: none;
}

#wolontariat #newsletter-form .notification[aria-hidden=&quot;false&quot;] {
display: block;
position: absolute;
top: -25px;
left: 0px;
}

.vaporize {
animation: vaporize 1.5s forwards ease-out;
}
</code></pre>
<p>




Comments

0 responses to “Ajax registration for WordPress Newsletter plugin”

  1. Marcel Avatar
    Marcel

    Thank you so much for this!! It helped me a lot

  2. Stephan Avatar
    Stephan

    I’m very thankful for this solution. Unfortunately, it isn’t completely flawless; it adds subscribers to the database but it doesn’t send confirmation e-mails to these subscribers if double opt-in is enabled. Is there any solution to this? My PHP knowledge is too limited to figure this out myself (despite trying). 🙁

    1. Konrad Fedorczyk Avatar
      Konrad Fedorczyk

      Hi! I don’t remember how I did this but I believe that also e-mails worked for me. I’ll try to find source code of this website and help you.

      1. Stephan Avatar
        Stephan

        Thanks. Just for the records: I don’t see any server errors in the log file; and as far as I can analyze it I could trace it down to this section in the PHP code:

        if ($opt_in == 0) {
        $newsletter = Newsletter::instance();
        $user = NewsletterUsers::instance()->get_user( $wpdb->insert_id );
        NewsletterSubscription::instance()->mail($user->email, $newsletter->replace($opts['confirmation_subject'], $user), $newsletter->replace($opts['confirmation_message'], $user));
        }

        I have double opt-in activated and it does return zero, so the function should fire. But from there on I’m clueless.

        And it doesn’t make a difference whether SMTP in the Newsletter plugin is active or inactive.
        As said, it works if I use the standard form that comes with the Newsletter plugin, but not with this AJAX form, so there must be something to it.

      2. Stephan Avatar
        Stephan

        OK, I found something else: looking at the debug log after registering for a newsletter I see this entry:

        19-06-2019 11:58:52 – ERROR – m: 48,7 MB, u: 1 – mail> You must provide at least one recipient email address.

        Also, looking at this line: NewsletterSubscription::instance()->mail($user->email, $newsletter->replace($opts['confirmation_subject'], $user), $newsletter->replace($opts['confirmation_message'], $user));

        am I right in assuming that it isn’t even sending the email through SMTP?

        1. Mike Socorec Avatar

          he encontrado una solucion al problema que no envia el correo electronico.

          mi codigo antes
          if ($opt_in == 0) {
          $newsletter = Newsletter::instance();
          $user = NewsletterUsers::instance()->get_user( $wpdb->insert_id );
          NewsletterSubscription::instance()->mail($user->email, $newsletter->replace($opts[‘confirmation_subject’], $user), $newsletter->replace($opts[‘confirmation_message’], $user));
          }

          codigo despues (solucion)
          if ($opt_in == 1) {
          $newsletter = Newsletter::instance();
          $user = NewsletterUsers::instance()->get_user( $wpdb->insert_id );
          NewsletterSubscription::instance()->mail($user, $newsletter->replace($opts[‘confirmation_subject’], $user), $newsletter->replace($opts[‘confirmation_message’], $user));
          }

          el problema esta en que al metodo ->mail() se le esta pasando el correo del usuario, pero el metodo espera toda la informacion del usuario es decir, espera que le pasemos la variable $user

  3. xszejdi Avatar
    xszejdi

    Cześć chłopaki!

    Czy problem z e-mailem aktywacyjnym wciąż istnieje?

    1. Konrad Fedorczyk Avatar
      Konrad Fedorczyk

      Hej,
      Ja niestety nie miałem czasu już podjąć tematu więc nie sprawdzałem… Ale jak masz rozwiązanie to podeślij, opublikuję i napiszę kto jest autorem (z linkiem).

  4. Alex Avatar
    Alex

    This is lovely, but couldn’t this be achieved using a simple JS script to AJAXify the form + enabling the Newsletter API?

    Seems like a simpler solution to the issue.