1<?php 2 3declare(strict_types=1); 4 5/* 6 * This file is part of the TYPO3 CMS project. 7 * 8 * It is free software; you can redistribute it and/or modify it under 9 * the terms of the GNU General Public License, either version 2 10 * of the License, or any later version. 11 * 12 * For the full copyright and license information, please read the 13 * LICENSE.txt file that was distributed with this source code. 14 * 15 * The TYPO3 project - inspiring people to share! 16 */ 17 18namespace TYPO3\CMS\Backend\Form\Behavior; 19 20use TYPO3\CMS\Core\Utility\GeneralUtility; 21 22trait OnFieldChangeTrait 23{ 24 /** 25 * @param array<string, string|OnFieldChangeInterface> $items `fieldChangeFunc` items 26 * @return array<int, array> 27 */ 28 protected function getOnFieldChangeItems(array $items): array 29 { 30 if (empty($items)) { 31 return []; 32 } 33 return array_map( 34 static function (OnFieldChangeInterface $item) { 35 return $item->toArray(); 36 }, 37 // omitting array keys 38 array_values($items) 39 ); 40 } 41 42 /** 43 * @param string $event target client event, either `change` or `click` 44 * @param array<string, string|OnFieldChangeInterface> $items `fieldChangeFunc` items 45 * @return array<string, string> HTML attrs, not encoded - consumers MUST encode with `htmlspecialchars` 46 */ 47 protected function getOnFieldChangeAttrs(string $event, array $items): array 48 { 49 if (empty($items)) { 50 return []; 51 } 52 if ($this->validateOnFieldChange($items)) { 53 $onFieldChangeItems = $this->getOnFieldChangeItems($items); 54 $attrs = [ 55 'data-formengine-field-change-event' => $event, 56 'data-formengine-field-change-items' => GeneralUtility::jsonEncodeForHtmlAttribute($onFieldChangeItems, false), 57 ]; 58 } else { 59 $attrs = [ 60 'on' . $event => implode(';', $items), 61 ]; 62 } 63 return $attrs; 64 } 65 66 /** 67 * @param array<string, string|OnFieldChangeInterface> $items `fieldChangeFunc` items 68 * @param bool $deprecate whether to trigger deprecations 69 * @return bool whether all items implement `OnFieldChangeInterface` 70 */ 71 protected function validateOnFieldChange(array $items, bool $deprecate = true): bool 72 { 73 $result = true; 74 // all items are processed, to log all possible deprecated usages 75 foreach ($items as $name => $item) { 76 if ($item instanceof OnFieldChangeInterface) { 77 continue; 78 } 79 $result = false; 80 if (!$deprecate) { 81 continue; 82 } 83 trigger_error( 84 sprintf('Using scalar `fieldChangeFunc` for `%s` is deprecated and will be removed in TYPO3 v12.0. Use `OnFieldChangeInterface` instead.', $name), 85 E_USER_DEPRECATED 86 ); 87 } 88 return $result; 89 } 90 91 /** 92 * Forwards URL query params for `LinkBrowserController` 93 * @param array<string, string|OnFieldChangeInterface> $items `fieldChangeFunc` items 94 * @return array<string, string> relevant URL query params for `LinkBrowserController` 95 */ 96 protected function forwardOnFieldChangeQueryParams(array $items): array 97 { 98 if ($this->validateOnFieldChange($items, false)) { 99 $type = 'items'; 100 $func = $this->getOnFieldChangeItems($items); 101 } else { 102 $type = 'raw'; 103 $func = $items; 104 } 105 return [ 106 'fieldChangeFunc' => $func, 107 'fieldChangeFuncType' => $type, 108 'fieldChangeFuncHash' => GeneralUtility::hmac(serialize($func), 'backend-link-browser'), 109 ]; 110 } 111} 112