From 32d110741d783f1086c9247ea5a7ddd7dc8faeac Mon Sep 17 00:00:00 2001 From: mgbaybay Date: Thu, 29 Aug 2024 01:54:04 +0800 Subject: [PATCH] Reports: Add MySql data grouping --- lib/Report/ProofOfPlay.php | 88 ++++++++++++++++++++++++++-- reports/proofofplay-report-form.twig | 48 +++++++++------ 2 files changed, 115 insertions(+), 21 deletions(-) diff --git a/lib/Report/ProofOfPlay.php b/lib/Report/ProofOfPlay.php index cef45eeed6..9b91fa2e82 100644 --- a/lib/Report/ProofOfPlay.php +++ b/lib/Report/ProofOfPlay.php @@ -324,6 +324,8 @@ public function getResults(SanitizerInterface $sanitizedParams) $exactTags = $sanitizedParams->getCheckbox('exactTags'); $operator = $sanitizedParams->getString('logicalOperator', ['default' => 'OR']); $parentCampaignId = $sanitizedParams->getInt('parentCampaignId'); + $groupBy = $sanitizedParams->getString('groupBy'); + $displayGroupIds = $sanitizedParams->getIntArray('displayGroupId', ['default' => []]); // Display filter. try { @@ -472,7 +474,9 @@ public function getResults(SanitizerInterface $sanitizedParams) $tags, $tagsType, $exactTags, - $operator + $operator, + $groupBy, + $displayGroupIds ); } @@ -505,6 +509,8 @@ public function getResults(SanitizerInterface $sanitizedParams) $entry['minStart'] = Carbon::createFromTimestamp($row['minStart'])->format(DateFormatHelper::getSystemFormat()); $entry['maxEnd'] = Carbon::createFromTimestamp($row['maxEnd'])->format(DateFormatHelper::getSystemFormat()); $entry['mediaId'] = $sanitizedRow->getInt('mediaId'); + $entry['displayGroup'] = $sanitizedRow->getString('displayGroup'); + $entry['displayGroupId'] = $sanitizedRow->getInt('displayGroupId'); $rows[] = $entry; } @@ -541,6 +547,8 @@ public function getResults(SanitizerInterface $sanitizedParams) * @param $tags string * @param $tagsType string * @param $exactTags mixed + * @param $groupBy string + * @param $displayGroupIds array * @return array[array result, date periodStart, date periodEnd, int count, int totalStats] */ private function getProofOfPlayReportMySql( @@ -555,7 +563,9 @@ private function getProofOfPlayReportMySql( $tags, $tagsType, $exactTags, - $logicalOperator + $logicalOperator, + $groupBy, + $displayGroupIds ) { $fromDt = $fromDt->format('U'); $toDt = $toDt->format('U'); @@ -585,6 +595,11 @@ private function getProofOfPlayReportMySql( stat.displayId '; + + if ($groupBy === 'displayGroup') { + $select .= ', displaydg.displayGroup, displaydg.displayGroupId '; + } + $body = ' FROM stat LEFT OUTER JOIN display @@ -615,6 +630,15 @@ private function getProofOfPlayReportMySql( } } + // Grouping Option + if ($groupBy === 'displayGroup') { + $body .= 'INNER JOIN `lkdisplaydg` AS linkdg + ON linkdg.DisplayID = display.displayid + INNER JOIN `displaygroup` AS displaydg + ON displaydg.displaygroupId = linkdg.displaygroupId + AND `displaydg`.isDisplaySpecific = 0 '; + } + $body .= ' WHERE stat.type <> \'displaydown\' AND stat.end > :fromDt AND stat.start < :toDt @@ -816,6 +840,11 @@ private function getProofOfPlayReportMySql( stat.displayId '; + // Group By displayGroup Filter + if ($groupBy === 'displayGroup') { + $body .= ', displaydg.displayGroupId'; + } + $order = ''; if ($columns != null) { $order = 'ORDER BY ' . implode(',', $columns); @@ -843,10 +872,17 @@ private function getProofOfPlayReportMySql( $entry['widgetId'] = $row['widgetId']; $entry['mediaId'] = $row['mediaId']; $entry['tag'] = $row['tag']; - + $entry['displayGroupId'] = $row['displayGroupId'] ?? ''; + $entry['displayGroup'] = $row['displayGroup'] ?? ''; $rows[] = $entry; } + if ($groupBy != '') { + $filterKey = $groupBy === 'tag' ? 'tag' : 'displayGroupId'; + + $rows = $this->getByDisplayGroup($rows, $filterKey, $displayGroupIds); + } + return [ 'periodStart' => Carbon::createFromTimestamp($fromDt)->format(DateFormatHelper::getSystemFormat()), 'periodEnd' => Carbon::createFromTimestamp($toDt)->format(DateFormatHelper::getSystemFormat()), @@ -901,6 +937,8 @@ private function getBodyForTagsType($tagsType, $exclude) :string * @param $tags string * @param $tagsType string * @param $exactTags mixed + * @param $groupBy string + * @param $displayGroupIds array * @return array[array result, date periodStart, date periodEnd, int count, int totalStats] * @throws InvalidArgumentException * @throws \Xibo\Support\Exception\GeneralException @@ -917,7 +955,9 @@ private function getProofOfPlayReportMongoDb( $tags, $tagsType, $exactTags, - $operator + $operator, + $groupBy, + $displayGroupIds ) { $fromDt = new UTCDateTime($filterFromDt->format('U')*1000); $toDt = new UTCDateTime($filterToDt->format('U')*1000); @@ -1157,4 +1197,44 @@ private function getProofOfPlayReportMongoDb( 'count' => count($rows) ]; } + + /** + * Get the accumulated value by display groups + * @param array $rows + * @param string $type + * @param array $displayIds + * @return array + */ + private function getByDisplayGroup(array $rows, string $type, array $displayIds = []) : array + { + $data = []; + $groups = []; + + // Get the accumulated values by displayGroupId + foreach ($rows as $row) { + $groupId = $row[$type]; + + if (isset($groups[$groupId])) { + $groups[$groupId]['duration'] += $row['duration']; + $groups[$groupId]['numberPlays'] += $row['numberPlays']; + $groups[$groupId]['count'] += 1; + } else if ($row[$type] != '') { + $row['count'] = 1; + $groups[$groupId] = $row; + } + } + + if ($type === 'tag') { + return $groups; + } + + // Get all display groups or selected display groups only + foreach ($groups as $group) { + if (!$displayIds || in_array($group['displayGroupId'], $displayIds)) { + $data[] = $group; + } + } + + return $data; + } } diff --git a/reports/proofofplay-report-form.twig b/reports/proofofplay-report-form.twig index 2ca83d0291..c44cd05277 100644 --- a/reports/proofofplay-report-form.twig +++ b/reports/proofofplay-report-form.twig @@ -229,7 +229,6 @@ {% trans "Display" %} {% trans "Display Group ID" %} {% trans "Display Group" %} - {% trans "Tag ID" %} {% trans "Campaign" %} {% trans "Layout ID" %} {% trans "Layout" %} @@ -264,7 +263,6 @@ - @@ -308,16 +306,16 @@ // Hide and show appropriate columns switch ($('select[name="groupBy"]').val()) { case 'displayGroup': - $(this.api().columns([1, 2, 5, 6, 7, 8, 9, 10, 11]).visible(false)); + $(this.api().columns([1, 2, 5, 6, 7, 8, 9, 10, 14, 15]).visible(false)); $(this.api().columns([3, 4]).visible(true)); break; case 'tag': - $(this.api().columns([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]).visible(false)); - $(this.api().columns([5]).visible(true)); + $(this.api().columns([1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15]).visible(false)); + $(this.api().columns([10]).visible(true)); break; default: - $(this.api().columns([3, 4, 5]).visible(false)); - $(this.api().columns([1, 2, 5, 6, 7, 8, 9, 10, 11]).visible(true)); + $(this.api().columns([3, 4]).visible(false)); + $(this.api().columns([1, 2, 5, 6, 7, 8, 9, 10, 14, 15]).visible(true)); } }, filter: false, @@ -329,7 +327,6 @@ {"data": "display"}, {"data": "displayGroupId"}, {"data": "displayGroup"}, - {"data": "tagId"}, {"data": "parentCampaign"}, {"data": "layoutId"}, {"data": "layout"}, @@ -373,28 +370,27 @@ {"data": "duration"}, {"data": "minStart"}, {"data": "maxEnd"} - ], footerCallback: function (row, data, start, end, display) { let api = this.api(); // Total over all pages - let totalNumberPlays = api.column(9).data().reduce(function (a, b) { + let totalNumberPlays = api.column(11).data().reduce(function (a, b) { return a + b; }, 0); - let totalDuration = api.column(11).data().reduce(function (a, b) { + let totalDuration = api.column(13).data().reduce(function (a, b) { return a + b; }, 0); - let totalNumberPlaysPage = api.column(9, { page: 'current'}).data().reduce(function (a, b) { + let totalNumberPlaysPage = api.column(11, { page: 'current'}).data().reduce(function (a, b) { return a + b; }, 0); - let totalDurationPage = api.column(11, { page: 'current'}).data().reduce(function (a, b) { + let totalDurationPage = api.column(13, { page: 'current'}).data().reduce(function (a, b) { return a + b; }, 0); // Update footer - $(api.column(9).footer()).html(totalNumberPlaysPage + ' (' + totalNumberPlays + ' total)'); - $(api.column(11).footer()).html(Math.floor(totalDurationPage) + ' (' + Math.floor(totalDuration) + ' total)'); + $(api.column(11).footer()).html(totalNumberPlaysPage + ' (' + totalNumberPlays + ' total)'); + $(api.column(13).footer()).html(Math.floor(totalDurationPage) + ' (' + Math.floor(totalDuration) + ' total)'); }, }); @@ -474,10 +470,10 @@ getData($dataTable.data().url); }); - // If we select a displayId we hide the display group filter + // If we select a displayId, we hide the display group filter $('#displayId').off('change').change( function() { - let displayId = $('#displayId').val(); + if (displayId) { $('select[name="displayGroupId[]"] option').remove(); $('select[name="displayGroupId[]"]').next(".select2-container").parent().hide(); @@ -490,6 +486,24 @@ } }); + // If we select a group by filter, we hide the display filter + $("select[name='groupBy']").on('change', function() { + let optionSelected = $(this).find("option:selected").val(); + + if (optionSelected === 'tag') { + $('select[name="displayGroupId[]"] option').remove(); + $('select[name="displayGroupId[]"]').next(".select2-container").parent().hide(); + } else if (optionSelected === 'displayGroup') { + $('select[name="groupBy"]').parent().show(); + } + + if (optionSelected !== '') { + $("select[name='displayId']").parent().hide(); + } else { + $("select[name='displayId']").parent().show(); + } + }); + // Hide / Show FromDt and ToDt function checkReportFilter(reportFilter) { if (reportFilter.val() === '' || reportFilter.val() === undefined) {