PageRenderTime 74ms CodeModel.GetById 2ms app.highlight 62ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/newsletter/plugin.php

https://github.com/dedavidd/piratenpartij.nl
PHP | 1240 lines | 837 code | 239 blank | 164 comment | 202 complexity | 7c9bf726a39385cc0ec4c70bef45b570 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2
   3/*
   4  Plugin Name: Newsletter
   5  Plugin URI: http://www.satollo.net/plugins/newsletter
   6  Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="http://www.satollo.net/plugins/newsletter#update">this page</a> to know what's changed.</strong>
   7  Version: 3.5.9
   8  Author: Stefano Lissa
   9  Author URI: http://www.satollo.net
  10  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
  11
  12  Copyright 2009-2014 Stefano Lissa (email: stefano@satollo.net, web: http://www.satollo.net)
  13 */
  14
  15// Useed as dummy parameter on css and js links
  16define('NEWSLETTER_VERSION', '3.5.9');
  17
  18global $wpdb, $newsletter;
  19
  20//@include_once WP_CONTENT_DIR . '/extensions/newsletter/config.php';
  21
  22if (!defined('NEWSLETTER_EMAILS_TABLE'))
  23    define('NEWSLETTER_EMAILS_TABLE', $wpdb->prefix . 'newsletter_emails');
  24
  25if (!defined('NEWSLETTER_USERS_TABLE'))
  26    define('NEWSLETTER_USERS_TABLE', $wpdb->prefix . 'newsletter');
  27
  28if (!defined('NEWSLETTER_STATS_TABLE'))
  29    define('NEWSLETTER_STATS_TABLE', $wpdb->prefix . 'newsletter_stats');
  30
  31// Do not use basename(dirname()) since on activation the plugin is sandboxed inside a function
  32define('NEWSLETTER_SLUG', 'newsletter');
  33
  34define('NEWSLETTER_DIR', WP_PLUGIN_DIR . '/' . NEWSLETTER_SLUG);
  35define('NEWSLETTER_INCLUDES_DIR', WP_PLUGIN_DIR . '/' . NEWSLETTER_SLUG . '/includes');
  36
  37// Almost obsolete but the first two must be kept for compatibility with modules
  38define('NEWSLETTER_URL', WP_PLUGIN_URL . '/newsletter');
  39define('NEWSLETTER_EMAIL_URL', NEWSLETTER_URL . '/do/view.php');
  40
  41define('NEWSLETTER_SUBSCRIPTION_POPUP_URL', NEWSLETTER_URL . '/do/subscription-popup.php');
  42define('NEWSLETTER_SUBSCRIBE_URL', NEWSLETTER_URL . '/do/subscribe.php');
  43define('NEWSLETTER_SUBSCRIBE_POPUP_URL', NEWSLETTER_URL . '/do/subscribe-popup.php');
  44define('NEWSLETTER_PROFILE_URL', NEWSLETTER_URL . '/do/profile.php');
  45define('NEWSLETTER_SAVE_URL', NEWSLETTER_URL . '/do/save.php');
  46define('NEWSLETTER_CONFIRM_URL', NEWSLETTER_URL . '/do/confirm.php');
  47define('NEWSLETTER_CHANGE_URL', NEWSLETTER_URL . '/do/change.php');
  48define('NEWSLETTER_UNLOCK_URL', NEWSLETTER_URL . '/do/unlock.php');
  49define('NEWSLETTER_UNSUBSCRIBE_URL', NEWSLETTER_URL . '/do/unsubscribe.php');
  50define('NEWSLETTER_UNSUBSCRIPTION_URL', NEWSLETTER_URL . '/do/unsubscription.php');
  51
  52if (!defined('NEWSLETTER_LIST_MAX'))
  53    define('NEWSLETTER_LIST_MAX', 20);
  54
  55if (!defined('NEWSLETTER_PROFILE_MAX'))
  56    define('NEWSLETTER_PROFILE_MAX', 20);
  57
  58if (!defined('NEWSLETTER_FORMS_MAX'))
  59    define('NEWSLETTER_FORMS_MAX', 10);
  60
  61if (!defined('NEWSLETTER_CRON_INTERVAL'))
  62    define('NEWSLETTER_CRON_INTERVAL', 300);
  63
  64if (!defined('NEWSLETTER_HEADER'))
  65    define('NEWSLETTER_HEADER', true);
  66
  67// Force the whole system log level to this value
  68//define('NEWSLETTER_LOG_LEVEL', 4);
  69
  70require_once NEWSLETTER_INCLUDES_DIR . '/logger.php';
  71require_once NEWSLETTER_INCLUDES_DIR . '/store.php';
  72require_once NEWSLETTER_INCLUDES_DIR . '/module.php';
  73require_once NEWSLETTER_INCLUDES_DIR . '/themes.php';
  74
  75class Newsletter extends NewsletterModule {
  76
  77    // Limits to respect to avoid memory, time or provider limits
  78    var $time_start;
  79    var $time_limit;
  80    var $email_limit = 10; // Per run, every 5 minutes
  81    var $limits_set = false;
  82    var $max_emails = 20;
  83
  84    /**
  85     * @var PHPMailer
  86     */
  87    var $mailer;
  88    // Message shown when the interaction is inside a WordPress page
  89    var $message;
  90    var $user;
  91    var $error;
  92    var $theme;
  93    // Theme autocomposer variables
  94    var $theme_max_posts;
  95    var $theme_excluded_categories; // comma separated ids (eventually negative to exclude)
  96    var $theme_posts; // WP_Query object
  97    // Secret key to create a unique log file name (and may be other)
  98    var $lock_found = false;
  99    static $instance;
 100
 101    /**
 102     * @return Newsletter
 103     */
 104    static function instance() {
 105        if (self::$instance == null) {
 106            self::$instance = new Newsletter();
 107        }
 108        return self::$instance;
 109    }
 110
 111    function __construct() {
 112
 113
 114        $this->time_start = time();
 115
 116        // Here because the upgrade is called by the parent constructor and uses the scheduler
 117        add_filter('cron_schedules', array($this, 'hook_cron_schedules'), 1000);
 118
 119        parent::__construct('main', '1.2.2');
 120
 121        $max = $this->options['scheduler_max'];
 122        if (!is_numeric($max))
 123            $max = 100;
 124        $this->max_emails = max(floor($max / 12), 1);
 125
 126        add_action('init', array($this, 'hook_init'));
 127        add_action('newsletter', array($this, 'hook_newsletter'), 1);
 128        add_action('newsletter_check_versions', array($this, 'hook_check_versions'), 99);
 129
 130
 131        // This specific event is created by "Feed by mail" panel on configuration
 132        add_action('shutdown', array($this, 'hook_shutdown'));
 133
 134        if (defined('DOING_CRON') && DOING_CRON)
 135            return;
 136
 137        // TODO: Meditation on how to use those ones...
 138        register_activation_hook(__FILE__, array($this, 'hook_activate'));
 139        //register_deactivation_hook(__FILE__, array(&$this, 'hook_deactivate'));
 140
 141        add_action('admin_init', array($this, 'hook_admin_init'));
 142
 143        add_action('wp_head', array($this, 'hook_wp_head'));
 144
 145        add_shortcode('newsletter_lock', array($this, 'shortcode_newsletter_lock'));
 146        add_filter('the_content', array($this, 'hook_the_content'), 99);
 147        add_shortcode('newsletter_profile', array($this, 'shortcode_newsletter_profile'));
 148
 149        if (is_admin()) {
 150            add_action('admin_head', array($this, 'hook_admin_head'));
 151
 152            // Protection against strange schedule removal on some installations
 153            if (!wp_next_scheduled('newsletter') && !defined('WP_INSTALLING')) {
 154                wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
 155            }
 156        }
 157    }
 158
 159    function hook_activate() {
 160        // Ok, why? When the plugin is not active WordPress may remove the scheduled "newsletter" action because
 161        // the every-five-minutes schedule named "newsletter" is not present.
 162        // Since the activation does not forces an upgrade, that schedule must be reactivated here. It is activated on
 163        // the upgrade method as well for the user which upgrade the plugin without deactivte it (many).
 164        if (!wp_next_scheduled('newsletter')) {
 165            wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
 166        }
 167    }
 168
 169    function upgrade() {
 170        global $wpdb, $charset_collate;
 171
 172        parent::upgrade();
 173
 174        $this->upgrade_query("create table if not exists " . NEWSLETTER_EMAILS_TABLE . " (id int auto_increment, primary key (id)) $charset_collate");
 175        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column message longtext");
 176        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column message_text longtext");
 177        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column subject varchar(255) not null default ''");
 178        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column type varchar(50) not null default ''");
 179        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column created timestamp not null default current_timestamp");
 180
 181        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column status enum('new','sending','sent','paused') not null default 'new'");
 182
 183        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column total int not null default 0");
 184        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column last_id int not null default 0");
 185        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column sent int not null default 0");
 186        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column send_on int not null default 0");
 187        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column track tinyint not null default 0");
 188        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column editor tinyint not null default 0");
 189        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column sex char(1) not null default ''");
 190        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " change column sex sex char(1) not null default ''");
 191
 192        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column query text");
 193        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column preferences text");
 194        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " add column options longtext");
 195
 196        // Cleans up old installations
 197        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " drop column name");
 198        $this->upgrade_query("drop table if exists " . $wpdb->prefix . "newsletter_work");
 199        $this->upgrade_query("alter table " . NEWSLETTER_EMAILS_TABLE . " convert to character set utf8");
 200
 201        // Some setting check to avoid the common support request for mis-configurations
 202        $options = $this->get_options();
 203
 204        if (empty($options['sender_email'])) {
 205            // That code was taken from WordPress
 206            $sitename = strtolower($_SERVER['SERVER_NAME']);
 207            if (substr($sitename, 0, 4) == 'www.')
 208                $sitename = substr($sitename, 4);
 209            // WordPress build an address in the same way using wordpress@...
 210            $options['sender_email'] = 'newsletter@' . $sitename;
 211            $this->save_options($options);
 212        }
 213
 214        if (empty($options['scheduler_max']) || !is_numeric($options['scheduler_max'])) {
 215            $options['scheduler_max'] = 100;
 216            $this->save_options($options);
 217        }
 218
 219        if (empty($options['api_key'])) {
 220            $options['api_key'] = self::get_token();
 221            $this->save_options($options);
 222        }
 223
 224        if (empty($options['scheduler_max'])) {
 225            $options['scheduler_max'] = 100;
 226            $this->save_options($options);
 227        }
 228
 229        wp_clear_scheduled_hook('newsletter');
 230        wp_schedule_event(time() + 30, 'newsletter', 'newsletter');
 231
 232        wp_clear_scheduled_hook('newsletter_update');
 233        wp_clear_scheduled_hook('newsletter_check_versions');
 234        wp_schedule_event(time() + 30, 'newsletter_weekly', 'newsletter_check_versions');
 235
 236        wp_mkdir_p(WP_CONTENT_DIR . '/extensions/newsletter');
 237        wp_mkdir_p(WP_CONTENT_DIR . '/cache/newsletter');
 238
 239        //wp_clear_scheduled_hook('newsletter_updates_run');
 240        wp_clear_scheduled_hook('newsletter_statistics_version_check');
 241        wp_clear_scheduled_hook('newsletter_reports_version_check');
 242        wp_clear_scheduled_hook('newsletter_feed_version_check');
 243        wp_clear_scheduled_hook('newsletter_popup_version_check');
 244
 245
 246        return true;
 247    }
 248
 249    function admin_menu() {
 250        // This adds the main menu page
 251        add_menu_page('Newsletter', 'Newsletter', ($this->options['editor'] == 1) ? 'manage_categories' : 'manage_options', 'newsletter_main_index');
 252
 253        $this->add_menu_page('index', 'Welcome');
 254        $this->add_menu_page('main', 'Configuration');
 255        $this->add_menu_page('diagnostic', 'Diagnostic');
 256    }
 257
 258    /**
 259     * Returns a set of warnings about this installtion the suser should be aware of. Return an empty string
 260     * if there are no warnings.
 261     */
 262    function warnings() {
 263        $warnings = '';
 264        $x = wp_next_scheduled('newsletter');
 265        if ($x === false) {
 266            $warnings .= 'The delivery engine is off (it should never be off). Deactivate and reactivate the plugin. Thank you.<br>';
 267        } else if (time() - $x > 900) {
 268            $warnings .= 'The cron system seems not running correctly. See <a href="http://www.satollo.net/how-to-make-the-wordpress-cron-work" target="_blank">this page</a> for more information.<br>';
 269        }
 270
 271        if (!empty($warnings)) {
 272            echo '<div id="#newsletter-warnings">';
 273            echo $warnings;
 274            echo '</div>';
 275        }
 276    }
 277
 278    function hook_init() {
 279        global $cache_stop, $hyper_cache_stop, $wpdb;
 280
 281        if (is_admin()) {
 282            if ($this->is_admin_page()) {
 283                wp_enqueue_script('jquery-ui-tabs');
 284                wp_enqueue_script('media-upload');
 285                wp_enqueue_script('thickbox');
 286                wp_enqueue_style('thickbox');
 287            }
 288        }
 289
 290        $action = isset($_REQUEST['na']) ? $_REQUEST['na'] : '';
 291        if (empty($action) || is_admin())
 292            return;
 293
 294        // TODO: Remove!
 295        $cache_stop = true;
 296        $hyper_cache_stop = true;
 297
 298        if ($action == 'of') {
 299            echo $this->subscription_form('os');
 300            die();
 301        }
 302
 303        if ($action == 'fu') {
 304            $user = $this->check_user();
 305            if ($user == null)
 306                die('No user');
 307            $wpdb->query("update " . $wpdb->prefix . "newsletter set followup=2 where id=" . $user->id);
 308            $options_followup = get_option('newsletter_followup');
 309            $this->message = $options_followup['unsubscribed_text'];
 310            return;
 311        }
 312    }
 313
 314    function is_admin_page() {
 315        // TODO: Use the module list to detect that...
 316        if (!isset($_GET['page']))
 317            return false;
 318        $page = $_GET['page'];
 319        return strpos($page, 'newsletter_') === 0 || strpos($page, 'newsletter-statistics/') === 0 || strpos($page, 'newsletter/') === 0 ||
 320                strpos($page, 'newsletter-updates/') === 0 || strpos($page, 'newsletter-flows/') === 0;
 321    }
 322
 323    function hook_admin_init() {
 324        
 325    }
 326
 327    function hook_admin_head() {
 328        if ($this->is_admin_page()) {
 329            echo '<link type="text/css" rel="stylesheet" href="' . plugins_url('newsletter') . '/admin.css?' . NEWSLETTER_VERSION . '"/>';
 330            echo '<script src="' . plugins_url('newsletter') . '/admin.js?' . NEWSLETTER_VERSION . '"></script>';
 331        }
 332    }
 333
 334    function hook_wp_head() {
 335        if (!empty($this->options['css'])) {
 336            echo "<style type='text/css'>\n";
 337            echo $this->options['css'];
 338            echo "</style>";
 339        }
 340
 341        // TODO: move on subscription module
 342        $profile_options = get_option('newsletter_profile');
 343        if (!empty($profile_options['style'])) {
 344            echo '<link href="' . NewsletterSubscription::instance()->get_style_url($profile_options['style']) . '" type="text/css" rel="stylesheet">';
 345        }
 346        if (!empty($profile_options['widget_style'])) {
 347            echo '<link href="' . NewsletterSubscription::instance()->get_style_url($profile_options['widget_style']) . '" type="text/css" rel="stylesheet">';
 348        }
 349    }
 350
 351    function relink($text, $email_id, $user_id) {
 352        return NewsletterStatistics::instance()->relink($text, $email_id, $user_id);
 353    }
 354
 355    function hook_check_versions() {
 356        //$this->logger->info('Checking for new versions');
 357        $url = 'http://www.satollo.net/wp-content/plugins/file-commerce-pro/version.php?f=';
 358        $modules = array(
 359            'reports' => 34,
 360            'feed' => 35,
 361            'followup' => 37,
 362            'facebook' => 41,
 363            'sendgrid' => 40,
 364            'popup' => 43,
 365            'mandrill' => 44,
 366            'mailjet' => 38);
 367
 368        foreach ($modules as $name => $id) {
 369            $version = @file_get_contents($url . $id);
 370            if ($version) {
 371                update_option('newsletter_' . $name . '_available_version', $version);
 372            }
 373        }
 374    }
 375
 376    /**
 377     * Runs every 5 minutes and look for emails that need to be processed.
 378     */
 379    function hook_newsletter() {
 380        global $wpdb;
 381
 382        $this->logger->debug('hook_newsletter> Start');
 383
 384        // Do not accept job activation before at least 4 minutes are elapsed from the last run.
 385        if (!$this->check_transient('engine', NEWSLETTER_CRON_INTERVAL))
 386            return;
 387
 388        // Retrieve all email in "sending" status
 389        $emails = $wpdb->get_results("select * from " . NEWSLETTER_EMAILS_TABLE . " where status='sending' and send_on<" . time() . " order by id asc");
 390        $this->logger->debug('hook_newsletter> Emails found in sending status: ' . count($emails));
 391        foreach ($emails as &$email) {
 392            $this->logger->debug('hook_newsletter> Sending email ' . $email->id);
 393            if (!$this->send($email))
 394                break;
 395        }
 396        // Remove the semaphore so the delivery engine can be activated again
 397        $this->delete_transient('engine');
 398
 399        $this->logger->debug('hook_newsletter> End');
 400    }
 401
 402    /**
 403     * Sends an email to targeted users ot to users passed on. If a list of users is given (usually a list of test users)
 404     * the query inside the email to retrieve users is not used.
 405     *
 406     * @global type $wpdb
 407     * @global type $newsletter_feed
 408     * @param type $email
 409     * @param array $users
 410     * @return boolean True if the proccess completed, false if limits was reached. On false the caller should no continue to call it with other emails.
 411     */
 412    function send($email, $users = null) {
 413        global $wpdb;
 414
 415        if (is_array($email))
 416            $email = (object) $email;
 417
 418        // This stops the update of last_id and sent fields since it's not a scheduled delivery but a test.
 419        $test = $users != null;
 420
 421        if ($users == null) {
 422            if (empty($email->query)) {
 423                $email->query = "select * from " . NEWSLETTER_USERS_TABLE . " where status='C'";
 424            }
 425            $query = $email->query . " and id>" . $email->last_id . " order by id limit " . $this->max_emails;
 426            $users = $wpdb->get_results($query);
 427
 428            // If there was a database error, do nothing
 429            if ($wpdb->last_error) {
 430                $this->logger->fatal($wpdb->last_error);
 431                return;
 432            }
 433
 434            if (empty($users)) {
 435                $this->logger->info('No more users');
 436                $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set status='sent', total=sent where id=" . $email->id . " limit 1");
 437                return true;
 438            }
 439        }
 440
 441        foreach ($users as &$user) {
 442
 443            // Before try to send, check the limits.
 444            if (!$test && $this->limits_exceeded())
 445                return false;
 446
 447            $headers = array('List-Unsubscribe' => '<' . NEWSLETTER_UNSUBSCRIBE_URL . '?nk=' . $user->id . '-' . $user->token . '>');
 448            $headers['Precedence'] = 'bulk';
 449            $headers['X-Newsletter-Email-Id'] = $email->id;
 450            
 451
 452            if (!$test) {
 453                $wpdb->query("update " . NEWSLETTER_EMAILS_TABLE . " set sent=sent+1, last_id=" . $user->id . " where id=" . $email->id . " limit 1");
 454            }
 455
 456            $m = $this->replace($email->message, $user, $email->id);
 457            $mt = $this->replace($email->message_text, $user, $email->id);
 458
 459
 460            if ($email->track == 1)
 461                $m = $this->relink($m, $email->id, $user->id);
 462
 463            $s = $this->replace($email->subject, $user);
 464
 465            if (isset($user->wp_user_id) && $user->wp_user_id != 0) {
 466                $this->logger->debug('Have wp_user_id: ' . $user->wp_user_id);
 467                // TODO: possibly name extraction
 468                $wp_user_email = $wpdb->get_var($wpdb->prepare("select user_email from $wpdb->users where id=%d limit 1", $user->wp_user_id));
 469                if (!empty($wp_user_email)) {
 470                    $user->email = $wp_user_email;
 471                    $this->logger->debug('Email replaced with: ' . $user->email);
 472                } else {
 473                    $this->logger->debug('WP user has not an email?!');
 474                }
 475            }
 476
 477            $this->mail($user->email, $s, array('html' => $m, 'text' => $mt), $headers);
 478
 479            $this->email_limit--;
 480        }
 481
 482        return true;
 483    }
 484
 485    /**
 486     * Probably obsolete.
 487     */
 488    function execute($text, $user = null) {
 489        global $wpdb;
 490        ob_start();
 491        $r = eval('?' . '>' . $text);
 492        if ($r === false) {
 493            $this->error = 'Error while executing a PHP expression in a message body. See log file.';
 494            $this->log('Error on execution of ' . $text, 1);
 495            ob_end_clean();
 496            return false;
 497        }
 498
 499        return ob_get_clean();
 500    }
 501
 502    /**
 503     * This function checks is, during processing, we are getting to near to system limits and should stop any further
 504     * work (when returns true).
 505     */
 506    function limits_exceeded() {
 507        global $wpdb;
 508
 509        if (!$this->limits_set) {
 510            $this->logger->debug('limits_exceeded> Setting the limits for the first time');
 511
 512            $max_time = NEWSLETTER_CRON_INTERVAL;
 513
 514            // Actually it should be set on startup, anyway the scripts use as time base the startup time
 515            if (!empty($this->options['php_time_limit'])) {
 516                @set_time_limit((int) $this->options['php_time_limit']);
 517            } else if (defined('NEWSLETTER_MAX_EXECUTION_TIME')) {
 518                @set_time_limit(NEWSLETTER_MAX_EXECUTION_TIME);
 519            }
 520
 521            $max_time = (int) (@ini_get('max_execution_time') * 0.95);
 522            if ($max_time == 0 || $max_time > NEWSLETTER_CRON_INTERVAL)
 523                $max_time = (int) (NEWSLETTER_CRON_INTERVAL * 0.95);
 524
 525            $this->time_limit = $this->time_start + $max_time;
 526
 527            $this->logger->info('limits_exceeded> Max time set to ' . $max_time);
 528
 529            $max = $this->options['scheduler_max'];
 530            if (!is_numeric($max))
 531                $max = 100;
 532            $this->email_limit = max(floor($max / 12), 1);
 533            $this->logger->debug('limits_exceeded> Max number of emails can send: ' . $this->email_limit);
 534
 535            $wpdb->query("set session wait_timeout=300");
 536            // From default-constants.php
 537            if (function_exists('memory_get_usage') && ( (int) @ini_get('memory_limit') < 128 ))
 538                @ini_set('memory_limit', '256M');
 539
 540            $this->limits_set = true;
 541        }
 542
 543        // The time limit is set on constructor, since it has to be set as early as possible
 544        if (time() > $this->time_limit) {
 545            $this->logger->info('limits_exceeded> Max execution time limit reached');
 546            return true;
 547        }
 548
 549        if ($this->email_limit <= 0) {
 550            $this->logger->info('limits_exceeded> Max emails limit reached');
 551            return true;
 552        }
 553        return false;
 554    }
 555
 556    /**
 557     *
 558     * @param string $to
 559     * @param string $subject
 560     * @param string|array $message
 561     * @param type $headers
 562     * @return boolean
 563     */
 564    var $mail_method = null;
 565
 566    function register_mail_method($callable) {
 567        $this->mail_method = $callable;
 568    }
 569
 570    function mail($to, $subject, $message, $headers = null) {
 571
 572        $this->logger->debug('mail> To: ' . $to);
 573        $this->logger->debug('mail> Subject: ' . $subject);
 574        if (empty($subject)) {
 575            $this->logger->debug('mail> Subject empty, skipped');
 576            return true;
 577        }
 578
 579        // Message carrige returns and line feeds clean up
 580        if (!is_array($message)) {
 581            $message = str_replace("\r\n", "\n", $message);
 582            $message = str_replace("\r", "\n", $message);
 583            $message = str_replace("\n", "\r\n", $message);
 584        } else {
 585            if (!empty($message['text'])) {
 586                $message['text'] = str_replace("\r\n", "\n", $message['text']);
 587                $message['text'] = str_replace("\r", "\n", $message['text']);
 588                $message['text'] = str_replace("\n", "\r\n", $message['text']);
 589            }
 590
 591            if (!empty($message['html'])) {
 592                $message['html'] = str_replace("\r\n", "\n", $message['html']);
 593                $message['html'] = str_replace("\r", "\n", $message['html']);
 594                $message['html'] = str_replace("\n", "\r\n", $message['html']);
 595            }
 596        }
 597
 598        if ($this->mail_method != null) {
 599            return call_user_func($this->mail_method, $to, $subject, $message, $headers);
 600        }
 601
 602        if ($this->mailer == null)
 603            $this->mailer_init();
 604
 605        // Simple message is asumed to be html
 606        if (!is_array($message)) {
 607            $this->mailer->IsHTML(true);
 608            $this->mailer->Body = $message;
 609        } else {
 610            // Only html is present?
 611            if (empty($message['text'])) {
 612                $this->mailer->IsHTML(true);
 613                $this->mailer->Body = $message['html'];
 614            }
 615            // Only text is present?
 616            else if (empty($message['html'])) {
 617                $this->mailer->IsHTML(false);
 618                $this->mailer->Body = $message['text'];
 619            } else {
 620                $this->mailer->IsHTML(true);
 621                $this->mailer->Body = $message['html'];
 622                $this->mailer->AltBody = $message['text'];
 623            }
 624        }
 625
 626        $this->mailer->Subject = $subject;
 627
 628        $this->mailer->ClearCustomHeaders();
 629        if (!empty($headers)) {
 630            foreach ($headers as $key => $value) {
 631                $this->mailer->AddCustomHeader($key . ': ' . $value);
 632            }
 633        }
 634
 635        $this->mailer->ClearAddresses();
 636        $this->mailer->AddAddress($to);
 637        $this->mailer->Send();
 638
 639        if ($this->mailer->IsError()) {
 640            $this->logger->error('mail> ' . $this->mailer->ErrorInfo);
 641            // If the error is due to SMTP connection, the mailer cannot be reused since it does not clean up the connection
 642            // on error.
 643            $this->mailer = null;
 644            return false;
 645        }
 646        return true;
 647    }
 648
 649    function mailer_init() {
 650        require_once ABSPATH . WPINC . '/class-phpmailer.php';
 651        require_once ABSPATH . WPINC . '/class-smtp.php';
 652        $this->mailer = new PHPMailer();
 653
 654        $smtp_options = array();
 655        $smtp_options['enabled'] = $this->options['smtp_enabled'];
 656        $smtp_options['host'] = $this->options['smtp_host'];
 657        $smtp_options['port'] = $this->options['smtp_port'];
 658        $smtp_options['user'] = $this->options['smtp_user'];
 659        $smtp_options['pass'] = $this->options['smtp_pass'];
 660        $smtp_options['secure'] = $this->options['smtp_secure'];
 661
 662        $smtp_options = apply_filters('newsletter_smtp', $smtp_options);
 663
 664        if ($smtp_options['enabled'] == 1) {
 665            $this->mailer->IsSMTP();
 666            $this->mailer->Host = $smtp_options['host'];
 667            if (!empty($smtp_options['port']))
 668                $this->mailer->Port = (int) $smtp_options['port'];
 669
 670            if (!empty($smtp_options['user'])) {
 671                $this->mailer->SMTPAuth = true;
 672                $this->mailer->Username = $smtp_options['user'];
 673                $this->mailer->Password = $smtp_options['pass'];
 674            }
 675            $this->mailer->SMTPKeepAlive = true;
 676            $this->mailer->SMTPSecure = $smtp_options['secure'];
 677        } else {
 678            $this->mailer->IsMail();
 679        }
 680
 681        if (!empty($this->options['content_transfer_encoding'])) {
 682            $this->mailer->Encoding = $this->options['content_transfer_encoding'];
 683        } else {
 684            $this->mailer->Encoding = 'base64';
 685        }
 686
 687        $this->mailer->CharSet = 'UTF-8';
 688        $this->mailer->From = $this->options['sender_email'];
 689
 690        $return_path = $this->options['return_path'];
 691        if (!empty($return_path)) {
 692            $this->mailer->Sender = $return_path;
 693        }
 694        if (!empty($this->options['reply_to'])) {
 695            $this->mailer->AddReplyTo($this->options['reply_to']);
 696        }
 697
 698        $this->mailer->FromName = $this->options['sender_name'];
 699    }
 700
 701    function hook_deactivate() {
 702        wp_clear_scheduled_hook('newsletter');
 703        wp_clear_scheduled_hook('newsletter_feed');
 704    }
 705
 706    function hook_cron_schedules($schedules) {
 707        $schedules['newsletter'] = array(
 708            'interval' => NEWSLETTER_CRON_INTERVAL, // seconds
 709            'display' => 'Newsletter'
 710        );
 711        $schedules['newsletter_weekly'] = array(
 712            'interval' => 86400 * 7, // seconds
 713            'display' => 'Newsletter Weekly'
 714        );
 715        return $schedules;
 716    }
 717
 718    function shortcode_newsletter_form($attrs, $content) {
 719        return $this->form($attrs['form']);
 720    }
 721
 722    function form($number = null) {
 723        if ($number == null)
 724            return $this->subscription_form();
 725        $options = get_option('newsletter_forms');
 726
 727        $form = $options['form_' . $number];
 728
 729        if (stripos($form, '<form') !== false) {
 730            $form = str_replace('{newsletter_url}', plugins_url('newsletter/do/subscribe.php'), $form);
 731        } else {
 732            $form = '<form method="post" action="' . plugins_url('newsletter/do/subscribe.php') . '" onsubmit="return newsletter_check(this)">' .
 733                    $form . '</form>';
 734        }
 735
 736        $form = $this->replace_lists($form);
 737
 738        return $form;
 739    }
 740
 741    function find_file($file1, $file2) {
 742        if (is_file($file1))
 743            return $file1;
 744        return $file2;
 745    }
 746
 747    /**
 748     * Return a user if there are request parameters or cookie with identification data otherwise null.
 749     */
 750    function check_user() {
 751        global $wpdb, $current_user;
 752
 753        if (isset($_REQUEST['nk'])) {
 754            list($id, $token) = @explode('-', $_REQUEST['nk'], 2);
 755        } else if (isset($_REQUEST['ni'])) {
 756            $id = (int) $_REQUEST['ni'];
 757            $token = $_REQUEST['nt'];
 758        } else if (isset($_COOKIE['newsletter'])) {
 759            list ($id, $token) = @explode('-', $_COOKIE['newsletter'], 2);
 760        }
 761
 762        if (is_numeric($id) && !empty($token)) {
 763            return $wpdb->get_row($wpdb->prepare("select * from " . $wpdb->prefix . "newsletter where id=%d and token=%s limit 1", $id, $token));
 764        }
 765
 766        return null;
 767
 768        /*
 769          if ($this->options_main['wp_integration'] != 1) {
 770          return null;
 771          }
 772
 773          get_currentuserinfo();
 774
 775          // Retrieve the related newsletter user
 776          $user = $wpdb->get_row("select * from " . NEWSLETTER_USERS_TABLE . " where wp_user_id=" . $current_user->ID . " limit 1");
 777          // There is an email matching?
 778          if (empty($user)) {
 779          $user = $wpdb->get_row($wpdb->prepare("select * from " . NEWSLETTER_USERS_TABLE . " where email=%s limit 1", strtolower($current_user->user_email)));
 780          // If not found, create a new Newsletter user, else update the wp_user_id since this email must be linked
 781          // to the WP user email.
 782          if (empty($user)) {
 783          return null;
 784          //echo 'WP user not found';
 785          $user = array();
 786          $user['status'] = 'C';
 787          $user['wp_user_id'] = $current_user->ID;
 788          $user['token'] = $this->get_token();
 789          $user['email'] = strtolower($current_user->user_email);
 790
 791          $id = $wpdb->insert(NEWSLETTER_USERS_TABLE, $user);
 792          $user = NewsletterUsers::instance()->get_user($id);
 793          } else {
 794          //echo 'WP user found via email';
 795          $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set wp_user_id=" . $current_user->ID . ", email=%s", $current_user->user_email));
 796          }
 797          } else {
 798          //echo 'WP user found via id';
 799          }
 800
 801          return $user;
 802         */
 803    }
 804
 805    function replace_date($text) {
 806        $text = str_replace('{date}', date_i18n(get_option('date_format')), $text);
 807
 808        // Date processing
 809        $x = 0;
 810        while (($x = strpos($text, '{date_', $x)) !== false) {
 811            $y = strpos($text, '}', $x);
 812            if ($y === false)
 813                continue;
 814            $f = substr($text, $x + 6, $y - $x - 6);
 815            $text = substr($text, 0, $x) . date($f) . substr($text, $y + 1);
 816        }
 817        return $text;
 818    }
 819
 820    /**
 821     * Replace any kind of newsletter placeholder in a text.
 822     */
 823    function replace($text, $user = null, $email_id = null, $referrer = null) {
 824        global $wpdb;
 825
 826        $this->logger->debug('Replace start');
 827        if (is_array($user)) {
 828            $user = $this->get_user($user['id']);
 829        }
 830
 831        $email = null;
 832        if (is_numeric($email_id)) {
 833            $email = $this->get_email($email_id);
 834        }
 835
 836        $text = apply_filters('newsletter_replace', $text, $user, $email);
 837
 838        //$text = str_replace('{home_url}', get_option('home'), $text);
 839        //$text = str_replace('{blog_url}', get_option('home'), $text);
 840        $text = $this->replace_url($text, 'BLOG_URL', get_option('home'));
 841        $text = $this->replace_url($text, 'HOME_URL', get_option('home'));
 842
 843        $text = str_replace('{blog_title}', get_option('blogname'), $text);
 844        $text = str_replace('{blog_description}', get_option('blogdescription'), $text);
 845
 846        $text = $this->replace_date($text);
 847
 848        if ($user != null) {
 849            $options_profile = get_option('newsletter_profile');
 850
 851            $text = str_replace('{email}', $user->email, $text);
 852            if (empty($user->name)) {
 853                $text = str_replace(' {name}', '', $text);
 854                $text = str_replace('{name}', '', $text);
 855            } else {
 856                $text = str_replace('{name}', $user->name, $text);
 857            }
 858
 859            switch ($user->sex) {
 860                case 'm': $text = str_replace('{title}', $options_profile['title_male'], $text);
 861                    break;
 862                case 'f': $text = str_replace('{title}', $options_profile['title_female'], $text);
 863                    break;
 864                case 'n': $text = str_replace('{title}', $options_profile['title_none'], $text);
 865                    break;
 866                default:
 867                    $text = str_replace('{title}', '', $text);
 868            }
 869
 870
 871            $text = str_replace('{surname}', $user->surname, $text);
 872            $text = str_replace('{last_name}', $user->surname, $text);
 873
 874            $full_name = trim($user->name . ' ' . $user->surname);
 875            if (empty($full_name)) {
 876                $text = str_replace(' {full_name}', '', $text);
 877                $text = str_replace('{full_name}', '', $text);
 878            } else {
 879                $text = str_replace('{full_name}', $full_name, $text);
 880            }
 881
 882            $text = str_replace('{token}', $user->token, $text);
 883            $text = str_replace('%7Btoken%7D', $user->token, $text);
 884            $text = str_replace('{id}', $user->id, $text);
 885            $text = str_replace('%7Bid%7D', $user->id, $text);
 886            $text = str_replace('{ip}', $user->ip, $text);
 887            $text = str_replace('{key}', $user->id . '-' . $user->token, $text);
 888            $text = str_replace('%7Bkey%7D', $user->id . '-' . $user->token, $text);
 889
 890            if (strpos($text, '{profile_form}') !== false)
 891                $text = str_replace('{profile_form}', NewsletterSubscription::instance()->get_profile_form($user), $text);
 892
 893            for ($i = 1; $i < NEWSLETTER_PROFILE_MAX; $i++) {
 894                $p = 'profile_' . $i;
 895                $text = str_replace('{profile_' . $i . '}', $user->$p, $text);
 896            }
 897
 898//            $profile = $wpdb->get_results("select name,value from " . $wpdb->prefix . "newsletter_profiles where newsletter_id=" . $user->id);
 899//            foreach ($profile as $field) {
 900//                $text = str_ireplace('{np_' . $field->name . '}', htmlspecialchars($field->value), $text);
 901//            }
 902//
 903//            $text = preg_replace('/\\{np_.+\}/i', '', $text);
 904
 905            $base = (empty($this->options_main['url']) ? get_option('home') : $this->options_main['url']);
 906            $id_token = '&amp;ni=' . $user->id . '&amp;nt=' . $user->token;
 907            $nk = $user->id . '-' . $user->token;
 908
 909            //$text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', self::add_qs(plugins_url('do.php', __FILE__), 'a=c' . $id_token));
 910            $text = $this->replace_url($text, 'SUBSCRIPTION_CONFIRM_URL', plugins_url('newsletter/do/confirm.php') . '?nk=' . $nk);
 911            $text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', plugins_url('newsletter/do/unsubscribe.php') . '?nk=' . $nk);
 912            //$text = $this->replace_url($text, 'UNSUBSCRIPTION_CONFIRM_URL', NEWSLETTER_URL . '/do/unsubscribe.php?nk=' . $nk);
 913            $text = $this->replace_url($text, 'UNSUBSCRIPTION_URL', plugins_url('newsletter/do/unsubscription.php') . '?nk=' . $nk);
 914            $text = $this->replace_url($text, 'CHANGE_URL', plugins_url('newsletter/do/change.php'));
 915
 916            // Obsolete.
 917            $text = $this->replace_url($text, 'FOLLOWUP_SUBSCRIPTION_URL', self::add_qs($base, 'nm=fs' . $id_token));
 918            $text = $this->replace_url($text, 'FOLLOWUP_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=fu' . $id_token));
 919            $text = $this->replace_url($text, 'FEED_SUBSCRIPTION_URL', self::add_qs($base, 'nm=es' . $id_token));
 920            $text = $this->replace_url($text, 'FEED_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=eu' . $id_token));
 921
 922
 923            if (empty($options_profile['profile_url']))
 924                $text = $this->replace_url($text, 'PROFILE_URL', plugins_url('newsletter/do/profile.php') . '?nk=' . $nk);
 925            else
 926                $text = $this->replace_url($text, 'PROFILE_URL', self::add_qs($options_profile['profile_url'], 'ni=' . $user->id . '&amp;nt=' . $user->token));
 927
 928            //$text = $this->replace_url($text, 'UNLOCK_URL', self::add_qs($this->options_main['lock_url'], 'nm=m' . $id_token));
 929            $text = $this->replace_url($text, 'UNLOCK_URL', plugins_url('newsletter/do/unlock.php') . '?nk=' . $nk);
 930            if (!empty($email_id)) {
 931                $text = $this->replace_url($text, 'EMAIL_URL', plugins_url('newsletter/do/view.php') . '?id=' . $email_id . '&amp;nk=' . $nk);
 932            }
 933
 934            for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
 935                $text = $this->replace_url($text, 'LIST_' . $i . '_SUBSCRIPTION_URL', self::add_qs($base, 'nm=ls&amp;nl=' . $i . $id_token));
 936                $text = $this->replace_url($text, 'LIST_' . $i . '_UNSUBSCRIPTION_URL', self::add_qs($base, 'nm=lu&amp;nl=' . $i . $id_token));
 937            }
 938
 939            // Profile fields change links
 940            $text = $this->replace_url($text, 'SET_SEX_MALE', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nf=sex&nv=m');
 941            $text = $this->replace_url($text, 'SET_SEX_FEMALE', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nf=sex&nv=f');
 942            $text = $this->replace_url($text, 'SET_FEED', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=1&nf=feed');
 943            $text = $this->replace_url($text, 'UNSET_FEED', NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=0&nf=feed');
 944            for ($i = 1; $i <= NEWSLETTER_LIST_MAX; $i++) {
 945                $text = $this->replace_url($text, 'SET_PREFERENCE_' . $i, NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=1&nf=preference_' . $i);
 946                $text = $this->replace_url($text, 'UNSET_PREFERENCE_' . $i, NEWSLETTER_CHANGE_URL . '?nk=' . $nk . '&nv=0&nf=preference_' . $i);
 947            }
 948        }
 949
 950        if (strpos($text, '{subscription_form}') !== false) {
 951            $text = str_replace('{subscription_form}', NewsletterSubscription::instance()->get_subscription_form($referrer), $text);
 952        } else {
 953            for ($i = 1; $i <= 10; $i++) {
 954                if (strpos($text, "{subscription_form_$i}") !== false) {
 955                    $text = str_replace("{subscription_form_$i}", NewsletterSubscription::instance()->get_form($i), $text);
 956                    break;
 957                }
 958            }
 959        }
 960
 961        $this->logger->debug('Replace end');
 962        return $text;
 963    }
 964
 965    function replace_url($text, $tag, $url) {
 966        $home = get_option('home') . '/';
 967        $tag_lower = strtolower($tag);
 968        $text = str_replace($home . '{' . $tag_lower . '}', $url, $text);
 969        $text = str_replace($home . '%7B' . $tag_lower . '%7D', $url, $text);
 970        $text = str_replace('{' . $tag_lower . '}', $url, $text);
 971        $text = str_replace('%7B' . $tag_lower . '%7D', $url, $text);
 972
 973        // for compatibility
 974        $text = str_replace($home . $tag, $url, $text);
 975
 976        return $text;
 977    }
 978
 979    function hook_shutdown() {
 980        if ($this->mailer != null)
 981            $this->mailer->SmtpClose();
 982    }
 983
 984    function hook_the_content($content) {
 985        global $post, $cache_stop;
 986
 987        if ($this->lock_found || !is_singular() || is_user_logged_in()) {
 988            return $content;
 989        }
 990
 991        if (!empty($this->options['lock_ids'])) {
 992            $ids = explode(',', $this->options['lock_ids']);
 993        }
 994
 995        if (!empty($ids) && (has_tag($ids) || in_category($ids) || in_array($post->post_name, $ids))) {
 996            $cache_stop = true;
 997            $user = $this->check_user();
 998            if ($user == null || $user->status != 'C') {
 999                $buffer = $this->replace($this->options['lock_message']);
1000                return '<div class="newsletter-lock">' . do_shortcode($buffer) . '</div>';
1001            }
1002        }
1003
1004        return $content;
1005    }
1006
1007    function shortcode_newsletter_lock($attrs, $content = null) {
1008        global $hyper_cache_stop, $cache_stop;
1009
1010        $this->logger->debug('Lock short code start');
1011        $hyper_cache_stop = true;
1012        $cache_stop = true;
1013
1014        $this->lock_found = true;
1015
1016        $user = $this->check_user();
1017        if (is_user_logged_in() || ($user != null && $user->status == 'C')) {
1018            return do_shortcode($content);
1019        }
1020
1021        $buffer = $this->options['lock_message'];
1022//        ob_start();
1023//        eval('? >' . $buffer . "\n");
1024//        $buffer = ob_get_clean();
1025        // TODO: add the newsletter check on submit
1026        $buffer = str_ireplace('<form', '<form method="post" action="' . plugins_url('newsletter/do/subscribe.php') . '"', $buffer);
1027        $buffer = $this->replace($buffer, null, null, 'lock');
1028
1029        $buffer = do_shortcode($buffer);
1030        $this->logger->debug('Lock short code end');
1031
1032        return '<div class="newsletter-lock">' . $buffer . '</div>';
1033    }
1034
1035    function shortcode_newsletter_profile($attrs, $content) {
1036        global $wpdb, $current_user;
1037
1038        $user = $this->check_user();
1039
1040        if ($user == null) {
1041            return 'No user found.';
1042        }
1043
1044        return $this->profile_form($user);
1045    }
1046
1047    /**
1048     * Exceutes a query and log it.
1049     */
1050    function query($query) {
1051        global $wpdb;
1052
1053        $this->log($query, 3);
1054        return $wpdb->query($query);
1055    }
1056
1057    function notify_admin($user, $subject) {
1058        if ($this->options['notify'] != 1)
1059            return;
1060        $message = "Subscriber details:\n\n" .
1061                "email: " . $user->email . "\n" .
1062                "first name: " . $user->name . "\n" .
1063                "last name: " . $user->surname . "\n" .
1064                "gender: " . $user->sex . "\n";
1065
1066        $options_profile = get_option('newsletter_profile');
1067
1068        for ($i = 0; $i < NEWSLETTER_PROFILE_MAX; $i++) {
1069            if ($options_profile['profile_' . $i] == '')
1070                continue;
1071            $field = 'profile_' . $i;
1072            $message .= $options_profile['profile_' . $i] . ': ' . $user->$field . "\n";
1073        }
1074
1075        for ($i = 0; $i < NEWSLETTER_LIST_MAX; $i++) {
1076            if ($options_profile['list_' . $i] == '')
1077                continue;
1078            $field = 'list_' . $i;
1079            $message .= $options_profile['list_' . $i] . ': ' . $user->$field . "\n";
1080        }
1081
1082        $message .= "token: " . $user->token . "\n" .
1083                "status: " . $user->status . "\n" .
1084                "\nYours, Newsletter.";
1085
1086        wp_mail(get_option('admin_email'), '[' . get_option('blogname') . '] ' . $subject, $message, "Content-type: text/plain; charset=UTF-8\n");
1087    }
1088
1089    function get_user_from_request($required = false) {
1090        if (isset($_REQUEST['nk'])) {
1091            list($id, $token) = @explode('-', $_REQUEST['nk'], 2);
1092        } else if (isset($_REQUEST['ni'])) {
1093            $id = (int) $_REQUEST['ni'];
1094            $token = $_REQUEST['nt'];
1095        }
1096        $user = $this->get_user($id);
1097
1098        if ($user == null || $token != $user->token) {
1099            if ($required)
1100                die('No subscriber found.');
1101            else
1102                return null;
1103        }
1104        return $user;
1105    }
1106
1107    function save_email($email) {
1108        return $this->store->save(NEWSLETTER_EMAILS_TABLE, $email);
1109    }
1110
1111    function delete_email($id) {
1112        return $this->store->delete(NEWSLETTER_EMAILS_TABLE, $id);
1113    }
1114
1115    function get_email_field($id, $field_name) {
1116        return $this->store->get_field(NEWSLETTER_EMAILS_TABLE, $id, $field_name);
1117    }
1118
1119    /**
1120     * Returns a list of users marked as "test user".
1121     * @return array
1122     */
1123    function get_test_users() {
1124        return $this->store->get_all(NEWSLETTER_USERS_TABLE, "where test=1");
1125    }
1126
1127    function delete_user($id) {
1128        global $wpdb;
1129        $r = $this->store->delete(NEWSLETTER_USERS_TABLE, $id);
1130        if ($r !== false) {
1131            $wpdb->delete(NEWSLETTER_STATS_TABLE, array('user_id' => $id));
1132        }
1133    }
1134
1135    function set_user_status($id_or_email, $status) {
1136        global $wpdb;
1137
1138        $this->logger->debug('Status change to ' . $status . ' of subscriber ' . $id_or_email . ' from ' . $_SERVER['REQUEST_URI']);
1139
1140        $id_or_email = strtolower(trim($id_or_email));
1141        if (is_numeric($id_or_email)) {
1142            $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where id=%d limit 1", $status, $id_or_email));
1143        } else {
1144            $r = $wpdb->query($wpdb->prepare("update " . NEWSLETTER_USERS_TABLE . " set status=%s where email=%s limit 1", $status, $id_or_email));
1145        }
1146
1147        if ($wpdb->last_error) {
1148            $this->logger->error($wpdb->last_error);
1149            return false;
1150        }
1151        return $r;
1152    }
1153
1154}
1155
1156$newsletter = Newsletter::instance();
1157
1158require_once NEWSLETTER_DIR . '/subscription/subscription.php';
1159require_once NEWSLETTER_DIR . '/emails/emails.php';
1160require_once NEWSLETTER_DIR . '/users/users.php';
1161require_once NEWSLETTER_DIR . '/statistics/statistics.php';
1162
1163
1164if (!is_dir(WP_PLUGIN_DIR . '/newsletter-feed')) {
1165    if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/feed/feed.php')) {
1166        require_once WP_CONTENT_DIR . '/extensions/newsletter/feed/feed.php';
1167    } else {
1168        if (get_option('newsletter_feed_demo_disable') != 1) {
1169            if (is_file(NEWSLETTER_DIR . '/feed/feed.php')) {
1170                require_once NEWSLETTER_DIR . '/feed/feed.php';
1171            }
1172        }
1173    }
1174}
1175
1176//if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/updates/updates.php')) {
1177//    require_once WP_CONTENT_DIR . '/extensions/newsletter/updates/updates.php';
1178//}
1179
1180if (!is_dir(WP_PLUGIN_DIR . '/newsletter-followup')) {
1181    if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/followup/followup.php')) {
1182        require_once WP_CONTENT_DIR . '/extensions/newsletter/followup/followup.php';
1183    }
1184}
1185
1186if (!is_dir(WP_PLUGIN_DIR . '/newsletter-reports')) {
1187    if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/reports/reports.php')) {
1188        require_once WP_CONTENT_DIR . '/extensions/newsletter/reports/reports.php';
1189    }
1190}
1191
1192if (!is_dir(WP_PLUGIN_DIR . '/newsletter-mailjet')) {
1193    if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/mailjet/mailjet.php')) {
1194        require_once WP_CONTENT_DIR . '/extensions/newsletter/mailjet/mailjet.php';
1195    }
1196}
1197if (!is_dir(WP_PLUGIN_DIR . '/newsletter-sendgrid')) {
1198    if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/sendgrid/sendgrid.php')) {
1199        require_once WP_CONTENT_DIR . '/extensions/newsletter/sendgrid/sendgrid.php';
1200    }
1201}
1202
1203if (!is_dir(WP_PLUGIN_DIR . '/newsletter-facebook')) {
1204    if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/facebook/facebook.php')) {
1205        require_once WP_CONTENT_DIR . '/extensions/newsletter/facebook/facebook.php';
1206    }
1207}
1208
1209
1210if (!is_dir(WP_PLUGIN_DIR . '/newsletter-popup')) {
1211    if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/popup/popup.php')) {
1212        require_once WP_CONTENT_DIR . '/extensions/newsletter/popup/popup.php';
1213    }
1214}
1215
1216if (!is_dir(WP_PLUGIN_DIR . '/newsletter-mandrill')) {
1217    if (is_file(WP_CONTENT_DIR . '/extensions/newsletter/mandrill/mandrill.php')) {
1218        require_once WP_CONTENT_DIR . '/extensions/newsletter/mandrill/mandrill.php';
1219    }
1220}
1221
1222
1223require_once(dirname(__FILE__) . '

Large files files are truncated, but you can click here to view the full file