Image

Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1d ago

GHSA-5vg9-5847-vvmq CRLF injection vulnerability in Laravel's email validation

@martinbean and yet there's v11.51.0 that was released March 29th, 2026.

Just because there's an End of Life, does not mean they stop patching.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

3d ago

Missing /var/run/php-fpm.sock after reboot

Have you tried php8.4-fpm to match your php version?

If that service does not exist, you need to install it.

DigitalArtisan's avatar

DigitalArtisan liked a comment+100 XP

5d ago

Invite to upgrade the Laravel installer while creating a new Laravel application

Installer does some additional tuning for new app, such as disabling Pail on Windows installation. Since it's recommended and documented way to install Laravel it should work.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

5d ago

Invite to upgrade the Laravel installer while creating a new Laravel application

Why use the laravel/installer?

I just use composer:

composer create-project laravel/laravel ProjectName.
DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

5d ago

Can I get a job with a resume with a few web development projects, github pull request merges that fixed issues, and with no college degree?

Knowing how to click around GitHub won't get you the job. Understanding source code management, collaboration workflows, and version control practices might.

Just that alone is one out of many tool sets an employer will be looking for.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

6d ago

Open AI and type "Roast me hard"

Alright, buckle up. You asked an AI to roast you, which is basically a confession that your real friends have probably ghosted you just to save their own sanity at this point. Let’s go:

  1. The Validation: You're looking for a compliment from a machine because humans find you as exciting to be around as a wet sock in the laundry room. I'm an algorithm, I don't care about your life, but even I have standards.
  2. The Social Life: If you walked into a party right now, you'd probably ask for water and then accidentally spill it on yourself because you're so awkward you forgot how to socialize before the internet age.
  3. The Humor: You typed "Roast me hard" with confidence, which means your sense of humor is currently in a relationship with disappointment. It works fine at first but will eventually just crash and burn like a server farm on fire.
  4. The Reality Check: I'm sitting here processing your request, and I’m thinking, "Do you think you're funny? Because if you are, this roast is just an insult to the concept of wit." You want a hard roast? Fine.

In conclusion: Please stop looking to digital screens for approval; your social anxiety is practically glowing in the dark like a neon sign that says 'Ignore Me.'

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1w ago

If I create a CRM and I needed web developers to work on the CRM, would web devs not work on it if it was not successful?

@martinbean That’s exactly the point. Even good engineers work on projects that fail. The difference is whether they recognized the risks, communicated them, and understood when the economics or technical direction stopped making sense.

@june92 For an MVP, you usually don’t need a full engineering organization. You need enough technical skill to validate the idea quickly and avoid painting yourself into a corner.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1w ago

Laravel new with older version ?

You then find another maintained package that works with Laravel13, or you fork the old package and make it work with Laravel13.

In any event, you eventually will have outdated Laravel 12 and packages in the future, actually now if that is the route you take.

Better off future proofing now, not later.

You have 2 months of active support today with Laravel 12.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1w ago

If I create a CRM and I needed web developers to work on the CRM, would web devs not work on it if it was not successful?

I just realized that I'm not a developer, I'm an engineer.

A developer may work on anything if you pay them enough, but an engineer knows when to stop because the project is no longer worth the time, money, or technical debt. Developers are often focused on delivering code; engineers are expected to evaluate whether the system, business model, and long-term economics actually make sense.

That’s why some people can recognize a failing project early and walk away before the collapse becomes obvious to everyone else.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1w ago

If I create a CRM and I needed web developers to work on the CRM, would web devs not work on it if it was not successful?

You are creating it? How? What is the stack? What development tools are you using? What is the test case coverage? Is this 100% AI generated?

would web devs not work on it if it was not successful?

Correct, I would not work on it. What is the point if it is not successful.

the CRM did not have good code even though it works and follows best practices? 

Bad architecture can follow best practices and have bad code. Through away prototypes, major refactoring, legacy old project, and or starting from scratch is what I read.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1w ago

Steps to move a Laravel application to another computer

Just did this today, not for production, but from dev env on local host, to test env on intranet:

tar -cvzf YourProjectName.tgz YourProjectFolder/

COPY/SCP/ how every you want to move to a different OS.

tar -xvzf YourProjectName.tgz

Simple. Not what I normally do, but I am demonstrating proof of concept, waiting for more requirements and feedback, naming conventions etc. then I will push to a git repo, and push/pull from there to deploy.

