Logo Search packages:      
Sourcecode: egroupware version File versions  Download package

class.boaction.inc.php

<?php
      /**************************************************************************\
      * AngleMail - email BO Class for Message Actions                              *
      * http://www.anglemail.org                                                    *
      * Written by Angelo (Angles) Puglisi <angles@aminvestments.com>         *
      * Copyright (C) 2001, 2002 Angelo Tony Puglisi (Angles)                       *
      * --------------------------------------------                                      *
      *  This program is free software; you can redistribute it and/or modify it          *
      *  under the terms of the GNU General Public License as published by the      *
      *  Free Software Foundation; either version 2 of the License, or (at your           *
      *  option) any later version.                                           *
      \**************************************************************************/

      /* $Id: class.boaction.inc.php,v 1.25 2004/04/18 11:43:08 angles Exp $ */
      
      /*!
      @class boaction
      @abstract Processes client side requests for actions like deleting or moving mail, getting attachments and 
      for viewing html mail. Also contains code for an alternative to the redirect as a way to go to the next page view. 
      */    
00021       class boaction
      {
            var $public_functions = array(
                  'delmov' => True,
                  'get_attach' => True,
                  'view_html' => True,
                  'clearcache' => True
            );
            // class var to hold content to be downloaded
            var $output_data='';
            // if bomessage wants this preserves, we detect that and store it here
            var $no_fmt='';
            // debug level 0 is none, levels  1, 2, 3 is typical
            // debug level 4 has special side effects
            var $debug = 0;
            
            var $debug_new_env = 0;
            //var $debug_new_env = 3;
            //var $debug_new_env = 4;
            
            var $msg_bootstrap;
            // if moving or deleting more than "big_move_threshold", smart caching temporarily is disabled
            // that much activity is going to be slower no matter what, might as well get fresh data on next page view
            //var $big_move_threshold = 95;
            // reduce this until is is proven that a larger number actually makes something faster
            // MOVED TO MSG CLASS
            //var $big_move_threshold = 10;
            var $browser;
            var $redirect_to = '';
            var $redirect_if_error = '';
            var $error_str = '';
            
            var $expected_args=array();
            var $new_args_uri='';
            var $new_args_env=array();
            
            // if getting the next page is a problem, set this to true
            var $use_old_redirect_method=False;
            //var $use_old_redirect_method=True;
            
            var $next_obj;
            
            function boaction()
            {
                  //return;
            }
            
            /*!
            @function delmov
            @abstract used to delete or move messages, single message or groups of messages
            @author Angles and previous authors
            @discussion after a message delete or move is handled, this function redirect the browser back to 
            the appropiate page, and puts some data in the URI which the mail_msg class translates into a 
            report to the user recapping what actions just took place. ALSO, note with multiple accounts or with 
            filtering, it may be possible this function is processing a batch of messages that may be from or going to 
            different folders, accounts, and servers. Both here and at the mail_msg move and delete functions, some 
            grouping of message numbers is attempted, but this could be improved upon. 
            @access private
            */
00080             function delmov()
            {
                  //if ($this->debug > 0) { echo 'ENTERING email.boaction.delmov'.'<br>'; }
                  
                  // make sure we have msg object and a server stream
                  $this->msg_bootstrap = CreateObject("email.msg_bootstrap");
                  $this->msg_bootstrap->ensure_mail_msg_exists('email.boaction.delmov', $this->debug);
                  if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('ENTERING email.boaction.delmov'.'<br>'); }
                  
                  // initialize this to an "ignore me" value, we change it later only if it should have a meaning
                  // MOVED TO MSG CLASS
                  //$initial_session_cache_extreme = '-1';
                  
                  // get the not set value, usually '-1', 
                  // because php False, empty and 0 are too similar we use this instead, where a value of -1 is unlikely
                  if (isset($GLOBALS['phpgw']->msg->not_set))
                  {
                        $not_set = $GLOBALS['phpgw']->msg->not_set;
                  }
                  else
                  {
                        $not_set = '-1';
                  }
                  
                  // make an error report URL
                  $this->redirect_if_error = $GLOBALS['phpgw']->link('/index.php',$GLOBALS['phpgw']->msg->get_arg_value('index_menuaction'));
                  
                  $folder_info = array();
                  $folder_info = $GLOBALS['phpgw']->msg->get_folder_status_info();
                  $totalmessages = $folder_info['number_all'];
                  
                  // ---- MOVE (Multiple) Messages from folder to folder   -----
                  if ($GLOBALS['phpgw']->msg->get_arg_value('what') == "move")
                  {
                        /*!
                        @capability boaction.delmov code for moving messages 
                        @abstract Inside function "delmov", when GPC var "what" has value "move" 
                        @param get_arg_value("delmov_list") (structured array) list of msgball items that will be moved. 
                        @param get_arg_value("to_fldball") (array of type fldball) the destination folder for (all) the move(s). 
                        @param get_arg_value("move_postmove_goto") complete URI that we should redirect 
                        the browser to after the move is done. Provided by uimessage page, it is a "smart" value, 
                        the result of some logic in bomessage to determine what message the user should read 
                        after the current message is moved, based on data from the user prefs and the msgball list 
                        and the nav data used to make the prev next arrows on that uimessage page. NOTE: if 
                        this function is NOT called by the uimessage page, this param "move_postmove_goto" 
                        will NOT exist, see discussion for that case.
                        @discussion This function "delmov" has one code block to handle moving messages, 
                        either one or more messages, the same code block is used. Note that the code that 
                        handles deletes has different blocks for single message delete vs. multiple message 
                        deletes, not the case with moves. The params are gathered from GPC values (typically) 
                        and put into OOP accessable "arg" values, use "get_arg_value" to get the params. 
                        The inline docparser may number the params in some order, but in reality the 
                        params used in this code block are not expected to be in any particular order. 
                        WHEN CALLED: 
                        (1) generally called by the uiindex "move selected messages to" listbox onChange action. 
                        (2) also can be called by uimessage "move this message into" listbox onChange action. 
                        If NOT called by uimessage, then param "move_postmove_goto" does not exist, 
                        since we were called probably by a folder index page we should return so _some_ related 
                        folder index page after the move is done, i.e. redirect the browser to a folder index page instead 
                        of a uimessage page. That folder name  is hackishly obtained by getting the "folder" value from the first 
                        msgball in the "delmov_list", on the assumption that this is the folder the user was looking at 
                        before the move was issued. This works as long as the message list is all from the same folder, 
                        which is most likely at this point. HOWEVER, future search results with messages from different 
                        folders and or accounts will require a little better handling of this. NOTE that if an folder index 
                        page had all its messages moved, and there are no other messages to show for that particular 
                        "nextmatches" view, then the code _SHOULD_ page back to where there are messages to show, 
                        BUT this is not done yet. 
                        */
                        if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: get_arg_value(what) == "move") <br>'); }
                        
                        /*
                        $fromacctnum = (int)$GLOBALS['phpgw']->msg->get_arg_value('acctnum');
                        $tofolder = $GLOBALS['phpgw']->msg->prep_folder_in($GLOBALS['phpgw']->msg->get_arg_value('tofolder'));
                        $toacctnum = (int)$GLOBALS['phpgw']->msg->get_arg_value('toacctnum');
                        // report number messages moved (will be made = 0 if error below)
                        //$tm = count($GLOBALS['phpgw']->msg->get_arg_value('msglist'));
                        // mail_move accepts a single number (5); a comma seperated list of numbers (5,6,7,8); or a range with a colon (5:8)
                        //$msgs = $GLOBALS['phpgw']->msg->get_arg_value('msglist') ? implode($GLOBALS['phpgw']->msg->get_arg_value('msglist'), ",") : $GLOBALS['phpgw']->msg->get_arg_value('msglist');
                        $delmov_list = $GLOBALS['phpgw']->msg->get_arg_value('delmov_list');
                        // tm = "Total Moved" indicator
                        $tm = count($delmov_list);
                        $msgs = '';
                        for($i=0;$i<count($delmov_list);$i++)
                        {
                              if ($msgs != '')
                              {
                                    $prefix = ',';
                              }
                              $msgs .= $prefix . $delmov_list[$i]['msgball']['msgnum'];
                        }
                        $did_move = $GLOBALS['phpgw']->msg->phpgw_mail_move($msgs, $tofolder);
                        */
                        
                        $delmov_list = $GLOBALS['phpgw']->msg->get_arg_value('delmov_list');
                        $to_fldball = $GLOBALS['phpgw']->msg->get_arg_value('to_fldball');
                        // WHY URLDECODE SO SOON?
                        //$to_fldball['folder'] = $GLOBALS['phpgw']->msg->prep_folder_in($to_fldball['folder']);
                        $to_fldball['acctnum'] = (int)$to_fldball['acctnum'];
                        
                        // tm = "Total Moved" indicator
                        $tm = count($delmov_list);
                        // is this a "big move" as far as the "smart caching" is concerned?
                        // MOVED TO MSG CLASS
                        //if (count($delmov_list) > $this->big_move_threshold)
                        //{
                        //    if ($this->debug > 0) { echo 'email.boaction.delmov: LINE '.__LINE__.' $this->big_move_threshold ['.$this->big_move_threshold.'] exceeded, call "->msg->event_begin_big_move" to notice event of impending big batch moves or deletes<br>'; }
                        //    $initial_session_cache_extreme = $GLOBALS['phpgw']->msg->event_begin_big_move(array(), 'email.boaction.delmov: LINE '.__LINE__);
                        //}
                        //else
                        //{
                        //    // this "-1" tells us no big move was done
                        //    $initial_session_cache_extreme = '-1';
                        //}
                        
                        for ($i = 0; $i < count($delmov_list); $i++)
                        {
                              if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: in mail move loop ['.(string)($i+1).'] of ['.$tm.']<br>'); }
                              $mov_msgball = $delmov_list[$i];
                              // WHY URLDECODE SO SOON?
                              //$mov_msgball['folder'] = $GLOBALS['phpgw']->msg->prep_folder_in($mov_msgball['folder']);
                              $mov_msgball['acctnum'] = (int)$mov_msgball['acctnum'];
                              $did_move = False;
                              //if ($this->debug > 2) { echo 'email.boaction.delmov: calling  $GLOBALS[phpgw]->msg->interacct_mail_move('.serialize($mov_msgball).', '.serialize($to_fldball).'<br>'; }
                              //$did_move = $GLOBALS['phpgw']->msg->interacct_mail_move($mov_msgball, $to_fldball);
                              if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: calling  $GLOBALS[phpgw]->msg->industrial_interacct_mail_move('.serialize($mov_msgball).', '.serialize($to_fldball).'<br>'); }
                              // single move, NO NEED to use the move grouping stuff, NOTE $tm was filled above as count($delmov_list)
                              // MOVED TO FLUSH MOVES LOGIG
                              //if ($tm == 1)
                              //{
                              //    if ($this->debug > 1) { echo 'email.boaction.delmov: (single move $tm: ['.$tm.']) calling  $GLOBALS[phpgw]->msg->single_interacct_mail_move('.serialize($mov_msgball).', '.serialize($to_fldball).'<br>'; }
                              //    $did_move = $GLOBALS['phpgw']->msg->single_interacct_mail_move($mov_msgball, $to_fldball);
                              //}
                              //else
                              //{
                                    if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: calling  $GLOBALS[phpgw]->msg->industrial_interacct_mail_move('.serialize($mov_msgball).', '.serialize($to_fldball).'<br>'); }
                                    $did_move = $GLOBALS['phpgw']->msg->industrial_interacct_mail_move($mov_msgball, $to_fldball);
                              //}
                              if ($did_move == False)
                              {
                                    // error
                                    if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): ***ERROR**** $GLOBALS[phpgw]->msg->industrial_interacct_mail_move() returns FALSE, ERROR, break out of loop<br>'
                                                .' * * Server reports error: '.$GLOBALS['phpgw']->msg->phpgw_server_last_error().'<br>'); }
                                    break;
                              }
                              else
                              {
                                    if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): $GLOBALS[phpgw]->msg->industrial_interacct_mail_move() returns True<br>'); }
                                    //$did_expunge = False;
                                    //$did_expunge = $GLOBALS['phpgw']->msg->phpgw_expunge($mov_msgball['acctnum'], $mov_msgball);
                                    //if ($this->debug > 2) { echo 'email.boaction.delmov: $GLOBALS[phpgw]->msg->phpgw_expunge() returns '.serialize($did_expunge).'<br>'; }
                              }
                        }
                        
                        // ok, done moving, now expunge, "industrial_interacct_mail_move" uses ""
                        if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): done moving, now call $GLOBALS[phpgw]->msg->expunge_expungable_folders<br>'); }
                        $did_expunge = False;
                        $did_expunge = $GLOBALS['phpgw']->msg->expunge_expungable_folders('email.boaction.delmov LINE '.__LINE__);
                        if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): $GLOBALS[phpgw]->msg->expunge_expungable_folders() returns ['.serialize($did_expunge).']<br>'); }
                        
                        if (! $did_move)
                        {
                              // ERROR: report ZERO messages moved
                              $tm = 0;
                              //echo 'Server reports error: '.$GLOBALS['phpgw']->msg->dcom->server_last_error();
                        }
                        // report folder messages were moved to
                        //$tf = $GLOBALS['phpgw']->msg->prep_folder_out($to_fldball['folder']);
                        // folder in this array was never changed from its "prepped out" state, it is still urlencoded from when we first picked it up
                        $tf = $to_fldball['folder'];
                        //echo 'boaction: $tf ['.$tf.'] <br>';
                        
                        // folder or message we should go back to
                        if (($GLOBALS['phpgw']->msg->get_isset_arg('move_postmove_goto'))
                        && ($GLOBALS['phpgw']->msg->get_arg_value('move_postmove_goto') != ''))
                        {
                              // THIS MEANS WE WERE CALLED BY UIMESSAGE
                              // treat the post-move navigation like a "delete_single_msg", as per data passed to us from that page
                              $move_postmove_goto = $GLOBALS['phpgw']->msg->get_arg_value('move_postmove_goto');
                              if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): move single *called by uimessage*: $move_postmove_goto: : '.$move_postmove_goto.'<br>'); }
                              // ----  "Go To Previous Message" Handling  -----
                              // these insrustions passed from uimessage when prev_next_navigation is obtained anyway
                              $this->redirect_to = $move_postmove_goto;
                              if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: ('.__LINE__.') move single *called by uimessage*: determination of $this->redirect_to : ['.$this->redirect_to.']<br>'); }
                        }
                        else
                        {
                              //$return_to_fldball['folder'] = $GLOBALS['phpgw']->msg->prep_folder_out($delmov_list[0]['folder']);
                              // folder in this array was never changed from its "prepped out" state, it is still urlencoded from when we first picked it up
                              $return_to_fldball['folder'] = $delmov_list[0]['folder'];
                              //echo 'boaction: $return_to_fldball[folder] ['.$return_to_fldball['folder'].'] <br>';
                              $return_to_fldball['acctnum'] = $delmov_list[0]['acctnum'];
                              
                              $this->redirect_to = $GLOBALS['phpgw']->link(
                                                      '/index.php',
                                                       'menuaction=email.uiindex.index'
                                                      .'&fldball[folder]='.$return_to_fldball['folder']
                                                      .'&fldball[acctnum]='.$return_to_fldball['acctnum']
                                                      .'&tm='.$tm
                                                      .'&tf='.$tf
                                                      .'&sort='.$GLOBALS['phpgw']->msg->get_arg_value('sort')
                                                      .'&order='.$GLOBALS['phpgw']->msg->get_arg_value('order')
                                                      .'&start='.$GLOBALS['phpgw']->msg->get_arg_value('start'));
                              
                              if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): NOT called by uimessage, determination of $this->redirect_to : ['.$this->redirect_to.']<br>'); }
                        }
                  }
                  // ---- DELETE (MULTIPLE) MESSAGES ----
                  elseif ($GLOBALS['phpgw']->msg->get_arg_value('what') == 'delall')
                  {
                        /*!
                        @capability boaction.delmov code for deleting multiple messages 
                        @abstract Inside function "delmov", when GPC var "what" has value "delall" 
                        @param get_arg_value("delmov_list") (structured array) list of msgball items that will be deleted. 
                        @discussion WHEN CALLED: this is called from the index page after you check some boxes and click "delete" button. 
                        Folder index page to resirect to after the deletes are done is obtained using the LAST msgball in the "delmov_list", 
                        using its "folder" and "acctnum" values. 
                        */
                        
                        if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: get_arg_value(what) == "delall") <br>'); }
                        // this is called from the index pge after you check some boxes and click "delete" button
                        
                        $delmov_list = $GLOBALS['phpgw']->msg->get_arg_value('delmov_list');
                        // is this a "big move" as far as the "smart caching" is concerned?
                        // MOVED TOP MSG CLASS
                        //if (count($delmov_list) > $this->big_move_threshold)
                        //{
                        //    if ($this->debug > 0) { echo 'email.boaction.delmov: LINE '.__LINE__.' $this->big_move_threshold ['.$this->big_move_threshold.'] exceeded, call "->msg->event_begin_big_move" to notice event of impending big batch moves or deletes<br>'; }
                        //    $initial_session_cache_extreme = $GLOBALS['phpgw']->msg->event_begin_big_move(array(), 'email.boaction.delmov: LINE '.__LINE__);
                        //}
                        //else
                        //{
                        //    // this "-1" tells us no big move was done
                        //    $initial_session_cache_extreme = '-1';
                        //}
                        
                        $loops = count($delmov_list);
                        for ($i = 0; $i < $loops; $i++)
                        {
                              if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: (delete) in mail delete loop ['.(string)($i+1).'] of ['.$loops.']<br>'); }
                              $this_msgnum = $delmov_list[$i]['msgnum'];
                              // was_in_folder is used in Trash handling in the ->phpgw_delete function
                              // if a message "was_in_folder" Trash, it gets deleted for real, no option to move to Trash in that case
                              $was_in_folder = $delmov_list[$i]['folder'];
                              $was_in_folder_acctnum = (int)$delmov_list[$i]['acctnum'];
                              $did_delete = $GLOBALS['phpgw']->msg->phpgw_delete($this_msgnum,'',$was_in_folder);
                              if ($did_delete == False)
                              {
                                    // error
                                    if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: (delete) ***ERROR**** $GLOBALS[phpgw]->msg->phpgw_delete() returns FALSE, ERROR, break out of loop<br>'
                                                .' * * Server reports error: '.$GLOBALS['phpgw']->msg->phpgw_server_last_error().'<br>'); }
                                    break;
                              }
                              else
                              {
                                    if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: (delete) $GLOBALS[phpgw]->msg->phpgw_delete() returns True (so it buffered the command, really does not mean anything not that we buffer commands)<br>'); }
                                    
                                    //if ($this->debug > 0) { echo 'email.boaction.delmov: (delete) calling $GLOBALS[phpgw]->msg->phpgw_expunge('.$delmov_list[$i]['acctnum'].', $delmov_list[$i])<br>'; }
                                    //$did_expunge = False;
                                    //$did_expunge = $GLOBALS['phpgw']->msg->phpgw_expunge((int)$delmov_list[$i]['acctnum'], $delmov_list[$i]);
                                    //if ($this->debug > 2) { echo 'email.boaction.delmov: (delete) $GLOBALS[phpgw]->msg->phpgw_expunge('.$delmov_list[$i]['acctnum'].') returns '.serialize($did_expunge).'<br>'; }
                              }
                        }
                        
                        // ok, done deleting, now expunge
                        if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): done deleting, now call $GLOBALS[phpgw]->msg->expunge_expungable_folders<br>'); }
                        $did_expunge = False;
                        $did_expunge = $GLOBALS['phpgw']->msg->expunge_expungable_folders('email.boaction.delmov LINE '.__LINE__);
                        if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): $GLOBALS[phpgw]->msg->expunge_expungable_folders() returns ['.serialize($did_expunge).']<br>'); }

                        $totaldeleted = $i;
                        //$GLOBALS['phpgw']->msg->phpgw_expunge();
                        $this->redirect_to = $GLOBALS['phpgw']->link(
                                                '/index.php',
                                                 'menuaction=email.uiindex.index'
                                                .'&fldball[folder]='.$GLOBALS['phpgw']->msg->prep_folder_out($was_in_folder)
                                                .'&fldball[acctnum]='.$was_in_folder_acctnum
                                                .'&td='.$totaldeleted
                                                .'&sort='.$GLOBALS['phpgw']->msg->get_arg_value('sort')
                                                .'&order='.$GLOBALS['phpgw']->msg->get_arg_value('order')
                                                .'&start='.$GLOBALS['phpgw']->msg->get_arg_value('start'));
                        /*
                        // Experimental:
                        // NO REDIRECT - DIRECTLY MANUFACTURE THE NEXT PAGE VIEW RIGHT NOW
                        // NAME  THE DESIRED FLDBALL
                        $new_fldball = array();
                        $new_fldball['folder'] = $GLOBALS['phpgw']->msg->prep_folder_out($was_in_folder);
                        $new_fldball['acctnum'] = $was_in_folder_acctnum;
                        // GATHER THE OTHER ARGS WE WANT IN THE NEW PAGEVIEW
                        $new_args_env = array(
                              'td'  => $totaldeleted,
                              'sort'  => $GLOBALS['phpgw']->msg->get_arg_value('sort'),
                              'order'  => $GLOBALS['phpgw']->msg->get_arg_value('order'),
                              'start'  => $GLOBALS['phpgw']->msg->get_arg_value('start')
                        );
                        // UNSET ARGS WE USED IN THIS PAGE BUT ARE NO LONGER NEEDED
                        $GLOBALS['phpgw']->msg->unset_arg('delmov_list', $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->unset_arg('to_fldball_fake_uri', $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->unset_arg('to_fldball', $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->unset_arg('sort', $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->unset_arg('order', $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->unset_arg('start', $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->unset_arg('what', $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->unset_arg('folder', $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->unset_arg('acctnum', $new_fldball['acctnum']);
                        // REFILL ARGS WITH NEW PAGE VIEW VALUES
                        $GLOBALS['phpgw']->msg->set_acctnum($new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->set_arg_value('fldball', $new_fldball, $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->set_arg_value('folder', $new_fldball['folder'], $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->set_arg_value('td', $new_args_env['td'], $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->set_arg_value('sort', $new_args_env['sort'], $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->set_arg_value('order', $new_args_env['order'], $new_fldball['acctnum']);
                        $GLOBALS['phpgw']->msg->set_arg_value('start', $new_args_env['start'], $new_fldball['acctnum']);
                        // IF A "BIG MOVE", THEN TURN BACK ON THE SMART CACHE
                        if ((isset($initial_session_cache_extreme))
                        && ($initial_session_cache_extreme != '-1'))
                        {
                              $GLOBALS['phpgw']->msg->session_cache_extreme = $initial_session_cache_extreme;
                        }
                        // MAKE THE INDEX PAGE OBJECT
                        $this->next_obj = CreateObject('email.uiindex');
                        // CALL THE FUNCTION THAT DISPLAYS THE PAGE VIEW
                        $this->next_obj->index();
                        // close down ALL mailserver streams
                        if (is_object($GLOBALS['phpgw']->msg))
                        {
                              $GLOBALS['phpgw']->msg->end_request();
                        }
                        // shut down this transaction
                        $GLOBALS['phpgw']->common->phpgw_exit(False);
                        */
                        
                  }
                  // ---- DELETE A SINGLE MESSAGE  ----
                  elseif ($GLOBALS['phpgw']->msg->get_arg_value('what') == "delete_single_msg")
                  {
                        /*!
                        @capability boaction.delmov code for deleting a single messages 
                        @abstract Inside function "delmov", when GPC var "what" has value "delete_single_msg" 
                        @param get_arg_value("msgball") (array of type msgball) the msgball item to delete. 
                        @discussion WHEN CALLED: this is called from the uimessage page when you click "delete" image, 
                        (the image grouped with the repy, replyall, and forward actions) 
                        Redirects to a uimessage page (if possible) afrer the delete, which is determined by using 
                        the "msg->prev_next_navigation" return data. Will redirect to the folder index page if 
                        that was the last message to view (with respect to user prefs on sort and order). 
                        */
                        
                        // if preserving no_fmt then add it to every navigation (prev, next) links
                        // if no_fmt=1 is in the args it is because bomesage wants us to preserve it
                        if (($GLOBALS['phpgw']->msg->get_isset_arg('no_fmt'))
                        && ($GLOBALS['phpgw']->msg->get_arg_value('no_fmt') != ''))
                        {
                              $this->no_fmt = '&no_fmt=1';
                        }
                        if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): get_arg_value(what) == "delete_single_msg") <br>'); }
                        // called by clicking the "X" dutton while reading an individual message
                        $msgball = $GLOBALS['phpgw']->msg->get_arg_value('msgball');
                        if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): delete_single_msg: pre-delete $msgball[] DUMP:', $msgball); }
                        
                        // BEFORE we delete, if there is no mext message, then we will go back to index page
                        $nav_data = $GLOBALS['phpgw']->msg->prev_next_navigation($folder_info['number_all']);
                        if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): delete_single_msg: pre-delete $nav_data[] DUMP:', $nav_data); }
                        // ----  "Go To Previous Message" Handling  -----
                        if ($nav_data['prev_msg'] != $not_set)
                        {

                              $this->redirect_to = $GLOBALS['phpgw']->link(
                                    '/index.php',
                                     'menuaction=email.uimessage.message'
                                    .'&'.$nav_data['prev_msg']['msgball']['uri']
                                    .'&sort='.$GLOBALS['phpgw']->msg->get_arg_value('sort')
                                    .'&order='.$GLOBALS['phpgw']->msg->get_arg_value('order')
                                    .'&start='.$GLOBALS['phpgw']->msg->get_arg_value('start')
                                    .$this->no_fmt);
                        }
                        else
                        {
                              // post-delete back to index page - 
                              // LEX: I changed this cause i think its nicer behaviour
                              // to move to the nex message instead of going to index....this way we save clicks
                              // if anyone has an issue with this, ill make a preference for it
                              $this->redirect_to = $GLOBALS['phpgw']->link(
                                          '/index.php',
                                          'menuaction=email.uiindex.index'
                                          .'&fldball[folder]='.$GLOBALS['phpgw']->msg->prep_folder_out()
                                          .'&fldball[acctnum]='.$GLOBALS['phpgw']->msg->get_acctnum()
                                          .'&sort='.$GLOBALS['phpgw']->msg->get_arg_value('sort')
                                          .'&order='.$GLOBALS['phpgw']->msg->get_arg_value('order')
                                          .'&start='.$GLOBALS['phpgw']->msg->get_arg_value('start'));
                        }
                        if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): delete_single_msg: pre-delete determination of $this->redirect_to : ['.$this->redirect_to.']<br>'); }
                        
                        
                        if ($this->debug > 3)
                        {
                              $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: delete_single_msg ('.__LINE__.'): debug flag = 4 or higher, _SKIP_ the delete and expunge action<br>');
                        }
                        else
                        {
                              // ok, now do the delete
                              if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: delete_single_msg: ('.__LINE__.') : (single delete) calling $GLOBALS[phpgw]->msg->phpgw_delete('.$msgball['msgnum'].', " ",'.$msgball['folder'].', '.$msgball['acctnum'].', True) '); } 
                              // True = just a single delete call, don't use the buffer commands
                              // " just a single delete call" logic MOVED TO BUFFERED COMMANDS function
                              //$GLOBALS['phpgw']->msg->phpgw_delete($msgball['msgnum'],'',$msgball['folder'], (int)$msgball['acctnum'], True);
                              $GLOBALS['phpgw']->msg->phpgw_delete($msgball['msgnum'],'',$msgball['folder'], (int)$msgball['acctnum']);
                              // now do the expunge, both IMAP and POP3 require this, or the message is not really deleted
                              //if ($this->debug > 1) { echo 'email.boaction.delmov: delete_single_msg: ('.__LINE__.') : calling $GLOBALS[phpgw]->msg->phpgw_expunge('.$msgball['acctnum'].', $msgball) '; } 
                              // MOVED to "expunge_expungable_folders"
                              //$GLOBALS['phpgw']->msg->phpgw_expunge((int)$msgball['acctnum'], $msgball);
                              
                              // ok, done deleting, now expunge
                              if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: delete_single_msg: ('.__LINE__.'): done deleting, now call $GLOBALS[phpgw]->msg->expunge_expungable_folders<br>'); }
                              $did_expunge = False;
                              $did_expunge = $GLOBALS['phpgw']->msg->expunge_expungable_folders('email.boaction.delmov (delete_single_msg) LINE '.__LINE__);
                              if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: delete_single_msg: ('.__LINE__.'): $GLOBALS[phpgw]->msg->expunge_expungable_folders() returns ['.serialize($did_expunge).']<br>'); }
                        }
                  }
                  // ---- EMPTY FOLDER ex. EMPTY TRASH ----
                  elseif ($GLOBALS['phpgw']->msg->get_arg_value('what') == 'empty_folder')
                  {
                        /*!
                        @capability boaction.empty_folder  code for emptying trash folder for example
                        @abstract Inside function "delmov", when GPC var "what" has value "empty_folder" 
                        @param get_arg_value("fldball") (array of type fldball) the folder to delete all messages in.
                        @discussion WHEN CALLED: call from trash folder, and provide these 2 params.
                        */
                        
                        if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): get_arg_value(what) == "empty_folder") <br>'); }
                        // this is called from the index pge after you check some boxes and click "delete" button
                        $fldball = array();
                        $fldball = $GLOBALS['phpgw']->msg->get_arg_value('fldball');
                        if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): empty_folder: pre-delete $fldball[] DUMP:', $fldball); }
                        
                        // get general stats on the folder
                        $folder_info = $GLOBALS['phpgw']->msg->get_folder_status_info($fldball);
                        if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): empty_folder: pre-delete $folder_info DUMP:', $folder_info); }
                        
                        if ($folder_info['number_all'] == 0)
                        {
                              // nothing to delete, folder already empty
                              if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): empty_folder: nothing to delete, folder already empty <br>'); }
                              // used for number deleted message
                              $i = 0;
                              // used for the redirection back to the page
                              $this_acctnum = (int)$fldball['acctnum'];
                              // do we need to prep folder out on a fldball we just got?
                              $this_folder = $GLOBALS['phpgw']->msg->prep_folder_out($fldball['folder']);
                        }
                        else
                        {
                              // get msgball list of the folder we are to clean
                              // although we MUST be in the folder in question,  we still supply folder and acctnum specifically
                              $del_msgball_list = array();
                              $del_msgball_list = $GLOBALS['phpgw']->msg->get_msgball_list($fldball['acctnum'], $fldball['folder']);
                              if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): empty_folder: pre-delete $del_msgball_list DUMP:', $del_msgball_list); }
                              
                              $loops = count($del_msgball_list);
                              for ($i = 0; $i < $loops; $i++)
                              {
                                    if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: (empty_folder) in mail delete loop ['.(string)($i+1).'] of ['.$loops.']<br>'); }
                                    // turn the string URI type data into a single msgball item in its full  array form.
                                    $uri_msgball = $del_msgball_list[$i];
                                    if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): empty_folder: $uri_msgball ['.htmlspecialchars($uri_msgball).']: <br>'); }
                                    $full_msgball = $GLOBALS['phpgw']->msg->ball_data_parse_str($uri_msgball);
                                    if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: (empty_folder) in mail delete loop ['.(string)($i+1).'] of ['.$loops.'], $full_msgball DUMP:', $full_msgball); }
                                    $this_msgnum = $full_msgball['msgnum'];
                                    $this_folder = $full_msgball['folder'];
                                    $this_acctnum = (int)$full_msgball['acctnum'];
                                    $did_delete = $GLOBALS['phpgw']->msg->phpgw_delete($this_msgnum, '', $this_folder,$this_acctnum);
                                    if ($did_delete == False)
                                    {
                                          // error
                                          if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: (empty_folder) ***ERROR**** $GLOBALS[phpgw]->msg->phpgw_delete() returns FALSE, ERROR, break out of loop<br>'
                                                      .' * * Server reports error: '.$GLOBALS['phpgw']->msg->phpgw_server_last_error().'<br>'); }
                                          break;
                                    }
                                    else
                                    {
                                          if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov: (empty_folder) $GLOBALS[phpgw]->msg->phpgw_delete() returns True (so it buffered the command, really does not mean anything not that we buffer commands)<br>'); }
                                    }
                              }
                              
                              // ok, done deleting, now expunge
                              if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): done empty_folder, now call $GLOBALS[phpgw]->msg->expunge_expungable_folders<br>'); }
                              $did_expunge = False;
                              $did_expunge = $GLOBALS['phpgw']->msg->expunge_expungable_folders('email.boaction.delmov empty_folder LINE '.__LINE__);
                              if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov "empty_folder"('.__LINE__.'): $GLOBALS[phpgw]->msg->expunge_expungable_folders() returns ['.serialize($did_expunge).']<br>'); }
                        }
                        
                        $totaldeleted = $i;
                        $this->redirect_to = $GLOBALS['phpgw']->link(
                                                '/index.php',
                                                 'menuaction=email.uiindex.index'
                                                .'&fldball[folder]='.$this_folder
                                                .'&fldball[acctnum]='.$this_acctnum
                                                .'&td='.$totaldeleted
                                                .'&sort='.$GLOBALS['phpgw']->msg->get_arg_value('sort')
                                                .'&order='.$GLOBALS['phpgw']->msg->get_arg_value('order')
                                                .'&start='.$GLOBALS['phpgw']->msg->get_arg_value('start'));
                  }
                  else
                  {
                        if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): get_arg_value(what) == unknown_value<br>'); }
                        $error_str = '<p><center><b>'.lang('UNKNOWN ACTION')."<br> \r\n"
                                    .'called from '.$GLOBALS['PHP_SELF'].', delmov()'."<br> \r\n"
                                    .'</b></center></p>'."<br> \r\n";
                        $this->redirect_to = $this->redirect_if_error;
                  }
                  
                  // GOTO NECT PAGEVIEW VIA REDIRECT OR OBJECT CALL
                  if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): about to enter logic to display page defined in this URI: $this->redirect_to ['.$this->redirect_to.']<br>'); }
                  
                  /*!
                  @capability use_old_redirect_method
                  @abstract very old school and wasteful way to feed the next page
                  @discussion if this->use_old_redirect_method is set to true, then old style redirect will 
                  be used to doto the next page. This is slow and wasteful but may be necessary if the 
                  bew object call method is causing problems.
                  */
                  if ($this->use_old_redirect_method == True)
                  {
                        if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): EXITING with OLD REDIRECT CODE : $this->use_old_redirect_method: ['.serialize($this->use_old_redirect_method).']<br>'); }
                        $GLOBALS['phpgw']->redirect($this->redirect_to);
                        // kill this script, we re outa here...
                        if (is_object($GLOBALS['phpgw']->msg))
                        {
                              $GLOBALS['phpgw']->msg->end_request();
                              $GLOBALS['phpgw']->msg = '';
                              unset($GLOBALS['phpgw']->msg);
                        }
                        $GLOBALS['phpgw']->common->phpgw_exit(False);
                  }
                  
                  
                  // IF WE GET HERE... continue with new method ...
                  // args we expect to see which would be needed by the next pageview 
                  // NOTE unlike the others, the menuaction element must ne stristr tested
                  $expected_args = 
                        'index_php?menuaction'.','.
                        'fldball'.','.
                        'msgball'.','.
                        'td'.','.
                        'tm'.','.
                        'tf'.','.
                        'sort'.','.
                        'order'.','.
                        'start'.','.
                        'no_fmt';
                        //sessionid
                        //kp3
                        //domain
                  if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): calling $this->set_expected_args($expected_args) ; $expected_args DUMP:', $expected_args); }
                  $this->set_expected_args($expected_args);
                  // the URI of the redirect string contains data needed for the next page view
                  if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): calling $this->set_new_args_uri($this->redirect_to) ; $this->redirect_to ['.$this->redirect_to.']<br>'); }
                  $this->set_new_args_uri($this->redirect_to);
                  // clear existing args, apply the new arg enviornment, 
                  // we get back the menuaction the redirect would have asked for
                  if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): calling $this->apply_new_args_env()<br>'); }
                  $my_menuaction = $this->apply_new_args_env();
                  if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): $my_menuaction is ['.$my_menuaction.'] which was returned from $this->apply_new_args_env()<br>'); }
                  // (c) IF A "BIG MOVE", THEN TURN BACK ON THE SMART CACHE
                  // MOVED TO MSG CLASS
                  //if ((isset($initial_session_cache_extreme))
                  //&& ($initial_session_cache_extreme != '-1'))
                  //{
                  //    if ($this->debug > 1) { echo 'email.boaction.delmov ('.__LINE__.'): $initial_session_cache_extreme is set and is NOT "-1", meaning we issued a "big move" cache event, $initial_session_cache_extreme is ['.serialize($initial_session_cache_extreme).'] <br>'; }
                  //    if ($this->debug > 1) { echo 'email.boaction.delmov ('.__LINE__.'): "big move" will turn off session_cache_extreme if it was TRUE, so we undo that for the next page view with: $GLOBALS[phpgw]->msg->session_cache_extreme = $initial_session_cache_extreme<br>'; }
                  //    $GLOBALS['phpgw']->msg->session_cache_extreme = $initial_session_cache_extreme;
                  //}
                  //else
                  //{
                  //    if ($this->debug > 1) { echo 'email.boaction.delmov ('.__LINE__.'): $initial_session_cache_extreme is either NOT set or is "-1", meaning we did NOT issued a "big move" cache event earlier<br>'; }
                  //}
                  
                  // imitate the next menuaction command with direct object calls
                  if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): LEAVING by creating "next_obj" and calling its menuaction verb ...<br>'); }
                  if (stristr($my_menuaction, 'uimessage'))
                  {
                        //// NEW: mail so object group fill may need to be reset
                        //// we DO NOT use group data capability on the message view page
                        //// this allows the SO class to query for each individual thing it needs
                        //// which is OK for a message view, but not for an index page
                        //$GLOBALS['phpgw']->msg->so->so_prop_use_group_data(False);
                        // NEW: mail so object group fill may need to be reset
                        //clear existing data, if any, and reset the query attempt excess counter
                        $GLOBALS['phpgw']->msg->so->so_prop_use_group_data(False);
                        // then make sure group data capability it turned on
                        $GLOBALS['phpgw']->msg->so->so_prop_use_group_data(True);
                        // MAKE THE UIMESSAGE PAGE OBJECT
                        $this->next_obj = CreateObject('email.uimessage');
                        // CALL THE FUNCTION THAT DISPLAYS THE PAGE VIEW
                        $this->next_obj->message();
                  }
                  // else just ASSUME uiindex, it is the most forgiving about missing values, it has fallback defaults to use if needed
                  else
                  {
                        // NEW: mail so object group fill may need to be reset
                        //clear existing data, if any, and reset the query attempt excess counter
                        $GLOBALS['phpgw']->msg->so->so_prop_use_group_data(False);
                        // then make sure group data capability it turned on
                        $GLOBALS['phpgw']->msg->so->so_prop_use_group_data(True);
                        // MAKE THE INDEX PAGE OBJECT
                        $this->next_obj = CreateObject('email.uiindex');
                        // CALL THE FUNCTION THAT DISPLAYS THE PAGE VIEW
                        $this->next_obj->index();
                  }
                  // (e) cleanup
                  if (is_object($GLOBALS['phpgw']->msg))
                  {
                        if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): oops, not LEFT yet, cleanup and unset ->msg object<br>'); }
                        // close down ALL mailserver streams
                        $GLOBALS['phpgw']->msg->end_request();
                        // destroy the object
                        $GLOBALS['phpgw']->msg = '';
                        unset($GLOBALS['phpgw']->msg);
                  }
                  // shut down this transaction
                  if ($this->debug > 0 && is_object($GLOBALS['phpgw']->msg)) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.delmov ('.__LINE__.'): LEAVING for <b>real</b> with $GLOBALS[phpgw]->common->phpgw_exit(False)<br>'); }
                  $GLOBALS['phpgw']->common->phpgw_exit(False);
            }
            
            /*
            // placeholder for previous test code
            function just_a_placeholder()
            {     
                  // NOW GOTO THE NEXT PAGE SPECIFIED IN THIS->REDIRECT_TO 
                  // VIA REDIRECT OR DIRECT OBJECT CALL
                  if ($this->redirect_to != '')
                  {
                        if ($this->debug > 0) { echo 'email.boaction.delmov ('.__LINE__.'): next pageview redirect data to use is: ['.$this->redirect_to.']<br>'; } 
                        
                        // Experimental:
                        // NO REDIRECT - DIRECTLY MANUFACTURE THE NEXT PAGE VIEW RIGHT NOW
                        // RECOVED ENV DATA FROM THE REDIRECT URI STRING
                        $recovered_data = array();
                        parse_str($this->redirect_to, $recovered_data);
                        
                        if ($this->debug > 1) { echo 'email.boaction.delmov ('.__LINE__.'): redirect_to parsed_str $recovered_data DUMP:<pre>'; print_r($recovered_data); echo '</pre>'; } 
                        // ALL POSSIBLE VARS WE MIGHT FIND IN THE REDIRECT URI:
                        $new_args_env = array(
                              '/mail/index_php?menuaction'  => '-1',
                              'fldball'   => '-1',
                              'msgball'   => '-1',
                              'td'        => '-1',
                              'tm'        => '-1',
                              'tf'        => '-1',
                              'sort'      => '-1',
                              'order'           => '-1',
                              'start'     => '-1'
                        );
                        if ($this->debug > 1) { echo 'email.boaction.delmov ('.__LINE__.'): known possible recovered_data elements init $new_args_env DUMP:<pre>'; print_r($new_args_env); echo '</pre>'; } 
                        // loop thru KNOWN POSSIBLE new_args_env elements, GATHER the ones that are filled for later use
                        reset($new_args_env);
                        while(list($key,$value) = each($new_args_env))
                        {
                              $known_arg = $key;
                              if ((isset($recovered_data[$known_arg]))
                              && ((string)$recovered_data[$known_arg] != ''))
                              {
                                    // we have a arg to use for the next page view
                                    $new_args_env[$key] = $recovered_data[$known_arg];
                              }
                        }
                        reset($new_args_env);
                        
                        // GET GOOD ACCTNUM FOR THE UNSET COMMANDS BELOW
                        // (and also get other useful info while we are at it
                        if ($new_args_env['fldball'] != '-1')
                        {
                              $new_acctnum = (int)$new_args_env['fldball']['acctnum'];
                              $new_folder = $new_args_env['fldball']['folder'];
                        }
                        elseif ($new_args_env['msgball'] != '-1')
                        {
                              $new_acctnum = (int)$new_args_env['msgball']['acctnum'];
                              $new_folder = $new_args_env['msgball']['folder'];
                              // IMITATION: during grab_args_gpc, the code add an element [uri] to the existing msgball
                              // NOTE that for this uri element, the "folder" string shoulf be urlencoded
                              $new_uri_element =       'msgball[msgnum]='.$new_args_env['msgball']['msgnum']
                                                      .'&msgball[folder]='.urlencode($new_args_env['msgball']['folder'])
                                                      .'&msgball[acctnum]='.$new_args_env['msgball']['acctnum'];
                              $new_args_env['msgball']['uri'] = $new_uri_element;
                        }
                        else
                        {
                              echo 'email.boaction.delmov: LINE '.__LINE__.': ERROR getting valid acctnum for goto pageview, NO fldball NO msgball found <br>';
                        }
                        if ($this->debug > 1) { echo 'email.boaction.delmov ('.__LINE__.'): known possible recovered_data elements <b>Post-Gather</b> $new_args_env DUMP:<pre>'; print_r($new_args_env); echo '</pre>'; } 
                        if ($this->debug > 1) { echo 'email.boaction.delmov ('.__LINE__.'): will use $new_acctnum ['.$new_acctnum.'];  and $new_folder ['.$new_folder.'], BUT FIRST unset selected existing class args <br>'; }
                        
                        // UNSET ARGS WE USED IN THIS PAGE BUT ARE NO LONGER NEEDED
                        $GLOBALS['phpgw']->msg->unset_arg('delmov_list', $new_acctnum);
                        $GLOBALS['phpgw']->msg->unset_arg('to_fldball_fake_uri', $new_acctnum);
                        $GLOBALS['phpgw']->msg->unset_arg('to_fldball', $new_acctnum);
                        $GLOBALS['phpgw']->msg->unset_arg('move_postmove_goto', $new_acctnum);
                        $GLOBALS['phpgw']->msg->unset_arg('sort', $new_acctnum);
                        $GLOBALS['phpgw']->msg->unset_arg('order', $new_acctnum);
                        $GLOBALS['phpgw']->msg->unset_arg('start', $new_acctnum);
                        $GLOBALS['phpgw']->msg->unset_arg('what', $new_acctnum);
                        $GLOBALS['phpgw']->msg->unset_arg('folder', $new_acctnum);
                        $GLOBALS['phpgw']->msg->unset_arg('acctnum', $new_acctnum);
                        
                        // REFILL ARGS WITH NEW PAGE VIEW VALUES
                        // (a) set the very important acctnum arg we collected earlier, and also the folder arg, because these values are _derived_ values
                        // they are not plainly in the $new_args_env as simple key and value elements, they were derived from some of them, though
                        $GLOBALS['phpgw']->msg->set_acctnum($new_acctnum);
                        $GLOBALS['phpgw']->msg->set_arg_value('folder', $new_folder, $new_acctnum);
                        
                        // (b) LOOP thru Gathered Args, setting the class args to those values
                        reset($new_args_env);
                        while(list($key,$value) = each($new_args_env))
                        {
                              $arg_name = $key;
                              $arg_value = $new_args_env[$key];
                              // we do not set mail_msg class arg for 'index_php?menuaction'
                              if (($arg_name != 'index_php?menuaction')
                              && ($arg_value != '-1'))
                              {
                                    $GLOBALS['phpgw']->msg->set_arg_value($arg_name, $arg_value, $new_acctnum);
                              }
                        }
                        // (c) IF A "BIG MOVE", THEN TURN BACK ON THE SMART CACHE
                        // MOVED TO MSG CLASS
                        //if ((isset($initial_session_cache_extreme))
                        //&& ($initial_session_cache_extreme != '-1'))
                        //{
                        //    $GLOBALS['phpgw']->msg->session_cache_extreme = $initial_session_cache_extreme;
                        //}
                        // (d) make object and issue command
                        $new_menuaction = $new_args_env['index_php?menuaction'];
                        if ($this->debug > 1 || $this->debug_new_env > 1) { echo 'email.boaction.delmov ('.__LINE__.'): $new_menuaction ['.$new_menuaction.'] <br>'; } 
                        if (stristr($new_menuaction, 'uimessage'))
                        {
                              // MAKE THE UIMESSAGE PAGE OBJECT
                              $this->next_obj = CreateObject('email.uimessage');
                              // CALL THE FUNCTION THAT DISPLAYS THE PAGE VIEW
                              $this->next_obj->message();
                        }
                        // else just ASSUME uiindex, it is the most forgiving about missing values, it has fallback defaults to use if needed
                        else
                        {
                              // MAKE THE INDEX PAGE OBJECT
                              $this->next_obj = CreateObject('email.uiindex');
                              // CALL THE FUNCTION THAT DISPLAYS THE PAGE VIEW
                              $this->next_obj->index();
                        }
                        // (e) cleanup
                        if (is_object($GLOBALS['phpgw']->msg))
                        {
                              // close down ALL mailserver streams
                              $GLOBALS['phpgw']->msg->end_request();
                              // destroy the object
                              $GLOBALS['phpgw']->msg = '';
                              unset($GLOBALS['phpgw']->msg);
                        }
                        // shut down this transaction
                        $GLOBALS['phpgw']->common->phpgw_exit(False);
                  }
                  else
                  {
                        if ($this->debug > 0) { echo 'email.boaction.delmov ('.__LINE__.'): LEAVING, with ERROR, unhandled "where to go from here" condition<br>'; }
                        echo 'error: no redirect specified in '.$GLOBALS['PHP_SELF'].', delmov()'."<br> \r\n"
                              .'error_str: '.$error_str."<br> \r\n";
                        // close down ALL mailserver streams
                        $GLOBALS['phpgw']->msg->end_request();
                        // destroy the object
                        $GLOBALS['phpgw']->msg = '';
                        unset($GLOBALS['phpgw']->msg);
                        // shut down this transaction
                        $GLOBALS['phpgw']->common->phpgw_exit(False);
                  }
            }
            */
            
            /*!
            @function set_expected_args
            @abstract Tells "new_args_env" what args may be present in the "set_new_args_uri" data. WHY 
            is this necessary? Because the "expected" args *may* be gathered BEFORE the existing args are cleared. 
            This gives us a list of args to keep from the existing args before we batch clear the existing args,
            So we loop thru the "expected" args, examine any existing args that are "expected", and preserve their 
            @param $comma_set_str (comma seperated string) any arg we axpect to be needed in the next 
            page view, seperated by commas, no spaces. 
            @author Angles
            @discussion The comma seperated string will be exploded into an array where each expected arg name 
            is a KEY and gets an initial value of "-1". When collecting the expected args from wither the existing arg 
            enviornment or the "set_new_args_uri" data, any arg name in the expected array will have the initial 
            value of "-1" replaced with the value we found in those sources. This "expected_args" data will be the 
            data we use to set the new arg enviornment after unsetting the existing "external" args.
            @access Public
            */
