Laravel 10.13 Released
Published on by Paul Redmond
This week, the Laravel team released v10.13 with database escaping functionality in Grammar, Sleep test hooks, response preparation events, and more:
isHashed()
method
Hash Günther Debrauwer contributed an isHashed()
method that wraps the native password_get_info()
call, which determines if a string is already hashed:
Hash::isHashed($value); // bool
This means this method can be mocked and isn't locked in to the password_get_info()
function call to determine hashing.
Escaping functionality within the Grammar
Tobias Petry previously contributed database expressions with grammar-specific formatting, and is following that up with escaping functionality within the Grammar
class:
To solve the problem, I am proposing a solution to add support for database grammars to escape any value for safe embedding into SQL queries. PHP provides this natively with the
PDO::quote
method.
Individual connection instances (i.e., PostgresConnection
) implement database-specific escaping, which means you wouldn't have to use raw driver-specific queries to escape values:
// Taken from the Postgres escaping tests$this->assertSame( "'\\xdead00beef'::bytea", $this->app['db']->escape(hex2bin('dead00beef'), true)); $this->assertSame( '3.14159', $this->app['db']->escape(3.14159)); $this->assertSame( '-3.14159', $this->app['db']->escape(-3.14159)); $this->assertSame( "'Hello''World'", $this->app['db']->escape("Hello'World"));
Check out Pull Request #46558 for full details, implementation, and discussion around these concepts.
Provide Sleep testing hooks
Tim MacDonald contributed the ability to register a callback to execute while sleeping in a test:
// Implementation example from the PR:$timeout = now()->addMinute(); do { if (Work:attempt()) { return; } Sleep::for(100)->milliseconds();} while (now()->isAfter($timeout)); // Test code$this->freezeTime();Sleep::fake();Sleep::whenFakingSleep(fn (Interval $duration) => $this->travel( $duration->totalMilliseconds)->milliseconds()); // run test code. Sleep::assertSlept();
Effectively we can progress the now()
value to make sure our implementation is working as expected. See Pull Request #47228 for more details.
Additional status code assertions
Volodya Kurshudyan contributed a few status code assertion conveniences that are alternatives to asserting the status code directly:
$response->assertNotModified();$response->assertTemporaryRedirect();$response->assertPermanentRedirect();$response->assertNotAcceptable();
These convenience methods can be controversial regarding "should this be in the framework or not?". Feel free not to use them and use $response->assertStatus(308)
instead 💖
Wrap response preparation in events
Tim MacDonald contributed new response events to tap into the moment of preparing and after a response is prepared. This allows some interesting abilities, such as logging queries between the PreparingResponse
and ResponsePrepared
events. As illustrated below, you could throw an exception if any queries get executed during PreparingResponse
or log them out in production:
$logQueries = false; Event::listen(PreparingResponse::class, function () use (&$logQueries) { $logQueries = true;}); Event::listen(ResponsePrepared::class, function () use (&$logQueries) { $logQueries = false;}); DB::listen(function (QueryExecuted $event) use (&$logQueries) { if ($logQueries) { // log in production, throw locally. }});
See Pull Request #45603 for more details on the ideas behind these events, such as preventing queries during response preparation, view rendering, etc.
Release Notes
You can see the complete list of new features and updates below and the diff between 10.12.0 and 10.13.0 on GitHub. The following release notes are directly from the changelog:
v10.13.0
Added
- Added
Illuminate/Hashing/HashManager::isHashed()
(#47197) - Escaping functionality within the Grammar (#46558)
- Provide testing hooks in
Illuminate/Support/Sleep.php
(#47228) - Added missing methods to AssertsStatusCodes (#47277)
- Wrap response preparation in events (#47229)
Fixed
- Fixed bug when function wrapped around definition of related factory (#47168)
- Fixed inconsistentcy between report and render methods (#47201)
- Fixes Model::isDirty() when AsCollection or AsEncryptedCollection have arguments (#47235)
- Fixed escaped String for JSON_CONTAINS (#47244)
- Fixes missing output on ProcessFailedException exception (#47285)
Changed
- Remove useless else statements (#47186)
- RedisStore improvement - don't open transaction unless all values are serialaizable (#47193)
- Use carbon::now() to get current timestamp in takeUntilTimeout lazycollection-method (#47200)
- Avoid duplicates in visible/hidden on merge (#47264)
- Add a missing semicolon to CompilesClasses (#47280)
- Send along value to InvalidPayloadException (#47223)