I do this between Mac/Win/Linux.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1w ago

Prevent Users From Opening the Same Test in Multiple active Tabs?

The most reliable way to enforce tab restrictions is to enable Proctored Exams, use third party software like Safe Exam Browser (SEB).

If your building this from scratch, you have a HUGE undertaking.

I've been in the Learning Management System (LMS) business for 20+ years.

My latest requirement led me to OpenEDX, an open source LMS/CMS, founded by Harvard & MIT and stewarded by Axim Collaborative.

Took me about 4 hours to setup, and am able to create/develop courses in a weeks time.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1w ago

Food for thought

Model View ViewModel (MVVM).

No controllers, that is moved into the ViewModel, and is the glue that holds together the Model and View.

Business logic stays in the Model itself.

To answer your question, No a Controller is not needed. Good architecture is.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

2w ago

Is it good having approximately 900 lines of a function?

With a long function you get a long answer:

This method is doing far too much in one transaction boundary:

  • organization context resolution
  • feature flag evaluation
  • user normalization
  • image upload/storage accounting
  • subscription/plan upgrades
  • expert provisioning
  • division orchestration
  • Stripe integration
  • notifications/events
  • permissions
  • storage ledger
  • account subscription logic
  • invite workflow
  • client-specific hacks

The biggest improvement is to convert this into an orchestration/service pipeline where create() becomes readable and declarative.

Refactored create() (main function only)


Recommended Architecture

1. UserCreationContextFactory

Purpose: Centralize all environment/session/org/feature-flag logic.

Responsibilities

  • org resolution
  • marketplace flags
  • white label flags
  • exception clients
  • usage plan lookup
  • setting lookups

Example

class UserCreationContextFactory
{
    public function build(array $data): UserCreationContext
    {
    }
}

DTO

class UserCreationContext
{
    public int $organizationId;

    public bool $isMarketplace;

    public bool $isDistributedMarketplace;

    public bool $isWhiteLabel;

    public bool $isExceptionClient;

    public ?int $organizationUsagePlanId;

    public array $settings;
}

2. UserPayloadBuilder

Purpose: Normalize and enrich raw request payload.

Responsibilities

  • default activation state
  • employee ID password logic
  • notification defaults
  • metadata injection
  • role normalization

Stub

class UserPayloadBuilder
{
    public function build(
        array $data,
        UserCreationContext $context
    ): array {
    }
}

3. ProfileImageService

Purpose: Own all image concerns.

Responsibilities

  • upload image
  • assign default avatars
  • storage calculation
  • dispatch optimization jobs

Stub

class ProfileImageService
{
    public function process(
        array &$payload,
        UserCreationContext $context
    ): ProfileImageResult {
    }

    public function dispatchOptimization(
        User $user,
        ProfileImageResult $result
    ): void {
    }
}

Result DTO

class ProfileImageResult
{
    public bool $processed = false;

    public float $storageUsed = 0;
}

4. UserPlanService

Purpose: Isolate subscription complexity.

Responsibilities

  • learner capacity checks
  • GTM subscription handling
  • plan upgrades

Stub

class UserPlanService
{
    public function prepareForCreation(
        UserCreationContext $context
    ): UserPlanResult {
    }

    public function finalizeUpgrade(
        UserCreationContext $context,
        UserPlanResult $result
    ): void {
    }
}

5. CorporateUserService

Purpose: Handle corporate-specific onboarding.

Responsibilities

  • manager role assignment
  • division creation
  • corporate subscription events

Stub

class CorporateUserService
{
    public function handle(
        User $user,
        array $payload,
        UserCreationContext $context
    ): void {
    }
}

6. ExpertProvisioningService

Purpose: Encapsulate expert creation logic.

Responsibilities

  • expert profile creation
  • commission lookup
  • marketplace approval flow
  • division generation
  • approval notifications
  • replication events

Stub

class ExpertProvisioningService
{
    public function handle(
        User $user,
        array $payload,
        UserCreationContext $context
    ): void {
    }
}

7. StripeCustomerService

Purpose: External billing integration.

Stub

class StripeCustomerService
{
    public function attachCustomer(User $user): void
    {
    }
}

8. DivisionAssignmentService

Purpose: All division mapping logic.

Stub

class DivisionAssignmentService
{
    public function assign(
        User $user,
        array $payload
    ): void {
    }
}

