
=head1 NAME

Mail::Box::IMAP4 - handle IMAP4 folders as client


=head1 INHERITANCE

 Mail::Box::IMAP4
   is a Mail::Box::Net
   is a Mail::Box
   is a Mail::Reporter


=head1 SYNOPSIS

 use Mail::Box::IMAP4;
 my $folder = new Mail::Box::IMAP4 folder => $ENV{MAIL}, ...;


=head1 DESCRIPTION

UNDER DEVELOPMENT!!!! LIMITATIONS:

=over 4
=item * this implementation is close to NOT TESTED!
Of course, some testing has been done, but this is far from complete. Please
contribute with ideas are problem reports.

=item * messages are all treated as separte items

Performance can be improved combining request for multiple subjects. For
instance, a preloadFields() or a preloadEnvelope() would speed-up most

applications
=back

Maintain a folder which has its messages stored on a remote server.  The
communication between the client application and the server is implemented
using the IMAP4 protocol.

This class uses L<Mail::Transport::IMAP4|Mail::Transport::IMAP4> to hide the transport of
information, and focusses solely on the correct handling of messages
within a IMAP4 folder.  More than one IMAP4 folder can be handled by
one single IMAP4 connection.


=head1 OVERLOADED


overload: B<"">

=over 4

See L<Mail::Box/"OVERLOADED">

=back

overload: B<@{}>

=over 4

See L<Mail::Box/"OVERLOADED">

=back

overload: B<cmp>

=over 4

See L<Mail::Box/"OVERLOADED">

=back


=head1 METHODS


=head2 Constructors


$obj-E<gt>B<create>(FOLDER, OPTIONS)

Mail::Box::IMAP4-E<gt>B<create>(FOLDER, OPTIONS)

=over 4

See L<Mail::Box::Net/"METHODS">

=back

Mail::Box::IMAP4-E<gt>B<new>(OPTIONS)

=over 4

The C<new> can have many OPTIONS.  Not only the ones listed here below,
but also all the OPTIONS for L<Mail::Transport::IMAP4::new()|Mail::Transport::IMAP4/"METHODS"> can be
passed.

The default depends on the value of L<new(cache_head)|Mail::Box::IMAP4/"METHODS">.

Without folder name, no folder is selected.  Only few methods are
available now, for instance L<listSubFolders()|Mail::Box/"Sub-folders"> to get the top-level
folder names.  Usually, the folder named C<INBOX> will be present.

 Option             Defined in       Default                                                                                                           
 access             L<Mail::Box>     'r'                                                                                                               
 body_delayed_type  L<Mail::Box>     L<Mail::Message::Body::Delayed|Mail::Message::Body::Delayed>                                                      
 body_type          L<Mail::Box>     L<Mail::Message::Body::Lines|Mail::Message::Body::Lines>                                                          
 cache_body                          C<NO>                                                                                                             
 cache_head                          C<NO> or C<DELAY>                                                                                                 
 cache_labels                        C<NO> or C<DELAY>                                                                                                 
 coerce_options     L<Mail::Box>     C<[]>                                                                                                             
 create             L<Mail::Box>     <false>                                                                                                           
 extract            L<Mail::Box>     C<10240>                                                                                                          
 field_type         L<Mail::Box>     undef                                                                                                             
 fix_headers        L<Mail::Box>     <false>                                                                                                           
 folder             L<Mail::Box>     C</>                                                                                                              
 folderdir          L<Mail::Box>     <not used>                                                                                                        
 head_delayed_type  L<Mail::Box>     L<Mail::Message::Head::Delayed|Mail::Message::Head::Delayed>                                                      
 head_type          L<Mail::Box>     L<Mail::Box::IMAP4::Head|Mail::Box::IMAP4::Head> or L<Mail::Message::Head::Complete|Mail::Message::Head::Complete>
 join_connection                     C<true>                                                                                                           
 keep_dups          L<Mail::Box>     <false>                                                                                                           
 lock_file          L<Mail::Box>     undef                                                                                                             
 lock_timeout       L<Mail::Box>     1 hour                                                                                                            
 lock_type          L<Mail::Box>     C<'NONE'>                                                                                                         
 lock_wait          L<Mail::Box>     10 seconds                                                                                                        
 locker             L<Mail::Box>     undef                                                                                                             
 log                L<Mail::Reporter>  C<'WARNINGS'>                                                                                                     
 manager            L<Mail::Box>     undef                                                                                                             
 message_type       L<Mail::Box>     L<Mail::Box::IMAP4::Message|Mail::Box::IMAP4::Message>                                                            
 multipart_type     L<Mail::Box>     L<Mail::Message::Body::Multipart|Mail::Message::Body::Multipart>                                                  
 password           L<Mail::Box::Net>  undef                                                                                                             
 remove_when_empty  L<Mail::Box>     <false>                                                                                                           
 save_on_exit       L<Mail::Box>     <true>                                                                                                            
 server_name        L<Mail::Box::Net>  undef                                                                                                             
 server_port        L<Mail::Box::Net>  143                                                                                                               
 trace              L<Mail::Reporter>  C<'WARNINGS'>                                                                                                     
 transporter                         L<Mail::Transport::IMAP4|Mail::Transport::IMAP4>                                                                  
 trusted            L<Mail::Box>     <false>                                                                                                           
 username           L<Mail::Box::Net>  undef                                                                                                             

