Webklex / php-imap

PHP-IMAP is a wrapper for common IMAP communication without the need to have the php-imap module installed / enabled. The protocol is completely integrated and therefore supports IMAP IDLE operation and the "new" oAuth authentication process as well.
https://www.php-imap.com
MIT License
304 stars 144 forks source link

is it possible to search for emails that contain text or text or text ? #56

Closed vesper8 closed 3 years ago

vesper8 commented 3 years ago

In GMail for example I can add this to the search query:

(A job failed at https://api.mydomain.com) OR (from:support.digitalocean.com AND CPU is running HIGH) 

Basically I want to return all emails in a single query that match either one subject or another subject

Well it would certainly be great if I could go one step further as in my GMail example above and be able to get all emails that match multiple conditions such as matching one subject or another subject AND matching the from field as well

Is any of this possible or I have to run multiple queries?

Webklex commented 3 years ago

Hi @vesper8 , if the "OR" operation is supported by Google you can use it a few different ways:

$messages = $folder->query()->subject("some subject")->orWhere()->to("some@one.tld")->orWhere(function($query){
    $query->text("some custom text");
})->get();

Best regards,

vesper8 commented 3 years ago

Thanks @Webklex

I should have mentioned that I'm trying to get this functionality to work in a regular Imap email account, not in Google Mail

I will give that syntax a try

Webklex commented 3 years ago

..it depend on your provider - I thought you were using Google. Guess I was wrong :)

vesper8 commented 3 years ago

I was just using Google as an example of a complex query with multiple conditions. I'm trying to get this to work on a normal domain-based IMAP email account. My bad for misleading you.

I've tried these two now but neither work:

This works and finds X emails:

        $messages = $folder
        ->query()
        ->text('Some text')
        ->get()

This finds 0 emails.. it should at least be finding the same emails as above

        $messages = $folder
        ->query()
        ->text('some text')
        ->orWhere(function ($query) {
            $query->text('some other text');
        })
        ->get()

And I tried this thinking this might work

        $messages = $folder
        ->query()
        ->where(function ($query) {
            $query->text('some text');
        })
        ->orWhere(function ($query) {
            $query->text('some other text');
        })
        ->get();