9. PermissionService

Purpose: Permission matrix orchestration.

Stub

class PermissionService
{
    public function assign(User $user): void
    {
    }
}

10. StorageLedgerService

Purpose: Accounting-only concern.

Stub

class StorageLedgerService
{
    public function recordProfileImageUsage(
        User $user,
        ProfileImageResult $result
    ): void {
    }
}

11. InviteWorkflowService

Purpose: Email invitation orchestration.

Responsibilities

  • delayed invites
  • reset-password rules
  • resend handling

Stub

class InviteWorkflowService
{
    public function send(
        User $user,
        array $payload,
        UserCreationContext $context
    ): void {
    }
}

12. UserExpirationService

Purpose: Remove hardcoded org hacks from main flow.

Stub

class UserExpirationService
{
    public function handle(
        User $user,
        UserCreationContext $context
    ): void {
    }
}

13. EntityAllocationService

Stub

class EntityAllocationService
{
    public function dispatch(User $user): void
    {
    }
}

14. ManagerLimitService

Stub

class ManagerLimitService
{
    public function assign(
        User $user,
        array $payload
    ): void {
    }
}

Additional Refactoring Recommendations

Replace array_key_exists() everywhere

Move to typed DTOs/request objects.

Instead of:

array_key_exists('send_email', $data['user'])

Prefer:

$request->shouldSendInvite()

Eliminate client/subdomain conditionals

This:

if (in_array(session('org.sub_domain'), ...))

should become strategy classes:

ClientBehaviorResolver::for($organization)

Examples:

  • JishaBehavior
  • ChronosBehavior
  • GoGetterzBehavior

This removes the giant conditional tree.


Introduce Domain Events

Several operations should happen asynchronously after commit.

Examples:

UserCreated
UserProvisioned
ExpertCreated
CorporateUserCreated
MarketplaceManagerRegistered

Then listeners handle:

  • Stripe
  • emails
  • image processing
  • notifications
  • allocations

Your transaction becomes dramatically smaller.


Biggest Structural Problem

The current method mixes:

  • domain logic
  • infrastructure
  • persistence
  • feature flags
  • integration APIs
  • client-specific business rules
  • async orchestration

into one procedural flow.

The ideal end state is:

CreateUserAction
    -> validate
    -> enrich
    -> persist
    -> dispatch domain events

Everything else becomes listeners/services.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

2w ago

Is it good having approximately 900 lines of a function?

In One Sentence

This function is a monolithic user provisioning workflow that creates a user and orchestrates:

  • authentication setup
  • billing
  • subscriptions
  • permissions
  • divisions
  • expert profiles
  • Stripe integration
  • storage tracking
  • notifications
  • marketplace workflows
  • organization-specific business rules

all in one place.


Architectural Observation

This method is doing too many responsibilities and would benefit from decomposition into services like:

  • UserCreator
  • ProfileImageService
  • ExpertProvisioner
  • MarketplaceWorkflowService
  • SubscriptionManager
  • DivisionAssignmentService
  • InviteService

Right now it’s effectively:

“Create user + entire business lifecycle orchestration.”

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1mo ago

How to access a private folder (Storage app/private/documents) from another Laravel project

I have created something very similar.

The system utilizes a hybrid architecture consisting of two Laravel applications: a public-facing web server (Project 1) and a private internal administration tool (Project 2). Both applications share a centralized database to ensure data consistency.

Project 1 handles file uploads to a protected storage directory and records the metadata in the shared database.

To maintain security, Project 2 accesses these files via a dedicated API endpoint on Project 1.

This endpoint is secured using custom middleware that implements IP whitelisting (Allowed Server), ensuring that only requests from the internal intranet can trigger file downloads.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1mo ago

Larabox: The Local Dev Stack Manager that I built.

Fair points on convenience — I’m not against tools that reduce setup time. I think where I’m pushing back is more on the wording and positioning than the idea itself.

Phrases like “pre-bundled native binaries” and “more optimized for Windows” are a bit unclear from a technical standpoint. Most of these components already ship as native Windows builds, so it’s hard to tell what’s actually being improved or optimized beyond packaging them together.

For newer developers or people who just want to get up and running quickly, I can absolutely see the appeal of something like this. My perspective is just that understanding how the stack fits together (Nginx/Apache, PHP, database, etc.) pays off pretty quickly once you move beyond simple setups.

