New to the forum and new to php in general. As I noted in my introductory post in the Newbie section, I am fairly competent at modifying existing code (Frankensteining it as I prefer to refer to it), but my understanding of php is pretty rudimentary, so I don't always get it right and it takes a lot of trial and error. I've hit a wall on a project and could use some pointers.

I have installed osTicket v1.7.2 on our web server without incident; however, the software is not fully functional because our host doesn't have the imap extension enabled (or even installed) on our web server so the portion of osTicket that accepts e-mails and turns the e-mail message into a support ticket is not working correctly. After a lot of hair pulling and gnashing of teeth, I have determined that replacing the imap functions in the osTicket script with Zend\Mail functionality is the best way to go. I've isolated the two scripts that need to be Frankensteined and have gone through and done the best I can, but it is not working as expected. I've managed to get it to the point where it has stopped throwing a 500 Internal Error and returning just a blank screen, but it won't enable the e-mail fetching because it says I have invalid information. I have independently verified that my information is correct, so apparently there's a problem in the way I have converted the IMAP functions (imap_open, imap_fetchstructure, imap_fetchbody, etc) to Zend\Mail.

I'm attaching two files to this post. One is the original script ([ATTACH]4985[/ATTACH]) and the second is the script as I modified it ([ATTACH]4987[/ATTACH]). I am pretty sure that the problem is in the open function (starting at line 116 in the modified version).

