php-imap icon indicating copy to clipboard operation
php-imap copied to clipboard

how to put pagination code?

Open nancysavchenko opened this issue 5 years ago • 8 comments

how to put this code? $overview = $mailbox->imap('fetch_overview', $from . ':' . $to);

where should i put it?

require_once dirname(__FILE__) . '/vendor/autoload.php';
use PhpImap\Mailbox;
use PhpImap\Exceptions\ConnectionException;

$array = [];
$cmailbox = new PhpImap\Mailbox('{secureimap.t-online.de:993/imap/ssl}INBOX', 'afafaaad', 'adaaad', null, 'US-ASCII');

try 
{
	$smailids = $cmailbox->searchMailbox('ALL', SE_FREE, 'UTF-8');
	$cmailbox->setServerEncoding('UTF-8');

	foreach ($smailids as $key => $value) 
	{
		$fetchmail = $cmailbox->getMail($value, false);
		$array[] = ['id' => $fetchmail->id, 'subject' => $fetchmail->subject, 'date' => date('d F Y h:i:s A', strtotime($fetchmail->date))];
	}
}

catch (PhpImap\Exceptions\ConnectionException $ex) 
{
	$array['status'] = $ex;
}

echo json_encode($array, JSON_PRETTY_PRINT);

nancysavchenko avatar Feb 02 '20 06:02 nancysavchenko

@bapcltd-marv do you think it makes sense to add pagination by default to this library? And the most important question: Any idea how or if this can be archived? I never worked with pagination yet.

Sebbo94BY avatar May 06 '20 10:05 Sebbo94BY

@Sebi94nbg ~having a tinker.~: thoughts? https://github.com/barbushin/php-imap/compare/develop...bapcltd:pagination

haven't actually tested the implementation yet, just fleshed out & ran static analysis on it.

summary of implemenation:

  • adds a method on Mailbox that returns a class that wraps back to the Mailbox::searchMailbox* methods.
  • pagination class runs the search, then returns a class implementing Countable and SeekableIterator on the list<int> of mail ids.
    • Countable::count() indicates number of pages, IncomingMailSeekableIterator::countMailIds() indicates number of results
  • IncomingMailSeekableIterator::current() returns a child-class of LimitIterator
    • LimitIterator::current() is overridden to pass the current mail id to Mailbox::getMail(), which defaults to not marking the mail as seen.
      • because the mails are not fetched immediately, there's a chance that the mail might be gone in the short time between search and retrieval.
    • I still need to pass the $pageSize param to LimitIterator::__construct() so that the iterator doesn't skip past the page it represents.

example usage:

$results = $mailbox->searchPagination(20)->searchMailbox();
$i = 0;
foreach ($results as $page => $mails) {
    echo sprintf(
        'page %s of %s: %s-%s of %s',
        ($page + 1),
        count($results),
        $mails->getPosition() + 1,
        $mails->getPosition() + 20,
        $results->countMailIds()
    ), "\n";
    foreach ($mails as $mail) {
        echo ++$i, ': ', $mail->subject, "\n";
    }
}

which should spit out something like:

page 1 of 5: 1-20 of 100
1: foo
2: bar
3: etc....

page 2 of 5: 21-40 of 100
21: foo
22: bar
23: etc...

bapcltd-marv avatar May 06 '20 14:05 bapcltd-marv

I'm going to hazard a guess if we were to OOP up the pagination like this, we'd want inner iterators that return results for other mail-related Mailbox methods?

bapcltd-marv avatar May 06 '20 16:05 bapcltd-marv

@bapcltd-marv do you think it makes sense to add pagination by default to this library?

to answer this specific question, if it doesn't seem to fit there could always be a separate package.

bapcltd-marv avatar May 07 '20 08:05 bapcltd-marv

Your above example already looks very awesome. I guess a separate package doesn't make that much sense. I would include it directly into this package or leave it at all.

I think, the user should be able to decide when and if he wants to use pagination or not. So I would add pagination support as different function. This should be only required for getting the list of mails, right? So we don't need it for any other functions eg. "mark as read/unread" etc..

Sebbo94BY avatar May 08 '20 12:05 Sebbo94BY

This should be only required for getting the list of mails, right? So we don't need it for any other functions eg. "mark as read/unread" etc..

the constructor allows configuring the read-on-fetch flag, but I'm not sure what happens to read messages when this is false- do they get marked as unread again ?

if they don't get marked as read, then we could:

  • [x] remove the constructor flag
  • [ ] hardcode read-on-fetch to false
  • [ ] maybe remove the Mailbox::searchPagination() method, as it mostly just serves as a wrapper because the pagination constructor takes the mailbox as an argument.

bapcltd-marv avatar May 08 '20 14:05 bapcltd-marv

shall I pick this up again after the next release ?

bapcltd-marv avatar May 29 '20 20:05 bapcltd-marv

Sure, feel free. It's your knowledge and time. :)

Sebbo94BY avatar Jun 02 '20 20:06 Sebbo94BY