isConcreteSpecialistDomain($requested)) { return $requested; } if ($this->hasAnyAttribute($product, ['isbn', 'isbn_10', 'isbn_13'])) { return MediaType::BOOK; } if ($this->hasAnyAttribute($product, ['imdb_id'])) { return MediaType::MOVIE; } if ($this->hasAnyAttribute($product, ['mbid', 'musicbrainz_id'])) { return MediaType::MUSIC; } if ($this->hasAnyAttribute($product, ['aic', 'aic_package', 'atc', 'active_ingredient'])) { return MediaType::MEDICINE; } $authority = $this->attributeValue($product, 'classification_authority'); $canonical = MediaType::normalize($this->attributeValue($product, 'media_type')); if (in_array($authority, ClassificationDecision::authorities(), true) && $this->isConcreteSpecialistDomain($canonical)) { return $canonical; } return null; } private function attributeValue(ProductDTO $product, string $name): string { $name = strtolower(trim($name)); foreach ($product->getAttributes() as $attribute) { if ($attribute instanceof AttributeDTO && strtolower(trim($attribute->getName())) === $name) { return trim($attribute->getValue()); } } return ''; } private function hasAnyAttribute(ProductDTO $product, array $names): bool { $names = array_map(static fn (string $name): string => strtolower(trim($name)), $names); foreach ($product->getAttributes() as $attribute) { if ( $attribute instanceof AttributeDTO && in_array(strtolower(trim($attribute->getName())), $names, true) && trim($attribute->getValue()) !== '' ) { return true; } } return false; } private function isConcreteSpecialistDomain(string $mediaType): bool { return in_array($mediaType, [ MediaType::BOOK, MediaType::MOVIE, MediaType::MUSIC, MediaType::GAME, MediaType::FOOD, MediaType::BEAUTY, MediaType::JEWELRY, MediaType::MEDICINE, ], true); } }