Source for file imap_mailbox.php

Documentation is available at imap_mailbox.php

  1. <?php
  2.  
  3. /**
  4.  * imap_mailbox.php
  5.  *
  6.  * This implements all functions that manipulate mailboxes
  7.  *
  8.  * @copyright &copy; 1999-2006 The SquirrelMail Project Team
  9.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  10.  * @version $Id: imap_mailbox.php,v 1.172.2.28 2006/10/07 12:58:41 tokul Exp $
  11.  * @package squirrelmail
  12.  * @subpackage imap
  13.  */
  14.  
  15. /** UTF7 support */
  16. require_once(SM_PATH 'functions/imap_utf7_local.php');
  17.  
  18. global $boxesnew;
  19.  
  20. function sortSpecialMbx($a$b{
  21.     if ($a->is_inbox{
  22.         $acmp '0'$a->mailboxname_full;
  23.     else if ($a->is_special{
  24.         $acmp '1'$a->mailboxname_full;
  25.     else {
  26.         $acmp '2' $a->mailboxname_full;
  27.     }
  28.     if ($b->is_inbox{
  29.         $bcmp '0'$b->mailboxname_full;
  30.     }else if ($b->is_special{
  31.         $bcmp '1' $b->mailboxname_full;
  32.     else {
  33.         $bcmp '2' $b->mailboxname_full;
  34.     }
  35.     if ($acmp == $bcmpreturn 0;
  36.     return ($acmp $bcmp1: -1;
  37. }
  38.  
  39. function find_mailbox_name ($mailbox{
  40.     if (preg_match('/\*.+\"([^\r\n\"]*)\"[\s\r\n]*$/'$mailbox$regs))
  41.         return $regs[1];
  42.     if (ereg(" *\"([^\r\n\"]*)\"[ \r\n]*$"$mailbox$regs))
  43.         return $regs[1];
  44.     ereg(" *([^ \r\n\"]*)[ \r\n]*$",$mailbox,$regs);
  45.     return $regs[1];
  46. }
  47.  
  48. /**
  49.  * @return bool whether this is a Noselect mailbox.
  50.  */
  51. function check_is_noselect ($lsub_line{
  52.     return preg_match("/^\* (LSUB|LIST) \([^\)]*\\\\Noselect[^\)]*\)/i"$lsub_line);
  53. }
  54.  
  55. /**
  56.  * If $haystack is a full mailbox name, and $needle is the mailbox
  57.  * separator character, returns the second last part of the full
  58.  * mailbox name (i.e. the mailbox's parent mailbox)
  59.  */
  60. function readMailboxParent($haystack$needle{
  61.     if ($needle == ''{
  62.         $ret '';
  63.     else {
  64.         $parts explode($needle$haystack);
  65.         $elem array_pop($parts);
  66.         while ($elem == '' && count($parts)) {
  67.             $elem array_pop($parts);
  68.         }
  69.         $ret join($needle$parts);
  70.     }
  71.     return$ret );
  72. }
  73.  
  74. /**
  75.  * Check if $subbox is below the specified $parentbox
  76.  */
  77. function isBoxBelow$subbox$parentbox {
  78.     global $delimiter;
  79.     /*
  80.      * Eliminate the obvious mismatch, where the
  81.      * subfolder path is shorter than that of the potential parent
  82.      */
  83.     if strlen($subboxstrlen($parentbox) ) {
  84.       return false;
  85.     }
  86.     /* check for delimiter */
  87.         if (substr($parentbox,-1!= $delimiter{
  88.             $parentbox.=$delimiter;
  89.         }
  90.         if (substr($subbox,0,strlen($parentbox)) == $parentbox{
  91.             return true;
  92.         else {
  93.             return false;
  94.         }
  95. }
  96.  
  97. /**
  98.  * Defines special mailboxes: given a mailbox name, it checks if this is a
  99.  * "special" one: INBOX, Trash, Sent or Draft.
  100.  *
  101.  * Since 1.2.5 function includes special_mailbox hook.<br>
  102.  * Since 1.4.3 hook supports more than one plugin.
  103.  * @param string $box mailbox name
  104.  * @param boolean $include_subs (since 1.5.2 and 1.4.9) if true, subfolders of
  105.  *   system folders are special. if false, subfolders are not special mailboxes
  106.  *   unless they are tagged as special in 'special_mailbox' hook.
  107.  * @return boolean 
  108.  * @since 1.2.3
  109.  */
  110. function isSpecialMailbox($box,$include_subs=true{
  111.     $ret ( (strtolower($box== 'inbox'||
  112.              isTrashMailbox($box,$include_subs|| 
  113.              isSentMailbox($box,$include_subs|| 
  114.              isDraftMailbox($box,$include_subs) );
  115.  
  116.     if !$ret {
  117.         $ret boolean_hook_function('special_mailbox',$box,1);
  118.     }
  119.     return $ret;
  120. }
  121.  
  122. /**
  123.  * Detects if mailbox is a Trash folder or subfolder of Trash
  124.  * @param string $box mailbox name
  125.  * @param boolean $include_subs (since 1.5.2 and 1.4.9) if true, subfolders of
  126.  *   system folders are special. if false, subfolders are not special mailboxes.
  127.  * @return bool whether this is a Trash folder
  128.  * @since 1.4.0
  129.  */
  130. function isTrashMailbox ($box,$include_subs=true{
  131.     global $trash_folder$move_to_trash;
  132.     return $move_to_trash && $trash_folder &&
  133.            $box == $trash_folder || 
  134.              ($include_subs && isBoxBelow($box$trash_folder)) );
  135. }
  136.  
  137. /**
  138.  * Detects if mailbox is a Sent folder or subfolder of Sent
  139.  * @param string $box mailbox name
  140.  * @param boolean $include_subs (since 1.5.2 and 1.4.9) if true, subfolders of
  141.  *   system folders are special. if false, subfolders are not special mailboxes.
  142.  * @return bool whether this is a Sent folder
  143.  * @since 1.4.0
  144.  */
  145. function isSentMailbox($box,$include_subs=true{
  146.    global $sent_folder$move_to_sent;
  147.    return $move_to_sent && $sent_folder &&
  148.           $box == $sent_folder || 
  149.             ($include_subs && isBoxBelow($box$sent_folder)) );
  150. }
  151.  
  152. /**
  153.  * Detects if mailbox is a Drafts folder or subfolder of Drafts
  154.  * @param string $box mailbox name
  155.  * @param boolean $include_subs (since 1.5.2 and 1.4.9) if true, subfolders of
  156.  *   system folders are special. if false, subfolders are not special mailboxes.
  157.  * @return bool whether this is a Draft folder
  158.  * @since 1.4.0
  159.  */
  160. function isDraftMailbox($box,$include_subs=true{
  161.    global $draft_folder$save_as_draft;
  162.    return $save_as_draft &&
  163.           $box == $draft_folder || 
  164.             ($include_subs && isBoxBelow($box$draft_folder)) );
  165. }
  166.  
  167. /**
  168.  * Expunges a mailbox, ie. delete all contents.
  169.  */
  170. function sqimap_mailbox_expunge ($imap_stream$mailbox$handle_errors true$id=''{
  171.     global $uid_support;
  172.     if ($id{
  173.         if (is_array($id)) {
  174.             $id sqimap_message_list_squisher($id);
  175.         }
  176.         $id ' '.$id;
  177.         $uid $uid_support;
  178.     else {
  179.         $uid false;
  180.     }
  181.     $read sqimap_run_command($imap_stream'EXPUNGE'.$id$handle_errors,
  182.                                $response$message$uid);
  183.     $cnt 0;
  184.  
  185.     if (is_array($read)) {
  186.         foreach ($read as $r{
  187.             if (preg_match('/^\*\s[0-9]+\sEXPUNGE/AUi',$r,$regs)) {
  188.                 $cnt++;
  189.             }
  190.         }
  191.     }
  192.     return $cnt;
  193. }
  194.  
  195. /**
  196.  * Checks whether or not the specified mailbox exists
  197.  */
  198. function sqimap_mailbox_exists ($imap_stream$mailbox{
  199.     if (!isset($mailbox|| empty($mailbox)) {
  200.         return false;
  201.     }
  202.     $mbx sqimap_run_command($imap_stream"LIST \"\" \"$mailbox\"",
  203.                               true$response$message);
  204.     return isset($mbx[0]);
  205. }
  206.  
  207. /**
  208.  * Selects a mailbox
  209.  */
  210. function sqimap_mailbox_select ($imap_stream$mailbox{
  211.     global $auto_expunge;
  212.  
  213.     if ($mailbox == 'None'{
  214.         return;
  215.     }
  216.  
  217.     /**
  218.      * Default UW IMAP server configuration allows to access other files
  219.      * on server. $imap_server_type is not checked because interface can
  220.      * be used with 'other' or any other server type setting. $mailbox
  221.      * variable can be modified in any script that uses variable from GET 
  222.      * or POST. This code blocks all standard SquirrelMail IMAP API requests 
  223.      * that use mailbox with full path (/etc/passwd) or with ../ characters 
  224.      * in path (../../etc/passwd)
  225.      */
  226.     if (strstr($mailbox'../'|| substr($mailbox01== '/'{
  227.         global $color;
  228.         include_once(SM_PATH 'functions/display_messages.php');
  229.         error_box(sprintf(_("Invalid mailbox name: %s"),htmlspecialchars($mailbox)),$color);
  230.         sqimap_logout($imap_stream);
  231.         die('</body></html>');
  232.     }
  233.  
  234.     // cleanup $mailbox in order to prevent IMAP injection attacks
  235.     $mailbox str_replace(array("\r","\n")array("",""),$mailbox);
  236.  
  237.     $read sqimap_run_command($imap_stream"SELECT \"$mailbox\"",
  238.                                true$response$message);
  239.     $result array();
  240.     for ($i 0$cnt count($read)$i $cnt$i++{
  241.         if (preg_match('/^\*\s+OK\s\[(\w+)\s(\w+)\]/',$read[$i]$regs)) {
  242.             $result[strtoupper($regs[1])$regs[2];
  243.         else if (preg_match('/^\*\s([0-9]+)\s(\w+)/',$read[$i]$regs)) {
  244.             $result[strtoupper($regs[2])$regs[1];
  245.         else {
  246.             if (preg_match("/PERMANENTFLAGS(.*)/i",$read[$i]$regs)) {
  247.                 $regs[1]=trim(preg_replace (  array ("/\(/","/\)/","/\]/",''$regs[1])) ;
  248.                 $result['PERMANENTFLAGS'$regs[1];
  249.             else if (preg_match("/FLAGS(.*)/i",$read[$i]$regs)) {
  250.                 $regs[1]=trim(preg_replace (  array ("/\(/","/\)/",''$regs[1])) ;
  251.                 $result['FLAGS'$regs[1];
  252.             }
  253.         }
  254.     }
  255.     if (preg_match('/^\[(.+)\]/',$message$regs)) {
  256.         $result['RIGHTS']=$regs[1];
  257.     }
  258.  
  259.     if ($auto_expunge{
  260.         $tmp sqimap_run_command($imap_stream'EXPUNGE'false$a$b);
  261.     }
  262.     return $result;
  263. }
  264.  
  265. /**
  266.  * Creates a folder.
  267.  */
  268. function sqimap_mailbox_create ($imap_stream$mailbox$type{
  269.     global $delimiter;
  270.     if (strtolower($type== 'noselect'{
  271.         $create_mailbox $mailbox $delimiter;
  272.     else {
  273.         $create_mailbox $mailbox;
  274.     }
  275.  
  276.     $read_ary sqimap_run_command($imap_stream"CREATE \"$create_mailbox\"",
  277.                                    true$response$message);
  278.     sqimap_subscribe ($imap_stream$mailbox);
  279. }
  280.  
  281. /**
  282.  * Subscribes to an existing folder.
  283.  */
  284. function sqimap_subscribe ($imap_stream$mailbox{
  285.     $read_ary sqimap_run_command($imap_stream"SUBSCRIBE \"$mailbox\"",
  286.                                    true$response$message);
  287. }
  288.  
  289. /**
  290.  * Unsubscribes from an existing folder
  291.  */
  292. function sqimap_unsubscribe ($imap_stream$mailbox{
  293.     $read_ary sqimap_run_command($imap_stream"UNSUBSCRIBE \"$mailbox\"",
  294.                                    false$response$message);
  295. }
  296.  
  297. /**
  298.  * Deletes the given folder
  299.  */
  300. function sqimap_mailbox_delete ($imap_stream$mailbox{
  301.     global $data_dir$username;
  302.     sqimap_unsubscribe ($imap_stream$mailbox);
  303.     if (sqimap_mailbox_exists($imap_stream$mailbox)) {
  304.         $read_ary sqimap_run_command($imap_stream"DELETE \"$mailbox\"",
  305.                                        true$response$message);
  306.         if ($response !== 'OK'{
  307.             // subscribe again
  308.             sqimap_subscribe ($imap_stream$mailbox);
  309.         else {
  310.             do_hook_function('rename_or_delete_folder'$args array($mailbox'delete'''));
  311.             removePref($data_dir$username"thread_$mailbox");
  312.             removePref($data_dir$username"collapse_folder_$mailbox");
  313.         }
  314.     }
  315. }
  316.  
  317. /**
  318.  * Determines if the user is subscribed to the folder or not
  319.  */
  320. function sqimap_mailbox_is_subscribed($imap_stream$folder{
  321.     $boxesall sqimap_mailbox_list ($imap_stream);
  322.     foreach ($boxesall as $ref{
  323.         if ($ref['unformatted'== $folder{
  324.             return true;
  325.         }
  326.     }
  327.     return false;
  328. }
  329.  
  330. /**
  331.  * Renames a mailbox.
  332.  */
  333. function sqimap_mailbox_rename$imap_stream$old_name$new_name {
  334.     if $old_name != $new_name {
  335.         global $delimiter$imap_server_type$data_dir$username;
  336.         if substr$old_name-== $delimiter  {
  337.             $old_name substr$old_name0strlen$old_name );
  338.             $new_name substr$new_name0strlen$new_name );
  339.             $postfix $delimiter;
  340.         else {
  341.             $postfix '';
  342.         }
  343.  
  344.         $boxesall sqimap_mailbox_list_all($imap_stream);
  345.         $cmd 'RENAME "' $old_name '" "' $new_name '"';
  346.         $data sqimap_run_command($imap_stream$cmdtrue$response$message);
  347.         sqimap_unsubscribe($imap_stream$old_name.$postfix);
  348.         $oldpref_thread getPref($data_dir$username'thread_'.$old_name.$postfix);
  349.         $oldpref_collapse getPref($data_dir$username'collapse_folder_'.$old_name.$postfix);
  350.         removePref($data_dir$username'thread_'.$old_name.$postfix);
  351.         removePref($data_dir$username'collapse_folder_'.$old_name.$postfix);
  352.         sqimap_subscribe($imap_stream$new_name.$postfix);
  353.         setPref($data_dir$username'thread_'.$new_name.$postfix$oldpref_thread);
  354.         setPref($data_dir$username'collapse_folder_'.$new_name.$postfix$oldpref_collapse);
  355.         do_hook_function('rename_or_delete_folder',$args array($old_name'rename'$new_name));
  356.         $l strlen$old_name 1;
  357.         $p 'unformatted';
  358.  
  359.         foreach ($boxesall as $box{
  360.             if (substr($box[$p]0$l== $old_name $delimiter{
  361.                 $new_sub $new_name $delimiter substr($box[$p]$l);
  362.                 /* With Cyrus IMAPd >= 2.0 rename is recursive, so don't check for errors here */
  363.                 if ($imap_server_type == 'cyrus'{
  364.                     $cmd 'RENAME "' $box[$p'" "' $new_sub '"';
  365.                     $data sqimap_run_command($imap_stream$cmdfalse,
  366.                                                $response$message);
  367.                 }
  368.                 $was_subscribed sqimap_mailbox_is_subscribed($imap_stream$box[$p]);
  369.                 if $was_subscribed {
  370.                     sqimap_unsubscribe($imap_stream$box[$p]);
  371.                 }
  372.                 $oldpref_thread getPref($data_dir$username'thread_'.$box[$p]);
  373.                 $oldpref_collapse getPref($data_dir$username'collapse_folder_'.$box[$p]);
  374.                 removePref($data_dir$username'thread_'.$box[$p]);
  375.                 removePref($data_dir$username'collapse_folder_'.$box[$p]);
  376.                 if $was_subscribed {
  377.                     sqimap_subscribe($imap_stream$new_sub);
  378.                 }
  379.                 setPref($data_dir$username'thread_'.$new_sub$oldpref_thread);
  380.                 setPref($data_dir$username'collapse_folder_'.$new_sub$oldpref_collapse);
  381.                 do_hook_function('rename_or_delete_folder',
  382.                                  $args array($box[$p]'rename'$new_sub));
  383.             }
  384.         }
  385.     }
  386. }
  387.  
  388. /**
  389.  * Formats a mailbox into parts for the $boxesall array
  390.  *
  391.  * The parts are:
  392.  *
  393.  *     raw            - Raw LIST/LSUB response from the IMAP server
  394.  *     formatted      - nicely formatted folder name
  395.  *     unformatted    - unformatted, but with delimiter at end removed
  396.  *     unformatted-dm - folder name as it appears in raw response
  397.  *     unformatted-disp - unformatted without $folder_prefix
  398.  */
  399. function sqimap_mailbox_parse ($line$line_lsub{
  400.     global $folder_prefix$delimiter;
  401.  
  402.     /* Process each folder line */
  403.     for ($g 0$cnt count($line)$g $cnt++$g{
  404.         /* Store the raw IMAP reply */
  405.         if (isset($line[$g])) {
  406.             $boxesall[$g]['raw'$line[$g];
  407.         else {
  408.             $boxesall[$g]['raw''';
  409.         }
  410.  
  411.         /* Count number of delimiters ($delimiter) in folder name */
  412.         $mailbox  $line_lsub[$g];
  413.         $dm_count substr_count($mailbox$delimiter);
  414.         if (substr($mailbox-1== $delimiter{
  415.             /* If name ends in delimiter, decrement count by one */
  416.             $dm_count--;
  417.         }
  418.  
  419.         /* Format folder name, but only if it's a INBOX.* or has a parent. */
  420.         $boxesallbyname[$mailbox$g;
  421.         $parentfolder readMailboxParent($mailbox$delimiter);
  422.         if ( (strtolower(substr($mailbox05)) == "inbox"||
  423.              (substr($mailbox0strlen($folder_prefix)) == $folder_prefix||
  424.              (isset($boxesallbyname[$parentfolder]&&
  425.               (strlen($parentfolder0) ) ) {
  426.             $indent $dm_count (substr_count($folder_prefix$delimiter));
  427.             if ($indent 0{
  428.                 $boxesall[$g]['formatted'str_repeat('&nbsp;&nbsp;'$indent);
  429.             else {
  430.                 $boxesall[$g]['formatted''';
  431.             }
  432.             $boxesall[$g]['formatted'.= imap_utf7_decode_local(readShortMailboxName($mailbox$delimiter));
  433.         else {
  434.             $boxesall[$g]['formatted']  imap_utf7_decode_local($mailbox);
  435.         }
  436.  
  437.         $boxesall[$g]['unformatted-dm'$mailbox;
  438.         if (substr($mailbox-1== $delimiter{
  439.             $mailbox substr($mailbox0strlen($mailbox1);
  440.         }
  441.         $boxesall[$g]['unformatted'$mailbox;
  442.         if (substr($mailbox,0,strlen($folder_prefix))==$folder_prefix{
  443.             $mailbox substr($mailboxstrlen($folder_prefix));
  444.         }
  445.         $boxesall[$g]['unformatted-disp'$mailbox;
  446.         $boxesall[$g]['id'$g;
  447.  
  448.         $boxesall[$g]['flags'array();
  449.         if (isset($line[$g])) {
  450.             ereg("\(([^)]*)\)",$line[$g],$regs);
  451.             $flags trim(strtolower(str_replace('\\''',$regs[1])));
  452.             if ($flags{
  453.                 $boxesall[$g]['flags'explode(' '$flags);
  454.             }
  455.         }
  456.     }
  457.     return $boxesall;
  458. }
  459.  
  460. /**
  461.  * Sorting function used to sort mailbox names.
  462.  *     + Original patch from dave_michmerhuizen@yahoo.com
  463.  *     + Allows case insensitivity when sorting folders
  464.  *     + Takes care of the delimiter being sorted to the end, causing
  465.  *       subfolders to be listed in below folders that are prefixed
  466.  *       with their parent folders name.
  467.  *
  468.  *       For example: INBOX.foo, INBOX.foobar, and INBOX.foo.bar
  469.  *       Without special sort function: foobar between foo and foo.bar
  470.  *       With special sort function: foobar AFTER foo and foo.bar :)
  471.  */
  472. function user_strcasecmp($a$b{
  473.     return  strnatcasecmp($a$b);
  474. }
  475.  
  476. /**
  477.  * Returns list of options (to be echoed into select statement
  478.  * based on available mailboxes and separators
  479.  * Caller should surround options with <select ...> </select> and
  480.  * any formatting.
  481.  *   $imap_stream - $imapConnection to query for mailboxes
  482.  *   $show_selected - array containing list of mailboxes to pre-select (0 if none)
  483.  *   $folder_skip - array of folders to keep out of option list (compared in lower)
  484.  *   $boxes - list of already fetched boxes (for places like folder panel, where
  485.  *            you know these options will be shown 3 times in a row.. (most often unset).
  486.  *   $flag - flag to check for in mailbox flags, used to filter out mailboxes.
  487.  *           'noselect' by default to remove unselectable mailboxes.
  488.  *           'noinferiors' used to filter out folders that can not contain subfolders.
  489.  *           NULL to avoid flag check entirely.
  490.  *   $use_long_format - override folder display preference and always show full folder name.
  491.  */
  492. function sqimap_mailbox_option_list($imap_stream$show_selected 0$folder_skip 0$boxes 0,
  493.                                     $flag 'noselect'$use_long_format false {
  494.     global $username$data_dir;
  495.     $mbox_options '';
  496.     if $use_long_format {
  497.         $shorten_box_names 0;
  498.     else {
  499.         $shorten_box_names getPref($data_dir$username'mailbox_select_style'SMPREF_OFF);
  500.     }
  501.  
  502.     if ($boxes == 0{
  503.         $boxes sqimap_mailbox_list($imap_stream);
  504.     }
  505.  
  506.     foreach ($boxes as $boxes_part{
  507.         if ($flag == NULL || !in_array($flag$boxes_part['flags'])) {
  508.             $box $boxes_part['unformatted'];
  509.  
  510.             if ($folder_skip != && in_array($box$folder_skip) ) {
  511.                 continue;
  512.             }
  513.             $lowerbox strtolower($box);
  514.             // mailboxes are casesensitive => inbox.sent != inbox.Sent
  515.             // nevermind, to many dependencies this should be fixed!
  516.  
  517.             if (strtolower($box== 'inbox'// inbox is special and not casesensitive
  518.                 $box2 _("INBOX");
  519.             else {
  520.                 switch ($shorten_box_names)
  521.                 {
  522.                   case 2:   /* delimited, style = 2 */
  523.                     $box2 str_replace('&nbsp;&nbsp;''.&nbsp;'$boxes_part['formatted']);
  524.                     break;
  525.                   case 1:   /* indent, style = 1 */
  526.                     $box2 $boxes_part['formatted'];
  527.                     break;
  528.                   default:  /* default, long names, style = 0 */
  529.                     $box2 str_replace(' ''&nbsp;'htmlspecialchars(imap_utf7_decode_local($boxes_part['unformatted-disp'])));
  530.                     break;
  531.                 }
  532.             }
  533.             $box2 str_replace(array('<','>')array('&lt;','&gt;'$box2);
  534.  
  535.             if ($show_selected != && in_array($lowerbox$show_selected) ) {
  536.                 $mbox_options .= '<option value="' htmlspecialchars($box.'" selected="selected">'.$box2.'</option>' "\n";
  537.             else {
  538.                 $mbox_options .= '<option value="' htmlspecialchars($box.'">'.$box2.'</option>' "\n";
  539.             }
  540.         }
  541.     }
  542.     return $mbox_options;
  543. }
  544.  
  545. /**
  546.  * Mailboxes with some chars (like -) can mess up the order, this fixes it
  547.  */
  548. function mailtree_sort(&$lsub{
  549.     if(!is_array($lsub)) return;
  550.  
  551.     foreach($lsub as $index => $mailbox)
  552.         $lsub[$indexstr_replace('.',' -#- ',$lsub[$index]);
  553.  
  554.     usort($lsub'user_strcasecmp');
  555.  
  556.     foreach($lsub as $index => $mailbox)
  557.         $lsub[$indexstr_replace(' -#- ','.',$lsub[$index]);
  558. }
  559.  
  560. /**
  561.  * Returns sorted mailbox lists in several different ways.
  562.  * See comment on sqimap_mailbox_parse() for info about the returned array.
  563.  */
  564.  
  565.  
  566. function sqimap_mailbox_list($imap_stream$force=false{
  567.     global $default_folder_prefix;
  568.  
  569.     if (!sqgetGlobalVar('boxesnew',$boxesnew,SQ_SESSION|| $force{
  570.         global $data_dir$username$list_special_folders_first,
  571.                $folder_prefix$trash_folder$sent_folder$draft_folder,
  572.                $move_to_trash$move_to_sent$save_as_draft,
  573.                $delimiter$noselect_fix_enable;
  574.         $inbox_in_list false;
  575.         $inbox_subscribed false;
  576.  
  577.         require_once(SM_PATH 'include/load_prefs.php');
  578.  
  579.         if ($noselect_fix_enable{
  580.             $lsub_args "LSUB \"$folder_prefix\" \"*%\"";
  581.         else {
  582.             $lsub_args "LSUB \"$folder_prefix\" \"*\"";
  583.         }
  584.         /* LSUB array */
  585.         $lsub_ary sqimap_run_command ($imap_stream$lsub_args,
  586.                                         true$response$message);
  587.  
  588.         $sorted_lsub_ary array();
  589.         for ($i 0$cnt count($lsub_ary);$i $cnt$i++{
  590.             /*
  591.              * Workaround for mailboxes returned as literal
  592.              * Doesn't work if the mailbox name is multiple lines
  593.              * (larger then fgets buffer)
  594.              */
  595.             if (isset($lsub_ary[$i 1]&& substr($lsub_ary[$i],-3== "}\r\n"{
  596.                 if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$",
  597.                      $lsub_ary[$i]$regs)) {
  598.                         $i++;
  599.                         $lsub_ary[$i$regs[1'"' addslashes(trim($lsub_ary[$i])) '"' $regs[2];
  600.                 }
  601.             }
  602.             $temp_mailbox_name find_mailbox_name($lsub_ary[$i]);
  603.             $sorted_lsub_ary[$temp_mailbox_name;
  604.             if (!$inbox_subscribed && strtoupper($temp_mailbox_name== 'INBOX'{
  605.                 $inbox_subscribed true;
  606.             }
  607.         }
  608.         /* remove duplicates */
  609.         $sorted_lsub_ary array_unique($sorted_lsub_ary);
  610.  
  611.         /* natural sort mailboxes */
  612.         if (isset($sorted_lsub_ary)) {
  613.             mailtree_sort($sorted_lsub_ary);
  614.         }
  615.         /*
  616.          * The LSUB response doesn't provide us information about \Noselect
  617.          * mail boxes. The LIST response does, that's why we need to do a LIST
  618.          * call to retrieve the flags for the mailbox
  619.            * Note: according RFC2060 an imap server may provide \NoSelect flags in the LSUB response.
  620.            * in other words, we cannot rely on it.
  621.          */
  622.         $sorted_list_ary array();
  623.         for ($i=0$i count($sorted_lsub_ary)$i++{
  624.             if (substr($sorted_lsub_ary[$i]-1== $delimiter{
  625.                 $mbx substr($sorted_lsub_ary[$i]0strlen($sorted_lsub_ary[$i])-1);
  626.             }
  627.             else {
  628.                 $mbx $sorted_lsub_ary[$i];
  629.             }
  630.  
  631.             $read sqimap_run_command ($imap_stream"LIST \"\" \"$mbx\"",
  632.                                         true$response$message);
  633.  
  634.             /* Another workaround for literals */
  635.  
  636.             if (isset($read[1]&& substr($read[1],-3== "}\r\n"{
  637.                 if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$",
  638.                      $read[0]$regs)) {
  639.                     $read[0$regs[1'"' addslashes(trim($read[1])) '"' $regs[2];
  640.                 }
  641.             }
  642.  
  643.             if (isset($read[0])) {
  644.                 $sorted_list_ary[$i$read[0];
  645.             else {
  646.                 $sorted_list_ary[$i'';
  647.             }
  648.         }
  649.  
  650.         /*
  651.          * Just in case they're not subscribed to their inbox,
  652.          * we'll get it for them anyway
  653.          */
  654.         if (!$inbox_subscribed{
  655.             $inbox_ary sqimap_run_command ($imap_stream"LIST \"\" \"INBOX\"",
  656.                                              true$response$message);
  657.             /* Another workaround for literals */
  658.             if (isset($inbox_ary[1]&& substr($inbox_ary[0],-3== "}\r\n"{
  659.                 if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$",
  660.                      $inbox_ary[0]$regs)) {
  661.                     $inbox_ary[0$regs[1'"' addslashes(trim($inbox_ary[1])) .
  662.                                 '"' $regs[2];
  663.                 }
  664.             }
  665.             $sorted_list_ary[$inbox_ary[0];
  666.             $sorted_lsub_ary[find_mailbox_name($inbox_ary[0]);
  667.         }
  668.  
  669.         $boxesall sqimap_mailbox_parse ($sorted_list_ary$sorted_lsub_ary);
  670.  
  671.         /* Now, lets sort for special folders */
  672.         $boxesnew $used array();
  673.  
  674.         /* Find INBOX */
  675.         $cnt count($boxesall);
  676.         $used array_pad($used,$cnt,false);
  677.         for($k 0$k $cnt++$k{
  678.             if (strtolower($boxesall[$k]['unformatted']== 'inbox'{
  679.                 $boxesnew[$boxesall[$k];
  680.                 $used[$ktrue;
  681.                 break;
  682.             }
  683.         }
  684.  
  685.         /* List special folders and their subfolders, if requested. */
  686.         if ($list_special_folders_first{
  687.             for($k 0$k $cnt++$k{
  688.                 if (!$used[$k&& isSpecialMailbox($boxesall[$k]['unformatted'])) {
  689.                     $boxesnew[$boxesall[$k];
  690.                     $used[$k]   true;
  691.                 }
  692.             }
  693.         }
  694.  
  695.  
  696.         /* Find INBOX's children */
  697.         for($k 0$k $cnt++$k{
  698.             if (!$used[$k&& isBoxBelow(strtolower($boxesall[$k]['unformatted'])'inbox'&&
  699.                 strtolower($boxesall[$k]['unformatted']!= 'inbox'{
  700.                 $boxesnew[$boxesall[$k];
  701.                 $used[$ktrue;
  702.             }
  703.         }
  704.  
  705.  
  706.         /* Rest of the folders */
  707.         for($k 0$k $cnt$k++{
  708.             if (!$used[$k]{
  709.                 $boxesnew[$boxesall[$k];
  710.             }
  711.         }
  712.         sqsession_register($boxesnew,'boxesnew');
  713.     }
  714.     return $boxesnew;
  715. }
  716.  
  717. /**
  718.  *  Returns a list of all folders, subscribed or not
  719.  */
  720. function sqimap_mailbox_list_all($imap_stream{
  721.     global $list_special_folders_first$folder_prefix$delimiter;
  722.  
  723.     $ssid sqimap_session_id();
  724.     $lsid strlen$ssid );
  725.     fputs ($imap_stream$ssid " LIST \"$folder_prefix\" *\r\n");
  726.     $read_ary sqimap_read_data ($imap_stream$ssidtrue$response$message);
  727.     $g 0;
  728.     $phase 'inbox';
  729.     $fld_pre_length strlen($folder_prefix);
  730.  
  731.     for ($i 0$cnt count($read_ary)$i $cnt$i++{
  732.         /* Another workaround for EIMS */
  733.         if (isset($read_ary[$i 1]&&
  734.             ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$",
  735.                  $read_ary[$i]$regs)) {
  736.             $i ++;
  737.             $read_ary[$i$regs[1'"' addslashes(trim($read_ary[$i])) '"' $regs[2];
  738.         }
  739.         if (substr($read_ary[$i]0$lsid!= $ssid {
  740.             /* Store the raw IMAP reply */
  741.             $boxes[$g]['raw'$read_ary[$i];
  742.  
  743.             /* Count number of delimiters ($delimiter) in folder name */
  744.             $mailbox find_mailbox_name($read_ary[$i]);
  745.             $dm_count =  substr_count($mailbox$delimiter);
  746.             if (substr($mailbox-1== $delimiter{
  747.                 /* If name ends in delimiter - decrement count by one */
  748.                 $dm_count--;
  749.             }
  750.  
  751.             /* Format folder name, but only if it's a INBOX.* or has a parent. */
  752.             $boxesallbyname[$mailbox$g;
  753.             $parentfolder readMailboxParent($mailbox$delimiter);
  754.             if((eregi('^inbox'.quotemeta($delimiter)$mailbox)) ||
  755.                (ereg('^'.$folder_prefix$mailbox)) ||
  756.                isset($boxesallbyname[$parentfolder]&& (strlen($parentfolder0) ) ) {
  757.                 if ($dm_count{
  758.                     $boxes[$g]['formatted']  str_repeat('&nbsp;&nbsp;'$dm_count);
  759.                 else {
  760.                     $boxes[$g]['formatted''';
  761.                 }
  762.                 $boxes[$g]['formatted'.= imap_utf7_decode_local(readShortMailboxName($mailbox$delimiter));
  763.             else {
  764.                 $boxes[$g]['formatted']  imap_utf7_decode_local($mailbox);
  765.             }
  766.  
  767.             $boxes[$g]['unformatted-dm'$mailbox;
  768.             if (substr($mailbox-1== $delimiter{
  769.                 $mailbox substr($mailbox0strlen($mailbox1);
  770.             }
  771.             $boxes[$g]['unformatted'$mailbox;
  772.             $boxes[$g]['unformatted-disp'substr($mailbox,$fld_pre_length);
  773.  
  774.             $boxes[$g]['id'$g;
  775.  
  776.             /* Now lets get the flags for this mailbox */
  777.             $read_mlbx $read_ary[$i];
  778.  
  779. //            $read_mlbx = sqimap_run_command ($imap_stream, "LIST \"\" \"$mailbox\"",
  780. //                                             true, $response, $message);
  781.  
  782.             /* Another workaround for EIMS */
  783. //            if (isset($read_mlbx[1]) &&
  784. //                ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$", $read_mlbx[0], $regs)) {
  785. //                $read_mlbx[0] = $regs[1] . '"' . addslashes(trim($read_mlbx[1])) . '"' . $regs[2];
  786. //            }
  787. //            echo  $read_mlbx[0] .' raw 2 <br>';
  788.  
  789.             $flags substr($read_mlbxstrpos($read_mlbx'(')+1);
  790.             $flags substr($flags0strpos($flags')'));
  791.             $flags str_replace('\\'''$flags);
  792.             $flags trim(strtolower($flags));
  793.             if ($flags{
  794.                 $boxes[$g]['flags'explode(' '$flags);
  795.             else {
  796.                 $boxes[$g]['flags'array();
  797.             }
  798.         }
  799.         $g++;
  800.     }
  801.     if(is_array($boxes)) {
  802.         sort ($boxes);
  803.     }
  804.  
  805.     return $boxes;
  806. }
  807.  
  808. ?>

Documentation generated on Sat, 07 Oct 2006 16:31:43 +0300 by phpDocumentor 1.3.0RC6