How to get user activation URL in wordpress? - wordpress

for the following code:
add_action( 'user_register', 'my_user_register', 10, 1 );
function my_user_register($user_id){
// how do i get user activation url
// todo: send user an activation email
}
I want to send an activation email to user, but I don't know how to get the activation url. Please advice.

you can send email activation link like this.
global $theme_settings;
$hidDiv="none";
$login_page_url = get_permalink($theme_settings['userlogin_page']);
$home_url = get_option('siteurl');;
$firstname = sanitize_text_field($_POST['firstname']);
$username = sanitize_text_field($_POST['email']);
$password = sanitize_text_field($_POST['password']);
$email = sanitize_text_field($_POST['email']);
$lastname = $_POST['lastname'];
$company = $_POST['company'];
$city = $_POST['city'];
$state = $_POST['state'];
$zipcode = $_POST['zipcode'];
$mailemail = $_POST['mailingaddress'];
$user_id = wp_create_user( $username, $password, $email );
if ( is_wp_error( $user_id ) ) {
$error_string = $user_id->get_error_message();
}else
{
theme_user_register($user_id);
$thanks_msg_page_url = get_permalink($theme_settings['userthanks_page']);
$trackcode = get_user_meta($user_id, 'p_user_registration_code', true);
$site_name = get_option('blogname');
$track_url = get_option('siteurl').'/confirmation?trackid='.$user_id.'&trackcode='.$trackcode;
$headers = "MIME-Version: 1.0";
$headers .= "Content-Type: text/html; charset=UTF-8";
$headers .= "From: $site_name < $from >" . "\r\n";
$message = "<p> Hello ".$username;
$message.="<p>Thank you for registering with us. Please click on the below link or copy and paste to the browser to activate your account.</p>";
$message.="<p> $track_url</p><br>Best Regards,<br>Support Team";// Need to change this
$from = get_option('admin_email');
$site_name = get_option('blogname');
wp_mail($email, 'Registration Confirmation', $message, $headers,'');
$thanks_msg_page_url = get_permalink(theme_settings['userthanks_page']);
wp_redirect($thanks_msg_page_url);
exit;
}

I am not sure if I understand why you want to get activation URL through coding, unless of course if you want to customize the default new user notification email sent by WordPress.
If you simply want to customize the Notification Email sent to the New User upon successful User Registration then you should use Filters wp_new_user_notification_email - customise email sent to User and/or wp_new_user_notification_email_admin - customise email sent to Admin.
Both these functions are in "wp-includes/pluggable.php". The filter definitions are as follows...
/**
* Filters the contents of the new user notification email sent to the site admin.
*
* #since 4.9.0
*
* #param array $wp_new_user_notification_email {
* Used to build wp_mail().
*
* #type string $to The intended recipient - site admin email address.
* #type string $subject The subject of the email.
* #type string $message The body of the email.
* #type string $headers The headers of the email.
* }
* #param WP_User $user User object for new user.
* #param string $blogname The site title.
*/
$wp_new_user_notification_email_admin = apply_filters( 'wp_new_user_notification_email_admin', $wp_new_user_notification_email_admin, $user, $blogname );
... and ...
/**
* Filters the contents of the new user notification email sent to the new user.
*
* #since 4.9.0
*
* #param array $wp_new_user_notification_email {
* Used to build wp_mail().
*
* #type string $to The intended recipient - New user email address.
* #type string $subject The subject of the email.
* #type string $message The body of the email.
* #type string $headers The headers of the email.
* }
* #param WP_User $user User object for new user.
* #param string $blogname The site title.
*/
$wp_new_user_notification_email = apply_filters( 'wp_new_user_notification_email', $wp_new_user_notification_email, $user, $blogname );
The typical filter function code block looks like this...
function custom_wp_new_user_notification_email( $wp_new_user_notification_email, $user, $blogname ) {
$wp_new_user_notification_email['subject'] = 'Your Subject';
$wp_new_user_notification_email['message'] = 'Your Email Message';
return $wp_new_user_notification_email;
}
Inside the add_filter functions for these filters, you can get the User specific information using the $user passed to the filter function, like...
$user_name = $user->user_login;
$user_email = $user->user_email;
Using the $user object, you can get the User information and build your own activation link.
Again, I am not sure if I've followed the motive behind this question correctly; but this is the path I will follow if I'm at this sort of stuff to implement.

Related

how to send scheduled emails with sendGrid and symfony

