<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Samson Ojugo</title>
    <description>The latest articles on DEV Community by Samson Ojugo (@quietnoisemaker).</description>
    <link>https://dev.to/quietnoisemaker</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1071024%2F1b09307b-e771-41e6-b0a5-10a429a2e3cc.png</url>
      <title>DEV Community: Samson Ojugo</title>
      <link>https://dev.to/quietnoisemaker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/quietnoisemaker"/>
    <language>en</language>
    <item>
      <title>Automate Your Laravel Deployment on a VPS Using GitHub Actions: A Beginner's Guide</title>
      <dc:creator>Samson Ojugo</dc:creator>
      <pubDate>Wed, 24 Sep 2025 22:27:49 +0000</pubDate>
      <link>https://dev.to/quietnoisemaker/automate-your-laravel-deployment-on-a-vps-using-github-actions-a-beginners-guide-2033</link>
      <guid>https://dev.to/quietnoisemaker/automate-your-laravel-deployment-on-a-vps-using-github-actions-a-beginners-guide-2033</guid>
      <description>&lt;p&gt;Hey there, developers! 👋 I'm Ojugo Samson, a Lead Software Engineer, I build scalable solutions with PHP and Laravel. &lt;br&gt;
Deploying code manually—logging into a server, pulling changes, running migrations—can be a hassle, especially for frequent updates. In this guide, I’ll show you how to automate deployments for your Laravel app on a Virtual Private Server (VPS) using &lt;strong&gt;GitHub Actions&lt;/strong&gt;. This approach uses a secure SSH connection to trigger a deployment script on your server whenever you push to the &lt;code&gt;main&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;This tutorial is beginner-friendly, but I’ll assume you know the basics of Laravel, Git, and SSH. If you’re new to VPS, I recommend providers like DigitalOcean, Linode, or AWS Lightsail. Let’s get started!&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Use GitHub Actions for Deployment?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automation&lt;/strong&gt;: Push to GitHub, and your server updates automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Store sensitive data like SSH keys in GitHub Secrets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: Customize workflows for testing, staging, or production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visibility&lt;/strong&gt;: Track deployment status in GitHub’s Actions tab.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll deploy a sample Laravel app (like my &lt;a href="https://verifyplug.com" rel="noopener noreferrer"&gt;VerifyPlug&lt;/a&gt; project), but this works for any Laravel-based repo.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we begin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A GitHub repository with your Laravel project (e.g., on the &lt;code&gt;main&lt;/code&gt; branch).&lt;/li&gt;
&lt;li&gt;A VPS with Ubuntu (or similar Linux distro), PHP 8.3+, Composer, Git, and Laravel’s requirements installed.&lt;/li&gt;
&lt;li&gt;Your Laravel app cloned and running on the VPS (e.g., in &lt;code&gt;/var/www/your-app&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Nginx or Apache configured for your site.&lt;/li&gt;
&lt;li&gt;Supervisor or similar for queue workers (if using queues).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your VPS isn’t set up, check &lt;a href="https://laravel.com/docs/deployment" rel="noopener noreferrer"&gt;Laravel’s deployment docs&lt;/a&gt; for setup basics.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Set Up SSH Keys for Secure Access
&lt;/h2&gt;

&lt;p&gt;To let GitHub Actions connect to your VPS securely, generate an SSH key pair on your VPS and add the public key to GitHub Secrets.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SSH into your VPS:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh youruser@your-vps-ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Generate an SSH key pair (accept defaults or add a passphrase for extra security):
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"your_email@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This creates &lt;code&gt;~/.ssh/id_ed25519&lt;/code&gt; (private key) and &lt;code&gt;~/.ssh/id_ed25519.pub&lt;/code&gt; (public key).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the public key to &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_ed25519.pub &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.ssh/authorized_keys
   &lt;span class="nb"&gt;chmod &lt;/span&gt;600 ~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Copy the &lt;strong&gt;private key&lt;/strong&gt; for GitHub Secrets:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_ed25519
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Save this securely—you’ll need it in Step 4.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test SSH locally to ensure it works:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/id_ed25519 youruser@your-vps-ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Step 2: Clone Your Repository on the VPS (If Not Already Done)
&lt;/h2&gt;

&lt;p&gt;Navigate to your web directory and clone your repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/www/your-app
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nv"&gt;$USER&lt;/span&gt;:www-data /var/www/your-app
&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/your-app
git clone git@github.com:yourusername/your-repo.git &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;your-app&lt;/code&gt;, &lt;code&gt;yourusername&lt;/code&gt;, and &lt;code&gt;your-repo&lt;/code&gt; with your details.&lt;/p&gt;

&lt;p&gt;Install dependencies and configure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--optimize-autoloader&lt;/span&gt; &lt;span class="nt"&gt;--no-dev&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
php artisan key:generate
php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure your &lt;code&gt;.env&lt;/code&gt; is set up with database credentials and other configs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Create the Deployment Script
&lt;/h2&gt;

&lt;p&gt;We’ll create a &lt;code&gt;deploy.sh&lt;/code&gt; script on the VPS to handle pulling code, updating dependencies, and restarting services.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In &lt;code&gt;/var/www/your-app&lt;/code&gt;, create the script:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nano deploy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add the following:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
   &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;

   &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deployment started..."&lt;/span&gt;

   &lt;span class="c"&gt;# Navigate to project directory&lt;/span&gt;
   &lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/your-app

   &lt;span class="c"&gt;# Enter maintenance mode (ignore if already down)&lt;/span&gt;
   &lt;span class="o"&gt;(&lt;/span&gt;php artisan down &lt;span class="nt"&gt;--message&lt;/span&gt; &lt;span class="s2"&gt;"The app is being updated. Please try again in a minute."&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;

   &lt;span class="c"&gt;# Pull the latest code from the main branch&lt;/span&gt;
   git fetch origin main
   git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; origin/main

   &lt;span class="c"&gt;# Install Composer dependencies&lt;/span&gt;
   composer &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-dev&lt;/span&gt; &lt;span class="nt"&gt;--no-interaction&lt;/span&gt; &lt;span class="nt"&gt;--prefer-dist&lt;/span&gt; &lt;span class="nt"&gt;--optimize-autoloader&lt;/span&gt;

   &lt;span class="c"&gt;# Clear and recreate caches&lt;/span&gt;
   php artisan cache:clear
   php artisan config:cache
   php artisan route:cache
   php artisan view:cache

   &lt;span class="c"&gt;# Run database migrations&lt;/span&gt;
   php artisan migrate &lt;span class="nt"&gt;--force&lt;/span&gt;

   &lt;span class="c"&gt;# Restart queue workers (if using database queue)&lt;/span&gt;
   php artisan queue:restart

   &lt;span class="c"&gt;# Exit maintenance mode&lt;/span&gt;
   php artisan up

   &lt;span class="c"&gt;# Reload PHP-FPM to update opcache (adjust version if needed)&lt;/span&gt;
   &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; | &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-S&lt;/span&gt; service php8.3-fpm reload

   &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deployment finished!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Make it executable:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;chmod&lt;/span&gt; +x deploy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Test it manually:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ./deploy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fix any issues (e.g., permissions for &lt;code&gt;www-data&lt;/code&gt; or PHP-FPM version).&lt;/p&gt;

&lt;p&gt;This script handles maintenance mode, code updates, dependency installation, cache management, migrations, and service restarts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Set Up GitHub Actions Workflow
&lt;/h2&gt;

&lt;p&gt;We’ll create a &lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt; file in your repository to automate the deployment.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In your local repo, create the directory and file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .github/workflows
   &lt;span class="nb"&gt;touch&lt;/span&gt; .github/workflows/deploy.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add the following content:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;   &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Production&lt;/span&gt;
   &lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

   &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
       &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout Repository&lt;/span&gt;
           &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup SSH&lt;/span&gt;
           &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;webfactory/ssh-agent@v0.5.4&lt;/span&gt;
           &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="na"&gt;ssh-private-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DEPLOY_SERVER_KEY }}&lt;/span&gt;

         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to VPS&lt;/span&gt;
           &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appleboy/ssh-action@master&lt;/span&gt;
           &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DEPLOY_SERVER_IP }}&lt;/span&gt;
             &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DEPLOY_SERVER_USER }}&lt;/span&gt;
             &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DEPLOY_SERVER_KEY }}&lt;/span&gt;
             &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
               &lt;span class="s"&gt;cd ${{ secrets.DEPLOY_PATH }}&lt;/span&gt;
               &lt;span class="s"&gt;./deploy.sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Commit and push:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git add .github/workflows/deploy.yml
   git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add GitHub Actions deployment workflow"&lt;/span&gt;
   git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This workflow triggers on pushes to &lt;code&gt;main&lt;/code&gt;, checks out the code, sets up SSH, and runs &lt;code&gt;deploy.sh&lt;/code&gt; on your VPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Configure GitHub Secrets