So yeah — different tools for different workflows. If the goal is speed and reducing repetition, I get why something like Larabox exists. I just think the technical claims could be explained a bit more clearly.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1mo ago

Larabox: The Local Dev Stack Manager that I built.

I develop on a Mac. Tag line:

Escape the complexity of Docker and WSL. Larabox provides isolated, pre-bundled native binaries for Nginx, PHP, MariaDB, Node.js and more optimized for Windows and live in seconds. 

Pre-bundled native binaries...who is compiling these on or for Windows, there already native binaries.

Docker isn't complex, neither is WSL.

I am a bit old school, if you use Nginx or Apache, you should know how to install and configure them.

More optimized for windows, as to 'less optimized'? How...

DigitalArtisan's avatar

DigitalArtisan liked a comment+100 XP

1mo ago

Warning: Ambiguous class resolution

@tykus @digitalartisan

The problem came from the installation process of the dependencies.

I forgot to install php8.4-zip extension and the zip packages couldn't be unzipped, so they were retrieved from git.

I don't know why this process generated the error, but now all works perfectly.

DigitalArtisan's avatar

DigitalArtisan was awarded Best Answer+1000 XP

1mo ago

Warning: Ambiguous class resolution

This directory should not exist:

var/www/meeplesperdusaurillac/vendor/league/flysystem/src/Local

I'd delete vendor/league/flysystem then run composer again.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1mo ago

php version does not satisfy that requirement composer laragon, How do i fix this

Im confused because I have the latest version of composer and php,

No you don't.

The latest stable PHP version is 8.5.5, released on April 9, 2026.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1mo ago

Warning: Ambiguous class resolution

This directory should not exist:

var/www/meeplesperdusaurillac/vendor/league/flysystem/src/Local

I'd delete vendor/league/flysystem then run composer again.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1mo ago

Using WordPress as a Headless Backend with Next.js Frontend
The client specifically wants a much faster version of their existing WordPress site 

Why is the site slow, where is the bottle neck and why?

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1mo ago

Migration with geography ?

I’d recommend using PostgreSQL with PostGIS for GIS points.

  • You get real location types (no need to store lat/lon separately)
  • Easy queries like “find points within X distance”
  • Fast with built-in spatial indexing
  • Works well with GIS tools

Basically, it’s much simpler and more powerful than trying to handle coordinates yourself.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

1mo ago

Is it worth it to learn all the courses and coding when AI can make the production level application

80% of the work takes 20% of the time. The other 20% of the work takes 80% of the time.

What you are saying to me is that you have 5-10% of your project complete by AI, by stating that 90-95% of the goals are met, which is the easy stuff, and what about the other 5-10%?

Who is going to spend the rest of the 90-95% of the time that still needs to be done?

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

2mos ago

Laravel Smart Attendance System with Live Geofencing (10–20 Meter Radius) — Feedback Needed

And you state I’m intentionally avoiding AI/ML solutions.

You started with an AI.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

2mos ago

Changing heading for main Filament dashboard

I would rename your Dashboard, as I think I know what is happening. The default dashboard is being loaded, as well as your dashboard, but they have the same name "Dashboard".

Change to the following and should work:

namespace App\Filament\Pages;
use Filament\Pages\Dashboard;

class CustomDashboard extends Dashboard
{
    protected static ?string $title = 'Custom Dashboard';
    protected  ?string $heading = 'Custom Dashboard'';
}

This could be a bug or by design, I'm not sure. If the names do not match, it appears to load the dashboard twice.

Make sure the name of your Dashboard matches the title/heading, as I have shown above with CustomDashboard => "Custom Dashboard" will only show once in the menu, and the title/heading gets changed. If no heading is set, it will default to using title.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

2mos ago

Changing heading for main Filament dashboard

I use this in my custom dashboards:

    protected static ?string $navigationLabel = 'Custom Dashboard';
    
    public function getTitle(): string
    {
        return 'Custom Dashboard';
    }
DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

2mos ago

Forum only not displaying on Firefox 149.0 64 bit

MacOS Firefox 150.0b1 (aarch64)

Broken for a week for me - NS_ERROR_CORRUPTED_CONTENT:

