<?php
require_once 'modules/clients/models/user.php';
require_once 'newedge/classes/NE_MailGateway.php';
require_once 'modules/admin/models/ServicePlugin.php';
// require_once 'modules/clients/models/Client_EventLog.php';
require_once 'modules/support/models/AutoresponderTemplateGateway.php';
require_once 'modules/clients/models/UserPackageGateway.php';
require_once 'modules/admin/models/Package.php';

/**
* @package Plugins
*/
class PluginAutomailer extends ServicePlugin
{
    function getVariables()
    {
        $variables = array(
            /*T*/'Plugin Name'/*/T*/   => array(
                'type'          => 'hidden',
                'description'   => /*T*/''/*/T*/,
                'value'         => /*T*/'Auto Mailer'/*/T*/,
            ),
            /*T*/'Enabled'/*/T*/       => array(
                'type'          => 'yesno',
                'description'   => /*T*/'When enabled, email customers a set number of days before/after a given event.<br><b>NOTE:</b> Only run once per day to avoid duplicate E-mails.'/*/T*/,
                'value'         => '0',
            ),
            /*T*/'Events'/*/T*/       => array(
                'type'        => 'custom',
                'description' => /*T*/'List of the events that will send emails to your customers.<br>The email templates are of type \'Custom E-Mails\' and you can add more on <a href="index.php?fuse=admin&view=Admin_Emails"><b><u>E-Mail - Templates</u></b></a> and then select \'Custom E-Mails\''/*/T*/,
                'method'      => 'eventsGrid',    // This property only works for 'type' => 'custom'
                'value'       => ''
            ),
            /*T*/'Summary E-mail'/*/T*/     => array(
                'type'          => 'smallTextarea',
                'description'   => /*T*/'E-mail addresses to which a summary of each service run will be sent.  (Leave blank if you do not wish to receive a summary)'/*/T*/,
                'value'         => '',
            ),
            /*T*/'Summary E-mail Subject'/*/T*/     => array(
                'type'          => 'text',
                'description'   => /*T*/'E-mail subject for the summary notification.'/*/T*/,
                'value'         => 'Auto Mailer Summary',
            ),
            /*T*/'Run schedule - Minute'/*/T*/  => array(
                'type'          => 'text',
                'description'   => /*T*/'Enter number, range, list or steps'/*/T*/,
                'value'         => '0',
                'helpid'        => '8',
            ),
            /*T*/'Run schedule - Hour'/*/T*/  => array(
                'type'          => 'text',
                'description'   => /*T*/'Enter number, range, list or steps'/*/T*/,
                'value'         => '0',
            ),
            /*T*/'Run schedule - Day'/*/T*/  => array(
                'type'          => 'text',
                'description'   => /*T*/'Enter number, range, list or steps'/*/T*/,
                'value'         => '*',
            ),
            /*T*/'Run schedule - Month'/*/T*/  => array(
                'type'          => 'text',
                'description'   => /*T*/'Enter number, range, list or steps'/*/T*/,
                'value'         => '*',
            ),
            /*T*/'Run schedule - Day of the week'/*/T*/  => array(
                'type'          => 'text',
                'description'   => /*T*/'Enter number in range 0-6 (0 is Sunday) or a 3 letter shortcut (e.g. sun)'/*/T*/,
                'value'         => '*',
            ),
        );
    
        return $variables;
    }
    
