[RESOLVED] Modifying osTicket to use Zend\Mail instead of IMAP functions - Page 2
Page 2 of 2 FirstFirst 12
Results 16 to 21 of 21

Thread: [RESOLVED] Modifying osTicket to use Zend\Mail instead of IMAP functions

  1. #16
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    40
    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.)

    PHP Code:
        //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==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:

    PHP 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;
        } 
    PHP Code:
        /**
         * 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;
        } 
    PHP Code:
        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;
        } 
    PHP Code:
        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?

  2. #17
    Pedantic Curmudgeon Weedpacket's Avatar
    Join Date
    Aug 2002
    Location
    General Systems Vehicle "Thrilled To Be Here"
    Posts
    21,885
    By the code in your point #4, it is the body content of one part of the message.
    THERE IS AS YET INSUFFICIENT DATA FOR A MEANINGFUL ANSWER
    FAQs! FAQs! FAQs! Most forums have them!
    Search - Debugging 101 - Collected Solutions - General Guidelines - Getting help at all

  3. #18
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    40
    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:

    PHP 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:

    PHP 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.


    PHP Code:
        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), 100false);
                    }
                }
                
    $body trim($body) ? $body '--';
            }
            return 
    $body;
        } 

  4. #19
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    40
    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:
    PHP Code:
    //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($mimeTypegetMimeType($part))==//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($mimeTypegetMimeType($mailmsg))==//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:
    PHP Code:
    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 
    PHP Code:
    function mime_encode($text$charset=null$encoding='utf-8') {
        return 
    Format::encode($text$charset$encoding);
    //end function mime_encode 
    PHP Code:
    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:

    PHP Code:
    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.)

  5. #20
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    40
    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).

  6. #21
    Settled 4 red convertible dalecosp's Avatar
    Join Date
    Jul 2002
    Location
    Accelerating Windows at 9.81 m/s....
    Posts
    7,715
    Quote Originally Posted by mittra View Post
    (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.)
    Quote Originally Posted by mittra View Post
    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).
    Kudos! (for both items )
    /!!\ mysql_ is deprecated --- don't use it! Tell your hosting company you will switch if they don't upgrade! /!!!\ ereg() is deprecated --- don't use it!

    dalecosp "God doesn't play dice." --- Einstein "Perl is hardly a paragon of beautiful syntax." --- Weedpacket

    Getting Help at All --- Collected Solutions to Common Problems --- Debugging 101 --- Unanswered Posts --- OMBE: Office Machines, Business Equipment

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •