Posts

Since 2024
Artisan `make` Commands Automatically Chop `.php` Extension in Laravel 11.12
Artisan `make` Commands Automatically Chop `.php` Extension in Laravel 11.12

This week, the Laravel team released v11.12, which includes a multiply collection method, automatically chopping the .php extension in make commands, and more. Chop PHP Extension When Passed to make Commands (v11.11.1) Jason McCreary contributed a nice DX feature when passing .php to make:* commands for generating files for things like controllers, events, commands, etc. Nothing changes except that Laravel now handles the .php extension behind the scenes: php artisan make:controller UserController.php # Before - app/Http/Controllers/UserController.php.php # After - app/Http/Controllers/UserController.php It's painful when you accidentally do this because you have to either move the files or delete them and recreate everything. It's not clear if the command will take care of chopping the extension when typing, so this is a nice touch to some hidden pain—at least for me ;) Add multiply() Method to Collections <iframe width="1185" height="667" src="https://www.youtube.com/embed/AWvXjUnUdw8" title="Laravel collections now include a "multiply" method" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> Patrick O'Meara contributed a multiply() method to collections, which multiplies the items in the collection. It works by multiplying the existing values on the collection x number of times: $c = collect([ ['name' => 'User #1', 'email' => 'user1@example.com'], ['name' => 'User #2', 'email' => 'user2@example.com'], ])->multiply(2); The collection above would look as follows after calling multiply(2): Add Event Discovery Paths to the Event Service Provider @Jascha contributed a addEventDiscoveryPaths() method to the event service provider if you need to add additional event discovery paths dynamically. This feature isn't typically needed, but you can do so with: use Illuminate\Foundation\Support\Providers\EventServiceProvider; EventServiceProvider::addEventDiscoveryPaths('/some/path/to/events'); EventServiceProvider::addEventDiscoveryPaths([ '/some/path', '/another/path' ]); Release notes You can see the complete list of new features and updates below and the diff between 11.11.0 and 11.12.0 on GitHub. The following release notes are directly from the changelog: v11.12.0 [10.x] Fix typo in return comment of createSesTransport method by @zds-s in https://github.com/laravel/framework/pull/51688 [10.x] Fix collection shift less than one item by @faissaloux in https://github.com/laravel/framework/pull/51686 [10.x] Turn Enumerable unless() $callback parameter optional by @faissaloux in https://github.com/laravel/framework/pull/51701 Revert "[10.x] Turn Enumerable unless() $callback parameter optional" by @taylorotwell in https://github.com/laravel/framework/pull/51707 [10.x] Fixes unable to call another command as a initialized instance of Command class by @crynobone in https://github.com/laravel/framework/pull/51824 [10.x] fix handle shift() on an empty collection by @Treggats in https://github.com/laravel/framework/pull/51841 [10.x] Ensureschema:dump will dump the migrations table only if it exists by @NickSdot in https://github.com/laravel/framework/pull/51827 [11.x] Test Improvements by @crynobone in https://github.com/laravel/framework/pull/51847 [11.x] Test application storage path by @seriquynh in https://github.com/laravel/framework/pull/51848 [11.x] Fix PHP_MAXPATHLEN check for strings slightly smaller then PHP_MAXPATHLEN by @joshuaruesweg in https://github.com/laravel/framework/pull/51850 [11.x] Improve Bus::assertNothingDispatched(), Event::assertNothingDispatched(), Mail::assertNothingSent(), Notification::assertNothingSent() error messages by @macbookandrew in https://github.com/laravel/framework/pull/51846 [11.x] Update error page to show GET by @chu121su12 in https://github.com/laravel/framework/pull/51837 [11.x] Remove deprecated type attributes in the exception renderer by @osbre in https://github.com/laravel/framework/pull/51866 [11.x] Import classes in the exception templates by @osbre in https://github.com/laravel/framework/pull/51863 [11.x] Collection before/after optimization by @bert-w in https://github.com/laravel/framework/pull/51876 [11.x] Add multiply to collection by @patrickomeara in https://github.com/laravel/framework/pull/51870 [11.x] Add addEventDiscoveryPaths to EventServiceProvider by @ya-cha in https://github.com/laravel/framework/pull/51896 [11.x] Fix validation attributes when translations are empty or missing by @owenandrews in https://github.com/laravel/framework/pull/51890 [11.x] feat: add generics to tap() helper by @calebdw in https://github.com/laravel/framework/pull/51881 v11.11.1 [11.x] Remove useless variable assignment by @seriquynh in https://github.com/laravel/framework/pull/51838 [11.x] Fix event dispatcher typing in cache repository by @axlon in https://github.com/laravel/framework/pull/51835 Chop PHP extension when passed to make commands by @jasonmccreary in https://github.com/laravel/framework/pull/51842 [11.x] Simplify .php extension chopping in getNameInput by @osbre in https://github.com/laravel/framework/pull/51843 [11.x] fix: improve performance and robustness of Relation::getMorphAlias() by @calebdw in https://github.com/laravel/framework/pull/51845 Revert "[11.x] Change scope for afterCreating and afterMaking callbacks" by @driesvints in https://github.com/laravel/framework/pull/51858 The post Artisan `make` Commands Automatically Chop `.php` Extension in Laravel 11.12 appeared first on Laravel News. Join the Laravel Newsletter to get Laravel articles like this directly in your inbox.