I'm building an application with symfony3 in which I have an EmailService basin on SendGridService.
Sending emails is okay, but I want to schedule my emails.
This is SendGridEmailService :
<?php
namespace AppBundle\Services;
use SendGrid;
use Swift_Attachment;
use Swift_Mailer;
use Swift_Message;
use Swift_SmtpTransport;
use Twig_Environment;
class SendGirdEmailService
{
/**
* Library to facilitate email messages being sent out, sendMail deprecated in symfony 1.2
*
* #param string $partial - Array with html and text partials ie array('text'=>'textPartial', 'html'=>'htmlPartial')
* #param array $parameters - Array we will pass into the partials
* #param string $mailFrom - Email source
* #param string $mailTo - Email destination
* #param string $subject - The subject of the email message
* #param array $sgHeaders - What we will be placing in the SMTPAPI header. Must be null or a non-empty array
* #param array $attachments - Email contains the attachments
*/
public static function sendEmail($partials, $parameters, $mailFrom, $mailTo, $subject, $sgHeaders = null, $attachments = null)
{
// verify we have username/password to send out emails - IMPORTANT
/* if (!sfconfig::has('app_sendgrid_username') or !sfconfig::has('app_sendgrid_password')) {
throw new sfException('SMTP username/password is required to send email out');
}*/
$text = null;
$html = null;
if (is_array($partials)) {
// load libraries
//sfContext::getInstance()->getConfiguration()->loadHelpers('Partial');
if (isset($partials['text'])) {
$text = $partials['text'];
}
if (isset($partials['html'])) {
$html = $partials['html'];
}
}
if ($text === null and $html === null) {
throw new sfException('A text and/or HTML partial must be given');
}
try {
/*
* Load connection for mailer
*/
$connection = Swift_SmtpTransport::newInstance('smtp.sendgrid.net', 465, 'ssl')->setUsername('xxxxxx')->setPassword('xxxxxxx');
// setup connection/content
$mailer = Swift_Mailer::newInstance($connection);
$message = Swift_Message::newInstance()->setSubject($subject)->setTo($mailTo);
if ($text and $html) {
$message->setBody($html, 'text/html');
$message->addPart($text, 'text/plain');
} else if ($text) {
$message->setBody($text, 'text/plain');
} else {
$message->setBody($html, 'text/html');
}
// if contains SMTPAPI header add it
if (null !== $sgHeaders) {
$message->getHeaders()->addTextHeader('X-SMTPAPI', json_encode($sgHeaders));
}
// update the from address line to include an actual name
if (is_array($mailFrom) and count($mailFrom) == 2) {
$mailFrom = array(
$mailFrom['email'] => $mailFrom['name']
);
}
// add attachments to email
if ($attachments !== null and is_array($attachments)) {
foreach ($attachments as $attachment) {
$attach = Swift_Attachment::fromPath($attachment['file'], $attachment['mime'])->setFilename($attachment['filename']);
$message->attach($attach);
}
}
// Send
$message->setFrom($mailFrom);
$mailer->send($message);
}
catch (Exception $e) {
throw new sfException('Error sending email out - ' . $e->getMessage());
}
}
}
And this is the function I'm using to send my emails:
SendGirdEmailService::sendEmail(array(
'text' => $htmlContent,
'html' => $htmlContent
),
null,
$this->from,
$to,
$subject,
$sgHeaders = null,
$attachments = null
);
How can I set the parameters to send emails after one hour for example?
I found solution by setting an array with 'sent_at' index with timestamp value like :
SendGirdEmailService::sendEmail(array(
'text' => $htmlContent,
'html' => $htmlContent,
),
null,
$this->from,
$to,
$subject,
$sgHeaders =
array('send_at' => strtotime('+1 day', date_timestamp_get(new \DateTime()) ) ),
$attachments = null
);

Do not send Woocommerce new customer email if a condition is true

