$segment) { if ($segment !== '*') { continue; } $rowIndex = Arr::get($attributeSegments, $index); if ($rowIndex === null || !is_numeric($rowIndex)) { return null; } $pathSegments[$index] = $rowIndex; } return implode('.', $pathSegments); } /** * Mirror validateRequiredIf(): compare as booleans when the other field * holds one, so 'true' / 'false' in a rule definition still match. * * @param mixed $otherValue * @param array $expectedValues * @return array */ protected static function matchTypeOf($otherValue, array $expectedValues): array { if (!is_bool($otherValue)) { return $expectedValues; } return array_map(function ($expected) { if ($expected === 'true') { return true; } if ($expected === 'false') { return false; } return $expected; }, $expectedValues); } /** * Mirror validateRequired(). Public so WhenFilledRule can draw the same * empty/filled line this rule does — the two are complementary halves of one * attribute's validation and must agree on where that line sits. * * @param mixed $value * @return bool */ public static function isFilled($value): bool { if (is_null($value)) { return false; } if (is_string($value) && trim($value) === '') { return false; } if ((is_array($value) || $value instanceof Countable) && count($value) < 1) { return false; } return true; } }