SQLite Studio is a SQLite Database Explorer
SQLite Studio is a SQLite Database Explorer

SQLite seems to be cropping up everywhere! Laravel 11 uses SQLite by default when creating a new project, and Rails' default database is SQLite as well. A host of Database GUIs now support SQLite. Production services like Turso help use SQLite in production, and many prominent community developers are promoting SQLite. We covered TablePlus on Laravel News in 2017, and it remains a solid GUI option for managing SQLite databases. Other options include integrated database tools in PHPStorm and other JetBrains products, a full-on database IDE by JetBrains called DataGrip, and many others. SQLite Studio doesn't necessarily compete with the above-mentioned GUI tools; it is a single-file binary, single-command SQLite database explorer. It offers the following features: Overview page with common metadata. Tables page with each table's metadata, including the disk size being used by each table. Infinite scroll rows view. A custom query page that gives you more access to your db. Connect to a local SQLite database, a remote libSQL Server, or PostgreSQL Server My favorite feature is the infinite scroll rows view and the responsive updates as you write SQL queries in the Queries tab: SQLite Studio also gives you a Birds Eye view of the database on the Overview tab, which summarizes the database file size, SQLite version, total number of tables, rows per table, metadata, and more: The technology behind SQLite Studio looks fantastic—it uses Rust for the backend and TypeScript, React, Tailwind CSS, and Vite for the UI. If you want to see a live version of SQLite Studio in action, check out SQLite Studio's sample.db. This CLI is open-source on GitHub at frectonz/sqlite-studio. Related: DevDB - Access your database right inside VS Code! - Laravel News The post SQLite Studio is a SQLite Database Explorer appeared first on Laravel News. Join the Laravel Newsletter to get Laravel articles like this directly in your inbox.

Running a Single Test, Skipping Tests, and Other Tips and Tricks
Running a Single Test, Skipping Tests, and Other Tips and Tricks

