Skip to content

Commit

Permalink
Merge branch '11.x' into cache-view-factory-repeated-calls
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell authored Apr 22, 2024
2 parents 5d6375f + ca54cb6 commit 003d994
Show file tree
Hide file tree
Showing 15 changed files with 267 additions and 150 deletions.
26 changes: 12 additions & 14 deletions src/Illuminate/Database/Console/Migrations/FreshCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,18 @@ public function handle()

$database = $this->input->getOption('database');

if (! is_null($database)) {
$this->migrator->setConnection($database);
}

if ($this->migrator->repositoryExists()) {
$this->newLine();

$this->components->task('Dropping all tables', fn () => $this->callSilent('db:wipe', array_filter([
'--database' => $database,
'--drop-views' => $this->option('drop-views'),
'--drop-types' => $this->option('drop-types'),
'--force' => true,
])) == 0);
}
$this->migrator->usingConnection($database, function () use ($database) {
if ($this->migrator->repositoryExists()) {
$this->newLine();

$this->components->task('Dropping all tables', fn () => $this->callSilent('db:wipe', array_filter([
'--database' => $database,
'--drop-views' => $this->option('drop-views'),
'--drop-types' => $this->option('drop-types'),
'--force' => true,
])) == 0);
}
});

$this->newLine();