If i add a new customer to Woo using the REST API i need to avoid sending the new customer email.
The REST API docs don't talk about this and there's no parameter to set that can prevent the "WC_Email_Customer_New_Account" email
I've tried about 10 different things, I'll list the most recent ones
Editing the Woo source directly class-wc-emails.php. Not even that works, because when i collect the user meta it's still blank and only has the user ID and nice name
Creating a plugin that checks an external API and if a condition is met does remove_action('woocommerce_created_customer_notification', array($email_class->emails['WC_Email_Customer_New_Account'], 'trigger'));
Processing everything inside the plugin but i have the same problem as 1.
I think I managed to pull it off. My goal was to create a user (customer) via WooCommerce REST API (Customers endpoint) and not to trigger the New Account email.
The first suspect is the woocommerce_email_enabled_customer_new_account filter. It gives us the \WP_User and \WC_Email_Customer_Completed_Order objects. The first idea obviously is to just run get_user_meta() against the user.
add_filter( 'woocommerce_email_enabled_customer_new_account', function( $enabled, $user, $email ) {
/**
* #var bool $enabled
* #var \WP_User $user
* #var \WC_Email_Customer_Completed_Order $email
*/
$isOurGuy = 'foobar' === get_user_meta( $user->ID, 'meta_key_is_so_meta', true );
if ( $isOurGuy ) {
return false;
}
return $enabled;
}, 10, 3 );
As it turns out, the REST endpoint handler can only push metadata after the user is created, and email notification is triggered implicitly via a hook in \WC_Emails(). It means when our code is running during that email hook, no metadata is available yet.
Next thing to check was to go to the moment before the user is pushed anywhere at all. That would be woocommerce_before_data_object_save, an action this time. It gives us two objects, \WC_Customer and \WC_Customer_Data_Store. The \WC_Customer object has our metadata, yay! Let's enclose the existing code into another handler.
add_action( 'woocommerce_before_data_object_save', function( $customer, $store ) {
/**
* #var \WC_Customer $customer
* #var \WC_Customer_Data_Store $store
*/
if ( !( $customer instanceof \WC_Customer ) ) { // I guess other object types may end up here, let's make sure we only get to work with customers.
return;
}
$isOurGuy = 'foobar' === $customer->get_meta( 'meta_key_is_so_meta', true );
if ( !$isOurGuy ) {
return;
}
add_filter( 'woocommerce_email_enabled_customer_new_account', function( $enabled, $user, $email ) use ( $customer ) {
/**
* #var bool $enabled
* #var \WP_User $user
* #var \WC_Email_Customer_Completed_Order $email
*/
if ( $customer->get_id() !== $user->ID ) { // Is it our guy?
return $enabled;
}
return false;
}, 10, 3 );
}, 10, 2 );
It still does not work. Because this is before object save, the user did not exist at the moment when we captured $customer into our scope. So $customer->get_id() returns 0 (zero). It seems that we overshot in time a bit - need to roll forward. woocommerce_created_customer seems like a good candidate. It gives us among other things the new user ID.
Let's compile everything together.
add_action( 'woocommerce_before_data_object_save', function( $customer, $store ) {
/**
* #var \WC_Customer $customer
* #var \WC_Customer_Data_Store $store
*/
if ( !( $customer instanceof \WC_Customer ) ) { // I guess other object types may end up here, let's make sure we only get to work with customers.
return;
}
$isOurGuy = 'foobar' === $customer->get_meta( 'meta_key_is_so_meta', true );
if ( !$isOurGuy ) {
return;
}
/**
* Hook into the Customer Created event to capture the new customer ID.
*/
add_action( 'woocommerce_created_customer', function( $customerId ) {
add_filter( 'woocommerce_email_enabled_customer_new_account', function( $enabled, $user, $email ) use ( $customerId ) {
/**
* #var bool $enabled
* #var \WP_User $user
* #var \WC_Email_Customer_Completed_Order $email
*/
if ( $customerId !== $user->ID ) { // Is it our guy?
return $enabled;
}
return false;
}, 10, 3 );
}, 1 ); // NB: Email is also hooked here with priority 10.
}, 10, 2 );
Now let's recap. We hook into the data store and capture the moment a \WC_Customer object is saved. We perform custom metadata-based logic to decide whether to proceed. Then we skip to the moment when the user is created to retrieve their ID. Then we hop a little further in time during the "email enabled?" check to actually disable the notification for the given user.
Try this
Go to:
WooCommerce -> Settings -> Email tab
You can find the Options are "New account". Click the manage button.
Uncheck the "Enable this email notification".

Get multiple post thumbnail image title or description in Wordpress

Got multiple featured images in a post and need the description of all or title of all in the loop.
Function to get description
/**
* Retrieve Post Thumbnail Description.
*
* #param string $post_type The post type.
* #param string $id The id used to register the thumbnail.
* #param int $post_id Post ID.
* #return string
*/
public static function the_post_thumbnail_description($post_type, $id, $post_id) {
$post_id = (NULL === $post_id) ? get_the_ID() : $post_id;
$postThumbnailID = get_post_meta($post_id, "{$post_type}_{$id}_thumbnail_id", true);
$description = get_post($postThumbnailID)->post_content;
echo $description;
}
Below is the statement to call this function
MultiPostThumbnails::the_post_thumbnail_description(get_post_type(), 'feature-image-'.$i.'', Null).'<br>';