Nuno Maduro recently shared the ->only() method you can attach to tests with PestPHP. I love targeted ways to run and rerun tests efficiently, and this helper sparked an idea to collect the various ways to filter, skip, and target tests in PHP. This post is by no means exhaustive, but I hope to cover the most important techniques. I'll cover both PHPUnit and Pest, where each tool applies. Before we get started, here's a look at the only() method Nuno shared that you can attach to individual tests: it('returns a successful response', function () {     $response = $this->get('/');     $response->assertStatus(200); })->only(); // If you use ->only() with multiple tests it will // run all of those selected tests. it('another test', function () {     // ... })->only(); Using only() acts as a switch that will target individual tests while you focus on writing code and running tests for that feature. Besides the only() helper, both PHPUnit and Pest provide plenty of ways to isolate, skip, and iterate on a selected set of tests. Let's take a look! Filtering Tests Regardless of a project's size, I prefer to run small groups of tests in isolation while I work on a feature. Learning how to select and filter tests in PHP is an invaluable skill for developers to practice with. Pest has many options for filtering tests—including the aforementioned ->only() method—using a combination of code or command line flags. Here are some of the flags Pest offers to filter tests: pest --dirty pest --bail # stop execution on first non-passing test pest --filter 'returns a successful response' pest --retry # reorders higher priority to failed tests pest --group|--exclude-group # Like PHPUnit, filter by test groups. pest --todo # List tests marked as `->todo()` There are other flags and options for test selection in the Pest CLI Reference. PHPUnit also has a variety of ways to filter tests that you can use on the command line: # filter which tests to run phpunit --filter test_the_application_returns_a_successful_response # Group flags phpunit --list-groups # list available groups phpunit --group api phpunit --exclude-group live PHPUnit has a variety of other selection options that you can see by running phpunit --help or visiting the PHP CLI selection documentation. Laravel's Tim MacDonald wrote Tips to Speed up Your Phpunit Tests on Laravel News, which is a resource I recommend to build your test management skills. Pest offers selections similar to PHPUnit and builds some excellent DX helpers on top of PHPUnit that I find invaluable. Skipping Tests Skipping tests is useful when validating your test suite, but know that some tests are either outright broken or a work in progress. A theme I am seeing is that PHPUnit offers the ability to skip tests, and Pest builds on top of that with productive tools that empower you to Brainstorm Tests With PEST Todos and other test-skipping goodies. When I am writing a new feature, I get tons of ideas as I work on the initial features. Ideas come faster than I can write, so I jump to the test file and start creating a to-do checklist right in the code! it('returns a successful response', function () {     $response = $this->get('/');       $response->assertStatus(200); });   it('requires a valid email')->todo(); it('detects Gmail addresses with a "+" as a non-unique email.')->todo(); it('requires a strong password')->todo(); I can then run pest --todo and know exactly where to find new features or tests that I didn't quite finish and want to revisit. PHPUnit has CLI flags you can use to select/skip tests, such as the --exclude-filter or --exclude-group, which are broader. When you want to skip a specific test, you can use the provided markTestIncomplete() method in the test: public function test_the_application_returns_a_successful_response(): void {     $this->markTestIncomplete('it requires a valid email');     $response = $this->get('/');     $response->assertStatus(200); } If you run the test suite, you will get a note that you have one or more incomplete tests. You can list all of the incomplete tests in more detail using the --display-incomplete flag: I interpret incomplete tests to be the closest equivalent to Pest's todo() method. While you can achieve similar using markTestAsSkipped(), I would reserve that for skipping tests that shouldn't run on a target platform or given scenario. Run Tests for Specific PHP or OS Versions If your codebase supports multiple versions of PHP, sometimes it makes sense to skip specific tests on a given set of PHP versions, Operating systems, or extensions. Both Pest and PHPUnit offer flexible support for these needs. PHPUnit has a RequiresPhp attribute you can use to target PHP versions in tests, as well as various operating system attributes: use PHPUnit\Framework\Attributes\RequiresOperatingSystemFamily; use PHPUnit\Framework\Attributes\RequiresPhp; #[RequiresPhp('<=8.0.0')] #[RequiresOperatingSystemFamily('Windows')] public function test_the_application_returns_a_successful_response(): void {     $response = $this->get('/');     $response->assertStatus(200); } Note: Historically, PHPUnit used the @requires annotation (which is now deprecated) to target multiple types of common preconditions like PHP version, OS, functions, etc. When you run the above test, it is skipped for systems running a PHP version >8.0.0 or OS other than the Windows family. Running the test suite with --display-skipped gives you details on any skipped tests based on these attributes: As part of Pest's Skipping Tests docs, you can use the following methods to skip certain PHP versions, OS versions, etc. it('has home', function () {     // })->skipOnPhp('>=8.0.0'); it('has home', function () {     // })->skipOnWindows(); // or skipOnMac() or skipOnLinux() ...      it('has home', function() {     // })->onlyOnWindows(); // or onlyOnMac() or onlyOnLinux() ... Running a Single Test From Your Editor The last thing to mention is that IDEs offer ways to quickly run individual tests, groups of tests, all tests in one file, etc., with quick command shortcuts. The Better PHPUnit VS Code Extension supports both PHPUnit and Pest, and provides the following features: Run a test method Run a test file Run the entire suite Run a previous test PHPStorm offers a ton of useful ways to run (and rerun) tests with shortcuts and UI icons, making it super easy to run a test from the test file without jumping to the command line: See the PhpStorm documentation for details on setting up testing shortcuts and tools for both PHPUnit and Pest. An honorable mention is the sublime-phpunit plugin that gives you the ability to run Run individual unit tests and files directly from Sublime. What other IDE and text editor tools do you use to automate running tests? Let us know! The post Running a Single Test, Skipping Tests, and Other Tips and Tricks appeared first on Laravel News. Join the Laravel Newsletter to get Laravel articles like this directly in your inbox.

View Third-party Relations in model:show - Now Available in Laravel 11.11
View Third-party Relations in model:show - Now Available in Laravel 11.11