Here are the functions in class.email.php that are referenced by the mailfetch script (function load and function getId aren't referenced in mailfetch, but are called for in function Email and function getMailAccountInfo, respectively, so I included them here):

    
function Email($id) { $this->id=0; $this->load($id); } function load($id=0) { if(!$id && !($id=$this->getId())) return false; $sql='SELECT * FROM '.EMAIL_TABLE.' WHERE email_id='.db_input($id); if(!($res=db_query($sql)) || !db_num_rows($res)) return false; $this->ht=db_fetch_array($res); $this->id=$this->ht['email_id']; $this->address=$this->ht['name']?($this->ht['name'].'<'.$this->ht['email'].'>'):$this->ht['email']; $this->dept = null; return true; } function getMailAccountInfo() { /*NOTE: Do not change any of the tags - otherwise mail fetching will fail */ $info = array( //Mail server info 'host' => $this->ht['mail_host'], 'port' => $this->ht['mail_port'], 'protocol' => $this->ht['mail_protocol'], 'encryption' => $this->ht['mail_encryption'], 'username' => $this->ht['userid'], 'password' => Crypto::decrypt($this->ht['userpass'], SECRET_SALT, $this->ht['userid']), //osTicket specific 'email_id' => $this->getId(), //Required for email routing to work. 'max_fetch' => $this->ht['mail_fetchmax'], 'delete_mail' => $this->ht['mail_delete'], 'archive_folder' => $this->ht['mail_archivefolder'] ); return $info; } function getId() { return $this->id; }

And here is the part of class.email.php that is called when I try to update the settings to use e-mail fetching and is failing and saying my information is incorrect:

if(!$errors && $vars['mail_active']) {
    //note: password is unencrypted at this point...MailFetcher expect plain text.
    $fetcher = new MailFetcher(
            array(
                    'host'  => $vars['mail_host'],
                    'port'  => $vars['mail_port'],
                    'username'  => $vars['userid'],
                    'password'  => $passwd,
                    'protocol'  => $vars['mail_protocol'],
                    'encryption' => $vars['mail_encryption'])
                    );
    if(!($fetcher->open)) {
        $errors['err']='Invalid login. Check '.Format::htmlchars($vars['mail_protocol']).' settings';
        $errors['mail']='<br>'.$fetcher->getLastError();
    }elseif($vars['mail_archivefolder'] && !$fetcher->checkMailbox($vars['mail_archivefolder'],true)) {
         $errors['postfetch']='Invalid or unknown mail folder! >> '.$fetcher->getLastError().'';
         if(!$errors['mail'])
             $errors['mail']='Invalid or unknown archive folder!';
    }
}

Any direction/assistance you guys can give is super appreciated. I'm totally stumped and have been through it all multiple times trying to figure out what I'm missing and just don't know what else to modify to make the thing work.

class.mailfetch.txt class.zmailfetch.txt

    One more thing.... Just a little extra info if it helps:

    From phpinfo:
    System: Linux www2.g1.pair.com 2.6.32-50-server #112-Ubuntu SMP Tue Jul 9 20:45:08 UTC 2013 x86_64
    Host: x86_64-pc-linux-gnu
    SSL Version: OpenSSL/0.9.8k
    PHP Version: 5.3.27
    Configuration File (php.ini) Path: /usr/local/etc/php53
    Loaded Configuration File: /usr/home/[username]/public_html/fcgi-bin/php.ini

      I'm quite curious how you can to the conclusion that IMAP functionality and Zend/Mail are interchangeable?

      I'm not playing "pick on a newbie" here; I just looked at the introductory docs and it certainly appears to me that Zend/Mail is primarily responsible for interfacing with the MTA (Sendmail/Exim/etc.). Am I misunderstanding what you're trying to do?

        I'm not sure if you're misunderstanding or if I am, Dale.

        I need to fetch an email and read it without the imap_* functions. I can (or at least thought I could) do that with Zend\Mail. Am I wrong in thinking that Zend\Mail can do that?

        If you were asked to retrieve and read email (from gmail) without using the imap_* functions, how would you do it?

          I would use PHPMailer if I were asked to do that.

          Also, 'Sup Loveland!'

            Derokorian;11037355 wrote:

            I would use PHPMailer if I were asked to do that.

            It is my understanding that PHPMailer only incorporates SENDING email. I need to retrieve and read email. Am I incorrect in my understanding of PHPMailer?

              Oh maybe, I thought it had some retrieval functionality too. Not sure, been a long time since I tried to read mail from PHP.

                I think Zend\Mail\Storage\Pop3 has the functionality for retrieving mail via the POP3 protocol, which would be the alternative if you don't want to use IMAP. Note of course that some IMAP functionality just isn't meaningful over POP3.

                  Weedpacket;11037361 wrote:

                  I think Zend\Mail\Storage\Pop3 has the functionality for retrieving mail via the POP3 protocol

                  That would be correct, as I understand it, and Zend\Mail\Storage\Imap handles mail via IMAP. It's not that I don't want to use IMAP, it's that I can't use the php native IMAP extension because it's not be installed on our web server.

                  It's been my understanding that Zend\Mail is a way to retrieve mail programmatically without the aid of the IMAP_* functions built-in to php.

                  If there is another means to do it, I would love to hear it. Anything to get this software running at full functionality.

                    Well, I haven't searched deeply, but it is possible to write an IMAP client in PHP without the extension. One example (which again I only looked at long enough to confirm that it doesn't use the extension) is at http://dev.horde.org/imap_client/

                      5 days later

                      Horde looks promising, but is a lot like Zend\Mail in that it is a means of fetching and processing e-mail without the native php imap c-client functions. I'm not sure I want to spend a lot of time trying to work out a new mail system when I'm so close with Zend\Mail, but I have bookmarked it and may come back to it.

                        8 days later

                        I tried looking into Horde and figuring out what I needed to install or where to begin, it was more than I wanted to get into when I am so close to getting the Zend Mail to work.

                        I have upgraded my osTicket from v1.7.2 to v1.8.0 and gone through the code again. I figured out how to make "error_get_last()" a little more informative and provide me with more than just "Array". Here are the updated scripts:

                        class.email.php
                        [ATTACH=CONFIG]5021[/ATTACH]

                        class.zmailfetch.php
                        [ATTACH=CONFIG]5025[/ATTACH]

                        It's not crashing and returning a blank page, but it is giving me this error:

                        Non-static method Format::htmlencode() should not be called statically, assuming $this from incompatible context

                        This is from line 319-320 in class.email.php.

                        Although I'm sure you'll peruse through the entire script, the primary interaction between the two starts at line 307 of class.email.php.

                        If I had a better understanding of calling classes between scripts, passing values between functions and/or dependency injection, I'm sure I could get this sorted out pronto, but wrapping my head around those concepts has really been a struggle and I'm not sure I'm understanding what's going on exactly.

                        I'm sure it's just a matter of a missing line or reference I need to add. I found several places I had misinterpreted the original code in this round and have modified class.zmailfetch.php to be a better replacement for class.mailfetch.php.

                        Speaking of which.... here's the original class.mailfetch.php that I replaced with class.zmailfetch.php:
                        [ATTACH=CONFIG]5023[/ATTACH]

                        Thanks!!

                        class.email.txt class.mailfetch.txt class.zmailfetch.txt

                          First off, there is no reference to Format::htmlencode in either of those 3 files.

                          Anyway, this is how it works&#8230;
                          You do not "call classes". You may call their static methods, which then takes the class and method names separated by :: operator. You may also call member methods (or instance methods) through an existing instance and the member method separated by -> operator. Inside all member methods of a class you will have access to $this, which is a reference to the current instance.

                          class C {
                              # This is a member variable, or simply a member.
                              # Each instance of the class that you create, will contain its own $member
                              # I.e. memory will be allocated separately for $member for each new instance
                              private $member;
                          
                          # static members on the other hand belong to the class.
                          # Memory for these are allocated when the class is defined.
                          private static $staticMember = 0;
                          
                          public function __construct($in) {
                              # $this exists from the first line of the constructor.
                              # I.e. the instance has already be created
                          
                              # The constructor may also initialize data, or perform any other work
                              # necessary before you start using the instance
                              # Here, we assign $in to the instance being created.
                              $this->member = $in;
                          
                              # You may access static members inside the class in several different ways.
                              # Depending on your inheritance structure, they will mean slightly differnet things
                              self::$staticMember += 1;
                              C::$staticMember += 1;
                              static::$staticMember += 1;
                          
                              # At the end of the constructor, $this is returned.
                              # Wether you return nothing or specify something else
                              # does not matter. $this is always returned.
                              # Therefor, it would be pointless and misleading to try returning
                              # something else.
                          }
                          
                          # This method is defined static
                          public static function staticMethod() {
                              return self::$staticMember;
                          
                              # This is a static method. $this does not exist since there is no
                              # instance involved in the call.
                              # You may not use $this->member or $this->memberMethod()
                          }
                          
                          public function memberMethod() {
                              # In a member method, you may still reference the class and its static
                              # members and static member methods.
                              # C::staticMethod(), self::staticMember etc will all work
                          
                              return $this->member;
                          }
                          }
                          
                          # You may call static methods before any instance is created
                          echo C::staticMethod() . PHP_EOL;
                          
                          # Create a new instance of C and assign it to $a
                          $a = new C('a');
                          # staticMember will have been increased by 3 in the call to the constructor
                          echo C::staticMethod() . PHP_EOL;
                          
                          # Create a new instance of C and assign it to $b
                          $b = new C('b');
                          # staticMember will have been increased by another 3 in the call to the constructor
                          # since they both refer to the same static member
                          echo C::staticMethod() . PHP_EOL;
                          
                          # in C::memberMethod $this will refer to the same instance being stored in $a
                          # since you invoke the method for the $a instance.
                          # Also note that you may not call C::memberMethod (since C is not an instance).
                          # This is simply a way to annotate that memberMethod belongs to C.
                          echo $a->memberMethod() .PHP_EOL;
                          
                          
                          # Similarily on this invocation, $this will refer to the $b instance.
                          echo $b->memberMethod() .PHP_EOL;
                          

                            You're right, Johana, Class Format wasn't in any of those files and ironically, wasn't in any of the files called by those with require_once. I found it in an entirely unreferenced file class.format.php [ATTACH=CONFIG]5027[/ATTACH].

                            I added "require_once(INCLUDE_DIR.'class.format.php');" to class.zmailfetch.php and tried again, but it still failed to save and gave me the same errors.

                            I appreciate the in-depth explanation you've provided and will try to apply it to my scripts and see if I can't figure out what I'm missing.

                            I still think that I'm somehow incorrectly passing login credentials around. I would certainly appreciate someone more experienced reading through everything and helping me translate.

                            class.format.txt

                              I'm not talking about where it is defined. And there is nothing ironic about it. You simply never posted the code mentioned in the error message.

                                21 days later

                                Baby steps... baby steps...

                                I'm working through it function by function, line by line and am getting a lot closer to converting from the imap c-clent functions to zend\mail.

                                I could use a little assistance figuring out exactly what this function is supposed to return. I think I have figured out the individual lines, but the overall picture is eluding me.

                                (The comments in each of these functions are from the original script except for the #'s to coincide with my understanding below.)

                                    //search for specific mime type parts....encoding is the desired encoding.
                                    function getPart($mid, $mimeType, $encoding=false, $struct=null, $partNumber=false) {
                                
                                    #1
                                    if(!$struct && $mid)
                                        $struct=@imap_fetchstructure($this->mbox, $mid);
                                
                                   //Match the mime type.
                                   #2
                                   if($struct
                                            && strcasecmp($mimeType, $this->getMimeType($struct))==0
                                            && (!$struct->ifdparameters
                                                || !$this->findFilename($struct->dparameters))) {
                                
                                        #3
                                        $partNumber=$partNumber?$partNumber:1;
                                        #4
                                        if(($text=imap_fetchbody($this->mbox, $mid, $partNumber))) {
                                            if($struct->encoding==3 or $struct->encoding==4) //base64 and qp decode.
                                                $text=$this->decode($text, $struct->encoding);
                                
                                            $charset=null;
                                            #5
                                            if ($encoding) { //Convert text to desired mime encoding...
                                                if ($struct->ifparameters && $struct->parameters) {
                                                    foreach ($struct->parameters as $p) {
                                                        if (!strcasecmp($p->attribute, 'charset')) {
                                                            $charset = trim($p->value);
                                                            break;
                                                        }
                                                    }
                                                }
                                                #6
                                    	    $text = $this->mime_encode($text, $charset, $encoding);
                                            }
                                            return $text;
                                        }
                                    }
                                
                                   //Do recursive search
                                  $text='';
                                    if($struct && $struct->parts) {
                                        while(list($i, $substruct) = each($struct->parts)) {
                                            if($partNumber)
                                                $prefix = $partNumber . '.';
                                            if(($result=$this->getPart($mid, $mimeType, $encoding, $substruct, $prefix.($i+1))))
                                                $text.=$result;
                                        }
                                    }
                                
                                    return $text;
                                }
                                

                                Here's what I understand the function getPart to be doing:

                                #1
                                if $struct is null or empty AND $mid (message ID) is NOT null) get the structure of the message

                                #2
                                if $struct is NOT null
                                AND the structure did not return a predefined $mimeType
                                AND (there is not an array of objects corresponding to the parameters of the Content-disposition
                                OR can't locate a filename)

                                #3
                                if there's a part number use it, otherwise use 1

                                #4
                                if can retrieve the section (by $partNumber) of the specified message (by $mid)
                                then if the encoding is either base64 or quoted-printable decode it as an 8 bit string

                                #5
                                if an encoding type has been defined then
                                if an array of object parameters exists and is not null then
                                loop through the parameters to determine the charset

                                #6
                                mime encode the string $text (the decoded content of $partnumber) using
                                the $charset and $encoding method found in the structure

                                And here are the functions referenced:

                                    function getMimeType($struct) {
                                        $mimeType = array('TEXT', 'MULTIPART', 'MESSAGE', 'APPLICATION', 'AUDIO', 'IMAGE', 'VIDEO', 'OTHER');
                                        if(!$struct || !$struct->subtype)
                                            return 'TEXT/PLAIN';
                                
                                    return $mimeType[(int) $struct->type].'/'.$struct->subtype;
                                }
                                
                                    /**
                                     * Searches the attribute list for a possible filename attribute. If
                                     * found, the attribute value is returned. If the attribute uses rfc5987
                                     * to encode the attribute value, the value is returned properly decoded
                                     * if possible
                                     *
                                     * Attribute Search Preference:
                                     *   filename
                                     *   filename*
                                     *   name
                                     *   name*
                                     */
                                    function findFilename($attributes) {
                                        foreach (array('filename', 'name') as $pref) {
                                            foreach ($attributes as $a) {
                                                if (strtolower($a->attribute) == $pref)
                                                    return $a->value;
                                                // Allow the RFC5987 specification of the filename
                                                elseif (strtolower($a->attribute) == $pref.'*')
                                                    return Format::decodeRfc5987($a->value);
                                            }
                                        }
                                        return false;
                                    }
                                
                                    function decode($text, $encoding) {
                                
                                    switch($encoding) {
                                        case 1:
                                        $text=imap_8bit($text);
                                        break;
                                        case 2:
                                        $text=imap_binary($text);
                                        break;
                                        case 3:
                                        // imap_base64 implies strict mode. If it refuses to decode the
                                        // data, then fallback to base64_decode in non-strict mode
                                        $text = (($conv=imap_base64($text))) ? $conv : base64_decode($text);
                                        break;
                                        case 4:
                                        $text=imap_qprint($text);
                                        break;
                                    }
                                
                                    return $text;
                                }
                                
                                    function mailbox_encode($mailbox) {
                                        if (!$mailbox)
                                            return null;
                                        // Properly encode the mailbox to UTF-7, according to rfc2060,
                                        // section 5.1.3
                                        elseif (function_exists('mb_convert_encoding'))
                                            return mb_convert_encoding($mailbox, 'UTF7-IMAP', 'utf-8');
                                        else
                                            // XXX: This function has some issues on some versions of PHP
                                            return imap_utf7_encode($mailbox);
                                    }
                                

                                I just don't understand what it's doing overall... when all is said and done, what is $text?

                                  By the code in your point #4, it is the body content of one part of the message.

                                    Thanks for looking, Weedpacket.

                                    Are you familiar with Zend\Mail at all? Because I am trying to keep everything as close to its original form as possible so that functions, variables and such can still be referred to by other scripts in the ticket system, I am trying to work out the best way to replace the imap c-client functions with appropriate Zend\Mail functions.

                                    I guess I am a little confused by how the function getMimeType works. The variable $mimeType afaik is passed into function getPart from only one other function (getBody shown at the end of this post) and thus is always 'text/html' or 'text/plain' (searching the entire script, class.mailfetch.php, for "->getPart" only returns instances in function getBody and the one line of getPart in the recursive search section). Can you shed some light on what's going on in getMimeType? If it is just returning the MIME type of that particular part of the header/message I could replace the existing code:

                                    		function getMimeType($struct) {
                                    			$mimeType = array('TEXT', 'MULTIPART', 'MESSAGE', 'APPLICATION', 'AUDIO', 'IMAGE', 'VIDEO', 'OTHER');
                                    			if(!$struct || !$struct->subtype)
                                    				return 'TEXT/PLAIN';
                                    
                                    		return $mimeType[(int) $struct->type].'/'.$struct->subtype;
                                    	}
                                    

                                    with this code:

                                    		function getMimeType($part) {
                                    			$mimeType = strtok($part->contentType, ';');
                                    
                                    		return $mimeType;
                                    	}
                                    

                                    where $part is the header of that part of the message.

                                    Am I totally off base? Or should that work?

                                    Am I even asking the right questions? Am I making sense? Can I clarify anything?

                                    I appreciate any direction and/or feedback you can offer.

                                        function getBody($mid) {
                                            global $cfg;
                                    
                                        if ($cfg->isHtmlThreadEnabled()) {
                                            if ($body=$this->getPart($mid, 'text/html', $this->charset)) {
                                                //Cleanup the html.
                                                $body = (trim($body, " <>br/\t\n\r"))
                                                    ? Format::safe_html($body)
                                                    : '--';
                                            }
                                            elseif ($body=$this->getPart($mid, 'text/plain', $this->charset)) {
                                                $body = trim($body)
                                                    ? sprintf('<pre>%s</pre>',
                                                        Format::htmlchars($body))
                                                    : '--';
                                            }
                                        }
                                        else {
                                            if (!($body=$this->getPart($mid, 'text/plain', $this->charset))) {
                                                if ($body=$this->getPart($mid, 'text/html', $this->charset)) {
                                                    $body = Format::html2text(Format::safe_html($body), 100, false);
                                                }
                                            }
                                            $body = trim($body) ? $body : '--';
                                        }
                                        return $body;
                                    }

                                      I would appreciate a review. I think I have worked through the function and have converted it. I haven't tested it yet because I have a number of other functions yet to finish going through and converting, but on its own does this look like it's going to work okay?

                                      Here's the function:

                                      //search for specific mime type parts....encoding is the desired encoding.
                                      function getPart($mid, $mimeType, $encoding=false, $struct=null, $partNumber=false) {
                                      	try {
                                      		$mailmsg = $this->zmail->getMessage($mid);
                                      		$text = null;
                                      		if (!$part && $mid) {
                                      			if ($mailmsg->isMultipart()) {
                                      				$partNumber = null; //(re)sets $partNumber to null
                                      				foreach (new RecursiveIteratorIterator($this->zmail->getMessage($mid)) as $part) {
                                      					if(strcasecmp($mimeType, getMimeType($part))==0 //the part returned the predefined $mimeType
                                      						&& (!isset($part->contentdisposition) //AND no contentdisposition is set
                                      						||  !$part->getHeaderField('Content-Disposition', 'filename'))) { //OR there is no attached filename
                                      						$partNumber = $partNumber?$partNumber:1; //if there's a part number use it, otherwise use 1
                                      						if ($text = $mailmsg->getPart($partNumber)->getContent()) {
                                      							$encoding = null; //(re)set encoding to null
                                      							$charset=null; //(re)set $charset as null
                                      							if (isset($part->contenttransferencoding)) { //does the encoding field exist
                                      								$encoding = $part->contenttransferencoding; //get the encoding type
                                      								if ($encoding //if $encoding is NOT null
                                      									&& ($encoding == 'base64' || $encoding == 'quoted-printable')) { //AND if $encoding is either base64 or qp
                                      									$text = $this->decode($text, $encoding); //decode the content accordingly
                                      									$charset = $part->getHeaderField('Content-Type', 'charset'); //determine the $charset to be used
                                      									$text = $this->mime_encode($text, $charset, $encoding); //mime encode the string $text (the decoded content of $partnumber) using the $charset and $encoding method found in the message $part
                                      								}
                                      							} //end if encoding field exists
                                      						} //end if the content of the message can be retrieved (by $partNumber) of the specified message (by $mid)
                                      					} //end if the MIME Type is returned and there is no attachment
                                      					$partNumber++; //increase $partNumber by 1
                                      					return $text;
                                      				} // end foreach going through each mail part
                                      			} // end if multipart message
                                      			else {
                                      				if(strcasecmp($mimeType, getMimeType($mailmsg))==0 //the part returned the predefined $mimeType
                                      					&& (!isset($mailmsg->contentdisposition) //AND no contentdisposition is set
                                      					||  !$mailmsg->getHeaderField('Content-Disposition', 'filename'))) { //OR there is no attached filename
                                      					if ($text = $mailmsg->getContent()) {
                                      						$encoding = null; //(re)set encoding to null
                                      						$charset=null; //(re)set $charset as null
                                      						if (isset($mailmsg->contenttransferencoding)) { //does the encoding field exist
                                      							$encoding = $mailmsg->contenttransferencoding; //get the encoding type
                                      							if ($encoding //if $encoding is NOT null
                                      								&& ($encoding == 'base64' || $encoding == 'quoted-printable')) { //AND if $encoding is either base64 or qp
                                      								$text = $this->decode($text, $encoding); //decode the content accordingly
                                      								$charset = $mailmsg->getHeaderField('Content-Type', 'charset'); //determine the $charset to be used
                                      								$text = $this->mime_encode($text, $charset, $encoding); //mime encode the string $text (the decoded content of $partnumber) using the $charset and $encoding method found in the message $part
                                      							}
                                      						} //end if encoding field exists
                                      					} //end if the content of the message can be retrieved (by $partNumber) of the specified message (by $mid)
                                      				}//end if the MIME Type is returned and there is no attachment
                                      				return $text;
                                      			} //end if NOT multipart message
                                      			$part=null; //(re)set $text to null
                                      		} // end if $part is null and $mid is not null
                                      	} //end try
                                      	catch (\Exception $ex) {
                                      		$this->getLastError($ex);
                                      	}
                                      	/* This segment is from the original class.mailfetch.php and has not yet been translated to Zend\Mail
                                      	//Do recursive search
                                      	$text='';
                                      	if($struct && $struct->parts) {
                                      		while(list($i, $substruct) = each($struct->parts)) {
                                      			if($partNumber)
                                      				$prefix = $partNumber . '.';
                                      			if(($result=$this->getPart($mid, $mimeType, $encoding, $substruct, $prefix.($i+1))))
                                      				$text.=$result;
                                      		} //end while
                                      	}// end if
                                      	return $text;
                                      	//*/
                                      }
                                      

                                      And the functions referred to:

                                      function getMimeType($part) {
                                      	$maintype = strtok((strtok($part->contenttype, ';')), '/'); //breaks MIME Type into two parts, main and sub
                                      	$subtype = strtok('/');
                                      		$mimetype = array('TEXT', 'MULTIPART', 'MESSAGE', 'APPLICATION', 'AUDIO', 'IMAGE', 'VIDEO', 'OTHER');
                                      	if(!$part || !$subtype) {
                                      		return 'TEXT/PLAIN';
                                      	} //end if either $part or $subtype is null use text/plain
                                      		return $maintype.'/'.$subtype;
                                      } //end function getMimeType
                                      
                                      function mime_encode($text, $charset=null, $encoding='utf-8') {
                                      	return Format::encode($text, $charset, $encoding);
                                      } //end function mime_encode
                                      
                                      function decode($text, $encoding) {
                                      	switch($encoding) {
                                      		case 'utf-8': //Convert an 8bit string to a quoted-printable string
                                      			$text = quoted_printable_encode($text);
                                      			break;
                                      		case 'binary': //Convert an 8bit string to a base64 string
                                      			$text = base64_encode($text);
                                      			break;
                                      		case 'base64': //Decode BASE64 encoded text
                                      			$text = base64_decode($text);
                                      			break;
                                      		case 'quoted-printable': //Convert a quoted-printable string to an 8 bit string
                                      			$text = quoted_printable_decode($text);
                                      			break;
                                      	} //end switch-case for encoding $text with the proper $encoding type
                                      	return $text;
                                      } //end function decode
                                      

                                      The part I am most concerned about now is the recursive search. Zend\Mail has a RecursiveIteratorTerator for searching through each and every part:

                                      foreach (new RecursiveIteratorIterator($this->zmail->getMessage($mid)) as $part) {
                                          // Stuff to each $part here
                                      }
                                      

                                      I used this to cycle through the parts of the message since there isn't an equivalent to imap_fetchstructure in Zend\Mail, but to return the $text it breaks out of the foreach loop.... How would I send $text back to the calling function without breaking the loop? I thought about using "continue" but don't fully understand it and am not sure it will work.

                                      Thanks.

                                      (Oh... and if you hadn't noticed, I have modified not only how I ask questions, but my coding to match some of the suggested formats from your signature links. 😃 I'm trying to be a better coder and poster.)

                                        13 days later

                                        I'm going to go ahead and mark this one as Resolved. I have finished going through the script and replacing the imap c-client functions with Zend\Mail functions. It's not causing the system to crash and did generate a ticket, so for the moment, although a few of my questions in this thread went unanswered, the overall issue is resolved (sort of for the time-being).

                                          Write a Reply...