diff --git a/src/Illuminate/Collections/Arr.php b/src/Illuminate/Collections/Arr.php index 605f71499b93..1246498f8fb4 100644 --- a/src/Illuminate/Collections/Arr.php +++ b/src/Illuminate/Collections/Arr.php @@ -12,6 +12,23 @@ class Arr { use Macroable; + /** + * Extract prop names from given keys. + */ + public static function extractPropNames(array $keys): array + { + $props = []; + + foreach ($keys as $key => $defaultValue) { + $key = is_numeric($key) ? $defaultValue : $key; + + $props[] = $key; + $props[] = Str::kebab($key); + } + + return $props; + } + /** * Determine whether the given value is array accessible. * diff --git a/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php b/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php index 88617186fb20..9e8f85ec129d 100644 --- a/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php +++ b/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php @@ -68,7 +68,7 @@ public static function compileClassComponentOpening(string $component, string $a return implode("\n", [ '', '', - 'getIterator() : [])); ?>', + 'all() : [])); ?>', 'withName('.$alias.'); ?>', 'shouldRender()): ?>', 'startComponent($component->resolveView(), $component->data()); ?>', @@ -157,19 +157,37 @@ protected function compileEndComponentFirst() */ protected function compileProps($expression) { - return " -onlyProps{$expression} as \$__key => \$__value) { - \$\$__key = \$\$__key ?? \$__value; -} ?> -exceptProps{$expression}; ?> - \$__value) { + return "all() as \$__key => \$__value) { + if (in_array(\$__key, \$__propNames)) { + \$\$__key = \$\$__key ?? \$__value; + } else { + \$__newAttributes[\$__key] = \$__value; + } +} + +\$attributes = new \Illuminate\View\ComponentAttributeBag(\$__newAttributes); + +unset(\$__propNames); +unset(\$__newAttributes); + +foreach (array_filter({$expression}, 'is_string', ARRAY_FILTER_USE_KEY) as \$__key => \$__value) { \$\$__key = \$\$__key ?? \$__value; -} ?> - - \$__value) { +} + +\$__defined_vars = get_defined_vars(); + +foreach (\$attributes->all() as \$__key => \$__value) { if (array_key_exists(\$__key, \$__defined_vars)) unset(\$\$__key); -} ?> -"; +} + +unset(\$__defined_vars); ?>"; } /** diff --git a/src/Illuminate/View/ComponentAttributeBag.php b/src/Illuminate/View/ComponentAttributeBag.php index 368391c038ff..88395ab3711e 100644 --- a/src/Illuminate/View/ComponentAttributeBag.php +++ b/src/Illuminate/View/ComponentAttributeBag.php @@ -26,6 +26,14 @@ class ComponentAttributeBag implements ArrayAccess, IteratorAggregate, JsonSeria */ protected $attributes = []; + /** + * Get all values to save time converting from iterator to array. + */ + public function all(): array + { + return $this->attributes; + } + /** * Create a new component attribute bag instance. * @@ -207,7 +215,7 @@ public function thatStartWith($needles) */ public function onlyProps($keys) { - return $this->only($this->extractPropNames($keys)); + return $this->only(Arr::extractPropNames($keys)); } /** @@ -218,27 +226,7 @@ public function onlyProps($keys) */ public function exceptProps($keys) { - return $this->except($this->extractPropNames($keys)); - } - - /** - * Extract prop names from given keys. - * - * @param mixed|array $keys - * @return array - */ - protected function extractPropNames($keys) - { - $props = []; - - foreach ($keys as $key => $defaultValue) { - $key = is_numeric($key) ? $defaultValue : $key; - - $props[] = $key; - $props[] = Str::kebab($key); - } - - return $props; + return $this->except(Arr::extractPropNames($keys)); } /**