$callbacks) { if (!$callbacks) continue; $callbacks = is_array($callbacks) ? $callbacks : [$callbacks]; $array[$key] = $callbacks; if (str_contains($key, '*')) { $array = static::substituteWildcardKeys($array, $key, $data); } foreach ($array as $k => $callbacks) { $callbacks = static::mayBeFixCallbacks($callbacks); if (($value = Arr::get($data, $k)) !== null) { $callbacks = is_callable($callbacks) ? [$callbacks] : $callbacks; while ($callback = static::getCallback(array_shift($callbacks))) { if (is_array($value)) { $value = array_map($callback, $value); } else { $value = $callback($value); } } Arr::set($result, $k, $value); } } } return $result; } /** * Normalize wildcard rules to dotted rule. * * @param array $array * @param string $field * @param array $data * @return array */ protected static function substituteWildcardKeys($array, $field, $data) { $callback = $array[$field]; $keys = array_map(function($v) { return trim($v, '.'); }, explode('*', $field)); $key = array_shift($keys); if ($key && ($val = Arr::get($data, $key)) && is_array($val)) { $dotted = array_keys(Arr::dot($val, $key . '.')); foreach ($dotted as $dottedField) { $r = preg_replace('/[0-9]+/', '*', $dottedField); if (preg_match("/{$field}/", $r)) { $array[$dottedField] = $callback; if (isset($array[$field])) { unset($array[$field]); } } } } return $array; } /** * Check and fix if callbacks are given * as: callback1|callback2\callback3. * * @param array|string $callbacks * @return array */ protected static function mayBeFixCallbacks($callbacks) { $nonFunctionCallables = $functionCallables = []; foreach ($callbacks as $cb) { if (is_callable($cb)) { $nonFunctionCallables[] = $cb; } elseif (is_string($cb)) { $functionCallables[] = explode('|', $cb); } elseif (is_array($cb) && !str_contains($cb[0], '::')) { $functionCallables[] = $cb[0]; } elseif (is_array($cb) && str_contains($cb[0], '::')) { $nonFunctionCallables[] = explode('::', $cb[0]); } } $callbacks = array_merge( Arr::flatten($functionCallables), $nonFunctionCallables ); return $callbacks; } /** * Get the callback function. * * @param callable|string $callback * @return callable|null */ protected static function getCallback($callback) { if ($callback) { if ($cb = static::methodExists($callback)) { $callback = $cb; } } return $callback; } /** * Check if the method exists. * * @param string $method * @return callable|null */ protected static function methodExists($method) { $suffix = ''; if (Str::endsWith($method, '__')) { $suffix = '__'; } $method = Str::camel($method) . $suffix; if (method_exists(static::class, $method)) { return [static::class, $method]; } } }