    function execute()
    {
        $messages = array();
        $numCustomers = 0;
        $mailGateway = new NE_MailGateway();
        
        // Summary Variables
        $summaryNames = array();
        $summaryErrors = array();
        
        // Required Services
        $requiredServices = array();
        
        /*
        Get the params:
          - Email template (from custom emails. will display the template name, but will use the template id)
          - Number of days before/after the date (an integer number)
          - Event:
              'After Account Activated'
              'After Account Canceled'
              'After Package Activated'
              'After Package Canceled'
              'Before Domain Expires'
          
          For example:
            37 (Are you enjoying our application?)      $AutomailerRule['templateid']
            5                                           $AutomailerRule['days']
            After Account Activated                     $AutomailerRule['event']
        */
        $AutomailerRules = @htmlspecialchars_decode($this->settings->get('plugin_automailer_Events'), ENT_QUOTES);
        
        if($AutomailerRules == ''){
            array_unshift($messages, $this->user->lang('%s customer(s) were notified.', $numCustomers));
            return $messages;
        }
        $AutomailerRules = unserialize($AutomailerRules);
        if(!is_array($AutomailerRules)){
            array_unshift($messages, $this->user->lang('%s customer(s) were notified.', $numCustomers));
            return $messages;
        }
        
        //Get the customers for each case:
        foreach($AutomailerRules as $AutomailerRule){
            switch($AutomailerRule['event']){
                // Before Dates
                case 'Before Domain Expires':
                    $dateTimeStamp = mktime(0, 0, 0, date("m"), date("d") + $AutomailerRule['days'], date("Y"));
                    break;
                
                // After Dates
                case 'After Account Activated':
                case 'After Account Canceled':
                case 'After Package Activated':
                case 'After Package Canceled':
                default:
                    $dateTimeStamp = mktime(0, 0, 0, date("m"), date("d") - $AutomailerRule['days'], date("Y"));
                    break;
            }
            
            switch($AutomailerRule['event']){
                case 'After Account Activated':
                    $query = "SELECT u.`id` AS customer_id "
                            ."FROM `users` u "
                            ."WHERE u.`groupid` = 1 "
                            ."AND (UNIX_TIMESTAMP(u.`dateActivated`) >= ? )"
                            ."AND (UNIX_TIMESTAMP(u.`dateActivated`) < ? )";
                    $result = $this->db->query($query, $dateTimeStamp, $dateTimeStamp + 86400);
                    break;
                case 'After Account Canceled':  // Includes Canceled and Inactive Users
                    $query = "SELECT u.`id` AS customer_id "
                            ."FROM `users` u "
                            ."JOIN `user_customuserfields` ucuf "
                            ."ON u.`id` = ucuf.`userid` "
                            ."WHERE u.`groupid` = 1 "
                            ."AND u.`status` IN (".USER_STATUS_INACTIVE.", ".USER_STATUS_CANCELLED.") "
                            ."AND ucuf.`customid` IN ( "
                            ."SELECT cuf.`id` "
                            ."FROM `customuserfields` cuf "
                            ."WHERE cuf.`name` = 'Last Status Date' "
                            ."AND cuf.`type` = 52) "
                            ."AND (UNIX_TIMESTAMP(ucuf.`value`) >= ?) "
                            ."AND (UNIX_TIMESTAMP(ucuf.`value`) < ?) ";
                    $result = $this->db->query($query, $dateTimeStamp, $dateTimeStamp + 86400);
                    break;
                case 'After Package Activated':
                    $query = "SELECT DISTINCT u.`id` AS customer_id, d.`id` AS package_id "
                            ."FROM `users` u "
                            ."JOIN `domains` d "
                            ."ON u.`id` = d.`CustomerID` "
                            ."WHERE (UNIX_TIMESTAMP(d.`dateActivated`) >= ?) "
                            ."AND (UNIX_TIMESTAMP(d.`dateActivated`) < ?) ";
                    $result = $this->db->query($query, $dateTimeStamp, $dateTimeStamp + 86400);
                    break;
                case 'After Package Canceled':  // Includes Canceled, Suspended, and Expired Packages
                    $query = "SELECT DISTINCT u.`id` AS customer_id, d.`id` AS package_id "
                            ."FROM `users` u "
                            ."JOIN `domains` d "
                            ."ON u.`id` = d.`CustomerID` "
                            ."JOIN `object_customField` ocf "
                            ."ON d.`id` = ocf.`objectid` "
                            ."WHERE d.`status` IN (".PACKAGE_STATUS_SUSPENDED.", ".PACKAGE_STATUS_CANCELLED.", ".PACKAGE_STATUS_EXPIRED.") "
                            ."AND ocf.`customFieldId` IN ( "
                            ."SELECT cf.`id` "
                            ."FROM `customField` cf "
                            ."WHERE cf.`name` = 'Last Status Date' "
                            ."AND cf.`groupId` = 2) "
                            ."AND (UNIX_TIMESTAMP(ocf.`value`) >= ?) "
                            ."AND (UNIX_TIMESTAMP(ocf.`value`) < ?) ";
                    $result = $this->db->query($query, $dateTimeStamp, $dateTimeStamp + 86400);
                    break;
                case 'Before Domain Expires':  // Includes Active and Pending Cancellation Packages
                    /*
                    // Query based on the "nextbilldate" field of the "recurringfee" table. Not tested yet
                    $query = "SELECT DISTINCT u.`id` AS customer_id, d.`id` AS package_id "
                            ."FROM `users` u "
                            ."JOIN `domains` d "
                            ."ON u.`id` = d.`CustomerID` "
                            ."JOIN `recurringfee` rf "
                            ."ON d.`id` = rf.`appliestoid` "
                            ."AND rf.`billingtypeid` = -1 "
                            ."AND rf.`recurring` = 1 "
                            ."WHERE d.`status` IN (".PACKAGE_STATUS_ACTIVE.", ".PACKAGE_STATUS_PENDINGCANCELLATION.") "
                            ."AND d.`Plan` IN ( "
                            ."SELECT pa.`id` "
                            ."FROM `package` pa "
                            ."WHERE pa.`planid` IN ( "
                            ."SELECT pr.`id` "
                            ."FROM `promotion` pr "
                            ."WHERE pr.`type` = 3)) "
                            ."AND (UNIX_TIMESTAMP(rf.`nextbilldate`) >= ?) "
                            ."AND (UNIX_TIMESTAMP(rf.`nextbilldate`) < ?) ";
                    */
                    
                    // Query based on the custom field "Expiration Date".
                    $query = "SELECT DISTINCT u.`id` AS customer_id, d.`id` AS package_id "
                            ."FROM `users` u "
                            ."JOIN `domains` d "
                            ."ON u.`id` = d.`CustomerID` "
                            ."JOIN `object_customField` ocf "
                            ."ON d.`id` = ocf.`objectid` "
                            ."WHERE d.`status` IN (".PACKAGE_STATUS_ACTIVE.", ".PACKAGE_STATUS_PENDINGCANCELLATION.") "
                            ."AND d.`Plan` IN ( "
                            ."SELECT pa.`id` "
                            ."FROM `package` pa "
                            ."WHERE pa.`planid` IN ( "
                            ."SELECT pr.`id` "
                            ."FROM `promotion` pr "
                            ."WHERE pr.`type` = 3)) "
                            ."AND ocf.`customFieldId` IN ( "
                            ."SELECT cf.`id` "
                            ."FROM `customField` cf "
                            ."WHERE cf.`name` = 'Expiration Date' "
                            ."AND cf.`groupId` = 2 "
                            ."AND cf.`subGroupId` = 3) "
                            ."AND (UNIX_TIMESTAMP(ocf.`value`) >= ?) "
                            ."AND (UNIX_TIMESTAMP(ocf.`value`) < ?) ";
                    $result = $this->db->query($query, $dateTimeStamp, $dateTimeStamp + 86400);
                    
                    // Requires "Domain Updater" Service
                    $requiredServices[] = 'domainupdater';
                    break;
                default:
                    continue;
                    break;
            }
            
            // If find customers:
            if($result->getNumRows()){
                // - Setup the customer email template
                $templategateway = new AutoresponderTemplateGateway();
                $template = $templategateway->getAutoresponder($AutomailerRule['templateid']);
                
                if($template->getId() != $AutomailerRule['templateid']){
                    $summaryErrors[] = $AutomailerRule['templateid'];
                }else{
                    $strEmailArrT = $template->getContents(true);
                    $strSubjectEmailT = $template->getSubject();
                    $strNameEmailT = $template->getName();
                    
                    // - For each customer:
                    while($row = $result->fetch()){
                        // * Instantiate the user
                        $user = new User($row['customer_id']);
                        
                        // * Create a copy of the email template
                        $strEmailArr     = $strEmailArrT;
                        $strSubjectEmail = $strSubjectEmailT;
                        
                        // * Parse a copy of the email template and the email subject template
                        if(isset($row['package_id'])){
                            $userPackage = new UserPackage((int)$row['package_id']);
                            $package = new Package($userPackage->Plan);
                            
                            $gateway = new UserPackageGateway($this->user);
                            
                            $strSubjectEmail = $gateway->_replaceTags1($strSubjectEmail,$user,$package);
                            $strEmailArr = array(
                                'HTML'      => $gateway->_replaceTags1($strEmailArr['HTML'], $user, $package),
                                'plainText' => $gateway->_replaceTags1($strEmailArr['plainText'],$user,$package)
                            );
                            
                            $gateway->_replaceTagsByType($userPackage,$user,$strEmailArr, $strSubjectEmail);
                        }else{
                            $gateway = new UserPackageGateway($this->user);
                            
                            $strSubjectEmail = $gateway->_replaceTags1($strSubjectEmail,$user);
                            $strEmailArr = array(
                                'HTML'      => $gateway->_replaceTags1($strEmailArr['HTML'], $user),
                                'plainText' => $gateway->_replaceTags1($strEmailArr['plainText'],$user)
                            );
                        }
                        
                        // * Send a parsed copy of the email template to the customer
                        $mailerResult = $mailGateway->mailMessage(
                            $strEmailArr,
                            $this->settings->get('Support E-mail'),
                            $this->settings->get('Company Name'),
                            $row['customer_id'],
                            "",
                            $strSubjectEmail,
                            3,
                            0,
                            'notifications',
                            '',
                            '',
                            $user->isHTMLMails()? MAILGATEWAY_CONTENTTYPE_HTML : MAILGATEWAY_CONTENTTYPE_PLAINTEXT
                        );
                        
                        if(!is_a($mailerResult, 'NE_Error')){
// log the email was sent

/*
$clientLog = Client_EventLog::newInstance($row['customer_id'], $row['customer_id'], CLIENT_EVENTLOG_SENTUPCOMINGCHARGENOTIFICATION, $this->user->getId(), $batchAmount);
$this->logger->addEventLog($clientLog);
*/
                        }
                        
                        // * Add Customer to summary
                        $summaryNames[$strNameEmailT][$AutomailerRule['days']][$AutomailerRule['event']][] = $user->getFullName().((isset($row['package_id']))? ', package: '.$row['package_id'] : '');
                        $numCustomers++;
                    }
                }
            }
        }
        
        if($this->settings->get('plugin_automailer_Summary E-mail') != ""){
            $summaryEmail = '';
            if(count($requiredServices) > 0){
                $summaryEmailRequirementsIssues = array();
                $summaryEmailRequirementsTime = array();
                foreach($requiredServices as $requiredService){
                    // Get the Service name
                    $requiredServiceName = $this->settings->get('plugin_'.$requiredService.'_Plugin Name');
                    if(!$requiredServiceName){
                        $requiredServiceName = $requiredService;
                    }
                    
                    // Verify if the Service is enabled
                    if(!$this->settings->get('plugin_'.$requiredService.'_Enabled')){
                        $summaryEmailRequirementsIssues[] = $this->user->lang("The service %s is not enabled", $requiredServiceName);
                    }else{
                        // Verify the last time the Service ran
                        $requiredServiceInfo = $this->settings->get('service_'.$requiredService.'_info');
                        if(!$requiredServiceInfo){
                            $summaryEmailRequirementsIssues[] = $this->user->lang("The service %s do not have information about its last run.", $requiredServiceName);
                        }else{
                            $requiredServiceInfo = unserialize($requiredServiceInfo);
                            if(!is_array($requiredServiceInfo) || !isset($requiredServiceInfo['time'])){
                                $summaryEmailRequirementsIssues[] = $this->user->lang("The information of the service %s about its last run, seems to be corrupted.", $requiredServiceName);
                            }else{
                                $summaryEmailRequirementsTime[$requiredServiceName] = $requiredServiceInfo['time'];
                            }
                        }
                    }
                }
                if (count($summaryEmailRequirementsIssues) > 0) {
                    $summaryEmail .= $this->user->lang("Auto Mailer has detected issues with some of the required Services for the Events selected. Please take a look").":\n";
                    
                    foreach($summaryEmailRequirementsIssues as $summaryEmailRequirementsIssue){
                        $summaryEmail .= " - ".$summaryEmailRequirementsIssue."\n";
                    }
                    $summaryEmail .= "\n";
                }
                if (count($summaryEmailRequirementsTime) > 0) {
                    $summaryEmail .= $this->user->lang("Last execution of the required Services for the Events selected, were").":\n";
                    
                    foreach($summaryEmailRequirementsTime as $summaryEmailRequirementName => $summaryEmailRequirementTime){
                        $summaryEmail .= " - ".$summaryEmailRequirementName.". Executed on: ".$summaryEmailRequirementTime."\n";
                    }
                    $summaryEmail .= "\n";
                }
            }

            
            if (count($summaryErrors) > 0) {
                $summaryEmail .= $this->user->lang("Auto Mailer has not been able to find the E-mail Templates with the following ids. Please take a look").":\n";
                
                foreach($summaryErrors as $summaryError){
                    $summaryEmail .= " - ".$summaryError."\n";
                }
                $summaryEmail .= "\n";
            }
            
            if(count($summaryNames) > 0){
                $summaryEmail .= $this->user->lang("Auto Mailer has emailed the following events to the following customers").":\n";
                
                foreach($summaryNames as $emailTemplateName => $summaryDays){
                    foreach($summaryDays as $days => $summaryEvent){
                        foreach($summaryEvent as $event => $summaryCustomers){
                            $summaryEmail .= "\n".'"'.$emailTemplateName.'" emailed '.$days.' days '.$event.":\n";
                            
                            foreach($summaryCustomers as $summaryCustomer){
                                $summaryEmail .= " - ".$summaryCustomer."\n";
                            }
                        }
                    }
                }
            }
            
            if($summaryEmail != ''){
                $destinataries = explode("\r\n", $this->settings->get('plugin_automailer_Summary E-mail'));
                
                foreach($destinataries as $destinatary){
                    $mailGateway->mailMessageEmail(
                        $summaryEmail,
                        $this->settings->get('Support E-mail'),
                        $this->settings->get('Company Name'),
                        $destinatary,
                        "",
                        $this->settings->get('plugin_automailer_Summary E-mail Subject')
                    );
                }
            }
        }
        
        array_unshift($messages, $this->user->lang('%s customer(s) were notified.', $numCustomers));
        return $messages;
    }
    
