PDF Viewer

DLM PDF.js System

The DLM PDF.js System is a pair of WordPress code snippets that work together to provide protected PDF viewing and unified file event counting for sites using the Download Monitor and PDF.js Viewer Shortcode plugins.

It solves three problems that Download Monitor does not handle natively:

  • Protected PDF files managed by Download Monitor cannot be viewed inline — clicking a download link prompts a file download rather than opening a viewer.
  • The PDF.js Viewer plugin cannot access Download Monitor’s protected file storage directly, making it impossible to use the two plugins together without a proxy layer.
  • Download Monitor’s native download counter does not count PDF views (since PDFs bypass the normal download flow), and its counting features have not worked for me and some others as expressed in online support.

System Architecture

Click any component box to explore its detail diagram.

DLM PDF.js system — component overview WordPress page shortcodes placed by site author [dlm_pdfjs id="x"] opens PDF in new tab [download id="x"] ZIP / other downloads [file_event_count_live] live count + date display Required plugins must be installed and active in WordPress PDF.js Viewer viewer.php endpoint Download Monitor protected file storage Code Snippets runs the PHP snippets Required snippets installed via Code Snippets plugin DLM PDF.js Proxy Viewer Rev 1 — proxy + [dlm_pdfjs] DLM PDF.js Proxy Counter Rev 1 — counting + admin panel
[dlm_pdfjs] — PDF view request flow User clicks [dlm_pdfjs id="x"] link link opens in new browser tab viewer.php loads in new tab PDF.js viewer renders in browser PDF.js requests proxy URL /?dlm_pdf_proxy=x Proxy Viewer snippet handles request verifies ID, resolves path, checks security Counter incremented ron_increment_file_event() PDF streamed to browser readfile() with correct headers
The [dlm_pdfjs] shortcode renders a plain HTML link. Clicking opens viewer.php in a new tab. PDF.js then requests the proxy URL, which verifies the download ID, resolves the file path from Download Monitor metadata, increments the counter, and streams the PDF. The real file path in dlm_uploads is never exposed to the visitor.
[download id="x"] — ZIP download flow User clicks [download id="x"] link standard Download Monitor link Download Monitor serves file handles request natively dlm_downloading hook fires WordPress action after file served Counter snippet catches hook ron_unified_count_dlm_download() → ron_increment_file_event()
For ZIP files and any other non-PDF file type, the existing [download id=”x”] shortcode works unchanged. Download Monitor handles delivery natively and fires the dlm_downloading hook when done. The Proxy Counter snippet listens for this hook and increments the event counter automatically — no changes needed for any file type Download Monitor serves.
[file_event_count_live] — live counter flow [file_event_count_live id="x"] shortcode on page PHP renders span with initial count <span class="ron-file-event-count" data-id="x">47</span> Global flag set true CSS + JS this page only Count shown immediately no blank flash on load JS polls AJAX every 5 seconds admin-ajax.php?action=ron_get_file_event&id=x DOM updated only if value changed prevents unnecessary page reflows every 5s
The live counter renders the current count server-side on first load so there is never a blank value while JavaScript initializes. A global PHP flag ensures the polling JavaScript is only loaded on pages that use a live shortcode — other pages get no extra overhead. The polling loop only updates the DOM when the value has actually changed, preventing unnecessary reflows.
PDF.js Viewer plugin — role in the system Plugin by TwisterMc pdfjs-viewer-shortcode v3.0.4 Bundles Mozilla PDF.js open source PDF renderer viewer.php endpoint /wp-content/plugins/pdfjs-viewer-shortcode/pdfjs/web/ Accepts file= parameter renders PDF from proxy URL in browser
The PDF.js Viewer Shortcode plugin provides the viewer.php endpoint the system relies on. viewer.php is used instead of viewer.html because newer versions of PDF.js bundle ES modules (.mjs files) which require correct MIME types — viewer.php handles this internally. No plugin configuration changes are needed; the system simply calls its viewer endpoint with the proxy URL as the file= parameter.
Download Monitor — role in the system File storage dlm_uploads/YYYY/MM/ Download IDs unique ID per managed file dlm_downloading hook fires on every download Used by Proxy Viewer snippet resolves file path from DLM metadata [download id="x"] for ZIPs unchanged DLM handles delivery, hook triggers counter
Download Monitor stores protected files in a non-public uploads directory, assigns a unique download ID to each file, and fires the dlm_downloading hook when a file is served. The Proxy Viewer snippet uses DLM metadata to resolve the real file path server-side. DLM’s native display counter is disabled since the Proxy Counter provides unified tracking across both PDFs and ZIPs.
Code Snippets plugin — role in the system Code Snippets plugin manages and executes PHP snippets DLM PDF.js Proxy Viewer Rev 1 — snippet 1 DLM PDF.js Proxy Counter Rev 1 — snippet 2 Both snippets active and working together
Code Snippets executes the two PHP snippets within the WordPress environment. An important technical note: because Code Snippets runs snippets at an early load stage, WordPress transient functions are not yet available. This is why the counter uses a static PHP array combined with wp_cache (Redis) for duplicate-count prevention rather than the more common get_transient/set_transient pattern.
DLM PDF.js Proxy Viewer — what it contains DLM PDF.js Proxy Viewer — Rev 1 [dlm_pdfjs] shortcode renders link, opens viewer in new tab manual fallback map override auto-detect per download ID PDF proxy handler template_redirect, streams PDF path resolver 6-step DLM metadata lookup chain path cache _ron_pdfjs_relative_path post meta file_exists() guard graceful fallback if plugin missing
The Proxy Viewer snippet owns the complete PDF delivery pipeline. The [dlm_pdfjs] shortcode renders a link to viewer.php with the proxy URL as the file parameter. The proxy intercepts requests via template_redirect, runs security checks, resolves the file path through a 6-step metadata lookup, caches the result, increments the counter, and streams the PDF. The real file path in dlm_uploads is never exposed to the visitor.
DLM PDF.js Proxy Counter — what it contains DLM PDF.js Proxy Counter — Rev 1 ron_increment_file_event() static array + Redis two-layer lock dlm_downloading hook counts ZIP and all other downloads display shortcodes [file_event_count_live] + date AJAX endpoint ron_get_file_event — JSON response DLM PDF.js Stats panel Downloads → admin panel conditional JS enqueue only loads on pages that need it
The Proxy Counter is the shared counting engine for the entire system. It provides the core increment function called by both the PDF proxy and the ZIP download hook. The two-layer lock (static PHP array for within-request duplicates, Redis wp_cache for cross-request duplicates) prevents PDF.js byte-range requests from inflating counts. The admin panel under Downloads → DLM PDF.js Stats shows sortable stats with editable counts for restoring historical data.