megacolorboy

Abdush Shakoor's Weblog

Writings, experiments & ideas.

Generating custom snippets using Visual Studio Code

I've always wanted to write about this feature and I believe this is one of the most productivity hacks you can do to speed your work and worry-less about writing boilerplate code.

For example, if I wanted to write a piece of code that fetches a list of books asynchronously using JavaScript, I would have to type it or maybe copy-paste that stub from another file or project and edit it accordingly. That's fine but when working on a large project or tight deadlines, it can be quite time-consuming if all you want is just a boilerplate code that's ready to begin with.

Here's how you can create your own snippet:

  1. Press Ctrl+Shift+P
  2. Type Configure User Snippets and hit Enter
  3. Select the language for which it should appear and hit Enter

Once done, a new tab will open up with simple instructions for you to get started with. The instructions are quite straight-forward and you can write something like this right below the note:

{
    // Place your snippets for javascript here. Each snippet is defined under a snippet name and has a prefix, body and 
    // description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
    // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the 
    // same ids are connected.
    // Example:
    // "Print to console": {
    //  "prefix": "log",
    //  "body": [
    //      "console.log('$1');",
    //      "$2"
    //  ],
    //  "description": "Log output to console"
    // }
    "AJAX Get Method": {
        "prefix": "ajax-get",
        "body": [
            "$.ajax({",
            "\turl: '/',",
            "\tmethod: 'GET',",
            "\tdatatype: 'json',",
            "\tsuccess: (data) => {",
            "\t\tconsole.log(data);",
            "\t},",
            "\terror: (err) => {",
            "\t\tconsole.error(err);",
            "\t}",
            "});",
        ],
        "description": "A simple AJAX GET Method"
    }
}

Save the file and test if the snippet works fine by opening any file, in this case, open an empty .js file and type ajax-get and hit Tab at the end of the prefix. The generated snippet would look like this:

$.ajax({
    url: '/',
    method: 'GET',
    datatype: 'json',
    success: (data) => {
        console.log(data);
    },
    error: (err) => {
        console.error(err);
    }
});

Learn more about generating snippets by reading the documentation about it.

Hope this tip helps you out!

Using the null-coaleascing operator in C#

Null checks are the most underrated thing and despite years of experience, we still forget to write a null check in our code.

When it comes to writing null checks, this is what one would most write:

string foo = null;
string bar;
if(foo != null)
{
    bar = foo;
}
else
{
    bar = "Hello, friend!";
}
Console.WriteLine(bar) // Output: Hello, friend!

Yes, it does the job but it's a bit lengthy and not so readable. Let's see how the ?? operator i.e. the null-coalescing operator can help simplify your logic:

string foo = null;
string bar = foo ?? "Hello, friend!";
Console.WriteLine(bar) // Output: Hello, friend!

Now, you can bid goodbyes to writing verbose null checks and make your code more cleaner and readable.

Hope this tip helps you out!

Check if a string is a UNIQUEIDENTIFIER in SQL Server

Recently, when I was performing a data migration that contained previous payment history, I came across a table that had a column named PaymentId which is supposed to have a UUID styled format but funnily enough, it was kind of confusing because some of them had numbers in it.

Luckily, the ones that weren't in UUID format are not supposed to be migrated, so I decided to write a SELECT query and filter the records using the TRY_CONVERT function:

SELECT 
    * 
FROM 
    dbo.YourTable 
WHERE 
    TRY_CONVERT(UNIQUEIDENTIFIER, YourColumn) IS NOT NULL;

Yes, it's that simple. You don't need to write any complex regular expressions for such operations.

Hope you found this tip useful!

Filtering results by weekdays in SQL Server

Ever wanted to know how many people are actively posting something on a Monday? Or maybe during the weekends?

You can do that by using the DATEPART and DATENAME functions. Let me show you how they work.

Using DATEPART

The DATEPART function represents weekdays as integers from 1 (Sunday) to 7 (Saturday).

Let's say that you wanted to filter between Monday and Friday, you can achieve something like this:

SELECT * FROM dbo.YourTable WHERE DATEPART(WEEKDAY, YourDateColumn) BETWEEN 2 and 6;

One thing to note, in SQL Server, Sunday is the first day of the week. So, if you wanted to set the first day of the week, you can write the following statement before executing your query:

SET DATEFIRST 1;  -- Set Monday as the first day of the week
SELECT * FROM dbo.YourTable WHERE DATEPART(WEEKDAY, YourDateColumn) BETWEEN 1 and 5;

