settings ---------- /** Everything the dashboard controls, read from this site's options. */ public static function local_settings() { $cmd = get_option( 'postaramail_last_command', 0 ); return array( 'reg_mode' => get_option( 'postaramail_reg_mode', 'off' ), 'reg_notice' => get_option( 'postaramail_reg_notice', PostaraMail_Integrations::default_notice( 'reg' ) ), 'woo_mode' => get_option( 'postaramail_woo_mode', 'off' ), 'woo_notice' => get_option( 'postaramail_woo_notice', PostaraMail_Integrations::default_notice( 'woo' ) ), 'comment_mode' => get_option( 'postaramail_comment_mode', 'off' ), 'optin_label' => PostaraMail_Integrations::checkbox_label(), 'owner_confirmed_at' => get_option( 'postaramail_owner_confirmed' ) ? (int) get_option( 'postaramail_owner_confirmed' ) : null, 'start_automations' => (bool) get_option( 'postaramail_start_automations', 1 ), 'default_automation' => (int) get_option( 'postaramail_default_automation', 0 ), 'exist_banner' => (bool) get_option( 'postaramail_exist_banner', 0 ), 'exist_roles' => is_array( get_option( 'postaramail_exist_roles', null ) ) ? array_values( get_option( 'postaramail_exist_roles' ) ) : null, 'sync_pending' => (bool) get_option( 'postaramail_sync_pending', 1 ), 'form' => array( 'button_text' => get_option( 'postaramail_button_text', __( 'Subscribe', 'postaramail' ) ), 'consent_text' => get_option( 'postaramail_consent_text', __( 'Yes, I’d like to receive emails. I can unsubscribe at any time.', 'postaramail' ) ), 'success_text' => get_option( 'postaramail_success_text', __( 'Thanks! You’re subscribed.', 'postaramail' ) ), ), 'commands' => array(), '_last_command' => (int) $cmd, ); } /** Applies the dashboard's settings to this site's options. */ public static function apply( $s ) { $text = array( 'reg_mode' => 'postaramail_reg_mode', 'reg_notice' => 'postaramail_reg_notice', 'woo_mode' => 'postaramail_woo_mode', 'woo_notice' => 'postaramail_woo_notice', 'comment_mode' => 'postaramail_comment_mode', 'optin_label' => 'postaramail_optin_label', ); foreach ( $text as $key => $opt ) { if ( isset( $s[ $key ] ) ) { '' === $s[ $key ] ? delete_option( $opt ) : update_option( $opt, sanitize_text_field( $s[ $key ] ) ); } } if ( ! empty( $s['owner_confirmed_at'] ) ) { update_option( 'postaramail_owner_confirmed', (int) $s['owner_confirmed_at'], false ); } else { delete_option( 'postaramail_owner_confirmed' ); } update_option( 'postaramail_start_automations', ! empty( $s['start_automations'] ) ? 1 : 0 ); update_option( 'postaramail_default_automation', isset( $s['default_automation'] ) ? absint( $s['default_automation'] ) : 0 ); update_option( 'postaramail_exist_banner', ! empty( $s['exist_banner'] ) ? 1 : 0 ); $was = (int) get_option( 'postaramail_sync_pending', 1 ); update_option( 'postaramail_sync_pending', ( ! isset( $s['sync_pending'] ) || $s['sync_pending'] ) ? 1 : 0 ); if ( isset( $s['exist_roles'] ) && is_array( $s['exist_roles'] ) ) { update_option( 'postaramail_exist_roles', array_values( $s['exist_roles'] ) ); PostaraMail_Existing::remember_roles(); } else { delete_option( 'postaramail_exist_roles' ); } if ( isset( $s['form'] ) && is_array( $s['form'] ) ) { foreach ( array( 'button_text' => 'postaramail_button_text', 'consent_text' => 'postaramail_consent_text', 'success_text' => 'postaramail_success_text', ) as $k => $opt ) { if ( isset( $s['form'][ $k ] ) ) { '' === $s['form'][ $k ] ? delete_option( $opt ) : update_option( $opt, sanitize_text_field( $s['form'][ $k ] ) ); } } } if ( ! $was && get_option( 'postaramail_sync_pending', 1 ) ) { PostaraMail_Pending::schedule_soon(); } } // ---------- Talking to PostaraMail ---------- private static function stats() { $stats = get_option( 'postaramail_stats', array( 'added' => 0 ) ); $c = PostaraMail_Existing::counts( false ); // the cheap counts only $roles = array(); foreach ( wp_roles()->roles as $slug => $role ) { $roles[] = array( 'slug' => $slug, 'name' => translate_user_role( $role['name'] ), ); } return array( 'rev' => self::rev(), 'plugin_version' => POSTARAMAIL_WP_VERSION, 'wp_version' => get_bloginfo( 'version' ), 'woocommerce' => class_exists( 'WooCommerce' ), 'roles' => $roles, 'stats' => array( 'added' => (int) $stats['added'], 'queued' => PostaraMail_Queue::count(), 'pending_pushed' => PostaraMail_Pending::pushed_count(), 'existing' => array( 'yes' => (int) $c['yes'], 'no' => (int) $c['no'], 'pending' => PostaraMail_Pending::pending_count(), ), 'last_command_id' => (int) get_option( 'postaramail_last_command', 0 ), ), ); } /** The background task: also notes that background tasks really run on this site. */ public static function cron() { update_option( 'postaramail_sync_cron_last', time(), false ); self::run(); } /** At most once a minute. Used when the PostaraMail screen is opened. */ public static function maybe_run() { if ( get_transient( 'postaramail_synced' ) ) { return; } set_transient( 'postaramail_synced', 1, 60 ); self::run(); // Anyone still waiting (for example if background tasks do not run on this site) goes now. if ( PostaraMail_Pending::enabled() ) { PostaraMail_Pending::push_waiting( 100 ); } } /** One round trip: report, receive newer settings, run any command. */ public static function run() { if ( ! PostaraMail_API::configured() ) { return; } $r = PostaraMail_API::heartbeat( self::stats() ); if ( ! $r['ok'] ) { update_option( 'postaramail_sync_error', array( 'message' => substr( (string) $r['message'], 0, 200 ), 'time' => time(), ), false ); return; } delete_option( 'postaramail_sync_error' ); $d = $r['data']; $rev = isset( $d['rev'] ) ? (int) $d['rev'] : 0; if ( isset( $d['settings'] ) && is_array( $d['settings'] ) ) { self::apply( $d['settings'] ); update_option( 'postaramail_settings_rev', $rev, false ); self::run_commands( $d['settings'] ); } elseif ( 0 === $rev ) { self::push(); // PostaraMail has nothing yet: send this site's settings as the starting point. } if ( isset( $d['upgrade_url'] ) ) { update_option( 'postaramail_upgrade_url', esc_url_raw( $d['upgrade_url'] ), false ); } } /** Sends this site's settings to PostaraMail. Returns ok | stale | error. */ public static function push() { if ( ! PostaraMail_API::configured() ) { return 'error'; } $settings = self::local_settings(); unset( $settings['_last_command'], $settings['commands'] ); $r = PostaraMail_API::put_settings( $settings, self::rev() ); if ( $r['ok'] ) { update_option( 'postaramail_settings_rev', (int) $r['data']['rev'], false ); return 'ok'; } if ( 'stale' === $r['code'] ) { // The dashboard changed first. It wins: take its settings. delete_transient( 'postaramail_synced' ); $h = PostaraMail_API::heartbeat( array_merge( self::stats(), array( 'rev' => -1 ) ) ); if ( $h['ok'] && isset( $h['data']['settings'] ) ) { self::apply( $h['data']['settings'] ); update_option( 'postaramail_settings_rev', (int) $h['data']['rev'], false ); } return 'stale'; } return 'error'; } private static function run_commands( $s ) { $cmd = isset( $s['commands']['send_existing']['id'] ) ? (int) $s['commands']['send_existing']['id'] : 0; if ( $cmd > (int) get_option( 'postaramail_last_command', 0 ) ) { // The owner confirmed this in PostaraMail ("I am allowed to contact them once to ask"). PostaraMail_Existing::start_email( true ); update_option( 'postaramail_last_command', $cmd, false ); } } }