I'm having issues with drupal_mail(). I receive the email but the subject and body are empty.
Drupal version 7
code below
$params = array(
'subject' => t('Client Requests Quote'),
'body' => t("Body of the email goes here"),
);
drupal_mail("samplemail", "samplemail_html_mail", "email#email.com", language_default(), $params, "email#email.com", TRUE);
I have even tried it with the hook below and I get the same result.
function hook_mail($key, &$message, $params) {
switch ($key) {
case 'samplemail_html_mail':
/*
* Emails with this key will be HTML emails,
* we therefore cannot use drupal default headers, but set our own headers
*/
/*
* $vars required even if not used to get $language in there since t takes in: t($string, $args = array(), $langcode = NULL) */
$message['subject'] = t($params['subject'], $var, $language->language);
/* the email body is here, inside the $message array */
$body = "<html><body>
<h2>HTML Email Sample with Drupal</h2>
<hr /><br /><br />
{$params['body']}
</body></html>";
$message['body'][] = $body;
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
break;
}
}
drupal_mail_system() works but it comes in plain text.
in your module you shouldn't use hook_mail it should be <MODULE_NAME>_hook().
change
function hook_mail($key, &$message, $params) {
With
function samplemail_mail($key, &$message, $params) {
Try using the following snippet.
// Use these two lines when you want to send a mail.
global $user;
drupal_mail('test', 'test_mail', 'your_mail_id', user_preferred_language($user), $params, $from_mail_id, TRUE);
/**
* Implements hook_mail().
*/
function test_mail($key, &$message, $params) {
switch ($key) {
case 'test_mail':
$params['subject'] = t('Subject is here');
$params['message'] = 'message is here';
$message['subject'] = $params['subject'];
$message['body'][] = $params['message'];
break;
}
}
Note: 'test' is module name.
Solution !
Try with below code in your "registration_form" module. This code will send mail often on page refresh since mail trigger is done in hook_init. Use where ever you want.
/**
* Implements hook_init();
*/
function registration_form_init() {
$first_name = 'Shankar';
$params = array(
'subject' => 'Signup Invitation',
'body' => '<p>Dear ' . $first_name . ',</p>
<p>Congratulations! Your account <b> ' . $first_name . ' </b>has been successfully created with SOME portal.</p>
<p>Thanks,SOME portal POSTMASTER</p>',
'first_name' => $first_name
);
drupal_mail('registration_form', 'invitation', $email, language_default(), $params);
}
/**
* Implements hook_mail();
*/
function registration_form_mail($key, &$message, $params) {
switch ($key) {
case 'invitation':
$message['subject'] = $params['subject'];
$message['body'][] = $params['body'];
break;
}
}
Related
Could someone tell me what i am missing to send an HTML email using Drupal's function? Here is my call:
try{
drupal_mail('my_module', 'forgot', $node->field_email_address['und'][0]['value'], language_default(), array('reset_key' => $key),'do-not-reply#myemailaddress.com');
}catch(Exception $e){
print_r($e->getMessage());die();
}
And here is the function:
function my_module_mail($key, &$message, $params) {
$body = '<p>Click the link below to reset your password.</p>
<p>Click this link to reset your password</p>
';
// $headers = array(
// 'MIME-Version' => '1.0',
// 'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
// 'Content-Transfer-Encoding' => '8Bit',
// 'X-Mailer' => 'Drupal'
// );
// $message['headers'] = $headers;
$message['subject'] = 'Why wont this send html??';
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8;';
$message['body'][] = $body;
$message['from'] = 'do-not-reply#myemailaddress.com';
}
I tired just the html header and the full set that is commented out. What am I missing? The email sends fine but it's plain text. Thanks and let me know!
You can use this function
function my_module_custom_drupal_mail($target = NULL, $from = null, $subject, $message, $attachment = NULL){
$my_module = 'my_module';
$my_mail_token = microtime();
$message = array(
'id' => $my_module . '_' . $my_mail_token,
'to' => $target,
'subject' => $subject,
'body' => array($message),
'module' => $my_module,
'key' => $my_mail_token,
'from' => "$from <email#email.com>",
'headers' => array(
'From' => "$from <email#email.com>",
'Sender' => "$from <email#email.com>",
'Return-Path' => "$from <email#email.com>",
'Content-Type' => 'text/html; charset=utf-8'
),
);
if ($attachment) {
$file_content = file_get_contents($attachment[0]);
$message['params']['attachments'][] = array(
'filecontent' => $file_content,
'filename' => $attachment[1],
'filemime' => $attachment[2],
);
}
$system = drupal_mail_system($my_module, $my_mail_token);
$message = $system->format($message);
if ($system->mail($message)) {
return TRUE;
}
else {
return FALSE;
}
}
AND call it like :
$body = '<p>Click the link below to reset your password.</p>
<p>Click this link to reset your password</p>
';
$subject ='Why wont this send html??';
$from = 'myemail#email.com';
$sent = my_module_custom_drupal_mail($node->field_email_address['und'][0]['value'], $from, $subject, $body);
Customize it like you want ! :)
A few things need to be done:
/**
* Class SomeCustomModuleMailSystem Implements MailSystemInterface.
*
* Used to enable HTML email to be sent.
*/
class SomeCustomModuleMailSystem extends DefaultMailSystem {
public function format(array $message) {
$message['body'] = implode("\n\n", $message['body']);
$message['body'] = drupal_wrap_mail($message['body']);
return $message;
}
}
This to be done one time, so probably in a hook_enable or hook_update:
$current = variable_get('mail_system', ['default-system' => 'DefaultMailSystem']);
$addition = ['some_custom_module' => 'SomeCustomModuleMailSystem'];
variable_set('mail_system', array_merge($current, $addition));
Invoke hook_mail as normal, e.g.
/**
* Implements hook_mail().
*/
function some_custom_module_mail($key, &$message, $params) {
switch ($key) {
case 'some_mail_key':
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8;';
$message['subject'] = $params['subject'];
$message['body'][] = $params['body'];
break;
}
}
Finally call it with something like this:
// Set variables required for the email.
$module = 'some_custom_module';
$key = 'some_mail_key';
$to = $email = 'thetoaddress#something.com';
$language = language_default();
$params['subject'] = 'Email subject';
$params['body'] = '<html><body>The HTML!</body></html>';
$from = 'thefromaddress#something.com';
$send = TRUE;
// Send the mail and log the result.
$result = drupal_mail($module, $key, $to, $language, $params, $from, $send);
if ($result['result'] === TRUE) {
watchdog('some_custom_module', 'HTML email successfully sent.', [], WATCHDOG_INFO);
}
else {
watchdog('some_custom_module', 'HTML email failed to send', [], WATCHDOG_ERROR);
}
Here is the funcion im using
public function sendCredentialsEmailMessage(UserInterface $user)
{
$template = 'Emails/afterRegister.html.twig';
$rendered = $this->templating->render($template, array(
'user' => $user,
));
$this->sendEmailMessage($rendered,
$this->parameters['from_email']['confirmation'], $user->getEmail());
}
Basically I want the auto-mailer to send my template along with the login name. When i create a new user nothing is being sent. My email template is located in app>resources>views>emails>
and this controller file is located in src>myname>userbundle>mailer>
protected function sendEmailMessage($renderedTemplate, $fromEmail, $toEmail)
{
// Render the email, use the first line as the subject, and the rest as the body
$renderedLines = explode("\n", trim($renderedTemplate));
$subject = array_shift($renderedLines);
$body = implode("\n", $renderedLines);
$message = (new \Swift_Message())
->setSubject($subject)
->setFrom($fromEmail)
->setTo($toEmail)
->setBody($body);
$this->mailer->send($message);
}
Also this works for sure:
public function sendResettingEmailMessage(UserInterface $user)
{
$template = $this->parameters['resetting.template'];
$url = $this->router->generate('fos_user_resetting_reset', array('token' => $user->getConfirmationToken()),
UrlGeneratorInterface::ABSOLUTE_URL);
$rendered = $this->templating->render($template, array(
'user' => $user,
'confirmationUrl' => $url,
));
$this->sendEmailMessageCustom($rendered, $this->from, (string)$user->getEmail(),'Password resseting');
}
I'm working on integrating Twilio with Wordpress and Contact form 7 plugin.
I made a hook for Contact form 7 to send sms with Twilio on form submission. It works.
My next step is to send to different numbers based on the recipient ( I have 3 different location in the contact form 7 and the recipient changes based on the chosen location).
I can't make it work.
Below is my code, any thoughts?
This hook works and sends to 1 number only
add_action( 'wpcf7_mail_sent', 'your_wpcf7_mail_sent_function' );
function your_wpcf7_mail_sent_function() {
$sid = 'xxx';
$token = 'xxx';
$client = new Client($sid, $token);
$to = '+1111111111';
$client->messages->create(
// the number you'd like to send the message to
$to,
array(
'from' =>'+1212121211',
'body' => "form submitted"
)
);
}
This is the second part, I can't make it work.
global $to;
function wpcf7_do_something (&$WPCF7_ContactForm) {
if ($WPCF7_ContactForm->mail['recipient'] = "bla#bla.com") {
$to = '+1XXXXXXXXX';
} else if($WPCF7_ContactForm->mail['recipient'] = "blabla#blabla.com") {
$to = '+1x1x1x1x1x';
} else {
$to = "+1000000000"
}
}
add_action('wpcf7_before_send_mail', 'wpcf7_do_something');
add_action( 'wpcf7_mail_sent', 'your_wpcf7_mail_sent_function' );
function your_wpcf7_mail_sent_function() {
$sid = 'xxxxxxx';
$token = 'xxxxxxx';
$client = new Client($sid, $token);
$client->messages->create(
// the number you'd like to send the message to
$to,
array(
'from' =>'+1XXXXXXXXX',
'body' => "form submitted"
)
);
}
Twilio developer evangelist here.
From what I can tell from other Stack Overflow and Stack Exchange questions, you actually get passed the form to the wpcf7_mail_sent hook, so you don't need the two hooks like you have been trying. Something like the following should work:
add_action( 'wpcf7_mail_sent', 'your_wpcf7_mail_sent_function' );
function your_wpcf7_mail_sent_function($cf7form) {
if ($cf7form->mail['recipient'] = "bla#bla.com") {
$to = '+1XXXXXXXXX';
} else if($cf7form->mail['recipient'] = "blabla#blabla.com") {
$to = '+1x1x1x1x1x';
} else {
$to = "+1000000000"
}
$sid = 'xxx';
$token = 'xxx';
$client = new Client($sid, $token);
$client->messages->create(
// the number you'd like to send the message to
$to,
array(
'from' =>'+1212121211',
'body' => "form submitted"
)
);
}
Let me know if that helps at all.
I'm a Laravel developer. I develop one ecommerce plugin with Laravel and I just want to combine WordPress with Laravel. So I need to share or make common login session between Laravel and WordPress.
How could I implement this? And are there special plugins available for this? Or could I use laravel-Auth?
The right way of doing it is to Have a Laravel (or Wordpress) as an Auth server
And create like an SSO plugin.
I was doing the same with NodeBB Forum login from Laravel.
Steps that I suggest:
Look at this package Laravel OAuth Server
Create or find any SSO plugin for wordpress
So you have all users in laravel (Registration and etc)
and if they want to login to Wordpress they login to Laravel App and give permission to login to wordpress.
Think of it Like you add Facebook Login to your site
Reading more for wordpress SSO
But to play with session and cookies it can be security issues.
Hope Helped.
Enabling Single-Sign-On in WordPress took me 18+ hours of struggle but might take you only a few minutes:
I experimented with all sorts of things: Laravel Passport (OAuth2), OpenID Connect, etc.
But the only solution I could get to work was to have the WordPress login page redirect to an auth-protected Laravel route that generates a JWT (JSON Web Token) and redirects back to a special callback URL on WordPress that either creates a new user or logs in an existing user.
It works well.
class JwtController extends Controller {
/**
* Inspired by https://github.com/WebDevStudios/aad-first-party-sso-wordpress/tree/master/lib/php-jwt
*
* #param Request $request
* #return ResponseInterface
*/
public function redirectWithToken(Request $request) {
$key = config('jwt.key');
$wpJwtUrl = $request->input('callback');
$redirectUrlAfterLogin = $request->input('redirect_to'); //Get the original intended destination and append as URL param to /jwt.
$tokenArray = $this->getToken(auth()->user(), $redirectUrlAfterLogin);
$jwt = \Firebase\JWT\JWT::encode($tokenArray, $key);
$wpJwtUrlWithTokenAsParam = $wpJwtUrl . '?token=' . $jwt;
return redirect()->away($wpJwtUrlWithTokenAsParam);
}
/**
*
* #param \App\User $user
* #param string $redirectUrlAfterLogin
* #return array
*/
public function getToken($user, $redirectUrlAfterLogin) {
$now = \Carbon\Carbon::now();
$aud = config('jwt.audience'); //root URL of the WordPress site
$firstName = StrT::getFirstNameFromFullName($user->name);
$expirationMins = config('jwt.expirationMins');
$token = [
"iss" => url("/"),
"aud" => $aud, //"audience" https://tools.ietf.org/html/rfc7519#section-4.1.3
"iat" => $now->timestamp, //"issued at" https://tools.ietf.org/html/rfc7519#section-4.1.6
"exp" => $now->addMinutes($expirationMins)->timestamp, //"expiration" https://tools.ietf.org/html/rfc7519#section-4.1.4
"attributes" => [
'emailAddress' => $user->email,
'firstName' => $firstName,
'lastName' => StrT::getLastNameFromFullName($user->name),
'nickname' => $firstName,
'displayName' => $user->name,
'redirectUrlAfterLogin' => $redirectUrlAfterLogin//In plugin: use redirectUrlAfterLogin from attributes after login.
]
];
return $token;
}
}
Install this WordPress plugin, but don't activate it until you're finished with everything else: https://wordpress.org/plugins/wp-force-login/
Install this WordPress plugin: https://as.wordpress.org/plugins/jwt-authenticator/
And then edit its auth.php to be this:
// register the callback
add_action('rest_api_init', function () {
register_rest_route('jwt-auth/v1', 'callback', [
'methods' => 'GET',
'callback' => 'ja_login'
], true);
});
require_once('JWT.php');
function ja_login() {
//get all attributes
$options = get_option('ja_settings');
$token_name = $options['token_name'];
$secret_key = $options['secret_key'];
$iss = $options['iss'];
$aud = $options['aud'];
// decode the token
$token = $_GET[$token_name];
$key = $secret_key;
$JWT = new JWT;
$json = $JWT->decode($token, $key);
$jwt = json_decode($json, true);
// use unix time for comparision
$exp = is_int($jwt['exp']) ? $jwt['exp'] : strtotime($jwt['exp']);
$nbf = $jwt['nbf'] ?? null;
$now = strtotime("now");
// if authentication successful
if (($jwt['iss'] == $iss) && ($jwt['aud'] == $aud) && ($exp > $now) && ($now > $nbf)) {
return getUserFromValidToken($options, $jwt);
} else {
return 'Login failed. Please let us know exactly what happened, and we will help you out right away.';
}
}
/**
*
* #param array $options
* #param array $jwt
* #return string
*/
function getUserFromValidToken($options, $jwt) {
$attributesKey = $options['attributes'];
$mail = $options['mail'];
$givenname = $options['first_name'];
$surname = $options['last_name'];
$nickname = $options['nickname'];
$displayname = $options['displayname'];
$default_role = $options['default_role'];
$attributes = $jwt[$attributesKey];
$redirectUrlAfterLogin = $attributes['redirectUrlAfterLogin'] ?? get_site_url();
$_SESSION['attributes'] = $attributes;
$_SESSION['jwt'] = $jwt;
// find or create user
$user = ja_find_or_create_user($attributes[$mail], $attributes[$mail], $attributes[$givenname], $attributes[$surname], $attributes[$nickname], $attributes[$displayname], $default_role);
// login user
if ($user) {
wp_clear_auth_cookie();
wp_set_current_user($user->ID, $user->user_login);
wp_set_auth_cookie($user->ID);
do_action('wp_login', $user->user_login);
wp_safe_redirect($redirectUrlAfterLogin);
exit();
} else {
return 'getUserFromValidToken failed!';
}
}
/**
*
* #param string $username
* #param string $emailAddress
* #param string $firstName
* #param string $lastName
* #param string $nickname
* #param string $displayName
* #param string $defaultRole
* #return mixed
*/
function ja_find_or_create_user($username, $emailAddress, $firstName, $lastName, $nickname, $displayName, $defaultRole) {
// if user exists, return user
if (username_exists($username)) {
return get_user_by('login', $username);
} elseif (email_exists($emailAddress)) {
return get_user_by('email', $emailAddress);
} else {// create user
$length = 16;
$include_standard_special_chars = false;
$random_password = wp_generate_password($length, $include_standard_special_chars);
// create user
$user_id = wp_create_user($username, $random_password, $emailAddress);
// update user metadata and return user id
$userData = [
'ID' => $user_id,
'first_name' => $firstName,
'last_name' => $lastName,
'nickname' => $nickname,
'display_name' => $displayName,
'role' => $defaultRole
];
return wp_update_user($userData);//(If successful, returns the user_id, otherwise returns a WP_Error object.)
}
}
/**
* Get login message link HTML for adding to the login form
* #return string
*/
function getLoginMessage() {
$options = get_option('ja_settings');
$redirect_to = $_GET['redirect_to'] ?? null;
$login_url = $options['login_url'] . '?callback=' . urlencode(site_url('/wp-json/jwt-auth/v1/callback'));
if($redirect_to){
$login_url .= '&redirect_to=' . urlencode($redirect_to);
}
$login_message = $options['login_message'];
return "<a id='jwt_link' href='{$login_url}'>{$login_message}</a>";
}
add_filter('login_message', 'getLoginMessage');
add_action( 'load-profile.php', function() {//https://wordpress.stackexchange.com/a/195370/51462 Redirect from profile.php to the dashboard since there is no reason for WordPress users to see or manage their profile since their main account is on the other site.
if( ! current_user_can( 'manage_options' ) ){
$redirectUrl = get_site_url();//admin_url()
exit( wp_safe_redirect( $redirectUrl ) );
}
} );
function show_admin_bar_conditionally(){//remove the WordPress admin toolbar https://premium.wpmudev.org/blog/remove-the-wordpress-admin-toolbar/
return current_user_can( 'manage_options' );
}
add_filter('show_admin_bar', 'show_admin_bar_conditionally');//can use 'show_admin_bar_conditionally' or '__return_false' for never.
//------------------------------------------------------------------
//for https://wordpress.org/support/topic/rest-api-26/#post-9915078
//and https://github.com/kevinvess/wp-force-login/issues/35
//and https://wordpress.org/support/topic/rest-api-26/page/2/#post-10000740
//and https://wordpress.org/support/topic/jwt-authentication/#post-10698307
add_filter( 'rest_authentication_errors', '__return_true' );
This belongs in functions.php of your theme in WordPress:
// https://codex.wordpress.org/Customizing_the_Login_Form
function my_custom_login_page() { ?>
<style type="text/css">
#loginform, #login #nav{display: none;}
#jwt_link{font-weight: bold; font-size: 20px;}
</style>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
document.getElementById('jwt_link').click();//immediately upon load of login page, click the JWT link automatically
});
</script>
<?php }
add_action( 'login_enqueue_scripts', 'my_custom_login_page' );
I got this code that was working fine until WP 3.5.1 upgrade. Now it doesn't display anything, and I can't figure it out.
When I put inn the shortcode in admin panel the resulting post or page doesn't display anything. Not even the raw shortcode?
Basically this code display expiring links for amazon s3 content to prevent leaching.
define('FPEAS3', __FILE__);
define('FPEAS3_DIR', dirname(__FILE__));
#define('FPEAS3_AWS_S3_ACCESS_ID', '');
#define('FPEAS3_AWS_S3_SECRET', '');
add_action('init', 'fpeas3_init');
function fpeas3_init() {
add_shortcode('s3', 'fpeas3_shortcode');
}
function fpeas3_shortcode($atts, $content = null) {
extract(shortcode_atts(array(
'expires' => '5',
'bucket' => '',
'path' => ''
), $atts));
if (!$content = trim($content)) {
$content = 'Download';
}
$keys = array(
'access_id' => get_post_meta(get_the_ID(), 'aws_s3_access_id', true),
'secret' => get_post_meta(get_the_ID(), 'aws_s3_secret', true)
);
if (empty($keys['access_id']) || empty($keys['secret'])) {
$keys = fpeas3_get_static_keys();
}
if (empty($keys['access_id']) || empty($keys['secret'])) {
$error = "Expiring Amazon S3 Links not setup correctly: missing Access ID or Secret.";
error_log($error);
if (current_user_can('admin')) {
return $error;
} else {
return '';
}
}
return sprintf('<a rel="nofollow" href="%s" class="s3-temp-link">%s</a>',
fpeas3_get_temporary_link($keys['access_id'], $keys['secret'], $bucket, $path, $expires), $content);
}
function fpeas3_get_static_keys() {
return array(
'access_id' => FPEAS3_AWS_S3_ACCESS_ID,
'secret' => FPEAS3_AWS_S3_SECRET
);
}
/**
* Calculate the HMAC SHA1 hash of a string.
* #param string $key The key to hash against
* #param string $data The data to hash
* #param int $blocksize Optional blocksize
* #return string HMAC SHA1
*/
function fpeas3_crypto_hmacSHA1($key, $data, $blocksize = 64) {
if (strlen($key) > $blocksize) $key = pack('H*', sha1($key));
$key = str_pad($key, $blocksize, chr(0x00));
$ipad = str_repeat(chr(0x36), $blocksize);
$opad = str_repeat(chr(0x5c), $blocksize);
$hmac = pack( 'H*', sha1(
($key ^ $opad) . pack( 'H*', sha1(
($key ^ $ipad) . $data
))
));
return base64_encode($hmac);
}
/**
* Create temporary URLs to your protected Amazon S3 files.
* #param string $accessKey Your Amazon S3 access key
* #param string $secretKey Your Amazon S3 secret key
* #param string $bucket The bucket (bucket.s3.amazonaws.com)
* #param string $path The target file path
* #param int $expires In minutes
* #return string Temporary Amazon S3 URL
* #see http://awsdocs.s3.amazonaws.com/S3/20060301/s3-dg-20060301.pdf
*/
function fpeas3_get_temporary_link($accessKey, $secretKey, $bucket, $path, $expires = 5) {
// Calculate expiry time
$expires = time() + intval(floatval($expires) * 60);
// Fix the path; encode and sanitize
$path = str_replace('%2F', '/', rawurlencode($path = ltrim($path, '/')));
// Path for signature starts with the bucket
$signpath = '/'. $bucket .'/'. $path;
// S3 friendly string to sign
$signsz = implode("\n", $pieces = array('GET', null, null, $expires, $signpath));
// Calculate the hash
$signature = fpeas3_crypto_hmacSHA1($secretKey, $signsz);
// Glue the URL ...
$url = sprintf('http://%s.s3.amazonaws.com/%s', $bucket, $path);
// ... to the query string ...
$qs = http_build_query($pieces = array(
'AWSAccessKeyId' => $accessKey,
'Expires' => $expires,
'Signature' => $signature,
));
// ... and return the URL!
$tempUrl = $url.'?'.$qs;
return $tempUrl;
}
Ok, So I looked at this code again with fresh eyes. And I got it to work I think. Still testing some things.
I changed this line of code very slightly:
**return** sprintf('<a rel="nofollow" href="%s"
class="s3-temp-link">%s</a>',
fpeas3_get_temporary_link($keys['access_id'], $keys['secret'], $bucket, $path, $expires), $content);
Changed to:
**echo** sprintf('<a rel="nofollow" href="%s" class="s3-temp-link">%s</a>',
fpeas3_get_temporary_link($keys['access_id'], $keys['secret'], $bucket, $path, $expires), $content);
I'm not a programmer, but after some digging I found there are various ways to display the output.
Any opinions on if this is good way to code it?