[RESOLVED] Modifying osTicket to use Zend\Mail instead of IMAP functions
Page 1 of 2 12 LastLast
Results 1 to 15 of 21

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

  1. #1
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    37

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

    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 (class.mailfetch.txt) and the second is the script as I modified it (class.zmailfetch.txt). 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):

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

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

  2. #2
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    37
    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

  3. #3
    Settled 4 red convertible dalecosp's Avatar
    Join Date
    Jul 2002
    Location
    Accelerating Windows at 9.81 m/s....
    Posts
    7,697
    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?
    /!!\ 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

  4. #4
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    37
    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?

  5. #5
    Senior Member Derokorian's Avatar
    Join Date
    Apr 2011
    Location
    Denver
    Posts
    1,769
    I would use PHPMailer if I were asked to do that.

    Also, 'Sup Loveland!'
    Sadly, nobody codes for anyone on this forum. People taste your dishes and tell you what is missing, but they don't cook for you. ~anoopmail
    I'd rather be a comma, then a full stop.
    User Authentication in PHP with MySQLi - Don't forget to mark threads resolved - MySQL(i) warning

  6. #6
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    37
    Quote Originally Posted by Derokorian View Post
    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?

  7. #7
    Senior Member Derokorian's Avatar
    Join Date
    Apr 2011
    Location
    Denver
    Posts
    1,769
    Oh maybe, I thought it had some retrieval functionality too. Not sure, been a long time since I tried to read mail from PHP.
    Sadly, nobody codes for anyone on this forum. People taste your dishes and tell you what is missing, but they don't cook for you. ~anoopmail
    I'd rather be a comma, then a full stop.
    User Authentication in PHP with MySQLi - Don't forget to mark threads resolved - MySQL(i) warning

  8. #8
    Pedantic Curmudgeon Weedpacket's Avatar
    Join Date
    Aug 2002
    Location
    General Systems Vehicle "Thrilled To Be Here"
    Posts
    21,855
    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.
    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

  9. #9
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    37
    Quote Originally Posted by Weedpacket View Post
    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.

  10. #10
    Pedantic Curmudgeon Weedpacket's Avatar
    Join Date
    Aug 2002
    Location
    General Systems Vehicle "Thrilled To Be Here"
    Posts
    21,855
    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/
    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

  11. #11
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    37
    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.

  12. #12
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    37
    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
    class.email.txt

    class.zmailfetch.php
    class.zmailfetch.txt

    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:
    class.mailfetch.txt

    Thanks!!

  13. #13
    Senior Member
    Join Date
    Jul 2007
    Posts
    3,642
    First off, there is no reference to Format::htmlencode in either of those 3 files.

    Anyway, this is how it works…
    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.

    PHP Code:
    class {
        
    # 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

  14. #14
    Member
    Join Date
    Jan 2014
    Location
    Loveland, CO
    Posts
    37
    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 class.format.txt.

    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.

  15. #15
    Senior Member
    Join Date
    Jul 2007
    Posts
    3,642
    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.

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
  •