Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ Gotowe rozwiązania _ Przeszukiwanie skrzynki pocztowej

Napisany przez: DNMX 11.03.2023, 16:36:26

Hej
Napisałem prosty skrypcik w PHP który korzysta z biblikiteki php-imap i ma za zadanie znaleść w mojej skrzynce wszystkie maile powiedzmy od Allegro. Użyłem takiego kodu:

  1. <?php
  2. $mbox = imap_open("{imap.poczta.onet.pl:993/imap/ssl}", "mojlogin@onet.pl", "haslo");
  3. c1 = imap_search($mbox, 'SINCE "8 August 2022"', SE_UID);
  4. http://www.php.net/var_dump($c1);
  5. ?>

Tu jest ok, zwraca mi ładnie tablicę z id wiadomości otrzymanych po 8 sierpnia. Jednak gdy zrobię tak:
  1. <?php
  2. $mbox = imap_open("{imap.poczta.onet.pl:993/imap/ssl}", "mojlogin@onet.pl", "haslo");
  3. $c2 = imap_search($mbox, 'BODY "allegro"', SE_UID, "UTF-8");
  4. http://www.php.net/var_dump($c2);
  5. ?>

dostaję:
Cytat
bool(false)

Dlaczego? Co robię nie tak?

Napisany przez: Salvation 11.03.2023, 17:23:53

Z https://www.php.net/manual/en/function.imap-search.php:
Return false if it does not understand the search criteria or no messages have been found.

Swoją drogą, dlaczego użyłeś 'BODY', a nie 'SUBJECT' albo 'FROM'?

Napisany przez: DNMX 11.03.2023, 18:38:10

Dla SUBJECT też zwraca false. Jak to debugować? Skąd mam wiedzieć czy to funkcja, czy serwer Onetu nie zrozumiał mojego wyszukiwania?

Napisany przez: LowiczakPL 12.03.2023, 09:38:54

Cytat(DNMX @ 11.03.2023, 16:36:26 ) *
c1 = imap_search($mbox, 'SINCE "8 August 2022"', SE_UID);
$c2 = imap_search($mbox, 'BODY "allegro"', SE_UID, "UTF-8");


czy czasami w dokumentacji nie ma tak imap_search($imap_stream, $criteria, [$options, $charset]);

czy trzeci parametr to tablica nie string ?

Napisany przez: DNMX 12.03.2023, 11:34:45

W https://www.php.net/manual/en/function.imap-search pisze, że trzeci argument to flags i może przyjmować taką wartość jak w przykładzie.
Zresztą:

  1. $uids = imap_search($mbox, 'ALL', SE_UID, "UTF-8");
  2. http://www.php.net/var_dump($uids);

działa, tylko wyszukiwanie nie chce działać. Czy znacie może jakąś inną bibliotekę PHP która obsługiwałaby wyszukiwanie przez IMAP?

Napisany przez: Salvation 12.03.2023, 17:44:51

Nie korzystałem, ale ta jest chyba najbardziej aktualna i wciąż utrzymywana:
https://github.com/ddeboer/imap

Napisany przez: DNMX 12.03.2023, 19:06:52

Natknąłem się na tę bibliotekę jak sam googlowałem. Przykładowy kod z jej wykorzystaniem:

  1. <?php
  2. include("vendor/autoload.php");
  3. use Ddeboer\Imap\Server;
  4. use Ddeboer\Imap\SearchExpression;
  5. use Ddeboer\Imap\Search\Email\From;
  6. use Ddeboer\Imap\Search\Text\Body;
  7. use Ddeboer\Imap\Search\Text\Keyword;
  8. use Ddeboer\Imap\Search\Text\Subject;
  9. use Ddeboer\Imap\Search\Text\Text;
  10.  
  11. $server = new Server('imap.poczta.onet.pl');
  12. $connection = $server->authenticate('login@onet.pl', 'haslo');
  13. $mailboxes = $connection->getMailboxes();
  14.  
  15. foreach ($mailboxes as $mailbox) {
  16. // Skip container-only mailboxes
  17. // @see https://secure.php.net/manual/en/function.imap-getmailboxes.php
  18. if ($mailbox->getAttributes() & \LATT_NOSELECT) {
  19. continue;
  20. }
  21.  
  22. if($mailbox->getName() == "Społeczności") {
  23. http://www.php.net/echo $mailbox->count();
  24. $search = new SearchExpression();
  25. $search->addCondition(new Body('contents'));
  26. $messages = $mailbox->getMessages($search);
  27. http://www.php.net/printf($messages->count()."\n");
  28. if($messages) {
  29. <------>foreach ($messages as $message) {
  30. <------> $message->getBodyText();
  31. <------>}
  32. }
  33. }
  34. }
  35. ?>