In the example above, you'll achieve the same results as the previous one.

Using DATENAME

The DATENAME function represents weekdays as a string from Monday to Sunday.

Let's replicate the previous example using this function:

SELECT * FROM dbo.YourTable WHERE DATENAME(WEEKDAY, YourDateColumn) IN ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday');

If you want to know more about filtering your records effectively using these methods, you can the read the documentation:

Hope you found this tip useful!

Don't forget what sparked your passion

A short letter to myself and other fellow programmers.

Do you ever remember falling in love with programming when learning to code during school days or while working on a client's project? Probably not.

When I started learning to code, I never wrote code because I wanted to but because I desired to. No one to poke me around with tight deadlines, no need to race against time. Just the feeling of power and creativity in your hands to build something out of nothing but just pure code. It could have been anything as simple as building a small widget for my blog post, writing a game, solving a problem in LeetCode or Project Euler or maybe writing a bash script to automate my tasks.

You could probably relate to some but for me, these are some of the examples that resonate with me.

I'm writing this as a reminder to myself and other fellow programmers: don't ever forget that moment when your passion for programming had sparked. You might be older now and you're probably filled with a lot of responsibilities (especially if you're parenting).

Perhaps, you might never even experience that same amount of adrenaline and rush that you had when you were behind the computer in your room while your siblings and friends were trying to distract you.

There's never an end to learning. You can still find some passion projects that'll help you keep that spark. Have an open mind and be open to newer ideas. Solve a puzzle, read a book, write a game or maybe a blog post.

Don't do this because you need to impress someone or for the sake of it rather because you can and it brings you joy.

Oh and wishing you a Happy New Year! 😀🎄

Configure XDebug in Visual Studio Code

For the past 6 months, I've been writing code in C# 11 and .NET 7 Core and of course, using the amazing Visual Studio 2022 IDE was quite an amazing experience especially when it comes to debugging your code.

Recently, I had to switch back to classic ol' PHP and now, I wanted a similar debugging experience in Visual Studio Code.

Using XDebug and if configured correctly, it'll be quite useful in your debugging journey instead of using var_dump() or dd() your variables everytime.

Prerequisites

The only thing you need here is Visual Studio Code and ensure that it's the latest version. I'm writing this from a Windows Machine using the latest version of WAMP Server.

1. Download PHP Debug

The official XDebug team has released an extension that could be installed in your editor. So, here you go, first download it.

2. Install XDebug

In the previous step, we just installed the extension for the editor but that's just an adapter used between the editor and XDebug. Whereas, XDebug is a PHP extension that needs to be installed on your local system.

I'm not going to show you the installation process as this documentation explains that well enough and you can follow it based on your operating system of choice.

3. PHP Configuration

After you're done with installing the extension, open your php.ini file and add the following line in this file:

zend_extension=path/to/xdebug

Now, it's time to enable remote debugging. Depending on your XDebug version:

For XDebug v3.x.x:

xdebug.mode = debug
xdebug.start_with_request = yes

For XDebug v2.x.x:

xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_port = 9000

If you are looking for more specific options, please see read the documentation on remote debugging. Please note that the default port in XDebug v3.x.x has been changed from 9000 to 9003.

Once done, restart your PHP service and check if the configuration has taken effect. You can do this by creating a simple test.php with a phpinfo(); statement in there and look for your XDebug extension under the Loaded Configuration File section.

4. Visual Studio Code Configuration

In your editor, hold CTRL + SHIFT + P and type "Debug: Add Configuration" and it'll prompt you to select your language of preference and this case, of course, you should "PHP".

Upon selecting, it'll automatically generate a launch.json file in your .vscode folder in your project folder.

There'll be three different configurations in your file:

  • Listen for XDebug: This setting will simply start listening on the specified port (by default 9003) for XDebug.
  • Launch currently open script: It will launch the currently opened script as a CLI, show all stdout/stderr output in the debug console and end the debug session once the script exits.
  • Launch Built-in web server: This configuration starts the PHP built-in web server on a random port and opens the browser with the serverReadyAction directive.

Now, to test if it works, hit F5 and add a breakpoint in your PHP code and if it lands on your breakpoint, that means it works fine.

Hope you found this article useful!

References

Generate CSR with multiple subdomains using OpenSSL

I have done this many times but I never got to write about it and I felt that I should write about it after I helped a friend of mine with this.

Prerequisites

It doesn't matter which operating system you're going to do this on as long as you have openssl installed in your system, you should be fine.

