[ Index ] |
MailPress 7.0.1 |
[ Index ] [ Classes ] [ Functions ] [ Variables ] [ Constants ] [ Statistics ] |
[Summary view] [Print] [Text view]
1 <?php 2 class MP_Batch_spool extends MP_WP_db_connect_ 3 { 4 public static $count = 0; 5 6 function __construct() 7 { 8 $this->config = get_option( MailPress_batch_spool_send::option_name ); 9 $this->report = array(); 10 11 $this->trace = new MP_Log( 'mp_process_batch_spool_send', array( 'option_name' => 'batch_spool_send' ) ); 12 13 $this->process(); 14 if ( $this->have_batch() ) do_action( 'MailPress_schedule_batch_spool_send' ); 15 16 $this->write_report(); 17 $this->trace->end( true ); 18 } 19 20 // have_batch 21 function have_batch() 22 { 23 global $wpdb; 24 return $wpdb->get_var( $wpdb->prepare( "SELECT count( * ) FROM $wpdb->mp_mails WHERE status IN ( %s , %s ) ;", MailPress_batch_spool_send::status_mail(), 'paused' ) ); 25 } 26 27 // process 28 function process() 29 { 30 if ( self::$count ) return; 31 self::$count++; 32 33 global $wpdb; 34 35 // select path 36 $this->path = MP_UPL_ABSPATH . 'spool/' . get_current_blog_id() . '/'; 37 38 // select mail 39 $mails = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->mp_mails WHERE status = %s ;", MailPress_batch_spool_send::status_mail() ) ); 40 41 if ( !$mails ) { $this->alldone(); return; } 42 43 $this->mail = $this->mailmeta = false; 44 45 $mail = $mailmeta = $this->mail = $this->mailmeta = false; 46 $try = 10000; 47 48 foreach ( $mails as $this->mail ) 49 { 50 $this->spool_path = $this->path . $this->mail->id; 51 if ( !is_dir( $this->spool_path ) ) // no spool path for this mail => everything was sent 52 { 53 $this->update_mail_status(); 54 continue; 55 } 56 57 $this->mailmeta = $this->get_mailmeta(); 58 if ( !$this->mailmeta ) continue; 59 60 if ( $this->mailmeta['try'] < $try ) 61 { 62 $try = $this->mailmeta['try']; 63 $mail = $this->mail; 64 $mailmeta = $this->mailmeta; 65 } 66 } 67 if ( !$mail ) { $this->alldone(); return; } 68 69 $this->mail = $mail; 70 $this->mailmeta = $mailmeta; 71 $this->spool_path = $this->path . $this->mail->id; 72 unset( $mails, $mail, $mailmeta ); 73 74 $this->mailmeta['pass']++; 75 $this->report['header'] = 'Batch Spool Report mail #' . $this->mail->id . ' / count : ' . $this->mailmeta['count'] . ' / per_pass : ' . $this->config['per_pass'] . ' / max_try : ' . $this->config['max_retry']; 76 $this->report['start'] = $this->mailmeta; 77 78 // recipients 79 $max = ( $this->mailmeta['try'] ) ? count( $this->mailmeta['failed'] ) : $this->mailmeta['count']; 80 $count_recipients = ( ( $this->mailmeta['processed'] + $this->config['per_pass'] ) > $max ) ? fmod( $max, $this->config['per_pass'] ) : $this->config['per_pass']; 81 82 // processing 83 if ( !$count_recipients ) 84 { 85 $this->report['processing'] = array_merge( $this->mailmeta, array( ">> WARNING >>" => 'No more recipient' ) ); 86 $this->mailmeta['processed'] = $this->mailmeta['pass'] = 0; 87 $this->mailmeta['try']++; 88 } 89 else 90 { 91 $this->mailmeta['processed'] += $count_recipients; 92 $this->report['processing'] = $this->mailmeta; 93 $this->write_report(); 94 95 // saving context, if abort, current recipients may or may be not sent anyway empty spool will tell ! 96 if ( $this->mailmeta['try'] ) 97 { 98 if ( count( $this->mailmeta['failed'] ) <= $count_recipients ) $this->mailmeta['failed'] = array(); 99 else for ( $i = 1; $i <= $count_recipients; $i++ ) array_shift( $this->mailmeta['failed'] ); 100 } 101 102 if ( !MP_Mail_meta::add( $this->mail->id, MailPress_batch_spool_send::meta_key, $this->mailmeta, true ) ) 103 MP_Mail_meta::update( $this->mail->id, MailPress_batch_spool_send::meta_key, $this->mailmeta ); 104 $this->trace->restart(); 105 106 // sending 107 $swiftfailed = $this->send(); 108 109 // results 110 $this->trace->restart(); 111 switch ( true ) 112 { 113 case ( is_array( $swiftfailed ) ) : 114 $ko = array_flip( $swiftfailed ); 115 break; 116 default : 117 $ko = array(); 118 break; 119 } 120 121 if ( $this->mailmeta['try'] ) $this->mailmeta['failed'] = array_merge( $ko, $this->mailmeta['failed'] ); 122 else $this->mailmeta['failed'] = array_merge( $this->mailmeta['failed'], $ko ); 123 } 124 // saving context 125 $this->report['end'] = $this->mailmeta; 126 if ( !MP_Mail_meta::add( $this->mail->id, MailPress_batch_spool_send::meta_key, $this->mailmeta, true ) ) 127 MP_Mail_meta::update( $this->mail->id, MailPress_batch_spool_send::meta_key, $this->mailmeta ); 128 129 // the end for this mail ? 130 if ( $this->mailmeta['sent'] == $this->mailmeta['count'] ) $this->update_mail_status(); 131 if ( $this->mailmeta['try'] >= $this->config['max_retry'] + 1 ) $this->update_mail_status(); 132 } 133 134 // get mailmeta 135 function get_mailmeta() 136 { 137 $mailmeta = MP_Mail_meta::get( $this->mail->id , MailPress_batch_spool_send::meta_key ); 138 139 if ( !$mailmeta ) 140 { 141 $mailmeta = array(); 142 143 if ( is_serialized ( $this->mail->toemail ) ) $mailmeta['count'] = count( unserialize( $this->mail->toemail ) ); 144 else $mailmeta['count'] = 1; 145 146 $mailmeta['sent'] = $mailmeta['try'] = $mailmeta['processed'] = $mailmeta['pass'] = 0; 147 $mailmeta['failed'] = array(); 148 return $mailmeta; 149 } 150 151 $failed = ( isset( $mailmeta['failed'] ) ) ? count( $mailmeta['failed'] ) : 0; 152 153 if ( $mailmeta['sent'] == $mailmeta['count'] ) { $this->update_mail_status(); return false; } 154 155 $processed = $mailmeta['processed']; 156 $count = ( $mailmeta['try'] ) ? $failed : $mailmeta['count']; 157 158 if ( $processed >= $count ) 159 { 160 $mailmeta['processed'] = $mailmeta['pass'] = 0; 161 $mailmeta['try']++; 162 } 163 164 if ( $mailmeta['try'] >= $this->config ['max_retry'] + 1 ) { $this->update_mail_status(); return false; } 165 if ( $mailmeta['try'] && !$failed ) { $this->update_mail_status(); return false; } 166 167 return $mailmeta; 168 } 169 170 // finish 171 function update_mail_status( $failed = 0 ) 172 { 173 if ( is_dir( $this->spool_path ) ) 174 { 175 $directoryIterator = new DirectoryIterator( $this->spool_path ); 176 foreach ( $directoryIterator as $file ) 177 { 178 if ( in_array( $file, array( '.', '..' ) ) ) continue; 179 if ( unlink( "{$this->spool_path}/{$file}" ) ) $failed++; 180 } 181 rmdir( $this->spool_path ); 182 } 183 184 global $wpdb; 185 186 $x = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->mp_mails SET status = 'sent' WHERE id = %d ", $this->mail->id ) ); 187 if ( !$failed ) MP_Mail_meta::delete( $this->mail->id , MailPress_batch_spool_send::meta_key ); 188 } 189 190 // batch sending 191 function send() 192 { 193 return $this->swift_processing(); 194 } 195 196 // send 197 function swift_processing() 198 { 199 new MP_Swift(); 200 201 //¤ Swift spool connection ¤// 202 203 try 204 { 205 // 5.x _ $spool_conn = Swift_SpoolTransport::newInstance( new Swift_FileSpool( $this->spool_path ) ); 206 $spool_conn = new Swift_SpoolTransport( new Swift_FileSpool( $this->spool_path ) ); 207 } 208 catch ( Exception $e ) 209 { 210 if ( !( $e instanceof Swift_SwiftException ) ) throw $e; 211 212 $this->trace->log( 'SWIFTMAILER [ERROR] - ' . "There was an unexpected problem accessing spool :\n\n" . $e->getMessage() . "\n\n" ); 213 return false; 214 } 215 216 //¤ Swift connection ¤// 217 218 if ( !has_filter( 'MailPress_Swift_Connection_type' ) ) new MP_Swift_Connection_smtp(); 219 220 try 221 { 222 $Swift_Connection_type = apply_filters( 'MailPress_Swift_Connection_type', null ); 223 224 $conn = apply_filters( 'MailPress_Swift_Connection_' . $Swift_Connection_type , $this->mail->id, $this->trace ); 225 226 // 5.x _ $swift = Swift_Mailer::newInstance( $conn ); 227 $swift = new Swift_Mailer( $conn ); 228 } 229 catch ( Exception $e ) 230 { 231 if ( !( $e instanceof Swift_SwiftException ) ) throw $e; 232 233 $this->trace->log( 'SWIFTMAILER [ERROR] - ' . "There was a problem connecting with $Swift_Connection_type :\n\n" . $e->getMessage() . "\n\n" ); 234 $this->mysql_connect( __CLASS__ . ' connect error : ' . $Swift_Connection_type ); 235 return false; 236 } 237 238 //¤ Swift sending ... ¤// 239 try 240 { 241 $swift = apply_filters( 'MailPress_swift_registerPlugin', $swift ); 242 243 $this->mysql_disconnect( __CLASS__ ); 244 245 //¤ swift flushing queues ¤// 246 $spool = $spool_conn->getSpool(); 247 $spool->setMessageLimit( $this->config['per_pass'] ); 248 $spool->setTimeLimit( $this->config['time_limit'] ); 249 $this->mailmeta['sent'] += $spool->flushQueue( $conn, $failures ); 250 } 251 catch ( Exception $e ) 252 { 253 if ( !( $e instanceof Swift_SwiftException ) ) throw $e; 254 255 $this->trace->log( 'SWIFTMAILER [ERROR] - ' . "There was a problem sending with $Swift_Connection_type :\n\n" . $e->getMessage() . "\n\n" ); 256 $this->mysql_connect( __CLASS__ . ' sending error : ' . $Swift_Connection_type ); 257 return false; 258 } 259 260 $this->mysql_connect( __CLASS__ ); 261 262 return $failures; 263 } 264 265 //reports 266 function alldone() 267 { 268 $this->report['header2'] = 'Batch Spool Report'; 269 $this->report['alldone'] = true; 270 } 271 272 function write_report( $zz = 12 ) 273 { 274 $order = array( 'sent', 'processed', 'try', 'pass', 'failed' ); 275 $unsets = array( 'count', 'per_pass', 'max_try' ); 276 $t = ( count( $order ) + 1 ) * ( $zz + 1 ) -1; 277 278 foreach( $this->report as $k => $v ) 279 { 280 switch ( $k ) 281 { 282 case 'header' : 283 $this->trace->log( '!' . str_repeat( '-', $t ) . '!' ); 284 $l = strlen( $v ); 285 $this->trace->log( '!' . str_repeat( ' ', 5 ) . $v . str_repeat( ' ', $t - 5 - $l ) . '!' ); 286 $this->trace->log( '!' . str_repeat( ' ', 5 ) . $this->spool_path ); 287 $this->trace->log( '!' . str_repeat( '-', $t ) . '!' ); 288 $s = '! !'; 289 foreach( $order as $o ) 290 { 291 $l = strlen( $o ); 292 $s .= " $o" . str_repeat( ' ', $zz - $l -1 ) . '!'; 293 } 294 $this->trace->log( $s ); 295 $this->trace->log( '!' . str_repeat( '-', $t ) . '!' ); 296 break; 297 case 'header2' : 298 $t = count( $order ) * 15; 299 $this->trace->log( '!' . str_repeat( '-', $t ) . '!' ); 300 $l = strlen( $v ); 301 $this->trace->log( '!' . str_repeat( ' ', 5 ) . $v . str_repeat( ' ', $t - 5 - $l ) . '!' ); 302 $this->trace->log( '!' . str_repeat( '-', $t ) . '!' ); 303 break; 304 case 'alldone' : 305 $t = count( $order ) * 15; 306 $v = ' *** ALL DONE *** *** ALL DONE *** *** ALL DONE *** '; 307 $l = strlen( $v ); 308 $this->trace->log( '!' . str_repeat( ' ', 5 ) . $v . str_repeat( ' ', $t -15 - $l ) . '!' ); 309 break; 310 case 'locked' : 311 $t = count( $order ) * 15; 312 $v = " locked : $v "; 313 $l = strlen( $v ); 314 $this->trace->log( '!' . str_repeat( ' ', 5 ) . $v . str_repeat( ' ', $t -10 - $l ) . '!' ); 315 $this->trace->log( '!' . str_repeat( '-', $t ) . '!' ); 316 $this->trace->log( '!' . str_repeat( '-', $t ) . '!' ); 317 break; 318 case 'end' : 319 $this->trace->log( '!' . str_repeat( '-', $t ) . '!' ); 320 default : 321 foreach ( $unsets as $unset ) unset( $v[$unset] ); 322 $c = 0; 323 $l = strlen( $k ); 324 $s = "! $k" . str_repeat( ' ', $zz - $l -1 ) . '!'; 325 foreach( $order as $o ) 326 { 327 if ( isset( $v[$o] ) ) { if ( is_array( $v[$o] ) ) $v[$o] = count( $v[$o] ); $l = strlen( $v[$o] ); $s .= str_repeat( ' ', $zz - $l -1 ) . $v[$o] . ' !'; unset( $v[$o] ); $c++;} 328 } 329 if ( $c < count( $order ) ) do { $s.= str_repeat( ' ', $zz ) . '!'; $c++;} while( $c < count( $order ) ); 330 $this->trace->log( $s ); 331 if ( !empty( $v ) ) foreach( $v as $a => $b ) $this->trace->log( "$a $b" ); 332 break; 333 } 334 } 335 $this->trace->log( '!' . str_repeat( '-', $t ) . '!' ); 336 $this->report = array(); 337 } 338 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Jan 28 00:07:10 2019 | Cross-referenced by PHPXref 0.7.1 |