function groupingReportResultHtml(&$arParams, &$arResult, $level = 0, $arRowSet = array()) { $strHtml = ''; $total = array(); $arViewColumns =& $arResult['viewColumns']; $arData =& $arResult['data']; // static variables static $arGroups = array(); static $arColumns = array(); static $nGroups = 0; static $nColumns = 0; static $arValueTypes = array(); static $marginWidth = 20; // initialize static variables if ($level === 0) { foreach ($arViewColumns as $viewColumnIndex => $viewColumn) { if ($viewColumn['grouping']) { $arGroups[$nGroups++] = $viewColumnIndex; } else { $arColumns[$nColumns++] = $viewColumnIndex; } $arValueTypes[$viewColumnIndex] = getResultColumnDataType($viewColumn); } } $nRows = count($arRowSet); $bUseRowSet = $nRows > 0 ? true : false; if (!$bUseRowSet) { $nRows = count($arData); } if ($nGroups > 0) { // grouping table header if ($level === 0) { $bFirstGroup = true; $strHtml .= "\t" . '<table class="reports-grouping-table" cellpadding=2 cellspacing=0>' . PHP_EOL . "\t\t" . '<thead>' . PHP_EOL; foreach ($arGroups as $groupColumnIndex) { $strHtml .= "\t\t\t" . '<tr class="reports-grouping-table-head-row">' . PHP_EOL . "\t\t\t\t" . '<td>' . htmlspecialcharsbx($arViewColumns[$groupColumnIndex]['humanTitle']) . '</td>' . PHP_EOL; if ($bFirstGroup) { $bFirstGroup = false; foreach ($arColumns as $viewColumnIndex) { $strHtml .= "\t\t\t\t" . '<td style="text-align: center;"'; if ($nGroups > 1) { $strHtml .= ' rowspan="' . htmlspecialcharsbx($nGroups) . '"'; } $strHtml .= ' class="report-grouping-sort-column"'; $strHtml .= ' colId="' . $viewColumnIndex . '" defaultSort="' . $arViewColumns[$viewColumnIndex]['defaultSort'] . '">' . htmlspecialcharsbx($arViewColumns[$viewColumnIndex]['humanTitle']) . '</td>' . PHP_EOL; } } $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL; } $strHtml .= "\t\t" . '</thead>' . PHP_EOL; } if ($nRows > 0) { // table header separator if ($level === 0) { $strHtml .= "\t\t" . '<tbody>' . PHP_EOL . "\t\t\t" . '<tr class="reports-grouping-table-row-separator"><td></td></tr>' . PHP_EOL; } // init total if ($nColumns > 0) { foreach (array_keys($arColumns) as $columnIndex) { $total[$columnIndex] = null; } } if ($level < $nGroups) { // fill group arrays $arGroupValues = array(); $arGroupValuesIndexes = array(); $rowNumber = 0; $groupDataType = $arValueTypes[$arGroups[$level]]; $dataIndex = null; reset($arData); while ($rowNumber++ < $nRows) { // get index if ($bUseRowSet) { list(, $dataIndex) = each($arRowSet); } else { list($dataIndex, ) = each($arData); } // fill index and value of group $arGroupValuesIndexes[] = $dataIndex; $groupValue = $arData[$dataIndex][$arViewColumns[$arGroups[$level]]['resultName']]; if ($groupDataType === 'date' || $groupDataType === 'datetime') { $groupValue = MakeTimeStamp($groupValue, CSite::GetDateFormat('SHORT')); } // magic glue if (is_array($groupValue)) { $groupValue = join(' / ', $groupValue); } $arGroupValues[] = $groupValue; } // determine sort options $groupSortOption = SORT_STRING; $groupSortDirection = SORT_ASC; if (in_array($groupDataType, array('date', 'datetime', 'integer', 'float'))) { $groupSortOption = SORT_NUMERIC; } if ($arGroups[$level] == $arResult['sort_id']) { if ($arResult['sort_type'] != 'ASC') { $groupSortDirection = SORT_DESC; } } // sort group array_multisort($arGroupValues, $groupSortOption, $groupSortDirection, $arGroupValuesIndexes, SORT_NUMERIC, SORT_ASC); // recursive scan $prev = null; $newRowSet = array(); $nGroupValues = count($arGroupValues); $nSubRows = 0; for ($i = 0; $i < $nGroupValues; $i++) { $cur = $arGroupValues[$i]; if ($i == 0) { $prev = $cur; } $bLastValue = $nGroupValues - 1 == $i; if ($cur != $prev || $bLastValue) { $n = $bLastValue && $cur != $prev ? 2 : 1; while ($n-- > 0) { if ($bLastValue && $cur == $prev) { $newRowSet[] = $arGroupValuesIndexes[$i]; } $arGroupingResult = groupingReportResultHtml($arParams, $arResult, $level + 1, $newRowSet); $arSubTotal = $arGroupingResult['total']; $strSubHtml = $arGroupingResult['html']; unset($arGroupingResult); $newRowSet = array(); if (!$bLastValue) { $newRowSet[] = $arGroupValuesIndexes[$i]; } $prev = $cur; // show row $groupValueIndex = $bLastValue && $n === 0 ? $i : $i - 1; $groupValueKey = $arViewColumns[$arGroups[$level]]['resultName']; $groupValue = $arData[$arGroupValuesIndexes[$groupValueIndex]][$groupValueKey]; // magic glue if (is_array($groupValue)) { $groupValue = join(' / ', $groupValue); } if ($level == $nGroups - 1) { $rowClass = ' reports-grouping-data-row'; } else { $rowClass = ' reports-grouping-group-row'; } if (!empty($rowClass)) { $rowClass = ' class="' . ltrim($rowClass) . '"'; } $margin = $level > 0 ? ' style="margin-left: ' . $level * $marginWidth . 'px;"' : ''; /*$rowClass .= ' style="mso-outline-level:'.($level+1).'"';*/ $strHtml .= "\t\t\t" . '<tr' . $rowClass . '>' . PHP_EOL . "\t\t\t\t" . '<td><div' . $margin . '>' . $groupValue . '</div></td>' . PHP_EOL; foreach ($arSubTotal as $k => $subValue) { $cellStyle = ''; if ($arResult['settings']['red_neg_vals'] === true) { if (is_numeric($subValue) && $subValue < 0) { $cellStyle .= ' color: red;'; } } // cell align $colAlign = $arViewColumns[$arColumns[$k]]['align']; if ($colAlign === null) { if (CReport::isColumnPercentable($arViewColumns[$arColumns[$k]])) { $cellStyle .= ' text-align: right;'; } } else { if ($colAlign === 'right') { $cellStyle .= ' text-align: right;'; } } if (!empty($cellStyle)) { $cellStyle = ' style="' . ltrim($cellStyle) . '"'; } $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal']; if ($bGroupingSubtotal || $level == $nGroups - 1) { $finalSubValue = $subValue; if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) { // format subtotal value $subValueKey = $arViewColumns[$arColumns[$k]]['resultName']; call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalSubValue, 'cInfo' => &$arViewColumns[$arColumns[$k]])); } } else { $finalSubValue = ' '; } $strHtml .= "\t\t\t\t" . '<td' . $cellStyle . '>' . $finalSubValue . '</td>' . PHP_EOL; } $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL; $strHtml .= $strSubHtml; // total += subtotal if ($nColumns > 0) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { $columnDataType = $arValueTypes[$viewColumnIndex]; if ($columnDataType === 'integer' || $columnDataType === 'float') { if (is_string($arSubTotal[$columnIndex])) { $arSubTotal[$columnIndex] = str_replace(' ', '', $arSubTotal[$columnIndex]); } $total[$columnIndex] += $arSubTotal[$columnIndex]; } } $nSubRows++; } } // while ($n-- > 0) } else { $newRowSet[] = $arGroupValuesIndexes[$i]; } } // calculate average values if ($nSubRows > 1) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') { $total[$columnIndex] = $total[$columnIndex] / $nSubRows; } } } } else { if ($nColumns > 0) { $rowNumber = 0; while ($rowNumber++ < $nRows) { // get index if ($bUseRowSet) { list(, $dataIndex) = each($arRowSet); } else { list($dataIndex, ) = each($arData); } // total += values foreach ($arColumns as $columnIndex => $viewColumnIndex) { $columnDataType = $arValueTypes[$viewColumnIndex]; if ($nRows == 1) { $dataValueKey = $arViewColumns[$viewColumnIndex]['resultName']; $dataValue = $arData[$dataIndex][$dataValueKey]; if ($columnDataType === 'float' && is_string($dataValue)) { $dataValue = str_replace(' ', '', $dataValue); } $total[$columnIndex] = $dataValue; } else { if ($columnDataType === 'integer' || $columnDataType === 'float') { $dataValue = $arData[$dataIndex][$arViewColumns[$viewColumnIndex]['resultName']]; if (is_string($dataValue)) { $dataValue = str_replace(' ', '', $dataValue); } $total[$columnIndex] += $dataValue; } } } } // calculate average values if ($nRows > 1) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') { $total[$columnIndex] = $total[$columnIndex] / $nRows; } } } } } } // show total if ($level === 0) { if (count($total) > 0) { // show total check $bShowTotal = false; foreach ($total as $k => $v) { if ($arViewColumns[$arColumns[$k]]['grouping_subtotal']) { $bShowTotal = true; break; } } if ($bShowTotal) { $strHtml .= "\t\t\t" . '<tr class="reports-grouping-table-row-separator"><td></td></tr>' . PHP_EOL; $strHtml .= "\t\t\t" . '<tr class="reports-grouping-total-row">' . PHP_EOL . "\t\t\t\t" . '<td>' . htmlspecialcharsbx(GetMessage('REPORT_TOTAL')) . '</td>' . PHP_EOL; foreach ($total as $k => $v) { $cellStyle = ''; if ($arResult['settings']['red_neg_vals'] === true) { if (is_numeric($v) && $v < 0) { $cellStyle .= ' color: red;'; } } // cell align $colAlign = $arViewColumns[$arColumns[$k]]['align']; if ($colAlign === null) { if (CReport::isColumnPercentable($arViewColumns[$arColumns[$k]])) { $cellStyle = ' text-align: right;'; } } else { if ($colAlign === 'right') { $cellStyle = ' text-align: right;'; } } $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal']; if ($bGroupingSubtotal) { $finalTotalValue = $v; if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) { // format subtotal value $subValueKey = $arViewColumns[$arColumns[$k]]['resultName']; call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalTotalValue, 'cInfo' => &$arViewColumns[$arColumns[$k]])); } } else { $finalTotalValue = ' '; } if (!empty($cellStyle)) { $cellStyle = ' class="' . ltrim($cellStyle) . '"'; } $strHtml .= "\t\t\t\t" . '<td' . $cellStyle . '>' . $finalTotalValue . '</td>' . PHP_EOL; } $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL; } } $strHtml .= "\t\t" . '</tbody>' . PHP_EOL . "\t" . '</table>' . PHP_EOL; } } return array('total' => $total, 'html' => $strHtml); }
function groupingReportResultHtml(&$arParams, &$arResult, $level = 0, $arRowSet = array()) { $arReportData = array(); $total = array(); $arViewColumns =& $arResult['viewColumns']; $arData =& $arResult['data']; $finalRow = 0; $headerHtml = ''; // static variables static $arGroups = array(); static $arColumns = array(); static $nGroups = 0; static $nColumns = 0; static $arValueTypes = array(); // initialize static variables if ($level === 0) { foreach ($arViewColumns as $viewColumnIndex => $viewColumn) { if ($viewColumn['grouping']) { $arGroups[$nGroups++] = $viewColumnIndex; } else { $arColumns[$nColumns++] = $viewColumnIndex; } $arValueTypes[$viewColumnIndex] = getResultColumnDataType($viewColumn, $arResult['customColumnTypes']); } $headerHtml = getReportHeader($arGroups, $arResult); } $nRows = count($arRowSet); $bUseRowSet = $nRows > 0 ? true : false; if (!$bUseRowSet) { $nRows = count($arData); } if ($nGroups > 0) { if ($nRows > 0) { // init total if ($nColumns > 0) { foreach (array_keys($arColumns) as $columnIndex) { $total[$columnIndex] = null; } } if ($level < $nGroups) { // fill group arrays $arGroupValues = array(); $arGroupValuesIndexes = array(); $rowNumber = 0; $groupDataType = $arValueTypes[$arGroups[$level]]; $dataIndex = null; reset($arData); while ($rowNumber++ < $nRows) { // get index if ($bUseRowSet) { list(, $dataIndex) = each($arRowSet); } else { list($dataIndex, ) = each($arData); } // fill index and value of group $arGroupValuesIndexes[] = $dataIndex; $groupValue = $arData[$dataIndex][$arViewColumns[$arGroups[$level]]['resultName']]; if ($groupDataType === 'date' || $groupDataType === 'datetime') { $groupValue = MakeTimeStamp($groupValue, CSite::GetDateFormat('SHORT')); } // magic glue if (is_array($groupValue)) { $groupValue = join(' / ', $groupValue); } $arGroupValues[] = $groupValue; } // determine sort options $groupSortOption = SORT_STRING; $groupSortDirection = SORT_ASC; if (in_array($groupDataType, array('date', 'datetime', 'integer', 'float'))) { $groupSortOption = SORT_NUMERIC; } if ($arGroups[$level] == $arResult['sort_id']) { if ($arResult['sort_type'] != 'ASC') { $groupSortDirection = SORT_DESC; } } // sort group array_multisort($arGroupValues, $groupSortOption, $groupSortDirection, $arGroupValuesIndexes, SORT_NUMERIC, SORT_ASC); // recursive scan $prev = null; $newRowSet = array(); $nGroupValues = count($arGroupValues); $nSubRows = 0; $closeTBody = false; for ($i = 0; $i < $nGroupValues; $i++) { $cur = $arGroupValues[$i]; if ($i == 0) { $prev = $cur; } $bLastValue = $nGroupValues - 1 == $i; if ($cur != $prev || $bLastValue) { $n = $bLastValue && $cur != $prev ? 2 : 1; while ($n-- > 0) { $groupValueIndex = $bLastValue && $n === 0 ? $i : $i - 1; if ($bLastValue && $cur == $prev) { $newRowSet[] = $arGroupValuesIndexes[$i]; } $arGroupingResult = groupingReportResultHtml($arParams, $arResult, $level + 1, $newRowSet); $arSubTotal = $arGroupingResult['total']; $arReportData[$groupValueIndex]["CLOSED"] = true; if (!empty($arGroupingResult['array'])) { $arReportData[$groupValueIndex]["SECTIONS"] = $arGroupingResult['array']; } unset($arGroupingResult); $newRowSet = array(); if (!$bLastValue) { $newRowSet[] = $arGroupValuesIndexes[$i]; } $prev = $cur; // show row $groupValueKey = $arViewColumns[$arGroups[$level]]['resultName']; $groupValue = $arData[$arGroupValuesIndexes[$groupValueIndex]][$groupValueKey]; // magic glue if (is_array($groupValue)) { $groupValue = join(' / ', $groupValue); } if ($level == 0) { $closeTBody = true; $rowClass = ' class="mobile-admin-report-category"'; } else { $rowClass = ''; } foreach ($arSubTotal as $k => $subValue) { $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal']; if ($bGroupingSubtotal || $level == $nGroups - 1) { $finalSubValue = $subValue; if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) { // format subtotal value $subValueKey = $arViewColumns[$arColumns[$k]]['resultName']; call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalSubValue, 'cInfo' => &$arViewColumns[$arColumns[$k]])); } } else { $finalSubValue = ' '; } if ($k == 0) { $arReportData[$groupValueIndex]["TITLE"] = $groupValue; } if (empty($arReportData[$groupValueIndex]["SECTIONS"])) { $arReportData[$groupValueIndex]["CONTENT"][$k]["TITLE"] = $arViewColumns[$arColumns[$k]]['humanTitle'] . ": "; $arReportData[$groupValueIndex]["CONTENT"][$k]["VALUE"] = $finalSubValue; } } // total += subtotal if ($nColumns > 0) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { $columnDataType = $arValueTypes[$viewColumnIndex]; if ($columnDataType === 'integer' || $columnDataType === 'float') { if (is_string($arSubTotal[$columnIndex])) { $arSubTotal[$columnIndex] = str_replace(' ', '', $arSubTotal[$columnIndex]); } $total[$columnIndex] += $arSubTotal[$columnIndex]; } } $nSubRows++; } } // while ($n-- > 0) } else { $newRowSet[] = $arGroupValuesIndexes[$i]; } $finalRow = $i; } // calculate average values if ($nSubRows > 1) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') { $total[$columnIndex] = $total[$columnIndex] / $nSubRows; } } } } else { if ($nColumns > 0) { $rowNumber = 0; while ($rowNumber++ < $nRows) { // get index if ($bUseRowSet) { list(, $dataIndex) = each($arRowSet); } else { list($dataIndex, ) = each($arData); } // total += values foreach ($arColumns as $columnIndex => $viewColumnIndex) { $columnDataType = $arValueTypes[$viewColumnIndex]; if ($nRows == 1) { $dataValueKey = $arViewColumns[$viewColumnIndex]['resultName']; $dataValue = $arData[$dataIndex][$dataValueKey]; if ($columnDataType === 'integer' || $columnDataType === 'float' && is_string($dataValue)) { $dataValue = str_replace(' ', '', $dataValue); } // normal value $total[$columnIndex] = $dataValue; } else { if ($columnDataType === 'integer' || $columnDataType === 'float') { $dataValue = $arData[$dataIndex][$arViewColumns[$viewColumnIndex]['resultName']]; if (is_string($dataValue)) { $dataValue = str_replace(' ', '', $dataValue); } $total[$columnIndex] += $dataValue; } } } } // calculate average values if ($nRows > 1) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') { $total[$columnIndex] = $total[$columnIndex] / $nRows; } } } } } } // show total if ($level === 0) { if (count($total) > 0) { // show total check $bShowTotal = false; foreach ($total as $k => $v) { if ($arViewColumns[$arColumns[$k]]['grouping_subtotal']) { $bShowTotal = true; break; } } if ($bShowTotal) { $arReportData[$finalRow + 1]["TITLE"] = GetMessage('REPORT_TOTAL'); $arReportData[$finalRow + 1]["CLOSED"] = true; $arReportData[$finalRow + 1]["HIGHLIGHTED"] = true; foreach ($total as $k => $v) { $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal']; if ($bGroupingSubtotal) { $finalTotalValue = $v; if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) { // format subtotal value $subValueKey = $arViewColumns[$arColumns[$k]]['resultName']; call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalTotalValue, 'cInfo' => &$arViewColumns[$arColumns[$k]])); } } else { $finalTotalValue = ' '; } $arReportData[$finalRow + 1]["CONTENT"][$k]["TITLE"] = $arViewColumns[$arColumns[$k]]['humanTitle'] . ": "; $arReportData[$finalRow + 1]["CONTENT"][$k]["VALUE"] = $finalTotalValue; //$arReportData["finalTotalValue"][$k] = $finalTotalValue; } } } } } return array('total' => $total, 'array' => $arReportData, 'headerHtml' => $headerHtml); }
function groupingReportResultHtml(&$arParams, &$arResult, $level = 0, $arRowSet = array()) { $strHtml = ''; $total = array(); $arViewColumns =& $arResult['viewColumns']; $arData =& $arResult['data']; // static variables static $arGroups = array(); static $arColumns = array(); static $nGroups = 0; static $nColumns = 0; static $arValueTypes = array(); // initialize static variables if ($level === 0) { foreach ($arViewColumns as $viewColumnIndex => $viewColumn) { if ($viewColumn['grouping']) { $arGroups[$nGroups++] = $viewColumnIndex; } else { $arColumns[$nColumns++] = $viewColumnIndex; } $arValueTypes[$viewColumnIndex] = getResultColumnDataType($viewColumn, $arResult['customColumnTypes']); } } $nRows = count($arRowSet); $bUseRowSet = $nRows > 0 ? true : false; if (!$bUseRowSet) { $nRows = count($arData); } if ($nGroups > 0) { // grouping table header if ($level === 0) { $strHtml .= "\t" . '<div class="order_infoblock">' . PHP_EOL . "\t\t" . '<div class="order_infoblock_content">' . PHP_EOL . "\t\t\t" . '<table class="bx_table_item_remainder">' . PHP_EOL . "\t\t\t\t" . '<thead>' . PHP_EOL; $strHtml .= "\t\t\t\t\t" . '<tr class="mobile-admin-report-header">' . PHP_EOL . "\t\t\t\t\t\t" . '<td>' . htmlspecialcharsbx($arViewColumns[$groupColumnIndex]['humanTitle']); $bFirst = true; foreach ($arGroups as $groupColumnIndex) { if ($bFirst) { $strHtml .= htmlspecialcharsbx($arViewColumns[$groupColumnIndex]['humanTitle']); } else { $strHtml .= '<span>' . htmlspecialcharsbx($arViewColumns[$groupColumnIndex]['humanTitle']) . '</span>'; } $bFirst = false; } $strHtml .= "\t\t\t\t\t\t" . '</td>' . PHP_EOL; foreach ($arColumns as $viewColumnIndex) { $strHtml .= "\t\t\t\t\t\t" . '<td defaultSort="' . $arViewColumns[$viewColumnIndex]['defaultSort'] . '">' . htmlspecialcharsbx($arViewColumns[$viewColumnIndex]['humanTitle']) . "\t\t\t\t\t\t" . '</td>' . PHP_EOL; } $strHtml .= "\t\t\t\t\t" . '</tr>' . PHP_EOL; $strHtml .= "\t\t\t\t" . '</thead>' . PHP_EOL; } if ($nRows > 0) { // init total if ($nColumns > 0) { foreach (array_keys($arColumns) as $columnIndex) { $total[$columnIndex] = null; } } if ($level < $nGroups) { // fill group arrays $arGroupValues = array(); $arGroupValuesIndexes = array(); $rowNumber = 0; $groupDataType = $arValueTypes[$arGroups[$level]]; $dataIndex = null; reset($arData); while ($rowNumber++ < $nRows) { // get index if ($bUseRowSet) { list(, $dataIndex) = each($arRowSet); } else { list($dataIndex, ) = each($arData); } // fill index and value of group $arGroupValuesIndexes[] = $dataIndex; $groupValue = $arData[$dataIndex][$arViewColumns[$arGroups[$level]]['resultName']]; if ($groupDataType === 'date' || $groupDataType === 'datetime') { $groupValue = MakeTimeStamp($groupValue, CSite::GetDateFormat('SHORT')); } // magic glue if (is_array($groupValue)) { $groupValue = join(' / ', $groupValue); } $arGroupValues[] = $groupValue; } // determine sort options $groupSortOption = SORT_STRING; $groupSortDirection = SORT_ASC; if (in_array($groupDataType, array('date', 'datetime', 'integer', 'float'))) { $groupSortOption = SORT_NUMERIC; } if ($arGroups[$level] == $arResult['sort_id']) { if ($arResult['sort_type'] != 'ASC') { $groupSortDirection = SORT_DESC; } } // sort group array_multisort($arGroupValues, $groupSortOption, $groupSortDirection, $arGroupValuesIndexes, SORT_NUMERIC, SORT_ASC); // recursive scan $prev = null; $newRowSet = array(); $nGroupValues = count($arGroupValues); $nSubRows = 0; $closeTBody = false; for ($i = 0; $i < $nGroupValues; $i++) { $cur = $arGroupValues[$i]; if ($i == 0) { $prev = $cur; } $bLastValue = $nGroupValues - 1 == $i; if ($cur != $prev || $bLastValue) { $n = $bLastValue && $cur != $prev ? 2 : 1; while ($n-- > 0) { if ($bLastValue && $cur == $prev) { $newRowSet[] = $arGroupValuesIndexes[$i]; } $arGroupingResult = groupingReportResultHtml($arParams, $arResult, $level + 1, $newRowSet); $arSubTotal = $arGroupingResult['total']; $strSubHtml = $arGroupingResult['html']; unset($arGroupingResult); $newRowSet = array(); if (!$bLastValue) { $newRowSet[] = $arGroupValuesIndexes[$i]; } $prev = $cur; // show row $groupValueIndex = $bLastValue && $n === 0 ? $i : $i - 1; $groupValueKey = $arViewColumns[$arGroups[$level]]['resultName']; $groupValue = $arData[$arGroupValuesIndexes[$groupValueIndex]][$groupValueKey]; // magic glue if (is_array($groupValue)) { $groupValue = join(' / ', $groupValue); } if ($level == 0) { if ($closeTBody) { $strHtml .= "\t\t\t\t" . '</tbody>' . PHP_EOL; } $strHtml .= "\t\t\t\t" . '<tbody>' . PHP_EOL; $closeTBody = true; $rowClass = ' class="mobile-admin-report-category"'; } else { $rowClass = ''; } $strHtml .= "\t\t\t\t\t" . '<tr' . $rowClass . '>' . PHP_EOL . "\t\t\t\t\t\t" . '<td>'; if ($level == $nGroups - 1) { $strHtml .= '<span>' . $groupValue . '</span>'; } else { $strHtml .= $groupValue; } $strHtml .= "\t\t\t\t\t\t" . '</td>' . PHP_EOL; foreach ($arSubTotal as $k => $subValue) { $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal']; if ($bGroupingSubtotal || $level == $nGroups - 1) { $finalSubValue = $subValue; if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) { // format subtotal value $subValueKey = $arViewColumns[$arColumns[$k]]['resultName']; call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalSubValue, 'cInfo' => &$arViewColumns[$arColumns[$k]])); } } else { $finalSubValue = ' '; } $strHtml .= "\t\t\t\t\t\t" . '<td>' . $finalSubValue . '</td>' . PHP_EOL; } $strHtml .= "\t\t\t\t\t" . '</tr>' . PHP_EOL; $strHtml .= $strSubHtml; // total += subtotal if ($nColumns > 0) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { $columnDataType = $arValueTypes[$viewColumnIndex]; if ($columnDataType === 'integer' || $columnDataType === 'float') { if (is_string($arSubTotal[$columnIndex])) { $arSubTotal[$columnIndex] = str_replace(' ', '', $arSubTotal[$columnIndex]); } $total[$columnIndex] += $arSubTotal[$columnIndex]; } } $nSubRows++; } } // while ($n-- > 0) } else { $newRowSet[] = $arGroupValuesIndexes[$i]; } } // calculate average values if ($nSubRows > 1) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') { $total[$columnIndex] = $total[$columnIndex] / $nSubRows; } } } } else { if ($nColumns > 0) { $rowNumber = 0; while ($rowNumber++ < $nRows) { // get index if ($bUseRowSet) { list(, $dataIndex) = each($arRowSet); } else { list($dataIndex, ) = each($arData); } // total += values foreach ($arColumns as $columnIndex => $viewColumnIndex) { $columnDataType = $arValueTypes[$viewColumnIndex]; if ($nRows == 1) { $dataValueKey = $arViewColumns[$viewColumnIndex]['resultName']; $dataValue = $arData[$dataIndex][$dataValueKey]; if ($columnDataType === 'integer' || $columnDataType === 'float' && is_string($dataValue)) { $dataValue = str_replace(' ', '', $dataValue); } // normal value $total[$columnIndex] = $dataValue; } else { if ($columnDataType === 'integer' || $columnDataType === 'float') { $dataValue = $arData[$dataIndex][$arViewColumns[$viewColumnIndex]['resultName']]; if (is_string($dataValue)) { $dataValue = str_replace(' ', '', $dataValue); } $total[$columnIndex] += $dataValue; } } } } // calculate average values if ($nRows > 1) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') { $total[$columnIndex] = $total[$columnIndex] / $nRows; } } } } } } // show total if ($level === 0) { if (count($total) > 0) { // show total check $bShowTotal = false; foreach ($total as $k => $v) { if ($arViewColumns[$arColumns[$k]]['grouping_subtotal']) { $bShowTotal = true; break; } } if ($bShowTotal) { $strHtml .= "\t\t\t" . '</tbody><tbody><tr style="background: none repeat scroll 0 0 #EDF2D4;">' . PHP_EOL . "\t\t\t\t" . '<td>' . htmlspecialcharsbx(GetMessage('REPORT_TOTAL')) . ':</td>' . PHP_EOL; foreach ($total as $k => $v) { $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal']; if ($bGroupingSubtotal) { $finalTotalValue = $v; if (method_exists($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal')) { // format subtotal value $subValueKey = $arViewColumns[$arColumns[$k]]['resultName']; call_user_func(array($arParams['REPORT_HELPER_CLASS'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalTotalValue, 'cInfo' => &$arViewColumns[$arColumns[$k]])); } } else { $finalTotalValue = ' '; } $strHtml .= "\t\t\t\t" . '<td>' . $finalTotalValue . '</td>' . PHP_EOL; } $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL; } } $strHtml .= "\t" . '</tbody></table>' . PHP_EOL . '</div></div>' . PHP_EOL; } } return array('total' => $total, 'html' => $strHtml); }
function groupingReportResultHtml(&$arParams, &$arResult, $level = 0, $arRowSet = array()) { $strHtml = ''; $total = array(); $arViewColumns =& $arResult['viewColumns']; $arData =& $arResult['data']; // static variables static $arGroups = array(); static $arColumns = array(); static $nGroups = 0; static $nColumns = 0; static $arValueTypes = array(); static $marginWidth = 20; // chart info variables static $bChartGrouping = false; static $arChartColumns = array(); static $chartColumnMaxGroupLevel = -1; static $chartDataRowIndex = -1; static $arChartGroupingValues = array(); // initialize static variables if ($level === 0) { foreach ($arViewColumns as $viewColumnIndex => $viewColumn) { if ($viewColumn['grouping']) { $arGroups[$nGroups++] = $viewColumnIndex; } else { $arColumns[$nColumns++] = $viewColumnIndex; } $arValueTypes[$viewColumnIndex] = getResultColumnDataType($viewColumn, $arResult['customColumnTypes'], $arResult['helperClassName']); } // chart columns if ($arParams['USE_CHART'] && $arResult['settings']['chart']['display']) { $chartSettings = $arResult['settings']['chart']; if (isset($chartSettings['x_column']) && is_array($chartSettings['y_columns'])) { $arChartColumns[] = $chartSettings['x_column']; $arChartColumns = array_merge($arChartColumns, $chartSettings['y_columns']); } // obtain max group level of chart columns foreach ($arChartColumns as $nChartColumn) { foreach ($arGroups as $groupLevel => $nGroup) { if ($nChartColumn == $nGroup) { $bChartGrouping = true; $chartColumnMaxGroupLevel = max($chartColumnMaxGroupLevel, $groupLevel); } } } } } $nRows = count($arRowSet); $bUseRowSet = $nRows > 0 ? true : false; if (!$bUseRowSet) { $nRows = count($arData); } if ($nGroups > 0) { // grouping table header if ($level === 0) { $bFirstGroup = true; $strHtml .= '<div class="reports-grouping-table-wrap">' . PHP_EOL . "\t" . '<table id="report-result-table" class="reports-grouping-table" cellpadding=2 cellspacing=0>' . PHP_EOL . "\t\t" . '<thead>' . PHP_EOL; foreach ($arGroups as $groupColumnIndex) { $strHtml .= "\t\t\t" . '<tr class="adm-list-table-header reports-grouping-table-head-row">' . PHP_EOL . "\t\t\t\t" . '<td class="adm-list-table-cell">' . htmlspecialcharsbx($arViewColumns[$groupColumnIndex]['humanTitle']) . '</td>' . PHP_EOL; if ($bFirstGroup) { $bFirstGroup = false; foreach ($arColumns as $viewColumnIndex) { $strHtml .= "\t\t\t\t" . '<td class="adm-list-table-cell align-center"'; if ($nGroups > 1) { $strHtml .= ' rowspan="' . htmlspecialcharsbx($nGroups) . '"'; } $strHtml .= ' colId="' . $viewColumnIndex . '" defaultSort="' . $arViewColumns[$viewColumnIndex]['defaultSort'] . '">' . htmlspecialcharsbx($arViewColumns[$viewColumnIndex]['humanTitle']) . '</td>' . PHP_EOL; } } $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL; } $strHtml .= "\t\t" . '</thead>' . PHP_EOL; } if ($nRows > 0) { // table header separator if ($level === 0) { $strHtml .= "\t\t" . '<tbody>' . PHP_EOL . "\t\t\t" . '<tr class="reports-grouping-table-row-separator"><td></td></tr>' . PHP_EOL; } // init total if ($nColumns > 0) { foreach (array_keys($arColumns) as $columnIndex) { $total[$columnIndex] = null; } } if ($level < $nGroups) { // fill group arrays $arGroupValues = array(); $arGroupValuesIndexes = array(); $rowNumber = 0; $groupDataType = $arValueTypes[$arGroups[$level]]; $dataIndex = null; reset($arData); while ($rowNumber++ < $nRows) { // get index if ($bUseRowSet) { list(, $dataIndex) = each($arRowSet); } else { list($dataIndex, ) = each($arData); } // fill index and value of group $arGroupValuesIndexes[] = $dataIndex; $groupValue = $arData[$dataIndex][$arViewColumns[$arGroups[$level]]['resultName']]; if ($groupDataType === 'date' || $groupDataType === 'datetime') { $groupValue = MakeTimeStamp($groupValue, CSite::GetDateFormat('SHORT')); } // magic glue if (is_array($groupValue)) { $groupValue = join(' / ', $groupValue); } $arGroupValues[] = $groupValue; } // determine sort options $groupSortOption = SORT_STRING; $groupSortDirection = SORT_ASC; if (in_array($groupDataType, array('date', 'datetime', 'integer', 'float'))) { $groupSortOption = SORT_NUMERIC; } if ($arGroups[$level] == $arResult['sort_id']) { if ($arResult['sort_type'] != 'ASC') { $groupSortDirection = SORT_DESC; } } // sort group array_multisort($arGroupValues, $groupSortOption, $groupSortDirection, $arGroupValuesIndexes, SORT_NUMERIC, SORT_ASC); // recursive scan $prev = null; $newRowSet = array(); $nGroupValues = count($arGroupValues); $nSubRows = 0; for ($i = 0; $i < $nGroupValues; $i++) { $cur = $arGroupValues[$i]; if ($i == 0) { $prev = $cur; } $bLastValue = $nGroupValues - 1 == $i; if ($cur != $prev || $bLastValue) { $n = $bLastValue && $cur != $prev ? 2 : 1; while ($n-- > 0) { // chart values index if ($bChartGrouping && $level == $chartColumnMaxGroupLevel) { $chartDataRowIndex++; } if ($bLastValue && $cur == $prev) { $newRowSet[] = $arGroupValuesIndexes[$i]; } $arGroupingResult = groupingReportResultHtml($arParams, $arResult, $level + 1, $newRowSet); $arSubTotal = $arGroupingResult['total']; $strSubHtml = $arGroupingResult['html']; unset($arGroupingResult); $newRowSet = array(); if (!$bLastValue) { $newRowSet[] = $arGroupValuesIndexes[$i]; } $prev = $cur; // show row $groupValueIndex = $bLastValue && $n === 0 ? $i : $i - 1; $groupValueKey = $arViewColumns[$arGroups[$level]]['resultName']; $groupValue = $arData[$arGroupValuesIndexes[$groupValueIndex]][$groupValueKey]; // magic glue if (is_array($groupValue)) { $groupValue = join(' / ', $groupValue); } // add chart values if ($bChartGrouping && in_array($arGroups[$level], $arChartColumns)) { $tempChartDataRowIndex = $chartDataRowIndex; while ($tempChartDataRowIndex >= 0 && !isset($arChartGroupingValues[$tempChartDataRowIndex][$arGroups[$level]])) { $arChartGroupingValues[$tempChartDataRowIndex--][$arGroups[$level]] = $groupValue; } unset($tempChartDataRowIndex); } // values of groups were processed as normal values /*if (method_exists($arResult['helperClassName'], 'formatResultGroupingValue')) { // format group value call_user_func( array($arResult['helperClassName'], 'formatResultGroupingValue'), array( 'k' => $groupValueKey, 'v' => &$groupValue, 'row' => &$arData[$arGroupValuesIndexes[$groupValueIndex]], 'cInfo' => &$arViewColumns[$arGroups[$level]] ) ); }*/ $cellClassFirstColumn = ''; if ($level == $nGroups - 1) { $rowClass = ' reports-grouping-data-row'; } else { $rowClass = ' reports-grouping-group-row'; $cellClassFirstColumn = 'adm-list-table-cell'; } $cellClassAttr = ''; if (!empty($cellClassFirstColumn)) { $cellClassAttr = ' class="' . $cellClassFirstColumn . '"'; } $margin = $level > 0 ? ' style="margin-left: ' . $level * $marginWidth . 'px;"' : ''; $strHtml .= "\t\t\t" . '<tr class="adm-list-table-header' . $rowClass . '">' . PHP_EOL . "\t\t\t\t" . '<td' . $cellClassAttr . '><div' . $margin . '>' . ($groupValue === '' ? ' ' : $groupValue) . '</div></td>' . PHP_EOL; foreach ($arSubTotal as $k => $subValue) { $cellAlign = ''; $cellClass = $cellClassFirstColumn; if ($arResult['settings']['red_neg_vals'] === true) { if (is_numeric($subValue) && $subValue < 0) { $cellClass .= ' report-red-neg-val'; } } // cell align $colAlign = $arViewColumns[$arColumns[$k]]['align']; if ($colAlign === null) { if (CReport::isColumnPercentable($arViewColumns[$arColumns[$k]], $arResult['helperClassName'])) { $cellAlign = ' align-right'; } } else { if ($colAlign === 'right') { $cellAlign = ' align-right"'; } } if (!empty($cellAlign)) { $cellClass .= $cellAlign; } if (!empty($cellClass)) { $cellClass = ' class="' . ltrim($cellClass) . '"'; } $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal']; if ($bGroupingSubtotal || $level == $nGroups - 1) { $finalSubValue = $subValue; if (method_exists($arResult['helperClassName'], 'formatResultGroupingTotal')) { // format subtotal value $subValueKey = $arViewColumns[$arColumns[$k]]['resultName']; call_user_func(array($arResult['helperClassName'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalSubValue, 'cInfo' => &$arViewColumns[$arColumns[$k]])); } } else { $finalSubValue = ''; } $strHtml .= "\t\t\t\t" . '<td' . $cellClass . '>' . ($finalSubValue === '' ? ' ' : $finalSubValue) . '</td>' . PHP_EOL; // add chart values if ($bChartGrouping && $level == $chartColumnMaxGroupLevel && in_array($arColumns[$k], $arChartColumns)) { $arChartGroupingValues[$chartDataRowIndex][$arColumns[$k]] = $finalSubValue; } } $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL; $strHtml .= $strSubHtml; // total += subtotal if ($nColumns > 0) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { $columnDataType = $arValueTypes[$viewColumnIndex]; if ($columnDataType === 'integer' || $columnDataType === 'float') { if (is_string($arSubTotal[$columnIndex])) { $arSubTotal[$columnIndex] = str_replace(' ', '', $arSubTotal[$columnIndex]); } $total[$columnIndex] += $arSubTotal[$columnIndex]; } } $nSubRows++; } } // while ($n-- > 0) } else { $newRowSet[] = $arGroupValuesIndexes[$i]; } } // calculate average values if ($nSubRows > 1) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') { $total[$columnIndex] = $total[$columnIndex] / $nSubRows; } } } } else { if ($nColumns > 0) { $rowNumber = 0; while ($rowNumber++ < $nRows) { // get index if ($bUseRowSet) { list(, $dataIndex) = each($arRowSet); } else { list($dataIndex, ) = each($arData); } // total += values foreach ($arColumns as $columnIndex => $viewColumnIndex) { $columnDataType = $arValueTypes[$viewColumnIndex]; if ($nRows == 1) { $dataValueKey = $arViewColumns[$viewColumnIndex]['resultName']; $dataValue = $arData[$dataIndex][$dataValueKey]; // normal value /*if (method_exists($arResult['helperClassName'], 'formatResultGroupingValue')) { // format result value call_user_func( array($arResult['helperClassName'], 'formatResultGroupingValue'), array( 'k' => $dataValueKey, 'v' => &$dataValue, 'row' => &$arData[$dataIndex], 'cInfo' => &$arViewColumns[$viewColumnIndex] ) ); }*/ if ($columnDataType === 'integer' || $columnDataType === 'float' && is_string($dataValue)) { $dataValue = str_replace(' ', '', $dataValue); } $total[$columnIndex] = $dataValue; } else { if ($columnDataType === 'integer' || $columnDataType === 'float') { $dataValue = $arData[$dataIndex][$arViewColumns[$viewColumnIndex]['resultName']]; if (is_string($dataValue)) { $dataValue = str_replace(' ', '', $dataValue); } $total[$columnIndex] += $dataValue; } } } } // calculate average values if ($nRows > 1) { foreach ($arColumns as $columnIndex => $viewColumnIndex) { if ($arViewColumns[$viewColumnIndex]['aggr'] === 'AVG' || $arViewColumns[$viewColumnIndex]['grouping_aggr'] === 'AVG') { $total[$columnIndex] = $total[$columnIndex] / $nRows; } } } } } } // show total if ($level === 0) { if (count($total) > 0) { // show total check $bShowTotal = false; foreach ($total as $k => $v) { if ($arViewColumns[$arColumns[$k]]['grouping_subtotal']) { $bShowTotal = true; break; } } if ($bShowTotal) { $strHtml .= "\t\t\t" . '<tr class="reports-grouping-table-row-separator"><td></td></tr>' . PHP_EOL; $strHtml .= "\t\t\t" . '<tr class="adm-list-table-header reports-grouping-total-row">' . PHP_EOL . "\t\t\t\t" . '<td class="adm-list-table-cell">' . htmlspecialcharsbx(GetMessage('REPORT_TOTAL')) . '</td>' . PHP_EOL; foreach ($total as $k => $v) { $cellAlign = ''; $cellClass = ''; if ($arResult['settings']['red_neg_vals'] === true) { if (is_numeric($v) && $v < 0) { $cellClass .= ' report-red-neg-val'; } } // cell align $colAlign = $arViewColumns[$arColumns[$k]]['align']; if ($colAlign === null) { if (CReport::isColumnPercentable($arViewColumns[$arColumns[$k]], $arResult['helperClassName'])) { $cellAlign = ' align-right'; } } else { if ($colAlign === 'right') { $cellAlign = ' align-right'; } } if (!empty($cellAlign)) { $cellClass .= $cellAlign; } $bGroupingSubtotal = $arViewColumns[$arColumns[$k]]['grouping_subtotal']; if ($bGroupingSubtotal) { $finalTotalValue = $v; if (method_exists($arResult['helperClassName'], 'formatResultGroupingTotal')) { // format subtotal value $subValueKey = $arViewColumns[$arColumns[$k]]['resultName']; call_user_func(array($arResult['helperClassName'], 'formatResultGroupingTotal'), array('k' => $subValueKey, 'v' => &$finalTotalValue, 'cInfo' => &$arViewColumns[$arColumns[$k]])); } } else { $finalTotalValue = ''; } $strHtml .= "\t\t\t\t" . '<td class="adm-list-table-cell' . $cellClass . '">' . ($finalTotalValue === '' ? ' ' : $finalTotalValue) . '</td>' . PHP_EOL; } $strHtml .= "\t\t\t" . '</tr>' . PHP_EOL; } } $strHtml .= "\t\t" . '</tbody>' . PHP_EOL . "\t" . '</table>' . PHP_EOL . '</div>' . PHP_EOL; } } $result = array('total' => $total, 'html' => $strHtml); // return chart values if ($bChartGrouping && $level === 0) { $result['chart'] = $arChartGroupingValues; $arChartGroupingValues = array(); } return $result; }