Вход Регистрация
Файл: upload/module/newsletter/include/service/process.class.php
Строк: 485
<?php
/**
 * [PHPFOX_HEADER]
 */

defined('PHPFOX') or exit('NO DICE!');

/**
 *
 *
 * @copyright        [PHPFOX_COPYRIGHT]
 * @author          Raymond Benc
 * @package         Phpfox_Service
 * @version         $Id: process.class.php 4264 2012-06-13 11:03:47Z Miguel_Espinoza $
 */
class Newsletter_Service_Process extends Phpfox_Service
{
    
/**
     * Class constructor
     */
    
public function __construct()
    {
        
$this->_sTable = Phpfox::getT('newsletter');
    }

    
/**
     * Adds a new job to send the newsletter, first there is no cron jobs/tabs so this function's return
     * directs the flow of the script (refresh) to process the batches.
     * Sets the errors using Phpfox_Error::set
     * @param <type> $aVals
     * @return Int Next round to process | false on error.
     */
    
public function add($aVals, $iUser)
    {
        
// Check validations using the new method
        
        
$aForm = array(
            
'subject' => array(
                
'message' => Phpfox::getPhrase('newsletter.add_a_subject'),
                
'type' => 'string:required'
            
),
            
'total' => array(
                
'message' => Phpfox::getPhrase('newsletter.how_many_users_to_contact_per_round'),
                
'type' => 'int:required'
            
),
            
/*'type_id' => array(
                'message' => Phpfox::getPhrase('newsletter.please_choose_a_type_of_newsletter'),
                'type' => 'int:required'
            ),*/
            
'text' => array(
                
'message' => Phpfox::getPhrase('newsletter.you_need_to_write_a_message_to_send'),
                
'type' => 'string:required'
            
)
        );
        
$aVals['type_id'] = 2; // Internal newsletters are deprecated since 3.3.0 beta 1
        
$this->validator()->process($aForm, $aVals);
        if (!
Phpfox_Error::isPassed())
        {
            return 
false;
        }
        
// Phpfox::getService('ban')->checkAutomaticBan($aVals['subject'] . ' ' . $aVals['text'] . ' ' . $aVals['txtPlain']);

        
$iActive = $this->database()->select('COUNT(newsletter_id)')
            ->
from($this->_sTable)
            ->
where('state = 1')
            ->
execute('getSlaveField');

        
// insert the values in the database
        
$aInsert = array(
            
'subject' => $this->preParse()->clean($aVals['subject']),
            
'round' => 0,
            
'state' => $iActive > 0 ? 0 : 1, // 0 = not started; 1 = in progress; 2 = completed **
            
'age_from' => (int)$aVals['age_from'],
            
'age_to' => (int)$aVals['age_to'],
            
'type_id' => (int)$aVals['type_id'], // 1 = Internal ; 2 = External
            
'country_iso' => $this->preParse()->clean($aVals['country_iso']),
            
'gender' => (int)$aVals['gender'],
            
'user_group_id' => '',
            
'total' => (int)$aVals['total'],
            
'user_id' => (int)$iUser,
            
'time_stamp' => Phpfox::getTime(),
            
'archive' => (isset($aVals['archive'])) ? (int)$aVals['archive'] : 2, // 2 = delete, 1 = keep
            
'privacy' => (isset($aVals['privacy'])) ? (int)$aVals['privacy'] : 2
        
);
        
        if (isset(
$aVals['is_user_group']) && $aVals['is_user_group'] == 2)
        {
            
$aGroups = array();
            
$aUserGroups = Phpfox::getService('user.group')->get();
            if (isset(
$aVals['user_group']))
            {
                foreach (
$aUserGroups as $aUserGroup)
                {
                    if (
in_array($aUserGroup['user_group_id'], $aVals['user_group']))
                    {
                        
$aGroups[] = $aUserGroup['user_group_id'];
                    }
                }
            }
            
$aInsert['user_group_id'] = (count($aGroups) ? serialize($aGroups) : null);
        }

        
// ** when we implement the cron job this is the place to set the state differently
        
$iId = $this->database()->insert($this->_sTable, $aInsert);
        
$this->database()->insert(Phpfox::getT('newsletter_text'), array(
            
'newsletter_id' => $iId,
            
'text_plain' => $this->preParse()->clean($aVals['txtPlain']),
            
'text_html' => $aVals['text'])
        );
        
// store that we are processing a job
        
$aInsert['newsletter_id'] = $iId;
        
$aInsert['round'] = 0;
        return 
$aInsert;
    }

    
/**
     * Sends newsletters according to the round set in `newsletter`.`round`
     * Updates `newsletter`.`state` if needed.
     * user_field.newsletter_state =
     *        0 = no newsletter
     *        1 = received newsletter
     *
     * Steps:
     *        1. get the newsletter info
     *        2. get users to send with filtering by total
     *        3. send the message/email
     *        4. update the users so they dont receive it again
     *        5. update the round of the job.
     *        6. return the job id and the percentage completed
     * @param int | null $iId if null it fetches the first newsletter in progress and processes it.
     */
    
public function processJob($iId = null)
    {
        
// Step 1. Need to check the newsletter state is in progress
        
if ($iId === null)
        {
            
$this->database()->where('n.newsletter_state = 1') // in progress
            
->limit(1);
        }
        else
        {
            
$this->database()->where('n.newsletter_id = ' . (int)$iId);
        }
        
$aNewsletterInfo = $this->database()->select('*')
            ->
join(Phpfox::getT('newsletter_text'), 'nt', 'nt.newsletter_id = n.newsletter_id')
            ->
from($this->_sTable, 'n')
            ->
execute('getSlaveRow');
        if (!isset(
$aNewsletterInfo['text_plain']))
        {
            
$aNewsletterInfo['text_plain'] = null;
        }
        
// check if we have completed this job

        
if (empty($aNewsletterInfo) || (isset($aNewsletterInfo['state']) && $aNewsletterInfo['state'] == 2))
        {
            
$this->database()->update(Phpfox::getT('user_field'), array('newsletter_state' => 0), 'newsletter_state != 0');
            
            return array(
true, 100);
        }        

        
// Step 2: Get the pending members [the round field is unnecessary now]
        
$sSelect = Phpfox::getUserField() . ', un.user_id as notification, u.email, u.language_id';
        
$sWhere = 'uf.newsletter_state = 0'; // 0 = no newsletter ever sent, 1 last newsletter sent
        // filter the audience
        
if (isset($aNewsletterInfo['age_from']) && $aNewsletterInfo['age_from'] > 0)
        {
            
$iFromDate = PHPFOX_TIME  - (31556926 * $aNewsletterInfo['age_from']);
            
$sWhere .= ' AND u.birthday_search < ' . $iFromDate;
        }
        if (isset(
$aNewsletterInfo['age_to']) && $aNewsletterInfo['age_to'] > 0)
        {
            
$iToDate = PHPFOX_TIME - (31556926 * $aNewsletterInfo['age_to']);
            
$sWhere .= ' AND u.birthday_search > ' . $iToDate;
        }
        if (isset(
$aNewsletterInfo['country_iso']) && $aNewsletterInfo['country_iso'] != '')
        {
            
$sWhere .= ' AND country_iso = '' . $aNewsletterInfo['country_iso'] . '''; // no extra checks here since it comes directly from DB
        
}
        if (isset(
$aNewsletterInfo['gender']) && $aNewsletterInfo['gender'] > 0)
        {
            
$sWhere .= ' AND gender = ' . (int)$aNewsletterInfo['gender'];
        }
        if (!empty(
$aNewsletterInfo['user_group_id']))
        {
            
$aUserGroups = unserialize($aNewsletterInfo['user_group_id']);
            
            
$sWhere .= ' AND u.user_group_id IN(' . implode(',', $aUserGroups) . ')';
        }
        
        
// Should fix http://www.phpfox.com/tracker/view/8949/
        
if ($aNewsletterInfo['type_id'] == 2)
        {
            
$sWhere .= ' AND u.email != ""';
        }
        
$aUsers = $this->database()->select($sSelect)
            ->
from(Phpfox::getT('user'), 'u')
            ->
join(Phpfox::getT('user_field'), 'uf', 'uf.user_id = u.user_id')
            ->
limit((int)$aNewsletterInfo['total'])
            ->
leftjoin(Phpfox::getT('user_notification'), 'un', 'un.user_id = u.user_id')
            ->
group('u.user_id')
            ->
where($sWhere)
            ->
execute('getSlaveRows');            
            
        if (
count($aUsers) == 0)
        {
            if (
$aNewsletterInfo['archive'] != 1)
            {
                
$this->database()->delete($this->_sTable, 'newsletter_id = ' . $aNewsletterInfo['newsletter_id']);
                
$this->database()->delete(Phpfox::getT('newsletter_text'), 'newsletter_id = ' . $aNewsletterInfo['newsletter_id']);
            }
            else
            {
                
$this->database()->update($this->_sTable, array('state' => 2), 'newsletter_id = ' . (int)$aNewsletterInfo['newsletter_id']);
            }
            
$this->database()->update(Phpfox::getT('user_field'), array('newsletter_state' => 0), 'newsletter_state != 0');
            
            return array(
true, 100); // newsletter sent to everyone. finished successfully.
        
}
        
        
$sOriginalHtmlText = $aNewsletterInfo['text_html'];
        
$sOriginalPlainText = $aNewsletterInfo['text_plain'];
        
        
// store these users ID into a string to update them        
        
$sUpdate = '1=2 ';
        
// Step 3: Send the message
        
if ($aNewsletterInfo['type_id'] == 2) // External -> send email
        
{
            
$aValsT = $aNewsletterInfo;
            foreach (
$aUsers as $aUser)
            {
                
$aNewsletterInfo = $aValsT;
                
$sUpdate .= ' OR user_id = ' . $aUser['user_id'];
                
/*if (isset($aUser['user_group_id']) && Phpfox::getUserGroupParam($aUser['user_group_id'], 'newsletter.can_receive_notification') == false)
                {
                    
                }
                else*/
if (isset($aUser['notification']) && $aUser['notification'] != '' && $aNewsletterInfo['privacy'] != 1)
                { 
// user does not want to receive mails and admin set this newsletter to NOT override this                    
                    
continue;
                }
                
// keyword substitution
                
$aSearch = array('{FULL_NAME}', '{USER_NAME}', '{SITE_NAME}');
                
$aReplace = array($aUser['full_name'], $aUser['user_name'], Phpfox::getParam('core.site_title'));
                
                
$aNewsletterInfo['text_html'] = str_ireplace($aSearch, $aReplace, $sOriginalHtmlText);
                
$aNewsletterInfo['subject'] = str_ireplace($aSearch, $aReplace, $aNewsletterInfo['subject']);
                                
                if (
$aNewsletterInfo['text_plain'] !== null)
                {
                    
$aNewsletterInfo['text_plain'] = str_ireplace($aSearch, $aReplace, $sOriginalPlainText);
                }                
                unset(
$aSearch);
                unset(
$aReplace);
                
$this->_sendExternal($aNewsletterInfo, $aUser);
            }
        }
        elseif(
$aNewsletterInfo['type_id'] == 1) // internal message
        
{
            foreach (
$aUsers as $aUser)
            {
                
// keyword substitution
                
$aSearch = array('{FULL_NAME}', '{USER_NAME}', '{SITE_NAME}');
                
$aReplace = array($aUser['full_name'], $aUser['user_name'], Phpfox::getParam('core.site_title'));

                
$aNewsletter = $aNewsletterInfo;
                
$aNewsletter['text_html'] = str_ireplace($aSearch, $aReplace, $sOriginalHtmlText);
                
$aNewsletter['subject'] = str_ireplace($aSearch, $aReplace, $aNewsletterInfo['subject']);

                
$aNewsletter['user_id'] = $aUser['user_id'];
                unset(
$aSearch);
                unset(
$aReplace);
                
                                
                
$aNewsletter['full_name'] = $aUser['full_name'];
                
$aNewsletter['user_id'] = $aUser['user_id'];
                
$aNewsletter['email'] = $aUser['email'];
                
                
                
$this->_sendInternal($aNewsletter);
                
                
$sUpdate .= ' OR user_id = ' . $aUser['user_id'];
                
                if (isset(
$aUser['notification']) && $aUser['notification'] != '' && $aNewsletterInfo['privacy'] != 1)
                { 
// user does not want to receive mails and admin set this newsletter to NOT override this
                    
continue;
                }                
            }
        }
        
        
// Step 4: Update these users so they dont get the newsletter again
        
$this->database()->update(Phpfox::getT('user_field'), array('newsletter_state' => 1), $sUpdate);
        
//Step 5: Update the round
        
++$aNewsletterInfo['round'];
        
$this->database()->update($this->_sTable, array(
                
'round' => $aNewsletterInfo['round'],
                
'state' => 1,    // its in progress
            
), 'newsletter_id = ' . (int)$aNewsletterInfo['newsletter_id']);

        
// Step 6: return the id so it keeps sending in the next batch and calculate the percentage.
        // how many users do we have left?
        // check if we have a where
        
$sSelect = 'COUNT(user_id)';

        if (
str_replace('uf.newsletter_state = 0', '', $sWhere) != '')
        {
            
$sSelect = 'COUNT(uf.user_id)';
            
$this->database()->where($sWhere)
            ->
join(Phpfox::getT('user_field'), 'uf', 'uf.user_id = u.user_id');
        }
        
$iTotalUsers = $this->database()
            ->
select($sSelect)
            ->
from(Phpfox::getT('user'), 'u')
            ->
execute('getSlaveField');
        
$iSentTotal = $this->database()
            ->
select('count(user_id)')
            ->
from(Phpfox::getT('user_field'))
            ->
where('newsletter_state = 1')
            ->
execute('getSlaveField');


        if (
$iTotalUsers > 0 && $iTotalUsers != $iSentTotal)
        {
            
$iPerc = ceil( ($iSentTotal / $iTotalUsers) * 100 );
        }
        else
        {
            
$iPerc = 100;
        }
        if(
$iPerc >= 100)
        {
            if (
$aNewsletterInfo['archive'] != 1)
            {
                
$this->database()->delete($this->_sTable, 'newsletter_id = ' . $aNewsletterInfo['newsletter_id']);
                
$this->database()->delete(Phpfox::getT('newsletter_text'), 'newsletter_id = ' . $aNewsletterInfo['newsletter_id']);
            }
            else
            {
                
$this->database()->update(Phpfox::getT('user_field'), array('newsletter_state' => 0), 'newsletter_state != 0');
                
$this->database()->update($this->_sTable, array('state' => 2), 'newsletter_id = ' . $aNewsletterInfo['newsletter_id']);
            }
            
$this->database()->update(Phpfox::getT('user_field'), array('newsletter_state' => 0), 'newsletter_state != 0');
        }
        return array((int)
$aNewsletterInfo['newsletter_id'], $iPerc);
    }