This week, the Laravel team released v11.11, with support for third-party relations in the model:show command, new Collection methods, new cache events, and more. before and after Collection Methods Ryuta Hamasaki contributed before and after methods to Collection and LazyCollection instances Here are examples of the before method from the pull request description: $collection = collect([1, 2, 3, 4, 5, 'name' => 'taylor', 'framework' => 'laravel']); $collection->before(2) // 1 $collection->before('taylor') // 5 $collection->before('laravel') // 'taylor' $collection->before(fn ($value) => $value > 4) // 4 $collection->before(fn ($value) => ! is_numeric($value)) // 5 $collection->before(1) // null $collection->before('not found') // null Here are examples of the after method from the pull request description: $collection = collect([1, 2, 3, 4, 5, 'name' => 'taylor', 'framework' => 'laravel']); $collection->after(1) // 2 $collection->after('taylor') // 'laravel' $collection->after(fn ($value) => $value > 4) // 'taylor' $collection->after(fn ($value) => ! is_numeric($value)) // 'laravel' $collection->after('laravel') // null $collection->after('not found') // null Cache Events Alex Bouma contributed new cache events to the framework that applications can listen to: use Illuminate\Cache\Events\ForgettingKey; use Illuminate\Cache\Events\KeyForgetFailed; use Illuminate\Cache\Events\KeyWriteFailed; // Two public properties: `$this->value` and `$this->seconds` use Illuminate\Cache\Events\RetrievingKey; use Illuminate\Cache\Events\RetrievingManyKeys; // One public property: `$this->keys` use Illuminate\Cache\Events\WritingKey // Two public properties: `$this->value` and `$this->seconds` use Illuminate\Cache\Events\WritingManyKeys; // Three public properties: // `$this->keys`, `$this->values` and `$this->seconds` Support Third-party Relations in model:show Jonas Staudenmeir contributed the ability to include third-party package model relations in the model:show command: The model:show command finds a model's relations by analyzing the code of its methods and looking for $this->hasMany( etc. This doesn't detect third-party relations (like eloquent-has-many-deep). We could build a whole system for packages to hook into, but that would be overkill, IMO. Instead, we can check the method's return type and see if it's a subclass of the base Relation class. Not everybody uses return types, but I hope that most do nowadays. You can learn more about this addition in Pull Request #51807. Session ID Getter Tim MacDonald contributed the Session::id() method to the Session facade: Session::id(); // You can still use `getId()` too: Session::getId(); Timezone and Locale Added to the about Command Amir Khalife Soltani contributed to adding Locale and Timezone values to Laravel's about command. You can now quickly determine what the configured locale and timezone are at a glance with other important environment information: The `about` command with `Timezone` and `Locale` values 422 Unprocessable Content Status Code Dwight Watson contributed updates to the status code method for determining a 422 status code, which is now referred to as 422 Unprocessable Content instead of Unprocessable Entity. The way you interact with asserting a 422 status code hasn't changed: $response = $this->postJson('/example', []); $response->assertUnprocessable(); See RFC 9110: HTTP Semantics and Pull Request #51815 for details. Add Relation::getMorphAlias() Method Dennis Koch contributed a Relation::getMorphAlias() method Since there is a Relation::getMorphedModel() I think it would be beneficial to add the reverse getMorphAlias. This addition is particularly beneficial for testing, as it simplifies assertions with $this->assertDatabaseHas. Developers no longer need to recall the morph alias used: $this->assertDatabaseHas('taskables', [ 'taskable_type' => Relation::getMorphAlias(Document::class), 'taskable_id' => $mitigation->id, 'task_id' => $taskB->id ]); Release notes You can see the complete list of new features and updates below and the diff between 11.10.0 and 11.11.0 on GitHub. The following release notes are directly from the changelog: v11.11.0 [11.x] Add get, write and forget cache events by @stayallive in https://github.com/laravel/framework/pull/51560 [11.x] Add test for Arr::sortRecursiveDesc() method. by @lmottasin in https://github.com/laravel/framework/pull/51716 [11.x] Fix missing table name in db:table command by @benholmen in https://github.com/laravel/framework/pull/51710 Ensure files exist for install:broadcasting by @jasonmccreary in https://github.com/laravel/framework/pull/51719 [11.x] Restore exceptions/errors to test assertion failure messages by @jessarcher in https://github.com/laravel/framework/pull/51725 [11.x] Test Improvements by @crynobone in https://github.com/laravel/framework/pull/51723 [11.x] Add tests for accessible and take method by @saMahmoudzadeh in https://github.com/laravel/framework/pull/51724 Increment the totalJobs property for the BatchFake when add some jobs by @yankewei in https://github.com/laravel/framework/pull/51742 [11.x] Give session ID retrieval the Laravel treatment by @timacdonald in https://github.com/laravel/framework/pull/51732 [11.x] Fix the chunk method to an integer type in the splitIn method by @rookiexxk in https://github.com/laravel/framework/pull/51733 Update:update name method and doc by @mehdi-fathi in https://github.com/laravel/framework/pull/51744 [11.x] Fixes config:publish with dontMergeFrameworkConfiguration() set to true by @crynobone in https://github.com/laravel/framework/pull/51751 Updated phpdoc for Builder::from() by @boris-glumpler in https://github.com/laravel/framework/pull/51767 [11.x] Fixed pop on default Beankstalkd queue when not specifically added by @rinocs in https://github.com/laravel/framework/pull/51759 [11.x] Add before and after methods to Collection by @avosalmon in https://github.com/laravel/framework/pull/51752 [11.x] Change scope for afterCreating and afterMaking callbacks by @jacob418 in https://github.com/laravel/framework/pull/51772 Use numeric literal separator in file rule validation by @AmirKhalifehSoltani in https://github.com/laravel/framework/pull/51781 [11.x] Import Model class for Renderer\Exception by @seriquynh in https://github.com/laravel/framework/pull/51778 [11.x] About command improvement by @AmirKhalifehSoltani in https://github.com/laravel/framework/pull/51791 [11.x] Test abort behavior by @seriquynh in https://github.com/laravel/framework/pull/51800 [11.x] Container shares fixed values/initialized instances instead of singleton closure resolutions by @seriquynh in https://github.com/laravel/framework/pull/51804 [11.x] Fix altering a table that has a column with default 0 on SQLite by @hafezdivandari in https://github.com/laravel/framework/pull/51803 [11.x] Fix typo in VendorPublishCommand by @tamiroh in https://github.com/laravel/framework/pull/51812 [11.x] Fix some typos in the tests by @tamiroh in https://github.com/laravel/framework/pull/51811 [11.x] Add unprocessableContent and update unprocessableEntity by @dwightwatson in https://github.com/laravel/framework/pull/51815 [11.x] Improve Queue::assertNothingPushed() error message by @SjorsO in https://github.com/laravel/framework/pull/51814 [11.x] Add Relation::getMorphAlias() by @pxlrbt in https://github.com/laravel/framework/pull/51809 [11.x] Support third-party relations in model:show command by @staudenmeir in https://github.com/laravel/framework/pull/51807 [11.x] Fix nested rules custom attribute names by @owenandrews in https://github.com/laravel/framework/pull/51805 [11.x] Fix docblock of \Illuminate\Http\Response by @seriquynh in https://github.com/laravel/framework/pull/51823 The post View Third-party Relations in model:show - Now Available in Laravel 11.11 appeared first on Laravel News. Join the Laravel Newsletter to get Laravel articles like this directly in your inbox.