. access MODE

. body_delayed_type CLASS

. body_type CLASS|CODE

. cache_body 'NO'|'YES'|'DELAY'

=over 4

Body objects are immutable, but may still cached or not.  In common
case, the body of a message is requested via L<Mail::Message::body()|Mail::Message/"The body">
or L<Mail::Message::decoded()|Mail::Message/"The body">.  This returns a handle to a body object.
You may decide wether that body object can be reused or not.  C<NO>
means: retreive the data each time again, C<YES> will cache the body data,
C<DELAY> will send the whole message when the folder is closed.

        [local cache]  [write]
 NO         no           no
 YES        yes          no
 DELAY      yes          yes

=back

. cache_head 'NO'|'PARTIAL'|'DELAY'

=over 4

For a read-only folder, C<DELAY> is the default, otherwise C<NO> is
choosen.  The four configuration parameter have subtile consequences.
To start with a table:

        [local cache]  [write]  [default head_type]
 NO         no           no     Mail::Box::IMAP4::Head
 PARTIAL    yes          no     Mail::Box::IMAP4::Head
 DELAY      yes          yes    Mail::Message::Head::Complete

The default C<head_type> is L<Mail::Box::IMAP4::Head|Mail::Box::IMAP4::Head>, the
default C<cached_head_type> is L<Mail::Message::Head::Complete|Mail::Message::Head::Complete>.

Having a local cache means that a lookup for a field is first done
in a local data-structure (which extends L<Mail::Message::Head::Partial|Mail::Message::Head::Partial>),
and only on the remote server if it was not found.  This is dangerous,
because your locally cached data can be out-of-sync with the server.
However, it may give you a nice performance benefit.

C<DELAY> will always collect the whole
header for you.  This is required when you want to look for Resent Groups
(See L<Mail::Message::Head::ResentGroup|Mail::Message::Head::ResentGroup>) or other field order dependent
header access.  A L<Mail::Message::Head::Delayed|Mail::Message::Head::Delayed> will be created first.

=back

. cache_labels 'NO'|'WRITE'|'DELAY'

=over 4

When labels from a message are received, these values can be kept. However,
this imposes dangers where the server's internal label storage may get out
of sync with your data.

With C<NO>, no caching will take place (but the performance will be
worse). With C<WRITE>, all label access will be cached, but written to
the server as well.  Both C<NO> and C<WRITE> will update the labels on
the served, even when the folder was opened read-only.  C<DELAY> will
not write the changed information to the server, but delay that till
the moment that the folder is closed.  It only works when the folder is
opened read/write or write is enforced.