And this throws an error

 ErrorException

  strtoupper() expects parameter 1 to be string, object given

  at vendor/webklex/php-imap/src/Query/WhereQuery.php:107
    103▕      * @return string
    104▕      * @throws InvalidWhereQueryCriteriaException
    105▕      */
    106▕     protected function validate_criteria($criteria) {
  ➜ 107▕         $criteria = strtoupper($criteria);
    108▕         if (substr($criteria, 0, 7) === "CUSTOM ") {
    109▕             return substr($criteria, 7);
    110▕         }
    111▕         if(in_array($criteria, $this->available_criteria) === false) {

If you have any other ideas would appreciate hearing them

Webklex commented 3 years ago

Do you know which imap version your server supports? Is it talking IMAPv4? At least that's where it is available according to the rfc: https://tools.ietf.org/html/rfc3501

IMAP2 for example does not support OR: https://tools.ietf.org/html/rfc1064

Best regards,

vesper8 commented 3 years ago

Do you know how I can find out this information? Does your package expose it somehow? I have no idea, it's just a webmail that a client uses.

Webklex commented 3 years ago

Maybe:

var_dump($client->getConnection()->getCapabilities());
Webklex commented 3 years ago

If the server is running IMAP4 your capabilities array should contain IMAP4rev1 or something similar.

vesper8 commented 3 years ago

Hrmm.. I just did that and it printed an array that does contain IMAP4rev1

So then I'm confused as to why I was not able to run the above queries with success

I also noticed that using ->text('some text') is actually not explicit.. like it will actually return results that do not match exactly this query.. as if it was splitting the words and searching for some AND text. I'm having to check again on the returned messages to see if the subject matches exactly the string I'm looking for as this is what I want.

Are you aware if there's a way to search for an exact string?

Webklex commented 3 years ago

Hi @vesper8 , I'm guessing here;

In general: IMAP isn't made for complex search operations. That's why the search functionality in all imap clients is pretty limited.

Best regards,

Webklex commented 3 years ago

..I just found another possible option:

$messages = $folder->query()->orWhere()->text("some text")->text("other text")->get();

Best regards,

daniel89fg commented 11 months ago

I have an error when executing the following query.

$messages = $folder ->query() ->subject("Contacto Web") ->orWhere() ->to("messages-noreply@linkedin.com") ->orWhere(function($query){ $query->text("Fernando"); }) ->get();

This is a var_dump() of the error

object(Whoops\Exception\ErrorException)#291 (8) { ["message":protected]=> string(26) "Array to string conversion" ["string":"Exception":private]=> string(0) "" ["code":protected]=> int(2) ["file":protected]=> string(98) "/var/www/html/Plugins/MultiEmail/vendor/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php" ["line":protected]=> int(309) ["trace":"Exception":private]=> array(12) { [0]=> array(4) { ["function"]=> string(11) "handleError" ["class"]=> string(10) "Whoops\Run" ["type"]=> string(2) "->" ["args"]=> array(4) { [0]=> int(2) [1]=> string(26) "Array to string conversion" [2]=> string(98) "/var/www/html/Plugins/MultiEmail/vendor/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php" [3]=> int(309) } } [1]=> array(4) { ["file"]=> string(98) "/var/www/html/Plugins/MultiEmail/vendor/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php" ["line"]=> int(309) ["function"]=> string(7) "implode" ["args"]=> array(2) { [0]=> string(1) " " [1]=> array(10) { [0]=> string(3) "BAD" [1]=> string(5) "Error" [2]=> string(2) "in" [3]=> string(4) "IMAP" [4]=> string(7) "command" [5]=> string(3) "UID" [6]=> string(7) "SEARCH:" [7]=> string(7) "Missing" [8]=> string(8) "argument" [9]=> array(4) { [0]=> string(5) "0.001" [1]=> string(1) "+" [2]=> string(5) "0.000" [3]=> string(6) "secs)." } } } } [2]=> array(6) { ["file"]=> string(98) "/var/www/html/Plugins/MultiEmail/vendor/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php" ["line"]=> int(383) ["function"]=> string(12) "readResponse" ["class"]=> string(49) "Webklex\PHPIMAP\Connection\Protocols\ImapProtocol" ["type"]=> string(2) "->" ["args"]=> array(3) { [0]=> object(Webklex\PHPIMAP\Connection\Protocols\Response)#290 (8) { ["commands":protected]=> array(1) { [0]=> string(97) "TAG4 UID SEARCH SUBJECT "Contacto Web" OR TO "messages-noreply@linkedin.com" OR TEXT "Fernando" " } ["response":protected]=> array(1) { [0]=> string(83) "TAG4 BAD Error in IMAP command UID SEARCH: Missing argument (0.001 + 0.000 secs). " } ["errors":protected]=> array(0) { } ["result":protected]=> NULL ["noun":protected]=> int(4) ["response_stack":protected]=> array(0) { } ["debug":protected]=> bool(false) ["can_be_empty":protected]=> bool(false) } [1]=> string(4) "TAG4" [2]=> bool(false) } } [3]=> array(6) { ["file"]=> string(98) "/var/www/html/Plugins/MultiEmail/vendor/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php" ["line"]=> int(1223) ["function"]=> string(18) "requestAndResponse" ["class"]=> string(49) "Webklex\PHPIMAP\Connection\Protocols\ImapProtocol" ["type"]=> string(2) "->" ["args"]=> array(2) { [0]=> string(10) "UID SEARCH" [1]=> array(1) { [0]=> string(79) "SUBJECT "Contacto Web" OR TO "messages-noreply@linkedin.com" OR TEXT "Fernando"" } } } [4]=> array(6) { ["file"]=> string(76) "/var/www/html/Plugins/MultiEmail/vendor/webklex/php-imap/src/Query/Query.php" ["line"]=> int(197) ["function"]=> string(6) "search" ["class"]=> string(49) "Webklex\PHPIMAP\Connection\Protocols\ImapProtocol" ["type"]=> string(2) "->" ["args"]=> array(2) { [0]=> array(1) { [0]=> string(79) "SUBJECT "Contacto Web" OR TO "messages-noreply@linkedin.com" OR TEXT "Fernando"" } [1]=> int(1) } } [5]=> array(6) { ["file"]=> string(76) "/var/www/html/Plugins/MultiEmail/vendor/webklex/php-imap/src/Query/Query.php" ["line"]=> int(378) ["function"]=> string(6) "search" ["class"]=> string(27) "Webklex\PHPIMAP\Query\Query" ["type"]=> string(2) "->" ["args"]=> array(0) { } } [6]=> array(6) { ["file"]=> string(58) "/var/www/html/Plugins/MultiEmail/Controller/InboxEmail.php" ["line"]=> int(1254) ["function"]=> string(3) "get" ["class"]=> string(27) "Webklex\PHPIMAP\Query\Query" ["type"]=> string(2) "->" ["args"]=> array(0) { } } [7]=> array(6) { ["file"]=> string(58) "/var/www/html/Plugins/MultiEmail/Controller/InboxEmail.php" ["line"]=> int(131) ["function"]=> string(17) "renderInboxAction" ["class"]=> string(55) "FacturaScripts\Plugins\MultiEmail\Controller\InboxEmail" ["type"]=> string(2) "->" ["args"]=> array(0) { } } [8]=> array(6) { ["file"]=> string(40) "/var/www/html/Core/App/AppController.php" ["line"]=> int(187) ["function"]=> string(11) "privateCore" ["class"]=> string(55) }