Wordpress - Create custom shortcodes for emails - mysql

I use a custom emailer that alerts me whenever a new user signs up to my wordpress members site. The shortcodes that i am currently able to include within my emails are:
[name] = Displays user name.
[username] = Displays user username.
[password] = Displays user password.
[first_name] = Displays user first name.
[last_name] = Displays user last name.
[email] = Displays the user email.
[admin_email] = Displays the admin email.
[blogname] = Displays the blog anme.
[siteurl] = Displays site url.
[loginurl] = Displayslogin url.
[login_url] = Displays login url.
[passwordlink] = Displays password reset link.
[reason] = Displays the reason.
[expire_date] = Displays user expire date.
[post_title] = Displays the purchase post title.
[purchase_cost] = Displays the purchase post cost.
[amount] = Displays the membership amount.
[currency_sign] = Displays the currency symbol.
[membership_type] = Displays the membership type.
I would like to include the following wp_usermeta info within the emails to so want to setup another custom shortcode for these emails:
_mgm_cf_show_details_in_member_directory
How would i tell wordpress to echo this information in a new shortcode, something like [member-directory].
Upon registration, user's enter yes or no for this question so i want the email alert to tell me whether they have chosen Yes or No.
I hope that all makes sense, thanks again guys.

Without looking at the code, I can't give you a definitive answer, but;
It should be as simple as adding in a new array key to the outputting array.
There will be something somewhere that sends the short codes to the the emails, and that will be an object, something like:
$return['name'] = $user->name;
and you just need to add something like:
$return['member-directory'] = $user->_mgm_cf_show_details_in_member_directory
something along those lines should get you there

Related

How do I use a google apps script to auto fill a google form with info taken from the user? [duplicate]