The default is C<DELAY> for folders which where opened read-only.  This
means that you still can force an update with L<close(write)|Mail::Box/"The folder">.  For folders
which are opened read-write, the default is the safeset setting, which is
C<NO>.

=back

. coerce_options ARRAY

. create BOOLEAN

. extract INTEGER | CODE | METHOD | 'LAZY'|'ALWAYS'

. field_type CLASS

. fix_headers BOOLEAN

. folder FOLDERNAME

. folderdir DIRECTORY

. head_delayed_type CLASS

. head_type CLASS

. join_connection BOOLEAN

=over 4

Within this Mail::Box::IMAP4 class is registered which transporters are
already in use, i.e. which connections to the IMAP server are already
in established.  When this option is set, multiple folder openings on the
same server will try to reuse one connection.

=back

. keep_dups BOOLEAN

. lock_file FILENAME

. lock_timeout SECONDS

. lock_type CLASS|STRING|ARRAY

. lock_wait SECONDS

. locker OBJECT

. log LEVEL

. manager MANAGER

. message_type CLASS

. multipart_type CLASS

. password STRING

. remove_when_empty BOOLEAN

. save_on_exit BOOLEAN

. server_name HOSTNAME

. server_port INTEGER

. trace LEVEL

. transporter OBJECT|CLASS

=over 4

The name of the CLASS which will interface with the connection.  When you
implement your own extension to L<Mail::Transport::IMAP4|Mail::Transport::IMAP4>, you can either
specify a fully instantiated transporter OBJECT, or the name of your own
CLASS.  When an OBJECT is given, most other options will be ignored.

=back

. trusted BOOLEAN

. username STRING

I<Example:> 

 my $imap   = Mail::Box::IMAP4->new(username => 'myname',
    password => 'mypassword', server_name => 'imap.xs4all.nl');

 my $url    = 'imap4://user:password@imap.xs4all.nl');
 my $imap   = $mgr->open($url);

 my $client = Mail::IMAPClient->new(...);
 my $imap   = Mail::Box::IMAP4->new(imap_client => $client);

=back

=head2 The folder


$obj-E<gt>B<addMessage>(MESSAGE)

=over 4

See L<Mail::Box/"The folder">

=back

$obj-E<gt>B<addMessages>(MESSAGE [, MESSAGE, ...])

=over 4

See L<Mail::Box/"The folder">

=back

Mail::Box::IMAP4-E<gt>B<appendMessages>(OPTIONS)

=over 4

See L<Mail::Box/"The folder">

=back

$obj-E<gt>B<close>(OPTIONS)

=over 4

Close the folder.  In the case of IMAP, more than one folder can use
the same connection, therefore, closing a folder does not always close
the connection to the server.  Only when no folder is using the
connection anymore, a logout will be invoked by
L<Mail::Transport::IMAP4::DESTROY()|Mail::Transport::IMAP4/"Cleanup">

 Option        Defined in       Default    
 force         L<Mail::Box>     <false>    
 save_deleted  L<Mail::Box>     C<false>   
 write         L<Mail::Box>     C<MODIFIED>

. force BOOLEAN

. save_deleted BOOLEAN

. write 'ALWAYS'|'NEVER'|'MODIFIED'

=back

$obj-E<gt>B<copyTo>(FOLDER, OPTIONS)

=over 4

See L<Mail::Box/"The folder">

=back

$obj-E<gt>B<delete>

=over 4

See L<Mail::Box/"The folder">

=back

$obj-E<gt>B<folderdir>([DIRECTORY])

=over 4

See L<Mail::Box::Net/"METHODS">

=back

Mail::Box::IMAP4-E<gt>B<foundIn>([FOLDERNAME], OPTIONS)

=over 4

