Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
businessvalue.php
1<?php
2
4
11
12Loc::loadMessages(__FILE__);
13
14final class BusinessValueControl
15{
16 private $name;
17 private $consumerCodePersonMapping = array();
18 private $errors = array();
19
20 public function __construct($name)
21 {
22 $this->name = $name.'BizVal';
23 }
24
25 public function setMapFromPost()
26 {
27 if ($this->consumerCodePersonMapping)
28 throw new SystemException('Map is already set from post!');
29
30 if (isset($_POST[$this->name]['MAP']) && is_array($_POST[$this->name]['MAP']))
31 {
32 $_POST = Input\File::getPostWithFiles($_POST, $_FILES);
33 $consumerCodePersonMapping = $_POST[$this->name]['MAP'];
34 unset($_POST[$this->name]['MAP']);
35
36 $errors = array();
37
38 $consumers = BusinessValue::getConsumers();
39
40 foreach ($consumerCodePersonMapping as $consumerKey => &$codePersonMapping)
41 {
42 if ($consumerKey === BusinessValueTable::COMMON_CONSUMER_KEY)
43 {
44 $consumerKey = null;
45 $consumerCodePersonMapping[null] = &$codePersonMapping;
46 unset($consumerCodePersonMapping[BusinessValueTable::COMMON_CONSUMER_KEY]);
47 }
48
49 if (! (($consumer = $consumers[$consumerKey]) && is_array($consumer) && is_array($codePersonMapping)))
50 {
51 unset($consumerCodePersonMapping[$consumerKey]);
52 continue;
53 }
54
55 if (! (($codes = $consumer['CODES']) && is_array($codes)))
56 $codes = array();
57
58 $skipNewCodeSanitation = $consumer['SKIP_NEW_CODE_SANITATION'] ?? false;
59
60 $sanitizeMapping = $consumer['SANITIZE_MAPPING'] ?? null;
61 if (!is_callable($sanitizeMapping))
62 {
63 $sanitizeMapping = null;
64 }
65
66 $renderColumns = $consumer['RENDER_COLUMNS'] ?? null;
67 if (
68 (! $codes && ! $skipNewCodeSanitation)
69 || ($skipNewCodeSanitation && ! $sanitizeMapping)
70 || (is_callable($renderColumns) && ! $sanitizeMapping)
71 )
72 {
73 unset($consumerCodePersonMapping[$consumerKey]);
74 continue;
75 }
76
77 foreach ($codePersonMapping as $codeKey => &$personMapping)
78 {
79 $code = $codes[$codeKey];
80
81 if (! (is_array($personMapping) && (is_array($code) || $skipNewCodeSanitation)))
82 {
83 unset($codePersonMapping[$codeKey]);
84 continue;
85 }
86
87 foreach ($personMapping as $personTypeId => &$mapping)
88 {
89 if ($personTypeId === BusinessValueTable::COMMON_PERSON_TYPE_ID) // must be === coz 0 & null
90 {
91 $personTypeId = null;
92 $personMapping[null] = &$mapping;
93 unset($personMapping[BusinessValueTable::COMMON_PERSON_TYPE_ID]);
94 }
95
96 $codeDomains = $code['DOMAINS'] ?? null;
97 $personType = self::$personTypes[$personTypeId] ?? null;
98
99 if (! is_array($code) && $skipNewCodeSanitation)
100 {
101 //$skipNewCodeSanitation
102 }
103 elseif (! (is_array($code)
104 && (! isset($code['PERSON_TYPE_ID']) || $code['PERSON_TYPE_ID'] == $personTypeId)
105 && (! is_array($codeDomains) || in_array($personType['DOMAIN'], $codeDomains, true))
106 && is_array($mapping)))
107 {
108 unset($personMapping[$personTypeId]);
109 continue;
110 }
111
112 // delete record
113 if (
114 !empty($mapping['DELETE'])
115 || empty($mapping['PROVIDER_KEY'])
116 || empty($mapping['PROVIDER_VALUE'])
117 )
118 {
119 continue;
120 }
121
122 if ($sanitizeMapping)
123 {
124 if ($e = call_user_func_array($sanitizeMapping, array($codeKey, $personTypeId, &$mapping)))
125 $errors[$consumerKey][$codeKey][$personTypeId] = $e;
126 }
127 elseif (isset($code['INPUT']) && is_array($code['INPUT']))
128 {
129 $mapping['PROVIDER_KEY'] = 'INPUT';
130
131 if ($e = Input\Manager::getError($code['INPUT'], $mapping['PROVIDER_VALUE'] ?? []))
132 $errors[$consumerKey][$codeKey][$personTypeId]['PROVIDER_VALUE'] = $e;
133 }
134 else
135 {
136 if ($e = self::sanitizeMapping($personTypeId, $mapping, $code['PROVIDERS'] ?? $consumer['PROVIDERS'] ?? []))
137 $errors[$consumerKey][$codeKey][$personTypeId] = $e;
138 }
139
140 if (! $mapping)
141 {
142 unset($personMapping[$personTypeId]); // remove from post
143 }
144 }
145 }
146 }
147
148 $this->consumerCodePersonMapping = $consumerCodePersonMapping;
149 $this->errors = $errors;
150 }
151
152 return ! $this->errors;
153 }
154
156 public static function sanitizeMapping($personTypeId, array &$mapping, array $providerKeys = null)
157 {
158 $error = array();
159
160 if (($providerInput = self::getProviderInput($personTypeId, $providerKeys))
161 && ($providerValueInput = self::$personProviderValueInput[$personTypeId])
162 && ($valueInput = $providerValueInput[$mapping['PROVIDER_KEY']]))
163 {
164 if ($e = Input\Manager::getError($providerInput, $mapping['PROVIDER_KEY']))
165 $error['PROVIDER_KEY'] = $e;
166 else
167 $mapping['PROVIDER_KEY'] = Input\Manager::getValue($providerInput, $mapping['PROVIDER_KEY']);
168
169 if ($e = Input\Manager::getError($valueInput, $mapping['PROVIDER_VALUE'] ?? []))
170 $error['PROVIDER_VALUE'] = $e;
171 else
172 $mapping['PROVIDER_VALUE'] = Input\Manager::getValue($valueInput, $mapping['PROVIDER_VALUE'] ?? []);
173 }
174 else
175 {
176 $mapping = array(); // remove from post
177 }
178
179 return $error;
180 }
181
182 public function changeConsumerKey($fromConsumerKey, $toConsumerKey)
183 {
184 BusinessValue::changeConsumerKey($fromConsumerKey, $toConsumerKey);
185
186 if (isset($this->consumerCodePersonMapping[$fromConsumerKey]))
187 {
188 $this->consumerCodePersonMapping[$toConsumerKey] = $this->consumerCodePersonMapping[$fromConsumerKey];
189 unset($this->consumerCodePersonMapping[$fromConsumerKey]);
190 }
191 }
192
193 public function saveMap()
194 {
195 if ($this->errors)
196 throw new SystemException('There are errors in map!');
197
198 $consumers = BusinessValue::getConsumers();
199
200 foreach ($this->consumerCodePersonMapping as $consumerKey => $codePersonMapping)
201 {
202 $consumer = $consumers[$consumerKey] ?? [];
203 $setMapping =
204 isset($consumer['SET_MAPPING']) && is_callable($consumer['SET_MAPPING'])
205 ? $consumer['SET_MAPPING']
206 : null
207 ;
208 $codes = $consumer['CODES'] ?? [];
209
210 foreach ($codePersonMapping as $codeKey => $personMapping)
211 {
212 $code = $codes[$codeKey] ?? [];
213 $fileInput = $code['INPUT'] ?? [];
214 $fileType = $fileInput['TYPE'] ?? '';
215 if (!(is_array($fileInput) && ($fileType == 'FILE' || $fileType == 'DATABASE_FILE')))
216 {
217 $fileInput = [];
218 }
219
220 foreach ($personMapping as $personTypeId => $mapping)
221 {
222 if ($setMapping)
223 {
224 $result = call_user_func($setMapping, $codeKey, $personTypeId, $mapping);
225 }
226 else
227 {
228 $consumerCodePersonMapping = \Bitrix\Sale\BusinessValue::getConsumerCodePersonMapping();
229 if ($fileInput && ($file =& $mapping['PROVIDER_VALUE']))
230 {
231 if (Input\File::isDeletedSingle($file))
232 {
233 if ($fileInput['TYPE'] == 'FILE')
234 {
235 if (is_numeric($file['ID']) && isset($consumerCodePersonMapping[$consumerKey][$codeKey][$personTypeId]))
236 {
237 \CFile::Delete($file['ID']); // TODO isSuccess
238 }
239 }
240
241 $file = null;
242 }
243 elseif (Input\File::isUploadedSingle($file))
244 {
245 if ($fileInput['TYPE'] == 'FILE')
246 {
247 if (($file = \CFile::SaveFile(array('MODULE_ID' => 'sale') + $file, 'sale/bizval')) && is_numeric($file))
248 {
249 if (($oldFile = BusinessValue::getMapping($codeKey, $consumerKey, $personTypeId, array('MATCH' => BusinessValue::MATCH_EXACT))) && is_numeric($oldFile['PROVIDER_VALUE']))
250 \CFile::Delete($oldFile['PROVIDER_VALUE']); // TODO isSuccess
251 }
252 else
253 {
254 $this->errors[$consumerKey][$codeKey][$personTypeId]['DATABASE'] = 'unable to save file';
255 continue;
256 }
257
258 $file = Input\Manager::getValue($fileInput, $file);
259 }
260 elseif($fileInput['TYPE'] == 'DATABASE_FILE')
261 {
263 global $APPLICATION;
264 $content = $APPLICATION->GetFileContent($file['tmp_name']);
265 if (!$content)
266 {
267 continue;
268 }
269
270 $file = $content;
271 }
272 }
273 else
274 {
275 $file = $file['ID'];
276 }
277 }
278 elseif (isset($fileInput['TYPE']) && is_array($fileInput) && $fileInput['TYPE'] === 'FILE')
279 {
280 if (isset($consumerCodePersonMapping[$consumerKey][$codeKey][$personTypeId]))
281 {
282 \CFile::Delete($consumerCodePersonMapping[$consumerKey][$codeKey][$personTypeId]['PROVIDER_VALUE']);
283 }
284 }
285
286 $common = IsModuleInstalled('bitrix24') ? false : true;
287 $result = BusinessValue::setMapping($codeKey, $consumerKey, $personTypeId, $mapping, $common);
288 }
289
290 if (! $result->isSuccess())
291 $this->errors[$consumerKey][$codeKey][$personTypeId]['DATABASE'] = $result->getErrorMessages();
292 }
293 }
294 }
295
296 return ! $this->errors;
297 }
298
299 private static function getTabControl($name, $personGroupCodes)
300 {
301 $domains = array(
302 '' => Loc::getMessage('BIZVAL_DOMAIN_COMMON_DSC'),
303 BusinessValue::INDIVIDUAL_DOMAIN => Loc::getMessage('BIZVAL_DOMAIN_INDIVIDUAL'),
304 BusinessValue::ENTITY_DOMAIN => Loc::getMessage('BIZVAL_DOMAIN_ENTITY' ),
305 );
306
307 $tabs = array();
308
309 foreach ($personGroupCodes as $personTypeId => $groupCodes)
310 {
311 $personType = self::$personTypes[$personTypeId];
312 if (isset($personType['ENTITY_REGISTRY_TYPE'])
313 && $personType['ENTITY_REGISTRY_TYPE'] !== Registry::REGISTRY_TYPE_ORDER
314 )
315 {
316 continue;
317 }
318
319 $tabs []= array(
320 'DIV' => 'map'.$personTypeId,
321 'TAB' => htmlspecialcharsbx($personType['TITLE']),
322 'TITLE' => $domains[$personType['DOMAIN']],
323 );
324 }
325
326 return new \CAdminViewTabControl($name.'TabControl', $tabs);
327 }
328
329 private static function getPersonGroupCodes(array $consumers, array $filter)
330 {
331 $personGroupCodes = [];
332
333 $consumerCodePersonMapping = BusinessValue::getConsumerCodePersonMapping();
334
335 $consumer = $consumers[$filter['CONSUMER_KEY']];
336
337 if (
338 (empty($filter['PROVIDER_KEY']) && empty($filter['CODE_KEY']))
339 || !empty($filter['CONSUMER_KEY'])
340 )
341 {
342 $consumers = [
343 $filter['CONSUMER_KEY'] => $consumer,
344 ];
345 }
346
347 foreach (self::$personTypes as $personTypeId => $personType)
348 {
349 foreach ($consumers as $consumerKey => $consumer)
350 {
351 if (is_array($consumer) && isset($consumer['CODES']) && is_array($consumer['CODES']))
352 {
353 $consumerCodes = $consumer['CODES'];
354 foreach ($consumerCodes as $codeKey => $code)
355 {
356 $needCodeKey = !isset($filter['CODE_KEY']) || (string)$filter['CODE_KEY'] === (string)$codeKey;
357 $needPersonTypeId = !isset($code['PERSON_TYPE_ID']) || (int)$code['PERSON_TYPE_ID'] === (int)$personTypeId;
358 $needDomains =
359 !isset($code['DOMAINS'])
360 || !is_array($code['DOMAINS'])
361 || in_array($personType['DOMAIN'], $code['DOMAINS'], true)
362 ;
363
364 if (
365 is_array($code)
366 && $needCodeKey
367 && $needPersonTypeId
368 && $needDomains
369 )
370 {
371 $code['CONSUMER_KEY'] = $consumerKey;
372
373 if (!empty($filter['PROVIDER_KEY']))
374 {
375 if (isset($consumerCodePersonMapping[$consumerKey][$codeKey][$personTypeId]))
376 {
377 $mapping = $consumerCodePersonMapping[$consumerKey][$codeKey][$personTypeId];
378
379 if ($mapping['PROVIDER_KEY' ] == $filter['PROVIDER_KEY' ] &&
380 $mapping['PROVIDER_VALUE'] == $filter['PROVIDER_VALUE'])
381 {
382 $personGroupCodes[$personTypeId][$consumer['NAME'] ?? $consumerKey][$codeKey] = $code; // CONSUMER
383 }
384 }
385 }
386 elseif (!empty($filter['CODE_KEY']))
387 {
388 $personGroupCodes[$personTypeId][$consumer['NAME'] ?? $consumerKey][$codeKey] = $code; // CONSUMER
389 }
390 else
391 {
392 $codeGroup = $code['GROUP'] ?? '';
393 $personGroupCodes[$personTypeId][$codeGroup][$codeKey] = $code; // GROUP
394 }
395 }
396 }
397 }
398 }
399
400 if (isset($personGroupCodes[$personTypeId]) && empty($filter['PROVIDER_KEY']) && empty($filter['CODE_KEY'])) // GROUP
401 {
402 self::sortRenameGroups($personGroupCodes[$personTypeId], self::$groups);
403 }
404 }
405
406 return $personGroupCodes;
407 }
408
409 public function renderMap(array $options = array())
410 {
411 $hideFilledCodes =
412 isset($options['HIDE_FILLED_CODES']) && $options['HIDE_FILLED_CODES'] === false
413 ? false
414 : true
415 ;
416
417 $consumers = BusinessValue::getConsumers();
418 $personGroupCodes = self::getPersonGroupCodes($consumers, $options);
419 $tabControl = self::getTabControl($this->name, $personGroupCodes);
420
421 $consumerCodePersonMapping = BusinessValue::getConsumerCodePersonMapping();
422
423 if ($this->errors)
424 {
425 foreach ($this->consumerCodePersonMapping as $consumerKey => $codePersonMapping)
426 foreach ($codePersonMapping as $codeKey => $personMapping)
427 foreach ($personMapping as $personTypeId => $mapping)
428 if ($mapping['PROVIDER_KEY'])
429 $consumerCodePersonMapping[$consumerKey][$codeKey][$personTypeId] = $mapping;
430 }
431
432 $tabControl->Begin();
433
434 foreach ($personGroupCodes as $personTypeId => $groupCodes)
435 {
436 $personType = self::$personTypes[$personTypeId];
437 if (isset($personType['ENTITY_REGISTRY_TYPE'])
438 && $personType['ENTITY_REGISTRY_TYPE'] !== Registry::REGISTRY_TYPE_ORDER
439 )
440 {
441 continue;
442 }
443
444 $tabControl->BeginNextTab();
445
446 ?>
447 <table border="0" cellspacing="0" cellpadding="0" width="100%" class="adm-detail-content-table edit-table">
448 <colgroup>
449 <col class="adm-detail-content-cell-l" width="40%">
450 <col class="adm-detail-content-cell-r" width="60%">
451 </colgroup>
452 <?
453
454 $personHasHiddenRows = 0;
455
456 foreach ($groupCodes as $groupName => $codes)
457 {
458 $groupHasVisibleRows = false;
459
460 ?>
461 <tbody>
462 <?
463
464 ob_start(); // $rowsHTML
465
466 foreach ($codes as $codeKey => $code)
467 {
468 if ($codeKey === 'USER_COLUMNS')
469 continue;
470
471 $consumerKey = $code['CONSUMER_KEY'];
472 $consumer = $consumers[$consumerKey];
473
474 if (isset($this->errors[$consumerKey][$codeKey][$personTypeId]) &&
475 ($error = $this->errors[$consumerKey][$codeKey][$personTypeId]))
476 {
477 if (! is_array($error))
478 $error = array($error);
479
480 ?>
481 <tr>
482 <td></td>
483 <td style="color:#ff1118; padding: 1em 0 0 13em;">
484 <?
485
486 foreach ($error as $k => $e)
487 echo htmlspecialcharsbx(is_array($e) ? implode(', ', $e) : $e).'<br>';
488
489 ?>
490 </td>
491 </tr>
492 <?
493 }
494
495 $o = array(
496 'consumerCodePersonMapping' => $consumerCodePersonMapping,
497 'GET_VALUE' => array('PROPERTY' => 'BY_ID'),
498 );
499
500 $mappings = array(
501 'EXACT' => BusinessValue::getMapping($codeKey, $consumerKey, $personTypeId, array('MATCH' => BusinessValue::MATCH_EXACT ) + $o),
502 'COMMON' => BusinessValue::getMapping($codeKey, $consumerKey, $personTypeId, array('MATCH' => BusinessValue::MATCH_COMMON ) + $o),
503 'DEFAULT' => BusinessValue::getMapping($codeKey, $consumerKey, $personTypeId, array('MATCH' => BusinessValue::MATCH_DEFAULT) + $o),
504 );
505
506 $inputNamePrefix = $this->name.'[MAP]['
507 .($consumerKey ?: BusinessValueTable::COMMON_CONSUMER_KEY).']['
508 .$codeKey.']['
509 .($personTypeId ?: BusinessValueTable::COMMON_PERSON_TYPE_ID).']';
510
511 ob_start(); // $columnsHTML
512
513 if (isset($consumer['RENDER_COLUMNS']) && is_callable($consumer['RENDER_COLUMNS']))
514 {
515 $hideCode = call_user_func($consumer['RENDER_COLUMNS'], $codeKey, $personTypeId, $mappings, $inputNamePrefix);
516 }
517 else
518 {
519 ?>
520 <td>
521 <?
522
523 if (isset($code['CONSUMERS']) && is_array($code['CONSUMERS']) && count($code['CONSUMERS']) > 1)
524 {
525 echo implode(', ', array_map(function ($i) {return htmlspecialcharsbx($i);}, array_flip($code['NAMES'])));
526
527 ?>
528 <img src="/bitrix/js/main/core/images/hint.gif" style="cursor: help;"
529 title="<?=htmlspecialcharsbx(implode(', ', $code['CONSUMERS']))?>">
530 <?
531 }
532 else
533 {
534 echo htmlspecialcharsbx($code['NAME'] ?? $codeKey);
535 }
536
537 if (isset($code['DESCRIPTION']) && is_string($code['DESCRIPTION']))
538 {
539 ?>
540 <div style="font-size:10px;"><?=htmlspecialcharsbx($code['DESCRIPTION'])?></div>
541 <?
542 }
543
544 ?>
545 </td>
546 <td>
547 <?
548
549 $commonProviderInput = $commonProviderValueInput = null;
550
551 if (isset($code['INPUT']) && is_array($code['INPUT']))
552 {
553 $providerInput = array('TYPE' => 'ENUM', 'HIDDEN' => true, 'OPTIONS' => array('INPUT' => ''));
554 $providerValueInput = array(
555 'INPUT' => array(
556 'REQUIRED' => true,
557 'ONCHANGE' => "bizvalChangeValue(this)",
558 )
559 + $code['INPUT']
560 );
561 }
562 else
563 {
564 $providersValues = $code['PROVIDERS'] ?? $consumer['PROVIDERS'] ?? [];
565
566 $providerInput = self::getProviderInput($personTypeId, $providersValues);
567 $providerValueInput = self::getValueInput($personTypeId);
568
569 if ($personTypeId)
570 {
571 $commonProviderInput = self::getProviderInput('', $providersValues);
572 $commonProviderValueInput = self::getValueInput('');
573 }
574 }
575
576 try
577 {
578 $hideCode = self::renderMapping($mappings, $inputNamePrefix, $providerInput, $providerValueInput, $commonProviderInput, $commonProviderValueInput);
579 }
580 catch (SystemException $exception)
581 {
582 $hideCode = '';
583 }
584
585 ?>
586 </td>
587 <?
588 }
589
590 $columnsHTML = ob_get_clean();
591
592 ?>
593 <tr<?
594
595 if ($hideFilledCodes && $hideCode)
596 {
597 ?> class="<?=$this->name.$personTypeId?>row-with-value" style="display:none;"<?
598 $personHasHiddenRows = true;
599 }
600 else
601 {
602 $groupHasVisibleRows = true;
603 }
604
605 ?>>
606 <?=$columnsHTML?>
607 </tr>
608 <?
609 }
610
611 $rowsHTML = ob_get_clean();
612
613 if ($groupName)
614 {
615 ?>
616 <tr<?
617
618 if ($hideFilledCodes && ! $groupHasVisibleRows)
619 echo ' class="'.$this->name.$personTypeId.'row-with-value" style="display:none;"';
620
621 ?>>
622 <td colspan="2" style="
623 padding: 15px 15px 3px;
624 text-align: center; color: #4B6267;
625 font-weight: bold; border-bottom: 5px solid #E0E8EA;">
626 <?=htmlspecialcharsbx($groupName)?>
627 </td>
628 </tr>
629 <?
630 }
631
632 echo $rowsHTML;
633
634 ?>
635 </tbody>
636 <?
637 }
638
639 ?>
640 </table>
641 <?
642
643 if ($hideFilledCodes && $personHasHiddenRows)
644 {
645 ?>
646 <p>
647 <a href="#" onclick="bizvalToggleRowsVisibility(this, '<?=$this->name.$personTypeId.'row-with-value'?>'); return false;">
648 <?=Loc::getMessage('BIZVAL_PAGE_SHOW_ROWS')?>
649 </a>
650 </p>
651 <?
652 }
653 }
654
655 $tabControl->End();
656
657 self::renderScript();
658 }
659
661 public static function renderMapping(array $mappings, $inputNamePrefix, array $providerInput, array $providerValueInput, array $commonProviderInput = null, array $commonProviderValueInput = null)
662 {
663 foreach ($mappings as &$m)
664 $m = self::correctMapping($providerInput, $providerValueInput, $m);
665 unset($m);
666
667 $mappings['EXACT'] ??= [];
668 $mappings['COMMON'] ??= [];
669 $mappings['DEFAULT'] ??= [];
670
671 if ($m = ($mappings['EXACT'] ?: $mappings['COMMON'] ?: $mappings['DEFAULT']))
672 {
673 $providerKey = $m['PROVIDER_KEY' ];
674 $providerValue = $m['PROVIDER_VALUE'];
675 $valueInput = $providerValueInput[$providerKey];
676 }
677 else
678 {
679 $providerKey = is_array($providerInput['OPTIONS']) ? key($providerInput['OPTIONS']) : null;
680 $providerValue = null;
681 $valueInput = $providerValueInput[$providerKey] ?? array('TYPE' => 'STRING', 'HIDDEN' => true);
682 }
683
684 if ($providerKey == 'INPUT')
685 {
686 switch ($valueInput['TYPE'])
687 {
688 case 'ENUM':
689
690 $valueInput['OPTIONS'] = is_array($valueInput['OPTIONS'])
691 ? array('' => '') + $valueInput['OPTIONS']
692 : array('' => '');
693
694 break;
695
696 case 'FILE':
697
698 if ($providerValue)
699 $providerValue = Input\File::loadInfoSingle($providerValue);
700
701 $valueInput['CLASS'] = 'adm-designed-file';
702
703 break;
704
705 case 'DATABASE_FILE':
706 $valueInput['CLASS'] = 'adm-designed-file';
707
708 break;
709 }
710 }
711 else
712 {
713 if ($commonProviderInput
714 && $commonProviderValueInput
715 && ! $mappings['EXACT']
716 && ! $mappings['COMMON']
717 && $mappings['DEFAULT']
718 && $mappings['DEFAULT'] == self::correctMapping($commonProviderInput, $commonProviderValueInput, $mappings['DEFAULT']))
719 {
720 $mappings['COMMON'] = $mappings['DEFAULT'];
721 }
722 }
723
724// if (! $mappings['COMMON'] && is_array($code['DEFAULT']))
725// {
726// if ($personTypeId) // TODO
727// $defaultMapping = $code['DEFAULT'];
728// elseif (! $mapping)
729// $mapping = $code['DEFAULT'];
730// }
731
732 if (! $mappings['EXACT'] && $mappings['COMMON'])
733 $providerInput['DISABLED'] = $valueInput['DISABLED'] = true;
734
735 // !!! Do not change DOM !!!
736 ?><span><?=
737
738 Input\Manager::getEditHtml($inputNamePrefix.'[PROVIDER_KEY]', $providerInput, $providerKey)
739
740 ?> </span><span><?=
741
742 Input\Manager::getEditHtml($inputNamePrefix.'[PROVIDER_VALUE]', $valueInput, $providerValue)
743
744 ?> </span><label <?=$mappings['COMMON'] ? '' : ' style="display:none"'?>>
745 <?=Loc::getMessage('BIZVAL_PAGE_DELETE_MAPPING')?>
746 <input
747 type="checkbox"
748 name="<?=$inputNamePrefix?>[DELETE]"'
749 <?if (! $mappings['EXACT'] && $mappings['COMMON']):?>
750 checked
751 <?endif?>
752 <?if ($m = $mappings['EXACT']):?>
753 data-initial-key="<?=htmlspecialcharsbx($m['PROVIDER_KEY'])?>"
754 data-initial-value="<?=htmlspecialcharsbx($m['PROVIDER_VALUE'])?>"
755 <?endif?>
756 <?if ($m = $mappings['COMMON']):?>
757 data-default-key="<?=htmlspecialcharsbx($m['PROVIDER_KEY'])?>"
758 data-default-value="<?=htmlspecialcharsbx($m['PROVIDER_VALUE'])?>"
759 <?endif?>
760 onclick="bizvalToggleDelete(this)">
761 </label><?
762
763 return $providerValue; // $hideCode TODO
764 }
765
766 private static function correctMapping(array $providerInput, array $providerValueInput, array $mapping)
767 {
768 $key = $mapping['PROVIDER_KEY'] ?? null;
769 $value = $mapping['PROVIDER_VALUE'] ?? null;
770
771 $isValid =
772 !Input\Manager::getError($providerInput, $key)
773 && isset($providerValueInput[$key])
774 && !Input\Manager::getError($providerValueInput[$key], $value)
775 ;
776
777 if (!$isValid)
778 {
779 $mapping = array();
780 }
781
782 return $mapping;
783 }
784
785 private static function renderScript()
786 {
787 static $done;
788 if ($done)
789 return;
790 $done = true;
791
792 ?>
793 <script>
794
795 function bizvalChangeProvider(keyElement, personTypeId, filterMode)
796 {
797 'use strict';
798
799 var providerKey = keyElement.options[keyElement.selectedIndex].value,
800 wrapElement = keyElement.parentNode.nextSibling,
801 name = wrapElement.firstChild.name,
802 personProviderValueInput = <?
803
804 $personProviderValueInput = self::$personProviderValueInput;
805
806 echo \CUtil::PhpToJSObject(
807 call_user_func(
808 function () use ($personProviderValueInput)
809 {
810 foreach ($personProviderValueInput as &$providerFieldInput)
811 foreach ($providerFieldInput as &$fieldInput)
812 $fieldInput = Input\Manager::getEditHtml('', $fieldInput);
813
814 return $personProviderValueInput;
815 }
816 )
817 );
818
819 ?>;
820
821 wrapElement.innerHTML = personProviderValueInput[personTypeId][providerKey];
822 wrapElement.firstChild.name = name;
823
824 if (! filterMode)
825 {
826 if (! personTypeId)
827 bizvalChangeValue(wrapElement.firstChild);
828 }
829
830 return wrapElement.firstChild;
831 }
832
833 function bizvalToggleDelete(deleteElement)
834 {
835 'use strict';
836
837 var path = deleteElement.name.split('[');
838
839 if (! (path.length == 6
840 && path[1] == 'MAP]'
841 && path[5] == 'DELETE]'
842 )) return;
843
844 // [ 0 ][ 1 ][ 2 ][ 3 ][4][ 5 ]
845 // mBizVal[MAP][1CC][ZIP][2][PROVIDER_VALUE]
846
847 var elements = deleteElement.parentNode.parentNode.parentNode.querySelectorAll('input, select, textarea'), // TODO
848 i = 0, length = elements.length,
849 personTypeId = path[4].slice(0, -1);
850
851 if (personTypeId == '<?=BusinessValueTable::COMMON_PERSON_TYPE_ID?>')
852 personTypeId = '';
853
854 for (; i < length; ++i)
855 {
856 var keyElement = elements[i],
857 p = keyElement.name.split('[');
858
859 if (p.length == 6
860 && p[0] == path[0] && p[1] == path[1] && p[2] == path[2] && p[3] == path[3] && p[4] == path[4]
861 && p[5] == 'PROVIDER_KEY]')
862 {
863 // note that, data-default.., must be set since checkbox only visible with default mapping!
864
865 var valueElement, key, val;
866
867 if (deleteElement.checked)
868 {
869 key = deleteElement.getAttribute('data-default-key');
870 val = deleteElement.getAttribute('data-default-value');
871 }
872 else
873 {
874 key = deleteElement.hasAttribute('data-initial-key')
875 ? deleteElement.getAttribute('data-initial-key')
876 : deleteElement.getAttribute('data-default-key');
877 val = deleteElement.hasAttribute('data-initial-value')
878 ? deleteElement.getAttribute('data-initial-value')
879 : deleteElement.getAttribute('data-default-value');
880 }
881
882 if (keyElement.value == 'INPUT')
883 {
884 valueElement = keyElement.parentNode.nextSibling.firstChild;
885
886 if (valueElement.type == 'hidden') // checkbox
887 {
888 valueElement = valueElement.nextSibling;
889 valueElement.checked = val;
890 }
891 else
892 {
893 valueElement.value = val;
894 }
895 }
896 else
897 {
898 keyElement.value = key;
899 valueElement = bizvalChangeProvider(keyElement, personTypeId, true);
900 valueElement.value = val;
901 }
902
903 keyElement.disabled = deleteElement.checked;
904
905 var parentElement = valueElement.parentNode;
906 var tagList = ['input', 'select', 'textarea'];
907 for (var tagIndex in tagList)
908 {
909 if (tagList.hasOwnProperty(tagIndex))
910 {
911 var inputs = BX.findChildren(parentElement, {tag : tagList[tagIndex]}, true);
912 for (var k in inputs)
913 {
914 if (inputs.hasOwnProperty(k))
915 {
916 if (inputs[k].type != 'button')
917 inputs[k].disabled = deleteElement.checked;
918 }
919 }
920 }
921 }
922
923 if (! personTypeId)
924 bizvalChangeValue(valueElement);
925
926 break;
927 }
928 }
929 }
930
931 function bizvalChangeValue(valueElement)
932 {
933 'use strict';
934
935 var path = valueElement.name.split('[');
936
937 if (! (path.length == 6
938 && path[1] == 'MAP]'
939 && path[5] == 'PROVIDER_VALUE]'
940 && path[4] == '<?=BusinessValueTable::COMMON_PERSON_TYPE_ID?>]'
941 )) return;
942
943 // [ 0 ][ 1 ][ 2 ][ 3 ][4][ 5 ]
944 // mBizVal[MAP][1CC][ZIP][2][PROVIDER_VALUE]
945
946 var keyElement = valueElement.parentNode.previousSibling.firstChild, value,
947 elements = document.querySelectorAll('input, select, textarea'), // TODO
948 i = 0, length = elements.length;
949
950 switch (valueElement.type)
951 {
952 case 'checkbox': value = valueElement.checked ? 'true' : ''; break;
953 default: value = valueElement.value;
954 }
955
956 for (; i < length; ++i)
957 {
958 var de = elements[i],
959 p = de.name.split('[');
960
961 if (p.length == 6
962 && p[0] == path[0] && p[1] == path[1] && p[2] == path[2] && p[3] == path[3]
963 && p[4] != path[4] // self exclude
964 && p[5] == 'DELETE]')
965 {
966 de.setAttribute('data-default-key', keyElement.value);
967 de.setAttribute('data-default-value', value);
968
969 var we = de.parentNode,
970 v = valueElement.type == 'checkbox' ? we.previousSibling.firstChild.nextSibling.checked : we.previousSibling.firstChild.value;
971
972 if (value)
973 {
974 if (de.checked || ! v)
975 {
976 de.checked = true;
977 bizvalToggleDelete(de);
978 }
979
980 we.style.display = 'inline';
981 }
982 else
983 {
984 if (de.checked)
985 {
986 de.checked = false;
987 bizvalToggleDelete(de);
988 }
989
990 we.style.display = 'none';
991 }
992 }
993 }
994 }
995
996 function bizvalToggleRowsVisibility(anchor, className)
997 {
998 'use strict';
999
1000 var display;
1001
1002 if (anchor.rowsAreVisible)
1003 {
1004 anchor.rowsAreVisible = false;
1005 anchor.innerText = '<?=Loc::getMessage('BIZVAL_PAGE_SHOW_ROWS')?>';
1006 display = 'none';
1007 }
1008 else
1009 {
1010 anchor.rowsAreVisible = true;
1011 anchor.innerText = '<?=Loc::getMessage('BIZVAL_PAGE_HIDE_ROWS')?>';
1012 display = 'table-row';
1013 }
1014
1015 var nodes = document.querySelectorAll('.'+className), i, l = nodes.length;
1016
1017 for (i = 0; i < l; i++)
1018 nodes[i].style.display = display;
1019 }
1020
1021 <?
1022
1023 foreach (BusinessValue::getConsumers() as $consumerKey => $consumer)
1024 {
1025 if (isset($consumer['GET_JAVASCRIPT']) && is_callable($consumer['GET_JAVASCRIPT']))
1026 {
1027 echo call_user_func($consumer['GET_JAVASCRIPT']);
1028 }
1029 }
1030
1031 ?>
1032 </script>
1033 <?
1034 }
1035
1037 public static function getFilter($filter)
1038 {
1039 $filter =
1040 is_array($filter)
1041 ? array_intersect_key($filter, array('CODE_KEY'=>1,'CONSUMER_KEY'=>1,'PROVIDER_KEY'=>1,'PROVIDER_VALUE'=>1))
1042 : array()
1043 ;
1044
1045 if (self::$consumerInput['OPTIONS'])
1046 {
1047 $value = $filter['CONSUMER_KEY'] ?? null;
1048 $filter['CONSUMER_KEY'] =
1049 ! Input\Manager::getError(self::$consumerInput, $value)
1050 ? Input\Manager::getValue(self::$consumerInput, $value)
1051 : key(self::$consumerInput['OPTIONS']) // REQUIRED
1052 ;
1053 }
1054
1055 if (is_array(self::$consumerCodeInput[$filter['CONSUMER_KEY']]))
1056 {
1057 $value = $filter['CODE_KEY'] ?? null;
1058 $filter['CODE_KEY'] =
1059 ! Input\Manager::getError(self::$consumerCodeInput[$filter['CONSUMER_KEY']], $value)
1060 ? Input\Manager::getValue(self::$consumerCodeInput[$filter['CONSUMER_KEY']], $value)
1061 : null
1062 ;
1063 }
1064
1065
1066 // TODO null - personTypeId
1067 $value = $filter['PROVIDER_KEY'] ?? null;
1068 $filter['PROVIDER_KEY'] =
1069 ! Input\Manager::getError(self::$personProviderInput[null], $value)
1070 ? Input\Manager::getValue(self::$personProviderInput[null], $value)
1071 : null;
1072
1073 // TODO null - personTypeId
1074 $value = $filter['PROVIDER_VALUE'] ?? null;
1075 $filter['PROVIDER_VALUE'] = $filter['PROVIDER_KEY']
1076 && ! Input\Manager::getError(self::$personProviderValueInput[null][$filter['PROVIDER_KEY']], $value)
1077 ? Input\Manager::getValue(self::$personProviderValueInput[null][$filter['PROVIDER_KEY']], $value)
1078 : null;
1079
1080 return $filter;
1081 }
1082
1084
1085 private static $personTypes;
1086 private static $personProviderInput, $personProviderValueInput;
1087 private static $groups, $consumerInput, $consumerCodeInput;
1088
1090 public static function initialize()
1091 {
1092 self::$personTypes = array('' => array('DOMAIN' => '', 'TITLE' => Loc::getMessage('BIZVAL_DOMAIN_COMMON'))) + BusinessValue::getPersonTypes();
1093
1094 list (self::$personProviderInput, self::$personProviderValueInput) = self::getProviderInputs(BusinessValue::getProviders(), self::$personTypes);
1095
1096 self::$groups = array('' => array()) + BusinessValue::getGroups();
1097
1098 list (self::$consumerInput, self::$consumerCodeInput) = self::getConsumerInputs(BusinessValue::getConsumers(), self::$groups);
1099 }
1100
1102 public static function getProviderInput($personTypeId, array $providerKeys = null)
1103 {
1104 $providerInput = self::$personProviderInput[$personTypeId];
1105
1106 if ($providerKeys && is_array($providerInput['OPTIONS']))
1107 $providerInput['OPTIONS'] = array_intersect_key($providerInput['OPTIONS'], array_flip($providerKeys));
1108
1109 return $providerInput;
1110 }
1111
1113 public static function getValueInput($personTypeId, $providerKey = null)
1114 {
1115 return $providerKey
1116 ? self::$personProviderValueInput[$personTypeId][$providerKey]
1117 : self::$personProviderValueInput[$personTypeId];
1118 }
1119
1121 public static function getConsumerInput()
1122 {
1123 return self::$consumerInput;
1124 }
1125
1127 public static function getConsumerCodeInput()
1128 {
1129 return self::$consumerCodeInput;
1130 }
1131
1132 private static function getProviderInputs(array $providers, array $personTypes)
1133 {
1134 $personProviderInput = $personProviderValueInput = array();
1135
1136 $onChange = "bizvalChangeValue(this)";
1137
1138 foreach ($personTypes as $personTypeId => $personType)
1139 {
1140 $providerOptions = array();
1141
1142 foreach ($providers as $providerKey => $provider)
1143 {
1144 if (isset($provider['INPUT']) && is_array($provider['INPUT']))
1145 {
1146 $provider['INPUT']['REQUIRED'] = true;
1147 $provider['INPUT']['ONCHANGE'] = $onChange;
1148
1149 $providerOptions[$providerKey] = $provider['NAME'] ?? $providerKey;
1150 $personProviderValueInput[$personTypeId][$providerKey] = $provider['INPUT'];
1151 }
1152 elseif (isset($provider['FIELDS']) && is_array($provider['FIELDS']))
1153 {
1154 $fields = $provider['FIELDS'];
1155 $fieldOptions = array();
1156
1157 // group fields
1158 foreach ($fields as $fieldKey => $field)
1159 {
1160 if (
1161 is_array($field)
1162 && (empty($field['PERSON_TYPE_ID']) || $field['PERSON_TYPE_ID'] == $personTypeId)
1163 )
1164 {
1165 $group = $field['GROUP'] ?? null; // null is GENERAL
1166 $fieldOptions[$group][$fieldKey] = $field['NAME'] ?? $fieldKey;
1167 }
1168 }
1169
1170 if (count($fieldOptions) == 1)
1171 {
1172 $fieldOptions = reset($fieldOptions);
1173 }
1174 elseif (is_array($provider['FIELDS_GROUPS']))
1175 {
1176 self::sortRenameGroups($fieldOptions, $provider['FIELDS_GROUPS']);
1177 }
1178
1179 if (! empty($fieldOptions))
1180 {
1181 $providerOptions[$providerKey] = $provider['NAME'] ?? $providerKey;
1182 $personProviderValueInput[$personTypeId][$providerKey] = array('TYPE' => 'ENUM', 'OPTIONS' => $fieldOptions, 'ONCHANGE' => $onChange);
1183 }
1184 }
1185 else
1186 {
1187 $providerOptions[$providerKey] = $provider['NAME'] ?? $providerKey;
1188 $personProviderValueInput[$personTypeId][$providerKey] = array('TYPE' => 'STRING', 'SIZE' => 30, 'ONCHANGE' => $onChange);
1189 }
1190 }
1191
1192 $personProviderValueInput[$personTypeId][''] = array('TYPE' => 'STRING', 'SIZE' => 30); // for filter only
1193
1194 if ($providerOptions)
1195 {
1196 $personProviderInput[$personTypeId] = array(
1197 'TYPE' => 'ENUM',
1198 'OPTIONS' => $providerOptions,
1199 'REQUIRED' => true,
1200 'ONCHANGE' => "bizvalChangeProvider(this, '".$personTypeId."')",
1201 );
1202 }
1203 }
1204
1205 return array($personProviderInput, $personProviderValueInput);
1206 }
1207
1208 private static function getConsumerInputs(array $consumers, array $groups)
1209 {
1210 $consumerInput = array(
1211 'TYPE' => 'ENUM',
1212 'REQUIRED' => true,
1213 );
1214
1215 $consumerCodeInput = array();
1216
1217 $consumerOptions = array();
1218
1219 foreach ($consumers as $consumerKey => $consumer)
1220 {
1221 if (is_array($consumer) && isset($consumer['CODES']) && is_array($consumer['CODES']))
1222 {
1223 $consumerCodes = $consumer['CODES'];
1224 $consumerGroup = $consumer['GROUP'] ?? null; // null is GENERAL
1225
1226 $consumerOptions[$consumerGroup][$consumerKey] = $consumer['NAME'] ?? $consumerKey;
1227
1228 $codeOptions = array();
1229
1230 foreach ($consumerCodes as $codeKey => $code)
1231 {
1232 if (is_array($code) && isset($code['GROUP']))
1233 {
1234 $codeOptions[$code['GROUP']][$codeKey] = $code['NAME'] ?? $codeKey;
1235 }
1236 }
1237
1238 if (count($codeOptions) == 1)
1239 {
1240 $codeOptions = reset($codeOptions);
1241 }
1242 else
1243 {
1244 self::sortRenameGroups($codeOptions, $groups, true);
1245 }
1246
1247 $consumerCodeInput[$consumerKey] = array(
1248 'TYPE' => 'ENUM',
1249 'OPTIONS' => array('' => Loc::getMessage('BIZVAL_PAGE_ALL')) + $codeOptions,
1250 );
1251 }
1252 }
1253
1254 if ($consumerOptions)
1255 {
1256 self::sortRenameGroups($consumerOptions, $groups, true);
1257 $consumerInput['OPTIONS'] = $consumerOptions;
1258 }
1259
1260 return array($consumerInput, $consumerCodeInput);
1261 }
1262
1263 private static function sortRenameGroups(array &$groupedItems, array $groups, $flattenEmptyGroup = false)
1264 {
1265 $sortedItems = array();
1266
1267 if ($flattenEmptyGroup && isset($groupedItems['']))
1268 {
1269 $sortedItems = $groupedItems[''];
1270 unset($groupedItems['']);
1271 }
1272
1273 foreach ($groups as $groupKey => $group)
1274 {
1275 if (is_array($group) && isset($groupedItems[$groupKey]))
1276 {
1277 $sortedItems[$group['NAME'] ?? $groupKey] = $groupedItems[$groupKey];
1278 unset($groupedItems[$groupKey]);
1279 }
1280 }
1281
1282 $groupedItems = $sortedItems + $groupedItems;
1283 }
1284}
1285
1286BusinessValueControl::initialize();
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29