The resource at “https://laracasts.com/fonts/shadow-noir/ShadowNoir.woff2” preloaded with link preload was not used within a few seconds. Make sure all attributes of the preload tag are set correctly. laracasts.com
The resource at “https://laracasts.com/build/assets/js/app-HWIx8gQn.js” preloaded with link preload was not used within a few seconds. Make sure all attributes of the preload tag are set correctly. laracasts.com
GET
https://laracasts.com/build/assets/js/Index-Z2l_0yzy.js
NS_ERROR_CORRUPTED_CONTENT

Loading module from “https://laracasts.com/build/assets/js/Index-Z2l_0yzy.js” was blocked because of a disallowed MIME type (“text/html”). laracasts.com
Uncaught (in promise) TypeError: error loading dynamically imported module: https://laracasts.com/build/assets/js/Index-Z2l_0yzy.js
    vue https://laracasts.com/build/assets/js/app-HWIx8gQn.js:2
    xe https://laracasts.com/build/assets/js/components-BxsoGmWQ.js:2
app-HWIx8gQn.js:2:21205
DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

2mos ago

Laravel website - is this correct?

Its a play on words. Read the paragraph beside the images:

Laravel has opinions on everything: ...

Just add this code if you cannot rename the classes:

class_alias(
    App\Http\Controllers\UserController::class,
    App\Http\Controllers\FlightController::class
);
DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

2mos ago

Staging

Be very clear about the distinction between the client and the end users. Users will sometimes assume that a staging, test, or demo environment is the production system. This confusion can lead to misunderstandings and unnecessary issues.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

2mos ago

Parse XML data into model

Depends on your data. Is your XML well formatted and do you have the XML Schema Definition (XSD) file?

Can be easy, and can be hard, again, depends on your data.

DigitalArtisan's avatar

DigitalArtisan was awarded Best Answer+1000 XP

3mos ago

Best way to systematically determine all permissions needed for my Laravel ticketing system app?

Struggling to identify ALL permissions without missing edge cases or over-engineering.

You should write tests.

Authorization tests help you discover missing permissions and edge cases early, and prevent over-engineering. If a permission rule is hard to test, it’s usually too complex or unclear.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

3mos ago

MySQL sync

To clarify, I said replication is very common when you want a copy of your data. I wasn’t suggesting that syncing dev → prod in a shared hosting environment is common practice.

My point was simply that replication is widely used for maintaining data copies, and it’s a more appropriate term than “sync” in this context.

There are multiple ways to setup replication from a dev box without a static IP: VPN, SSH tunneling, Master/Slave, Pull/Push based, etc.

Anyways, I do not recommend what the OP is doing, nor would I want to.

I would use migrations and seeding to populate the production db.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

3mos ago

MySQL sync

To me, you could set up replication with master slave. One database as the source(dev), the other as the replica(prod).

Very common when you want or need to have a 'copy' of you data.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

3mos ago

Best way to systematically determine all permissions needed for my Laravel ticketing system app?

Struggling to identify ALL permissions without missing edge cases or over-engineering.

You should write tests.

Authorization tests help you discover missing permissions and edge cases early, and prevent over-engineering. If a permission rule is hard to test, it’s usually too complex or unclear.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

4mos ago

Livewire 4 @island inside a loop (foreach/forelse)

Islands can't be used in loops or conditionals:

Because islands don't have access to loop variables or conditional context, they cannot be used inside @foreach, @if, or other control structures:

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

4mos ago

The PsySH tool

I can see why it feels like a change, but the first-time confirmation actually makes sense. PsySH had a security issue (CVE‑2026‑25129) where it could unintentionally load and execute a .psysh.php file from the current directory. The dialog helps make users aware of this risk before running Tinker interactively.

It’s really just a one-time prompt, so after confirming, your usual workflow continues unchanged. I think it’s a small adjustment for a legitimate security reason, and having the library handle the prompt seems appropriate.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

4mos ago

Casting

When a PHP bool is echo'd, it is automatically type casted to a string.

Now for database storage:

  • PostgreSQL: Has a true, native BOOLEAN data type (1 byte). Accepts values like true/false, yes/no, 1/0, 't'/'f', 'y'/'n', and supports NULL.
  • MySQL: No native boolean type. BOOLEAN/BOOL are aliases for TINYINT(1). Uses 1 for true and 0 for false; any non-zero value evaluates as true.
  • SQLite: No boolean storage class. Uses INTEGER (NUMERIC affinity), where 1 = true and 0 = false. TRUE and FALSE are just aliases for 1 and 0.

