Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
countercalculation.php
1<?php
10
15
17{
18 private static $optionName = '~update_counters_16';
19 public static $maxExecutionTime = 10;
20 private static $startTime = null;
21 private static $stages = array(
22 'RECIPIENT_READ' => '1',
23 'RECIPIENT_CLICK' => '2',
24 'RECIPIENT_UNSUB' => '3',
25 'POSTING_STATUS' => '4',
26 'POSTING_READ' => '5',
27 'POSTING_CLICK' => '6',
28 'POSTING_UNSUB' => '7',
29 'MAILING_SUBSCRIPTION' => '8',
30 'CONTACT_EMAIL_REGISTER' => '9',
31 'FINISH' => '',
32 );
33
34 public static function wasCompleted($stageCode = 'FINISH')
35 {
36 $currentValue = Option::get('sender', self::$optionName, '');
37 $stageValue = self::$stages[$stageCode];
38
39 if($currentValue === '')
40 {
41 $currentValue = '100';
42 }
43 if($stageValue === '')
44 {
45 $stageValue = '100';
46 }
47
48 if(intval($currentValue) >= intval($stageValue))
49 {
50 return true;
51 }
52 else
53 {
54 return false;
55 }
56 }
57
58 public static function setCompleted($stageCode = 'FINISH')
59 {
60 Option::set('sender', self::$optionName, self::$stages[$stageCode]);
61 }
62
63 public static function getCompletedPercent()
64 {
65 $currentValue = Option::get('sender', self::$optionName, '');
66 if($currentValue === '')
67 {
68 $currentValue = count(self::$stages);
69 }
70 $currentValue = intval($currentValue);
71
72 return array('CURRENT' => $currentValue, 'ALL' => count(self::$stages));
73 }
74
75 private static function isTimeUp()
76 {
77 if(self::$startTime === null)
78 {
79 self::$startTime = getmicrotime();
80 }
81
82 if(self::$maxExecutionTime > 0 && (getmicrotime() - self::$startTime) > self::$maxExecutionTime)
83 {
84 return true;
85 }
86 else
87 {
88 return false;
89 }
90 }
91
92 public static function getExecutionTime()
93 {
94 if(!self::$startTime)
95 {
96 return 0;
97 }
98 else
99 {
100 return getmicrotime() - self::$startTime;
101 }
102 }
103
104 public static function update()
105 {
106 if(self::wasCompleted())
107 {
108 return false;
109 }
110
111 $haveData = false;
112
113 // update reading counters of recipients
114 foreach(array('READ', 'CLICK', 'UNSUB') as $type)
115 {
116 if($haveData || self::wasCompleted('RECIPIENT_' . $type))
117 {
118 continue;
119 }
120
121 $haveData = self::updateRecipientReadCounters($type);
122 if(!$haveData)
123 {
124 self::setCompleted('RECIPIENT_' . $type);
125 }
126 }
127
128 // update status counters of posting
129 if(!$haveData && !self::wasCompleted('POSTING_STATUS'))
130 {
132 if(!$haveData)
133 {
134 self::setCompleted('POSTING_STATUS');
135 }
136 }
137
138 // update reading counters of posting
139 foreach(array('READ', 'CLICK', 'UNSUB') as $type)
140 {
141 if($haveData || self::wasCompleted('POSTING_' . $type))
142 {
143 continue;
144 }
145
146 $haveData = self::updatePostingReadCounters($type);
147 if(!$haveData)
148 {
149 self::setCompleted('POSTING_' . $type);
150 }
151 }
152
153 // update status counters of posting
154 if(!$haveData && !self::wasCompleted('MAILING_SUBSCRIPTION'))
155 {
157 if(!$haveData)
158 {
159 self::setCompleted('MAILING_SUBSCRIPTION');
160 }
161 }
162
163 // update contact email register
164 if(!$haveData && !self::wasCompleted('CONTACT_EMAIL_REGISTER'))
165 {
167 if(!$haveData)
168 {
169 self::setCompleted('CONTACT_EMAIL_REGISTER');
170 }
171 }
172
173 // if all processed set done flag
174 if(!$haveData)
175 {
177 }
178
179 return $haveData;
180 }
181
182 public static function updateRecipientReadCounters($type)
183 {
184 $params = array(
185 'select' => array('RECIPIENT_ID'),
186 'runtime' => array(
187 new \Bitrix\Main\Entity\ReferenceField(
188 'UPDATE_RECIPIENT',
189 'Bitrix\Sender\PostingRecipientTable',
190 array('=this.RECIPIENT_ID' => 'ref.ID')
191 )
192 ),
193 'filter' => array(
194 '!UPDATE_RECIPIENT.ID' => null,
195 '=UPDATE_RECIPIENT.IS_' . $type => 'N',
196 ),
197 'group' => array('RECIPIENT_ID')
198 );
199 $dataDb = null;
200 switch($type)
201 {
202 case 'READ':
203 $dataDb = \Bitrix\Sender\PostingReadTable::getList($params);
204 break;
205 case 'CLICK':
206 $dataDb = \Bitrix\Sender\PostingClickTable::getList($params);
207 break;
208 case 'UNSUB':
209 $dataDb = \Bitrix\Sender\PostingUnsubTable::getList($params);
210 break;
211 }
212
213 if(!$dataDb)
214 {
215 return false;
216 }
217
218 while($item = $dataDb->fetch())
219 {
220 if(self::isTimeUp())
221 {
222 return true;
223 }
224
225 Model\Posting\RecipientTable::update($item['RECIPIENT_ID'], ['IS_' . $type => 'Y']);
226 }
227
228 return false;
229 }
230
231 public static function updatePostingStatusCounters()
232 {
233 $lastPostingId = null;
234 $statusList = array();
235
236 $resultDb = \Bitrix\Sender\PostingRecipientTable::getList(array(
237 'select' => array('POSTING_ID', 'STATUS', 'CALC_COUNT'),
238 'filter' => array(
239 '!UPDATE_POSTING.ID' => null,
240 '!STATUS' => null,
241 '=UPDATE_POSTING.COUNT_SEND_ALL' => 0, // run only for postings with empty count field
242 '>CALC_COUNT' => 0 // run only if posting have recipients
243 ),
244 'runtime' => array(
245 new \Bitrix\Main\Entity\ExpressionField('CALC_COUNT', 'COUNT(%s)', 'ID'),
246 new \Bitrix\Main\Entity\ReferenceField(
247 'UPDATE_POSTING',
248 'Bitrix\Sender\PostingTable',
249 array('=this.POSTING_ID' => 'ref.ID'),
250 array('join_type' => 'INNER')
251 ),
252 ),
253 'order' => array('CALC_COUNT' => 'DESC', 'POSTING_ID' => 'ASC'),
254 ));
255 $stopRun = false;
256 while(!$stopRun)
257 {
258 if(self::isTimeUp())
259 {
260 return true;
261 }
262
263 $data = $resultDb->fetch();
264
265 // do update if last record or starts records for another posting
266 if(!$data || $lastPostingId != $data['POSTING_ID'])
267 {
268 // do update if it have fields for update
269 $updateFields = self::getPostingStatusUpdateFields($lastPostingId, $statusList);
270 if($updateFields)
271 {
272 Model\PostingTable::update($lastPostingId, $updateFields);
273 }
274
275
276 $statusList = array();
277 }
278
279 if($data)
280 {
281 $lastPostingId = $data['POSTING_ID'];
282 $statusList[$data['STATUS']] = $data['CALC_COUNT'];
283 }
284
285 if(!$data)
286 {
287 $stopRun = true;
288 }
289
290
291 }
292
293
294 return false;
295 }
296
297 public static function updatePostingReadCounters($type)
298 {
299 $dataDb = \Bitrix\Sender\PostingRecipientTable::getList(array(
300 'select' => array(
301 'POSTING_ID',
302 'CNT'
303 ),
304 'filter' => array(
305 '=UPDATE_POSTING.COUNT_' . $type => 0,
306 '>CNT' => 0,
307 '=IS_' . $type => 'Y'
308 ),
309 'runtime' => array(
310 new \Bitrix\Main\Entity\ReferenceField(
311 'UPDATE_POSTING',
312 'Bitrix\Sender\PostingTable',
313 array('=this.POSTING_ID' => 'ref.ID'),
314 array('join_type' => 'INNER')
315 ),
316 new \Bitrix\Main\Entity\ExpressionField('CNT', 'COUNT(%s)', 'ID')
317 ),
318 'order' => array('CNT' => 'DESC', 'POSTING_ID' => 'ASC'),
319 ));
320
321 while($item = $dataDb->fetch())
322 {
323 if(self::isTimeUp())
324 {
325 return true;
326 }
327
328 Model\PostingTable::update($item['POSTING_ID'], array('COUNT_' . $type => $item['CNT']));
329 }
330
331 return false;
332 }
333
334 public static function updateMailingSubscription()
335 {
336 $dataDb = \Bitrix\Sender\PostingUnsubTable::getList(array(
337 'select' => array(
338 'CONTACT_ID' => 'POSTING_RECIPIENT.CONTACT_ID',
339 'MAILING_ID' => 'POSTING.MAILING_ID',
340 ),
341 'filter' => array(),
342 'order' => array('ID' => 'ASC'),
343 ));
344 while($data = $dataDb->fetch())
345 {
346 if(self::isTimeUp())
347 {
348 return true;
349 }
350
351 $primary = array('MAILING_ID' => $data['MAILING_ID'], 'CONTACT_ID' => $data['CONTACT_ID']);
352 $fields = array('IS_UNSUB' => 'Y');
353 $row = \Bitrix\Sender\MailingSubscriptionTable::getRowById($primary);
354 if(!$row)
355 {
356 $result = \Bitrix\Sender\MailingSubscriptionTable::add($fields + $primary);
357 $result->isSuccess();
358 }
359 }
360
361 return false;
362 }
363
364 public static function updateContactEmailRegister()
365 {
366 $connection = \Bitrix\Main\Application::getConnection();
367 switch(mb_strtoupper($connection->getType()))
368 {
369 case 'MSSQL':
370 $query = "SELECT ID FROM b_sender_contact WHERE TYPE_ID=1 AND CODE LIKE '%[A-Z]%' COLLATE Latin1_General_BIN";
371 break;
372 case 'MYSQL':
373 $query = "SELECT ID FROM b_sender_contact WHERE TYPE_ID=1 AND CODE REGEXP BINARY '[A-Z]'";
374 break;
375 case 'ORACLE':
376 $query = "SELECT ID FROM b_sender_contact WHERE TYPE_ID=1 AND REGEXP_LIKE(CODE, '[A-Z]')";
377 break;
378 default:
379 $helper = $connection->getSqlHelper();
380 $query = "SELECT ID FROM b_sender_contact WHERE TYPE_ID=1 AND {$helper->getRegexpOperator('CODE', "'[A-Z]'")}";
381 }
382
383 $senderContactDb = $connection->query($query);
384 while ($senderContact = $senderContactDb->fetch())
385 {
386 if (self::isTimeUp())
387 {
388 return true;
389 }
390
391 $connection->Query("UPDATE b_sender_contact SET CODE = LOWER(CODE) WHERE TYPE_ID=1 AND ID = " . intval($senderContact['ID']));
392 }
393
394 return false;
395 }
396
397 private static function getPostingStatusUpdateFields($postingId, $statusList)
398 {
399 if(!$postingId || count($statusList) == 0)
400 {
401 return null;
402 }
403
404 $postingUpdateFields = array('COUNT_SEND_ALL' => 0);
405
406 $map = \Bitrix\Sender\PostingTable::getRecipientStatusToPostingFieldMap();
407 foreach($map as $recipientStatus => $postingFieldName)
408 {
409 if(!array_key_exists($recipientStatus, $statusList))
410 {
411 continue;
412 }
413 else
414 {
415 $postingCountFieldValue = $statusList[$recipientStatus];
416 }
417
418 $postingUpdateFields['COUNT_SEND_ALL'] += $postingCountFieldValue;
419 $postingUpdateFields[$postingFieldName] = $postingCountFieldValue;
420 }
421
422 if($postingUpdateFields['COUNT_SEND_ALL'] == 0)
423 {
424 return null;
425 }
426
427 return $postingUpdateFields;
428 }
429
435 public static function updateRecipientsAgent()
436 {
438
439 $hasData = false;
440 if ($conn->isTableExists('b_sender_posting_rcpnt_old'))
441 {
442 $limit = 1000;
443 $timer = new Runtime\Timer(Runtime\Env::getJobExecutionTimeout(), 100);
444 while (!$timer->isElapsed())
445 {
446 $hasData = true;
447 $sql = "INSERT IGNORE
448 INTO b_sender_posting_recipient
449 (
450 CONTACT_ID,
451 POSTING_ID,
452 STATUS,
453 USER_ID,
454 FIELDS,
455 ROOT_ID,
456 IS_READ,
457 IS_CLICK,
458 IS_UNSUB,
459 DATE_DENY,
460 DATE_SENT
461 )
462 SELECT
463 c.ID as CONTACT_ID,
464 ro2.POSTING_ID,
465 ro2.STATUS,
466 ro2.USER_ID,
467 ro2.FIELDS,
468 ro2.ROOT_ID,
469 ro2.IS_READ,
470 ro2.IS_CLICK,
471 ro2.IS_UNSUB,
472 ro2.DATE_DENY,
473 ro2.DATE_SENT
474 FROM
475 (
476 SELECT
477 ro.ID,
478 ro.POSTING_ID,
479 ro.STATUS,
480 ro.USER_ID,
481 ro.FIELDS,
482 ro.ROOT_ID,
483 ro.IS_READ,
484 ro.IS_CLICK,
485 ro.IS_UNSUB,
486 ro.DATE_DENY,
487 ro.EMAIL,
488 ro.DATE_SENT
489 FROM
490 b_sender_posting_rcpnt_old ro
491 order by
492 ro.ID ASC
493 limit $limit
494 ) ro2,
495 b_sender_posting p,
496 b_sender_contact c
497 WHERE
498 ro2.POSTING_ID = p.ID
499 and c.TYPE_ID = 1
500 and c.CODE = ro2.EMAIL
501 order by ro2.ID ASC
502 limit $limit";
503 $conn->query($sql);
504 $conn->query("delete from b_sender_posting_rcpnt_old order by ID asc limit $limit");
505 if (!$conn->query('select ID from b_sender_posting_rcpnt_old limit 1')->fetch())
506 {
507 $hasData = false;
508 break;
509 }
510 }
511 }
512
513 if (!$hasData)
514 {
516 "DROP TABLE IF EXISTS b_sender_posting_rcpnt_old"
517 );
518
519 return '';
520 }
521 else
522 {
523 return '\Bitrix\Sender\Internals\CounterCalculation::updateRecipientsAgent();';
524 }
525 }
526}
static getConnection($name="")