PageSourceSearch

https://digicyber.in/modules/digi-membership-pro-3/public/js/dmp.js?rnd=55602

js digicyber.in collected 2026-10-02 01:56:02 UTC 14,476 bytes, 406 lines download raw bytes

1jQuery(function($){
2 'use strict';
3
4 function triggerPayment(planId, gateway, btn) {
5  if (!window.DMP_CFG || !DMP_CFG.logged_in) {
6   var currentUrl = window.location.href;
7   var loginUrl = (DMP_CFG && DMP_CFG.login_url) ? DMP_CFG.login_url : '/wp-login.php';
8   window.location.href = loginUrl + (loginUrl.indexOf('?') !== -1 ? '&' : '?') + 'redirect_to=' + encodeURIComponent(currentUrl);
9   return;
10  }
11
12  var originalText = '';
13  if (btn && btn.length) {
14   originalText = btn.is('input') ? btn.val() : btn.text();
15   btn.prop('disabled', true);
16   if (btn.is('input')) btn.val('Processing...'); else btn.text('Processing...');
17  }
18
19  var resetBtn = function() {
20   if (btn && btn.length) {
21    btn.prop('disabled', false);
22    if (btn.is('input')) btn.val(originalText); else btn.text(originalText);
23   }
24  };
25
26  $.post(DMP_CFG.ajax, {
27   action: 'dmp_start_payment',
28   nonce: DMP_CFG.nonce,
29   plan_id: planId,
30   gateway: gateway || ''
31  }, function(r) {
32   if (!r.success) {
33    alert(r.data && r.data.message ? r.data.message : 'Payment initiation failed.');
34    resetBtn();
35    return;
36   }
37   if (r.data.provider === 'phonepe') {
38    window.location.href = r.data.redirect_url;
39    return;
40   }
41   if (r.data.provider === 'razorpay') {
42    var openRzp = function() {
43     var rzp = new Razorpay({
44      key: r.data.key_id,
45      amount: r.data.amount,
46      currency: r.data.currency,
47      name: r.data.name,
48      description: r.data.description,
49      order_id: r.data.order_id,
50      handler: function(resp) {
51       $.post(DMP_CFG.ajax, {
52        action: 'dmp_verify_razorpay',
53        nonce: DMP_CFG.nonce,
54        razorpay_payment_id: resp.razorpay_payment_id,
55        razorpay_order_id: resp.razorpay_order_id,
56        razorpay_signature: resp.razorpay_signature
57       }, function(vr) {
58        if (vr.success) {
59         // Broadcast cross-tab sync event
60         try {
61          localStorage.setItem('dmp_membership_synced', Date.now().toString());
62         } catch(e){}
63
64         if (vr.data.redirect) {
65          window.location.href = vr.data.redirect;
66         } else {
67          syncMembershipState();
68          resetBtn();
69         }
70        } else {
71         alert(vr.data && vr.data.message ? vr.data.message : 'Payment verification failed.');
72         resetBtn();
73        }
74       }).fail(function() {
75        alert('Verification request failed. Please check your dashboard.');
76        resetBtn();
77       });
78      },
79      modal: {
80       ondismiss: function() {
81        resetBtn();
82       }
83      }
84     });
85     rzp.open();
86    };
87
88    if (window.Razorpay) {
89     openRzp();
90    } else {
91     $.getScript('https://checkout.razorpay.com/v1/checkout.js').done(openRzp).fail(function() {
92      alert('Could not load Razorpay checkout SDK.');
93      resetBtn();
94     });
95    }
96   }
97  }).fail(function() {
98   alert('Network error connecting to payment gateway.');
99   resetBtn();
100  });
101 }
102
103 // Click handler for plan shortcode buttons
104 $(document).on('click', '.dmp-pay', function(e) {
105  e.preventDefault();
106  var b = $(this);
107  triggerPayment(b.data('plan'), b.data('gateway'), b);
108 });
109
110 // Click handler for Elementor buttons or links targeting dmp_pay / dmp_checkout
111 $(document).on('click', 'a[href*="dmp_pay="], a[href*="dmp_checkout="], a[href*="dmp_plan="]', function(e) {
112  var href = $(this).attr('href');
113  if (!href) return;
114  var match = href.match(/[?&](?:dmp_pay|dmp_checkout|dmp_plan)=([^&#]+)/);
115  if (match && match[1]) {
116   e.preventDefault();
117   var gwMatch = href.match(/[?&]gateway=([^&#]+)/);
118   var gw = gwMatch ? gwMatch[1] : '';
119   triggerPayment(match[1], gw, $(this));
120  }
121 });
122
123 /* ----------------------------------------------------
124  * REAL-TIME COUNTDOWN TIMER (Year, Month, Day, Hour, Min, Sec)
125  * Uses authoritative server target timestamp with client offset.
126  * ---------------------------------------------------- */
127 function padZero(num) {
128  return num < 10 ? '0' + num : '' + num;
129 }
130
131 var countdownIntervals = [];
132
133 function clearAllCountdownIntervals() {
134  for (var i = 0; i < countdownIntervals.length; i++) {
135   clearInterval(countdownIntervals[i]);
136  }
137  countdownIntervals = [];
138 }
139
140 function padZero(n) {
141  var num = parseInt(n, 10);
142  if (isNaN(num)) return n;
143  return (num < 10 && num >= 0) ? '0' + num : '' + num;
144 }
145
146 function initCountdowns() {
147  clearAllCountdownIntervals();
148
149  var timers = $('[data-dmp-countdown]');
150  if (!timers.length) return;
151
152  var clientInitTime = Date.now();
153
154  timers.each(function() {
155   var wrapper = $(this);
156   var targetTs = parseInt(wrapper.attr('data-dmp-countdown'), 10);
157   var serverNowTs = parseInt(wrapper.attr('data-dmp-now'), 10) || Math.floor(Date.now() / 1000);
158   var expiredText = wrapper.attr('data-expired-text') || 'Membership Expired';
159
160   if (!targetTs || isNaN(targetTs)) return;
161
162   var hasYears = wrapper.find('[data-dmp-unit="years"]').length > 0;
163   var hasMonths = wrapper.find('[data-dmp-unit="months"]').length > 0;
164
165   function updateTimer() {
166    var elapsedSeconds = Math.floor((Date.now() - clientInitTime) / 1000);
167    var currentServerTs = serverNowTs + elapsedSeconds;
168    var remaining = targetTs - currentServerTs;
169
170    if (remaining <= 0) {
171     wrapper.find('[data-dmp-unit="years"]').text('00');
172     wrapper.find('[data-dmp-unit="months"]').text('00');
173     wrapper.find('[data-dmp-unit="days"]').text('00');
174     wrapper.find('[data-dmp-unit="hours"]').text('00');
175     wrapper.find('[data-dmp-unit="minutes"]').text('00');
176     wrapper.find('[data-dmp-unit="seconds"]').text('00');
177     wrapper.addClass('dmp-countdown-ended');
178     wrapper.find('.dmp-countdown-status-badge').text('EXPIRED').css({
179      'border-color':'#ef4444','color':'#f87171','background':'rgba(239,68,68,.12)'
180     });
181     // Ask server once if renewed/extended
182     if (!wrapper.data('rechecked')) {
183      wrapper.data('rechecked', true);
184      setTimeout(syncMembershipState, 2000);
185     }
186     return;
187    }
188
189    var DAY_SEC = 86400;
190    var HOUR_SEC = 3600;
191    var MIN_SEC = 60;
192    var MONTH_SEC = 30.4375 * DAY_SEC;
193    var YEAR_SEC = 365.25 * DAY_SEC;
194
195    var years = 0, months = 0, days = 0, hours = 0, minutes = 0, seconds = 0;
196    var rem = remaining;
197
198    if (hasYears) {
199     years = Math.floor(rem / YEAR_SEC);
200     rem = rem % YEAR_SEC;
201    }
202
203    if (hasMonths) {
204     months = Math.floor(rem / MONTH_SEC);
205     rem = rem % MONTH_SEC;
206    }
207
208    days = Math.floor(rem / DAY_SEC);
209    rem = rem % DAY_SEC;
210
211    hours = Math.floor(rem / HOUR_SEC);
212    rem = rem % HOUR_SEC;
213
214    minutes = Math.floor(rem / MIN_SEC);
215    seconds = Math.floor(rem % MIN_SEC);
216
217    if (hasYears) wrapper.find('[data-dmp-unit="years"]').text(padZero(years));
218    if (hasMonths) wrapper.find('[data-dmp-unit="months"]').text(padZero(months));
219    wrapper.find('[data-dmp-unit="days"]').text(padZero(days));
220    wrapper.find('[data-dmp-unit="hours"]').text(padZero(hours));
221    wrapper.find('[data-dmp-unit="minutes"]').text(padZero(minutes));
222    wrapper.find('[data-dmp-unit="seconds"]').text(padZero(seconds));
223   }
224
225   updateTimer();
226   var timerId = setInterval(updateTimer, 1000);
227   countdownIntervals.push(timerId);
228  });
229 }
230
231 /* ----------------------------------------------------
232  * REAL-TIME CLIENT HYDRATION & CACHE BYPASS ENGINE
233  * Solves page caching issues by asynchronously validating live status.
234  * ---------------------------------------------------- */
235 var isSyncing = false;
236 var lastKnownStatus = null;
237
238 function syncMembershipState() {
239  if (isSyncing || !window.DMP_CFG || !DMP_CFG.logged_in) return;
240
241  isSyncing = true;
242
243  var customContainer = $('.dmp-countdown-realtime-container[data-dmp-user-id]');
244  var customUid = (customContainer.length && customContainer.data('dmp-user-id')) ? customContainer.data('dmp-user-id') : null;
245
246  var reqData = {
247   action: 'dmp_get_user_status',
248   _t: Date.now()
249  };
250  if (customUid) {
251   reqData.user_id = customUid;
252  }
253
254  $.ajax({
255   url: DMP_CFG.ajax,
256   type: 'GET',
257   cache: false,
258   data: reqData,
259   dataType: 'json',
260   success: function(res) {
261    isSyncing = false;
262    if (!res || !res.success || !res.data) return;
263    var d = res.data;
264
265    // Real-time access sync: If on a locked content page and now active, reload page to unlock!
266    if (d.active && $('.dmp-locked-content-box').length) {
267     window.location.reload();
268     return;
269    }
270
271    // Real-time role & status sync: If status changed (e.g. active -> expired), reload page to reflect real-time permissions!
272    if (lastKnownStatus !== null && lastKnownStatus !== d.status) {
273     lastKnownStatus = d.status;
274     try {
275      if (window.localStorage) localStorage.setItem('dmp_user_status', d.status);
276     } catch(e){}
277     window.location.reload();
278     return;
279    }
280    lastKnownStatus = d.status;
281    try {
282     if (window.localStorage) localStorage.setItem('dmp_user_status', d.status);
283    } catch(e){}
284
285    // 1. Update Status Component Badges
286    $('[data-dmp-status-live]').each(function() {
287     var el = $(this);
288     el.removeClass('dmp-status-comp-active dmp-status-comp-expired dmp-status-comp-suspended dmp-status-comp-lifetime dmp-status-comp-inactive')
289       .addClass('dmp-status-comp-' + d.status);
290     var labelSpan = el.find('.dmp-status-text');
291     if (labelSpan.length) {
292      labelSpan.text(d.status_label);
293     } else {
294      el.text(d.status_label);
295     }
296    });
297
298    // 2. If user is active but page was showing "Expired" notice: Hydrate with Live Countdown!
299    var expiredCards = $('.dmp-countdown-expired-card');
300    if (d.active && expiredCards.length) {
301     expiredCards.each(function() {
302      var expCard = $(this);
303      var container = expCard.closest('.dmp-countdown-realtime-container');
304      if (container.length && container.data('dmp-template')) {
305       // Replace expired card with the live countdown template
306       container.html(container.data('dmp-template'));
307       var newWrapper = container.find('[data-dmp-countdown]');
308       newWrapper.attr('data-dmp-countdown', d.target_ts);
309       newWrapper.attr('data-dmp-now', d.now_ts);
310       initCountdowns();
311      } else {
312       // Graceful inline transformation
313       expCard.replaceWith(
314        '<div class="dmp-countdown-wrapper dmp-countdown-layout-boxes" data-dmp-countdown="' + d.target_ts + '" data-dmp-now="' + d.now_ts + '" style="margin:20px auto;max-width:560px;">' +
315        '<div class="dmp-countdown-header"><div class="dmp-countdown-title-wrap"><span class="dmp-countdown-icon">⏱️</span><span class="dmp-countdown-title">MEMBERSHIP ACCESS TIME REMAINING</span></div><span class="dmp-countdown-status-badge">ACTIVE</span></div>' +
316        '<div class="dmp-countdown-grid">' +
317        '<div class="dmp-countdown-box" data-unit="days"><span class="dmp-countdown-num" data-dmp-unit="days">' + padZero(d.days) + '</span><span class="dmp-countdown-label">DAYS</span></div><div class="dmp-countdown-sep">:</div>' +
318        '<div class="dmp-countdown-box" data-unit="hours"><span class="dmp-countdown-num" data-dmp-unit="hours">' + padZero(d.hours) + '</span><span class="dmp-countdown-label">HOURS</span></div><div class="dmp-countdown-sep">:</div>' +
319        '<div class="dmp-countdown-box" data-unit="minutes"><span class="dmp-countdown-num" data-dmp-unit="minutes">' + padZero(d.minutes) + '</span><span class="dmp-countdown-label">MIN</span></div><div class="dmp-countdown-sep">:</div>' +
320        '<div class="dmp-countdown-box" data-unit="seconds"><span class="dmp-countdown-num" data-dmp-unit="seconds">' + padZero(d.seconds) + '</span><span class="dmp-countdown-label">SEC</span></div>' +
321        '</div>' +
322        '<div class="dmp-countdown-footer"><div class="dmp-countdown-footer-pill"><span>Expires: <strong>' + (d.formatted_expiry || 'Active') + '</strong></span></div></div>' +
323        '</div>'
324       );
325       initCountdowns();
326      }
327     });
328    }
329
330    // 3. Update Existing Active Countdown Timers if Expiry Changed (e.g. admin extended date)
331    $('[data-dmp-countdown]').each(function() {
332     var wrap = $(this);
333     var curTarget = parseInt(wrap.attr('data-dmp-countdown'), 10);
334     if (d.active && d.target_ts && d.target_ts !== curTarget) {
335      wrap.attr('data-dmp-countdown', d.target_ts);
336      wrap.attr('data-dmp-now', d.now_ts);
337      wrap.removeClass('dmp-countdown-ended');
338      wrap.find('.dmp-countdown-status-badge').text('ACTIVE').removeAttr('style');
339      wrap.find('.dmp-countdown-footer strong').text(d.formatted_expiry);
340      initCountdowns();
341     }
342    });
343
344    // 4. Update Member Card if on page
345    $('.dmp-member-card').each(function() {
346     var card = $(this);
347     card.find('.dmp-mc-plan').text(d.plan_name || 'Membership');
348     card.find('.dmp-mc-status').text(d.status_label).removeClass('dmp-mc-status-active dmp-mc-status-expired').addClass('dmp-mc-status-' + d.status);
349     card.find('.dmp-mc-expiry').text(d.formatted_expiry || 'Lifetime');
350    });
351
352    // 5. Update Days Remaining shortcode outputs
353    $('[data-dmp-days-count]').text(d.is_unlimited ? 'Unlimited' : (d.days + ' days'));
354   },
355   error: function() {
356    isSyncing = false;
357   }
358  });
359 }
360
361 /* ----------------------------------------------------
362  * CROSS-TAB REAL-TIME SYNCHRONIZATION
363  * Listen for storage events across open browser tabs.
364  * ---------------------------------------------------- */
365 window.addEventListener('storage', function(e) {
366  if (e.key === 'dmp_membership_synced') {
367   window.location.reload();
368  }
369 });
370
371 // Re-check when window regains focus or becomes visible
372 document.addEventListener('visibilitychange', function() {
373  if (!document.hidden) {
374   syncMembershipState();
375  }
376 });
377 $(window).on('focus', function() {
378  syncMembershipState();
379 });
380
381 // Periodic live heartbeat every 20 seconds
382 setInterval(syncMembershipState, 20000);
383
384 /* ----------------------------------------------------
385  * INITIALIZATION & ELEMENTOR INTEGRATION
386  * ---------------------------------------------------- */
387 $(document).ready(function() {
388  initCountdowns();
389  // Hydrate live state on mount
390  setTimeout(syncMembershipState, 300);
391 });
392
393 // Elementor Editor live preview hooks
394 if (window.elementorFrontend && window.elementorFrontend.hooks) {
395  window.elementorFrontend.hooks.addAction('frontend/element_ready/global', function() {
396   initCountdowns();
397   syncMembershipState();
398  });
399 }
400
401 // Global on-demand status sync function
402 window.dmpSyncStatus = function() {
403  isSyncing = false;
404  syncMembershipState();
405 };
406});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.