getBaseDomain($domain); $parts = explode('.', $domain); $combinations = []; for ($i = 0; $i < count($parts) - 1; $i++) { $combinations[] = implode('.', array_slice($parts, $i)); } usort($combinations, function ($a, $b) { return strlen($b) - strlen($a); }); return $combinations; } /** * Retrieves merged rules for a domain * @param string $domain Target domain * @return array|null Combined ruleset or global rules */ public function getDomainRules($domain) { $domainParts = $this->getDomainParts($domain); foreach ($this->domainRules as $pattern => $rules) { if ($this->getBaseDomain($domain) === $this->getBaseDomain($pattern)) { return $this->mergeWithGlobalRules($rules); } } foreach ($domainParts as $part) { foreach ($this->domainRules as $pattern => $rules) { if ($part === $this->getBaseDomain($pattern)) { return $this->mergeWithGlobalRules($rules); } } } return $this->getGlobalRules(); } /** * Retrieves merged rules for a domain * @param string $domain Target domain * @return array|null Combined ruleset or global rules */ public function hasDomainRules($domain) { $domainParts = $this->getDomainParts($domain); // Check for exact domain match first foreach ($this->domainRules as $pattern => $rules) { if ($this->getBaseDomain($domain) === $this->getBaseDomain($pattern)) { return true; } } // Check for partial domain matches foreach ($domainParts as $part) { foreach ($this->domainRules as $pattern => $rules) { if ($part === $this->getBaseDomain($pattern)) { return true; } } } return false; } /** * Combines domain rules with global configuration * @param array $rules Domain-specific rules */ private function mergeWithGlobalRules($rules) { $globalRules = $this->getGlobalRules(); $mergedRules = []; $excludeGlobalRules = $rules['excludeGlobalRules'] ?? []; unset($rules['excludeGlobalRules']); foreach ($globalRules as $ruleType => $globalTypeRules) { if (!in_array($ruleType, $this->supportedRuleTypes)) continue; if (isset($excludeGlobalRules[$ruleType])) { if (is_assoc_array($globalTypeRules)) { $result = array_diff_key($globalTypeRules, array_flip($excludeGlobalRules[$ruleType])); $mergedRules[$ruleType] = is_array($result) ? $result : []; } else { $result = array_diff($globalTypeRules, $excludeGlobalRules[$ruleType]); $mergedRules[$ruleType] = is_array($result) ? $result : []; } } else { $mergedRules[$ruleType] = is_array($globalTypeRules) ? $globalTypeRules : []; } } foreach ($rules as $ruleType => $domainTypeRules) { if (!in_array($ruleType, $this->supportedRuleTypes)) continue; if (!isset($mergedRules[$ruleType])) { $mergedRules[$ruleType] = $domainTypeRules; continue; } if (in_array($ruleType, ['cookies', 'headers'])) { $mergedRules[$ruleType] = array_merge( is_array($mergedRules[$ruleType]) ? $mergedRules[$ruleType] : [], is_array($domainTypeRules) ? $domainTypeRules : [] ); } else { $mergedRules[$ruleType] = array_values(array_unique(array_merge( is_array($mergedRules[$ruleType]) ? $mergedRules[$ruleType] : [], (array)$domainTypeRules ))); } } return $mergedRules; } /** @return array Global rule configuration */ public function getGlobalRules() { return $this->globalRules; } } // Helper function for associative array check function is_assoc_array($array) { return array_keys($array) !== range(0, count($array) - 1); }