I am currently working on building a system for my client that could be classed as a type of ticket system. However, instead of users inputting tickets like a normal system, the tickets are received from a third party (always the same third party) in email format that will be piped in.
What I need to look at (which I've thought using various ways but cant seem to pick out the best) is taking the details from the email and putting them into individual variables.
An example of the email that will be recieved is:
Name: Harry Smith
Status: Married
Address: 14 Tyne Road,
Littlewood
Manchester
MC2 3DN
Telephone: 01551 221502
Obviously the full email is alot longer, however what I am looking at doing is putting out the details from the email so I can process them as required by the new system. In reality I am looking for something that can store the information in the style of:
Name: %name%
Status: %status%
Address: %address%
Telephone: %telephone%
I just haven't quite worked out how to code a string search that will find Name: and store every after it up until Status: is reached.
Any help or pointers would be great.
Thanks :)
Read the data file in line by line. Explode each line with a ":". If a count of that == 2 then you know you are on a new token, and in which case the key = index[0] and the value = index[1]. Now check the next line, if there is only one element after you run explode, simply add it to the previous key.
$email = ...;//email here
$email = str_replace(array("\r\n","\n\r","\n","\r"), "\r", $email); //fix line breaks
$emaillines = explode("\r", $email);
$result = array();
$key = "first";
foreach($emaillines as $line)
{
$parts = explode(":",$line,2);
if(count($parts)>1)
{
$key = $parts[0];
$result[$key] = $parts[1];
}
else
$result[$key] .= "\r".$parts[0];
}
print_r($result);
You can use basic string manipulation and regular expressions to extract data from the email message. Following code can serve as a starting point. The regular expression has lots of room for improvement.
<?php
$message = "Name: Harry Smith
Status: Married
Address: 14 Tyne Road,
Littlewood
Manchester
MC2 3DN
Telephone: 01551 221502";
preg_match(
"#" .
"^Name:(.*)" .
"^Status:(.*)" .
"^Address:(.*)" .
"^Telephone:(.*)" .
"#ms",
$message,
$match
);
var_dump($match);
// $match[1]...[4] contain the desired information
// you may want to trim() each value
?>
You can use str_replace.
$string = str_replace("%name%", $name, $string);
Related
I'm looping a multidimensional array with a for loop and triggering and email for every item in the loop. I want change {{fname}} to the real name from the key.
foreach($customermarketingarray as $key => $value){
$customeremail = $value['email'];
$fname = $value['first_name'];
$body = str_replace("{{fname}}",$fname,$body);
}
For some reason everything is coming out unique except the {{fname}} is using the first name in the first loop for every fname in the loop. If the first person is Joe, it's making every fname Joe
Because you are using one $body over and over again, and once the replacement has been made there is nothing more to replace. Use a fresh version of $body on every iteration.
foreach($customermarketingarray as $key => $value){
$customeremail = $value['email'];
$fname = $value['first_name'];
$tempBody = str_replace("{{fname}}",$fname,$body);
// now use this $tempBody for display
}
This way on every iteration of your loop you get a new template from $body again and you can make replacements to it and then use it.
First time you are using str_replace it replaces occurrences of {{fname}} in entire body. There is nothing to replace in further loop iterations.
Use preg_replace which has additional parameter (limit) which states how many replacements will be made at most. In your example if there is only one {{fname}} per each name using 1 as count parameter will do.
Read the documentation. It's pretty self explanatory.
http://php.net/manual/en/function.preg-replace.php
Another thing is problem with construction of your data. You cannot distinguish, without additional rules, which {{fname}} goes to which replacement.
It is not clear whether you want to use $body as template (I've assumed as no, because you are not using $body for anything except replacement in loop iterations). My answer is valid if there are multiple occurrences of {{fname}} in body and you want to replace them one by one with names from loop iterations.
You are replacing the variable $body in each loop. Just use a new variable to store the result. See my example below.
<?php
$customermarketingarray=array(
0=>array("email"=>"1#test.com","first_name"=>"Joe1"),
1=>array("email"=>"2#test.com","first_name"=>"Joe2"),
2=>array("email"=>"3#test.com","first_name"=>"Joe3"),
3=>array("email"=>"4#test.com","first_name"=>"Joe4")
);
$body="First Name: {{fname}}<br>Email: {{email}}<br><br>";
foreach($customermarketingarray as $key => $value){
$customeremail = $value['email'];
$fname = $value['first_name'];
$email = $value['email'];
$res_body .= str_replace(array("{{fname}}","{{email}}"),array($fname,$email),$body);
}
echo $res_body;
?>
The result for the above code is
First Name: Joe1
Email: 1#test.com
First Name: Joe2
Email: 2#test.com
First Name: Joe3
Email: 3#test.com
First Name: Joe4
Email: 4#test.com
Using preg_replace
It can be done using preg_replace instead str_replace
Answer: PHP variables and loops in HTML format
go through and check deprecated, http://php.net/manual/en/function.preg-replace.php
$body_message = $body;
foreach($customermarketingarray as $key => $value){
$customeremail = $value['email'];
$fname = $value['first_name'];
// $body = str_replace("{{fname}}",$fname,$body);
$body_message = preg_replace("/{{(.*?)}}/e","#$$1", $body);
}
Using str_replace
$body_message = $body;
foreach($customermarketingarray as $key => $value){
$customeremail = $value['email'];
$fname = $value['first_name'];
$body_message = str_replace("{{fname}}",$fname,$body);
}
I'm looping through rows in my database to get information from whois results.
Here's what I have right now:
function GetEmailFromWhois($domain){
$whois = new Whois();
$query = $domain;
$whois->deep_whois=TRUE;
$result = $whois->Lookup($query, false);
$raw_data = $result["rawdata"];
$email = "";
foreach($raw_data as $item){
$items = explode(":",$item);
if($items[0] == "Registrant Email"){
$email = $items[1];
}
}
return $email;
}
The code above gets the Registrant Email from the whois results.
I reference it later on in my code like this: $email = GetEmailFromWhois($domain);
However, at the same time as getting the registrant email, I'd also like to get the Registrant Name, Registrant Phone, and Registrant Country.
I could just copy the code above 3 more times for each of those additional fields, but that would cause there to be 4 whois queries for each domain - instead of just one.
Anyone know how I can get the info I need in a single query and then use it later on in my code?
As I recently noted in another answer, parsing WHOIS data is a complex, messy affair. The exact format of WHOIS responses is not specified by any standard, and not all registries/registrars will use the format you're attempting to parse here. (Some use different labels to mark the fields you're searching for, some use labels that are ambiguous without context, some don't label certain fields at all, and some won't even include the information you're searching for here.) Worse, some registries/registrars will heavily rate limit you if it becomes apparent that you're trying to extract more than a few responses from them. In short, I'd recommend that you avoid attempting to parse WHOIS responses if at all possible.
To solve your immediate problem, though, you can create an associative array to represent the WHOIS response like so:
$arr = [];
foreach($raw_data as $item) {
list($k, $v) = explode(":", $item);
$arr[$k] = $v;
}
This will give you an associative array of the results, so you can pull out individual values using e.g.
$email = $arr["Registrant Email"];
i am trying to find the common errors users have while entering email ids. I can always validate EMAIL using PHP Email Filter
$email = "someone#exa mple.com";
if(!filter_var($email, FILTER_VALIDATE_EMAIL))
{
echo "E-mail is not valid";
}
else
{
echo "E-mail is valid";
}
or pattern matching
$email = test_input($_POST["email"]);
if (!preg_match("/([\w\-]+\#[\w\-]+\.[\w\-]+)/",$email))
{
$emailErr = "Invalid email format";
}
I agree that these are not full proof ways to validate emails. However they should capture 80% of cases.
What I want is - Which position email became invalid? if its a space, at what position user had entered space. or did it fail because of "." in the end?
Any pointers?
-Ajay
PS : I have seen other thread regarding email validations. I can add complexity and make it 100%. concern here is to capture the most common mistakes made by people when entering Email ID.
This is difficult because sometimes it's not always a single character that makes an email address invalid. The example you give could easily be solved by:
$position = strpos('someone#exa mple.com', ' ');
However, it seems you are not interested in an all encompassing solution but rather something that will catch the majority of character based errors. I would take the approach of using the regular expression but capture each section of the email address in a sub pattern for further validation. For example:
$matches = null;
$result = preg_match("/(([\w\-]+)\#([\w\-]+)\.([\w\-]+))/", $email, $matches);
var_dump($matches);
By capturing sections of the regex validation in sub patterns you could then dive further into each section and run similar or different tests to determine where the user went wrong. For example you could try and match up the TLD of the email address against a whitelist. Of course there are also much more robust email validators in frameworks like Zend or Symfony that will tell you more specifically WHY an email address is not valid, but in terms of knowing which specific character position is at fault (assuming it's a character that is at fault) I think a combination of tactics would work best.
There is no way I know of in Java to report back the point at which a regex failed. What you could do is start building a set of common errors (as described by Manu) that you can check for (this might or might not use regex expressions). Then categorize into these known errors and 'other', counting the frequency of each. When an 'other' error occurs, develop a regex that would catch it.
If you want some assistance with tracking down why the regex failed you could use a utility such as regexbuddy, shown in this answer.
Just implement some checks on your own:
Point at the end:
if(substr($email, -1) == '.')
echo "Please remove the point at the end of you email";
Spaces found:
$spacePos = strpos($email, ' ');
if(spacePos !== false)
echo "Please remove the space at pos: ".$spacePos;
And so on...
First of all, I would like to say that the reason your example fails is not the space. It is the lack of '.' in former part and lack of '#' in the latter part.
If you input
'someone#example.co m' or 's omeone#example.com', it will success.
So you may need 'begin with' and 'end with' pattern to check strictly.
There is no exist method to check where a regular expression match fails as I know since check only gives the matches, but if you really want to find it out , we can do something by 'break down' the regular expression.
Let's take a look at your example check.
preg_match ("/^[\w\-]+\#[\w\-]+\.[\w\-]+$/",'someone#example.com.');
If it fails, you can check where its 'sub expression' successes and find out where the problem is:
$email = "someone#example.com.";
if(!preg_match ("/^[\w\-]+\#[\w\-]+\.[\w\-]+$/",$email)){ // fails because the final '.'
if(preg_match("/^[\w\-]+\#[\w\-]+\./",$email,$matches)){ // successes
$un_match = "[\w\-]+"; // What is taken from the tail of the regular expression.
foreach ($matches as $match){
$email_tail = str_replace($match,'',$email); // The email without the matching part. in this case : 'com.'
if(preg_match('/^'.$un_match.'/',$email_tail,$match_tails)){ // Check and delete the part that tail match the sub expression. In this example, 'com' matches /[\w\-]+/ but '.' doesn't.
$result = str_replace($match_tails[0],'',$email_tail);
}else{
$result = $email_tail;
}
}
}
}
var_dump($result); // you will get the last '.'
IF you understand the upper example, then we can make our solution more common, for instance, something like below:
$email = 'som eone#example.com.';
$pattern_chips = array(
'/^[\w\-]+\#[\w\-]+\./' => '[\w\-]+',
'/^[\w\-]+\#[\w\-]+/' => '\.',
'/^[\w\-]+\#/' => '[\w\-]+',
'/^[\w\-]+/' => '\#',
);
if(!preg_match ("/^[\w\-]+\#[\w\-]+\.[\w\-]+$/",$email)){
$result = $email;
foreach ($pattern_chips as $pattern => $un_match){
if(preg_match($pattern,$email,$matches)){
$email_tail = str_replace($matches[0],'',$email);
if(preg_match('/^'.$un_match.'/',$email_tail,$match_tails)){
$result = str_replace($match_tails[0],'',$email_tail);
}else{
$result = $email_tail;
}
break;
}
}
if(empty($result)){
echo "There has to be something more follows {$email}";
}else{
var_dump($result);
}
}else{
echo "success";
}
and you will get output:
string ' eone#example.com.' (length=18)
My following script runs fine when a single email address is entered into the textarea, but once two are entered, no emails are sent. What am I doing wrong?
if($_POST['submit']=='Send Email') {
$email_addresses = explode(",\n", $_POST['email']);
foreach($email_addresses as $email_address){
$email_address = trim($email_address);
send_mail( 'noreply#noreply.com',
$email_address,
'Test Email',
"Hello This Email Is A Test");
}
}
var_dump($email_addresses) results in this
array(1) { [0]=> string(39) "email1#test.com email2#test.com" }
You're using the same variable name twice
foreach($email_addresses as $email_addresses)
so on the second loop, the source is overwritten
Edit:
please post the output of
var_dump($_POST['email']);
var_dump(explode(",\n", $_POST['email']));
It should be:
foreach($email_addresses as $email_address){
$email_address = trim($email_address);
send_mail( 'noreply#noreply.com',
$email_address,
'Test Email',
"Hello This Email Is A Test");
}
Also splitting using explode on ",\n" separator isn't a good idea (people can send ",\r\n" in some cases). Provide multiple fields or use preg_split().
If it doesn't work try var_dump($email_address); after the explode() function to get the information what exactly happens with the input (and so you can see that input is actually correct).
UPDATE: As you can clearly see there is no \n in $email_address. It depends on your HTML form.
For a quick fix just explode(', ', $email_addresses); Also - you missed , in your input, which you require to explode that string.
obviously a#b.com b#c.com is not a valid email, and my psychic powers tell me that this is not the correct way to do this. What if I enter something else than an email address? Try to sanitise the data you receive from user. You can not trust user input blindly.
foreach($email_addresses as $email_addresses){
Means that you are overwriting the source array ($email_addresses) with the first entry in the array, because they are the same variable name. Unfortunately, PHP throw an error on this, so you end up rewriting your array with the first email address, and then prematurely (to your needs) exiting the loop (though this is expected and logical behaviour).
okay, here is the code
while (!feof($text)) {
$name = fgets($text);
$number = fgets($text);
$carrier = fgets($text);
$date = fgets($text);
$line = fgets($text);
$content = $_POST['message'];
$message .= $content;
$message .= "\n";
$number = $number;
mail("$number#vtext.com", "Event Alert", $message, "SGA");
Header("Location: mailconf.php");
}
I am trying to get a message sent to a phone, I have 'message' coming in from a text area, and then I assign it to "$content" then I put "$content" into "$message" and then as you can see, in my mail line, I want the address to be the variable "number"#vtext.com I have the while loop because there are many people in these files I wish to send a message to...
When I change the "$number#vtext.com" to my email address, it sends everything fine, I just cannot seem to get it to send to a phone number, please help!
thanks!
The problem is that fgets includes the newline character as part of the return. So you are effectively sending an email to:
1234567890
#vtext.com
Which of course is invalid. Change your line that reads $number = $number to:
$number = trim($number);
And the rest of your code should function as expected, with the email being received on your phone.
Part of my original answer
I would highly recommend using a (probably paid) service to send SMS messages to phones if you need anything remotely reliable. A quick search yielded a few results:
PHP/SMS Tutorial
A list of 5 ways to Text for free <-- This link is dated, but might still be helpful
You need to append the number variable and the "#vtext.com" literal string together:
mail($number . "#vtext.com", "Event Alert", $message, "SGA");