daje:
Kod
Fatal error</b>:  Uncaught Ddeboer\Imap\Exception\InvalidSearchCriteriaException: Invalid search criteria [BODY "contents"]
imap_alerts (0):
imap_errors (1):
- [SERVERBUG] BUG: Unknown internal error (0.003 + 0.000 + 0.002 secs). in /var/www/html/vendor/ddeboer/imap/src/Mailbox.php:139
Stack trace:
#0 /var/www/html/ndex.php(26): Ddeboer\Imap\Mailbox->getMessages()
#1 {main}
  thrown in <b>/var/www/html/src/Mailbox.php</b> on line <b>139</b><br />

i tak się zastanawiam, czy ten błąd " Invalid search criteria" wywala serwer Onetu czy gdzieś coś pod spodem na moim serwerze

Googluję dalej i natknąłem się na https://bugs.php.net/bug.php?id=15238 mówiącą, że PHP korzysta z funkcji wyszukiwania z IMAP2. Tymczasem jak odezwiemy się telnetem do serwera pocztowego Onetu mówi on nam, ze komunikuje się z nami za pomocą IMAP w wersji czwartej:
Kod
telnet imap.poczta.onet.pl 143
Trying 213.180.147.154...
Connected to imap.poczta.onet.pl.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID LITERAL+ STARTTLS AUTH=PLAIN AUTH=LOGIN AUTH=XOAUTH2] Onet server ready.
* BYE Disconnected for inactivity.
Connection closed by foreign host

Napisany przez: Salvation 12.03.2023, 19:24:28

Najlepiej, to odpalić xdebuga i przejść krok po kroku co się dzieje pod spodem.
Błąd dotyczy linii 139, ale sam Exception jest dopiero w linii 157...
https://github.com/ddeboer/imap/blob/master/src/Mailbox.php#L155

Napisany przez: DNMX 13.03.2023, 12:09:43

Pogadałem sobie z Onetem przez telnet i w taki sposób też nie udało mi się przeszukać skrzynki. Postanowiłem podejśc do zagadnienia inaczej. Szukam na moim koncie dwóch interesujacych mnie skrzynek pocztowych - Społeczności i odebrane (INBOX). Pobieram 50 najnoszywch wiadomosci i sprawdzam, czy wśród nich jest coś od Allegro. Stworzyłem taki kod:

  1. $provider['mailboxes'] = http://www.php.net/array('Społeczności', 'INBOX');
  2. $any_valid_mailbox = false;
  3. $mailboxes = $connection->getMailboxes();
  4. //debug("Znalezione mailboxy:\n");
  5. //var_dump($mailboxes);
  6. foreach($mailboxes as $found_mailbox) {
  7. foreach($provider['mailboxes'] as $valid_mailbox) {
  8. debug("Czy jest tu ".$valid_mailbox);
  9. if($found_mailbox->getName() == $valid_mailbox) {
  10. $any_valid_mailbox = true;
  11. // Sprawdź ile w tym mailboxie wiadomosci, przeszukaj nie więcej niż MAX_MESSAGES najświeższych
  12. $messages = $found_mailbox->getMessages($search);
  13. $msg_count = $messages->count();
  14. http://www.php.net/var_dump($messages);
  15. debug("Jest $valid_mailbox z $msg_count wiadomościami !!!");
  16. }
  17. }
  18. }

W odpowiedzi dostaję coś takiego:
https://pastebin.com/raw/UNzgVq6k

Tylko nie mam pojecia jak się proszuać po takim objekcie żeby wydobyć wszystkie ID wiadomości, posortować je od najwyższego i wydobyć 50 największych (konkretnie chodzi mi o numerki 1187, 1186 .. 1040 dla INBOX i analogicznie 587 ... 533 dla Społeczności. Próbowałem foreacha na $messages ale nie działa

Napisany przez: ohm 13.03.2023, 17:09:41

Cytat
Tylko nie mam pojecia jak się proszuać po takim objekcie


Ta klasa z tego co widze robi extends po \ArrayIterator więc powinno się dać go ogarniać jak array iteratora,

https://github.com/ddeboer/imap/blob/master/src/MessageIterator.php
https://www.php.net/manual/en/class.arrayiterator.php

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)