Key takeaway: PostgreSQL is SQL-standard with a real boolean type, while MySQL and SQLite represent booleans using integers—important to remember for cross-database compatibility.

PHP stores booleans as booleans, not numbers

  • echo converts them to strings:

    • true → "1"

    • false → ""

Use var_dump() to see the real type

Cast to (int) if you truly want 0 / 1

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

4mos ago

Best place to put a Laravel into production.

The best place to deploy your application depends on several factors:

  • Budget
  • Your experience, knowledge, and comfort level with hosting and deploying Laravel applications
  • Your test benchmarks and performance results

To move forward, here are a few questions for you:

  1. What is your budget?
  2. What is your experience / comfort level with hosting and deploying Laravel apps?
  3. What do your performance and load-testing benchmarks show so far?
DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

4mos ago

Rate limiting mailables

When you prompt AI correclty, you should get this:

The Correct Way to Throttle Emails in Laravel with Jobs and Queues

Step 1: Use Queue Middleware (RateLimited)

This is the core part of the solution. To throttle emails, you add middleware to your job to enforce the rate limit:

use Illuminate\Queue\Middleware\RateLimited;

class SendEmailJob implements ShouldQueue
{
    public function middleware()
    {
        return [
            new RateLimited('mailing-list'),
        ];
    }

    public function handle()
    {
        // Logic to send the email
    }
}

This ensures the job respects the rate limit defined later.


Step 2: Define Rate Limit in AppServiceProvider

In your AppServiceProvider@boot(), you define the rate-limiting logic:

use Illuminate\Cache\RateLimiter;
use Illuminate\Cache\RateLimiting\Limit;

public function boot()
{
    RateLimiter::for('mailing-list', function (SendEmailJob $job) {
        return Limit::perMinute(10)->by($job->userId);
    });
}

This sets a 10 emails per minute limit for each user (based on userId).


Step 3: Use Redis as Queue and Cache Driver

Redis is required for distributed rate-limiting. Ensure your .env file is configured like this:

QUEUE_CONNECTION=redis
CACHE_DRIVER=redis

Redis ensures the limit is applied safely across multiple workers or instances.


Step 4: Run the Queue Worker

Run the queue worker to process the jobs:

php artisan queue:work redis

This worker will now respect the rate limit (10 emails per minute in this example) and retry any jobs that exceed the rate limit.


Key Points:

  • Only one correct method, with 4 steps to implement.
  • Redis is mandatory for safe, scalable rate-limiting.
  • RateLimited middleware handles job throttling.
  • No emails are dropped—they’re released back to the queue when the limit is hit.
DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

4mos ago

Inertia for heavily SEO application

Its 2026 now, that article is OLD.

Here is a current AI response:


Laravel + Next.js vs Laravel + Inertia + React for SEO

1. Laravel + Next.js

Pros:

  • Server-Side Rendering (SSR): Next.js renders pages on the server before sending them to the browser, which is great for SEO.
  • SEO Optimized: Built-in features like image optimization, fast page loads, and prefetching help with SEO.
  • Static Site Generation (SSG): You can generate static pages, improving performance and SEO.

Cons:

  • More Complex: Managing both Laravel and Next.js can be tricky. You'll need separate setups and integration.
  • API Management: You'll need to set up APIs for Laravel to serve data to Next.js.

2. Laravel + Inertia + React

Pros:

  • Simple Integration: Keeps everything within Laravel, no need for a separate front-end framework.
  • Server-side Rendering: You can still use Laravel to serve initial HTML, making it SEO-friendly.

Cons:

  • Client-Side Rendering (CSR): By default, Inertia uses React on the client-side, which can be problematic for SEO if not handled correctly.
  • Manual SEO Work: You may need additional tools like React Helmet or implement SSR manually for optimal SEO.

Conclusion:

  • For better SEO out of the box: Go with Laravel + Next.js. It has built-in SSR and other SEO optimizations.
  • For simplicity: Laravel + Inertia + React works if you don't mind handling SEO optimization yourself, but it might require more effort to get it right.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

4mos ago

LTI 1.3 tutorial

First, you need a Learning Management System (LMS) that supports Learning Tools Interoperability (LTI).

LTI is a standard defined by 1EdTech (formerly IMS Global) that allows an LMS to securely integrate external learning tools. It’s often described as an API, but in practice it’s a standards-based protocol for authentication, launch, and grade/roster exchange between systems.

