1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
mailboxconnector.php
См. документацию.
1<?php
2
3namespace Bitrix\Mail\Helper\Mailbox;
4
5use Bitrix\Mail\Helper\Mailbox;
6use Bitrix\Main;
7use Bitrix\Mail;
8use Bitrix\Main\Localization\Loc;
9use Bitrix\Mail\Helper\LicenseManager;
10use Bitrix\Main\Config\Configuration;
11use Bitrix\Main\Mail\Address;
12use Bitrix\Mail\MailServicesTable;
13
15{
16 private const STANDARD_ERROR_KEY = 1;
17 private const LIMIT_ERROR_KEY = 2;
18 private const OAUTH_ERROR_KEY = 3;
19 private const EXISTS_ERROR_KEY = 4;
20 private const NO_MAIL_SERVICES_ERROR_KEY = 5;
21 private const SMTP_PASS_BAD_SYMBOLS_ERROR_KEY = 6;
22 public const CRM_MAX_AGE = 7;
23 public const MESSAGE_MAX_AGE = 7;
24
25 private bool $isSuccess = false;
26
27 private array $errorCollection = [];
28
29 private bool $isSMTPAvailable = false;
30
31 public function getSuccess(): bool
32 {
33 return $this->isSuccess;
34 }
35
36 public function setSuccess(): void
37 {
38 $this->isSuccess = true;
39 }
40
41 public function getErrors(): array
42 {
43 return $this->errorCollection;
44 }
45
46 protected function addError(string $error): void
47 {
48 $this->errorCollection[] = new Main\Error($error);
49 }
50
51 protected function addErrors(
53 bool $isOAuth = false,
54 bool $isSender = false
55 ): void
56 {
57 $messages = [];
58 $details = [];
59
60 foreach ($errors as $item)
61 {
62 if ($item->getCode() < 0)
63 {
64 $details[] = $item;
65 }
66 else
67 {
68 $messages[] = $item;
69 }
70 }
71
72 if (count($messages) == 1 && reset($messages)->getCode() == Mail\Imap::ERR_AUTH)
73 {
74 $authError = Loc::getMessage('MAIL_MAILBOX_CONNECTOR_CLIENT_IMAP_AUTH_ERR_EXT');
75 if ($isOAuth && Loc::getMessage('MAIL_MAILBOX_CONNECTOR_CLIENT_ERR_OAUTH'))
76 {
77 $authError = Loc::getMessage('MAIL_MAILBOX_CONNECTOR_CLIENT_ERR_OAUTH');
78 }
79 if ($isOAuth && $isSender && Loc::getMessage('MAIL_MAILBOX_CONNECTOR_CLIENT_ERR_OAUTH_SMTP'))
80 {
81 $authError = Loc::getMessage('MAIL_MAILBOX_CONNECTOR_CLIENT_ERR_OAUTH_SMTP');
82 }
83
84 $messages = [
85 new Main\Error($authError, Mail\Imap::ERR_AUTH),
86 ];
87
88 $moreDetailsSection = false;
89 }
90 else
91 {
92 $moreDetailsSection = true;
93 }
94
95 $reduce = function($error)
96 {
97 return $error->getMessage();
98 };
99
100 if($moreDetailsSection)
101 {
102 $this->errorCollection[] = new Main\Error(
103 implode(': ', array_map($reduce, $messages)),
104 0,
105 implode(': ', array_map($reduce, $details))
106 );
107 }
108 else
109 {
110 $this->errorCollection[] = new Main\Error(
111 implode(': ', array_map($reduce, $messages)),
112 0,
113 );
114 }
115 }
116
117 private function setError(int $code = self::STANDARD_ERROR_KEY): void
118 {
119 switch ($code) {
120 case self::STANDARD_ERROR_KEY:
121 $this->addError(Loc::getMessage('MAIL_MAILBOX_CONNECTOR_CLIENT_FORM_ERROR'));
122 break;
123 case self::LIMIT_ERROR_KEY:
124 $this->addError(Loc::getMessage('MAIL_MAILBOX_CONNECTOR_CLIENT_LIMIT_ERROR'));
125 break;
126 case self::OAUTH_ERROR_KEY:
127 $this->addError(Loc::getMessage('MAIL_MAILBOX_CONNECTOR_CLIENT_OAUTH_ERROR'));
128 break;
129 case self::EXISTS_ERROR_KEY:
130 $this->addError(Loc::getMessage('MAIL_MAILBOX_CONNECTOR_CLIENT_EMAIL_EXISTS_ERROR'));
131 break;
132 case self::NO_MAIL_SERVICES_ERROR_KEY:
133 $this->addError(Loc::getMessage('MAIL_MAILBOX_CONNECTOR_CLIENT_THERE_ARE_NO_MAIL_SERVICES'));
134 break;
135 case self::SMTP_PASS_BAD_SYMBOLS_ERROR_KEY:
136 $this->addError(Loc::getMessage('MAIL_MAILBOX_CONNECTOR_SMTP_PASS_BAD_SYMBOLS'));
137 break;
138 }
139 }
140
141 private static function getUserOwnedMailboxCount()
142 {
143 global $USER;
144
145 $res = Mail\MailboxTable::getList([
146 'select' => [
147 new Main\Entity\ExpressionField('OWNED', 'COUNT(%s)', 'ID'),
148 ],
149 'filter' => [
150 '=ACTIVE' => 'Y',
151 '=USER_ID' => $USER->getId(),
152 '=SERVER_TYPE' => 'imap',
153 ],
154 ])->fetch();
155
156 return $res['OWNED'];
157 }
158
159 public static function canConnectNewMailbox(): bool
160 {
161 $userMailboxesLimit = LicenseManager::getUserMailboxesLimit();
162 if ($userMailboxesLimit >= 0)
163 {
164 if (self::getUserOwnedMailboxCount() >= $userMailboxesLimit)
165 {
166 return false;
167 }
168 }
169
170 return true;
171 }
172
173 private function syncMailbox(int $mailboxId): void
174 {
175 Main\Application::getInstance()->addBackgroundJob(function ($mailboxId) {
176 $mailboxHelper = Mailbox::createInstance($mailboxId, false);
177 $mailboxHelper->sync();
178 },[$mailboxId]);
179 }
180
181 private function setIsSmtpAvailable(): void
182 {
183 $defaultMailConfiguration = Configuration::getValue("smtp");
184 $this->isSMTPAvailable = Main\ModuleManager::isModuleInstalled('bitrix24')
185 || $defaultMailConfiguration['enabled'];
186 }
187
188 private function getSmtpAvailable(): bool
189 {
190 return $this->isSMTPAvailable;
191 }
192
200 public static function isOauthSmtpEnabled(string $serviceName): bool
201 {
202 switch ($serviceName)
203 {
204 case 'gmail':
205 return Main\Config\Option::get('mail', '~disable_gmail_oauth_smtp') !== 'Y';
206 case 'yandex':
207 return Main\Config\Option::get('mail', '~disable_yandex_oauth_smtp') !== 'Y';
208 case 'mail.ru':
209 return Main\Config\Option::get('mail', '~disable_mailru_oauth_smtp') !== 'Y';
210 case 'office365':
211 case 'outlook.com':
212 case 'exchangeOnline':
213 return Main\Config\Option::get('mail', '~disable_microsoft_oauth_smtp') !== 'Y';
214 default:
215 return false;
216 }
217 }
218
219 public static function isValidMailHost(string $host): bool
220 {
222 {
223 // Private addresses can't be used in the cloud
225 if ($ip->isPrivate())
226 {
227 return false;
228 }
229 }
230
231 return true;
232 }
233
242 public static function appendSender(array $senderFields, string $userPrincipalName, int $mailboxId = 0): array
243 {
244 if($mailboxId)
245 {
246 $senderFields['PARENT_ID'] = $mailboxId;
247 $senderFields['PARENT_MODULE_ID'] = 'mail';
248 }
249
250 $result = Main\Mail\Sender::add($senderFields);
251
252 if (empty($result['confirmed']) && $userPrincipalName)
253 {
254 $address = new Address($userPrincipalName);
255 $currentSmtpLogin = $senderFields['OPTIONS']['smtp']['login'] ?? '';
256 if ($currentSmtpLogin && $currentSmtpLogin !== $userPrincipalName && $address->validate())
257 {
258 // outlook workaround, sometimes SMTP auth only works with userPrincipalName
259 $senderFields['OPTIONS']['smtp']['login'] = $userPrincipalName;
260 $result = Main\Mail\Sender::add($senderFields);
261 }
262 }
263 return $result;
264 }
265
266 public function connectMailbox(
267 string $login = '',
268 string $password = '',
269 int $serviceId = 0,
270 string $server = '',
271 int $port = 993,
272 bool $ssl = true,
273 string $storageOauthUid = '',
274 bool $syncAfterConnection = true,
275 bool $useSmtp = true,
276 string $serverSmtp = '',
277 int $portSmtp = 587,
278 bool $sslSmtp = true,
279 string $loginSmtp = '',
280 string $passwordSMTP = '',
281 bool $useLimitSmtp = false,
282 int $limitSmtp = null,
283 string $mailboxName = '',
284 string $senderName = '',
285 ): array
286 {
287 $login = trim($login);
288 $password = trim($password);
289 $server = trim($server);
290
291 $currentSite = \CSite::getById(SITE_ID)->fetch();
292 global $USER;
293
294 $this->setIsSmtpAvailable();
295
296 $service = Mail\MailServicesTable::getList([
297 'filter' => [
298 '=ID' => $serviceId,
299 'SERVICE_TYPE' => 'imap',
300 ],
301 ])->fetch();
302
303 if (empty($service))
304 {
305 $this->setError(self::NO_MAIL_SERVICES_ERROR_KEY);
306 return [];
307 }
308
309 if ($service['ACTIVE'] !== 'Y')
310 {
311 $this->setError();
312 return [];
313 }
314
315 if (!$this->canConnectNewMailbox())
316 {
317 $this->setError(self::LIMIT_ERROR_KEY);
318 return [];
319 }
320
321 if ($ssl)
322 {
323 $ssl = 'Y';
324 }
325 else
326 {
327 $ssl = 'N';
328 }
329
330 if ($sslSmtp)
331 {
332 $sslSmtp = 'Y';
333 }
334 else
335 {
336 $sslSmtp = 'N';
337 }
338
339 $mailboxData = [
340 'USERNAME' => $senderName ?: '',
341 'SERVER' => $service['SERVER'] ?: trim($server),
342 'PORT' => $service['PORT'] ?: $port,
343 'USE_TLS' => $service['ENCRYPTION'] ?: $ssl,
344 'LINK' => $service['LINK'],
345 'EMAIL' => $login,
346 'NAME' => $mailboxName ?? $login,
347 'PERIOD_CHECK' => 60 * 24,
348 'OPTIONS' => [
349 'flags' => [],
350 'sync_from' => time(),
351 'crm_sync_from' => time(),
352 'activateSync' => false,
353 'name' => '',
354 ],
355 ];
356
357 if ('N' == $service['UPLOAD_OUTGOING'] || empty($service['UPLOAD_OUTGOING']))
358 {
359 $mailboxData['OPTIONS']['flags'][] = 'deny_upload';
360 }
361
362 $isOAuth = false;
363 if ($storageOauthUid !== '' && $oauthHelper = Mail\MailServicesTable::getOAuthHelper($service))
364 {
365 $oauthHelper->getStoredToken($storageOauthUid);
366 $mailboxData['LOGIN'] = $mailboxData['EMAIL'];
367 $mailboxData['PASSWORD'] = $oauthHelper->buildMeta();
368 $isOAuth = true;
369 }
370 else
371 {
372 $mailboxData['LOGIN'] = $login;
373 $mailboxData['PASSWORD'] = $password;
374 }
375
376 if (empty($mailbox['EMAIL']))
377 {
378 $address = new Address($mailboxData['EMAIL']);
379 if (!$address->validate())
380 {
381 $this->setError(self::OAUTH_ERROR_KEY);
382 return [];
383 }
384
385 $mailboxData['EMAIL'] = $address->getEmail();
386 $this->email = $mailboxData['EMAIL'];
387 }
388 else
389 {
390 $this->email = $mailbox['EMAIL'];
391 }
392
393 if (empty($mailbox))
394 {
395 $mailbox = Mail\MailboxTable::getList([
396 'filter' => [
397 '=EMAIL' => $mailboxData['EMAIL'],
398 '=USER_ID' => $USER->getId(),
399 '=ACTIVE' => 'Y',
400 '=LID' => $currentSite['LID'],
401 ],
402 ])->fetch();
403
404 if (!empty($mailbox))
405 {
406 $this->setError(self::EXISTS_ERROR_KEY);
407 return [];
408 }
409 }
410
411 if (empty($mailboxData['NAME']))
412 {
413 $mailboxData['NAME'] = $mailboxData['EMAIL'];
414 }
415
416 if (!in_array($mailboxData['USE_TLS'], array('Y', 'S')))
417 {
418 $mailboxData['USE_TLS'] = 'N';
419 }
420
421 $unseen = Mail\Helper::getImapUnseen($mailboxData, 'inbox', $error, $errors);
422 if ($unseen === false)
423 {
424 if ($errors instanceof Main\ErrorCollection)
425 {
426 $this->addErrors($errors, $isOAuth);
427 }
428 else
429 {
430 $this->setError();
431 }
432 return [];
433 }
434
435 $isSmtpOauthEnabled = !empty(MailServicesTable::getOAuthHelper($service))
437 $useSmtp = $useSmtp || $isSmtpOauthEnabled;
438
439 if ($this->getSmtpAvailable() && !$useSmtp && !empty($mailbox))
440 {
442 'filter' => array(
443 'IS_CONFIRMED' => true,
444 '=EMAIL' => $mailboxData['EMAIL'],
445 ),
446 ));
447 while ($item = $res->fetch())
448 {
449 if (!empty($item['OPTIONS']['smtp']['server']))
450 {
451 unset($item['OPTIONS']['smtp']);
453 $item['ID'],
454 array(
455 'OPTIONS' => $item['OPTIONS'],
456 )
457 );
458 }
459 }
460
461 Main\Mail\Sender::clearCustomSmtpCache($mailboxData['EMAIL']);
462 }
463
464 if ($this->getSmtpAvailable() && $useSmtp)
465 {
466 $senderFields = [
467 'NAME' => $mailboxData['USERNAME'],
468 'EMAIL' => $mailboxData['EMAIL'],
469 'USER_ID' => $USER->getId(),
470 'IS_CONFIRMED' => false,
471 'IS_PUBLIC' => false,
472 'OPTIONS' => [
473 'source' => 'mail.client.config',
474 ],
475 ];
476
477 $mailboxSenders = Main\Mail\Internal\SenderTable::query()
478 ->setSelect(['ID', 'OPTIONS'])
479 ->where('IS_CONFIRMED', true)
480 ->where('EMAIL', $senderFields['EMAIL'])
481 ->where('USER_ID', $senderFields['USER_ID'])
482 ->fetchAll()
483 ;
484
485 foreach ($mailboxSenders as $sender)
486 {
487 if (empty($smtpConfirmed))
488 {
489 if (!empty($sender['OPTIONS']['smtp']['server']) && empty($sender['OPTIONS']['smtp']['encrypted']))
490 {
491 $smtpConfirmed = $sender['OPTIONS']['smtp'];
492 }
493 }
494 }
495 }
496
497 if (!empty($senderFields))
498 {
499 $smtpConfig = array(
500 'server' => $service['SMTP_SERVER'] ?: trim($serverSmtp),
501 'port' => $service['SMTP_PORT'] ?: $portSmtp,
502 'protocol' => ('Y' == ($service['SMTP_ENCRYPTION'] ?: $sslSmtp) ? 'smtps' : 'smtp'),
503 'login' => $service['SMTP_LOGIN_AS_IMAP'] == 'Y' ? $mailboxData['LOGIN'] : $loginSmtp,
504 'password' => '',
505 );
506
507 if (!empty($smtpConfirmed) && is_array($smtpConfirmed))
508 {
509 // server, port, protocol, login, password
510 $smtpConfig = array_filter($smtpConfig) + $smtpConfirmed;
511 }
512
513 if ($useLimitSmtp)
514 {
515 $smtpConfig['limit'] = $limitSmtp;
516 }
517
518 if ($service['SMTP_PASSWORD_AS_IMAP'] == 'Y' && (!$storageOauthUid || $isSmtpOauthEnabled))
519 {
520 $smtpConfig['password'] = $mailboxData['PASSWORD'];
521 $smtpConfig['isOauth'] = !empty($storageOauthUid) && $isSmtpOauthEnabled;
522 }
523 else if ($passwordSMTP <> '')
524 {
525 if (preg_match('/^\^/', $passwordSMTP))
526 {
527 $this->setError(self::SMTP_PASS_BAD_SYMBOLS_ERROR_KEY);
528 return [];
529 }
530 else if (preg_match('/\x00/', $passwordSMTP))
531 {
532 $this->setError(self::SMTP_PASS_BAD_SYMBOLS_ERROR_KEY);
533 return [];
534 }
535
536 $smtpConfig['password'] = $passwordSMTP;
537 $smtpConfig['isOauth'] = !empty($storageOauthUid) && $isSmtpOauthEnabled;
538 }
539
540 if (!$service['SMTP_SERVER'])
541 {
542 $regex = '/^(?:(?:http|https|ssl|tls|smtp):\/\/)?((?:[a-z0-9](?:-*[a-z0-9])*\.?)+)$/i';
543 if (!preg_match($regex, $smtpConfig['server'], $matches) && $matches[1] <> '')
544 {
545 $this->setError(self::OAUTH_ERROR_KEY);
546 return [];
547 }
548
549 $smtpConfig['server'] = $matches[1];
550
551 if (!self::isValidMailHost($smtpConfig['server']))
552 {
553 $this->setError(self::OAUTH_ERROR_KEY);
554 return [];
555 }
556 }
557
558 if (!$service['SMTP_PORT'])
559 {
560 if ($smtpConfig['port'] <= 0 || $smtpConfig['port'] > 65535)
561 {
562 $this->setError(self::OAUTH_ERROR_KEY);
563 return [];
564 }
565 }
566
567 $senderFields['OPTIONS']['smtp'] = $smtpConfig;
568
569 if (!empty($smtpConfirmed))
570 {
571 $senderFields['IS_CONFIRMED'] = !array_diff(
572 array('server', 'port', 'protocol', 'login', 'password', 'isOauth'),
573 array_keys(array_intersect_assoc($smtpConfig, $smtpConfirmed))
574 );
575 }
576 }
577
578 if (\Bitrix\Mail\Integration\Crm\Permissions::getInstance()->hasAccessToCrm())
579 {
580 $crmAvailable = $USER->isAdmin() || $USER->canDoOperation('bitrix24_config')
581 || \COption::getOptionString('intranet', 'allow_external_mail_crm', 'Y', SITE_ID) == 'Y';
582
583 $mailboxData['OPTIONS']['sync_from'] = strtotime('today UTC 00:00'.sprintf('-%u days', self::MESSAGE_MAX_AGE));
584
585 if ($crmAvailable)
586 {
587 $maxAge = self::CRM_MAX_AGE;
588 $mailboxData['OPTIONS']['flags'][] = 'crm_connect';
589 $mailboxData['OPTIONS']['crm_sync_from'] = strtotime(sprintf('-%u days', $maxAge));
590 $mailboxData['OPTIONS']['crm_new_entity_in'] = \CCrmOwnerType::LeadName;
591 $mailboxData['OPTIONS']['crm_new_entity_out'] = \CCrmOwnerType::ContactName;
592 $mailboxData['OPTIONS']['crm_lead_source'] = 'EMAIL';
593 $mailboxData['OPTIONS']['crm_lead_resp'] = [empty($mailbox) ? $USER->getId() : $mailbox['USER_ID']];
594 }
595 }
596
597 $mailboxData['OPTIONS']['version'] = 6;
598
599 if (empty($mailbox))
600 {
601 $mailboxData = array_merge([
602 'LID' => $currentSite['LID'],
603 'ACTIVE' => 'Y',
604 'SERVICE_ID' => $service['ID'],
605 'SERVER_TYPE' => $service['SERVICE_TYPE'],
606 'CHARSET' => $currentSite['CHARSET'],
607 'USER_ID' => $USER->getId(),
608 'SYNC_LOCK' => time()
609 ], $mailboxData);
610
611 $result = $mailboxId = \CMailbox::add($mailboxData);
612
613 addEventToStatFile('mail', 'add_mailbox', $service['NAME'], ($result > 0 ? 'success' : 'failed'));
614 }
615 else
616 {
617 $this->setError(self::EXISTS_ERROR_KEY);
618 return [];
619 }
620
621 if (!($result > 0))
622 {
623 $this->setError();
624 return [];
625 }
626
627 if (!empty($senderFields) && empty($senderFields['IS_CONFIRMED']))
628 {
629 $result = $this->appendSender($senderFields, (string)($fields['user_principal_name'] ?? ''), (int)$mailboxId);
630
631 if (!empty($result['errors']) && $result['errors'] instanceof Main\ErrorCollection)
632 {
633 $this->addErrors($result['errors'], $isOAuth, true);
634 return [];
635 }
636 else if (!empty($result['error']))
637 {
638 $this->addError($result['error']);
639 return [];
640 }
641 else if (empty($result['confirmed']))
642 {
643 $this->addError('MAIL_CLIENT_CONFIG_SMTP_CONFIRM');
644 return [];
645 }
646 }
647
648 $ownerAccessCode = 'U' . (empty($mailbox) ? $USER->getId() : $mailbox['USER_ID']);
649 $access = array($ownerAccessCode);
650
651 foreach (array_unique($access) as $item)
652 {
654 'MAILBOX_ID' => $mailboxId,
655 'TASK_ID' => 0,
656 'ACCESS_CODE' => $item,
657 ));
658 }
659
660 $mailboxHelper = Mailbox::createInstance($mailboxId);
661 $mailboxHelper->cacheDirs();
662
663 $filterFields = [
664 'MAILBOX_ID' => $mailboxId,
665 'NAME' => sprintf('CRM IMAP %u', $mailboxId),
666 'ACTION_TYPE' => 'crm_imap',
667 'WHEN_MAIL_RECEIVED' => 'Y',
668 'WHEN_MANUALLY_RUN' => 'Y',
669 ];
670
671 \CMailFilter::add($filterFields);
672
673 $this->setSuccess();
674
675 if ($syncAfterConnection)
676 {
677 $this->syncMailbox($mailboxId);
678 }
679
680 return [
681 'id' => $mailboxId,
682 'email' => trim($mailboxData['EMAIL']),
683 ];
684 }
685}
$login
Определения change_password.php:8
static getUserMailboxesLimit()
Определения licensemanager.php:391
static isOauthSmtpEnabled(string $serviceName)
Определения mailboxconnector.php:200
connectMailbox(string $login='', string $password='', int $serviceId=0, string $server='', int $port=993, bool $ssl=true, string $storageOauthUid='', bool $syncAfterConnection=true, bool $useSmtp=true, string $serverSmtp='', int $portSmtp=587, bool $sslSmtp=true, string $loginSmtp='', string $passwordSMTP='', bool $useLimitSmtp=false, int $limitSmtp=null, string $mailboxName='', string $senderName='',)
Определения mailboxconnector.php:266
static appendSender(array $senderFields, string $userPrincipalName, int $mailboxId=0)
Определения mailboxconnector.php:242
addErrors(Main\ErrorCollection $errors, bool $isOAuth=false, bool $isSender=false)
Определения mailboxconnector.php:51
static isValidMailHost(string $host)
Определения mailboxconnector.php:219
static getOAuthHelper($data)
Определения mailservices.php:218
static getInstance()
Определения application.php:98
add($name, $value)
Определения configuration.php:141
static get($moduleId, $name, $default="", $siteId=false)
Определения option.php:30
Определения error.php:15
static isModuleInstalled($moduleName)
Определения modulemanager.php:125
static getList(array $parameters=array())
Определения datamanager.php:431
static add(array $data)
Определения datamanager.php:877
static update($primary, array $data)
Определения datamanager.php:1256
static createByName($name)
Определения ipaddress.php:32
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$result
Определения get_property_values.php:14
$errors
Определения iblock_catalog_edit.php:74
$filterFields
Определения iblock_catalog_list.php:55
global $USER
Определения csv_new_run.php:40
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
if(!is_array($deviceNotifyCodes)) $access
Определения options.php:174
Определения ufield.php:9
Определения address.php:8
$password
Определения mysql_to_pgsql.php:34
$host
Определения mysql_to_pgsql.php:32
$service
Определения payment.php:18
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$messages
Определения template.php:8
$matches
Определения index.php:22
const SITE_ID
Определения sonet_set_content_view.php:12
$error
Определения subscription_card_product.php:20
$fields
Определения yandex_run.php:501