00870             function set_expected_args($comma_set_str='-1')
            {
                  if ($this->debug_new_env > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.set_expected_args ('.__LINE__.'): ENTERING<br>'); } 
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.set_expected_args ('.__LINE__.'): param $comma_set_str: ['.$comma_set_str.'] <br>'); } 
                  $exploded_expected_args = array();
                  $exploded_expected_args = explode(',',$comma_set_str);
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.set_expected_args ('.__LINE__.'): $exploded_expected_args DUMP:', $exploded_expected_args); } 
                  
                  //$this->expected_args = array();
                  $this->expected_args = array();
                  $loops = count($exploded_expected_args);
                  for ($i = 0; $i < $loops; $i++)
                  {
                        $arg_name = $exploded_expected_args[$i];
                        $this->expected_args[$arg_name] = '-1';
                  }
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.set_expected_args ('.__LINE__.'): $this->expected_args DUMP:', $this->expected_args); } 
                  if ($this->debug_new_env > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.set_expected_args ('.__LINE__.'): LEAVING<br>'); } 
            }
            
            /*!
            @function set_new_args_uri
            @abstract Takes a URI such as used in a redirect, extracts any args that are listed in the "set_expected_args" data. 
            @param $new_args_uri (URI type string) a string the same as would be used in a redirect.
            page view, seperated by commas, no spaces. 
            @author Angles
            @discussion Eases the transition from redirect to using "apply_new_args_env" by accepting that redirect URI 
            string as a data source for the "apply_new_args_env" function.
            @access Public
            */
00900             function set_new_args_uri($new_args_uri='-1')
            {
                  if ($this->debug_new_env > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.set_new_args_uri ('.__LINE__.'): ENTERING, $new_args_uri ['.$new_args_uri.']<br>'); } 
                  $this->new_args_uri = $new_args_uri;
                  if ($this->debug_new_env > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): LEAVING<br>'); } 
            }
            
            /*!
            @function apply_new_args_env
            @abstract unsets ALL known internal args then sets new values for "expected" args that exist. 
            Used as an alternative to redirect, the expected and actual args must be set via "set_expected_args" and 
            "set_new_args_uri" companion functions. "apply_new_args_env" will set (or apply) the new arg enviornment. 
            @result (string) Returns the menuaction var from the processed data, tells calling function what to do 
            now that the new arg enviornment is set.
            @author Angles
            @discussion Alternative to redirect. That is why "set_new_args_uri" is in the format of a URI, so that 
            functions that previously used redirects can easily transition to this new way of preparing the next page 
            view arg enviornment. The calling process should call "set_expected_args" and "set_new_args_uri", which 
            defines (a) what args we are looking to gather and (b) gives a data source for those args, with the existing 
            args being a secondary data source if "set_new_args_uri" is not provided or is missing information. 
            NOTE: I AM CONSIDERING NOT USING THE EXISTING ARGS AS A SOURCE, but for now they are. 
            Thenm the calling process should call this function "apply_new_args_env", which unsets all existing _known_ 
            _external_ args, hen the calling function can create the desired UI object and then call its main function, 
            imitating exactly what would happen if the redirect had occured with the menuaction command in that URI. 
            NOTE terms "known" means the arg is listed in msg class ->known_external_args which is set in 
            mail_msg_base constructor function. "external" means these are args we would normally look for at the 
            start of any page view, as source data for the mail_msg class OOP "get_arg_value" way of accessing args 
            as seperate from the actual GPC data, so that other data sources (XML-RPC) can be used to fill those 
            args, and the mail_msg class does not care where they came from in that respect.
            @access Public
            */
00931             function apply_new_args_env()
            {
                  if ($this->debug_new_env > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): ENTERING<br>'); } 
                  $recovered_data = array();
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): source data is $this->new_args_uri DUMP:', $this->new_args_uri); } 
                  parse_str($this->new_args_uri, $recovered_data);
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): used command "parsed_str" on that to get this $recovered_data DUMP:', $recovered_data); } 
                  
                  // NOTE PARSE_STR ***WILL ADD SLASHES*** TO ESCAPE QUOTES
                  // NO MATTER WHAT YOUR MAGIC SLASHES SETTING IS
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): NOTE PARSE_STR ***WILL ADD SLASHES*** TO ESCAPE QUOTES NO MATTER WHAT YOUR MAGIC SLASHES SETTING IS **stripping slashes NOW*** from any folder names'.'<br>'); }  
                  if (isset($recovered_data['fldball']['folder']))
                  {
                        $recovered_data['fldball']['folder'] = stripslashes($recovered_data['fldball']['folder']);
                        $recovered_data['fldball']['folder'] = $GLOBALS['phpgw']->msg->prep_folder_out($recovered_data['fldball']['folder']);
                  }
                  if (isset($recovered_data['msgball']['folder']))
                  {
                        $recovered_data['msgball']['folder'] = stripslashes($recovered_data['msgball']['folder']);
                        $recovered_data['msgball']['folder'] = $GLOBALS['phpgw']->msg->prep_folder_out($recovered_data['msgball']['folder']);
                  }
                  if (isset($recovered_data['tf']))
                  {
                        $recovered_data['tf'] = stripslashes($recovered_data['tf']);
                        $recovered_data['tf'] = $GLOBALS['phpgw']->msg->prep_folder_out($recovered_data['tf']);
                  }
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): AFTER STRIPSLASH: used command "parsed_str" on that to get this $recovered_data DUMP:', $recovered_data); } 
                  
                  $new_args_env = array();
                  $new_args_env = $this->expected_args;
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): $this->expected_args DUMP:', $new_args_env); } 
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): initial $new_args_env DUMP:', $new_args_env); } 
                  
                  // loop thru KNOWN POSSIBLE new_args_env elements, GATHER the ones that are filled for later use
                  reset($new_args_env);
                  while(list($key,$value) = each($new_args_env))
                  {
                        if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out(' * ('.__LINE__.') $key: ['.$key.']  $value: ['.$value.']<br>'); } 
                        $known_arg = $key;
                        //handle the special URI not match case
                        if ($key == 'index_php?menuaction')
                        {
                              //find the menuaction
                              reset($recovered_data);
                              while(list($recovered_key,$recovered_value) = each($recovered_data))
                              {
                                    if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out(' * * ('.__LINE__.') $recovered_key: ['.$recovered_key.']  $recovered_value: ['.$recovered_value.']<br>'); } 
                                    if (stristr($recovered_key, 'menuaction'))
                                    {
                                          $new_args_env[$key] = $recovered_data[$recovered_key];
                                          $my_menuaction = $new_args_env[$key];
                                          break;
                                    }
                              }
                              if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out(' ** found menuaction ** ('.__LINE__.') ['.$recovered_data[$recovered_key].']<br>'); } 
                        }
                        elseif ((isset($recovered_data[$known_arg]))
                        && ((string)$recovered_data[$known_arg] != ''))
                        {
                              // we have a arg to use for the next page view
                              $new_args_env[$key] = $recovered_data[$known_arg];
                        }
                  }
                  reset($new_args_env);
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): FIRST PASS filled available known possible recovered_data elements <b>Post-Gather</b> $new_args_env DUMP:', $new_args_env); } 
                  
                  // we are NOT DONE yet, extract some more args that we derive from what we gathered so far
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): ADDITIONALLY extract embedded "*ball" items "acctnum" and "folder" AND if a "msgball", add a "uri" element to it<br>'); } 
                  // GET GOOD ACCTNUM FOR THE UNSET COMMANDS BELOW
                  // and also get other useful info while we are at it (folder), and if we find a "msgball", make and add to it a "uri" element
                  if ($new_args_env['fldball'] != '-1')
                  {
                        $new_acctnum = (int)$new_args_env['fldball']['acctnum'];
                        $new_folder = $new_args_env['fldball']['folder'];
                  }
                  elseif ($new_args_env['msgball'] != '-1')
                  {
                        $new_acctnum = (int)$new_args_env['msgball']['acctnum'];
                        $new_folder = $new_args_env['msgball']['folder'];
                        // IMITATION: during grab_args_gpc, the code add an element [uri] to the existing msgball
                        // NOTE that for this uri element, the "folder" string shoulf be urlencoded
                        $new_uri_element =       'msgball[msgnum]='.$new_args_env['msgball']['msgnum']
                                                //.'&msgball[folder]='.urlencode($new_args_env['msgball']['folder'])
                                                //.'&msgball[folder]='.$GLOBALS['phpgw']->msg->prep_folder_out($new_args_env['msgball']['folder'])
                                                .'&msgball[folder]='.$new_args_env['msgball']['folder']
                                                .'&msgball[acctnum]='.$new_args_env['msgball']['acctnum'];
                        $new_args_env['msgball']['uri'] = $new_uri_element;
                  }
                  else
                  {
                        echo 'email.boaction.apply_new_args_env: LINE '.__LINE__.': ERROR getting valid acctnum for goto pageview, NO fldball NO msgball found <br>';
                        $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env: LINE '.__LINE__.': ERROR getting valid acctnum for goto pageview, NO fldball NO msgball found <br>');
                  }
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): extracted additional data: will use $new_acctnum ['.$new_acctnum.'];  and $new_folder ['.$new_folder.'] <br>'); }
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): FINAL filled available known possible recovered_data elements <b>Post-Gather</b> $new_args_env DUMP:', $new_args_env); } 
                  
                  // UNSET ARGS WE USED IN THIS PAGE BUT ARE NO LONGER NEEDED
                  // HELL, JUST UNSET ALL EXTERNAL ARGS
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): unset ALL known external class args as defined in array $GLOBALS[phpgw]->msg->known_external_args<br>'); }
                  $loops = count($GLOBALS['phpgw']->msg->known_external_args);
                  for ($i = 0; $i < $loops; $i++)
                  {
                        $arg_name = $GLOBALS['phpgw']->msg->known_external_args[$i];
                        if ($GLOBALS['phpgw']->msg->get_isset_arg($arg_name, $new_acctnum) == True)
                        {
                              if ($this->debug_new_env > 2) { $GLOBALS['phpgw']->msg->dbug->out(' * email.boaction.apply_new_args_env ('.__LINE__.'):UNSETTING with $GLOBALS[phpgw]->msg->unset_arg('.$arg_name.', '.$new_acctnum.') <br>'); }
                              $GLOBALS['phpgw']->msg->unset_arg($arg_name, $new_acctnum);
                        }
                        else
                        {
                              if ($this->debug_new_env > 2) { $GLOBALS['phpgw']->msg->dbug->out(' * email.boaction.apply_new_args_env ('.__LINE__.'): <i>was not set $arg_name ['.$arg_name.'];  and $new_acctnum ['.$new_acctnum.']</i><br>'); }
                        }
                  }
                  
                  // REFILL ARGS WITH NEW PAGE VIEW VALUES
                  // (a) set the very important acctnum arg we collected earlier, and also the folder arg, because these values are _derived_ values
                  // they are not plainly in the $new_args_env as simple key and value elements, they were derived from some of them, though
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): BEGIN setting new arg env by setting the "new_acctnum" and "new_folder"<br>'); } 
                  $GLOBALS['phpgw']->msg->set_acctnum($new_acctnum);
                  $GLOBALS['phpgw']->msg->set_arg_value('folder', $new_folder, $new_acctnum);
                  
                  // (b) LOOP thru Gathered Args, setting the class args to those values
                  if ($this->debug_new_env > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): continue by LOOPING thru Final Gathered Args, setting the class args to those values that are not still "-1" (that data was found for)<br>'); } 
                  reset($new_args_env);
                  while(list($key,$value) = each($new_args_env))
                  {
                        $arg_name = $key;
                        $arg_value = $new_args_env[$key];
                        // we do not set mail_msg class arg for 'index_php?menuaction'
                        if ((!stristr($arg_name, 'index_php?menuaction'))
                        && ($arg_value != '-1'))
                        {
                              if ($this->debug_new_env > 2) { $GLOBALS['phpgw']->msg->dbug->out(' * email.boaction.apply_new_args_env ('.__LINE__.'): calling $GLOBALS[phpgw]->msg->set_arg_value('.$arg_name.', '.$arg_value.', '.$new_acctnum.') <br>'); }
                              $GLOBALS['phpgw']->msg->set_arg_value($arg_name, $arg_value, $new_acctnum);
                        }
                  }
                  //$my_menuaction = $new_args_env['/mail/index_php?menuaction'];
                  if ($this->debug_new_env > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.apply_new_args_env ('.__LINE__.'): LEAVING, returning next menuaction command $my_menuaction ['.$my_menuaction.'] <br>'); } 
                  return $my_menuaction;
            }
            
            /*!
            @function content_header2
            @abstract similar to API browser class function but add Content-description to the headers
            @example
                  Content-Disposition: attachment; filename=something
                  Content-Description: something
            ??    Connection: close
            ??    Transfer-Encoding: chunked
                  Content-Type: application/octet-stream
            */
            function content_header2($fn='',$mime='',$length='',$nocache=True)
            {
                  if (!is_object($this->browser))
                  {
                        if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.content_header2: creating $this->browser <br>'); }
                        $this->browser = CreateObject('phpgwapi.browser');
                  }
                  // if no mime-type is given or it's the default binary-type, guess it from the extension
                  if(empty($mime) || $mime == 'application/octet-stream')
                  {
                        $mime_magic = createObject('phpgwapi.mime_magic');
                        $mime = $mime_magic->filename2mime($fn);
                  }
                  if($fn)
                  {
                        if($this->browser->get_agent() == 'IE') // && browser_get_version() == "5.5")
                        {
                              $attachment = '';
                        }
                        else
                        {
                              $attachment = ' attachment;';
                        }
                        // Show this for all
                        header('Content-Disposition: '.$attachment.' filename='.$fn);
                        header('Content-Description: '.$fn);
                        //header('Connection: close');
                        //header('Transfer-Encoding: chunked');
                        if($length)
                        {
                              header('Content-Length: '.$length);
                        }
                        //header('Content-Type: '.$mime.'; filename="foo.bar"');
                        header('Content-Type: '.$mime.'; name="'.$fn.'"');
                        if($nocache)
                        {
                              header('Pragma: no-cache');
                              header('Pragma: public');
                              header('Expires: 0');
                              header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
                        }
                  }
            }
            
            /*!
            @function get_attach
            @abstract browser requests a specific MIME part number, this function will get it from the mail server 
            and send it to the browser.
            @author Angles and previous maintainers
            @discussion Uses the phpgw api browser class to generate the headers which preceed the actual attachment 
            data. Note this is tricky because different browsers, especially the MSIE versions, require different headers 
            to be present in order to handle the data effectively at the clients browser. Incorrect headers can cause things 
            like the browser not getting the name of the attachment, or not starting the associated viewer for the attachment, 
            or even several save_or_open dialogs in a row.
            */
