. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ namespace Espo\Core\FieldSanitize; use Espo\Core\FieldSanitize\Sanitizer\Data; use Espo\Core\InjectableFactory; use Espo\Core\Utils\FieldUtil; use Espo\Core\Utils\Metadata; use stdClass; class SanitizeManager { public function __construct( private Metadata $metadata, private FieldUtil $fieldUtil, private InjectableFactory $injectableFactory ) {} public function process(string $entityType, stdClass $rawData): void { $data = new Data($rawData); foreach ($this->fieldUtil->getEntityTypeFieldList($entityType) as $field) { if (!$this->isFieldSetInData($entityType, $field, $rawData)) { continue; } $this->processField($entityType, $field, $data); } } private function processField(string $entityType, string $field, Data $data): void { foreach ($this->getSanitizerList($entityType, $field) as $sanitizer) { $sanitizer->sanitize($data, $field); } } private function isFieldSetInData(string $entityType, string $field, stdClass $data): bool { $attributeList = $this->fieldUtil->getActualAttributeList($entityType, $field); $isSet = false; foreach ($attributeList as $attribute) { if (property_exists($data, $attribute)) { $isSet = true; break; } } return $isSet; } /** * @return Sanitizer[] */ private function getSanitizerList(string $entityType, string $field): array { $classNameList = $this->getClassNameList($entityType, $field); return array_map( fn ($className) => $this->injectableFactory->createWith($className, ['entityType' => $entityType]), $classNameList ); } /** * @return class-string[] */ private function getClassNameList(string $entityType, string $field): array { $fieldType = $this->fieldUtil->getFieldType($entityType, $field); if (!$fieldType) { return []; } $classNameList = []; /** @var ?class-string $className */ $className = $this->metadata->get("fields.$fieldType.sanitizerClassName"); if ($className) { $classNameList[] = $className; } /** @var class-string[] $typeClassNameList */ $typeClassNameList = $this->metadata->get("fields.$fieldType.sanitizerClassNameList") ?? []; $classNameList = array_merge($classNameList, $typeClassNameList); /** @var class-string[] $fieldClassNameList */ $fieldClassNameList = $this->metadata->get("entityDefs.$entityType.fields.$field.sanitizerClassNameList") ?? []; $ignoreList = $this->metadata->get("entityDefs.$entityType.fields.$field.sanitizerSuppressClassNameList") ?? []; $list = array_merge($classNameList, $fieldClassNameList); if ($ignoreList === []) { return $list; } $list = array_diff($list, $ignoreList); return array_values($list); } }