Expand Down
2 changes: 1 addition & 1 deletion src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ protected function compileLegacyRenameColumn(Blueprint $blueprint, Fluent $comma
default => $column['type_name'],
},
'nullable' => $column['nullable'],
'default' => $column['default'] && str_starts_with(strtolower($column['default']), 'current_timestamp')
'default' => $column['default'] && (str_starts_with(strtolower($column['default']), 'current_timestamp') || $column['default'] === 'NULL')
? new Expression($column['default'])
: $column['default'],
'autoIncrement' => $column['auto_increment'],
Expand Down
5 changes: 3 additions & 2 deletions src/Illuminate/Validation/NestedRules.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ public function __construct(callable $callback)
* @param string $attribute
* @param mixed $value
* @param mixed $data
* @param mixed $context
* @return \stdClass
*/
public function compile($attribute, $value, $data = null)
public function compile($attribute, $value, $data = null, $context = null)
{
$rules = call_user_func($this->callback, $value, $attribute, $data);
$rules = call_user_func($this->callback, $value, $attribute, $data, $context);

$parser = new ValidationRuleParser(
Arr::undot(Arr::wrap($data))
Expand Down
6 changes: 4 additions & 2 deletions src/Illuminate/Validation/ValidationRuleParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ protected function prepareRule($rule, $attribute)

if ($rule instanceof NestedRules) {
return $rule->compile(
$attribute, $this->data[$attribute] ?? null, Arr::dot($this->data)
$attribute, $this->data[$attribute] ?? null, Arr::dot($this->data), $this->data
)->rules[$attribute];
}

Expand All @@ -152,7 +152,9 @@ protected function explodeWildcardRules($results, $attribute, $rules)
if (Str::startsWith($key, $attribute) || (bool) preg_match('/^'.$pattern.'\z/', $key)) {
foreach ((array) $rules as $rule) {
if ($rule instanceof NestedRules) {
$compiled = $rule->compile($key, $value, $data);
$context = Arr::get($this->data, Str::beforeLast($key, '.'));

$compiled = $rule->compile($key, $value, $data, $context);

$this->implicitAttributes = array_merge_recursive(
$compiled->implicitAttributes,
Expand Down
4 changes: 2 additions & 2 deletions src/Illuminate/View/Compilers/ComponentTagCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,8 @@ protected function componentString(string $component, array $attributes)
}

return "##BEGIN-COMPONENT-CLASS##@component('{$class}', '{$component}', [".$this->attributesToString($parameters, $escapeBound = false).'])
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag && $constructor = (new ReflectionClass('.$class.'::class))->getConstructor()): ?>
<?php $attributes = $attributes->except(collect($constructor->getParameters())->map->getName()->all()); ?>
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
<?php $attributes = $attributes->except(\\'.$class.'::ignoredParameterNames()); ?>
<?php endif; ?>
<?php $component->withAttributes(['.$this->attributesToString($attributes->all(), $escapeAttributes = $class !== DynamicComponent::class).']); ?>';
}
Expand Down
40 changes: 28 additions & 12 deletions src/Illuminate/View/Compilers/Concerns/CompilesComponents.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public static function compileClassComponentOpening(string $component, string $a
return implode("\n", [
'<?php if (isset($component)) { $__componentOriginal'.$hash.' = $component; } ?>',
'<?php if (isset($attributes)) { $__attributesOriginal'.$hash.' = $attributes; } ?>',
'<?php $component = '.$component.'::resolve('.($data ?: '[]').' + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? (array) $attributes->getIterator() : [])); ?>',
'<?php $component = '.$component.'::resolve('.($data ?: '[]').' + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>',
'<?php $component->withName('.$alias.'); ?>',
'<?php if ($component->shouldRender()): ?>',
'<?php $__env->startComponent($component->resolveView(), $component->data()); ?>',
Expand Down Expand Up @@ -157,19 +157,35 @@ protected function compileEndComponentFirst()
*/
protected function compileProps($expression)
{
return "<?php \$attributes ??= new \\Illuminate\\View\\ComponentAttributeBag; ?>
<?php foreach(\$attributes->onlyProps{$expression} as \$__key => \$__value) {
\$\$__key = \$\$__key ?? \$__value;
} ?>
<?php \$attributes = \$attributes->exceptProps{$expression}; ?>
<?php foreach (array_filter({$expression}, 'is_string', ARRAY_FILTER_USE_KEY) as \$__key => \$__value) {
return "<?php \$attributes ??= new \\Illuminate\\View\\ComponentAttributeBag;
\$__newAttributes = [];
\$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames({$expression});
foreach (\$attributes->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;
} ?>
<?php \$__defined_vars = get_defined_vars(); ?>
<?php foreach (\$attributes as \$__key => \$__value) {
}
\$__defined_vars = get_defined_vars();
foreach (\$attributes->all() as \$__key => \$__value) {
if (array_key_exists(\$__key, \$__defined_vars)) unset(\$\$__key);
} ?>
<?php unset(\$__defined_vars); ?>";
}
unset(\$__defined_vars); ?>";
}

/**
Expand Down
31 changes: 31 additions & 0 deletions src/Illuminate/View/Component.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ abstract class Component
*/
protected static $constructorParametersCache = [];

/**
* The cache of ignored parameter names.
*
* @var array
*/
protected static $ignoredParameterNames = [];

/**
* Get the view / view contents that represent the component.
*
Expand Down Expand Up @@ -417,6 +424,30 @@ protected function factory()
return static::$factory;
}

/**
* Get the cached set of anonymous component constructor parameter names to exclude.
*
* @return array
*/
public static function ignoredParameterNames()
{
if (! isset(static::$ignoredParameterNames[static::class])) {
$constructor = (new ReflectionClass(
static::class
))->getConstructor();

if (! $constructor) {
return static::$ignoredParameterNames[static::class] = [];
}

static::$ignoredParameterNames[static::class] = collect($constructor->getParameters())
->map->getName()
->all();
}

return static::$ignoredParameterNames[static::class];
}

/**
* Flush the component's cached state.
*
Expand Down
54 changes: 32 additions & 22 deletions src/Illuminate/View/ComponentAttributeBag.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ public function __construct(array $attributes = [])
$this->attributes = $attributes;
}

/**
* Get all of the attribute values.
*
* @return array
*/
public function all()
{
return $this->attributes;
}

/**
* Get the first attribute's value.
*
Expand Down Expand Up @@ -207,7 +217,7 @@ public function thatStartWith($needles)
*/
public function onlyProps($keys)
{
return $this->only($this->extractPropNames($keys));
return $this->only(static::extractPropNames($keys));
}

/**
Expand All @@ -218,27 +228,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(static::extractPropNames($keys));
}

/**
Expand Down Expand Up @@ -401,6 +391,26 @@ public function setAttributes(array $attributes)
$this->attributes = $attributes;
}

/**
* Extract "prop" names from given keys.
*
* @param array $keys
* @return array
*/
public static function extractPropNames(array $keys)
{
$props = [];

foreach ($keys as $key => $default) {
$key = is_numeric($key) ? $default : $key;

$props[] = $key;
$props[] = Str::kebab($key);
}

return $props;
}

/**
* Get content as a string of HTML.
*
Expand Down
8 changes: 6 additions & 2 deletions src/Illuminate/View/Concerns/ManagesEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ protected function addEventListener($name, $callback)
*/
public function callComposer(ViewContract $view)
{
$this->events->dispatch('composing: '.$view->name(), [$view]);
if ($this->events->hasListeners($event = 'composing: '.$view->name())) {
$this->events->dispatch($event, [$view]);
}
}

/**
Expand All @@ -185,6 +187,8 @@ public function callComposer(ViewContract $view)
*/
public function callCreator(ViewContract $view)
{
$this->events->dispatch('creating: '.$view->name(), [$view]);
if ($this->events->hasListeners($event = 'creating: '.$view->name())) {
$this->events->dispatch($event, [$view]);
}
}
}
3 changes: 3 additions & 0 deletions tests/Database/DatabaseSchemaBlueprintTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ public function testNativeRenameColumnOnLegacyMariaDB()
$table->renameColumn('name', 'title');
$table->renameColumn('id', 'key');
$table->renameColumn('generated', 'new_generated');
$table->renameColumn('foo', 'bar');
});

$connection = m::mock(Connection::class);
Expand All @@ -224,12 +225,14 @@ public function testNativeRenameColumnOnLegacyMariaDB()
['name' => 'name', 'type' => 'varchar(255)', 'type_name' => 'varchar', 'nullable' => true, 'collation' => 'utf8mb4_unicode_ci', 'default' => 'foo', 'comment' => null, 'auto_increment' => false],
['name' => 'id', 'type' => 'bigint unsigned', 'type_name' => 'bigint', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => 'lorem ipsum', 'auto_increment' => true],
['name' => 'generated', 'type' => 'int', 'type_name' => 'int', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => null, 'auto_increment' => false, 'generation' => ['type' => 'stored', 'expression' => 'expression']],
['name' => 'foo', 'type' => 'int', 'type_name' => 'int', 'nullable' => true, 'collation' => null, 'default' => 'NULL', 'comment' => null, 'auto_increment' => false, 'generation' => null],
]);

$this->assertEquals([
"alter table `users` change `name` `title` varchar(255) collate 'utf8mb4_unicode_ci' null default 'foo'",
"alter table `users` change `id` `key` bigint unsigned not null auto_increment comment 'lorem ipsum'",
'alter table `users` change `generated` `new_generated` int as (expression) stored not null',
'alter table `users` change `foo` `bar` int null default NULL',
], $blueprint->toSql($connection, new MariaDbGrammar));
}