See L<Mail::Box/"The folder">

=back

$obj-E<gt>B<name>

=over 4

See L<Mail::Box/"The folder">

=back

$obj-E<gt>B<organization>

=over 4

See L<Mail::Box/"The folder">

=back

$obj-E<gt>B<size>

=over 4

See L<Mail::Box/"The folder">

=back

$obj-E<gt>B<type>

=over 4

See L<Mail::Box/"The folder">

=back

$obj-E<gt>B<update>(OPTIONS)

=over 4

See L<Mail::Box/"The folder">

=back

$obj-E<gt>B<url>

=over 4

See L<Mail::Box/"The folder">

=back

=head2 Folder flags


$obj-E<gt>B<isModified>

=over 4

See L<Mail::Box/"Folder flags">

=back

$obj-E<gt>B<modified>([BOOLEAN])

=over 4

See L<Mail::Box/"Folder flags">

=back

$obj-E<gt>B<writable>

=over 4

See L<Mail::Box/"Folder flags">

=back

=head2 The messages


$obj-E<gt>B<current>([NUMBER|MESSAGE|MESSAGE-ID])

=over 4

See L<Mail::Box/"The messages">

=back

$obj-E<gt>B<find>(MESSAGE-ID)

=over 4

See L<Mail::Box/"The messages">

=back

$obj-E<gt>B<findFirstLabeled>(LABEL, [BOOLEAN, [ARRAY-OF-MSGS]])

=over 4

See L<Mail::Box/"The messages">

=back

$obj-E<gt>B<message>(INDEX [,MESSAGE])

=over 4

See L<Mail::Box/"The messages">

=back

$obj-E<gt>B<messageId>(MESSAGE-ID [,MESSAGE])

=over 4

See L<Mail::Box/"The messages">

=back

$obj-E<gt>B<messageIds>

=over 4

See L<Mail::Box/"The messages">

=back

$obj-E<gt>B<messages>(['ALL',RANGE,'ACTIVE','DELETED',LABEL,!LABEL,FILTER])

=over 4

See L<Mail::Box/"The messages">

=back

$obj-E<gt>B<scanForMessages>(MESSAGE, MESSAGE-IDS, TIMESPAN, WINDOW)

=over 4

See L<Mail::Box/"The messages">

=back

=head2 Sub-folders


$obj-E<gt>B<listSubFolders>(OPTIONS)

Mail::Box::IMAP4-E<gt>B<listSubFolders>(OPTIONS)

=over 4

See L<Mail::Box/"Sub-folders">

=back

$obj-E<gt>B<nameOfSubFolder>(NAME)

=over 4

See L<Mail::Box/"Sub-folders">

=back

$obj-E<gt>B<openRelatedFolder>(OPTIONS)

=over 4

See L<Mail::Box/"Sub-folders">

=back

$obj-E<gt>B<openSubFolder>(NAME, OPTIONS)

=over 4

See L<Mail::Box/"Sub-folders">

=back

=head2 Internals


$obj-E<gt>B<body>([BODY])

=over 4

=back

$obj-E<gt>B<coerce>(MESSAGE)

=over 4

See L<Mail::Box/"Internals">

=back

$obj-E<gt>B<createTransporter>(CLASS, OPTIONS)

=over 4

