Download Monitor - Version 4.7.0

Version Description

  • 14.10.2022 = Fixed: Quick add - recreate Uploader if file upload ended in error ( #1079 ) Changed: Show grouped dates as period instead of a single day on repoprt chart tooltip ( #1082 ) Fixed: Performance issues on larga databases ( #1081 ) Changed: Get user data first ( #1086 ) Fixed: Downloading big files error ( #1084 ) Changed: Get chart data un chunks ( #1083 )
Download this release

Release Info

Developer raldea89
Plugin Icon 128x128 Download Monitor
Version 4.7.0
Comparing to
See all releases

Code changes from version 4.6.5 to 4.7.0

assets/js/database-upgrader.js CHANGED
@@ -147,7 +147,8 @@
147
  } else {
148
  ProgressBar.progressHandler((dlmDBUpgrader.completed + dlmDBUpgrader.upgraderResumeOffset) * 100);
149
  }
150
-
 
151
  }
152
  };
153
 
@@ -193,13 +194,6 @@
193
  ProgressBar.label.text(ProgressBar.el.progressbar('value') + '%');
194
  },
195
  complete: () => {
196
- setTimeout(function () {
197
- ProgressBar.label.text('Complete! Page will be reloaded in 5 seconds.');
198
- ProgressBar.el.addClass('completed');
199
- setTimeout(function () {
200
- window.location.reload(false);
201
- }, 5000);
202
- }, 3000);
203
  }
204
  });
205
  },
147
  } else {
148
  ProgressBar.progressHandler((dlmDBUpgrader.completed + dlmDBUpgrader.upgraderResumeOffset) * 100);
149
  }
150
+ jQuery('#dlm_progress-bar').parent().find('.dlm-progress-label').text('Upgrade completed!');
151
+ jQuery('#dlm_progress-bar').addClass('completed');
152
  }
153
  };
154
 
194
  ProgressBar.label.text(ProgressBar.el.progressbar('value') + '%');
195
  },
196
  complete: () => {
 
 
 
 
 
 
 
197
  }
198
  });
199
  },