All you have to do is just create a simple configuration file and give it a name like multiple-domains.cnf:

[req]
default_bits       = 2048
distinguished_name = req_distinguished_name
req_extensions     = req_ext

[req_distinguished_name]
countryName         = [COUNTRYCODE]
stateOrProvinceName = [STATE]
localityName        = [LOCALITY]
organizationName    = [ORGANIZATION]
commonName          = website.com

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = website.org
DNS.2 = wesbite.ae
DNS.3 = wesbite.co.uk

Save the file and copy-paste this into your command prompt or terminal:

openssl req -out <your-csr-name>.csr -newkey rsa:2048 -nodes -keyout <your-private-key-name>.key -config multiple-domains.cnf

Once executed, it should be generated for you and if not, verify your configuration file for any typos.

Hope this helps you out!

Clean Controllers in Laravel: Best practices for handling form submissions

Learn how to write clean Laravel controllers for efficient contact form handling using validation, Eloquent, Mail, and events.

Unlike most frameworks, Laravel is an unopinionated framework and doesn't force the developer to follow a particular pattern.

In this article, I'm going to show you how your codebase could benefit by following Laravel's best practices like separation of concerns, utilizing Laravel's in-built features like Eloquent models, Form Requests and Mail.

To begin with, here's a dirty method that handles a simple contact form submission:

<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;

class ContactController extends Controller
{
    public function submit(Request $request)
    {
        // Validate the form inputs
        $request->validate([
            'name' => 'required',
            'email' => 'required|email',
            'message' => 'required',
        ]);

        // Get the form data
        $name = $request->input('name');
        $email = $request->input('email');
        $message = $request->input('message');

        // Save the form data in the database
        DB::table('contact_forms')->insert([
            'name' => $name,
            'email' => $email,
            'message' => $message,
        ]);

        // Send an email to the user
        $mailData = [
            'name' => $name,
            'email' => $email,
            'message' => $message,
        ];

        Mail::send('emails.contact', $mailData, function ($message) use ($email) {
            $message->to($email)->subject('Thank you for contacting us');
        });

        // Return a response to the user
        return redirect()->back()->with('success', 'Thank you for contacting us! We will get back to you soon.');
    }
}

To most developers, this method might seem straight-forward and they might even debate with you that it's completely fine. But allow me to highlight the issues of that this method brings to the table:

  1. Lack of separation of concerns: The controller is responsible for handling form validation, saving data to the database, and sending an email. This violates the Single Responsibility Principle.

  2. Direct usage of the database query builder: Instead of utilizing Eloquent models for database interactions, the example directly uses the query builder, which can make the code less maintainable and harder to read.

  3. Inline email sending: The email sending functionality is implemented inline within the controller method, making the code harder to test and reuse.

  4. Lack of error handling: The example does not handle any potential errors that may occur during form validation, database insertion, or email sending.

Now, it's time to make it cleaner.

Save data using Form Requests and Laravel's Eloquent ORM

Let's start with creating a form request that is dedicated to handling the validation logic:

  1. Quickly, open up your terminal and type the following command:
php artisan make:request ContactFormRequest

This command will generate a new file named ContactFormRequest.php in the app/Http/Requests directory.

  1. Open the ContactFormRequest.php file and modify it as follows:
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ContactFormRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        // Set the authorization logic based on your requirements
        // For example, you may check if the user is authenticated or has certain permissions.
        // Return true if the user is authorized to submit the form; otherwise, return false.
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required',
            'email' => 'required|email',
            'message' => 'required',
        ];
    }

    public function messages()
    {
        return [
            'name.required' => 'Please enter your name',
            'email.required' => 'Please enter your email address',
            'email.email' => 'Please enter a valid email address',
            'message.required' => 'Write a message before submit the form',
        ];
    }
}

In the rules() method, you can define validation rules for each field in the form. You can adjust according to your own preferences and if you want to know more about them, read this documentation.

  1. Save the ContactFormRequest.php file.

Great, now you have a separate class for validating your contact form and this promotes code-reusability, improves code readability and separates the validation logic from your controller.

Now let's update the submit() method in the ContactController.php example:

<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Http\Requests\ContactFormRequest;
use App\Models\ContactFormModel;

