<?php
ini_set('display_errors', 1);
define('ATTACHMENTS_DIR', 'emails/attachments');

class EmailDaemon
{

    private $imap;

    private $db;

    public $users;

    private $mailbox;

    public $emails;

    public $id;

    public $emailAdress;

    public $emailType;

    public $emailText;

    public $savedId;

    public $modules = array(
            'Accounts',
            'Contacts'
    );
    
    public $relationToSave; 

    public function __construct ()
    {
        require_once ('emails/ImapMailbox.php');
        
        $this->db = $GLOBALS['db'];
    }

    public function getUsers ()
    {
        $usersBean = new User();
        $this->users = $usersBean->get_full_list('', 
                "deleted=0 and status='Active' and google_login is not null and google_password is not null and id='2e72f487-d92b-954e-f50c-528b10ce81c9'");
    }

    public function setConnection ($host, $login, $password, $box)
    {
        $this->mailbox = new ImapMailbox($host, $login, $password, 
                ATTACHMENTS_DIR, 'utf-8');
    }

    public function generateEmailID ($header)
    {
        return md5(
                $header[0]->udate . "" . $header[0]->date . "" . $header[0]->to .
                         "" . $header[0]->subject);
    }

    public function isExistEmail ($id)
    {
        $emailsBean = new Email();
        $email = $emailsBean->get_full_list('', "message_id='" . $id . "'");
        
        if (count($email) > 0) {
            return true;
        } else {
            return false;
        }
    }
    // pobiera ID emaili na poczcie
    public function getEmailsId ($date)
    {
        if ($date != '' && $date != '0000-00-00 00:00:00') {
            $da = date("d M Y", strtotime($date) - 86400);
        } else {
            $da = date("d M Y", strtotime("-1 day"));
        }
        $this->emails = $this->mailbox->searchMailBox("SINCE \"$da\"");
    }
    
    // pobiera całego emaila
    public function getFullEmailData ($email)
    {
        return $this->mailbox->getMail($email);
    }
    
    // tylko nagłowek emaila
    public function getEmailHeader ($email)
    {
        return $this->mailbox->getMailInfo($email);
    }
    
    // ustawia flagę jako nieprzeczytany
    public function setNotReadedFlag ($email)
    {
        $this->mailbox->markMailAsUnread($email);
    }

    public function getUserPassword ($id)
    {
        $r = $this->db->query(
                "select CAST(AES_DECRYPT(google_password, 'jakistamhash123') as CHAR)
AS google_password FROM users where id='" . $id . "'");
        $dane = $this->db->fetchByAssoc($r);
        return $dane['google_password'];
    }

    public function setEmailAdress ($user)
    {
        if ($user->google_address == '') {
            $this->emailAdress = $user->google_login;
        } else {
            $this->emailAdress = $user->google_address;
        }
    }

    public function getNewEmails ()
    {
        $this->getUsers();
        foreach ($this->users as $user) {
            
            if ($user->mail_server == '') {
                $server = '{imap.gmail.com:993/imap/ssl}[Gmail]/Wszystkie';
            } else {
                $server = $user->mail_server;
            }
            
            $this->setEmailAdress($user);
            
            $this->setConnection($server, $user->google_login, 
                    $this->getUserPassword($user->id));
            if ($this->mailbox->connected != false) {
                $this->getEmailsId($user->google_last_login);
                $this->checkEmails();
            } else {
                echo 'coś złego';
            }
            break;
        }
    }

    public function checkEmails ()
    {
        foreach ($this->emails as $email) {
            
            $header = $this->getEmailHeader($email);
            
            $this->id = $this->generateEmailID($header);
            
            if ($this->isExistEmail($this->id) != true) {
                $this->SaveFreshEmail($email);
                $this->setNotReadedFlag($email);
            }
        }
    }

    public function saveEmail ($email)
    {
        $e = new Email();
        $e->message_id = $this->id;
        $e->type = $this->emailType;
        $e->status = 'archived';
        $e->date_send=$email->date;
        $e->intent = 'read';
        $e->flagged = 0;
        $e->reply_to_status = 0;
        $e->name = $email->subject;
        $e->description = $email->textPlain;
        $e->description_html = $email->textHtml;
        $e->from_addr_name = $email->fromAddress;
        $to = '';
        foreach ($email->to as $key => $val) {
            $to .= $key;
        }
        $e->to_addrs_names = $to;
        $this->savedId = $e->save();
     
    }

    public function searchRelations ($email)
    {
        $this->relationToSave=array();
        foreach ($this->modules as $module) {
            $ss = new SugarEmailAddress();
            if ($this->emailType == 'out') {
                foreach ($email->to as $key => $val) {
                   $this->relationToSave[$module]= $ss->getRelatedId($key, $module);
                }
            } else {
          
                   $this->relationToSave[$module]= $ss->getRelatedId($email->fromAddress, $module);
                
            }
        }
    }

    public function relationSqlSave($parent_id,$module){
        $query=" INSERT into email_id_rel VALUES(
                '".create_guid()."',
                '".$this->savedId."',
                '".$parent_id."',
                '".$module."',
                '0'        
                )";
   
        $this->db->query($query);
    }
    
    public function saveRelations ()
    {

        foreach ($this->relationToSave as $module=>$key){
            foreach ($key as $relation_id=>$val2){

                if($module=='Contacts'){
                    if($val2!=false){
                        $this->relationSqlSave($val2,$module);
                    }
                    $a = new Contact();
                    $a->retrieve($val2);
                    if($a->account_id!=''){
                        $this->relationSqlSave($a->account_id,'Accounts');
                    }
                } else {
                    if($val2!=false){
                        $this->relationSqlSave($val2,$module);
                    }
                
                } 
            }
        }
    }

    public function SaveFreshEmail ($email)
    {
        $email = $this->getFullEmailData($email);

        $this->setEmailType($email);
        $this->searchRelations($email);
        $this->saveEmail($email);
        $this->saveRelations();
        $this->saveAttachments($email);
    }

    public function setEmailType ($email)
    {
        if ($email->fromAddress == $this->emailAdress) {
            // wychodzący
            $this->emailType = 'out';
        } else {
            // przychodzący
            $this->emailType = 'inbound';
        }
    }

    public function setEmailText ($email)
    {
        $this->emailText = $email->textHtml;
    }
    
    public function saveAttachments($email){
        foreach ($email->attachments as &$value) {

            $note=$this->saveAttachment($value);
            substr($value->filePath,strlen(ATTACHMENTS_DIR.'/')).'<br>';
            rename($value->filePath, '/var/www/html/crm/upload/'.$note);
           // unlink($value->filePath);

        }
    }
    
    public function saveAttachment($value){
        $n = new Note();

        $n->name=$value->name;
        $n->filename=$value->name;
        $n->parent_type='Emails';
        $n->parent_id=$this->savedId;
        return $n->save();
    }
}

echo "<pre>";
$ed = new EmailDaemon();
$ed->getNewEmails();
// $ed->getEmailsId();

?>