645 lines
27 KiB
PHP
645 lines
27 KiB
PHP
<?php
|
||
namespace App\DevExtreme;
|
||
|
||
use App\DevExtreme\SummaryContext;
|
||
class AggregateHelper {
|
||
const MIN_OP = "MIN";
|
||
const MAX_OP = "MAX";
|
||
const AVG_OP = "AVG";
|
||
const COUNT_OP = "COUNT";
|
||
const SUM_OP = "SUM";
|
||
const AS_OP = "AS";
|
||
const GENERATED_FIELD_PREFIX = "dx_";
|
||
private static function _RecalculateGroupCountAndSummary(&$dataItem, $groupInfo) {
|
||
if ($groupInfo["groupIndex"] <= $groupInfo["groupCount"] - 3) {
|
||
$items = $dataItem["items"];
|
||
foreach ($items as $item) {
|
||
$grInfo = $groupInfo;
|
||
$grInfo["groupIndex"]++;
|
||
self::_RecalculateGroupCountAndSummary($item, $grInfo);
|
||
}
|
||
}
|
||
if (isset($groupInfo["summaryTypes"]) && $groupInfo["groupIndex"] < $groupInfo["groupCount"] - 2) {
|
||
$result = array();
|
||
$items = $dataItem["items"];
|
||
$itemsCount = count($items);
|
||
foreach ($items as $index => $item) {
|
||
$currentSummaries = $item["summary"];
|
||
if ($index == 0) {
|
||
foreach ($currentSummaries as $summaryItem) {
|
||
$result[] = $summaryItem;
|
||
}
|
||
continue;
|
||
}
|
||
foreach ($groupInfo["summaryTypes"] as $si => $stItem) {
|
||
if ($stItem == self::MIN_OP) {
|
||
if ($result[$si] > $currentSummaries[$si]) {
|
||
$result[$si] = $currentSummaries[$si];
|
||
}
|
||
continue;
|
||
}
|
||
if ($stItem == self::MAX_OP) {
|
||
if ($result[$si] < $currentSummaries[$si]) {
|
||
$result[$si] = $currentSummaries[$si];
|
||
}
|
||
continue;
|
||
}
|
||
$result[$si] += $currentSummaries[$si];
|
||
}
|
||
}
|
||
foreach ($groupInfo["summaryTypes"] as $si => $stItem) {
|
||
if ($stItem == self::AVG_OP) {
|
||
$result[$si] /= $itemsCount;
|
||
}
|
||
}
|
||
$dataItem["summary"] = $result;
|
||
}
|
||
}
|
||
private static function _GetNewDataItem($row, $groupInfo) {
|
||
$dataItem = array();
|
||
$dataFieldCount = count($groupInfo["dataFieldNames"]);
|
||
for ($index = 0; $index < $dataFieldCount; $index++) {
|
||
$dataItem[$groupInfo["dataFieldNames"][$index]] = $row[$groupInfo["groupCount"] + $index];
|
||
}
|
||
return $dataItem;
|
||
}
|
||
private static function _GetNewGroupItem($row, $groupInfo, $explicitKey = null) {
|
||
$groupIndexOffset = $groupInfo["lastGroupExpanded"] ? 1 : 2;
|
||
|
||
// Direkt row değerini al, explode kullanma
|
||
$item = $explicitKey !== null ? $explicitKey : (isset($row[$groupInfo["groupIndex"]]) ? trim($row[$groupInfo["groupIndex"]]) : null);
|
||
|
||
$groupItem = array();
|
||
$groupItem["key"] = ($item === "" || $item === null) ? null : $item;
|
||
$groupItem["items"] = $groupInfo["groupIndex"] < $groupInfo["groupCount"] - $groupIndexOffset ? array() :
|
||
($groupInfo["lastGroupExpanded"] ? array() : NULL);
|
||
if ($groupInfo["groupIndex"] == $groupInfo["groupCount"] - $groupIndexOffset) {
|
||
if (isset($groupInfo["summaryTypes"])) {
|
||
$summaries = array();
|
||
$endIndex = $groupInfo["groupIndex"] + count($groupInfo["summaryTypes"]) + 1;
|
||
for ($index = $groupInfo["groupCount"]; $index <= $endIndex; $index++) {
|
||
$summaries[] = $row[$index];
|
||
}
|
||
$groupItem["summary"] = $summaries;
|
||
}
|
||
if (!$groupInfo["lastGroupExpanded"]) {
|
||
$groupItem["count"] = $row[$groupInfo["groupIndex"] + 1];
|
||
}
|
||
else {
|
||
$groupItem["items"][] = self::_GetNewDataItem($row, $groupInfo);
|
||
}
|
||
}
|
||
|
||
return $groupItem;
|
||
}
|
||
private static function _GroupData($row, &$resultItems, $groupInfo) {
|
||
$itemsCount = count($resultItems);
|
||
if (!isset($row) && !$itemsCount) {
|
||
return;
|
||
}
|
||
$currentItem = NULL;
|
||
$groupIndexOffset = $groupInfo["lastGroupExpanded"] ? 1 : 2;
|
||
|
||
// Eğer bu bir tarih filtresi ise, özel yönetim yapalım
|
||
$dateSequenceInfo = self::_getDateSequence($groupInfo);
|
||
|
||
if ($dateSequenceInfo['isDateSequence']) {
|
||
// Tarih sırası algılandı, özel tarih işleme mantığını kullan
|
||
self::_processDateSequence($row, $resultItems, $groupInfo, $dateSequenceInfo);
|
||
return;
|
||
}
|
||
|
||
// Standart (tarih olmayan) gruplamalar için normal akış
|
||
$currentKey = isset($row[$groupInfo["groupIndex"]]) ? trim($row[$groupInfo["groupIndex"]]) : null;
|
||
|
||
// Comma separation logic
|
||
if (isset($groupInfo["processCommas"]) && $groupInfo["processCommas"] === true &&
|
||
$currentKey !== null && strpos($currentKey, ',') !== false) {
|
||
|
||
$keys = explode(',', $currentKey);
|
||
foreach ($keys as $key) {
|
||
self::_processGroupDataItem($row, $resultItems, $groupInfo, trim($key));
|
||
}
|
||
return;
|
||
}
|
||
|
||
// Standart grup işlemlerini yapan yardımcı fonksiyon
|
||
self::_processGroupDataItem($row, $resultItems, $groupInfo, $currentKey);
|
||
}
|
||
|
||
// Standart grup işlemlerini yapan yardımcı fonksiyon
|
||
private static function _processGroupDataItem($row, &$resultItems, $groupInfo, $explicitKey = null) {
|
||
$currentKey = $explicitKey;
|
||
if ($currentKey === "") {
|
||
$currentKey = null;
|
||
}
|
||
|
||
$groupIndexOffset = $groupInfo["lastGroupExpanded"] ? 1 : 2;
|
||
|
||
// Eğer bu key zaten varsa, ilgili item'ı kullan
|
||
$keyExists = false;
|
||
$currentItem = null;
|
||
|
||
foreach($resultItems as $index => $item) {
|
||
if(isset($item["key"]) && (trim($item["key"]) === trim($currentKey) ||
|
||
($item["key"] === null && ($currentKey === null || $currentKey === "")))) {
|
||
$keyExists = true;
|
||
$currentItem = &$resultItems[$index];
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!$keyExists) {
|
||
$currentItem = self::_GetNewGroupItem($row, $groupInfo, $currentKey);
|
||
$resultItems[] = &$currentItem;
|
||
} else {
|
||
// MERGE LOGIC for leaf groups
|
||
if ($groupInfo["groupIndex"] == $groupInfo["groupCount"] - $groupIndexOffset) {
|
||
// Update count
|
||
if (isset($currentItem["count"])) {
|
||
$currentItem["count"] += $row[$groupInfo["groupIndex"] + 1];
|
||
}
|
||
|
||
// Update summaries if needed
|
||
if (isset($currentItem["summary"]) && isset($groupInfo["summaryTypes"])) {
|
||
$newSummaries = array();
|
||
$endIndex = $groupInfo["groupIndex"] + count($groupInfo["summaryTypes"]) + 1;
|
||
for ($index = $groupInfo["groupCount"]; $index <= $endIndex; $index++) {
|
||
$newSummaries[] = $row[$index];
|
||
}
|
||
|
||
foreach ($groupInfo["summaryTypes"] as $si => $stItem) {
|
||
if ($stItem == self::MIN_OP) {
|
||
if ($currentItem["summary"][$si] > $newSummaries[$si]) $currentItem["summary"][$si] = $newSummaries[$si];
|
||
} else if ($stItem == self::MAX_OP) {
|
||
if ($currentItem["summary"][$si] < $newSummaries[$si]) $currentItem["summary"][$si] = $newSummaries[$si];
|
||
} else if ($stItem == self::SUM_OP || $stItem == self::COUNT_OP) {
|
||
$currentItem["summary"][$si] += $newSummaries[$si];
|
||
} else if ($stItem == self::AVG_OP) {
|
||
$count1 = isset($currentItem["count"]) ? $currentItem["count"] : 1;
|
||
$count2 = isset($row[$groupInfo["groupIndex"] + 1]) ? $row[$groupInfo["groupIndex"] + 1] : 1;
|
||
|
||
if (($count1 + $count2) > 0)
|
||
$currentItem["summary"][$si] = (($currentItem["summary"][$si] * $count1) + ($newSummaries[$si] * $count2)) / ($count1 + $count2);
|
||
else
|
||
$currentItem["summary"][$si] = ($currentItem["summary"][$si] + $newSummaries[$si]) / 2;
|
||
}
|
||
}
|
||
}
|
||
|
||
// If expanded, append items
|
||
if ($groupInfo["lastGroupExpanded"]) {
|
||
$currentItem["items"][] = self::_GetNewDataItem($row, $groupInfo);
|
||
}
|
||
}
|
||
}
|
||
|
||
if ($groupInfo["groupIndex"] < $groupInfo["groupCount"] - $groupIndexOffset) {
|
||
$groupInfo["groupIndex"]++;
|
||
self::_GroupData($row, $currentItem["items"], $groupInfo);
|
||
}
|
||
}
|
||
|
||
// Tarih dizisini tanımla ve işle
|
||
private static function _getDateSequence($groupInfo) {
|
||
// Tarih sırası bilgisi
|
||
$result = [
|
||
'isDateSequence' => false,
|
||
'sequence' => []
|
||
];
|
||
|
||
if (!isset($groupInfo["groupNames"]) || count($groupInfo["groupNames"]) < 2) {
|
||
return $result;
|
||
}
|
||
|
||
$dateFields = [];
|
||
|
||
// Tüm tarih alanlarını tespit et
|
||
foreach ($groupInfo["groupNames"] as $index => $name) {
|
||
if (strpos($name, 'dx_') !== 0) {
|
||
continue;
|
||
}
|
||
|
||
$type = '';
|
||
if (strpos($name, '_year') !== false) {
|
||
$type = 'year';
|
||
} else if (strpos($name, '_month') !== false) {
|
||
$type = 'month';
|
||
} else if (strpos($name, '_day') !== false) {
|
||
$type = 'day';
|
||
} else {
|
||
continue;
|
||
}
|
||
|
||
$dateFields[] = [
|
||
'index' => $index,
|
||
'type' => $type,
|
||
'name' => $name
|
||
];
|
||
}
|
||
|
||
// Eğer en az 2 tarih alanı varsa, tarih sırası oluştur
|
||
if (count($dateFields) >= 2) {
|
||
// Yıl, ay, gün sırasına göre sırala
|
||
usort($dateFields, function($a, $b) {
|
||
$order = ['year' => 0, 'month' => 1, 'day' => 2];
|
||
return $order[$a['type']] - $order[$b['type']];
|
||
});
|
||
|
||
$result['isDateSequence'] = true;
|
||
$result['sequence'] = $dateFields;
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
// Tarih dizisini doğru bir şekilde işle
|
||
private static function _processDateSequence($row, &$resultItems, $groupInfo, $dateSequenceInfo) {
|
||
$groupIndexOffset = $groupInfo["lastGroupExpanded"] ? 1 : 2;
|
||
$sequence = $dateSequenceInfo['sequence'];
|
||
|
||
// İlk seviye için gruplama yap (genellikle yıl)
|
||
$firstLevelIndex = $sequence[0]['index'];
|
||
$firstLevelType = $sequence[0]['type'];
|
||
|
||
$currentKey = isset($row[$firstLevelIndex]) ? trim($row[$firstLevelIndex]) : null;
|
||
if ($currentKey === "") {
|
||
$currentKey = null;
|
||
}
|
||
|
||
// İlk seviyede (yıl) item ara
|
||
$yearItem = null;
|
||
foreach($resultItems as &$item) {
|
||
if(isset($item["key"]) && (trim($item["key"]) === trim($currentKey) ||
|
||
($item["key"] === null && ($currentKey === null || $currentKey === "")))) {
|
||
$yearItem = &$item;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Yıl item'ı yoksa oluştur
|
||
if ($yearItem === null) {
|
||
// Özel yıl item'ı oluştur
|
||
$tempGroupInfo = $groupInfo;
|
||
$tempGroupInfo["groupIndex"] = $firstLevelIndex;
|
||
|
||
$yearItem = self::_GetNewGroupItem($row, $tempGroupInfo);
|
||
$yearItem["dateLevel"] = $firstLevelType;
|
||
$resultItems[] = &$yearItem;
|
||
}
|
||
|
||
// İkinci seviye için (genellikle ay)
|
||
if (count($sequence) > 1) {
|
||
$secondLevelIndex = $sequence[1]['index'];
|
||
$secondLevelType = $sequence[1]['type'];
|
||
$secondKey = isset($row[$secondLevelIndex]) ? trim($row[$secondLevelIndex]) : null;
|
||
if ($secondKey === "") {
|
||
$secondKey = null;
|
||
}
|
||
|
||
// İkinci seviyede (ay) item ara
|
||
$monthItem = null;
|
||
foreach($yearItem["items"] as &$item) {
|
||
if(isset($item["key"]) && (trim($item["key"]) === trim($secondKey) ||
|
||
($item["key"] === null && ($secondKey === null || $secondKey === "")))) {
|
||
$monthItem = &$item;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Ay item'ı yoksa oluştur
|
||
if ($monthItem === null) {
|
||
// Özel ay item'ı oluştur
|
||
$tempGroupInfo = $groupInfo;
|
||
$tempGroupInfo["groupIndex"] = $secondLevelIndex;
|
||
|
||
$monthItem = self::_GetNewGroupItem($row, $tempGroupInfo);
|
||
$monthItem["dateLevel"] = $secondLevelType;
|
||
$yearItem["items"][] = &$monthItem;
|
||
}
|
||
|
||
// Üçüncü seviye için (genellikle gün)
|
||
if (count($sequence) > 2) {
|
||
$thirdLevelIndex = $sequence[2]['index'];
|
||
$thirdLevelType = $sequence[2]['type'];
|
||
$thirdKey = isset($row[$thirdLevelIndex]) ? trim($row[$thirdLevelIndex]) : null;
|
||
if ($thirdKey === "") {
|
||
$thirdKey = null;
|
||
}
|
||
|
||
// Üçüncü seviyede (gün) item ara
|
||
$dayItem = null;
|
||
foreach($monthItem["items"] as &$item) {
|
||
if(isset($item["key"]) && (trim($item["key"]) === trim($thirdKey) ||
|
||
($item["key"] === null && ($thirdKey === null || $thirdKey === "")))) {
|
||
$dayItem = &$item;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Gün item'ı yoksa oluştur
|
||
if ($dayItem === null) {
|
||
// Özel gün item'ı oluştur
|
||
$tempGroupInfo = $groupInfo;
|
||
$tempGroupInfo["groupIndex"] = $thirdLevelIndex;
|
||
|
||
$dayItem = self::_GetNewGroupItem($row, $tempGroupInfo);
|
||
$dayItem["dateLevel"] = $thirdLevelType;
|
||
$monthItem["items"][] = &$dayItem;
|
||
}
|
||
|
||
// Veriler için
|
||
if ($groupInfo["lastGroupExpanded"]) {
|
||
$dataItem = self::_GetNewDataItem($row, $groupInfo);
|
||
$dayItem["items"][] = $dataItem;
|
||
}
|
||
} else if ($groupInfo["lastGroupExpanded"]) {
|
||
// İki seviye varsa (sadece yıl ve ay), veriyi ay seviyesinde göster
|
||
$dataItem = self::_GetNewDataItem($row, $groupInfo);
|
||
$monthItem["items"][] = $dataItem;
|
||
}
|
||
} else if ($groupInfo["lastGroupExpanded"]) {
|
||
// Tek seviye varsa (sadece yıl), veriyi yıl seviyesinde göster
|
||
$dataItem = self::_GetNewDataItem($row, $groupInfo);
|
||
$yearItem["items"][] = $dataItem;
|
||
}
|
||
}
|
||
public static function GetGroupedDataFromQuery($queryResult, $groupSettings) {
|
||
$result = array();
|
||
$row = NULL;
|
||
$groupSummaryTypes = NULL;
|
||
$dataFieldNames = NULL;
|
||
$startSummaryFieldIndex = NULL;
|
||
$endSummaryFieldIndex = NULL;
|
||
if ($groupSettings["lastGroupExpanded"]) {
|
||
$queryFields = $queryResult->fetch_fields();
|
||
$dataFieldNames = array();
|
||
for ($i = $groupSettings["groupCount"]; $i < count($queryFields); $i++) {
|
||
$dataFieldNames[] = $queryFields[$i]->name;
|
||
}
|
||
}
|
||
if (isset($groupSettings["summaryTypes"])) {
|
||
$groupSummaryTypes = $groupSettings["summaryTypes"];
|
||
$startSummaryFieldIndex = $groupSettings["groupCount"] - 1;
|
||
$endSummaryFieldIndex = $startSummaryFieldIndex + count($groupSummaryTypes);
|
||
}
|
||
|
||
// Grup isimlerini al (tarih filtreleri için gerekli)
|
||
$groupNames = array();
|
||
if (isset($groupSettings["groupNames"])) {
|
||
$groupNames = $groupSettings["groupNames"];
|
||
} elseif ($queryResult && $queryResult->field_count > 0) {
|
||
$fields = $queryResult->fetch_fields();
|
||
for ($i = 0; $i < $groupSettings["groupCount"]; $i++) {
|
||
if (isset($fields[$i])) {
|
||
$groupNames[] = $fields[$i]->name;
|
||
}
|
||
}
|
||
// Sonuçlar için yeniden başa dönmek gerek
|
||
$queryResult->data_seek(0);
|
||
}
|
||
|
||
// Tarih alanlarını sıralamak için düzenleme (yıl, ay, gün)
|
||
$dateGroupIndices = self::getDateGroupIndices($groupNames);
|
||
|
||
$groupInfo = array(
|
||
"groupCount" => $groupSettings["groupCount"],
|
||
"groupIndex" => 0,
|
||
"summaryTypes" => $groupSummaryTypes,
|
||
"lastGroupExpanded" => $groupSettings["lastGroupExpanded"],
|
||
"dataFieldNames" => $dataFieldNames,
|
||
"processCommas" => isset($groupSettings["processCommas"]) ? $groupSettings["processCommas"] : true,
|
||
"groupNames" => $groupNames,
|
||
"dateGroupIndices" => $dateGroupIndices
|
||
);
|
||
|
||
while ($row = $queryResult->fetch_array(MYSQLI_NUM)) {
|
||
if (isset($startSummaryFieldIndex)) {
|
||
for ($i = $startSummaryFieldIndex; $i <= $endSummaryFieldIndex; $i++) {
|
||
$row[$i] = Utils::StringToNumber($row[$i]);
|
||
}
|
||
}
|
||
self::_GroupData($row, $result, $groupInfo);
|
||
}
|
||
if (!$groupSettings["lastGroupExpanded"]) {
|
||
self::_GroupData($row, $result, $groupInfo);
|
||
}
|
||
else {
|
||
if (isset($groupSettings["skip"]) && $groupSettings["skip"] >= 0 &&
|
||
isset($groupSettings["take"]) && $groupSettings["take"] >= 0) {
|
||
$result = array_slice($result, $groupSettings["skip"], $groupSettings["take"]);
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
private static function getDateGroupIndices($groupNames) {
|
||
$yearIndex = -1;
|
||
$monthIndex = -1;
|
||
$dayIndex = -1;
|
||
|
||
foreach ($groupNames as $index => $name) {
|
||
if (strpos($name, 'dx_') === 0) {
|
||
if (strpos($name, '_year') !== false) {
|
||
$yearIndex = $index;
|
||
} else if (strpos($name, '_month') !== false) {
|
||
$monthIndex = $index;
|
||
} else if (strpos($name, '_day') !== false) {
|
||
$dayIndex = $index;
|
||
}
|
||
}
|
||
}
|
||
|
||
return [
|
||
'year' => $yearIndex,
|
||
'month' => $monthIndex,
|
||
'day' => $dayIndex
|
||
];
|
||
}
|
||
public static function IsLastGroupExpanded($items) {
|
||
$result = true;
|
||
$itemsCount = count($items);
|
||
if ($itemsCount > 0) {
|
||
$lastItem = $items[$itemsCount - 1];
|
||
if (gettype($lastItem) === "object") {
|
||
$result = isset($lastItem->isExpanded) ? $lastItem->isExpanded === true : true;
|
||
}
|
||
else {
|
||
$result = true;
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
public static function GetFieldSetBySelectors($items) {
|
||
$group = "";
|
||
$sort = "";
|
||
$select = "";
|
||
foreach ($items as $item) {
|
||
$groupField = NULL;
|
||
$sortField = NULL;
|
||
$selectField = NULL;
|
||
$desc = false;
|
||
if (is_string($item) && strlen($item = trim($item))) {
|
||
$selectField = $groupField = $sortField = Utils::QuoteStringValue($item);
|
||
}
|
||
else if (gettype($item) === "object" && isset($item->selector)) {
|
||
$quoteSelector = Utils::QuoteStringValue($item->selector);
|
||
$desc = isset($item->desc) ? $item->desc : false;
|
||
|
||
// Tarih gruplamalarını düzenle
|
||
if (isset($item->groupInterval)) {
|
||
if (is_int($item->groupInterval)) {
|
||
$groupField = Utils::QuoteStringValue(sprintf("%s%s_%d", self::GENERATED_FIELD_PREFIX, $item->selector, $item->groupInterval));
|
||
$selectField = sprintf("(%s - (%s %% %d)) %s %s",
|
||
$quoteSelector,
|
||
$quoteSelector,
|
||
$item->groupInterval,
|
||
self::AS_OP,
|
||
$groupField);
|
||
}
|
||
else {
|
||
// Tarih gruplamalarını düzgün şekilde yap
|
||
$interval = strtolower($item->groupInterval);
|
||
$groupField = Utils::QuoteStringValue(sprintf("%s%s_%s", self::GENERATED_FIELD_PREFIX, $item->selector, $interval));
|
||
|
||
if ($interval == 'year') {
|
||
$selectField = sprintf("YEAR(%s) %s %s",
|
||
$quoteSelector,
|
||
self::AS_OP,
|
||
$groupField);
|
||
}
|
||
else if ($interval == 'month') {
|
||
$selectField = sprintf("MONTH(%s) %s %s",
|
||
$quoteSelector,
|
||
self::AS_OP,
|
||
$groupField);
|
||
}
|
||
else if ($interval == 'day') {
|
||
$selectField = sprintf("DAY(%s) %s %s",
|
||
$quoteSelector,
|
||
self::AS_OP,
|
||
$groupField);
|
||
}
|
||
else if ($interval == 'dayofweek') {
|
||
$selectField = sprintf("DAYOFWEEK(%s) - 1 %s %s",
|
||
$quoteSelector,
|
||
self::AS_OP,
|
||
$groupField);
|
||
}
|
||
else {
|
||
$selectField = sprintf("%s(%s) %s %s",
|
||
strtoupper($interval),
|
||
$quoteSelector,
|
||
self::AS_OP,
|
||
$groupField);
|
||
}
|
||
}
|
||
$sortField = $groupField;
|
||
}
|
||
else {
|
||
$selectField = $groupField = $sortField = $quoteSelector;
|
||
}
|
||
}
|
||
if (isset($selectField)) {
|
||
$select .= (strlen($select) > 0 ? ", ".$selectField : $selectField);
|
||
}
|
||
if (isset($groupField)) {
|
||
$group .= (strlen($group) > 0 ? ", ".$groupField : $groupField);
|
||
}
|
||
if (isset($sortField)) {
|
||
$sort .= (strlen($sort) > 0 ? ", ".$sortField : $sortField).
|
||
($desc ? " DESC" : "");
|
||
}
|
||
}
|
||
return array(
|
||
"group" => $group,
|
||
"sort" => $sort,
|
||
"select" => $select
|
||
);
|
||
}
|
||
private static function _IsSummaryTypeValid($summaryType) {
|
||
return in_array($summaryType, array(self::MIN_OP, self::MAX_OP, self::AVG_OP, self::COUNT_OP, self::SUM_OP));
|
||
}
|
||
public static function GetSummaryInfo($expression, $tableName = null) {
|
||
$result = array();
|
||
$fields = "";
|
||
$summaryTypes = array();
|
||
foreach ($expression as $index => $item) {
|
||
if (gettype($item) === "object" && isset($item->summaryType)) {
|
||
$summaryType = strtoupper(trim($item->summaryType));
|
||
if (!self::_IsSummaryTypeValid($summaryType)) {
|
||
continue;
|
||
}
|
||
$summaryTypes[] = $summaryType;
|
||
$selector = (isset($item->selector) && is_string($item->selector)) ? $item->selector : null;
|
||
$quotedSelector = isset($selector) ? Utils::QuoteStringValue($selector) : "1";
|
||
if (self::shouldApplyWeldedFilter($tableName, $item, $summaryType)) {
|
||
$quotedSelector = self::applyWeldedFilterExpression($quotedSelector, $summaryType);
|
||
}
|
||
$fields .= sprintf("%s(%s) %s %sf%d",
|
||
strlen($fields) > 0 ? ", ".$summaryType : $summaryType,
|
||
$quotedSelector,
|
||
self::AS_OP,
|
||
self::GENERATED_FIELD_PREFIX,
|
||
$index);
|
||
}
|
||
}
|
||
$result["fields"] = $fields;
|
||
$result["summaryTypes"] = $summaryTypes;
|
||
return $result;
|
||
}
|
||
|
||
private static function shouldApplyWeldedFilter($tableName, $item, $summaryType) {
|
||
if ($tableName !== 'weld_logs') {
|
||
return false;
|
||
}
|
||
|
||
$hasExplicitFlag = isset($item->weldedOnly) && $item->weldedOnly;
|
||
$forceByContext = SummaryContext::shouldExcludeMechanical();
|
||
|
||
if (!$hasExplicitFlag && !$forceByContext) {
|
||
return false;
|
||
}
|
||
|
||
return in_array($summaryType, [self::SUM_OP, self::AVG_OP]);
|
||
}
|
||
|
||
private static function getMechanicalTypesList() {
|
||
static $cachedList = null;
|
||
if ($cachedList !== null) {
|
||
return $cachedList;
|
||
}
|
||
|
||
if (function_exists('get_mechanical_joint_types')) {
|
||
$types = get_mechanical_joint_types();
|
||
} else {
|
||
$types = ['BJ', 'FJ', 'TH', 'CJ'];
|
||
}
|
||
|
||
$escaped = array_map(function($type) {
|
||
$normalized = strtoupper(trim($type));
|
||
return "'" . addslashes($normalized) . "'";
|
||
}, $types);
|
||
|
||
$cachedList = implode(",", $escaped);
|
||
if ($cachedList === '') {
|
||
$cachedList = "''";
|
||
}
|
||
|
||
return $cachedList;
|
||
}
|
||
|
||
private static function applyWeldedFilterExpression($quotedSelector, $summaryType) {
|
||
$mechanicalList = self::getMechanicalTypesList();
|
||
$typeColumnExpr = "UPPER(TRIM(COALESCE(`type_of_welds`, '')))";
|
||
$thenValue = $summaryType === self::AVG_OP ? "NULL" : "0";
|
||
return sprintf(
|
||
"CASE WHEN %s IN (%s) THEN %s ELSE %s END",
|
||
$typeColumnExpr,
|
||
$mechanicalList,
|
||
$thenValue,
|
||
$quotedSelector
|
||
);
|
||
}
|
||
}
|