Woocommerce call url (after complete order)

I have 3 questions (need help):
I do not know, how to run this plugin (gives me fatal error) please check my script (I am beginner)
Need help with admin page to set up APIkey and choose language for call url http://xxx.CZ or http://xxx.SK (This page is not scripted yet)
How to add my plugin admin page to woocommerce admin page?
This plugin is for Woocommerce. It is supposed to call specific URL (http://heureka.cz/or .sk/dotaznik/"Clients API set up in admin page in woocommerce"/"Customers email"/"Order ID"/"bought Products ID"/) when customers order si complete.
I am beginner in PHP and Wordpress. Thank you all for helping me.
CODE:
<?php
/*
Plugin Name: Overené zákazníkmi Heureka
Plugin URI: http://www.podujatie.eu
Version: 0.1
Description:
Author: Podujatie.eu, Ing. Igor Kóňa
Tested up to: 3.6
Author URI: http://www.podujatie.eu
Text Domain: woocommerce-new-badge
License: GNU General Public License v3.0
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
/**
* Check if WooCommerce is active
**/
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
if ( ! class_exists( 'WC_HO' ) ) {
class WC_HO {
function heurekaovereno( $order_id ) {
error_log( "Order complete for order $order_id", 0 ); }
add_action( 'woocommerce_order_status_completed', 'heurekaovereno' );
// order object (optional but handy)
$order = new WC_Order( $order_id );
// do some stuff here
private function sendRequest($url)
{
$parsed = parse_url($url);
$fp = fsockopen($parsed['host'], 80, $errno, $errstr, 5);
if (!$fp) {
throw new HeurekaOverenoException($errstr . ' (' . $errno . ')');
} else {
$return = '';
$out = "GET " . $parsed['path'] . "?" . $parsed['query'] . " HTTP/1.1\r\n" .
"Host: " . $parsed['host'] . "\r\n" .
"Connection: Close\r\n\r\n";
fputs($fp, $out);
while (!feof($fp)) {
$return .= fgets($fp, 128);
}
fclose($fp);
$returnParsed = explode("\r\n\r\n", $return);
return empty($returnParsed[1]) ? '' : trim($returnParsed[1]);
}
}
/**
* Sends request to Heureka Overeno service and checks for valid response
*
* #return boolean true
*/
public function send()
{
if (empty($this->email)) {
throw new HeurekaOverenoException('Customer email address not set');
}
// create URL
$url = $this->getUrl() . '?id=' . $this->apiKey . '&email=' . urlencode($this->email);
foreach ($this->products as $product) {
$url .= '&produkt[]=' . urlencode($product);
}
foreach ($this->productsItemId as $itemId) {
$url .= '&itemId[]=' . urlencode($itemId);
}
// add order ID
if (isset($this->orderId)) {
$url .= '&orderid=' . urlencode($this->orderId);
}
// send request and check for valid response
$contents = $this->sendRequest($url);
if ($contents == FALSE) {
throw new HeurekaOverenoException('Unable to create HTTP request to Heureka Overeno service');
} elseif ($contents == self::RESPONSE_OK) {
return TRUE;
} else {
throw new HeurekaOverenoException($contents);
}
}
/**
* Adds ordered products using item ID
*
* #param string $itemId Ordered product item ID
*/
public function addProductItemId($itemId)
{
$this->productsItemId[] = $itemId;
}
/**
* Adds ordered products using name
*
* Products names should be provided in UTF-8 encoding. The service can handle
* WINDOWS-1250 and ISO-8859-2 if necessary
*
* #param string $productName Ordered product name
*/
public function addProduct($productName)
{
$this->products[] = $productName;
}
/**
* Heureka endpoint URL
*
* #var string
*/
const BASE_URL = 'http://www.heureka.cz/direct/dotaznik/objednavka.php';
const BASE_URL_SK = 'http://www.heureka.sk/direct/dotaznik/objednavka.php';
/**
* Language IDs
*
* #var int
*/
const LANGUAGE_CZ = 1;
const LANGUAGE_SK = 2;
/**
* Valid response value
*
* #var string
*/
const RESPONSE_OK = 'ok';
/**
* Shop API key
*
* #var string
*/
private $apiKey;
/**
* Customer email
*
* #var string
*/
private $email;
/**
* Ordered products
*
* #var array
*/
private $products = array();
/**
* Order ID
*
* #var int
*/
private $orderId;
/**
* Current language identifier
*
* #var int
*/
private $languageId = 1;
/**
* Ordered products provided using item ID
*
* #var array
*/
private $productsItemId = array();
/**
* Initialize Heureka Overeno service
*
* #param string $apiKey Shop API key
* #param int $languageId Language version settings
*/
public function __construct($apiKey, $languageId = self::LANGUAGE_CZ)
{
$this->setApiKey($apiKey);
$this->languageId = $languageId;
}
/**
* Sets API key and check well-formedness
*
* #param string $apiKey Shop api key
*/
public function setApiKey($apiKey)
{
if (preg_match('(^[0-9abcdef]{32}$)', $apiKey)) {
$this->apiKey = $apiKey;
} else {
throw new OverflowException('Api key ' . $apiKey . ' is invalid.');
}
}
/**
* Sets customer email
*
* #param string $email Customer email address
*/
public function setEmail($email)
{
$this->email = $email;
}
// Default options
add_option( 'wc_nb_newness', '30' );
// Admin
add_action( 'woocommerce_settings_image_options_after', array( $this, 'admin_settings' ), 20);
add_action( 'woocommerce_update_options_catalog', array( $this, 'save_admin_settings' ) );
/*-----------------------------------------------------------------------------------*/
/* Class Functions */
/*-----------------------------------------------------------------------------------*/
// Load the settings
function admin_settings() {
woocommerce_admin_fields( $this->settings );
}
// Save the settings
function save_admin_settings() {
woocommerce_update_options( $this->settings );
}
if (!isset($wpdb)) $wpdb = $GLOBALS['wpdb'];
$heurekaovereno_ver = '1.00';
$WC_HO = new WC_HO();
}
}
}
?>
This script works (it has few bugs, but it works) only when you put it in functions.php
Here is where I am asking, why is it.

