No release, weekly updates, and 🔥 tip

No release

No release today with Taylor on vacation.

A reminder subscribers to a Shifty Plan automatically receive a PR bumping Laravel, as well as other packages, anytime there is a new release.

This automation is a nice way to stay up-to-date and periodically kick-off your CI builds. However, they're really just a bonus for subscribers. The main value of a Shifty Plan are the included Shifts, full access to the Workbench, and webhooks.

Weekly Journal

Last week Jess and I paired to create a Shift to convert Laravel Mix to Vite. I released a beta version on Wednesday and continued to make tweaks into the weekend.

At this point I feel it's pretty complete. It will remain free as a sort of honeypot. Hopefully to catch those last reluctant customers still not convinced of Shift's awesomeness.

The Vite integration itself is still maturing. So I will continue to add automation as the community discovers more ways to handle heavily customized Laravel Mix configurations.

Last week I also live streamed converting ternary to null safe operators. There was a remaining logic bug which I fixed this morning and updated the task within the Shift Workbench.

Tomorrow I'll live stream writing automation for normalizing request data within a Laravel application. I'll probably continue to work on this the rest of the week.

Finally, a Human Shift came in late last week where I paired with a team to solve some deployment issues after upgrading to Laravel 9 + PHP 8.1.

🔥 Tip

Much of Shift uses string replacement to make changes within files. To determine if I should make a commit or leave a comment, I need to know if a replacement was made.

Instead of testing if the replacement exists beforehand (which makes the code noisy), many of the replacement functions have a count parameter you may pass by reference.

However, there is, of course, an exception. preg_replace_callback will set count to the number of times the callback is invoked. Depending on the logic within the callback, this may not necessarily be the same as the number of replacements. So you may need to track the count yourself.

Here's a little snippet from the Vite Converter where I track the dirty state:

$contents = preg_replace_callback(
function ($matches) use ($components) {
if (!in_array($matches[2], $components)) {
return $matches[0];
return rtrim($matches[0], $matches[1]) . '.vue' . $matches[1];