* Invision Power Services * IP.Board v3.4.8 * Bulk mail management * Last Updated: $Date: 2015-01-06 07:55:43 -0500 (Tue, 06 Jan 2015) $ * * * @author $Author: stuarts $ * @copyright (c) 2001 - 2009 Invision Power Services, Inc. * @license http://www.invisionpower.com/company/standards.php#license * @package IP.Board * @subpackage Members * @link http://www.invisionpower.com * @version $Revision: 12583 $ */ if ( ! defined( 'IN_ACP' ) ) { print "

Incorrect access

You cannot access this file directly."; exit(); } class admin_members_bulkmail_bulkmail extends ipsCommand { /** * Skin object * * @var object Skin templates */ protected $html; /** * Shortcut for url * * @var string URL shortcut */ protected $form_code; /** * Shortcut for url (javascript) * * @var string JS URL shortcut */ protected $form_code_js; /** * Main class entry point * * @param object ipsRegistry reference * @return @e void [Outputs to screen] */ public function doExecute( ipsRegistry $registry ) { require_once IPSLib::getAppDir( 'members' ) . '/sources/classes/bulkMailFilter.php'; //----------------------------------------- // Load skin //----------------------------------------- $this->html = $this->registry->output->loadTemplate('cp_skin_bulkmail'); //----------------------------------------- // Set up stuff //----------------------------------------- $this->form_code = $this->html->form_code = 'module=bulkmail&section=bulkmail'; $this->form_code_js = $this->html->form_code_js = 'module=bulkmail§ion=bulkmail'; //----------------------------------------- // Load lang //----------------------------------------- ipsRegistry::getClass('class_localization')->loadLanguageFile( array( 'admin_bulkmail' ) ); switch( $this->request['do'] ) { case 'mail_new': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'bulkmail_addedit' ); $this->_mailForm('add'); break; case 'mail_edit': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'bulkmail_addedit' ); $this->_mailForm('edit'); break; case 'mail_save': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'bulkmail_addedit' ); $this->_mailSave(); break; case 'mail_preview': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'bulkmail_view' ); $this->_mailPreviewStart(); break; case 'mail_preview_do': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'bulkmail_view' ); $this->_mailPreviewComplete(); break; case 'mail_send_start': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'bulkmail_send' ); $this->_mailSendStart(); break; case 'mail_send_complete': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'bulkmail_send' ); $this->_mailSendComplete(); break; case 'mail_send_mandrill': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'bulkmail_send' ); $this->_mailSendMandrill(); break; case 'mail_send_cancel': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'bulkmail_cancel' ); $this->_mailSendCancel(); break; case 'mail_delete': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'bulkmail_delete' ); $this->_mailDelete(); break; default: case 'bulk_mail': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'bulkmail_view' ); $this->_mailStart(); break; } //----------------------------------------- // Pass to CP output hander //----------------------------------------- $this->registry->getClass('output')->html_main .= $this->registry->getClass('output')->global_template->global_frame_wrapper(); $this->registry->getClass('output')->sendOutput(); } /** * Delete a bulk mail * * @return @e void [Outputs to screen] */ protected function _mailDelete() { $id = intval( $this->request['id'] ); $active = $this->DB->buildAndFetch( array( 'select' => 'mail_id', 'from' => 'bulk_mail', 'where' => 'mail_active=1 AND mail_id <>' . $id ) ); if( !$active['mail_id'] ) { $this->DB->update( 'task_manager', array( 'task_enabled' => 0 ), "task_key='bulkmail'" ); } $this->DB->delete( 'bulk_mail', 'mail_id=' . $id ); $this->registry->output->global_message = $this->lang->words['b_deleted']; $this->_mailStart(); } /** * Cancels a bulk mail * * @return @e void [Outputs to screen] */ protected function _mailSendCancel() { $this->DB->update( 'bulk_mail', array( 'mail_active' => 0, 'mail_updated' => time(), ), "mail_active=1" ); $this->DB->update( 'task_manager', array( 'task_enabled' => 0 ), "task_key='bulkmail'" ); $this->registry->output->global_message = $this->lang->words['b_cancelled']; $this->_mailStart(); } /** * Processes a bulk mail * * @return @e void */ public function mailSendProcess() { //----------------------------------------- // Init //----------------------------------------- $done = 0; $sent = 0; $mail = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'bulk_mail', 'where' => 'mail_active=1' ) ); if ( ! $mail['mail_subject'] and ! $mail['mail_content'] ) { /* Just return, if there's nothing to send. Bug #21494 */ return; } $opts = unserialize( $mail['mail_opts'] ); //----------------------------------------- // What's the plan, Stan? // Let's limit to 100 to be safe - tickets have come in where duplicates are received because the task times out //----------------------------------------- $pergo = intval( $mail['mail_pergo'] ); if ( ! $pergo or $pergo > 100 ) { $pergo = 50; } $sofar = intval($mail['mail_sentto']); //----------------------------------------- // Clear out any other temp headers //----------------------------------------- IPSText::getTextClass('email')->clearHeaders(); //----------------------------------------- // Get Members //----------------------------------------- /* Start with a basic query */ $queryData = array( 'select' => 'm.*', 'from' => array( 'members' => 'm' ), 'order' => 'm.member_id', 'limit' => array( $sofar, $pergo ) ); /* Add in filters */ $_queryData = $this->_buildMembersQuery( $opts['filters'] ); $queryData['add_join'] = $_queryData['add_join']; $queryData['where'] = implode( ' AND ' , $_queryData['where'] ); /* Count */ $this->DB->build( $queryData ); $e = $this->DB->execute(); while ( $r = $this->DB->fetch( $e ) ) { /* Convert Tags */ $contents = $this->_convertQuicktags( $mail['mail_content'], $r ); /* Clear out previous data */ IPSText::getTextClass('email')->clearContent(); /* We need an unsubscribe link */ IPSText::getTextClass('email')->unsubscribe = true; /* What kinf of email IS this!? */ if ( $opts['mail_html_on'] ) { IPSText::getTextClass('email')->setHtmlEmail( true ); IPSText::getTextClass('email')->setHtmlTemplate( str_replace( "\n", "", $contents ) ); IPSText::getTextClass('email')->setHtmlWrapper( '<#content#>' ); } else if ( $this->settings['email_use_html'] ) { IPSText::getTextClass('email')->setHtmlEmail( true ); IPSText::getTextClass('email')->setHtmlTemplate( $contents ); } else { IPSText::getTextClass('email')->setPlainTextTemplate( $contents ); } /* Build it */ IPSText::getTextClass('email')->from = $this->settings['email_out']; IPSText::getTextClass('email')->to = $r['email']; IPSText::getTextClass('email')->subject = $mail['mail_subject']; IPSText::getTextClass('email')->setHeader( 'Precedence', 'bulk' ); IPSText::getTextClass('email')->buildMessage( array(), false, true, $r ); /* Send it */ IPSText::getTextClass('email')->sendMail(); /* Increase sent count */ $sent++; } //----------------------------------------- // Did we send any? //----------------------------------------- if ( ! $sent ) { $done = 1; } //----------------------------------------- // Save out.. //----------------------------------------- if ( $done ) { $this->DB->update( 'bulk_mail', array( 'mail_active' => 0, 'mail_updated' => time(), 'mail_sentto' => $sofar + $sent ), 'mail_id=' . $mail['mail_id'] ); $this->DB->update( 'task_manager', array( 'task_enabled' => 0 ), "task_key='bulkmail'" ); } else { $this->DB->update( 'bulk_mail', array( 'mail_updated' => time(), 'mail_sentto' => $sofar + $sent ), 'mail_id=' . $mail['mail_id'] ); } } /** * Send Bulk Mail via Mandrill */ protected function _mailSendMandrill() { //----------------------------------------- // Load it //----------------------------------------- $id = intval( $this->request['id'] ); $mail = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'bulk_mail', 'where' => 'mail_id=' . $id ) ); if ( !$mail['mail_id'] or !$mail['mail_subject'] or !$mail['mail_content'] ) { $this->registry->output->global_message = $this->lang->words['b_nosend']; $this->_mailStart(); return; } $opts = unserialize( $mail['mail_opts'] ); //----------------------------------------- // Work out which vars we've actually used //----------------------------------------- $usedVars = array( 'unsubscribe' ); foreach( array_keys( $this->_getVariableInformation( $this->memberData ) ) as $k ) { if ( strpos( $mail['mail_content'], '{' . $k . '}' ) !== FALSE ) { $usedVars[] = $k; } } //----------------------------------------- // Build the JSON document //----------------------------------------- $pergo = 2000; $recipientsTo = array(); $recipientsMerge = array(); /* Start with a basic query */ $queryData = array( 'select' => 'm.*', 'from' => array( 'members' => 'm' ), 'order' => 'm.member_id', 'limit' => array( $this->request['st'], $pergo ) ); /* Add in filters */ $done = 0; $complete = FALSE; $_queryData = $this->_buildMembersQuery( $opts['filters'] ); $queryData['add_join'] = $_queryData['add_join']; $queryData['where'] = implode( ' AND ' , $_queryData['where'] ); /* Write the file */ $this->DB->build( $queryData ); $e = $this->DB->execute(); if ( !$this->DB->getTotalRows( $e ) ) { $complete = TRUE; } while ( $r = $this->DB->fetch( $e ) ) { /* Skip any invalid emails - the chars presented here are allowed via RFC (note that _ and - are already allowed in alphanumericClean and don't need to be specified) */ if ( !$r['email'] or !$r['members_display_name'] OR !IPSText::checkEmailAddress( $r['email'] ) OR $r['email'] != IPSText::alphanumericalClean( $r['email'], '@.+!#$%&\'*/=?^`{|}~ ' ) ) { continue; } $recipientsTo[] = array( 'email' => $r['email'], 'name' => $r['members_display_name'] ); $vars = array(); foreach ( $this->_getVariableInformation( $r, 1 ) as $k => $v ) { if ( in_array( $k, $usedVars ) ) { $vars[] = array( 'name' => $k, 'content' => $v ); } } if ( !empty( $vars ) ) { $recipientsMerge[] = array( 'rcpt' => $r['email'], 'vars' => $vars ); } $done++; } //----------------------------------------- // Build Content //----------------------------------------- /* Sort out member vars */ $content = $mail['mail_content']; foreach ( $this->_getVariableInformation( $this->memberData ) as $k => $v ) { $content = str_replace( '{'.$k.'}', '*|'.$k.'|*', $content ); } /* Sort out global vars */ $globalMergeVars = array(); foreach ( $this->_getVariableInformation( NULL, 2 ) as $k => $v ) { if ( in_array( $k, $usedVars ) ) { $globalMergeVars[] = array( 'name' => $k, 'content' => $v ); } } /* Get the full content */ IPSText::getTextClass('email')->clearContent(); IPSText::getTextClass('email')->unsubscribe = true; if ( $opts['mail_html_on'] ) { IPSText::getTextClass('email')->setHtmlEmail( true ); IPSText::getTextClass('email')->setHtmlTemplate( str_replace( "\n", "", $content ) ); IPSText::getTextClass('email')->setHtmlWrapper( '<#content#>' ); } else if ( $this->settings['email_use_html'] ) { IPSText::getTextClass('email')->setHtmlEmail( true ); IPSText::getTextClass('email')->setHtmlTemplate( $content ); } else { IPSText::getTextClass('email')->setPlainTextTemplate( $content, true ); } if ( $opts['mail_html_on'] or $this->settings['email_use_html'] ) { IPSText::getTextClass('email')->buildMessage( array( 'UNSUBSCRIBE' => '*|unsubscribe|*' ), true, true ); $content = IPSText::getTextClass('email')->getHtmlContent(); } else { IPSText::getTextClass('email')->buildMessage( array( 'UNSUBSCRIBE' => '*|unsubscribe|*' ) ); $content = nl2br( IPSText::getTextClass('email')->getPlainTextContent() ); } //----------------------------------------- // Send to Mandrill //----------------------------------------- if( IPS_DOC_CHAR_SET != "UTF-8" ) { $mail['mail_subject'] = IPSText::convertCharsets( $mail['mail_subject'], IPS_DOC_CHAR_SET, "UTF-8" ); } require_once IPSLib::getAppDir('members') . '/sources/classes/mandrill.php'; $mandrill = new Mandrill(); $response = $mandrill->messages_send( array( 'message' => array( 'html' => $content, 'subject' => $mail['mail_subject'], 'from_email' => $this->settings['email_out'], 'from_name' => $this->settings['board_name'], 'to' => $recipientsTo, 'auto_text' => true, 'url_strip_qs' => false, 'preserve_recipients' => false, 'merge' => true, 'global_merge_vars' => $globalMergeVars, 'merge_vars' => $recipientsMerge, 'tags' => array_merge( array( 'ips' ), array_filter( $opts['mandrill_tags'], create_function( '$v', 'return (bool) $v;' ) ) ) ), 'async' => true ) ); if ( isset( $response->status ) and $response->status == 'error' ) { $this->registry->output->showError( 'mandrill_error' ); } //----------------------------------------- // Save //----------------------------------------- $this->DB->update( 'bulk_mail', array( 'mail_active' => 0, 'mail_updated' => time(), 'mail_sentto' => $mail['mail_sentto'] + count( $recipientsTo ) ), 'mail_id=' . $mail['mail_id'] ); if ( $complete !== TRUE ) { $url = "{$this->settings['base_url']}app=members&module=bulkmail§ion=bulkmail&do=mail_send_mandrill&id={$id}&countmembers={$this->request['countmembers']}&st=" . ( $this->request['st'] + $pergo ); if ( !$this->request['st'] ) { $this->registry->output->multipleRedirectInit( $url ); $this->registry->getClass('output')->html_main .= $this->registry->getClass('output')->global_template->global_frame_wrapper(); $this->registry->getClass('output')->sendOutput(); } else { $percentage = ( ( 100 / $this->request['countmembers'] ) * $this->request['st'] ); $percentage = floor( $percentage ); $this->registry->output->multipleRedirectHit( $url, "Processing ({$percentage}% complete)" ); } return; } else { $this->registry->output->multipleRedirectFinish(); } } /** * Complete bulk mail processing * * @return @e void */ protected function _mailSendComplete() { $pergo = intval( $this->request['pergo'] ); $id = intval( $this->request['id'] ); if ( ! $id ) { $this->registry->output->global_message = $this->lang->words['b_norecord']; $this->_mailStart(); return; } //----------------------------------------- // Get it from the db //----------------------------------------- $mail = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'bulk_mail', 'where' => 'mail_id=' . $id ) ); if ( ! $mail['mail_subject'] and ! $mail['mail_content'] ) { $this->registry->output->global_message = $this->lang->words['b_nosend']; $this->_mailStart(); return; } //----------------------------------------- // Update mail //----------------------------------------- if ( ! $pergo or $pergo > 100 ) { $pergo = 50; } $this->DB->update( 'bulk_mail', array( 'mail_active' => 1, 'mail_pergo' => $pergo, 'mail_sentto' => 0, 'mail_start' => time() ), 'mail_id=' . $id ); $this->DB->update( 'bulk_mail', array( 'mail_active' => 0 ) , 'mail_id <> ' . $id ); //----------------------------------------- // Wake up task manager //----------------------------------------- $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/class_taskmanager.php', 'class_taskmanager' ); $task = new $classToLoad( $this->registry ); $this->DB->update( 'task_manager', array( 'task_enabled' => 1 ), "task_key='bulkmail'" ); $this_task = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'task_manager', 'where' => "task_key='bulkmail'" ) ); $newdate = $task->generateNextRun( $this_task ); $this->DB->update( 'task_manager', array( 'task_next_run' => $newdate ), "task_id=".$this_task['task_id'] ); $task->saveNextRunStamp(); //----------------------------------------- // Sit back and watch the show //----------------------------------------- $this->registry->output->global_message = $this->lang->words['b_initiated']; $this->_mailStart(); } /** * Start the sending of the bulk mail * * @return @e void */ protected function _mailSendStart() { //----------------------------------------- // Init //----------------------------------------- $id = intval( $this->request['id'] ); $mail = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'bulk_mail', 'where' => 'mail_id=' . $id ) ); if ( ! $mail['mail_subject'] and ! $mail['mail_content'] ) { $this->registry->output->global_message = $this->lang->words['b_nosend']; $this->_mailStart(); return; } $opts = unserialize( stripslashes( $mail['mail_opts'] ) ); $mail['mail_html_on'] = $opts['mail_html_on']; //----------------------------------------- // Get Members //----------------------------------------- /* Start with a basic query */ $queryData = array( 'select' => 'count(*) as count', 'from' => array( 'members' => 'm' ), 'order' => 'm.members_display_name', ); /* Add in filters */ $_queryData = $this->_buildMembersQuery( $opts['filters'] ); $queryData['add_join'] = $_queryData['add_join']; $queryData['where'] = implode( ' AND ' , $_queryData['where'] ); /* Get Count */ $countmembers = $this->DB->buildAndFetch( $queryData ); /* Get Em */ $queryData['select'] = 'm.member_id, m.members_display_name, m.email'; $queryData['limit'] = array( 0, 10000 ); $this->DB->build( $queryData ); $this->DB->execute(); while ( $row = $this->DB->fetch() ) { $members[] = $row; } if ( empty( $members ) ) { $this->registry->output->showError( $this->lang->words['b_nonefound'] ); } //----------------------------------------- // Print 'continue' screen //----------------------------------------- $this->registry->output->html .= $this->html->mailSendStart( $mail, $members, $countmembers['count'] ); } /** * Process the sending of the bulk mail * * @return @e void */ protected function _mailPreviewComplete() { //----------------------------------------- // Init //----------------------------------------- $id = intval( $this->request['id'] ); $mail = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'bulk_mail', 'where' => 'mail_id=' . $id ) ); $mailopts = unserialize( $mail['mail_opts'] ); //----------------------------------------- // Build It //----------------------------------------- $contents = $this->_convertQuicktags( $mail['mail_content'], $this->memberData ); /* Clear out previous data */ IPSText::getTextClass('email')->clearContent(); IPSText::getTextClass('email')->unsubscribe = true; /* Specifically a HTML email */ if ( $mailopts['mail_html_on'] ) { IPSText::getTextClass('email')->setHtmlEmail( true ); IPSText::getTextClass('email')->setHtmlTemplate( str_replace( "\n", "", $contents ) ); IPSText::getTextClass('email')->setHtmlWrapper( '<#content#>' ); IPSText::getTextClass('email')->buildMessage( array(), false, true, $this->memberData ); } else if ( $this->settings['email_use_html'] ) { IPSText::getTextClass('email')->setHtmlEmail( true ); IPSText::getTextClass('email')->setHtmlTemplate( $contents ); IPSText::getTextClass('email')->buildMessage( array(), false, true, $this->memberData ); } else { IPSText::getTextClass('email')->setPlainTextTemplate( $contents ); IPSText::getTextClass('email')->buildMessage( array(), false, false, $this->memberData ); } IPSText::getTextClass('email')->from = $this->settings['email_out']; IPSText::getTextClass('email')->to = $this->memberData['email']; IPSText::getTextClass('email')->subject = $mail['mail_subject']; IPSText::getTextClass('email')->setHeader( 'Precedence', 'bulk' ); //----------------------------------------- // Display //----------------------------------------- if ( $mailopts['mail_html_on'] or $this->settings['email_use_html'] ) { echo IPSText::getTextClass('email')->getHtmlContent(); } else { echo '
';
			echo IPSText::getTextClass('email')->getPlainTextContent();
			echo '