01137             function get_attach()
            {
                  $GLOBALS['phpgw_info']['flags']['noheader'] = True;
                  $GLOBALS['phpgw_info']['flags']['nonavbar'] = True;
                  $GLOBALS['phpgw_info']['flags']['nofooter'] = True;
                  $GLOBALS['phpgw_info']['flags']['noappheader'] = True;
                  $GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
                  
                  $this->msg_bootstrap = CreateObject('email.msg_bootstrap');
                  $this->msg_bootstrap->ensure_mail_msg_exists('email.boaction.get_attach', $this->debug);
                  if (!is_object($this->browser))
                  {
                        if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.get_attach: creating $this->browser <br>'); }
                        $this->browser = CreateObject('phpgwapi.browser');
                  }
                  $msgball = $GLOBALS['phpgw']->msg->get_arg_value('msgball');
                  if (!isset($msgball['part_no']))
                  {
                        $part_no = $GLOBALS['phpgw']->msg->get_arg_value('part_no');
                        $msgball['part_no'] = $part_no;
                  }
                  
                  // decode rfc2047 encoded attachment name MIME part headers
                  // see RFC2047 "Message Header Extensions for Non-ASCII Text"
                  /*
                  //$att_name = $GLOBALS['phpgw']->msg->decode_rfc_header($GLOBALS['phpgw']->msg->get_arg_value('name'));
                  $att_name = $GLOBALS['phpgw']->msg->decode_header_string($GLOBALS['phpgw']->msg->get_arg_value('name'));
                  if (($att_name != $GLOBALS['phpgw']->msg->get_arg_value('name'))
                  && (trim($att_name) != '')
                  && (trim($GLOBALS['phpgw']->msg->get_arg_value('name')) != ''))
                  {
                        $GLOBALS['phpgw']->msg->set_arg_value('name', $att_name);
                  }
                  // altered as per PATCH 2770 from lex "fix-filename-encoding.diff"
                  //Check if the name changed thru the header decoding im not shure
                  //if (($header_decoded_name != urldecode($GLOBALS['phpgw']->msg->get_arg_value('name')))
                  //&& (trim($header_decoded_name) != '')
                  //&& (trim(urldecode($GLOBALS['phpgw']->msg->get_arg_value('name'))) != ''))
                  //{
                  //    $GLOBALS['phpgw']->msg->set_arg_value('name', $header_decoded_name);
                  //}
                  */
                  $urlencoded_name = '';
                  $urldecoded_name = '';
                  $header_decoded_name = '';
                  $final_att_name = '';
                  $urlencoded_name = $GLOBALS['phpgw']->msg->get_arg_value('name');
                  $urldecoded_name = urldecode($GLOBALS['phpgw']->msg->get_arg_value('name'));
                  // it is possible we have this now: "=?ISO-8859-1?Q?instala=E7=E3o_padr=E3o_esta=E7=F5es_windows=2Edoc?="
                  // therefor we my also need to header decode
                  $header_decoded_name = $GLOBALS['phpgw']->msg->decode_header_string($urldecoded_name);
                  $max_ord = 0;
                  $max_char = '';
                  for( $i = 0 ; $i < strlen($header_decoded_name) ; $i++ )
                  {
                        $val = ord($header_decoded_name[$i]);
                        //if ($this->debug > 1) { echo '$header_decoded_name['.$i.'] ['.$header_decoded_name[$i].'], $val ['.$val.'] <br>'."\r\n"; }
                        if ($val > $max_ord)
                        {
                              $max_ord = $val;
                              $max_char = $header_decoded_name[$i];
                        }
                  }
                  if ($this->debug > 1) { echo '$header_decoded_name: $max_ord ['.$max_ord.'], $max_char ['.$max_char.']  <br>'."\r\n"; }
                  // now we have header decoded we can again urlencode and this time is is directly from the actual string, not an RFC2047 header encoding of it
                  // fallback value
                  $final_att_name = urlencode($header_decoded_name);
                  // handle non us-ascii filenames
                  if ($max_ord > 123)
                  {
                        // out us US-ASCII common chars range, this is NOT en_US name
                        //$final_att_name = urlencode($header_decoded_name);
                        // MORE RESEARCH NEEDED, i18n ENCODING NEEDS TO GO HERE
                        //if ((ini_get('output_buffering'))
                        //&& (ini_get('output_handler') == 'mb_output_handler'))
                        //default_charset
                        $has_mbstring = False;
                        $has_mbstring = extension_loaded('mbstring') || @dl(PHP_SHLIB_PREFIX.'mbstring.'.PHP_SHLIB_SUFFIX);
                        //if (($has_mbstring)
                        //&& (ini_get('mbstring.internal_encoding'))
                        //&& (ini_get('mbstring.func_overload') > 2))
                        // just hope for the best :)
                        if ($has_mbstring)
                        {
                              // WE CAN HANDLE THIS CHARSET, SEND OUT WITH NO ENCODING
                              $final_att_name = $header_decoded_name;
                        }
                        else
                        {
                              // if not then we need to do something here may be to make it look more human readable than straight urlencoding
                              // there is NOTHING we can do here, there are too many charsets in the world to make substitutions
                        }
                  }
                  
                  // FOR TESTING
                  //$final_att_name = $urlencoded_name;
                  //$final_att_name = $urldecoded_name;
                  //$final_att_name = rawurlencode($header_decoded_name);
                  //$final_att_name = $header_decoded_name;
                  //$final_att_name = urlencode($header_decoded_name);
                  //$final_att_name = htmlspecialchars($header_decoded_name);
                  //$final_att_name = htmlentities($header_decoded_name);
                  
                  // set the new name param
                  $GLOBALS['phpgw']->msg->set_arg_value('name', $final_att_name);
                  
                  $mime = strtolower($GLOBALS['phpgw']->msg->get_arg_value('type')) .'/' .strtolower($GLOBALS['phpgw']->msg->get_arg_value('subtype'));
                  // do not do this until we get a length
                  //$this->browser->content_header($GLOBALS['phpgw']->msg->get_arg_value('name'), $mime);
                  if ($this->debug > 1)
                  {
                        echo 'get all args dump<pre> '; print_r($GLOBALS['phpgw']->msg->get_all_args()); echo ' </pre>'."\r\n";
                        echo '$urlencoded_name: ['.$urlencoded_name.'] <br>'."\r\n";
                        echo '$urldecoded_name ['.$urldecoded_name.']  <br>'."\r\n";
                        echo '$header_decoded_name ['.$header_decoded_name.']  <br>'."\r\n";
                        echo '$mime ['.$mime.']  <br>'."\r\n";
                        echo '$GLOBALS[phpgw]->msg->get_arg_value(encoding): ['.$GLOBALS['phpgw']->msg->get_arg_value('encoding').'] <br>'."\r\n";
                        echo '$final_att_name ['.$final_att_name.']  <br>'."\r\n";
                        echo '$GLOBALS[phpgw]->msg->get_arg_value(name): ['.$GLOBALS['phpgw']->msg->get_arg_value('name').'] <br>'."\r\n";
                        echo 'get_cfg_var(output_buffering) ['.serialize(get_cfg_var('output_buffering')).']  <br>'."\r\n";
                        echo 'ini_get(output_buffering) ['.serialize(ini_get('output_buffering')).']  <br>'."\r\n";
                        echo 'get_cfg_var(cfg_file_path) ['.serialize(get_cfg_var('cfg_file_path')).']  <br>'."\r\n";
                        set_time_limit(40);
                        echo 'get_cfg_var(max_execution_time) ['.serialize(get_cfg_var('max_execution_time')).']  <br>'."\r\n";
                        echo 'ini_get(max_execution_time) ['.serialize(ini_get('max_execution_time')).']  <br>'."\r\n";
                        echo 'get_cfg_var(default_charset) ['.serialize(get_cfg_var('default_charset')).']  <br>'."\r\n";
                        echo 'ini_get(default_charset) ['.serialize(ini_get('default_charset')).']  <br>'."\r\n";
                        //$charset = $GLOBALS['phpgw']->translation->system_charset ? $GLOBALS['phpgw']->translation->system_charset : 'iso-8859-1';
                        echo 'is_object($GLOBALS[phpgw]->translation) ['.serialize(is_object($GLOBALS['phpgw']->translation)).']  <br>'."\r\n";
                        echo '$GLOBALS[phpgw]->translation->system_charset ['.serialize($GLOBALS['phpgw']->translation->system_charset).']  <br>'."\r\n";
                        echo '$GLOBALS[phpgw]->translation->charset() ['.serialize($GLOBALS['phpgw']->translation->charset()).']  <br>'."\r\n";
                        echo '$GLOBALS[phpgw_info][server][system_charset] ['.serialize($GLOBALS['phpgw_info']['server']['system_charset']).']  <br>'."\r\n";
                        echo '$GLOBALS[phpgw]->translation->mbstring ['.serialize($GLOBALS['phpgw']->translation->mbstring).']  <br>'."\r\n";
                        $we_have_mbstring = extension_loaded('mbstring') || @dl(PHP_SHLIB_PREFIX.'mbstring.'.PHP_SHLIB_SUFFIX);
                        echo '$we_have_mbstring ['.serialize($we_have_mbstring).']  <br>'."\r\n";
                  }
                  
                  // is this only a header PEEK?
                  if ((string)$msgball['part_no'] == '0')
                  {
                        // just getting headers should be via PEEK so the "seen" flag is left alone
                        $this->output_data = $GLOBALS['phpgw']->msg->phpgw_fetchheader($msgball);
                        $size = strlen($this->output_data);
                        $this->browser->content_header($GLOBALS['phpgw']->msg->get_arg_value('name'), $mime, $size);
                        echo $this->output_data;
                        $this->output_data = '';
                  }
                  // ----  'irregular' "view raw message" functionality  ----
                  elseif ($msgball['part_no'] == 'raw_message')
                  {
                        // NOTE no length for this purpose
                        $this->browser->content_header($GLOBALS['phpgw']->msg->get_arg_value('name'), $mime);
                        // to dump out the whole raw message, do this:
                        // 1) output the headers, 2) output the raw body 3) output a "closing" CRLF
                        //headers_msgball will be used get the message headers, by specifying "part_no" = 0
                        $headers_msgball = $msgball;
                        $headers_msgball['part_no'] = 0;
                        // that can also be used to ge tthe raw message body because phpgw_body() doesn't care about "part_no" 
                        echo $GLOBALS['phpgw']->msg->phpgw_fetchbody($headers_msgball);
                        echo $GLOBALS['phpgw']->msg->phpgw_body($headers_msgball);
                        echo "\r\n";
                  }
                  // ---- "regular" attachment handling  ----
                  elseif ($GLOBALS['phpgw']->msg->get_arg_value('encoding') == 'base64')
                  {
                        //echo $GLOBALS['phpgw']->msg->de_base64($GLOBALS['phpgw']->msg->phpgw_fetchbody($msgball));
                        $this->output_data = $GLOBALS['phpgw']->msg->de_base64($GLOBALS['phpgw']->msg->phpgw_fetchbody($msgball));
                        $size = strlen($this->output_data);
                        //$this->browser->content_header($GLOBALS['phpgw']->msg->get_arg_value('name'), $mime, $size);
                        $this->content_header2($GLOBALS['phpgw']->msg->get_arg_value('name'), $mime, $size);
                        echo $this->output_data;
                        $this->output_data = '';
                  }
                  elseif ($GLOBALS['phpgw']->msg->get_arg_value('encoding') == 'qprint')
                  {
                        //echo $GLOBALS['phpgw']->msg->qprint($GLOBALS['phpgw']->msg->phpgw_fetchbody($msgball));
                        $this->output_data = $GLOBALS['phpgw']->msg->qprint($GLOBALS['phpgw']->msg->phpgw_fetchbody($msgball));
                        $size = strlen($this->output_data);
                        //$this->browser->content_header($GLOBALS['phpgw']->msg->get_arg_value('name'), $mime, $size);
                        $this->content_header2($GLOBALS['phpgw']->msg->get_arg_value('name'), $mime, $size);
                        echo $this->output_data;
                        $this->output_data = '';
                  }
                  else
                  {
                        //echo $GLOBALS['phpgw']->msg->phpgw_fetchbody($msgball);
                        $this->output_data = $GLOBALS['phpgw']->msg->phpgw_fetchbody($msgball);
                        $size = strlen($this->output_data);
                        //$this->browser->content_header($GLOBALS['phpgw']->msg->get_arg_value('name'), $mime, $size);
                        $this->content_header2($GLOBALS['phpgw']->msg->get_arg_value('name'), $mime, $size);
                        echo $this->output_data;
                        $this->output_data = '';
                  }
                  // you may feed "end_request" a msgball or a fldball and "end_request" will close the acctnum specified therein
                  //$GLOBALS['phpgw']->msg->end_request($msgball);
                  //$GLOBALS['phpgw']->common->phpgw_footer();
                  // close down ALL mailserver streams
                  $GLOBALS['phpgw']->msg->end_request();
                  // destroy the object
                  $GLOBALS['phpgw']->msg = '';
                  unset($GLOBALS['phpgw']->msg);
                  // shut down this transaction
                  $GLOBALS['phpgw']->common->phpgw_exit(False);
            }
            
            /*!
            @function view_html
            @abstract special handler to view certain types of html mail
            @author Angles
            @discussion Used in special cases when simply giving the client browser unprocessed html MIME part(s) 
            is not a good idea or needs special attention. Not a good idea means that there is CSS in the html part which would 
            totally b0rk the look of the clients browser, or certain unusual script. Special Handling means a MULTIPART 
            RELATED message such as Outkrook stationary or Evolutions version of the same, where the html has IMG 
            tags in it that are not real HREFs but rather a reference to another MIME part in the same message. To handle 
            that this message display code swaps that IMG mime part reference with an actual URL used by "get_attach" function 
            to retrieve that particular MIME part from the email server and send it to the browser, this the IMG appears in the 
            HTML message as intended. In that case the processing is done before the message is dispayed, and the processed HTML 
            part is stored as a form hiddenvar in base64 encoded format. The user sees a button saying "View HTML", if clicked this 
            processed HTML part is submitted to this function which base64 decodes it and sends it to the browser as a simgle 
            html page, not a part of a mail like is typical. In either case the user gets that button and the buttons associated form 
            submits data to this function. If the part is not RELATED, i.e. did not require special IMG tag swapping, then this 
            function gets submitted to is a reference to the particular HTML part of the message and it is sent to the browser 
            as a page unto itself. In either case, the part is not displayed inline with other MIME parts, not displayed in the same 
            browser window as the rest of the groupware template, instead this part will be viewed in its own page.
            */