Wordpress - GD Star Rating - Set Rating after wp_insert_post

is it possbile to rate the new post (with admin account) after this?
$post_id = wp_insert_post( $my_post, $wp_error );
According to this post of the Wordpress support forum, what you should do is something like this:
function set_rating($post_id, $vote) { // $vote = 0..10
$admin = get_user_by('login', 'admin');
if ($admin !== false) {
$ip = $_SERVER['SERVER_ADDR'];
$ua = $_SERVER['HTTP_USER_AGENT'];
gdsrBlgDB::save_vote($post_id, $admin->ID, $ip, $ua, $vote);
}
return $admin;
}
You need to add a hook after that happens. First write a function and then this:
add_action('wp_insert_post', 'set_star_rating');
function set_star_rating() {
global $post;
$post = ...
}
There is also save_posts hook which happens while you're saving the post and is better documented.
This may be useful for doing some custom development based on GD Star Rating Plugin. Find my functions to 'save post like', to get 'like count for a post' and to 'check whether current user liked a post'. This is working for custom Post Types as well.
/**
* Function to save post like
* #param type $post_id
* #param type $user_id
*/
function save_post_like($post_id, $user_id) {
$ip = $_SERVER['SERVER_ADDR'];
$ua = $_SERVER['HTTP_USER_AGENT'];
if(has_user_liked_post($post_id) == 0)
gdsrBlgDB::save_vote_thumb($post_id, $user_id, $ip, $ua, 1);
}
/**
* Function to check if user like the post
* #global type $wpdb
* #global type $table_prefix
* #param type $post_id
* #return type
*/
function has_user_liked_post($post_id) {
global $wpdb, $table_prefix;
$userdata = wp_get_current_user();
$user_id = is_object($userdata) ? $userdata->ID : 0;
$sql = "SELECT * FROM " . $table_prefix . "gdsr_votes_log WHERE vote_type = 'artthumb' AND id = " . $post_id . " AND user_id = " . $user_id;
$results = $wpdb->get_row($sql, OBJECT);
if (count($results))
return 1;
else
return 0;
}
/**
* Function to get total Likes of a Post
* #global type $wpdb
* #global type $table_prefix
* #param type $post_id
* #return type
*/
function get_post_like_count($post_id) {
global $wpdb, $table_prefix;
$sql = "SELECT * FROM " . $table_prefix . "gdsr_data_article WHERE post_id = " . $post_id;
$results = $wpdb->get_row($sql, OBJECT);
if (count($results))
return $results->user_recc_plus;
else
return 0;
}

Resources