0
X
Add Snippet To Project
New Project
Add To Existing Project
<?php
/*
Plugin Name: Nofixal
Plugin URI: https://nofixal.com
Description: Plugin untuk tracking klik WhatsApp + Pixel + Notifikasi + Statistik.
Version: 1.0
Author: Carles Dafitson
*/
defined('ABSPATH') or die('Akses ditolak langsung.');
define('NOFIXAL_PATH', plugin_dir_path(__FILE__));
define('NOFIXAL_URL', plugin_dir_url(__FILE__));
// Dummy License Check
function nofixal_is_license_valid() {
$token = get_option('nofixal_license_token');
return !empty($token) && $token === 'TOKEN_VALID';
}
if (!nofixal_is_license_valid()) {
add_action('admin_notices', function() {
echo '<div class="notice notice-error"><p><strong>Nofixal:</strong> Lisensi tidak valid. Silakan aktivasi.</p></div>';
});
return;
}
// JS Inline Tracking
add_action('wp_footer', function() {
?>
<script>
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.nofixal-wa-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
const data = {
action: 'nofixal_track',
number: btn.dataset.wa,
event: btn.dataset.event,
device: navigator.userAgent.includes('Mobile') ? 'Mobile' : 'Desktop',
browser: navigator.userAgent
};
navigator.sendBeacon('<?php echo admin_url('admin-ajax.php'); ?>', new URLSearchParams(data));
});
});
});
</script>
<?php
});
// Elementor WhatsApp Button Widget
add_action('elementor/widgets/widgets_registered', function() {
if (!class_exists('ElementorWidget_Base')) return;
class Nofixal_WA_Button_Widget extends ElementorWidget_Base {
public function get_name() { return 'nofixal_wa_button'; }
public function get_title() { return 'Nofixal WA Button'; }
public function get_icon() { return 'eicon-button'; }
public function get_categories() { return ['general']; }
protected function register_controls() {
$this->start_controls_section('content_section', ['label' => __('Pengaturan Tombol WA', 'nofixal')]);
$this->add_control('wa_number', ['label' => __('Nomor WhatsApp', 'nofixal'), 'type' => ElementorControls_Manager::TEXT]);
$this->add_control('button_text', ['label' => __('Teks Tombol', 'nofixal'), 'type' => ElementorControls_Manager::TEXT, 'default' => 'Chat via WhatsApp']);
$this->add_control('event_name', ['label' => __('Nama Event Custom', 'nofixal'), 'type' => ElementorControls_Manager::TEXT, 'default' => 'click_wa']);
$this->end_controls_section();
}
protected function render() {
$s = $this->get_settings_for_display();
echo "<a href='https://wa.me/{$s['wa_number']}' target='_blank' class='nofixal-wa-btn' data-wa='{$s['wa_number']}' data-event='{$s['event_name']}'>{$s['button_text']}</a>";
}
}
ElementorPlugin::instance()->widgets_manager->register_widget_type(new Nofixal_WA_Button_Widget());
});
// Tracking AJAX
add_action('wp_ajax_nofixal_track', 'nofixal_handle_tracking');
add_action('wp_ajax_nopriv_nofixal_track', 'nofixal_handle_tracking');
function nofixal_handle_tracking() {
$data = [
'number' => sanitize_text_field($_POST['number'] ?? ''),
'event' => sanitize_text_field($_POST['event'] ?? ''),
'device' => sanitize_text_field($_POST['device'] ?? ''),
'browser' => sanitize_text_field($_POST['browser'] ?? ''),
'datetime' => current_time('mysql')
];
global $wpdb;
$wpdb->insert($wpdb->prefix . 'nofixal_logs', $data);
nofixal_send_notifications($data);
nofixal_send_to_google_sheets($data);
nofixal_send_to_pixels($data);
wp_send_json_success(['message' => 'Event tracked']);
}
function nofixal_send_notifications($data) {
$hour = (int) current_time('H');
if ($hour >= 22 || $hour < 7) return;
$chat_id = get_option('nofixal_telegram_chat_id');
$token = get_option('nofixal_telegram_token');
if ($token && $chat_id) {
wp_remote_post("https://api.telegram.org/bot{$token}/sendMessage", ['body' => ['chat_id' => $chat_id, 'text' => "[Nofixal] {$data['event']} | {$data['number']} | {$data['device']} | {$data['browser']} | {$data['datetime']}"]]);
}
$email = get_option('nofixal_notification_email');
if ($email) {
wp_mail($email, "[Nofixal] {$data['event']}", "Nomor: {$data['number']}nDevice: {$data['device']}nBrowser: {$data['browser']}nWaktu: {$data['datetime']}");
}
}
// Admin Settings & Dashboard
add_action('admin_menu', function() {
add_menu_page('Nofixal', 'Nofixal', 'manage_options', 'nofixal', 'nofixal_render_dashboard', 'dashicons-chart-area');
add_submenu_page('nofixal', 'Pengaturan Notifikasi', 'Pengaturan', 'manage_options', 'nofixal-settings', 'nofixal_render_settings_page');
});
add_action('admin_init', function() {
register_setting('nofixal_settings_group', 'nofixal_telegram_token');
register_setting('nofixal_settings_group', 'nofixal_telegram_chat_id');
register_setting('nofixal_settings_group', 'nofixal_notification_email');
register_setting('nofixal_settings_group', 'nofixal_gsheet_webhook');
register_setting('nofixal_settings_group', 'nofixal_gsheet_enabled');
register_setting('nofixal_settings_group', 'nofixal_fb_pixel');
register_setting('nofixal_settings_group', 'nofixal_fb_token');
register_setting('nofixal_settings_group', 'nofixal_tt_pixel');
register_setting('nofixal_settings_group', 'nofixal_tt_token');
register_setting('nofixal_settings_group', 'nofixal_ga_id');
register_setting('nofixal_settings_group', 'nofixal_ga_secret');
});
function nofixal_render_settings_page() {
?>
<div class="wrap">
<h2>Pengaturan Notifikasi Nofixal</h2>
<form method="post" action="options.php">
<?php settings_fields('nofixal_settings_group'); ?>
<table class="form-table">
<tr><th>Telegram Bot Token</th><td><input type="text" name="nofixal_telegram_token" value="<?php echo esc_attr(get_option('nofixal_telegram_token')); ?>" class="regular-text"></td></tr>
<tr><th>Telegram Chat ID</th><td><input type="text" name="nofixal_telegram_chat_id" value="<?php echo esc_attr(get_option('nofixal_telegram_chat_id')); ?>" class="regular-text"></td></tr>
<tr><th>Email Notifikasi</th><td><input type="email" name="nofixal_notification_email" value="<?php echo esc_attr(get_option('nofixal_notification_email')); ?>" class="regular-text"></td></tr>
<tr><th>Google Sheets Webhook URL</th><td><input type="text" name="nofixal_gsheet_webhook" value="<?php echo esc_attr(get_option('nofixal_gsheet_webhook')); ?>" class="regular-text"></td></tr>
<tr><th>Aktifkan Google Sheets</th><td><input type="checkbox" name="nofixal_gsheet_enabled" value="1" <?php checked(1, get_option('nofixal_gsheet_enabled'), true); ?>></td></tr>
$1
<?php submit_button('Simpan Pengaturan'); ?>
</form>
<hr><h2>Test Notifikasi</h2>
<form method="post"><input type="submit" name="nofixal_test_notif" class="button" value="Kirim Tes Notifikasi"></form>
<?php if (isset($_POST['nofixal_test_notif'])) {
nofixal_send_notifications([
'number' => '08123456789',
'event' => 'test_event',
'device' => 'Desktop',
'browser' => 'Chrome',
'datetime' => current_time('mysql')
]);
echo '<div class="notice notice-success"><p>Notifikasi test berhasil dikirim.</p></div>';
} ?>
</div>
<?php
}
function nofixal_render_dashboard() {
if (isset($_GET['nofixal_export']) && $_GET['nofixal_export'] === 'csv') {
nofixal_export_csv();
exit;
}
global $wpdb;
$results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}nofixal_logs ORDER BY datetime DESC LIMIT 100");
$stats = $wpdb->get_results("SELECT DATE(datetime) as date, COUNT(*) as total FROM {$wpdb->prefix}nofixal_logs GROUP BY DATE(datetime) ORDER BY date ASC");
?>
<div class="wrap">
$1 <a href="" + admin_url('admin.php?page=nofixal&nofixal_export=csv') + "" class="button-primary" style="float:right;margin-top:10px;">Export CSV</a>
<canvas id="nofixalChart" height="100"></canvas>
<hr>
<table class="widefat">
<thead><tr><th>No</th><th>Nomor WA</th><th>Event</th><th>Device</th><th>Browser</th><th>Waktu</th></tr></thead>
<tbody>
<?php $no=1; foreach ($results as $r) {
echo "<tr><td>{$no}</td><td>{$r->number}</td><td>{$r->event}</td><td>{$r->device}</td><td>{$r->browser}</td><td>{$r->datetime}</td></tr>";
$no++;
} ?>
</tbody>
<tr><th>Facebook Pixel ID</th><td><input type="text" name="nofixal_fb_pixel" value="<?php echo esc_attr(get_option('nofixal_fb_pixel')); ?>" class="regular-text"></td></tr>
<tr><th>Facebook Access Token</th><td><input type="text" name="nofixal_fb_token" value="<?php echo esc_attr(get_option('nofixal_fb_token')); ?>" class="regular-text"></td></tr>
<tr><th>TikTok Pixel ID</th><td><input type="text" name="nofixal_tt_pixel" value="<?php echo esc_attr(get_option('nofixal_tt_pixel')); ?>" class="regular-text"></td></tr>
<tr><th>TikTok Access Token</th><td><input type="text" name="nofixal_tt_token" value="<?php echo esc_attr(get_option('nofixal_tt_token')); ?>" class="regular-text"></td></tr>
<tr><th>Google Ads Measurement ID</th><td><input type="text" name="nofixal_ga_id" value="<?php echo esc_attr(get_option('nofixal_ga_id')); ?>" class="regular-text"></td></tr>
<tr><th>Google Ads API Secret</th><td><input type="text" name="nofixal_ga_secret" value="<?php echo esc_attr(get_option('nofixal_ga_secret')); ?>" class="regular-text"></td></tr>
$1
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const ctx = document.getElementById('nofixalChart').getContext('2d');
const chart = new Chart(ctx, {
type: 'line',
data: {
labels: <?php echo json_encode(array_column($stats, 'date')); ?>,
datasets: [{
label: 'Total Klik WA per Hari',
data: <?php echo json_encode(array_column($stats, 'total')); ?>,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1
}]
},
options: {
responsive: true,
plugins: {
legend: { display: true },
title: { display: true, text: 'Statistik Interaksi WA' }
}
}
});
</script>
<?php
}nofixal_logs ORDER BY datetime DESC LIMIT 100");
?>
<div class="wrap">
<h1>Nofixal Dashboard</h1>
<table class="widefat">
<thead><tr><th>No</th><th>Nomor WA</th><th>Event</th><th>Device</th><th>Browser</th><th>Waktu</th></tr></thead>
<tbody>
<?php $no=1; foreach ($results as $r) {
echo "<tr><td>{$no}</td><td>{$r->number}</td><td>{$r->event}</td><td>{$r->device}</td><td>{$r->browser}</td><td>{$r->datetime}</td></tr>";
$no++;
} ?>
</tbody>
</table>
</div>
<?php
}
function nofixal_export_csv() {
global $wpdb;
$results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}nofixal_logs ORDER BY datetime DESC", ARRAY_A);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="nofixal_logs.csv"');
$output = fopen('php://output', 'w');
fputcsv($output, ['Nomor WA', 'Event', 'Device', 'Browser', 'Waktu']);
foreach ($results as $row) {
fputcsv($output, [$row['number'], $row['event'], $row['device'], $row['browser'], $row['datetime']]);
}
fclose($output);
}
function nofixal_send_to_google_sheets($data) {
if (!get_option('nofixal_gsheet_enabled')) return;
$url = get_option('nofixal_gsheet_webhook');
if (!$url) return;
$payload = [
'number' => $data['number'],
'event' => $data['event'],
'device' => $data['device'],
'browser' => $data['browser'],
'datetime' => $data['datetime']
];
wp_remote_post($url, [
'method' => 'POST',
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode($payload)
]);
}
function nofixal_send_to_pixels($data) {
$fb_pixel_id = get_option('nofixal_fb_pixel');
$fb_token = get_option('nofixal_fb_token');
if ($fb_pixel_id && $fb_token) {
wp_remote_post("https://graph.facebook.com/v17.0/{$fb_pixel_id}/events?access_token={$fb_token}", [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode([
'data' => [[
'event_name' => $data['event'],
'event_time' => time(),
'action_source' => 'website',
'event_source_url' => home_url(),
'user_data' => []
]]
])
]);
}
$tiktok_pixel_id = get_option('nofixal_tt_pixel');
$tiktok_token = get_option('nofixal_tt_token');
if ($tiktok_pixel_id && $tiktok_token) {
wp_remote_post("https://business-api.tiktok.com/open_api/v1.2/pixel/track/?access_token={$tiktok_token}", [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode([
'pixel_code' => $tiktok_pixel_id,
'event' => $data['event'],
'timestamp' => round(microtime(true) * 1000),
'properties' => [
'url' => home_url(),
'button_text' => $data['event'],
'referrer' => $_SERVER['HTTP_REFERER'] ?? ''
]
])
]);
}
$ga_measurement_id = get_option('nofixal_ga_id');
$ga_api_secret = get_option('nofixal_ga_secret');
if ($ga_measurement_id && $ga_api_secret) {
$client_id = isset($_COOKIE['_ga']) ? explode('.', $_COOKIE['_ga'])[2] . '.' . explode('.', $_COOKIE['_ga'])[3] : '555';
wp_remote_post("https://www.google-analytics.com/mp/collect?measurement_id={$ga_measurement_id}&api_secret={$ga_api_secret}", [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode([
'client_id' => $client_id,
'events' => [[ 'name' => $data['event'], 'params' => ['engagement_time_msec' => 100, 'page_location' => home_url()] ]]
])
]);
}
};