01362             function view_html()
            {
                  $GLOBALS['phpgw_info']['flags']['noheader'] = True;
                  $GLOBALS['phpgw_info']['flags']['nonavbar'] = True;
                  $GLOBALS['phpgw_info']['flags']['nofooter'] = True;
                  $GLOBALS['phpgw_info']['flags']['noappheader'] = True;
                  $GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
                  
                  $this->msg_bootstrap = CreateObject('email.msg_bootstrap');
                  $this->msg_bootstrap->ensure_mail_msg_exists('email.boaction.get_attach', $this->debug);
                  
                  if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.view_html: creating $this->browser <br>'); }
                  $this->browser = CreateObject('phpgwapi.browser');
                  
                  //$this->browser->content_header($name,$mime);
                  if ((($GLOBALS['phpgw']->msg->get_isset_arg('html_part')))
                  && ($GLOBALS['phpgw']->msg->get_arg_value('html_part') != ''))
                  {
                        $this->browser->content_header('','');
                        $html_part = $GLOBALS['phpgw']->msg->stripslashes_gpc($GLOBALS['phpgw']->msg->get_arg_value('html_part'));
                        echo $GLOBALS['phpgw']->msg->de_base64($html_part);
                        $GLOBALS['phpgw']->msg->end_request();
                  }
                  elseif ((($GLOBALS['phpgw']->msg->get_isset_arg('html_reference')))
                  && ($GLOBALS['phpgw']->msg->get_arg_value('html_reference') != ''))
                  {
                        $html_reference = $GLOBALS['phpgw']->msg->stripslashes_gpc($GLOBALS['phpgw']->msg->get_arg_value('html_reference'));
                        $GLOBALS['phpgw']->msg->end_request();
                        //header('Location: ' . $html_reference);
                        $GLOBALS['phpgw']->redirect($html_reference);
                        //$GLOBALS['phpgw']->common->phpgw_footer();
                  }
                  else
                  {
                        $GLOBALS['phpgw']->msg->end_request();
                        //$GLOBALS['phpgw']->common->phpgw_footer();
                  }
                  // close down ALL mailserver streams
                  $GLOBALS['phpgw']->msg->end_request();
                  // destroy the object
                  $GLOBALS['phpgw']->msg = '';
                  unset($GLOBALS['phpgw']->msg);
                  // shut down this transaction
                  $GLOBALS['phpgw']->common->phpgw_exit(False);
            }

            /*!
            @function clearcache
            @abstract will remove all cached data for this user, all cahced data for all email accounts
            @author Angles
            @discussion if caching is enabled, this function will clear the cache for this user, 
            That is all data for all email accounts this user has that email app has cached, this will 
            be wiped clean. Mostly good for debugging.
            It expects a fldball just to know where to redirect to after the wipe is done.
            @access public
            */