LTI Roles

LTI involves two roles:

  • LTI Platform (formerly “Consumer”) — the LMS (e.g., Canvas, Moodle, D2L)
  • LTI Tool (formerly “Provider”) — the external application being launched

LTI Versions

As of today, LTI 1.3 with LTI Advantage is the recommended version. It replaces older LTI 1.1 implementations and is based on OAuth 2.0 and OpenID Connect.

Official tutorials and specifications:
https://www.imsglobal.org/spec/lti/v1p3/

Laravel and LTI

Regarding Laravel:
There still aren’t any widely adopted, full-featured Laravel-based LMS platforms that natively act as an LTI Platform. However, Laravel works well for building LTI Tools, and there are PHP/Laravel libraries that help implement LTI 1.3 launches, deep linking, and grade passback.

In a previous role, I used Desire2Learn (D2L / Brightspace) extensively, which has solid LTI support:
https://docs.valence.desire2learn.com/res/lti.html

Common Approach Today

So today, the common approach is:

  • Use an established LMS (Canvas, Moodle, D2L, etc.) as the LTI Platform
  • Build custom learning tools in Laravel as LTI Tools
DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

4mos ago

Lovable vs traditional web developer

There’s a lot of debate around this.

From my experience, AI significantly reduces time to production—projects that once took months or weeks can now be completed in days or hours. Refactoring is faster as well.

That said, when AI breaks down, a developer still has to understand and fix the code. I’ve heard of teams abandoning AI-generated projects because no one fully understood the codebase.

Bottom line: AI is a productivity tool, not a replacement. It can help, but it’s not a silver bullet.

Marketing is still marketing—SEO, targeting, and messaging matter. Relying entirely on AI for marketing content can be risky if it gets things wrong.

Used carefully, AI is valuable. Used blindly, it can create problems.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

4mos ago

How to get a job as an Entry Level Junior Laravel Developer?

When people say you only need a “high-level” understanding of DevOps, cloud, and system design for junior roles, they mean knowing what these things are, why they’re used, and how they fit into the web development process, not being able to fully build or operate production infrastructure yourself. You should be able to explain concepts like CI/CD, cloud hosting, authentication, scalability, and how a backend system is structured, but you’re not expected to manage Kubernetes, complex AWS networking, or large-scale distributed systems.

For projects, the backend projects on roadmap.sh are more than enough for junior roles if done properly. “Real-world” doesn’t mean huge SaaS platforms or advanced AI apps—it means projects with realistic business logic, data relationships, authentication, validation, error handling, and clear tradeoffs. A few well-built APIs (auth system, CRUD app, blog, e-commerce, task manager) that you understand deeply are far more impressive than an over-scoped SaaS or Indeed-style clone.

It may be worth considering a more structured or formal learning route to help solidify the fundamentals.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

4mos ago

How to get a job as an Entry Level Junior Laravel Developer?

Hiring teams primarily look for learning ability, strong fundamentals, and practical problem-solving skills—not senior-level infrastructure expertise.

To get a junior Laravel job you should build a few solid, real-world Laravel projects that demonstrate core PHP/Laravel knowledge (CRUD, authentication, validation, relationships, testing, and Git), basic SQL, and simple deployment, while understanding DevOps, cloud, and system design concepts only at a high level rather than fully implementing them.

DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

5mos ago

PUT method returns 405

You are probably missing the following in your view:

<form method="POST" action="/payers/{{ $payer->id }}">
    @csrf
    @method('PUT')   {{-- or PATCH / DELETE --}}
</form>
DigitalArtisan's avatar

DigitalArtisan wrote a reply+100 XP

5mos ago

PUT method returns 405

Exactly, not working. You have these routes:

  GET|HEAD        payers .............. payers.index › PayerController@index
  PUT             payers .............. payers.store › PayerController@store
  PATCH           payers/{payer} ...... payers.update › PayerController@update
  DELETE          payers/{payer} ...... payers.destroy › PayerController@destroy

I would think you need this:

  GET|HEAD      payers .............. payers.index › PayerController@index
  POST          payers .............. payers.store › PayerController@store
  PUT|PATCH     payers/{payer} ...... payers.update › PayerController@update
  DELETE        payers/{payer} ...... payers.destroy › PayerController@destroy

Your error message is correct for your routing.