class ContactController extends Controller
{
    public function submit(ContactFormRequest $request)
    {
        // Validate the form inputs
        // All of the validated form data is accessible via this property.
        $validated = $request->validated();

        // Save the submission
        ContactFormModel::create($validated);

        // Send an email to the user
        $mailData = [
            'name' => $name,
            'email' => $email,
            'message' => $message,
        ];

        Mail::send('emails.contact', $mailData, function ($message) use ($email) {
            $message->to($email)->subject('Thank you for contacting us');
        });

        // Return a response to the user
        return redirect()->back()->with('success', 'Thank you for contacting us! We will get back to you soon.');
    }
}

Ensure that you have an appropriate model for your contact_forms table like ContactFormModel.php and update the following like so:

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class ContactForm extends Model
{
    protected $table = 'contact_forms';

    // Define any additional model configurations, relationships, or methods.
    protected $fillable = [
        'name',
        'email',
        'message'
    ];

    protected $timestamps = true;
}

This allows you to leverage Laravel's ORM in which you could benefit from easy quering, relationship management and automatic timestamps.

Making use of Laravel Events and Mail

  1. Generate a new event class by writing the following artisan command:
php artisan make:event ContactFormSubmitted

This will generate a ContactFormSubmitted class in the app/Events directory.

  1. Open up ContactFormSubmitted.php file and update as follows:
<?php
namespace App\Events;

use App\Models\ContactForm;
use Illuminate\Foundation\Events\Dispatchable;

class ContactFormSubmitted
{
    use Dispatchable;

    public $contactForm;

    /**
     * Create a new event instance.
     *
     * @param  ContactForm  $contactForm
     * @return void
     */
    public function __construct(ContactForm $contactForm)
    {
        $this->contactForm = $contactForm;
    }
}
  1. Next, let's generate an event listener using artisan command:
php artisan make:listener SendContactFormEmail --event=ContactFormSubmitted

This command will generate SendContactFormEmail event listener in the app/Listeners directory.

  1. Open the SendContactFormEmail.php file and update as follows:
<?php
namespace App\Listeners;

use App\Events\ContactFormSubmitted;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Mail;
use App\Mail\ContactFormSubmitted as ContactFormSubmittedMail;

class SendContactFormEmail implements ShouldQueue
{
    use InteractsWithQueue;

    /**
     * Handle the event.
     *
     * @param  ContactFormSubmitted  $event
     * @return void
     */
    public function handle(ContactFormSubmitted $event)
    {
        $contactForm = $event->contactForm;

        // Send an email to the user
        Mail::to($contactForm->email)
            ->send(new ContactFormSubmittedMail($contactForm));
    }
}
  1. Create a mailable class using the following artisan command:
php artisan make:mail ContactFormSubmitted

This command will generate a new ContactFormSubmitted mailable class in the app/Mail directory.

Now, update the ContactFormSubmitted.php file as follows:

<?php
namespace App\Mail;

use App\Models\ContactForm;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class ContactFormSubmitted extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    public $contactForm;

    /**
     * Create a new message instance.
     *
     * @param  ContactForm  $contactForm
     * @return void
     */
    public function __construct(ContactForm $contactForm)
    {
        $this->contactForm = $contactForm;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->subject('Thank you for contacting us')
            ->view('emails.contact')
            ->with('contactForm', $this->contactForm);
    }
}
  1. Let's open up the ContactController.php and import the necessary classes on top:
<?php
use App\Events\ContactFormSubmitted;
use Illuminate\Support\Facades\Mail;
  1. Lastly, update the submit() method as follows:
<?php
use App\Http\Requests\ContactFormRequest;
use App\Models\ContactForm;
use App\Events\ContactFormSubmitted;
use Illuminate\Support\Facades\Mail;
use App\Mail\ContactFormSubmitted;

class ContactController extends Controller
{
    public function submit(ContactFormRequest $request)
    {
        // Validated form data is accessible via the $validatedData property of the form request instance
        $validatedData = $request->validated();

        // Save the form data in the database using Eloquent
        $contactForm = new ContactForm();
        $contactForm->name = $validatedData['name'];
        $contactForm->email = $validatedData['email'];
        $contactForm->message = $validatedData['message'];
        $contactForm->save();

        // Dispatch an event to handle email sending asynchronously
        event(new ContactFormSubmitted($contactForm));

        // Return a response to the user
        return redirect()->back()->with('success', 'Thank you for contacting us! We will get back to you soon.');
    }
}

Ah! Finally, this looks much better now, doesn't it?

By making use of Laravel's Mail method, events and listeners, we've separated the logic for sending emails from the controller. The email is now sent asynchronously using an event and listener combination. This approach improves code organization, maintainability, and scalability.

Hope you found this article to be useful.