&lt;/h2&gt;

&lt;p&gt;To securely store sensitive data, add the following to your repo’s Settings &amp;gt; Secrets and variables &amp;gt; Actions &amp;gt; Secrets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to your GitHub repo &amp;gt; Settings &amp;gt; Secrets and variables &amp;gt; Actions &amp;gt; New repository secret.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add these secrets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;DEPLOY_SERVER_KEY&lt;/code&gt;: The private SSH key from Step 1 (&lt;code&gt;id_ed25519&lt;/code&gt; content).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DEPLOY_SERVER_IP&lt;/code&gt;: Your VPS IP address (e.g., &lt;code&gt;192.168.1.1&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DEPLOY_SERVER_USER&lt;/code&gt;: Your VPS username (e.g., &lt;code&gt;youruser&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DEPLOY_PATH&lt;/code&gt;: The full path to your app (e.g., &lt;code&gt;/var/www/your-app&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 6: Test the Deployment
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Make a small change locally (e.g., update a view).&lt;/li&gt;
&lt;li&gt;Commit and push to &lt;code&gt;main&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Test deployment"&lt;/span&gt;
   git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to your repo &amp;gt; Actions tab to monitor the workflow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check &lt;code&gt;/var/www/your-app&lt;/code&gt; on the VPS to confirm updates. Debug using the Actions logs or by adding &lt;code&gt;&amp;gt; deploy.log 2&amp;gt;&amp;amp;1&lt;/code&gt; to the script step for output.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Common issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SSH errors&lt;/strong&gt;: Verify the private key and &lt;code&gt;authorized_keys&lt;/code&gt; setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions&lt;/strong&gt;: Ensure &lt;code&gt;www-data&lt;/code&gt; has access to &lt;code&gt;/var/www/your-app&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PHP-FPM version&lt;/strong&gt;: Adjust the &lt;code&gt;php8.3-fpm&lt;/code&gt; service name if using a different version.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test First&lt;/strong&gt;: Use a &lt;code&gt;staging&lt;/code&gt; branch to test deployments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backups&lt;/strong&gt;: Snapshot your VPS and database before migrations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring&lt;/strong&gt;: Use tools like Sentry for error tracking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Downtime&lt;/strong&gt;: For production, explore tools like Laravel Forge or Envoyer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Restrict SSH access to your GitHub Actions runner IP range.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup powers my projects like VerifyPlug, saving hours of manual work!&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;You’ve now automated your Laravel app’s deployment with GitHub Actions! Push to &lt;code&gt;main&lt;/code&gt;, and your VPS updates seamlessly. If you hit issues, check the Actions logs or reach out on &lt;a href="https://www.linkedin.com/in/samsonojugo" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ojugo Samson&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Lead Software Engineer @ Cargoplug | Techstars '24&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/samsonojugo" rel="noopener noreferrer"&gt;samsonojugo&lt;/a&gt;&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;GitHub: &lt;a href="https://github.com/quitenoisemaker" rel="noopener noreferrer"&gt;quitenoisemaker&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>laravel</category>
      <category>github</category>
      <category>programming</category>
    </item>
    <item>
      <title>Simplify Logistics with ShippingTracker v1.1.0 for Laravel</title>
      <dc:creator>Samson Ojugo</dc:creator>
      <pubDate>Tue, 24 Jun 2025 16:00:41 +0000</pubDate>
      <link>https://dev.to/quietnoisemaker/simplify-logistics-with-shippingtracker-v110-for-laravel-52c4</link>
      <guid>https://dev.to/quietnoisemaker/simplify-logistics-with-shippingtracker-v110-for-laravel-52c4</guid>
      <description>&lt;p&gt;As a Laravel developer passionate about e-commerce in Africa and Europe, I know logistics can be a headache. Couriers like Sendbox and Cargoplug use inconsistent APIs and webhook formats, making shipment tracking a chore. That’s why I built ShippingTracker v1.1.0, an open-source Laravel package to streamline logistics, and I’m excited to share it with you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why ShippingTracker?
&lt;/h2&gt;

&lt;p&gt;ShippingTracker abstracts the mess of courier APIs, letting you focus on building great e-commerce apps. Here’s what it offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easy Webhook Handling:&lt;/strong&gt; Processes Sendbox and Cargoplug webhooks, saving tracking data (e.g., “delivered in Lagos”) with a clean event system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Extensible:&lt;/strong&gt; Add new providers (like DHL, planned for v1.2.1) without touching core code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Laravel 9–12 Ready:&lt;/strong&gt; Works across Laravel 9, 10, 11, and 12.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Beginner-Friendly:&lt;/strong&gt; Simple setup with commands like composer &lt;code&gt;install quitenoisemaker/shipping-tracker:^1.1&lt;/code&gt;`&lt;code&gt;and a facade&lt;/code&gt;(ShippingTracker::use('sendbox')-&amp;gt;track('101782511')&lt;code&gt;)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tested &amp;amp; Reliable:&lt;/strong&gt; PHPUnit tests ensure webhook validation and provider switching work flawlessly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why It Matters
&lt;/h2&gt;

&lt;p&gt;E-commerce is growing fast, but logistics remains tricky. ShippingTracker empowers devs to deliver real-time tracking to customers without API headaches, perfect for shops in Lagos or London.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;Install it in minutes:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;`&lt;br&gt;
composer require quitenoisemaker/shipping-tracker:^1.1&lt;br&gt;
php artisan vendor:publish --provider="Quitenoisemaker\ShippingTracker\ShippingTrackerServiceProvider" --tag=config&lt;br&gt;
`&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Update &lt;code&gt;config/shipping-tracker.php&lt;/code&gt; and &lt;code&gt;.env&lt;/code&gt; with your courier credentials, run migrations, and you’re good to go! Check the GitHub repo for setup and webhook examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;I’m planning v1.2.1 with DHL support and more. Want a specific courier or feature? File an issue or PR on &lt;a href="https://github.com/quitenoisemaker/shipping-tracker" rel="noopener noreferrer"&gt;&lt;/a&gt; input shapes the future!&lt;/p&gt;

&lt;p&gt;Try ShippingTracker today: &lt;a href="https://packagist.org/packages/quitenoisemaker/shipping-tracker" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What’s your biggest logistics challenge in Laravel? Drop a comment below! &lt;/p&gt;

&lt;h1&gt;
  
  
  Laravel #PHP #Ecommerce #Logistics #OpenSource
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>Building a simple Referral System API with Laravel 11</title>
      <dc:creator>Samson Ojugo</dc:creator>
      <pubDate>Tue, 28 May 2024 08:24:49 +0000</pubDate>
      <link>https://dev.to/quietnoisemaker/building-a-simple-referral-system-api-with-laravel-11-2aom</link>
      <guid>https://dev.to/quietnoisemaker/building-a-simple-referral-system-api-with-laravel-11-2aom</guid>
      <description>&lt;p&gt;With the use of special referral codes, referral systems are an effective marketing technique that encourages current customers to promote business offerings. For those who are new to using Laravel 11 and want to handle user referrals through APIs, this tutorial will show you how to create a basic referral system API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's get started.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Prerequisites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic understanding of PHP, Laravel concepts, and RESTful APIs&lt;/li&gt;
&lt;li&gt;A local development environment with Laravel 11 installed&lt;/li&gt;
&lt;li&gt;A database (e.g., MySQL) configured with Laravel&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Project Setup and Modify the User Migration Schema
&lt;/h2&gt;

&lt;p&gt;Create a new Laravel project using the Artisan command and navigate to the project directory. We'll need a table to store user information. Laravel provides a User model by default.&lt;/p&gt;

&lt;p&gt;Go to the users migration and modify accordingly.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Schema::create('users', function (Blueprint $table) {
            $table-&amp;gt;id();
            $table-&amp;gt;string('name');
            $table-&amp;gt;string('email')-&amp;gt;unique();
            $table-&amp;gt;timestamp('email_verified_at')-&amp;gt;nullable();
            $table-&amp;gt;rememberToken();
            $table-&amp;gt;string('referral_code')-&amp;gt;index()-&amp;gt;unique();
            $table-&amp;gt;unsignedBigInteger('referred_by')-&amp;gt;nullable();
            $table-&amp;gt;integer('referral_count')-&amp;gt;default(0);
            $table-&amp;gt;string('password');    
            $table-&amp;gt;timestamps();

            $table-&amp;gt;foreign('referred_by')-&amp;gt;references('id')-&amp;gt;on('users')-&amp;gt;onUpdate('cascade')-&amp;gt;onDelete('set null');
        });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then run the php artisan migrate to run your migrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Define API route
&lt;/h2&gt;

&lt;p&gt;We'll create two main API endpoints to manage referrals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;POST /users - This endpoint will handle user registration and potentially generate a referral code for the new user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /users/{user}/referrals - This endpoint will retrieve referral data for a specific user&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enable API routing using the &lt;code&gt;install:api&lt;/code&gt; Artisan command and define the route in your &lt;code&gt;routes/api.php&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;install:api&lt;/code&gt; command installs Laravel Sanctum, which provides a robust, yet simple API token authentication guard which can be used to authenticate third-party API consumers, SPAs, or mobile applications. In addition, the &lt;code&gt;install:api&lt;/code&gt; command creates the &lt;code&gt;routes/api.php&lt;/code&gt; file: read more &lt;a href="https://laravel.com/docs/11.x/routing" rel="noopener noreferrer"&gt;https://laravel.com/docs/11.x/routing&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route::prefix('/users')-&amp;gt;group(function () {
    Route::post('/', [UserReferralProgramController::class, 'store']);
    Route::get('/{user}/referrals', [UserReferralProgramController::class, 'fetchUserReferral']);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Consider using versioning in your API URL structure (e.g., /api/v1/users) to maintain flexibility for future changes. You may change the prefix by modifying your application's &lt;strong&gt;bootstrap/app.php&lt;/strong&gt; file.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-&amp;gt;withRouting(
        web: __DIR__ . '/../routes/web.php',
        api: __DIR__ . '/../routes/api.php',
        commands: __DIR__ . '/../routes/console.php',
        health: '/up',
        apiPrefix: 'api/v1',
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 3: Define Methods in your Controller
&lt;/h2&gt;

&lt;p&gt;Run the command &lt;code&gt;php artisan make:controller Api/UserReferralProgramController&lt;/code&gt;&lt;br&gt;
Goto &lt;strong&gt;app\Http\Controllers\Api\UserReferralProgramController.php&lt;/strong&gt; and define the methods. Later, we shall return to the controller.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UserReferralProgramController extends Controller
{
    /**
     * Store a newly created resource in storage.
     */
    public function store(UserStoreRequest $request): void
    {
    }

    /**
     * fetch user referrals.
     */
    public function fetchUserReferral(User $user): void
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 4: Utilize the service class(if applicable).
&lt;/h2&gt;

&lt;p&gt;run the command &lt;code&gt;php artisan make:class Service/ReferralCodeGenerator&lt;/code&gt; to create the class&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Service;

use App\Models\User;

class ReferralCodeGenerator
{
    /**
     * Generates a random referral code.
     *
     * This method generates a random string of specified length using the provided character set.
     * It then checks for existing codes in the database and regenerates if necessary.
     *
     * @return string The generated referral code.
     * 
     * @throws \Exception If an error occurs during code generation or validation.
     */
    public function generate(): string
    {
        $codeLength = 10;
        $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $code = '';

        $code = substr(str_shuffle(str_repeat($characters, 5)), 0, $codeLength);

        return $this-&amp;gt;checkAndRegenerate($code);
    }

    /**
     * Checks if a referral code already exists in the database and regenerates if necessary.
     *
     * This method takes a generated referral code as input and checks if it exists in the database.
     * If the code already exists, it regenerates a new code using the `generate` method and calls itself recursively to check again.
     * This process continues until a unique, non-existing code is found.
     *
     * @param string $code The referral code to be checked.
     * 
     * @return string A unique, non-existing referral code.
     * 
     */
    private function checkAndRegenerate(string $code): string
    {
        if (User::where('referral_code', $code)-&amp;gt;exists()) {
            return $this-&amp;gt;checkAndRegenerate($this-&amp;gt;generate());
        }

        return $code;
    }

    /**
     * Finds a user by referral code and increments their referral count in a single database query.
     *
     * This method takes a referral code as input and attempts to find a matching user in the database.
     * If a user is found, it atomically increments their `referral_count` by 1 and retrieves the user's ID.
     * 
     * This method utilizes a single database query with Laravel's `update` method and raw expressions for efficiency.
     *
     * @param string $referralCode The referral code to be checked.
     * 
     * @return int|null The user ID if found, otherwise null.
     *
     */
    public function getUserIdByReferralCodeAndIncrementCount(string $referralCode): int|null
    {
        $userId = User::where('referral_code', $referralCode)-&amp;gt;value('id');

        if ($userId) {
            $this-&amp;gt;incrementReferralCount($userId);
            return $userId;
        }
        return null;
    }

    private function incrementReferralCount(int $userId): void
    {
        User::where('id', $userId)-&amp;gt;increment('referral_count');
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Code Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;ReferralCodeGenerator&lt;/strong&gt; class provides functionality to generate unique referral codes and manage user referral counts. Here's a summary:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;generate&lt;/strong&gt; Method: Creates a random 10-character referral code using a specified character set and ensures its uniqueness by checking against the database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;checkAndRegenerate&lt;/strong&gt; Method: Recursively verifies the uniqueness of a referral code and regenerates it if necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;getUserIdByReferralCodeAndIncrementCount&lt;/strong&gt; Method: Finds a user by referral code, increments their referral count atomically, and returns the user's ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;incrementReferralCount&lt;/strong&gt; Method: Increments the referral_count of a user by their ID.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This class ensures that generated referral codes are unique and facilitates updating user referral counts efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8: Modify our existing Controller
&lt;/h2&gt;

&lt;p&gt;Let’s go back to our controller &lt;strong&gt;app\Http\Controllers\Api\UserReferralProgramController.php&lt;/strong&gt; and make some modifications.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UserReferralProgramController extends Controller
{

    /**
     * Create a new class instance.
     */
    public function __construct(public ReferralCodeGenerator $referralCodeGenerator)
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(UserStoreRequest $request): JsonResponse
    {

        $validatedData = $request-&amp;gt;validated();

        $referredBy = null;

        if ($request-&amp;gt;has('referral_code')) {
            $referredBy = $this-&amp;gt;referralCodeGenerator-&amp;gt;getUserIdByReferralCodeAndIncrementCount($request-&amp;gt;referral_code);
        }

        $requestData = array_merge(
            $validatedData,
            [
                'referred_by' =&amp;gt; $referredBy,
                'referral_code' =&amp;gt; $this-&amp;gt;referralCodeGenerator-&amp;gt;generate()
            ]
        );

        $user  = User::create($requestData);

        return response()-&amp;gt;json([
            'message' =&amp;gt; 'user created',
            'data' =&amp;gt; $user
        ], Response::HTTP_CREATED);
    }

    /**
     * fetch user referrals.
     */
    public function fetchUserReferral(User $user): JsonResponse
    {
        $referrals = User::where('referred_by', $user-&amp;gt;id)-&amp;gt;get();

        return response()-&amp;gt;json([
            'message' =&amp;gt; 'success',
            'data' =&amp;gt; [
                'referrals_count' =&amp;gt; $user-&amp;gt;referral_count,
                'referrals' =&amp;gt; $referrals
            ]
        ], Response::HTTP_OK);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In our controller method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I Initialized the controller with a ReferralCodeGenerator instance, which is used for generating and validating referral codes.&lt;/li&gt;
&lt;li&gt;Also validated the incoming request data (name, email, password, etc.).&lt;/li&gt;
&lt;li&gt;If a referral_code parameter is present in the request, use it to find the referring user.&lt;/li&gt;
&lt;li&gt;Created a new User model instance with the provided data and generated code.&lt;/li&gt;
&lt;li&gt;Saved the user to the database and potentially update the referring user's referral count &lt;/li&gt;
&lt;li&gt;Returned a successful response with relevant user information (excluding password) or an error response in case of validation issues or database errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Remember&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This example has been simplified. Ensure that your system is production-ready by integrating &lt;em&gt;strong authentication methods&lt;/em&gt;, &lt;em&gt;Database transaction&lt;/em&gt;, &lt;em&gt;resource to transform the result&lt;/em&gt;, &lt;em&gt;extensive error handling&lt;/em&gt;, and extra features depending on your requirements.&lt;/p&gt;

&lt;p&gt;Using Laravel 11, you can create a robust referral system API that facilitates user growth and acquisition for your application by following these instructions and experimenting with advanced features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test our Endpoint on POSTMAN&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;code&gt;{{url}}/api/v1/users&lt;/code&gt; to store users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwc825a7sa3snn7fe25jt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwc825a7sa3snn7fe25jt.png" alt="register user with referal code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;{{url}}/api/v1/users/:userId/referrals&lt;/code&gt; to fetch user referrals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxicg54cgwxcxj6fty3f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxicg54cgwxcxj6fty3f.png" alt="fetch user with their referrals"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can get the complete code from &lt;a href="https://github.com/quitenoisemaker/customer_incentive_programs" rel="noopener noreferrer"&gt;https://github.com/quitenoisemaker/customer_incentive_programs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>php</category>
      <category>laravel</category>
      <category>api</category>
    </item>
    <item>
      <title>Creating a Laravel Artisan command that sends mail to all active users in the database.</title>
      <dc:creator>Samson Ojugo</dc:creator>
      <pubDate>Wed, 24 May 2023 09:23:02 +0000</pubDate>
      <link>https://dev.to/quietnoisemaker/creating-a-laravel-artisan-command-that-sends-mail-to-all-active-users-in-the-database-4onl</link>
      <guid>https://dev.to/quietnoisemaker/creating-a-laravel-artisan-command-that-sends-mail-to-all-active-users-in-the-database-4onl</guid>
      <description>&lt;p&gt;I’ll be guiding you through some fundamental artisan command creation implementations. Our objective is to develop an artisan command that sends email to every active user in the database.&lt;/p&gt;

&lt;p&gt;Artisan is the command line interface included with Laravel. Artisan exists at the root of your application as the artisan script and provides a number of helpful commands that can assist you while you build your application.&lt;/p&gt;

&lt;p&gt;Let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Modify the User Migration Schema
&lt;/h2&gt;

&lt;p&gt;I’m assuming that you just created a fresh Laravel application. Let’s add a new column to the user migration file, which Laravel has already produced.&lt;/p&gt;

&lt;p&gt;Go to the users migration and modify accordingly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Schema::create('users', function (Blueprint $table) {
    $table-&amp;gt;id();
    $table-&amp;gt;string('name');
    $table-&amp;gt;string('email')-&amp;gt;unique();
    $table-&amp;gt;timestamp('email_verified_at')-&amp;gt;nullable();
    $table-&amp;gt;string('password');
    $table-&amp;gt;boolean('is_active');
    $table-&amp;gt;rememberToken();
    $table-&amp;gt;timestamps();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added the boolean column “is_active” which indicates whether the user’s account is active or inactive.&lt;/p&gt;

&lt;p&gt;Then run the &lt;strong&gt;php artisan migrate&lt;/strong&gt; to run your migrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Generate fake user data and seed data
&lt;/h2&gt;

&lt;p&gt;We will need to generate fake data for the user table. The &lt;strong&gt;UserFactory&lt;/strong&gt; class is already created by Laravel upon installation.&lt;/p&gt;

&lt;p&gt;Go to &lt;strong&gt;database\factories\UserFactory.php&lt;/strong&gt; and make modifications to it. I will be adding the key-value pair &lt;strong&gt;‘is_active’ =&amp;gt;fake()-&amp;gt;boolean()&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function definition()
{
    return [
        'name' =&amp;gt; fake()-&amp;gt;name(),
        'email' =&amp;gt; fake()-&amp;gt;unique()-&amp;gt;safeEmail(),
        'email_verified_at' =&amp;gt; now(),
        'is_active' =&amp;gt;fake()-&amp;gt;boolean(),//generate 1 or 0
        'password' =&amp;gt; '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' =&amp;gt; Str::random(10),
    ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we go to the &lt;strong&gt;database\seeders\DatabaseSeeder.php&lt;/strong&gt; and uncomment the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;\App\Models\User::factory(10)-&amp;gt;create();// add 10 records to the user table&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we can run &lt;strong&gt;php artisan db:seed&lt;/strong&gt; to seed our data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Generate a command and define appropriate values.
&lt;/h2&gt;

&lt;p&gt;Create a new command by running&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:command SendMailToActiveUsers.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Go to the newly created command class, &lt;strong&gt;app/Console/Commands/SendMailToActiveUsers.php&lt;/strong&gt; and define appropriate values for the signature and description properties of the class. These properties will be used when displaying your command on the list screen.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;signature&lt;/code&gt; property also allows you to define your command’s input expectations. Modify your signature and description properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protected $signature = 'send:active-user-mail';

/**
 * The console command description.
 *
 * @var string
 */
protected $description = 'Command sends mail to all active users';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can view your newly created command by running the &lt;code&gt;php artisan list&lt;/code&gt; command to view the list of all commands.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JQ74tVu8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pgj53vqnmj12zb89n3hh.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JQ74tVu8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pgj53vqnmj12zb89n3hh.PNG" alt="Image to show the command created" width="800" height="729"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Generate Mailables class
&lt;/h2&gt;

&lt;p&gt;I will be generating Markdown Mailable. The Markdown mailable messages allow you to take advantage of the pre-built templates and components of mail notifications in your mailables. Run the command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:mail ActiveUser — markdown=emails.active-user&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command above will create the &lt;strong&gt;app/Mail/ActiveUser.php&lt;/strong&gt; class and a blade file, &lt;strong&gt;resources/views/emails/active-user.blade.php&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can customize the blade template message with any text of your choice. Also configure Laravel’s email services via your application’s &lt;strong&gt;config/mail.php&lt;/strong&gt; configuration file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Implement logic&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, I’ll place DB-related functionality into Eloquent models by defining the query constraints in the User model class using the Eloquent local scope. In &lt;strong&gt;app/Models/User.php&lt;/strong&gt;, define the following method:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * Scope a query to only include active users.
 */
public function scopeActive($query): void
{
    $query-&amp;gt;where('is_active', 1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Second, I will implement my logic in the SendMailToActiveUsers class handle method (created in step 3).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modify the handle method in &lt;strong&gt;app/Console/Commands/SendMailToActiveUsers.php&lt;/strong&gt; to this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use App\Mail\ActiveUser;
use App\Models\User;


public function handle()
{
    $activeUsersEmail = User::active()-&amp;gt;pluck('email');
    foreach ($activeUsersEmail as $user) {
        Mail::to($user)-&amp;gt;send(new ActiveUser());
    }
    return Command::SUCCESS;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The active scope methods were used when querying the user model. The pluck() method retrieves a collection of values from a single column of the database table, in this case, the email column of the active users. It returns a Laravel collection containing only the values of the email column of the active users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send individual emails in a loop by passing an instance of your mailable class to the send method&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; There are a few ways to improve this technique so that fewer requests are made to your mail server. You can batch process the email sending procedure to send emails instead of sending each one one at a time in a loop. To outsource the email sending process, you may also think about leveraging Laravel’s queueing system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;php artisan send:active-user-mail&lt;/code&gt; to send mail.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>laravel</category>
      <category>php</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Code Documentation</title>
      <dc:creator>Samson Ojugo</dc:creator>
      <pubDate>Wed, 10 May 2023 10:55:20 +0000</pubDate>
      <link>https://dev.to/quietnoisemaker/code-documentation-4ma3</link>
      <guid>https://dev.to/quietnoisemaker/code-documentation-4ma3</guid>
      <description>&lt;p&gt;A DocBlock explains the purpose of a specific class, method, or other structural component. DocComments are a specific form of comment that always enclose DocBlocks. A DocComment is denoted by the characters &lt;code&gt;/** (opener)&lt;/code&gt; and &lt;code&gt;*/ (closer)&lt;/code&gt;.&lt;br&gt;
There should be an asterisk (*) at the beginning of every line between the DocComment opener and its closer.&lt;/p&gt;

&lt;p&gt;The phpdoc command can be used with phpDocumentor to provide comprehensive documentation for your Laravel project.&lt;/p&gt;

&lt;p&gt;How effectively is your source code documented?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q3nXQSQ---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5cauek3n8p2hzm5y2yo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q3nXQSQ---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5cauek3n8p2hzm5y2yo.png" alt="Image description" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>documentation</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to read data from an API and populate the database without duplicates in Laravel</title>
      <dc:creator>Samson Ojugo</dc:creator>
      <pubDate>Thu, 04 May 2023 16:20:58 +0000</pubDate>
      <link>https://dev.to/quietnoisemaker/how-to-read-data-from-an-api-and-populate-the-database-without-duplicates-in-laravel-316e</link>
      <guid>https://dev.to/quietnoisemaker/how-to-read-data-from-an-api-and-populate-the-database-without-duplicates-in-laravel-316e</guid>
      <description>&lt;p&gt;Today in this tutorial, you will learn how to read data from an External API and populate the database without duplicates in Laravel 8 applications. This tutorial assumes you are already familiar with basic Laravel implementations. I will be using a Public API that fetches entry records &lt;a href="https://api.publicapis.org/entries"&gt;https://api.publicapis.org/entries&lt;/a&gt;. This API does not require a token for authorization.&lt;/p&gt;

&lt;p&gt;Before getting started, you should ensure that you have installed the Guzzle package as a dependency of your application. By default, Laravel automatically includes this dependency. However, if you have previously removed the package, you may install it again via Composer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create a model and migration
&lt;/h2&gt;

&lt;p&gt;Generate a database migration when you generate the model with this command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:model ApiEntry -m&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Define database Schema
&lt;/h2&gt;

&lt;p&gt;Go to the migration file that was just created and define your database schema :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function up()
    {
        Schema::create('api_entries', function (Blueprint $table) {
            $table-&amp;gt;id();
            $table-&amp;gt;string('api');
            $table-&amp;gt;string('description');
            $table-&amp;gt;string('auth')-&amp;gt;nullable();
            $table-&amp;gt;boolean('https');
            $table-&amp;gt;string('cors');
            $table-&amp;gt;string('link');
            $table-&amp;gt;string('category');
            $table-&amp;gt;timestamps();
    });
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The column here is what I’m expecting from the external API I will be consuming.&lt;/p&gt;

&lt;p&gt;Then run the &lt;code&gt;php artisan migrate&lt;/code&gt; command to migrate your table&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Define the model attribute
&lt;/h2&gt;

&lt;p&gt;You should define which model attributes you want to make mass assignable. You may do this using the &lt;strong&gt;$fillable&lt;/strong&gt; property on the model.&lt;/p&gt;

&lt;p&gt;Go to &lt;strong&gt;app\Models\ApiEntry.php&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ApiEntry extends Model
{
    use HasFactory;

    protected $fillable = [
        'api',
        'description',
        'auth',
        'https',
        'cors',
        'link',
        'category'
    ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Define routes
&lt;/h2&gt;

&lt;p&gt;Define your &lt;strong&gt;routes/web.php&lt;/strong&gt; file. You can also define your route in &lt;strong&gt;routes/api.php&lt;/strong&gt; (if you want to create an API route).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ApiEntryController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/public/endpoint', [ApiEntryController::class, 'insertApiRecords']);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Create a Controller
&lt;/h2&gt;

&lt;p&gt;Create the &lt;strong&gt;ApiEntryController&lt;/strong&gt; using the command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Php artisan make:controller ApiEntryController&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Implement logic&lt;/strong&gt;&lt;br&gt;
Here I choose to keep my controller skinny and the model thin. So I put my logic in a Service class and import it into the controller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
namespace App\Services\ReadDataApiService;
use App\Models\ApiEntry;
use Illuminate\Support\Facades\Http;

class ReadDataApi
{
    public function getApiEntry()
    {
        $url = "https://api.publicapis.org/entries";//assign API to a variable
        $response = Http::get(
            $url
        );
        $responseBodyClient = $response-&amp;gt;json();
        $externalApiEntries = $responseBodyClient['entries'];

        foreach ($externalApiEntries as $externalApiEntry) {
            ApiEntry::updateOrInsert(
                [
                    'api' =&amp;gt; $externalApiEntry['API'],
                    'description' =&amp;gt; $externalApiEntry['Description'],
                    'link' =&amp;gt; $externalApiEntry['Link'],
                    'category' =&amp;gt; $externalApiEntry['Category'],
                ],
                [
                    'auth' =&amp;gt; $externalApiEntry['Auth'],
                    'httpS' =&amp;gt; $externalApiEntry['HTTPS'],
                    'cors' =&amp;gt; $externalApiEntry['Cors'],
                ]
            );
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I created the file ReadDataApi.php - &lt;strong&gt;app/Services/ReadDataApiService/ReadDataApi.php&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assign the API URL to a variable $url.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I make a get request to the URL&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Convert the response to a JSON format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I loop through the response and use the &lt;strong&gt;updateOrInsert&lt;/strong&gt; method (I made sure to specify the unique attributes in the first parameter to ensure that there are no duplicates)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The updateOrInsert method will attempt to locate a matching database record using the first argument's column and value pairs. If the record exists, it will be updated with the values in the second argument. If the record can not be found, a new record will be inserted with the merged attributes of both arguments. Read more here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can also use the &lt;strong&gt;firstOrCreate&lt;/strong&gt; or &lt;strong&gt;UpdateOrCreate&lt;/strong&gt; method. Also, make sure to specify the unique attributes in the first parameter to ensure that there are no duplicates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Import it into your controller
&lt;/h2&gt;

&lt;p&gt;Go to &lt;strong&gt;app/Http/Controllers/ApiEntryController&lt;/strong&gt; and use Controller dependency injection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\ReadDataApiService\ReadDataApi;

class ApiEntryController extends Controller
{
    protected $readDataApi;

    public function __construct(ReadDataApi $readDataApi)
    {
        $this-&amp;gt;readDataApi = $readDataApi;
    }

    public function insertApiRecords()
    {
        try {

            $this-&amp;gt;readDataApi-&amp;gt;getApiEntry();
        } catch (\Throwable $th) {
            return $th-&amp;gt;getMessage();//you can also return you custom exception
        }
        return 'Operation Successful';//you can return a view or JSON
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Go to &lt;strong&gt;&lt;a href="http://127.0.0.1:8000/public/endpoint"&gt;http://127.0.0.1:8000/public/endpoint&lt;/a&gt;&lt;/strong&gt; to test your implementation. You can get the complete code from the &lt;a href="https://github.com/quitenoisemaker/consume_external_api"&gt;Github repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>api</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to create Laravel middleware that only allows specific users.</title>
      <dc:creator>Samson Ojugo</dc:creator>
      <pubDate>Sun, 30 Apr 2023 13:09:35 +0000</pubDate>
      <link>https://dev.to/quietnoisemaker/how-to-create-laravel-middleware-that-only-allows-specific-users-in8</link>
      <guid>https://dev.to/quietnoisemaker/how-to-create-laravel-middleware-that-only-allows-specific-users-in8</guid>
      <description>&lt;p&gt;Today in this post, you will learn how to create middleware that allows specific users (emails) only in Laravel 8 applications.&lt;/p&gt;

&lt;p&gt;Laravel middleware provide a convenient mechanism for inspecting and filtering HTTP requests entering your application. For example, Laravel includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to your application’s login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step1 :Create Helper function that return arrays of the specific users email&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's create a function in our helper file that return arrays of specific user's email address. Go to in &lt;strong&gt;app\helpers.php&lt;/strong&gt; and create the function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function usersThatCanAccessClientLogPage()
    {
        $userEmails = [
            "samadmin@example.com",
            "johndoe@example.com"
        ];
       return $userEmails;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will later call this function when implementing the logic in our middleware.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 2 :Create Middleware:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Lets assume there is a page for &lt;strong&gt;Client logs&lt;/strong&gt; and only certain email can access that page&lt;/p&gt;

&lt;p&gt;Open the terminal and execute the following command to create custom middleware in Laravel 8. So let’s open our command prompt and execute below command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:middleware CheckClientDownloadPage&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command will create a new &lt;strong&gt;CheckClientDownloadPage&lt;/strong&gt; class within your &lt;strong&gt;app/Http/Middleware&lt;/strong&gt; directory&lt;/p&gt;

&lt;p&gt;After successfully creating your middleware, go to &lt;strong&gt;app/http/kernel.php&lt;/strong&gt; and register your custom middleware here :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Register your CheckClientDownloadPage middleware and import the class
protected $routeMiddleware = [
    'auth' =&amp;gt; \App\Http\Middleware\Authenticate::class,
    'auth.basic' =&amp;gt; \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' =&amp;gt; \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'cache.headers' =&amp;gt; \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' =&amp;gt; \Illuminate\Auth\Middleware\Authorize::class,
    'guest' =&amp;gt; \App\Http\Middleware\RedirectIfAuthenticated::class,
    'signed' =&amp;gt; \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' =&amp;gt; \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' =&amp;gt; \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    'client.log' =&amp;gt; CheckClientDownloadPage::class,
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Step 3: Implement Logic In Middleware:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After successfully registering your middleware in &lt;strong&gt;app/http/kernel.php&lt;/strong&gt;, go to &lt;strong&gt;app/Http/Middleware/CheckClientDownloadPage.php&lt;/strong&gt; and implement your logic here :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;app/Http/Middleware/CheckClientDownloadPage.php&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class CheckClientDownloadPage
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $loginUser = Auth::user(); // Get the currently authenticated user...
        if (Auth::check()) {
          // The user is logged in...
            if (in_array($loginUser-&amp;gt;email, usersThatCanAccessClientLogPage())) {
                return $next($request);
            }
            return redirect('/user/admin/dashboard');
        }
        return redirect('/login');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Step 4:Add Route&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Simply create a Laravel route and use custom middleware with routes to filter every HTTP request:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;routes/web.php&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Route group for route that uses the middleware
Route::middleware(['client.log'])-&amp;gt;group(function () {
//add your route here
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