    public function 
delete($iId)
    {
        if (!
Phpfox::getUserParam('newsletter.can_create_newsletter'))
        {
            return 
false;
        }
        
$iState = $this->database()->select('state')
        ->
from($this->_sTable)
        ->
where('newsletter_id = ' . (int)$iId)
        ->
execute('getSlaveField');
        if (
$iState == 1)
        {
            
$this->database()->update(Phpfox::getT('user_field'), array('newsletter_state' => 0), 'newsletter_state != 0');
        }
        
$this->database()->delete($this->_sTable, 'newsletter_id = ' . (int)$iId);
        
$this->database()->delete(Phpfox::getT('newsletter_text'), 'newsletter_id = ' . (int)$iId);
        return 
true;
    }
    
/**
     * Performes maintenance tasks such as resetting the user_field.newsletter_id to null
     * @param int $iAction
     * @return true on success
     */
    
public function purge($iAction, $iId)
    {
        switch(
$iAction)
        {
            case 
1: // clear users
                
$this->database()->update(Phpfox::getT('user_field'), array(
                    
'newsletter_state' => 0
                    
), 'newsletter_state != 0');
                return 
true;
                break;
            default:
                
Phpfox_Error::set(Phpfox::getPhrase('newsletter.purge_action_not_valid'));
                return 
false;
                break;
        }

    }

    
/**
     * If a call is made to an unknown method attempt to connect
     * it to a specific plug-in with the same name thus allowing
     * plug-in developers the ability to extend classes.
     *
     * @param string $sMethod is the name of the method
     * @param array $aArguments is the array of arguments of being passed
     */
    
public function __call($sMethod, $aArguments)
    {
        
/**
         * Check if such a plug-in exists and if it does call it.
         */
        
if ($sPlugin = Phpfox_Plugin::get('notification.service_process__call'))
        {
            return eval(
$sPlugin);
        }

        
/**
         * No method or plug-in found we must throw a error.
         */
        
Phpfox_Error::trigger('Call to undefined method ' . __CLASS__ . '::' . $sMethod . '()', E_USER_ERROR);
    }
    
