*/ public function getAncestors(): array { return self::ancestorMap()[$this] ?? []; } /** * @return list * @internal */ public function getFamily(): array { $family = [$this]; foreach (self::ancestorMap() as $child => $ancestors) { if (in_array($this, $ancestors, true)) { $family[] = $child; } } return $family; } /** * Determines whether a mutation for the current directive would be reasonable. * For instance, changing the `default-src` or `report-uri` would not qualify. */ public function isMutationReasonable(): bool { return in_array($this, self::reasonableMutationItems(), true); } /** * Determines whether the current directive can be used without any values, * like for instance `sandbox`, `trusted-types` or `upgrade-insecure-requests`. */ public function isStandAlone(): bool { return in_array($this, self::STAND_ALONE, true); } /** * @return \WeakMap> */ private static function ancestorMap(): \WeakMap { /** @var \WeakMap> $map temporary, internal \WeakMap */ $map = new \WeakMap(); $map[self::ChildSrc] = [self::DefaultSrc]; $map[self::ConnectSrc] = [self::DefaultSrc]; $map[self::FontSrc] = [self::DefaultSrc]; $map[self::FrameSrc] = [self::ChildSrc, self::DefaultSrc]; $map[self::ImgSrc] = [self::DefaultSrc]; $map[self::ManifestSrc] = [self::DefaultSrc]; $map[self::MediaSrc] = [self::DefaultSrc]; $map[self::ObjectSrc] = [self::DefaultSrc]; $map[self::ScriptSrc] = [self::DefaultSrc]; $map[self::ScriptSrcAttr] = [self::ScriptSrc, self::DefaultSrc]; $map[self::ScriptSrcElem] = [self::ScriptSrc, self::DefaultSrc]; $map[self::StyleSrc] = [self::DefaultSrc]; $map[self::StyleSrcAttr] = [self::StyleSrc, self::DefaultSrc]; $map[self::StyleSrcElem] = [self::StyleSrc, self::DefaultSrc]; $map[self::WorkerSrc] = [self::ChildSrc, self::ScriptSrc, self::DefaultSrc]; return $map; } /** * @return list */ private static function reasonableMutationItems(): array { return [ self::ConnectSrc, self::FontSrc, self::FrameSrc, self::ImgSrc, self::MediaSrc, self::ScriptSrcElem, self::StyleSrcElem, ]; } }