1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
reportbuilder.php
См. документацию.
1<?php
2
3namespace Bitrix\Seo\Analytics\Services\Helpers\Yandex;
4
5use Bitrix\Main;
6use Bitrix\Seo;
7
8final class ReportBuilder
9{
10 private Dto\ReportCollection $reportCollection;
11 private Dto\AdCollection $adCollection;
12
13 private Sender $sender;
14
15 private Main\Type\Date $dateTo;
16 private Main\Type\Date $dateFrom;
17 private ?string $currency = null;
18
19 public function __construct(Sender $sender)
20 {
21 $this->sender = $sender;
22
23 $this->initDefaultPeriod();
24 }
25
26 private function getSender(): Sender
27 {
28 return $this->sender;
29 }
30
36 private function initDefaultPeriod(): void
37 {
38 $this->dateTo = new Main\Type\Date();
39
40 $this->dateFrom = new Main\Type\Date();
41 $this->dateFrom->add('-1 week');
42 }
43
44 public function setPeriod(?Main\Type\Date $dateFrom, ?Main\Type\Date $dateTo): self
45 {
46 if ($dateFrom)
47 {
48 $this->dateFrom = $dateFrom;
49 }
50
51 if ($dateTo)
52 {
53 $this->dateTo = $dateTo;
54 }
55
56 return $this;
57 }
58
59 public function buildDailyExpensesReport(): Main\Result
60 {
61 $result = new Main\Result();
62
63 $this->reportCollection = new Dto\ReportCollection();
64 $this->adCollection = new Dto\AdCollection();
65
66 $this->currency = $this->getSender()->getCurrency();
67
68 $reportResult = $this->loadReports();
69 if (!$reportResult->isSuccess())
70 {
71 return $result->addErrors($reportResult->getErrors());
72 }
73
74 $campaignIds = $this->reportCollection->getUniqCampaignIds();
75
76 $adResult = $this->loadAds($campaignIds);
77 if (!$adResult->isSuccess())
78 {
79 $result->addErrors($adResult->getErrors());
80
81 return $result;
82 }
83
84 $expensesCollection = new Seo\Analytics\Internals\ExpensesCollection();
86 foreach ($this->reportCollection as $report)
87 {
88 $expensesCollection->addItem(new Seo\Analytics\Internals\Expenses($this->formatExpensesData($report)));
89 }
90
91 $result->setData(['expenses' => $expensesCollection]);
92
93 return $result;
94 }
95
96 private function loadReports(): Main\Result
97 {
98 $result = new Main\Result();
99
101 $reportResult = $this->getSender()->getDailyExpensesReport($this->dateFrom, $this->dateTo);
102 if ($reportResult->isSuccess())
103 {
104 foreach ($this->parseReportData((string)$reportResult->getResponse()) as $report)
105 {
106 $this->reportCollection->addItem(Dto\Report::makeFromArray($report));
107 }
108 }
109 else
110 {
111 $result->addErrors($reportResult->getErrors());
112 }
113
114 return $result;
115 }
116
117 private function loadAds(array $campaignIds): Main\Result
118 {
119 $result = new Main\Result();
120
121 $campaignIdsForRequest = [];
122
123 $cache = Main\Data\Cache::createInstance();
124 $cacheDir = '/biconnector/integration/crm/dailyexpenses/yandex/ads';
125 $cacheTtl = 86400; // 60 * 60 * 24
126
127 foreach ($campaignIds as $campaignId)
128 {
129 $cacheName = (string)$campaignId;
130
131 if ($cache->initCache($cacheTtl, $cacheName, $cacheDir . '/' . $cacheName))
132 {
133 $cacheDataAds = $cache->getVars();
134 foreach ($cacheDataAds as $cacheDataAd)
135 {
136 $this->adCollection->set((int)$cacheDataAd['Id'], Dto\Ad::makeFromArray($cacheDataAd));
137 }
138 }
139 else
140 {
141 $campaignIdsForRequest[] = $campaignId;
142 }
143 }
144
145 $adsForCache = [];
146
147 foreach (array_chunk($campaignIdsForRequest, 10) as $chunkCampaignIds)
148 {
149 $adResult = $this->getSender()->getAds($chunkCampaignIds);
150 if ($adResult->isSuccess())
151 {
152 $response = $adResult->getResponse();
153 if (isset($response['result']['Ads']))
154 {
155 foreach ($response['result']['Ads'] as $ad)
156 {
157 $this->adCollection->set((int)$ad['Id'], Dto\Ad::makeFromArray($ad));
158 $adsForCache[(int)$ad['CampaignId']][(int)$ad['Id']] = $ad;
159 }
160 }
161 }
162 else
163 {
164 $result->addErrors($adResult->getErrors());
165
166 return $result;
167 }
168 }
169
170 foreach ($campaignIdsForRequest as $campaignId)
171 {
172 $cacheName = (string)$campaignId;
173
174 $cache->initCache($cacheTtl, $cacheName, $cacheDir . '/' . $cacheName);
175 $cache->startDataCache();
176 $cache->endDataCache($adsForCache[$campaignId] ?? []);
177 }
178
179 return $result;
180 }
181
182 private function parseReportData(string $data): \Generator
183 {
184 if (empty($data))
185 {
186 return;
187 }
188
189 $titles = [];
190 $strings = explode("\n", $data);
191 foreach ($strings as $number => $string)
192 {
193 if ($number === 0)
194 {
195 $titles = explode("\t", $string);
196 }
197 elseif (!empty($string) && !str_starts_with($string, 'Total'))
198 {
199 yield array_combine($titles, explode("\t", $string));
200 }
201 }
202 }
203
204 private function formatExpensesData(Dto\Report $report): array
205 {
207 $ad = $this->adCollection->get($report->adId);
208 if ($ad?->href)
209 {
210 DynamicParamFiller::fill($report, $ad->href);
211 }
212
213 $cpm = 0;
214 if ($report->impressions > 0)
215 {
216 $cpm = round(($report->cost / $report->impressions) * 1000, 2);
217 }
218
219 return [
220 'impressions' => $report->impressions,
221 'campaignName' => $report->campaignName,
222 'adId' => $report->adId,
223 'adName' => $ad?->title,
224 'groupId' => $report->adGroupId,
225 'groupName' => $report->adGroupName,
226 'campaignId' => $report->campaignId,
227 'clicks' => $report->clicks,
228 'actions' => $report->conversions + $report->clicks,
229 'spend' => $report->cost,
230 'cpc' => $report->avgCpc,
231 'date' => $report->date,
232 'cpm' => $cpm,
233 'currency' => $this->currency,
234 'utmSource' => $report->utmSource,
235 'utmMedium' => $report->utmMedium,
236 'utmCampaign' => $report->utmCampaign,
237 'utmContent' => $report->utmContent,
238 ];
239 }
240}
Определения result.php:20
Определения date.php:9
static fill(Dto\Report $report, string $href)
Определения dynamicparamfiller.php:7
setPeriod(?Main\Type\Date $dateFrom, ?Main\Type\Date $dateTo)
Определения reportbuilder.php:44
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
Определения collection.php:2
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$currency
Определения template.php:266
$response
Определения result.php:21