    private function 
_sendExternal($aVals, $aUser)
    {
        
$aVals['text_html'] = str_replace("n", '', $aVals['text_html']);
        
$aVals['text_html'] = Phpfox::getLib('parse.input')->prepare($aVals['text_html'], true);
        
        
Phpfox::getLib('mail')->to($aVals)
            ->
aUser($aUser)
            ->
subject($aVals['subject'])
            ->
message($aVals['text_html'])
            ->
messagePlain(strip_tags($aVals['text_plain']))
            ->
fromName(Phpfox::getParam('core.mail_from_name'))
            ->
sendToSelf(true)
            ->
send();
            
        return 
true;
    }    
    
    
/**
     * This function can probably still be improved by not adding data to the mail_text and recycle the reference to the first entry
     * @param <type> $aVals
     */
    
private function _sendInternal($aVals)
    {        
        
$oFilter = Phpfox::getLib('parse.input');
        
$aVals['subject'] = (isset($aVals['subject']) ? $oFilter->clean($aVals['subject'], 255) : null);
        
        
$aSend = array();
        
$aSend['to'] = array($aVals['user_id']);
        
$aSend['subject'] = $aVals['subject'];
        
$aSend['message'] = $aVals['text_html'];
        
$aSend['bIsNewsletter'] = true;
        
Phpfox::getService('mail.process')->add($aSend);
        
        return ;
        
/*$aInsert = array(
            'parent_id' => 0,
            'subject' => $aVals['subject'],
            'preview' => $oFilter->clean($oFilter->prepare($aVals['text_html']), 255),
            'owner_user_id' => 0,
            'viewer_user_id' => $aVals['user_id'],
            'viewer_is_new' => 1,
            'time_stamp' => PHPFOX_TIME,
            'time_updated' => PHPFOX_TIME,
            'total_attachment' => 0,
        );

        $iId = $this->database()->insert(Phpfox::getT('mail'), $aInsert);

        $this->database()->insert(Phpfox::getT('mail_text'), array(
                'mail_id' => $iId,
                'text' => $oFilter->clean($aVals['text_html']),
                'text_parsed' => $oFilter->prepare($aVals['text_html'])
            )
        );
        
        // Send the user an email
        $sLink = Phpfox::getLib('url')->makeUrl('mail.view', array('id' => $iId));
        Phpfox::getLib('mail')->to($aVals['user_id'])
            ->subject(array('newsletter.site_newsletter_title', array('title' => $aVals['subject'])))
            ->message(array('newsletter.you_have_received_a_newsletter_from_title', array(
                        'title' => Phpfox::getParam('core.site_title'),
                        'link' => $sLink
                    )
                )
            )
            ->notification('mail.new_message')
            ->send();        */
    
}    
}

?>
Онлайн: 0
Реклама