If you want to know how many people open/download/view your pdf file, follow below
Insert this class in your button wrap - pdf-tracker
/**
* PDF Download Tracker
* Tracks PDF clicks and provides an admin dashboard
* with the ability to delete/reset individual records.
*/
/* =========================================================
* 1. AJAX CLICK TRACKING
* ========================================================= */
add_action('wp_ajax_track_pdf_download', 'my_pdf_track_download');
add_action('wp_ajax_nopriv_track_pdf_download', 'my_pdf_track_download');
function my_pdf_track_download() {
if (empty($_POST['url'])) {
wp_die();
}
$url = esc_url_raw(wp_unslash($_POST['url']));
$path = parse_url($url, PHP_URL_PATH);
// Only track PDF files
if (strtolower(pathinfo($path, PATHINFO_EXTENSION)) !== 'pdf') {
wp_die();
}
// Unique ID based on PDF URL
$id = md5($url);
$key = 'pdf_tracker_' . $id;
// Get existing data
$data = get_option($key, array());
if (!is_array($data)) {
$data = array();
}
// Extract readable filename
$filename = basename($path);
$filename = urldecode($filename);
// Update data
$data['filename'] = sanitize_text_field($filename);
$data['url'] = $url;
/*
* NEW PDF STARTING COUNT
*
* Currently set so that the FIRST click shows as 101.
* Change 101 to 1 if you ever want normal counting.
*/
$data['count'] = isset($data['count'])
? (int) $data['count'] + 1
: 101;
$data['last_click'] = current_time('mysql');
update_option($key, $data, false);
wp_die();
}
/* =========================================================
* 2. FRONT-END CLICK DETECTION
* ========================================================= */
add_action('wp_footer', function () {
?>
<script>
document.addEventListener('click', function(e) {
const link = e.target.closest('a');
if (!link) return;
// Works whether the class is on <a> or its parent/wrapper
const shouldTrack =
link.classList.contains('track-pdf-download') ||
link.closest('.track-pdf-download');
if (!shouldTrack) return;
const pdfUrl = link.href;
if (!pdfUrl) return;
try {
const url = new URL(pdfUrl);
// Only track PDF files
if (!url.pathname.toLowerCase().endsWith('.pdf')) {
return;
}
} catch (error) {
return;
}
const data = new FormData();
data.append('action', 'track_pdf_download');
data.append('url', pdfUrl);
if (navigator.sendBeacon) {
navigator.sendBeacon(
'<?php echo esc_url(admin_url('admin-ajax.php')); ?>',
data
);
} else {
fetch(
'<?php echo esc_url(admin_url('admin-ajax.php')); ?>',
{
method: 'POST',
body: data,
keepalive: true
}
);
}
});
</script>
<?php
});
/* =========================================================
* 3. WORDPRESS ADMIN MENU
* ========================================================= */
add_action('admin_menu', function () {
add_menu_page(
'PDF Downloads',
'PDF Downloads',
'manage_options',
'pdf-downloads',
'my_pdf_download_dashboard',
'dashicons-media-document',
30
);
});
/* =========================================================
* 4. DELETE PDF TRACKING RECORD
* ========================================================= */
add_action('admin_post_delete_pdf_tracking', 'my_delete_pdf_tracking');
function my_delete_pdf_tracking() {
// Only administrators / users with this capability
if (!current_user_can('manage_options')) {
wp_die('You do not have permission to do this.');
}
// Make sure ID exists
if (empty($_GET['pdf_id'])) {
wp_die('Invalid PDF tracking record.');
}
$pdf_id = sanitize_text_field(wp_unslash($_GET['pdf_id']));
// MD5 IDs must contain exactly 32 hexadecimal characters
if (!preg_match('/^[a-f0-9]{32}$/', $pdf_id)) {
wp_die('Invalid PDF ID.');
}
// Security check
check_admin_referer(
'delete_pdf_tracking_' . $pdf_id
);
// Delete tracking record
delete_option(
'pdf_tracker_' . $pdf_id
);
// Return to dashboard
wp_safe_redirect(
add_query_arg(
'pdf_deleted',
'1',
admin_url('admin.php?page=pdf-downloads')
)
);
exit;
}
/* =========================================================
* 5. PDF DOWNLOAD DASHBOARD
* ========================================================= */
function my_pdf_download_dashboard() {
global $wpdb;
if (!current_user_can('manage_options')) {
return;
}
$results = $wpdb->get_results(
"SELECT option_name, option_value
FROM {$wpdb->options}
WHERE option_name LIKE 'pdf_tracker_%'"
);
$downloads = array();
foreach ($results as $row) {
$data = maybe_unserialize($row->option_value);
if (!is_array($data)) {
continue;
}
// Extract the PDF ID from the option name
$data['pdf_id'] = str_replace(
'pdf_tracker_',
'',
$row->option_name
);
$downloads[] = $data;
}
// Highest downloads first
usort($downloads, function ($a, $b) {
return ($b['count'] ?? 0) <=> ($a['count'] ?? 0);
});
?>
<div class="wrap">
<h1>PDF Downloads</h1>
<?php
/* Success message after deleting a record */
if (
isset($_GET['pdf_deleted']) &&
$_GET['pdf_deleted'] === '1'
) :
?>
<div class="notice notice-success is-dismissible">
<p>
PDF tracking record deleted successfully.
</p>
</div>
<?php endif; ?>
<p>
PDF button clicks recorded by your website.
</p>
<table class="widefat striped">
<thead>
<tr>
<th>PDF File</th>
<th style="width:120px;">
Downloads
</th>
<th style="width:220px;">
Last Click
</th>
<th style="width:120px;">
Action
</th>
</tr>
</thead>
<tbody>
<?php if (!empty($downloads)) : ?>
<?php foreach ($downloads as $data) : ?>
<tr>
<!-- PDF FILE -->
<td>
<?php if (!empty($data['url'])) : ?>
<a
href="<?php echo esc_url($data['url']); ?>"
target="_blank"
rel="noopener"
>
<strong>
<?php
echo esc_html(
$data['filename'] ?? 'Unknown PDF'
);
?>
</strong>
</a>
<?php else : ?>
<?php
echo esc_html(
$data['filename'] ?? 'Unknown PDF'
);
?>
<?php endif; ?>
</td>
<!-- DOWNLOAD COUNT -->
<td>
<strong>
<?php
echo number_format_i18n(
(int) ($data['count'] ?? 0)
);
?>
</strong>
</td>
<!-- LAST CLICK -->
<td>
<?php
if (!empty($data['last_click'])) {
echo esc_html(
mysql2date(
get_option('date_format') . ' ' .
get_option('time_format'),
$data['last_click']
)
);
} else {
echo '—';
}
?>
</td>
<!-- DELETE BUTTON -->
<td>
<?php
$delete_url = wp_nonce_url(
admin_url(
'admin-post.php?action=delete_pdf_tracking&pdf_id=' .
urlencode($data['pdf_id'])
),
'delete_pdf_tracking_' . $data['pdf_id']
);
?>
<a
href="<?php echo esc_url($delete_url); ?>"
class="button button-small"
style="color:#b32d2e;"
onclick="return confirm('Are you sure you want to delete this PDF tracking record? The download count will be removed.');"
>
Delete
</a>
</td>
</tr>
<?php endforeach; ?>
<?php else : ?>
<tr>
<td colspan="4">
No PDF downloads have been recorded yet.
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?php
}