    /**
     *
     * @param type $tplView 
     */
    function eventsGrid($tplView,$settingConfig,$user)
    {
        //here we create our stores
        //and just pass them to our own template to build our grid
        
        $tplView->settingId = $settingConfig['id']; //needs to have the setting id here
        
        
        $settingConfig['value'] = @htmlspecialchars_decode($settingConfig['value'], ENT_QUOTES);
        $gridDataArray = array();
        if($settingConfig['value'] != ''){
            $settingConfig['value'] = unserialize($settingConfig['value']);
            foreach($settingConfig['value'] AS $gridRow){
                //you need to store template name with the setting config
                $gridDataArray[] = "['".implode("', '", $gridRow)."']";
            }
        }
        $tplView->gridData = "[".implode(", ", $gridDataArray)."]";
        
        $storeArray = array();
        $fieldValues = $this->getEmailTemplates();
        if(is_array($fieldValues)){
            foreach($fieldValues as $fieldValue){
                $storeArray[] = "['".implode("', '", $fieldValue)."']";
            }
        }
        $tplView->emailTemplates = "[".implode(", ", $storeArray)."]";
        
        return $tplView->fetch('/plugins/services/automailer/PluginAutomailer.tpl.php');
    }
    
    function getEmailTemplates()
    {
        $values = array();
        
        $query = "SELECT `id`, `name` "
                ."FROM `autoresponders` "
                ."WHERE `type` = 2 ";
        $result = $this->db->query($query);
        
        while(list($templateid, $templatename) = $result->fetch()){
            $values[] = array($templateid, $templatename);
        }
        
        return $values;
    }
}
?>