assets/js/database-upgrader.min.js CHANGED
@@ -1 +1 @@
1
- !function(a){"use strict";var t={counts:0,upgraderResumeOffset:0,completed:0,ajaxRequests:[],ajaxStarted:1,ajaxTimeout:null,ajax:ajaxurl,entries:0,requestsNumber:0,init:function(){a(document).on("click","button#dlm-upgrade-db,a.dlm-db-upgrade-link",function(e){e.preventDefault(),a(this).prop("disabled",!0),a("body").find(".dlm-upgrade-db-notice").addClass("started");e={url:t.ajax,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"dlm_db_log_entries",nonce:dlm_upgrader.nonce},success:function(e){"0"!==e&&"0"!==e.entries?(t.entries=e.entries,e.offset,0!==parseInt(e.offset)&&(t.upgraderResumeOffset=parseInt(e.offset),e={url:t.ajax,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"dlm_upgrade_db_clear_offset",nonce:dlm_upgrader.nonce,offset:parseInt(e.offset)},success:function(){console.log("previous offset cleared")}},a.ajax(e))):t.entries=0,t.processAjax(),s.init(Math.ceil(1e6*t.upgraderResumeOffset/t.entries))}};a.ajax(e)})},processAjax:function(){if(0<t.entries-1e4*t.upgraderResumeOffset){t.requestsNumber=1e4<=t.entries?parseInt(Math.ceil(t.entries/1e4)):1;for(let e=0;e<=t.requestsNumber-t.upgraderResumeOffset;e++){var a={url:t.ajax,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"dlm_upgrade_db",nonce:dlm_upgrader.nonce,offset:t.counts+t.upgraderResumeOffset},success:function(){t.ajaxStarted=t.ajaxStarted-1,t.completed=t.completed+1,s.progressHandler(100*(t.completed+t.upgraderResumeOffset)/t.requestsNumber)}};t.counts+=1,t.ajaxRequests.push(a)}}var e={url:t.ajax,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"dlm_alter_download_log",nonce:dlm_upgrader.nonce},success:function(){t.ajaxStarted=t.ajaxStarted-1,t.completed=t.completed+1,0<t.entries?s.progressHandler(100*(t.completed+t.upgraderResumeOffset)/t.requestsNumber):s.progressHandler(100*(t.completed+t.upgraderResumeOffset))}};t.ajaxRequests.push(e),t.runAjaxs()},runAjaxs:function(){for(var e;t.ajaxStarted<2&&0<t.ajaxRequests.length;)t.ajaxStarted=t.ajaxStarted+1,e=t.ajaxRequests.shift(),a.ajax(e);0<t.ajaxRequests.length&&(t.ajaxTimeout=setTimeout(function(){console.log("Delayed 1s"),t.runAjaxs()},1e3))}};const s={el:{},label:{},init:(e=0)=>{s.el=jQuery("#dlm_progress-bar"),s.label=jQuery("#dlm_progress-bar").parent().find(".dlm-progress-label"),s.label.text(Math.ceil(e)+"%"),s.el.progressbar({value:e,change:()=>{s.label.text(s.el.progressbar("value")+"%")},complete:()=>{setTimeout(function(){s.label.text("Complete! Page will be reloaded in 5 seconds."),s.el.addClass("completed"),setTimeout(function(){window.location.reload(!1)},5e3)},3e3)}})},progressHandler:e=>{s.el.progressbar("value",Math.ceil(e))}};a(document).ready(function(){t.init()})}(jQuery);
1
+ !function(a){"use strict";var t={counts:0,upgraderResumeOffset:0,completed:0,ajaxRequests:[],ajaxStarted:1,ajaxTimeout:null,ajax:ajaxurl,entries:0,requestsNumber:0,init:function(){a(document).on("click","button#dlm-upgrade-db,a.dlm-db-upgrade-link",function(e){e.preventDefault(),a(this).prop("disabled",!0),a("body").find(".dlm-upgrade-db-notice").addClass("started");e={url:t.ajax,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"dlm_db_log_entries",nonce:dlm_upgrader.nonce},success:function(e){"0"!==e&&"0"!==e.entries?(t.entries=e.entries,e.offset,0!==parseInt(e.offset)&&(t.upgraderResumeOffset=parseInt(e.offset),e={url:t.ajax,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"dlm_upgrade_db_clear_offset",nonce:dlm_upgrader.nonce,offset:parseInt(e.offset)},success:function(){console.log("previous offset cleared")}},a.ajax(e))):t.entries=0,t.processAjax(),s.init(Math.ceil(1e6*t.upgraderResumeOffset/t.entries))}};a.ajax(e)})},processAjax:function(){if(0<t.entries-1e4*t.upgraderResumeOffset){t.requestsNumber=1e4<=t.entries?parseInt(Math.ceil(t.entries/1e4)):1;for(let e=0;e<=t.requestsNumber-t.upgraderResumeOffset;e++){var a={url:t.ajax,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"dlm_upgrade_db",nonce:dlm_upgrader.nonce,offset:t.counts+t.upgraderResumeOffset},success:function(){t.ajaxStarted=t.ajaxStarted-1,t.completed=t.completed+1,s.progressHandler(100*(t.completed+t.upgraderResumeOffset)/t.requestsNumber)}};t.counts+=1,t.ajaxRequests.push(a)}}var e={url:t.ajax,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"dlm_alter_download_log",nonce:dlm_upgrader.nonce},success:function(){t.ajaxStarted=t.ajaxStarted-1,t.completed=t.completed+1,0<t.entries?s.progressHandler(100*(t.completed+t.upgraderResumeOffset)/t.requestsNumber):s.progressHandler(100*(t.completed+t.upgraderResumeOffset)),jQuery("#dlm_progress-bar").parent().find(".dlm-progress-label").text("Upgrade completed!"),jQuery("#dlm_progress-bar").addClass("completed")}};t.ajaxRequests.push(e),t.runAjaxs()},runAjaxs:function(){for(var e;t.ajaxStarted<2&&0<t.ajaxRequests.length;)t.ajaxStarted=t.ajaxStarted+1,e=t.ajaxRequests.shift(),a.ajax(e);0<t.ajaxRequests.length&&(t.ajaxTimeout=setTimeout(function(){console.log("Delayed 1s"),t.runAjaxs()},1e3))}};const s={el:{},label:{},init:(e=0)=>{s.el=jQuery("#dlm_progress-bar"),s.label=jQuery("#dlm_progress-bar").parent().find(".dlm-progress-label"),s.label.text(Math.ceil(e)+"%"),s.el.progressbar({value:e,change:()=>{s.label.text(s.el.progressbar("value")+"%")},complete:()=>{}})},progressHandler:e=>{s.el.progressbar("value",Math.ceil(e))}};a(document).ready(function(){t.init()})}(jQuery);
assets/js/reports/reports.js CHANGED
@@ -5,6 +5,9 @@ jQuery(function ($) {
5
 
6
  // Let's initiate the reports.
7
  const reports = new DLM_Reports();
 
 
 
8
  dlmReportsInstance.fetchReportsData();
9
  $(document).on('dlm_downloads_report_fetched', function () {
10
  reports.init();
@@ -100,11 +103,24 @@ class DLM_Reports {
100
 
101
  /**
102
  * Fetch our needed data from REST API. This includes the init() function because we need our data to be present and the moment of the initialization
 
 
 
103
  */
104
- async fetchReportsData() {
105
 
106
  const pageWrapper = jQuery('div[data-id="general_info"]');
107
- const fetchedDownloadsData = await fetch(dlmDownloadReportsAPI);
 
 
 
 
 
 
 
 
 
 
108
 
109
  if (!fetchedDownloadsData.ok) {
110
  const errorText = document.createElement('div');
@@ -122,31 +138,39 @@ class DLM_Reports {
122
  throw new Error('Something went wrong! Reports response did not come OK - ' + fetchedData.statusText);
123
  }
124
 
125
- dlmReportsInstance.dlmReportsStats = await fetchedDownloadsData.json();
126
  dlmReportsInstance.mostDownloaded = false;
127
  dlmReportsInstance.stats = false;
128
  dlmReportsInstance.chartType = 'day';
129
 
130
- // Set the all time reports if URL has dlm_time. Used when coming from Dashboard widget
131
- if (window.location.href.indexOf('dlm_time') > 0) {
132
- dlmReportsInstance.dates.downloads.start_date = (Object.keys(dlmReportsInstance.dlmReportsStats).length > 0) ? new Date(dlmReportsInstance.dlmReportsStats[0].date) : new Date();
133
- dlmReportsInstance.dates.downloads.end_date = new Date();
134
- jQuery('#dlm-date-range-picker .date-range-info').html(dlmReportsInstance.dates.downloads.start_date.toLocaleDateString(undefined, {
135
- year: 'numeric', month: 'short', day: '2-digit'
136
- }) + ' - ' + dlmReportsInstance.dates.downloads.end_date.toLocaleDateString(undefined, {
137
- year: 'numeric', month: 'short', day: '2-digit'
138
- }));
139
- }
140
- dlmReportsInstance.createDataOnDate(dlmReportsInstance.dates.downloads.start_date, dlmReportsInstance.dates.downloads.end_date);
141
 
142
- dlmReportsInstance.datePicker = {
143
- opened: false
144
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
- jQuery(document).trigger('dlm_downloads_report_fetched', [
147
- dlmReportsInstance,
148
- dlmReportsInstance.dlmReportsStats
149
- ]);
 
 
 
 
 
150
  }
151
 
152
  /**
@@ -211,8 +235,6 @@ class DLM_Reports {
211
  dlmReportsInstance.overViewTab();
212
  dlmReportsInstance.togglePageSettings();
213
 
214
- // Fetch our users and the logs.
215
- dlmReportsInstance.fetchUserData();
216
  dlmReportsInstance.setSpinner(jQuery('#users_download_log'));
217
  dlmReportsInstance.setSpinner(jQuery('#total_downloads_table_wrapper2'));
218
  dlmReportsInstance.fetchUsersReportsData();
@@ -1888,6 +1910,7 @@ class DLM_Reports {
1888
  const dateString = moment(dateInput).format("YYYY-MM");
1889
 
1890
  if (11 > month) {
 
1891
  if (dateString === prevLastDate) {
1892
 
1893
  date = moment(dateString).format("MMMM, YYYY");
@@ -1908,11 +1931,26 @@ class DLM_Reports {
1908
 
1909
  }
1910
 
1911
- } else if ('undefined' !== plugin.chartType && 'months' === plugin.chartType) {
1912
 
1913
- date = moment(dateInput).format("MMMM, YYYY");
1914
- } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1915
 
 
1916
  date = moment(dateInput).format("MMMM Do, YY");
1917
  }
1918
 
5
 
6
  // Let's initiate the reports.
7
  const reports = new DLM_Reports();
8
+ // Fetch our users and the logs. Do this first so that we query for users we have data.
9
+ dlmReportsInstance.fetchUserData();
10
+ // Get the data used for the chart.
11
  dlmReportsInstance.fetchReportsData();
12
  $(document).on('dlm_downloads_report_fetched', function () {
13
  reports.init();
103
 
104
  /**
105
  * Fetch our needed data from REST API. This includes the init() function because we need our data to be present and the moment of the initialization
106
+ *
107
+ * @param offset Offset used for database query
108
+ * @param limit Limit used for database query
109
  */
110
+ async fetchReportsData(offset = 0, limit = 1000) {
111
 
112
  const pageWrapper = jQuery('div[data-id="general_info"]');
113
+ // Set spinner so that users know there is something going on.
114
+ dlmReportsInstance.setSpinner(jQuery('.total_downloads_chart-wrapper'));
115
+ dlmReportsInstance.setSpinner(jQuery('#users_download_log'));
116
+ dlmReportsInstance.setSpinner(jQuery('#total_downloads_table_wrapper2'));
117
+ // Let's see if these are pretty permalinks or plain
118
+ let fetchingLink = dlmDownloadReportsAPI + '?offset=' + offset + '&limit=' + limit;
119
+ if (dlmDownloadReportsAPI.indexOf('index.php?') > 0) {
120
+ fetchingLink = dlmDownloadReportsAPI + '&offset=' + offset + '&limit=' + limit;
121
+ }
122
+ // Fetch our data
123
+ const fetchedDownloadsData = await fetch(fetchingLink);
124
 
125
  if (!fetchedDownloadsData.ok) {
126
  const errorText = document.createElement('div');
138
  throw new Error('Something went wrong! Reports response did not come OK - ' + fetchedData.statusText);
139
  }
140
 
 
141
  dlmReportsInstance.mostDownloaded = false;
142
  dlmReportsInstance.stats = false;
143
  dlmReportsInstance.chartType = 'day';
144
 
145
+ let response = await fetchedDownloadsData.json();
146
+ dlmReportsInstance.dlmReportsStats = dlmReportsInstance.dlmReportsStats.concat(response.stats);
 
 
 
 
 
 
 
 
 
147
 
148
+ if (true === response.done) {
149
+ // Set the "all time" reports if URL has dlm_time. Used when coming from Dashboard widget
150
+ if (window.location.href.indexOf('dlm_time') > 0) {
151
+ dlmReportsInstance.dates.downloads.start_date = (Object.keys(dlmReportsInstance.dlmReportsStats).length > 0) ? new Date(dlmReportsInstance.dlmReportsStats[0].date) : new Date();
152
+ dlmReportsInstance.dates.downloads.end_date = new Date();
153
+ jQuery('#dlm-date-range-picker .date-range-info').html(dlmReportsInstance.dates.downloads.start_date.toLocaleDateString(undefined, {
154
+ year: 'numeric', month: 'short', day: '2-digit'
155
+ }) + ' - ' + dlmReportsInstance.dates.downloads.end_date.toLocaleDateString(undefined, {
156
+ year: 'numeric', month: 'short', day: '2-digit'
157
+ }));
158
+ }
159
+ dlmReportsInstance.createDataOnDate(dlmReportsInstance.dates.downloads.start_date, dlmReportsInstance.dates.downloads.end_date);
160
+
161
+ dlmReportsInstance.datePicker = {
162
+ opened: false
163
+ };
164
 
165
+ jQuery(document).trigger('dlm_downloads_report_fetched', [
166
+ dlmReportsInstance,
167
+ dlmReportsInstance.dlmReportsStats
168
+ ]);
169
+
170
+ dlmReportsInstance.stopSpinner(jQuery('.total_downloads_chart-wrapper'));
171
+ } else {
172
+ dlmReportsInstance.fetchReportsData(response.offset);
173
+ }
174
  }
175
 
176
  /**
235
  dlmReportsInstance.overViewTab();
236
  dlmReportsInstance.togglePageSettings();
237
 
 
 
238
  dlmReportsInstance.setSpinner(jQuery('#users_download_log'));
239
  dlmReportsInstance.setSpinner(jQuery('#total_downloads_table_wrapper2'));
240
  dlmReportsInstance.fetchUsersReportsData();
1910
  const dateString = moment(dateInput).format("YYYY-MM");
1911
 
1912
  if (11 > month) {
1913
+
1914
  if (dateString === prevLastDate) {
1915
 
1916
  date = moment(dateString).format("MMMM, YYYY");
1931
 
1932
  }
1933
 
1934
+ } else if ('undefined' !== plugin.chartType && 'days' === plugin.chartType) {
1935
 
1936
+ const year = moment(dateInput).year();
1937
+ const day = moment(dateInput).day();
1938
+ const dayMonth = moment(dateInput).format("MMMM");
1939
+ const nextDayMonth = moment(dateInput).day(day + 1).format("MMMM");
1940
+ const lastDate = dlmReportsInstance.dates.downloads.end_date;
1941
+ const prevLastDate = moment(lastDate).day(moment(lastDate).day() - 1).format("MMMM Do");
1942
+
1943
+ if (moment(dateInput).format("MMMM Do") === moment(lastDate).format("MMMM Do") || moment(dateInput).format("MMMM Do") === prevLastDate) {
1944
+ date = moment(dateInput).format("MMMM Do, YYYY");
1945
+ } else {
1946
+ if (dayMonth === nextDayMonth) {
1947
+ date = moment(dateInput).format("MMMM Do") + ' - ' + moment(dateInput).day(day + 1).format("Do") + moment(dateInput).format(", YYYY");
1948
+ } else {
1949
+ date = moment(dateInput).format("MMM Do") + ' - ' + moment(dateInput).day(day + 1).format("MMM Do") + moment(dateInput).format(", YYYY");
1950
+ }
1951
+ }
1952
 
1953
+ } else {
1954
  date = moment(dateInput).format("MMMM Do, YY");
1955
  }
1956
 
assets/js/reports/reports.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function(e){const t=new DLM_Reports;dlmReportsInstance.fetchReportsData(),e(document).on("dlm_downloads_report_fetched",function(){t.init()})});class DLM_Reports{dlmReportsStats=[];dlmUsersStats={logs:[],users:[]};currentFilters=[];tempDownloads=null;templates={};totalDownloads=0;perPage=dlmReportsPerPage;constructor(){(dlmReportsInstance=this).chartContainer=document.getElementById("total_downloads_chart");const e=dlmReportsInstance.chartContainer.getContext("2d");dlmReportsInstance.chartColors={purple:{default:"rgba(149, 76, 233, 1)",threesome:"rgba(149, 76, 233, 0.75)",half:"rgba(149, 76, 233, 0.5)",quarter:"rgba(149, 76, 233, 0.5)",zero:"rgba(149, 76, 233, 0.05)"},blue:{default:"rgba(67, 56, 202, 1)",threesome:"rgba(67, 56, 202, 0.75)",half:"rgba(67, 56, 202, 0.5)",quarter:"rgba(67, 56, 202, 0.25)",zero:"rgba(67, 56, 202, 0.05)"},green:{default:"rgba(00, 255, 00, 1)",threesome:"rgba(00, 255, 00, 0.75)",half:"rgba(00, 255, 00, 0.5)",quarter:"rgba(00, 255, 00, 0.25)",zero:"rgba(67, 56, 202, 0.05)"},royalBlue:{default:"rgba(65, 105, 225, 1)",threesome:"rgba(65, 105, 225, 0.75)",half:"rgba(65, 105, 225, 0.5)",quarter:"rgba(65, 105, 225, 0.25)",zero:"rgba(65, 105, 225, 0.05)"},persianBlue:{default:"rgba(28, 57, 187, 1)",threesome:"rgba(28, 57, 187, 0.75)",half:"rgba(28, 57, 187, 0.5)",quarter:"rgba(28, 57, 187, 0.25)",zero:"rgba(28, 57, 187, 0.05)"},darkCyan:{default:"rgba(0,129,167, 1)",threesome:"rgba(0,129,167, 0.75)",half:"rgba(0,129,167, 0.5)",quarter:"rgba(0,129,167, 0.25)",zero:"rgba(0,129,167, 0.05)"},strongCyan:{default:"rgba(0, 175, 185, 1)",threesome:"rgba(0, 175, 185, 0.75)",half:"rgba(0, 175, 185, 0.5)",quarter:"rgba(0, 175, 185, 0.25)",zero:"rgba(0, 175, 185, 0.05)"}},dlmReportsInstance.chartGradient=e.createLinearGradient(0,25,0,300),dlmReportsInstance.chartGradient.addColorStop(0,dlmReportsInstance.chartColors.darkCyan.half),dlmReportsInstance.chartGradient.addColorStop(.45,dlmReportsInstance.chartColors.darkCyan.quarter),dlmReportsInstance.chartGradient.addColorStop(1,dlmReportsInstance.chartColors.darkCyan.zero),dlmReportsInstance.datePickerContainer=document.getElementById("dlm-date-range-picker"),dlmReportsInstance.dataSets=[];let t=new Date;dlmReportsInstance.dates={downloads:{start_date:new Date(t.setMonth(t.getMonth()-1)),end_date:new Date}},dlmReportsInstance.chartDataObject={}}async fetchReportsData(){const e=jQuery('div[data-id="general_info"]'),t=await fetch(dlmDownloadReportsAPI);if(!t.ok){const a=document.createElement("div"),n=(a.className="dlm-loading-data",document.createTextNode("Seems like we bumped into an error! ")),s=document.createTextNode("Data fetching returned a status text of : "+fetchedData.statusText),o=document.createElement("h1"),r=document.createElement("h3");throw o.appendChild(n),r.appendChild(s),a.appendChild(o),a.appendChild(r),e.find(".dlm-loading-data").remove(),e.append(a),new Error("Something went wrong! Reports response did not come OK - "+fetchedData.statusText)}dlmReportsInstance.dlmReportsStats=await t.json(),dlmReportsInstance.mostDownloaded=!1,dlmReportsInstance.stats=!1,dlmReportsInstance.chartType="day",0<window.location.href.indexOf("dlm_time")&&(dlmReportsInstance.dates.downloads.start_date=0<Object.keys(dlmReportsInstance.dlmReportsStats).length?new Date(dlmReportsInstance.dlmReportsStats[0].date):new Date,dlmReportsInstance.dates.downloads.end_date=new Date,jQuery("#dlm-date-range-picker .date-range-info").html(dlmReportsInstance.dates.downloads.start_date.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"2-digit"})+" - "+dlmReportsInstance.dates.downloads.end_date.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"2-digit"}))),dlmReportsInstance.createDataOnDate(dlmReportsInstance.dates.downloads.start_date,dlmReportsInstance.dates.downloads.end_date),dlmReportsInstance.datePicker={opened:!1},jQuery(document).trigger("dlm_downloads_report_fetched",[dlmReportsInstance,dlmReportsInstance.dlmReportsStats])}async fetchUsersReportsData(e=0,t=dlmPHPinfo.retrieved_rows){const a=jQuery('div[data-id="user_reports"]');let n=dlmUserReportsAPI+"?offset="+e+"&limit="+t;0<dlmUserReportsAPI.indexOf("index.php?")&&(n=dlmUserReportsAPI+"&offset="+e+"&limit="+t);const s=await fetch(n);if(!s.ok)throw new Error("Something went wrong! Reports response did not come OK - "+s.statusText);e=await s.json();dlmReportsInstance.dlmUsersStats.logs=dlmReportsInstance.dlmUsersStats.logs.concat(e.logs),!0===e.done?(dlmReportsInstance.userDownloads=void 0!==dlmReportsInstance.dlmUsersStats.logs?JSON.parse(JSON.stringify(dlmReportsInstance.dlmUsersStats.logs)):{},a.find(".dlm-loading-data").remove(),dlmReportsInstance.userReportsTab(),dlmReportsInstance.setTopDownloads(),dlmReportsInstance.stopSpinner(jQuery("#total_downloads_table_wrapper2"))):dlmReportsInstance.fetchUsersReportsData(e.offset)}async fetchUserData(){const e=await fetch(dlmUserDataAPI);if(!e.ok)throw new Error("Something went wrong! Reports response did not come OK - "+e.statusText);var t=await e.json();dlmReportsInstance.dlmUsersStats.users=dlmReportsInstance.dlmUsersStats.users.concat(t)}init(){dlmReportsInstance.tabNagivation(),dlmReportsInstance.overViewTab(),dlmReportsInstance.togglePageSettings(),dlmReportsInstance.fetchUserData(),dlmReportsInstance.setSpinner(jQuery("#users_download_log")),dlmReportsInstance.setSpinner(jQuery("#total_downloads_table_wrapper2")),dlmReportsInstance.fetchUsersReportsData(),jQuery(document).trigger("dlm_reports_init",[dlmReportsInstance]),dlmReportsInstance.eventsFunctions()}overViewTab(){dlmReportsInstance.dlmCreateChart(dlmReportsInstance.stats.chartStats,dlmReportsInstance.chartContainer),dlmReportsInstance.dlmDownloadsSummary(),dlmReportsInstance.datePickerContainer.addEventListener("click",dlmReportsInstance.toggleDatepicker.bind(this)),dlmReportsInstance.setTodayDownloads(),dlmReportsInstance.handleTopDownloads(),jQuery(document).on("click","body",function(e){e.stopPropagation(),0<jQuery(dlmReportsInstance.datePickerContainer).find("#dlm_date_range_picker").length&&dlmReportsInstance.hideDatepicker(jQuery(dlmReportsInstance.datePickerContainer),{target:"dlm-date-range-picker"})})}userReportsTab(){0!==Object.values(dlmReportsInstance.dlmUsersStats).length&&(dlmReportsInstance.logsDataByDate(dlmReportsInstance.dates.downloads.start_date,dlmReportsInstance.dates.downloads.end_date),dlmReportsInstance.handleUserDownloads(),dlmReportsInstance.filterDownloads())}getDates(e,t){const a={};let n=e;for(;n<=t;)a[this.createDateElement(n)]=0,n=this.getNextDay(n);return a}getMonths(e){const t={};return Object.keys(e).map(e=>{e=e.substring(0,7);void 0===t[e]&&(t[e]=0)}),t}getDoubleMonths(e){const t={},a=Object.keys(e)[0],n=Object.keys(e)[Object.keys(e).length-1];let s=0,o=a.substring(0,7),r=n.substring(0,7);return Object.keys(e).map(e=>{e=e.substring(0,7);o!==e&&r!==e&&(o=e,s++),void 0===t[e]&&0==s%2&&(t[e]=0)}),t}getWeeks(e){let a={};return Object.keys(e).forEach(e=>{let t;t=15<moment(e).date()?e.substring(0,7)+"-15":e.substring(0,7)+"-01",void 0===a[t]&&(a[t]=0)}),a}getWeek(e){let t={},a=Object.keys(e)[Object.keys(e).length-1],n=0;return Object.keys(e).map(e=>{void 0===t[e]&&0==n%7&&(t[e]=0),n++}),void 0===t[a]&&(t[a]=0),t}getDoubleDays(e){let t={},a=Object.keys(e)[0],n=Object.keys(e)[Object.keys(e).length-1],s=0;return Object.keys(e).map(e=>{a!==e&&n!==e&&(a=e,s++),void 0===t[e]&&0==s%2&&(t[e]=0)}),t}getNextDay(e){const t=new Date(e);return t.setDate(e.getDate()+1),t}createDateElement(e){var t=(e.getMonth()+1<10?"0":"")+(e.getMonth()+1);return e.getFullYear()+"-"+t+"-"+("0"+e.getDate()).slice(-2)}getSetDates(e,t){let a,n;if(void 0!==e&&e)a=dlmReportsInstance.createDateElement(new Date(e));else{const s=new Date;s.setDate(s.getDate()-30),a=dlmReportsInstance.createDateElement(s)}if(void 0!==t&&t){e=new Date(t);n=dlmReportsInstance.createDateElement(e)}else{const o=new Date;o.setDate(o.getDate()+1),n=dlmReportsInstance.createDateElement(o)}return{startDate:a,endDate:n}}createDataOnDate(e,t){let{startDate:a,endDate:n}={...dlmReportsInstance.getSetDates(e,t)},s,o,r,d,l,c=(dlmReportsInstance.reportsData=void 0!==dlmReportsInstance.dlmReportsStats?JSON.parse(JSON.stringify(dlmReportsInstance.dlmReportsStats)):{},o=moment(n,"YYYY-MM-DD").month()-moment(a,"YYYY-MM-DD").month(),r=moment(n,"YYYY-MM-DD").year()-moment(a,"YYYY-MM-DD").year(),s=moment(n).date()-moment(a).date(),dlmReportsInstance.chartType="day",0==r&&-6<o&&o<6?1<o||o<-1?dlmReportsInstance.chartType=2==o?"week":"weeks":1==o&&(8<s||-14<s||0==s)&&(dlmReportsInstance.chartType="days"):o<=0?dlmReportsInstance.chartType="month":dlmReportsInstance.chartType="months",dlmReportsInstance.getDates(new Date(a),new Date(n))),p,m,i,g;switch(dlmReportsInstance.chartType){case"months":m=dlmReportsInstance.getDoubleMonths(c),l=m;break;case"month":var u=dlmReportsInstance.getMonths(c);l=u;break;case"weeks":i=dlmReportsInstance.getWeeks(c),l=i;break;case"week":g=dlmReportsInstance.getWeek(c),l=g;break;case"days":p=dlmReportsInstance.getDoubleDays(c),l=p;break;case"day":l=c}Object.values(dlmReportsInstance.reportsData).forEach((s,e)=>{var o=JSON.parse(s.download_ids);if(void 0!==c[s.date])switch(dlmReportsInstance.chartType){case"months":d=s.date.substring(0,7);let e=parseInt(s.date.substring(5,7)),t=s.date.substring(0,5),a=6<(e-1).length?t+(e-1):t+"0"+(e-1);Object.values(o).forEach((e,t)=>{void 0===m[d]?void 0!==m[a]&&(m[a]=m[a]+e.downloads):m[d]=m[d]+e.downloads}),l=m;break;case"month":d=s.date.substring(0,7),Object.values(o).forEach((e,t)=>{monthDownloads[d]=void 0!==monthDownloads[d]?monthDownloads[d]+e.downloads:e.downloads}),l=monthDownloads;break;case"weeks":d=15<moment(s.date).date()?s.date.substring(0,7)+"-15":s.date.substring(0,7)+"-01",Object.values(o).forEach((e,t)=>{i[d]=void 0!==i[d]?i[d]+e.downloads:e.downloads}),l=i;break;case"week":d=s.date,Object.values(o).forEach((t,e)=>{if(void 0===g[d])for(let e=1;e<8;e++){var a=moment(s.date).date(moment(s.date).date()-e).format("YYYY-MM-DD");void 0!==g[a]&&(g[a]=g[a]+t.downloads)}else g[d]=g[d]+t.downloads}),l=g;break;case"days":d=s.date;let n=moment(s.date).date(moment(s.date).date()-1).format("YYYY-MM-DD");Object.values(o).forEach((e,t)=>{void 0===p[d]?void 0!==p[n]&&(p[n]=p[n]+e.downloads):p[d]=p[d]+e.downloads}),l=p;break;case"day":Object.values(o).forEach((e,t)=>{c[s.date]=c[s.date]+e.downloads}),l=c}else delete dlmReportsInstance.reportsData[e]});const I=Object.keys(c);e=I.length,t=I.findIndex(e=>a===e);let h=I.findIndex(e=>n===e);-1===t&&-1===h?dlmReportsInstance.stats={chartStats:Object.assign({},l),summaryStats:!1,daysLength:e}:(-1===h&&(h=e),dlmReportsInstance.stats={chartStats:Object.assign({},l),summaryStats:dlmReportsInstance.reportsData,daysLength:e})}dlmCreateChart(t,a,n=!1){if(t&&a){let e=Chart.getChart("total_downloads_chart");dlmReportsInstance.chartDataObject={dataSetLabel:"Downloads",dataSetColor:"#27ae60",dataSetbg:dlmReportsInstance.chartGradient,dataSetPointbg:dlmReportsInstance.chartColors.darkCyan.default,dataSetBorder:dlmReportsInstance.chartColors.darkCyan.default,dataSetElementColor:"#2ecc71",lineType:"original",xAxis:"x",chartData:t},void 0!==e&&e.destroy(),jQuery(document).trigger("dlm_reports_before_data_sets",[dlmReportsInstance.chartDataObject,t,n]),0<dlmReportsInstance.dataSets.length&&(dlmReportsInstance.dataSets=dlmReportsInstance.dataSets.filter(e=>dlmReportsInstance.chartDataObject.lineType!==e.origin)),dlmReportsInstance.dataSets.push({origin:dlmReportsInstance.chartDataObject.lineType,label:dlmReportsInstance.chartDataObject.dataSetLabel,color:dlmReportsInstance.chartDataObject.dataSetColor,data:dlmReportsInstance.chartDataObject.chartData,type:"line",fill:!0,backgroundColor:dlmReportsInstance.chartDataObject.dataSetbg,pointBackgroundColor:dlmReportsInstance.chartDataObject.dataSetPointbg,pointHoverBackgroundColor:"#fff",borderColor:dlmReportsInstance.chartDataObject.dataSetBorder,pointBorderWidth:1,lineTension:.3,borderWidth:1,pointRadius:3,elements:{line:{borderColor:dlmReportsInstance.chartDataObject.dataSetElementColor,borderWidth:1},point:{radius:4,hoverRadius:4,pointStyle:"circle"}}});t=Object.values(dlmReportsInstance.dataSets).filter(e=>"original"===e.origin);let o=Object.keys(t[0].data);dlmReportsInstance.dataSets.sort(function(e,t){return"original"===e.origin?-1:1}),dlmReportsInstance.chart=new Chart(a,{title:"",data:{datasets:dlmReportsInstance.dataSets},height:450,is_series:1,options:{aspectRatio:5,animation:!1,interaction:{mode:"index",intersect:!1},stacked:!1,scales:{x:{grid:{display:!1},ticks:{callback:e=>{let t="";var a=o[e],n=o[o.length-1],s=moment(n).month(moment(n).month()-1).format("YYYY-MM");return t="undefined"!==dlmReportsInstance.chartType&&"months"===dlmReportsInstance.chartType?(e=moment(o[e]).month())<11?a===s?moment(a).format("MMM, YYYY"):moment(a).format("MMM")+" - "+moment(a).month(e+1).format("MMM")+moment(a).format(", YYYY"):a===s||a===n?moment(a).format("MMM, YYYY"):moment(a).format("MMM")+moment(a).format(" YYYY")+" - "+moment(a).month(e+1).format("MMM")+moment(a).month(e+1).format(", YYYY"):"undefined"!==dlmReportsInstance.chartType&&"months"===dlmReportsInstance.chartType?moment(a).format("MMMM, YYYY"):moment(a).format("D MMM")}}},y:{grid:{drawBorder:!1},min:0,max:0!==dlmReportsInstance.getMaxDownload()?1===Math.ceil(dlmReportsInstance.getMaxDownload()/10)?dlmReportsInstance.getMaxDownload()+1:10*Math.ceil(dlmReportsInstance.getMaxDownload()/10):100,ticks:{stepSize:0!==dlmReportsInstance.getMaxDownload()?Math.ceil(dlmReportsInstance.getMaxDownload()/4):25,callback:e=>dlmReportsInstance.shortNumber(e)}}},normalized:!0,parsing:{xAxisKey:"x",yAxisKey:"y"},plugins:{tooltip:{enabled:!1,external:dlmReportsInstance.externalTooltipHandler.bind(dlmReportsInstance,this)},legend:{display:!0}}}})}}dlmDownloadsSummary(){let a={};if(!1===dlmReportsInstance.stats||!1===dlmReportsInstance.stats.summaryStats||Object.keys(dlmReportsInstance.stats.summaryStats).length<=0)return this.setTotalDownloads(0),this.setDailyAverage(0),void this.setMostDownloaded("--");dlmReportsInstance.totalDownloads=0,dlmReportsInstance.stats.summaryStats.forEach(e=>{e=JSON.parse(e.download_ids),Object.entries(e).forEach(([e,t])=>{dlmReportsInstance.totalDownloads+=t.downloads,a[e]=void 0===a[e]?{downloads:t.downloads,title:t.title,id:e}:{downloads:a[e].downloads+t.downloads,title:t.title,id:e}})}),dlmReportsInstance.mostDownloaded=dlmReportsInstance.orderItems(Object.values(a),"desc","downloads"),dlmReportsInstance.setTotalDownloads(dlmReportsInstance.totalDownloads),dlmReportsInstance.setDailyAverage((dlmReportsInstance.totalDownloads/parseInt(dlmReportsInstance.stats.daysLength)).toFixed(0)),dlmReportsInstance.setMostDownloaded(dlmReportsInstance.mostDownloaded[0].title)}createDatepicker(e,t,a){const n=new Date;let s=n.getDate()-1,o=n.getMonth()+1,r=o-1;var d=n.getFullYear(),l=(s<10&&(s="0"+s),o<10&&(o="0"+o),r<10&&(r="0"+r),d+"-"+o+"-"+s),d=d+"-"+r+"-"+s,c=jQuery("<div>").addClass("dlm_rdrs_overlay"),a=jQuery("<div>").attr("id",a.replace("#",""));return"dlm-date-range-picker"===t.target?(dlmReportsInstance.startDateInput=jQuery("<input>").attr("type","hidden").attr("id","dlm_start_date").attr("value",d),dlmReportsInstance.endDateInput=jQuery("<input>").attr("type","hidden").attr("id","dlm_end_date").attr("value",l),c.append(a).append(dlmReportsInstance.startDateInput).append(dlmReportsInstance.endDateInput)):jQuery(document).trigger("dlm_create_date_picker_"+t.target,[dlmReportsInstance,c,a,d,l]),c}displayDatepicker(e,o){var t;if(jQuery(e)){if(t="#"+jQuery(e).attr("id").replace(/-/gi,"_"),"dlm-date-range-picker"===o.target){if(dlmReportsInstance.datePicker.opened)return;dlmReportsInstance.datePicker.opened=!0}else jQuery(document).trigger("dlm_display_datepicker_"+o.target,[dlmReportsInstance,o,e]);let s=dlmReportsInstance.createDatepicker(e,o,t);e.append(s);var a=0<Object.keys(dlmReportsInstance.dlmReportsStats).length?new Date(dlmReportsInstance.dlmReportsStats[0].date):new Date,n=(new Date,[]),e=(jQuery(document).trigger("dlm_datepicker_shortcuts_"+o.target,[dlmReportsInstance,o,e,n]),{separator:" to ",autoClose:!0,getValue:function(){},setValue:function(e,t,a){s.find('input[type="hidden"]').first().val(t),s.find('input[type="hidden"]').last().val(a)},inline:!0,alwaysOpen:!0,container:t,endDate:new Date,startDate:a,showShortcuts:!0,shortcuts:null,customShortcuts:n});s.dateRangePicker(e).on("datepicker-change",(e,t)=>{var a,n;t.date1&&t.date2&&(a=t.date1.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"2-digit"}),n=t.date2.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"2-digit"}),s.parent().find("span.date-range-info").text(a+" - "+n)),"dlm-date-range-picker"===o.target?(dlmReportsInstance.dates.downloads={start_date:t.date1,end_date:t.date2},dlmReportsInstance.createDataOnDate(dlmReportsInstance.dates.downloads.start_date,dlmReportsInstance.dates.downloads.end_date),dlmReportsInstance.dlmCreateChart(dlmReportsInstance.stats.chartStats,dlmReportsInstance.chartContainer,!1),dlmReportsInstance.dlmDownloadsSummary(),0<Object.values(dlmReportsInstance.dlmUsersStats.logs).length&&dlmReportsInstance.logsDataByDate(dlmReportsInstance.dates.downloads.start_date,dlmReportsInstance.dates.downloads.end_date)):jQuery(document).trigger("dlm_daterangepicker_init_"+o.target,[dlmReportsInstance,t.date1,t.date2]),dlmReportsInstance.setTopDownloads(),s.data("dateRangePicker").close()}),"dlm-date-range-picker"===o.target?s.data("dateRangePicker").setDateRange(dlmReportsInstance.dates.downloads.start_date,dlmReportsInstance.dates.downloads.end_date):jQuery(document).trigger("dlm_daterangepicker_after_init_"+o.target,[s,dlmReportsInstance])}}hideDatepicker(e,t){"dlm-date-range-picker"===t.target?dlmReportsInstance.datePicker.opened=!1:jQuery(document).trigger("dlm_hide_datepicker_"+t.target,[dlmReportsInstance,e,t]),e.find(".dlm_rdrs_overlay").remove()}toggleDatepicker(e){e.stopPropagation();const t=jQuery(e.target).parents(".dlm-reports-header-date-selector");e={target:t.attr("id"),object:dlmReportsInstance.datePicker};dlmReportsInstance.closeDatePickers(t),"dlm-date-range-picker"===e.target?dlmReportsInstance.datePicker.opened?dlmReportsInstance.hideDatepicker(t,e):dlmReportsInstance.displayDatepicker(t,e):jQuery(document).trigger("dlm_toggle_datepicker_"+e.target,[dlmReportsInstance,t,e])}setTotalDownloads(e){jQuery(".dlm-reports-block-summary li#total span").html(e.toLocaleString())}setDailyAverage(e){jQuery(".dlm-reports-block-summary li#average span").html(e.toLocaleString())}setMostDownloaded(e){jQuery(".dlm-reports-block-summary li#most_popular span").html(e)}setTodayDownloads(){let e=0;Object.keys(dlmReportsInstance.dlmReportsStats).length<=0?jQuery(".dlm-reports-block-summary li#today span").html(e.toLocaleString()):(dlmReportsInstance.dlmReportsStats[dlmReportsInstance.dlmReportsStats.length-1].date===dlmReportsInstance.createDateElement(new Date)&&(e=Object.values(JSON.parse(dlmReportsInstance.dlmReportsStats[dlmReportsInstance.dlmReportsStats.length-1].download_ids)).reduce((e,t)=>e+t.downloads,0)),jQuery(".dlm-reports-block-summary li#today span").html(e))}setTopDownloads(e=0,t=!1){const a=jQuery("#total_downloads_table_wrapper2"),n=jQuery("#total_downloads_table_wrapper2 .total_downloads_table__list");if(n.empty(),n.parent().addClass("empty"),dlmReportsInstance.mostDownloaded&&!0!==t){var s=JSON.parse(JSON.stringify(dlmReportsInstance.mostDownloaded)).slice(dlmReportsInstance.perPage*parseInt(e),dlmReportsInstance.perPage*parseInt(e+1));for(let e=0;e<s.length;e++){const r=dlmReportsInstance.getDownloadByID(s[e].id);if(void 0===r)return;var o={id:s[e].id,title:s[e].title,edit_link:dlmAdminUrl+"post.php?post="+s[e].id+"&action=edit",total_downloads:r.total.toLocaleString()};jQuery(document).trigger("dlm_reports_top_downloads_item_before_render",[o,dlmReportsInstance,s[e],r]),new dlmBackBone.modelTopDownloads(o)}n.parent().removeClass("empty"),a.find(".dlm-reports-total-pages").html(Math.ceil(dlmReportsInstance.mostDownloaded.length/dlmReportsInstance.perPage)),parseInt(dlmReportsInstance.perPage)!==parseInt(s.length)?a.find('.downloads-block-navigation button[data-action="load-more"]').attr("disabled","disabled"):a.find('.downloads-block-navigation button[data-action="load-more"]').removeAttr("disabled"),dlmReportsInstance.mostDownloaded.length>dlmReportsInstance.perPage?a.find(".downloads-block-navigation button").removeClass("hidden"):a.find(".downloads-block-navigation button").addClass("hidden"),dlmReportsInstance.stopSpinner(jQuery("#total_downloads_table_wrapper2"))}}handleTopDownloads(){jQuery("html body").on("click","#total_downloads_table_wrapper2 .downloads-block-navigation button",function(){let e=jQuery(this).parents("#total_downloads_table_wrapper2"),t=e,a=e.attr("data-page"),n=jQuery(this),s=parseInt(a)+1,o=0!==a?parseInt(a)-1:0,r=e.find(".downloads-block-navigation").find("button").first(),d=e.find(".downloads-block-navigation").find("button").last();n.attr("disabled","disabled");var l={data:dlmReportsInstance.mostDownloaded,main_parent:e,offsetHolder:t,offset:a,link:n,nextPage:s,prevPage:o,prevButton:r,nextButton:d,doAction:dlmReportsInstance.setTopDownloads};dlmReportsInstance.handleSliderNavigation(l)}),jQuery("#total_downloads_table_wrapper2").find("input.dlm-reports-current-page").on("change",function(){dlmReportsInstance.paginationChange(jQuery(this),dlmReportsInstance.mostDownloaded,jQuery("#total_downloads_table_wrapper2"),jQuery(this).parents("#total_downloads_table_wrapper2"),dlmReportsInstance.setTopDownloads)})}handleSliderNavigation(e){const{data:t,main_parent:a,offsetHolder:n,offset:s,link:o,nextPage:r,prevPage:d,prevButton:l,nextButton:c,doAction:p}={...e};let m=1;"load-more"===o.data("action")?(n.attr("data-page",r),p(r),Math.ceil(t.length/dlmReportsInstance.perPage)>r+1&&c.removeAttr("disabled"),l.removeAttr("disabled"),m=parseInt(r)+1):0!==parseInt(s)&&(n.attr("data-page",d),p(d),1!==parseInt(s)&&l.removeAttr("disabled"),c.removeAttr("disabled"),m=parseInt(d)+1),a.find(".dlm-reports-current-page").val(m)}tabNagivation(){jQuery(document).on("click",".dlm-reports .dlm-insights-tab-navigation > li",function(){const e=jQuery(this),t=jQuery(".dlm-reports .dlm-insights-tab-navigation > li").not(e),a=jQuery('div.dlm-insights-tab-navigation__content[data-id="'+e.attr("id")+'"]'),n=jQuery("div.dlm-insights-tab-navigation__content").not(a);e.hasClass("active")||(e.addClass("active"),t.removeClass("active"),a.addClass("active"),n.removeClass("active"))})}getOrCreateTooltip(e){let t=e.canvas.parentNode.querySelector("div.dlm-canvas-tooltip"),a=e.canvas.parentNode.querySelector("div.dlm-reports-tooltip__line");if(t||((a=document.createElement("div")).className="dlm-reports-tooltip__line"),!t){(t=document.createElement("div")).className="dlm-canvas-tooltip";const n=document.createElement("div");n.className="dlm-reports-tooltip",t.appendChild(n),e.canvas.parentNode.appendChild(t),e.canvas.parentNode.appendChild(a)}return{tooltipEl:t,tooltipLine:a}}externalTooltipHandler(d,e){const{chart:t,tooltip:l}=e,{tooltipEl:a,tooltipLine:n}={...d.getOrCreateTooltip(t)};e=jQuery(a).parent().width();if(0===l.opacity)return a.style.opacity=0,void(n.style.opacity=0);if(l.body){const c=l.title||[],p=document.createElement("div"),m=(p.className="dlm-reports-tooltip__header",c.forEach(e=>{const t=document.createElement("div"),a=(t.className="dlm-reports-tooltip__row",document.createElement("p")),n=(a.className="dlm-reports-tooltip__info",a.appendChild(document.createTextNode("Downloads")),t.appendChild(a),jQuery(document).trigger("dlm_chart_tooltip_before",[dlmReportsInstance,l,t,d]),document.createElement("p"));n.className="dlm-reports-tooltip__date";var s=dlmReportsInstance.setChartTooltipDate(l.dataPoints[0].label,d,d.stats.chartStats);n.appendChild(document.createTextNode(s)),t.appendChild(n);const o=document.createElement("p"),r=(o.className="dlm-reports-tooltip__downloads",document.createElement("span"));r.className="dlm-reports-tooltip__downloads_pointer",r.style.backgroundColor=dlmReportsInstance.chartColors.darkCyan.default,o.appendChild(r),o.appendChild(document.createTextNode(dlmReportsInstance.shortNumber(l.dataPoints[0].formattedValue))),t.appendChild(o),jQuery(document).trigger("dlm_chart_tooltip_after",[dlmReportsInstance,l,t,d]),p.appendChild(t)}),a.querySelector("div.dlm-reports-tooltip"));for(;m.firstChild;)m.firstChild.remove();m.appendChild(p)}var{offsetLeft:s,offsetTop:o}=t.canvas;a.style.opacity=1;let r={isMargin:!(n.style.opacity=1),left:!1};l.caretX-l.width<0&&(r.isMargin=!0,r.left=!0),s+l.caretX+l.width>e&&(r.isMargin=!0,r.left=!1),r.isMargin?r.left?a.style.left=s+l.width+"px":a.style.left=e-l.width+"px":a.style.left=s+l.caretX+"px",n.style.left=s+l.caretX+"px",a.style.top=o+l.caretY-a.offsetHeight-10+"px"}createUserRelatedData(){dlmReportsInstance.userRelatedData=[],Object.values(dlmReportsInstance.userDownloads).forEach((e,t)=>{var a;"0"!==e.user_id&&(a=[e.user_id,e.download_id,e.download_date,e.download_status],e="user_"+e.user_id,void 0!==dlmReportsInstance.userRelatedData[e]?dlmReportsInstance.userRelatedData[e].push(a):dlmReportsInstance.userRelatedData[e]=[a])})}logsDataByDate(e,t){var{startDate:e,endDate:t}={...dlmReportsInstance.getSetDates(e,t)};dlmReportsInstance.userDownloads=JSON.parse(JSON.stringify(dlmReportsInstance.dlmUsersStats.logs));let a=new Date(e),n=(a.setDate(a.getDate()-1),a=a.getTime(),new Date(t));n.setDate(n.getDate()+1),n=n.getTime(),dlmReportsInstance.userDownloads=dlmReportsInstance.userDownloads.filter((e,t)=>{e=dlmReportsInstance.createDateElement(new Date(e.download_date));return(e=new Date(e).getTime())>a&&e<n}),dlmReportsInstance.createUserRelatedData(),dlmReportsInstance.filterDownloads(),dlmReportsInstance.setMostActiveUser(),dlmReportsInstance.setLoggedOutDownloads(),dlmReportsInstance.setLoggedInDownloads(),jQuery(document).trigger("dlm_set_logs_data_by_date",[dlmReportsInstance])}setMostActiveUser(){var e=dlmReportsInstance.getUserByID(dlmReportsInstance.getMostActiveID()[0]);jQuery(".dlm-reports-block-summary li#most_active_user span").html(dlmReportsInstance.userToolTipMarkup(e))}getMostActiveID(){return Object.values(dlmReportsInstance.userRelatedData).length?Object.values(dlmReportsInstance.userRelatedData).reduce((e,t,a)=>parseInt(e.length)>parseInt(t.length)&&0<e.length&&null!==dlmReportsInstance.getUserByID(e[0][0])?e:null!==dlmReportsInstance.getUserByID(t[0][0])?t:[],[]):0}getUserByID(t){if(!t)return null;if("0"===t)return{role:"Guest",display_name:"Guest"};var e=Object.values(dlmReportsInstance.dlmUsersStats.users).filter(e=>parseInt(t)===parseInt(e.id));return Array.isArray(e)?0===e.length?null:e[0]:e}getLoggedInDownloads(){return Object.values(dlmReportsInstance.userRelatedData).length?1<Object.values(dlmReportsInstance.userRelatedData).length?Object.values(dlmReportsInstance.userRelatedData).reduce((e,t)=>parseInt(e)+parseInt(t.length),0):Object.values(dlmReportsInstance.userRelatedData)[0].length:0}setLoggedInDownloads(){const e=dlmReportsInstance.getLoggedInDownloads();jQuery(".dlm-reports-block-summary li#logged_in span,#total_downloads_summary_wrapper .dlm-reports-logged-in").html(e.toLocaleString())}getLoggedOutDownloads(){return dlmReportsInstance.userDownloads.length-dlmReportsInstance.getLoggedInDownloads()}setLoggedOutDownloads(){const e=dlmReportsInstance.getLoggedOutDownloads();jQuery(".dlm-reports-block-summary li#logged_out span,#total_downloads_summary_wrapper .dlm-reports-logged-out").html(e.toLocaleString())}userToolTipMarkup(e){let t='<div class="dlm-user-reports">';return t=(t=t+'<div class="wpchill-tooltip"><i>[?]</i>'+'<div class="wpchill-tooltip-content">')+("<span>User ID: "+(null!==e?e.id:"--")+"</span>"),"object"!=typeof e&&e.url.length&&(t+="<span>User URL: "+(null!==e?e.url:"--")+"</span>"),t+="<span>User registration date: "+(null!==e?e.registered:"--")+"</span>",null!==e&&void 0!==e.role&&e.role.length&&(t+="<span>User role: "+e.role+"</span>"),t=(t+="</div></div>")+(null!==e?e.display_name:"--")+"</div>"}setUserDownloads(e=0,t=!1){const a=jQuery("#users_download_log"),n=jQuery("#users_download_log .user-logs__list");if(n.empty(),!0!==t){let t=[];t=(null!==dlmReportsInstance.tempDownloads?JSON.parse(JSON.stringify(dlmReportsInstance.tempDownloads)):JSON.parse(JSON.stringify(dlmReportsInstance.userDownloads))).slice(dlmReportsInstance.perPage*parseInt(e),dlmReportsInstance.perPage*parseInt(e+1));for(let e=0;e<t.length;e++){var s=dlmReportsInstance.getUserByID(t[e].user_id.toString()),o=dlmReportsInstance.getDownloadCPT(t[e].download_id.toString()),r={key:e,user:null!=s?s.display_name:"--",ip:t[e].user_ip,role:null!==s&&null!==s.role?s.role:"--",download:null!=o?o.title:"--",valid_user:"0"!==t[e].user_id,edit_link:"0"!==t[e].user_id?"user-edit.php?user_id="+t[e].user_id:"#",edit_download_link:null!=o?dlmAdminUrl+"post.php?post="+o.id+"&action=edit":"#",status:t[e].download_status,download_date:t[e].download_date};jQuery(document).trigger("dlm_reports_user_logs_item_before_render",[r,dlmReportsInstance,t[e],s,o]),new dlmBackBone.modelUserLogs(r)}dlmReportsInstance.stopSpinner(jQuery("#users_download_log")),a.find(".dlm-reports-total-pages").html(Math.ceil(dlmReportsInstance.tempDownloads.length/dlmReportsInstance.perPage)),parseInt(dlmReportsInstance.perPage)!==parseInt(t.length)?a.find('.user-downloads-block-navigation button[data-action="load-more"]').attr("disabled","disabled"):a.find('.user-downloads-block-navigation button[data-action="load-more"]').removeAttr("disabled"),dlmReportsInstance.userDownloads.length>dlmReportsInstance.perPage?a.find(".user-downloads-block-navigation button").removeClass("hidden"):a.find(".user-downloads-block-navigation button").addClass("hidden")}}filterDownloads(){dlmReportsInstance.tempDownloads=JSON.parse(JSON.stringify(dlmReportsInstance.userDownloads)),dlmReportsInstance.currentFilters.length&&dlmReportsInstance.currentFilters.forEach(t=>{dlmReportsInstance.tempDownloads=dlmReportsInstance.tempDownloads.filter(e=>t.on===e[t.type])}),dlmReportsInstance.setUserDownloads()}handleUserDownloads(){jQuery(".user-downloads-block-navigation").on("click","button",function(e){e.stopPropagation();let t=jQuery(this).parents("#users_downloads_table_wrapper"),a=t.find("#users_download_log"),n=a.attr("data-page"),s=jQuery(this),o=parseInt(n)+1,r=0!==n?parseInt(n)-1:0,d=t.find(".downloads-block-navigation button").first(),l=t.find(".downloads-block-navigation button").last();s.attr("disabled","disabled");e={data:dlmReportsInstance.tempDownloads,main_parent:t,offsetHolder:a,offset:n,link:s,nextPage:o,prevPage:r,prevButton:d,nextButton:l,doAction:dlmReportsInstance.setUserDownloads};dlmReportsInstance.handleSliderNavigation(e)}),jQuery("#users_downloads_table_wrapper").find("input.dlm-reports-current-page").on("change",function(){dlmReportsInstance.paginationChange(jQuery(this),dlmReportsInstance.tempDownloads,jQuery("#users_downloads_table_wrapper"),jQuery("#users_downloads_table_wrapper").find("#users_download_log"),dlmReportsInstance.setUserDownloads)})}togglePageSettings(){jQuery("#dlm-toggle-settings").on("click",function(e){e.stopPropagation(),jQuery(this).find(".dlm-toggle-settings__settings").toggleClass("display")}),jQuery(".dlm-toggle-settings__settings").on("click",function(e){e.stopPropagation()}),jQuery("html,body").on("click",function(){jQuery(this).find(".dlm-toggle-settings__settings").removeClass("display")}),jQuery(document).on("change",".wpchill-toggle__input",function(e){const t=jQuery(this),a=t.attr("name"),n={action:"dlm_update_report_setting",name:a,checked:t.is(":checked"),_ajax_nonce:dlmReportsNonce};jQuery.post(ajaxurl,n,function(e){a,jQuery(document).trigger("dlm_settings_ajax_response",[dlmReportsInstance,t,e])})})}getMaxDownload(){let t=0;return dlmReportsInstance.dataSets.forEach(e=>{e=Object.values(e.data).reduce((e,t)=>t<e?e:t,0);t<e&&(t=e)}),parseInt(t)}setChartTooltipDate(e,t,a){let n="";var s,o,r;return n="undefined"!==t.chartType&&"months"===t.chartType?(moment(e).year(),s=moment(e).month(),a=Object.keys(a)[Object.keys(a).length-1],o=moment(a).month(moment(a).month()-1).format("YYYY-MM"),r=moment(e).format("YYYY-MM"),s<11?r===o?moment(r).format("MMMM, YYYY"):moment(e).format("MMM")+" - "+moment(e).month(s+1).format("MMM")+moment(e).format(", YYYY"):r===o||r===a?moment(r).format("MMMM, YYYY"):moment(e).format("MMM")+moment(e).format(" YYYY")+" - "+moment(e).month(s+1).format("MMM")+moment(e).month(s+1).format(", YYYY")):"undefined"!==t.chartType&&"months"===t.chartType?moment(e).format("MMMM, YYYY"):moment(e).format("MMMM Do, YY")}closeDatePickers(e){jQuery(".dlm-reports-header-date-selector").not(e).each(function(){var e={target:jQuery(this).attr("id")};dlmReportsInstance.hideDatepicker(jQuery(this),e)})}shortNumber(e){return e=4<=(e="string"==typeof e?e.replace(/,/gi,""):parseInt(e).toString()).length?parseInt(e.substring(0,e.length-3)).toLocaleString()+"k":e}getDownloadByID(t){let a={total:0},n;return dlmReportsInstance.tempDownloads.forEach(function(e){t===e.download_id&&(n=e,a.total=a.total+1,jQuery(document).trigger("dlm_download_by_id",[dlmReportsInstance,a,n]))}),a}getDownloadCPT(t){let e=null;return Array.isArray(dlmReportsInstance.mostDownloaded)&&(e=dlmReportsInstance.mostDownloaded.filter(e=>e.id===t,0)[0]),jQuery(document).trigger("dlm_download_cpt",[dlmReportsInstance,e]),e}setSpinner(e){e.append('<div class="dlm-reports-spinner"><span></span></div>')}stopSpinner(e){e.find(".dlm-reports-spinner").remove()}eventsFunctions(){jQuery("body").on("click",".total_downloads_table_filters_total_downloads > a",function(e){e.preventDefault(),jQuery(this).parent().find("span.dashicons").toggleClass("dashicons-arrow-down dashicons-arrow-up"),dlmReportsInstance.orderOverviewItemsByTotal()}),jQuery("body").on("click",".total_downloads_table_filters_download_date > a",function(e){e.preventDefault(),jQuery(this).parent().find("span.dashicons").toggleClass("dashicons-arrow-down dashicons-arrow-up"),dlmReportsInstance.orderUserReportsItemsByDate()}),jQuery("body").on("change","select.dlm-reports-per-page",function(e){dlmReportsInstance.perPage=jQuery(this).val(),dlmReportsInstance.setTopDownloads(),dlmReportsInstance.setUserDownloads(),jQuery.post(ajaxurl,{action:"dlm_update_report_setting",name:"dlm-reports-per-page",value:dlmReportsInstance.perPage,_ajax_nonce:dlmReportsNonce},function(e){})})}orderItems(e,a,n,t=0){return e.sort((e,t)=>"asc"!==a?t[n]-e[n]:e[n]-t[n]),e}orderOverviewItemsByTotal(){dlmReportsInstance.mostDownloaded=dlmReportsInstance.mostDownloaded.reverse(),dlmReportsInstance.setTopDownloads()}orderUserReportsItemsByDate(){dlmReportsInstance.tempDownloads=dlmReportsInstance.tempDownloads.reverse(),dlmReportsInstance.setUserDownloads()}paginationChange(e,t,a,n,s){let o=parseInt(e.val()),r=(0===o&&(o=1),t.length<o*dlmReportsInstance.perPage&&(o=Math.ceil(t.length/dlmReportsInstance.perPage)),jQuery(this).next('button[data-action="load-more"]')),d=o+1,l=o-1,c=a.find(".downloads-block-navigation button").first(),p=a.find(".downloads-block-navigation button").last();r.attr("disabled","disabled");e={data:t,main_parent:a,offsetHolder:n,offset:o,link:r,nextPage:d,prevPage:l,prevButton:c,nextButton:p,doAction:s};dlmReportsInstance.handleSliderNavigation(e)}}
1
+ jQuery(function(e){const t=new DLM_Reports;dlmReportsInstance.fetchUserData(),dlmReportsInstance.fetchReportsData(),e(document).on("dlm_downloads_report_fetched",function(){t.init()})});class DLM_Reports{dlmReportsStats=[];dlmUsersStats={logs:[],users:[]};currentFilters=[];tempDownloads=null;templates={};totalDownloads=0;perPage=dlmReportsPerPage;constructor(){(dlmReportsInstance=this).chartContainer=document.getElementById("total_downloads_chart");const e=dlmReportsInstance.chartContainer.getContext("2d");dlmReportsInstance.chartColors={purple:{default:"rgba(149, 76, 233, 1)",threesome:"rgba(149, 76, 233, 0.75)",half:"rgba(149, 76, 233, 0.5)",quarter:"rgba(149, 76, 233, 0.5)",zero:"rgba(149, 76, 233, 0.05)"},blue:{default:"rgba(67, 56, 202, 1)",threesome:"rgba(67, 56, 202, 0.75)",half:"rgba(67, 56, 202, 0.5)",quarter:"rgba(67, 56, 202, 0.25)",zero:"rgba(67, 56, 202, 0.05)"},green:{default:"rgba(00, 255, 00, 1)",threesome:"rgba(00, 255, 00, 0.75)",half:"rgba(00, 255, 00, 0.5)",quarter:"rgba(00, 255, 00, 0.25)",zero:"rgba(67, 56, 202, 0.05)"},royalBlue:{default:"rgba(65, 105, 225, 1)",threesome:"rgba(65, 105, 225, 0.75)",half:"rgba(65, 105, 225, 0.5)",quarter:"rgba(65, 105, 225, 0.25)",zero:"rgba(65, 105, 225, 0.05)"},persianBlue:{default:"rgba(28, 57, 187, 1)",threesome:"rgba(28, 57, 187, 0.75)",half:"rgba(28, 57, 187, 0.5)",quarter:"rgba(28, 57, 187, 0.25)",zero:"rgba(28, 57, 187, 0.05)"},darkCyan:{default:"rgba(0,129,167, 1)",threesome:"rgba(0,129,167, 0.75)",half:"rgba(0,129,167, 0.5)",quarter:"rgba(0,129,167, 0.25)",zero:"rgba(0,129,167, 0.05)"},strongCyan:{default:"rgba(0, 175, 185, 1)",threesome:"rgba(0, 175, 185, 0.75)",half:"rgba(0, 175, 185, 0.5)",quarter:"rgba(0, 175, 185, 0.25)",zero:"rgba(0, 175, 185, 0.05)"}},dlmReportsInstance.chartGradient=e.createLinearGradient(0,25,0,300),dlmReportsInstance.chartGradient.addColorStop(0,dlmReportsInstance.chartColors.darkCyan.half),dlmReportsInstance.chartGradient.addColorStop(.45,dlmReportsInstance.chartColors.darkCyan.quarter),dlmReportsInstance.chartGradient.addColorStop(1,dlmReportsInstance.chartColors.darkCyan.zero),dlmReportsInstance.datePickerContainer=document.getElementById("dlm-date-range-picker"),dlmReportsInstance.dataSets=[];let t=new Date;dlmReportsInstance.dates={downloads:{start_date:new Date(t.setMonth(t.getMonth()-1)),end_date:new Date}},dlmReportsInstance.chartDataObject={}}async fetchReportsData(e=0,t=1e3){const a=jQuery('div[data-id="general_info"]');dlmReportsInstance.setSpinner(jQuery(".total_downloads_chart-wrapper")),dlmReportsInstance.setSpinner(jQuery("#users_download_log")),dlmReportsInstance.setSpinner(jQuery("#total_downloads_table_wrapper2"));let n=dlmDownloadReportsAPI+"?offset="+e+"&limit="+t;0<dlmDownloadReportsAPI.indexOf("index.php?")&&(n=dlmDownloadReportsAPI+"&offset="+e+"&limit="+t);const o=await fetch(n);if(!o.ok){const s=document.createElement("div"),r=(s.className="dlm-loading-data",document.createTextNode("Seems like we bumped into an error! ")),d=document.createTextNode("Data fetching returned a status text of : "+fetchedData.statusText),l=document.createElement("h1"),m=document.createElement("h3");throw l.appendChild(r),m.appendChild(d),s.appendChild(l),s.appendChild(m),a.find(".dlm-loading-data").remove(),a.append(s),new Error("Something went wrong! Reports response did not come OK - "+fetchedData.statusText)}dlmReportsInstance.mostDownloaded=!1,dlmReportsInstance.stats=!1,dlmReportsInstance.chartType="day";e=await o.json();dlmReportsInstance.dlmReportsStats=dlmReportsInstance.dlmReportsStats.concat(e.stats),!0===e.done?(0<window.location.href.indexOf("dlm_time")&&(dlmReportsInstance.dates.downloads.start_date=0<Object.keys(dlmReportsInstance.dlmReportsStats).length?new Date(dlmReportsInstance.dlmReportsStats[0].date):new Date,dlmReportsInstance.dates.downloads.end_date=new Date,jQuery("#dlm-date-range-picker .date-range-info").html(dlmReportsInstance.dates.downloads.start_date.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"2-digit"})+" - "+dlmReportsInstance.dates.downloads.end_date.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"2-digit"}))),dlmReportsInstance.createDataOnDate(dlmReportsInstance.dates.downloads.start_date,dlmReportsInstance.dates.downloads.end_date),dlmReportsInstance.datePicker={opened:!1},jQuery(document).trigger("dlm_downloads_report_fetched",[dlmReportsInstance,dlmReportsInstance.dlmReportsStats]),dlmReportsInstance.stopSpinner(jQuery(".total_downloads_chart-wrapper"))):dlmReportsInstance.fetchReportsData(e.offset)}async fetchUsersReportsData(e=0,t=dlmPHPinfo.retrieved_rows){const a=jQuery('div[data-id="user_reports"]');let n=dlmUserReportsAPI+"?offset="+e+"&limit="+t;0<dlmUserReportsAPI.indexOf("index.php?")&&(n=dlmUserReportsAPI+"&offset="+e+"&limit="+t);const o=await fetch(n);if(!o.ok)throw new Error("Something went wrong! Reports response did not come OK - "+o.statusText);e=await o.json();dlmReportsInstance.dlmUsersStats.logs=dlmReportsInstance.dlmUsersStats.logs.concat(e.logs),!0===e.done?(dlmReportsInstance.userDownloads=void 0!==dlmReportsInstance.dlmUsersStats.logs?JSON.parse(JSON.stringify(dlmReportsInstance.dlmUsersStats.logs)):{},a.find(".dlm-loading-data").remove(),dlmReportsInstance.userReportsTab(),dlmReportsInstance.setTopDownloads(),dlmReportsInstance.stopSpinner(jQuery("#total_downloads_table_wrapper2"))):dlmReportsInstance.fetchUsersReportsData(e.offset)}async fetchUserData(){const e=await fetch(dlmUserDataAPI);if(!e.ok)throw new Error("Something went wrong! Reports response did not come OK - "+e.statusText);var t=await e.json();dlmReportsInstance.dlmUsersStats.users=dlmReportsInstance.dlmUsersStats.users.concat(t)}init(){dlmReportsInstance.tabNagivation(),dlmReportsInstance.overViewTab(),dlmReportsInstance.togglePageSettings(),dlmReportsInstance.setSpinner(jQuery("#users_download_log")),dlmReportsInstance.setSpinner(jQuery("#total_downloads_table_wrapper2")),dlmReportsInstance.fetchUsersReportsData(),jQuery(document).trigger("dlm_reports_init",[dlmReportsInstance]),dlmReportsInstance.eventsFunctions()}overViewTab(){dlmReportsInstance.dlmCreateChart(dlmReportsInstance.stats.chartStats,dlmReportsInstance.chartContainer),dlmReportsInstance.dlmDownloadsSummary(),dlmReportsInstance.datePickerContainer.addEventListener("click",dlmReportsInstance.toggleDatepicker.bind(this)),dlmReportsInstance.setTodayDownloads(),dlmReportsInstance.handleTopDownloads(),jQuery(document).on("click","body",function(e){e.stopPropagation(),0<jQuery(dlmReportsInstance.datePickerContainer).find("#dlm_date_range_picker").length&&dlmReportsInstance.hideDatepicker(jQuery(dlmReportsInstance.datePickerContainer),{target:"dlm-date-range-picker"})})}userReportsTab(){0!==Object.values(dlmReportsInstance.dlmUsersStats).length&&(dlmReportsInstance.logsDataByDate(dlmReportsInstance.dates.downloads.start_date,dlmReportsInstance.dates.downloads.end_date),dlmReportsInstance.handleUserDownloads(),dlmReportsInstance.filterDownloads())}getDates(e,t){const a={};let n=e;for(;n<=t;)a[this.createDateElement(n)]=0,n=this.getNextDay(n);return a}getMonths(e){const t={};return Object.keys(e).map(e=>{e=e.substring(0,7);void 0===t[e]&&(t[e]=0)}),t}getDoubleMonths(e){const t={},a=Object.keys(e)[0],n=Object.keys(e)[Object.keys(e).length-1];let o=0,s=a.substring(0,7),r=n.substring(0,7);return Object.keys(e).map(e=>{e=e.substring(0,7);s!==e&&r!==e&&(s=e,o++),void 0===t[e]&&0==o%2&&(t[e]=0)}),t}getWeeks(e){let a={};return Object.keys(e).forEach(e=>{let t;t=15<moment(e).date()?e.substring(0,7)+"-15":e.substring(0,7)+"-01",void 0===a[t]&&(a[t]=0)}),a}getWeek(e){let t={},a=Object.keys(e)[Object.keys(e).length-1],n=0;return Object.keys(e).map(e=>{void 0===t[e]&&0==n%7&&(t[e]=0),n++}),void 0===t[a]&&(t[a]=0),t}getDoubleDays(e){let t={},a=Object.keys(e)[0],n=Object.keys(e)[Object.keys(e).length-1],o=0;return Object.keys(e).map(e=>{a!==e&&n!==e&&(a=e,o++),void 0===t[e]&&0==o%2&&(t[e]=0)}),t}getNextDay(e){const t=new Date(e);return t.setDate(e.getDate()+1),t}createDateElement(e){var t=(e.getMonth()+1<10?"0":"")+(e.getMonth()+1);return e.getFullYear()+"-"+t+"-"+("0"+e.getDate()).slice(-2)}getSetDates(e,t){let a,n;if(void 0!==e&&e)a=dlmReportsInstance.createDateElement(new Date(e));else{const o=new Date;o.setDate(o.getDate()-30),a=dlmReportsInstance.createDateElement(o)}if(void 0!==t&&t){e=new Date(t);n=dlmReportsInstance.createDateElement(e)}else{const s=new Date;s.setDate(s.getDate()+1),n=dlmReportsInstance.createDateElement(s)}return{startDate:a,endDate:n}}createDataOnDate(e,t){let{startDate:a,endDate:n}={...dlmReportsInstance.getSetDates(e,t)},o,s,r,d,l,m=(dlmReportsInstance.reportsData=void 0!==dlmReportsInstance.dlmReportsStats?JSON.parse(JSON.stringify(dlmReportsInstance.dlmReportsStats)):{},s=moment(n,"YYYY-MM-DD").month()-moment(a,"YYYY-MM-DD").month(),r=moment(n,"YYYY-MM-DD").year()-moment(a,"YYYY-MM-DD").year(),o=moment(n).date()-moment(a).date(),dlmReportsInstance.chartType="day",0==r&&-6<s&&s<6?1<s||s<-1?dlmReportsInstance.chartType=2==s?"week":"weeks":1==s&&(8<o||-14<o||0==o)&&(dlmReportsInstance.chartType="days"):s<=0?dlmReportsInstance.chartType="month":dlmReportsInstance.chartType="months",dlmReportsInstance.getDates(new Date(a),new Date(n))),c,p,i,g;switch(dlmReportsInstance.chartType){case"months":p=dlmReportsInstance.getDoubleMonths(m),l=p;break;case"month":var u=dlmReportsInstance.getMonths(m);l=u;break;case"weeks":i=dlmReportsInstance.getWeeks(m),l=i;break;case"week":g=dlmReportsInstance.getWeek(m),l=g;break;case"days":c=dlmReportsInstance.getDoubleDays(m),l=c;break;case"day":l=m}Object.values(dlmReportsInstance.reportsData).forEach((o,e)=>{var s=JSON.parse(o.download_ids);if(void 0!==m[o.date])switch(dlmReportsInstance.chartType){case"months":d=o.date.substring(0,7);let e=parseInt(o.date.substring(5,7)),t=o.date.substring(0,5),a=6<(e-1).length?t+(e-1):t+"0"+(e-1);Object.values(s).forEach((e,t)=>{void 0===p[d]?void 0!==p[a]&&(p[a]=p[a]+e.downloads):p[d]=p[d]+e.downloads}),l=p;break;case"month":d=o.date.substring(0,7),Object.values(s).forEach((e,t)=>{monthDownloads[d]=void 0!==monthDownloads[d]?monthDownloads[d]+e.downloads:e.downloads}),l=monthDownloads;break;case"weeks":d=15<moment(o.date).date()?o.date.substring(0,7)+"-15":o.date.substring(0,7)+"-01",Object.values(s).forEach((e,t)=>{i[d]=void 0!==i[d]?i[d]+e.downloads:e.downloads}),l=i;break;case"week":d=o.date,Object.values(s).forEach((t,e)=>{if(void 0===g[d])for(let e=1;e<8;e++){var a=moment(o.date).date(moment(o.date).date()-e).format("YYYY-MM-DD");void 0!==g[a]&&(g[a]=g[a]+t.downloads)}else g[d]=g[d]+t.downloads}),l=g;break;case"days":d=o.date;let n=moment(o.date).date(moment(o.date).date()-1).format("YYYY-MM-DD");Object.values(s).forEach((e,t)=>{void 0===c[d]?void 0!==c[n]&&(c[n]=c[n]+e.downloads):c[d]=c[d]+e.downloads}),l=c;break;case"day":Object.values(s).forEach((e,t)=>{m[o.date]=m[o.date]+e.downloads}),l=m}else delete dlmReportsInstance.reportsData[e]});const I=Object.keys(m);e=I.length,t=I.findIndex(e=>a===e);let R=I.findIndex(e=>n===e);-1===t&&-1===R?dlmReportsInstance.stats={chartStats:Object.assign({},l),summaryStats:!1,daysLength:e}:(-1===R&&(R=e),dlmReportsInstance.stats={chartStats:Object.assign({},l),summaryStats:dlmReportsInstance.reportsData,daysLength:e})}dlmCreateChart(t,a,n=!1){if(t&&a){let e=Chart.getChart("total_downloads_chart");dlmReportsInstance.chartDataObject={dataSetLabel:"Downloads",dataSetColor:"#27ae60",dataSetbg:dlmReportsInstance.chartGradient,dataSetPointbg:dlmReportsInstance.chartColors.darkCyan.default,dataSetBorder:dlmReportsInstance.chartColors.darkCyan.default,dataSetElementColor:"#2ecc71",lineType:"original",xAxis:"x",chartData:t},void 0!==e&&e.destroy(),jQuery(document).trigger("dlm_reports_before_data_sets",[dlmReportsInstance.chartDataObject,t,n]),0<dlmReportsInstance.dataSets.length&&(dlmReportsInstance.dataSets=dlmReportsInstance.dataSets.filter(e=>dlmReportsInstance.chartDataObject.lineType!==e.origin)),dlmReportsInstance.dataSets.push({origin:dlmReportsInstance.chartDataObject.lineType,label:dlmReportsInstance.chartDataObject.dataSetLabel,color:dlmReportsInstance.chartDataObject.dataSetColor,data:dlmReportsInstance.chartDataObject.chartData,type:"line",fill:!0,backgroundColor:dlmReportsInstance.chartDataObject.dataSetbg,pointBackgroundColor:dlmReportsInstance.chartDataObject.dataSetPointbg,pointHoverBackgroundColor:"#fff",borderColor:dlmReportsInstance.chartDataObject.dataSetBorder,pointBorderWidth:1,lineTension:.3,borderWidth:1,pointRadius:3,elements:{line:{borderColor:dlmReportsInstance.chartDataObject.dataSetElementColor,borderWidth:1},point:{radius:4,hoverRadius:4,pointStyle:"circle"}}});t=Object.values(dlmReportsInstance.dataSets).filter(e=>"original"===e.origin);let s=Object.keys(t[0].data);dlmReportsInstance.dataSets.sort(function(e,t){return"original"===e.origin?-1:1}),dlmReportsInstance.chart=new Chart(a,{title:"",data:{datasets:dlmReportsInstance.dataSets},height:450,is_series:1,options:{aspectRatio:5,animation:!1,interaction:{mode:"index",intersect:!1},stacked:!1,scales:{x:{grid:{display:!1},ticks:{callback:e=>{let t="";var a=s[e],n=s[s.length-1],o=moment(n).month(moment(n).month()-1).format("YYYY-MM");return t="undefined"!==dlmReportsInstance.chartType&&"months"===dlmReportsInstance.chartType?(e=moment(s[e]).month())<11?a===o?moment(a).format("MMM, YYYY"):moment(a).format("MMM")+" - "+moment(a).month(e+1).format("MMM")+moment(a).format(", YYYY"):a===o||a===n?moment(a).format("MMM, YYYY"):moment(a).format("MMM")+moment(a).format(" YYYY")+" - "+moment(a).month(e+1).format("MMM")+moment(a).month(e+1).format(", YYYY"):"undefined"!==dlmReportsInstance.chartType&&"months"===dlmReportsInstance.chartType?moment(a).format("MMMM, YYYY"):moment(a).format("D MMM")}}},y:{grid:{drawBorder:!1},min:0,max:0!==dlmReportsInstance.getMaxDownload()?1===Math.ceil(dlmReportsInstance.getMaxDownload()/10)?dlmReportsInstance.getMaxDownload()+1:10*Math.ceil(dlmReportsInstance.getMaxDownload()/10):100,ticks:{stepSize:0!==dlmReportsInstance.getMaxDownload()?Math.ceil(dlmReportsInstance.getMaxDownload()/4):25,callback:e=>dlmReportsInstance.shortNumber(e)}}},normalized:!0,parsing:{xAxisKey:"x",yAxisKey:"y"},plugins:{tooltip:{enabled:!1,external:dlmReportsInstance.externalTooltipHandler.bind(dlmReportsInstance,this)},legend:{display:!0}}}})}}dlmDownloadsSummary(){let a={};if(!1===dlmReportsInstance.stats||!1===dlmReportsInstance.stats.summaryStats||Object.keys(dlmReportsInstance.stats.summaryStats).length<=0)return this.setTotalDownloads(0),this.setDailyAverage(0),void this.setMostDownloaded("--");dlmReportsInstance.totalDownloads=0,dlmReportsInstance.stats.summaryStats.forEach(e=>{e=JSON.parse(e.download_ids),Object.entries(e).forEach(([e,t])=>{dlmReportsInstance.totalDownloads+=t.downloads,a[e]=void 0===a[e]?{downloads:t.downloads,title:t.title,id:e}:{downloads:a[e].downloads+t.downloads,title:t.title,id:e}})}),dlmReportsInstance.mostDownloaded=dlmReportsInstance.orderItems(Object.values(a),"desc","downloads"),dlmReportsInstance.setTotalDownloads(dlmReportsInstance.totalDownloads),dlmReportsInstance.setDailyAverage((dlmReportsInstance.totalDownloads/parseInt(dlmReportsInstance.stats.daysLength)).toFixed(0)),dlmReportsInstance.setMostDownloaded(dlmReportsInstance.mostDownloaded[0].title)}createDatepicker(e,t,a){const n=new Date;let o=n.getDate()-1,s=n.getMonth()+1,r=s-1;var d=n.getFullYear(),l=(o<10&&(o="0"+o),s<10&&(s="0"+s),r<10&&(r="0"+r),d+"-"+s+"-"+o),d=d+"-"+r+"-"+o,m=jQuery("<div>").addClass("dlm_rdrs_overlay"),a=jQuery("<div>").attr("id",a.replace("#",""));return"dlm-date-range-picker"===t.target?(dlmReportsInstance.startDateInput=jQuery("<input>").attr("type","hidden").attr("id","dlm_start_date").attr("value",d),dlmReportsInstance.endDateInput=jQuery("<input>").attr("type","hidden").attr("id","dlm_end_date").attr("value",l),m.append(a).append(dlmReportsInstance.startDateInput).append(dlmReportsInstance.endDateInput)):jQuery(document).trigger("dlm_create_date_picker_"+t.target,[dlmReportsInstance,m,a,d,l]),m}displayDatepicker(e,s){var t;if(jQuery(e)){if(t="#"+jQuery(e).attr("id").replace(/-/gi,"_"),"dlm-date-range-picker"===s.target){if(dlmReportsInstance.datePicker.opened)return;dlmReportsInstance.datePicker.opened=!0}else jQuery(document).trigger("dlm_display_datepicker_"+s.target,[dlmReportsInstance,s,e]);let o=dlmReportsInstance.createDatepicker(e,s,t);e.append(o);var a=0<Object.keys(dlmReportsInstance.dlmReportsStats).length?new Date(dlmReportsInstance.dlmReportsStats[0].date):new Date,n=(new Date,[]),e=(jQuery(document).trigger("dlm_datepicker_shortcuts_"+s.target,[dlmReportsInstance,s,e,n]),{separator:" to ",autoClose:!0,getValue:function(){},setValue:function(e,t,a){o.find('input[type="hidden"]').first().val(t),o.find('input[type="hidden"]').last().val(a)},inline:!0,alwaysOpen:!0,container:t,endDate:new Date,startDate:a,showShortcuts:!0,shortcuts:null,customShortcuts:n});o.dateRangePicker(e).on("datepicker-change",(e,t)=>{var a,n;t.date1&&t.date2&&(a=t.date1.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"2-digit"}),n=t.date2.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"2-digit"}),o.parent().find("span.date-range-info").text(a+" - "+n)),"dlm-date-range-picker"===s.target?(dlmReportsInstance.dates.downloads={start_date:t.date1,end_date:t.date2},dlmReportsInstance.createDataOnDate(dlmReportsInstance.dates.downloads.start_date,dlmReportsInstance.dates.downloads.end_date),dlmReportsInstance.dlmCreateChart(dlmReportsInstance.stats.chartStats,dlmReportsInstance.chartContainer,!1),dlmReportsInstance.dlmDownloadsSummary(),0<Object.values(dlmReportsInstance.dlmUsersStats.logs).length&&dlmReportsInstance.logsDataByDate(dlmReportsInstance.dates.downloads.start_date,dlmReportsInstance.dates.downloads.end_date)):jQuery(document).trigger("dlm_daterangepicker_init_"+s.target,[dlmReportsInstance,t.date1,t.date2]),dlmReportsInstance.setTopDownloads(),o.data("dateRangePicker").close()}),"dlm-date-range-picker"===s.target?o.data("dateRangePicker").setDateRange(dlmReportsInstance.dates.downloads.start_date,dlmReportsInstance.dates.downloads.end_date):jQuery(document).trigger("dlm_daterangepicker_after_init_"+s.target,[o,dlmReportsInstance])}}hideDatepicker(e,t){"dlm-date-range-picker"===t.target?dlmReportsInstance.datePicker.opened=!1:jQuery(document).trigger("dlm_hide_datepicker_"+t.target,[dlmReportsInstance,e,t]),e.find(".dlm_rdrs_overlay").remove()}toggleDatepicker(e){e.stopPropagation();const t=jQuery(e.target).parents(".dlm-reports-header-date-selector");e={target:t.attr("id"),object:dlmReportsInstance.datePicker};dlmReportsInstance.closeDatePickers(t),"dlm-date-range-picker"===e.target?dlmReportsInstance.datePicker.opened?dlmReportsInstance.hideDatepicker(t,e):dlmReportsInstance.displayDatepicker(t,e):jQuery(document).trigger("dlm_toggle_datepicker_"+e.target,[dlmReportsInstance,t,e])}setTotalDownloads(e){jQuery(".dlm-reports-block-summary li#total span").html(e.toLocaleString())}setDailyAverage(e){jQuery(".dlm-reports-block-summary li#average span").html(e.toLocaleString())}setMostDownloaded(e){jQuery(".dlm-reports-block-summary li#most_popular span").html(e)}setTodayDownloads(){let e=0;Object.keys(dlmReportsInstance.dlmReportsStats).length<=0?jQuery(".dlm-reports-block-summary li#today span").html(e.toLocaleString()):(dlmReportsInstance.dlmReportsStats[dlmReportsInstance.dlmReportsStats.length-1].date===dlmReportsInstance.createDateElement(new Date)&&(e=Object.values(JSON.parse(dlmReportsInstance.dlmReportsStats[dlmReportsInstance.dlmReportsStats.length-1].download_ids)).reduce((e,t)=>e+t.downloads,0)),jQuery(".dlm-reports-block-summary li#today span").html(e))}setTopDownloads(e=0,t=!1){const a=jQuery("#total_downloads_table_wrapper2"),n=jQuery("#total_downloads_table_wrapper2 .total_downloads_table__list");if(n.empty(),n.parent().addClass("empty"),dlmReportsInstance.mostDownloaded&&!0!==t){var o=JSON.parse(JSON.stringify(dlmReportsInstance.mostDownloaded)).slice(dlmReportsInstance.perPage*parseInt(e),dlmReportsInstance.perPage*parseInt(e+1));for(let e=0;e<o.length;e++){const r=dlmReportsInstance.getDownloadByID(o[e].id);if(void 0===r)return;var s={id:o[e].id,title:o[e].title,edit_link:dlmAdminUrl+"post.php?post="+o[e].id+"&action=edit",total_downloads:r.total.toLocaleString()};jQuery(document).trigger("dlm_reports_top_downloads_item_before_render",[s,dlmReportsInstance,o[e],r]),new dlmBackBone.modelTopDownloads(s)}n.parent().removeClass("empty"),a.find(".dlm-reports-total-pages").html(Math.ceil(dlmReportsInstance.mostDownloaded.length/dlmReportsInstance.perPage)),parseInt(dlmReportsInstance.perPage)!==parseInt(o.length)?a.find('.downloads-block-navigation button[data-action="load-more"]').attr("disabled","disabled"):a.find('.downloads-block-navigation button[data-action="load-more"]').removeAttr("disabled"),dlmReportsInstance.mostDownloaded.length>dlmReportsInstance.perPage?a.find(".downloads-block-navigation button").removeClass("hidden"):a.find(".downloads-block-navigation button").addClass("hidden"),dlmReportsInstance.stopSpinner(jQuery("#total_downloads_table_wrapper2"))}}handleTopDownloads(){jQuery("html body").on("click","#total_downloads_table_wrapper2 .downloads-block-navigation button",function(){let e=jQuery(this).parents("#total_downloads_table_wrapper2"),t=e,a=e.attr("data-page"),n=jQuery(this),o=parseInt(a)+1,s=0!==a?parseInt(a)-1:0,r=e.find(".downloads-block-navigation").find("button").first(),d=e.find(".downloads-block-navigation").find("button").last();n.attr("disabled","disabled");var l={data:dlmReportsInstance.mostDownloaded,main_parent:e,offsetHolder:t,offset:a,link:n,nextPage:o,prevPage:s,prevButton:r,nextButton:d,doAction:dlmReportsInstance.setTopDownloads};dlmReportsInstance.handleSliderNavigation(l)}),jQuery("#total_downloads_table_wrapper2").find("input.dlm-reports-current-page").on("change",function(){dlmReportsInstance.paginationChange(jQuery(this),dlmReportsInstance.mostDownloaded,jQuery("#total_downloads_table_wrapper2"),jQuery(this).parents("#total_downloads_table_wrapper2"),dlmReportsInstance.setTopDownloads)})}handleSliderNavigation(e){const{data:t,main_parent:a,offsetHolder:n,offset:o,link:s,nextPage:r,prevPage:d,prevButton:l,nextButton:m,doAction:c}={...e};let p=1;"load-more"===s.data("action")?(n.attr("data-page",r),c(r),Math.ceil(t.length/dlmReportsInstance.perPage)>r+1&&m.removeAttr("disabled"),l.removeAttr("disabled"),p=parseInt(r)+1):0!==parseInt(o)&&(n.attr("data-page",d),c(d),1!==parseInt(o)&&l.removeAttr("disabled"),m.removeAttr("disabled"),p=parseInt(d)+1),a.find(".dlm-reports-current-page").val(p)}tabNagivation(){jQuery(document).on("click",".dlm-reports .dlm-insights-tab-navigation > li",function(){const e=jQuery(this),t=jQuery(".dlm-reports .dlm-insights-tab-navigation > li").not(e),a=jQuery('div.dlm-insights-tab-navigation__content[data-id="'+e.attr("id")+'"]'),n=jQuery("div.dlm-insights-tab-navigation__content").not(a);e.hasClass("active")||(e.addClass("active"),t.removeClass("active"),a.addClass("active"),n.removeClass("active"))})}getOrCreateTooltip(e){let t=e.canvas.parentNode.querySelector("div.dlm-canvas-tooltip"),a=e.canvas.parentNode.querySelector("div.dlm-reports-tooltip__line");if(t||((a=document.createElement("div")).className="dlm-reports-tooltip__line"),!t){(t=document.createElement("div")).className="dlm-canvas-tooltip";const n=document.createElement("div");n.className="dlm-reports-tooltip",t.appendChild(n),e.canvas.parentNode.appendChild(t),e.canvas.parentNode.appendChild(a)}return{tooltipEl:t,tooltipLine:a}}externalTooltipHandler(d,e){const{chart:t,tooltip:l}=e,{tooltipEl:a,tooltipLine:n}={...d.getOrCreateTooltip(t)};e=jQuery(a).parent().width();if(0===l.opacity)return a.style.opacity=0,void(n.style.opacity=0);if(l.body){const m=l.title||[],c=document.createElement("div"),p=(c.className="dlm-reports-tooltip__header",m.forEach(e=>{const t=document.createElement("div"),a=(t.className="dlm-reports-tooltip__row",document.createElement("p")),n=(a.className="dlm-reports-tooltip__info",a.appendChild(document.createTextNode("Downloads")),t.appendChild(a),jQuery(document).trigger("dlm_chart_tooltip_before",[dlmReportsInstance,l,t,d]),document.createElement("p"));n.className="dlm-reports-tooltip__date";var o=dlmReportsInstance.setChartTooltipDate(l.dataPoints[0].label,d,d.stats.chartStats);n.appendChild(document.createTextNode(o)),t.appendChild(n);const s=document.createElement("p"),r=(s.className="dlm-reports-tooltip__downloads",document.createElement("span"));r.className="dlm-reports-tooltip__downloads_pointer",r.style.backgroundColor=dlmReportsInstance.chartColors.darkCyan.default,s.appendChild(r),s.appendChild(document.createTextNode(dlmReportsInstance.shortNumber(l.dataPoints[0].formattedValue))),t.appendChild(s),jQuery(document).trigger("dlm_chart_tooltip_after",[dlmReportsInstance,l,t,d]),c.appendChild(t)}),a.querySelector("div.dlm-reports-tooltip"));for(;p.firstChild;)p.firstChild.remove();p.appendChild(c)}var{offsetLeft:o,offsetTop:s}=t.canvas;a.style.opacity=1;let r={isMargin:!(n.style.opacity=1),left:!1};l.caretX-l.width<0&&(r.isMargin=!0,r.left=!0),o+l.caretX+l.width>e&&(r.isMargin=!0,r.left=!1),r.isMargin?r.left?a.style.left=o+l.width+"px":a.style.left=e-l.width+"px":a.style.left=o+l.caretX+"px",n.style.left=o+l.caretX+"px",a.style.top=s+l.caretY-a.offsetHeight-10+"px"}createUserRelatedData(){dlmReportsInstance.userRelatedData=[],Object.values(dlmReportsInstance.userDownloads).forEach((e,t)=>{var a;"0"!==e.user_id&&(a=[e.user_id,e.download_id,e.download_date,e.download_status],e="user_"+e.user_id,void 0!==dlmReportsInstance.userRelatedData[e]?dlmReportsInstance.userRelatedData[e].push(a):dlmReportsInstance.userRelatedData[e]=[a])})}logsDataByDate(e,t){var{startDate:e,endDate:t}={...dlmReportsInstance.getSetDates(e,t)};dlmReportsInstance.userDownloads=JSON.parse(JSON.stringify(dlmReportsInstance.dlmUsersStats.logs));let a=new Date(e),n=(a.setDate(a.getDate()-1),a=a.getTime(),new Date(t));n.setDate(n.getDate()+1),n=n.getTime(),dlmReportsInstance.userDownloads=dlmReportsInstance.userDownloads.filter((e,t)=>{e=dlmReportsInstance.createDateElement(new Date(e.download_date));return(e=new Date(e).getTime())>a&&e<n}),dlmReportsInstance.createUserRelatedData(),dlmReportsInstance.filterDownloads(),dlmReportsInstance.setMostActiveUser(),dlmReportsInstance.setLoggedOutDownloads(),dlmReportsInstance.setLoggedInDownloads(),jQuery(document).trigger("dlm_set_logs_data_by_date",[dlmReportsInstance])}setMostActiveUser(){var e=dlmReportsInstance.getUserByID(dlmReportsInstance.getMostActiveID()[0]);jQuery(".dlm-reports-block-summary li#most_active_user span").html(dlmReportsInstance.userToolTipMarkup(e))}getMostActiveID(){return Object.values(dlmReportsInstance.userRelatedData).length?Object.values(dlmReportsInstance.userRelatedData).reduce((e,t,a)=>parseInt(e.length)>parseInt(t.length)&&0<e.length&&null!==dlmReportsInstance.getUserByID(e[0][0])?e:null!==dlmReportsInstance.getUserByID(t[0][0])?t:[],[]):0}getUserByID(t){if(!t)return null;if("0"===t)return{role:"Guest",display_name:"Guest"};var e=Object.values(dlmReportsInstance.dlmUsersStats.users).filter(e=>parseInt(t)===parseInt(e.id));return Array.isArray(e)?0===e.length?null:e[0]:e}getLoggedInDownloads(){return Object.values(dlmReportsInstance.userRelatedData).length?1<Object.values(dlmReportsInstance.userRelatedData).length?Object.values(dlmReportsInstance.userRelatedData).reduce((e,t)=>parseInt(e)+parseInt(t.length),0):Object.values(dlmReportsInstance.userRelatedData)[0].length:0}setLoggedInDownloads(){const e=dlmReportsInstance.getLoggedInDownloads();jQuery(".dlm-reports-block-summary li#logged_in span,#total_downloads_summary_wrapper .dlm-reports-logged-in").html(e.toLocaleString())}getLoggedOutDownloads(){return dlmReportsInstance.userDownloads.length-dlmReportsInstance.getLoggedInDownloads()}setLoggedOutDownloads(){const e=dlmReportsInstance.getLoggedOutDownloads();jQuery(".dlm-reports-block-summary li#logged_out span,#total_downloads_summary_wrapper .dlm-reports-logged-out").html(e.toLocaleString())}userToolTipMarkup(e){let t='<div class="dlm-user-reports">';return t=(t=t+'<div class="wpchill-tooltip"><i>[?]</i>'+'<div class="wpchill-tooltip-content">')+("<span>User ID: "+(null!==e?e.id:"--")+"</span>"),"object"!=typeof e&&e.url.length&&(t+="<span>User URL: "+(null!==e?e.url:"--")+"</span>"),t+="<span>User registration date: "+(null!==e?e.registered:"--")+"</span>",null!==e&&void 0!==e.role&&e.role.length&&(t+="<span>User role: "+e.role+"</span>"),t=(t+="</div></div>")+(null!==e?e.display_name:"--")+"</div>"}setUserDownloads(e=0,t=!1){const a=jQuery("#users_download_log"),n=jQuery("#users_download_log .user-logs__list");if(n.empty(),!0!==t){let t=[];t=(null!==dlmReportsInstance.tempDownloads?JSON.parse(JSON.stringify(dlmReportsInstance.tempDownloads)):JSON.parse(JSON.stringify(dlmReportsInstance.userDownloads))).slice(dlmReportsInstance.perPage*parseInt(e),dlmReportsInstance.perPage*parseInt(e+1));for(let e=0;e<t.length;e++){var o=dlmReportsInstance.getUserByID(t[e].user_id.toString()),s=dlmReportsInstance.getDownloadCPT(t[e].download_id.toString()),r={key:e,user:null!=o?o.display_name:"--",ip:t[e].user_ip,role:null!==o&&null!==o.role?o.role:"--",download:null!=s?s.title:"--",valid_user:"0"!==t[e].user_id,edit_link:"0"!==t[e].user_id?"user-edit.php?user_id="+t[e].user_id:"#",edit_download_link:null!=s?dlmAdminUrl+"post.php?post="+s.id+"&action=edit":"#",status:t[e].download_status,download_date:t[e].download_date};jQuery(document).trigger("dlm_reports_user_logs_item_before_render",[r,dlmReportsInstance,t[e],o,s]),new dlmBackBone.modelUserLogs(r)}dlmReportsInstance.stopSpinner(jQuery("#users_download_log")),a.find(".dlm-reports-total-pages").html(Math.ceil(dlmReportsInstance.tempDownloads.length/dlmReportsInstance.perPage)),parseInt(dlmReportsInstance.perPage)!==parseInt(t.length)?a.find('.user-downloads-block-navigation button[data-action="load-more"]').attr("disabled","disabled"):a.find('.user-downloads-block-navigation button[data-action="load-more"]').removeAttr("disabled"),dlmReportsInstance.userDownloads.length>dlmReportsInstance.perPage?a.find(".user-downloads-block-navigation button").removeClass("hidden"):a.find(".user-downloads-block-navigation button").addClass("hidden")}}filterDownloads(){dlmReportsInstance.tempDownloads=JSON.parse(JSON.stringify(dlmReportsInstance.userDownloads)),dlmReportsInstance.currentFilters.length&&dlmReportsInstance.currentFilters.forEach(t=>{dlmReportsInstance.tempDownloads=dlmReportsInstance.tempDownloads.filter(e=>t.on===e[t.type])}),dlmReportsInstance.setUserDownloads()}handleUserDownloads(){jQuery(".user-downloads-block-navigation").on("click","button",function(e){e.stopPropagation();let t=jQuery(this).parents("#users_downloads_table_wrapper"),a=t.find("#users_download_log"),n=a.attr("data-page"),o=jQuery(this),s=parseInt(n)+1,r=0!==n?parseInt(n)-1:0,d=t.find(".downloads-block-navigation button").first(),l=t.find(".downloads-block-navigation button").last();o.attr("disabled","disabled");e={data:dlmReportsInstance.tempDownloads,main_parent:t,offsetHolder:a,offset:n,link:o,nextPage:s,prevPage:r,prevButton:d,nextButton:l,doAction:dlmReportsInstance.setUserDownloads};dlmReportsInstance.handleSliderNavigation(e)}),jQuery("#users_downloads_table_wrapper").find("input.dlm-reports-current-page").on("change",function(){dlmReportsInstance.paginationChange(jQuery(this),dlmReportsInstance.tempDownloads,jQuery("#users_downloads_table_wrapper"),jQuery("#users_downloads_table_wrapper").find("#users_download_log"),dlmReportsInstance.setUserDownloads)})}togglePageSettings(){jQuery("#dlm-toggle-settings").on("click",function(e){e.stopPropagation(),jQuery(this).find(".dlm-toggle-settings__settings").toggleClass("display")}),jQuery(".dlm-toggle-settings__settings").on("click",function(e){e.stopPropagation()}),jQuery("html,body").on("click",function(){jQuery(this).find(".dlm-toggle-settings__settings").removeClass("display")}),jQuery(document).on("change",".wpchill-toggle__input",function(e){const t=jQuery(this),a=t.attr("name"),n={action:"dlm_update_report_setting",name:a,checked:t.is(":checked"),_ajax_nonce:dlmReportsNonce};jQuery.post(ajaxurl,n,function(e){a,jQuery(document).trigger("dlm_settings_ajax_response",[dlmReportsInstance,t,e])})})}getMaxDownload(){let t=0;return dlmReportsInstance.dataSets.forEach(e=>{e=Object.values(e.data).reduce((e,t)=>t<e?e:t,0);t<e&&(t=e)}),parseInt(t)}setChartTooltipDate(e,t,a){let n="";var o,s,r;return n="undefined"!==t.chartType&&"months"===t.chartType?(moment(e).year(),r=moment(e).month(),a=Object.keys(a)[Object.keys(a).length-1],o=moment(a).month(moment(a).month()-1).format("YYYY-MM"),s=moment(e).format("YYYY-MM"),r<11?s===o?moment(s).format("MMMM, YYYY"):moment(e).format("MMM")+" - "+moment(e).month(r+1).format("MMM")+moment(e).format(", YYYY"):s===o||s===a?moment(s).format("MMMM, YYYY"):moment(e).format("MMM")+moment(e).format(" YYYY")+" - "+moment(e).month(r+1).format("MMM")+moment(e).month(r+1).format(", YYYY")):"undefined"!==t.chartType&&"days"===t.chartType?(moment(e).year(),o=moment(e).day(),a=moment(e).format("MMMM"),s=moment(e).day(o+1).format("MMMM"),r=dlmReportsInstance.dates.downloads.end_date,t=moment(r).day(moment(r).day()-1).format("MMMM Do"),moment(e).format("MMMM Do")===moment(r).format("MMMM Do")||moment(e).format("MMMM Do")===t?moment(e).format("MMMM Do, YYYY"):a===s?moment(e).format("MMMM Do")+" - "+moment(e).day(o+1).format("Do")+moment(e).format(", YYYY"):moment(e).format("MMM Do")+" - "+moment(e).day(o+1).format("MMM Do")+moment(e).format(", YYYY")):moment(e).format("MMMM Do, YY")}closeDatePickers(e){jQuery(".dlm-reports-header-date-selector").not(e).each(function(){var e={target:jQuery(this).attr("id")};dlmReportsInstance.hideDatepicker(jQuery(this),e)})}shortNumber(e){return e=4<=(e="string"==typeof e?e.replace(/,/gi,""):parseInt(e).toString()).length?parseInt(e.substring(0,e.length-3)).toLocaleString()+"k":e}getDownloadByID(t){let a={total:0},n;return dlmReportsInstance.tempDownloads.forEach(function(e){t===e.download_id&&(n=e,a.total=a.total+1,jQuery(document).trigger("dlm_download_by_id",[dlmReportsInstance,a,n]))}),a}getDownloadCPT(t){let e=null;return Array.isArray(dlmReportsInstance.mostDownloaded)&&(e=dlmReportsInstance.mostDownloaded.filter(e=>e.id===t,0)[0]),jQuery(document).trigger("dlm_download_cpt",[dlmReportsInstance,e]),e}setSpinner(e){e.append('<div class="dlm-reports-spinner"><span></span></div>')}stopSpinner(e){e.find(".dlm-reports-spinner").remove()}eventsFunctions(){jQuery("body").on("click",".total_downloads_table_filters_total_downloads > a",function(e){e.preventDefault(),jQuery(this).parent().find("span.dashicons").toggleClass("dashicons-arrow-down dashicons-arrow-up"),dlmReportsInstance.orderOverviewItemsByTotal()}),jQuery("body").on("click",".total_downloads_table_filters_download_date > a",function(e){e.preventDefault(),jQuery(this).parent().find("span.dashicons").toggleClass("dashicons-arrow-down dashicons-arrow-up"),dlmReportsInstance.orderUserReportsItemsByDate()}),jQuery("body").on("change","select.dlm-reports-per-page",function(e){dlmReportsInstance.perPage=jQuery(this).val(),dlmReportsInstance.setTopDownloads(),dlmReportsInstance.setUserDownloads(),jQuery.post(ajaxurl,{action:"dlm_update_report_setting",name:"dlm-reports-per-page",value:dlmReportsInstance.perPage,_ajax_nonce:dlmReportsNonce},function(e){})})}orderItems(e,a,n,t=0){return e.sort((e,t)=>"asc"!==a?t[n]-e[n]:e[n]-t[n]),e}orderOverviewItemsByTotal(){dlmReportsInstance.mostDownloaded=dlmReportsInstance.mostDownloaded.reverse(),dlmReportsInstance.setTopDownloads()}orderUserReportsItemsByDate(){dlmReportsInstance.tempDownloads=dlmReportsInstance.tempDownloads.reverse(),dlmReportsInstance.setUserDownloads()}paginationChange(e,t,a,n,o){let s=parseInt(e.val()),r=(0===s&&(s=1),t.length<s*dlmReportsInstance.perPage&&(s=Math.ceil(t.length/dlmReportsInstance.perPage)),jQuery(this).next('button[data-action="load-more"]')),d=s+1,l=s-1,m=a.find(".downloads-block-navigation button").first(),c=a.find(".downloads-block-navigation button").last();r.attr("disabled","disabled");e={data:t,main_parent:a,offsetHolder:n,offset:s,link:r,nextPage:d,prevPage:l,prevButton:m,nextButton:c,doAction:o};dlmReportsInstance.handleSliderNavigation(e)}}
changelog.txt CHANGED
@@ -1,3 +1,11 @@
 
 
 
 
 
 
 
 
1
  = 4.6.5 - 10.10.2022 =
2
  Fixed: Elementor compatibility error ( [#1073](https://github.com/WPChill/download-monitor/issues/1073) )
3
  Fixed: Log meta data not saved ( [#1076](https://github.com/WPChill/download-monitor/issues/1076) )
1
+ = 4.7.0 - 14.10.2022 =
2
+ Fixed: Quick add - recreate Uploader if file upload ended in error ( [#1079](https://github.com/WPChill/download-monitor/issues/1079) )
3
+ Changed: Show grouped dates as period instead of a single day on repoprt chart tooltip ( [#1082](https://github.com/WPChill/download-monitor/issues/1082) )
4
+ Fixed: Performance issues on larga databases ( [#1081](https://github.com/WPChill/download-monitor/issues/1081) )
5
+ Changed: Get user data first ( [#1086](https://github.com/WPChill/download-monitor/issues/1086) )
6
+ Fixed: Downloading big files error ( [#1084](https://github.com/WPChill/download-monitor/issues/1084) )
7
+ Changed: Get chart data un chunks ( [#1083](https://github.com/WPChill/download-monitor/issues/1083) )
8
+
9
  = 4.6.5 - 10.10.2022 =
10
  Fixed: Elementor compatibility error ( [#1073](https://github.com/WPChill/download-monitor/issues/1073) )
11
  Fixed: Log meta data not saved ( [#1076](https://github.com/WPChill/download-monitor/issues/1076) )
download-monitor.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Download Monitor
4
  Plugin URI: https://www.download-monitor.com
5
  Description: A full solution for managing and selling downloadable files, monitoring downloads and outputting download links and file information on your WordPress powered site.
6
- Version: 4.6.5
7
  Author: WPChill
8
  Author URI: https://wpchill.com
9
  Requires at least: 5.4
@@ -34,7 +34,7 @@ if ( ! defined( 'ABSPATH' ) ) {
34
 
35
  // Define DLM Version
36
 
37
- define( 'DLM_VERSION', '4.6.5' );
38
  define( 'DLM_UPGRADER_VERSION', '4.6.0' );
39
 
40
  // Define DLM FILE
3
  Plugin Name: Download Monitor
4
  Plugin URI: https://www.download-monitor.com
5
  Description: A full solution for managing and selling downloadable files, monitoring downloads and outputting download links and file information on your WordPress powered site.
6
+ Version: 4.7.0
7
  Author: WPChill
8
  Author URI: https://wpchill.com
9
  Requires at least: 5.4
34
 
35
  // Define DLM Version
36
 
37
+ define( 'DLM_VERSION', '4.7.0' );
38
  define( 'DLM_UPGRADER_VERSION', '4.6.0' );
39
 
40
  // Define DLM FILE
includes/admin/uninstall/class-dlm-uninstall.php CHANGED
@@ -284,6 +284,7 @@ class DLM_Uninstall {
284
  $wpdb->prefix . 'dlm_order_transaction',
285
  $wpdb->prefix . 'dlm_order',
286
  $wpdb->prefix . 'dlm_reports_log',
 
287
  )
288
  );
289
 
284
  $wpdb->prefix . 'dlm_order_transaction',
285
  $wpdb->prefix . 'dlm_order',
286
  $wpdb->prefix . 'dlm_reports_log',
287
+ $wpdb->prefix . 'dlm_downloads',
288
  )
289
  );
290
 
includes/backwards-compatibility/class-dlm-backwards-compatibility.php CHANGED
@@ -158,7 +158,8 @@ class DLM_Backwards_Compatibility {
158
  add_filter( 'dlm_admin_sort_columns', array( $this, 'query_args_download_count_compatibility' ), 60 );
159
  add_filter( 'dlm_query_args_filter', array( $this, 'query_args_download_count_compatibility' ), 60 );
160
  add_filter( 'posts_join', array( $this, 'join_download_count_compatibility' ) );
161
- add_filter( 'posts_where', array( $this, 'where_download_count_compatibility' ) );
 
162
  add_filter( 'posts_groupby', array( $this, 'groupby_download_count_compatibility' ) );
163
  add_filter( 'posts_fields', array( $this, 'select_download_count_compatibility' ) );
164
  add_filter( 'posts_orderby', array( $this, 'orderby_download_count_compatibility' ) );
@@ -176,7 +177,7 @@ class DLM_Backwards_Compatibility {
176
  public function join_download_count_compatibility( $join ) {
177
  global $wpdb;
178
 
179
- $join .= " LEFT JOIN {$wpdb->download_log} ON ({$wpdb->posts}.ID = {$wpdb->download_log}.download_id) ";
180
 
181
  return $join;
182
 
@@ -189,6 +190,7 @@ class DLM_Backwards_Compatibility {
189
  *
190
  * @return string
191
  */
 
192
  public function where_download_count_compatibility( $where ) {
193
  global $wpdb;
194
 
@@ -209,7 +211,7 @@ class DLM_Backwards_Compatibility {
209
 
210
  global $wpdb;
211
 
212
- $fields .= ", COUNT({$wpdb->download_log}.ID) as counts ";
213
 
214
  return $fields;
215
  }
@@ -264,7 +266,8 @@ class DLM_Backwards_Compatibility {
264
  remove_filter( 'posts_groupby', array( $this, 'groupby_download_count_compatibility' ) );
265
  remove_filter( 'posts_fields', array( $this, 'select_download_count_compatibility' ) );
266
  remove_filter( 'posts_orderby', array( $this, 'orderby_download_count_compatibility' ) );
267
- remove_filter( 'posts_where', array( $this, 'where_download_count_compatibility' ) );
 
268
  }
269
 
270
  /**
158
  add_filter( 'dlm_admin_sort_columns', array( $this, 'query_args_download_count_compatibility' ), 60 );
159
  add_filter( 'dlm_query_args_filter', array( $this, 'query_args_download_count_compatibility' ), 60 );
160
  add_filter( 'posts_join', array( $this, 'join_download_count_compatibility' ) );
161
+ // @todo: delete this filter and function after feedback, as version 4.7.0 doesn't need it.
162
+ //add_filter( 'posts_where', array( $this, 'where_download_count_compatibility' ) );
163
  add_filter( 'posts_groupby', array( $this, 'groupby_download_count_compatibility' ) );
164
  add_filter( 'posts_fields', array( $this, 'select_download_count_compatibility' ) );
165
  add_filter( 'posts_orderby', array( $this, 'orderby_download_count_compatibility' ) );
177
  public function join_download_count_compatibility( $join ) {
178
  global $wpdb;
179
 
180
+ $join .= " LEFT JOIN {$wpdb->dlm_downloads} ON ({$wpdb->posts}.ID = {$wpdb->dlm_downloads}.download_id) ";
181
 
182
  return $join;
183
 
190
  *
191
  * @return string
192
  */
193
+ // @todo: delete this filter and function after feedback, as version 4.7.0 doesn't need it.
194
  public function where_download_count_compatibility( $where ) {
195
  global $wpdb;
196
 
211
 
212
  global $wpdb;
213
 
214
+ $fields .= ", {$wpdb->dlm_downloads}.download_count as counts ";
215
 
216
  return $fields;
217
  }
266
  remove_filter( 'posts_groupby', array( $this, 'groupby_download_count_compatibility' ) );
267
  remove_filter( 'posts_fields', array( $this, 'select_download_count_compatibility' ) );
268
  remove_filter( 'posts_orderby', array( $this, 'orderby_download_count_compatibility' ) );
269
+ // @todo: delete this filter and function after feedback, as version 4.7.0 doesn't need it.
270
+ //remove_filter( 'posts_where', array( $this, 'where_download_count_compatibility' ) );
271
  }
272
 
273
  /**
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: wpchill, silkalns, barrykooij, mikejolley
3
  Tags: download manager, document management, file manager, digital store, ecommerce, document management plugin, download monitor, download counter, password protection, download protection, password, protect downloads, tracker, sell, shop, ecommerce, paypal
4
  Requires at least: 5.4
5
  Tested up to: 6.0
6
- Stable tag: 4.6.5
7
  License: GPLv3
8
  Text Domain: -
9
  Requires PHP: 5.6
@@ -121,6 +121,14 @@ More documentation can be found in our [Knowledge Base](https://www.download-mon
121
 
122
  == Changelog ==
123
 
 
 
 
 
 
 
 
 
124
  = 4.6.5 - 10.10.2022 =
125
  Fixed: Elementor compatibility error ( [#1073](https://github.com/WPChill/download-monitor/issues/1073) )
126
  Fixed: Log meta data not saved ( [#1076](https://github.com/WPChill/download-monitor/issues/1076) )
3
  Tags: download manager, document management, file manager, digital store, ecommerce, document management plugin, download monitor, download counter, password protection, download protection, password, protect downloads, tracker, sell, shop, ecommerce, paypal
4
  Requires at least: 5.4
5
  Tested up to: 6.0
6
+ Stable tag: 4.7.0
7
  License: GPLv3
8
  Text Domain: -
9
  Requires PHP: 5.6
121
 
122
  == Changelog ==
123
 
124
+ = 4.7.0 - 14.10.2022 =
125
+ Fixed: Quick add - recreate Uploader if file upload ended in error ( [#1079](https://github.com/WPChill/download-monitor/issues/1079) )
126
+ Changed: Show grouped dates as period instead of a single day on repoprt chart tooltip ( [#1082](https://github.com/WPChill/download-monitor/issues/1082) )
127
+ Fixed: Performance issues on larga databases ( [#1081](https://github.com/WPChill/download-monitor/issues/1081) )
128
+ Changed: Get user data first ( [#1086](https://github.com/WPChill/download-monitor/issues/1086) )
129
+ Fixed: Downloading big files error ( [#1084](https://github.com/WPChill/download-monitor/issues/1084) )
130
+ Changed: Get chart data un chunks ( [#1083](https://github.com/WPChill/download-monitor/issues/1083) )
131
+
132
  = 4.6.5 - 10.10.2022 =
133
  Fixed: Elementor compatibility error ( [#1073](https://github.com/WPChill/download-monitor/issues/1073) )
134
  Fixed: Log meta data not saved ( [#1076](https://github.com/WPChill/download-monitor/issues/1076) )
src/Admin/MediaInsert.php CHANGED
@@ -222,6 +222,9 @@ class DLM_Admin_Media_Insert {
222
  <p class="drag-drop-buttons">
223
  <input id="plupload-browse-button" type="button" value="<?php esc_attr_e( 'Select File', 'download-monitor' ); ?>" class="button"/>
224
  </p>
 
 
 
225
  </div>
226
  </div>
227
  <p>
@@ -351,7 +354,8 @@ class DLM_Admin_Media_Insert {
351
  if ( max > hundredmb && file.size > hundredmb && up.runtime != 'html5' ) {
352
  // file size error?
353
  } else {
354
- jQuery( '.drag-drop-inside' ).html( '<p><?php echo esc_html__( 'Please wait...', 'download-monitor' ); ?></p>' );
 
355
  }
356
  } );
357
 
@@ -372,11 +376,14 @@ class DLM_Admin_Media_Insert {
372
 
373
  if ( is_json && !JSON.parse(response.response).success) {
374
  jQuery(up.settings.container).append('<p class="error description" style="color:red;">' + JSON.parse(response.response).data.error + '</p>');
 
375
  setTimeout(function () {
376
  jQuery(up.settings.container).find('.error.description').remove();
377
  }, 5500);
378
 
379
- up.refresh();
 
 
380
  return;
381
  }
382
  jQuery('#quick-add-details').find('input.download_url').val(response.response);
222
  <p class="drag-drop-buttons">
223
  <input id="plupload-browse-button" type="button" value="<?php esc_attr_e( 'Select File', 'download-monitor' ); ?>" class="button"/>
224
  </p>
225
+ <p class="dlm-drag-drop-loading" style="display:none;">
226
+ <?php echo esc_html__( 'Please wait...', 'download-monitor' ); ?>
227
+ </p>
228
  </div>
229
  </div>
230
  <p>
354
  if ( max > hundredmb && file.size > hundredmb && up.runtime != 'html5' ) {
355
  // file size error?
356
  } else {
357
+ jQuery( '.dlm-drag-drop-loading' ).show();
358
+ jQuery( '.drag-drop-inside *:not(.dlm-drag-drop-loading)' ).hide();
359
  }
360
  } );
361
 
376
 
377
  if ( is_json && !JSON.parse(response.response).success) {
378
  jQuery(up.settings.container).append('<p class="error description" style="color:red;">' + JSON.parse(response.response).data.error + '</p>');
379
+
380
  setTimeout(function () {
381
  jQuery(up.settings.container).find('.error.description').remove();
382
  }, 5500);
383
 
384
+ jQuery( '.dlm-drag-drop-loading' ).hide();
385
+ jQuery( '.drag-drop-inside *:not(.dlm-drag-drop-loading)' ).show();
386
+
387
  return;
388
  }
389
  jQuery('#quick-add-details').find('input.download_url').val(response.response);
src/Admin/Reports/Page.php CHANGED
@@ -381,7 +381,7 @@ class DLM_Reports_Page {
381
  <div class="wrap">
382
  <hr class="wp-header-end">
383
  <div class="main">
384
- <h3><?php echo __( 'Please <a href="#" class="dlm-db-upgrade-link">upgrade the database</a>.', 'download-monitor' ); ?></h3>
385
  </div>
386
  </div>
387
  <?php
381
  <div class="wrap">
382
  <hr class="wp-header-end">
383
  <div class="main">
384
+ <h3><?php echo __( 'Hello there! We made some changes on how Download Monitor\'s data is structured. Please <a href="#" class="dlm-db-upgrade-link">upgrade the database</a>.', 'download-monitor' ); ?></h3>
385
  </div>
386
  </div>
387
  <?php
src/Admin/Reports/class-dlm-reports.php CHANGED
@@ -250,15 +250,24 @@ if ( ! class_exists( 'DLM_Reports' ) ) {
250
  return array();
251
  }
252
 
253
- $cache_key = 'dlm_insights';
254
- $stats = wp_cache_get( $cache_key, 'dlm_reports_page' );
 
 
 
 
255
 
256
  if ( ! $stats ) {
257
- $stats = $wpdb->get_results( "SELECT * FROM {$wpdb->dlm_reports};", ARRAY_A );
 
 
 
 
 
258
  wp_cache_set( $cache_key, $stats, 'dlm_reports_page', 12 * HOUR_IN_SECONDS );
259
  }
260
 
261
- return $stats;
262
  }
263
 
264
  /**
250
  return array();
251
  }
252
 
253
+ $cache_key = 'dlm_insights';
254
+ $stats = wp_cache_get( $cache_key, 'dlm_reports_page' );
255
+ $offset = isset( $_REQUEST['offset'] ) ? absint( sanitize_text_field( wp_unslash( $_REQUEST['offset'] ) ) ) : 0;
256
+ $count = isset( $_REQUEST['limit'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['limit'] ) ) : 1000;
257
+ $offset_limit = $offset * 1000;
258
+ $download_stats = array();
259
 
260
  if ( ! $stats ) {
261
+ $stats = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->dlm_reports} LIMIT {$offset_limit}, {$count};", null ), ARRAY_A );
262
+ $download_stats = array(
263
+ 'stats' => $stats,
264
+ 'offset' => ( 1000 === count( $stats ) ) ? $offset + 1 : '',
265
+ 'done' => ( 1000 > count( $stats ) ) ? true : false,
266
+ );
267
  wp_cache_set( $cache_key, $stats, 'dlm_reports_page', 12 * HOUR_IN_SECONDS );
268
  }
269
 
270
+ return $download_stats;
271
  }
272
 
273
  /**
src/Admin/class-dlm-admin-helper.php CHANGED
@@ -141,11 +141,12 @@ class DLM_Admin_Helper {
141
  }
142
 
143
  // Drop the dlm_reports_log
144
- $drop_statement = "DROP TABLE IF EXISTS {$wpdb->prefix}dlm_reports_log";
145
  $wpdb->query( $drop_statement );
146
 
147
  // Delete upgrade history and set the need DB pgrade
148
  delete_option( 'dlm_db_upgraded' );
 
149
  set_transient( 'dlm_needs_upgrade', '1', 30 * DAY_IN_SECONDS );
150
 
151
  return true;
141
  }
142
 
143
  // Drop the dlm_reports_log
144
+ $drop_statement = "DROP TABLE IF EXISTS {$wpdb->prefix}dlm_reports_log,{$wpdb->prefix}dlm_downloads";
145
  $wpdb->query( $drop_statement );
146
 
147
  // Delete upgrade history and set the need DB pgrade
148
  delete_option( 'dlm_db_upgraded' );
149
+ delete_transient('dlm_db_upgrade_offset');
150
  set_transient( 'dlm_needs_upgrade', '1', 30 * DAY_IN_SECONDS );
151
 
152
  return true;
src/Admin/class-dlm-db-upgrader.php CHANGED
@@ -14,7 +14,7 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
14
  /**
15
  * Holds the class object.
16
  *
17
- * @since 4.5.0
18
  *
19
  * @var object
20
  */
@@ -24,7 +24,7 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
24
  * Class constructor
25
  *
26
  * @return void
27
- * @since 4.5.0
28
  */
29
  public function __construct() {
30
 
@@ -36,7 +36,7 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
36
  * Returns the singleton instance of the class.
37
  *
38
  * @return object The DLM_Admin_Helper object.
39
- * @since 4.5.0
40
  */
41
  public static function get_instance() {
42
 
@@ -59,6 +59,8 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
59
  DLM_Admin_Helper::redo_upgrade();
60
  }
61
 
 
 
62
  $this->init();
63
  }
64
 
@@ -70,7 +72,6 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
70
  public function init(){
71
  // Don't do anything if we don't need to or if upgrader already done.
72
  if ( ! self::do_upgrade() ) {
73
-
74
  return;
75
  }
76
 
@@ -99,7 +100,7 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
99
  /**
100
  * Check to see if we need to upgrade
101
  *
102
- * @since 4.5.0
103
  *
104
  * @return bool
105
  */
@@ -109,7 +110,7 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
109
  return false;
110
  }
111
 
112
- if ( false !== get_transient( 'dlm_db_upgrade_offset' ) ) {
113
  return true;
114
  }
115
 
@@ -150,7 +151,7 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
150
  /**
151
  * Check the old table entries
152
  *
153
- * @since 4.5.0
154
  */
155
  public function count_log_entries() {
156
 
@@ -160,7 +161,40 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
160
  $posts_table = "{$wpdb->prefix}posts";
161
 
162
  // Made it here, now let's create the table and start migrating.
163
- $this->create_new_table( $wpdb->dlm_reports );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
  // Check if the table exists. User might have deleted it in the past.
166
  if ( ! DLM_Utils::table_checker( $wpdb->download_log ) ) {
@@ -220,13 +254,13 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
220
  // Now lets clear all transients.
221
  download_monitor()->service( 'transient_manager' )->clear_all_version_transients();
222
 
223
- // Add uuid column to download_log table.
224
  global $wpdb;
225
 
226
  // In the event that the user had previously deleted the downlod_log table, we need to create it again.
227
  if ( ! DLM_Utils::table_checker( $wpdb->download_log ) ) {
228
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
229
-
230
  $dlm_tables = '
231
  CREATE TABLE `' . $wpdb->prefix . "download_log` (
232
  ID bigint(20) NOT NULL auto_increment,
@@ -245,7 +279,7 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
245
  meta_data longtext DEFAULT NULL,
246
  PRIMARY KEY (ID),
247
  KEY attribute_name (download_id)
248
- ) $collate;
249
  ";
250
 
251
  dbDelta( $dlm_tables );
@@ -253,53 +287,42 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
253
  exit;
254
  }
255
 
256
- $alter_statement = "ALTER TABLE {$wpdb->download_log} ADD COLUMN uuid VARCHAR(200) AFTER USER_IP,ADD COLUMN download_location VARCHAR(200) AFTER download_status_message,ADD COLUMN download_category VARCHAR(200) AFTER download_status_message;";
257
- $hash_statement = "UPDATE {$wpdb->download_log} SET uuid = md5(user_ip) WHERE uuid IS NULL;";
258
- // SQL to add index for download_log
259
- $add_index = "ALTER TABLE {$wpdb->download_log} ADD INDEX download_count (version_id);";
260
-
261
- $wpdb->query( $alter_statement );
262
- $wpdb->query( $hash_statement );
263
- $wpdb->query( $add_index );
264
-
265
- wp_send_json( array( 'success' => true ) );
266
- exit;
267
- }
268
-
269
- /**
270
- * Create the new table
271
- *
272
- * @return void
273
- * @since 4.5.0
274
- */
275
- public function create_new_table( $table ) {
276
-
277
- global $wpdb;
278
 
279
- // Let check if table does not exist.
280
- if ( ! DLM_Utils::table_checker( $table ) ) {
 
281
 
282
- $charset_collate = $wpdb->get_charset_collate();
 
 
283
 
284
- $sql = "CREATE TABLE IF NOT EXISTS `$table` (
285
- `date` DATE NOT NULL,
286
- `download_ids` longtext NULL,
287
- `revenue` longtext NULL,
288
- `refunds` longtext NULL,
289
- PRIMARY KEY (`date`))
290
- ENGINE = InnoDB $charset_collate;";
291
 
292
- require_once ABSPATH . 'wp-admin/includes/upgrade.php';
293
- dbDelta( $sql );
 
 
 
 
294
  }
295
 
 
 
 
 
 
 
 
296
  }
297
 
298
  /**
299
  * Check if DB migrated or not
300
  *
301
  * @return bool
302
- * @since 4.5.0
303
  */
304
  public static function check_if_migrated() {
305
 
@@ -318,13 +341,14 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
318
  /**
319
  * The new table update functionality
320
  *
321
- * @since 4.5.0
322
  */
323
  public function update_log_table_db() {
324
 
325
  wp_verify_nonce( $_POST['nonce'], 'dlm_db_log_nonce' );
326
 
327
  global $wpdb;
 
328
 
329
  $limit = 10000;
330
 
@@ -332,60 +356,65 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
332
 
333
  $sql_limit = "LIMIT {$offset},{$limit}";
334
 
335
- $items = array();
336
- $table_1 = "{$wpdb->download_log}";
337
- $able_2 = "{$wpdb->posts}";
338
-
339
- $data = $wpdb->get_results( $wpdb->prepare( "SELECT dlm_log.download_id as `ID`, DATE_FORMAT(dlm_log.download_date, '%%Y-%%m-%%d') AS `date`, dlm_posts.post_title AS `title` FROM $table_1 dlm_log LEFT JOIN $able_2 dlm_posts ON dlm_log.download_id = dlm_posts.ID WHERE 1=1 $sql_limit" ), ARRAY_A );
340
-
341
- foreach ( $data as $row ) {
 
 
 
 
 
 
 
 
342
 
343
- if ( ! isset( $items[ $row['date'] ][ $row['ID'] ] ) ) {
344
- $items[ $row['date'] ][ $row['ID'] ] = array(
345
- 'downloads' => 1,
346
- 'title' => $row['title'],
347
- );
348
- } else {
349
- $items[ $row['date'] ][ $row['ID'] ]['downloads'] = absint( $items[ $row['date'] ][ $row['ID'] ]['downloads'] ) + 1;
350
- }
351
  }
 
 
352
 
353
- foreach ( $items as $key => $log ) {
354
-
355
- $table = "{$wpdb->dlm_reports}";
356
-
357
- $sql_check = "SELECT * FROM $table WHERE date = %s;";
358
- $sql_insert = "INSERT INTO $table (date,download_ids) VALUES ( %s , %s );";
359
- $sql_update = "UPDATE $table dlm SET dlm.download_ids = %s WHERE dlm.date = %s";
360
- $check = $wpdb->get_results( $wpdb->prepare( $sql_check, $key ), ARRAY_A );
361
 
362
- if ( null !== $check && ! empty( $check ) ) {
363
-
364
- $downloads = json_decode( $check[0]['download_ids'], ARRAY_A );
365
-
366
- foreach ( $log as $item_key => $item ) {
367
 
368
- if ( isset( $downloads[ $item_key ] ) ) {
369
- $downloads[ $item_key ]['downloads'] = $downloads[ $item_key ]['downloads'] + $item['downloads'];
370
- unset( $downloads[ $item_key ]['date'] );
371
- } else {
372
- $downloads[ $item_key ] = array(
373
- 'downloads' => $item['downloads'],
374
- 'title' => $item['title'],
375
- );
376
- }
 
 
377
  }
378
-
379
- $wpdb->query( $wpdb->prepare( $sql_update, wp_json_encode( $downloads ), $key ) );
380
-
381
- } else {
382
-
383
- $wpdb->query( $wpdb->prepare( $sql_insert, $key, wp_json_encode( $log ) ) );
384
  }
385
  }
386
-
 
 
 
 
 
 
 
387
  set_transient( 'dlm_db_upgrade_offset', absint( $_POST['offset'] ) );
388
-
389
  // We save the previous so that we make sure all the entries from that range will be saved.
390
  wp_send_json( $offset );
391
  exit;
@@ -401,56 +430,78 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
401
  wp_verify_nonce( $_POST['nonce'], 'dlm_db_log_nonce' );
402
 
403
  if ( ! isset( $_POST['offset'] ) ) {
404
-
405
  // We need the previous set offset
406
  wp_send_json_error();
407
  exit;
408
  }
409
 
410
  global $wpdb;
411
-
412
- $limit = 10000;
413
- $offset = $_POST['offset'];
414
- $sql_limit = "LIMIT {$offset},{$limit}";
415
- $items = array();
416
- $table_1 = "{$wpdb->download_log}";
417
- $able_2 = "{$wpdb->prefix}posts";
418
-
419
- $data = $wpdb->get_results( $wpdb->prepare( "SELECT dlm_log.download_id as `ID`, DATE_FORMAT(dlm_log.download_date, '%%Y-%%m-%%d') AS `date`, dlm_posts.post_title AS `title` FROM $table_1 dlm_log INNER JOIN $able_2 dlm_posts ON dlm_log.download_id = dlm_posts.ID WHERE 1=1 $sql_limit" ), ARRAY_A );
 
 
 
 
 
 
 
 
420
 
421
  foreach ( $data as $row ) {
422
 
423
- if ( ! isset( $items[ $row['date'] ][ $row['ID'] ] ) ) {
424
- $items[ $row['date'] ][ $row['ID'] ] = array(
425
- 'downloads' => 1,
426
- 'title' => $row['title'],
427
- );
428
- } else {
429
- $items[ $row['date'] ][ $row['ID'] ]['downloads'] = absint( $items[ $row['date'] ][ $row['ID'] ]['downloads'] ) + 1;
 
 
 
 
 
 
 
 
430
  }
431
  }
432
 
433
- foreach ( $items as $key => $log ) {
 
 
 
 
 
 
434
 
435
- $table = "{$wpdb->dlm_reports}";
436
 
437
- $sql_check = "SELECT * FROM $table WHERE date = %s;";
438
- $sql_update = "UPDATE $table dlm SET dlm.download_ids = %s WHERE dlm.date = %s";
439
- $check = $wpdb->get_results( $wpdb->prepare( $sql_check, $key ), ARRAY_A );
440
 
441
- if ( null !== $check && ! empty( $check ) ) {
442
 
443
- $downloads = json_decode( $check[0]['download_ids'], ARRAY_A );
444
 
445
- foreach ( $log as $item_key => $item ) {
446
 
447
- if ( isset( $downloads[ $item_key ] ) ) {
448
- $downloads[ $item_key ]['downloads'] = $downloads[ $item_key ]['downloads'] - $item['downloads'];
 
449
  }
450
- }
451
 
452
- $wpdb->query( $wpdb->prepare( $sql_update, wp_json_encode( $downloads ), $key ) );
453
 
 
454
  }
455
  }
456
 
@@ -461,7 +512,7 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
461
  /**
462
  * Add the DB Upgrader notice
463
  *
464
- * @since 4.5.0
465
  */
466
  public function add_db_update_notice() {
467
 
@@ -473,7 +524,7 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
473
  <div class="inside">
474
  <div class="main">
475
  <img class="dlm-notice-logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIECAYAAABv6ZbsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAACZASURBVHgB7d09cFzXeTfwAxCEXUhjlFZlaoZMa1Cdgg8DpdSYnknkUrTU2pLcJXEhqsgknaTIbWSqdTIjppFLwviwStJt6Bkjldy98FiFBwDB9zyrXXoJ4mOx2Lv33Ht/vxlkQQByPBaxz/885znnpgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXMpMAhrtyy+/vDbKzx0dHS3Ex3k/Nzc3t5tG8Oqrr470c0CZBACYsEFBHhTcJ0+eRNF9WnhnZmZ635+dnY2vfWfw9fxz14b+Ywb/XBr65575zylV/u+9O/zn/N/71D/n/33+b+jzvfy9veM/MwgkAgdMlgAAxwwK+OHh4bVB8Y7XKNhDRXth+HtNKc4tsZf/Nx+EheHA8OcIEUNBovea/531PgQIeJYAQKsdK+a9z2MFPijk/a8p4h0SHYpBh2E4OPQ7F09Dw/7+/u76+vpegpYSAGiU+/fvL3z7299eGBT0oZX59+L7/a9di88HrXa4pAgBu6kfDuI1ti76nYbdQWBYWlp6mKBBBACKFCv3g4ODtf5q/Xu5qC/2V+nXEpQrAsLDCAU5IPw+/519eOXKlV3hgBIJANRuZ2dnMa/o1+bm5r4fhT5/6VrSiqd9NnIw+P3jx48jFDwUCqibAMBURQs/F/rFvKr/QS72a/lLUfAVe7qo1y3Ivwe/za8bKysrGwmmSACgctHO39/fv5VXPT9MCj6cphcI8tbBZ7lLsLG+vr6boEICAJXY2tpay6v8W/nN7If27WEsMUvw2/w7dE93gCoIAEzMoOjnluabySofJqZ/XHEjf3xsdoBJEQC4lNjTn5+ffzcX/feSog+VizCQtwg+sE3AZQkAjGVzc/NWXu2/mz9dS0Atchi4l4PAZ6urq/cSXJAAwMis9qFMugKMQwDgXLG3n99gbudPY4pf4YeC5d/Vu/v7+x8IApxHAOBU/cL/ftLmh8YRBDiPAMBzFH5oD0GA0wgAPKXwQ3sJAhwnABDDfdfm5+c/fPLkya0EtJogwIAA0GGm+qG7chC4s7S09EGiswSAjvrd73737tHR0Z2k8ENnDY4Prq6u3k10jgDQMXnVv3j16tUPk31+oM+2QDcJAB0x1O6/kwBOYFugWwSADug/pOdXufhfSwBniG2B3A1Y1w1oPwGgxWLVn9v9cazvvQRwAboB7ScAtFR/r/9u/vT7CWA8Dw8ODn6kG9BOs4nWiQn/XPzvJ8UfuJzF+fn5+5ubm7cTraMD0CL9Qb9fudAHmLTZ2dmP/v7v//7nidYQAFoiWv65+H9u0A+oigHBdrEF0AJffvnlm9HyV/yBKsV7TH9LQJexBXQAGm57ezsu9THlD0yVUwLNJwA0VP+I3+fJjX5ATcwFNJsA0ED9p/dp+QMlcFSwoQSAhlH8gdIYDmwmAaBB+pf7xPl+T/ADiiIENI9TAA0xmPRPij9QoOhK5veoBzs7O4uJRtABaIAo/o8fP76bAMq3l7sB60tLSw8TRdMBKJziDzTMQu4GPIj3rkTRdAAKpvgDTXblypXbr7766meJIgkAhVL8gTbI2wE3bQeUyRZAgRR/oC3ydsB9g4Fl0gEoTP+o34ME0B4GAwukA1CQuOSnf9QPoE3i+PLn8R6XKIYAUIjBDX/JOX+ghQZPEhQCymELoACu9wU6JJ4dEDcG7iVqpQNQgNz2v6f4Ax2xmBc8HyZqJwDUbHt7O34Rvp8AOiIveG7v7Oy8n6iVLYAaxS9A/kW4kwA6yEVB9RIAauK4H0DaOzg4uOkJgvWwBVCD/tDf5wmg2xb6JwOcfqqBAFCDvPL/laE/gKfHAw0F1kAAmLL+4MtaAqAnhgK3t7ffS0yVGYApsu8PcCrzAFOmAzAl9v0BzrSQF0jeI6dIAJiS/Bf7jn1/gDMt/u53vzMPMCW2AKZgc3Pz9uzs7K8SAOfKi6X1lZWVjUSlBICKuecf4GJmZmZ29/f3b3peQLVsAVRM6x/gYuI981vf+pargiumA1ChvJf17tHR0UcJgAuzFVAtAaAi0frvH/lzwxXAGGwFVMsWQEXiEb9J8QcYW/+WQAPUFREAKtC/7c8jfgEuKYeAW24JrIYtgAnrt/7/mACYFLcEVkAHYMLiyF8CYJLilkBbARMmAExQtP4d+QOoxJqtgMmyBTAhHvQDUDlbAROkAzABufgveNAPQOVsBUyQADAB+S+k1j/AdKxtbW3dSVyaLYBL8qAfgOmbmZm5ubS09DAxNh2AS4gjf1euXHFfNcD0fR7br4mxCQCX4EE/APXwwKDLswUwJq1/gPp5YND4BIAxROs/Lvyx+geolwcGjc8WwBi0/gHKYCtgfDoAF6T1D1AeWwEXJwBcgNY/QJlsBVycLYAL0PoHKJOtgIvTARiR1j9A+WwFjE4AGIHWP0Az2AoYnS2AEWj9AzSDrYDR6QCcQ+sfoHlsBZxPADiD1j9AM9kKOJ8tgDNo/QM0k62A8+kAnELrH6D5bAWcTgfgBB7zC9AOeSvgw8SJBIATaP0DtMbi1tbWncRzbAEck/+irOXEeD8B0BoHBwcvr6+v7yae0gE4xr4/QPvkzq739mMEgCE7Ozvva/0DtNLa9vb2e4mnbAH0xeBfToh/TAC01V7eCrhpK+AbOgB9ceFPAqDNFmwF/I0AkLT+ATpkbXNz81bCFkC/9f8gf7qQAOiCvf6pgE5fE9z5DkCc+U+KP0CXLLgmuOMdANf9AnRX168J7mwA8KQ/gG7r+hMDO7sF4LpfgG6LGjA3N9fZuwE62QFw5h+Avs7eDdDJDoAz/wD0dfZugM4FAGf+ATimk9cEd2oLQOsfgFN07m6ATnUA+mf+AeC4zt0N0JkOgDP/AJynS3cDdKIDkFv/C1euXOn8rU8AnG1mZubD1BGdCADz8/PvGvwDYASLXRkIbP0WgME/AC6oE3cDtL4D4NnPAFzQQu4ct34roNUBIAb/8staAoALyNvGt7a2ttZSi7U2AETr3+AfAONq+8mx1gaA3Po3+AfA2KKG5C7AndRSrRwCNPgHwIS0diCwlR2AXPw/TwBwea0dCGxdAOgP/i0mAJiAtg4EtioAuPEPgCq08YbAVgUAN/4BUJHW3RDYmiFAg38AVKxVjwxuTQfAo34BqFirHhncig6AR/0CMC1teWRwKzoABv8AmJaZmZlW1JzGB4CdnZ33Df4BMEVr/SPnjdboLYAY/Jufn78vAAAwZY0fCGx0ByAG/xR/AGqwMDc31+hjgY3tADj2B0DNGv2cgMZ2ANz3D0DNFnItauwJtEYGAPf9A1CItaY+J6CRAcCxPwBK0dRjgY0LAI79AVCYtSY+J6BRQ4CO/QFQqMYdC2xUB8CxPwAK1bhjgY3pADj2B0DhGnUssDEdgNz6/zABQLkWcq1qzEBgIzoAnvYHQFM05WmBjegAOPYHQFM05Vhg8QEgVv8G/wBokEZcDlR0ALh///6C1T8ATdOEbeuiA8D8/Py7Vv8ANE3UrtIvByp2CNCxPwAarujLgYrtAMSlPwkAmqvoy4GK7ABY/QPQEsV2AYrsAFj9A9ASC6VeZFdcByCOTszMzNxPANAS/S7AbipIcR2AXPxd+QtAq+TOdnHHAovqALjyl1E8ePAgcXkvvPBC7+O4l156KQGTV9oVwXOpIHHpT/4fKMFZfvaznyWqF0FgEBLi47vf/W568cUX040bN3p/HrwCo+lfEbyRClFMB8Dqn1EtLy8nyjAcBF555ZV0/fp1wQDOUFIXoJgOgNU/NM/XX3/9dEtma2vr6dcjBETHIELB4uJi78/A0zm3m6kARXQArP65CB2A5omOwM2bN9Pq6mrvNcIBdNXR0dFP8u/C3VSz2gNAXPozPz9/353/jEoAaL7oCERn4PXXX9cdoHNyF2B3f3//Zt2XA9W+BZCL/5uKP3TLo0ePeh//9V//1esG5D3R9OMf/1hngE6Imte/IvhOqlGtHYD+lb+xgbiQYEQ6AO0V3YA33njDNgFdUPsVwbV2APpX/ir+QE90Bf71X/+19/lrr73WCwO2CGiphbq7ALV1ADzwh3HpAHRLdANiViACAbRMrV2A2q4C9sAfYBRxzDC6Av/wD/+QfvOb3yRokVofF1xLB8Dqn8vQAei2mA14++23dQRoi9q6ALV0AKz+gXH96U9/0hGgTWrrAky9A2D1z2XpADBMR4AWqKULMPUOgNU/MEmDjsA///M/9z6HBlr41re+9X6asql2AKz+mQQdAM4SRwffeustDySicfpdgN00JVPtAFj9A1X79a9/nW7fvm0+gMaZn5+fahdgah0Aq38mRQeAUcVcQMwHuFWQpphmF2BqHQCrf2Daogvw05/+VDeAxphmF2AqHYCtra21mZmZ+wkmQAeAccRswDvvvJOgdNPqAkylA5CL/9SnGwGGxWxA3B3gpAClm1YXoPIAEKv//LKWAGoWxd+AIKV78uTJ7ZibSxWrPABY/QMl+frrr3v3Bnz66acJSjWNLkClAcDqHyhVBIC4PCgCAZRmGl2ASgOA1T9QsrxI6W0JmAugRFV3ASoLAFb/QBNE8Y+jgkIApam6C1BZAMir/9sJoAEGIeDRo0cJSlJlF6CSANBPLG8mgIaIEPCzn/1MCKAoVXYBKgkAbv0DmigGAoUASlNVF2DiAcDqH2gyIYDSVNUFmHgAsPoHmk4IoDRzc3PvpQmbaACw+gfaIkJA3BPgdAAlmJmZeTPX2IU0QRMNAFb/QJs4IkhBFibdBZhYALD6B9ooir8bAylB7gK8O8kuwMQCgNU/0FYxC/Af//EfCWo20S7ARAKA1T/Qdl988UXvkcJQp0l2ASYSAKz+gS6ILsCDBw8S1GhiXYBLBwCrf6BL4lHC5gGo06S6AJcOAPPz84o/0BmDoUCo0US6AJcKAP3V/+0E0CGxDWAegDpFFyBd0qUCwJUrV9aePHlyLQF0zKeffup+AOq0sLm5eTtdwmUDQGWPKQQoWcwBxDwA1OWyNXjsABDJw+of6DJbAdQpavDW1tZaGtPYAcDqH8BWAPWamZkZuxaPFQCs/gG+EVsBH3/8cYKarI3bBRgrAFj9A/xNfgN2QRC1GbcLcOEAYPUP8DzPCqBGY3UBLhwArP4BnhcPDDIQSF3G6QJcKABEwrD6BzhZDAS6JpiaXLgLcKEAcJlpQ4C2i+KvC0BdLlqjZ0b9wfv37y9evXrVlAu1W15eTm332muvpV/84hdpGr766qte4YqjbPHxv//7v+kPf/hDr6XNxb3wwgvpv//7v3uvMG0HBwcvr6+v747ys3NpRLn4T+Txg0BZXnrppd7rjRs3nvl6hIIIAZubm70pd2fdRzPoArz11lsJpq3/kKCR6vVIHYB46E8OAH9MUAAdgHoMhtziuJswcDZdAGq01+8C7J33gyPNAOTifycBnRYdgggld+/e7b1+97vfTZwsugDRNYEajPyo4JECwMzMzA8SQPpmdRsdil/+8pfa3Gf44osvEtRh1EcFnxsAXPwDnCQ6ABEAotV98+bNxLNiq8TtgNRkYZQjgecGgNnZ2ZGSBNBNEQQ++eST9O6779rzPibuBYA6jHIk8MwAEMN/+WUxAZzjH//xH3vzAWYD/iY6AC4GoiZruYYvnPUDZwYAw3/ARUTxjxCwsrKS+IaLgajLecOAZwYAw3/ARcU2wL/9278ZEOwzDEhdzhsGPDUAbG5u3jL8B4wrAoAQkHp3JhgGpCZnDgOeGgBmZ2dvJYBLEAK+4U4AanRqLT9rC+CHCeCShADbANQnbwO8edr3TgwA0f7PL2dODwKMKgLA66+/nroqTgLYBqAmp24DnBgAtP+BSXvnnXeee+BQl9gGoEYn1vQTA4Dpf2DSBqcDunpZUDxVEepw2jbAcwEgWgWm/4EqxD0BcWNgF8VpgK+++ipBDU7cBjipA6D9D1QmHiTU1YuCbANQo7XjX3guAGj/A1WLxwl3cStAAKAuJ9X2ZwKAu/+BaYji/8Ybb6SuefToUYKaPPdsgGcCwJUrVxR/YCriaGDXHhzkOCB1yjV+bfjPzwQAx/+AaXr77bdT1+gCUJe8DbA2/OfjMwDfTwBTEgOBXesC6ABQl+NzAE8DQH9vwBYAMFVdmwXQAaBGi8NzAE8DwPG9AYBpiCuCu3QiIO4DiFkAqMPc3NzThf7TAJBbA1b/wNRF8e/acwJsA1CX4Vo/HACc/wdq0bWLgdwISI3WBp8MDwHqAAC1uHnzZnrppZdSV5gDoC5Pnjx5OuzfCwD9oQCP/wVq06UugABAXXK3/9pgELAXAIaHAgDq0KUAEIOAUJdBze8FAAOAQN1u3LjRmdMAcQrASQDqMqj5gxkAAQCoVRT/CAFdYRCQujx58uRavA4CwPcSQM26FABsA1CXmAOIVx0AoBhxGqArbAFQl8FJgFknAIBSXL9+PXWFLQDqMtwBuJYAChB3AXRlEFAAoE5ffvnltdm5uTmrf6AYXboQCOpyeHh4bXYwDQhQgq48HtgQIHWK2j872AsAKIEOAFQvan/MANgCAIphBgCmYkEHACiKDgBUb3Z29jvRAfhOAgA6ozcDkACAznEKAChKV04BQJ10AACgo2II0CkAAOgYxwCBorggB6o3uAcAAOgYAQAoyl/+8pcEVE8AAIry9ddfpy7oyo2HlEsAAIrSlStyX3zxxQR1EgCAohgChOkQAICidGULwIVH1C1uAtxNAIV49OhR6gJbANRsTwcAKMaDBw9SVxgCpE558S8AAOXoyuo/eOwxdYurgHcTQAG6FADMAFCnqP06AEAxbAHA9EQA+L8EULM4/telI4A3btxIUKM/xymAvQRQsy6t/rX/qVucAIwOgAAA1O6LL75IXWEAkALsuQcAqF20/rvUAdD+p269DoBTAEDdulT8gy0A6tY7BXB4eLibAGr0n//5n6lLdACo2+zs7N7s+vr6bgKoSaz+u/YAIAGAui0tLT3s3QNgDgCoS5eG/8L169fdAUDdesP/vQCQ9wJ+nwCmLFb+v/nNb1KXWP1TgIfxf3QAgNp0be8/vPLKKwnqlGt+b9E/6ADsJoAp6uLqP8QWANRpUPMHHYCHCWCKurj6j+N/tgCo26Dm9wLA4eGhAABMTaz8u7j6V/wpwaDm9wLA+vr6njkAYBqi9d/F1X9YXV1NULO9qPnxydPHATsJAExDFP+unfsfuHnzZoKaPe34zw59cSMBVOjXv/51J1v/IYq/K4CpW+72/3bw+ezQF80BAJWJVf+nn36aumplZSVBATYGnzwNAAYBgapE8f/pT3+avv7669RV9v8pwXCtfxoA+kMBQgAwUYPi39V9/xBn/7X/KcDDwQBgGJ4BeGZvAOCyYsX/T//0T50u/uHHP/5xgrrNzMw8s8g/HgA2EsAERNG/fft2+sMf/pC6zvQ/JXj8+PH/DP959tg3NxLAJWn7/43pf0qRa/zpHYD+3sBGAhjT1tZWb+Wv+H/j9ddfT1CA2P/fHf7C3PGfiDmAvE+wlgAuIPb745hfnPXnG7Hyf+211xLU7aQZv9kTfm4jAVzAgwcPeqt+xf9ZVv8U5N7xLzzXAVhZWdnY3t6OrYCFBHCGwb3+Xb3d7zwCACWIx/8uLy9vHP/63Ek/nFsFn+V/4N0EcIJo98dqPz66fLnPWaL1b/iPQmyc9MW5U344WgUCAPCMaPV/8cUXVvwjePvttxOU4Pjxv4ETA4BtAGAgVvhR8Dc3N3sBgPM5+kdB9lZXV++d9I3TOgC2AaCjouA/evSoV+wHH1zMW2+9laAEuY7fO+17c2f8c7YBoCYxXDeNNnsU+7/85S/pq6++6n0et/bF54wvVv9u/qMUR0dHn532vZkz/rmUtwH+X7INQGGWl5cTlOqTTz4RAChCTP8vLS29fNr3Z8/6h/M2wMcJgJHE5L/iT0E2zvrmmQHg8PDwowTASEz+U5L9/f0Pzvr+mQHAswEARuPcP4XZOH73/3FnBoCQtwE+SACcKgq/1T8lOWv4b+DcABB3AuSXvQTAiaL4W/1Tihj+W11dvXvez50bAIJhQICTeeIfBdoY5YdGCgD9YUBdAIBjfvnLXyYoyXnDfwMjBYAYBoybARMAT8WNf1r/lCS3/++eN/w3MFIACI4EAvxNFH5X/lKaUVf/YeQA0E8UGwmg41544QWtf0q0MerqP4wcAIIjgQBa/5TpojX6QgGgfyRwIwF01BtvvNH7gMJs9Gv0yC4UAIIuANBVsep/5513EpRmlIt/jrtwANAFALooir99f0o06sU/x104AARdAKBr/v3f/92+P0V6/PjxWDV5rACgCwB0SbT9r1+/nqA0467+w1gBIOgCAF0QE/+G/ijVuKv/MHYAiC5AJI8E0FJR/F32Q6kus/oPYweAcJnkAVAyxZ/SXbYGXyoA9JOHhwQBraL4U7rLrv7DpQJA8KhgoE0Uf5pgnHP/x106AHhUMNAWij9NEKv/XHvvpku6dADoPypYFwBoNMWfBrnQQ39Oc+kAEHQBgCaLc/6KP01xkUf+nmUiAUAXAGiieKzvJ5984pw/jZHb/3cnsfoPEwkAQRcAaJK41vfu3bvp5s2bCZpiUqv/MLEAoAsANEUU/Xiwj7v9aZJJrv7DxAJA0AUAShft/mj7K/40zSRX/2GiAaDfBbj02USASYv9/n/5l3/pDfxB00x69R8mGgBCvwsAUIxo+cd+/+uvv56giSa9+g8TDwD9hKILABQhjvdp+dNkVaz+w8QDQDg4OLiTAGp0/fr13qrf+X6arorVf6gkAOgCAHWJvf4o+lH8IwRAk1W1+g9zqSLRBbh69eqbCWBKYq//F7/4hXY/rVHV6j9U0gEIugDAtETBj31+e/20SZWr/1BZByDoAgBVinZ/nOuPj/gc2qTK1X+oNABEctne3o4ugBAATIzCT9tVvfoPlQaAoAsATIrCT1dUvfoPlQcAXQDgshR+umQaq/9QeQAIugDAOGKqf3V1Nb322msKP50xjdV/mEoA0AUARhWFPgp/rPY9qpeumdbqP0wlAARdAOAsVvswvdV/mFoA0AUAjouiHx9R9F966aUEXTbN1X+YWgAIugDQbbGyv3HjRm+lv7y8rOjDkGmu/sNUA0Akm62trY9zynk3AZ0QBX9xcbFX9ONz7X143rRX/2GqASAcHh4OugALCWiVWNHHA3heeeWV3quCD6OZ9uo/TD0A5ISz1+8CvJ+AxomC/uKLL/YKfNy7/3d/93e9z6P4K/ZwcXWs/sPUA0DIXYCPchcgtgF0AbgwR8OqEwV8UMSjoEehH3wtir0iD5NXx+o/zKSa5C7AHV0AALosVv9LS0s/STWo7HHA54kuQH7ZSwDQUXWt/kNtASBmAZ48efJxAoAOyjXwgzr2/gdqCwBBFwCALsqt/91cA++mGtUaAHQBAOiio6Ojz+pc/YdaA0CILkAkoQQAHRA1b2Vl5U6qWe0BILoAjx8/rm0IAgCmqZSaV9sxwOO2t7fv55e1BAAtFav/paWll1MBau8ADMQ0ZAKAFiup411MByDoAgDQViWt/kMxHYCgCwBAW5U271ZUByDoAgDQQhvLy8vrqSBFdQDCwcFBLXciA0BVSqxtxQWAuBjB5UAAtEVdj/s9T3EBIBweHt5JrggGoAXqfODPWYoMAK4IBqANSl39hyIDQPCgIACaLI79lbr6D8UGgOgC5BfHAgFopBIe+HOW4o4BHrezs/PHvB1wLQFAQ5R26c9Jiu0ADOQE5VggAI3ShIfcFd8BCC4HAqApmrD6D8V3AIIrggFoiqZ0rhsRAFZWVjbyy2cJAAoWx/76Nat4jQgA4eDg4E5yLBCAgpV87O+4xgQAVwQDULKSL/05SWMCQHA5EAAlKv3Sn5M0KgDE5UBHR0c/TwBQkDj216TVf2jEMcDjHAsEoBRNOfZ3XKM6AAOOBQJQiiZc+nOSRnYAws7Ozuc5CNxKAFCTvPq/l1f/P0oN1MgOQNjf349ZAAOBANSmX4saqbEBwLFAAOrUtGN/xzU2AIQ4FhjDFwkApqiJx/6Oa3QAiGOBTR2+AKC5mnjs77jGDgEOcywQgGlp6rG/4xrdARhwLBCAacmr/1ZcSNeKABBPXjIQCEDVYvBvdXX1XmqBVgSAcHh4eCc5FghAhZo++DesNQEgBgLzi60AACoR281NH/wb1oohwGHb29sP8stiAoAJacvg37DWdAAGckLztEAAJqqNR85bFwBiIDDuZk4AMAH9wb+7qWVaFwCC5wQAMCltGvwb1soA4DkBAExC2wb/hrVuCHDYzs7OH/O/vGsJAC6ojYN/w1rZARg4Ojr6SQKAMbT9WTOtDgAGAgEYR1sH/4a1OgCE/f396AIYCARgZG0d/BvW+gDghkAALqLNg3/DWj0EOMwNgQCcp+2Df8Na3wEYcEMgAOdp++DfsM4EAI8MBuAsXRj8G9aZABA8MhiAk0TrvwuDf8M6FQBiIPDo6MhWAADPiA5xFwb/hnVmCHDY9vb2/fyylgDovC4N/g3rVAdg4ODgwN0AAPTk1v966qBOBgAPCwIgdLH1P9DJABAODw8/irZPAqCTogb0h8M7qbMBoD8Q6GFBAB0VZ/77t8V2UmcDQHA3AEA3de3M/0k6HQCCuwEAuqWLZ/5P0vkAYCsAoFv6rf/d1HGdvAfgJO4GAOiEh8vLyzcTOgAD7gYAaL/8Xv+jRI8A0NdvB3V+TwigrZ48eaL1P8QWwDG2AgDap6vX/Z5FB+AYWwEA7dPV637PIgAc45pggHbR+j+ZAHCClZWVO/nlYQKg0frX/X6UeI4AcIqcGH+eAGi0uOely9f9nkUAOIVrggGaLa77jffyxIkEgDPENcGeGAjQPK77PZ8AcAbXBAM0k+t+zycAnMNWAECzeNLfaASAEdgKAGgGrf/RCQAjsBUA0Axa/6MTAEZkKwCgbFr/FyMAXICtAIAyaf1fnABwAbYCAMqk9X9xAsAF2QoAKIvW/3gEgDHYCgAog9b/+ASAMdgKACiD1v/4BIAx2QoAqFe8B2v9j08AuARbAQD16D/m905ibDOJS9nZ2VnMKfRBAmBq8vvuuif9XY4OwCUtLS09zH8RDaAATEm85yr+l6cDMCHb29v388taAqAy0frPC6+XE5emAzAhBwcHcSpgLwFQmf39/fXERAgAE9I/hmIrAKAi0fp35G9ybAFMmK0AgMnT+p88HYAJsxUAMHF7Wv+TJwBMWLSnclL9eQJgUrT+K2ALoCI7Ozuf5/2qWwmAscWDfnLr39XrFdABqEhuV/3ELYEA4/Ogn2oJABXxwCCAy/Ggn2oJABXywCCA8XjQT/UEgIp5YBDAxXjQz3QYApyCra2ttfwX+n4C4FwHBwcva/1XTwdgCmwFAIzGbX/TowMwRdvb2/HY4MUEwHPc9jddOgBTlNtaP0puCQQ4idv+pkwAmCIPDAI4ldb/lAkAU7a8vPyReQCAv4n3xHhvTEyVAFADRwMBvuHIX30MAdbk/v37165evRpDgQsJoJv2Dg4Obmr910MHoCbxF95VwUCXxXug4l8fAaBGq6ur9+LMawLomHjvi/fARG1sARRga2vro7wP9m4C6IAY+ltZWXkvUSsBoBAuCQI64vfLy8ve6wpgC6AQBwcH604GAG0W73H5ve5WoggCQCHW19d7t2AJAUAbxXtbvMcZ+iuHLYDCxPHA+fn5+3mP7FoCaAHFv0wCQIF2dnYWcwCIxwe7IwBoujjrH8X/YaIoAkChhACgBRT/ggkABRMCgAZT/AsnABROCAAaSPFvAAGgAYQAoEEU/4ZwDLABlpaWHsYDMxwRBErWP+d/U/FvBh2ABnFEECiVo37NowPQIPGL5bIgoEC/V/ybRwBomH4IiO0AT9ECahfvRbntv6b4N48tgAbb2tq6k3/53k8ANfBUv2YTABpue3s7fvk+TADT9fPl5eWPEo0lALRAHBPML58bDgSq1h/2+5FJ/+YzA9ACcUwwBnDypxsJoDob/WE/xb8FdABaxlwAUIXcYfwg7/ffSbSGANBCOQSszc7O/sqWAHBZ0fI/Ojr6SS7+G4lWsQXQQvGL2t8S+CwBjCmO+MWxY8W/nXQAWm5zc/P2lStX3tcNAC5gL398YMq/3QSADogrhK9evXonf/pmAjjbxsHBwU9c7NN+AkCH6AYAZ9jLe/0/X11dvZvoBDMAHRK/2GYDgOPiRr+86n9Z8e8WHYCO8mRBINvoH+/bSHSOANBxtgWgk7T7EQDodQMW5ubm3pudnX1TEIBW24t2/+Hh4Ufr6+t7iU4TAHjKaQFoLYWf5wgAPEcQgNZQ+DmVAMCpBkFgZmbmB7YGoFEUfs4lAHCuCAJXrlxZMywIxVP4GZkAwIXEqYEYFsyfriWgFBtHR0cfr66u3kswIgGAsdgegNrt5d+/z3Lhv+ccP+MQALi0/l0CP8xB4FYCqtZb7T9+/HhDm5/LEACYmMGsgC0CmLiNXPD/Jxf+u4o+kyIAUImhwUGdAbi4KPIPFX2qJAAwFVtbW9EZuJXDwA/yHxcT8Iz8u7Gbf0ei4N87PDx8qOhTNQGAqet3BxajQyAQ0GEPZ2ZmfptX+bHSv6fgM20CALXrP4tgMa98FvPr4FSBUECbRLF/mFf2v8+r/IdW+JRAAKBYOzs7i3lldC2/cS7mN83vRTCIj/znawkK02/hP8yf7kWhz39P965evbrx6quv7iYokABAI0XXYH5+/lruGiz0g8FCfvONj+/lb8fXFuI1f1zrv8KFREGP11zId+MjPs9/3/4vf8T5+/jYzR2r3tcVeZpIAKATjgWGXjiITkKEhvz5dwaXGfU7DIPwQHvEFblPC3f6Zsr+z1HM+4W+970o6H/961/3tOfpAgEAThGh4dvf/vZCbudeiz8PQsJgC6LfbUhDNyH2woUAMXmD1Xjor8ijQPeKdKzKh38mvp//3ezFh2IOpxMAoEKDEBGdh/gYfH2o47DQ70L0DDoSx39u2GlXL09pNqK3kk4n///fPfbnp0V6YFCsw3BRT/0VeHwyaKsHrXUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADO9f8BiZVBFMCdLXQAAAAASUVORK5CYII=">
476
- <h4><?php echo wp_kses_post( __('Hello there! We changed the way we display our reports, made it faster than ever, and added some new options. Please <a href="#" class="dlm-db-upgrade-link">click here</a> to upgrade your database', 'download-monitor' ) ); ?></h4>
477
  <button id="dlm-upgrade-db" class="button button-primary">
478
  <?php
479
  // If the transient is present it means that this is a Resume Upgrade request
@@ -495,7 +546,7 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
495
  /**
496
  * Enqueue the DB Upgrader scripts
497
  *
498
- * @since 4.5.0
499
  */
500
  public function enqueue_db_upgrader_scripts() {
501
 
@@ -507,5 +558,219 @@ if ( ! class_exists( 'DLM_DB_Upgrader' ) ) {
507
  wp_enqueue_style( 'dlm-db-upgrade-style', download_monitor()->get_plugin_url() . '/assets/css/db-upgrader.min.css', array(), '4.4.7' );
508
  wp_enqueue_style( 'jquery-ui-style', download_monitor()->get_plugin_url() . '/assets/css/jquery-ui.min.css', array(), DLM_VERSION );
509
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
510
  }
511
  }
14
  /**
15
  * Holds the class object.
16
  *
17
+ * @since 4.6.0
18
  *
19
  * @var object
20
  */
24
  * Class constructor
25
  *
26
  * @return void
27
+ * @since 4.6.0
28
  */
29
  public function __construct() {
30
 
36
  * Returns the singleton instance of the class.
37
  *
38
  * @return object The DLM_Admin_Helper object.
39
+ * @since 4.6.0
40
  */
41
  public static function get_instance() {
42
 
59
  DLM_Admin_Helper::redo_upgrade();
60
  }
61
 
62
+ $this->check_upgrade_type();
63
+
64
  $this->init();
65
  }
66
 
72
  public function init(){
73
  // Don't do anything if we don't need to or if upgrader already done.
74
  if ( ! self::do_upgrade() ) {
 
75
  return;
76
  }
77
 
100
  /**
101
  * Check to see if we need to upgrade
102
  *
103
+ * @since 4.6.0
104
  *
105
  * @return bool
106
  */
110
  return false;
111
  }
112
 
113
+ if ( false !== get_transient( 'dlm_db_upgrade_offset' ) || false !== get_transient( 'dlm_upgrade_type' ) ) {
114
  return true;
115
  }
116
 
151
  /**
152
  * Check the old table entries
153
  *
154
+ * @since 4.6.0
155
  */
156
  public function count_log_entries() {
157
 
161
  $posts_table = "{$wpdb->prefix}posts";
162
 
163
  // Made it here, now let's create the table and start migrating.
164
+ // Let check if table does not exist.
165
+ if ( ! DLM_Utils::table_checker( $wpdb->dlm_reports ) ) {
166
+
167
+ $charset_collate = $wpdb->get_charset_collate();
168
+
169
+ $sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->dlm_reports}` (
170
+ `date` DATE NOT NULL,
171
+ `download_ids` longtext NULL,
172
+ `revenue` longtext NULL,
173
+ `refunds` longtext NULL,
174
+ PRIMARY KEY (`date`))
175
+ ENGINE = InnoDB $charset_collate;";
176
+
177
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
178
+ dbDelta( $sql );
179
+ }
180
+
181
+ // Made it here, now let's create the table and start migrating.
182
+ // Let check if table does not exist.
183
+ if ( ! DLM_Utils::table_checker( $wpdb->dlm_downloads ) ) {
184
+
185
+ $charset_collate = $wpdb->get_charset_collate();
186
+
187
+ $sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->dlm_downloads}` (
188
+ ID bigint(20) NOT NULL auto_increment,
189
+ download_id bigint(20) NOT NULL,
190
+ download_count bigint(20) NOT NULL,
191
+ download_versions varchar(200) NOT NULL,
192
+ PRIMARY KEY (`ID`))
193
+ ENGINE = InnoDB $charset_collate;";
194
+
195
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
196
+ dbDelta( $sql );
197
+ }
198
 
199
  // Check if the table exists. User might have deleted it in the past.
200
  if ( ! DLM_Utils::table_checker( $wpdb->download_log ) ) {
254
  // Now lets clear all transients.
255
  download_monitor()->service( 'transient_manager' )->clear_all_version_transients();
256
 
257
+ // Add extra columns to the table
258
  global $wpdb;
259
 
260
  // In the event that the user had previously deleted the downlod_log table, we need to create it again.
261
  if ( ! DLM_Utils::table_checker( $wpdb->download_log ) ) {
262
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
263
+ $charset_collate = $wpdb->get_charset_collate();
264
  $dlm_tables = '
265
  CREATE TABLE `' . $wpdb->prefix . "download_log` (
266
  ID bigint(20) NOT NULL auto_increment,
279
  meta_data longtext DEFAULT NULL,
280
  PRIMARY KEY (ID),
281
  KEY attribute_name (download_id)
282
+ ) $charset_collate;
283
  ";
284
 
285
  dbDelta( $dlm_tables );
287
  exit;
288
  }
289
 
290
+ $columns = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
 
292
+ if ( ! DLM_Utils::column_checker( $wpdb->download_log, 'uuid' ) ) {
293
+ $columns .= 'ADD COLUMN uuid VARCHAR(200) AFTER USER_IP';
294
+ }
295
 
296
+ if ( ! DLM_Utils::column_checker( $wpdb->download_log, 'download_location' ) ) {
297
+ $columns .= ( ! empty( $columns ) ) ? ',ADD COLUMN download_location VARCHAR(200) AFTER download_status_message' : 'ADD COLUMN download_location VARCHAR(200) AFTER download_status_message';
298
+ }
299
 
300
+ if ( ! DLM_Utils::column_checker( $wpdb->download_log, 'download_category' ) ) {
301
+ $columns .= ( ! empty( $columns ) ) ? ',ADD COLUMN download_category VARCHAR(200) AFTER download_status_message' : 'ADD COLUMN download_category VARCHAR(200) AFTER download_status_message';
302
+ }
 
 
 
 
303
 
304
+ // Let's check if all the required columns are present. If not, let's add them.
305
+ if ( ! empty( $columns ) ) {
306
+ $alter_statement = "ALTER TABLE {$wpdb->download_log} {$columns}";
307
+ $hash_statement = "UPDATE {$wpdb->download_log} SET uuid = md5(user_ip) WHERE uuid IS NULL;";
308
+ $wpdb->query( $alter_statement );
309
+ $wpdb->query( $hash_statement );
310
  }
311
 
312
+ // SQL to add index for download_log
313
+ $add_index = "ALTER TABLE {$wpdb->download_log} ADD INDEX download_count (version_id);";
314
+ $wpdb->query( $add_index );
315
+ // Keep transient deletion here, we are using it to check if the upgrade is total or partial.
316
+ delete_transient( 'dlm_upgrade_type' );
317
+ wp_send_json( array( 'success' => true ) );
318
+ exit;
319
  }
320
 
321
  /**
322
  * Check if DB migrated or not
323
  *
324
  * @return bool
325
+ * @since 4.6.0
326
  */
327
  public static function check_if_migrated() {
328
 
341
  /**
342
  * The new table update functionality
343
  *
344
+ * @since 4.6.0
345
  */
346
  public function update_log_table_db() {
347
 
348
  wp_verify_nonce( $_POST['nonce'], 'dlm_db_log_nonce' );
349
 
350
  global $wpdb;
351
+ $upgrade_type = get_transient( 'dlm_upgrade_type' );
352
 
353
  $limit = 10000;
354
 
356
 
357
  $sql_limit = "LIMIT {$offset},{$limit}";
358
 
359
+ $items = array();
360
+ $table_1 = "{$wpdb->download_log}";
361
+ $able_2 = "{$wpdb->posts}";
362
+ // Table that contains downlaod counts about each Download and their versions. Used for performance issues introduced in version 4.6.0 of the plugin.
363
+ $downloads_table = "{$wpdb->dlm_downloads}";
364
+ // If at this point the table does not exist, we need to create it.
365
+ if ( ! DLM_Utils::table_checker( $wpdb->dlm_downloads ) ) {
366
+ $charset_collate = $wpdb->get_charset_collate();
367
+ $sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->dlm_downloads}` (
368
+ ID bigint(20) NOT NULL auto_increment,
369
+ download_id bigint(20) NOT NULL,
370
+ download_count bigint(20) NOT NULL,
371
+ download_versions varchar(200) NOT NULL,
372
+ PRIMARY KEY (`ID`))
373
+ ENGINE = InnoDB $charset_collate;";
374
 
375
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
376
+ dbDelta( $sql );
 
 
 
 
 
 
377
  }
378
+ // Check if data has been introduced into table and update it, else we need to populate it.
379
+ $data = $wpdb->get_results( $wpdb->prepare( "SELECT dlm_log.download_id as `ID`, dlm_log.version_id as `version`, DATE_FORMAT(dlm_log.download_date, '%%Y-%%m-%%d') AS `date`, dlm_log.download_status as `status`, dlm_posts.post_title AS `title` FROM {$table_1} dlm_log LEFT JOIN {$able_2} dlm_posts ON dlm_log.download_id = dlm_posts.ID WHERE 1=1 {$sql_limit}" ), ARRAY_A );
380
 
381
+ // Create empty array of downloads. Will be used to add to the table as a bulk insert and not each row at a time.
382
+ // This will improve performance.
383
+ $downloads = array();
384
+ // This should not be a problem as the number of entries would be the number of existing downloads.
385
+ $saved_downloads = $wpdb->get_results( "SELECT * FROM {$downloads_table};", ARRAY_A );
386
+ $download_id_column = array_column( $saved_downloads,'download_id' );
387
+ $looped = array();
 
388
 
389
+ foreach ( $data as $row ) {
390
+ // Only add non-failed attempts to the table.
391
+ if ( 'failed' !== $row['status'] ) {
392
+ list( $loop_key, $download ) = $this->create_downloads( $row, $downloads, $download_id_column, $saved_downloads, $looped );
393
+ $downloads[ $row['ID'] ] = $download;
394
 
395
+ if ( false !== $loop_key ) {
396
+ $looped[] = $loop_key;
397
+ }
398
+ }
399
+ // Only do this if we need to recreate the dlm_reports_log table also.
400
+ if ( 'total' === $upgrade_type ) {
401
+ $item = $this->create_dates( $row, $items );
402
+ if ( is_array( $item ) ) {
403
+ $items[ $row['date'] ][ $row['ID'] ] = $item;
404
+ } else {
405
+ $items[ $row['date'] ][ $row['ID'] ]['downloads'] = $item;
406
  }
 
 
 
 
 
 
407
  }
408
  }
409
+ // Import Downloads into new table.
410
+ if ( ! empty( $downloads ) ) {
411
+ $this->import_downloads( $downloads );
412
+ }
413
+ // Import Report Dates into new table.
414
+ if ( 'total' === $upgrade_type ) {
415
+ $this->import_dates( $items );
416
+ }
417
  set_transient( 'dlm_db_upgrade_offset', absint( $_POST['offset'] ) );
 
418
  // We save the previous so that we make sure all the entries from that range will be saved.
419
  wp_send_json( $offset );
420
  exit;
430
  wp_verify_nonce( $_POST['nonce'], 'dlm_db_log_nonce' );
431
 
432
  if ( ! isset( $_POST['offset'] ) ) {
 
433
  // We need the previous set offset
434
  wp_send_json_error();
435
  exit;
436
  }
437
 
438
  global $wpdb;
439
+ $downloads_table = "{$wpdb->dlm_downloads}";
440
+ $limit = 10000;
441
+ $offset = ( isset( $_POST['offset'] ) ) ? $limit * absint( $_POST['offset'] ) : 0;
442
+ $sql_limit = "LIMIT {$offset},{$limit}";
443
+ $items = array();
444
+ $table_1 = "{$wpdb->download_log}";
445
+ $able_2 = "{$wpdb->prefix}posts";
446
+
447
+ $data = $wpdb->get_results( $wpdb->prepare( "SELECT dlm_log.download_id as `ID`, dlm_log.version_id as `version`, DATE_FORMAT(dlm_log.download_date, '%%Y-%%m-%%d') AS `date`, dlm_log.download_status as `status`, dlm_posts.post_title AS `title` FROM {$table_1} dlm_log LEFT JOIN {$able_2} dlm_posts ON dlm_log.download_id = dlm_posts.ID WHERE 1=1 {$sql_limit}" ), ARRAY_A );
448
+
449
+ // Create empty array of downloads. Will be used to add to the table as a bulk insert and not each row at a time.
450
+ // This will improve performance.
451
+ $downloads = array();
452
+ // This should not be a problem as the number of entries would be the number of existing downloads.
453
+ $saved_downloads = $wpdb->get_results( "SELECT * FROM {$downloads_table};", ARRAY_A );
454
+ $download_id_column = array_column( $saved_downloads, 'download_id' );
455
+ $looped = array();
456
 
457
  foreach ( $data as $row ) {
458
 
459
+ if ( 'failed' !== $row['status'] ) {
460
+ list( $loop_key, $download ) = $this->create_downloads( $row, $downloads, $download_id_column, $saved_downloads, $looped );
461
+ $downloads[ $row['ID'] ] = $download;
462
+ if ( false !== $loop_key ) {
463
+ $looped[] = $loop_key;
464
+ }
465
+ }
466
+
467
+ if ( 'total' === get_transient( 'dlm_upgrade_type' ) ) {
468
+ $item = $this->create_dates( $row, $items );
469
+ if ( is_array( $item ) ) {
470
+ $items[ $row['date'] ][ $row['ID'] ] = $item;
471
+ } else {
472
+ $items[ $row['date'] ][ $row['ID'] ]['downloads'] = $item;
473
+ }
474
  }
475
  }
476
 
477
+ // Clear offset Downloads.
478
+ if ( ! empty( $downloads ) ) {
479
+ $this->clear_downloads( $downloads );
480
+ }
481
+ // Clear offset Report Dates
482
+ if ( 'total' === get_transient( 'dlm_upgrade_type' ) ) {
483
+ foreach ( $items as $key => $log ) {
484
 
485
+ $table = "{$wpdb->dlm_reports}";
486
 
487
+ $sql_check = "SELECT * FROM $table WHERE date = %s;";
488
+ $sql_update = "UPDATE $table dlm SET dlm.download_ids = %s WHERE dlm.date = %s";
489
+ $check = $wpdb->get_results( $wpdb->prepare( $sql_check, $key ), ARRAY_A );
490
 
491
+ if ( null !== $check && ! empty( $check ) ) {
492
 
493
+ $downloads = json_decode( $check[0]['download_ids'], ARRAY_A );
494
 
495
+ foreach ( $log as $item_key => $item ) {
496
 
497
+ if ( isset( $downloads[ $item_key ] ) ) {
498
+ $downloads[ $item_key ]['downloads'] = $downloads[ $item_key ]['downloads'] - $item['downloads'];
499
+ }
500
  }
 
501
 
502
+ $wpdb->query( $wpdb->prepare( $sql_update, wp_json_encode( $downloads ), $key ) );
503
 
504
+ }
505
  }
506
  }
507
 
512
  /**
513
  * Add the DB Upgrader notice
514
  *
515
+ * @since 4.6.0
516
  */
517
  public function add_db_update_notice() {
518
 
524
  <div class="inside">
525
  <div class="main">
526
  <img class="dlm-notice-logo" src="data:image/png;base64,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">
527
+ <h4><?php echo wp_kses_post( __('Hello there! We made some changes on how Download Monitor\'s data is structured. Please <a href="#" class="dlm-db-upgrade-link">click here</a> to upgrade your database', 'download-monitor' ) ); ?></h4>
528
  <button id="dlm-upgrade-db" class="button button-primary">
529
  <?php
530
  // If the transient is present it means that this is a Resume Upgrade request
546
  /**
547
  * Enqueue the DB Upgrader scripts
548
  *
549
+ * @since 4.6.0
550
  */
551
  public function enqueue_db_upgrader_scripts() {
552
 
558
  wp_enqueue_style( 'dlm-db-upgrade-style', download_monitor()->get_plugin_url() . '/assets/css/db-upgrader.min.css', array(), '4.4.7' );
559
  wp_enqueue_style( 'jquery-ui-style', download_monitor()->get_plugin_url() . '/assets/css/jquery-ui.min.css', array(), DLM_VERSION );
560
  }
561
+
562
+ /**
563
+ * Import downloads in upgrader. Imports data to new {prefix}dlm_downloads table.
564
+ *
565
+ * @param $downloads
566
+ *
567
+ * @return void
568
+ * @since 4.7.0
569
+ */
570
+ public function import_downloads( $downloads ) {
571
+ global $wpdb;
572
+ $downloads_table = "{$wpdb->dlm_downloads}";
573
+ // The queries we need to make so that we insert each download as a row.
574
+ $check_for_downloads = "SELECT * FROM {$downloads_table} WHERE download_id = %s;";
575
+ $downloads_insert = "INSERT INTO {$downloads_table} (download_id,download_count,download_versions) VALUES ( %s , %s, %s );";
576
+ $downloads_update = "UPDATE {$downloads_table} dlm SET dlm.download_count = %s, dlm.download_versions = %s WHERE dlm.download_id = %s";
577
+
578
+ if ( ! empty( $downloads ) ) {
579
+ foreach ( $downloads as $key => $dlm ) {
580
+ $check = $wpdb->get_results( $wpdb->prepare( $check_for_downloads, $key ), ARRAY_A );
581
+ if ( ! empty( $check ) ) {
582
+ $wpdb->query( $wpdb->prepare( $downloads_update, $dlm['download_count'], $dlm['download_versions'], $key ) );
583
+ } else {
584
+ $wpdb->query( $wpdb->prepare( $downloads_insert, $key, $dlm['download_count'], $dlm['download_versions'] ) );
585
+ }
586
+ }
587
+ }
588
+ }
589
+
590
+ /**
591
+ * Clear created downloads
592
+ *
593
+ * @param $downloads
594
+ *
595
+ * @return void
596
+ * @since 4.7.0
597
+ */
598
+ public function clear_downloads( $downloads ) {
599
+ global $wpdb;
600
+ $downloads_table = "{$wpdb->dlm_downloads}";
601
+ // The queries we need to make so that we insert each download as a row.
602
+ $check_for_downloads = "SELECT * FROM {$downloads_table} WHERE download_id = %s;";
603
+ $downloads_update = "UPDATE {$downloads_table} dlm SET dlm.download_count = %s, dlm.download_versions = %s WHERE dlm.download_id = %s";
604
+
605
+ if ( ! empty( $downloads ) ) {
606
+ foreach ( $downloads as $key => $dlm ) {
607
+ $check = $wpdb->get_results( $wpdb->prepare( $check_for_downloads, $key ), ARRAY_A );
608
+ if ( ! empty( $check ) ) {
609
+ $saved_download = $check[0];
610
+ $download_count = absint( $saved_download['download_count'] ) - absint( $dlm['download_count'] );
611
+ $saved_versions = json_decode( $saved_download['download_versions'], true );
612
+ $current_versions = json_decode( $dlm['download_versions'], true );
613
+ foreach ( $saved_versions as $id => $count ) {
614
+ if ( isset( $current_versions[ $id ] ) ) {
615
+ $saved_versions[ $id ] = absint( $count ) - absint( $current_versions[ $id ] );
616
+ }
617
+ }
618
+ $wpdb->query( $wpdb->prepare( $downloads_update, $download_count, json_encode( $saved_versions ), $key ) );
619
+ }
620
+ }
621
+ }
622
+ }
623
+
624
+ /**
625
+ * Import data used for Reports chart. Adds data to new table {prefix}dlm_reports_log
626
+ *
627
+ * @param $items
628
+ *
629
+ * @return void
630
+ * @since 4.7.0
631
+ */
632
+ public function import_dates( $items ){
633
+ global $wpdb;
634
+
635
+ foreach ( $items as $key => $log ) {
636
+
637
+ $table = "{$wpdb->dlm_reports}";
638
+
639
+ $sql_check = "SELECT * FROM {$table} WHERE date = %s;";
640
+ $sql_insert = "INSERT INTO {$table} (date,download_ids) VALUES ( %s , %s );";
641
+ $sql_update = "UPDATE {$table} dlm SET dlm.download_ids = %s WHERE dlm.date = %s";
642
+ $check = $wpdb->get_results( $wpdb->prepare( $sql_check, $key ), ARRAY_A );
643
+
644
+ if ( null !== $check && ! empty( $check ) ) {
645
+
646
+ $downloads = json_decode( $check[0]['download_ids'], ARRAY_A );
647
+
648
+ foreach ( $log as $item_key => $item ) {
649
+ if ( isset( $downloads[ $item_key ] ) ) {
650
+ $downloads[ $item_key ]['downloads'] = $downloads[ $item_key ]['downloads'] + $item['downloads'];
651
+ unset( $downloads[ $item_key ]['date'] );
652
+ } else {
653
+ $downloads[ $item_key ] = array(
654
+ 'downloads' => $item['downloads'],
655
+ 'title' => $item['title'],
656
+ );
657
+ }
658
+ }
659
+
660
+ $wpdb->query( $wpdb->prepare( $sql_update, wp_json_encode( $downloads ), $key ) );
661
+
662
+ } else {
663
+
664
+ $wpdb->query( $wpdb->prepare( $sql_insert, $key, wp_json_encode( $log ) ) );
665
+ }
666
+ }
667
+ }
668
+
669
+ /**
670
+ * Check what type of upgrade we need
671
+ *
672
+ * @since 4.7.0
673
+ */
674
+ public function check_upgrade_type() {
675
+ global $wpdb;
676
+ $transient = 'dlm_upgrade_type';
677
+ if ( ! DLM_Utils::table_checker( $wpdb->dlm_downloads ) ) {
678
+ set_transient( $transient, 'partial', 7 * DAY_IN_SECONDS );
679
+ if ( ! DLM_Utils::table_checker( $wpdb->dlm_reports ) ) {
680
+ set_transient( $transient, 'total', 7 * DAY_IN_SECONDS );
681
+ }
682
+ }
683
+ }
684
+
685
+ /**
686
+ * Create upgrader downloads
687
+ *
688
+ * @param $row
689
+ * @param $downloads
690
+ * @param array $download_id_column
691
+ * @param array $saved_downloads
692
+ * @param array $looped
693
+ *
694
+ * @return array
695
+ * @since 4.7.0
696
+ */
697
+ public function create_downloads( $row, $downloads, $download_id_column = array(), $saved_downloads = array(), $looped = array() ) {
698
+
699
+ $download_versions = array();
700
+ $download_id = $row['ID'];
701
+ $version_id = $row['version'];
702
+ $download_count = 1;
703
+ $existing_versions = array(
704
+ $version_id => 1,
705
+ );
706
+ $looped_key = false;
707
+
708
+ // If download already exists in $downloads means we looped through, and we should take into consideration the existing data.
709
+ if ( isset( $downloads[ $download_id ] ) ) {
710
+ $existing_versions = json_decode( $downloads[ $download_id ]['download_versions'], true );
711
+ $download_count = absint( $downloads[ $download_id ]['download_count'] ) + 1;
712
+ if ( isset( $existing_versions[ $version_id ] ) ) {
713
+ $existing_versions[ $version_id ] = absint( $existing_versions[ $version_id ] ) + 1;
714
+ } else {
715
+ $existing_versions = array(
716
+ $version_id => 1,
717
+ );
718
+ }
719
+ }
720
+
721
+ // IF the download does not exist in the table, we need to insert it, else we need to update it.
722
+ if ( ! empty( $saved_downloads ) ) {
723
+ // Search in a multidimensional array if download_id exists.
724
+ $key = array_search( $download_id, $download_id_column );
725
+ // We should only search the saved downloads once, otherwise it will falsely add data.
726
+ if ( false !== $key && ! in_array( $key, $looped ) ) {
727
+ $looped_key = $key;
728
+ $download = $saved_downloads[ $key ];
729
+ $download_versions = ! empty( $download['download_versions'] ) ? json_decode( $download['download_versions'], true ) : array();
730
+ $download_count = absint( $download['download_count'] ) + absint( $download_count );
731
+
732
+ if ( isset( $download_versions[ $version_id ] ) ) {
733
+ $download_versions[ $version_id ] = absint( $download_versions[ $version_id ] ) + absint( $existing_versions[ $version_id ] );
734
+ } else {
735
+ $download_versions[ $version_id ] = absint( $existing_versions[ $version_id ] );
736
+ }
737
+ }
738
+ }
739
+
740
+ if ( empty( $download_versions ) ) {
741
+ $download_versions = $existing_versions;
742
+ }
743
+
744
+ $download = array(
745
+ 'download_id' => $download_id,
746
+ 'download_count' => $download_count,
747
+ 'download_versions' => wp_json_encode( $download_versions )
748
+ );
749
+
750
+ return array(
751
+ $looped_key,
752
+ $download
753
+ );
754
+ }
755
+
756
+ /**
757
+ * Create upgrader dates.
758
+ *
759
+ * @param $row array Current row of the query.
760
+ * @param $items array Array of items parsed.
761
+ *
762
+ * @return array|int
763
+ * @since 4.7.0
764
+ */
765
+ public function create_dates( $row, $items ) {
766
+ if ( ! isset( $items[ $row['date'] ][ $row['ID'] ] ) ) {
767
+ return array(
768
+ 'downloads' => 1,
769
+ 'title' => $row['title'],
770
+ );
771
+ } else {
772
+ return absint( $items[ $row['date'] ][ $row['ID'] ]['downloads'] ) + 1;
773
+ }
774
+ }
775
  }
776
  }
src/DLM.php CHANGED
@@ -70,8 +70,10 @@ class WP_DLM {
70
 
71
  // Table for Download Infos.
72
  $wpdb->download_log = "{$wpdb->prefix}download_log";
73
- // New Table for logs.
74
  $wpdb->dlm_reports = "{$wpdb->prefix}dlm_reports_log";
 
 
75
 
76
  // Setup admin classes.
77
  if ( is_admin() ) {
70
 
71
  // Table for Download Infos.
72
  $wpdb->download_log = "{$wpdb->prefix}download_log";
73
+ // New Table for reports.
74
  $wpdb->dlm_reports = "{$wpdb->prefix}dlm_reports_log";
75
+ // New Table for individual Downloads.
76
+ $wpdb->dlm_downloads = "{$wpdb->prefix}dlm_downloads";
77
 
78
  // Setup admin classes.
79
  if ( is_admin() ) {
src/Download/WordPressDownloadRepository.php CHANGED
@@ -86,8 +86,8 @@ class DLM_WordPress_Download_Repository implements DLM_Download_Repository {
86
  global $wpdb;
87
  $download_count = 0;
88
  // Check to see if the table exists first.
89
- if ( DLM_Utils::table_checker( $wpdb->download_log ) ) {
90
- $download_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`ID`) FROM {$wpdb->download_log} WHERE download_id = %s AND {$wpdb->download_log}.download_status IN ( 'completed', 'redirected' );", $download_id ) );
91
  }
92
 
93
  return apply_filters( 'dlm_add_meta_download_count', $download_count, $download_id );
@@ -363,12 +363,6 @@ class DLM_WordPress_Download_Repository implements DLM_Download_Repository {
363
  $download->set_featured( ( 'yes' === get_post_meta( $post->ID, '_featured', true ) ) );
364
  $download->set_members_only( ( 'yes' === get_post_meta( $post->ID, '_members_only', true ) ) );
365
  $download->set_download_count( absint( $this->retrieve_download_count( $post->ID ) ) );
366
- $download->set_total_download_count( absint( $this->retrieve_total_download_count( $post->ID ) ) );
367
- $download->set_redirected_downloads( absint( $this->retrieve_redirected_download_count( $post->ID ) ) );
368
- $download->set_completed_downloads( absint( $this->retrieve_completed_download_count( $post->ID ) ) );
369
- $download->set_failed_downloads( absint( $this->retrieve_failed_download_count( $post->ID ) ) );
370
- $download->set_logged_in_downloads( absint( $this->retrieve_logged_in_downloads( $post->ID ) ) );
371
- $download->set_non_logged_in_downloads( absint( $this->retrieve_non_logged_in_downloads( $post->ID ) ) );
372
 
373
  // This is added for backwards compatibility but will be removed in a later version!
374
  $download->post = $post;
86
  global $wpdb;
87
  $download_count = 0;
88
  // Check to see if the table exists first.
89
+ if ( DLM_Utils::table_checker( $wpdb->dlm_downloads ) ) {
90
+ $download_count = $wpdb->get_var( $wpdb->prepare( "SELECT download.download_count FROM {$wpdb->dlm_downloads} as download WHERE download_id = %s;", $download_id ) );
91
  }
92
 
93
  return apply_filters( 'dlm_add_meta_download_count', $download_count, $download_id );
363
  $download->set_featured( ( 'yes' === get_post_meta( $post->ID, '_featured', true ) ) );
364
  $download->set_members_only( ( 'yes' === get_post_meta( $post->ID, '_members_only', true ) ) );
365
  $download->set_download_count( absint( $this->retrieve_download_count( $post->ID ) ) );
 
 
 
 
 
 
366
 
367
  // This is added for backwards compatibility but will be removed in a later version!
368
  $download->post = $post;
src/DownloadHandler.php CHANGED
@@ -602,16 +602,11 @@ class DLM_Download_Handler {
602
  $range = false;
603
  }
604
 
605
- // Add our file contents to the output buffer, so we can set the cookie for the 60 seconds download.
606
- ob_start();
607
- $this->readfile_chunked( $file_path, false, $range );
608
- $contents = ob_get_clean();
609
-
610
- if ( $contents ) {
611
  if ( ! $this->check_for_xhr() ) {
612
  $this->dlm_logging->log( $download, $version, 'completed' );
613
  }
614
- echo $contents;
615
  } elseif ( $remote_file ) {
616
  // Redirect - we can't track if this completes or not.
617
  if ( $this->check_for_xhr() ) {
602
  $range = false;
603
  }
604
 
605
+ // Adding contents to an object will trigger error on big files.
606
+ if ( $this->readfile_chunked( $file_path, false, $range ) ) {
 
 
 
 
607
  if ( ! $this->check_for_xhr() ) {
608
  $this->dlm_logging->log( $download, $version, 'completed' );
609
  }
 
610
  } elseif ( $remote_file ) {
611
  // Redirect - we can't track if this completes or not.
612
  if ( $this->check_for_xhr() ) {
src/Installer.php CHANGED
@@ -228,7 +228,7 @@ class DLM_Installer {
228
 
229
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
230
 
231
- $dlm_tables = '
232
  CREATE TABLE `' . $wpdb->prefix . "download_log` (
233
  ID bigint(20) NOT NULL auto_increment,
234
  user_id bigint(20) NOT NULL,
@@ -249,15 +249,25 @@ class DLM_Installer {
249
  ) $collate;
250
  ";
251
 
252
- $sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}dlm_reports_log` (
253
  `date` DATE NOT NULL,
254
  `download_ids` longtext NULL,
255
  `revenue` longtext NULL,
256
  `refunds` longtext NULL,
257
  PRIMARY KEY (`date`)) $collate;";
258
 
259
- dbDelta( $dlm_tables );
260
- dbDelta( $sql );
 
 
 
 
 
 
 
 
 
 
261
 
262
  // install shop tables.
263
  $this->create_shop_tables();
228
 
229
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
230
 
231
+ $dlm_log = '
232
  CREATE TABLE `' . $wpdb->prefix . "download_log` (
233
  ID bigint(20) NOT NULL auto_increment,
234
  user_id bigint(20) NOT NULL,
249
  ) $collate;
250
  ";
251
 
252
+ $dlm_reports = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}dlm_reports_log` (
253
  `date` DATE NOT NULL,
254
  `download_ids` longtext NULL,
255
  `revenue` longtext NULL,
256
  `refunds` longtext NULL,
257
  PRIMARY KEY (`date`)) $collate;";
258
 
259
+ $dlm_downloads = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}dlm_downloads` (
260
+ ID bigint(20) NOT NULL auto_increment,
261
+ download_id bigint(20) NOT NULL,
262
+ download_count bigint(20) NOT NULL,
263
+ download_versions varchar(200) NOT NULL,
264
+ PRIMARY KEY (`ID`))
265
+ ENGINE = InnoDB $collate;";
266
+
267
+
268
+ dbDelta( $dlm_log );
269
+ dbDelta( $dlm_reports );
270
+ dbDelta( $dlm_downloads );
271
 
272
  // install shop tables.
273
  $this->create_shop_tables();
src/Logs/LogItem.php CHANGED
@@ -321,6 +321,7 @@ class DLM_Log_Item {
321
  }
322
 
323
  $download_date = current_time( 'mysql', false );
 
324
 
325
  // Add filters for download_log column entries, so in case the upgrader failed we can still log the download.
326
  /**
@@ -337,7 +338,7 @@ class DLM_Log_Item {
337
  'version_id' => absint( $this->get_version_id() ),
338
  'version' => $this->get_version(),
339
  'download_date' => sanitize_text_field( $download_date ),
340
- 'download_status' => $this->get_download_status(),
341
  'download_status_message' => $this->get_download_status_message(),
342
  'meta_data' => $meta_data
343
  ),
@@ -352,7 +353,7 @@ class DLM_Log_Item {
352
  array(
353
  '%d',
354
  '%s',
355
- '%d',
356
  '%d',
357
  '%s',
358
  '%s',
@@ -369,6 +370,32 @@ class DLM_Log_Item {
369
  $log_entries,
370
  $log_values
371
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
 
373
  do_action( 'dlm_increase_download_count', $this );
374
  }
321
  }
322
 
323
  $download_date = current_time( 'mysql', false );
324
+ $download_status = $this->get_download_status();
325
 
326
  // Add filters for download_log column entries, so in case the upgrader failed we can still log the download.
327
  /**
338
  'version_id' => absint( $this->get_version_id() ),
339
  'version' => $this->get_version(),
340
  'download_date' => sanitize_text_field( $download_date ),
341
+ 'download_status' => $download_status,
342
  'download_status_message' => $this->get_download_status_message(),
343
  'meta_data' => $meta_data
344
  ),
353
  array(
354
  '%d',
355
  '%s',
356
+ '%s',
357
  '%d',
358
  '%s',
359
  '%s',
370
  $log_entries,
371
  $log_values
372
  );
373
+ // Let's check if table exists.
374
+ if ( DLM_Utils::table_checker( $wpdb->dlm_downloads ) && 'failed' !== $download_status ) {
375
+ // Table exists, now log new download into table. This is used for faster download counts, performance issues introduced in version 4.6.0 of plugin
376
+ $download_id = absint( $this->get_download_id() );
377
+ $version_id = absint( $this->get_version_id() );
378
+ $downloads_table = "{$wpdb->dlm_downloads}";
379
+ $check_for_downloads = "SELECT * FROM {$downloads_table} WHERE download_id = %s;";
380
+ $downloads_insert = "INSERT INTO {$downloads_table} (download_id,download_count,download_versions) VALUES ( %s , %s, %s );";
381
+ $downloads_update = "UPDATE {$downloads_table} dlm SET dlm.download_count = dlm.download_count + 1, dlm.download_versions = %s WHERE dlm.download_id = %s";
382
+ $check = $wpdb->get_results( $wpdb->prepare( $check_for_downloads, $download_id ), ARRAY_A );
383
+ $download_versions = array();
384
+ // Check if there is anything there, else insert new row.
385
+ if ( null !== $check && ! empty( $check ) ) {
386
+ // If meta exists update it, lese insert it.
387
+ $download_versions = ! empty( $check[0]['download_versions'] ) ? json_decode( $check[0]['download_versions'], true ) : array();
388
+ if ( isset( $download_versions[ $version_id ] ) ) {
389
+ $download_versions[ $version_id ] = absint( $download_versions[ $version_id ] ) + 1;
390
+ } else {
391
+ $download_versions[ $version_id ] = 1;
392
+ }
393
+ $wpdb->query( $wpdb->prepare( $downloads_update, json_encode( $download_versions ), $download_id ) );
394
+ } else {
395
+ $download_versions[ $version_id ] = 1;
396
+ $wpdb->query( $wpdb->prepare( $downloads_insert, $download_id, 1, json_encode( $download_versions ) ) );
397
+ }
398
+ }
399
 
400
  do_action( 'dlm_increase_download_count', $this );
401
  }
src/Shortcodes.php CHANGED
@@ -39,8 +39,9 @@ class DLM_Shortcodes {
39
 
40
  $total = false;
41
 
42
- if ( DLM_Utils::table_checker( $wpdb->download_log ) && DLM_Logging::is_logging_enabled() ) {
43
- $total = $wpdb->get_var( "SELECT COUNT('ID') FROM $wpdb->download_log WHERE version_id != 0 AND download_status IN ( 'completed','redirected' );" );
 
44
  } else {
45
 
46
  if ( ! DLM_Logging::is_logging_enabled() ) {
39
 
40
  $total = false;
41
 
42
+ if ( DLM_Utils::table_checker( $wpdb->dlm_downloads ) && DLM_Logging::is_logging_enabled() ) {
43
+ $total = $wpdb->get_results( "SELECT download.download_count FROM {$wpdb->dlm_downloads} as download;",ARRAY_A );
44
+ $total = array_sum( array_column( $total, 'download_count' ) );
45
  } else {
46
 
47
  if ( ! DLM_Logging::is_logging_enabled() ) {
src/Version/WordPressVersionRepository.php CHANGED
@@ -78,18 +78,27 @@ class DLM_WordPress_Version_Repository implements DLM_Version_Repository {
78
  /**
79
  * Retreieve the version download count
80
  *
81
- * @param mixed $version_id
 
82
  * @return string
83
  */
84
  public function retrieve_version_download_count( $version_id ) {
85
  global $wpdb;
86
- $download_count = 0;
 
87
  // Check to see if the table exists first.
88
- if ( DLM_Utils::table_checker( $wpdb->download_log ) ) {
89
- $download_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM {$wpdb->download_log} WHERE version_id = %s AND download_status IN ( 'completed','redirected' )", $version_id ) );
 
 
 
 
 
 
 
90
  }
91
 
92
- return apply_filters( 'dlm_add_version_meta_download_count', $download_count, $version_id );
93
  }
94
 
95
  /**
78
  /**
79
  * Retreieve the version download count
80
  *
81
+ * @param mixed $version_id
82
+ *
83
  * @return string
84
  */
85
  public function retrieve_version_download_count( $version_id ) {
86
  global $wpdb;
87
+ $version_count = 0;
88
+ $download_id = get_post_parent( $version_id )->ID;
89
  // Check to see if the table exists first.
90
+ if ( DLM_Utils::table_checker( $wpdb->dlm_downloads ) ) {
91
+ // Data in the table are based on Download and it's meta, so we need to get the Download to find the version count.
92
+ $download_count = $wpdb->get_results( $wpdb->prepare( "SELECT download.download_versions FROM {$wpdb->dlm_downloads} download WHERE download_id = %s;", $download_id ), ARRAY_A );
93
+ // Version counts are present in the `download_versions` column of the table, as a json object, containing information for all versions.
94
+ $meta = ( ! empty( $download_count[0]['download_versions'] ) ) ? json_decode( $download_count[0]['download_versions'], true ) : array();
95
+ // Get the information for our current version.
96
+ if ( ! empty( $meta ) && isset( $meta[ $version_id ] ) ) {
97
+ $version_count = $meta[ $version_id ];
98
+ }
99
  }
100
 
101
+ return apply_filters( 'dlm_add_version_meta_download_count', $version_count, $version_id );
102
  }
103
 
104
  /**