foreach (array('_fbp' => 'fbp', '_fbc' => 'fbc') as $cookie => $field) { if (!empty($_COOKIE[$cookie]) && is_string($_COOKIE[$cookie])) { $data[$field] = sanitize_text_field(wp_unslash($_COOKIE[$cookie])); } } return array_filter($data); } private static function server($order) { if (!self::eligible($order) || !self::consent() || NR_PMPRO_META_TOKEN === '') { return; } $browser_sent = (int) get_option(self::key($order->id, 'browser'), 0); if ($browser_sent && $browser_sent < time() - DAY_IN_SECONDS) { return; } $first_attempt = (int) get_option(self::key($order->id, 'event_time'), 0); // Ambiguous timeouts must not lead to retries outside the deduplication window. if ($first_attempt && $first_attempt < time() - DAY_IN_SECONDS) { return; } $sent_key = self::key($order->id, 'capi'); if (get_option($sent_key, false)) { return; } // Atomic lock prevents concurrent checkout/confirmation requests sending twice. $lock = self::key($order->id, 'lock'); $now = time(); if (!add_option($lock, $now, '', false)) { $old = (int) get_option($lock, 0); if ($old > 0 && $old < $now - 60) { delete_option($lock); } return; } try { if (get_option($sent_key, false)) { return; } $event = self::data($order); $time_key = self::key($order->id, 'event_time'); add_option($time_key, $now, '', false); $payload = array( 'data' => array(array( 'event_name' => $event['name'], 'event_time' => (int) get_option($time_key, $now), 'event_id' => $event['id'], 'action_source' => 'website', 'event_source_url' => pmpro_url('confirmation'), 'user_data' => self::user_data($order), 'custom_data' => $event['params'], )), ); if (NR_PMPRO_META_TEST_CODE !== '') { $payload['test_event_code'] = NR_PMPRO_META_TEST_CODE; } $response = wp_remote_post('https://graph.facebook.com/' . NR_PMPRO_META_API . '/' . NR_PMPRO_META_PIXEL . '/events', array( 'timeout' => 5, 'headers' => array('Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . NR_PMPRO_META_TOKEN), 'body' => wp_json_encode($payload), )); $body = is_wp_error($response) ? array() : json_decode(wp_remote_retrieve_body($response), true); $code = is_wp_error($response) ? 0 : (int) wp_remote_retrieve_response_code($response); if ($code >= 200 && $code < 300 && !empty($body['events_received'])) { update_option($sent_key, time(), false); } else { // Never log token, payload, email, or raw API response. error_log('NR PMPro Meta: CAPI fehlgeschlagen; PMPro-Bestellung ' . absint($order->id) . ', HTTP ' . $code); } } finally { delete_option($lock); } } public static function footer() { if (!self::$browser || !self::consent()) { return; } $config = self::$browser; $config['pixel'] = (string) NR_PMPRO_META_PIXEL; $config['ajax'] = admin_url('admin-ajax.php'); $config['nonce'] = wp_create_nonce('nr_pmpro_meta_ack_' . $config['order']); echo ''; self::$browser = null; } public static function ack() { $id = isset($_POST['order']) ? absint($_POST['order']) : 0; check_ajax_referer('nr_pmpro_meta_ack_' . $id); if (!class_exists('MemberOrder') || !self::consent()) { wp_send_json_error(null, 403); } $order = new MemberOrder($id); if (!self::eligible($order) || (int) $order->user_id !== (int) get_current_user_id()) { wp_send_json_error(null, 403); } update_option(self::key($id, 'browser'), time(), false); wp_send_json_success(); } public static function notice() { if (current_user_can('manage_options') && NR_PMPRO_META_TOKEN === '') { echo '
NR PMPro Meta: CAPI-Token fehlt. Nur Browser-Tracking ist verfügbar. NR_PMPRO_META_TOKEN in wp-config.php setzen. Einwilligung muss über mconsent=1 signalisiert werden.
Automatische Bereinigung: alle 12 Stunden (WP-Cron; abhängig vom Cron-Aufruf)
'; echo 'Abgeschlossen/Abgebrochen: keine Aufbewahrung · Fehlgeschlagen: 3 Tage
Maximal ' . esc_html(self::BATCH) . ' Aktionen je Durchlauf; Zeitbudget ' . esc_html(self::MAX_SECONDS) . ' Sekunden.
Letzter Lauf: ' . esc_html($last['time']) . '
';
echo 'Gelöscht: ' . esc_html($last['deleted']) . '
';
echo 'Status: ' . esc_html($last['message']) . '
Noch keine Bereinigung ausgeführt.
'; } $next = wp_next_scheduled(self::CRON); if ($next) { echo 'Nächster Lauf: ' . esc_html(wp_date('d.m.Y H:i', $next)) . '
'; } echo ''; if (isset($_GET['nr_asc_done'])) { echo 'Bereinigung ausgeführt. Ergebnis siehe oben.
'; } } public static function manual() { if (!current_user_can('manage_options')) { wp_die('Keine Berechtigung.'); } check_admin_referer(self::NONCE); self::cleanup(); wp_safe_redirect(add_query_arg('nr_asc_done', '1', admin_url('index.php'))); exit; } } NR_Action_Scheduler_Cleaner::init(); register_deactivation_hook(__FILE__, function () { wp_clear_scheduled_hook(NR_Action_Scheduler_Cleaner::CRON); });
Dein Warenkorb ist noch nicht leer. Wenn du möchtest, kannst du deine Bestellung jetzt direkt abschließen.