'; } IPSText::getTextClass('email')->clearContent(); exit(); } /** * Preview the email (javascript popup) * * @return @e void */ protected function _mailPreviewStart() { $this->registry->output->html .= $this->html->mailPopupContent(); $this->registry->output->printPopupWindow(); exit(); } /** * Save the new or edited bulk mail * * @return @e void */ protected function _mailSave() { //----------------------------------------- // Init //----------------------------------------- $id = intval( $this->request['id'] ); $type = $this->request['type']; //----------------------------------------- // Validate //----------------------------------------- $errors = array(); /* Basic */ if ( ! $this->request['mail_subject'] or ! $this->request['mail_content'] ) { $errors[] = $this->lang->words['b_entercont']; } /* Filters */ $opts = array( 'mail_html_on' => ( $this->settings['email_use_html'] and $_POST['mail_html_on'] ), 'filters' => array(), 'mandrill_tags' => array_map( 'trim', explode( ',', $this->request['mandrill_tags'] ) ) ); foreach ( IPSLib::getEnabledApplications() as $app ) { $extensionFile = IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/bulkMailFilters.php'; if ( file_exists( $extensionFile ) ) { $classToLoad = IPSLib::loadLibrary( $extensionFile, 'bulkMailFilters_' . $app['app_directory'] ); $class = new $classToLoad( $this->registry ); foreach ( $class->filters as $f ) { $classToLoad = IPSLib::loadLibrary( $extensionFile, "bulkMailFilter_{$app['app_directory']}_{$f}" ); $_class = new $classToLoad( $this->registry ); try { $value = $_class->save( $_POST ); if ( $value !== FALSE ) { $opts['filters'][ $app['app_directory'] ][ $f ] = $value; } } catch ( Exception $e ) { $errors[] = $e->getMessage(); } } } } /* Anything? */ if ( !empty( $errors ) ) { return $this->_mailForm( $type, $errors ); } //----------------------------------------- // Count how many matches //----------------------------------------- /* Start with a basic query */ $queryData = array( 'select' => 'count(*) as count', 'from' => array( 'members' => 'm' ), ); /* Add in filters */ $_queryData = $this->_buildMembersQuery( $opts['filters'] ); $queryData['add_join'] = $_queryData['add_join']; $queryData['where'] = implode( ' AND ' , $_queryData['where'] ); /* Count */ $count = $this->DB->buildAndFetch( $queryData ); /* If there aren't any, error */ if ( !$count['count'] ) { return $this->_mailForm( $type, array( $this->lang->words['b_nonefound'] ) ); } //----------------------------------------- // Save //----------------------------------------- $save_array = array( 'mail_subject' => IPSText::stripslashes( $_POST['mail_subject'] ), 'mail_content' => $this->request['mail_html_on'] ? $_POST['mail_content_plain'] : IPSText::stripslashes( $_POST['mail_content'] ), 'mail_start' => time(), 'mail_updated' => time(), 'mail_sentto' => 0, 'mail_groups' => '', 'mail_opts' => serialize( $opts ) ); if ( $type == 'add' ) { //----------------------------------------- // Save to DB //----------------------------------------- $this->DB->insert( 'bulk_mail', $save_array ); $id = $this->DB->getInsertId(); ipsRegistry::getClass('adminFunctions')->saveAdminLog( sprintf( $this->lang->words['b_maillogadd'], $this->request['mail_subject'] ) ); $this->registry->output->silentRedirect( "{$this->settings['base_url']}app=members&module=bulkmail§ion=bulkmail&do=mail_send_start&id={$id}" ); return; } else { if ( ! $id ) { $this->registry->output->global_message = $this->lang->words['b_norecord']; $this->_mailForm( $type ); return; } $this->DB->update( 'bulk_mail', $save_array, 'mail_id=' . $id ); ipsRegistry::getClass('adminFunctions')->saveAdminLog( sprintf( $this->lang->words['b_maillogedit'], $this->request['mail_subject'] ) ); $this->registry->output->redirect( "{$this->settings['base_url']}app=members&module=bulkmail§ion=bulkmail&do=mail_send_start&id={$id}", $this->lang->words['b_edited'] ); return; } } /** * Show the edit bulk mail form * * @param string [add|edit] * @param array Error messages * @return @e void */ protected function _mailForm( $type='add', $errors=array() ) { //----------------------------------------- // Init some values //----------------------------------------- $id = intval($this->request['id']); if ( $type == 'add' ) { $mail = array(); } else { $mail = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'bulk_mail', 'where' => 'mail_id='.$this->request['id'] ) ); } if ( $this->request['mail_groups'] ) { $mail['mail_groups'] = $this->request['mail_groups']; } //----------------------------------------- // Format mail content //----------------------------------------- $mail_content = $_POST['mail_content'] ? IPSText::stripslashes($_POST['mail_content']) : $mail['mail_content']; $mail_content = preg_replace( "[^\r]\n", "\r\n", $mail_content ); if ( !$mail_content and $type == 'add' ) { $mail_content = $this->_getDefaultMailContents(); } /* Bug report #39173 */ $mail_content = IPSText::htmlspecialchars( $mail_content ); //----------------------------------------- // Get Filters //----------------------------------------- $opts = unserialize( $mail['mail_opts'] ); $id = 1; $filters = array(); foreach ( IPSLib::getEnabledApplications() as $app ) { $extensionFile = IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/bulkMailFilters.php'; if ( file_exists( $extensionFile ) ) { $classToLoad = IPSLib::loadLibrary( $extensionFile, 'bulkMailFilters_' . $app['app_directory'] ); $class = new $classToLoad( $this->registry ); $filters[ $id ] = array( 'appName' => $app['app_title'], 'appKey' => $app['app_directory'], 'filters' => array() ); foreach ( $class->filters as $f ) { $classToLoad = IPSLib::loadLibrary( $extensionFile, "bulkMailFilter_{$app['app_directory']}_{$f}" ); $_class = new $classToLoad( $this->registry ); $filters[ $id ]['filters'][] = array( 'title' => $this->lang->words[ "bulkMailFilter_{$app['app_directory']}_{$f}" ], 'field' => $_class->getSettingField( $opts['filters'][ $app['app_directory'] ][ $f ] ) ); } $id++; } } /* We want the members tab to be first so it shows groups, which will be the most common filter */ uasort( $filters, create_function( '$a, $b', 'if ( $a[\'appKey\'] == "members" ) { return 0; } else { return 1; }' ) ); //----------------------------------------- // Output //----------------------------------------- $this->registry->output->html .= $this->html->mailForm( $type, $mail, $mail_content, $filters, $errors ); } /** * Show the main bulk mail overview screen * * @return @e void */ protected function _mailStart() { $content = ''; $st = intval( $this->request['st'] ); $perpage = 50; /* Get count */ $items = $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as cnt', 'from' => 'bulk_mail' ) ); //----------------------------------------- // Get mail from DB // WHERE clause helps query use index properly //----------------------------------------- $this->DB->build( array( 'select' => '*', 'from' => 'bulk_mail', 'where' => 'mail_start > 0', 'order' => 'mail_start DESC', 'limit' => array( $st, $perpage ) ) ); $this->DB->execute(); while( $r = $this->DB->fetch() ) { $r['_mail_start'] = ipsRegistry::getClass( 'class_localization')->getDate( $r['mail_start'], 'SHORT' ); $r['_mail_sentto'] = ipsRegistry::getClass('class_localization')->formatNumber( $r['mail_sentto'] ) . ' members'; $content .= $this->html->mailOverviewRow( $r ); } /* Pages */ $pages = $this->registry->output->generatePagination( array( 'totalItems' => $items['cnt'], 'itemsPerPage' => $perpage, 'currentStartValue' => $st, 'baseUrl' => $this->settings['base_url'] . 'app=members&module=bulkmail&do=bulk_mail' ) ); $this->registry->output->html .= $this->html->mailOverviewWrapper( $content, $pages ); } /** * Build the query to retrieve the members * * @param array Filter values * @return array Query Data */ public function _buildMembersQuery( $args = array() ) { $queryData = array( 'add_join' => array(), 'where' => array( "m.allow_admin_mails=1", "m.member_banned=0" ), 'group' => 'm.member_id' ); foreach ( $args as $app => $filters ) { $extensionFile = IPSLib::getAppDir( $app ) . '/extensions/bulkMailFilters.php'; if ( IPSLib::appIsInstalled( $app ) and file_exists( $extensionFile ) ) { $classToLoad = IPSLib::loadLibrary( $extensionFile, 'bulkMailFilters_' . $app ); $class = new $classToLoad( $this->registry ); foreach ( $filters as $key => $data ) { $classToLoad = IPSLib::loadLibrary( $extensionFile, "bulkMailFilter_{$app}_{$key}" ); $_class = new $classToLoad( $this->registry ); $r = $_class->getMembers( $data ); if ( isset( $r['joins'] ) ) { $queryData['add_join'] = array_merge( $queryData['add_join'], $r['joins'] ); } if( isset( $r['where'] ) ) { $haveCriteria = TRUE; $queryData['where'] = array_merge( $queryData['where'], $r['where'] ); } } } } return $queryData; } /** * Conver the 'quick tags' in the email * * @param string The email contents * @param array Member information * @return string The email contents, replaced */ protected function _convertQuickTags( $contents="", $member=array() ) { foreach ( $this->_getVariableInformation( $member ) as $k => $v ) { $contents = str_replace( '{'.$k.'}', $v, $contents ); } return $contents; } /** * Get variable values * * @param array Member information * @param int 0 All 1 Member Specific only 2 Global only * @retrun array key/value pairs */ protected function _getVariableInformation( $member, $type=0, $html=TRUE ) { $variables = array(); if ( $type == 0 or $type == 2 ) { $variables['board_name'] = str_replace( "'", "'", $this->settings['board_name'] ) ; $variables['board_url'] = $this->settings['board_url'] . "/index." . $this->settings['php_ext'] ; $variables['reg_total'] = $this->caches['stats']['mem_count'] ; $variables['total_posts'] = $this->caches['stats']['total_topics'] + $this->caches['stats']['total_replies'] ; $variables['busy_count'] = $this->caches['stats']['most_count'] ; $variables['busy_time'] = ipsRegistry::getClass( 'class_localization')->getDate( $this->caches['stats']['most_date'], 'SHORT' ); } if ( $type == 0 or $type == 1 ) { $variables['member_id'] = $member['member_id']; $variables['member_name'] = $member['members_display_name']; $variables['member_joined'] = ipsRegistry::getClass( 'class_localization')->getDate( $member['joined'], 'JOINED', TRUE ); $variables['member_posts'] = $member['posts']; $variables['member_last_visit'] = ipsRegistry::getClass( 'class_localization')->getDate( $member['last_visit'], 'JOINED', TRUE ); $this->registry->class_localization->loadLanguageFile( array( 'public_global' ), 'core', $member['language'] ? $member['language'] : IPSLib::getDefaultLanguage(), TRUE ); $key = md5( $member['email'] . ':' . $member['members_pass_hash'] ); $link = $this->registry->output->buildUrl( "app=core&module=global&section=unsubscribe&member={$member['member_id']}&key={$key}", 'publicNoSession' ); $variables['unsubscribe'] = $html ? "" . $this->registry->class_localization->words['email_unsubscribe'] . '' : "{$this->registry->class_localization->words['email_unsubscribe']}: {$link}"; } return $variables; } /** * Retrieve the 'default' email contents * * @return string Default email contents */ protected function _getDefaultMailContents() { if ( $this->settings['email_use_html'] ) { return <<{member_name},

 

 

CONTENT; } else { return "{member_name},\n\n"; } } }