01418             function clearcache()
            {
                  // make sure we have msg object and a server stream
                  $this->msg_bootstrap = CreateObject("email.msg_bootstrap");
                  // NO LOGIN wanted at this moment, because preferences may not be set yet. Login will occur later if needed automatically
                  $this->msg_bootstrap->set_do_login(BS_LOGIN_NEVER);
                  $this->msg_bootstrap->ensure_mail_msg_exists('email.boaction.clearcache', 0);
                  if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('ENTERING email.boaction.clearcache line('.__LINE__.')'.'<br>'); }
                  //if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.clearcache line('.__LINE__.') GLOBALS DUMP:', $GLOBALS); }
                  //if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.clearcache line('.__LINE__.'): get_defined_constants DUMP:', get_defined_constants()); }
                  //if ($this->debug > 2) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.clearcache line('.__LINE__.') GLOBALS[phpgw_info] DUMP:', $GLOBALS['phpgw_info']); }

                  // make an error report URL
                  $this->redirect_if_error = $GLOBALS['phpgw']->link('/home.php');
                  if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.clearcache ('.__LINE__.'): $this->redirect_if_error is ['.htmlspecialchars($this->redirect_if_error).']<br>'); }
                  
                  // where do we goto after done here
                  // if coming from the email app itself, use fldball
                  // function called from preferences or admin page, go back to referer
                  $came_from = '';
                  $came_from = get_var('HTTP_REFERER', 'SERVER');
                  if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.clearcache ('.__LINE__.'): $came_from is ['.htmlspecialchars($came_from).']<br>'); }
                  
                  if ((stristr($came_from, '/admin/index.php?'))
                  && (isset($GLOBALS['phpgw_info']['apps']['admin'])))
                  {
                        $this->redirect_to = $GLOBALS['phpgw']->link('/admin/index.php');
                  }
                  elseif ((stristr($came_from, '/preferences/index.php?'))
                  && (isset($GLOBALS['phpgw_info']['apps']['preferences'])))
                  {
                        $this->redirect_to = $GLOBALS['phpgw']->link('/preferences/index.php');
                  }
                  elseif (stristr($came_from, 'index.php?menuaction=email.'))
                  {
                        $goback_fldball = array();
                        // we sent param "target_fldball" because that param does not lookup list verify at initialization time
                        // thus no unwanted login attempt is triggered which could happen if we sent param fldball instead
                        if ($GLOBALS['phpgw']->msg->get_isset_arg('target_fldball'))
                        {
                              $goback_fldball = $GLOBALS['phpgw']->msg->get_arg_value('target_fldball');
                              if (isset($goback_fldball['folder']))
                              {
                                    // this is the first time we do anything that might require a login, because we are lookup list verifying the folder name
                                    $goback_fldball['folder'] = $GLOBALS['phpgw']->msg->prep_folder_in($goback_fldball['folder']);
                              }
                              else
                              {
                                    $goback_fldball['folder'] = 'INBOX';
                              }
                        }
                        else
                        {
                              $goback_fldball['acctnum'] = $GLOBALS['phpgw']->msg->get_acctnum();
                              // does this need to be langed?
                              $goback_fldball['folder'] = 'INBOX';
                        }
                        if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.clearcache ('.__LINE__.'): goback_fldball[] DUMP:', $goback_fldball); }
                        // $totaldeleted gets displayed in the report to the user, typically "X messages have been moved", we use a string here though
                        $totaldeleted = 'cachedata';
                        $this->redirect_to = $GLOBALS['phpgw']->link('/index.php',array(
                                                'menuaction' => 'email.uiindex.index',
                                                'fldball[folder]' => $GLOBALS['phpgw']->msg->prep_folder_out($goback_fldball['folder']),
                                                'fldball[acctnum]' => $goback_fldball['acctnum'],
                                                'td' => $totaldeleted,
                                                'sort' => $GLOBALS['phpgw']->msg->get_arg_value('sort'),
                                                'order' => $GLOBALS['phpgw']->msg->get_arg_value('order'),
                                                'start' => $GLOBALS['phpgw']->msg->get_arg_value('start')
                                                ));
                  }
                  else
                  {
                        // we have no idea where we came from, just goto home page
                        $this->redirect_to = $this->redirect_if_error;
                  }
                  if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.clearcache ('.__LINE__.'): $GLOBALS[phpgw]->msg->session_cache_enabled is ['.serialize($GLOBALS['phpgw']->msg->session_cache_enabled).']  $$GLOBALS[phpgw]->msg->session_cache_extreme is ['.serialize($GLOBALS['phpgw']->msg->session_cache_extreme).'] <br>'); } 
                  if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.clearcache ('.__LINE__.'): decision: $this->redirect_to is ['.htmlspecialchars($this->redirect_to).']<br>'); }
                  
                  
                  // is there any cache to delete
                  //if (($GLOBALS['phpgw']->msg->session_cache_enabled == True)
                  //|| ($GLOBALS['phpgw']->msg->session_cache_extreme == True))
                  
                  if ($this->debug > 1) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.clearcache ('.__LINE__.'): about to call $GLOBALS[phpgw]->msg->clearcache_all(email.boaction.clearcache line(LINENUM)) <br>'); }
                  $GLOBALS['phpgw']->msg->clearcache_all('email.boaction.clearcache line('.__LINE__.')');
                  
                  // we ALWAYS use classic redirect after this function is done, no need for speed here
                  if ($this->debug > 0) { $GLOBALS['phpgw']->msg->dbug->out('email.boaction.clearcache ('.__LINE__.'): EXITING ... about redirect to: $this->redirect_to ['.$this->redirect_to.']<br>'); }
                  
                  if ($this->debug > 3)
                  {
                        $GLOBALS['phpgw']->msg->dbug->out('email.boaction.clearcache ('.__LINE__.'): $this->debug ['.$this->debug.'] means SKIP redirect <br>');
                  }
                  else
                  {
                        $GLOBALS['phpgw']->redirect($this->redirect_to);
                  }
                  // kill this script, we re outa here...
                  if (is_object($GLOBALS['phpgw']->msg))
                  {
                        $GLOBALS['phpgw']->msg->end_request();
                        $GLOBALS['phpgw']->msg = '';
                        unset($GLOBALS['phpgw']->msg);
                  }
                  $GLOBALS['phpgw']->common->phpgw_exit(False);
            }
      
      }
?>

Generated by  Doxygen 1.6.0   Back to index