Create a transporter object (an instance of L<Mail::Transport::IMAP4|Mail::Transport::IMAP4>), where
CLASS defines the exact object type.  As OPTIONS, everything which is
acceptable to a transporter initiation can be used (see
L<Mail::Transport::IMAP4::new()|Mail::Transport::IMAP4/"METHODS">.

 Option           Defined in  Default
 join_connection              C<true>

. join_connection BOOLEAN

=over 4

See L<new(join_connection)|Mail::Box::IMAP4/"METHODS">.  When false, the connection will never be shared
with other IMAP mail boxes.

=back

=back

$obj-E<gt>B<determineBodyType>(MESSAGE, HEAD)

=over 4

See L<Mail::Box/"Internals">

=back

$obj-E<gt>B<fetch>(ARRAY-OF-MESSAGES|MESSAGE-SELECTION, INFO)

=over 4

Low-level data retreival about one or more messages via IMAP4 from
the remote server. Some of this data may differ from the information
which is stored in the message objects which are created by MailBox,
so you should avoid the use of this method for your own purposes.
The IMAP implementation provides some wrappers around this, providing
the correct behavior.

An array of MESSAGES may be specified or some MESSAGE SELECTION,
acceptable to L<Mail::Box::messages()|Mail::Box/"The messages">.  Examples of the latter are
C<'ALL'>, C<'DELETED'>, or C<spam> (messages labelled to contain spam).

The INFO contains one or more attributes as defined by the IMAP protocol.
You have to read the full specs of the related RFCs to see these.

=back

$obj-E<gt>B<getHead>(MESSAGE)

=over 4

Read the header for the specified message from the remote server.
C<undef> is returned in case the message disappeared.

=back

$obj-E<gt>B<getHeadAndBody>(MESSAGE)

=over 4

Read all data for the specified message from the remote server.
Return head and body of the mesasge as list, or an empty list
if the MESSAGE disappeared from the server.

=back

$obj-E<gt>B<lineSeparator>([STRING|'CR'|'LF'|'CRLF'])

=over 4

See L<Mail::Box/"Internals">

=back

$obj-E<gt>B<locker>

=over 4

See L<Mail::Box/"Internals">

=back

$obj-E<gt>B<read>(OPTIONS)

=over 4

See L<Mail::Box/"Internals">

=back

$obj-E<gt>B<readMessages>(OPTIONS)

=over 4

See L<Mail::Box/"Internals">

=back

$obj-E<gt>B<storeMessage>(MESSAGE)

=over 4

See L<Mail::Box/"Internals">

=back

$obj-E<gt>B<toBeThreaded>(MESSAGES)

=over 4

See L<Mail::Box/"Internals">

=back

$obj-E<gt>B<toBeUnthreaded>(MESSAGES)

=over 4

See L<Mail::Box/"Internals">

=back

$obj-E<gt>B<transporter>([OBJECT])

=over 4

Returns the object which is the interface to the IMAP4 protocol handler.
The IMAP4 handler has the current folder selected.
When an OBJECT is specified, it is set to be the transporter from
that moment on.  The OBJECT must extend L<Mail::Transport::IMAP4|Mail::Transport::IMAP4>.

=back

$obj-E<gt>B<updateMessages>(OPTIONS)

=over 4

See L<Mail::Box/"Internals">

=back

$obj-E<gt>B<write>(OPTIONS)

=over 4

The IMAP protocol usually writes the data immediately to the remote server,
because that's what the protocol wants.  However, some options to L<new()|Mail::Box::IMAP4/"METHODS">
may delay that to boost performance.  This method will, when the folder is
being closed, write that info after all.

 Option        Defined in       Default
 force         L<Mail::Box>     <false>
 save_deleted                   <false>

. force BOOLEAN

. save_deleted BOOLEAN

=over 4

You may be able to save the messages which are flagged for deletion now,
but they will be removed anyway when the folder is closed.

=back

=back

$obj-E<gt>B<writeMessages>(OPTIONS)

=over 4

 Option       Defined in       Default   
 messages     L<Mail::Box>     <required>
 transporter                   <required>

. messages ARRAY

. transporter OBJECT

=back

=head2 Other methods


$obj-E<gt>B<timespan2seconds>(TIME)

Mail::Box::IMAP4-E<gt>B<timespan2seconds>(TIME)

=over 4

See L<Mail::Box/"Other methods">

=back

=head2 Error handling


$obj-E<gt>B<AUTOLOAD>

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<addReport>(OBJECT)

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<defaultTrace>([LEVEL, [LEVEL])

Mail::Box::IMAP4-E<gt>B<defaultTrace>([LEVEL, [LEVEL])

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<errors>

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<log>([LEVEL [,STRINGS]])

Mail::Box::IMAP4-E<gt>B<log>([LEVEL [,STRINGS]])

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<logPriority>(LEVEL)

Mail::Box::IMAP4-E<gt>B<logPriority>(LEVEL)

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<logSettings>

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<notImplemented>

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<report>([LEVEL])

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<reportAll>([LEVEL])

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<trace>([LEVEL])

=over 4

See L<Mail::Reporter/"Error handling">

=back

$obj-E<gt>B<warnings>

=over 4

See L<Mail::Reporter/"Error handling">

=back

=head2 Cleanup


$obj-E<gt>B<DESTROY>

=over 4

See L<Mail::Box/"Cleanup">

=back

$obj-E<gt>B<inGlobalDestruction>

=over 4

See L<Mail::Reporter/"Cleanup">

=back



=head1 DIAGNOSTICS

I<Warning:> Cannot find head back for $uidl in $folder.

The header was read before, but now seems empty: the IMAP4 server does
not produce the header lines anymore.

I<Warning:> Cannot read body for $uidl in $folder.

The header of the message was retreived from the IMAP4 server, but the
body is not read, for an unknown reason.

I<Error:> Copying failed for one message.

For some reason, for instance disc full, removed by external process, or
read-protection, it is impossible to copy one of the messages.  Copying will
proceed for the other messages.

I<Error:> Destination folder $name is not writable.

The folder where the messages are copied to is not opened with write
access (see L<new(access)|Mail::Box/"Constructors">).  This has no relation with write permission
to the folder which is controled by your operating system.

I<Warning:> Different messages with id $msgid.

The message id is discovered more than once within the same folder, but the
content of the message seems to be different.  This should not be possible:
each message must be unique.

I<Error:> Folder $name not deleted: not writable.

The folder must be opened with write access via L<new(access)|Mail::Box/"Constructors">, otherwise
removing it will be refused.  So, you may have write-access according to
the operating system, but that will not automatically mean that this
C<delete> method permits you to.  The reverse remark is valid as well.

I<Notice:> Impossible to keep deleted messages in IMAP

Some folder type have a 'deleted' flag which can be stored in the folder to
be performed later.  The folder keeps that knowledge even when the folder
is rewritten.  Well, IMAP4 cannot play that trick.

I<Error:> Invalid timespan '$timespan' specified.

The string does not follow the strict rules of the time span syntax which
is permitted as parameter.

I<Warning:> Message $uidl disappeared from $folder.

Trying to get the specific message from the server, but it appears to be
gone.

I<Warning:> Message $uidl disappeared from $folder.

Trying to get the specific message from the server, but it appears to be
gone.

I<Warning:> Message-id '$msgid' does not contain a domain.

According to the RFCs, message-ids need to contain a unique random part,
then an C<@>, and then a domain name.  This is made to avoid the creation
of two messages with the same id.  The warning emerges when the C<@> is
missing from the string.

I<Error:> Package $package does not implement $method.

Fatal error: the specific package (or one of its superclasses) does not
implement this method where it should. This message means that some other
related classes do implement this method however the class at hand does
not.  Probably you should investigate this and probably inform the author
of the package.

I<Error:> Unable to create subfolder $name of $folder.

The copy includes the subfolders, but for some reason it was not possible
to copy one of these.  Copying will proceed for all other sub-folders.


=head1 DETAILS


=head2 How IMAP4 folders work






=head1 REFERENCES

See the MailBox website at L<http://perl.overmeer.net/mailbox/> for more details.

=head1 COPYRIGHTS

Distribution version 2.055.
Written by Mark Overmeer (mark@overmeer.net).  See the ChangeLog for
other contributors.

Copyright (c) 2001-2003 by the author(s). All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.


