Scalr\Stats\CostAnalytics\Usage::getFarmPeriodData PHP Метод

getFarmPeriodData() публичный Метод

Gets analytics data for the specified farm and period
public getFarmPeriodData ( integer $farmId, Scalr_Environment $environment, string $mode, string $startDate, string $endDate ) : array
$farmId integer The identifier of the Farm
$environment Scalr_Environment Current environment
$mode string Mode (week, month, quarter, year, custom)
$startDate string Start date in UTC (Y-m-d)
$endDate string End date in UTC (Y-m-d)
Результат array Returns analytics data for the specified farm and period
    public function getFarmPeriodData($farmId, Scalr_Environment $environment, $mode, $startDate, $endDate)
    {
        $utcTz = new DateTimeZone('UTC');
        $iterator = ChartPeriodIterator::create($mode, new DateTime($startDate, $utcTz), new DateTime($endDate, $utcTz), 'UTC');
        $start = $iterator->getStart();
        $end = $iterator->getEnd();
        $dbFarm = new DBFarm($farmId);
        $projectId = $dbFarm->GetSetting('project_id');
        //Interval which is used in the database query for grouping
        $queryInterval = preg_replace('/^1 /', '', $iterator->getInterval());
        $criteria = ['farmId' => $farmId, 'envId' => $environment->id];
        //Requests data for the specified period
        $rawUsage = $this->getFarmData($environment->clientId, $criteria, $start, $end, [$queryInterval, TagEntity::TAG_ID_FARM_ROLE], true);
        //Requests data for the previous period
        $rawPrevUsage = $this->getFarmData($environment->clientId, $criteria, $iterator->getPreviousStart(), $iterator->getPreviousEnd(), [$queryInterval, TagEntity::TAG_ID_FARM_ROLE], true);
        $usgByInstanceDetailed = (new AggregationCollection(['period', 'farmRoleId'], ['cost' => 'sum']))->load($rawUsage)->calculatePercentage();
        $usgByInstancePrevDetailed = (new AggregationCollection(['period', 'farmRoleId'], ['cost' => 'sum']))->load($rawPrevUsage)->calculatePercentage();
        $quarterIterator = $this->getCurrentQuarterIterator();
        $queryQuarterInterval = preg_replace('/^1 /', '', $quarterIterator->getInterval());
        $rawQuarterUsage = $this->getFarmData($environment->clientId, $criteria, $quarterIterator->getStart(), $quarterIterator->getEnd(), [TagEntity::TAG_ID_FARM_ROLE], true);
        $itemsRollingAvg = $this->getRollingAvg(['farmId' => $farmId], $queryQuarterInterval, $quarterIterator->getEnd(), $environment->clientId, $rawQuarterUsage);
        $farmRolesData = [];
        $timeline = [];
        $prevPointKey = null;
        foreach ($iterator as $chartPoint) {
            /* @var $chartPoint \Scalr\Stats\CostAnalytics\ChartPointInfo */
            $i = $chartPoint->i;
            $currentPeriodTotal = isset($usgByInstanceDetailed['data'][$chartPoint->key]) ? $usgByInstanceDetailed['data'][$chartPoint->key] : null;
            $ppTotal = isset($usgByInstancePrevDetailed['data'][$chartPoint->previousPeriodKey]) ? $usgByInstancePrevDetailed['data'][$chartPoint->previousPeriodKey] : null;
            $pptTotal = isset($usgByInstanceDetailed['data'][$prevPointKey]) ? $usgByInstanceDetailed['data'][$prevPointKey] : null;
            $pointDataTotal = $this->getPointDataArray($currentPeriodTotal, $ppTotal, $pptTotal);
            $timeline[] = ['datetime' => $chartPoint->dt->format('Y-m-d H:00'), 'label' => $chartPoint->label, 'onchart' => $chartPoint->show, 'events' => null] + $pointDataTotal;
            //Period - FarmRoles subtotals
            if (!isset($usgByInstanceDetailed['data'][$chartPoint->key]['data'])) {
                foreach ($farmRolesData as $farmRoleId => $v) {
                    if (!$iterator->isFuture()) {
                        //Previous period details
                        if (isset($usgByInstancePrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$farmRoleId])) {
                            $pp = $usgByInstancePrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$farmRoleId];
                        } else {
                            $pp = null;
                        }
                        //Previous point details
                        if (isset($usgByInstanceDetailed['data'][$prevPointKey]['data'][$farmRoleId])) {
                            $ppt = $usgByInstanceDetailed['data'][$prevPointKey]['data'][$farmRoleId];
                        } else {
                            $ppt = null;
                        }
                        $r = $this->getPointDataArray(null, $pp, $ppt);
                        $farmRolesData[$farmRoleId]['name'] = AccountTagEntity::fetchName($farmRoleId, TagEntity::TAG_ID_FARM_ROLE);
                        $farmRolesData[$farmRoleId]['data'][] = $r;
                    } else {
                        $farmRolesData[$farmRoleId]['data'][] = null;
                    }
                }
            } else {
                //Initializes with empty values to prevent data shifts on charts.
                if (!isset($usgByInstanceDetailed['data'][$chartPoint->key]['data'])) {
                    $usgByInstanceDetailed['data'][$chartPoint->key]['data'] = [];
                }
                $combined =& $usgByInstanceDetailed['data'][$chartPoint->key]['data'];
                if (!empty($farmRolesData)) {
                    foreach ($farmRolesData as $farmRoleId => $t) {
                        if (!array_key_exists($farmRoleId, $combined)) {
                            $combined[$farmRoleId] = [];
                        }
                    }
                }
                foreach ($combined as $farmRoleId => $v) {
                    //Previous period details
                    if (isset($usgByInstancePrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$farmRoleId])) {
                        $pp = $usgByInstancePrevDetailed['data'][$chartPoint->previousPeriodKey]['data'][$farmRoleId];
                    } else {
                        $pp = null;
                    }
                    //Previous point details
                    if (isset($usgByInstanceDetailed['data'][$prevPointKey]['data'][$farmRoleId])) {
                        $ppt = $usgByInstanceDetailed['data'][$prevPointKey]['data'][$farmRoleId];
                    } else {
                        $ppt = null;
                    }
                    if (!isset($farmRolesData[$farmRoleId]) && $i > 0) {
                        $farmRolesData[$farmRoleId]['name'] = AccountTagEntity::fetchName($farmRoleId, TagEntity::TAG_ID_FARM_ROLE);
                        $farmRolesData[$farmRoleId]['data'] = array_fill(0, $i, null);
                    }
                    if (!$iterator->isFuture()) {
                        $r = $this->getPointDataArray($v, $pp, $ppt);
                        $farmRolesData[$farmRoleId]['name'] = AccountTagEntity::fetchName($farmRoleId, TagEntity::TAG_ID_FARM_ROLE);
                        $farmRolesData[$farmRoleId]['data'][] = $r;
                    } else {
                        $farmRolesData[$farmRoleId]['data'][] = null;
                    }
                }
            }
            $prevPointKey = $chartPoint->key;
        }
        $cntpoints = count($timeline);
        foreach ($farmRolesData as $farmRoleId => $v) {
            if (($j = count($v['data'])) < $cntpoints) {
                while ($j < $cntpoints) {
                    $farmRolesData[$farmRoleId]['data'][] = null;
                    $j++;
                }
            }
        }
        //Subtotals by usageItem
        $usage = (new AggregationCollection(['farmRoleId' => ['cloudLocation', 'platform']], ['cost' => 'sum']))->load($rawUsage)->calculatePercentage();
        //Previous period subtotals by usageItem
        $prevUsage = (new AggregationCollection(['farmRoleId'], ['cost' => 'sum']))->load($rawPrevUsage)->calculatePercentage();
        if ($iterator->getWholePreviousPeriodEnd() != $iterator->getPreviousEnd()) {
            $rawPrevUsageWhole = $this->getFarmData($environment->clientId, $criteria, $iterator->getPreviousStart(), $iterator->getWholePreviousPeriodEnd(), [TagEntity::TAG_ID_FARM_ROLE], true);
            //Previous whole period usage subtotals by farm role
            $prevUsageWhole = (new AggregationCollection(['farmRoleId'], ['cost' => 'sum']))->load($rawPrevUsageWhole);
        } else {
            $prevUsageWhole = $prevUsage;
        }
        //Build farm roles total
        $farmRolesTotal = [];
        $it = $usage->getIterator();
        foreach ($it as $farmRoleId => $p) {
            $pp = isset($prevUsage['data'][$farmRoleId]) ? $prevUsage['data'][$farmRoleId] : null;
            $pw = isset($prevUsageWhole['data'][$farmRoleId]) ? $prevUsageWhole['data'][$farmRoleId] : null;
            $frPrev = $this->getTotalDataArray($farmRoleId, AccountTagEntity::fetchName($farmRoleId, TagEntity::TAG_ID_FARM_ROLE), $p, $pp, $pw, $farmRolesData, $iterator);
            $frPrev['platform'] = $p['platform'];
            $frPrev['cloudLocation'] = $p['cloudLocation'];
            $farmRolesTotal[] = $frPrev;
        }
        //Subtotals by distr types
        $usage3 = (new AggregationCollection(['distributionType'], ['cost' => 'sum']))->load($this->getFarmData($environment->clientId, $criteria, $start, $end, ['distributionType', 'usageType', 'usageItem'], true))->calculatePercentage();
        // Build cost dist types total
        $distributionTypesTotal = [];
        foreach ($usage3->getIterator() as $distributionType => $costUsage) {
            $distributionTypesTotal[] = $this->getTotalDataArray($distributionType, $distributionType, $costUsage, null, null, [], null, true);
        }
        $data = ['totals' => ['cost' => round($usage['cost'], 2), 'prevCost' => round($prevUsage['cost'], 2), 'growth' => round($usage['cost'] - $prevUsage['cost'], 2), 'growthPct' => $prevUsage['cost'] == 0 ? null : round(abs(($usage['cost'] - $prevUsage['cost']) / $prevUsage['cost'] * 100), 0), 'farmRoles' => $farmRolesTotal, 'distributionTypes' => $distributionTypesTotal, 'trends' => $this->calculateSpendingTrends(['farmId' => $farmId], $timeline, $queryInterval, $iterator->getEnd(), $environment->clientId), 'forecastCost' => null], 'timeline' => $timeline, 'farmRoles' => $farmRolesData, 'interval' => $queryInterval, 'startDate' => $iterator->getStart()->format('Y-m-d'), 'endDate' => $iterator->getEnd()->format('Y-m-d'), 'previousStartDate' => $iterator->getPreviousStart()->format('Y-m-d'), 'previousEndDate' => $iterator->getPreviousEnd()->format('Y-m-d')];
        if ($iterator->getTodayDate() < $iterator->getEnd()) {
            //Today is in the selected period
            $data['totals']['forecastCost'] = self::calculateForecast($data['totals']['cost'], $start, $end, $prevUsageWhole['cost'], ($data['totals']['growth'] >= 0 ? 1 : -1) * $data['totals']['growthPct'], isset($itemsRollingAvg['rollingAverageDaily']) ? $itemsRollingAvg['rollingAverageDaily'] : null);
        }
        $budgetRequest = ['projectId' => $projectId, 'usage' => $data['totals']['cost']];
        if ($mode != 'custom') {
            //We need to get budget for the appropriate quarter
            $budgetRequest['period'] = $iterator->getQuarterPeriod();
        }
        $budget = $this->getBudgetUsedPercentage($budgetRequest);
        $this->calculateBudgetEstimateOverspend($budget);
        $data['totals']['budget'] = $budget;
        return $data;
    }