With the recent study-from-home dynamics hastly implemented by budget schools, I am now facing a mindless-robot-like-task of filling in attendance for my kids everyday multiple times per child. The school shared this form:
I, being a developer, want to create a UI and have my kids submit thier attendance to this form on thier own when the teacher asks for one over Zoom. Ids it possible? I'm a .Net developer and have not developed anything for Office 365 Online and have no idea where to start looking for Google.
It is possible by reconstructing the form URL with pre-filled values.
In the Google Form, each question is named internally with "entry.". For each of the question, you need to find the entry number and assign them the right values and add it to the URL parameters like in the below image:
(Edited Oct 2021: The ids are no longer found in the name attribute of each input field in the HTML as shown in the image. They are now located in a div within the form element. #hdrz's answer below to look in the Javascript present just at the end of the body tag is now also defunct.)
I've recreated your form here https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/viewform
And here is the reconstructed URL with prefill values
https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/viewform?entry.1475351979=Julia&entry.280503419=Andrews&entry.519373518=4&entry.301819105=E
Hope it helps
As #AHunt writes, the entry number used to be in a name attribute on the form fields. As of this answer time, I can no longer find the name attribute on any of the form fields. However, now there is a script tag at the end of the body tag, with a short javascript code, and in it you can find the entry numbers, see here:
Also, it is possible to submit the form directly with pre-filled values. Just replace viewform in the URL with formResponse.
Similar URL as in the accepted answer, but now it will be submitted at once. Note that all required fields have to be filled!
https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/formResponse?entry.1475351979=Julia&entry.280503419=Andrews&entry.519373518=4&entry.301819105=E&entry.1124370742=Art
I think I may be late but still give you a solution. I had made similar script to send my school attendance.
Every field in Google Forms is associated with a entry.<id>. You have two ways to automate the form.
One way is to extract those IDs with and make a dictionary where entry.<id> is the key and your answer is the value.Then you have to send a POST request to the form URL with the dictionary as the data. You have automated the form.
To extract the IDs, inspect the html code and look at the <script> at the (very) end of the page. It lòoks something like this :
var FB_PUBLIC_LOAD_DATA_ = [null,[null,[[2030831236,"First Name (in English)",null,0,[[1475351979,null,1]
]
]
,[86681139,"Last Name (in English)",null,0,[[280503419,null,1]
]
]
,[836880978,"Grade",null,2,[[519373518,[["KG 1",null,null,null,0]
,["KG 2",null,null,null,0]
,["1",null,null,null,0]
,["2",null,null,null,0]
,["3",null,null,null,0]
,["4",null,null,null,0]
,["5",null,null,null,0]
,["6",null,null,null,0]
,["7",null,null,null,0]
,["8",null,null,null,0]
,["9",null,null,null,0]
,["10",null,null,null,0]
,["11",null,null,null,0]
,["12",null,null,null,0]
]
,1,null,null,null,null,null,0]
]
]
,[221348070,"Section",null,2,[[301819105,[["A",null,null,null,0]
,["B",null,null,null,0]
,["C",null,null,null,0]
,["D",null,null,null,0]
,["E",null,null,null,0]
,["G",null,null,null,0]
]
,1,null,null,null,null,null,0]
]
]
,[366027193,"Subject",null,2,[[1124370742,[["Math",null,null,null,0]
,["Science",null,null,null,0]
,["English",null,null,null,0]
,["Arabic",null,null,null,0]
,["Islamic",null,null,null,0]
,["Social",null,null,null,0]
,["Moral",null,null,null,0]
,["Art",null,null,null,0]
,["Computer",null,null,null,0]
,["French",null,null,null,0]
,["Physics",null,null,null,0]
,["Chemistry",null,null,null,0]
,["Biology",null,null,null,0]
,["Business",null,null,null,0]
]
,1,null,null,null,null,null,0]
]
]
]
,null,null,[null,null,null,null,null,[null,null,null,[3,169,244,null,1]
,[217,242,253,null,1]
]
]
,null,null,null,"Attendance Form",48,null,null,null,null,null,[2]
]
As you can see there are two numbers with each field. One of them is the ID and another one I don't know. The second number is the ID we need. Using RegEx we can extract all the numbers and collect every second number in a list. This list will contain all the IDs.
Another way, as stated by others, is to reconstruct the URL with prefilled values. But in this too you have to extract the IDs.
I have included both of them in one and made this script :
import requests
from bs4 import BeautifulSoup
import re
def get_questions(url):
page = requests.get(url)
soup = BeautifulSoup(page.content, 'html.parser')
content = soup.body.find_all(text = re.compile('var FB'))
match = re.findall('[,]["][\w\s]+["][,]', str(content))
#It will match all the questions in the form
question_strings = [x.strip('"') for x in match]
match_ids = re.findall('(?<=\[\[)(\d+)', str(content))
#It will find all the numbers in the content
question_ids = ['entry.' + x for x in match_ids[1:]]
#It will leave the first numbers (they are not the ids)
return question_ids
# Below are only for when you want to know the form fills with their corresponding entry ids
# questions = dict(zip(question_strings, question_ids))
# return questions
def send_answers(url, fname, lname, grade, section, subject): #arrange this as per your form requirements
ids = get_questions(url)
answers = [fname, lname, grade, section, subject]
response = dict(zip(ids, answers))
if 'viewform' in url:
s = url.index('viewform')
response_url = url.replace(url[s::], 'formResponse?')
try:
r = requests.post(response_url, response)
if r.status_code == 200:
return '[!] Attendence posted !'
#In case an error happens, it will raise an exception
else:
raise Exception
#After raising the exception it will retry to submit using url reconstruction with prefilled values
except:
try:
ans_list = [x + '=' + y for x, y in zip(ids, answers)]
for i in range(0, len(ans_list)):
response_url += ans_list[i]
response_url += '&'
response_url.strip("&")
r = requests.get(response_url)
status = r.status_code
if status == 200:
return '[!] Attendance sent !'
else:
raise Exception
#If still an error happens, it will print out a message.
except:
return '[!] Attendance not sent !'
url = 'Form URL here'
fname = 'Your first name here'
lname = 'Your last name here'
grade = 'Your grade here'
section = 'Section here'
subject = 'Enter subject'
print(send_answers(url, fname, lname, grade, section, subject))
Hope it helps. Sorry for my bad English.
As a Google Form editor you can get a pre-filled URL (complete with entry values) by choosing the 'Get pre-filled link' option at the top right of the page, after clicking the three dots.
This will open the form in a new tab. The Submit (or Next) button will be replaced with a 'Get link' button.
After filling in the desired form responses, clicking 'Get link' will open a preview of what users will see. If everything is correct, clicking the 'COPY LINK' button (at the bottom left of page) will provide the URL.
The URL will look like this:
https://docs.google.com/forms/d/e/yourFormidhere/viewform?usp=pp_url&entry.1890935147=exampleprefilledvalue1&entry.1928475566=exampleprefilledvalue2&entry.2145528193=exampleprefilledvalue3
You can find the IDs in the console development section of Chrome.
Fill the form open networks tabs.
You can find the ID of each query in the form.
Easiest way is to simply launch Developer Tools (F12 or Ctrl+Shift+I usually) and go to the Network tab. Enable "Preserve log". Then just submit your form as usual, with the values you want (or test values).
In the Network tab, type "formResponse" in the filter bar. Find the latest entry and select it. Then go to Payload tab and click "view source". You should see something like this.
The text you see in the form data is simply what your append to the link of your form plus a '?' (question mark). So in this case our link will be https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/viewform?entry.1475351979=test&entry.280503419=test&entry.519373518=KG+1&entry.1124370742=French&entry.301819105=A&dlut=1662432187937&hud=true&entry.519373518_sentinel=&entry.301819105_sentinel=&entry.1124370742_sentinel=&fvv=1&partialResponse=%5Bnull%2Cnull%2C%22-6523749705829110087%22%5D&pageHistory=0&fbzx=-6523749705829110087.
Now let's just remove the extra parameters that aren't answers. Find the last answer you input and remove the rest. Our new link will be https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/viewform?entry.1475351979=test&entry.280503419=test&entry.519373518=KG+1&entry.1124370742=French&entry.301819105=A
This will open the form page with pre-filled values. If you actually want to submit the response right away, replace "viewform" with "formResponse".
The google form I tried is from #AHunt's answer, so thank you for that sample google form.

How to send mail multiple selected users

I have a meetings table where I am storing meeting information and where I can select a meeting between 2 types of user visitor type user and host type user. I have a many to many relationships between users and meeting that's why I have a pivot table meeting_user. I need to send mail all of the selected users for one meeting.
I am trying to send email using this but it's storing the meeting_id into notifiable_id column of db. so how can I store users_id in the notifiable_id column of db.
$meetings->save();
$meetings->users()->attach($request->user_id);
$users = Meeting::with('users')->get();
\Mail::to($user->send(New NewMeeting($meetings('id')));
There are two scenarios in which you can send an email to users to the meeting:
When the user has been added to the meeting
When alerting all users (in bulk) of a meeting which they have been added to.
When emailing the user which has just been added
In the event where you would like to email the users once added, you can do the following:
...
$meeting = Meeting::find($meeting_id);
$user = User::find($request->user_id);
$meeting->users()->attach($user->id);
\Notification::send($user, new NewMeetingNotification($user));
This is to be added within code which only adds a user to a meeting, not multiple users.
When emailing all users within a meeting at once
In the event where you would like to email users, in bulk, once you've added all users, you can do the following.
...
$meeting = Meeting::with('users')->where('id', $meeting_id)->first();
$meeting->users()->each(function ($user, $key) {
\Notification::send($user, new NewMeetingNotification($user));
});
$meeting_id being the meeting in question.
Notify User (Optional)
If the user model has the notifiable trait, you can change the code to:
...
$meeting = Meeting::with('users')->where('id', $meeting_id)->first();
$meeting->users()->each(function ($user, $key) {
$user->notify(new NewMeetingNotification($user));
});
I hope this helps.

How to store hidden fields inside message in web application?

I have web app (laravel 5.3, mysql) where users can comment any entity in project (almost every page contains something like chat)
I want to add possibility to mention other users inside message via '#' symbol ("Hello, #John, see here", for example).
When this message is posted to chat user named John must get notification about new message (via email, if he is offline).
Every message is connected to some page (/object/45, for example), so when email is sent user will know the page where he was mentioned.
The question is how to store this inside database?
message field has type text
In this example row would contain this data "Hello, #John, see here" (without quotes).
Problem is that there can be many users with name "John" so I can not not do simple:
select email from users where username = 'John' -- email is used as login
Also username can be something like #John Malkovich, so I have to parse string to find out, if "John" or "John Malkovich" was mentioned.
What is unique - user id.
So how to store this inside database?
Possible solution:
Hello, [user=34], see here - field in database
Parse string before displaying to web browser and replace this string with
Hello, #John, see here
but, obviously, no one can paste literal text '[user=123]' inside message, because it would be interpreted as userid.
P.S. Inside one message many users can be mentioned.
Maybe you could create something like <span value="user34">John Malkovich</span> and parse the value?
Or <span data-user-id="user34">John Malkovich</span> is probably better semantically.
Have absolutely no experience in this kind of stuff though, so don't take me too seriously ;)

Is HTML5 localstorage appropriate to store input field values?

I have a question, on how to best store local values of some form fields.
In my website, users use the keypad to keep a tally count of items. They can enter a label for the items they count. The problem is that each user apply different labels for their needs - and, each time they visit the labels are blank.
My sites are running through site44.com, which does not allow the use of server side php. So, in my research, I think using HTML5 localstorage may allow a user to keep the label after the exit the site?
Is this a correct interpretation?
Can someone give me a guide if I have, say 3 inputs - with different ids - how to set up the script?
you can use the local storage like this :
var fn = document.getElementById("firstname").value;
localStorage.setItem("firstname", fn);
var ln = document.getElementById("lastname").value;
localStorage.setItem("lastname", ln);
var em = document.getElementById("email").value;
localStorage.setItem("email", em);
thus the clients browser will have these items set in their local storage.
Now if a user visits the website afterwards. you can check for the value of localStorage and find the items of your need.
Suppose on users' next visit you want to send him a greet message ( he has not logged in ofcourse ) you can use a script like this below:
var name = localStorage.getItem("firstname");
alert("Hello"+name);

Wordpress Authenticate Filter

I'm currently trying to override Wordpress' wp_authenticate function (without modifying the core files, mainly pluggable.php), however I'm not sure if I'm going about it the correct way. There are two great references (see below), but they don't explicitly state what to do in order to prevent the login provided certain criteria are met.
In short, I'm trying to prevent registered users who have not activated their account. I've already implemented creating a user with a md5 unique id in the usermeta table (attached to their user id). I'm basically trying to check for that "activation_key' value in the usermeta table on login, if a value exists, I want to prevent the login from occurring.
The authenticate filter seems to be exactly what I need but after modifying it and placing it into my functions.php file, it doesn't seem to work! Login occurs per usual.
References:
How do I hook into the Wordpress login system to stop some users programmatically?
http://willnorris.com/2009/03/authentication-in-wordpress-28
I actually found a work around.
Using a custom form you can log into Wordpress using the wp_signon function.
var $creds = array();
$creds['user_login'] = 'example';
$creds['user_password'] = 'plaintextpw';
$creds['remember'] = true;
//check if user has an activation key in the usermeta table
$user = get_userdatabylogin($creds['user_login']);
if(get_usermeta($user->ID,'activation_key')) {
} else {
$procLogin = wp_signon( $creds, false );
if ( is_wp_error($procLogin) ) {
echo $user->get_error_message();
}
echo 'success!';
}
hope this helps someone out there