I have been using php-imap-client for some time and has always worked great. The issue is that recently it seems to break with fetching email from outlook/office365 mailboxes now and I can't pinpoint the issue. As far as I know it seems to be breaking with imap_fetchbody() but that is as far as I get.
getMessages() basically does not work and I was wondering if anyone has come across this yet and maybe can shed some light to a solution to fix it.
Things like countMessages and countUnreadMessages work fine but once you try get the email contents that is where it breaks.
$overallMessages = $imap->countMessages();
$unreadMessages = $imap->countUnreadMessages();
Here is all my code
$mailbox = $row['imap_server_address'];
$username = $row['imap_username'];
$password = $row['imap_password'];
$encryption = Imap::ENCRYPT_SSL; // TLS OR NULL accepted
// Open connection
try{
$imap = new Imap($mailbox, $username, $password, $encryption);
// You can also check out example-connect.php for more connection options
}catch (ImapClientException $error){
echo $error->getMessage().PHP_EOL; // You know the rule, no errors in production ...
die(); // Oh no :( we failed
}
// Select the folder INBOX
$imap->selectFolder('INBOX');
// Count the messages in current folder
$overallMessages = $imap->countMessages();
$unreadMessages = $imap->countUnreadMessages();
// Fetch all the messages in the current folder
echo "This echos fine";
$emails = $imap->getMessages();
echo "This does not echo";
var_dump($emails);
I can connect to the server just fine. I can select the INBOX, I can get overall messages and as well as unread. var_dump($email) produces nothing. And there are unread emails in the inbox.
When I echo after $emails = $imap->getMessages(); nothing is echo'd to the screen so something is breaking here.
Related
So my current code is this in PHP:
$mailbox = imap_open('{imap.gmail.com:993/imap/ssl}INBOX', 'example#gmail.com', 'password') or die('Cannot connect to Gmail: ' . imap_last_error());
This code allows PHP to see my email inbox using IMAP and it works fine.
Now my question is, how to make it so that It checks all the new emails in my inbox and outputs "n New Emails!" and marks each of them as seen automatically.
I would really appreciate It If someone were to shed some light on this as I am very new to IMAP and handling emails programmatically in general.
You could use a combination of imap_search1 and imap_setflag_full2
$mailbox = imap_open('{imap.gmail.com:993/imap/ssl}INBOX', 'example#gmail.com', 'password');
// This gives an array of message IDs for all messages that are UNSEEN
$unseenMessages = imap_search($mailbox, 'UNSEEN');
// Keep in mind that imap_search returns false, if it doesn't find anything
$unseenCount = !$unseenMessages ? 0 : count($unseenMessages);
echo "$unseenCount New Emails!\n";
if ($unseenMessages) {
// The second parameter of imap_setflag_full function is a comma separated string of message IDs
// It can also be a range eg 1:5, which would be the same as 1,2,3,4,5
imap_setflag_full($mailbox, implode(',', $unseenMessages), '\Seen');
}
I searched every days for my problem, I tried many solutions and I didn't find... :(
I want to create an user using ldap_add with PHP. Working fine without enable account and without password. You find the code below.
Can you help me, please?
Config :
PHP 5.6
Windows Server 2012 R2 with AD
I can enable an account when I use $info["useraccountcontrol"]=544; but the account isn't with a password... User must loggon without password and type his new password at the first connection. *
I tried to add a password with $info['userPassword'] and chand useraccountontrol at 512 and I get this error :
ldap_add(): Add: Server is unwilling to perform
Here is my code :
<?php
$name = htmlspecialchars($_POST["name_build"]);
$lastname = htmlspecialchars($_POST["lastname_build"]);
$department = utf8_encode(htmlspecialchars($_POST["department_build"]));
$title = utf8_encode(htmlspecialchars($_POST["title_build"]));
$dn="CN=$name OU=Users, o=Domocom, c=net";
$ds = ldap_connect("192.168.1.1",389);
if ($ds) {
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); // IMPORTANT
ldap_bind($ds, "administrateur#domocom.net", "password");
// Prépareles données
$cn = $info["cn"] = "$lastname $name";
$info["sn"]="$name";
$info["givenname"]="$lastname";
$info["displayname"]="$lastname $name";
$info["name"]="$lastname $name";
$info["userprincipalname"]= "$lastname.$name#domocom.net";
$info["samaccountname"]= "$lastname.$name";
$info["title"]="$title";
$info["department"]="$department";
$info["mail"]="$lastname.$name#domocom.fr";
$info["postalcode"]="69009";
$info["objectClass"][0]="user";
//$info['userPassword'] = "password";
//$info["useraccountcontrol"]=544;
$r = ldap_add($ds,"CN=$cn,OU=Users,OU=Direction,OU=Domocom-SP,DC=domocom,DC=net", $info);
ldap_close($ds);
} else {
echo "unable to connect to ldap server";
}
?>
Thanks a lot.
PS : it's fake society for my school. :p
If it's an AD you might need to use a secure LDAP-Connection.
For that you'll need to call ldap_connect('ldaps://192.168.1.1:<port of the AD>');. Calling ldap_connect with two parameters is deprecated and should be avoided. Use it with an LDAP-URI!
You can also omit the if…else around the ldap_connect as it will return true in almost all cases. And a true return-value does not mean that a connection to the server actually as established. A connection is first established on the first ldap_-command that needs a connection which is typically ldap_bind.
And then you might want to have a look at Change AD password using PHP, Issue updating AD password using PHP and Change AD Password using PHP/COM/ADSI/LDAP
I'm using the following code which you may recognise from php.net to delete all the emails in my inbox:
function deleteEmails($emailAddress)
{
// connect to gmail with your credentials
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = $emailAddress; # e.g somebody#gmail.com
$password = '****************';
// try to connect
$inbox = imap_open($hostname,$username,$password) or die('Cannot download information: ' . imap_last_error());
$check = imap_mailboxmsginfo($inbox);
echo "Messages before delete: " . $check->Nmsgs . "<br />\n";
imap_delete($inbox, '1:*');
$check = imap_mailboxmsginfo($inbox);
echo "Messages after delete: " . $check->Nmsgs . "<br />\n";
imap_expunge($inbox);
$check = imap_mailboxmsginfo($inbox);
echo "Messages after expunge: " . $check->Nmsgs . "<br />\n";
imap_close($inbox);
}
which helps deal with a clog in my account that happens on occasion if I let it get out of hand. However, what I really need is for it to delete all my email except the most recent one. I have tried to change imap_delete($inbox, '1:*'); to imap_delete($inbox, '2:*'); but this just caused it to not work at all.
What am I missing?
EDIT
With advise below I tried the following:
imap_delete($inbox, "2:$check->Nmsgs");
But interestingly it deleted all but one of the 'conversations' but in gmail 'conversations' can max out at 61 emails! I'm not sure how to get around this. Also, the deleted ones returned after a few mins...
I know gmail does some interesting stuff with just tagging it differently and putting it in an All Mail folder, since there aren't actual "Folders" like on most IMAP systems. Have you tried just giving it a range, such as
imap_delete($inbox,2:$check->Nmsgs);
If that doesn't work, you might have to just loop through marking them for deletion and then expunge after that.
I found the issue. Gmail by default is set up using 'conversations' meaning any emails coming in with the same subject get grouped together. This screws with everything but it can be turned off in gmail settings. Once done I needed to make sure I was deleting all but the most recent. using imap_delete($inbox,2:$check->Nmsgs); deleted all but the oldest. so the following code did it for me:
$emails = ($check->Nmsgs)-1;
imap_delete($inbox, '1:' . $emails);
so that I was getting the numbers but was deleting all up to the last one to come in (the most recent)
Done
How can I make it so when a user email's to my email address their email text/information is written into a mysql table? So basically extract the contents of a new email and write them into mysql table.
I tried this but I get nothing:
<?php
$imap = imap_open("{gmail.com}", "username", "password");
if( $imap ) {
//Check no.of.msgs
$num = imap_num_msg($imap)
//if there is a message in your inbox
if( $num >0 ) {
//read that mail recently arrived
echo imap_qprint(imap_body($imap, $num));
}
//close the stream
imap_close($imap);
}
?>
We are using an exchange server..I am a coop student so I am not really advanced at this.
I tried this as a test to see if it works, logging in gmail to read email. It didnt work.
<?php
// connect to the mailbox
$m_mail = imap_open("{mail.https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1<mpl=default<mplcache=2}INBOX", "username", "password");
//get all messages
$m_search=imap_search ($m_mail, 'ALL ');
// Order results starting from newest message
rsort($m_search);
//loop through and do what's necessary
foreach ($m_search as $onem) {
//get imap header info for obj thang
$headers = imap_headerinfo($m_mail, $onem);
$head = imap_fetchheader($m_mail, $headers->Msgno);
$body = imap_body($m_mail, $headers->Msgno, FT_INTERNAL );
echo $body;
}
//purge messages (if necessary)
imap_expunge($m_mail);
//close mailbox
imap_close($m_mail);
?>
use IMAP functions for that. Set up another email account if necessary. Here's the example code:
// connect to the mailbox
$m_mail = imap_open("{mail.YOURHOST.com:993/imap/ssl/novalidate-cert}INBOX", "address#YOURHOST.com", "YOURPASSWORD");
//get all messages
$m_search=imap_search ($m_mail, 'ALL ');
// Order results starting from newest message
rsort($m_search);
//loop through and do what's necessary
foreach ($m_search as $onem) {
//get imap header info for obj thang
$headers = imap_headerinfo($m_mail, $onem);
$head = imap_fetchheader($m_mail, $headers->Msgno);
$body = imap_body($m_mail, $headers->Msgno, FT_INTERNAL );
//
DO WHAT YOU NEED TO DO HERE - insert to the database, etc
}
//purge messages (if necessary)
imap_expunge($m_mail);
//close mailbox
imap_close($m_mail);
read your mailbox via pop3 or imap and add the new emails to your database
Take a look a this class: http://php.net/manual/en/book.imap.php
you could read the pop3/imap in some intervals.
other method would be to redirect your email to a php script. I don't know which email system you are using on your server but here is an example with postfix.
the pop3/imap method is easier and you don't need to edit your server configs but the second method is faster because your script will start as it receives an email.
I'm using zend mail extended with zend_mail_storage_imap and I built an application that looks for keywords in user's emails.
The problem is that it opens up each email and keeps it marked as read. Is there a way to check the body of emails and not mark each mail checked as read?
Here's current working code. It's part of an ajax query that automatically looks through someone's inbox. In this current form, it will mark each mail starting with a user's most current mail as read (in gmail). Would it be possible to check the body text, but not mark the email as read. Alternatively, will I need to check if each mail is read or unread before looking it up, and then restore it to that state as a workaround?
if (strpos(htmlentities($storage->getMessage($i)),$searchterm))
{
$fromaddress = str_replace("'","",$storage->getMessage($i)->from);
$fromaddress = str_replace('"','',$fromaddress);
$sql = "SELECT `senderemail`,`subscribed` FROM email_spam WHERE `useremail` = '$_SESSION[email_address]' AND `senderemail` = '$fromaddress'";
$result = mysql_query($sql) or die (mysql_error());
$num = mysql_num_rows($result);
if($num == 0)
{
$emailmessage = mysql_escape_string($storage->getMessage($i)->getContent());
$sql_insert = "INSERT into `email_spam` (`message`,`useremail`,`senderemail`,`datetime`,`subscribed`) VALUES ('$emailmessage','$_SESSION[email_address]','$fromaddress',now(),1)";
mysql_query($sql_insert,$link) or die("Insertion Failed:" . mysql_error());
$sql = "SELECT `emailid`,`datetime` FROM email_spam WHERE `useremail` = '$_SESSION[email_address]' ORDER BY `datetime` desc";
$getid = mysql_query($sql) or die (mysql_error());
$num = mysql_num_rows($getid);
}
}
EDIT - here's the final code for those interested
$storage = new Zend_Mail_Storage_Imap($imap);
$flags = $storage->getMessage($i)->getFlags();
$newflag = $flags[Zend_Mail_Storage::FLAG_RECENT];
$oldflag = $flags['\Seen'];
if(!empty($flags['\Seen']))
{
$read=1;
}
else
{
$read=0;
}
The entire code is looped, so here, I perform my entire searching/sorting algorithm for each individual email.
if ($read==0)
{
$storage->setFlags($i, array(Zend_Mail_Storage::FLAG_RECENT)); //marks as new
}
Here, I go and mark the emails that were not read (before the implementations) as unread. I think this is the most efficient way (that I could find) of performing this operation. I welcome any other codes or comments.
After reading a message, you could unset the seen flag. See also the imap implementation of the setFlags method. Api documentation
To unset the "seen" flag:
$flags = $msg->getFlags();
unset($flags[Zend_Mail_Storage::FLAG_SEEN]);
$storage->setFlags($i, $flags);
Setting the "recent" flag does not necessarily do what you want it to! On gmail, it will mark emails as "important".
When reading mails with the IMAP Storage in Zend Framework you have access to a method called setFlags in Zend_Mail_Storage_Imap
I don't think it's documented in the ZF manual but you might want to look into the API docs (see link above) to set the status/flag on a message.
You could also just use empty array to reset any flags
$mailstorage->setFlags($messageID, array());
Flag change seem to be done via getContent() method after fetching the message in zend-mail 2. Below is an example to read content and keep initial flags :
$imap = [
'host' => $connection['mailhost'],
'user' => $connection['username'],
'password' => $password,
];
$storage = new \Zend\Mail\Storage\Imap($imap);
$lastMsgIndex = $storage->countMessages();
$msg = $storage->getMessage($lastMsgIndex);
$msgFlags = $msg->getFlags();
// Line below will mark email as seen if getContent is called
$content = $msg->isMultipart() ? 'Multipart Email' : $msg->getContent();
$storage->setFlags($lastMsgIndex, $msgFlags);