$batch -> data = $data;
} else {
foreach ($data as $dkey => $dval) {
if (empty($dval['error'])) {
unset($data[$dkey]);
}
}
$batch -> data = $data;
}
if (!empty($batch -> data)) {
$batches[] = $batch;
}
} else {
$batches[] = $batch;
}
if ($this -> memory_exceeded()) {
$this -> memory_exceeded = true;
return $batches;
}
}
}
return $batches;
}
function get_queued_count($key = null) {
global $wpdb, $wpMail;
$count = 0;
$table = $wpdb->options;
$column = 'option_name';
$key_column = 'option_id';
$value_column = 'option_value';
$key = $this->identifier . '_batch_' . "%";
$query = $wpdb -> prepare( "
SELECT {$value_column}
FROM {$table}
WHERE {$column} LIKE %s
ORDER BY {$key_column} ASC", $key);
$query = "SELECT " . $value_column . " FROM " . $table . " WHERE " . $column . " LIKE '" . $key . "' ORDER BY " . $key_column . " ASC";
$results = $wpdb -> get_results($query);
foreach ($results as $result) {
$batchcount = preg_match("/^a:([0-9]+):.*/si", $result -> {$value_column}, $matches);
$batchcount = $matches[1];
$count += $batchcount;
if ($this -> memory_exceeded()) {
$count = (string) $count . '+';
break;
}
}
return $count;
}
function unlock() {
$this -> unlock_process();
return true;
}
function cancel_all_processes() {
global $wpdb;
$table = $wpdb -> options;
$key = $this -> identifier . '_batch_%';
$query = "DELETE FROM `" . $table . "` WHERE `option_name` LIKE '" . $key . "'";
$wpdb -> query($query);
if ($batches = $this -> get_batches(true)) {
delete_transient('newsletters_queue_count');
foreach ($batches as $batch) {
$this -> delete($batch -> key);
}
}
parent::complete();
return true;
}
function do_specific_item($item = null, $override = false) {
$result = $this -> task($item, true);
return $result;
}
/**
* Task
*
* Override this method to perform any actions required on each
* queue item. Return the modified item for further processing
* in the next pass through. Or, return false to remove the
* item from the queue.
*
* @param mixed $item Queue item to iterate over
*
* @return mixed
*/
function task( $item = null, $override = false ) {
// Make the original body a closure so we can feed it to our helper.
$task_body = function () use ( $item, $override ) {
global $wpMail, $wpdb, $Html, $Db, $Email, $Subscriber, $SubscribersList;
// Respect the “pause” switch.
if ( empty( $override ) ) {
$queue_status = $wpMail->get_option( 'queue_status' );
if ( 'pause' === $queue_status ) {
return $item; // keep it in the batch
}
}
// Try to send the queued e-mail.
if ( $wpMail->send_queued_email( $item ) ) {
return false; // ← success, remove from batch
}
// Sending failed – keep a note and re-queue.
global $mailerrors;
$item['error'] = strip_tags( $mailerrors );
$this->push_to_queue( $item );
return false; // remove from *current* batch
};
// Run the body safely.
return $this -> wpml_safe_task( $task_body, $item, $this );
}
/**
* Handle cron healthcheck
*
* Restart the background process if not already running
* and data exists in the queue.
*/
public function handle_cron_healthcheck() {
if ( $this->is_process_running() ) {
// Background process already running.
echo esc_html_e('The process is already running') . '
';
return;
}
$queue_status = get_option('wpmlqueue_status');
if (!empty($queue_status) && $queue_status == "pause") {
echo esc_html_e('The queue is currently paused') . '
';
return;
}
if ( $this->is_queue_empty() ) {
echo esc_html_e('The queue is currently empty') . '
';
$this -> clear_scheduled_event();
return;
}
$this->handle();
}
/**
* Schedule cron healthcheck
*
* @access public
* @param mixed $schedules Schedules.
* @return mixed
*/
public function schedule_cron_healthcheck( $schedules ) {
$interval = apply_filters($this -> identifier . '_cron_interval', 2);
if ( property_exists( $this, 'cron_interval' ) ) {
$interval = apply_filters($this -> identifier . '_cron_interval', $this -> cron_interval_identifier);
}
$scheduleinterval = get_option('wpmlscheduleinterval');
if (!empty($schedules[$scheduleinterval])) {
$schedules[$this -> identifier . '_cron_interval'] = $schedules[$scheduleinterval];
} else {
$seconds = $this->translate_scheule_interval($scheduleinterval);
// Adds every 2 minutes to the existing schedules.
$schedules[$this -> identifier . '_cron_interval'] = $seconds;
}
return $schedules;
}
public function scheduling() {
$this -> clear_scheduled_event();
$this -> schedule_event();
}
public function clear_scheduled_event() {
$timestamp = wp_next_scheduled( $this->cron_hook_identifier );
if ( $timestamp ) {
wp_unschedule_event( $timestamp, $this->cron_hook_identifier );
}
}
protected function memory_exceeded() {
// override the memory check for now
return false;
}
/**
* Handle
*
* Pass each queue item to the task handler, while remaining
* within server memory and time limit constraints.
*/
protected function handle() {
$scheduleintervalseconds = get_option('wpmlscheduleintervalseconds');
$this -> queue_lock_time = (empty($scheduleintervalseconds)) ? (MINUTE_IN_SECONDS * 2) : $scheduleintervalseconds;
$this -> lock_process();
//$emailsperinterval = round((int) get_option('wpmlemailsperinterval') / 3);
$emailsperinterval = (int) get_option('wpmlemailsperinterval');
$e = 0;
$successful = 0;
do {
$batch = $this->get_batch();
foreach ( $batch->data as $key => $value ) {
$task = $this -> task($value);
if ( false !== $task ) {
$batch -> data[ $key ] = $task;
} else {
unset( $batch->data[ $key ] );
$successful++;
}
// Update or delete current batch.
if (!empty($batch -> data)) {
$this -> update( $batch->key, $batch->data );
// Comment out it was already updated above.
} else {
$this -> delete($batch->key);
}
$e++;
if ( $this->time_exceeded() || $this->memory_exceeded() || $e >= $emailsperinterval) {
// Batch limits reached.
break 2;
}
}
} while ( (! $this->time_exceeded() && ! $this->memory_exceeded() && ! $this->is_queue_empty()) && $e < $emailsperinterval);
// save and dispatch any previous error messages in the queue
$this -> save();
$this -> reset_data();
$this -> unlock_process();
// Start next batch or complete process.
if ( ! $this->is_queue_empty() ) {
$this->dispatch();
} else {
$this->complete();
}
echo sprintf(__('%s emails have been sent out'), $successful) . '
';
return true;
}
/**
* Dispatch
*
* @access public
* @return void
*/
public function dispatch() {
// Schedule the cron healthcheck.
$this -> schedule_event();
// Perform remote post.
//return parent::dispatch();
}
/**
* Get memory limit
*
* @return int
*/
protected function get_memory_limit() {
if ( function_exists( 'ini_get' ) ) {
$memory_limit = ini_get( 'memory_limit' );
} else {
// Sensible default.
$memory_limit = '1024M';
}
if (empty($memory_limit) || -1 == (int) $memory_limit ) {
// Unlimited, set to 32GB.
$memory_limit = '32000M';
}
return intval( $memory_limit ) * 1024 * 1024;
}
/**
* Complete
*
* Override if applicable, but ensure that the below actions are
* performed, or, call parent::complete().
*/
protected function complete() {
global $wpMail;
$wpMail -> admin_notification_queue_complete();
parent::complete();
// Show notice to user or perform some other arbitrary task...
}
public function debug($var = array()) {
echo '
' . print_r($var, true) . ''; } } }