Asserting a JSON Response Structure in Laravel
Asserting a JSON Response Structure in Laravel

When writing tests for API responses in Laravel, it can be useful to validate the structure of the response. Laravel has the fluent assertJson() method, which you can use to verify JSON values in a given test response: it('Returns Arizona sports teams', function () { $this->get('api/teams/arizona') ->assertJson(function (AssertableJson $json) { $json->has('teams', 3); $json->has('teams.0', function (AssertableJson $json) { $json ->where('name', 'Phoenix Suns') ->etc(); }); }); }); Given the above test, here's a static example of the JSON data: { "teams": [ { "name": "Phoenix Suns", "sport": "Basketball" }, { "name": "Arizona Cardinals", "sport": "Football" }, { "name": "Arizona Diamondbacks", "sport": "Baseball" } ] } Our test validates that three teams are listed in Arizona and that the name property exists on the first record. That's excellent for validating the actual values to sample the response using the powerful JSON assertion APIs in Laravel. To complement those assertions, we can also validate the general structure of the whole response: $response->assertJsonStructure([ 'teams' => [ '*' => ['name', 'sport'], ], ]); One caveat to the assertJsonStucture() assertion: if we add a new key in the future, this test will continue to pass. If you require more exactness, you might need to reach for the assertExactJson(). For just generalizing a JSON structure to ensure specific properties exist in the response, assertJsonStructure() can give you confidence that the entire structure contains properties you expect. If you need more extensive assertions around the structure of the JSON, you might also want to reach for whereType() and whereAllType() assertions. Given our earlier example, you could validate the types in your JSON responses using the following: $response->assertJson(function (AssertableJson $json) { $json->has('teams', 3); $json->has('teams.0', function (AssertableJson $json) { $json->whereAllType([ 'name' => 'string', 'sport' => 'string', ]); }); }); Using whereAllType requires us to define types for each and every key in the teams item, unless you use the above with ->etc(): $json->whereAllType([ 'name' => 'string', // 'sport' => 'string', ])->etc(); As mentioned, the above code doesn't assert the whole response and assumes the other teams have the same structure. You could assert each team in the array, and even use Eloquent factory data to validate the response values match. Typically, combining the above assertions will ensure you have the expected JSON response shape, and you can mix in more complicated assertions where needed. See the Laravel Documentation for more examples and useful JSON assertions. The post Asserting a JSON Response Structure in Laravel appeared first on Laravel News. Join the Laravel Newsletter to get Laravel articles like this directly in your inbox.

Create a DateTime from a Timestamp With this New Method Coming to PHP 8.4
Create a DateTime from a Timestamp With this New Method Coming to PHP 8.4

Creating a DateTime from a Unix timestamp will be more convenient in PHP 8.4 with the new createFromTimestamp() method. It will support both a typical Unix timestamp as well as timestamps containing microseconds: $dt = DateTimeImmutable::createFromTimestamp(1718337072); $dt->format('Y-m-d'); // 2024-06-14 $dt = DateTimeImmutable::createFromTimestamp(1718337072.432); $dt->format('Y-m-d h:i:s.u'); // 2024-06-14 03:51:12.432000 With PHP 8.3 and below, you need to use the createFromFormat() method to convert a timestamp into a DateTime or DateTimeImmutable instance. As you can see below, it's not too complicated, but it'll be nice to have a new method to take care of both cases below: $dt = DateTimeImmutable::createFromFormat('U', (string) 1718337072); // DateTimeImmutable @1718337072 {#7948 // date: 2024-06-14 03:51:12.0 +00:00, // } $dt = DateTimeImmutable::createFromFormat('U.u', (string) 1718337072.432); // DateTimeImmutable @1718337072 {#7950 // date: 2024-06-14 03:51:12.432 +00:00, // } For those using the Carbon PHP library, it already has a createFromTimestamp() method available! It is encouraging that PHP is getting this new method at the language level as well! Carbon\Carbon::createFromTimestamp(1718337072.432); // Carbon\Carbon @1718337072 {#7981 // date: 2024-06-14 03:51:12.432 UTC (+00:00), // } Carbon\CarbonImmutable::createFromTimestamp(1718337072); // Carbon\CarbonImmutable @1718337072 {#7999 // date: 2024-06-14 03:51:12.0 UTC (+00:00), // } The post Create a DateTime from a Timestamp With this New Method Coming to PHP 8.4 appeared first on Laravel News. Join the Laravel Newsletter to get Laravel articles like this directly in your inbox.

Backpack turns 8 years old, celebrates with 40% discount
Backpack turns 8 years old, celebrates with 40% discount

Time sure flies by! Backpack for Laravel has been around for so many years now, everybody in the team is getting a bit nostalgic. To celebrate our anniversary: we've told the story of our 8 year-history of building Laravel admin panels; we've tracked down 40+ Laravel admin panels, to create a comprehensive article about Laravel admin panel libraries and learn from them (contact us if you've launched one); we're doing a HUGE discount campaign, to celebrate; Read on to find out what Backpack is, what makes it different and what discounts you can use right now: About Backpack Admin Panels Never heard of Backpack? Boy, do we have news for you! Let me give you the TLDR: Backpack CRUD (our free & open-source core) includes all the basics an admin panel needs - authentication, 300+ HTML components and basic CRUDs. You can then build your own custom features on top of it or purchase paid add-ons, that bring so much functionality it's difficult to list a few. But here goes: 25+ field types, Calendar operation, editable columns... the list goes on and on. What makes Backpack different? In short, Backpack is the best at KISS ("keep it simple, stupid"). It's a lesson we've learnt the hard way, and never compromise on. 8 years ago we had already built dozens of websites & apps for clients and one important thing we've learnt from our many mistakes: the simplest solution is usually the best. When we decided we needed an admin panel, we built one with KISS as the guiding principle (actually we built four, but who's counting). The point is, we followed that KISS guiding principle all the way to 2024 and that has proven to be an EXCELLENT decision, avoiding complete rewrites and making our lives a lot easier. KISS has manifested itself in what makes Backpack different technically. So here goes. As opposed to other Laravel admin panels: Backpack uses a minimalist stack. To use it, all you need to know is Laravel. To customize it, you might need to know some Bootstrap & Javascript for heavy customizations - but that's it. This makes it it incredibly easy to customize, super easy to onboard developers (from junior to senior) and a pleasure to come back in a few years to make a change. Backpack has an obsession on choosing long-term tech. Out of 40+ Laravel admin panels that have been launched over the past decade... 90% are now dead. Why? Because they've chosen this or that cool new tech. And it's either proven to be a bad choice or people have just gotten bored of it and moved to the next cool tech. Backpack has always tried to stay away from tech trends. We only adopt something when we know we'll enjoy using it 5 years from now. That's why we still use Bootstrap. Hell, that's why we still have bits that use jQuery in 2024 - because it's still a good long-term tech for that specific use case. Backpack offers all features you need, from one single vendor. It is very very difficult to build out all the features an admin panel might need. So difficult it took us almost 8 years to do it. To get around that, most admin panels build the core, then invite other devs to build 3rd party add-ons. But that's a trap! In most cases, your project ends up with dozens of dependencies, on dozens of developers, of dozens degrees of quality. By contrast, Backpack offers everything you need, from one vendor with a proven track record - Backpack. We have 3rd party add-ons too... but they're usually small and niche, very few projects need them. Backpack truly helps with everything you might need - not just code, but also HTML components, wireframing, design, code generation, support and outsourcing. A lot of times, building an admin panel becomes way more than "coding an admin panel". We know, because we've built e-commerce, ERPs, social networks and more on Backpack, so we know how complex it can get: That's why we offer 300+ HTML components out-of-the-box. That's why we offer an optional Figma template to help prototype/design. That's why we offer an optional GUI for generating admin panels. That's why we offer optional services, from premium support to feature development & full outsourcing. To sum up, Backpack has been around for 8 years now, it's battle-tested, well-maintained, feature-packed and has a truly complete offering. Our goal was for you to have EVERYTHING you need to finish your admin panel, and after these 8 years... many people say "everything" is selling it short 🤣 Our KISS approach has proven to be a great way to build admin panels for today and for the future. If any of the things that make us different resonate with you... we think you'll love Backpack! Maybe even as much as we do. If you decide to try it out... we have some great news! Discounts We've decided to celebrate our 8-year anniversay with a 4-week celebration, where everything is 25% off! In addition, we have a few flash discounts planned, where the discount is even higher (but it will be limited to the first N buyers). Here are all the coupons codes and their details: HAPPY8THBIRTHDAY40 - 40% off for 40 purchases, starting June 10th (flash sale); HAPPY8THBIRTHDAY33 - 33% off for 33 purchases, starting June 17th (flash sale); HAPPY8THBIRTHDAY25 - 25% off, for 4 weeks, starting June 10th 2024; Terms: Who can use them? Anybody. New buyers and repeat buyers too. When do you use them? In the time windows above. All discounts expire July 7th 2024. Can I buy if my updates haven't expired? Yes, 12 more months of updates will be added to your access. How do you use them? At checkout, right before the TOTAL, click "Add Coupon". If you're new to Backpack, I hope you enjoy this opportunity to try what we've worked on for the past 8 years. If you've been with us for a while, thanks again for supporting us, all of these years. We couldn't do our jobs building out this software, if it weren't for people like you. You are freakin' awesome and we are super-grateful to have you 🙏 Now go ahead - go to https://backpackforlaravel.com and purchase our paid add-ons, at a huge discount. We recommend "everything", since that will give you the best experience. But you can start off with a Single-Project PRO license for as little as 42 EUR! 🤯 Here's to many more years of building and maintaining software for you 🍻 Cheers! The post Backpack turns 8 years old, celebrates with 40% discount appeared first on Laravel News. Join the Laravel Newsletter to get Laravel articles like this directly in your inbox.

Sentry and Laravel announce a new partnership
Sentry and Laravel announce a new partnership

Sentry and Laravel announced a new partnership, making Sentry the preferred monitoring and debugging solution for Laravel projects using Forge or Vapor. Sentry is committed to the Laravel and PHP community, and we continue to build with you in mind. With the new Forge and Vapor integration, we’re forging (pun intended) a new standard for managing, deploying, and debugging your Laravel apps. Here is a video showing how this new integration works: <iframe width="560" height="315" src="https://www.youtube.com/embed/QcOfXATrAkg?si=ndtfrt_-OqxLgIus" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> Or, if you prefer step-by-step instructions: Log in to Laravel Forge or Vapor Navigate to “User Profile” in Forge or “Team Settings” in Vapor (when logged in as the team owner) where you can find the new Sentry integration option. Follow the prompts to link your Sentry account Configure Sentry and connect your site to create a Sentry project create the project from the site’s or project’s Sentry panel Deploy your application, and Sentry will start tracking errors immediately If you haven't tried Sentry yet, check out our guide on how Sentry can improve your Laravel application. It's also super easy to install and comes with new features like a new widget to get direct feedback from users when they encounter a bug on your site. Sentry will attach their comment with all the debugging context you could dream of, like replay events, screenshots, error details, URL tags, and more. The post Sentry and Laravel announce a new partnership appeared first on Laravel News. Join the Laravel Newsletter to get Laravel articles like this directly in your inbox.

"Fast Projects" by Larafast: Real life, ready to use Laravel based Boilerplates
"Fast Projects" by Larafast: Real life, ready to use Laravel based Boilerplates

Larafast continues to extend its boilerplates list. Introducing Larafast Fast Projects, a new collection of ready-to-go boilerplates designed to accelerate your Laravel development journey. This launch includes the Larafast Directories Boilerplate and the Larafast API Boilerplate. Larafast Directories Boilerplate The Larafast Directories Boilerplate is a solution for creating directory websites with ease. Built on top of Larafast, it includes all the essential features you need to get your directory website up and running quickly. Key Features: Larafast Integration: Larafast Directories Boilerplate comes with Larafast Full Package features, providing access to a rich set of functionalities, including Admin, User Dashboard, SEO, Payments, Blog, Themes. You can find all Larafast features here Directory-specific Features: Enjoy a set of directory-specific features, such as listing management, user profiles, advanced search capabilities, categories. These features are crafted to meet the unique requirements of directory websites. SEO Optimization: Built-in SEO optimization features comes with programmatic SEO for Categories and Products, with implemented sitemap to quickly index all the categories and products in Google, you just need to run a command to generate a sitemap and boom! Subscriptions and One-time Payments: If your directory requires subscription or lifetime payment for project listing, Larafast Directories Boilerplate comes with it out of the box. Set your payment keys and you are good to go! Easy-peasy, doesn't it? Customizable Templates: Choose from a variety of customizable templates provided by DaisyUI and give your directory website a unique and visually appealing look. Larafast's flexible design allows for easy customization to match your branding and user experience preferences. Admin Dashboard: Easy to use admin dashboard, where you can manage all your categories and products, add new ones, approve new products or restrict the ones that does not meet your project requirements. Documentation and Support: Gain access to comprehensive documentation and dedicated support resources to help you navigate through the setup and customization process. Larafast API Boilerplate The Larafast API Boilerplate is perfect for developers looking to build their SPA website or mobile app and use Laravel as a backend API. Larafast API Boilerplate comes with all necessary features for your next Single Page or Mobile Applicatio Key Features: Auth: User Registration, Login, Forgot Password, Social Auth Subscriptions and One-time Payments: Powered by Stripe and LemonSqueezy, access to Billing Portal, and protected routes. Admin Dashboard: Easy to use admin dashboard, where you can manage all your Users, Blog Articles, "Coming Soon" emails, etc. OpenAI Service: Integrated OpenAI service, for text completion, text to speech and image generation with OpenAI API. Documentation and Support: Gain access to comprehensive documentation and dedicated support resources to help you navigate through the setup and customization process. The Main Larafast Boilerplate At the heart of these Fast Projects is the main Larafast Boilerplate. Larafast provides a solid foundation with features such as authentication, payment integration, pre-built UI components, and extensive documentation. Main Features of Larafast: Payments. Plan Checkout Sessions, Single Product Purchases, Customer Portal, Webhook Handling. All out of the box with Stripe, LemonSqueezy or Paddle. Users. User Registrations and Logins, Magic Links, Social Auth for Github, Twitter and Google out of the box. Admin Panel. Built with amazing FilamentPHP, admin panel comes with Users and Blog Articles management. SEO. SEO Meta Tags, Twitter Cards, Automatic Sitemap builder, Schema.org markup integrated, Blog and Articles SEO. Styles. Larafast styles are based on TailwindCSS and DaisyUI, which comes with 32 amazing themes out of the box. ...and many more. Components, OpenAI Service, Coming Soon Page, Terms and Privacy pages. Conclusion Larafast Fast Projects are designed to help developers launch their projects faster and with less hassle. Whether you're building a directory site, an API these boilerplates offer a comprehensive and efficient solution. Stay tuned for more exciting updates and new releases from Larafast! For more information and to get started with Larafast "Fast Projects", visit the official website. Happy coding! The post "Fast Projects" by Larafast: Real life, ready to use Laravel based Boilerplates appeared first on Laravel News. Join the Laravel Newsletter to get Laravel articles like this directly in your inbox.

Randomize Command Execution Time with the Chaotic Schedule Package for Laravel
Randomize Command Execution Time with the Chaotic Schedule Package for Laravel

The chaotic-schedule package for Laravel allows you to randomize scheduled command execution time and date intervals via Pseudorandom number generators (PRNGs): Ever wanted to run your scheduled commands on random times of the day, or on certain days of the week? Or you may need to send some notifications not on fixed date times, but rather on random intervals hence it feels more human. Then this is the package you're looking for. This Laravel packages enables you to run commands on random intervals and periods while respecting the boundaries set exclusively by you. One use-case mentioned in the readme is sending user notifications or emails but sending them randomly to add a more personal human touch. Avoiding the sending of these messages at regular intervals at the same time would be more recognizably automated: // Run a command daily on a random time between 08:15 and 11:42 $schedule->command('inspire')->daily()->atRandom('08:15','11:42'); // Run a command every Tuesday, Saturday and Sunday on a random time between 04:20 and 06:09 $schedule->command('your-command-signature:here') ->days([Schedule::TUESDAY, Schedule::SATURDAY, Schedule::SUNDAY]) ->atRandom('04:20','06:09'); This package includes quite a few methods to define your random specifications based on several factors, such as: dailyAtRandom() hourlyAtRandom() hourlyMultipleAtRandom() randomDays() And more... You can learn more about this package, get full installation instructions, and view the source code on GitHub. The post Randomize Command Execution Time with the Chaotic Schedule Package for Laravel appeared first on Laravel News. Join the Laravel Newsletter to get Laravel articles like this directly in your inbox.