Expand Down
11 changes: 7 additions & 4 deletions tests/Validation/ValidationRuleParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,16 @@ public function testExplodeGeneratesNestedRules()
{
$parser = (new ValidationRuleParser([
'users' => [
['name' => 'Taylor Otwell'],
['name' => 'Taylor Otwell', 'email' => '[email protected]'],
],
]));

$results = $parser->explode([
'users.*.name' => Rule::forEach(function ($value, $attribute, $data) {
'users.*.name' => Rule::forEach(function ($value, $attribute, $data, $context) {
$this->assertSame('Taylor Otwell', $value);
$this->assertSame('users.0.name', $attribute);
$this->assertEquals($data['users.0.name'], 'Taylor Otwell');
$this->assertEquals(['name' => 'Taylor Otwell', 'email' => '[email protected]'], $context);

return [Rule::requiredIf(true)];
}),
Expand All @@ -201,13 +202,15 @@ public function testExplodeGeneratesNestedRulesForNonNestedData()
{
$parser = (new ValidationRuleParser([
'name' => 'Taylor Otwell',
'email' => '[email protected]',
]));

$results = $parser->explode([
'name' => Rule::forEach(function ($value, $attribute, $data = null) {
'name' => Rule::forEach(function ($value, $attribute, $data = null, $context) {
$this->assertSame('Taylor Otwell', $value);
$this->assertSame('name', $attribute);
$this->assertEquals(['name' => 'Taylor Otwell'], $data);
$this->assertEquals(['name' => 'Taylor Otwell', 'email' => '[email protected]'], $data);
$this->assertEquals(['name' => 'Taylor Otwell', 'email' => '[email protected]'], $context);

return 'required';
}),
Expand Down
Loading

0 comments on commit 003d994

Please sign in to comment.